Me queda claro por qué es potencialmente inseguro usar solo un control en == en scriptPubKey. Por un lado, no verificar una firma en el script de canje significa que alguien podría hacerse pasar por el redentor. De la guía para desarrolladores de Bitcoin :
Esto permite que el script pubkey verifique que Bob posee la clave privada que creó la clave pública.
La firma secp256k1 de Bob no solo prueba que Bob controla su clave privada; también hace que las partes de su transacción que no son de firma sean a prueba de manipulaciones para que Bob pueda transmitirlas de manera segura a través de la red de igual a igual.
¿Por qué no sería seguro usar solo una verificación en V(sigA, pkA, m={txprev_txid, txprev_outid, txprev_scriptPK, tx_scriptPubKey, tx_amount}_skA) == 1? Parece que esto es lo que estamos haciendo en multisig. Es decir, tenga un ScriptSig que consista solo en (una) firma (s) en lugar de firma y pk como en P2PKH.
¿Por qué no verificamos las firmas en lugar de verificar tanto pkhash como una firma?
Vamos a empezar desde el principio.
p2pk
Si observa los bloques iniciales en la cadena, notará que la salida de la transacción de la base de monedas va a un script de bloqueo de clave pública (también conocido como salida o gravamen)
Un script de bloqueo p2pk es simplemente PUSH <pubkey> OP_CHECKSIG
. Para gastar esta salida, uno simplemente necesita proporcionar una firma válida. El scriptsig contendría PUSH sig
, que cuando se combina con el script de bloqueo produce PUSH sig PUSH <pubkey> OP_CHECKSIG
. Si la firma proporcionada es válida para la clave pública dada, puede demostrar tanto la propiedad de las monedas como la intención de gastarlas en un solo movimiento.
p2pkh
p2pk fue reemplazado (quizás no sea el término correcto, ya que Bitcoin 0.1 contenía soporte tanto para p2pk como para p2pkh) por pay-to-pubkey-hash. Esto tiene un par de ventajas sobre el p2pk de vainilla. Por un lado, redujo el tamaño del script de bloqueo. Dado que el conjunto utxo debe contener el script de bloqueo para fines de validación, esto genera un ahorro de espacio directo. Por otro lado, el hash de la clave pública agrega una capa de protección contra cualquier ataque futuro de recuperación de clave ecdsa que pueda desarrollarse, ya que también necesitaría romper la operación HASH160 para recuperar la clave pública primero.
El uso de p2pkh conlleva cierta complejidad adicional. El script de bloqueo ahora toma la forma de OP_DUP OP_HASH160 PUSH <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
. Dado que ya no tenemos la clave pública real en el script, un script de desbloqueo debe probar dos cosas:
Para 1, debemos demostrar que el hash de clave pública en el script corresponde al hash de clave pública de la clave utilizada para realizar la firma. Para 2, debemos verificar que la firma sea válida contra esa clave pública.
Para lograr esto, el script de desbloqueo toma la forma PUSH sig PUSH pubkey
. Cuando se combina con el script de bloqueo, esto producePUSH sig PUSH pubkey OP_DUP OP_HASH160 PUSH <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
Ahora, durante la evaluación, la clave pública se duplica. El duplicado se codifica y se compara con el hash almacenado en el script de bloqueo. Si el hash es válido, la firma se valida con la clave pública proporcionada. Este flujo garantiza que se utilice la misma clave pública para la verificación de firma y la comparación con el hash en el script de bloqueo, cumpliendo así ambos requisitos.
p2sh
pay-to-script-hash fue desarrollado para proporcionar una forma estandarizada de usar scripts de bitcoin más avanzados. Para este ejemplo, centrémonos en multisig p2sh. Un típico script de bloqueo de salida de 1 de 2 multisig p2sh será similar a OP_HASH160 PUSH <hash> OP_EQUAL
. Esto no contiene ninguna clave pública, ni siquiera un código de operación de verificación de firma, entonces, ¿qué está pasando aquí?
El secreto está en el script de canje. Cada dirección p2sh está respaldada por un script de canje, y el hash
valor en el script de bloqueo es un hash de este script de canje.
Al gastar desde una dirección p2sh, debe proporcionar una secuencia de comandos de desbloqueo que se valide con la secuencia de comandos de canje y la secuencia de comandos de canje en sí. Para nuestra dirección multisig 1of2, un script de canje parece OP_1 PUSH pubkey1 PUSH pubkey2 OP_2 OP_CHECKMULTISIG
. Esta secuencia de comandos completa está codificada para la secuencia de comandos de bloqueo. Tenga en cuenta que dado que las claves públicas contenidas en este script ya están codificadas como parte de todo el script de canje, no es necesario codificarlas por separado, como lo hacemos con p2pkh.
Al gastar la salida, proporcionaríamos: OP_0 PUSH sig PUSH redeemscript
. Esto da como resultado un script final de OP_0 PUSH sig PUSH redeemscript OP_HASH160 PUSH <hash> OP_EQUAL
. Durante la evaluación:
PUSH redeemscript
trata el script de canje como datos normales, los códigos de operación dentro del script de canje no se interpretan como códigos de operación en este paso.Seguir este orden de operaciones brinda la misma garantía que la salida p2pkh: que la transacción tiene la intención de gastar las monedas y que las claves involucradas son las mismas claves que se comprometieron durante el bloqueo de las monedas.
En una entrada que gasta una salida P2PKH, si solo verificara que la firma es una firma válida con la clave pública en la entrada, entonces un atacante podría usar su propia clave pública y producir una firma válida y, por lo tanto, una transacción válida bajo este modelo. La clave pública no se recupera del script de salida ni la proporciona la salida; más bien se proporciona en la entrada. Por lo tanto, debe asegurarse de que la clave pública proporcionada sea de hecho la clave pública correcta, por lo tanto, verifique que su hash coincida con el hash proporcionado en la salida.
En multisig, las claves públicas se proporcionan en la entrada, además de las firmas. Están en el script redimido. Para evitar los mismos problemas (que el atacante proporcione sus propias claves públicas), el script de redimir tiene un hash y el hash está en el script de salida. Hay una comparación allí para garantizar que el script de redimir sea el script correcto.
Hay un tipo de salida en el que solo proporciona una firma. Este tipo de salida es una secuencia de comandos en la que la clave pública se encuentra en la salida, por lo que no es necesario proporcionar la clave pública en la entrada. Solo se necesita la firma. Esto se conoce como salida Pay to Pubkey (P2PK). Estos no se usan mucho porque las claves públicas son grandes y esto hace que sea más difícil darlas.
acnalb
andres chow