bitcoin-ruby 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. data/.gitignore +4 -1
  2. data/Gemfile +21 -0
  3. data/README.rdoc +85 -25
  4. data/Rakefile +7 -3
  5. data/bin/bitcoin_node +39 -42
  6. data/bin/bitcoin_shell +1 -0
  7. data/bin/bitcoin_wallet +129 -53
  8. data/bitcoin-ruby.gemspec +4 -7
  9. data/concept-examples/blockchain-pow.rb +1 -1
  10. data/doc/CONFIG.rdoc +5 -5
  11. data/doc/EXAMPLES.rdoc +9 -5
  12. data/doc/NAMECOIN.rdoc +34 -0
  13. data/doc/NODE.rdoc +147 -10
  14. data/examples/balance.rb +10 -4
  15. data/examples/bbe_verify_tx.rb +7 -2
  16. data/examples/forwarder.rb +73 -0
  17. data/examples/generate_tx.rb +34 -0
  18. data/examples/simple_network_monitor_and_util.rb +187 -0
  19. data/examples/verify_tx.rb +1 -1
  20. data/lib/bitcoin.rb +308 -18
  21. data/lib/bitcoin/builder.rb +62 -36
  22. data/lib/bitcoin/config.rb +2 -0
  23. data/lib/bitcoin/connection.rb +11 -8
  24. data/lib/bitcoin/electrum/mnemonic.rb +162 -0
  25. data/lib/bitcoin/ffi/openssl.rb +187 -21
  26. data/lib/bitcoin/gui/addr_view.rb +2 -0
  27. data/lib/bitcoin/gui/conn_view.rb +2 -0
  28. data/lib/bitcoin/gui/connection.rb +2 -0
  29. data/lib/bitcoin/gui/em_gtk.rb +2 -0
  30. data/lib/bitcoin/gui/gui.rb +2 -0
  31. data/lib/bitcoin/gui/helpers.rb +2 -0
  32. data/lib/bitcoin/gui/tree_view.rb +2 -0
  33. data/lib/bitcoin/gui/tx_view.rb +2 -0
  34. data/lib/bitcoin/key.rb +77 -11
  35. data/lib/bitcoin/litecoin.rb +81 -0
  36. data/lib/bitcoin/logger.rb +20 -1
  37. data/lib/bitcoin/namecoin.rb +279 -0
  38. data/lib/bitcoin/network/command_client.rb +7 -6
  39. data/lib/bitcoin/network/command_handler.rb +229 -43
  40. data/lib/bitcoin/network/connection_handler.rb +182 -70
  41. data/lib/bitcoin/network/node.rb +231 -106
  42. data/lib/bitcoin/protocol.rb +44 -23
  43. data/lib/bitcoin/protocol/address.rb +5 -3
  44. data/lib/bitcoin/protocol/alert.rb +3 -4
  45. data/lib/bitcoin/protocol/aux_pow.rb +123 -0
  46. data/lib/bitcoin/protocol/block.rb +98 -18
  47. data/lib/bitcoin/protocol/handler.rb +6 -5
  48. data/lib/bitcoin/protocol/parser.rb +44 -19
  49. data/lib/bitcoin/protocol/tx.rb +105 -52
  50. data/lib/bitcoin/protocol/txin.rb +39 -19
  51. data/lib/bitcoin/protocol/txout.rb +28 -13
  52. data/lib/bitcoin/protocol/version.rb +16 -7
  53. data/lib/bitcoin/script.rb +579 -122
  54. data/lib/bitcoin/storage/{dummy.rb → dummy/dummy_store.rb} +8 -14
  55. data/lib/bitcoin/storage/models.rb +20 -7
  56. data/lib/bitcoin/storage/{sequel_store/sequel_migrations.rb → sequel/migrations.rb} +22 -7
  57. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +52 -0
  58. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +50 -0
  59. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +18 -0
  60. data/lib/bitcoin/storage/sequel/sequel_store.rb +436 -0
  61. data/lib/bitcoin/storage/storage.rb +233 -28
  62. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +52 -0
  63. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +18 -0
  64. data/lib/bitcoin/storage/utxo/utxo_store.rb +361 -0
  65. data/lib/bitcoin/validation.rb +369 -0
  66. data/lib/bitcoin/version.rb +1 -1
  67. data/lib/bitcoin/wallet/coinselector.rb +3 -0
  68. data/lib/bitcoin/wallet/keygenerator.rb +3 -1
  69. data/lib/bitcoin/wallet/keystore.rb +6 -2
  70. data/lib/bitcoin/wallet/txdp.rb +6 -4
  71. data/lib/bitcoin/wallet/wallet.rb +54 -16
  72. data/spec/bitcoin/bitcoin_spec.rb +48 -3
  73. data/spec/bitcoin/builder_spec.rb +40 -17
  74. data/spec/bitcoin/fixtures/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +3697 -0
  75. data/spec/bitcoin/fixtures/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +23 -0
  76. data/spec/bitcoin/fixtures/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +24 -0
  77. data/spec/bitcoin/fixtures/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +37 -0
  78. data/spec/bitcoin/fixtures/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +31 -0
  79. data/spec/bitcoin/fixtures/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +27 -0
  80. data/spec/bitcoin/fixtures/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +72 -0
  81. data/spec/bitcoin/fixtures/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +27 -0
  82. data/spec/bitcoin/fixtures/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +24 -0
  83. data/spec/bitcoin/fixtures/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +30 -0
  84. data/spec/bitcoin/fixtures/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +28 -0
  85. data/spec/bitcoin/fixtures/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +27 -0
  86. data/spec/bitcoin/fixtures/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +27 -0
  87. data/spec/bitcoin/fixtures/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +27 -0
  88. data/spec/bitcoin/fixtures/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +34 -0
  89. data/spec/bitcoin/fixtures/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
  90. data/spec/bitcoin/fixtures/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +24 -0
  91. data/spec/bitcoin/fixtures/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +41 -0
  92. data/spec/bitcoin/fixtures/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +23 -0
  93. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  94. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +43 -0
  95. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  96. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +67 -0
  97. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
  98. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +39 -0
  99. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
  100. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +39 -0
  101. data/spec/bitcoin/fixtures/rawblock-auxpow.bin +0 -0
  102. data/spec/bitcoin/fixtures/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +30 -0
  103. data/spec/bitcoin/fixtures/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +23 -0
  104. data/spec/bitcoin/fixtures/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +30 -0
  105. data/spec/bitcoin/fixtures/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +28 -0
  106. data/spec/bitcoin/key_spec.rb +128 -3
  107. data/spec/bitcoin/namecoin_spec.rb +182 -0
  108. data/spec/bitcoin/network_spec.rb +5 -3
  109. data/spec/bitcoin/node/command_api_spec.rb +376 -0
  110. data/spec/bitcoin/protocol/addr_spec.rb +2 -0
  111. data/spec/bitcoin/protocol/alert_spec.rb +2 -0
  112. data/spec/bitcoin/protocol/aux_pow_spec.rb +44 -0
  113. data/spec/bitcoin/protocol/block_spec.rb +134 -39
  114. data/spec/bitcoin/protocol/getblocks_spec.rb +32 -0
  115. data/spec/bitcoin/protocol/inv_spec.rb +10 -8
  116. data/spec/bitcoin/protocol/notfound_spec.rb +31 -0
  117. data/spec/bitcoin/protocol/ping_spec.rb +2 -0
  118. data/spec/bitcoin/protocol/tx_spec.rb +83 -17
  119. data/spec/bitcoin/protocol/version_spec.rb +7 -5
  120. data/spec/bitcoin/script/opcodes_spec.rb +412 -133
  121. data/spec/bitcoin/script/script_spec.rb +112 -13
  122. data/spec/bitcoin/spec_helper.rb +68 -0
  123. data/spec/bitcoin/storage/reorg_spec.rb +199 -0
  124. data/spec/bitcoin/storage/storage_spec.rb +337 -0
  125. data/spec/bitcoin/storage/validation_spec.rb +261 -0
  126. data/spec/bitcoin/wallet/coinselector_spec.rb +10 -7
  127. data/spec/bitcoin/wallet/keygenerator_spec.rb +2 -0
  128. data/spec/bitcoin/wallet/keystore_spec.rb +2 -0
  129. data/spec/bitcoin/wallet/txdp_spec.rb +2 -0
  130. data/spec/bitcoin/wallet/wallet_spec.rb +91 -58
  131. metadata +105 -51
  132. data/lib/bitcoin/storage/sequel.rb +0 -335
  133. data/spec/bitcoin/fixtures/0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json +0 -27
  134. data/spec/bitcoin/fixtures/477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json +0 -27
  135. data/spec/bitcoin/reorg_spec.rb +0 -129
  136. data/spec/bitcoin/storage_spec.rb +0 -229
