Esta é a Parte 5 da série de artigos técnicos sobre covenants de Bitcoin da Cointelegraph Research. Para ler o artigo anterior, clique aqui. 

MATT (Merkleize All The Things) é uma estrutura de contratos inteligentes para Bitcoin que permite contratos com estado e provas de fraude escaláveis. Um contrato com estado carrega informações de uma transação para outra e pode atualizar essas informações à medida que o contrato evolui. Os scripts padrão do Bitcoin não oferecem esse recurso, pois cada transação é avaliada de forma independente, sem memória das execuções anteriores.

Toda proposta de covenant permite, até certo ponto, UTXOs que carregam estado, como ilustram linguagens de script como Sapio, que se baseia em OP_CTV. Isso funciona usando endereços para representar um autômato de estados finitos, em que as transações funcionam como transições de estado. No entanto, não há uma maneira elegante de implementar lógica numérica nesse paradigma — uma lacuna que o MATT preenche, em particular com sua implementação proposta por meio de OP_CCV. Como o MATT permite que dados comprometidos sejam computados no momento do gasto e incorporados novamente à saída seguinte, cada gasto pode derivar dinamicamente um novo estado, em vez de escolher entre um conjunto predeterminado de estados.

Como OP_CCV compromete o estado em uma chave Taproot

Para entender a proposta MATT, é útil primeiro rever como a Taproot compromete dados por meio de chaves públicas. Toda saída Taproot contém uma chave pública base, chamada chave interna, que pode ser modificada criptograficamente, ou “ajustada”, para comprometer informações adicionais. Formalmente, a chave pública ajustada é Q = P + t·G, em que P é a chave interna, G é o gerador da curva elíptica secp256k1 e t é um hash com etiqueta de P e dos dados comprometidos.

Em uma saída Taproot comum, esse compromisso normalmente codifica a raiz de Merkle de uma árvore taptree, que contém caminhos de gasto ocultos. O MATT baseia-se nesse mecanismo para também incorporar o estado do contrato à chave. Em vez de inserir lógica complexa diretamente na linguagem de script do Bitcoin, o MATT codifica a computação como uma sequência de compromissos de estado, e a cadeia verifica apenas se cada transição de estado é válida.

O MATT pode ser implementado por meio de diferentes combinações de opcodes. A implementação mais direta e bem especificada baseia-se em OP_CHECKCONTRACTVERIFY (OP_CCV). OP_CCV fornece a primitiva que torna viáveis os UTXOs que carregam estado dentro da Taproot. OP_CCV permite que um script verifique se a chave de entrada ou de saída Taproot foi ajustada para comprometer um dado estado específico. Primeiro, a chave interna é ajustada com um hash do estado atual do contrato; em seguida, aplica-se por cima o ajuste padrão da árvore taptree da Taproot. Portanto, a chave de saída resultante compromete tanto o tapscript (o conjunto de condições de gasto) quanto o estado atual do contrato.

OP_CCV pode então impor qual estado é levado adiante para a saída seguinte. Ele permite que o script inspecione os dados de estado fornecidos na pilha witness, faça cálculos com eles e exija que o estado atualizado resultante seja novamente comprometido corretamente em uma saída especificada. É assim que as transições de estado são impostas na cadeia. O formato da pilha é:

<data> <index> <pk> <taptree> <mode> OP_CHECKCONTRACTVERIFY

O opcode oferece três modos para verificar uma saída, além de um modo separado para entradas. No modo padrão, todo o valor em BTC do UTXO de entrada é alocado à saída especificada; no modo de dedução, atribui-se apenas uma parcela igual ao valor da saída, deixando o restante disponível para outras saídas; e, no modo de ignorar, o script e o compromisso dos dados são verificados sem impor restrições ao valor. Como os modos padrão e de dedução foram concebidos para preservar o valor entre as saídas verificadas, as taxas de transação precisam ser pagas por meio de entradas separadas destinadas a esse fim. É possível adicionar à transação uma entrada específica para pagar taxas e uma saída de troco sem entrar em conflito com as restrições do covenant. Isso evita a queima acidental de fundos que pode ocorrer em implementações mais primitivas de covenant, como OP_CTV ou SIGHASH_ANYPREVOUT. Também resolve uma grande limitação dos covenants no estilo de transações pré-assinadas, que normalmente definem os valores de antemão e, por isso, não conseguem acomodar ajustes dinâmicos de taxas nem unvaults parciais.

OP_CCV + OP_CAT: provas de Merkle e provas de fraude

Quando OP_CCV é combinado com OP_CAT, o framework MATT completo torna-se ainda mais expressivo. OP_CAT permite concatenar bytes em Script, o que possibilita construir e verificar provas de Merkle diretamente na cadeia. Nessa configuração, há duas árvores de Merkle distintas associadas a uma saída Taproot. A primeira é a conhecida árvore de scripts Taproot (a taptree), cujas folhas são os scripts de gasto do contrato. A segunda é uma árvore de estado separada, cujas folhas são os dados do contrato, como as etapas intermediárias de uma computação. O script OP_CCV + OP_CAT pode verificar uma prova de Merkle em relação à raiz atual da árvore de estado, calcular a raiz atualizada após uma transição e usar OP_CCV para obrigar a saída seguinte a comprometer essa raiz.

Essa construção possibilita sistemas de prova de fraude com uma condição de penalização, nos quais uma computação longa é comprometida fora da cadeia e apenas a etapa específica contestada (junto com seu caminho na árvore binária) precisa ser revelada e verificada na cadeia. Sistemas semelhantes existem como rollups otimistas em outras redes blockchain: toda a computação é executada fora da cadeia, e o contrato na cadeia só intervém quando alguém apresenta um desafio. As provas de fraude exigem que a computação seja compilada em um circuito binário ou em uma representação equivalente, etapa a etapa, que possa ser comprometida em uma árvore de Merkle. OP_CCV + OP_CAT dispensaria o uso de assinaturas únicas de Lamport e de grafos de transações pré-assinadas, dos quais o BitVM depende para impor a consistência do estado.

Além das provas de fraude, a combinação de OP_CCV e OP_CAT também tem implicações para os cofres. OP_CCV sozinho pode implementar cofres, mas, combinado com OP_CAT, permite criar cofres completos, essencialmente equivalentes à funcionalidade proposta por OP_VAULT. Como observou James O’Beirne, autor de OP_VAULT, OP_CCV representa um projeto mais geral e robusto que, na prática, substitui sua proposta anterior.

No próximo artigo desta série, deixaremos de lado as propostas gerais de covenant para analisar opcodes específicos de aplicações, como OP_VAULT, OP_UNVAULT e OP_EVICT. Cada um desses opcodes foi concebido para resolver um problema específico, em vez de oferecer ampla programabilidade.

Revista: Os detentores de Bitcoin receberam eCash — o que podem fazer com ele?