Comprobando una firma de Transacción Validando que un script de desbloqueo satisface las condiciones de un script de bloqueo.
Autor EntrePlanctonyBallenas. Twitter para correcciones, comentarios o sugerencias: @entreplanctony1
El presente tutorial fue elaborado para el Seminario socrático de Mastering Bitcoin a través de @libreriadesatoshi .
Elabora una transacción para gastar El presente tutorial asume que has creado una transacción usando una billetera sin “descriptors ” con una dirección de tipo “legacy ” en tu billetera y que has fondeado dicha billetera para tener bitcoin testnet en esa dirección.
Puedes ver más información sobre como lograr esto en los siguientes enlaces:
Configurar una wallet en Bitcoin Core ¿Cómo crear una transacción usando bitcoin-cli para hacer pruebas?
Se tiene la siguiente transacción sin firmar:
$ bitcoin-cli decoderawtransaction 020000000179d5220fa628d9fd463fa6fb5cf45df7b49b81467a6eb7fd7d948e3a6ec0f22b0000000000ffffffff0200e1f505000000001976a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac1fb23f71000000001976a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac00000000 { "txid": "aefd489df6b3f1b824922bf23733b95bd19e5c99aad2ceef503a95b187f8df9c", "hash": "aefd489df6b3f1b824922bf23733b95bd19e5c99aad2ceef503a95b187f8df9c", "version": 2, "size": 119, "vsize": 119, "weight": 476, "locktime": 0, "vin": [ { "txid": "2bf2c06e3a8e947dfdb76e7a46819bb4f75df45cfba63f46fdd928a60f22d579", "vout": 0, "scriptSig": { "asm": "" , "hex": "" }, "sequence": 4294967295 } ], "vout": [ { "value": 1.00000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 b47a6f225525f7f4674952ce91ddbc8ef755aee1 OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac", "address": "mwyEbTMHvYKaNaJnAVNzhRRCFUyb1B7mQC", "type": "pubkeyhash" } }, { "value": 18.99999775, "n": 1, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 a16ef9a4f940070c8360f7a9bb8853756d5ca2c9 OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac", "address": "mvEY2dS4Ah1oG58eF36pvk6bfqTAqZs8Rs" , "type": "pubkeyhash" } } ] }
Si filtramos la salida de decoderawtransaction para visualizar únicamente los campos del arreglo de vin de nuestra transacción (agregamos al comando | jq .<campo> ) , podemos ver que el campo llamado scriptsig se encuentra vacío. Esto implica que nuestra transacción no esta firmada todavía.
$ bitcoin-cli decoderawtransaction 020000000179d5220fa628d9fd463fa6fb5cf45df7b49b81467a6eb7fd7d948e3a6ec0f22b0000000000ffffffff0200e1f505000000001976a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac1fb23f71000000001976a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac00000000 |jq .vin [ { "txid": "2bf2c06e3a8e947dfdb76e7a46819bb4f75df45cfba63f46fdd928a60f22d579", "vout": 0, "scriptSig": { "asm": "", "hex": "" }, "sequence": 4294967295 } ]
💡 Filtrando las salidas con el comando jq El comando
jq se puede utilzar para filtrar datos de un
arreglo json para mirar unicamente los datos que nos interesen. Puedes mirar como instalar
jq en este link:
Download JQ. Ejemplos útiles para utilizarlo:
jq for Creating and Updating JSON Encuentra los datos de salida de la transacción padre Ahora miramos los datos de la salida de transacción que vamos a gastar.
$ bitcoin-cli getrawtransaction 2bf2c06e3a8e947dfdb76e7a46819bb4f75df45cfba63f46fdd928a60f22d579 02000000000101f7414d339ad4f721b680f4c085bb6b169b2a746557f924a60c43ff912032fcbd0100000000feffffff0200943577000000001976a91400573e46e99808aed09a23a5adab6d009323bea388acdebe9a3b000000001600144e46d9555cc0a946d2f564808a269df43e6e38040247304402201e218cb74066756b839f468a107bb3b670c970483d415869381350a1760ee62702202bc7e6cca2ed2d95f27dada4de585dd61d3752532c1c30e694db9f76c4ac996e012103aeb1de40909bc2e3e3a573121b962bb5718484cb952f00ba537dd2600f6624c165000000
Mirando a detalle los datos de la salida a gastar únicamente, vemos que el campo
scriptPubKey tiene varios campos, entre ellos un campo llamado “
asm ”. El campo “
asm ” son los datos “decodificados” del
script de bloqueo que indica que esta salida esta bloqueada usando un script de tipo “
Pay-to-Public-Key-Hash (P2PKH) ” (
ver esta definición en el libro de MB ).
$ bitcoin-cli decoderawtransaction 02000000000101f7414d339ad4f721b680f4c085bb6b169b2a746557f924a60c43ff912032fcbd0100000000feffffff0200943577000000001976a91400573e46e99808aed09a23a5adab6d009323bea388acdebe9a3b000000001600144e46d9555cc0a946d2f564808a269df43e6e38040247304402201e218cb74066756b839f468a107bb3b670c970483d415869381350a1760ee62702202bc7e6cca2ed2d95f27dada4de585dd61d3752532c1c30e694db9f76c4ac996e012103aeb1de40909bc2e3e3a573121b962bb5718484cb952f00ba537dd2600f6624c165000000 |jq .vout[0] { "value": 20.00000000, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 00573e46e99808aed09a23a5adab6d009323bea3 OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a91400573e46e99808aed09a23a5adab6d009323bea388ac", "address": "mfYkopfgCymnGRiDK64nS9CjfspoTUKoxk" , "type": "pubkeyhash" } }
El siguiente diagrama indica el orden en el que se ejecutan estos scripts, se van checando de izquierda a derecha, comenzando por los campos <sig> y <PubK> .
Donde <sig> es la firma criptográfica con la llave privada de todo el contenido de la transacción no firmada, y <PubK> es la llave Pública de la dirección que se está usando.
Diagrama 1. Ejecución de scripts de transacción Si queremos mirar la llave publica de una direccion que poseemos
$ bitcoin-cli -rpcwallet=Pruebas -named getaddressinfo address=mfYkopfgCymnGRiDK64nS9CjfspoTUKoxk |jq -r .pubkey 03865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de
Firma la transacción y mira los datos que se llenan Ahora miremos que datos se llenan en la transacción cuando se firma con la wallet:
$ bitcoin-cli -rpcwallet=Pruebas signrawtransactionwithwallet 020000000179d5220fa628d9fd463fa6fb5cf45df7b49b81467a6eb7fd7d948e3a6ec0f22b0000000000ffffffff0200e1f505000000001976a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac1fb23f71000000001976a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac00000000 |jq -r .hex 020000000179d5220fa628d9fd463fa6fb5cf45df7b49b81467a6eb7fd7d948e3a6ec0f22b000000006a47304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d5012103865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45deffffffff0200e1f505000000001976a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac1fb23f71000000001976a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac00000000 $ bitcoin-cli decoderawtransaction 020000000179d5220fa628d9fd463fa6fb5cf45df7b49b81467a6eb7fd7d948e3a6ec0f22b000000006a47304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d5012103865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45deffffffff0200e1f505000000001976a914b47a6f225525f7f4674952ce91ddbc8ef755aee188ac1fb23f71000000001976a914a16ef9a4f940070c8360f7a9bb8853756d5ca2c988ac00000000 |jq .vin [ { "txid": "2bf2c06e3a8e947dfdb76e7a46819bb4f75df45cfba63f46fdd928a60f22d579", "vout": 0, "scriptSig": { "asm": "304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d5[ALL] 03865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de", "hex": "47304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d5012103865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de" }, "sequence": 4294967295 } ]
El campo asm contiene el script de desblqueo (decodificado) necesario para poder gastar esta salida.
Desbloqueo vs Bloqueo Finalmente para poder confirmar que el script de desblqueo satisface las condiciones establecidas por el script de bloqueo debemos ejecutar de izquierda a derecha comenzando por el script de desbloqueo, como lo muestra la siguiente imagen:
Diagrama 2. Estructura de los scripts de bloqueo y desbloqueo Decodificamos el script de desbloqueo de la transacción firmada, tomamos solo el campo asm .
$ bitcoin-cli decodescript 47304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d5012103865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de { "asm": " 304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d501 03865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de", "type": "nonstandard" , "p2sh": "2N85jCBcRsoG4qFN9o9zw9aVoXsxCNsRKxs" , "segwit": { "asm": "0 1948bb32108965460f6dd638b9ba7935f45a6ee0e02dcbe8d254703d727ccf18" , "hex": "00201948bb32108965460f6dd638b9ba7935f45a6ee0e02dcbe8d254703d727ccf18" , "address": "bcrt1qr9ytkvss39j5vrmd6cutnwnexh695mhquqkuh6xj23cr6unueuvqezxrsv" , "type": "witness_v0_scripthash" , "p2sh-segwit": "2N5PsDhW4nNPwf5gqREofWYnoRZQ4V9wgP6" } }
Agregando los datos que tenemos:
304402207363809dea44ee307f4ce74e6b51b451984625d9212bf8f30bb5862311bfcb8302201312bce412e43550cb4002eab96967abdfc527f161bb47181c86473b0df7e0d501 03865176c3174200de1b60f0dae80f3ed28c920fe78bff02eb0d028d65fcaa45de OP_DUP OP_HASH160 00573e46e99808aed09a23a5adab6d009323bea3 OP_EQUALVERIFY OP_CHECKSIG
Introduzcamos estos datos en la siguiente pagina para validar paso a paso lo que hace nuestro script:
Bitcoin IDE
¿Puedes decir cual es el resultado?