bitcoin-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/COPYING +18 -0
- data/Gemfile +4 -0
- data/README.rdoc +189 -0
- data/Rakefile +104 -0
- data/bin/bitcoin_dns_seed +130 -0
- data/bin/bitcoin_gui +80 -0
- data/bin/bitcoin_node +174 -0
- data/bin/bitcoin_shell +12 -0
- data/bin/bitcoin_wallet +323 -0
- data/bitcoin-ruby.gemspec +27 -0
- data/concept-examples/blockchain-pow.rb +151 -0
- data/doc/CONFIG.rdoc +66 -0
- data/doc/EXAMPLES.rdoc +9 -0
- data/doc/NODE.rdoc +35 -0
- data/doc/STORAGE.rdoc +21 -0
- data/doc/WALLET.rdoc +102 -0
- data/examples/balance.rb +60 -0
- data/examples/bbe_verify_tx.rb +55 -0
- data/examples/connect.rb +36 -0
- data/examples/relay_tx.rb +22 -0
- data/examples/verify_tx.rb +57 -0
- data/lib/bitcoin.rb +370 -0
- data/lib/bitcoin/builder.rb +266 -0
- data/lib/bitcoin/config.rb +56 -0
- data/lib/bitcoin/connection.rb +126 -0
- data/lib/bitcoin/ffi/openssl.rb +121 -0
- data/lib/bitcoin/gui/addr_view.rb +42 -0
- data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
- data/lib/bitcoin/gui/bitcoin-ruby.svg +80 -0
- data/lib/bitcoin/gui/conn_view.rb +36 -0
- data/lib/bitcoin/gui/connection.rb +68 -0
- data/lib/bitcoin/gui/em_gtk.rb +28 -0
- data/lib/bitcoin/gui/gui.builder +1643 -0
- data/lib/bitcoin/gui/gui.rb +290 -0
- data/lib/bitcoin/gui/helpers.rb +113 -0
- data/lib/bitcoin/gui/tree_view.rb +82 -0
- data/lib/bitcoin/gui/tx_view.rb +67 -0
- data/lib/bitcoin/key.rb +125 -0
- data/lib/bitcoin/logger.rb +65 -0
- data/lib/bitcoin/network/command_client.rb +93 -0
- data/lib/bitcoin/network/command_handler.rb +179 -0
- data/lib/bitcoin/network/connection_handler.rb +274 -0
- data/lib/bitcoin/network/node.rb +399 -0
- data/lib/bitcoin/protocol.rb +140 -0
- data/lib/bitcoin/protocol/address.rb +48 -0
- data/lib/bitcoin/protocol/alert.rb +47 -0
- data/lib/bitcoin/protocol/block.rb +154 -0
- data/lib/bitcoin/protocol/handler.rb +38 -0
- data/lib/bitcoin/protocol/parser.rb +148 -0
- data/lib/bitcoin/protocol/tx.rb +205 -0
- data/lib/bitcoin/protocol/txin.rb +97 -0
- data/lib/bitcoin/protocol/txout.rb +73 -0
- data/lib/bitcoin/protocol/version.rb +70 -0
- data/lib/bitcoin/script.rb +634 -0
- data/lib/bitcoin/storage/dummy.rb +164 -0
- data/lib/bitcoin/storage/models.rb +133 -0
- data/lib/bitcoin/storage/sequel.rb +335 -0
- data/lib/bitcoin/storage/sequel_store/sequel_migrations.rb +84 -0
- data/lib/bitcoin/storage/storage.rb +243 -0
- data/lib/bitcoin/version.rb +3 -0
- data/lib/bitcoin/wallet/coinselector.rb +30 -0
- data/lib/bitcoin/wallet/keygenerator.rb +75 -0
- data/lib/bitcoin/wallet/keystore.rb +203 -0
- data/lib/bitcoin/wallet/txdp.rb +116 -0
- data/lib/bitcoin/wallet/wallet.rb +243 -0
- data/spec/bitcoin/bitcoin_spec.rb +472 -0
- data/spec/bitcoin/builder_spec.rb +90 -0
- data/spec/bitcoin/fixtures/0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json +27 -0
- data/spec/bitcoin/fixtures/23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63.json +23 -0
- data/spec/bitcoin/fixtures/477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json +27 -0
- data/spec/bitcoin/fixtures/60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1.json +45 -0
- data/spec/bitcoin/fixtures/bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba.json +34 -0
- data/spec/bitcoin/fixtures/rawblock-0.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-0.json +39 -0
- data/spec/bitcoin/fixtures/rawblock-1.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-1.json +39 -0
- data/spec/bitcoin/fixtures/rawblock-131025.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-131025.json +5063 -0
- data/spec/bitcoin/fixtures/rawblock-170.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-170.json +68 -0
- data/spec/bitcoin/fixtures/rawblock-9.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-9.json +39 -0
- data/spec/bitcoin/fixtures/rawblock-testnet-26478.bin +0 -0
- data/spec/bitcoin/fixtures/rawblock-testnet-26478.json +64 -0
- data/spec/bitcoin/fixtures/rawtx-01.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-01.json +27 -0
- data/spec/bitcoin/fixtures/rawtx-02.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-02.json +27 -0
- data/spec/bitcoin/fixtures/rawtx-03.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-03.json +48 -0
- data/spec/bitcoin/fixtures/rawtx-04.json +27 -0
- data/spec/bitcoin/fixtures/rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-05.json +23 -0
- data/spec/bitcoin/fixtures/rawtx-14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json +27 -0
- data/spec/bitcoin/fixtures/rawtx-406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602.json +23 -0
- data/spec/bitcoin/fixtures/rawtx-52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json +37 -0
- data/spec/bitcoin/fixtures/rawtx-c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73.json +24 -0
- data/spec/bitcoin/fixtures/rawtx-de35d060663750b3975b7997bde7fb76307cec5b270d12fcd9c4ad98b279c28c.json +23 -0
- data/spec/bitcoin/fixtures/rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-a220adf1902c46a39db25a24bc4178b6a88440f977a7e2cabfdd8b5c1dd35cfb.json +27 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.json +41 -0
- data/spec/bitcoin/fixtures/reorg/blk_0_to_4.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_3A.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_4A.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_5A.dat +0 -0
- data/spec/bitcoin/fixtures/testnet/block_0.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_1.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_2.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_3.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_4.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_5.bin +0 -0
- data/spec/bitcoin/fixtures/txdp-1.txt +32 -0
- data/spec/bitcoin/fixtures/txdp-2-signed.txt +19 -0
- data/spec/bitcoin/fixtures/txdp-2-unsigned.txt +14 -0
- data/spec/bitcoin/key_spec.rb +123 -0
- data/spec/bitcoin/network_spec.rb +48 -0
- data/spec/bitcoin/protocol/addr_spec.rb +68 -0
- data/spec/bitcoin/protocol/alert_spec.rb +20 -0
- data/spec/bitcoin/protocol/block_spec.rb +101 -0
- data/spec/bitcoin/protocol/inv_spec.rb +124 -0
- data/spec/bitcoin/protocol/ping_spec.rb +49 -0
- data/spec/bitcoin/protocol/tx_spec.rb +226 -0
- data/spec/bitcoin/protocol/version_spec.rb +77 -0
- data/spec/bitcoin/reorg_spec.rb +129 -0
- data/spec/bitcoin/script/opcodes_spec.rb +417 -0
- data/spec/bitcoin/script/script_spec.rb +246 -0
- data/spec/bitcoin/spec_helper.rb +36 -0
- data/spec/bitcoin/storage_spec.rb +229 -0
- data/spec/bitcoin/wallet/coinselector_spec.rb +35 -0
- data/spec/bitcoin/wallet/keygenerator_spec.rb +64 -0
- data/spec/bitcoin/wallet/keystore_spec.rb +188 -0
- data/spec/bitcoin/wallet/txdp_spec.rb +74 -0
- data/spec/bitcoin/wallet/wallet_spec.rb +207 -0
- metadata +295 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'Bitcoin::Protocol::Parser (alert)' do
|
4
|
+
|
5
|
+
it 'parses alert' do
|
6
|
+
payload = "s\x01\x00\x00\x007f@O\x00\x00\x00\x00\xB3\x05CO\x00\x00\x00\x00\xF2\x03\x00\x00\xF1\x03\x00\x00\x00\x10'\x00\x00H\xEE\x00\x00\x00d\x00\x00\x00\x00FSee bitcoin.org/feb20 if you have trouble connecting after 20 February\x00G0E\x02!\x00\x83\x89\xDFE\xF0p?9\xEC\x8C\x1C\xC4,\x13\x81\x0F\xFC\xAE\x14\x99[\xB6H4\x02\x19\xE3S\xB6;S\xEB\x02 \t\xECe\xE1\xC1\xAA\xEE\xC1\xFD3LkhK\xDE+?W0`\xD5\xB7\f:Fr3&\xE4\xE8\xA4\xF1"
|
7
|
+
|
8
|
+
alert = Bitcoin::Protocol::Alert.parse(payload)
|
9
|
+
alert.values.should == [1, 1329620535, 1329792435, 1010, 1009, nil, 10000, 61000, nil, 100, nil, "See bitcoin.org/feb20 if you have trouble connecting after 20 February", nil]
|
10
|
+
alert.valid_signature?.should == true
|
11
|
+
|
12
|
+
|
13
|
+
payload = "\xAC\x01\x00\x00\x00o\xF2cO\x00\x00\x00\x00k\"EQ\x00\x00\x00\x00\xF4\x03\x00\x00\xF2\x03\x00\x00\x00`\xEA\x00\x00`\xEA\x00\x00\x03\x11/Satoshi:0.6.0.3/\x0F/Satoshi:0.6.0/\x12/bitcoin-qt:0.6.0/\x88\x13\x00\x00\x00JURGENT: security fix for Bitcoin-Qt on Windows: http://bitcoin.org/critfix\x00H0F\x02!\x00\xB7\xB1o\x86\x0F\x9EZ\x87bt\xAE\xB7$u\xD2\xDE\xC3\x86j\xA7\xAF\x82\xAD\x97\\\x83Qd\xA9\x97\xA7\x16\x02!\x00\x86\xB4\x18)\xCB\x84\xBE\xD2\x86\x10\x82G\xBE\xBF;\xE9{\xD9\xB3\x1E\xB4/g\xB4\xD33\xCE\x8B\x1D}\xF8^"
|
14
|
+
|
15
|
+
alert = Bitcoin::Protocol::Alert.parse(payload)
|
16
|
+
alert.values.should == [1, 1331950191, 1363485291, 1012, 1010, nil, 60000, 60000, ["/Satoshi:0.6.0.3/", "/Satoshi:0.6.0/", "/bitcoin-qt:0.6.0/"], 5000, nil, "URGENT: security fix for Bitcoin-Qt on Windows: http://bitcoin.org/critfix", nil]
|
17
|
+
alert.valid_signature?.should == true
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'Bitcoin::Protocol::Block' do
|
4
|
+
|
5
|
+
@blocks = {
|
6
|
+
# block 0: 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
|
7
|
+
'0' => fixtures_file('rawblock-0.bin'),
|
8
|
+
# block 1: 000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd
|
9
|
+
'1' => fixtures_file('rawblock-1.bin'),
|
10
|
+
# block 9: 000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805
|
11
|
+
'9' => fixtures_file('rawblock-9.bin'),
|
12
|
+
# block 170: 00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee
|
13
|
+
'170' => fixtures_file('rawblock-170.bin'),
|
14
|
+
# block 131025: 00000000000007d938dbdd433c5ae12a782de74abf7f566518bc2b2d0a1df145
|
15
|
+
'131025' => fixtures_file('rawblock-131025.bin'),
|
16
|
+
# block 26478: 000000000214a3f06ee99a033a7f2252762d6a18d27c3cd8c8fe2278190da9f3
|
17
|
+
'testnet-26478' => fixtures_file('rawblock-testnet-26478.bin'),
|
18
|
+
}
|
19
|
+
|
20
|
+
|
21
|
+
it '#new' do
|
22
|
+
proc{
|
23
|
+
Bitcoin::Protocol::Block.new( nil )
|
24
|
+
@block = Bitcoin::Protocol::Block.new( @blocks['0'] )
|
25
|
+
}.should.not.raise Exception
|
26
|
+
|
27
|
+
proc{
|
28
|
+
Bitcoin::Protocol::Block.new( @blocks['0'][0..20] )
|
29
|
+
}.should.raise Exception
|
30
|
+
|
31
|
+
block = Bitcoin::Protocol::Block.new(nil)
|
32
|
+
block.parse_data(@blocks['0']).should == true
|
33
|
+
block.header_info[7].should == 215
|
34
|
+
block.to_payload.should == @blocks['0']
|
35
|
+
|
36
|
+
block = Bitcoin::Protocol::Block.new(nil)
|
37
|
+
block.parse_data(@blocks['0'] + "AAAA").should == "AAAA"
|
38
|
+
block.header_info[7].should == 215
|
39
|
+
block.to_payload.should == @blocks['0']
|
40
|
+
end
|
41
|
+
|
42
|
+
it '#hash' do
|
43
|
+
@block.hash.should == "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
|
44
|
+
end
|
45
|
+
|
46
|
+
it '#tx' do
|
47
|
+
@block.tx.size.should == 1
|
48
|
+
@block.tx[0].is_a?(Bitcoin::Protocol::Tx).should == true
|
49
|
+
@block.tx[0].hash.should == "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
|
50
|
+
end
|
51
|
+
|
52
|
+
it '#to_hash' do
|
53
|
+
@block.to_hash.keys.should == ["hash", "ver", "prev_block", "mrkl_root", "time", "bits", "nonce", "n_tx", "size", "tx", "mrkl_tree"]
|
54
|
+
end
|
55
|
+
|
56
|
+
it '#to_json' do
|
57
|
+
@block.to_json.should == fixtures_file('rawblock-0.json')
|
58
|
+
Bitcoin::Protocol::Block.new( @blocks['1'] ).to_json.should == fixtures_file('rawblock-1.json')
|
59
|
+
Bitcoin::Protocol::Block.new( @blocks['131025'] ).to_json.should == fixtures_file('rawblock-131025.json')
|
60
|
+
Bitcoin::Protocol::Block.new( @blocks['testnet-26478'] ).to_json.should == fixtures_file('rawblock-testnet-26478.json')
|
61
|
+
Bitcoin::P::Block.from_json(@block.to_json).tx[0].in[0].sequence.should == "\xff\xff\xff\xff"
|
62
|
+
end
|
63
|
+
|
64
|
+
it '#to_payload' do
|
65
|
+
@block.to_payload.should == @block.payload
|
66
|
+
Bitcoin::Protocol::Block.new( @block.to_payload ).to_payload.should == @block.payload
|
67
|
+
Bitcoin::Protocol::Block.new( @blocks['1'] ).to_payload.should == @blocks['1']
|
68
|
+
Bitcoin::Protocol::Block.new( @blocks['131025'] ).to_payload.should == @blocks['131025']
|
69
|
+
Bitcoin::Protocol::Block.new( @blocks['testnet-26478'] ).to_payload.should == @blocks['testnet-26478']
|
70
|
+
end
|
71
|
+
|
72
|
+
it '#from_json' do
|
73
|
+
block = Bitcoin::Protocol::Block.from_json(fixtures_file('rawblock-0.json'))
|
74
|
+
block.to_payload.should == @blocks['0']
|
75
|
+
block.tx[0].in[0].sequence.should == "\xff\xff\xff\xff"
|
76
|
+
Bitcoin::Protocol::Block.from_json(fixtures_file('rawblock-1.json')).to_payload.should == @blocks['1']
|
77
|
+
|
78
|
+
Bitcoin::Protocol::Block.from_json(fixtures_file('rawblock-131025.json'))
|
79
|
+
.to_payload.should == @blocks['131025']
|
80
|
+
|
81
|
+
Bitcoin::Protocol::Block.from_json(fixtures_file('rawblock-testnet-26478.json'))
|
82
|
+
.to_payload.should == @blocks['testnet-26478']
|
83
|
+
end
|
84
|
+
|
85
|
+
it '#header_to_json' do
|
86
|
+
@block.header_to_json.should == (<<-JSON).chomp
|
87
|
+
{
|
88
|
+
"hash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048",
|
89
|
+
"ver":1,
|
90
|
+
"prev_block":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
91
|
+
"mrkl_root":"0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
|
92
|
+
"time":1231469665,
|
93
|
+
"bits":486604799,
|
94
|
+
"nonce":2573394689,
|
95
|
+
"n_tx":1,
|
96
|
+
"size":215
|
97
|
+
}
|
98
|
+
JSON
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'Bitcoin::Protocol::Parser - Inventory Vectors' do
|
4
|
+
|
5
|
+
class Test_Handler < Bitcoin::Protocol::Handler
|
6
|
+
attr_reader :tx_inv
|
7
|
+
attr_reader :block_inv
|
8
|
+
def on_inv_transaction(hash); (@tx_inv ||= []) << hth(hash); end
|
9
|
+
def on_get_transaction(hash); (@tx_inv ||= []) << hth(hash); end
|
10
|
+
def on_inv_block(hash); (@block_inv ||= []) << hth(hash); end
|
11
|
+
def on_get_block(hash); (@block_inv ||= []) << hth(hash); end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
it 'parses inv (transaction)' do
|
16
|
+
pkt = [
|
17
|
+
"f9 be b4 d9 69 6e 76 00 00 00 00 00 00 00 00 00 49 00 00 00 11 ea 1c 91 02 01 00 00 00 e0 41 c2 38 f7 32 1a 68 0a 34 06 bf fd 72 12 e3 d1 2c b5 12 2a 8c 0b 52 76 de 82 30 b1 00 7a 42 01 00 00 00 33 00 09 71 a9 70 7b 6c 6d 6e 77 aa 2e ac 43 f3 e5 67 84 cb 61 b2 35 fb 8d fe e0 86 8b 40 7c f3"
|
18
|
+
.split(" ").join].pack("H*")
|
19
|
+
|
20
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
21
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
22
|
+
|
23
|
+
handler.tx_inv.should == [
|
24
|
+
"427a00b13082de76520b8c2a12b52cd1e31272fdbf06340a681a32f738c241e0",
|
25
|
+
"f37c408b86e0fe8dfb35b261cb8467e5f343ac2eaa776e6d6c7b70a971090033"
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
it 'parses getdata (transaction)' do
|
31
|
+
# 000013C4 f9 be b4 d9 67 65 74 64 61 74 61 00 00 00 00 00 ....getd ata.....
|
32
|
+
# 000013D4 25 00 00 00 c5 38 cd bb 01 01 00 00 00 b4 02 2d %....8.. .......-
|
33
|
+
# 000013E4 9f e5 28 fb 90 70 50 01 16 4b 0c c3 a8 f5 a1 9c ..(..pP. .K......
|
34
|
+
# 000013F4 b8 ed 02 bf d4 fc 2c b6 25 66 d1 9d 6e ......,. %f..n
|
35
|
+
|
36
|
+
pkt = [
|
37
|
+
"f9 be b4 d9 67 65 74 64 61 74 61 00 00 00 00 00 25 00 00 00 c5 38 cd bb 01 01 00 00 00 b4 02 2d 9f e5 28 fb 90 70 50 01 16 4b 0c c3 a8 f5 a1 9c b8 ed 02 bf d4 fc 2c b6 25 66 d1 9d 6e"
|
38
|
+
.split(" ").join].pack("H*")
|
39
|
+
|
40
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
41
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
42
|
+
|
43
|
+
handler.tx_inv.should == [
|
44
|
+
"6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4"
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
it 'parses inv (block)' do
|
50
|
+
# 00003C27 f9 be b4 d9 69 6e 76 00 00 00 00 00 00 00 00 00 ....inv. ........
|
51
|
+
# 00003C37 25 00 00 00 ae 13 a1 04 01 02 00 00 00 9d b9 c4 %....... ........
|
52
|
+
# 00003C47 e2 7c 5b cd 3f 62 e1 af 18 fd 9d 81 6d 6c 6b c7 .|[.?b.. ....mlk.
|
53
|
+
# 00003C57 b2 26 0a 39 c5 49 39 00 00 00 00 00 00 .&.9.I9. .....
|
54
|
+
pkt = [
|
55
|
+
"f9 be b4 d9 69 6e 76 00 00 00 00 00 00 00 00 00 25 00 00 00 ae 13 a1 04 01 02 00 00 00 9d b9 c4 e2 7c 5b cd 3f 62 e1 af 18 fd 9d 81 6d 6c 6b c7 b2 26 0a 39 c5 49 39 00 00 00 00 00 00"
|
56
|
+
.split(" ").join].pack("H*")
|
57
|
+
|
58
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
59
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
60
|
+
handler.block_inv.should == [
|
61
|
+
"0000000000003949c5390a26b2c76b6c6d819dfd18afe1623fcd5b7ce2c4b99d"
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
it 'parses getdata (block)' do
|
67
|
+
# 000039E3 f9 be b4 d9 67 65 74 64 61 74 61 00 00 00 00 00 ....getd ata.....
|
68
|
+
# 000039F3 25 00 00 00 ae 13 a1 04 01 02 00 00 00 9d b9 c4 %....... ........
|
69
|
+
# 00003A03 e2 7c 5b cd 3f 62 e1 af 18 fd 9d 81 6d 6c 6b c7 .|[.?b.. ....mlk.
|
70
|
+
# 00003A13 b2 26 0a 39 c5 49 39 00 00 00 00 00 00 .&.9.I9. .....
|
71
|
+
pkt = [
|
72
|
+
"f9 be b4 d9 67 65 74 64 61 74 61 00 00 00 00 00 25 00 00 00 ae 13 a1 04 01 02 00 00 00 9d b9 c4 e2 7c 5b cd 3f 62 e1 af 18 fd 9d 81 6d 6c 6b c7 b2 26 0a 39 c5 49 39 00 00 00 00 00 00"
|
73
|
+
.split(" ").join].pack("H*")
|
74
|
+
|
75
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
76
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
77
|
+
|
78
|
+
handler.block_inv.should == [
|
79
|
+
"0000000000003949c5390a26b2c76b6c6d819dfd18afe1623fcd5b7ce2c4b99d"
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
it 'parses getblocks' do
|
85
|
+
class Test_Handler < Bitcoin::Protocol::Handler
|
86
|
+
attr_reader :pkt
|
87
|
+
def on_getblocks(version, hashes, stop_hash); @pkt = { :version => version, :locator_hashes => hashes, :stop_hash => stop_hash }; end
|
88
|
+
end
|
89
|
+
|
90
|
+
locator_hashes = ["00000000068866924696f410b778911316f92035e9b69b62afa03573974fd750", "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"]
|
91
|
+
stop_hash = "0000000000000000000000000000000000000000000000000000000000000000"
|
92
|
+
pkt = Bitcoin::Protocol.getblocks_pkt( locator_hashes )
|
93
|
+
|
94
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
95
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
96
|
+
|
97
|
+
handler.pkt.should == {
|
98
|
+
:version => Bitcoin.network[:magic_head],
|
99
|
+
:locator_hashes => locator_hashes,
|
100
|
+
:stop_hash => "0000000000000000000000000000000000000000000000000000000000000000"
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'parses getheaders' do
|
105
|
+
class Test_Handler < Bitcoin::Protocol::Handler
|
106
|
+
attr_reader :pkt
|
107
|
+
def on_getheaders(version, hashes, stop_hash); @pkt = { :version => version, :locator_hashes => hashes, :stop_hash => stop_hash }; end
|
108
|
+
end
|
109
|
+
|
110
|
+
locator_hashes = ["00000000068866924696f410b778911316f92035e9b69b62afa03573974fd750", "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"]
|
111
|
+
stop_hash = "0000000000000000000000000000000000000000000000000000000000007e57"
|
112
|
+
pkt = Bitcoin::Protocol.getblocks_pkt( locator_hashes, stop_hash )
|
113
|
+
|
114
|
+
parser = Bitcoin::Protocol::Parser.new( handler = Test_Handler.new )
|
115
|
+
parser.parse(pkt + "AAAA").should == "AAAA"
|
116
|
+
|
117
|
+
handler.pkt.should == {
|
118
|
+
:version => Bitcoin.network[:magic_head],
|
119
|
+
:locator_hashes => locator_hashes,
|
120
|
+
:stop_hash => "0000000000000000000000000000000000000000000000000000000000007e57"
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'Bitcoin::Protocol::Parser (ping/pong)' do
|
4
|
+
|
5
|
+
class Ping_Handler < Bitcoin::Protocol::Handler
|
6
|
+
attr_reader :nonce
|
7
|
+
def on_ping(nonce)
|
8
|
+
@nonce = nonce
|
9
|
+
end
|
10
|
+
def on_pong(nonce)
|
11
|
+
@nonce = nonce
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
@parser = Bitcoin::Protocol::Parser.new( @handler = Ping_Handler.new )
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'parses ping without nonce' do
|
20
|
+
@parser.parse(Bitcoin::Protocol.pkt("ping", "") + "AAAA").should == "AAAA"
|
21
|
+
@handler.nonce.should == nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'parses ping with nonce' do
|
25
|
+
@parser.parse(Bitcoin::Protocol.pkt("ping", [12345].pack("Q")) + "AAAA").should == "AAAA"
|
26
|
+
@handler.nonce.should == 12345
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'builds ping without nonce' do
|
30
|
+
@parser.parse(Bitcoin::Protocol::ping_pkt)
|
31
|
+
@handler.nonce.should != nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'builds ping with nonce' do
|
35
|
+
@parser.parse(Bitcoin::Protocol::ping_pkt(12345))
|
36
|
+
@handler.nonce.should == 12345
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'parses pong' do
|
40
|
+
@parser.parse(Bitcoin::Protocol.pkt("pong", [12345].pack("Q")) + "AAAA").should == "AAAA"
|
41
|
+
@handler.nonce.should == 12345
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'builds pong' do
|
45
|
+
@parser.parse(Bitcoin::Protocol::pong_pkt(12345))
|
46
|
+
@handler.nonce.should == 12345
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
include Bitcoin::Protocol
|
4
|
+
|
5
|
+
describe 'Tx' do
|
6
|
+
|
7
|
+
@payload = [
|
8
|
+
fixtures_file('rawtx-01.bin'),
|
9
|
+
fixtures_file('rawtx-02.bin'),
|
10
|
+
fixtures_file('rawtx-03.bin'),
|
11
|
+
]
|
12
|
+
|
13
|
+
@json = [
|
14
|
+
fixtures_file('rawtx-01.json'),
|
15
|
+
fixtures_file('rawtx-02.json'),
|
16
|
+
fixtures_file('rawtx-03.json')
|
17
|
+
]
|
18
|
+
|
19
|
+
|
20
|
+
it '#new' do
|
21
|
+
proc{
|
22
|
+
Tx.new( nil )
|
23
|
+
@payload.each{|payload| Tx.new( payload ) }
|
24
|
+
}.should.not.raise Exception
|
25
|
+
|
26
|
+
proc{
|
27
|
+
Tx.new( @payload[0][0..20] )
|
28
|
+
}.should.raise Exception
|
29
|
+
end
|
30
|
+
|
31
|
+
it '#parse_data' do
|
32
|
+
tx = Tx.new( nil )
|
33
|
+
|
34
|
+
tx.hash.should == nil
|
35
|
+
tx.parse_data( @payload[0] ).should == true
|
36
|
+
tx.hash.size.should == 64
|
37
|
+
|
38
|
+
tx = Tx.new( nil )
|
39
|
+
tx.parse_data( @payload[0] + "AAAA" ).should == "AAAA"
|
40
|
+
tx.hash.size.should == 64
|
41
|
+
end
|
42
|
+
|
43
|
+
it '#hash' do
|
44
|
+
tx = Tx.new( @payload[0] )
|
45
|
+
tx.hash.size.should == 64
|
46
|
+
tx.hash.should == "6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4"
|
47
|
+
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"
|
48
|
+
end
|
49
|
+
|
50
|
+
it '#to_payload' do
|
51
|
+
tx = Tx.new( @payload[0] )
|
52
|
+
tx.to_payload.size.should == @payload[0].size
|
53
|
+
tx.to_payload.should == @payload[0]
|
54
|
+
end
|
55
|
+
|
56
|
+
it '#to_hash' do
|
57
|
+
tx = Tx.new( @payload[0] )
|
58
|
+
tx.to_hash.keys.should == ["hash", "ver", "vin_sz", "vout_sz", "lock_time", "size", "in", "out"]
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'Tx.from_hash' do
|
62
|
+
orig_tx = Tx.new( @payload[0] )
|
63
|
+
tx = Tx.from_hash( orig_tx.to_hash )
|
64
|
+
tx.to_payload.size.should == @payload[0].size
|
65
|
+
tx.to_payload.should == @payload[0]
|
66
|
+
tx.to_hash.should == orig_tx.to_hash
|
67
|
+
Tx.binary_from_hash( orig_tx.to_hash ).should == @payload[0]
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'Tx.binary_from_hash' do
|
71
|
+
orig_tx = Tx.new( @payload[0] )
|
72
|
+
Tx.binary_from_hash( orig_tx.to_hash ).size.should == @payload[0].size
|
73
|
+
Tx.binary_from_hash( orig_tx.to_hash ).should == @payload[0]
|
74
|
+
end
|
75
|
+
|
76
|
+
it '#to_json' do
|
77
|
+
tx = Tx.new( @payload[0] )
|
78
|
+
tx.to_json.should == @json[0]
|
79
|
+
|
80
|
+
tx = Tx.new( @payload[1] )
|
81
|
+
tx.to_json.should == @json[1]
|
82
|
+
|
83
|
+
tx = Tx.new( @payload[2] )
|
84
|
+
tx.to_json.should == @json[2]
|
85
|
+
|
86
|
+
tx = Tx.new( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin') )
|
87
|
+
tx.to_json.should == fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'Tx.from_json' do
|
91
|
+
tx = Tx.from_json( json_string = fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json') )
|
92
|
+
tx.to_json.should == json_string
|
93
|
+
|
94
|
+
tx = Tx.from_json( json_string = fixtures_file('rawtx-testnet-a220adf1902c46a39db25a24bc4178b6a88440f977a7e2cabfdd8b5c1dd35cfb.json') )
|
95
|
+
tx.to_json.should == json_string
|
96
|
+
|
97
|
+
tx = Tx.from_json( json_string = fixtures_file('rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.json') )
|
98
|
+
tx.to_payload.should == fixtures_file('rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.bin')
|
99
|
+
tx.to_json.should == json_string
|
100
|
+
|
101
|
+
tx = Tx.from_json( fixtures_file('rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json') )
|
102
|
+
Tx.new( tx.to_payload ).to_json.should == tx.to_json
|
103
|
+
tx.hash.should == 'ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5'
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'Tx.binary_from_json' do
|
107
|
+
Tx.binary_from_json( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json') ).should ==
|
108
|
+
fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin')
|
109
|
+
end
|
110
|
+
|
111
|
+
it '#verify_input_signature' do
|
112
|
+
# transaction-2 of block-170
|
113
|
+
tx = Tx.new( fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin') )
|
114
|
+
tx.hash.should == "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16"
|
115
|
+
|
116
|
+
# transaction-1 (coinbase) of block-9
|
117
|
+
outpoint_tx = Tx.new( fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin') )
|
118
|
+
outpoint_tx.hash.should == "0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"
|
119
|
+
|
120
|
+
tx.verify_input_signature(0, outpoint_tx).should == true
|
121
|
+
|
122
|
+
|
123
|
+
tx = Tx.from_json( fixtures_file('rawtx-c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73.json') )
|
124
|
+
tx.hash.should == 'c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73'
|
125
|
+
|
126
|
+
outpoint_tx = Tx.from_json( fixtures_file('rawtx-406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602.json') )
|
127
|
+
outpoint_tx.hash.should == '406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602'
|
128
|
+
|
129
|
+
tx.verify_input_signature(0, outpoint_tx).should == true
|
130
|
+
end
|
131
|
+
|
132
|
+
it '#sign_input_signature' do
|
133
|
+
prev_tx = Tx.new( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin') )
|
134
|
+
prev_tx.hash.should == "2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a"
|
135
|
+
|
136
|
+
key = Bitcoin.open_key("56e28a425a7b588973b5db962a09b1aca7bdc4a7268cdd671d03c52a997255dc",
|
137
|
+
pubkey="04324c6ebdcf079db6c9209a6b715b955622561262cde13a8a1df8ae0ef030eaa1552e31f8be90c385e27883a9d82780283d19507d7fa2e1e71a1d11bc3a52caf3")
|
138
|
+
new_tx = Tx.new(nil)
|
139
|
+
new_tx.add_in( TxIn.new(prev_tx.binary_hash, 0, 0) )
|
140
|
+
new_tx.add_out( TxOut.value_to_address(1000000, "1BVJWLTCtjA8wRivvrCiwjNdL6KjdMUCTZ") )
|
141
|
+
signature_hash = new_tx.signature_hash_for_input(0, prev_tx)
|
142
|
+
sig = Bitcoin.sign_data(key, signature_hash)
|
143
|
+
new_tx.in[0].script_sig = Bitcoin::Script.to_pubkey_script_sig(sig, [pubkey].pack("H*"))
|
144
|
+
|
145
|
+
new_tx = Tx.new( new_tx.to_payload )
|
146
|
+
new_tx.hash.should != nil
|
147
|
+
new_tx.verify_input_signature(0, prev_tx).should == true
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
prev_tx = Tx.new( fixtures_file('rawtx-14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984.bin') )
|
152
|
+
prev_tx.hash.should == "14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984"
|
153
|
+
|
154
|
+
key = Bitcoin.open_key("115ceda6c1e02d41ce65c35a30e82fb325fe3f815898a09e1a5d28bb1cc92c6e",
|
155
|
+
pubkey="0409d103127d26ce93ee41f1b9b1ed4c1c243acf48e31eb5c4d88ad0342ccc010a1a8d838846cf7337f2b44bc73986c0a3cb0568fa93d068b2c8296ce8d47b1545")
|
156
|
+
new_tx = Tx.new(nil)
|
157
|
+
new_tx.add_in( TxIn.new(prev_tx.binary_hash, 0, 0) )
|
158
|
+
pk_script = Bitcoin::Script.to_address_script("1FEYAh1x5jeKQMPPuv3bKnKvbgVAqXvqjW")
|
159
|
+
new_tx.add_out( TxOut.new(1000000, pk_script) )
|
160
|
+
signature_hash = new_tx.signature_hash_for_input(0, prev_tx)
|
161
|
+
sig = Bitcoin.sign_data(key, signature_hash)
|
162
|
+
new_tx.in[0].script_sig = Bitcoin::Script.to_pubkey_script_sig(sig, [pubkey].pack("H*"))
|
163
|
+
|
164
|
+
new_tx = Tx.new( new_tx.to_payload )
|
165
|
+
new_tx.hash.should != nil
|
166
|
+
new_tx.verify_input_signature(0, prev_tx).should == true
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
prev_tx = Tx.new( fixtures_file('rawtx-b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d.bin') )
|
171
|
+
prev_tx.hash.should == "b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d"
|
172
|
+
|
173
|
+
key = Bitcoin.open_key("56e28a425a7b588973b5db962a09b1aca7bdc4a7268cdd671d03c52a997255dc",
|
174
|
+
pubkey="04324c6ebdcf079db6c9209a6b715b955622561262cde13a8a1df8ae0ef030eaa1552e31f8be90c385e27883a9d82780283d19507d7fa2e1e71a1d11bc3a52caf3")
|
175
|
+
new_tx = Tx.new(nil)
|
176
|
+
new_tx.add_in( TxIn.new(prev_tx.binary_hash, 0, 0) )
|
177
|
+
new_tx.add_out( TxOut.value_to_address(1000000, "14yz7fob6Q16hZu4nXfmv1kRJpSYaFtet5") )
|
178
|
+
signature_hash = new_tx.signature_hash_for_input(0, prev_tx)
|
179
|
+
sig = Bitcoin.sign_data(key, signature_hash)
|
180
|
+
new_tx.in[0].script_sig = Bitcoin::Script.to_pubkey_script_sig(sig, [pubkey].pack("H*"))
|
181
|
+
|
182
|
+
new_tx = Tx.new( new_tx.to_payload )
|
183
|
+
new_tx.hash.should != nil
|
184
|
+
new_tx.verify_input_signature(0, prev_tx).should == true
|
185
|
+
|
186
|
+
#File.open("rawtx-#{new_tx.hash}.bin",'wb'){|f| f.print new_tx.to_payload }
|
187
|
+
prev_tx = Tx.new( fixtures_file('rawtx-52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2.bin') )
|
188
|
+
prev_tx.hash.should == "52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2"
|
189
|
+
#File.open("rawtx-#{prev_tx.hash}.json",'wb'){|f| f.print prev_tx.to_json }
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
describe "Tx - BIP Scripts" do
|
194
|
+
|
195
|
+
it "should do OP_CHECKHASHVERIFY (BIP_0017)" do # https://en.bitcoin.it/wiki/BIP_0017
|
196
|
+
# scriptSig: [signatures...] OP_CODESEPARATOR 1 [pubkey1] [pubkey2] 2 OP_CHECKMULTISIG
|
197
|
+
# scriptPubKey: [20-byte-hash of {1 [pubkey1] [pubkey2] 2 OP_CHECKMULTISIG} ] OP_CHECKHASHVERIFY OP_DROP
|
198
|
+
|
199
|
+
tx = Tx.from_json(fixtures_file('bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba.json'))
|
200
|
+
tx.hash.should == "bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba"
|
201
|
+
|
202
|
+
prev_tx1 = Tx.from_json(fixtures_file('477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json'))
|
203
|
+
prev_tx1.hash.should == "477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590"
|
204
|
+
|
205
|
+
prev_tx2 = Tx.from_json(fixtures_file('0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json'))
|
206
|
+
prev_tx2.hash.should == "0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd"
|
207
|
+
|
208
|
+
tx.verify_input_signature(0, prev_tx1).should == true
|
209
|
+
tx.verify_input_signature(1, prev_tx2).should == true
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should do OP_CHECKMULTISIG" do
|
213
|
+
# checkmultisig without checkhashverify
|
214
|
+
tx = Tx.from_json(fixtures_file('23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63.json'))
|
215
|
+
prev_tx = Tx.from_json(fixtures_file('60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1.json'))
|
216
|
+
tx.verify_input_signature(0, prev_tx).should == true
|
217
|
+
|
218
|
+
# p2sh + multisig transaction from mainnet
|
219
|
+
tx = Tx.from_json( fixtures_file('rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json') )
|
220
|
+
prev_tx = Tx.from_json( fixtures_file("rawtx-de35d060663750b3975b7997bde7fb76307cec5b270d12fcd9c4ad98b279c28c.json") )
|
221
|
+
tx.verify_input_signature(0, prev_tx).should == true
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|