monacoin-ruby 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +5 -0
  4. data/COPYING +18 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +33 -0
  7. data/README.rdoc +210 -0
  8. data/Rakefile +112 -0
  9. data/bin/monacoin_shell +12 -0
  10. data/bitcoin-ruby.gemspec +23 -0
  11. data/examples/bbe_verify_tx.rb +60 -0
  12. data/examples/concept-blockchain-pow.rb +151 -0
  13. data/examples/connect.rb +36 -0
  14. data/examples/generate_tx.rb +34 -0
  15. data/examples/simple_network_monitor_and_util.rb +195 -0
  16. data/spec/bitcoin/bitcoin_spec.rb +598 -0
  17. data/spec/bitcoin/bloom_filter_spec.rb +23 -0
  18. data/spec/bitcoin/builder_spec.rb +342 -0
  19. data/spec/bitcoin/contracthash_spec.rb +45 -0
  20. data/spec/bitcoin/dogecoin_spec.rb +176 -0
  21. data/spec/bitcoin/ext_key_spec.rb +180 -0
  22. data/spec/bitcoin/ffi_openssl.rb +45 -0
  23. data/spec/bitcoin/fixtures/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +3697 -0
  24. data/spec/bitcoin/fixtures/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +23 -0
  25. data/spec/bitcoin/fixtures/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +24 -0
  26. data/spec/bitcoin/fixtures/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +37 -0
  27. data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
  28. data/spec/bitcoin/fixtures/23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63.json +23 -0
  29. data/spec/bitcoin/fixtures/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +31 -0
  30. data/spec/bitcoin/fixtures/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +27 -0
  31. data/spec/bitcoin/fixtures/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +72 -0
  32. data/spec/bitcoin/fixtures/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +27 -0
  33. data/spec/bitcoin/fixtures/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +24 -0
  34. data/spec/bitcoin/fixtures/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +30 -0
  35. data/spec/bitcoin/fixtures/60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1.json +45 -0
  36. data/spec/bitcoin/fixtures/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +28 -0
  37. data/spec/bitcoin/fixtures/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +27 -0
  38. data/spec/bitcoin/fixtures/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +27 -0
  39. data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
  40. data/spec/bitcoin/fixtures/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +27 -0
  41. data/spec/bitcoin/fixtures/bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba.json +34 -0
  42. data/spec/bitcoin/fixtures/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +34 -0
  43. data/spec/bitcoin/fixtures/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
  44. data/spec/bitcoin/fixtures/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +24 -0
  45. data/spec/bitcoin/fixtures/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +41 -0
  46. data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
  47. data/spec/bitcoin/fixtures/coinbase.json +24 -0
  48. data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
  49. data/spec/bitcoin/fixtures/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +23 -0
  50. data/spec/bitcoin/fixtures/filteredblock-0.bin +0 -0
  51. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
  52. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +39 -0
  53. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
  54. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +39 -0
  55. data/spec/bitcoin/fixtures/litecoin-tx-f5aa30f574e3b6f1a3d99c07a6356ba812aabb9661e1d5f71edff828cbd5c996.json +259 -0
  56. data/spec/bitcoin/fixtures/rawblock-0.bin +0 -0
  57. data/spec/bitcoin/fixtures/rawblock-0.json +39 -0
  58. data/spec/bitcoin/fixtures/rawblock-1.bin +0 -0
  59. data/spec/bitcoin/fixtures/rawblock-1.json +39 -0
  60. data/spec/bitcoin/fixtures/rawblock-131025.bin +0 -0
  61. data/spec/bitcoin/fixtures/rawblock-131025.json +5063 -0
  62. data/spec/bitcoin/fixtures/rawblock-170.bin +0 -0
  63. data/spec/bitcoin/fixtures/rawblock-170.json +68 -0
  64. data/spec/bitcoin/fixtures/rawblock-9.bin +0 -0
  65. data/spec/bitcoin/fixtures/rawblock-9.json +39 -0
  66. data/spec/bitcoin/fixtures/rawblock-auxpow.bin +0 -0
  67. data/spec/bitcoin/fixtures/rawblock-testnet-1151351.bin +0 -0
  68. data/spec/bitcoin/fixtures/rawblock-testnet-26478.bin +0 -0
  69. data/spec/bitcoin/fixtures/rawblock-testnet-26478.json +64 -0
  70. data/spec/bitcoin/fixtures/rawblock-testnet-265322.bin +0 -0
  71. data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
  72. data/spec/bitcoin/fixtures/rawtx-01.bin +0 -0
  73. data/spec/bitcoin/fixtures/rawtx-01.json +27 -0
  74. data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
  75. data/spec/bitcoin/fixtures/rawtx-02.bin +0 -0
  76. data/spec/bitcoin/fixtures/rawtx-02.json +27 -0
  77. data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
  78. data/spec/bitcoin/fixtures/rawtx-03.bin +0 -0
  79. data/spec/bitcoin/fixtures/rawtx-03.json +48 -0
  80. data/spec/bitcoin/fixtures/rawtx-04.json +27 -0
  81. data/spec/bitcoin/fixtures/rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin +0 -0
  82. data/spec/bitcoin/fixtures/rawtx-05.json +23 -0
  83. data/spec/bitcoin/fixtures/rawtx-14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984.bin +0 -0
  84. data/spec/bitcoin/fixtures/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin +0 -0
  85. data/spec/bitcoin/fixtures/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json +27 -0
  86. data/spec/bitcoin/fixtures/rawtx-406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602.json +23 -0
  87. data/spec/bitcoin/fixtures/rawtx-52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2.bin +0 -0
  88. data/spec/bitcoin/fixtures/rawtx-b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d.bin +0 -0
  89. data/spec/bitcoin/fixtures/rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json +37 -0
  90. data/spec/bitcoin/fixtures/rawtx-c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73.json +24 -0
  91. data/spec/bitcoin/fixtures/rawtx-de35d060663750b3975b7997bde7fb76307cec5b270d12fcd9c4ad98b279c28c.json +23 -0
  92. data/spec/bitcoin/fixtures/rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin +0 -0
  93. data/spec/bitcoin/fixtures/rawtx-p2wpkh.bin +0 -0
  94. data/spec/bitcoin/fixtures/rawtx-p2wpkh.json +67 -0
  95. data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
  96. data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
  97. data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
  98. data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
  99. data/spec/bitcoin/fixtures/rawtx-testnet-a220adf1902c46a39db25a24bc4178b6a88440f977a7e2cabfdd8b5c1dd35cfb.json +27 -0
  100. data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
  101. data/spec/bitcoin/fixtures/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.bin +0 -0
  102. data/spec/bitcoin/fixtures/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.json +41 -0
  103. data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
  104. data/spec/bitcoin/fixtures/reorg/blk_0_to_4.dat +0 -0
  105. data/spec/bitcoin/fixtures/reorg/blk_3A.dat +0 -0
  106. data/spec/bitcoin/fixtures/reorg/blk_4A.dat +0 -0
  107. data/spec/bitcoin/fixtures/reorg/blk_5A.dat +0 -0
  108. data/spec/bitcoin/fixtures/script_tests.json +1947 -0
  109. data/spec/bitcoin/fixtures/sighash.json +1004 -0
  110. data/spec/bitcoin/fixtures/testnet/block_0.bin +0 -0
  111. data/spec/bitcoin/fixtures/testnet/block_1.bin +0 -0
  112. data/spec/bitcoin/fixtures/testnet/block_2.bin +0 -0
  113. data/spec/bitcoin/fixtures/testnet/block_3.bin +0 -0
  114. data/spec/bitcoin/fixtures/testnet/block_4.bin +0 -0
  115. data/spec/bitcoin/fixtures/testnet/block_5.bin +0 -0
  116. data/spec/bitcoin/fixtures/tx-0295028ef826b2a188409cb905b631faebb9bb3cdf14510571c5f4bd8591338f.json +64 -0
  117. data/spec/bitcoin/fixtures/tx-03339a725007a279484fb6f5361f522dd1cf4d0923d30e6b973290dba4275f92.json +64 -0
  118. data/spec/bitcoin/fixtures/tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json +139 -0
  119. data/spec/bitcoin/fixtures/tx-0ce7e5238fbdb6c086cf1b384b21b827e91cc23f360417265874a5a0d86ce367.json +64 -0
  120. data/spec/bitcoin/fixtures/tx-0ef34c49f630aea17df0080728b0fc67bf5f87fbda936934a4b11b4a69d7821e.json +64 -0
  121. data/spec/bitcoin/fixtures/tx-1129d2a8bd5bb3a81e54dc96a90f1f6b2544575748caa17243470935c5dd91b7.json +28 -0
  122. data/spec/bitcoin/fixtures/tx-19aa42fee0fa57c45d3b16488198b27caaacc4ff5794510d0c17f173f05587ff.json +23 -0
  123. data/spec/bitcoin/fixtures/tx-1a4f3b9dc4494aeedeb39f30dd37e60541b2abe3ed4977992017cc0ad4f44956.json +64 -0
  124. data/spec/bitcoin/fixtures/tx-1f9191dcf2b1844ca28c6ef4b969e1d5fab70a5e3c56b7007949e55851cb0c4f.json +64 -0
  125. data/spec/bitcoin/fixtures/tx-22cd5fef23684d7b304e119bedffde6f54538d3d54a5bfa237e20dc2d9b4b5ad.json +64 -0
  126. data/spec/bitcoin/fixtures/tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json +34 -0
  127. data/spec/bitcoin/fixtures/tx-2958fb00b4fd6fe0353503b886eb9a193d502f4fd5fc042d5e03216ba918bbd6.json +64 -0
  128. data/spec/bitcoin/fixtures/tx-29f277145749ad6efbed3ae6ce301f8d33c585ec26b7c044ad93c2f866e9e942.json +64 -0
  129. data/spec/bitcoin/fixtures/tx-2c5e5376c20e9cc78d0fb771730e5d840cc2096eff0ef045b599fe92475ace1c.json +28 -0
  130. data/spec/bitcoin/fixtures/tx-2c63aa814701cef5dbd4bbaddab3fea9117028f2434dddcdab8339141e9b14d1.json +30 -0
  131. data/spec/bitcoin/fixtures/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +30 -0
  132. data/spec/bitcoin/fixtures/tx-326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e.json +23 -0
  133. data/spec/bitcoin/fixtures/tx-345bed8785c3282a264ffb0dbee61cde54854f10e16f1b3e75b7f2d9f62946f2.json +64 -0
  134. data/spec/bitcoin/fixtures/tx-39ba7440b7103557560cc8ce258009936796485aaf8b478e66ab4cb97c66e31b.json +32 -0
  135. data/spec/bitcoin/fixtures/tx-3a04d57a833367f1655cc5ec3beb587888ef4977a86caa8c8ad4ba7cc717eae7.json +64 -0
  136. data/spec/bitcoin/fixtures/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +23 -0
  137. data/spec/bitcoin/fixtures/tx-4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9.json +38 -0
  138. data/spec/bitcoin/fixtures/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +30 -0
  139. data/spec/bitcoin/fixtures/tx-46224764c7870f95b58f155bce1e38d4da8e99d42dbb632d0dd7c07e092ee5aa.json +23 -0
  140. data/spec/bitcoin/fixtures/tx-5df1375ffe61ac35ca178ebb0cab9ea26dedbd0e96005dfcee7e379fa513232f.json +30 -0
  141. data/spec/bitcoin/fixtures/tx-62d9a565bd7b5344c5352e3e9e5f40fa4bbd467fa19c87357216ec8777ba1cce.json +64 -0
  142. data/spec/bitcoin/fixtures/tx-6327783a064d4e350c454ad5cd90201aedf65b1fc524e73709c52f0163739190.json +23 -0
  143. data/spec/bitcoin/fixtures/tx-6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba.json +27 -0
  144. data/spec/bitcoin/fixtures/tx-6aaf18b9f1283b939d8e5d40ff5f8a435229f4178372659cc3a0bce4e262bf78.json +28 -0
  145. data/spec/bitcoin/fixtures/tx-6b48bba6f6d2286d7ec0883c0fc3085955090813a4c94980466611c798b868cc.json +64 -0
  146. data/spec/bitcoin/fixtures/tx-70cfbc6690f9ab46712db44e3079ac227962b2771a9341d4233d898b521619ef.json +40 -0
  147. data/spec/bitcoin/fixtures/tx-7a1a9db42f065f75110fcdb1bc415549c8ef7670417ba1d35a67f1b8adc562c1.json +64 -0
  148. data/spec/bitcoin/fixtures/tx-9a768fc7d0c4bdc86e25154357ef7c0063ca21310e5740a2f12f90b7455184a7.json +64 -0
  149. data/spec/bitcoin/fixtures/tx-9cad8d523a0694f2509d092c39cebc8046adae62b4e4297102d568191d9478d8.json +64 -0
  150. data/spec/bitcoin/fixtures/tx-9e052eb694bd7e15906433f064dff0161a12fd325c1124537766377004023c6f.json +64 -0
  151. data/spec/bitcoin/fixtures/tx-9fb65b7304aaa77ac9580823c2c06b259cc42591e5cce66d76a81b6f51cc5c28.json +23 -0
  152. data/spec/bitcoin/fixtures/tx-a6ce7081addade7676cd2af75c4129eba6bf5e179a19c40c7d4cf6a5fe595954.json +30 -0
  153. data/spec/bitcoin/fixtures/tx-a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944.json +23 -0
  154. data/spec/bitcoin/fixtures/tx-aab7ef280abbb9cc6fbaf524d2645c3daf4fcca2b3f53370e618d9cedf65f1f8.json +23 -0
  155. data/spec/bitcoin/fixtures/tx-ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742.json +27 -0
  156. data/spec/bitcoin/fixtures/tx-ad4bcf3241e5d2ad140564e20db3567d41594cf4c2012433fe46a2b70e0d87b8.json +64 -0
  157. data/spec/bitcoin/fixtures/tx-b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9.json +27 -0
  158. data/spec/bitcoin/fixtures/tx-b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d.json +28 -0
  159. data/spec/bitcoin/fixtures/tx-bbca0628c42cb8bf7c3f4b2ad688fa56da5308dd2a10255da89fb1f46e6e413d.json +36 -0
  160. data/spec/bitcoin/fixtures/tx-bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224.json +23 -0
  161. data/spec/bitcoin/fixtures/tx-c192b74844e4837a34c4a5a97b438f1c111405b01b99e2d12b7c96d07fc74c04.json +28 -0
  162. data/spec/bitcoin/fixtures/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +28 -0
  163. data/spec/bitcoin/fixtures/tx-e335562f7e297aadeed88e5954bc4eeb8dc00b31d829eedb232e39d672b0c009.json +406 -0
  164. data/spec/bitcoin/fixtures/tx-eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb.json +35 -0
  165. data/spec/bitcoin/fixtures/tx-fee1b9b85531c8fb6cd7831f83490c7f2aa768b6eefe29854ef5e89ce7b9ecb1.json +64 -0
  166. data/spec/bitcoin/fixtures/txdp-1.txt +32 -0
  167. data/spec/bitcoin/fixtures/txdp-2-signed.txt +19 -0
  168. data/spec/bitcoin/fixtures/txdp-2-unsigned.txt +14 -0
  169. data/spec/bitcoin/fixtures/txscript-invalid-too-many-sigops-followed-by-invalid-pushdata.bin +1 -0
  170. data/spec/bitcoin/helpers/fake_blockchain.rb +183 -0
  171. data/spec/bitcoin/key_spec.rb +326 -0
  172. data/spec/bitcoin/network_spec.rb +50 -0
  173. data/spec/bitcoin/performance/storage_spec.rb +41 -0
  174. data/spec/bitcoin/protocol/addr_spec.rb +82 -0
  175. data/spec/bitcoin/protocol/alert_spec.rb +22 -0
  176. data/spec/bitcoin/protocol/aux_pow_spec.rb +45 -0
  177. data/spec/bitcoin/protocol/bip143_spec.rb +116 -0
  178. data/spec/bitcoin/protocol/block_spec.rb +208 -0
  179. data/spec/bitcoin/protocol/getblocks_spec.rb +32 -0
  180. data/spec/bitcoin/protocol/inv_spec.rb +134 -0
  181. data/spec/bitcoin/protocol/notfound_spec.rb +31 -0
  182. data/spec/bitcoin/protocol/parser_spec.rb +50 -0
  183. data/spec/bitcoin/protocol/partial_merkle_tree_spec.rb +38 -0
  184. data/spec/bitcoin/protocol/ping_spec.rb +51 -0
  185. data/spec/bitcoin/protocol/reject.rb +17 -0
  186. data/spec/bitcoin/protocol/tx_spec.rb +894 -0
  187. data/spec/bitcoin/protocol/txin_spec.rb +45 -0
  188. data/spec/bitcoin/protocol/txout_spec.rb +27 -0
  189. data/spec/bitcoin/protocol/version_spec.rb +110 -0
  190. data/spec/bitcoin/script/opcodes_spec.rb +773 -0
  191. data/spec/bitcoin/script/script_spec.rb +971 -0
  192. data/spec/bitcoin/secp256k1_spec.rb +78 -0
  193. data/spec/bitcoin/spec_helper.rb +108 -0
  194. data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
  195. metadata +237 -0
