bitcoin-ruby 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +46 -0
- data/.travis.yml +5 -1
- data/Gemfile +11 -9
- data/Gemfile.lock +64 -12
- data/README.rdoc +17 -4
- data/Rakefile +58 -83
- data/bitcoin-ruby.gemspec +5 -2
- data/lib/bitcoin.rb +31 -14
- data/lib/bitcoin/bech32.rb +126 -132
- data/lib/bitcoin/bloom_filter.rb +24 -21
- data/lib/bitcoin/builder.rb +168 -126
- data/lib/bitcoin/connection.rb +21 -24
- data/lib/bitcoin/contracthash.rb +20 -24
- data/lib/bitcoin/dogecoin.rb +79 -77
- data/lib/bitcoin/electrum/mnemonic.rb +28 -25
- data/lib/bitcoin/ext_key.rb +3 -3
- data/lib/bitcoin/ffi/bitcoinconsensus.rb +17 -13
- data/lib/bitcoin/ffi/openssl.rb +355 -338
- data/lib/bitcoin/ffi/secp256k1.rb +97 -64
- data/lib/bitcoin/protocol.rb +6 -3
- data/lib/bitcoin/protocol/address.rb +15 -13
- data/lib/bitcoin/protocol/aux_pow.rb +12 -15
- data/lib/bitcoin/protocol/block.rb +102 -76
- data/lib/bitcoin/protocol/handler.rb +2 -4
- data/lib/bitcoin/protocol/parser.rb +108 -92
- data/lib/bitcoin/protocol/partial_merkle_tree.rb +59 -47
- data/lib/bitcoin/protocol/reject.rb +26 -28
- data/lib/bitcoin/protocol/script_witness.rb +3 -8
- data/lib/bitcoin/protocol/tx.rb +250 -137
- data/lib/bitcoin/protocol/txin.rb +44 -38
- data/lib/bitcoin/protocol/txout.rb +27 -20
- data/lib/bitcoin/protocol/version.rb +47 -34
- data/lib/bitcoin/script.rb +18 -17
- data/lib/bitcoin/trezor/mnemonic.rb +113 -98
- data/lib/bitcoin/version.rb +1 -1
- data/spec/examples.txt +399 -0
- data/spec/{bitcoin/fixtures → fixtures}/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/base58_keys_invalid.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/base58_keys_valid.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/bc179baab547b7d7c1d5d8d6f8b0cc6318eaa4b0dd0a093ad6ac7f5a1cb6b3ba.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/coinbase-toshi.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/coinbase.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/filteredblock-0.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/litecoin-tx-f5aa30f574e3b6f1a3d99c07a6356ba812aabb9661e1d5f71edff828cbd5c996.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-0.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-0.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-1.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-1.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-131025.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-131025.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-170.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-9.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-auxpow.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-1151351.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-26478.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-26478.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawblock-testnet-265322.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-01-toshi.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-01.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-01.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-02-toshi.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-02.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-02.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-03-toshi.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-03.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-03.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-04.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-05.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-14be6fff8c6014f7c9493b4a6e4a741699173f39d74431b6b844fcb41ebb9984.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-2f4a2717ec8c9f077a87dde6cbe0274d5238793a3f3f492b63c744837285e58a.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-52250a162c7d03d2e1fbc5ebd1801a88612463314b55102171c5b5d817d2d7b2.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-b5d4e8883533f99e5903ea2cf001a133a322fa6b1370b18a16c57c946a40823d.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-ba1ff5cd66713133c062a871a8adab92416f1e38d17786b2bf56ac5f6ffdfdf5.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-de35d060663750b3975b7997bde7fb76307cec5b270d12fcd9c4ad98b279c28c.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-p2wpkh.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-p2wpkh.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-a220adf1902c46a39db25a24bc4178b6a88440f977a7e2cabfdd8b5c1dd35cfb.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-e232e0055dbdca88bbaa79458683195a0b7c17c5b6c524a8d146721d4d4d652f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/script_tests.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/sighash.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-0295028ef826b2a188409cb905b631faebb9bb3cdf14510571c5f4bd8591338f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-03339a725007a279484fb6f5361f522dd1cf4d0923d30e6b973290dba4275f92.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-0ce7e5238fbdb6c086cf1b384b21b827e91cc23f360417265874a5a0d86ce367.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-0ef34c49f630aea17df0080728b0fc67bf5f87fbda936934a4b11b4a69d7821e.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-1129d2a8bd5bb3a81e54dc96a90f1f6b2544575748caa17243470935c5dd91b7.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-19aa42fee0fa57c45d3b16488198b27caaacc4ff5794510d0c17f173f05587ff.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-1a4f3b9dc4494aeedeb39f30dd37e60541b2abe3ed4977992017cc0ad4f44956.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-1f9191dcf2b1844ca28c6ef4b969e1d5fab70a5e3c56b7007949e55851cb0c4f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-22cd5fef23684d7b304e119bedffde6f54538d3d54a5bfa237e20dc2d9b4b5ad.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-2958fb00b4fd6fe0353503b886eb9a193d502f4fd5fc042d5e03216ba918bbd6.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-29f277145749ad6efbed3ae6ce301f8d33c585ec26b7c044ad93c2f866e9e942.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-2c5e5376c20e9cc78d0fb771730e5d840cc2096eff0ef045b599fe92475ace1c.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-2c63aa814701cef5dbd4bbaddab3fea9117028f2434dddcdab8339141e9b14d1.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-345bed8785c3282a264ffb0dbee61cde54854f10e16f1b3e75b7f2d9f62946f2.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-39ba7440b7103557560cc8ce258009936796485aaf8b478e66ab4cb97c66e31b.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-3a04d57a833367f1655cc5ec3beb587888ef4977a86caa8c8ad4ba7cc717eae7.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-46224764c7870f95b58f155bce1e38d4da8e99d42dbb632d0dd7c07e092ee5aa.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-5df1375ffe61ac35ca178ebb0cab9ea26dedbd0e96005dfcee7e379fa513232f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-62d9a565bd7b5344c5352e3e9e5f40fa4bbd467fa19c87357216ec8777ba1cce.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-6327783a064d4e350c454ad5cd90201aedf65b1fc524e73709c52f0163739190.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-6aaf18b9f1283b939d8e5d40ff5f8a435229f4178372659cc3a0bce4e262bf78.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-6b48bba6f6d2286d7ec0883c0fc3085955090813a4c94980466611c798b868cc.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-70cfbc6690f9ab46712db44e3079ac227962b2771a9341d4233d898b521619ef.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-7a1a9db42f065f75110fcdb1bc415549c8ef7670417ba1d35a67f1b8adc562c1.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-9a768fc7d0c4bdc86e25154357ef7c0063ca21310e5740a2f12f90b7455184a7.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-9cad8d523a0694f2509d092c39cebc8046adae62b4e4297102d568191d9478d8.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-9e052eb694bd7e15906433f064dff0161a12fd325c1124537766377004023c6f.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-9fb65b7304aaa77ac9580823c2c06b259cc42591e5cce66d76a81b6f51cc5c28.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-a6ce7081addade7676cd2af75c4129eba6bf5e179a19c40c7d4cf6a5fe595954.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-aab7ef280abbb9cc6fbaf524d2645c3daf4fcca2b3f53370e618d9cedf65f1f8.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-ad4bcf3241e5d2ad140564e20db3567d41594cf4c2012433fe46a2b70e0d87b8.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-bbca0628c42cb8bf7c3f4b2ad688fa56da5308dd2a10255da89fb1f46e6e413d.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-c192b74844e4837a34c4a5a97b438f1c111405b01b99e2d12b7c96d07fc74c04.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-e335562f7e297aadeed88e5954bc4eeb8dc00b31d829eedb232e39d672b0c009.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/tx-fee1b9b85531c8fb6cd7831f83490c7f2aa768b6eefe29854ef5e89ce7b9ecb1.json +0 -0
- data/spec/{bitcoin/fixtures → fixtures}/txscript-invalid-too-many-sigops-followed-by-invalid-pushdata.bin +0 -0
- data/spec/helpers/block_helpers.rb +58 -0
- data/spec/helpers/fixture_helpers.rb +20 -0
- data/spec/helpers/library_helpers.rb +15 -0
- data/spec/spec_helper.rb +109 -0
- data/spec/unit/bitcoin/bech32_spec.rb +187 -0
- data/spec/unit/bitcoin/bitcoin_spec.rb +1079 -0
- data/spec/unit/bitcoin/bloom_filter_spec.rb +33 -0
- data/spec/unit/bitcoin/builder_spec.rb +559 -0
- data/spec/unit/bitcoin/contracthash_spec.rb +52 -0
- data/spec/unit/bitcoin/ext_key_spec.rb +281 -0
- data/spec/unit/bitcoin/key_spec.rb +457 -0
- data/spec/unit/bitcoin/network_spec.rb +71 -0
- data/spec/unit/bitcoin/protocol/addr_spec.rb +90 -0
- data/spec/unit/bitcoin/protocol/aux_pow_spec.rb +45 -0
- data/spec/unit/bitcoin/protocol/bip143_spec.rb +334 -0
- data/spec/unit/bitcoin/protocol/block_spec.rb +280 -0
- data/spec/unit/bitcoin/protocol/getblocks_spec.rb +44 -0
- data/spec/unit/bitcoin/protocol/inv_spec.rb +166 -0
- data/spec/unit/bitcoin/protocol/notfound_spec.rb +44 -0
- data/spec/unit/bitcoin/protocol/parser_spec.rb +69 -0
- data/spec/unit/bitcoin/protocol/partial_merkle_tree_spec.rb +47 -0
- data/spec/unit/bitcoin/protocol/ping_spec.rb +62 -0
- data/spec/unit/bitcoin/protocol/tx_spec.rb +1515 -0
- data/spec/unit/bitcoin/protocol/txin_spec.rb +47 -0
- data/spec/unit/bitcoin/protocol/txout_spec.rb +36 -0
- data/spec/unit/bitcoin/protocol/version_spec.rb +121 -0
- data/spec/unit/bitcoin/script/opcodes_spec.rb +864 -0
- data/spec/unit/bitcoin/script/script_spec.rb +1610 -0
- data/spec/unit/bitcoin/secp256k1_spec.rb +138 -0
- data/spec/unit/bitcoin/trezor/mnemonic_spec.rb +193 -0
- data/spec/unit/integrations/dogecoin_spec.rb +215 -0
- metadata +381 -372
- data/lib/bitcoin/logger.rb +0 -86
- data/lib/bitcoin/protocol/alert.rb +0 -46
- data/spec/bitcoin/bech32_spec.rb +0 -160
- data/spec/bitcoin/bitcoin_spec.rb +0 -666
- data/spec/bitcoin/bloom_filter_spec.rb +0 -23
- data/spec/bitcoin/builder_spec.rb +0 -375
- data/spec/bitcoin/contracthash_spec.rb +0 -45
- data/spec/bitcoin/dogecoin_spec.rb +0 -176
- data/spec/bitcoin/ext_key_spec.rb +0 -180
- data/spec/bitcoin/ffi_openssl.rb +0 -45
- data/spec/bitcoin/fixtures/rawblock-170.json +0 -68
- data/spec/bitcoin/fixtures/rawblock-9.json +0 -39
- data/spec/bitcoin/fixtures/reorg/blk_0_to_4.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_3A.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_4A.dat +0 -0
- data/spec/bitcoin/fixtures/reorg/blk_5A.dat +0 -0
- data/spec/bitcoin/fixtures/testnet/block_0.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_1.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_2.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_3.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_4.bin +0 -0
- data/spec/bitcoin/fixtures/testnet/block_5.bin +0 -0
- data/spec/bitcoin/fixtures/txdp-1.txt +0 -32
- data/spec/bitcoin/fixtures/txdp-2-signed.txt +0 -19
- data/spec/bitcoin/fixtures/txdp-2-unsigned.txt +0 -14
- data/spec/bitcoin/helpers/fake_blockchain.rb +0 -183
- data/spec/bitcoin/key_spec.rb +0 -326
- data/spec/bitcoin/network_spec.rb +0 -50
- data/spec/bitcoin/performance/storage_spec.rb +0 -41
- data/spec/bitcoin/protocol/addr_spec.rb +0 -82
- data/spec/bitcoin/protocol/alert_spec.rb +0 -22
- data/spec/bitcoin/protocol/aux_pow_spec.rb +0 -45
- data/spec/bitcoin/protocol/bip143_spec.rb +0 -116
- data/spec/bitcoin/protocol/block_spec.rb +0 -208
- data/spec/bitcoin/protocol/getblocks_spec.rb +0 -32
- data/spec/bitcoin/protocol/inv_spec.rb +0 -134
- data/spec/bitcoin/protocol/notfound_spec.rb +0 -31
- data/spec/bitcoin/protocol/parser_spec.rb +0 -50
- data/spec/bitcoin/protocol/partial_merkle_tree_spec.rb +0 -38
- data/spec/bitcoin/protocol/ping_spec.rb +0 -51
- data/spec/bitcoin/protocol/reject.rb +0 -17
- data/spec/bitcoin/protocol/tx_spec.rb +0 -894
- data/spec/bitcoin/protocol/txin_spec.rb +0 -45
- data/spec/bitcoin/protocol/txout_spec.rb +0 -33
- data/spec/bitcoin/protocol/version_spec.rb +0 -110
- data/spec/bitcoin/script/opcodes_spec.rb +0 -773
- data/spec/bitcoin/script/script_spec.rb +0 -977
- data/spec/bitcoin/secp256k1_spec.rb +0 -78
- data/spec/bitcoin/spec_helper.rb +0 -108
- data/spec/bitcoin/trezor/mnemonic_spec.rb +0 -161
data/lib/bitcoin/logger.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
begin
|
4
|
-
require 'log4r'
|
5
|
-
# monkey-patch Log4r to accept level names as symbols
|
6
|
-
class Log4r::Logger
|
7
|
-
def level= l = 0
|
8
|
-
_level = l.is_a?(Fixnum) ? l : Log4r::LNAMES.index(l.to_s.upcase)
|
9
|
-
Log4r::Log4rTools.validate_level(_level)
|
10
|
-
@level = _level
|
11
|
-
LoggerFactory.define_methods(self)
|
12
|
-
Log4r::Logger.log_internal {"Logger '#{@fullname}' set to #{LNAMES[@level]}"}
|
13
|
-
@level
|
14
|
-
end
|
15
|
-
end
|
16
|
-
rescue LoadError
|
17
|
-
end
|
18
|
-
|
19
|
-
module Bitcoin
|
20
|
-
# this is a very simple logger that is used if log4r is not available
|
21
|
-
module Logger
|
22
|
-
|
23
|
-
module TimeLogger
|
24
|
-
|
25
|
-
def time message
|
26
|
-
time = Time.now
|
27
|
-
res = yield
|
28
|
-
debug { message % (Time.now - time) }
|
29
|
-
res
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
class Logger
|
35
|
-
LEVELS = [:debug, :info, :warn, :error, :fatal]
|
36
|
-
|
37
|
-
include TimeLogger
|
38
|
-
|
39
|
-
attr_accessor :level
|
40
|
-
|
41
|
-
def initialize(name)
|
42
|
-
@name, @level = name, :info
|
43
|
-
end
|
44
|
-
|
45
|
-
def level= level
|
46
|
-
@level = level.is_a?(Fixnum) ? LEVELS[level] : level.to_sym
|
47
|
-
end
|
48
|
-
|
49
|
-
LEVELS.each do |level|
|
50
|
-
define_method(level) do |*msg, &block|
|
51
|
-
return if LEVELS.index(level.to_sym) < LEVELS.index(@level.to_sym)
|
52
|
-
msg = block ? block.call : msg.join
|
53
|
-
puts "#{level.to_s.upcase.ljust(5)} #{@name}: #{msg}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
# wrap a logger and prepend a special name in front of the messages
|
60
|
-
class LogWrapper
|
61
|
-
def initialize(name, log); @name, @log = name, log; end
|
62
|
-
def method_missing(m, *a, &blk)
|
63
|
-
@log.send(m, *a, &proc{ "#{@name} #{blk.call}" })
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# create a logger with given +name+. if log4r is installed, the logger
|
68
|
-
# will have a stdout and a fileout outputter to `log/<name>.log`.
|
69
|
-
# otherwise, the internal dummy logger is used which only logs to stdout.
|
70
|
-
def self.create name, level = :info
|
71
|
-
if defined?(Log4r)
|
72
|
-
dir = "log"
|
73
|
-
FileUtils.mkdir_p(dir) rescue dir = nil
|
74
|
-
@log = Log4r::Logger.new(name.to_s)
|
75
|
-
@log.extend(TimeLogger)
|
76
|
-
@log.level = level
|
77
|
-
@log.outputters << Log4r::Outputter.stdout
|
78
|
-
@log.outputters << Log4r::FileOutputter.new("fout", :filename => "#{dir}/#{name}.log") if dir
|
79
|
-
else
|
80
|
-
@log = Bitcoin::Logger::Logger.new(name)
|
81
|
-
end
|
82
|
-
@log
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
module Protocol
|
5
|
-
|
6
|
-
class Alert < Struct.new(:version, :relay_until, :expiration, :id, :cancel, :set_cancel,
|
7
|
-
:min_ver, :max_ver, :set_sub_ver, :priority, :comment, :status_bar, :reserved)
|
8
|
-
|
9
|
-
attr_accessor :payload, :signature
|
10
|
-
|
11
|
-
def initialize(values, alert_payload=nil, alert_signature=nil)
|
12
|
-
@payload, @signature = alert_payload, alert_signature
|
13
|
-
super(*values)
|
14
|
-
end
|
15
|
-
|
16
|
-
def valid_signature?
|
17
|
-
return false unless @payload && @signature
|
18
|
-
hash = Digest::SHA256.digest(Digest::SHA256.digest(@payload))
|
19
|
-
Bitcoin.network[:alert_pubkeys].any?{|public_key| Bitcoin.verify_signature(hash, @signature, public_key) }
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
def self.parse(payload)
|
24
|
-
count, payload = Bitcoin::Protocol.unpack_var_int(payload)
|
25
|
-
alert_payload, payload = payload.unpack("a#{count}a*")
|
26
|
-
count, payload = Bitcoin::Protocol.unpack_var_int(payload)
|
27
|
-
alert_signature, payload = payload.unpack("a#{count}a*")
|
28
|
-
|
29
|
-
version, relay_until, expiration, id, cancel, payload = alert_payload.unpack("VQQVVa*")
|
30
|
-
|
31
|
-
set_cancel, payload = Bitcoin::Protocol.unpack_var_int_array(payload)
|
32
|
-
min_ver, max_ver, payload = payload.unpack("VVa*")
|
33
|
-
set_sub_ver, payload = Bitcoin::Protocol.unpack_var_string_array(payload)
|
34
|
-
priority, payload = payload.unpack("Va*")
|
35
|
-
comment, payload = Bitcoin::Protocol.unpack_var_string(payload)
|
36
|
-
status_bar, payload = Bitcoin::Protocol.unpack_var_string(payload)
|
37
|
-
reserved, payload = Bitcoin::Protocol.unpack_var_string(payload)
|
38
|
-
|
39
|
-
values = [ version, relay_until, expiration, id, cancel, set_cancel, min_ver, max_ver, set_sub_ver, priority, comment, status_bar, reserved ]
|
40
|
-
|
41
|
-
new(values, alert_payload, alert_signature)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
data/spec/bitcoin/bech32_spec.rb
DELETED
@@ -1,160 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
require_relative 'spec_helper'
|
4
|
-
|
5
|
-
describe Bitcoin::Bech32 do
|
6
|
-
before do
|
7
|
-
Bitcoin.network = :bitcoin
|
8
|
-
|
9
|
-
@invalid_address_enc = [
|
10
|
-
["BC", 0, 20],
|
11
|
-
["bc", 0, 21],
|
12
|
-
["bc", 17, 32],
|
13
|
-
["bc", 1, 1],
|
14
|
-
["bc", 16, 41],
|
15
|
-
]
|
16
|
-
|
17
|
-
@valid_address = [
|
18
|
-
[
|
19
|
-
"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
|
20
|
-
22, [
|
21
|
-
0x00, 0x14, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
|
22
|
-
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
|
23
|
-
]
|
24
|
-
],
|
25
|
-
[
|
26
|
-
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
|
27
|
-
34, [
|
28
|
-
0x00, 0x20, 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 0x04,
|
29
|
-
0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 0x6c, 0x98, 0x56, 0x78,
|
30
|
-
0xcd, 0x4d, 0x27, 0xa1, 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32,
|
31
|
-
0x62
|
32
|
-
]
|
33
|
-
],
|
34
|
-
[
|
35
|
-
"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
|
36
|
-
42, [
|
37
|
-
0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
|
38
|
-
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6,
|
39
|
-
0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c,
|
40
|
-
0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
|
41
|
-
]
|
42
|
-
],
|
43
|
-
[
|
44
|
-
"BC1SW50QA3JX3S",
|
45
|
-
4, [
|
46
|
-
0x60, 0x02, 0x75, 0x1e
|
47
|
-
]
|
48
|
-
],
|
49
|
-
[
|
50
|
-
"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
|
51
|
-
18, [
|
52
|
-
0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
|
53
|
-
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23
|
54
|
-
]
|
55
|
-
],
|
56
|
-
[
|
57
|
-
"tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
|
58
|
-
34, [
|
59
|
-
0x00, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21,
|
60
|
-
0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5,
|
61
|
-
0xe9, 0x1c, 0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64,
|
62
|
-
0x33
|
63
|
-
]
|
64
|
-
]
|
65
|
-
]
|
66
|
-
|
67
|
-
@valid_checksum = [
|
68
|
-
"A12UEL5L",
|
69
|
-
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
|
70
|
-
"abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
|
71
|
-
"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
|
72
|
-
"split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
|
73
|
-
]
|
74
|
-
|
75
|
-
@invalid_checksum = [
|
76
|
-
" 1nwldj5",
|
77
|
-
"\x7f""1axkwrx",
|
78
|
-
"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
|
79
|
-
"pzry9x0s0muk",
|
80
|
-
"1pzry9x0s0muk",
|
81
|
-
"x1b4n0q5v",
|
82
|
-
"li1dgmt3",
|
83
|
-
"de1lg7wt\xff",
|
84
|
-
]
|
85
|
-
|
86
|
-
@invalid_address = [
|
87
|
-
"tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
|
88
|
-
"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
|
89
|
-
"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
|
90
|
-
"bc1rw5uspcuh",
|
91
|
-
"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
|
92
|
-
"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
|
93
|
-
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
|
94
|
-
"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du",
|
95
|
-
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
|
96
|
-
"bc1gmk9yu",
|
97
|
-
]
|
98
|
-
end
|
99
|
-
|
100
|
-
describe '#decode and #encode' do
|
101
|
-
it "test vectors" do
|
102
|
-
@valid_checksum.each do |testdata|
|
103
|
-
hrp, data = Bitcoin::Bech32.decode(testdata)
|
104
|
-
newdata = Bitcoin::Bech32.encode(hrp, data)
|
105
|
-
newdata.should == testdata.downcase
|
106
|
-
end
|
107
|
-
|
108
|
-
@invalid_checksum.each do |testdata|
|
109
|
-
hrp, data = Bitcoin::Bech32.decode(testdata)
|
110
|
-
hrp.should == nil
|
111
|
-
end
|
112
|
-
|
113
|
-
@valid_address.each do |testdata, _, _|
|
114
|
-
hrp, data = Bitcoin::Bech32.decode(testdata)
|
115
|
-
newdata = Bitcoin::Bech32.encode(hrp, data)
|
116
|
-
newdata.should == testdata.downcase
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe '#decode_segwit_address and #encode_segwit_address' do
|
122
|
-
it "test vectors" do
|
123
|
-
@valid_address.each do |testaddress, _, testscript|
|
124
|
-
Bitcoin.network = :bitcoin
|
125
|
-
version, program = Bitcoin.decode_segwit_address(testaddress)
|
126
|
-
if version.nil?
|
127
|
-
Bitcoin.network = :testnet3
|
128
|
-
version, program = Bitcoin.decode_segwit_address(testaddress)
|
129
|
-
end
|
130
|
-
version.should != nil
|
131
|
-
|
132
|
-
script = Bitcoin::Script.to_witness_script(version, program)
|
133
|
-
script.should == testscript.pack("C*")
|
134
|
-
|
135
|
-
newaddress = Bitcoin.encode_segwit_address(version, program)
|
136
|
-
newaddress.should != nil
|
137
|
-
newaddress.should == testaddress.downcase
|
138
|
-
end
|
139
|
-
|
140
|
-
@invalid_address.each do |testaddress|
|
141
|
-
Bitcoin.network = :bitcoin
|
142
|
-
version, program = Bitcoin.decode_segwit_address(testaddress)
|
143
|
-
if version.nil?
|
144
|
-
Bitcoin.network = :testnet3
|
145
|
-
version, program = Bitcoin.decode_segwit_address(testaddress)
|
146
|
-
end
|
147
|
-
version.should == nil
|
148
|
-
end
|
149
|
-
|
150
|
-
Bitcoin.network = :bitcoin
|
151
|
-
@invalid_address_enc.each do |testhrp, testversion, testlength|
|
152
|
-
Bitcoin.network[:bech32_hrp] = testhrp
|
153
|
-
program_hex = Array.new(testlength){ 0 }.pack("C*").unpack("H*").first
|
154
|
-
newaddress = Bitcoin.encode_segwit_address(testversion, program_hex)
|
155
|
-
newaddress.should == nil
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
end
|
@@ -1,666 +0,0 @@
|
|
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
|
-
Bitcoin.hash160_from_address("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4")
|
94
|
-
.should == "751e76e8199196d454941c45d1b3a323f1433bd6"
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should survive rounds of hash160 <-> address' do
|
98
|
-
hex = "62e907b15cbf27d5425399ebf6f0fb50ebb88f18"
|
99
|
-
|
100
|
-
Bitcoin::network = :testnet
|
101
|
-
addr = "mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt"
|
102
|
-
Bitcoin.hash160_from_address(Bitcoin.hash160_to_address(hex)).should == hex
|
103
|
-
Bitcoin.hash160_to_address(Bitcoin.hash160_from_address(addr)).should == addr
|
104
|
-
|
105
|
-
Bitcoin::network = :bitcoin
|
106
|
-
addr = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
|
107
|
-
Bitcoin.hash160_from_address(Bitcoin.hash160_to_address(hex)).should == hex
|
108
|
-
Bitcoin.hash160_to_address(Bitcoin.hash160_from_address(addr)).should == addr
|
109
|
-
end
|
110
|
-
|
111
|
-
it '#address_checksum?' do
|
112
|
-
Bitcoin::network = :testnet
|
113
|
-
Bitcoin.address_checksum?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
|
114
|
-
Bitcoin.address_checksum?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == true
|
115
|
-
Bitcoin.address_checksum?("f0f0f0").should == false
|
116
|
-
|
117
|
-
Bitcoin::network = :bitcoin
|
118
|
-
Bitcoin.address_checksum?("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa").should == true
|
119
|
-
Bitcoin.address_checksum?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
|
120
|
-
Bitcoin.address_checksum?("f0f0f0").should == false
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'validate bitcoin-address' do
|
124
|
-
|
125
|
-
Bitcoin::network = :testnet
|
126
|
-
|
127
|
-
Bitcoin.valid_address?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == true
|
128
|
-
Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == false
|
129
|
-
Bitcoin.valid_address?("1moYFpRM4LkTV4Ho5eCxiEPB2bSm3AsJNGj").should == false
|
130
|
-
Bitcoin.valid_address?("f0f0f0").should == false
|
131
|
-
|
132
|
-
Bitcoin::network = :bitcoin
|
133
|
-
|
134
|
-
Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == true
|
135
|
-
Bitcoin.valid_address?("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == false
|
136
|
-
Bitcoin.valid_address?("2D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == false
|
137
|
-
Bitcoin.valid_address?("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cX").should == false
|
138
|
-
Bitcoin.valid_address?("1moYFpRM4LkTV4Ho5eCxiEPB2bSm3AsJNGj").should == false
|
139
|
-
|
140
|
-
Bitcoin.valid_address?("1ZQxJYBRmbb2rDNYPhd96x3eMbNnPD98q").should == true
|
141
|
-
Bitcoin.valid_address?("12KhCL8nGK3Luy7ehU3AxPs1mTocdessLM").should == true
|
142
|
-
Bitcoin.valid_address?("1AnNQgfaGgSKejzR6km74tyQPDGwZBBVT").should == true
|
143
|
-
Bitcoin.valid_address?("f0f0f0").should == false
|
144
|
-
|
145
|
-
|
146
|
-
Bitcoin.base58_to_int("114EpVhtPpJQKti8HiH2fvXZFPiPkgDZrE").should \
|
147
|
-
== 15016857106811133404017207799481956647721349092596212439
|
148
|
-
|
149
|
-
Bitcoin.network, success = :testnet, true
|
150
|
-
400.times{
|
151
|
-
addr = Bitcoin.generate_address
|
152
|
-
success = false if Bitcoin.hash160_from_address(addr[0]) != addr[-1]
|
153
|
-
success = false if Bitcoin.hash160_to_address(addr[-1]) != addr[0]
|
154
|
-
success = false if Bitcoin.valid_address?(addr[0]) != true
|
155
|
-
}
|
156
|
-
success.should == true
|
157
|
-
|
158
|
-
Bitcoin.network, success = :bitcoin, true
|
159
|
-
400.times{
|
160
|
-
addr = Bitcoin.generate_address
|
161
|
-
success = false if Bitcoin.hash160_from_address(addr[0]) != addr[-1]
|
162
|
-
success = false if Bitcoin.hash160_to_address(addr[-1]) != addr[0]
|
163
|
-
success = false if Bitcoin.valid_address?(addr[0]) != true
|
164
|
-
}
|
165
|
-
success.should == true
|
166
|
-
end
|
167
|
-
|
168
|
-
it 'validate bitcoin public key' do
|
169
|
-
key = Bitcoin::Key.generate
|
170
|
-
Bitcoin.valid_pubkey?(key.pub_compressed).should == true
|
171
|
-
Bitcoin.valid_pubkey?(key.pub_uncompressed).should == true
|
172
|
-
Bitcoin.valid_pubkey?(key.addr).should == false
|
173
|
-
Bitcoin.valid_pubkey?(key.priv).should == false
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'validate p2sh address' do
|
177
|
-
Bitcoin.network = :testnet
|
178
|
-
Bitcoin.valid_address?("2MyLngQnhzjzatKsB7XfHYoP9e2XUXSiBMM").should == true
|
179
|
-
Bitcoin.network = :bitcoin
|
180
|
-
Bitcoin.valid_address?("3CkxTG25waxsmd13FFgRChPuGYba3ar36B").should == true
|
181
|
-
end
|
182
|
-
|
183
|
-
it '#address_type' do
|
184
|
-
Bitcoin.network = :testnet
|
185
|
-
Bitcoin.address_type("2MyLngQnhzjzatKsB7XfHYoP9e2XUXSiBMM").should == :p2sh
|
186
|
-
Bitcoin.address_type("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == :hash160
|
187
|
-
Bitcoin.address_type("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == nil
|
188
|
-
Bitcoin.network = :bitcoin
|
189
|
-
Bitcoin.address_type("3CkxTG25waxsmd13FFgRChPuGYba3ar36B").should == :p2sh
|
190
|
-
Bitcoin.address_type("1D3KpY5kXnYhTbdCbZ9kXb2ZY7ZapD85cW").should == :hash160
|
191
|
-
Bitcoin.address_type("mpXwg4jMtRhuSpVq4xS3HFHmCmWp9NyGKt").should == nil
|
192
|
-
Bitcoin.address_type("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4").should == :witness_v0_keyhash
|
193
|
-
Bitcoin.address_type("bc1qw508d6qejxtdg4y5r3zarvayr0c5xw7kv8f3t4").should == nil
|
194
|
-
Bitcoin.address_type("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3").should == :witness_v0_scripthash
|
195
|
-
|
196
|
-
# address_type recognizes Litecoin addresses encoded with the legacy P2SH version byte
|
197
|
-
Bitcoin.network = :litecoin
|
198
|
-
Bitcoin.address_type("3CkxTG25waxsmd13FFgRChPuGYba3ar36B").should == :p2sh
|
199
|
-
Bitcoin.address_type("MJy6m9S3thpJa8GwM8fm2LeJbFC22w18Vx").should == :p2sh
|
200
|
-
Bitcoin.address_type("2MyLngQnhzjzatKsB7XfHYoP9e2XUXSiBMM").should == nil
|
201
|
-
|
202
|
-
Bitcoin.network = :bitcoin
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'Bitcoin#checksum' do
|
206
|
-
Bitcoin.checksum("0062e907b15cbf27d5425399ebf6f0fb50ebb88f18").should == "c29b7d93"
|
207
|
-
end
|
208
|
-
|
209
|
-
it '#bitcoin_mrkl' do
|
210
|
-
# block 170 is the first block that has a transaction.
|
211
|
-
# hash 00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee
|
212
|
-
a = "b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082"
|
213
|
-
b = "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16"
|
214
|
-
c = "7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
|
215
|
-
|
216
|
-
Bitcoin.bitcoin_hash(b + a) .should == c
|
217
|
-
Bitcoin.bitcoin_mrkl(a , b) .should == c
|
218
|
-
end
|
219
|
-
|
220
|
-
it 'mrkl_tree from transaction-hashes' do
|
221
|
-
|
222
|
-
# mrkl tree for block 170
|
223
|
-
mrkl_tree = [
|
224
|
-
"b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082",# tx 1
|
225
|
-
"f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",# tx 2
|
226
|
-
"7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
|
227
|
-
]
|
228
|
-
Bitcoin.hash_mrkl_tree(mrkl_tree[0...2]).should == mrkl_tree
|
229
|
-
|
230
|
-
|
231
|
-
mrkl_tree = [
|
232
|
-
"4fa598026d9be1ca0c2bff1b531e566b7ea7f90b72e75fda0c1795bc2dfa375c",
|
233
|
-
"186640daf908156e2616790d7c816235b0c43f668c3c38351b348c08ca44d457",
|
234
|
-
"ef3928700309b4deceac9a992a19a7481b4e520cbc0b1ab74e2645eee39c8da0",
|
235
|
-
|
236
|
-
"688c53517f62f7a65c0e87519c18a4de98f2ccafbf389b269d0bb867f88d166a",
|
237
|
-
"01889506f7fe9210045f588361881e2d16a034a62bc48ebd7b6b0a3edeaf5a6d",
|
238
|
-
|
239
|
-
"74f3a7df861d6a58957b84a3e425a8cf57e1e2e3a3def046dd200baeb8714f00"
|
240
|
-
]
|
241
|
-
|
242
|
-
Bitcoin.hash_mrkl_tree( mrkl_tree[0...3] ).should == mrkl_tree
|
243
|
-
|
244
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[3]
|
245
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[2] ).should == mrkl_tree[4]
|
246
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[3], mrkl_tree[4] ).should == mrkl_tree[5]
|
247
|
-
|
248
|
-
mrkl_tree[0...3].each.with_index do |target, idx|
|
249
|
-
branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0...3], target )
|
250
|
-
Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
|
251
|
-
end
|
252
|
-
|
253
|
-
mrkl_tree = [
|
254
|
-
"349f717b6630e1f305f95964a2d94117dacca76e0b715d4d7a5657698ec96c6c", # 0
|
255
|
-
"7f44a84349200473455bcfc05ee68036e23993a6f58dce3f6a7faab46a754440", # 1
|
256
|
-
"6b3ba3fdfb7eeb6c2e5fd0e36e5bb4634da294521f7b1b808286c214981f9b17", # 2
|
257
|
-
"0467b41043d654ba3dc3940cbefec0eb38feed6e7085a8e825e4f782eccb48e3", # 3
|
258
|
-
"83d0231624f7a7d5c37557461ac0d09a8ad7a1f4ab673dd697acb275d4b114de", # 4
|
259
|
-
"074970aaa98db7d00e6f97a719fe85e9c7f51b75fa5a9a92218d568ccc2b21fe", # 5
|
260
|
-
|
261
|
-
"c1b6d2a416de6b63e42c1b50f229911bfb07f816e0795bb86ff7dcf0463ab0df", # 6
|
262
|
-
"751bcfd8acc10792f42050dca5b852f7a2fcd5300897d05907a98473f59a5650", # 7
|
263
|
-
"7abf551000d942efb93afc2d6174dc1bb7d41e8ea5fd76724685000734f1d77b", # 8
|
264
|
-
|
265
|
-
"e268927aa50d44de5365c11a2e402478767b7b98856a21a0715f9db65709aabb", # 9
|
266
|
-
"ed5ecc6b0e2fdd81be806599d6509d166e26849049e60e8d8b398641282b1e5a", # 10
|
267
|
-
|
268
|
-
"72e0e61880cc5fc9c7b5990c2d40b22eba783391b72807d2d5349fb55875c015" # 11
|
269
|
-
]
|
270
|
-
|
271
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[6]
|
272
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[3] ).should == mrkl_tree[7]
|
273
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[4], mrkl_tree[5] ).should == mrkl_tree[8]
|
274
|
-
|
275
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[6], mrkl_tree[7] ).should == mrkl_tree[9]
|
276
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[8], mrkl_tree[8] ).should == mrkl_tree[10]
|
277
|
-
|
278
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[9], mrkl_tree[10] ).should == mrkl_tree[11]
|
279
|
-
|
280
|
-
Bitcoin.hash_mrkl_tree(mrkl_tree[0...6]).should == mrkl_tree
|
281
|
-
|
282
|
-
mrkl_tree[0...5].each.with_index do |target, idx|
|
283
|
-
branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0..5], target )
|
284
|
-
Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
|
285
|
-
end
|
286
|
-
|
287
|
-
mrkl_tree = [
|
288
|
-
"627c859b5af6d537930fd16148eb0597542bea543f65fc2b0e5f188b5a458529", # 0
|
289
|
-
"d00b90525820a74f30ce26488db7f77c6ee9577e650568a051edd8560bbf83a1", # 1
|
290
|
-
"706b8ac1a433bc28385450626e12c1c7806032dc8b7e12221f417c5f22059d70", # 2
|
291
|
-
"10107ad569400a5f9621498e410845e6db0551671a2cafcf4358bd7867c6bc14", # 3
|
292
|
-
"ac6b08a363aedd5e58177c7f68bb213403ef78d24be0012c06b3483a9e2461fe", # 4
|
293
|
-
"d3074f5b33a44d9961f40eadf250cdc1425f7975012fccb6b06abc5202c53f4b", # 5
|
294
|
-
"3270c13599266d3a8da90a85a07fc003c58a8ff2938988356783b6261be335a6", # 6
|
295
|
-
"e097c3e2e3a07385628ac5a5a775e8a5e22dda3732bee32ae65b1430d080fc32", # 7
|
296
|
-
"c335a3963e8d89a9f46b94158d33f9b0dee25e776cba91be5eda44898bd31a78", # 8
|
297
|
-
|
298
|
-
"eb52315c6b26f72fa58ed95cd4886f1aa047ecd8f34ed8a367f59854f20733d8", # 9
|
299
|
-
"f97bf49e42e1732c0b515ecbac7cffc29c8c75c20c6783ad48b09d348fe0b6cf", # 10
|
300
|
-
"fc655dfc41eed4e2ea4cfe33ebb6bf593eb256bf86c17802fd03567668d0bf71", # 11
|
301
|
-
"06c4abf5dae15d5fa3632e7e5f82f05e7afbbfd495ea8015c6094764d868654c", # 12
|
302
|
-
"31bbd6e4523aeaaaf75b6ea4ef63d0fe3dba66fb719f4a4232891a3b58ad5cec", # 13
|
303
|
-
|
304
|
-
"0c728622b795e14ac40c4aa13cb732a0407b2b85c9108c6f06c083220bb6d65d", # 14
|
305
|
-
"f83f6ea46edcbeaa738ce4701bf48412a10c4b1a9f109efe44bc8fe5cb6b0017", # 15
|
306
|
-
"5e6168778c8407ace3ae9901a2f5197d6f21a6634ae0af639e52d14c39b13e02", # 16
|
307
|
-
|
308
|
-
"b92a7980b8a8a64f896027c0de732298d04ca56bea66c18cf97983037486e456", # 17
|
309
|
-
"2a2fd5e450b6ec31ccbe9d827f2e903714eb69c351300b1e76c587aef60e000c", # 18
|
310
|
-
|
311
|
-
"9ed561bb49c47648e0250cb074721d94cba84ed1e083f1e57c29eca78e36d73d" # 19
|
312
|
-
]
|
313
|
-
|
314
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[0], mrkl_tree[1] ).should == mrkl_tree[9]
|
315
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[2], mrkl_tree[3] ).should == mrkl_tree[10]
|
316
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[4], mrkl_tree[5] ).should == mrkl_tree[11]
|
317
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[6], mrkl_tree[7] ).should == mrkl_tree[12]
|
318
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[8], mrkl_tree[8] ).should == mrkl_tree[13]
|
319
|
-
|
320
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[9], mrkl_tree[10] ).should == mrkl_tree[14]
|
321
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[11], mrkl_tree[12] ).should == mrkl_tree[15]
|
322
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[13], mrkl_tree[13] ).should == mrkl_tree[16]
|
323
|
-
|
324
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[14], mrkl_tree[15] ).should == mrkl_tree[17]
|
325
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[16], mrkl_tree[16] ).should == mrkl_tree[18]
|
326
|
-
|
327
|
-
Bitcoin.bitcoin_mrkl( mrkl_tree[17], mrkl_tree[18] ).should == mrkl_tree[19]
|
328
|
-
|
329
|
-
Bitcoin.hash_mrkl_tree(mrkl_tree[0...9]).should == mrkl_tree
|
330
|
-
|
331
|
-
mrkl_tree[0..8].each.with_index do |target, idx|
|
332
|
-
branch = Bitcoin.hash_mrkl_branch( mrkl_tree[0..8], target )
|
333
|
-
Bitcoin.mrkl_branch_root( branch, target, idx ).should == mrkl_tree[-1]
|
334
|
-
end
|
335
|
-
|
336
|
-
end
|
337
|
-
|
338
|
-
it 'should not allow duplicate hash in merkle trees' do
|
339
|
-
Bitcoin.hash_mrkl_tree(["aa", "bb", "cc"]).last.should !=
|
340
|
-
Bitcoin.hash_mrkl_tree(["aa", "bb", "cc", "cc"]).last
|
341
|
-
end
|
342
|
-
|
343
|
-
it 'return a value even if a merkle branch is empty' do
|
344
|
-
branch = []
|
345
|
-
mrkl_index = 0
|
346
|
-
target = "089b911f5e471c0e1800f3384281ebec5b372fbb6f358790a92747ade271ccdf"
|
347
|
-
Bitcoin.mrkl_branch_root(branch.map(&:hth), target, mrkl_index).should == target
|
348
|
-
end
|
349
|
-
|
350
|
-
it 'nonce compact bits to bignum hex' do
|
351
|
-
Bitcoin.decode_compact_bits( "1b00b5ac".to_i(16) ).index(/[^0]/).should == 12
|
352
|
-
Bitcoin.decode_compact_bits( "1b00b5ac".to_i(16) ).to_i(16).should ==
|
353
|
-
"000000000000b5ac000000000000000000000000000000000000000000000000".to_i(16)
|
354
|
-
|
355
|
-
|
356
|
-
target = 453031340
|
357
|
-
Bitcoin.decode_compact_bits( target ).should ==
|
358
|
-
"000000000000b5ac000000000000000000000000000000000000000000000000"
|
359
|
-
Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
|
360
|
-
|
361
|
-
target = 486604799
|
362
|
-
Bitcoin.decode_compact_bits( target ).should ==
|
363
|
-
"00000000ffff0000000000000000000000000000000000000000000000000000"
|
364
|
-
Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
|
365
|
-
|
366
|
-
target = 476399191 # from block 40,320
|
367
|
-
Bitcoin.decode_compact_bits(target).should ==
|
368
|
-
"0000000065465700000000000000000000000000000000000000000000000000"
|
369
|
-
Bitcoin.encode_compact_bits( Bitcoin.decode_compact_bits( target ) ).should == target
|
370
|
-
|
371
|
-
#Bitcoin.network = :dogecoin
|
372
|
-
#Bitcoin.decode_compact_bits( "01fedcba".to_i(16) ).to_i(16).should == -0x7e
|
373
|
-
end
|
374
|
-
|
375
|
-
it '#block_hash' do
|
376
|
-
# block 0 n_tx: 1
|
377
|
-
prev_block="0000000000000000000000000000000000000000000000000000000000000000"
|
378
|
-
mrkl_root ="4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
379
|
-
time, bits, nonce, ver = 1231006505, 486604799, 2083236893, 1
|
380
|
-
|
381
|
-
Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
|
382
|
-
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
383
|
-
|
384
|
-
|
385
|
-
# block 1 n_tx: 1
|
386
|
-
prev_block="000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
387
|
-
mrkl_root ="0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
|
388
|
-
time, bits, nonce, ver = 1231469665, 486604799, 2573394689, 1
|
389
|
-
|
390
|
-
Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
|
391
|
-
"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
|
392
|
-
|
393
|
-
# .. only n_tx: 1
|
394
|
-
|
395
|
-
# block 169 n_tx: 1
|
396
|
-
prev_block="00000000567e95797f93675ac23683ae3787b183bb36859c18d9220f3fa66a69"
|
397
|
-
mrkl_root ="d7b9a9da6becbf47494c27e913241e5a2b85c5cceba4b2f0d8305e0a87b92d98"
|
398
|
-
time, bits, nonce, ver = 1231730523, 486604799, 3718213931, 1
|
399
|
-
|
400
|
-
Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
|
401
|
-
"000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55"
|
402
|
-
|
403
|
-
|
404
|
-
# block 170 n_tx: 2
|
405
|
-
prev_block="000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55"
|
406
|
-
mrkl_root ="7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff"
|
407
|
-
time, bits, nonce, ver = 1231731025, 486604799, 1889418792, 1
|
408
|
-
|
409
|
-
Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
|
410
|
-
"00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee"
|
411
|
-
|
412
|
-
|
413
|
-
# block 171 n_tx: 1
|
414
|
-
prev_block="00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee"
|
415
|
-
mrkl_root ="d5f2d21453a6f0e67b5c42959c9700853e4c4d46fa7519d1cc58e77369c893f2"
|
416
|
-
time, bits, nonce, ver = 1231731401, 486604799, 653436935, 1
|
417
|
-
Bitcoin.block_hash(prev_block, mrkl_root, time, bits, nonce, ver).should ==
|
418
|
-
"00000000c9ec538cab7f38ef9c67a95742f56ab07b0a37c5be6b02808dbfb4e0"
|
419
|
-
end
|
420
|
-
|
421
|
-
it 'generates openssl-secp256k1 private/public keypair' do
|
422
|
-
private_key, public_key = Bitcoin.generate_key
|
423
|
-
|
424
|
-
private_key.size .should == 64 # bytes in hex
|
425
|
-
public_key.size .should == 130 # bytes in hex
|
426
|
-
|
427
|
-
key = Bitcoin.open_key(private_key, public_key)
|
428
|
-
Bitcoin.inspect_key( key ).should == [ private_key, public_key ]
|
429
|
-
end
|
430
|
-
|
431
|
-
begin
|
432
|
-
Bitcoin::OpenSSL_EC
|
433
|
-
it 'opens key from private key and resolves public key' do
|
434
|
-
50.times.all?{
|
435
|
-
private_key, public_key = Bitcoin.generate_key
|
436
|
-
key = Bitcoin.open_key(private_key)
|
437
|
-
[ key.private_key_hex, key.public_key_hex ] == [ private_key, public_key ]
|
438
|
-
}.should == true
|
439
|
-
end
|
440
|
-
|
441
|
-
it 'extract private key from uncompressed DER format' do
|
442
|
-
der = "308201130201010420a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6cd417b808db1ccd0aa081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a14403420004768cfc6c44b927b0e69e9dd343e96132f7cd1d360d8cb8d65c83d89d7beaceadfd19918e076606a099344156acdb026b1065a958e39f098cfd0a34dd976291d6"
|
443
|
-
|
444
|
-
Bitcoin::OpenSSL_EC.der_to_private_key(der).should == "a29fe0f28b2936dbc89f889f74cd1f0662d18a873ac15d6cd417b808db1ccd0a"
|
445
|
-
end
|
446
|
-
|
447
|
-
it 'sign and verify text messages (signmessage/verifymessage)' do
|
448
|
-
[
|
449
|
-
["1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ", "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747",
|
450
|
-
"040b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a7447b5f0bba9e01e6fe4735c8383e6e7a3347a0fd72381b8f797a19f694054e5a69"],
|
451
|
-
["1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs", "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747",
|
452
|
-
"030b4c866585dd868a9d62348a9cd008d6a312937048fff31670e7e920cfc7a744"]
|
453
|
-
].each{|address, privkey, pubkey|
|
454
|
-
key = Bitcoin.open_key(privkey)
|
455
|
-
16.times.each { |n|
|
456
|
-
#10_000.times.all?{|n|
|
457
|
-
# puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip if (n % 1_000) == 0
|
458
|
-
s = Bitcoin.sign_message(key.private_key_hex, key.public_key_hex, "Very secret message %d: 11" % n)
|
459
|
-
Bitcoin.verify_message(s['address'], 'invalid-signature', s['message']).should == false
|
460
|
-
Bitcoin.verify_message(s['address'], s['signature'], s['message']).should == true
|
461
|
-
}
|
462
|
-
}
|
463
|
-
|
464
|
-
Bitcoin.network = :testnet3
|
465
|
-
Bitcoin.verify_message("mwPVMbZQgkpwJJt2YP3sLSgbEBQw3FWZSc", "H5GER0Nz+L7TPZMQzXtv0hnLSsyfPok9lkdHIv01vksREpEpOhTPTonU1xvyPAOIIKhU3++Ol+LaWKWmsfyxDXk=", "A"*500).should == true
|
466
|
-
Bitcoin.network = :bitcoin
|
467
|
-
end
|
468
|
-
rescue LoadError
|
469
|
-
end
|
470
|
-
|
471
|
-
it 'generates new bitcoin-address' do
|
472
|
-
address, private_key, public_key, hash160 = Bitcoin.generate_address
|
473
|
-
|
474
|
-
private_key.size .should == 64 # bytes in hex
|
475
|
-
public_key.size .should == 130 # bytes in hex
|
476
|
-
#Bitcoin.valid_address?(address).should == true # fix/extend
|
477
|
-
Bitcoin.hash160_to_address(Bitcoin.hash160(public_key)).should == address
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'encodes and decodes base58' do
|
481
|
-
# fixtures from: https://github.com/bitcoin/bitcoin/blob/master/src/test/base58_tests.cpp
|
482
|
-
bin = [
|
483
|
-
"",
|
484
|
-
"\x61",
|
485
|
-
"\x62\x62\x62",
|
486
|
-
"\x63\x63\x63",
|
487
|
-
"\x73\x69\x6d\x70\x6c\x79\x20\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67",
|
488
|
-
"\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",
|
489
|
-
"\x51\x6b\x6f\xcd\x0f",
|
490
|
-
"\xbf\x4f\x89\x00\x1e\x67\x02\x74\xdd",
|
491
|
-
"\x57\x2e\x47\x94",
|
492
|
-
"\xec\xac\x89\xca\xd9\x39\x23\xc0\x23\x21",
|
493
|
-
"\x10\xc8\x51\x1e",
|
494
|
-
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
495
|
-
]
|
496
|
-
out = [
|
497
|
-
"",
|
498
|
-
"2g",
|
499
|
-
"a3gV",
|
500
|
-
"aPEr",
|
501
|
-
"2cFupjhnEsSn59qHXstmK2ffpLv2",
|
502
|
-
"1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L",
|
503
|
-
"ABnLTmg",
|
504
|
-
"3SEo3LWLoPntC",
|
505
|
-
"3EFU7m",
|
506
|
-
"EJDM8drfXA6uyA",
|
507
|
-
"Rt5zm",
|
508
|
-
"1111111111"
|
509
|
-
]
|
510
|
-
|
511
|
-
fixtures = bin.zip(out).map{|b,out| [ b.unpack("H*")[0], out ] }
|
512
|
-
#fixtures.each{|hex,out| p [hex, out, Bitcoin.encode_base58(hex), Bitcoin.decode_base58(out)] }
|
513
|
-
fixtures.all?{|hex,out| Bitcoin.encode_base58(hex) == out }.should == true
|
514
|
-
fixtures.all?{|hex,out| Bitcoin.decode_base58(out) == hex }.should == true
|
515
|
-
end
|
516
|
-
|
517
|
-
it '#block_next_retarget' do
|
518
|
-
Bitcoin.block_next_retarget(189408).should == 189503
|
519
|
-
Bitcoin.block_next_retarget(189503).should == 189503
|
520
|
-
Bitcoin.block_next_retarget(189504).should == 191519
|
521
|
-
end
|
522
|
-
|
523
|
-
it '#block_difficulty' do
|
524
|
-
Bitcoin.block_difficulty(436835377).should == "1751454.5353407"
|
525
|
-
end
|
526
|
-
|
527
|
-
it 'should calculate retarget difficulty' do
|
528
|
-
prev_height = 201599
|
529
|
-
prev_block_time = 1349227021
|
530
|
-
prev_block_bits = 0x1a05db8b
|
531
|
-
last_retarget_time = 1348092851
|
532
|
-
new_difficulty = Bitcoin.block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
|
533
|
-
|
534
|
-
Bitcoin.decode_compact_bits(new_difficulty.should) == Bitcoin.decode_compact_bits(0x1a057e08)
|
535
|
-
end
|
536
|
-
|
537
|
-
it '#block_hashes_to_win' do
|
538
|
-
Bitcoin.block_hashes_to_win(436835377).should == 7522554734795001
|
539
|
-
end
|
540
|
-
|
541
|
-
it '#block_probability' do
|
542
|
-
Bitcoin.block_probability(436835377).should ==
|
543
|
-
"0.0000000000000001329335625003267087884673003372881794348"
|
544
|
-
end
|
545
|
-
|
546
|
-
it '#block_average_hashing_time' do
|
547
|
-
Bitcoin.block_average_hashing_time(436835377, 630_000_000).should == 11940563
|
548
|
-
end
|
549
|
-
|
550
|
-
it '#block_average_mining_time' do
|
551
|
-
Bitcoin.block_average_mining_time(0x1a022fbe, 231337, 270.0, 1.0).should == 56.50855038530773 # days
|
552
|
-
end
|
553
|
-
|
554
|
-
it '#blockchain_total_btc' do
|
555
|
-
# 0.step(6930000, 210000){|height|
|
556
|
-
# p total_btc(height-1) unless height == 0
|
557
|
-
# p total_btc(height)
|
558
|
-
# }
|
559
|
-
[0, 209999, 210000, 419999, 420000, 1680000].map{|height|
|
560
|
-
Bitcoin.blockchain_total_btc(height)
|
561
|
-
}.should == [
|
562
|
-
[5000000000, 1, 5000000000, 0],
|
563
|
-
[1050000000000000, 1, 5000000000, 209999],
|
564
|
-
[1050005000000000, 2, 2500000000, 210000],
|
565
|
-
[1575002500000000, 2, 2500000000, 419999],
|
566
|
-
[1575005000000000, 3, 1250000000, 420000],
|
567
|
-
[2091801875000000, 9, 19531250, 1680000]
|
568
|
-
]
|
569
|
-
end
|
570
|
-
|
571
|
-
it '#block_creation_reward' do
|
572
|
-
[0, 209999, 210000, 419999, 420000, 1680000].map{|height|
|
573
|
-
Bitcoin.block_creation_reward(height)
|
574
|
-
}.should == [ 5000000000, 5000000000, 2500000000, 2500000000, 1250000000, 19531250 ]
|
575
|
-
end
|
576
|
-
|
577
|
-
# Port of Bitcoin Core test vectors.
|
578
|
-
# https://github.com/bitcoin/bitcoin/blob/595a7bab23bc21049526229054ea1fff1a29c0bf/src/test/base58_tests.cpp#L139
|
579
|
-
it "valid address JSON tests" do
|
580
|
-
restore_network = Bitcoin.network_name
|
581
|
-
|
582
|
-
test_cases = JSON.parse(fixtures_file('base58_keys_valid.json'))
|
583
|
-
test_cases.each do |test_case|
|
584
|
-
# Single element arrays in tests are comments.
|
585
|
-
next if test_case.length == 1
|
586
|
-
|
587
|
-
address = test_case[0]
|
588
|
-
script = test_case[1].htb
|
589
|
-
is_privkey = test_case[2].fetch('isPrivkey')
|
590
|
-
is_swapcase_valid = test_case[2].fetch('tryCaseFlip', false)
|
591
|
-
|
592
|
-
Bitcoin.network =
|
593
|
-
case test_case[2].fetch('chain').to_sym
|
594
|
-
when :main then :bitcoin
|
595
|
-
when :test then :testnet3
|
596
|
-
when :regtest then :regtest
|
597
|
-
end
|
598
|
-
|
599
|
-
# This spec only tests address generation, not base58 private key encoding
|
600
|
-
next if is_privkey
|
601
|
-
|
602
|
-
computed_script = Bitcoin::Script.to_address_script(address)
|
603
|
-
computed_script.should == script
|
604
|
-
|
605
|
-
Bitcoin.valid_address?(address.swapcase).should == is_swapcase_valid
|
606
|
-
|
607
|
-
computed_address = Bitcoin::Script.new(script).get_address
|
608
|
-
computed_address.should == address
|
609
|
-
end
|
610
|
-
|
611
|
-
Bitcoin.network = restore_network
|
612
|
-
end
|
613
|
-
|
614
|
-
# Port of Bitcoin Core test vectors.
|
615
|
-
# https://github.com/bitcoin/bitcoin/blob/595a7bab23bc21049526229054ea1fff1a29c0bf/src/test/base58_tests.cpp#L179
|
616
|
-
it "invalid address JSON tests" do
|
617
|
-
restore_network = Bitcoin.network_name
|
618
|
-
|
619
|
-
test_cases = JSON.parse(fixtures_file('base58_keys_invalid.json'))
|
620
|
-
test_cases.each do |test_case|
|
621
|
-
address = test_case[0]
|
622
|
-
|
623
|
-
%i(bitcoin testnet3 regtest).each do |network_name|
|
624
|
-
Bitcoin.network = network_name
|
625
|
-
|
626
|
-
Bitcoin.valid_address?(address).should == false
|
627
|
-
end
|
628
|
-
end
|
629
|
-
|
630
|
-
Bitcoin.network = restore_network
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
|
635
|
-
__END__
|
636
|
-
describe 'Bitcoin-Wiki - Common Standards - Hashes' do
|
637
|
-
# https://en.bitcoin.it/wiki/Protocol_specification
|
638
|
-
# Hashes
|
639
|
-
# Usually, when a hash is computed within bitcoin, it is computed twice.
|
640
|
-
# Most of the time SHA-256 hashes are used, however RIPEMD-160 is also
|
641
|
-
# used when a shorter hash is desirable.
|
642
|
-
|
643
|
-
require 'digest/sha2'
|
644
|
-
require 'digest/rmd160'
|
645
|
-
|
646
|
-
|
647
|
-
it 'double-SHA-256 encoding of string "hello"' do
|
648
|
-
# first round sha256
|
649
|
-
Digest::SHA256.hexdigest("hello").should ==
|
650
|
-
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
|
651
|
-
|
652
|
-
# second round sha256
|
653
|
-
Digest::SHA256.hexdigest( Digest::SHA256.digest("hello") ).should ==
|
654
|
-
"9595c9df90075148eb06860365df33584b75bff782a510c6cd4883a419833d50"
|
655
|
-
end
|
656
|
-
|
657
|
-
it 'RIPEMD-160 encoding of string "hello"' do
|
658
|
-
# first round sha256
|
659
|
-
Digest::SHA256.hexdigest("hello").should ==
|
660
|
-
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
|
661
|
-
|
662
|
-
# second round rmd160
|
663
|
-
Digest::RMD160.hexdigest( Digest::SHA256.digest("hello") ).should ==
|
664
|
-
"b6a9c8c230722b7c748331a8b450f05566dc7d0f"
|
665
|
-
end
|
666
|
-
end
|