Reinstalando o OP_CAT na Linguagem de Script do Bitcoin.
By
Alex Emidio
December 16, 2023
· Edited October 24, 2024
OP_CAT é um opcode simples, mas poderoso, que combina dois valores de entrada em uma saída. Originalmente, ele foi desativado devido a preocupações com problemas de memória, mas as condições mudaram. OP_CAT é um opcode que lida com a concatenação de valores de entrada, unindo dois valores em um. Embora possa parecer simples à primeira vista, suas possibilidades são amplas e intrigantes.
Especificação
O opcode OP_CAT opera abrindo dois elementos da pilha, concatenando-os na ordem em que estão empilhados e empurrando o elemento resultante de volta para a pilha. Dada a pilha [x1, x2], onde x2 está no topo da pilha, o OP_CAT colocará x1 x2 na pilha, onde ‘’ denota concatenação.
Essa implementação é baseada na implementação do OP_CAT em elementos.
O valor de MAX_SCRIPT_ELEMENT_SIZE é 520 bytes.
Notas
O OP_CAT existia na base de código Bitcoin antes do commit “alterações diversas” 4bd188c que o desativou. A implementação original funcionava da seguinte forma:
Essas informações detalhadas sobre a especificação e a implementação do OP_CAT esclarecem como ele funciona e como as operações são executadas.
OP_CAT não é uma novidade, sendo parte das instruções do Bitcoin Script em versões antigas. Foi desativado devido a preocupações de aumento exponencial de memória na pilha de elementos. No entanto, desde que foi desativado, um tamanho máximo de 512 bytes foi fornecido para elementos de pilha, e isso também é aplicado ativamente hoje no Tapscript, que é o Bitcoin Script na atualização Taproot. O problema daquela época realmente não se aplica aqui, pois um script que desejasse criar elementos acima desse limite seria simplesmente inválido.
OP_CAT possibilita novas opções de assinatura, assinaturas Lamport com segurança quântica, cofres Bitcoin e convênios/CTV que determinam as condições de saída. Isso abre portas para métodos de escalonamento , Confirmação instantânea de transações on-chain , Livre mercado de sidechains, como Ark, e simplifica a implementação de BitVM para contratos inteligentes.
Várias aplicações possíveis para o OP_CAT, como covenants, verificação de provas SPV, proteção contra gastos duplos em transações não confirmadas, tornar o BitVM mais eficiente, realizar aritmética com números grandes, criar vaults e assinaturas resistentes a computadores quânticos.
Para reintroduzir o OP_CAT, seria necessária uma atualização (soft fork) nas regras de consenso do Bitcoin, o que exige planejamento cuidadoso. No entanto, a proposta atual é gerenciável e não apresenta as preocupações anteriores devido às limitações estabelecidas.
O OP_CAT promete ser uma adição valiosa à linguagem de script do Bitcoin, proporcionando um leque de possibilidades interessantes para desenvolvedores e usuários. A reintrodução desse opcode parece promissora, oferecendo um equilíbrio entre esforço e casos de uso potenciais, e ainda há espaço para discussões sobre suas vantagens e desvantagens.
In his article, CAT and Schnorr Tricks I, Andrew Poelstra showed how to emulate OP_CHECKSIGFROMSTACK-like covenants using only OP_CATand Schnorr signatures.
Here, we show that a similar trick is possible to emulate covenants using only OP_CAT and ECDSA signatures.
The High-Level Idea
Recall the ECDSA Signature Equation
Given a secret key x and the corresponding public key P = xG. The signer chooses some random secret nonce k and computes public nonce R = kG. We call r the first coordinate of the point R. Then the signature equation for message hash H = Hash(message) is
s = ( H + r * x ) / k
Getting the Sighash onto the Stack
We get the sighash onto the stack by choosing k = 1 and x = 1/r, so the signature becomes s = H + 1.
We make the script require a signature from public key P = xG = 1/r G and require that signature to use public nonce R = kG = 1G = G. The nonce and the sighash are glued together (DER encoded) using OP_CAT into a ECDSA signature that can be verified using OP_CHECKSIGVERIFY.
So essentially, copying this signature before verifying it puts sighash + 1 onto the stack.
Further Details
Adding 1 to the Hash
Computing s = H + 1 is a bit tricky as there is no 256-bit arithmetic in Script. Either we can use Andrew's workaround
We just require the user grind her transaction data until the actual hash ends in the byte 01, which is pretty cheap (takes 256 tries on average, which at 250ns per shot would take 64 microseconds, comparable to the signing algorithm itself). Then her s value will end it 2, which we enforce by asking her to leave it off; we'll add it ourselves.
Alternatively, the unlocking script can contain H, chunked into 8 different 32-bit chunks. Then we can use regular 32-bit arithmetic to compute 1 + chunk_0 and finally, glue back together (1+chunk_0) | chunk_1 | ... | chunk_7 using OP_CAT.
Putting it all together to get a Covenant
The covenant works similar to OP_CHECKSIGFROMSTACK. However, it requires only a single signature check.
The locking script commits to prefix and postfix of the covenant TX. In the unlocking script is only the TXID of the prev TX to resolve the hash cycle. The locking script assembles the covenant TX using OP_CAT and computes its sighash by hashing it. (The covenant TX is serialized as for computing its sighash.)
Write a comment