@@ -0,0 +1,598 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require_relative 'spec_helper.rb'
4
+ require 'bitcoin'
5
+
6
+
7
+ describe 'Bitcoin Address/Hash160/PubKey' do
8
+
9
+ it 'bitcoin-hash160 from public key' do
10
+ # 65 bytes (8 bit version + 512 bits) pubkey in hex (130 bytes)
11
+ pubkey = "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"
12
+ Bitcoin.hash160(pubkey).should == "62e907b15cbf27d5425399ebf6f0fb50ebb88f18"
13
+ end
14
+
15
+ it 'bitcoin-address from bitcoin-hash160' do
16
+ # 20 bytes (160 bit) hash160 in hex (40 bytes)
17
+
18
+ Bitcoin::network = :testnet
19
+ Bitcoin.hash160_to_address("62e907b15cbf27d5425399ebf6f0fb50ebb88f18")
20
+ .should == "mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt"
21
+
22
+ Bitcoin::network = :bitcoin
23
+ Bitcoin.hash160_to_address("62e907b15cbf27d5425399ebf6f0fb50ebb88f18")
24
+ .should == "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
25
+ end
26
+
27
+ it 'bitcoin-address from pubkey' do
28
+ Bitcoin::network = :testnet
29
+ Bitcoin.pubkey_to_address("029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4")
30
+ .should == "mu6vSuyvpVxvDAJyZczjxaU56pXLNBSf9C"
31
+ Bitcoin.pubkey_to_address("049e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4b82314814017e4e9b06a0fd8e01772bb410cb1c36cfc2d03079c315bc7494b86")
32
+ .should == "n4bZ82i9SdLj6YauPn3PPKFRhQHMZrdaPq"
33
+
34
+ Bitcoin::network = :bitcoin
35
+ Bitcoin.pubkey_to_address("029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4")
36
+ .should == "1Eay9rtx1UXfS3qMr42N8fFkEpvdR2euvg"
37
+ Bitcoin.pubkey_to_address("049e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4b82314814017e4e9b06a0fd8e01772bb410cb1c36cfc2d03079c315bc7494b86")
38
+ .should == "1Q5bpydAdbuUKS7HgD51ZQ36qQgeiN8cBE"
39
+ end
40
+
41
+ it 'bitcoin p2sh multisig address from pubkeys' do
42
+ Bitcoin::network = :testnet
43
+ address, redeem_script = Bitcoin.pubkeys_to_p2sh_multisig_address(2, "029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4",
44
+ "0299acf23a65c31fe02052d7474769529c21612b1afa56cc149747fe63867592ec")
45
+ address.should == "2NGaiH7MNYWhsWPQKudZEvy8KnoWPfuGPg1"
46
+ redeem_script.hth.should == "52" + # OP_2
47
+ "21" + "029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4" + # pubkey.bytesize + pubkey
48
+ "21" + "0299acf23a65c31fe02052d7474769529c21612b1afa56cc149747fe63867592ec" + # pubkey.bytesize + pubkey
49
+ "52" + # OP_2
50
+ "ae" # OP_CHECKMULTISIG
51
+
52
+ Bitcoin::network = :bitcoin
53
+ address, redeem_script = Bitcoin.pubkeys_to_p2sh_multisig_address(2, "029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4",
54
+ "0299acf23a65c31fe02052d7474769529c21612b1afa56cc149747fe63867592ec",
55
+ "020b16a7227f873ac68cf3140f1101d2eda5acb28bf3e7d546409139caf25142e4")
56
+ address.should == "38eiL6Jac27TVAu83wj81Miso9rXiVqgcP"
57
+ redeem_script.hth.should == "52" + # OP_2
58
+ "21" + "029e31ccb7308c2525d542024b8119a3ab3767933e82aedd1471f9c714d998d1b4" + # pubkey.bytesize + pubkey
59
+ "21" + "0299acf23a65c31fe02052d7474769529c21612b1afa56cc149747fe63867592ec" + # pubkey.bytesize + pubkey
60
+ "21" + "020b16a7227f873ac68cf3140f1101d2eda5acb28bf3e7d546409139caf25142e4" + # pubkey.bytesize + pubkey
61
+ "53" + # OP_3
62
+ "ae" # OP_CHECKMULTISIG
63
+ end
64
+
65
+ it 'bitcoin p2sh address from bitcoin-hash160' do
66
+ Bitcoin::network = :testnet
67
+ Bitcoin.hash160_to_p2sh_address("d11e2f2f385efeecd30f867f1d55c0bc8a27f29e")
68
+ .should == "2NCJwNct2SVE5VwdrPXmnek59kCfdgCpxeF"
69
+
70
+ Bitcoin::network = :bitcoin
71
+ Bitcoin.hash160_to_p2sh_address("d11e2f2f385efeecd30f867f1d55c0bc8a27f29e")
72
+ .should == "3LkjJswzq2ijJA1JiQ9v2o5tXrTTvPtAMe"
73
+ end
74
+
75
+ it 'bitcoin-hash160 from bitcoin-address' do
76
+ Bitcoin::network = :testnet
77
+ Bitcoin.hash160_from_address("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt")
78
+ .should == "62e907b15cbf27d5425399ebf6f0fb50ebb88f18"
79
+ Bitcoin.hash160_from_address("totally-invalid").should == nil
80
+
81
+ Bitcoin::network = :bitcoin
82
+ Bitcoin.hash160_from_address("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa")
83
+ .should == "62e907b15cbf27d5425399ebf6f0fb50ebb88f18"
84
+
85
+ Bitcoin.hash160_from_address("11ofrrzv87Ls97jN4TUetfQp4gEsUSL7A")
86
+ .should == "0026f5494b39ea04b7bcb05e583acf3b0102d61f"
87
+ Bitcoin.hash160_from_address("11122RGUQSszAsTpptd2h8sdyYGR6nKs6f")
88
+ .should == "0000daec8d6f05e949710f202c4f73258aa7791e"
89
+ Bitcoin.hash160_from_address("11119uLoMQCBHmKevdsFKHMaUoyrwLa9Y")
90
+ .should == "00000090c66372823859c935149e2e32d276a1e6"
91
+ Bitcoin.hash160_from_address("1111136sgL8UNSTVL9ize2uGFPxFDGwFp")
92
+ .should == "0000000096d3ad65d030a36e2c23f7fdd5dfcadb"
93
+ end
94
+
95
+ it 'should survive rounds of hash160 <-> address' do
96
+ hex = "62e907b15cbf27d5425399ebf6f0fb50ebb88f18"
97
+
98
+ Bitcoin::network = :testnet
99
+ addr = "mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt"
100
+ Bitcoin.hash160_from_address(Bitcoin.hash160_to_address(hex)).should == hex
101
+ Bitcoin.hash160_to_address(Bitcoin.hash160_from_address(addr)).should == addr
102
+
103
+ Bitcoin::network = :bitcoin
104
+ addr = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
105
+ Bitcoin.hash160_from_address(Bitcoin.hash160_to_address(hex)).should == hex
106
+ Bitcoin.hash160_to_address(Bitcoin.hash160_from_address(addr)).should == addr
107
+ end
108
+
109
+ it '#address_checksum?' do
110
+ Bitcoin::network = :testnet
111
+ Bitcoin.address_checksum?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
112
+ Bitcoin.address_checksum?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == true
113
+ Bitcoin.address_checksum?("f0f0f0").should == false
114
+
115
+ Bitcoin::network = :bitcoin
116
+ Bitcoin.address_checksum?("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa").should == true
117
+ Bitcoin.address_checksum?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
118
+ Bitcoin.address_checksum?("f0f0f0").should == false
119
+ end
120
+
121
+ it 'validate bitcoin-address' do
122
+
123
+ Bitcoin::network = :testnet
124
+
125
+ Bitcoin.valid_address?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
126
+ Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == false
127
+ Bitcoin.valid_address?("1moYFpRM4LkTV4Ho5eCxiEPB2bSm3AsJNGj").should == false
128
+ Bitcoin.valid_address?("f0f0f0").should == false
129
+
130
+ Bitcoin::network = :bitcoin
131
+
132
+ Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == true
133
+ Bitcoin.valid_address?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == false
134
+ Bitcoin.valid_address?("2D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == false
135
+ Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cX").should == false
136
+ Bitcoin.valid_address?("1moYFpRM4LkTV4Ho5eCxiEPB2bSm3AsJNGj").should == false
137
+
138
+ Bitcoin.valid_address?("1ZQxJYBRmbb2rDNYPhd96x3eMbNnPD98q").should == true
139
+ Bitcoin.valid_address?("12KhCL8nGK3Luy7ehU3AxPs1mTocdessLM").should == true
140
+ Bitcoin.valid_address?("1AnNQgfaGgSKejzR6km74tyQPDGwZBBVT").should == true
141
+ Bitcoin.valid_address?("f0f0f0").should == false
142
+
143
+
144
+ Bitcoin.base58_to_int("114EpVhtPpJQKti8HiH2fvXZFPiPkgDZrE").should \
145
+ == 15016857106811133404017207799481956647721349092596212439
146
+
147
+ Bitcoin.network, success = :testnet, true
148
+ 400.times{
149
+ addr = Bitcoin.generate_address
150
+ success = false if Bitcoin.hash160_from_address(addr[0]) != addr[-1]
151
+ success = false if Bitcoin.hash160_to_address(addr[-1]) != addr[0]
152
+ success = false if Bitcoin.valid_address?(addr[0]) != true
153
+ }
154
+ success.should == true
155
+
156
+ Bitcoin.network, success = :bitcoin, true
157
+ 400.times{
158
+ addr = Bitcoin.generate_address
159
+ success = false if Bitcoin.hash160_from_address(addr[0]) != addr[-1]
160
+ success = false if Bitcoin.hash160_to_address(addr[-1]) != addr[0]
161
+ success = false if Bitcoin.valid_address?(addr[0]) != true
162
+ }
163
+ success.should == true
164
+ end
165
+
166
+ it 'validate bitcoin public key' do
167
+ key = Bitcoin::Key.generate
168
+ Bitcoin.valid_pubkey?(key.pub_compressed).should == true
169
+ Bitcoin.valid_pubkey?(key.pub_uncompressed).should == true
170
+ Bitcoin.valid_pubkey?(key.addr).should == false
171
+ Bitcoin.valid_pubkey?(key.priv).should == false
172
+ end
173
+
174
+ it 'validate p2sh address' do
175
+ Bitcoin.network = :testnet
176
+ Bitcoin.valid_address?("2MyLngQnhzjzatKsB7XfHYoP9e2XUXSiBMM").should == true
177
+ Bitcoin.network = :bitcoin
178
+ Bitcoin.valid_address?("3CkxTG25waxsmd13FFgRChPuGYba3ar36B").should == true
179
+ end
180
+
181
+ it '#address_type' do
182
+ Bitcoin.network = :testnet
183
+ Bitcoin.address_type("2MyLngQnhzjzatKsB7XfHYoP9e2XUXSiBMM").should == :p2sh
184
+ Bitcoin.address_type("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == :hash160
185
+ Bitcoin.address_type("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == nil
186
+ Bitcoin.network = :bitcoin
187
+ Bitcoin.address_type("3CkxTG25waxsmd13FFgRChPuGYba3ar36B").should == :p2sh
188
+ Bitcoin.address_type("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == :hash160
189
+ Bitcoin.address_type("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == nil
190
+ end
191
+
192
+ it 'Bitcoin#checksum' do
193
+ Bitcoin.checksum("0062e907b15cbf27d5425399ebf6f0fb50ebb88f18").should == "c29b7d93"
194
+ end
195
+
196
+ it '#bitcoin_mrkl' do
197
+ # block 170 is the first block that has a transaction.
198
+ # hash 00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee
199
+ a = "b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082"
200
+ b = "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16"
201
+ c = "7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
202
+
203
+ Bitcoin.bitcoin_hash(b + a) .should == c
204
+ Bitcoin.bitcoin_mrkl(a , b) .should == c
205
+ end
206
+
207
+ it 'mrkl_tree from transaction-hashes' do
208
+
209
+ # mrkl tree for block 170
210
+ mrkl_tree = [
211
+ "b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082",# tx 1
212
+ "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",# tx 2
213
+ "7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
214
+ ]
215
+ Bitcoin.hash_mrkl_tree(mrkl_tree[0...2]).should == mrkl_tree
216
+
217
+
218
+ mrkl_tree = [
219
+ "4fa598026d9be1ca0c2bff1b531e566b7ea7f90b72e75fda0c1795bc2dfa375c",
220
+ "186640daf908156e2616790d7c816235b0c43f668c3c38351b348c08ca44d457",
221
+ "ef3928700309b4deceac9a992a19a7481b4e520cbc0b1ab74e2645eee39c8da0",
222
+
223
+ "688c53517f62f7a65c0e87519c18a4de98f2ccafbf389b269d0bb867f88d166a",
224
+ "01889506f7fe9210045f588361881e2d16a034a62bc48ebd7b6b0a3edeaf5a6d",
225
+
226
+ "74f3a7df861d6a58957b84a3e425a8cf57e1e2e3a3def046dd200baeb8714f00"
227
+ ]
228
+
229
+ Bitcoin.hash_mrkl_tree( mrkl_tree[0...3] ).should == mrkl_tree
230
+
231
+ Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[3]
232
+ Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[2] ).should == mrkl_tree[4]
233
+ Bitcoin.bitcoin_mrkl( mrkl_tree[3], mrkl_tree[4] ).should == mrkl_tree[5]
234
+
235
+ mrkl_tree[0...3].each.with_index do |target, idx|
236
+ branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0...3], target )
237
+ Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
238
+ end
239
+
240
+ mrkl_tree = [
241
+ "349f717b6630e1f305f95964a2d94117dacca76e0b715d4d7a5657698ec96c6c", # 0
242
+ "7f44a84349200473455bcfc05ee68036e23993a6f58dce3f6a7faab46a754440", # 1
243
+ "6b3ba3fdfb7eeb6c2e5fd0e36e5bb4634da294521f7b1b808286c214981f9b17", # 2
244
+ "0467b41043d654ba3dc3940cbefec0eb38feed6e7085a8e825e4f782eccb48e3", # 3
245
+ "83d0231624f7a7d5c37557461ac0d09a8ad7a1f4ab673dd697acb275d4b114de", # 4
246
+ "074970aaa98db7d00e6f97a719fe85e9c7f51b75fa5a9a92218d568ccc2b21fe", # 5
247
+
248
+ "c1b6d2a416de6b63e42c1b50f229911bfb07f816e0795bb86ff7dcf0463ab0df", # 6
249
+ "751bcfd8acc10792f42050dca5b852f7a2fcd5300897d05907a98473f59a5650", # 7
250
+ "7abf551000d942efb93afc2d6174dc1bb7d41e8ea5fd76724685000734f1d77b", # 8
251
+
252
+ "e268927aa50d44de5365c11a2e402478767b7b98856a21a0715f9db65709aabb", # 9
253
+ "ed5ecc6b0e2fdd81be806599d6509d166e26849049e60e8d8b398641282b1e5a", # 10
254
+
255
+ "72e0e61880cc5fc9c7b5990c2d40b22eba783391b72807d2d5349fb55875c015" # 11
256
+ ]
257
+
258
+ Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[6]
259
+ Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[3] ).should == mrkl_tree[7]
260
+ Bitcoin.bitcoin_mrkl( mrkl_tree[4], mrkl_tree[5] ).should == mrkl_tree[8]
261
+
262
+ Bitcoin.bitcoin_mrkl( mrkl_tree[6], mrkl_tree[7] ).should == mrkl_tree[9]
263
+ Bitcoin.bitcoin_mrkl( mrkl_tree[8], mrkl_tree[8] ).should == mrkl_tree[10]
264
+
265
+ Bitcoin.bitcoin_mrkl( mrkl_tree[9], mrkl_tree[10] ).should == mrkl_tree[11]
266
+
267
+ Bitcoin.hash_mrkl_tree(mrkl_tree[0...6]).should == mrkl_tree
268
+
269
+ mrkl_tree[0...5].each.with_index do |target, idx|
270
+ branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0..5], target )
271
+ Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
272
+ end
273
+
274
+ mrkl_tree = [
275
+ "627c859b5af6d537930fd16148eb0597542bea543f65fc2b0e5f188b5a458529", # 0
276
+ "d00b90525820a74f30ce26488db7f77c6ee9577e650568a051edd8560bbf83a1", # 1
277
+ "706b8ac1a433bc28385450626e12c1c7806032dc8b7e12221f417c5f22059d70", # 2
278
+ "10107ad569400a5f9621498e410845e6db0551671a2cafcf4358bd7867c6bc14", # 3
279
+ "ac6b08a363aedd5e58177c7f68bb213403ef78d24be0012c06b3483a9e2461fe", # 4
280
+ "d3074f5b33a44d9961f40eadf250cdc1425f7975012fccb6b06abc5202c53f4b", # 5
281
+ "3270c13599266d3a8da90a85a07fc003c58a8ff2938988356783b6261be335a6", # 6
282
+ "e097c3e2e3a07385628ac5a5a775e8a5e22dda3732bee32ae65b1430d080fc32", # 7
283
+ "c335a3963e8d89a9f46b94158d33f9b0dee25e776cba91be5eda44898bd31a78", # 8
284
+
285
+ "eb52315c6b26f72fa58ed95cd4886f1aa047ecd8f34ed8a367f59854f20733d8", # 9
286
+ "f97bf49e42e1732c0b515ecbac7cffc29c8c75c20c6783ad48b09d348fe0b6cf", # 10
287
+ "fc655dfc41eed4e2ea4cfe33ebb6bf593eb256bf86c17802fd03567668d0bf71", # 11
288
+ "06c4abf5dae15d5fa3632e7e5f82f05e7afbbfd495ea8015c6094764d868654c", # 12
289
+ "31bbd6e4523aeaaaf75b6ea4ef63d0fe3dba66fb719f4a4232891a3b58ad5cec", # 13
290
+
291
+ "0c728622b795e14ac40c4aa13cb732a0407b2b85c9108c6f06c083220bb6d65d", # 14
292
+ "f83f6ea46edcbeaa738ce4701bf48412a10c4b1a9f109efe44bc8fe5cb6b0017", # 15
293
+ "5e6168778c8407ace3ae9901a2f5197d6f21a6634ae0af639e52d14c39b13e02", # 16
294
+
295
+ "b92a7980b8a8a64f896027c0de732298d04ca56bea66c18cf97983037486e456", # 17
296
+ "2a2fd5e450b6ec31ccbe9d827f2e903714eb69c351300b1e76c587aef60e000c", # 18
297
+
298
+ "9ed561bb49c47648e0250cb074721d94cba84ed1e083f1e57c29eca78e36d73d" # 19
299
+ ]
300
+
301
+ Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[9]
302
+ Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[3] ).should == mrkl_tree[10]
303
+ Bitcoin.bitcoin_mrkl( mrkl_tree[4], mrkl_tree[5] ).should == mrkl_tree[11]
304
+ Bitcoin.bitcoin_mrkl( mrkl_tree[6], mrkl_tree[7] ).should == mrkl_tree[12]
305
+ Bitcoin.bitcoin_mrkl( mrkl_tree[8], mrkl_tree[8] ).should == mrkl_tree[13]
306
+
307
+ Bitcoin.bitcoin_mrkl( mrkl_tree[9], mrkl_tree[10] ).should == mrkl_tree[14]
308
+ Bitcoin.bitcoin_mrkl( mrkl_tree[11], mrkl_tree[12] ).should == mrkl_tree[15]
309
+ Bitcoin.bitcoin_mrkl( mrkl_tree[13], mrkl_tree[13] ).should == mrkl_tree[16]
310
+
311
+ Bitcoin.bitcoin_mrkl( mrkl_tree[14], mrkl_tree[15] ).should == mrkl_tree[17]
312
+ Bitcoin.bitcoin_mrkl( mrkl_tree[16], mrkl_tree[16] ).should == mrkl_tree[18]
313
+
314
+ Bitcoin.bitcoin_mrkl( mrkl_tree[17], mrkl_tree[18] ).should == mrkl_tree[19]
315
+
316
+ Bitcoin.hash_mrkl_tree(mrkl_tree[0...9]).should == mrkl_tree
317
+
318
+ mrkl_tree[0..8].each.with_index do |target, idx|
319
+ branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0..8], target )
320
+ Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
321
+ end
322
+
323
+ end
324
+
325
+ it 'should not allow duplicate hash in merkle trees' do
326
+ Bitcoin.hash_mrkl_tree(["aa", "bb", "cc"]).last.should !=
327
+ Bitcoin.hash_mrkl_tree(["aa", "bb", "cc", "cc"]).last
328
+ end
329
+
330
+ it 'return a value even if a merkle branch is empty' do
331
+ branch = []
332
+ mrkl_index = 0
333
+ target = "089b911f5e471c0e1800f3384281ebec5b372fbb6f358790a92747ade271ccdf"
334
+ Bitcoin.mrkl_branch_root(branch.map(&:hth), target, mrkl_index).should == target
335
+ end
336
+
337
+ it 'nonce compact bits to bignum hex' do
338
+ Bitcoin.decode_compact_bits( "1b00b5ac".to_i(16) ).index(/[^0]/).should == 12
339
+ Bitcoin.decode_compact_bits( "1b00b5ac".to_i(16) ).to_i(16).should ==
340
+ "000000000000b5ac000000000000000000000000000000000000000000000000".to_i(16)
341
+
342
+
343
+ target = 453031340
344
+ Bitcoin.decode_compact_bits( target ).should ==
345
+ "000000000000b5ac000000000000000000000000000000000000000000000000"
346
+ Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
347
+
348
+ target = 486604799
349
+ Bitcoin.decode_compact_bits( target ).should ==
350
+ "00000000ffff0000000000000000000000000000000000000000000000000000"
351
+ Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
352
+
353
+ target = 476399191 # from block 40,320
354
+ Bitcoin.decode_compact_bits(target).should ==
355
+ "0000000065465700000000000000000000000000000000000000000000000000"
356
+ Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
357
+
358
+ #Bitcoin.network = :dogecoin
359
+ #Bitcoin.decode_compact_bits( "01fedcba".to_i(16) ).to_i(16).should == -0x7e
360
+ end
361
+
362
+ it '#block_hash' do
363
+ # block 0 n_tx: 1
364
+ prev_block="0000000000000000000000000000000000000000000000000000000000000000"
365
+ mrkl_root ="4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
366
+ time, bits, nonce, ver = 1231006505, 486604799, 2083236893, 1
367
+
368
+ Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
369
+ "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
370
+
371
+
372
+ # block 1 n_tx: 1
373
+ prev_block="000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
374
+ mrkl_root ="0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
375
+ time, bits, nonce, ver = 1231469665, 486604799, 2573394689, 1
376
+
377
+ Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
378
+ "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
379
+
380
+ # .. only n_tx: 1
381
+
382
+ # block 169 n_tx: 1
383
+ prev_block="00000000567e95797f93675ac23683ae3787b183bb36859c18d9220f3fa66a69"
384
+ mrkl_root ="d7b9a9da6becbf47494c27e913241e5a2b85c5cceba4b2f0d8305e0a87b92d98"
385
+ time, bits, nonce, ver = 1231730523, 486604799, 3718213931, 1
386
+
387
+ Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
388
+ "000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55"
389
+
390
+
391
+ # block 170 n_tx: 2
392
+ prev_block="000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55"
393
+ mrkl_root ="7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
394
+ time, bits, nonce, ver = 1231731025, 486604799, 1889418792, 1
395
+
396
+ Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
397
+ "00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee"
398
+
399
+
400
+ # block 171 n_tx: 1
401
+ prev_block="00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee"
402
+ mrkl_root ="d5f2d21453a6f0e67b5c42959c9700853e4c4d46fa7519d1cc58e77369c893f2"
403
+ time, bits, nonce, ver = 1231731401, 486604799, 653436935, 1
404
+ Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
405
+ "00000000c9ec538cab7f38ef9c67a95742f56ab07b0a37c5be6b02808dbfb4e0"
406
+ end
407
+
408
+ it 'generates openssl-secp256k1 private/public keypair' do
409
+ private_key, public_key = Bitcoin.generate_key
410
+
411
+ private_key.size .should == 64 # bytes in hex
412
+ public_key.size .should == 130 # bytes in hex
413
+
414
+ key = Bitcoin.open_key(private_key, public_key)
415
+ Bitcoin.inspect_key( key ).should == [ private_key, public_key ]
416
+ end
417
+
418
+ begin
419
+ Bitcoin::OpenSSL_EC
420
+ it 'opens key from private key and resolves public key' do
421
+ 50.times.all?{
422
+ private_key, public_key = Bitcoin.generate_key
423
+ key = Bitcoin.open_key(private_key)
424
+ [ key.private_key_hex, key.public_key_hex ] == [ private_key, public_key ]
425
+ }.should == true
426
+ end
427
+
428
+ it 'extract private key from uncompressed DER format' do
429
+ der = "308201130201010420a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6cd417b808db1ccd0aa081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a14403420004768cfc6c44b927b0e69e9dd343e96132f7cd1d360d8cb8d65c83d89d7beaceadfd19918e076606a099344156acdb026b1065a958e39f098cfd0a34dd976291d6"
430
+
431
+ Bitcoin::OpenSSL_EC.der_to_private_key(der).should == "a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6cd417b808db1ccd0a"
432
+ end
433
+
434
+ it 'sign and verify text messages (signmessage/verifymessage)' do
435
+ [
436
+ ["1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ", "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747",
437
+ "040b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a7447b5f0bba9e01e6fe4735c8383e6e7a3347a0fd72381b8f797a19f694054e5a69"],
438
+ ["1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs", "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747",
439
+ "030b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a744"]
440
+ ].each{|address, privkey, pubkey|
441
+ key = Bitcoin.open_key(privkey)
442
+ 16.times.each { |n|
443
+ #10_000.times.all?{|n|
444
+ # puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip if (n % 1_000) == 0
445
+ s = Bitcoin.sign_message(key.private_key_hex, key.public_key_hex, "Very secret message %d: 11" % n)
446
+ Bitcoin.verify_message(s['address'], 'invalid-signature', s['message']).should == false
447
+ Bitcoin.verify_message(s['address'], s['signature'], s['message']).should == true
448
+ }
449
+ }
450
+
451
+ Bitcoin.network = :testnet3
452
+ Bitcoin.verify_message("mwPVMbZQgkpwJJt2YP3sLSgbEBQw3FWZSc", "H5GER0Nz+L7TPZMQzXtv0hnLSsyfPok9lkdHIv01vksREpEpOhTPTonU1xvyPAOIIKhU3++Ol+LaWKWmsfyxDXk=", "A"*500).should == true
453
+ Bitcoin.network = :bitcoin
454
+ end
455
+ rescue LoadError
456
+ end
457
+
458
+ it 'generates new bitcoin-address' do
459
+ address, private_key, public_key, hash160 = Bitcoin.generate_address
460
+
461
+ private_key.size .should == 64 # bytes in hex
462
+ public_key.size .should == 130 # bytes in hex
463
+ #Bitcoin.valid_address?(address).should == true # fix/extend
464
+ Bitcoin.hash160_to_address(Bitcoin.hash160(public_key)).should == address
465
+ end
466
+
467
+ it 'encodes and decodes base58' do
468
+ # fixtures from: https://github.com/bitcoin/bitcoin/blob/master/src/test/base58_tests.cpp
469
+ bin = [
470
+ "",
471
+ "\x61",
472
+ "\x62\x62\x62",
473
+ "\x63\x63\x63",
474
+ "\x73\x69\x6d\x70\x6c\x79\x20\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67",
475
+ "\x00\xeb\x15\x23\x1d\xfc\xeb\x60\x92\x58\x86\xb6\x7d\x06\x52\x99\x92\x59\x15\xae\xb1\x72\xc0\x66\x47",
476
+ "\x51\x6b\x6f\xcd\x0f",
477
+ "\xbf\x4f\x89\x00\x1e\x67\x02\x74\xdd",
478
+ "\x57\x2e\x47\x94",
479
+ "\xec\xac\x89\xca\xd9\x39\x23\xc0\x23\x21",
480
+ "\x10\xc8\x51\x1e",
481
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
482
+ ]
483
+ out = [
484
+ "",
485
+ "2g",
486
+ "a3gV",
487
+ "aPEr",
488
+ "2cFupjhnEsSn59qHXstmK2ffpLv2",
489
+ "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L",
490
+ "ABnLTmg",
491
+ "3SEo3LWLoPntC",
492
+ "3EFU7m",
493
+ "EJDM8drfXA6uyA",
494
+ "Rt5zm",
495
+ "1111111111"
496
+ ]
497
+
498
+ fixtures = bin.zip(out).map{|b,out| [ b.unpack("H*")[0], out ] }
499
+ #fixtures.each{|hex,out| p [hex, out, Bitcoin.encode_base58(hex), Bitcoin.decode_base58(out)] }
500
+ fixtures.all?{|hex,out| Bitcoin.encode_base58(hex) == out }.should == true
501
+ fixtures.all?{|hex,out| Bitcoin.decode_base58(out) == hex }.should == true
502
+ end
503
+
504
+ it '#block_next_retarget' do
505
+ Bitcoin.block_next_retarget(189408).should == 189503
506
+ Bitcoin.block_next_retarget(189503).should == 189503
507
+ Bitcoin.block_next_retarget(189504).should == 191519
508
+ end
509
+
510
+ it '#block_difficulty' do
511
+ Bitcoin.block_difficulty(436835377).should == "1751454.5353407"
512
+ end
513
+
514
+ it 'should calculate retarget difficulty' do
515
+ prev_height = 201599
516
+ prev_block_time = 1349227021
517
+ prev_block_bits = 0x1a05db8b
518
+ last_retarget_time = 1348092851
519
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
520
+
521
+ Bitcoin.decode_compact_bits(new_difficulty.should) == Bitcoin.decode_compact_bits(0x1a057e08)
522
+ end
523
+
524
+ it '#block_hashes_to_win' do
525
+ Bitcoin.block_hashes_to_win(436835377).should == 7522554734795001
526
+ end
527
+
528
+ it '#block_probability' do
529
+ Bitcoin.block_probability(436835377).should ==
530
+ "0.0000000000000001329335625003267087884673003372881794348"
531
+ end
532
+
533
+ it '#block_average_hashing_time' do
534
+ Bitcoin.block_average_hashing_time(436835377, 630_000_000).should == 11940563
535
+ end
536
+
537
+ it '#block_average_mining_time' do
538
+ Bitcoin.block_average_mining_time(0x1a022fbe, 231337, 270.0, 1.0).should == 56.50855038530773 # days
539
+ end
540
+
541
+ it '#blockchain_total_btc' do
542
+ # 0.step(6930000, 210000){|height|
543
+ # p total_btc(height-1) unless height == 0
544
+ # p total_btc(height)
545
+ # }
546
+ [0, 209999, 210000, 419999, 420000, 1680000].map{|height|
547
+ Bitcoin.blockchain_total_btc(height)
548
+ }.should == [
549
+ [5000000000, 1, 5000000000, 0],
550
+ [1050000000000000, 1, 5000000000, 209999],
551
+ [1050005000000000, 2, 2500000000, 210000],
552
+ [1575002500000000, 2, 2500000000, 419999],
553
+ [1575005000000000, 3, 1250000000, 420000],
554
+ [2091801875000000, 9, 19531250, 1680000]
555
+ ]
556
+ end
557
+
558
+ it '#block_creation_reward' do
559
+ [0, 209999, 210000, 419999, 420000, 1680000].map{|height|
560
+ Bitcoin.block_creation_reward(height)
561
+ }.should == [ 5000000000, 5000000000, 2500000000, 2500000000, 1250000000, 19531250 ]
562
+ end
563
+
564
+ end
565
+
566
+
567
+ __END__
568
+ describe 'Bitcoin-Wiki - Common Standards - Hashes' do
569
+ # https://en.bitcoin.it/wiki/Protocol_specification
570
+ # Hashes
571
+ # Usually, when a hash is computed within bitcoin, it is computed twice.
572
+ # Most of the time SHA-256 hashes are used, however RIPEMD-160 is also
573
+ # used when a shorter hash is desirable.
574
+
575
+ require 'digest/sha2'
576
+ require 'digest/rmd160'
577
+
578
+
579
+ it 'double-SHA-256 encoding of string "hello"' do
580
+ # first round sha256
581
+ Digest::SHA256.hexdigest("hello").should ==
582
+ "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
583
+
584
+ # second round sha256
585
+ Digest::SHA256.hexdigest( Digest::SHA256.digest("hello") ).should ==
586
+ "9595c9df90075148eb06860365df33584b75bff782a510c6cd4883a419833d50"
587
+ end
588
+
589
+ it 'RIPEMD-160 encoding of string "hello"' do
590
+ # first round sha256
591
+ Digest::SHA256.hexdigest("hello").should ==
592
+ "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
593
+
594
+ # second round rmd160
595
+ Digest::RMD160.hexdigest( Digest::SHA256.digest("hello") ).should ==
596
+ "b6a9c8c230722b7c748331a8b450f05566dc7d0f"
597
+ end
598
+ end