P2MS

Pay To Multisig — travando bitcoins a múltiplas chaves públicas

BIP 11: M-of-N Standard Transactions

Diagrama mostrando a estrutura de um P2MS.

O P2MS é um padrão de script que permite travar bitcoins a múltiplas chaves públicas e exigir assinaturas de algumas (ou todas) essas chaves públicas para destravá-las.

A notação geral para scripts multisig é "m-de-n":

Por exemplo, um script multisig 2-de-3 exige 2 assinaturas de 3 chaves públicas para ser destravado.

Diagrama mostrando um script P2MS sendo travado a 3 chaves públicas diferentes e exigindo 2 assinaturas de qualquer uma dessas 3 chaves públicas para destravá-lo.

Neste exemplo, o ScriptPubKey do P2MS inclui as chaves públicas de 3 pessoas diferentes, mas apenas 2 dessas pessoas precisariam fornecer a sua assinatura para destravá-lo.

Embora o P2MS seja um script padrão, é mais comum embrulhar esse tipo de script em um P2SH ou P2WSH.

Script legado. Este é um padrão de script legado e é raramente usado diretamente nas saídas.

Uso

Como o P2MS funciona?

Scripts multisig crus são bem diretos de criar.

ScriptPubKey (trava)

Para criar um script P2MS cru, você inclui os seguintes OP_CODES e dados no ScriptPubKey:

  1. Um opcode de número M para indicar quantas assinaturas são necessárias.
  2. Depois, empurre cada uma das chaves públicas.
  3. Um opcode de número N para indicar quantas chaves públicas há.
  4. O opcode OP_CHECKMULTISIG no fim.

Então, no exemplo a seguir, temos um script de travamento multisig 2-de-3 (M-de-N), em que OP_2 assinaturas serão necessárias para destravar as OP_3 chaves públicas:

ASM

OP_2
OP_PUSHBYTES_65
04d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a2
OP_PUSHBYTES_65
04ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb1
OP_PUSHBYTES_65
04b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e7
OP_3
OP_CHECKMULTISIG

Hex

524104d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a24104ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb14104b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e753ae

Transação: 581d30e2a73a2db683ac2f15d53590bd0cd72de52555c2722d9d6a78e9fea510 (Saída 0)

Um P2MS pode conter tanto chaves públicas comprimidas (33 bytes) quanto chaves públicas não comprimidas (65 bytes).

O P2MS é um script de travamento padrão para até 3 chaves públicas. É possível criar um script multisig com mais chaves públicas, mas ele será considerado não padrão e não será retransmitido pelos nós. Porém, você pode usar até 15 chaves públicas se embrulhar o P2MS dentro de um P2SH.

ScriptSig (destrava)

Para destravar um script P2MS, você só precisa fornecer o número exigido de assinaturas no ScriptSig.

Então, para este exemplo, precisamos fornecer OP_2 assinaturas (como solicitado no ScriptPubKey acima):

ASM

OP_0
OP_PUSHBYTES_72
3045022100af204ef91b8dba5884df50f87219ccef22014c21dd05aa44470d4ed800b7f6e40220428fe058684db1bb2bfb6061bff67048592c574effc217f0d150daedcf36787601
OP_PUSHBYTES_72
3045022100e8547aa2c2a2761a5a28806d3ae0d1bbf0aeff782f9081dfea67b86cacb321340220771a166929469c34959daf726a2ac0c253f9aff391e58a3c7cb46d8b7e0fdc4801

Hex

00483045022100af204ef91b8dba5884df50f87219ccef22014c21dd05aa44470d4ed800b7f6e40220428fe058684db1bb2bfb6061bff67048592c574effc217f0d150daedcf36787601483045022100e8547aa2c2a2761a5a28806d3ae0d1bbf0aeff782f9081dfea67b86cacb321340220771a166929469c34959daf726a2ac0c253f9aff391e58a3c7cb46d8b7e0fdc4801

Transação: 949591ad468cef5c41656c0a502d9500671ee421fadb590fbc6373000039b693 (Entrada 0)

Bug do OP_CHECKMULTISIG. Este opcode tem um bug em que ele retira um elemento a mais da pilha do que precisa (um erro de off-by-one). É por isso que adicionamos um "valor fictício" (dummy) no início do ScriptSig, para compensar isso e impedir que o script falhe.

Desde o BIP 147, esse valor fictício precisa ser OP_0 se usar o P2MS diretamente, ou o byte vazio 00 se usar o P2MS embrulhado em um P2WSH.

Você precisa fornecer as assinaturas correspondentes na mesma ordem que a ordem das chaves públicas no ScriptPubKey. Você verá o porquê nos passos de execução abaixo.

Execução

Diagrama mostrando a montagem de um P2MS antes da execução do script.

Quando este script é executado, todas as assinaturas e chaves públicas são, primeiro, empurradas para a pilha.

Então chegamos ao OP_CHECKMULTISIG, que:

  1. Retira o N e, então, retira esse número de chaves públicas da pilha.
  2. Retira o M e, então, retira esse número de assinaturas da pilha.

Depois de retirar todas as chaves públicas e assinaturas da pilha, o OP_CHECKMULTISIG compara cada assinatura com cada chave pública:

Depois de todas as assinaturas serem verificadas, se o contador de assinaturas válidas for igual a M, então o OP_CHECKMULTISIG empurra um OP_1 para a pilha e o script é válido.

Animação mostrando a execução de um script P2MS completo.

Exemplos

Onde você encontra scripts P2MS?