@@ -0,0 +1,24 @@
1
+ {
2
+ "hash":"cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2",
3
+ "ver":1,
4
+ "confirmations":788,
5
+ "vin_sz":1,
6
+ "vout_sz":1,
7
+ "lock_time":0,
8
+ "size":165,
9
+ "in":[
10
+ {
11
+ "prev_out":{
12
+ "hash":"514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58",
13
+ "n":0
14
+ },
15
+ "scriptSig":"0:1:01 3046022100be13275293b79346f8d14d158cc0864ff214b123aeae15fb7411df7c06a970ce022100de54627449d397aebad5e79f8215572201bb78be5f9c0b6ed8d7846b6f6cecb501 0:1:01 0:1:00"
16
+ }
17
+ ],
18
+ "out":[
19
+ {
20
+ "value":"0.09990000",
21
+ "scriptPubKey":"OP_DUP OP_HASH160 b0c1c1de86419f7c6f3186935e6bd6ccb52b8ee5 OP_EQUALVERIFY OP_CHECKSIG"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "hash":"ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b",
3
+ "ver":1,
4
+ "vin_sz":3,
5
+ "vout_sz":2,
6
+ "lock_time":0,
7
+ "size":618,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"a54793d252108ae2c5973ad3fe10e1b720e0e8dc6a59f08fb39aa8a0cc765034",
12
+ "n":0
13
+ },
14
+ "scriptSig":"3045022056ef791729029c2ca502fa983b8c8a5d1c02783773f8b0c684d07f3066c2f2b4022100ceb9493e3ce3e89775310b499075d0ed825004948a946b9bdb24b553fdb6e55d01 0420859ae0ac36f20d15783fea389daf66f313d4ed35ce96462adf8dd3ed6c9c49ed440e207d2815f1a0404f125356e1f0e5b0d71a100b3560ace2b055b4ae65e9"
15
+ },
16
+ {
17
+ "prev_out":{
18
+ "hash":"c93e09ae971cfda491c258d49e86d3592a70a0527191993df2d7b54e4b0bea42",
19
+ "n":0
20
+ },
21
+ "scriptSig":"3046022100de6358a315af7d1699674c996deb0a2c41f2158dd3643e642f87d40676f65c0f022100be829bc54368377877305e47d88ada1643e8a4dbd9ab852261ef3dc7e31321e301 04f5fe23c461f0ee8b56c2158a278268ae536dde65660d8ef864af6f3a8cbea54af7ff29c267f21782da838785a9d3ec5fb1b011cec26fa4cf5f08540022aa86b0"
22
+ },
23
+ {
24
+ "prev_out":{
25
+ "hash":"567d40f0607260e418fb39102796934faadc047c416ff42bc53d2339d4734c76",
26
+ "n":0
27
+ },
28
+ "scriptSig":"3046022100dc1cd153d066d125fab16ecc69b8e4dc5a43a2e1448aebeaec8b9c88a633b79a022100966c1d4914862417b49f24eb90a49f9385ec9a0214bfaacfe7ecedbeb3a9391701 04c6434ebe457221255280cb20c2eb734a275f2fa5169f64bbfc0273b6427506c0ea0e7149a87fbe6c26b4e641b2e0b6d86185a7af4bbc8f4667012ee75c799e94"
29
+ }
30
+ ],
31
+ "out":[
32
+ {
33
+ "value":"0.01809460",
34
+ "scriptPubKey":"OP_DUP OP_HASH160 564392f7bb454f2c8afe2c98db5fe179a4de796a OP_EQUALVERIFY OP_CHECKSIG"
35
+ },
36
+ {
37
+ "value":"0.01000000",
38
+ "scriptPubKey":"OP_HASH160 ce5e5d5792ff236e8b6bc52e1702b6906ba459dd OP_EQUAL"
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "hash":"f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b",
3
+ "ver":1,
4
+ "vin_sz":1,
5
+ "vout_sz":1,
6
+ "lock_time":0,
7
+ "size":223,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"812586b9d5822260190f2179a9b7d4dacdfb7feb7add9df6f96dc7154c3c4987",
12
+ "n":0
13
+ },
14
+ "scriptSig":"304402202d9e9f75be9c8a4c4304931b032e1de83fd2c6af2c1154a3d2b885efd5c3bfda02201184139215fb74499eae9c71ae86354c41b4d20b95a6b1fffcb8f1c5f051288101 0497d11f5c33adb7c3fed0adc637358279de04f72851b7b93fb4a8655613729047c7e2908966551b5fb7f6899f6c3dd358b57eb20a61b2c9909aa106eac6310f9f"
15
+ }
16
+ ],
17
+ "out":[
18
+ {
19
+ "value":"0.01000000",
20
+ "scriptPubKey":"OP_DUP OP_HASH160 07e761706c63b36e5a328fab1d94e9397f40704d OP_EQUALVERIFY OP_EVAL"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "hash":"000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c",
3
+ "ver":2,
4
+ "prev_block":"000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c",
5
+ "mrkl_root":"a0b9ec1d860e0786b0be7380eac76fe6180ca98b20aa03c08097bda1fbbce895",
6
+ "time":1356123634,
7
+ "bits":486604799,
8
+ "nonce":2536343301,
9
+ "n_tx":1,
10
+ "size":220,
11
+ "tx":[
12
+ {
13
+ "hash":"898cf5a16a1a40342fb193d0ec5dd9de13951c6121b95be96d88042d1e7fcc66",
14
+ "ver":2,
15
+ "vin_sz":1,
16
+ "vout_sz":2,
17
+ "lock_time":0,
18
+ "size":139,
19
+ "in":[
20
+ {
21
+ "prev_out":{
22
+ "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
+ "n":4294967295
24
+ },
25
+ "coinbase":"51010f062f503253482f"
26
+ }
27
+ ],
28
+ "out":[
29
+ {
30
+ "value":"254.53572875",
31
+ "scriptPubKey":"036c370a402c3e50063d3abd46d49ad174aae679bdc25f2a4ce5a3a4ca15b8b86e OP_CHECKSIG"
32
+ },
33
+ {
34
+ "value":"496.03174604",
35
+ "scriptPubKey":"OP_DUP OP_HASH160 85e54144c4020a65fa0a8fdbac8bba75dbc2fd00 OP_EQUALVERIFY OP_CHECKSIG"
36
+ }
37
+ ]
38
+ }
39
+ ],
40
+ "mrkl_tree":[
41
+ "898cf5a16a1a40342fb193d0ec5dd9de13951c6121b95be96d88042d1e7fcc66"
42
+ ]
43
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "hash":"000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c",
3
+ "ver":1,
4
+ "prev_block":"0000000000000000000000000000000000000000000000000000000000000000",
5
+ "mrkl_root":"f53b1baa971ea40be88cf51288aabd700dfec96c486bf7155a53a4919af4c8bd",
6
+ "time":1356123600,
7
+ "bits":486604799,
8
+ "nonce":278229610,
9
+ "n_tx":1,
10
+ "size":1374,
11
+ "tx":[
12
+ {
13
+ "hash":"cfc428c86c94c63341d5466b214afd01f3fa4db9471831c233138a257601b102",
14
+ "ver":2,
15
+ "vin_sz":1,
16
+ "vout_sz":8,
17
+ "lock_time":0,
18
+ "size":1293,
19
+ "in":[
20
+ {
21
+ "prev_out":{
22
+ "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
+ "n":4294967295
24
+ },
25
+ "coinbase":"04ffff001d01044554656c6567726170682032372f4a756e2f3230313220426172636c61797320686974207769746820c2a33239306d2066696e65206f766572204c69626f7220666978696e67"
26
+ }
27
+ ],
28
+ "out":[
29
+ {
30
+ "value":"254.53671561",
31
+ "scriptPubKey":"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG"
32
+ },
33
+ {
34
+ "value":"0.00000001",
35
+ "scriptPubKey":"5029d180e0c5ed798d877b1ada99772986c1422ca932c41b2d04000000000000 OP_DROP 0"
36
+ },
37
+ {
38
+ "value":"0.00000001",
39
+ "scriptPubKey":"202020 OP_DROP 4d6574616c73207765726520616e20696d706c696369746c7920616275736976652061677265656d656e742e0a4d6f6465726e2022706170657222206973206120666c6177656420746f6f6c2c2069747320656e67696e656572696e672069732061206e657374206f66206c6565636865732e0a546865206f6c64206d6f6e6579206973206f62736f6c6574652e0a4c65742074686520696e646976696475616c206d6f6e6574697a65206974732063726564697420776974686f75742063617274656c20696e7465726d65646961726965732e0a4769766520757320612072656e742d6c657373206361736820736f2077652063616e206265206672656520666f72207468652066697273742074696d652e0a4c65742074686973206265207468652061776169746564206461776e2e OP_DROP OP_DUP OP_HASH160 0ef0f9d19a653023554146a866238b8822bc84df OP_EQUALVERIFY OP_CHECKSIG"
40
+ },
41
+ {
42
+ "value":"0.00000001",
43
+ "scriptPubKey":"2020202020202020 OP_DROP 224c65742075732063616c63756c6174652c20776974686f757420667572746865722061646f2c20696e206f7264657220746f207365652077686f2069732072696768742e22202d2d476f747466726965642057696c68656c6d204c6569626e697a0acebec2b4efbda5e28880efbda560efbc89e38080e38080e38080e3808020206e0aefbfa3e38080e38080e380802020efbcbce38080e380802020efbc882045efbc8920676f6f64206a6f622c206d61616b75210aefbe8ce38080e38080e3808020202fe383bd20e383bd5fefbc8fefbc8f OP_DROP OP_DUP OP_HASH160 c26be5ec809aa4bf6b30aa89823cff7cedc3679a OP_EQUALVERIFY OP_CHECKSIG"
44
+ },
45
+ {
46
+ "value":"0.00000001",
47
+ "scriptPubKey":"202020202020 OP_DROP 4963682077c3bc6e736368652046726569636f696e207669656c204572666f6c67207a756d204e75747a656e206465722039392050726f7a656e7421 OP_DROP OP_DUP OP_HASH160 2939acd60037281a708eb11e4e9eda452c029eca OP_EQUALVERIFY OP_CHECKSIG"
48
+ },
49
+ {
50
+ "value":"0.00000001",
51
+ "scriptPubKey":"20202020202020202020202020 OP_DROP 225468652076616c7565206f662061206d616e2073686f756c64206265207365656e20696e207768617420686520676976657320616e64206e6f7420696e20776861742068652069732061626c6520746f20726563656976652e22202d2d416c626572742045696e737465696e OP_DROP OP_DUP OP_HASH160 f9ca5caab4bda4dc28b5556aa79a2eec0447f0bf OP_EQUALVERIFY OP_CHECKSIG"
52
+ },
53
+ {
54
+ "value":"0.00000001",
55
+ "scriptPubKey":"202020202020202020202020 OP_DROP 22416e2061726d79206f66207072696e6369706c65732063616e2070656e65747261746520776865726520616e2061726d79206f6620736f6c64696572732063616e6e6f742e22202d2d54686f6d6173205061696e65 OP_DROP OP_DUP OP_HASH160 08f320cbb41a1ae25b794f6175f96080681989f3 OP_EQUALVERIFY OP_CHECKSIG"
56
+ },
57
+ {
58
+ "value":"496.03174604",
59
+ "scriptPubKey":"OP_DUP OP_HASH160 85e54144c4020a65fa0a8fdbac8bba75dbc2fd00 OP_EQUALVERIFY OP_CHECKSIG"
60
+ }
61
+ ]
62
+ }
63
+ ],
64
+ "mrkl_tree":[
65
+ "cfc428c86c94c63341d5466b214afd01f3fa4db9471831c233138a257601b102"
66
+ ]
67
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "hash":"80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f",
3
+ "ver":1,
4
+ "prev_block":"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2",
5
+ "mrkl_root":"fa3906a4219078364372d0e2715f93e822edd0b47ce146c71ba7ba57179b50f6",
6
+ "time":1318055359,
7
+ "bits":504365040,
8
+ "nonce":272255,
9
+ "n_tx":1,
10
+ "size":215,
11
+ "tx":[
12
+ {
13
+ "hash":"fa3906a4219078364372d0e2715f93e822edd0b47ce146c71ba7ba57179b50f6",
14
+ "ver":1,
15
+ "vin_sz":1,
16
+ "vout_sz":1,
17
+ "lock_time":0,
18
+ "size":134,
19
+ "in":[
20
+ {
21
+ "prev_out":{
22
+ "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
+ "n":4294967295
24
+ },
25
+ "coinbase":"045dec8f4e0102"
26
+ }
27
+ ],
28
+ "out":[
29
+ {
30
+ "value":"50.00000000",
31
+ "scriptPubKey":"04284464458f95a72e610ecd7a561e8c2bdb46c491b347e4a375aa8f2e3b3ed56e99552e789265b6e52a2fc9a00edcdd6c032979dd81a7f1201b62427076768a7a OP_CHECKSIG"
32
+ }
33
+ ]
34
+ }
35
+ ],
36
+ "mrkl_tree":[
37
+ "fa3906a4219078364372d0e2715f93e822edd0b47ce146c71ba7ba57179b50f6"
38
+ ]
39
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "hash":"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2",
3
+ "ver":1,
4
+ "prev_block":"0000000000000000000000000000000000000000000000000000000000000000",
5
+ "mrkl_root":"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9",
6
+ "time":1317972665,
7
+ "bits":504365040,
8
+ "nonce":2084524493,
9
+ "n_tx":1,
10
+ "size":280,
11
+ "tx":[
12
+ {
13
+ "hash":"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9",
14
+ "ver":1,
15
+ "vin_sz":1,
16
+ "vout_sz":1,
17
+ "lock_time":0,
18
+ "size":199,
19
+ "in":[
20
+ {
21
+ "prev_out":{
22
+ "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
+ "n":4294967295
24
+ },
25
+ "coinbase":"04ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536"
26
+ }
27
+ ],
28
+ "out":[
29
+ {
30
+ "value":"50.00000000",
31
+ "scriptPubKey":"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9 OP_CHECKSIG"
32
+ }
33
+ ]
34
+ }
35
+ ],
36
+ "mrkl_tree":[
37
+ "97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9"
38
+ ]
39
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "hash":"313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0",
3
+ "ver":1,
4
+ "vin_sz":2,
5
+ "vout_sz":1,
6
+ "lock_time":0,
7
+ "size":417,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"95afe351496b28d7c4bc8167157506a0f9cc5cc14ace8da1b05439403ec48d47",
12
+ "n":0
13
+ },
14
+ "scriptSig":"0 304502206904f2fc30e49ece1c7b59189b82f057db8b542047bfad25f9508a4fcc7f4a9b022100fba908458cbe9dce2c8e8f6f04115904c7b1c73894dc99474b15f21caaaa4bbf01 3045022100f789401c467c8d69afb335baf5f129145cb32a90e09d8320a71165d9adf2ca920220421ec3d4bd92ae1a2708c7af507e4efef0d7c2f0ed2f8be98ac19d1c394ea08a01"
15
+ },
16
+ {
17
+ "prev_out":{
18
+ "hash":"10b433a227ca8f7b75c98d3df7e1cbd529cbec613a1546bc09cc67461e0500f0",
19
+ "n":0
20
+ },
21
+ "scriptSig":"0 304402205dd25d59494cecd5cbc79ca14bbb41424221f01cc02d5948e9a499567a3be246022047785bf632f8c6719df5736908502051d63b259f5db1359ac2b3c4c57569b88e01 3045022100e08e98c3cad884603224441d61300e9f11f3826e52d58a3d34e01be5f0286f4402205f85d91d1cff6272f10c41de27e30a3db8cb9b176f011635bb4d11687ebe06dd01"
22
+ }
23
+ ],
24
+ "out":[
25
+ {
26
+ "value":"0.06990000",
27
+ "scriptPubKey":"OP_HASH160 47f070cd693c5fcc481f181caeb5515f7928c6ca OP_EQUAL"
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "hash":"3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae",
3
+ "ver":1,
4
+ "vin_sz":1,
5
+ "vout_sz":1,
6
+ "lock_time":0,
7
+ "size":358,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a",
12
+ "n":0
13
+ },
14
+ "scriptSig":"304502210088984573e3e4f33db7df6aea313f1ce67a3ef3532ea89991494c7f018258371802206ceefc9291450dbd40d834f249658e0f64662d52a41cf14e20c9781144f2fe0701 0:1:01 a97614c51b66bced5e4491001bd702669770dccf440982876375210273bf5dec1bf4ba5725a110b475e729d3604177a3a9762580d6800749710bd52cac6714a6bb94c8792c395785787280dc188d114e1f339b87632103ea09d5c689aa76277ee934126bd98278103a42263e45b1fbf450a3ad5f64bb7bac6752210273bf5dec1bf4ba5725a110b475e729d3604177a3a9762580d6800749710bd52c2103ea09d5c689aa76277ee934126bd98278103a42263e45b1fbf450a3ad5f64bb7b52ae6868"
15
+ }
16
+ ],
17
+ "out":[
18
+ {
19
+ "value":"0.06980000",
20
+ "scriptPubKey":"OP_DUP OP_HASH160 ae6097cb40d43f440bc5d39ff1e4f0ad51713895 OP_EQUALVERIFY OP_CHECKSIG"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "hash":"44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a",
3
+ "ver":1,
4
+ "vin_sz":2,
5
+ "vout_sz":1,
6
+ "lock_time":0,
7
+ "size":419,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"5822461429324c29c3ef4cb23b2ea82938e33871830a60a24c3c49db80104daa",
12
+ "n":0
13
+ },
14
+ "scriptSig":"0 3045022100e563a659d9d17968eeca88107097fc9708c93dcffd03e9d6656d93ea50a4cf740220027349c42751ecfc6a70f464a16261acec96907ad24fec65d007a1bd57c2c37601 304602210093a507e19abfda44aafaad634276c78e092d90639174a4abcab15361399e634902210082a83459a135eb6c3850fab4e19f4bb57b6594b3529169ef5b68159f27f3e36c01"
15
+ },
16
+ {
17
+ "prev_out":{
18
+ "hash":"72cf8dd9c0b233ec2320a3f690123a3c7c1f7c928496b33d3c71a4ce87b1ae11",
19
+ "n":0
20
+ },
21
+ "scriptSig":"0 304502204c1e9d94bfbafc2679f78b07c480b110a206475f4e076079682649866ffc0bf4022100d2a8a0755ebb94229b446cb7bddbe51facb6656232066e397cd56ab0eb02b27101 30450220058809214ae17872aaab482f4d67ba419f3bc86297e094c2651270383a1a5db8022100a3815c75b3bdc3fd3a468434f7d133a25a9eb68799a7283a9ff9d1c03aac1b9801"
22
+ }
23
+ ],
24
+ "out":[
25
+ {
26
+ "value":"0.06990000",
27
+ "scriptPubKey":"OP_HASH160 47f070cd693c5fcc481f181caeb5515f7928c6ca OP_EQUAL"
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "hash":"d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830",
3
+ "ver":1,
4
+ "vin_sz":1,
5
+ "vout_sz":2,
6
+ "lock_time":1377151594,
7
+ "size":463,
8
+ "in":[
9
+ {
10
+ "prev_out":{
11
+ "hash":"313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0",
12
+ "n":0
13
+ },
14
+ "scriptSig":"0 3044022033ef5da1526952decbc7ab3b05a1ddccb6b1974fab128951216d8b9148de27c102204b44c05cea515ed3431ac92b4cfcfdce09c314e4f0315f5f9d275ba484c0fdf201 3044022026ccacee8e4411dd3c81fcaa49f22d2f50e1a205d6e09cf99270343da1c7b1a302207c3a62b8c1d741db506f1c7f43df4c2322bee3f644666035ab82ea0d7460610b01 0 a97614c51b66bced5e4491001bd702669770dccf440982876375210273bf5dec1bf4ba5725a110b475e729d3604177a3a9762580d6800749710bd52cac6714a6bb94c8792c395785787280dc188d114e1f339b87632103ea09d5c689aa76277ee934126bd98278103a42263e45b1fbf450a3ad5f64bb7bac6752210273bf5dec1bf4ba5725a110b475e729d3604177a3a9762580d6800749710bd52c2103ea09d5c689aa76277ee934126bd98278103a42263e45b1fbf450a3ad5f64bb7b52ae6868",
15
+ "sequence":0
16
+ }
17
+ ],
18
+ "out":[
19
+ {
20
+ "value":"0.02490000",
21
+ "scriptPubKey":"OP_DUP OP_HASH160 ae6097cb40d43f440bc5d39ff1e4f0ad51713895 OP_EQUALVERIFY OP_CHECKSIG"
22
+ },
23
+ {
24
+ "value":"0.00990000",
25
+ "scriptPubKey":"OP_DUP OP_HASH160 7cd75fec08657194e75001764622349f74285255 OP_EQUALVERIFY OP_CHECKSIG"
26
+ }
27
+ ]
28
+ }
@@ -1,3 +1,5 @@
1
+ # encoding: ascii-8bit
2
+
1
3
  require_relative 'spec_helper'
2
4
 
3
5
  describe "Bitcoin::Key" do
@@ -63,8 +65,40 @@ describe "Bitcoin::Key" do
63
65
 
64
66
  it "should verify signature" do
65
67
  sig = @key.sign("foobar")
66
- key2 = Bitcoin::Key.new(nil, @key.pub)
67
- @key.verify("foobar", sig).should == true
68
+ key = Bitcoin::Key.new(nil, @key.pub)
69
+ key.verify("foobar", sig).should == true
70
+ end
71
+
72
+ it "recovers public keys from compact signatures" do
73
+ tests = [
74
+ # normal
75
+ { address: "16vqGo3KRKE9kTsTZxKoJKLzwZGTodK3ce",
76
+ signature: "HPDs1TesA48a9up4QORIuub67VHBM37X66skAYz0Esg23gdfMuCTYDFORc6XGpKZ2/flJ2h/DUF569FJxGoVZ50=",
77
+ message: "test message",
78
+ expected: true },
79
+
80
+ # different message
81
+ { address: "16vqGo3KRKE9kTsTZxKoJKLzwZGTodK3ce",
82
+ signature: "HPDs1TesA48a9up4QORIuub67VHBM37X66skAYz0Esg23gdfMuCTYDFORc6XGpKZ2/flJ2h/DUF569FJxGoVZ50=",
83
+ message: "not what I signed",
84
+ expected: false },
85
+
86
+ # different address
87
+ { address: "1JbYZRKyysprVjSSBobs8LX6QVjzsscQNU",
88
+ signature: "HPDs1TesA48a9up4QORIuub67VHBM37X66skAYz0Esg23gdfMuCTYDFORc6XGpKZ2/flJ2h/DUF569FJxGoVZ50=",
89
+ message: "test message",
90
+ expected: false },
91
+
92
+ # compressed
93
+ { address: "18uitB5ARAhyxmkN2Sa9TbEuoGN1he83BX",
94
+ signature: "IMAtT1SjRyP6bz6vm5tKDTTTNYS6D8w2RQQyKD3VGPq2i2txGd2ar18L8/nvF1+kAMo5tNc4x0xAOGP0HRjKLjc=",
95
+ message: "testtest",
96
+ expected: true },
97
+ ]
98
+ tests.each do |test|
99
+ key = Bitcoin::Key.recover_compact_signature_to_key(test[:message], test[:signature])
100
+ test[:expected].should == (key.addr == test[:address])
101
+ end
68
102
  end
69
103
 
70
104
  it "should export private key in base58 format" do
@@ -89,6 +123,64 @@ describe "Bitcoin::Key" do
89
123
  Bitcoin.network = :bitcoin
90
124
  end
91
125
 
126
+ it "should export private key in compressed base58 format" do
127
+ Bitcoin.network = :bitcoin
128
+ Bitcoin::Key.new("98e4483a197fb686fe9afb51389f329aabc67964b1d0e0a5340c962a0d63c44a",
129
+ nil, true).to_base58.should == "L2LusdhGSagfUVvNWrUuPDygn5mdAhxUDEANfABvBj36Twn1mKgQ"
130
+ Bitcoin.network = :testnet3
131
+ Bitcoin::Key.new("e3ff5d7e592669d0c1714f1496b260815edd0c3a00186e896dc7f36ede914dd2",
132
+ nil, true).to_base58.should == "cVDu6aXUWHTM2vpztZW14BMnKkCcd5th6177VnCsa8XozoMyp73C"
133
+ Bitcoin.network = :bitcoin end
134
+
135
+ it "should import private key in compressed base58 format" do
136
+ Bitcoin.network = :bitcoin
137
+ key = Bitcoin::Key.from_base58("L2LusdhGSagfUVvNWrUuPDygn5mdAhxUDEANfABvBj36Twn1mKgQ")
138
+ key.priv.should == "98e4483a197fb686fe9afb51389f329aabc67964b1d0e0a5340c962a0d63c44a"
139
+ key.pub.should == "02e054ee811165ac294c992ff410067db6491228725fe09db2a415493c897973a8"
140
+ key.addr.should == "1C7Ni4zuV3zfLs8T1S7s29wNAtRoDHHnpw"
141
+ Bitcoin.network = :testnet3
142
+ key = Bitcoin::Key.from_base58("cVDu6aXUWHTM2vpztZW14BMnKkCcd5th6177VnCsa8XozoMyp73C")
143
+ key.priv.should == "e3ff5d7e592669d0c1714f1496b260815edd0c3a00186e896dc7f36ede914dd2"
144
+ key.pub.should == "0390bb61c062266a1e8460ec902379749ae30f569013d82bd448a61591f20b8ee2"
145
+ key.addr.should == "mjh9RgZh14FfJQ2pFpRSqEQ5BH1nHo5To7"
146
+ Bitcoin.network = :bitcoin
147
+ end
148
+
149
+ it "should hanlde compressed and uncompressed pubkeys" do
150
+ compressed = "0351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da78"
151
+ uncompressed = "0451efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da787f71a2e8ac5aacedab47904d4bd42f636429e9ce069ebcb99f675aad31306a53"
152
+ Bitcoin::Key.new(nil, compressed).compressed.should == true
153
+ Bitcoin::Key.new(nil, compressed).pub.should == compressed
154
+ Bitcoin::Key.new(nil, compressed).addr.should == "1NdB761LmTmrJixxp93nz7pEiCx5cKPW44"
155
+ Bitcoin::Key.new(nil, uncompressed).compressed.should == false
156
+ Bitcoin::Key.new(nil, uncompressed).pub.should == uncompressed
157
+ Bitcoin::Key.new(nil, uncompressed).addr.should == "19FBCg9295EBQ4P6bSLTGyz2BdbbPcqQD"
158
+
159
+ key = Bitcoin::Key.new(nil, compressed)
160
+ key.pub_compressed.should == compressed
161
+ key.pub_uncompressed.should == uncompressed
162
+
163
+ sig = @key.sign(msg="foobar")
164
+ Bitcoin::Key.new(nil, @key.pub_compressed ).verify(msg, sig).should == true
165
+ Bitcoin::Key.new(nil, @key.pub_uncompressed).verify(msg, sig).should == true
166
+
167
+ compressed = "02f01984446a994a9e422c9ba9c6f33f1f40c01d9d872064a49679d702fae33064"
168
+ Bitcoin::Key.new(nil, compressed).pub.should == compressed
169
+ Bitcoin::Key.new(nil, compressed).addr.should == "18TWywxjESkg4pzJqBYNDo39S2QMPaWWJ5"
170
+
171
+ k = Bitcoin::Key.new(nil, nil)
172
+ k.instance_eval{ set_pub("02f01984446a994a9e422c9ba9c6f33f1f40c01d9d872064a49679d702fae33064") }
173
+ k.compressed.should == true
174
+
175
+ k = Bitcoin::Key.new(nil, nil)
176
+ k.instance_eval{ set_pub("0351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da78") }
177
+ k.compressed.should == true
178
+
179
+ k = Bitcoin::Key.new(nil, nil)
180
+ k.instance_eval{ set_pub("0451efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da787f71a2e8ac5aacedab47904d4bd42f636429e9ce069ebcb99f675aad31306a53") }
181
+ k.compressed.should == false
182
+ end
183
+
92
184
  end
93
185
 
94
186
  begin
@@ -96,7 +188,6 @@ begin
96
188
  Bitcoin::OpenSSL_EC
97
189
 
98
190
  it 'resolves public from private key' do
99
- Bitcoin.network = :testnet
100
191
  privkey = ["56e28a425a7b588973b5db962a09b1aca7bdc4a7268cdd671d03c52a997255dc"].pack("H*")
101
192
  pubkey = ["04324c6ebdcf079db6c9209a6b715b955622561262cde13a8a1df8ae0ef030eaa1552e31f8be90c385e27883a9d82780283d19507d7fa2e1e71a1d11bc3a52caf3"].pack("H*")
102
193
 
@@ -118,6 +209,40 @@ begin
118
209
  }.all?.should == true
