bitcoin-ruby 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +2 -7
- data/COPYING +1 -1
- data/Gemfile +2 -6
- data/Gemfile.lock +34 -0
- data/README.rdoc +16 -68
- data/Rakefile +3 -6
- data/bin/bitcoin_shell +0 -1
- data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
- data/lib/bitcoin.rb +350 -296
- data/lib/bitcoin/builder.rb +3 -1
- data/lib/bitcoin/connection.rb +2 -1
- data/lib/bitcoin/contracthash.rb +76 -0
- data/lib/bitcoin/dogecoin.rb +97 -0
- data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
- data/lib/bitcoin/ffi/openssl.rb +98 -2
- data/lib/bitcoin/ffi/secp256k1.rb +144 -0
- data/lib/bitcoin/key.rb +12 -2
- data/lib/bitcoin/logger.rb +3 -12
- data/lib/bitcoin/protocol/block.rb +3 -9
- data/lib/bitcoin/protocol/parser.rb +6 -2
- data/lib/bitcoin/protocol/tx.rb +44 -13
- data/lib/bitcoin/protocol/txin.rb +4 -2
- data/lib/bitcoin/protocol/txout.rb +2 -2
- data/lib/bitcoin/script.rb +212 -37
- data/lib/bitcoin/trezor/mnemonic.rb +130 -0
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bitcoin_spec.rb +32 -3
- data/spec/bitcoin/builder_spec.rb +18 -0
- data/spec/bitcoin/contracthash_spec.rb +45 -0
- data/spec/bitcoin/dogecoin_spec.rb +176 -0
- data/spec/bitcoin/ffi_openssl.rb +45 -0
- data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
- data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
- data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
- data/spec/bitcoin/fixtures/coinbase.json +24 -0
- data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
- data/spec/bitcoin/protocol/block_spec.rb +0 -22
- data/spec/bitcoin/protocol/tx_spec.rb +145 -2
- data/spec/bitcoin/script/script_spec.rb +282 -0
- data/spec/bitcoin/secp256k1_spec.rb +48 -0
- data/spec/bitcoin/spec_helper.rb +0 -51
- data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
- metadata +48 -98
- data/bin/bitcoin_dns_seed +0 -130
- data/bin/bitcoin_gui +0 -80
- data/bin/bitcoin_node +0 -153
- data/bin/bitcoin_node_cli +0 -81
- data/bin/bitcoin_wallet +0 -402
- data/doc/CONFIG.rdoc +0 -66
- data/doc/EXAMPLES.rdoc +0 -13
- data/doc/NAMECOIN.rdoc +0 -34
- data/doc/NODE.rdoc +0 -225
- data/doc/STORAGE.rdoc +0 -33
- data/doc/WALLET.rdoc +0 -102
- data/examples/balance.rb +0 -66
- data/examples/forwarder.rb +0 -73
- data/examples/index_nhash.rb +0 -24
- data/examples/reindex_p2sh_addrs.rb +0 -44
- data/examples/relay_tx.rb +0 -22
- data/examples/verify_tx.rb +0 -57
- data/lib/bitcoin/config.rb +0 -58
- data/lib/bitcoin/gui/addr_view.rb +0 -44
- data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
- data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
- data/lib/bitcoin/gui/conn_view.rb +0 -38
- data/lib/bitcoin/gui/connection.rb +0 -70
- data/lib/bitcoin/gui/em_gtk.rb +0 -30
- data/lib/bitcoin/gui/gui.builder +0 -1643
- data/lib/bitcoin/gui/gui.rb +0 -292
- data/lib/bitcoin/gui/helpers.rb +0 -115
- data/lib/bitcoin/gui/tree_view.rb +0 -84
- data/lib/bitcoin/gui/tx_view.rb +0 -69
- data/lib/bitcoin/namecoin.rb +0 -280
- data/lib/bitcoin/network/command_client.rb +0 -104
- data/lib/bitcoin/network/command_handler.rb +0 -570
- data/lib/bitcoin/network/connection_handler.rb +0 -387
- data/lib/bitcoin/network/node.rb +0 -565
- data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
- data/lib/bitcoin/storage/models.rb +0 -171
- data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
- data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
- data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
- data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
- data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
- data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
- data/lib/bitcoin/storage/storage.rb +0 -517
- data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
- data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
- data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
- data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
- data/lib/bitcoin/validation.rb +0 -400
- data/lib/bitcoin/wallet/coinselector.rb +0 -33
- data/lib/bitcoin/wallet/keygenerator.rb +0 -77
- data/lib/bitcoin/wallet/keystore.rb +0 -207
- data/lib/bitcoin/wallet/txdp.rb +0 -118
- data/lib/bitcoin/wallet/wallet.rb +0 -281
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
- data/spec/bitcoin/namecoin_spec.rb +0 -182
- data/spec/bitcoin/node/command_api_spec.rb +0 -663
- data/spec/bitcoin/storage/models_spec.rb +0 -104
- data/spec/bitcoin/storage/reorg_spec.rb +0 -236
- data/spec/bitcoin/storage/storage_spec.rb +0 -387
- data/spec/bitcoin/storage/validation_spec.rb +0 -300
- data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
- data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
- data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
- data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
- data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require_relative 'spec_helper.rb'
|
4
|
+
require 'bitcoin'
|
5
|
+
|
6
|
+
|
7
|
+
describe 'Bitcoin FFI OpenSSL Helpers' do
|
8
|
+
it 'should convert high-S DER signatures to low-S equivalents' do
|
9
|
+
Bitcoin.network = 'testnet'
|
10
|
+
|
11
|
+
tx_in = Bitcoin::Protocol::Tx.new( fixtures_file('rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin') )
|
12
|
+
tx_out = Bitcoin::Protocol::Tx.new( fixtures_file('rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin') )
|
13
|
+
original_hash = tx_out.hash
|
14
|
+
tx_out.verify_input_signature(0, tx_in).should == true
|
15
|
+
script_sig = Bitcoin::Script.new(tx_out.in[0].script_sig)
|
16
|
+
sig = script_sig.chunks[0]
|
17
|
+
pubkey = script_sig.chunks[1]
|
18
|
+
Bitcoin::Script::is_low_der_signature?(sig).should == false
|
19
|
+
|
20
|
+
sig = Bitcoin::OpenSSL_EC.signature_to_low_s(sig)
|
21
|
+
Bitcoin::Script::is_low_der_signature?(sig).should == true
|
22
|
+
|
23
|
+
tx_out.in[0].script_sig = Bitcoin::Script.to_signature_pubkey_script(sig, pubkey)
|
24
|
+
tx_out.verify_input_signature(0, tx_in).should == true
|
25
|
+
|
26
|
+
# Repack the transaction to force hash update
|
27
|
+
tx_out = Bitcoin::Protocol::Tx.new( tx_out.to_payload )
|
28
|
+
original_hash.should != tx_out.hash
|
29
|
+
|
30
|
+
Bitcoin.network = 'bitcoin'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'Bitcoin::OpenSSL_EC.repack_der_signature' do
|
34
|
+
s = "304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"
|
35
|
+
ns = Bitcoin::OpenSSL_EC.repack_der_signature([s].pack("H*")).unpack("H*")[0]
|
36
|
+
ns.should == s
|
37
|
+
|
38
|
+
[
|
39
|
+
"304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860",
|
40
|
+
"304402204e45e16932",
|
41
|
+
"304402204",
|
42
|
+
"3044",
|
43
|
+
].all?{|s| Bitcoin::OpenSSL_EC.repack_der_signature([s].pack("H*")) == false }.should == true
|
44
|
+
end
|
45
|
+
end
|
data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"hash": "156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a",
|
3
|
+
"ver": 1,
|
4
|
+
"vin_sz": 1,
|
5
|
+
"vout_sz": 1,
|
6
|
+
"lock_time": 0,
|
7
|
+
"size": 209,
|
8
|
+
"in": [
|
9
|
+
{
|
10
|
+
"prev_out": {
|
11
|
+
"hash": "8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c",
|
12
|
+
"n": 0
|
13
|
+
},
|
14
|
+
"scriptSig": "4b4f2a0ae06225be0790dc295d651360 3045022039b01bb4a34f2758bf542b4a372660c598e0ade4fac8dc0b4e5503aa09bcf7dd02210086d07d2ad014834fe57734ff5272e470687bb0f921b0b304307a3e726074bae801 0314d45f33e01a0feaf065cd7ef3050c941bc16e90534b0b5f50860da9930bee00"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"out": [
|
18
|
+
{
|
19
|
+
"value": "0.00010000",
|
20
|
+
"scriptPubKey": "OP_DUP OP_HASH160 85eb47fe98f349065d6f044e27a4ac541af79ee2 OP_EQUALVERIFY OP_CHECKSIG"
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"nid": "42f84e00c7450f066085574529e3420b86cb79be98b84590fb56676dd579df5d"
|
24
|
+
}
|
data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"hash": "8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c",
|
3
|
+
"ver": 1,
|
4
|
+
"vin_sz": 1,
|
5
|
+
"vout_sz": 1,
|
6
|
+
"lock_time": 0,
|
7
|
+
"size": 327,
|
8
|
+
"in": [
|
9
|
+
{
|
10
|
+
"prev_out": {
|
11
|
+
"hash": "cd279a4bb51d61e7ad9482fed6e5dc042babf3b9ec754245b44d6ffa62f08c7c",
|
12
|
+
"n": 1
|
13
|
+
},
|
14
|
+
"scriptSig": "0 3045022100f45a6fd9c99594d66223af3ba8c93beffadd3a41369e56692893ae1fd36d57a302201584848a46c22f7ab1ac718286aa1492a3d77e4f3827e7256ffff99d6846bd2301 304502203e78dda25f19e38cf5fd03f4c2ef5fd743569563972ebad9d77979d35d96652b022100873d842c4d307999b2ece5069e9bc64117c100200773cf6fa048a67bd9a51ec101 2 2102e5bbbce26a2a35bbeee2adbb7237efabd2228809dc27815611c480b4c4037ac4210314d45f33e01a0feaf065cd7ef3050c941bc16e90534b0b5f50860da9930bee0052ae"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"out": [
|
18
|
+
{
|
19
|
+
"value": "0.00010000",
|
20
|
+
"scriptPubKey": "OP_DUP OP_HASH160 b689ebc262f50297139e7d16c4f8909e14ed4322 OP_EQUALVERIFY OP_CHECKSIGVERIFY OP_HASH160 1b6246121883816fc0637e4aa280aca1df219b1a OP_EQUAL"
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"nid": "6db404bcf4a44b5982d74d07250c4a052598abadcd52d789ff20f9de01fe7f9d"
|
24
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"hash":"6d7e160109d3d6bdfadfeb7f2a041d57dd6c910e0798554b495f2963c1b0c787",
|
3
|
+
"version":1,
|
4
|
+
"lock_time":0,
|
5
|
+
"size":177,
|
6
|
+
"inputs":[
|
7
|
+
{
|
8
|
+
"previous_transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000",
|
9
|
+
"output_index":4294967295,
|
10
|
+
"amount":2500000000,
|
11
|
+
"coinbase":"03c4ed04e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6da1f05b26289f973240ae74a5768b942e93b459a7af0e01f99c9868492e543ebb1000000000000000ea8f12dcc51201004d696e6564206279206368656e6775616e67667531"
|
12
|
+
}
|
13
|
+
],
|
14
|
+
"outputs":[
|
15
|
+
{
|
16
|
+
"amount":2502773013,
|
17
|
+
"spent":false,
|
18
|
+
"script":"OP_DUP OP_HASH160 c825a1ecf2a6830c4401620c3a16f1995057c2ab OP_EQUALVERIFY OP_CHECKSIG",
|
19
|
+
"script_hex":"76a914c825a1ecf2a6830c4401620c3a16f1995057c2ab88ac",
|
20
|
+
"script_type":"hash160",
|
21
|
+
"addresses":[
|
22
|
+
"1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY"
|
23
|
+
]
|
24
|
+
}
|
25
|
+
],
|
26
|
+
"amount":2502773013,
|
27
|
+
"fees":0,
|
28
|
+
"confirmations":19,
|
29
|
+
"block_height":323012,
|
30
|
+
"block_hash":"000000000000000019b16f4a6cd8717ab8f4836bbc9822894cc49785badfdaa7",
|
31
|
+
"block_time":"2014-09-29T04:24:35Z",
|
32
|
+
"block_branch":"main"
|
33
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"hash": "6d7e160109d3d6bdfadfeb7f2a041d57dd6c910e0798554b495f2963c1b0c787",
|
3
|
+
"ver": 1,
|
4
|
+
"vin_sz": 1,
|
5
|
+
"vout_sz": 1,
|
6
|
+
"lock_time": 0,
|
7
|
+
"size": 177,
|
8
|
+
"in": [
|
9
|
+
{
|
10
|
+
"prev_out": {
|
11
|
+
"hash": "0000000000000000000000000000000000000000000000000000000000000000",
|
12
|
+
"n": 4294967295
|
13
|
+
},
|
14
|
+
"coinbase": "03c4ed04e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6da1f05b26289f973240ae74a5768b942e93b459a7af0e01f99c9868492e543ebb1000000000000000ea8f12dcc51201004d696e6564206279206368656e6775616e67667531"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"out": [
|
18
|
+
{
|
19
|
+
"value": "25.02773013",
|
20
|
+
"scriptPubKey": "OP_DUP OP_HASH160 c825a1ecf2a6830c4401620c3a16f1995057c2ab OP_EQUALVERIFY OP_CHECKSIG"
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"nid": "c1935bec4c6363aa7f727bfbeacbac4a87766ffe6f352a6b3f8c0c4600dde75f"
|
24
|
+
}
|
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"hash":"6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4",
|
3
|
+
"version":1,
|
4
|
+
"lock_time":0,
|
5
|
+
"size":258,
|
6
|
+
"inputs":[
|
7
|
+
{
|
8
|
+
"previous_transaction_hash":"c866fc2aea0e36ce632886f26a66487ba751762d0f085763d01efc438336f6b0",
|
9
|
+
"output_index":0,
|
10
|
+
"amount":29000000,
|
11
|
+
"script":"3045022100bde2e702380813d61069845a75e330779bbacc6a1330bd9dfd1fec1bd94f8f17022075c29d9b37957c80068436609755942be0f7f6fbd30983a557a6e0640edeeb1601 049de89dd4f0b3801c2d28a334f0fb8b0bfd7a9d67530e9dffa536bd7130e8dfd32a01e7bafcdd956fdeece0f341fa4f2727890bf09fe0dd1dea9169aad9c30242",
|
12
|
+
"addresses":[
|
13
|
+
"1PiiBch7CrLgYscAeTrUhHq1TvaCZxyhwo"
|
14
|
+
]
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"outputs":[
|
18
|
+
{
|
19
|
+
"amount":24956381,
|
20
|
+
"spent":true,
|
21
|
+
"script":"OP_DUP OP_HASH160 b2e21c1db922e3bdc529de7b38b4c401399e9afd OP_EQUALVERIFY OP_CHECKSIG",
|
22
|
+
"script_hex":"76a914b2e21c1db922e3bdc529de7b38b4c401399e9afd88ac",
|
23
|
+
"script_type":"hash160",
|
24
|
+
"addresses":[
|
25
|
+
"1HJr9Xs4dGdLxCxmYpDnHb1WbkaNw3EezN"
|
26
|
+
]
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"amount":3993619,
|
30
|
+
"spent":true,
|
31
|
+
"script":"OP_DUP OP_HASH160 7766347a890638dc3cd8d4ef99b8e40c6519d11e OP_EQUALVERIFY OP_CHECKSIG",
|
32
|
+
"script_hex":"76a9147766347a890638dc3cd8d4ef99b8e40c6519d11e88ac",
|
33
|
+
"script_type":"hash160",
|
34
|
+
"addresses":[
|
35
|
+
"1BtKrA1bUBn9na7BQK8npBYbMXuMAfxszK"
|
36
|
+
]
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"amount":28950000,
|
40
|
+
"fees":50000,
|
41
|
+
"confirmations":197382,
|
42
|
+
"block_height":125539,
|
43
|
+
"block_hash":"0000000000002f9e18114d2a56714e1a1fdb58525857fc0b5460e51da682ac2b",
|
44
|
+
"block_time":"2011-05-21T15:45:32Z",
|
45
|
+
"block_branch":"main"
|
46
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"hash":"e6d0a1bc0355e4208c606cb3ae1f047875c13f966c6c861a154e2fe61a4132a5",
|
3
|
+
"version":1,
|
4
|
+
"lock_time":0,
|
5
|
+
"size":258,
|
6
|
+
"inputs":[
|
7
|
+
{
|
8
|
+
"previous_transaction_hash":"0abe13b3a6e01b12ec7abc592328d5edd5e9029d7d9ee9cd1440382812953ee1",
|
9
|
+
"output_index":0,
|
10
|
+
"amount":12814000000,
|
11
|
+
"script":"304502207442f42bb0c64f948df0711ae61e8612a011d83e755507d73c8cf6b1ae71fcd5022100a61a91f426a20db8778e35d14792f64daa0e8edf2acd5a9329adc25e0074a2cf01 045833aa1677dc0f5bd773b835622d53b4d31bc194577290a48897fb157e6af925bec9ce0dad4fc9e613d9d4661d78c111b02f219ca446e0c101b730d1234c4978",
|
12
|
+
"addresses":[
|
13
|
+
"14nvWuw7VpLdwtDdv2HATBSH8vEgD1snd3"
|
14
|
+
]
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"outputs":[
|
18
|
+
{
|
19
|
+
"amount":12781000000,
|
20
|
+
"spent":true,
|
21
|
+
"script":"OP_DUP OP_HASH160 7bc2e19b0afd1c78ec792bbad334d41db2da8845 OP_EQUALVERIFY OP_CHECKSIG",
|
22
|
+
"script_hex":"76a9147bc2e19b0afd1c78ec792bbad334d41db2da884588ac",
|
23
|
+
"script_type":"hash160",
|
24
|
+
"addresses":[
|
25
|
+
"1CHPaBddn5zyZy7Ac1HmqisGkBd6cDAsRy"
|
26
|
+
]
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"amount":33000000,
|
30
|
+
"spent":true,
|
31
|
+
"script":"OP_DUP OP_HASH160 ffad3e6ddcfdb412953d41887a21e9ff9805a93c OP_EQUALVERIFY OP_CHECKSIG",
|
32
|
+
"script_hex":"76a914ffad3e6ddcfdb412953d41887a21e9ff9805a93c88ac",
|
33
|
+
"script_type":"hash160",
|
34
|
+
"addresses":[
|
35
|
+
"1QJtr7TuNdPKW9t5Q2a4ByStS4Hk5n5obX"
|
36
|
+
]
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"amount":12814000000,
|
40
|
+
"fees":0,
|
41
|
+
"confirmations":197378,
|
42
|
+
"block_height":125543,
|
43
|
+
"block_hash":"0000000000003949c5390a26b2c76b6c6d819dfd18afe1623fcd5b7ce2c4b99d",
|
44
|
+
"block_time":"2011-05-21T16:09:47Z",
|
45
|
+
"block_branch":"main"
|
46
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
{
|
2
|
+
"hash":"56577828eace17d718e538d51f3122bc7193bf37879b8a9d6638c4c5101159bc",
|
3
|
+
"version":1,
|
4
|
+
"lock_time":0,
|
5
|
+
"size":798,
|
6
|
+
"inputs":[
|
7
|
+
{
|
8
|
+
"previous_transaction_hash":"1f130699a1eb657f4eb051865ef4399dcaf8a34d5bbff879107829e687acf865",
|
9
|
+
"output_index":0,
|
10
|
+
"amount":61000000,
|
11
|
+
"script":"3045022100fd9d06ec1b74060a6e85e2ff614d4cf01c41a30debd86ac669ee5370b038a29302204ce4595ea7658ba2a1487aa784ed7543d0b394b0393d732a3ea4f247ffd7f49301 04974deddf7b6dbfdbe6799f58b4460b0f80e609d52d5ab13c398b8456c8dd9ea29fc6702a69edfe76bd2b7e7361e0a81523cba342133ed0e270b2d38e51429a33",
|
12
|
+
"addresses":[
|
13
|
+
"1AQbAurg1xxWr7Devd6rLTpDUutd49XkU2"
|
14
|
+
]
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"previous_transaction_hash":"d9fe5ba4752e3b7dd1c0fceaaa3124c73eef34d8dc2a0bf8e6dc6e9413556f84",
|
18
|
+
"output_index":0,
|
19
|
+
"amount":9000000,
|
20
|
+
"script":"304502210096782e8d62ec98f14b51639a0aa04588f847ea124d9709d2e48ec649d562ed0602203d5a6fec66af2518960bdbaf556d10732882ad9563d8ec38c22a1668306a5acf01 04b65a4e775c8d55676ddd25f97236c6b452b5ab986e2ed7562db453ebce7c95badfb890e0da2653747a21b463c63eb8ba6ab9ff9ce268a3600c1b906d5e295695",
|
21
|
+
"addresses":[
|
22
|
+
"18qL22NhdTywF91oVX1SeNq933x9bngeT2"
|
23
|
+
]
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"previous_transaction_hash":"d634f4d77f0f407077e6b11168c33d7d17c18d8c962dcc14b5ca2fc4a4e1efcf",
|
27
|
+
"output_index":0,
|
28
|
+
"amount":15000000,
|
29
|
+
"script":"3044022025c899f50e42b79a258d10a941e61529d4ad1e1d5dfd891ee243a186fbbbf81f02201a4aaa633245f29fbeab365151c3f9cdfcdc374b5077aa5ee32249e3c60071a201 04b8778189c915eb353393f9fbb01c3b50a263fa69f64f5e30d786bba3b79396b6646683c1a52dd5be120d5a3b6bdb87875e8a9634d980b0d8b30b70913b403a58",
|
30
|
+
"addresses":[
|
31
|
+
"13XwYPMxKa7GykVfD9nxEBJGqVBxRfojdF"
|
32
|
+
]
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"previous_transaction_hash":"175dfd12170980b391b66822b5a699ed18d24d572b719429026d42168801024e",
|
36
|
+
"output_index":24,
|
37
|
+
"amount":117000000,
|
38
|
+
"script":"3046022100909ef47b3138490e129d932eedc3de6ddf67c58bd0a54d75e915b31b793c83080221008bfa4b84c932380be3561fd4d4dcd68dbf00b8b40aa605630702cbfee1a440c701 0483c5d3b9eb6a4b6f1812ede42f7d86726f9aa0bbb1a25d7604bbc632c093b0d47a23263252ffbbd2995ca1da2fbbb6c642eaaa75eae26310b20aec04493afa1a",
|
39
|
+
"addresses":[
|
40
|
+
"171wMNEqsWK9GCi9ATZCo9w2dBcyXDThpb"
|
41
|
+
]
|
42
|
+
}
|
43
|
+
],
|
44
|
+
"outputs":[
|
45
|
+
{
|
46
|
+
"amount":1000000,
|
47
|
+
"spent":true,
|
48
|
+
"script":"OP_DUP OP_HASH160 3129d7051d509424d23d533fa2d5258977e822e3 OP_EQUALVERIFY OP_CHECKSIG",
|
49
|
+
"script_hex":"76a9143129d7051d509424d23d533fa2d5258977e822e388ac",
|
50
|
+
"script_type":"hash160",
|
51
|
+
"addresses":[
|
52
|
+
"15UxEVL3rmBLctJY4r6rpATrpZ9STBM1dg"
|
53
|
+
]
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"amount":200000000,
|
57
|
+
"spent":true,
|
58
|
+
"script":"OP_DUP OP_HASH160 f3de26ff7d472d5365e3adafece9bbdcace915a0 OP_EQUALVERIFY OP_CHECKSIG",
|
59
|
+
"script_hex":"76a914f3de26ff7d472d5365e3adafece9bbdcace915a088ac",
|
60
|
+
"script_type":"hash160",
|
61
|
+
"addresses":[
|
62
|
+
"1PETL2itvQxneQguBjBLGBmjHhMprtQHNZ"
|
63
|
+
]
|
64
|
+
}
|
65
|
+
],
|
66
|
+
"amount":201000000,
|
67
|
+
"fees":1000000,
|
68
|
+
"confirmations":197381,
|
69
|
+
"block_height":125540,
|
70
|
+
"block_hash":"00000000000015ba72d71f8c7aebfcac65a689adce10d86c11e786e96edefd40",
|
71
|
+
"block_time":"2011-05-21T16:02:46Z",
|
72
|
+
"block_branch":"main"
|
73
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -116,28 +116,6 @@ describe 'Bitcoin::Protocol::Block' do
|
|
116
116
|
Bitcoin.network = :bitcoin
|
117
117
|
end
|
118
118
|
|
119
|
-
it "should work with freicoin blocks" do
|
120
|
-
Bitcoin.network = :freicoin # change to freicoin
|
121
|
-
freicoin_block = "freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c"
|
122
|
-
Block.from_json(fixtures_file(freicoin_block + '.json'))
|
123
|
-
.to_payload.should == fixtures_file(freicoin_block + '.bin')
|
124
|
-
|
125
|
-
json = Block.new(fixtures_file(freicoin_block + '.bin')).to_json
|
126
|
-
Block.from_json(json)
|
127
|
-
.to_payload.should == fixtures_file(freicoin_block + '.bin')
|
128
|
-
Block.from_json(json).hash == freicoin_block.split("-").last
|
129
|
-
|
130
|
-
freicoin_block = "freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c"
|
131
|
-
Block.from_json(fixtures_file(freicoin_block + '.json'))
|
132
|
-
.to_payload.should == fixtures_file(freicoin_block + '.bin')
|
133
|
-
|
134
|
-
json = Block.new(fixtures_file(freicoin_block + '.bin')).to_json
|
135
|
-
Block.from_json(json)
|
136
|
-
.to_payload.should == fixtures_file(freicoin_block + '.bin')
|
137
|
-
Block.from_json(json).hash == freicoin_block.split("-").last
|
138
|
-
Bitcoin.network = :bitcoin
|
139
|
-
end
|
140
|
-
|
141
119
|
it 'should check block hash' do
|
142
120
|
block = Block.from_json(fixtures_file('rawblock-0.json'))
|
143
121
|
h = block.to_hash
|
@@ -52,7 +52,7 @@ describe 'Tx' do
|
|
52
52
|
it '#normalized_hash' do
|
53
53
|
tx = Tx.new( @payload[0] )
|
54
54
|
tx.normalized_hash.size.should == 64
|
55
|
-
tx.normalized_hash.should == "
|
55
|
+
tx.normalized_hash.should == "393a12b91d5b5e2449f2d27a22ffc0af937c3796a08c8213cc37690b10302e40"
|
56
56
|
|
57
57
|
new_tx = JSON.parse(tx.to_json)
|
58
58
|
script = Bitcoin::Script.from_string(new_tx['in'][0]['scriptSig'])
|
@@ -63,7 +63,7 @@ describe 'Tx' do
|
|
63
63
|
|
64
64
|
new_tx.hash.should != tx.hash
|
65
65
|
new_tx.normalized_hash.size.should == 64
|
66
|
-
new_tx.normalized_hash.should == "
|
66
|
+
new_tx.normalized_hash.should == "393a12b91d5b5e2449f2d27a22ffc0af937c3796a08c8213cc37690b10302e40"
|
67
67
|
end
|
68
68
|
|
69
69
|
it '#to_payload' do
|
@@ -124,12 +124,124 @@ describe 'Tx' do
|
|
124
124
|
# coinbase tx with non-default sequence
|
125
125
|
tx = Tx.from_json( json=fixtures_file('0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json'))
|
126
126
|
Tx.new( tx.to_payload ).to_json.should == json
|
127
|
+
|
128
|
+
# toshi format
|
129
|
+
Tx.from_json(fixtures_file('rawtx-02-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('rawtx-02.json')).to_payload
|
130
|
+
Tx.from_json(fixtures_file('rawtx-03-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('rawtx-03.json')).to_payload
|
131
|
+
Tx.from_json(fixtures_file('coinbase-toshi.json')).to_payload.should == Tx.from_json(fixtures_file('coinbase.json')).to_payload
|
127
132
|
end
|
128
133
|
|
129
134
|
it 'Tx.binary_from_json' do
|
130
135
|
Tx.binary_from_json( fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json') ).should ==
|
131
136
|
fixtures_file('rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin')
|
132
137
|
end
|
138
|
+
|
139
|
+
it 'compares arrays of bytes' do
|
140
|
+
# This function is used in validating an ECDSA signature's S value
|
141
|
+
c1 = []
|
142
|
+
c2 = []
|
143
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 0
|
144
|
+
|
145
|
+
c1 = [0]
|
146
|
+
c2 = []
|
147
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 0
|
148
|
+
|
149
|
+
c1 = []
|
150
|
+
c2 = [0]
|
151
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 0
|
152
|
+
|
153
|
+
c1 = [5]
|
154
|
+
c2 = [5]
|
155
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 0
|
156
|
+
|
157
|
+
c1 = [04]
|
158
|
+
c2 = [5]
|
159
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == -1
|
160
|
+
|
161
|
+
c1 = [4]
|
162
|
+
c2 = [05]
|
163
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == -1
|
164
|
+
|
165
|
+
c1 = [5]
|
166
|
+
c2 = [4]
|
167
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 1
|
168
|
+
|
169
|
+
c1 = [05]
|
170
|
+
c2 = [004]
|
171
|
+
Bitcoin::Script::compare_big_endian(c1, c2).should == 1
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'validates ECDSA signature format' do
|
176
|
+
# TX 3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae
|
177
|
+
sig_orig = ["304502210088984573e3e4f33db7df6aea313f1ce67a3ef3532ea89991494c7f018258371802206ceefc9291450dbd40d834f249658e0f64662d52a41cf14e20c9781144f2fe0701"].pack("H*")
|
178
|
+
Bitcoin::Script::is_der_signature?(sig_orig).should == true
|
179
|
+
Bitcoin::Script::is_defined_hashtype_signature?(sig_orig).should == true
|
180
|
+
|
181
|
+
# Trimmed to be too short
|
182
|
+
sig = sig_orig.slice(0, 8)
|
183
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
184
|
+
|
185
|
+
# Zero-padded to be too long
|
186
|
+
sig = String.new(sig_orig)
|
187
|
+
sig << 0x00
|
188
|
+
sig << 0x00
|
189
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
190
|
+
|
191
|
+
# Wrong first byte
|
192
|
+
sig_bytes = sig_orig.unpack("C*")
|
193
|
+
sig_bytes[0] = 0x20
|
194
|
+
sig = sig_bytes.pack("C*")
|
195
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
196
|
+
|
197
|
+
# Length byte broken
|
198
|
+
sig_bytes = sig_orig.unpack("C*")
|
199
|
+
sig_bytes[1] = 0x20
|
200
|
+
sig = sig_bytes.pack("C*")
|
201
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
202
|
+
|
203
|
+
# Incorrect R value type
|
204
|
+
sig_bytes = sig_orig.unpack("C*")
|
205
|
+
sig_bytes[2] = 0x03
|
206
|
+
sig = sig_bytes.pack("C*")
|
207
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
208
|
+
|
209
|
+
# R value length infeasibly long
|
210
|
+
sig_bytes = sig_orig.unpack("C*")
|
211
|
+
sig_bytes[3] = sig_orig.size - 4
|
212
|
+
sig = sig_bytes.pack("C*")
|
213
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
214
|
+
|
215
|
+
# Negative R value
|
216
|
+
sig_bytes = sig_orig.unpack("C*")
|
217
|
+
sig_bytes[4] = 0x80 | sig_bytes[4]
|
218
|
+
sig = sig_bytes.pack("C*")
|
219
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
220
|
+
|
221
|
+
# R value excessively padded
|
222
|
+
sig_bytes = sig_orig.unpack("C*")
|
223
|
+
sig_bytes[5] = 0x00
|
224
|
+
sig = sig_bytes.pack("C*")
|
225
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
226
|
+
|
227
|
+
# Incorrect S value type
|
228
|
+
sig_bytes = sig_orig.unpack("C*")
|
229
|
+
sig_bytes[37] = 0x03
|
230
|
+
sig = sig_bytes.pack("C*")
|
231
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
232
|
+
|
233
|
+
# Zero S length
|
234
|
+
sig_bytes = sig_orig.unpack("C*")
|
235
|
+
sig_bytes[38] = 0x00
|
236
|
+
sig = sig_bytes.pack("C*")
|
237
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
238
|
+
|
239
|
+
# Negative S value
|
240
|
+
sig_bytes = sig_orig.unpack("C*")
|
241
|
+
sig_bytes[39] = 0x80 | sig_bytes[39]
|
242
|
+
sig = sig_bytes.pack("C*")
|
243
|
+
Bitcoin::Script::is_der_signature?(sig).should == false
|
244
|
+
end
|
133
245
|
|
134
246
|
it '#verify_input_signature' do
|
135
247
|
# transaction-2 of block-170
|
@@ -247,6 +359,37 @@ describe 'Tx' do
|
|
247
359
|
tx.in.each.with_index{|i,idx|
|
248
360
|
tx.verify_input_signature(idx, prev_txs[i.previous_output]).should == true
|
249
361
|
}
|
362
|
+
|
363
|
+
# BIP62 rule #2 - spend transaction has operations in its signature
|
364
|
+
tx = Tx.new( fixtures_file('rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin') )
|
365
|
+
tx.hash.should == "3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e"
|
366
|
+
outpoint_tx = Tx.new( fixtures_file('rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin') )
|
367
|
+
outpoint_tx.hash.should == "04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4"
|
368
|
+
tx.verify_input_signature(0, outpoint_tx, Time.now.to_i).should == true
|
369
|
+
tx.verify_input_signature(0, outpoint_tx, Time.now.to_i, verify_sigpushonly: true).should == false
|
370
|
+
|
371
|
+
# BIP62 rule #6 - spend transaction has an unused "0" on the signature stack
|
372
|
+
tx = Tx.new( fixtures_file('rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin') )
|
373
|
+
tx.hash.should == "0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f"
|
374
|
+
outpoint_tx = Tx.new( fixtures_file('rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin') )
|
375
|
+
outpoint_tx.hash.should == "f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5"
|
376
|
+
tx.verify_input_signature(0, outpoint_tx, Time.now.to_i).should == true
|
377
|
+
tx.verify_input_signature(0, outpoint_tx, Time.now.to_i, verify_cleanstack: true).should == false
|
378
|
+
|
379
|
+
# Ensure BIP62 is applied to P2SH scripts
|
380
|
+
tx = Bitcoin::P::Tx.from_json(fixtures_file('7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json'))
|
381
|
+
tx.hash.should == "7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d"
|
382
|
+
outpoint_tx = Bitcoin::P::Tx.from_json(fixtures_file('3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json'))
|
383
|
+
outpoint_tx.hash.should == "3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477"
|
384
|
+
tx.verify_input_signature(0, outpoint_tx).should == true
|
385
|
+
tx.verify_input_signature(0, outpoint_tx, Time.now.to_i, verify_low_s: true).should == false
|
386
|
+
|
387
|
+
# testnet3 P2SH check
|
388
|
+
tx = Bitcoin::P::Tx.from_json(fixtures_file('156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json'))
|
389
|
+
tx.hash.should == "156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a"
|
390
|
+
outpoint_tx = Bitcoin::P::Tx.from_json(fixtures_file('8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json'))
|
391
|
+
outpoint_tx.hash.should == "8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c"
|
392
|
+
tx.verify_input_signature(0, outpoint_tx).should == true
|
250
393
|
end
|
251
394
|
|
252
395
|
it '#sign_input_signature' do
|