bitcoin-ruby 0.0.18 → 0.0.19

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 (255) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +8 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +46 -0
  5. data/.travis.yml +5 -1
  6. data/Gemfile +11 -9
  7. data/Gemfile.lock +64 -12
  8. data/README.rdoc +17 -4
  9. data/Rakefile +58 -83
  10. data/bitcoin-ruby.gemspec +5 -2
  11. data/lib/bitcoin.rb +31 -14
  12. data/lib/bitcoin/bech32.rb +126 -132
  13. data/lib/bitcoin/bloom_filter.rb +24 -21
  14. data/lib/bitcoin/builder.rb +168 -126
  15. data/lib/bitcoin/connection.rb +21 -24
  16. data/lib/bitcoin/contracthash.rb +20 -24
  17. data/lib/bitcoin/dogecoin.rb +79 -77
  18. data/lib/bitcoin/electrum/mnemonic.rb +28 -25
  19. data/lib/bitcoin/ext_key.rb +3 -3
  20. data/lib/bitcoin/ffi/bitcoinconsensus.rb +17 -13
  21. data/lib/bitcoin/ffi/openssl.rb +355 -338
  22. data/lib/bitcoin/ffi/secp256k1.rb +97 -64
  23. data/lib/bitcoin/protocol.rb +6 -3
  24. data/lib/bitcoin/protocol/address.rb +15 -13
  25. data/lib/bitcoin/protocol/aux_pow.rb +12 -15
  26. data/lib/bitcoin/protocol/block.rb +102 -76
  27. data/lib/bitcoin/protocol/handler.rb +2 -4
  28. data/lib/bitcoin/protocol/parser.rb +108 -92
  29. data/lib/bitcoin/protocol/partial_merkle_tree.rb +59 -47
  30. data/lib/bitcoin/protocol/reject.rb +26 -28
  31. data/lib/bitcoin/protocol/script_witness.rb +3 -8
  32. data/lib/bitcoin/protocol/tx.rb +250 -137
  33. data/lib/bitcoin/protocol/txin.rb +44 -38
  34. data/lib/bitcoin/protocol/txout.rb +27 -20
  35. data/lib/bitcoin/protocol/version.rb +47 -34
  36. data/lib/bitcoin/script.rb +18 -17
  37. data/lib/bitcoin/trezor/mnemonic.rb +113 -98
  38. data/lib/bitcoin/version.rb +1 -1
  39. data/spec/examples.txt +399 -0
  40. data/spec/{bitcoin/fixtures → fixtures}/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +0 -0
  41. data/spec/{bitcoin/fixtures → fixtures}/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +0 -0
  42. data/spec/{bitcoin/fixtures → fixtures}/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +0 -0
  43. data/spec/{bitcoin/fixtures → fixtures}/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +0 -0
  44. data/spec/{bitcoin/fixtures → fixtures}/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +0 -0
  45. data/spec/{bitcoin/fixtures → fixtures}/23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63.json +0 -0
  46. data/spec/{bitcoin/fixtures → fixtures}/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +0 -0
  47. data/spec/{bitcoin/fixtures → fixtures}/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +0 -0
  48. data/spec/{bitcoin/fixtures → fixtures}/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +0 -0
  49. data/spec/{bitcoin/fixtures → fixtures}/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +0 -0
  50. data/spec/{bitcoin/fixtures → fixtures}/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +0 -0
  51. data/spec/{bitcoin/fixtures → fixtures}/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +0 -0
  52. data/spec/{bitcoin/fixtures → fixtures}/60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1.json +0 -0
  53. data/spec/{bitcoin/fixtures → fixtures}/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +0 -0
  54. data/spec/{bitcoin/fixtures → fixtures}/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +0 -0
  55. data/spec/{bitcoin/fixtures → fixtures}/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +0 -0
  56. data/spec/{bitcoin/fixtures → fixtures}/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +0 -0
  57. data/spec/{bitcoin/fixtures → fixtures}/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +0 -0
  58. data/spec/{bitcoin/fixtures → fixtures}/base58_keys_invalid.json +0 -0
  59. data/spec/{bitcoin/fixtures → fixtures}/base58_keys_valid.json +0 -0
  60. data/spec/{bitcoin/fixtures → fixtures}/bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba.json +0 -0
  61. data/spec/{bitcoin/fixtures → fixtures}/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +0 -0
  62. data/spec/{bitcoin/fixtures → fixtures}/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
  63. data/spec/{bitcoin/fixtures → fixtures}/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +0 -0
  64. data/spec/{bitcoin/fixtures → fixtures}/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +0 -0
  65. data/spec/{bitcoin/fixtures → fixtures}/coinbase-toshi.json +0 -0
  66. data/spec/{bitcoin/fixtures → fixtures}/coinbase.json +0 -0
  67. data/spec/{bitcoin/fixtures → fixtures}/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
  68. data/spec/{bitcoin/fixtures → fixtures}/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +0 -0
  69. data/spec/{bitcoin/fixtures → fixtures}/filteredblock-0.bin +0 -0
  70. data/spec/{bitcoin/fixtures → fixtures}/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
  71. data/spec/{bitcoin/fixtures → fixtures}/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +0 -0
  72. data/spec/{bitcoin/fixtures → fixtures}/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
  73. data/spec/{bitcoin/fixtures → fixtures}/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +0 -0
  74. data/spec/{bitcoin/fixtures → fixtures}/litecoin-tx-f5aa30f574e3b6f1a3d99c07a6356ba812aabb9661e1d5f71edff828cbd5c996.json +0 -0
  75. data/spec/{bitcoin/fixtures → fixtures}/rawblock-0.bin +0 -0
  76. data/spec/{bitcoin/fixtures → fixtures}/rawblock-0.json +0 -0
  77. data/spec/{bitcoin/fixtures → fixtures}/rawblock-1.bin +0 -0
  78. data/spec/{bitcoin/fixtures → fixtures}/rawblock-1.json +0 -0
  79. data/spec/{bitcoin/fixtures → fixtures}/rawblock-131025.bin +0 -0
  80. data/spec/{bitcoin/fixtures → fixtures}/rawblock-131025.json +0 -0
  81. data/spec/{bitcoin/fixtures → fixtures}/rawblock-170.bin +0 -0
  82. data/spec/{bitcoin/fixtures → fixtures}/rawblock-9.bin +0 -0
  83. data/spec/{bitcoin/fixtures → fixtures}/rawblock-auxpow.bin +0 -0
  84. data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-1151351.bin +0 -0
  85. data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-26478.bin +0 -0
  86. data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-26478.json +0 -0
  87. data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-265322.bin +0 -0
  88. data/spec/{bitcoin/fixtures → fixtures}/rawtx-01-toshi.json +0 -0
  89. data/spec/{bitcoin/fixtures → fixtures}/rawtx-01.bin +0 -0
  90. data/spec/{bitcoin/fixtures → fixtures}/rawtx-01.json +0 -0
  91. data/spec/{bitcoin/fixtures → fixtures}/rawtx-02-toshi.json +0 -0
  92. data/spec/{bitcoin/fixtures → fixtures}/rawtx-02.bin +0 -0
  93. data/spec/{bitcoin/fixtures → fixtures}/rawtx-02.json +0 -0
  94. data/spec/{bitcoin/fixtures → fixtures}/rawtx-03-toshi.json +0 -0
  95. data/spec/{bitcoin/fixtures → fixtures}/rawtx-03.bin +0 -0
  96. data/spec/{bitcoin/fixtures → fixtures}/rawtx-03.json +0 -0
  97. data/spec/{bitcoin/fixtures → fixtures}/rawtx-04.json +0 -0
  98. data/spec/{bitcoin/fixtures → fixtures}/rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin +0 -0
  99. data/spec/{bitcoin/fixtures → fixtures}/rawtx-05.json +0 -0
  100. data/spec/{bitcoin/fixtures → fixtures}/rawtx-14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984.bin +0 -0
  101. data/spec/{bitcoin/fixtures → fixtures}/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin +0 -0
  102. data/spec/{bitcoin/fixtures → fixtures}/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json +0 -0
  103. data/spec/{bitcoin/fixtures → fixtures}/rawtx-406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602.json +0 -0
  104. data/spec/{bitcoin/fixtures → fixtures}/rawtx-52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2.bin +0 -0
  105. data/spec/{bitcoin/fixtures → fixtures}/rawtx-b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d.bin +0 -0
  106. data/spec/{bitcoin/fixtures → fixtures}/rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json +0 -0
  107. data/spec/{bitcoin/fixtures → fixtures}/rawtx-c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73.json +0 -0
  108. data/spec/{bitcoin/fixtures → fixtures}/rawtx-de35d060663750b3975b7997bde7fb76307cec5b270d12fcd9c4ad98b279c28c.json +0 -0
  109. data/spec/{bitcoin/fixtures → fixtures}/rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin +0 -0
  110. data/spec/{bitcoin/fixtures → fixtures}/rawtx-p2wpkh.bin +0 -0
  111. data/spec/{bitcoin/fixtures → fixtures}/rawtx-p2wpkh.json +0 -0
  112. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
  113. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
  114. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
  115. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
  116. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-a220adf1902c46a39db25a24bc4178b6a88440f977a7e2cabfdd8b5c1dd35cfb.json +0 -0
  117. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
  118. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.bin +0 -0
  119. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.json +0 -0
  120. data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
  121. data/spec/{bitcoin/fixtures → fixtures}/script_tests.json +0 -0
  122. data/spec/{bitcoin/fixtures → fixtures}/sighash.json +0 -0
  123. data/spec/{bitcoin/fixtures → fixtures}/tx-0295028ef826b2a188409cb905b631faebb9bb3cdf14510571c5f4bd8591338f.json +0 -0
  124. data/spec/{bitcoin/fixtures → fixtures}/tx-03339a725007a279484fb6f5361f522dd1cf4d0923d30e6b973290dba4275f92.json +0 -0
  125. data/spec/{bitcoin/fixtures → fixtures}/tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json +0 -0
  126. data/spec/{bitcoin/fixtures → fixtures}/tx-0ce7e5238fbdb6c086cf1b384b21b827e91cc23f360417265874a5a0d86ce367.json +0 -0
  127. data/spec/{bitcoin/fixtures → fixtures}/tx-0ef34c49f630aea17df0080728b0fc67bf5f87fbda936934a4b11b4a69d7821e.json +0 -0
  128. data/spec/{bitcoin/fixtures → fixtures}/tx-1129d2a8bd5bb3a81e54dc96a90f1f6b2544575748caa17243470935c5dd91b7.json +0 -0
  129. data/spec/{bitcoin/fixtures → fixtures}/tx-19aa42fee0fa57c45d3b16488198b27caaacc4ff5794510d0c17f173f05587ff.json +0 -0
  130. data/spec/{bitcoin/fixtures → fixtures}/tx-1a4f3b9dc4494aeedeb39f30dd37e60541b2abe3ed4977992017cc0ad4f44956.json +0 -0
  131. data/spec/{bitcoin/fixtures → fixtures}/tx-1f9191dcf2b1844ca28c6ef4b969e1d5fab70a5e3c56b7007949e55851cb0c4f.json +0 -0
  132. data/spec/{bitcoin/fixtures → fixtures}/tx-22cd5fef23684d7b304e119bedffde6f54538d3d54a5bfa237e20dc2d9b4b5ad.json +0 -0
  133. data/spec/{bitcoin/fixtures → fixtures}/tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json +0 -0
  134. data/spec/{bitcoin/fixtures → fixtures}/tx-2958fb00b4fd6fe0353503b886eb9a193d502f4fd5fc042d5e03216ba918bbd6.json +0 -0
  135. data/spec/{bitcoin/fixtures → fixtures}/tx-29f277145749ad6efbed3ae6ce301f8d33c585ec26b7c044ad93c2f866e9e942.json +0 -0
  136. data/spec/{bitcoin/fixtures → fixtures}/tx-2c5e5376c20e9cc78d0fb771730e5d840cc2096eff0ef045b599fe92475ace1c.json +0 -0
  137. data/spec/{bitcoin/fixtures → fixtures}/tx-2c63aa814701cef5dbd4bbaddab3fea9117028f2434dddcdab8339141e9b14d1.json +0 -0
  138. data/spec/{bitcoin/fixtures → fixtures}/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +0 -0
  139. data/spec/{bitcoin/fixtures → fixtures}/tx-326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e.json +0 -0
  140. data/spec/{bitcoin/fixtures → fixtures}/tx-345bed8785c3282a264ffb0dbee61cde54854f10e16f1b3e75b7f2d9f62946f2.json +0 -0
  141. data/spec/{bitcoin/fixtures → fixtures}/tx-39ba7440b7103557560cc8ce258009936796485aaf8b478e66ab4cb97c66e31b.json +0 -0
  142. data/spec/{bitcoin/fixtures → fixtures}/tx-3a04d57a833367f1655cc5ec3beb587888ef4977a86caa8c8ad4ba7cc717eae7.json +0 -0
  143. data/spec/{bitcoin/fixtures → fixtures}/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +0 -0
  144. data/spec/{bitcoin/fixtures → fixtures}/tx-4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9.json +0 -0
  145. data/spec/{bitcoin/fixtures → fixtures}/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +0 -0
  146. data/spec/{bitcoin/fixtures → fixtures}/tx-46224764c7870f95b58f155bce1e38d4da8e99d42dbb632d0dd7c07e092ee5aa.json +0 -0
  147. data/spec/{bitcoin/fixtures → fixtures}/tx-5df1375ffe61ac35ca178ebb0cab9ea26dedbd0e96005dfcee7e379fa513232f.json +0 -0
  148. data/spec/{bitcoin/fixtures → fixtures}/tx-62d9a565bd7b5344c5352e3e9e5f40fa4bbd467fa19c87357216ec8777ba1cce.json +0 -0
  149. data/spec/{bitcoin/fixtures → fixtures}/tx-6327783a064d4e350c454ad5cd90201aedf65b1fc524e73709c52f0163739190.json +0 -0
  150. data/spec/{bitcoin/fixtures → fixtures}/tx-6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba.json +0 -0
  151. data/spec/{bitcoin/fixtures → fixtures}/tx-6aaf18b9f1283b939d8e5d40ff5f8a435229f4178372659cc3a0bce4e262bf78.json +0 -0
  152. data/spec/{bitcoin/fixtures → fixtures}/tx-6b48bba6f6d2286d7ec0883c0fc3085955090813a4c94980466611c798b868cc.json +0 -0
  153. data/spec/{bitcoin/fixtures → fixtures}/tx-70cfbc6690f9ab46712db44e3079ac227962b2771a9341d4233d898b521619ef.json +0 -0
  154. data/spec/{bitcoin/fixtures → fixtures}/tx-7a1a9db42f065f75110fcdb1bc415549c8ef7670417ba1d35a67f1b8adc562c1.json +0 -0
  155. data/spec/{bitcoin/fixtures → fixtures}/tx-9a768fc7d0c4bdc86e25154357ef7c0063ca21310e5740a2f12f90b7455184a7.json +0 -0
  156. data/spec/{bitcoin/fixtures → fixtures}/tx-9cad8d523a0694f2509d092c39cebc8046adae62b4e4297102d568191d9478d8.json +0 -0
  157. data/spec/{bitcoin/fixtures → fixtures}/tx-9e052eb694bd7e15906433f064dff0161a12fd325c1124537766377004023c6f.json +0 -0
  158. data/spec/{bitcoin/fixtures → fixtures}/tx-9fb65b7304aaa77ac9580823c2c06b259cc42591e5cce66d76a81b6f51cc5c28.json +0 -0
  159. data/spec/{bitcoin/fixtures → fixtures}/tx-a6ce7081addade7676cd2af75c4129eba6bf5e179a19c40c7d4cf6a5fe595954.json +0 -0
  160. data/spec/{bitcoin/fixtures → fixtures}/tx-a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944.json +0 -0
  161. data/spec/{bitcoin/fixtures → fixtures}/tx-aab7ef280abbb9cc6fbaf524d2645c3daf4fcca2b3f53370e618d9cedf65f1f8.json +0 -0
  162. data/spec/{bitcoin/fixtures → fixtures}/tx-ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742.json +0 -0
  163. data/spec/{bitcoin/fixtures → fixtures}/tx-ad4bcf3241e5d2ad140564e20db3567d41594cf4c2012433fe46a2b70e0d87b8.json +0 -0
  164. data/spec/{bitcoin/fixtures → fixtures}/tx-b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9.json +0 -0
  165. data/spec/{bitcoin/fixtures → fixtures}/tx-b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d.json +0 -0
  166. data/spec/{bitcoin/fixtures → fixtures}/tx-bbca0628c42cb8bf7c3f4b2ad688fa56da5308dd2a10255da89fb1f46e6e413d.json +0 -0
  167. data/spec/{bitcoin/fixtures → fixtures}/tx-bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224.json +0 -0
  168. data/spec/{bitcoin/fixtures → fixtures}/tx-c192b74844e4837a34c4a5a97b438f1c111405b01b99e2d12b7c96d07fc74c04.json +0 -0
  169. data/spec/{bitcoin/fixtures → fixtures}/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +0 -0
  170. data/spec/{bitcoin/fixtures → fixtures}/tx-e335562f7e297aadeed88e5954bc4eeb8dc00b31d829eedb232e39d672b0c009.json +0 -0
  171. data/spec/{bitcoin/fixtures → fixtures}/tx-eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb.json +0 -0
  172. data/spec/{bitcoin/fixtures → fixtures}/tx-fee1b9b85531c8fb6cd7831f83490c7f2aa768b6eefe29854ef5e89ce7b9ecb1.json +0 -0
  173. data/spec/{bitcoin/fixtures → fixtures}/txscript-invalid-too-many-sigops-followed-by-invalid-pushdata.bin +0 -0
  174. data/spec/helpers/block_helpers.rb +58 -0
  175. data/spec/helpers/fixture_helpers.rb +20 -0
  176. data/spec/helpers/library_helpers.rb +15 -0
  177. data/spec/spec_helper.rb +109 -0
  178. data/spec/unit/bitcoin/bech32_spec.rb +187 -0
  179. data/spec/unit/bitcoin/bitcoin_spec.rb +1079 -0
  180. data/spec/unit/bitcoin/bloom_filter_spec.rb +33 -0
  181. data/spec/unit/bitcoin/builder_spec.rb +559 -0
  182. data/spec/unit/bitcoin/contracthash_spec.rb +52 -0
  183. data/spec/unit/bitcoin/ext_key_spec.rb +281 -0
  184. data/spec/unit/bitcoin/key_spec.rb +457 -0
  185. data/spec/unit/bitcoin/network_spec.rb +71 -0
  186. data/spec/unit/bitcoin/protocol/addr_spec.rb +90 -0
  187. data/spec/unit/bitcoin/protocol/aux_pow_spec.rb +45 -0
  188. data/spec/unit/bitcoin/protocol/bip143_spec.rb +334 -0
  189. data/spec/unit/bitcoin/protocol/block_spec.rb +280 -0
  190. data/spec/unit/bitcoin/protocol/getblocks_spec.rb +44 -0
  191. data/spec/unit/bitcoin/protocol/inv_spec.rb +166 -0
  192. data/spec/unit/bitcoin/protocol/notfound_spec.rb +44 -0
  193. data/spec/unit/bitcoin/protocol/parser_spec.rb +69 -0
  194. data/spec/unit/bitcoin/protocol/partial_merkle_tree_spec.rb +47 -0
  195. data/spec/unit/bitcoin/protocol/ping_spec.rb +62 -0
  196. data/spec/unit/bitcoin/protocol/tx_spec.rb +1515 -0
  197. data/spec/unit/bitcoin/protocol/txin_spec.rb +47 -0
  198. data/spec/unit/bitcoin/protocol/txout_spec.rb +36 -0
  199. data/spec/unit/bitcoin/protocol/version_spec.rb +121 -0
  200. data/spec/unit/bitcoin/script/opcodes_spec.rb +864 -0
  201. data/spec/unit/bitcoin/script/script_spec.rb +1610 -0
  202. data/spec/unit/bitcoin/secp256k1_spec.rb +138 -0
  203. data/spec/unit/bitcoin/trezor/mnemonic_spec.rb +193 -0
  204. data/spec/unit/integrations/dogecoin_spec.rb +215 -0
  205. metadata +381 -372
  206. data/lib/bitcoin/logger.rb +0 -86
  207. data/lib/bitcoin/protocol/alert.rb +0 -46
  208. data/spec/bitcoin/bech32_spec.rb +0 -160
  209. data/spec/bitcoin/bitcoin_spec.rb +0 -666
  210. data/spec/bitcoin/bloom_filter_spec.rb +0 -23
  211. data/spec/bitcoin/builder_spec.rb +0 -375
  212. data/spec/bitcoin/contracthash_spec.rb +0 -45
  213. data/spec/bitcoin/dogecoin_spec.rb +0 -176
  214. data/spec/bitcoin/ext_key_spec.rb +0 -180
  215. data/spec/bitcoin/ffi_openssl.rb +0 -45
  216. data/spec/bitcoin/fixtures/rawblock-170.json +0 -68
  217. data/spec/bitcoin/fixtures/rawblock-9.json +0 -39
  218. data/spec/bitcoin/fixtures/reorg/blk_0_to_4.dat +0 -0
  219. data/spec/bitcoin/fixtures/reorg/blk_3A.dat +0 -0
  220. data/spec/bitcoin/fixtures/reorg/blk_4A.dat +0 -0
  221. data/spec/bitcoin/fixtures/reorg/blk_5A.dat +0 -0
  222. data/spec/bitcoin/fixtures/testnet/block_0.bin +0 -0
  223. data/spec/bitcoin/fixtures/testnet/block_1.bin +0 -0
  224. data/spec/bitcoin/fixtures/testnet/block_2.bin +0 -0
  225. data/spec/bitcoin/fixtures/testnet/block_3.bin +0 -0
  226. data/spec/bitcoin/fixtures/testnet/block_4.bin +0 -0
  227. data/spec/bitcoin/fixtures/testnet/block_5.bin +0 -0
  228. data/spec/bitcoin/fixtures/txdp-1.txt +0 -32
  229. data/spec/bitcoin/fixtures/txdp-2-signed.txt +0 -19
  230. data/spec/bitcoin/fixtures/txdp-2-unsigned.txt +0 -14
  231. data/spec/bitcoin/helpers/fake_blockchain.rb +0 -183
  232. data/spec/bitcoin/key_spec.rb +0 -326
  233. data/spec/bitcoin/network_spec.rb +0 -50
  234. data/spec/bitcoin/performance/storage_spec.rb +0 -41
  235. data/spec/bitcoin/protocol/addr_spec.rb +0 -82
  236. data/spec/bitcoin/protocol/alert_spec.rb +0 -22
  237. data/spec/bitcoin/protocol/aux_pow_spec.rb +0 -45
  238. data/spec/bitcoin/protocol/bip143_spec.rb +0 -116
  239. data/spec/bitcoin/protocol/block_spec.rb +0 -208
  240. data/spec/bitcoin/protocol/getblocks_spec.rb +0 -32
  241. data/spec/bitcoin/protocol/inv_spec.rb +0 -134
  242. data/spec/bitcoin/protocol/notfound_spec.rb +0 -31
  243. data/spec/bitcoin/protocol/parser_spec.rb +0 -50
  244. data/spec/bitcoin/protocol/partial_merkle_tree_spec.rb +0 -38
  245. data/spec/bitcoin/protocol/ping_spec.rb +0 -51
  246. data/spec/bitcoin/protocol/reject.rb +0 -17
  247. data/spec/bitcoin/protocol/tx_spec.rb +0 -894
  248. data/spec/bitcoin/protocol/txin_spec.rb +0 -45
  249. data/spec/bitcoin/protocol/txout_spec.rb +0 -33
  250. data/spec/bitcoin/protocol/version_spec.rb +0 -110
  251. data/spec/bitcoin/script/opcodes_spec.rb +0 -773
  252. data/spec/bitcoin/script/script_spec.rb +0 -977
  253. data/spec/bitcoin/secp256k1_spec.rb +0 -78
  254. data/spec/bitcoin/spec_helper.rb +0 -108
  255. data/spec/bitcoin/trezor/mnemonic_spec.rb +0 -161
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Bitcoin::BloomFilter do
6
+ let(:item1) { '99108ad8ed9bb6274d3980bab5a85c048f0950c8' }
7
+ let(:item2) { 'b5a2c786d9ef4658287ced5914b37a1b4aa32eee' }
8
+ let(:item3) { 'b9300670b4c5366e95b2699e8b18bc75e5f729c5' }
9
+
10
+ subject { Bitcoin::BloomFilter.new(3, 0.01, 2_147_483_649) }
11
+
12
+ describe '#contains?' do
13
+ it 'contains items that have been added to it' do
14
+ subject.add_data(item1.htb)
15
+ subject.add_data(item2.htb)
16
+ subject.add_data(item3.htb)
17
+
18
+ expect(subject).to be_contains(item1.htb)
19
+ expect(subject).to be_contains(item2.htb)
20
+ expect(subject).to be_contains(item3.htb)
21
+ end
22
+ end
23
+
24
+ describe '#filter' do
25
+ it 'produces the expected filter' do
26
+ subject.add_data(item1.htb)
27
+ subject.add_data(item2.htb)
28
+ subject.add_data(item3.htb)
29
+
30
+ expect(subject.filter.bth).to eq('ce4299')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,559 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Bitcoin::Builder do
6
+ let(:keys) { Array.new(5) { Bitcoin::Key.generate } }
7
+ let(:target) { '00'.ljust(64, 'f') }
8
+ let(:genesis_block) { create_block('00' * 32, false) }
9
+ let(:block) { create_block(genesis_block.hash, false, [], keys[0]) }
10
+
11
+ before { Bitcoin.network = :spec }
12
+
13
+ it 'should build blocks' do
14
+ result = build_block(target) do |b|
15
+ b.prev_block block.hash
16
+
17
+ b.tx do |t|
18
+ t.input { |i| i.coinbase 'foobar' }
19
+
20
+ t.output do |o|
21
+ o.value 5_000_000_000
22
+
23
+ o.script do |s|
24
+ s.type :address
25
+ s.recipient keys[0].addr
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ expect(result.hash[0..1]).to eq('00')
32
+ expect(result.ver).to eq(1)
33
+ expect(result.prev_block).to eq(block.binary_hash.reverse)
34
+ expect(result.tx.size).to eq(1)
35
+
36
+ tx = result.tx[0]
37
+ expect(tx.in.size).to eq(1)
38
+ expect(tx.out.size).to eq(1)
39
+ expect(tx.in[0].script_sig).to eq(['foobar'].pack('H*'))
40
+ expect(tx.out[0].value).to eq(5_000_000_000)
41
+ end
42
+
43
+ it 'should build transactions with input and output signatures' do
44
+ tx = build_tx do |t|
45
+ t.input do |i|
46
+ i.prev_out block.tx[0]
47
+ i.prev_out_index 0
48
+ i.signature_key keys[0]
49
+ end
50
+
51
+ t.output do |o|
52
+ o.value 123
53
+
54
+ o.script do |s|
55
+ s.type :address
56
+ s.recipient keys[1].addr
57
+ end
58
+ end
59
+ end
60
+
61
+ expect(tx.in[0].prev_out.reverse_hth).to eq(block.tx[0].hash)
62
+ expect(tx.in[0].prev_out_index).to eq(0)
63
+ expect(
64
+ Bitcoin::Script.new(tx.in[0].script_sig).chunks[1].unpack('H*')[0]
65
+ ).to eq(keys[0].pub)
66
+
67
+ expect(tx.out[0].value).to eq(123)
68
+ script = Bitcoin::Script.new(tx.out[0].pk_script)
69
+ expect(script.type).to eq(:hash160)
70
+ expect(script.get_address).to eq(keys[1].addr)
71
+
72
+ expect(tx.verify_input_signature(0, block.tx[0])).to be true
73
+
74
+ # check shortcuts also work
75
+ tx2 = build_tx do |t|
76
+ t.input do |i|
77
+ i.prev_out block.tx[0], 0
78
+ i.signature_key keys[0]
79
+ end
80
+ t.output do |o|
81
+ o.value 123
82
+ o.script { |s| s.recipient keys[1].addr }
83
+ end
84
+ t.output do |o|
85
+ o.to keys[1].addr
86
+ o.value 321
87
+ end
88
+ t.output { |o| o.to 'deadbeef', :op_return }
89
+ end
90
+
91
+ expect(tx2.in[0].prev_out).to eq(tx.in[0].prev_out)
92
+ expect(tx2.in[0].prev_out_index).to eq(tx.in[0].prev_out_index)
93
+ expect(tx2.out[0].value).to eq(tx.out[0].value)
94
+ expect(tx2.out[0].pk_script).to eq(tx.out[0].pk_script)
95
+
96
+ expect(
97
+ Bitcoin::Script.new(tx2.out[0].pk_script).to_string
98
+ ).to eq(
99
+ "OP_DUP OP_HASH160 #{keys[1].hash160} OP_EQUALVERIFY OP_CHECKSIG"
100
+ )
101
+ expect(
102
+ Bitcoin::Script.new(tx2.out[0].pk_script).to_string
103
+ ).to eq(
104
+ "OP_DUP OP_HASH160 #{keys[1].hash160} OP_EQUALVERIFY OP_CHECKSIG"
105
+ )
106
+ expect(tx2.out[2].value).to eq(0)
107
+ end
108
+
109
+ it 'should build transactions with p2wpkh signatures' do
110
+ key = Bitcoin::Key.new('619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9')
111
+ script_pubkey = '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb
112
+
113
+ tx = build_tx do |t|
114
+ t.input do |i|
115
+ i.prev_out(
116
+ '8ac60eb9575db5b2d987e29f301b5b819ea83a5c6579d282d189cc04b8e151ef',
117
+ 1,
118
+ script_pubkey,
119
+ 600_000_000
120
+ )
121
+ i.signature_key key
122
+ end
123
+ end
124
+
125
+ expect(
126
+ tx.verify_witness_input_signature(0, script_pubkey, 600_000_000)
127
+ ).to be true
128
+ expect(tx.in[0].script_sig).to eq('')
129
+ end
130
+
131
+ it 'should failure to build tx with p2wpkh signatures due to inconsistency of key' do
132
+ key = Bitcoin::Key.new('619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9')
133
+ script_pubkey = '0014deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf'.htb
134
+
135
+ expect do
136
+ build_tx do |t|
137
+ t.input do |i|
138
+ i.prev_out(
139
+ '8ac60eb9575db5b2d987e29f301b5b819ea83a5c6579d282d189cc04b8e151ef',
140
+ 1,
141
+ script_pubkey,
142
+ 600_000_000
143
+ )
144
+ i.signature_key key
145
+ end
146
+ end
147
+ end.to raise_error(RuntimeError, 'Signature error')
148
+ end
149
+
150
+ it 'should build p2sh transaction with p2wpkh signatures' do
151
+ key = Bitcoin::Key.new('619c335025c7f4012e556c2a58b2506e30b8511b53ade95ea316fd8c3286feb9')
152
+ witness_prog = '00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1'.htb
153
+ script_pubkey = Bitcoin::Script.to_p2sh_script('bdbb096c26dd64dca06d0fbe8bb5e990ac3cdb42')
154
+ tx = build_tx do |t|
155
+ t.input do |i|
156
+ i.prev_out(SecureRandom.hex(32), 0, script_pubkey, 600_000_000)
157
+ i.redeem_script witness_prog
158
+ i.signature_key key
159
+ end
160
+ end
161
+
162
+ expect(
163
+ tx.verify_witness_input_signature(0, witness_prog, 600_000_000)
164
+ ).to be true
165
+ expect(tx.in[0].script_sig).to eq(Bitcoin::Script.pack_pushdata(witness_prog))
166
+ end
167
+
168
+ it 'should allow txin.prev_out as tx or hash' do
169
+ prev_tx = block.tx[0]
170
+ tx1 = build_tx do |t|
171
+ t.input { |i| i.prev_out prev_tx, 0 }
172
+ end
173
+ tx2 = build_tx do |t|
174
+ t.input { |i| i.prev_out prev_tx.hash, 0, prev_tx.out[0].pk_script }
175
+ end
176
+ expect(tx1.in[0]).to eq(tx2.in[0])
177
+ end
178
+
179
+ it 'should provide tx#output shortcut' do
180
+ tx1 = build_tx { |t| t.output(123, keys[1].addr) }
181
+ expect(tx1).to eq(
182
+ build_tx do |t|
183
+ t.output do |o|
184
+ o.value 123
185
+ o.to keys[1].addr
186
+ end
187
+ end
188
+ )
189
+
190
+ tx2 = build_tx { |t| t.output(123, keys[1].pub, :pubkey) }
191
+ expect(tx2).to eq(
192
+ build_tx do |t|
193
+ t.output do |o|
194
+ o.value 123
195
+ o.to keys[1].pub, :pubkey
196
+ end
197
+ end
198
+ )
199
+ end
200
+
201
+ it 'should provide txout#to shortcut' do
202
+ tx1 = build_tx do |t|
203
+ t.output do |o|
204
+ o.value 123
205
+ o.to keys[1].addr
206
+ end
207
+ end
208
+ tx2 = build_tx do |t|
209
+ t.output do |o|
210
+ o.value 123
211
+ o.script { |s| s.recipient keys[1].addr }
212
+ end
213
+ end
214
+ expect(tx1.out[0]).to eq(tx2.out[0])
215
+ end
216
+
217
+ it 'should build unsigned transactions and add the signature hash' do
218
+ tx = build_tx do |t|
219
+ t.input do |i|
220
+ i.prev_out block.tx[0]
221
+ i.prev_out_index 0
222
+ # no signature key
223
+ end
224
+ t.output do |o|
225
+ o.value 123
226
+ o.script { |s| s.recipient keys[1].addr }
227
+ end
228
+ end
229
+
230
+ expect(tx).to be_a(Bitcoin::P::Tx)
231
+ expect(tx.in[0].sig_hash).not_to be_nil
232
+ end
233
+
234
+ it 'should build unsigned multisig transactions and add the signature hash' do
235
+ tx1 = build_tx do |t|
236
+ t.input do |i|
237
+ i.prev_out(block.tx[0], 0)
238
+ i.signature_key(keys[0])
239
+ end
240
+ t.output do |o|
241
+ o.value 123
242
+ o.to [2, *keys[0..2].map(&:pub)], :multisig
243
+ end
244
+ end
245
+
246
+ tx2 = build_tx do |t|
247
+ t.input do |i|
248
+ i.prev_out tx1, 0
249
+ i.signature_key keys[0]
250
+ end
251
+ t.output do |o|
252
+ o.value 123
253
+ o.to keys[0].addr
254
+ end
255
+ end
256
+
257
+ expect(tx2).to be_a(Bitcoin::P::Tx)
258
+ expect(tx2.in[0].sig_hash).not_to be_nil
259
+ end
260
+
261
+ it 'should build unsigned p2sh multisig transactions and add the signature hash' do
262
+ tx1 = build_tx do |t|
263
+ t.input do |i|
264
+ i.prev_out(block.tx[0], 0)
265
+ i.signature_key(keys[0])
266
+ end
267
+ t.output do |o|
268
+ o.value 123
269
+ o.to [2, *keys[0..2].map(&:pub)], :p2sh_multisig
270
+ end
271
+ end
272
+
273
+ tx2 = build_tx do |t|
274
+ t.input do |i|
275
+ i.prev_out tx1, 0
276
+ i.signature_key keys[0]
277
+ i.redeem_script tx1.out[0].redeem_script
278
+ end
279
+ t.output do |o|
280
+ o.value 123
281
+ o.to keys[0].addr
282
+ end
283
+ end
284
+
285
+ expect(tx2).to be_a(Bitcoin::P::Tx)
286
+ expect(tx2.in[0].sig_hash).not_to be_nil
287
+ end
288
+
289
+ it 'should add change output' do
290
+ change_address = Bitcoin::Key.generate.addr
291
+ input_value = block.tx[0].out.map(&:value).inject(:+)
292
+
293
+ tx = build_tx(input_value: input_value, change_address: change_address) do |t|
294
+ t.input do |i|
295
+ i.prev_out block.tx[0]
296
+ i.prev_out_index 0
297
+ i.signature_key keys[0]
298
+ end
299
+ t.output do |o|
300
+ o.value 12_345
301
+ o.script { |s| s.recipient keys[1].addr }
302
+ end
303
+ end
304
+
305
+ expect(tx.out.count).to be(2)
306
+ expect(tx.out.last.value).to eq(50e8 - 12_345)
307
+ expect(
308
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address
309
+ ).to eq(change_address)
310
+ end
311
+
312
+ it 'should add change output and leave fee' do
313
+ change_address = Bitcoin::Key.generate.addr
314
+ input_value = block.tx[0].out.map(&:value).inject(:+)
315
+
316
+ tx = build_tx(input_value: input_value,
317
+ change_address: change_address, leave_fee: true) do |t|
318
+ t.input do |i|
319
+ i.prev_out block.tx[0]
320
+ i.prev_out_index 0
321
+ i.signature_key keys[0]
322
+ end
323
+ t.output do |o|
324
+ o.value 12_345
325
+ o.script { |s| s.recipient keys[1].addr }
326
+ end
327
+ end
328
+ expect(tx.out.count).to eq(2)
329
+ expect(tx.out.last.value)
330
+ .to eq(50e8 - 12_345 - Bitcoin.network[:min_tx_fee])
331
+ expect(
332
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address
333
+ ).to eq(change_address)
334
+
335
+ input_value = block.tx[0].out.map(&:value).inject(:+)
336
+ tx = build_tx(input_value: input_value,
337
+ change_address: change_address, leave_fee: true) do |t|
338
+ t.input do |i|
339
+ i.prev_out block.tx[0]
340
+ i.prev_out_index 0
341
+ i.signature_key keys[0]
342
+ end
343
+ 49.times do
344
+ t.output do |o|
345
+ o.value 1e8
346
+ o.script { |s| s.recipient keys[1].addr }
347
+ end
348
+ end
349
+ t.output do |o|
350
+ o.value(1e8 - 10_000)
351
+ o.script { |s| s.recipient keys[1].addr }
352
+ end
353
+ end
354
+
355
+ expect(tx.out.size).to eq(50)
356
+ expect(tx.out.map(&:value).inject(:+)).to eq(50e8 - 10_000)
357
+ end
358
+
359
+ it 'randomize_outputs should not modify output values or fees' do
360
+ change_address = Bitcoin::Key.generate.addr
361
+ input_value = block.tx[0].out.map(&:value).inject(:+)
362
+ tx = build_tx(input_value: input_value,
363
+ change_address: change_address, leave_fee: true) do |t|
364
+ t.input do |i|
365
+ i.prev_out block.tx[0]
366
+ i.prev_out_index 0
367
+ i.signature_key keys[0]
368
+ end
369
+ t.output do |o|
370
+ o.value 12_345
371
+ o.script { |s| s.recipient keys[1].addr }
372
+ end
373
+ t.randomize_outputs
374
+ end
375
+
376
+ expect(tx.out.count).to eq(2)
377
+ expect(tx.out.last.value).to eq(50e8 - 12_345 - Bitcoin.network[:min_tx_fee])
378
+ expect(
379
+ Bitcoin::Script.new(tx.out.last.pk_script).get_address
380
+ ).to eq(change_address)
381
+
382
+ input_value = block.tx[0].out.map(&:value).inject(:+)
383
+ tx = build_tx(input_value: input_value,
384
+ change_address: change_address, leave_fee: true) do |t|
385
+ t.input do |i|
386
+ i.prev_out block.tx[0]
387
+ i.prev_out_index 0
388
+ i.signature_key keys[0]
389
+ end
390
+ 49.times do
391
+ t.output do |o|
392
+ o.value 1e8
393
+ o.script { |s| s.recipient keys[1].addr }
394
+ end
395
+ end
396
+ t.output do |o|
397
+ o.value(1e8 - 10_000)
398
+ o.script { |s| s.recipient keys[1].addr }
399
+ end
400
+ t.randomize_outputs
401
+ end
402
+
403
+ expect(tx.out.size).to eq(50)
404
+ expect(tx.out.map(&:value).inject(:+)).to eq(50e8 - 10_000)
405
+ end
406
+
407
+ it 'should build op_return output' do
408
+ builder = Bitcoin::Builder::TxOutBuilder.new
409
+ builder.to 'deadbeef', :op_return
410
+
411
+ expect(builder.txout.parsed_script.to_string).to eq('OP_RETURN deadbeef')
412
+ end
413
+
414
+ it 'should build op_return script' do
415
+ result = script do |s|
416
+ s.type :op_return
417
+ s.recipient 'deadbeef'
418
+ end
419
+
420
+ expect(Bitcoin::Script.new(result).to_string).to eq('OP_RETURN deadbeef')
421
+ end
422
+
423
+ it 'should build address script' do
424
+ key = Bitcoin::Key.generate
425
+ result = script do |s|
426
+ s.type :address
427
+ s.recipient key.addr
428
+ end
429
+
430
+ expect(Bitcoin::Script.new(result).to_string)
431
+ .to eq("OP_DUP OP_HASH160 #{Bitcoin.hash160_from_address(key.addr)} " \
432
+ 'OP_EQUALVERIFY OP_CHECKSIG')
433
+ end
434
+
435
+ it 'should build pubkey script' do
436
+ key = Bitcoin::Key.generate
437
+ result = script do |s|
438
+ s.type :pubkey
439
+ s.recipient key.pub
440
+ end
441
+
442
+ expect(Bitcoin::Script.new(result).to_string)
443
+ .to eq("#{key.pub} OP_CHECKSIG")
444
+ end
445
+
446
+ it 'should build multisig script' do
447
+ keys = Array.new(3) { Bitcoin::Key.generate }
448
+ result = script do |s|
449
+ s.type :multisig
450
+ s.recipient 1, keys[0].pub, keys[1].pub
451
+ end
452
+
453
+ expect(Bitcoin::Script.new(result).to_string)
454
+ .to eq("1 #{keys[0].pub} #{keys[1].pub} 2 OP_CHECKMULTISIG")
455
+ end
456
+
457
+ it 'should build and spend multisig output' do
458
+ tx1 = build_tx do |t|
459
+ t.input do |i|
460
+ i.prev_out(block.tx[0], 0)
461
+ i.signature_key(keys[0])
462
+ end
463
+ t.output do |o|
464
+ o.value 123
465
+ o.to [2, *keys[0..2].map(&:pub)], :multisig
466
+ end
467
+ end
468
+
469
+ expect(
470
+ Bitcoin::Script.new(tx1.out[0].pk_script).to_string
471
+ ).to eq("2 #{keys[0..2].map(&:pub).join(' ')} 3 OP_CHECKMULTISIG")
472
+
473
+ tx2 = build_tx do |t|
474
+ t.input do |i|
475
+ i.prev_out tx1, 0
476
+ i.signature_key keys[0..1]
477
+ end
478
+ t.output do |o|
479
+ o.value 123
480
+ o.to keys[0].addr
481
+ end
482
+ end
483
+
484
+ expect(tx2.verify_input_signature(0, tx1)).to be true
485
+ end
486
+
487
+ it 'should build and spend p2sh multisig output' do
488
+ tx1 = build_tx do |t|
489
+ t.input do |i|
490
+ i.prev_out(block.tx[0], 0)
491
+ i.signature_key(keys[0])
492
+ end
493
+ t.output do |o|
494
+ o.value 123
495
+ o.to [2, *keys[0..2].map(&:pub)], :p2sh_multisig
496
+ end
497
+ end
498
+
499
+ expect(Bitcoin::Script.new(tx1.out[0].pk_script).to_string)
500
+ .to eq("OP_HASH160 #{Bitcoin.hash160(tx1.out[0].redeem_script.hth)} OP_EQUAL")
501
+
502
+ tx2 = build_tx do |t|
503
+ t.input do |i|
504
+ i.prev_out tx1, 0
505
+ # provide 2 required keys for signing
506
+ i.signature_key keys[0..1]
507
+ # provide the redeem script from the previous output
508
+ i.redeem_script tx1.out[0].redeem_script
509
+ end
510
+
511
+ t.output do |o|
512
+ o.value 123
513
+ o.to keys[0].addr
514
+ end
515
+ end
516
+
517
+ script = Bitcoin::Script.new(tx2.in[0].script_sig, tx1.out[0].pk_script)
518
+ # check script execution is valid
519
+ expect(script.run { true }).to be true
520
+ # check signatures are valid
521
+ expect(tx2.verify_input_signature(0, tx1)).to be true
522
+ end
523
+
524
+ it 'should build and sign bcash transaction' do
525
+ tx = build_tx do |t|
526
+ t.input do |i|
527
+ prev_tx = block.tx[0]
528
+ utxo = prev_tx.out[0]
529
+ i.prev_out prev_tx.hash, 0, utxo.script, utxo.amount, 0
530
+ i.signature_key keys[0]
531
+ end
532
+
533
+ t.output do |o|
534
+ o.value 4_999_900_000
535
+
536
+ o.script do |s|
537
+ s.type :address
538
+ s.recipient keys[1].addr
539
+ end
540
+ end
541
+ end
542
+
543
+ expect(tx.in[0].prev_out.reverse_hth).to eq(block.tx[0].hash)
544
+ expect(tx.in[0].prev_out_index).to eq(0)
545
+ expect(
546
+ Bitcoin::Script.new(tx.in[0].script_sig).chunks[1].unpack('H*')[0]
547
+ ).to eq(keys[0].pub)
548
+ expect(tx.out[0].value).to eq(4_999_900_000)
549
+
550
+ script = Bitcoin::Script.new(tx.out[0].pk_script)
551
+ expect(script.type).to eq(:hash160)
552
+ expect(script.get_address).to eq(keys[1].addr)
553
+ expect(
554
+ tx.verify_input_signature(0, block.tx[0], Time.now.to_i, fork_id: 0)
555
+ ).to be true
556
+ expect(Bitcoin::Script.new(tx.out[0].pk_script).to_string)
557
+ .to eq("OP_DUP OP_HASH160 #{keys[1].hash160} OP_EQUALVERIFY OP_CHECKSIG")
558
+ end
559
+ end