Glossário / Protocolo e atualizações
SIGHASH_ANYPREVOUT
Outros nomes: APO.
- O que é SIGHASH_ANYPREVOUT?
- SIGHASH_ANYPREVOUT é um modo de assinatura proposto para scripts de Taproot que permite que uma única assinatura gaste qualquer bitcoin bloqueado em um script correspondente, em vez do único bitcoin para o qual foi criada.
Especificação no BIP-118.
O BIP-118 define um novo tipo de chave pública para tapscript, com 33 bytes começando por 0x01, e não um sinalizador acrescentado às chaves comuns. Atribuído em fevereiro de 2017, nunca foi ativado, e funciona apenas em gastos por caminho de script, nunca em gastos por caminho de chave. Nada na sua carteira consegue assinar desse modo, então qualquer produto que prometa canais eltoo na mainnet está descrevendo um futuro.
Como funciona
Status: o BIP-118 é um Draft (rascunho), atribuído em 2017-02-28, que exige o BIP-340, o BIP-341 e o BIP-342, e a sua própria seção Deployment (implantação) diz TODO. Nada foi substituído, porque nada entrou em vigor.
Uma assinatura Taproot se compromete com o outpoint do bitcoin sendo gasto, 36 bytes de txid e índice no resumo ANYONECANPAY que o BIP-118 modifica, soldando-o a um único bitcoin para sempre. Remova o outpoint da mensagem sendo assinada e a assinatura deixa de nomear um bitcoin e passa a nomear um formato, de modo que qualquer UTXO desse formato pode ser vinculado a ela depois. O BIP chama isso de dynamic rebinding (revinculação dinâmica).
Duas variantes são definidas, e a diferença entre elas é o que ainda fica comprometido.
- SIGHASH_ANYPREVOUT, valor de bit 0x40, descarta o outpoint mas mantém o valor da entrada (8 bytes), seu scriptPubKey (sempre de 35 bytes aqui) e o hash da folha. A assinatura então serve para qualquer bitcoin com o mesmo valor sob o mesmo script.
- SIGHASH_ANYPREVOUTANYSCRIPT, valor de bit 0xc0, descarta também o valor, o scriptPubKey e o hash da folha. Ela serve para qualquer bitcoin cujo script essa chave consiga satisfazer.
A adesão acontece na criação do endereço, não no momento de assinar. Essas chaves funcionam apenas por uma folha de tapscript, então o endereço precisa carregar essa folha em sua árvore de Merkle, e até ser gasto ele é indistinguível de qualquer outro endereço Taproot. Uma constante separa os dois: key_version é 0x01 para uma chave do BIP-118 contra 0x00 para uma chave de tapscript comum, de modo que uma mesma chave privada não pode produzir uma assinatura válida sob as duas regras. Seis novos bytes hash_type passam a ser legais: 0x41, 0x42, 0x43, 0xc1, 0xc2 e 0xc3.
Onde você o vê
SIGHASH_ANYPREVOUT não aparece em nenhuma transação da mainnet, e o BIP-118 prevê que ele "only be rarely used in practice" (só será usado raramente na prática) mesmo depois de existir, já que os gastos por caminho de script são mais pesados e mais identificáveis.
O projeto para o qual ele foi escrito é o eltoo, um esquema de atualização off-chain. Protocolos off-chain precisam responder a qualquer estado antigo que uma contraparte publique, e como uma assinatura comum se compromete com a transação exata à qual responde, é necessária uma nova assinatura para cada estado que possa aparecer. O eltoo, em vez disso, usa script e nLockTime para tornar as assinaturas assimétricas, de modo que uma transação que carrega uma assinatura posterior pode gastar uma que carrega uma assinatura anterior, mas nunca o contrário, e uma única assinatura de atualização pode ser aplicada sobre qualquer atualização anterior que sua contraparte tenha publicado.
O nome registra uma correção. Joseph Poon propôs a ideia como SIGHASH_NOINPUT em fevereiro de 2016, depois que o artigo original da Lightning a levantou, e a renomeação diz que a entrada não é realmente ignorada: o nSequence é sempre assinado, e sob o SIGHASH_ANYPREVOUT o script e o valor também são assinados.
A seção de segurança do BIP nomeia o preço: a repetição. Uma assinatura ANYPREVOUT pode ser reutilizada contra qualquer outro UTXO com o mesmo script e o mesmo valor, e uma assinatura ANYPREVOUTANYSCRIPT contra qualquer UTXO que reutilize essa chave em um de seus scripts, então a reutilização de chaves deixa de ser um incômodo para a privacidade e passa a ser uma forma de perder dinheiro. Essas transações também são maleáveis por desconhecidos: qualquer um capaz de fornecer uma entrada correspondente pode mudar o txid sem uma chave privada.
SIGHASH_ANYPREVOUT vs SIGHASH_ANYONECANPAY
O SIGHASH_ANYONECANPAY existe na rede hoje e remove todas as entradas, exceto a que está sendo assinada; o SIGHASH_ANYPREVOUT remove também parte dessa entrada sobrevivente. O BIP-118 descreve seu resumo como o resumo ANYONECANPAY com o outpoint deixado de fora, uma diferença de uma linha com uma grande consequência. Uma assinatura ANYONECANPAY não pode ser repetida, porque o outpoint que ela nomeia só pode ser gasto uma vez. Abra mão desse compromisso e a proteção contra repetição tem de vir do protocolo construído por cima, não da assinatura.