monacoin-ruby 0.1.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 (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,23 @@
1
+ require_relative 'spec_helper.rb'
2
+
3
+ #
4
+ # following test cases are borrowed from
5
+ # https://github.com/bitcoinj/bitcoinj/blob/master/core/src/test/java/org/bitcoinj/core/BloomFilterTest.java
6
+ #
7
+ describe 'Bloom Filter' do
8
+ before do
9
+ @filter = Bitcoin::BloomFilter.new(3, 0.01, 2147483649)
10
+
11
+ @filter.add_data('99108ad8ed9bb6274d3980bab5a85c048f0950c8'.htb)
12
+ @filter.add_data('b5a2c786d9ef4658287ced5914b37a1b4aa32eee'.htb)
13
+ @filter.add_data('b9300670b4c5366e95b2699e8b18bc75e5f729c5'.htb)
14
+ end
15
+ it "#contains?" do
16
+ @filter.contains?('99108ad8ed9bb6274d3980bab5a85c048f0950c8'.htb).should == true
17
+ @filter.contains?('19108ad8ed9bb6274d3980bab5a85c048f0950c8'.htb).should == false
18
+ @filter.contains?('b5a2c786d9ef4658287ced5914b37a1b4aa32eee'.htb).should == true
19
+ end
20
+ it "#filter" do
21
+ @filter.filter.bth.should == 'ce4299'
22
+ end
23
+ end
@@ -0,0 +1,342 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ include Bitcoin::Builder
6
+
7
+ describe "Bitcoin::Builder" do
8
+
9
+ before do
10
+ Bitcoin.network = :spec
11
+ @keys = 5.times.map { Bitcoin::Key.generate }
12
+ @target = target = "00".ljust(64, 'f')
13
+ @genesis = create_block("00"*32, false)
14
+ @block = create_block(@genesis.hash, false, [], @keys[0])
15
+ end
16
+
17
+ it "should build blocks" do
18
+ block = build_block(@target) do |b|
19
+ b.prev_block @block.hash
20
+
21
+ b.tx do |t|
22
+ t.input {|i| i.coinbase "foobar" }
23
+
24
+ t.output do |o|
25
+ o.value 5000000000
26
+
27
+ o.script do |s|
28
+ s.type :address
29
+ s.recipient @keys[0].addr
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ block.hash[0..1].should == "00"
36
+ block.ver.should == 1
37
+ block.prev_block.should == @block.binary_hash.reverse
38
+ block.tx.size.should == 1
39
+ tx = block.tx[0]
40
+ tx.in.size.should == 1
41
+ tx.out.size.should == 1
42
+ tx.in[0].script_sig.should == ["foobar"].pack("H*")
43
+
44
+ tx.out[0].value.should == 5000000000
45
+ end
46
+
47
+ it "should build transactions with in/outputs and signatures" do
48
+ tx = build_tx do |t|
49
+ t.input do |i|
50
+ i.prev_out @block.tx[0]
51
+ i.prev_out_index 0
52
+ i.signature_key @keys[0]
53
+ end
54
+
55
+ t.output do |o|
56
+ o.value 123
57
+
58
+ o.script do |s|
59
+ s.type :address
60
+ s.recipient @keys[1].addr
61
+ end
62
+ end
63
+ end
64
+
65
+ tx.in[0].prev_out.reverse_hth.should == block.tx[0].hash
66
+ tx.in[0].prev_out_index.should == 0
67
+ Bitcoin::Script.new(tx.in[0].script_sig).chunks[1].unpack("H*")[0].should == @keys[0].pub
68
+
69
+ tx.out[0].value.should == 123
70
+ script = Bitcoin::Script.new(tx.out[0].pk_script)
71
+ script.type.should == :hash160
72
+ script.get_address.should == @keys[1].addr
73
+
74
+ tx.verify_input_signature(0, block.tx[0]).should == true
75
+
76
+
77
+ # check shortcuts also work
78
+ tx2 = build_tx do |t|
79
+ t.input {|i| i.prev_out @block.tx[0], 0; i.signature_key @keys[0] }
80
+ t.output {|o| o.value 123; o.script {|s| s.recipient @keys[1].addr } }
81
+ t.output {|o| o.to @keys[1].addr; o.value 321 }
82
+ t.output {|o| o.to "deadbeef", :op_return }
83
+ end
84
+ tx2.in[0].prev_out.should == tx.in[0].prev_out
85
+ tx2.in[0].prev_out_index.should == tx.in[0].prev_out_index
86
+ tx2.out[0].value.should == tx.out[0].value
87
+ tx2.out[0].pk_script.should == tx.out[0].pk_script
88
+ Bitcoin::Script.new(tx2.out[0].pk_script).to_string.should ==
89
+ "OP_DUP OP_HASH160 #{@keys[1].hash160} OP_EQUALVERIFY OP_CHECKSIG"
90
+ Bitcoin::Script.new(tx2.out[0].pk_script).to_string.should ==
91
+ "OP_DUP OP_HASH160 #{@keys[1].hash160} OP_EQUALVERIFY OP_CHECKSIG"
92
+ tx2.out[2].value.should == 0
93
+ end
94
+
95
+ it "should build transactions with p2wpkh signatures" do
96
+ key = Bitcoin::Key.new('619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9')
97
+ script_pubkey = '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb
98
+ tx = build_tx do |t|
99
+ t.input do |i|
100
+ i.prev_out '8ac60eb9575db5b2d987e29f301b5b819ea83a5c6579d282d189cc04b8e151ef', 1, script_pubkey, 600000000
101
+ i.signature_key key
102
+ end
103
+ end
104
+ tx.verify_witness_input_signature(0, script_pubkey, 600000000).should == true
105
+ end
106
+
107
+ it "should allow txin.prev_out as tx or hash" do
108
+ prev_tx = @block.tx[0]
109
+ tx1 = build_tx do |t|
110
+ t.input {|i| i.prev_out prev_tx, 0 }
111
+ end
112
+ tx2 = build_tx do |t|
113
+ t.input {|i| i.prev_out prev_tx.hash, 0, prev_tx.out[0].pk_script }
114
+ end
115
+ tx1.in[0].should == tx2.in[0]
116
+ end
117
+
118
+ it "should provide tx#output shortcut" do
119
+ tx1 = build_tx {|t| t.output(123, @keys[1].addr) }
120
+ tx1.should == build_tx do |t|
121
+ t.output {|o| o.value 123; o.to @keys[1].addr }
122
+ end
123
+
124
+ tx2 = build_tx {|t| t.output(123, @keys[1].pub, :pubkey) }
125
+ tx2.should == build_tx do |t|
126
+ t.output {|o| o.value 123; o.to @keys[1].pub, :pubkey }
127
+ end
128
+ end
129
+
130
+ it "should provide txout#to shortcut" do
131
+ tx1 = build_tx do |t|
132
+ t.output {|o| o.value 123; o.to @keys[1].addr }
133
+ end
134
+ tx2 = build_tx do |t|
135
+ t.output {|o| o.value 123
136
+ o.script {|s| s.recipient @keys[1].addr } }
137
+ end
138
+ tx1.out[0].should == tx2.out[0]
139
+ end
140
+
141
+ it "should build unsigned transactions and add the signature hash" do
142
+ tx = build_tx do |t|
143
+ t.input do |i|
144
+ i.prev_out @block.tx[0]
145
+ i.prev_out_index 0
146
+ # no signature key
147
+ end
148
+ t.output do |o|
149
+ o.value 123
150
+ o.script {|s| s.recipient @keys[1].addr }
151
+ end
152
+ end
153
+
154
+ tx.is_a?(Bitcoin::P::Tx).should == true
155
+ tx.in[0].sig_hash.should != nil
156
+ end
157
+
158
+ it "should build unsigned multisig transactions and add the signature hash" do
159
+ tx1 = build_tx do |t|
160
+ t.input {|i| i.prev_out(@block.tx[0], 0); i.signature_key(@keys[0]) }
161
+ t.output do |o|
162
+ o.value 123
163
+ o.to [2, *@keys[0..2].map(&:pub)], :multisig
164
+ end
165
+ end
166
+
167
+ tx2 = build_tx do |t|
168
+ t.input do |i|
169
+ i.prev_out tx1, 0
170
+ i.signature_key @keys[0]
171
+ end
172
+ t.output {|o| o.value 123; o.to @keys[0].addr }
173
+ end
174
+
175
+ tx2.is_a?(Bitcoin::P::Tx).should == true
176
+ tx2.in[0].sig_hash.should != nil
177
+ end
178
+
179
+ it "should build unsigned p2sh multisig transactions and add the signature hash" do
180
+ tx1 = build_tx do |t|
181
+ t.input {|i| i.prev_out(@block.tx[0], 0); i.signature_key(@keys[0]) }
182
+ t.output do |o|
183
+ o.value 123
184
+ o.to [2, *@keys[0..2].map(&:pub)], :p2sh_multisig
185
+ end
186
+ end
187
+
188
+ tx2 = build_tx do |t|
189
+ t.input do |i|
190
+ i.prev_out tx1, 0
191
+ i.signature_key @keys[0]
192
+ i.redeem_script tx1.out[0].redeem_script
193
+ end
194
+ t.output {|o| o.value 123; o.to @keys[0].addr }
195
+ end
196
+
197
+ tx2.is_a?(Bitcoin::P::Tx).should == true
198
+ tx2.in[0].sig_hash.should != nil
199
+ end
200
+
201
+ it "should add change output" do
202
+ change_address = Bitcoin::Key.generate.addr
203
+ tx = build_tx(input_value: @block.tx[0].out.map(&:value).inject(:+),
204
+ change_address: change_address) do |t|
205
+ t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @keys[0] }
206
+ t.output {|o| o.value 12345; o.script {|s| s.recipient @keys[1].addr } }
207
+ end
208
+ tx.out.count.should == 2
209
+ tx.out.last.value.should == 50e8 - 12345
210
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address.should == change_address
211
+ end
212
+
213
+ it "should add change output and leave fee" do
214
+ change_address = Bitcoin::Key.generate.addr
215
+ tx = build_tx(input_value: @block.tx[0].out.map(&:value).inject(:+),
216
+ change_address: change_address, leave_fee: true) do |t|
217
+ t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @keys[0] }
218
+ t.output {|o| o.value 12345; o.script {|s| s.recipient @keys[1].addr } }
219
+ end
220
+ tx.out.count.should == 2
221
+ tx.out.last.value.should == 50e8 - 12345 - Bitcoin.network[:min_tx_fee]
222
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address.should == change_address
223
+
224
+ tx = build_tx(input_value: @block.tx[0].out.map(&:value).inject(:+),
225
+ change_address: change_address, leave_fee: true) do |t|
226
+ t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @keys[0] }
227
+ 49.times { t.output {|o| o.value 1e8; o.script {|s| s.recipient @keys[1].addr } } }
228
+ t.output {|o| o.value(1e8 - 10000); o.script {|s| s.recipient @keys[1].addr } }
229
+ end
230
+ tx.out.size.should == 50
231
+ tx.out.map(&:value).inject(:+).should == 50e8 - 10000
232
+ end
233
+
234
+ it "randomize_outputs should not modify output values or fees" do
235
+ change_address = Bitcoin::Key.generate.addr
236
+ tx = build_tx(input_value: @block.tx[0].out.map(&:value).inject(:+),
237
+ change_address: change_address, leave_fee: true) do |t|
238
+ t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @keys[0] }
239
+ t.output {|o| o.value 12345; o.script {|s| s.recipient @keys[1].addr } }
240
+ t.randomize_outputs
241
+ end
242
+
243
+ tx.out.count.should == 2
244
+ tx.out.last.value.should == 50e8 - 12345 - Bitcoin.network[:min_tx_fee]
245
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address.should == change_address
246
+
247
+ tx = build_tx(input_value: @block.tx[0].out.map(&:value).inject(:+),
248
+ change_address: change_address, leave_fee: true) do |t|
249
+ t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @keys[0] }
250
+ 49.times { t.output {|o| o.value 1e8; o.script {|s| s.recipient @keys[1].addr } } }
251
+ t.output {|o| o.value(1e8 - 10000); o.script {|s| s.recipient @keys[1].addr } }
252
+ t.randomize_outputs
253
+ end
254
+ tx.out.size.should == 50
255
+ tx.out.map(&:value).inject(:+).should == 50e8 - 10000
256
+ end
257
+
258
+ it "should build op_return output" do
259
+ builder = TxOutBuilder.new
260
+ builder.to "deadbeef", :op_return
261
+ builder.txout.parsed_script.to_string.should == "OP_RETURN deadbeef"
262
+ end
263
+
264
+ it "should build op_return script" do
265
+ s = script {|s| s.type :op_return; s.recipient "deadbeef" }
266
+ Bitcoin::Script.new(s).to_string.should == "OP_RETURN deadbeef"
267
+ end
268
+
269
+ it "should build address script" do
270
+ key = Bitcoin::Key.generate
271
+ s = script {|s| s.type :address; s.recipient key.addr }
272
+ Bitcoin::Script.new(s).to_string.should ==
273
+ "OP_DUP OP_HASH160 #{Bitcoin.hash160_from_address(key.addr)} OP_EQUALVERIFY OP_CHECKSIG"
274
+ end
275
+
276
+ it "should build pubkey script" do
277
+ key = Bitcoin::Key.generate
278
+ s = script {|s| s.type :pubkey; s.recipient key.pub }
279
+ Bitcoin::Script.new(s).to_string.should == "#{key.pub} OP_CHECKSIG"
280
+ end
281
+
282
+ it "should build multisig script" do
283
+ keys = 3.times.map { Bitcoin::Key.generate }
284
+ s = script {|s| s.type :multisig; s.recipient 1, keys[0].pub, keys[1].pub }
285
+ Bitcoin::Script.new(s).to_string.should == "1 #{keys[0].pub} #{keys[1].pub} 2 OP_CHECKMULTISIG"
286
+ end
287
+
288
+ it "should build and spend multisig output" do
289
+ tx1 = build_tx do |t|
290
+ t.input {|i| i.prev_out(@block.tx[0], 0); i.signature_key(@keys[0]) }
291
+ t.output do |o|
292
+ o.value 123
293
+ o.to [2, *@keys[0..2].map(&:pub)], :multisig
294
+ end
295
+ end
296
+
297
+ Bitcoin::Script.new(tx1.out[0].pk_script).to_string.should ==
298
+ "2 #{@keys[0..2].map(&:pub).join(' ')} 3 OP_CHECKMULTISIG"
299
+
300
+ tx2 = build_tx do |t|
301
+ t.input do |i|
302
+ i.prev_out tx1, 0
303
+ i.signature_key @keys[0..1]
304
+ end
305
+ t.output {|o| o.value 123; o.to @keys[0].addr }
306
+ end
307
+
308
+ tx2.verify_input_signature(0, tx1).should == true
309
+ end
310
+
311
+ it "should build and spend p2sh multisig output" do
312
+ tx1 = build_tx do |t|
313
+ t.input {|i| i.prev_out(@block.tx[0], 0); i.signature_key(@keys[0]) }
314
+ t.output do |o|
315
+ o.value 123
316
+ o.to [2, *@keys[0..2].map(&:pub)], :p2sh_multisig
317
+ end
318
+ end
319
+
320
+ Bitcoin::Script.new(tx1.out[0].pk_script).to_string.should ==
321
+ "OP_HASH160 #{Bitcoin.hash160(tx1.out[0].redeem_script.hth)} OP_EQUAL"
322
+
323
+ tx2 = build_tx do |t|
324
+ t.input do |i|
325
+ i.prev_out tx1, 0
326
+ # provide 2 required keys for signing
327
+ i.signature_key @keys[0..1]
328
+ # provide the redeem script from the previous output
329
+ i.redeem_script tx1.out[0].redeem_script
330
+ end
331
+
332
+ t.output {|o| o.value 123; o.to @keys[0].addr }
333
+ end
334
+
335
+ script = Bitcoin::Script.new(tx2.in[0].script_sig, tx1.out[0].pk_script)
336
+ # check script execution is valid
337
+ script.run { true }.should == true
338
+ # check signatures are valid
339
+ tx2.verify_input_signature(0, tx1).should == true
340
+ end
341
+
342
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require_relative 'spec_helper.rb'
4
+
5
+ # https://github.com/aalness/contracthashtool-ruby
6
+ # ruby port of https://github.com/Blockstream/contracthashtool
7
+
8
+ describe 'Bitcoin::ContractHash' do
9
+ it 'should generate and claim' do
10
+ Bitcoin::network = :testnet3
11
+
12
+ # Example parameters from the original tool's usage().
13
+
14
+ redeem_script_template = '5121038695b28f1649c711aedb1fec8df54874334cfb7ddf31ba3132a94d00bdc9715251ae'
15
+ payee_address = 'mqWkEAFeQdrQvyaWNRn5vijPJeiQAjtxL2'
16
+ nonce_hex = '3a11be476485a6273fad4a0e09117d42'
17
+ private_key_wif = 'cMcpaCT6pHkyS4347i4rSmecaQtLiu1eH28NWmBiePn8bi6N4kzh'
18
+
19
+ # Someone wanting to send funds to the sidechain would call this
20
+ # to calculate a P2SH address to send to. They would then send the
21
+ # MDFs (mutually distrusting functionaries) the target address
22
+ # and nonce so they are able to locate the subsequent transaction.
23
+ # The caller would then send the desired amount of coin to the P2SH
24
+ # address to initiate the peg protocol.
25
+
26
+ nonce, redeem_script, p2sh_address = Bitcoin::ContractHash.generate(redeem_script_template, payee_address, nonce_hex)
27
+
28
+ nonce.should == "3a11be476485a6273fad4a0e09117d42"
29
+ p2sh_address.should == "2MvGPFfDXbJZyH79u187VNZbuCgyRBhcdsw"
30
+ redeem_script.should == "512102944aba05d40d8df1724f8ab2f5f3a58d052d26aedc93e175534cb782becc8ff751ae"
31
+
32
+ # Each MDF would call this to derive a private key to redeem the
33
+ # locked transaction.
34
+
35
+ key = Bitcoin::ContractHash.claim(private_key_wif, payee_address, nonce)
36
+ key.to_base58.should == "cSBD8yM62R82RfbugiGK8Lui9gdMB81NtZBckxe5YxRsDSKySwHK"
37
+
38
+ # Verify homomorphic derivation was successful.
39
+
40
+ signature = key.sign_message(message="derp")
41
+ script = Bitcoin::Script.new([redeem_script].pack("H*"))
42
+ pubkey = Bitcoin::Key.new(nil, script.get_multisig_pubkeys.first.unpack("H*").first)
43
+ pubkey.verify_message(signature, message).should == true
44
+ end
45
+ end
@@ -0,0 +1,176 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require_relative 'spec_helper.rb'
4
+ require 'bitcoin/script'
5
+
6
+ include Bitcoin
7
+ include Bitcoin::Builder
8
+
9
+ describe 'Bitcoin::Dogecoin' do
10
+ it 'validate dogecoin-address' do
11
+
12
+ Bitcoin::network = :dogecoin_testnet
13
+
14
+ # Testnet address
15
+ Bitcoin.valid_address?("nUtMFED5VRg5xuj9QCrNFt9mVPFDXo7TTE").should == true
16
+ # Livenet address
17
+ Bitcoin.valid_address?("DSpgzjPyfQB6ZzeSbMWpaZiTTxGf2oBCs4").should == false
18
+ # Broken address
19
+ Bitcoin.valid_address?("DRjyUS2uuieEPkhZNdQz8hE5YycxVEqSXA").should == false
20
+
21
+ Bitcoin::network = :dogecoin
22
+
23
+ # Testnet address
24
+ Bitcoin.valid_address?("nUtMFED5VRg5xuj9QCrNFt9mVPFDXo7TTE").should == false
25
+ # Livenet address
26
+ Bitcoin.valid_address?("DSpgzjPyfQB6ZzeSbMWpaZiTTxGf2oBCs4").should == true
27
+ # Broken address
28
+ Bitcoin.valid_address?("DRjyUS2uuieEPkhZNdQz8hE5YycxVEqSXA").should == false
29
+ end
30
+
31
+ it 'should calculate retarget difficulty' do
32
+ Bitcoin::network = :dogecoin
33
+
34
+ prev_height = 239
35
+ prev_block_time = 1386475638 # Block 239
36
+ prev_block_bits = 0x1e0ffff0
37
+ last_retarget_time = 1386474927 # Block 1
38
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
39
+ new_difficulty.to_s(16).should == 0x1e00ffff.to_s(16)
40
+
41
+ prev_height = 479
42
+ prev_block_time = 1386475840
43
+ prev_block_bits = 0x1e0fffff
44
+ last_retarget_time = 1386475638 # Block 239
45
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
46
+ new_difficulty.to_s(16).should == 0x1e00ffff.to_s(16)
47
+
48
+ prev_height = 9_599
49
+ prev_block_time = 1386954113
50
+ prev_block_bits = 0x1c1a1206
51
+ last_retarget_time = 1386942008 # Block 9359
52
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
53
+ new_difficulty.to_s(16).should == 0x1c15ea59.to_s(16)
54
+
55
+ # First hard-fork at 145,000, which applies to block 145,001 onwards
56
+ prev_height = 145_000
57
+ prev_block_time = 1395094679
58
+ prev_block_bits = 0x1b499dfd
59
+ last_retarget_time = 1395094427
60
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
61
+ new_difficulty.to_s(16).should == 0x1b671062.to_s(16)
62
+
63
+ # Test case for correct rounding of modulated time - by default C++ and Ruby do not
64
+ # necessarily round identically
65
+ prev_height = 145_001
66
+ prev_block_time = 1395094727
67
+ prev_block_bits = 0x1b671062
68
+ last_retarget_time = 1395094679
69
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
70
+ new_difficulty.to_s(16).should == 0x1b6558a4.to_s(16)
71
+
72
+ # Test the second hard-fork at 371,337 as well
73
+ prev_height = 371336
74
+ prev_block_time = 1410464569
75
+ prev_block_bits = 0x1b2fdf75
76
+ last_retarget_time = 1410464445
77
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
78
+ new_difficulty.to_s(16).should == 0x1b364184.to_s(16)
79
+
80
+ prev_height = 408_596
81
+ prev_block_time = 1412800112
82
+ prev_block_bits = 0x1b033d8b
83
+ last_retarget_time = 1412799989 # Block 408,595
84
+ new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
85
+ new_difficulty.to_s(16).should == 0x1b039e52.to_s(16)
86
+ end
87
+
88
+ it 'should calculate reward upper bounds' do
89
+ Bitcoin::network = :dogecoin
90
+
91
+ Bitcoin.block_creation_reward(99000).should == 1000000 * COIN # Note this is the maximum possible, not actual reward
92
+ Bitcoin.block_creation_reward(144999).should == 500000 * COIN
93
+ Bitcoin.block_creation_reward(145000).should == 250000 * COIN # Hard-forked to remove random rewards
94
+ Bitcoin.block_creation_reward(199999).should == 250000 * COIN
95
+ Bitcoin.block_creation_reward(299999).should == 125000 * COIN
96
+ Bitcoin.block_creation_reward(399999).should == 62500 * COIN
97
+ Bitcoin.block_creation_reward(499999).should == 31250 * COIN
98
+ Bitcoin.block_creation_reward(599999).should == 15625 * COIN
99
+ Bitcoin.block_creation_reward(600000).should == 10000 * COIN
100
+ Bitcoin.block_creation_reward(700000).should == 10000 * COIN
101
+ end
102
+
103
+ it 'should calculate merkle root from AuxPoW transaction branch' do
104
+ # Taken directly from Dogecoin block #403,931
105
+
106
+ # Branch stored as bytes to reflect how data is stored in AuxPow class
107
+ branch = [
108
+ "\xbe\x07\x90\x78\x86\x93\x99\xfa\xcc\xaa\x76\x4c\x10\xe9\xdf\x6e\x99\x81\x70\x17\x59\xad\x18\xe1\x37\x24\xd9\xca\x58\x83\x13\x48",
109
+ "\x5f\x5b\xfb\x2c\x79\x54\x17\x78\x49\x9c\xab\x95\x6a\x10\x38\x87\x14\x7f\x2a\xb5\xd4\xa7\x17\xf3\x2f\x9e\xee\xbd\x29\xe1\xf8\x94",
110
+ "\xd8\xc6\xfe\x42\xca\x25\x07\x61\x59\xcd\x12\x1a\x5e\x20\xc4\x8c\x1b\xc5\x3a\xb9\x07\x30\x08\x3e\x44\xa3\x34\x56\x6e\xa6\xbb\xcb"
111
+ ]
112
+ mrkl_index = 0
113
+ target = "089b911f5e471c0e1800f3384281ebec5b372fbb6f358790a92747ade271ccdf" # Coinbase TX ID
114
+ Bitcoin.mrkl_branch_root(branch.map(&:hth), target, mrkl_index).should == "f29cd14243ed542d9a0b495efcb9feca1b208bb5b717dc5ac04f068d2fef595a"
115
+ end
116
+
117
+ it 'should calculate merkle root from AuxPoW branch' do
118
+ # Taken directly from Dogecoin block #403,931
119
+
120
+ # Branch stored as bytes to reflect how data is stored in AuxPow class
121
+ aux_branch = [
122
+ "\x47\xa0\x22\x8b\x06\xc9\x36\x8f\x96\xc5\xf0\x4e\xb1\x09\xf8\x2c\xef\x36\xda\xe7\xc1\xbf\x25\x4c\x1a\x3f\x78\x61\x5e\xb0\xbe\x83",
123
+ "\xee\x67\xde\x31\x75\x76\x58\xdd\xd7\x40\x3e\x1a\x35\xd9\xc0\x6a\x5a\x13\xe6\x68\x98\x44\x3b\x45\x8c\xd6\xa7\x1b\x66\x27\x41\x6c",
124
+ "\xab\x9e\xf9\xbd\xa0\x2c\xad\x27\x90\xef\x9b\xb7\xc9\xa0\x7f\xe1\x79\x1a\x9d\x5a\xe0\x43\x09\xc0\xe9\x06\x48\x19\x19\x4c\x28\x31",
125
+ "\xff\x51\x61\x01\x80\xf6\x4d\x33\xa8\xc1\xba\x1d\xd9\xa9\xd0\x40\x48\x88\xc9\x6e\xaf\xd1\x57\x03\x64\x35\x8b\xbe\x99\x8f\x2d\xfe",
126
+ "\x9e\xe4\x18\x36\x7c\x3b\xce\x06\x5e\x7c\x01\x61\x29\x6e\xaa\x0d\x54\x96\xf9\x0f\x8b\x7b\x24\xeb\xf7\x2c\xc4\xba\xa5\x60\x9a\x1f",
127
+ "\x0b\x35\xf3\x73\x10\xe1\xde\x3f\xa4\xe1\x37\x7c\x02\x12\x62\x20\xe1\x64\xfa\x59\xec\xfe\xdc\xf4\x71\x4e\x61\xad\x74\xcc\x4b\x08"
128
+ ]
129
+ aux_mrkl_index = 56
130
+ target = "0c836b86991631d34a8a68054e2f62db919b39d1ee43c27ab3344d6aa82fa609" # Block hash
131
+ Bitcoin.mrkl_branch_root(aux_branch.map(&:hth), target, aux_mrkl_index).should == "ce3040fdb7e37484f6a1ca4f8f5da81e6b7e404ec91102315a233e03a0c39c95" # Merkle root in coinbase script
132
+ end
133
+
134
+ it 'parse AuxPoW' do
135
+ Bitcoin::network = :dogecoin
136
+
137
+ block_hash = "60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053"
138
+ data = fixtures_file("dogecoin-block-#{block_hash}.bin")
139
+ block = P::Block.new(data)
140
+ aux_pow = block.aux_pow
141
+ aux_pow.nil?.should == false
142
+ aux_pow.coinbase_index.should == 0
143
+
144
+ parent_block_merkle_root = Bitcoin.mrkl_branch_root(aux_pow.coinbase_branch, aux_pow.coinbase_tx.hash, aux_pow.coinbase_index)
145
+ parent_block_merkle_root.should == aux_pow.parent_block.mrkl_root.reverse.unpack("H*")[0]
146
+
147
+ # Find the merged mining header in the coinbase input script
148
+ merged_mining_header = "\xfa\xbemm"
149
+ script = aux_pow.coinbase_tx.in[0].script
150
+ header_idx = script.index(merged_mining_header)
151
+
152
+ header_idx.should == 4
153
+
154
+ chain_merkle_root = Bitcoin.mrkl_branch_root(aux_pow.chain_branch, block_hash, aux_pow.chain_index)
155
+
156
+ # Drop everything up to the merged mining data
157
+ script = script.slice(header_idx + merged_mining_header.length, chain_merkle_root.length / 2 + 8)
158
+
159
+ tx_root_hash = script.slice(0, chain_merkle_root.length / 2).unpack("H*")[0]
160
+ chain_merkle_root.should == tx_root_hash
161
+
162
+ merkle_branch_size = script.slice(chain_merkle_root.length / 2, 4).unpack("V")[0]
163
+ merkle_branch_size.should == (1 << aux_pow.chain_branch.length)
164
+
165
+ # Choose a pseudo-random slot in the chain merkle tree
166
+ # but have it be fixed for a size/nonce/chain combination.
167
+ nonce = script.slice(chain_merkle_root.length / 2 + 4, 4).unpack("V")[0]
168
+ rand = nonce
169
+ rand = rand * 1103515245 + 12345
170
+ rand += Bitcoin.network[:auxpow_chain_id]
171
+ rand = rand * 1103515245 + 12345
172
+
173
+ aux_pow.chain_index.should == (rand % merkle_branch_size)
174
+ end
175
+
176
+ end