P2PKH
Pay To Public Key Hash — o script legado mais comum
O P2PKH (Pay To Public Key Hash) é um padrão de script legado usado para "enviar" bitcoins a alguém.
Foi o script mais comum para travar uma saída à chave pública de alguém.
O P2PKH também é funcionalmente similar ao P2PK, mas uma trava P2PKH contém um hash de chave pública em vez de uma chave pública bruta.
Script legado. Este é um padrão de script legado. Ainda é usado ocasionalmente, mas o P2WPKH é agora a escolha preferida (que funciona da mesma forma).
Uso
Como o P2PKH funciona?
ScriptPubKey (trava)
O padrão de script P2PKH contém um hash de chave pública cercado pelos seguintes opcodes no ScriptPubKey:
ASM
OP_DUP
OP_HASH160
OP_PUSHBYTES_20
55ae51684c43435da751ac8d2173b2652eb64105
OP_EQUALVERIFY
OP_CHECKSIG Hex
76a91455ae51684c43435da751ac8d2173b2652eb6410588ac Transação: 0b6461de422c46a221db99608fcbe0326e4f2325ebf2a47c9faf660ed61ee6a4 (Saída 1)
ScriptSig (destrava)
Para resolver este script, o dono da chave pública hasheada acima precisa fornecer a chave pública original, junto com uma assinatura válida no ScriptSig:
ASM
OP_PUSHBYTES_72
3045022100c233c3a8a510e03ad18b0a24694ef00c78101bfd5ac075b8c1037952ce26e91e02205aa5f8f88f29bb4ad5808ebc12abfd26bd791256f367b04c6d955f01f28a772401
OP_PUSHBYTES_33
03f0609c81a45f8cab67fc2d050c21b1acd3d37c7acfd54041be6601ab4cef4f31 Hex
483045022100c233c3a8a510e03ad18b0a24694ef00c78101bfd5ac075b8c1037952ce26e91e02205aa5f8f88f29bb4ad5808ebc12abfd26bd791256f367b04c6d955f01f28a7724012103f0609c81a45f8cab67fc2d050c21b1acd3d37c7acfd54041be6601ab4cef4f31 Transação: 40e331b67c0fe7750bb3b1943b378bf702dce86124dc12fa5980f975db7ec930 (Entrada 0)
A chave pública original fornecida no ScriptSig pode ser uma chave pública comprimida (33 bytes) ou uma chave pública não comprimida (65 bytes).
Você pode usar qualquer uma dentro de um P2PKH, desde que use o mesmo formato de chave pública usado para criar o hash da chave pública no ScriptPubKey. Por exemplo, você não pode colocar o hash de uma chave pública comprimida no ScriptPubKey e então destravá-lo usando a chave pública não comprimida no ScriptSig (porque ela não vai gerar o mesmo valor de hash).
É raro ver chaves públicas não comprimidas sendo usadas dentro de um P2PKH, mas é tecnicamente possível.
Execução
Quando este script roda:
- A chave pública original é duplicada (
OP_DUP) e então passa peloOP_HASH160. - Esse valor hasheado é comparado com o hash de chave pública no ScriptPubKey para garantir que sejam iguais (
OP_EQUALVERIFY). - Se corresponder, o script continua e o
OP_CHECKSIGverifica a assinatura contra a chave pública, colocando umOP_1na pilha se ela for válida (assim como em um script P2PK).
Exemplos
Como é um script P2PKH?
O P2PKH foi o script padrão usado pelas carteiras quando você queria "enviar" bitcoins a alguém até por volta de 2016, então você o encontra na maioria dos blocos até essa época (e até os dias de hoje).
Aqui estão algumas transações interessantes que usam P2PKH:
- ScriptPubKey: 6f7cf9580f1c2dfb3c4d5d043cdbb128c640e3f20161245aa7372e9666168516 (saída 0)
ScriptSig: 12e753ef5cc30925a6eee2c457aa7f53022443ca013ea81882a6b59b69e342a6 (entrada 1) - Esta foi a primeira transação P2PKH de todas.
- ScriptPubKey: a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d (saída 0)
ScriptSig: cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79 (entrada 0) - Esta foi a transação da pizza de 10.000 BTC.
- ScriptPubKey: a2bf21f6d8b7aa77c740d0374e4759791d97c0134bc918c93bae8e14879c8ecc (saída 0)
ScriptSig: faf2987fd2240d9c46575cc35c354eeca71b794c482f3cc49fba1a5f9a80808c (entrada 0) - Esta é apenas uma transação P2PKH aleatória feita em 2023. Incluí-a aqui só para mostrar que scripts de travamento P2PKH ainda estão em uso, mesmo que o P2WPKH (disponibilizado após a atualização Segregated Witness em 2016) seja agora a escolha mais popular para enviar bitcoins ao endereço de alguém.
Endereço
Como você cria um endereço para um script P2PKH?
O padrão de script de travamento P2PKH recebeu o seu próprio endereço.
O endereço de um script de travamento P2PKH é a codificação Base58Check do hash da chave pública com um prefixo de 1 byte de 00 (mainnet) ou 6f (testnet).
Endereço (Base58)
Um endereço P2PKH sempre começa com um 1 (mainnet) ou m/n (testnet).
Quando uma carteira encontra esse tipo de endereço, ela o decodifica de base58 para extrair o hash da chave pública e, então, usa isso para construir um script de travamento P2PKH a ser colocado na saída da transação.
História
Por que usamos P2PKH?
Por que temos o P2PKH além do P2PK? Ou, em outras palavras, se o P2PK faz um bom trabalho de travar bitcoins a uma chave pública, por que temos o script P2PKH, mais complexo?
Acredito que a razão seja mais ou menos assim…
O Satoshi queria uma forma mais fácil de as pessoas compartilharem suas chaves públicas umas com as outras. O Satoshi queria melhorar o uso direto das chaves públicas tornando-as:
- Mais seguras, adicionando um checksum (para detectar erros).
- Mais curtas, convertendo a chave pública para base58.
Porém, o resultado ainda era bem grande:
O Satoshi provavelmente não conhecia as chaves públicas comprimidas na época. Isso fazia com que o endereço não fosse tão curto quanto poderia ser usando chaves públicas diretamente.
Exemplo de Endereço (Chave Pública Não Comprimida)
chave pública (não comprimida) = 04283338ffd784c198147f99aed2cc16709c90b1522e3b3637b312a6f9130e0eda7081e373a96d36be319710cd5c134aaffba81ff08650d7de8af332fe4d8cde20
prefixo + chave pública + checksum = 0004283338ffd784c198147f99aed2cc16709c90b1522e3b3637b312a6f9130e0eda7081e373a96d36be319710cd5c134aaffba81ff08650d7de8af332fe4d8cde2067da00eb
endereço base58 = 13QECtNiFPXijbMZmcgaTom3pCXwHvDYTUWGtRxZN7fY24u4fG5iiqXaQz3TvuQydLrkz9L4YhcYn3khC44yQwaZme6uoXQ
Chave Pública
Checksum
Base58
Portanto, uma solução para obter um endereço ainda mais curto é fazer o hash da chave pública primeiro:
Exemplo de Endereço (HASH160 da Chave Pública Não Comprimida)
chave pública (não comprimida) = 04283338ffd784c198147f99aed2cc16709c90b1522e3b3637b312a6f9130e0eda7081e373a96d36be319710cd5c134aaffba81ff08650d7de8af332fe4d8cde20
hash160(chave pública) = bc73550c1612ee81155d29254217cbd60084a6d1
prefixo + hash160(chave pública) + checksum = 00bc73550c1612ee81155d29254217cbd60084a6d1691c58b9
endereço base58 = 1JBSCVF6VM6QjFZyTnbpLjoCJTQEqVbepG
Chave Pública
HASH160
Endereço (Base58)
Uma função de hash é útil para criar uma representação curta de algum dado.
Então, aí temos uma versão muito mais curta da nossa chave pública (um endereço) que podemos compartilhar facilmente com outras pessoas.
Agora, em termos da lógica do script de travamento, a única coisa que temos que fazer para isso funcionar é mudar o mecanismo de travamento para que travemos uma saída ao hash da chave pública em vez disso.
Portanto, quando formos destravá-lo, fornecemos a chave pública original, e o hash dela será verificado antes de prosseguir com a verificação da assinatura, como de costume:
É um pouco mais complexo do ponto de vista de programação, mas isso permite o uso de endereços mais curtos e convenientes para enviar e receber bitcoins.
Então, em resumo, acredito que o Satoshi, em última análise, tinha a usabilidade em mente para o Bitcoin, e é por isso que ele criou o P2PKH.
Ainda usaríamos P2PKH se o Satoshi conhecesse as chaves públicas comprimidas?
Talvez, talvez não. Boa pergunta.
Se você codificasse em base58 uma chave pública comprimida, obteria um endereço de 51 caracteres (ao contrário dos 34 caracteres que você obtém ao fazer o hash dela antes), então pode não ter havido tanto incentivo para fazer o hash antes de criar um endereço:
E 51 caracteres não é tão ruim para passar adiante.
Exemplo de Endereço (Chave Pública Comprimida)
chave pública (comprimida) = 02283338ffd784c198147f99aed2cc16709c90b1522e3b3637b312a6f9130e0eda
prefixo + chave pública + checksum = 0002283338ffd784c198147f99aed2cc16709c90b1522e3b3637b312a6f9130e0eda85f983ee
endereço base58 = 15CCDBsovXLij5wtGe5joZNymEZSnQhpfXjbxybMMybrMqnmBUy Mesmo assim, o P2PKH já havia se tornado o padrão para enviar e receber bitcoins a essa altura, e é por isso que ficamos com ele.
Ainda assim, teria sido mais simples usar P2PK com endereços feitos de chaves públicas comprimidas.