119
210
  end
120
211
 
212
+ it 'recover public key from compact signature' do
213
+ args = [
214
+ "\x12&\x17\x9D\xDFc\x83\xFB\xCFQ\x02\xC9I%8\xB7 ls\x9A\xE7\x9E\xB0d@\x8C*\xBDg\xD3\x9B\xED",
215
+ "\x1C\xF0\xEC\xD57\xAC\x03\x8F\x1A\xF6\xEAx@\xE4H\xBA\xE6\xFA\xEDQ\xC13~\xD7\xEB\xAB$\x01\x8C\xF4\x12\xC86\xDE\a_2\xE0\x93`1NE\xCE\x97\x1A\x92\x99\xDB\xF7\xE5'h\x7F\rAy\xEB\xD1I\xC4j\x15g\x9D",
216
+ 1, false
217
+ ]
218
+ expected = "047840b97f46d4c32c62119f9e069172272592ec7741a3aec81e339b87387350740dce89837c8332910f349818060b66070b94e8bb11442d49d3f6c0d7f31ba6a6"
219
+
220
+ # 10_000.times{|n| # enable for memory leak testing
221
+ # puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip if (n % 1_000) == 0
222
+ Bitcoin::OpenSSL_EC.recover_public_key_from_signature(*args).should == expected
223
+ # }
224
+ end
225
+
226
+ it 'sign and verify text messages' do
227
+ [
228
+ ["5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj", false],
229
+ ["5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3", false],
230
+ ["Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw", true],
231
+ ["L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g", true],
232
+ ].each{|privkey_base58,expected_compression|
233
+ k = Bitcoin::Key.from_base58(privkey_base58)
234
+ k.compressed.should == expected_compression
235
+ k2 = Bitcoin::Key.new(nil, k.pub)
236
+ k2.compressed.should == expected_compression
237
+ 16.times{|n|
238
+ msg = "Very secret message %d: 11" % n
239
+ signature = k.sign_message(msg)
240
+ k2.verify_message(signature, msg).should == true
241
+ Bitcoin::Key.verify_message(k.addr, signature, msg).should == true
242
+ }
243
+ }
244
+ end
245
+
121
246
  end
122
247
  rescue LoadError
123
248
  end