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.
- 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
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
module Bitcoin
|
|
4
4
|
module Protocol
|
|
5
|
-
|
|
5
|
+
# TxIn section of https://en.bitcoin.it/wiki/Protocol_documentation#tx
|
|
6
6
|
class TxIn
|
|
7
|
-
|
|
8
7
|
# previous output hash
|
|
9
8
|
attr_accessor :prev_out_hash
|
|
10
|
-
alias
|
|
11
|
-
def prev_out=(hash)
|
|
9
|
+
alias prev_out prev_out_hash
|
|
10
|
+
def prev_out=(hash)
|
|
11
|
+
@prev_out_hash = hash
|
|
12
|
+
end
|
|
12
13
|
|
|
13
14
|
# previous output index
|
|
14
15
|
attr_accessor :prev_out_index
|
|
15
16
|
|
|
16
17
|
# script_sig input Script (signature)
|
|
17
|
-
|
|
18
|
+
attr_reader :script_sig
|
|
19
|
+
attr_accessor :script_sig_length
|
|
18
20
|
|
|
19
21
|
# signature hash and the address of the key that needs to sign it
|
|
20
22
|
# (used when dealing with unsigned or partly signed tx)
|
|
@@ -23,17 +25,17 @@ module Bitcoin
|
|
|
23
25
|
# segregated witness
|
|
24
26
|
attr_accessor :script_witness
|
|
25
27
|
|
|
26
|
-
alias
|
|
27
|
-
alias
|
|
28
|
+
alias script script_sig
|
|
29
|
+
alias script_length script_sig_length
|
|
28
30
|
|
|
29
31
|
# sequence
|
|
30
32
|
attr_accessor :sequence
|
|
31
33
|
|
|
32
|
-
DEFAULT_SEQUENCE = "\xff\xff\xff\xff"
|
|
33
|
-
NULL_HASH = "\x00"*32
|
|
34
|
+
DEFAULT_SEQUENCE = "\xff\xff\xff\xff".freeze
|
|
35
|
+
NULL_HASH = "\x00" * 32
|
|
34
36
|
COINBASE_INDEX = 0xffffffff
|
|
35
37
|
|
|
36
|
-
def initialize
|
|
38
|
+
def initialize(*args)
|
|
37
39
|
@prev_out_hash, @prev_out_index, @script_sig_length,
|
|
38
40
|
@script_sig, @sequence = *args
|
|
39
41
|
@script_sig_length ||= 0
|
|
@@ -48,13 +50,18 @@ module Bitcoin
|
|
|
48
50
|
@prev_out_index == other.prev_out_index &&
|
|
49
51
|
@script_sig == other.script_sig &&
|
|
50
52
|
@sequence == other.sequence
|
|
51
|
-
rescue
|
|
53
|
+
rescue StandardError
|
|
52
54
|
false
|
|
53
55
|
end
|
|
54
|
-
|
|
56
|
+
|
|
57
|
+
def is_final? # rubocop:disable Naming/PredicateName
|
|
58
|
+
warn '[DEPRECATION] `TxIn.is_final?` is deprecated. Use `final?` instead.'
|
|
59
|
+
final?
|
|
60
|
+
end
|
|
61
|
+
|
|
55
62
|
# returns true if the sequence number is final (DEFAULT_SEQUENCE)
|
|
56
|
-
def
|
|
57
|
-
|
|
63
|
+
def final?
|
|
64
|
+
sequence == DEFAULT_SEQUENCE
|
|
58
65
|
end
|
|
59
66
|
|
|
60
67
|
# parse raw binary data for transaction input
|
|
@@ -65,11 +72,13 @@ module Bitcoin
|
|
|
65
72
|
end
|
|
66
73
|
|
|
67
74
|
def self.from_io(buf)
|
|
68
|
-
txin = new
|
|
75
|
+
txin = new
|
|
76
|
+
txin.parse_data_from_io(buf)
|
|
77
|
+
txin
|
|
69
78
|
end
|
|
70
79
|
|
|
71
80
|
def parse_data_from_io(buf)
|
|
72
|
-
@prev_out_hash, @prev_out_index = buf.read(36).unpack(
|
|
81
|
+
@prev_out_hash, @prev_out_index = buf.read(36).unpack('a32V')
|
|
73
82
|
@script_sig_length = Protocol.unpack_var_int_from_io(buf)
|
|
74
83
|
@script_sig = buf.read(@script_sig_length)
|
|
75
84
|
@sequence = buf.read(4)
|
|
@@ -79,40 +88,39 @@ module Bitcoin
|
|
|
79
88
|
@parsed_script ||= Bitcoin::Script.new(script_sig)
|
|
80
89
|
end
|
|
81
90
|
|
|
82
|
-
def to_payload(script
|
|
83
|
-
[@prev_out_hash, @prev_out_index].pack(
|
|
91
|
+
def to_payload(script = @script_sig, sequence = @sequence)
|
|
92
|
+
[@prev_out_hash, @prev_out_index].pack('a32V') << Protocol.pack_var_int(script.bytesize) \
|
|
93
|
+
<< script << (sequence || DEFAULT_SEQUENCE)
|
|
84
94
|
end
|
|
85
95
|
|
|
86
|
-
def to_hash(
|
|
87
|
-
t = { 'prev_out'
|
|
96
|
+
def to_hash(_options = {})
|
|
97
|
+
t = { 'prev_out' => { 'hash' => @prev_out_hash.reverse_hth, 'n' => @prev_out_index } }
|
|
88
98
|
if coinbase?
|
|
89
|
-
t['coinbase'] = @script_sig.unpack(
|
|
99
|
+
t['coinbase'] = @script_sig.unpack('H*')[0]
|
|
90
100
|
else # coinbase tx
|
|
91
101
|
t['scriptSig'] = Bitcoin::Script.new(@script_sig).to_string
|
|
92
102
|
end
|
|
93
|
-
t['sequence']
|
|
94
|
-
t['witness'] = @script_witness.stack.map
|
|
103
|
+
t['sequence'] = @sequence.unpack('V')[0] unless @sequence == "\xff\xff\xff\xff"
|
|
104
|
+
t['witness'] = @script_witness.stack.map(&:bth) unless @script_witness.empty?
|
|
95
105
|
t
|
|
96
106
|
end
|
|
97
107
|
|
|
98
108
|
def self.from_hash(input)
|
|
99
109
|
previous_hash = input['previous_transaction_hash'] || input['prev_out']['hash']
|
|
100
110
|
previous_output_index = input['output_index'] || input['prev_out']['n']
|
|
101
|
-
txin = TxIn.new([
|
|
102
|
-
if input['coinbase']
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if input['witness']
|
|
108
|
-
|
|
109
|
-
end
|
|
110
|
-
txin.sequence = [ input['sequence'] || 0xffffffff ].pack("V")
|
|
111
|
+
txin = TxIn.new([previous_hash].pack('H*').reverse, previous_output_index)
|
|
112
|
+
txin.script_sig = if input['coinbase']
|
|
113
|
+
[input['coinbase']].pack('H*')
|
|
114
|
+
else
|
|
115
|
+
Script.binary_from_string(input['scriptSig'] || input['script'])
|
|
116
|
+
end
|
|
117
|
+
input['witness'].each { |w| txin.script_witness.stack << w.htb } if input['witness']
|
|
118
|
+
txin.sequence = [input['sequence'] || 0xffffffff].pack('V')
|
|
111
119
|
txin
|
|
112
120
|
end
|
|
113
121
|
|
|
114
122
|
def self.from_hex_hash(hash, index)
|
|
115
|
-
TxIn.new([hash].pack(
|
|
123
|
+
TxIn.new([hash].pack('H*').reverse, index, 0)
|
|
116
124
|
end
|
|
117
125
|
|
|
118
126
|
# previous output in hex
|
|
@@ -130,13 +138,11 @@ module Bitcoin
|
|
|
130
138
|
@script_sig_length = script_sig.bytesize
|
|
131
139
|
@script_sig = script_sig
|
|
132
140
|
end
|
|
133
|
-
alias
|
|
141
|
+
alias script= script_sig=
|
|
134
142
|
|
|
135
143
|
def add_signature_pubkey_script(sig, pubkey_hex)
|
|
136
|
-
self.script = Bitcoin::Script.to_signature_pubkey_script(sig, [pubkey_hex].pack(
|
|
144
|
+
self.script = Bitcoin::Script.to_signature_pubkey_script(sig, [pubkey_hex].pack('H*'))
|
|
137
145
|
end
|
|
138
|
-
|
|
139
146
|
end
|
|
140
|
-
|
|
141
147
|
end
|
|
142
148
|
end
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Bitcoin
|
|
4
4
|
module Protocol
|
|
5
|
-
|
|
5
|
+
# TxOut section of https://en.bitcoin.it/wiki/Protocol_documentation#tx
|
|
6
6
|
class TxOut
|
|
7
|
-
|
|
8
7
|
# output value (in base units; "satoshi")
|
|
9
8
|
attr_accessor :value
|
|
10
9
|
|
|
@@ -14,16 +13,20 @@ module Bitcoin
|
|
|
14
13
|
# p2sh redeem script (optional, not included in the serialized binary format)
|
|
15
14
|
attr_accessor :redeem_script
|
|
16
15
|
|
|
17
|
-
def initialize
|
|
16
|
+
def initialize(*args)
|
|
18
17
|
if args.size == 2
|
|
19
|
-
@value
|
|
18
|
+
@value = args[0]
|
|
19
|
+
@pk_script_length = args[1].bytesize
|
|
20
|
+
@pk_script = args[1]
|
|
20
21
|
else
|
|
21
22
|
@value, @pk_script_length, @pk_script = *args
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def ==(other)
|
|
26
|
-
@value == other.value && @pk_script == other.pk_script
|
|
27
|
+
@value == other.value && @pk_script == other.pk_script
|
|
28
|
+
rescue StandardError
|
|
29
|
+
false
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
# parse raw binary data for transaction output
|
|
@@ -34,18 +37,20 @@ module Bitcoin
|
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def self.from_io(buf)
|
|
37
|
-
txout = new
|
|
40
|
+
txout = new
|
|
41
|
+
txout.parse_data_from_io(buf)
|
|
42
|
+
txout
|
|
38
43
|
end
|
|
39
44
|
|
|
40
45
|
# parse raw binary data for transaction output
|
|
41
46
|
def parse_data_from_io(buf)
|
|
42
47
|
clear_parsed_script_cache
|
|
43
|
-
@value = buf.read(8).unpack(
|
|
48
|
+
@value = buf.read(8).unpack('Q')[0]
|
|
44
49
|
@pk_script_length = Protocol.unpack_var_int_from_io(buf)
|
|
45
50
|
@pk_script = buf.read(@pk_script_length)
|
|
46
51
|
end
|
|
47
52
|
|
|
48
|
-
alias
|
|
53
|
+
alias parse_payload parse_data
|
|
49
54
|
|
|
50
55
|
def parsed_script
|
|
51
56
|
@parsed_script ||= Bitcoin::Script.new(pk_script)
|
|
@@ -56,7 +61,7 @@ module Bitcoin
|
|
|
56
61
|
end
|
|
57
62
|
|
|
58
63
|
def to_payload
|
|
59
|
-
[@value].pack(
|
|
64
|
+
[@value].pack('Q') << Protocol.pack_var_int(@pk_script_length) << @pk_script
|
|
60
65
|
end
|
|
61
66
|
|
|
62
67
|
def to_null_payload
|
|
@@ -64,14 +69,17 @@ module Bitcoin
|
|
|
64
69
|
end
|
|
65
70
|
|
|
66
71
|
def to_hash(options = {})
|
|
67
|
-
h = { 'value' =>
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
h = { 'value' => format('%.8f', (@value / 100_000_000.0)),
|
|
73
|
+
'scriptPubKey' => parsed_script.to_string }
|
|
74
|
+
if options[:with_address]
|
|
75
|
+
addrs = parsed_script.get_addresses
|
|
76
|
+
h['address'] = addrs.first if addrs.size == 1
|
|
77
|
+
end
|
|
70
78
|
h
|
|
71
79
|
end
|
|
72
80
|
|
|
73
81
|
def self.from_hash(output)
|
|
74
|
-
amount = output['value'] ? output['value'].
|
|
82
|
+
amount = output['value'] ? output['value'].delete('.').to_i : output['amount']
|
|
75
83
|
script = Script.binary_from_string(output['scriptPubKey'] || output['script'])
|
|
76
84
|
new(amount, script)
|
|
77
85
|
end
|
|
@@ -79,14 +87,15 @@ module Bitcoin
|
|
|
79
87
|
# set pk_script and pk_script_length
|
|
80
88
|
def pk_script=(pk_script)
|
|
81
89
|
clear_parsed_script_cache
|
|
82
|
-
@pk_script_length
|
|
90
|
+
@pk_script_length = pk_script.bytesize
|
|
91
|
+
@pk_script = pk_script
|
|
83
92
|
end
|
|
84
93
|
|
|
85
|
-
alias
|
|
86
|
-
alias
|
|
94
|
+
alias amount value
|
|
95
|
+
alias amount= value=
|
|
87
96
|
|
|
88
|
-
alias
|
|
89
|
-
alias
|
|
97
|
+
alias script pk_script
|
|
98
|
+
alias script= pk_script=
|
|
90
99
|
|
|
91
100
|
# create output spending +value+ btc (base units) to +address+
|
|
92
101
|
def self.value_to_address(value, address)
|
|
@@ -94,8 +103,6 @@ module Bitcoin
|
|
|
94
103
|
raise "Script#pk_script nil with address #{address}" unless pk_script
|
|
95
104
|
new(value, pk_script)
|
|
96
105
|
end
|
|
97
|
-
|
|
98
106
|
end
|
|
99
|
-
|
|
100
107
|
end
|
|
101
108
|
end
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Bitcoin
|
|
4
4
|
module Protocol
|
|
5
|
-
|
|
6
5
|
# https://en.bitcoin.it/wiki/Protocol_specification#version
|
|
7
6
|
class Version
|
|
8
7
|
# services bit constants
|
|
@@ -11,78 +10,92 @@ module Bitcoin
|
|
|
11
10
|
|
|
12
11
|
attr_reader :fields
|
|
13
12
|
|
|
14
|
-
def initialize(opts={})
|
|
13
|
+
def initialize(opts = {})
|
|
15
14
|
@fields = {
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
:
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
:
|
|
23
|
-
:
|
|
24
|
-
:
|
|
25
|
-
}.merge(
|
|
15
|
+
version: Bitcoin.network[:protocol_version],
|
|
16
|
+
services: NODE_NETWORK,
|
|
17
|
+
time: Time.now.tv_sec,
|
|
18
|
+
from: '127.0.0.1:8333',
|
|
19
|
+
to: '127.0.0.1:8333',
|
|
20
|
+
nonce: Bitcoin::Protocol::Uniq,
|
|
21
|
+
user_agent: "/bitcoin-ruby:#{Bitcoin::VERSION}/",
|
|
22
|
+
last_block: 0, # 188617
|
|
23
|
+
relay: true # BIP0037
|
|
24
|
+
}.merge(opts.reject { |_k, v| v.nil? })
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def to_payload
|
|
29
28
|
[
|
|
30
|
-
@fields.values_at(:version, :services, :time).pack(
|
|
29
|
+
@fields.values_at(:version, :services, :time).pack('VQQ'),
|
|
31
30
|
pack_address_field(@fields[:from]),
|
|
32
31
|
pack_address_field(@fields[:to]),
|
|
33
|
-
@fields.values_at(:nonce).pack(
|
|
32
|
+
@fields.values_at(:nonce).pack('Q'),
|
|
34
33
|
Protocol.pack_var_string(@fields[:user_agent]),
|
|
35
|
-
@fields.values_at(:last_block).pack(
|
|
36
|
-
|
|
34
|
+
@fields.values_at(:last_block).pack('V'),
|
|
35
|
+
# Satoshi 0.8.6 doesn't send this but it does respect it
|
|
36
|
+
Protocol.pack_boolean(@fields[:relay])
|
|
37
37
|
].join
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def to_pkt
|
|
41
|
-
Bitcoin::Protocol.pkt(
|
|
41
|
+
Bitcoin::Protocol.pkt('version', to_payload)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def parse(payload)
|
|
45
|
-
version, services, timestamp, to, from, nonce, payload = payload.unpack(
|
|
46
|
-
to
|
|
45
|
+
version, services, timestamp, to, from, nonce, payload = payload.unpack('VQQa26a26Qa*')
|
|
46
|
+
to = unpack_address_field(to)
|
|
47
|
+
from = unpack_address_field(from)
|
|
47
48
|
user_agent, payload = Protocol.unpack_var_string(payload)
|
|
48
|
-
last_block, payload = payload.unpack(
|
|
49
|
-
relay,
|
|
49
|
+
last_block, payload = payload.unpack('Va*')
|
|
50
|
+
relay, = unpack_relay_field(version, payload)
|
|
50
51
|
|
|
51
52
|
@fields = {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
version: version, services: services, time: timestamp,
|
|
54
|
+
from: from, to: to, nonce: nonce,
|
|
55
|
+
user_agent: user_agent.to_s, last_block: last_block, relay: relay
|
|
55
56
|
}
|
|
56
57
|
self
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def unpack_address_field(payload)
|
|
60
|
-
ip, port = payload.unpack(
|
|
61
|
-
"#{ip.unpack(
|
|
61
|
+
ip, port = payload.unpack('x8x12a4n')
|
|
62
|
+
"#{ip.unpack('C*').join('.')}:#{port}"
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
def pack_address_field(addr_str)
|
|
65
|
-
host, port = addr_str.split(
|
|
66
|
+
host, port = addr_str.split(':')
|
|
66
67
|
port = port ? port.to_i : 8333
|
|
67
68
|
sockaddr = Socket.pack_sockaddr_in(port, host)
|
|
68
|
-
#raise "invalid IPv4 Address: #{addr}" unless sockaddr[0...2] == "\x02\x00"
|
|
69
|
-
port
|
|
70
|
-
|
|
69
|
+
# raise "invalid IPv4 Address: #{addr}" unless sockaddr[0...2] == "\x02\x00"
|
|
70
|
+
port = sockaddr[2...4]
|
|
71
|
+
host = sockaddr[4...8]
|
|
72
|
+
[[1].pack('Q'), "\x00" * 10, "\xFF\xFF", host, port].join
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
# BIP0037: this field starts with version 70001 and is allowed to be missing, defaults to true
|
|
74
76
|
def unpack_relay_field(version, payload)
|
|
75
|
-
|
|
77
|
+
version >= 70_001 && payload ? Protocol.unpack_boolean(payload) : [true, nil]
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
def uptime
|
|
79
81
|
@fields[:time] - Time.now.tv_sec
|
|
80
82
|
end
|
|
81
83
|
|
|
82
|
-
def method_missing(*a)
|
|
84
|
+
def method_missing(*a)
|
|
85
|
+
@fields[a.first]
|
|
86
|
+
rescue StandardError
|
|
87
|
+
super
|
|
88
|
+
end
|
|
83
89
|
|
|
84
|
-
def
|
|
85
|
-
|
|
90
|
+
def respond_to_missing?(*a)
|
|
91
|
+
@fields[a.first]
|
|
92
|
+
rescue StandardError
|
|
93
|
+
super
|
|
94
|
+
end
|
|
86
95
|
|
|
96
|
+
def self.parse(payload)
|
|
97
|
+
new.parse(payload)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
87
100
|
end
|
|
88
101
|
end
|
data/lib/bitcoin/script.rb
CHANGED
|
@@ -161,9 +161,13 @@ class Bitcoin::Script
|
|
|
161
161
|
attr_reader :raw, :chunks, :debug, :stack
|
|
162
162
|
|
|
163
163
|
# create a new script. +bytes+ is typically input_script + output_script
|
|
164
|
+
|
|
164
165
|
def initialize(input_script, previous_output_script=nil)
|
|
165
166
|
@raw_byte_sizes = [input_script.bytesize, previous_output_script ? previous_output_script.bytesize : 0]
|
|
166
167
|
@input_script, @previous_output_script = input_script, previous_output_script
|
|
168
|
+
@parse_invalid = nil
|
|
169
|
+
@inner_p2sh = nil
|
|
170
|
+
@script_codeseparator_index = nil
|
|
167
171
|
|
|
168
172
|
@raw = if @previous_output_script
|
|
169
173
|
@input_script + [ Bitcoin::Script::OP_CODESEPARATOR ].pack("C") + @previous_output_script
|
|
@@ -258,7 +262,7 @@ class Bitcoin::Script
|
|
|
258
262
|
(chunks || @chunks).each.with_index{|i,idx|
|
|
259
263
|
string << " " unless idx == 0
|
|
260
264
|
string << case i
|
|
261
|
-
when
|
|
265
|
+
when Bitcoin::Integer
|
|
262
266
|
if opcode = OPCODES_PARSE_BINARY[i]
|
|
263
267
|
opcode
|
|
264
268
|
else
|
|
@@ -276,9 +280,10 @@ class Bitcoin::Script
|
|
|
276
280
|
end
|
|
277
281
|
|
|
278
282
|
def to_binary(chunks=nil)
|
|
283
|
+
|
|
279
284
|
(chunks || @chunks).map{|chunk|
|
|
280
285
|
case chunk
|
|
281
|
-
when
|
|
286
|
+
when Bitcoin::Integer; [chunk].pack("C*")
|
|
282
287
|
when String; self.class.pack_pushdata(chunk)
|
|
283
288
|
end
|
|
284
289
|
}.join
|
|
@@ -317,7 +322,7 @@ class Bitcoin::Script
|
|
|
317
322
|
# Adds opcode (OP_0, OP_1, ... OP_CHECKSIG etc.)
|
|
318
323
|
# Returns self.
|
|
319
324
|
def append_opcode(opcode)
|
|
320
|
-
raise "Opcode should be
|
|
325
|
+
raise "Opcode should be an integer" if !opcode.is_a?(Bitcoin::Integer)
|
|
321
326
|
if opcode >= OP_0 && opcode <= 0xff
|
|
322
327
|
@chunks << opcode
|
|
323
328
|
else
|
|
@@ -417,7 +422,7 @@ class Bitcoin::Script
|
|
|
417
422
|
end
|
|
418
423
|
end
|
|
419
424
|
|
|
420
|
-
buf << if i.is_a?(
|
|
425
|
+
buf << if i.is_a?(Bitcoin::Integer)
|
|
421
426
|
i < 256 ? [i].pack("C") : [OpenSSL::BN.new(i.to_s,10).to_hex].pack("H*")
|
|
422
427
|
else
|
|
423
428
|
i
|
|
@@ -452,7 +457,7 @@ class Bitcoin::Script
|
|
|
452
457
|
#p [@stack, @do_exec]
|
|
453
458
|
|
|
454
459
|
case chunk
|
|
455
|
-
when
|
|
460
|
+
when Bitcoin::Integer
|
|
456
461
|
if DISABLED_OPCODES.include?(chunk)
|
|
457
462
|
@script_invalid = true
|
|
458
463
|
@debug << "DISABLED_#{OPCODES[chunk]}"
|
|
@@ -550,7 +555,8 @@ class Bitcoin::Script
|
|
|
550
555
|
|
|
551
556
|
# is this a :script_hash (pay-to-script-hash/p2sh) script?
|
|
552
557
|
def is_pay_to_script_hash?
|
|
553
|
-
|
|
558
|
+
@inner_p2sh ||= false
|
|
559
|
+
return false if @inner_p2sh
|
|
554
560
|
if @previous_output_script
|
|
555
561
|
chunks = Bitcoin::Script.new(@previous_output_script).chunks
|
|
556
562
|
chunks.size == 3 &&
|
|
@@ -590,7 +596,7 @@ class Bitcoin::Script
|
|
|
590
596
|
|
|
591
597
|
# is this a multisig script
|
|
592
598
|
def is_multisig?
|
|
593
|
-
return false if @chunks.size < 4 || !@chunks[-2].is_a?(
|
|
599
|
+
return false if @chunks.size < 4 || !@chunks[-2].is_a?(Bitcoin::Integer)
|
|
594
600
|
@chunks[-1] == OP_CHECKMULTISIG and get_multisig_pubkeys.all?{|c| c.is_a?(String) }
|
|
595
601
|
end
|
|
596
602
|
|
|
@@ -616,12 +622,12 @@ class Bitcoin::Script
|
|
|
616
622
|
|
|
617
623
|
# Verify the script is only pushing data onto the stack
|
|
618
624
|
def is_push_only?(script_data=nil)
|
|
619
|
-
check_pushes(
|
|
625
|
+
check_pushes(true, false, (script_data||@input_script))
|
|
620
626
|
end
|
|
621
627
|
|
|
622
628
|
# Make sure opcodes used to push data match their intended length ranges
|
|
623
629
|
def pushes_are_canonical?(script_data=nil)
|
|
624
|
-
check_pushes(
|
|
630
|
+
check_pushes(false, true, (script_data||@raw))
|
|
625
631
|
end
|
|
626
632
|
|
|
627
633
|
def check_pushes(push_only=true, canonical_only=false, buf)
|
|
@@ -930,7 +936,7 @@ class Bitcoin::Script
|
|
|
930
936
|
elsif chunk == OP_CHECKMULTISIG || chunk == OP_CHECKMULTISIGVERIFY
|
|
931
937
|
# Accurate mode counts exact number of pubkeys required (not signatures, but pubkeys!). Only used in P2SH scripts.
|
|
932
938
|
# Inaccurate mode counts every multisig as 20 signatures.
|
|
933
|
-
if is_accurate && last_opcode && last_opcode.is_a?(
|
|
939
|
+
if is_accurate && last_opcode && last_opcode.is_a?(Bitcoin::Integer) && last_opcode >= OP_1 && last_opcode <= OP_16
|
|
934
940
|
count += ::Bitcoin::Script.decode_OP_N(last_opcode)
|
|
935
941
|
else
|
|
936
942
|
count += 20
|
|
@@ -956,7 +962,7 @@ class Bitcoin::Script
|
|
|
956
962
|
data = nil
|
|
957
963
|
@chunks.each do |chunk|
|
|
958
964
|
case chunk
|
|
959
|
-
when
|
|
965
|
+
when Bitcoin::Integer
|
|
960
966
|
data = ""
|
|
961
967
|
return 0 if chunk > OP_16
|
|
962
968
|
when String
|
|
@@ -974,7 +980,7 @@ class Bitcoin::Script
|
|
|
974
980
|
if opcode == OP_0
|
|
975
981
|
return 0
|
|
976
982
|
end
|
|
977
|
-
if opcode.is_a?(
|
|
983
|
+
if opcode.is_a?(Bitcoin::Integer) && opcode >= OP_1 && opcode <= OP_16
|
|
978
984
|
return opcode - (OP_1 - 1);
|
|
979
985
|
else
|
|
980
986
|
nil
|
|
@@ -1533,11 +1539,6 @@ class Bitcoin::Script
|
|
|
1533
1539
|
op_verify
|
|
1534
1540
|
end
|
|
1535
1541
|
|
|
1536
|
-
# op_eval: https://en.bitcoin.it/wiki/BIP_0012
|
|
1537
|
-
# the BIP was never accepted and must be handled as old OP_NOP1
|
|
1538
|
-
def op_nop1
|
|
1539
|
-
end
|
|
1540
|
-
|
|
1541
1542
|
OPCODES_METHOD = Hash[*instance_methods.grep(/^op_/).map{|m|
|
|
1542
1543
|
[ (OPCODES.find{|k,v| v == m.to_s.upcase }.first rescue nil), m ]
|
|
1543
1544
|
}.flatten]
|