Pular para o conteúdo
buybitcoinsmart

Glossário / Referência do desenvolvedor

OP_VERIFY

O que é OP_VERIFY?
OP_VERIFY desempilha o item do topo da pilha e aborta todo o script, a menos que esse item seja verdadeiro, o que transforma qualquer teste no Bitcoin Script em um requisito obrigatório.

O byte 0x69 é a asserção de uso geral da linguagem. O Script pode ramificar com OP_IF, mas não tem como gerar um erro nem um valor de retorno além do que sobrevive na pilha, então um contrato exige uma condição calculando a resposta e entregando-a a esta instrução. Quase todo pagamento já feito passou por uma, geralmente escondida dentro de um opcode combinado.

Como funciona

OP_VERIFY remove um item da pilha e faz uma única pergunta: isto é verdadeiro?

Aqui, verdadeiro é uma noção em nível de byte, não numérica. Um item vazio é falso. Uma sequência de bytes zero também é, e o zero negativo também, uma sequência de zeros terminando em 0x80. Todo o resto conta como verdadeiro, incluindo um hash de 20 bytes ou uma chave pública de 33 bytes. Se o item for falso, o script termina na hora e a entrada que o contém é inválida, o que invalida a transação em torno dela. Se o item for verdadeiro, nada volta para a pilha e a avaliação passa para o próximo opcode.

Esse comportamento é o que permite a um script verificar várias coisas em sequência. Um script só tem sucesso quando exatamente um valor verdadeiro permanece no final, então, sem asserções, cada condição teria que ser condensada em um único booleano final. Com elas, um contrato pode exigir um bloqueio temporal, depois exigir uma pré-imagem de hash e depois exigir uma assinatura, falhando na primeira condição não atendida.

Quatro opcodes têm a asserção incorporada e existem apenas para economizar um byte: OP_EQUALVERIFY, OP_CHECKSIGVERIFY, OP_CHECKMULTISIGVERIFY e OP_NUMEQUALVERIFY. Como esses cobrem os casos comuns, um 0x69 isolado é raro na mainnet.

Dois opcodes trazem VERIFY no nome e não se comportam assim de forma alguma. OP_CHECKLOCKTIMEVERIFY, do BIP65, e OP_CHECKSEQUENCEVERIFY, do BIP112, foram adicionados por soft fork sobre opcodes que antes não tinham significado, então, para manter os nós antigos satisfeitos, tinham que deixar a pilha exatamente como a encontraram. Ambos inspecionam o item do topo e falham quando a condição não é atendida, mas nenhum o consome, e é por isso que os scripts reais sempre os seguem com OP_DROP.

Onde você o encontra

As asserções se concentram onde um script tem mais de uma coisa a provar.

Um cofre simples com bloqueio temporal se lê como uma chave pública, OP_CHECKSIGVERIFY, um atraso como 144 blocos (aproximadamente um dia) e depois OP_CHECKSEQUENCEVERIFY. Os scripts de compromisso e de HTLC da Lightning são construídos do mesmo modo, encadeando uma verificação de pré-imagem e uma verificação de assinatura para que nenhuma das duas baste sozinha para mover dinheiro. Os gastos por caminho de script do Taproot se apoiam muito nesse padrão, já que o tapscript substituiu OP_CHECKMULTISIG por OP_CHECKSIGADD e usa variantes VERIFY para manter compactas as políticas de várias chaves.

O Miniscript, o compilador de políticas que várias carteiras de desktop já usam para descrever condições de gasto de forma legível, emite esses opcodes para você. É a forma mais fácil de ver asserções sendo geradas sem escrever à mão um script bruto.

OP_VERIFY vs OP_RETURN

OP_VERIFY e OP_RETURN ambos terminam um script de forma ruim, mas só um deles faz antes uma pergunta. OP_VERIFY falha quando o valor que recebe é falso, então um gasto correto passa direto sem deixar rastro. OP_RETURN, o byte 0x6a, falha sempre que é executado, sem nenhuma condição associada, e é justamente por isso que ele é usado para construir saídas que nunca podem ser gastas e para anexar dados a uma transação. Um script que morre no primeiro recebeu algo errado. Um script que morre no segundo nunca foi feito para ser gastável desde o início.

Não confundir com

Perguntas frequentes

O que conta como verdadeiro dentro do Bitcoin Script?

Tudo o que não seja um item vazio, não seja uma sequência de bytes zero e não seja o zero negativo. Um hash, uma chave pública ou o único byte 0x01 contam como verdadeiros, e o interpretador nunca olha para o que os bytes deveriam significar.

Por que OP_CHECKLOCKTIMEVERIFY e OP_CHECKSEQUENCEVERIFY não mexem na pilha?

Porque foram adicionados por soft fork sobre opcodes que os nós antigos tratam como se não fizessem nada. Consumir um item faria esses nós discordarem sobre a pilha, então os novos opcodes apenas a inspecionam e os scripts adicionam OP_DROP depois.

Termos relacionados

Mais em Referência do desenvolvedor

Ler esta página em inglês