Bitcoin Script e opcodes

A pequena linguagem de pilha que bloqueia cada moeda.

As moedas não são guardadas em contas. Cada UTXO carrega um pequeno programa, o script de bloqueio (scriptPubKey), que diz o que é preciso para gastá-la. Quem gasta fornece um script de desbloqueio (scriptSig, ou o witness para SegWit). Um nó os executa e, se o resultado é «true», o gasto é válido.

Uma máquina de pilha

O Script é lido da esquerda para a direita. Os dados são empurrados para uma pilha, e cada opcode retira elementos, trabalha neles e empurra resultados. Não há loops, o que significa que todo script termina e o seu custo é previsível. Isso é deliberado: o Script não é Turing-completo.

Percorrendo P2PKH

O script de bloqueio clássico «pay to public key hash» é:

OP_DUP OP_HASH160 <20-byte pubkey hash> OP_EQUALVERIFY OP_CHECKSIG

Quem gasta fornece <signature> <public key>. O intérprete:

  1. empurra a assinatura e a chave pública,
  2. duplica a chave pública (OP_DUP),
  3. faz o hash da cópia com SHA-256 e depois RIPEMD-160 (OP_HASH160),
  4. verifica se coincide com o hash no script de bloqueio (OP_EQUALVERIFY),
  5. verifica a assinatura digital contra a chave e a transação (OP_CHECKSIG).

Se todos os passos passam, fica um «true» na pilha e a moeda pode ser gasta.

O que a assinatura cobre

OP_CHECKSIG não assina bytes arbitrários. Verifica um hash de partes selecionadas da transação, escolhidas pelo flag sighash. Costuma ser tudo, para que ninguém possa mudar as saídas depois que você assina.

Limites por segurança

Scripts legacy têm limites rígidos: no máximo 10.000 bytes, no máximo 201 opcodes que não são push, e no máximo 1.000 elementos na pilha. Opcodes como OP_CAT foram desativados em 2010 depois que falhas foram encontradas. Tapscript (BIP342) removeu os limites de 10.000 bytes e 201 opcodes e apoia-se num orçamento de assinaturas ligado ao tamanho do witness.

Além de assinaturas únicas

As mesmas ferramentas expressam multisig (OP_CHECKMULTISIG, ou OP_CHECKSIGADD em Tapscript), bloqueios por hash (OP_SHA256 <hash> OP_EQUAL) e timelocks (OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY). Combiná-los dá cofres, planos de herança e canais Lightning. Escrever esses scripts à mão é propenso a erros, por isso existe Miniscript.