bitcoin-ruby 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/COPYING +1 -1
- data/Gemfile.lock +9 -10
- data/README.rdoc +1 -1
- data/Rakefile +4 -2
- data/lib/bitcoin.rb +4 -2
- data/lib/bitcoin/bloom_filter.rb +125 -0
- data/lib/bitcoin/builder.rb +34 -9
- data/lib/bitcoin/ext_key.rb +191 -0
- data/lib/bitcoin/ffi/openssl.rb +1 -1
- data/lib/bitcoin/key.rb +6 -4
- data/lib/bitcoin/protocol.rb +13 -11
- data/lib/bitcoin/protocol/block.rb +38 -2
- data/lib/bitcoin/protocol/parser.rb +8 -0
- data/lib/bitcoin/protocol/partial_merkle_tree.rb +61 -0
- data/lib/bitcoin/protocol/script_witness.rb +31 -0
- data/lib/bitcoin/protocol/tx.rb +170 -10
- data/lib/bitcoin/protocol/txin.rb +8 -0
- data/lib/bitcoin/protocol/version.rb +2 -1
- data/lib/bitcoin/script.rb +58 -8
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bloom_filter_spec.rb +23 -0
- data/spec/bitcoin/builder_spec.rb +12 -0
- data/spec/bitcoin/ext_key_spec.rb +180 -0
- data/spec/bitcoin/fixtures/filteredblock-0.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-testnet-1151351.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-p2wpkh.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-p2wpkh.json +67 -0
- data/spec/bitcoin/fixtures/tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json +139 -0
- data/spec/bitcoin/fixtures/tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json +34 -0
- data/spec/bitcoin/protocol/bip143_spec.rb +116 -0
- data/spec/bitcoin/protocol/block_spec.rb +27 -0
- data/spec/bitcoin/protocol/partial_merkle_tree_spec.rb +38 -0
- data/spec/bitcoin/protocol/tx_spec.rb +134 -1
- data/spec/bitcoin/script/script_spec.rb +53 -2
- metadata +27 -3
data/spec/bitcoin/fixtures/tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
{
|
2
|
+
"hash": "0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3",
|
3
|
+
"ver": 1,
|
4
|
+
"vin_sz": 17,
|
5
|
+
"vout_sz": 2,
|
6
|
+
"lock_time": 0,
|
7
|
+
"size": 2585,
|
8
|
+
"in": [
|
9
|
+
{
|
10
|
+
"prev_out": {
|
11
|
+
"hash": "643e5f4e66373a57251fb173151e838ccd27d279aca882997e005016bb53d5aa",
|
12
|
+
"n": 0
|
13
|
+
},
|
14
|
+
"scriptSig": "304402205438cedd30ee828b0938a863e08d810526123746c1f4abee5b7bc2312373450c02207f26914f4275f8f0040ab3375bacc8c5d610c095db8ed0785de5dc57456591a601 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"prev_out": {
|
18
|
+
"hash": "28e0fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2",
|
19
|
+
"n": 0
|
20
|
+
},
|
21
|
+
"scriptSig": "3045022100f81d98c1de9bb61063a5e6671d191b400fda3a07d886e663799760393405439d0220234303c9af4bad3d665f00277fe70cdd26cd56679f114a40d9107249d29c979401 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"prev_out": {
|
25
|
+
"hash": "f0a130a84912d03c1d284974f563c5949ac13f8342b8112edff52971599e6a45",
|
26
|
+
"n": 0
|
27
|
+
},
|
28
|
+
"scriptSig": "304402202310b00924794ef68a8f09564fd0bb128838c66bc45d1a3f95c5cab52680f166022039fc99138c29f6c434012b14aca651b1c02d97324d6bd9dd0ffced0782c7e3bd01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"prev_out": {
|
32
|
+
"hash": "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57",
|
33
|
+
"n": 0
|
34
|
+
},
|
35
|
+
"scriptSig": "3045022100d276251f1f4479d8521269ec8b1b45c6f0e779fcf1658ec627689fa8a55a9ca50220212a1e307e6182479818c543e1b47d62e4fc3ce6cc7fc78183c7071d245839df01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"prev_out": {
|
39
|
+
"hash": "381de9b9ae1a94d9c17f6a08ef9d341a5ce29e2e60c36a52d333ff6203e58d5d",
|
40
|
+
"n": 1
|
41
|
+
},
|
42
|
+
"scriptSig": "30450221008768eeb1240451c127b88d89047dd387d13357ce5496726fc7813edc6acd55ac022015187451c3fb66629af38fdb061dfb39899244b15c45e4a7ccc31064a059730d01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"prev_out": {
|
46
|
+
"hash": "f320832a9d2e2452af63154bc687493484a0e7745ebd3aaf9ca19eb80834ad60",
|
47
|
+
"n": 0
|
48
|
+
},
|
49
|
+
"scriptSig": "30450221009be4261ec050ebf33fa3d47248c7086e4c247cafbb100ea7cee4aa81cd1383f5022008a70d6402b153560096c849d7da6fe61c771a60e41ff457aac30673ceceafee01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"prev_out": {
|
53
|
+
"hash": "de0411a1e97484a2804ff1dbde260ac19de841bebad1880c782941aca883b4e9",
|
54
|
+
"n": 1
|
55
|
+
},
|
56
|
+
"scriptSig": "30450221009bc40eee321b39b5dc26883f79cd1f5a226fc6eed9e79e21d828f4c23190c57e022078182fd6086e265589105023d9efa4cba83f38c674a499481bd54eee196b033f01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"prev_out": {
|
60
|
+
"hash": "3b8b2f8efceb60ba78ca8bba206a137f14cb5ea4035e761ee204302d46b98de2",
|
61
|
+
"n": 0
|
62
|
+
},
|
63
|
+
"scriptSig": "304402200fb572b7c6916515452e370c2b6f97fcae54abe0793d804a5a53e419983fae1602205191984b6928bf4a1e25b00e5b5569a0ce1ecb82db2dea75fe4378673b53b9e801 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"prev_out": {
|
67
|
+
"hash": "54ffff182965ed0957dba1239c27164ace5a73c9b62a660c74b7b7f15ff61e7a",
|
68
|
+
"n": 1
|
69
|
+
},
|
70
|
+
"scriptSig": "304402206bc218a925f7280d615c8ea4f0131a9f26e7fc64cff6eeeb44edb88aba14f1910220779d5d67231bc2d2d93c3c5ab74dcd193dd3d04023e58709ad7ffbf95161be6201 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"prev_out": {
|
74
|
+
"hash": "bafd65e3c7f3f9fdfdc1ddb026131b278c3be1af90a4a6ffa78c4658f9ec0c85",
|
75
|
+
"n": 0
|
76
|
+
},
|
77
|
+
"scriptSig": "3044022047df98cc26bd2bfdc5b2b97c27aead78a214810ff023e721339292d5ce50823d02205fe99dc5f667908974dae40cc7a9475af7fa6671ba44f64a00fcd01fa12ab52301 02ca46fa75454650afba1784bc7b079d687e808634411e4beff1f70e44596308a1"
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"prev_out": {
|
81
|
+
"hash": "a5e899dddb28776ea9ddac0a502316d53a4a3fca607c72f66c470e0412e34086",
|
82
|
+
"n": 0
|
83
|
+
},
|
84
|
+
"scriptSig": "304402205566aa84d3d84226d5ab93e6f253b57b3ef37eb09bb73441dae35de86271352a02206ee0b7f800f73695a2073a2967c9ad99e19f6ddf18ce877adf822e408ba9291e01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"prev_out": {
|
88
|
+
"hash": "7a1de137cbafb5c70405455c49c5104ca3057a1f1243e6563bb9245c9c88c191",
|
89
|
+
"n": 0
|
90
|
+
},
|
91
|
+
"scriptSig": "3045022100df61d45bbaa4571cdd6c5c822cba458cdc55285cdf7ba9cd5bb9fc18096deb9102201caf8c771204df7fd7c920c4489da7bc3a60e1d23c1a97e237c63afe53250b4a01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"prev_out": {
|
95
|
+
"hash": "26aa6e6d8b9e49bb0630aac301db6757c02e3619feb4ee0eea81eb1672947024",
|
96
|
+
"n": 1
|
97
|
+
},
|
98
|
+
"scriptSig": "3044022031501a0b2846b8822a32b9947b058d89d32fc758e009fc2130c2e5effc925af70220574ef3c9e350cef726c75114f0701fd8b188c6ec5f84adce0ed5c393828a5ae001 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"prev_out": {
|
102
|
+
"hash": "402b2c02411720bf409eff60d05adad684f135838962823f3614cc657dd7bc0a",
|
103
|
+
"n": 1
|
104
|
+
},
|
105
|
+
"scriptSig": "3045022100a6ac110802b699f9a2bff0eea252d32e3d572b19214d49d8bb7405efa2af28f1022033b7563eb595f6d7ed7ec01734e17b505214fe0851352ed9c3c8120d53268e9a01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
106
|
+
},
|
107
|
+
{
|
108
|
+
"prev_out": {
|
109
|
+
"hash": "7d037ceb2ee0dc03e82f17be7935d238b35d1deabf953a892a4507bfbeeb3ba4",
|
110
|
+
"n": 1
|
111
|
+
},
|
112
|
+
"scriptSig": "3045022100ebc77ed0f11d15fe630fe533dc350c2ddc1c81cfeb81d5a27d0587163f58a28c02200983b2a32a1014bab633bfc9258083ac282b79566b6b3fa45c1e6758610444f401 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
113
|
+
},
|
114
|
+
{
|
115
|
+
"prev_out": {
|
116
|
+
"hash": "6c1d56f31b2de4bfc6aaea28396b333102b1f600da9c6d6149e96ca43f1102b1",
|
117
|
+
"n": 1
|
118
|
+
},
|
119
|
+
"scriptSig": "3044022010f8731929a55c1c49610722e965635529ed895b2292d781b183d465799906b20220098359adcbc669cd4b294cc129b110fe035d2f76517248f4b7129f3bf793d07f01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"prev_out": {
|
123
|
+
"hash": "b4112b8f900a7ca0c8b0e7c4dfad35c6be5f6be46b3458974988e1cdb2fa61b8",
|
124
|
+
"n": 0
|
125
|
+
},
|
126
|
+
"scriptSig": "304402207328142bb02ef5d6496a210300f4aea71f67683b842fa3df32cae6c88b49a9bb022020f56ddff5042260cfda2c9f39b7dec858cc2f4a76a987cd2dc25945b04e15fe01 0391064d5b2d1c70f264969046fcff853a7e2bfde5d121d38dc5ebd7bc37c2b210"
|
127
|
+
}
|
128
|
+
],
|
129
|
+
"out": [
|
130
|
+
{
|
131
|
+
"value": "4.00057456",
|
132
|
+
"scriptPubKey": "OP_DUP OP_HASH160 4a5fba237213a062f6f57978f796390bdcf8d015 OP_EQUALVERIFY OP_CHECKSIG"
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"value": "400.00000000",
|
136
|
+
"scriptPubKey": "OP_DUP OP_HASH160 5be32612930b8323add2212a4ec03c1562084f84 OP_EQUALVERIFY OP_CHECKSIG"
|
137
|
+
}
|
138
|
+
]
|
139
|
+
}
|
data/spec/bitcoin/fixtures/tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
{
|
2
|
+
"hash": "28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f",
|
3
|
+
"ver": 1,
|
4
|
+
"vin_sz": 2,
|
5
|
+
"vout_sz": 2,
|
6
|
+
"lock_time": 0,
|
7
|
+
"size": 389,
|
8
|
+
"in": [
|
9
|
+
{
|
10
|
+
"prev_out": {
|
11
|
+
"hash": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055",
|
12
|
+
"n": 0
|
13
|
+
},
|
14
|
+
"scriptSig": "3045022100aa46504baa86df8a33b1192b1b9367b4d729dc41e389f2c04f3e5c7f0559aae702205e82253a54bf5c4f65b7428551554b2045167d6d206dfe6a2e198127d3f7df1501"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"prev_out": {
|
18
|
+
"hash": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055",
|
19
|
+
"n": 1
|
20
|
+
},
|
21
|
+
"scriptSig": "304402202329484c35fa9d6bb32a55a70c0982f606ce0e3634b69006138683bcd12cbb6602200c28feb1e2555c3210f1dddb299738b4ff8bbe9667b68cb8764b5ac17b7adf0001"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"out": [
|
25
|
+
{
|
26
|
+
"value": "1.00000000",
|
27
|
+
"scriptPubKey": "046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0c OP_CHECKSIG"
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"value": "24.00000000",
|
31
|
+
"scriptPubKey": "044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45af OP_CHECKSIG"
|
32
|
+
}
|
33
|
+
]
|
34
|
+
}
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require_relative '../spec_helper.rb'
|
4
|
+
|
5
|
+
include Bitcoin::Protocol
|
6
|
+
|
7
|
+
# this spec requires secp256k1 library
|
8
|
+
describe 'BIP143 spec' do
|
9
|
+
|
10
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Example
|
11
|
+
|
12
|
+
it 'Native P2WPKH' do
|
13
|
+
tx = Tx.new('0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000'.htb)
|
14
|
+
|
15
|
+
sig_hash0 = tx.signature_hash_for_input(0, '2103c9f4836b9a4f77fc0d81f7bcb01b7f1b35916864b9476c241ce9fc198bd25432ac'.htb)
|
16
|
+
sig0 = Bitcoin::Secp256k1.sign(sig_hash0, 'bbc27228ddcb9209d7fd6f36b02f7dfa6252af40bb2f1cbc7a557da8027ff866'.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C")
|
17
|
+
|
18
|
+
tx.in[0].script_sig = Bitcoin::Script.new(Bitcoin::Script.pack_pushdata(sig0)).to_payload
|
19
|
+
|
20
|
+
sig_hash1 = tx.signature_hash_for_witness_input(1, '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb, 600000000)
|
21
|
+
sig1 = Bitcoin::Secp256k1.sign(sig_hash1, '619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9'.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C")
|
22
|
+
|
23
|
+
tx.in[1].script_witness.stack << sig1
|
24
|
+
tx.in[1].script_witness.stack << '025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357'.htb
|
25
|
+
|
26
|
+
tx.to_witness_payload.bth.should == '01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'P2SH-P2WPKH' do
|
30
|
+
redeem_script = '001479091972186c449eb1ded22b78e40d009bdf0089'
|
31
|
+
tx = Tx.new('0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a54770100000000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000'.htb)
|
32
|
+
|
33
|
+
tx.in[0].script_sig = Bitcoin::Script.new(Bitcoin::Script.pack_pushdata(redeem_script.htb)).to_payload
|
34
|
+
|
35
|
+
sig_hash = tx.signature_hash_for_witness_input(0, redeem_script.htb, 1000000000)
|
36
|
+
sig = Bitcoin::Secp256k1.sign(sig_hash, 'eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf'.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C")
|
37
|
+
|
38
|
+
tx.in[0].script_witness.stack << sig
|
39
|
+
tx.in[0].script_witness.stack << '03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873'.htb
|
40
|
+
|
41
|
+
tx.to_witness_payload.bth.should == '01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Native P2WSH' do
|
45
|
+
# <026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae> CHECKSIGVERIFY CODESEPERATOR <0255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465> CHECKSIG
|
46
|
+
# this script needs two privkey signature
|
47
|
+
witness_script = Bitcoin::Script.new('21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac'.htb)
|
48
|
+
script_pubkey = '00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0'
|
49
|
+
|
50
|
+
tx = Tx.new('0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000'.htb)
|
51
|
+
|
52
|
+
sig_hash0 = tx.signature_hash_for_input(0, '21036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8ac'.htb)
|
53
|
+
sig0 = Bitcoin::Secp256k1.sign(sig_hash0, 'b8f28a772fccbf9b4f58a4f027e07dc2e35e7cd80529975e292ea34f84c4580c'.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C")
|
54
|
+
tx.in[0].script_sig = Bitcoin::Script.new(Bitcoin::Script.pack_pushdata(sig0)).to_payload
|
55
|
+
|
56
|
+
sig_hash1 = tx.signature_hash_for_witness_input(1, script_pubkey.htb, 4900000000, witness_script.to_payload, Tx::SIGHASH_TYPE[:single])
|
57
|
+
sig1 = Bitcoin::Secp256k1.sign(sig_hash1, '8e02b539b1500aa7c81cf3fed177448a546f19d2be416c0c61ff28e577d8d0cd'.htb) + [Tx::SIGHASH_TYPE[:single]].pack("C")
|
58
|
+
|
59
|
+
sig_hash2 = tx.signature_hash_for_witness_input(1, script_pubkey.htb, 4900000000, witness_script.to_payload, Tx::SIGHASH_TYPE[:single], 1)
|
60
|
+
sig2 = Bitcoin::Secp256k1.sign(sig_hash2, '86bf2ed75935a0cbef03b89d72034bb4c189d381037a5ac121a70016db8896ec'.htb) + [Tx::SIGHASH_TYPE[:single]].pack("C")
|
61
|
+
|
62
|
+
tx.in[1].script_witness.stack << sig2
|
63
|
+
tx.in[1].script_witness.stack << sig1
|
64
|
+
tx.in[1].script_witness.stack << witness_script.to_payload
|
65
|
+
|
66
|
+
tx.to_witness_payload.bth.should == '01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000'
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
it 'P2SH-P2WSH' do
|
71
|
+
redeem_script = '0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54'
|
72
|
+
# 6-of-6 multisig
|
73
|
+
witness_script = Bitcoin::Script.new('56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae'.htb)
|
74
|
+
|
75
|
+
tx = Tx.new('010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000'.htb)
|
76
|
+
tx.in[0].script_sig = Bitcoin::Script.new(Bitcoin::Script.pack_pushdata(redeem_script.htb)).to_payload
|
77
|
+
|
78
|
+
|
79
|
+
tx.in[0].script_witness.stack << ''
|
80
|
+
|
81
|
+
sig_hash0 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload)
|
82
|
+
sig0 = Bitcoin::Secp256k1.sign(sig_hash0, '730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6'.htb) + [Tx::SIGHASH_TYPE[:all]].pack("C")
|
83
|
+
sig0.bth.should == '304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01'
|
84
|
+
tx.in[0].script_witness.stack << sig0
|
85
|
+
|
86
|
+
sig_hash1 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload, Tx::SIGHASH_TYPE[:none])
|
87
|
+
sig1 = Bitcoin::Secp256k1.sign(sig_hash1, '11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3'.htb) + [Tx::SIGHASH_TYPE[:none]].pack("C")
|
88
|
+
sig1.bth.should == '3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502'
|
89
|
+
tx.in[0].script_witness.stack << sig1
|
90
|
+
|
91
|
+
sig_hash2 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload, Tx::SIGHASH_TYPE[:single])
|
92
|
+
sig2 = Bitcoin::Secp256k1.sign(sig_hash2, '77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661'.htb) + [Tx::SIGHASH_TYPE[:single]].pack("C")
|
93
|
+
sig2.bth.should == '3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403'
|
94
|
+
tx.in[0].script_witness.stack << sig2
|
95
|
+
|
96
|
+
sig_hash3 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload, Tx::SIGHASH_TYPE[:all] | Tx::SIGHASH_TYPE[:anyonecanpay])
|
97
|
+
sig3 = Bitcoin::Secp256k1.sign(sig_hash3, '14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49'.htb) + [Tx::SIGHASH_TYPE[:all] | Tx::SIGHASH_TYPE[:anyonecanpay]].pack("C")
|
98
|
+
sig3.bth.should == '3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381'
|
99
|
+
tx.in[0].script_witness.stack << sig3
|
100
|
+
|
101
|
+
sig_hash4 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload, Tx::SIGHASH_TYPE[:none] | Tx::SIGHASH_TYPE[:anyonecanpay])
|
102
|
+
sig4 = Bitcoin::Secp256k1.sign(sig_hash4, 'fe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323'.htb) + [Tx::SIGHASH_TYPE[:none] | Tx::SIGHASH_TYPE[:anyonecanpay]].pack("C")
|
103
|
+
sig4.bth.should == '3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882'
|
104
|
+
tx.in[0].script_witness.stack << sig4
|
105
|
+
|
106
|
+
sig_hash5 = tx.signature_hash_for_witness_input(0, redeem_script.htb, 987654321, witness_script.to_payload, Tx::SIGHASH_TYPE[:single] | Tx::SIGHASH_TYPE[:anyonecanpay])
|
107
|
+
sig5 = Bitcoin::Secp256k1.sign(sig_hash5, '428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890'.htb) + [Tx::SIGHASH_TYPE[:single] | Tx::SIGHASH_TYPE[:anyonecanpay]].pack("C")
|
108
|
+
sig5.bth.should == '30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783'
|
109
|
+
tx.in[0].script_witness.stack << sig5
|
110
|
+
|
111
|
+
tx.in[0].script_witness.stack << witness_script.to_payload
|
112
|
+
|
113
|
+
tx.to_witness_payload.bth.should == '0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000'
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -20,6 +20,10 @@ describe 'Bitcoin::Protocol::Block' do
|
|
20
20
|
# block 26478: 000000000214a3f06ee99a033a7f2252762d6a18d27c3cd8c8fe2278190da9f3
|
21
21
|
'testnet-26478' => fixtures_file('rawblock-testnet-26478.bin'),
|
22
22
|
'testnet-265322' => fixtures_file('rawblock-testnet-265322.bin'),
|
23
|
+
# block 1151351: 000000000000031525003c4e061fd2e5ce5f4fda6121a836e66f70ec2df621de
|
24
|
+
'testnet-1151351' => fixtures_file('rawblock-testnet-1151351.bin'),
|
25
|
+
# block 100005: 000000000000dab0130bbcc991d3d7ae6b81aa6f50a798888dfe62337458dc45
|
26
|
+
'filtered-0' => fixtures_file('filteredblock-0.bin'),
|
23
27
|
}
|
24
28
|
end
|
25
29
|
|
@@ -42,6 +46,10 @@ describe 'Bitcoin::Protocol::Block' do
|
|
42
46
|
block.parse_data(@blocks['0'] + "AAAA").should == "AAAA"
|
43
47
|
block.header_info[7].should == 215
|
44
48
|
block.to_payload.should == @blocks['0']
|
49
|
+
|
50
|
+
# parse block which includes segwit tx
|
51
|
+
block = Block.new(@blocks['testnet-1151351'])
|
52
|
+
block.mrkl_root.should == 'e4bbfc681f2bf0ed5fe13a01f5f82bd1844d406fe793a7ec590151f4ea4060d5'.htb.reverse
|
45
53
|
end
|
46
54
|
|
47
55
|
it '#hash' do
|
@@ -54,6 +62,10 @@ describe 'Bitcoin::Protocol::Block' do
|
|
54
62
|
@block.tx[0].hash.should == "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
|
55
63
|
end
|
56
64
|
|
65
|
+
it "#tx_hashes" do
|
66
|
+
@block.tx_hashes.should == ["0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"]
|
67
|
+
end
|
68
|
+
|
57
69
|
it '#to_hash' do
|
58
70
|
@block.to_hash.keys.should == ["hash", "ver", "prev_block", "mrkl_root", "time", "bits", "nonce", "n_tx", "size", "tx", "mrkl_tree"]
|
59
71
|
end
|
@@ -135,6 +147,21 @@ describe 'Bitcoin::Protocol::Block' do
|
|
135
147
|
|
136
148
|
end
|
137
149
|
|
150
|
+
#
|
151
|
+
# following test cases are borrowed from
|
152
|
+
# https://github.com/bitcoinj/bitcoinj/blob/master/core/src/test/java/org/bitcoinj/core/FilteredBlockAndPartialMerkleTreeTests.java
|
153
|
+
#
|
154
|
+
it "filtered block parsing" do
|
155
|
+
block = Block.new
|
156
|
+
proc {
|
157
|
+
block.parse_data_from_io(@blocks['filtered-0'], :filtered)
|
158
|
+
}.should.not.raise Exception
|
159
|
+
|
160
|
+
block.verify_mrkl_root.should == true
|
161
|
+
block.hash.should == '000000000000dab0130bbcc991d3d7ae6b81aa6f50a798888dfe62337458dc45'
|
162
|
+
block.tx_hashes.should == ['63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5']
|
163
|
+
end
|
164
|
+
|
138
165
|
it '#header_to_json' do
|
139
166
|
@block.header_to_json.should == (<<-JSON).chomp
|
140
167
|
{
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
|
5
|
+
#
|
6
|
+
# following test cases are borrowed from
|
7
|
+
# https://github.com/bitcoinj/bitcoinj/blob/master/core/src/test/java/org/bitcoinj/core/FilteredBlockAndPartialMerkleTreeTests.java
|
8
|
+
#
|
9
|
+
describe 'Bitcoin::Protocol::PartialMerkleTree' do
|
10
|
+
it "initialize" do
|
11
|
+
hashes = [
|
12
|
+
'4c30b63cfcdc2d35e3329421b9805ef0c6565d35381ca857762ea0b3a5a128bb',
|
13
|
+
'ca5065ff9617cbcba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb',
|
14
|
+
'bb15ac1d57d0182aaee61c74743a9c4f785895e563909bafec45c9a2b0ff3181',
|
15
|
+
'd77706be8b1dcc91112eada86d424e2d0a8907c3488b6e44fda5a74a25cbc7d6',
|
16
|
+
'bb4fa04245f4ac8a1a571d5537eac24adca1454d65eda446055479af6c6d4dd3',
|
17
|
+
'c9ab658448c10b6921b7a4ce3021eb22ed6bb6a7fde1e5bcc4b1db6615c6abc5',
|
18
|
+
'ca042127bfaf9f44ebce29cb29c6df9d05b47f35b2edff4f0064b578ab741fa7',
|
19
|
+
'8276222651209fe1a2c4c0fa1c58510aec8b090dd1eb1f82f9d261b8273b525b',
|
20
|
+
].map(&:htb)
|
21
|
+
tree = Bitcoin::P::PartialMerkleTree.new(12, hashes, 'ff1a'.htb)
|
22
|
+
tree.set_value
|
23
|
+
|
24
|
+
tx_hashes = Set.new(tree.tx_hashes)
|
25
|
+
# following 6 are leaves (tx_hash) of merkle tree
|
26
|
+
tx_hashes.include?('bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c').should == true
|
27
|
+
tx_hashes.include?('fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca').should == true
|
28
|
+
tx_hashes.include?('8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb').should == true
|
29
|
+
tx_hashes.include?('c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9').should == true
|
30
|
+
tx_hashes.include?('d6c7cb254aa7a5fd446e8b48c307890a2d4e426da8ad2e1191cc1d8bbe0677d7').should == true
|
31
|
+
tx_hashes.include?('a71f74ab78b564004fffedb2357fb4059ddfc629cb29ceeb449fafbf272104ca').should == true
|
32
|
+
# following 2 are edge node of merkle tree
|
33
|
+
tx_hashes.include?('d34d6d6caf79540546a4ed654d45a1dc4ac2ea37551d571a8aacf44542a04fbb').should == false
|
34
|
+
tx_hashes.include?('5b523b27b861d2f9821febd10d098bec0a51581cfac0c4a2e19f205126227682').should == false
|
35
|
+
|
36
|
+
tree.root.value.should == '7fe79307aeb300d910d9c4bec5bacb4c7e114c7dfd6789e19f3a733debb3bb6a'
|
37
|
+
end
|
38
|
+
end
|
@@ -10,12 +10,14 @@ describe 'Tx' do
|
|
10
10
|
fixtures_file('rawtx-01.bin'),
|
11
11
|
fixtures_file('rawtx-02.bin'),
|
12
12
|
fixtures_file('rawtx-03.bin'),
|
13
|
+
fixtures_file('rawtx-p2wpkh.bin'),
|
13
14
|
]
|
14
15
|
|
15
16
|
@json = [
|
16
17
|
fixtures_file('rawtx-01.json'),
|
17
18
|
fixtures_file('rawtx-02.json'),
|
18
|
-
fixtures_file('rawtx-03.json')
|
19
|
+
fixtures_file('rawtx-03.json'),
|
20
|
+
fixtures_file('rawtx-p2wpkh.json')
|
19
21
|
]
|
20
22
|
|
21
23
|
|
@@ -42,11 +44,29 @@ describe 'Tx' do
|
|
42
44
|
tx.hash.size.should == 64
|
43
45
|
end
|
44
46
|
|
47
|
+
it '#parse_witness_data' do
|
48
|
+
tx = Tx.new( @payload[3] )
|
49
|
+
tx.hash.size.should == 64
|
50
|
+
|
51
|
+
tx = Tx.new( @payload[3] + "AAAA" )
|
52
|
+
tx.hash.size.should == 64
|
53
|
+
end
|
54
|
+
|
45
55
|
it '#hash' do
|
46
56
|
tx = Tx.new( @payload[0] )
|
47
57
|
tx.hash.size.should == 64
|
48
58
|
tx.hash.should == "6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4"
|
49
59
|
tx.binary_hash.should == "\xB4\x02-\x9F\xE5(\xFB\x90pP\x01\x16K\f\xC3\xA8\xF5\xA1\x9C\xB8\xED\x02\xBF\xD4\xFC,\xB6%f\xD1\x9Dn"
|
60
|
+
|
61
|
+
tx = Tx.new(@payload[3])
|
62
|
+
tx.hash.size.should == 64
|
63
|
+
tx.hash.should == "f22f5168cf0bc55a31003b0fc532152da551e1ec4289c4fd92e7ec512c6e87a0"
|
64
|
+
end
|
65
|
+
|
66
|
+
it '#witness_hash' do
|
67
|
+
tx = Tx.new(@payload[3])
|
68
|
+
tx.witness_hash.size.should == 64
|
69
|
+
tx.witness_hash.should == "c9609ed4d7e60ebcf4cce2854568b54a855a12b5bda15433ca96e72cd445a5cf"
|
50
70
|
end
|
51
71
|
|
52
72
|
it '#normalized_hash' do
|
@@ -72,9 +92,19 @@ describe 'Tx' do
|
|
72
92
|
tx.to_payload.should == @payload[0]
|
73
93
|
end
|
74
94
|
|
95
|
+
it '#to_witness_payload' do
|
96
|
+
tx = Tx.new( @payload[3] )
|
97
|
+
tx.to_witness_payload.size.should == @payload[3].size
|
98
|
+
tx.to_witness_payload.should == @payload[3]
|
99
|
+
end
|
100
|
+
|
75
101
|
it '#to_hash' do
|
76
102
|
tx = Tx.new( @payload[0] )
|
77
103
|
tx.to_hash.keys.should == ["hash", "ver", "vin_sz", "vout_sz", "lock_time", "size", "in", "out"]
|
104
|
+
|
105
|
+
# witness tx
|
106
|
+
tx = Tx.new( @payload[3] )
|
107
|
+
tx.to_hash.keys.should == ["hash", "ver", "vin_sz", "vout_sz", "lock_time", "size", "in", "out"]
|
78
108
|
end
|
79
109
|
|
80
110
|
it 'Tx.from_hash' do
|
@@ -88,12 +118,23 @@ describe 'Tx' do
|
|
88
118
|
h = orig_tx.to_hash.merge("ver" => 123)
|
89
119
|
-> { tx = Tx.from_hash(h) }.should.raise(Exception)
|
90
120
|
.message.should == "Tx hash mismatch! Claimed: 6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4, Actual: 395cd28c334ac84ed125ec5ccd5bc29eadcc96b79c337d0a87a19df64ea3b548"
|
121
|
+
|
122
|
+
# witness tx(P2WPKH)
|
123
|
+
orig_tx = Tx.new( @payload[3] )
|
124
|
+
tx = Tx.from_hash( orig_tx.to_hash )
|
125
|
+
tx.to_witness_payload.size.should == @payload[3].size
|
126
|
+
tx.to_witness_payload.should == @payload[3]
|
127
|
+
tx.to_hash == orig_tx.to_hash
|
91
128
|
end
|
92
129
|
|
93
130
|
it 'Tx.binary_from_hash' do
|
94
131
|
orig_tx = Tx.new( @payload[0] )
|
95
132
|
Tx.binary_from_hash( orig_tx.to_hash ).size.should == @payload[0].size
|
96
133
|
Tx.binary_from_hash( orig_tx.to_hash ).should == @payload[0]
|
134
|
+
|
135
|
+
orig_tx = Tx.new( @payload[3] )
|
136
|
+
Tx.binary_from_hash( orig_tx.to_hash ).size.should == @payload[3].size
|
137
|
+
Tx.binary_from_hash( orig_tx.to_hash ).should == @payload[3]
|
97
138
|
end
|
98
139
|
|
99
140
|
it '#to_json' do
|
@@ -108,6 +149,9 @@ describe 'Tx' do
|
|
108
149
|
|
109
150
|
tx = Tx.new( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin') )
|
110
151
|
tx.to_json.should == fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json')
|
152
|
+
|
153
|
+
tx = Tx.new(@payload[3])
|
154
|
+
tx.to_json.should == @json[3]
|
111
155
|
end
|
112
156
|
|
113
157
|
it 'Tx.from_json' do
|
@@ -133,6 +177,11 @@ describe 'Tx' do
|
|
133
177
|
Tx.from_json(fixtures_file('rawtx-02-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('rawtx-02.json')).to_payload
|
134
178
|
Tx.from_json(fixtures_file('rawtx-03-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('rawtx-03.json')).to_payload
|
135
179
|
Tx.from_json(fixtures_file('coinbase-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('coinbase.json')).to_payload
|
180
|
+
|
181
|
+
# witness tx
|
182
|
+
tx = Tx.from_json(json_string = fixtures_file('rawtx-p2wpkh.json'))
|
183
|
+
tx.to_witness_payload.should == @payload[3]
|
184
|
+
tx.to_json == json_string
|
136
185
|
end
|
137
186
|
|
138
187
|
it 'Tx.binary_from_json' do
|
@@ -396,6 +445,24 @@ describe 'Tx' do
|
|
396
445
|
tx.verify_input_signature(0, outpoint_tx).should == true
|
397
446
|
end
|
398
447
|
|
448
|
+
it '#verify_witness_input_signature' do
|
449
|
+
#P2WPKH
|
450
|
+
tx = Tx.new('01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000'.htb)
|
451
|
+
tx.verify_witness_input_signature(1, '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb, 600000000).should == true
|
452
|
+
|
453
|
+
# P2WSH
|
454
|
+
tx = Tx.new('01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000'.htb)
|
455
|
+
tx.verify_witness_input_signature(1, '00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0'.htb, 4900000000).should == true
|
456
|
+
|
457
|
+
# P2SH-P2WPKH
|
458
|
+
tx = Bitcoin::P::Tx.new('01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000'.htb)
|
459
|
+
tx.verify_witness_input_signature(0, 'a9144733f37cf4db86fbc2efed2500b4f4e49f31202387'.htb, 1000000000).should == true
|
460
|
+
|
461
|
+
# P2SH-P2WSH
|
462
|
+
tx = Bitcoin::P::Tx.new('0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000'.htb)
|
463
|
+
tx.verify_witness_input_signature(0, 'a9149993a429037b5d912407a71c252019287b8d27a587'.htb, 987654321).should == true
|
464
|
+
end
|
465
|
+
|
399
466
|
it '#sign_input_signature' do
|
400
467
|
prev_tx = Tx.new( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin') )
|
401
468
|
prev_tx.hash.should == "2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a"
|
@@ -455,6 +522,28 @@ describe 'Tx' do
|
|
455
522
|
prev_tx.hash.should == "52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2"
|
456
523
|
#File.open("rawtx-#{prev_tx.hash}.json",'wb'){|f| f.print prev_tx.to_json }
|
457
524
|
end
|
525
|
+
|
526
|
+
it '#signature_hash_for_witness_input' do
|
527
|
+
# P2WPKH https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Native_P2WPKH
|
528
|
+
tx = Tx.new('0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f0000000000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000'.htb)
|
529
|
+
signature_hash = tx.signature_hash_for_witness_input(1, '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb, 600000000)
|
530
|
+
signature_hash.bth.should == 'c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670'
|
531
|
+
|
532
|
+
# P2WSH https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Native_P2WSH
|
533
|
+
tx = Tx.new('0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000'.htb)
|
534
|
+
script_pubkey = '00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0'
|
535
|
+
witness_script = '21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac'
|
536
|
+
signature_hash = tx.signature_hash_for_witness_input(1, script_pubkey.htb, 4900000000, witness_script.htb, Tx::SIGHASH_TYPE[:single])
|
537
|
+
signature_hash.bth.should == '82dde6e4f1e94d02c2b7ad03d2115d691f48d064e9d52f58194a6637e4194391'
|
538
|
+
|
539
|
+
# P2WSH with invalid witness script
|
540
|
+
tx = Tx.new('0100000002fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e0000000000ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac00000000'.htb)
|
541
|
+
script_pubkey = '00205d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0'
|
542
|
+
witness_script = 'AAA'
|
543
|
+
proc{
|
544
|
+
tx.signature_hash_for_witness_input(1, script_pubkey.htb, 4900000000, witness_script.htb)
|
545
|
+
}.should.raise Exception
|
546
|
+
end
|
458
547
|
|
459
548
|
it "#legacy_sigops_count" do
|
460
549
|
Tx.new(@payload[0]).legacy_sigops_count.should == 2
|
@@ -625,5 +714,49 @@ describe 'Tx' do
|
|
625
714
|
end
|
626
715
|
|
627
716
|
end
|
717
|
+
|
718
|
+
it 'lexicographical_sort' do
|
719
|
+
tx = Bitcoin::P::Tx.from_json(fixtures_file('tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json'))
|
720
|
+
tx.hash.should == '0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3'
|
721
|
+
tx.lexicographical_sort!
|
722
|
+
tx.in[0].previous_output.should == '0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57'
|
723
|
+
tx.in[1].previous_output.should == '26aa6e6d8b9e49bb0630aac301db6757c02e3619feb4ee0eea81eb1672947024'
|
724
|
+
tx.in[2].previous_output.should == '28e0fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2'
|
725
|
+
tx.in[3].previous_output.should == '381de9b9ae1a94d9c17f6a08ef9d341a5ce29e2e60c36a52d333ff6203e58d5d'
|
726
|
+
tx.in[4].previous_output.should == '3b8b2f8efceb60ba78ca8bba206a137f14cb5ea4035e761ee204302d46b98de2'
|
727
|
+
tx.in[5].previous_output.should == '402b2c02411720bf409eff60d05adad684f135838962823f3614cc657dd7bc0a'
|
728
|
+
tx.in[6].previous_output.should == '54ffff182965ed0957dba1239c27164ace5a73c9b62a660c74b7b7f15ff61e7a'
|
729
|
+
tx.in[7].previous_output.should == '643e5f4e66373a57251fb173151e838ccd27d279aca882997e005016bb53d5aa'
|
730
|
+
tx.in[8].previous_output.should == '6c1d56f31b2de4bfc6aaea28396b333102b1f600da9c6d6149e96ca43f1102b1'
|
731
|
+
tx.in[9].previous_output.should == '7a1de137cbafb5c70405455c49c5104ca3057a1f1243e6563bb9245c9c88c191'
|
732
|
+
tx.in[10].previous_output.should == '7d037ceb2ee0dc03e82f17be7935d238b35d1deabf953a892a4507bfbeeb3ba4'
|
733
|
+
tx.in[11].previous_output.should == 'a5e899dddb28776ea9ddac0a502316d53a4a3fca607c72f66c470e0412e34086'
|
734
|
+
tx.in[12].previous_output.should == 'b4112b8f900a7ca0c8b0e7c4dfad35c6be5f6be46b3458974988e1cdb2fa61b8'
|
735
|
+
tx.in[13].previous_output.should == 'bafd65e3c7f3f9fdfdc1ddb026131b278c3be1af90a4a6ffa78c4658f9ec0c85'
|
736
|
+
tx.in[14].previous_output.should == 'de0411a1e97484a2804ff1dbde260ac19de841bebad1880c782941aca883b4e9'
|
737
|
+
tx.in[15].previous_output.should == 'f0a130a84912d03c1d284974f563c5949ac13f8342b8112edff52971599e6a45'
|
738
|
+
tx.in[16].previous_output.should == 'f320832a9d2e2452af63154bc687493484a0e7745ebd3aaf9ca19eb80834ad60'
|
739
|
+
tx.out[0].value.should == 400057456
|
740
|
+
tx.out[1].value.should == 40000000000
|
741
|
+
|
742
|
+
tx = Bitcoin::P::Tx.from_json(fixtures_file('tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json'))
|
743
|
+
tx.hash.should == '28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f'
|
744
|
+
tx.lexicographical_sort!
|
745
|
+
tx.in[0].previous_output.should == '35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055'
|
746
|
+
tx.in[0].prev_out_index.should == 0
|
747
|
+
tx.in[1].previous_output.should == '35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055'
|
748
|
+
tx.in[1].prev_out_index.should == 1
|
749
|
+
tx.out[0].value.should == 100000000
|
750
|
+
tx.out[1].value.should == 2400000000
|
751
|
+
|
752
|
+
tx = Bitcoin::P::Tx.new
|
753
|
+
tx.add_out(Bitcoin::P::TxOut.new(500, 'bbbbbbbb'.htb))
|
754
|
+
tx.add_out(Bitcoin::P::TxOut.new(500, 'aaaaaaaa'.htb))
|
755
|
+
tx.add_out(Bitcoin::P::TxOut.new(500, 'cccccccc'.htb))
|
756
|
+
tx.lexicographical_sort!
|
757
|
+
tx.out[0].pk_script.bth.should == 'aaaaaaaa'
|
758
|
+
tx.out[1].pk_script.bth.should == 'bbbbbbbb'
|
759
|
+
tx.out[2].pk_script.bth.should == 'cccccccc'
|
760
|
+
end
|
628
761
|
|
629
762
|
end
|