Não é comum encontrar scripts P2MS na blockchain, pois a maioria das transações multisig é embrulhada em P2SH ou P2WSH.

Mesmo assim, aqui estão algumas transações de exemplo que têm scripts de travamento P2MS crus nas suas saídas:

ScriptPubKey: 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1 (saída 0)
ScriptSig: 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 (entrada 0)
Primeira transação P2MS, feita em 30 de janeiro de 2012. Usa multisig 1-de-2.
ScriptPubKey: 2daea775df11a98646c475c04247b998bbed053dc0c72db162dd6b0a99a59c26 (saída 0)
ScriptSig: e8ac451e7f47d566d4dd822a67fea2181ecfa7c7ba96d9faa63e2f6b26e55fd3 (entrada 0)
Segunda transação P2MS, feita em 03 de fevereiro de 2012. Usa multisig 3-de-3.
ScriptPubKey: 14237b92d26850730ffab1bfb138121e487ddde444734ef195eb7928102bc939 (saída 0)
ScriptSig: 10c61e258e0a2b19b245a96a2d0a1538fe81cd4ecd547e0a3df7ed6fd3761ada (entrada 0)
Terceira transação P2MS, feita em 03 de fevereiro de 2012. Usa multisig 2-de-3.
ScriptPubKey: ac1d9ed701af32ea52fabd0834acfb1ba4e3584cf0553551f1b61b3d7fb05ee7 (saída 0)
ScriptSig: a38824b0a5e5aa373ab79e05b3e17d4e0cfa67908a509cf7b64314282d9aece8 (entrada 5)
Um exemplo aleatório de multisig 1-de-1.
ScriptPubKey: 78b28d3c2324da8c2f01840021addbcabb68f7ce1d4da870cabe5e9df6afe63d (saída 0)
ScriptSig: 99cb2139052dc88508f2fe35235c1c5685229a45bef3db70413c5ac43c41ca0a (entrada 0)
Um exemplo aleatório de multisig 1-de-2. A segunda "chave pública" no ScriptPubKey não é, na verdade, uma chave pública válida (elas sempre começam com 02, 03 ou 04), mas isso não importou, porque apenas uma assinatura era necessária para destravar esta saída, e a primeira chave pública era válida.
ScriptPubKey: 581d30e2a73a2db683ac2f15d53590bd0cd72de52555c2722d9d6a78e9fea510 (saída 0)
ScriptSig: 949591ad468cef5c41656c0a502d9500671ee421fadb590fbc6373000039b693 (entrada 0)
Um exemplo aleatório de multisig 2-de-3.
ScriptPubKey: c4aaf7fbec7a9a079e670e50f6a672315451c7618814494ab1f89cf3fd97b3bb (saída 0)
ScriptSig: da738e29f64e90ae46dcc3e6b4154041d6324abbe7919e722d486a4a3148b7dc (entrada 0)
Um grande exemplo de multisig 20-de-20. Tecnicamente, isto não é um P2MS, pois um P2MS é um script padrão e é limitado a um máximo de 3 chaves públicas, então, se você criasse um P2MS desse tamanho, ele não seria retransmitido pelos nós. Mesmo assim, o opcode OP_CHECKMULTISIG é válido para até 20 chaves públicas (esse limite é definido em script.h).

Endereço

O P2MS tem um endereço?

Um script de travamento P2MS cru não tem um endereço.

Claro, o ScriptPubKey de um P2MS contém chaves públicas, então você pode converter cada uma delas em um endereço, se quiser, o que corresponderia ao que o script de travamento P2PKH de cada uma dessas chaves públicas seria. Mas o script de travamento P2MS padrão em si não recebeu o seu próprio formato de endereço.

Se você quer usar um endereço para travar moedas em um P2MS, deve embrulhar o script P2MS dentro de um P2SH ou P2WSH.

P2MS em P2SH/P2WSH

Diagrama mostrando um P2MS embrulhado dentro de um P2SH.

O método mais comum de usar scripts de travamento P2MS (multisig) é embrulhá-los em um P2SH ou P2WSH. Isso te dá algumas vantagens em relação a usar scripts P2MS crus diretamente:

  1. O P2MS não tem formato de endereço. Então, se você quer que alguém coloque uma trava P2MS nos seus bitcoins, você mesmo precisará construir e enviar a eles o script de travamento cru. Pior ainda, eles podem não conseguir criar essa transação para você, pois a maioria das carteiras só permite usar endereços (e não scripts crus) ao fazer uma transação.
  2. O P2MS é limitado a 3 chaves públicas. O script de travamento de um P2MS pode ficar bem grande com todas as chaves públicas, então é limitado a 3 (para impedir que dados demais sejam armazenados no conjunto de UTXOs). Porém, com o P2SH você pode usar travas multisig com até 15 chaves públicas.

Então você ainda pode usar P2MS se quiser, mas é mais conveniente usar P2SH para alcançar a mesma coisa.

Por que temos tanto P2MS quanto P2SH?

Porque o P2MS se tornou um script padrão antes de o P2SH estar disponível.

  • P2MS – Tornou-se um script padrão em janeiro de 2012 (BIP 11)
  • P2SH – Tornou-se um script padrão em abril de 2012 (BIP 16)

Ele poderia ser removido como script padrão, mas…

Não dá para simplesmente introduzir uma política que quebra funcionalidades existentes.
Pieter Wuille (conversa privada no IRC)

Então o P2MS permanece como uma relíquia da época anterior à existência do P2SH.

Recursos