-
Notifications
You must be signed in to change notification settings - Fork 19
Transaction
shigeyuki azuchi edited this page Aug 22, 2023
·
4 revisions
Transaction can be processed with Bitcoin::Tx
class.
Bitcoin::Tx#parse_from_payload
method parses the transaction payload (binary) and creates a Transaction object.
tx = Bitcoin::Tx.parse_from_payload('010000000553719240c8624f9f0d80a8cc9f067176178336ca0f8a31539c5c749d4e714e4d03000000fdfe00004830450221008027faa1a0ab9d5476c39de3b9cd92120dd5100d52891f4466160fd51603167a0220183b58a4a9e109c129b489ee064ea5d5d93a953abda4faf4198a3fd776efd04101483045022100fe95ed912ea6e4b85ab42929dbf7f50493b17a9c9933c728871b280fcda070db0220176f893a2444cfa7f797f897b2b5001fef0502137130fa3dd5b956875078fc9b014c69522102aa05d9b4bb2e93d8b27f5b7be7b2c43c856795f14a5a277fac5e626e4b9fefbe2102d23c610c9cda2e33743036c93e837c830ea0662e71989001cc5066e88cbbe6f72103c110c7485bf0c3b1d1c0d5c74600c2bf6fe4cb9dad32a8e333ac4aaf7a24206253aeffffffffb7c9ddaceccf185ad464cea0fc72dc7e47e29d3ac1c0c2fa69145854477b0d0100000000fc0047304402202de4e27bab1bf3a91ec9eb57bc49301968671213fd37d40c2f809a58e9959c720220711eb9dfd74578f6562e0fdbe9a3bc9602e99e885b2ae88328398991ea29828a0147304402201a62a60dfbc51c1366a6c12ffd3307615edee6dd8fcf7148a6d165c427f122bb022048420c6cffb89968f2303f6771494a814962e3e1164755410e397e564cb91429014c69522102000455b4426f83dfd1045a3818b5fec22d833540661abbea6eeb2770232d52a921030cf72e76c921d0d2019a42924ac08c431edd889389dde79e584419cefdd233432103f5fc9ea29534c4f30f00a923ccdfc6a209652afdaa264fc69416606a6bc7c62453aeffffffff7b929c18638c5bf0a6184eb66c011cdb9ff1ade959c8d710c2c80efa3b3fd76903000000fc004730440220091b720e33174c64a68f7ca42066c9bef6471553c861e223cde0890a5e6136b1022003dac012592f922163c1c65692017f4f2ad21db91bf3288d54416d884731fb1b01473044022045aeeb6eb527d12f41b7ffc405b29f0ac6f85609c4cec455ddd31275036cd54d02207402a1418729ee298f95a991f5b087e25a852473f14fce49e6178dd4c3c7e922014c6952210317232383a9878dd8393a042f57c7657c59d9cd31c4aae1a41e348b2e3ad7ac0521035577d9bed96f8b4ac41805d757d546e1a16c1a68d0039e9a949354b6c72642032103718e9bc49e62c4589283a8028aa0d8f533422e0d602c972ed493ea0fccd213b553aeffffffff3d58febe2909a87018855ac7e053857e1b29b376655aaef3ab6b5c4a3b40620303000000fdfd000047304402204f6523b8fe24b1b942b23c5f4bb7ecd6334c45d0ddde4c29ec4d6aa55e84bfe102205f9551bca57ea563f501657e544e7fcdd6cc482c6a04d1eac699a682cd9c32c801483045022100e67bfdd7a25444fd795331a4c257fdafe54d3429d1ea2e87b127be1bbbd18887022065b0600683bffa163749024a32768cd7c23c59e040374b0ede11bd99e27369aa014c6952210240a9bc56fa8cf2028cb9c8eaccbcf8c4bae7d29f9a0ee4dec4d6428a59a5995921029ce5054c90020489a62d195bcd8ddddab563ce6e90c2e2a9efb882d8a8fa7beb2103742da09083a1dc781be2e0c04bfc3c1e55f0e98c614ebe47c689f9c95e25df4253aeffffffff78e21420a23df3e0d379f40ba8364ad232fb24255cb84a2b6109229f73af99f601000000fdfd000047304402207965668e0c7b5fed335c8a5145d0ce8c0816e9ef9b232117abc0678577d7cb0f02207211e2ec7a707223ce3cd964624583c95fd3027c8f69bf4922cac5a00994dd120148304502210082dbefc5d6eb06e78d490084f59badecd93315dafa13efb3a86b685b80677cf30220188bbd937c8b5d0458b3b02de825cd2bb34342b4fff0921cfd2e4189f9019d86014c6952210244411019872828c7481f60ab4f3c9cb61f0716131910951b76baa878edbaccf62102e4a0cffb8d87abf49dd3bbe8104474e96df1466c1c7e30180a2fe104100851cc210311aa090667831101d196fd0fc2db919613e88326c9a513a97e1108a29b16230553aeffffffff02533f00000000000017a914d0846f31ec305fbc9f24d1144555560bc2584abb872fff0c000000000017a914e9b2d888bc7cefd62df1fd3fbae4e3f73fb0009e8700000000'.htb)
On the other hand, you can generate a transaction payload (binary) from a transaction object with the Bitcoin::Tx#to_payload
method.
payload = tx.to_payload
You can also create transactions from scratch with Bitcoin::Tx
.
tx = Bitcoin::Tx.new
# add input
tx.in << Bitcoin::TxIn.new(out_point: Bitcoin::OutPoint.from_txid('75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858', 0))
# add output
tx.out << Bitcoin::TxOut.new(value: 15000, script_pubkey: Bitcoin::Script.parse_from_addr('191arn68nSLRiNJXD8srnmw4bRykBkVv6o'))
# if you use CLTV, set version 2
tx.version = 2
# sign transaction
input_index = 0
script_pubkey = Bitcoin::Script.parse_from_payload('00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb) # script pubkey of input 0
## generate sighash with SIGHASH_ALL
sig_hash = tx.sighash_for_input(input_index, script_pubkey)
## if use other sighash, you can specify hash_type option
sig_hash = tx.sighash_for_input(input_index, script_pubkey, hash_type: Bitcoin::SIGHASH_TYPE[:single])
## if sign segwit input, you must specifiy sig_version and amount(value of satoshi)
sig_hash = tx.sighash_for_input(input_index, script_pubkey, sig_version: :witness_v0, amount: 16000)
## generate signature
key = Bitcoin::Key.from_base58('xxxxxx')
signature = key.sign(sig_hash) + [Bitcoin::SIGHASH_TYPE[:all]].pack('C')
## set signature to input for legacy tx
tx.in[0].script_sig << signature
tx.in[0].script_sig << key.pubkey.htb
## set signature to input for segwit tx
tx.in[0].script_witness.stack << signature
tx.in[0].script_witness.stack << key.pubkey.htb
## verify signature and script
tx.verify_input_sig(0, script_pubkey)
=> true/false
## verify signature and script for segwit tx
tx.verify_input_sig(0, script_pubkey, amount: 16000)
=> true/false
# show txid
tx.txid
tx.wtxid
# show hash(txid and tx_hash differ only in endianness)
tx.tx_hash
tx.witness_hash
In addition, please refer to the test case of BIP-143 for the signing method of segwit tx nested in P2SH, P2WSH and P2SH.