bitcoin-ruby 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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