def test_sign_input(self): private_key = PrivateKey(secret=8675309) tx_ins = [] prev_tx = bytes.fromhex( '0025bc3c0fa8b7eb55b9437fdbd016870d18e0df0ace7bc9864efc38414147c8') tx_ins.append( TxIn( prev_tx=prev_tx, prev_index=0, script_sig=b'', sequence=0xffffffff, )) tx_outs = [] h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2') tx_outs.append( TxOut(amount=int(0.99 * 100000000), script_pubkey=p2pkh_script(h160))) h160 = decode_base58('mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf') tx_outs.append( TxOut(amount=int(0.1 * 100000000), script_pubkey=p2pkh_script(h160))) tx = Tx( version=1, tx_ins=tx_ins, tx_outs=tx_outs, locktime=0, testnet=True, ) self.assertTrue(tx.sign_input(0, private_key, SIGHASH_ALL))
def test_sign_input(self): private_key = PrivateKey(secret=8675309) tx_ins = [] prev_tx = unhexlify( '0025bc3c0fa8b7eb55b9437fdbd016870d18e0df0ace7bc9864efc38414147c8') tx_ins.append( TxIn( prev_tx=prev_tx, prev_index=0, script_sig=b'', sequence=0xffffffff, )) tx_ins[0]._value = 110000000 tx_ins[0]._script_pubkey = Script.parse( private_key.point.p2pkh_script()) tx_outs = [] h160 = Tx.get_address_data( 'mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2')['h160'] tx_outs.append( TxOut(amount=int(0.99 * 100000000), script_pubkey=p2pkh_script(h160))) h160 = Tx.get_address_data( 'mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf')['h160'] tx_outs.append( TxOut(amount=int(0.1 * 100000000), script_pubkey=p2pkh_script(h160))) tx = Tx( version=1, tx_ins=tx_ins, tx_outs=tx_outs, locktime=0, testnet=True, ) self.assertTrue(tx.sign_input(0, private_key, SIGHASH_ALL))
def test_sbtc(self): raw = unhexlify( '0100000002a81e0df5218289cc4ee761a1747b494990cc1f5b2dc84f0542ad6f28f69d5f4c040000006b483045022100aaf4a05870a9a8ca79a612600936d27bbfce97ebf4e2fe4d311e40c4b78ca6550220175ecff50679023ffce58019ee711784229b8c738b85093d34b4ccc72592087341210313910dbdf4ecfc35f6193b8f6484ab554587f6c7e5e376351e0978e7433d8c80ffffffff17a8282d91fccc03f7d422f5b124427c09c391aca3743cc1e04b7afbe8e282b9010000006b483045022100ef1c6716e19cf7de6eea6cb6468ce7efb2480d72795dc2066d7b1ea823830a6102204cbcdc56e420d9a88a650c126375815443636a0d628096b1439814445156bb0a41210313910dbdf4ecfc35f6193b8f6484ab554587f6c7e5e376351e0978e7433d8c80ffffffff01a05d5804000000001976a9144c3496d9f64847b45318baa5afd6b515c76013cf88ac00000000' ) stream = BytesIO(raw) tx = SBTCTx.parse(stream) tx.tx_ins[0]._value = 67700000 h160 = SBTCTx.get_address_data( '14fR5g6ypHFx3F9mJwiHaHXkMs5YjS4fJZ')['h160'] tx.tx_ins[0]._script_pubkey = Script.parse(p2pkh_script(h160)) tx.tx_ins[1]._value = 5300000 tx.tx_ins[0]._script_pubkey = Script.parse(p2pkh_script(h160)) self.assertTrue(tx.verify())
def test_btg(self): raw = unhexlify( '0200000002618c8a9c486a961e57e99c8a249cd43937f4447083a3c9589cc30eebb38e0d8d010000006a473044022075173f771f997652e94c461a22147c1154336fb498cfb2cc4a5af5d0b94f43960220322a22f4290a580e3f0953cff7ba548c63d0829936413fc805a802bb005881014121034a66bef852adc6fa774d95a7ebef5a2b18e3b61d05e23130b9a4ad6fffa536bdfeffffff8afa4e2c895facf0354e66910cf6ed02e8549eaad8926688dedb754781e118b2010000006a473044022025575c1912ae89a29a639fca6ac3d72423214dbff62afd7a48a358464585da0d022068706419a61e60a571c084797177856f514a9ecd8d8df2f2e113c5daa4e560f041210259316ac5f9f5fecb6597929de0cb05739432b067b79444a57adbf9e413fc61defeffffff021f7a1b1d000000001976a914dd23a9af489c2b1e08a13122aac1a06752df8ed188ac7af11400000000001976a914bd31883c773888a0f99e16deeff118ff0ec15d0888ac7dbf0700' ) stream = BytesIO(raw) tx = BTGTx.parse(stream) tx.tx_ins[0]._value = 488779958 h160 = BTGTx.get_address_data( 'GWmfLaQ7ZKmUX7rmW63u63b9ghbuwr9yN1')['h160'] tx.tx_ins[0]._script_pubkey = Script.parse(p2pkh_script(h160)) tx.tx_ins[1]._value = 969979 h160 = BTGTx.get_address_data( 'GgvZtZ8aV1UhTgLzzRbXVLrwwVoJL9WywW')['h160'] tx.tx_ins[1]._script_pubkey = Script.parse(p2pkh_script(h160)) self.assertTrue(tx.verify())
def test_bch(self): raw = unhexlify( '01000000021128db2baee531447170d0916a553b07e8912a1c47e4e174afc7bfdf4afd3185010000008a4730440220211497a5609bcdeba19552e54a96b63f153656ecc5ba997ca8174a8102b4d8c602206a079685c36b46902ba366e112ba17b44e79dc8cb9b3b4792848c4f2f97192ae41410456e1306c1068ff31f1e8dbdd0b976092b1b4903b1a8ee3fe878508fa7f584d399b3a0a48c4215cded444257ce358b04720c62c73d5a8c0bb4ad261096baaaec4ffffffffedc5aa7918bd8beb801277177b3b7d15924682358e6342570be84f91e6d11835010000008a47304402203b0ee7aedaa5237325caee0433eeaba2ce2aff53d5c09c91bc2a79c51500f0b702201ecfd381d027a0d08b2409691bc73c16e626cbcd3c80a9980fa1e41b7a11cb5041410456e1306c1068ff31f1e8dbdd0b976092b1b4903b1a8ee3fe878508fa7f584d399b3a0a48c4215cded444257ce358b04720c62c73d5a8c0bb4ad261096baaaec4ffffffff01ac3ae60e000000001976a91441e904a482e61766cec490a8a5f3fbcf6bffdb2a88ac00000000' ) stream = BytesIO(raw) tx = BCHTx.parse(stream) self.assertTrue(tx.verify()) raw_tx = unhexlify( '01000000066f267f335a54abf404c66a7a6e9ed3d77566a09ce11632f57029a677f42c6095000000006b483045022100fb0b16699c9b0984345c7860e208c04694aaa5117c8306082cfafc58b53e489a02203cd53408f1f8c8ff29701a9d1f6960b2dc5e1039f0eea949c5a886ac367e1e38412102fdcae0e5a55b20c8d3cbdf451d39f6d47daa50f884ed0ffcf0ae0adfeec4abb9ffffffff4ceb6a2894b19b96fedd543750bf7307805a2f6ca189c8c42d1abbe2930235fa000000006a4730440220794c269d519b567aa694de6dcde1d09dffa30b69dc18a619ce9ea65f239899150220156394f70f405c0710851490b9f21dc8a23931fbdc8a70ea51f73e9b00274a5c412103b708cd0b3329cff03611b0155384d1d4f40cb3aa30f82d8f4a34da044c868058ffffffff15053ac5123a25e0adf0ed998dfb710fff827861ac1a4c6601be8034179350ab000000006a473044022020e7b448318fa44b977d557b639aaf3a9666cf6d8dd446bd7812e752ddfcd1d302207159d22c2e379b77b0514b8e0767d0e9fff7063a659c268d605be436f65703884121031a97eb1664ceffa32988f7ea7c6726d681f1385b9765be1a40d6083fba4e6c69ffffffff2e1fb2ad94461104b147ffe95d0534eb98495c45831547b70eae652ac6cf52d0000000006b483045022100b0ce5496d51673f82430eee24c57f7f2f2631e5b9b32c78bbd79e1cbf3f6297b02201c807ecfa86c1c493e83f1235a19e4426da651e8f76c2f4b41ceebf1222a9291412102e4aa3631fd0b4a877c7c0a040b8211636f743c392ce17e6f266beb1b62490af9ffffffff311368bcf1bac2ae2e906bd7e84e9b45da861a63154ae5c3d69840f65486ba86000000006b483045022100d5f63c5284604eefb942fa9710f8d5b5bccf431e63c496237a0c41eb5c6debf102202bda17f3b7406b9c41f44c7377261413cfa144489a70a40e9e9126b3e7f2fc734121032e413587a71814365b7912eac3a052d8ac0c5f2351d3d84863a02bafefd41f19ffffffff2e9e219c5a68079891a8d2b00bfcf3772fa605997773c2c516bb5ac99aa8ee06000000006a47304402207b6e0d96d0ce538fb54fcb1731a35632b6e40efde834ce45ee22f0c0f5baa886022009327de37e3fb657af29161d265db558869c09e295e84ddb2f686a492db0015a41210389c44f336f7c8cc3096f8f40bc5bdbffea24da9e26649dbe6b862d7d369698d0ffffffff0102b84f05000000001976a9145c52250125494685f133df34f47fb88799b2903588ac00000000' ) stream = BytesIO(raw_tx) tx = BCHTx.parse(stream) inputs = ( ('18Lk6CB2WSpc4BVbxWhZrxLaYaJA2XVtyU', 24285000), ('13xY6E2tnBC5eGFCkayAUdVVcuGkFPoebJ', 824730), ('1BjFmsA4StiDa9xjAwahFXNpzR6SfXxBFD', 7583000), ('1Nn5QirD9iFT5kSF35XN8E3SX3SJM1daPL', 13150000), ('1HE8AdXHkP2bbnKmgENET4iyCHncP7rd7G', 32850000), ('1J3BgNjoqeR5JhHzC2rgorzBXTmdbmYcau', 10422900), ) for i, data in enumerate(inputs): addr, value = data tx_in = tx.tx_ins[i] i += 1 h160 = Tx.get_address_data(addr)['h160'] tx_in._value = value tx_in._script_pubkey = Script.parse(p2pkh_script(h160)) self.assertTrue(tx.verify())
def buildoutputs(pubkeysarr, amountsarr): tx_outs = [] for i in range(len(pubkeysarr)): if amountsarr[i] != 0: tx_outs.append( TxOut( amount=int(amountsarr[i]), script_pubkey=p2pkh_script(decode_base58(pubkeysarr[i])), )) return tx_outs
def test_bcd(self): raw = unhexlify( '0c00000025b6923ff3cb4264408ed5d5cca3cc41c7586820c95aeec24503d5a11418dd2501d0b96dd7ff4e3de5113ca48cefcbb4083541154c75e51a2e7b09879301a71cc5000000006a47304402201e10a7a5d03235236475feede87c57a38a79ab3399aafe90fcb9c47de525603b0220547fd8897c0e9d318dbe6c350c784eeb31b3cb18fbf550516fcc0168c22810e5012103e97b79d9aa924bfcea2915235ebc5b4cc7db5414e63ccb61ed2d197e29cb9fdbffffffff0280cb7831000000001976a91449664b451210fc8b3c055ce5606f0d8199ceae6788ac5a434600000000001976a9148868e1942ff8445f2e3791d9fa1dc881b8aec08c88ac00000000' ) stream = BytesIO(raw) tx = BCDTx.parse(stream) tx.tx_ins[0]._value = 834614762 h160 = BCDTx.get_address_data( '1MtE3mjo4AByFJSB8bAuVUHeqb21brLKJ5')['h160'] tx.tx_ins[0]._script_pubkey = Script.parse(p2pkh_script(h160)) self.assertTrue(tx.verify())
def test_btcp(self): raw = bytes.fromhex( '0100000001d5b2052ed9921a83228a9412074425f1b9878588c57cf52961b898d4df345aeb000000008248304502210094d1109cd76909af898aa68c7344a64e18fb7e7a041744a6eecb189f6bdf343802205235353c2fa55c8b087f912511b74350754eb337dbab3b693d1c1232e471b6034121023ec8c89df7dd593314119de90a5535ab8904bef24b3bbd7e459b8cf30a9f49321600148b8f8534e4164c763bec8e674391eadb4ab82903ffffffff02709ebd79000000001976a914e75092ac5b36c1af6f90913729a6353cc5aca9c488ace0516806000000001976a914b3b255028648e151b3e419ab6c5b2e9656ba363988ac00000000' ) stream = BytesIO(raw) tx = BTCPTx.parse(stream) tx.tx_ins[0]._value = 2150000000 redeem_script = Script.parse( bytes.fromhex('1600148b8f8534e4164c763bec8e674391eadb4ab82903')) h160 = Script.parse(redeem_script.elements[0]).elements[1] tx.tx_ins[0]._script_pubkey = Script.parse(p2pkh_script(h160)) self.assertTrue(tx.verify())
def get_address_data(cls, addr): b58 = decode_base58(addr) prefix = b58[0] h160 = b58[1:] testnet = prefix in cls.testnet_prefixes if prefix in cls.p2pkh_prefixes: script_pubkey = Script.parse(p2pkh_script(h160)) elif prefix in cls.p2sh_prefixes: script_pubkey = Script.parse(p2sh_script(h160)) else: raise RuntimeError('unknown type of address {}'.format(addr)) return { 'testnet': testnet, 'h160': h160, 'script_pubkey': script_pubkey, }
def test_sig_hash_bip143(self): raw_tx = unhexlify( '0100000001fd5145175fafdee6d20ac376e376cf26d933848ba5aa177d0d163a462fb3f183010000006b483045022100f49a17e80098bc057e319b890bdc42fe7224e7f6beb69a650102f802239be154022069742f504fdd52906c14d0d18ff0808e01146813775602163ec10d419270c1c541210223f1c80f382f086e2af7ad9d05227d94b6cf292596b9853f04a91194048f9048ffffffff0236820100000000001976a914dc10e999a5f18eb510feec09206d1812fa24a9c288ac5c058049000000001976a91421704f258089af191df1a4abed2b48ec11d6063e88ac00000000' ) stream = BytesIO(raw_tx) tx = Tx.parse(stream) tx_in = tx.tx_ins[0] raw_tx2 = unhexlify( '010000000185037eb5531900f2f450e55cd950c509310229c0444e318a8811eecfa3b5c183010000006b483045022100f4a6e308ff7846bd19d394ec1b7263e051f2a60e6819feb006cdb9047bdd21a502206d969dfb5dfee3e53ed1a79b441d1cc2b7b8fe945ac7507c3b5e180565fbaead4121037765d8921f9559a6f03d620a1687a57e5b4ecb9efa5b41fc44555da0a376f81affffffff021ffc6c00000000001976a914fe1f6bea216c790c30d07f52966850268a3f90a788acfc8b8149000000001976a9142563b8536a228ec866e1c1084044a7730e53758888ac00000000' ) stream2 = BytesIO(raw_tx2) tx2 = Tx.parse(stream2) tx_in._value = tx2.tx_outs[1].amount tx_in._script_pubkey = tx2.tx_outs[1].script_pubkey.serialize() der, hash_type = tx_in.der_signature() sec = tx_in.sec_pubkey() sig = Signature.parse(der) point = S256Point.parse(sec) z = tx.sig_hash_bip143(0, hash_type) self.assertTrue(point.verify(z, sig)) self.assertTrue(tx.verify_input(0)) self.assertTrue(tx.verify()) raw_tx = unhexlify( '01000000066f267f335a54abf404c66a7a6e9ed3d77566a09ce11632f57029a677f42c6095000000006b483045022100fb0b16699c9b0984345c7860e208c04694aaa5117c8306082cfafc58b53e489a02203cd53408f1f8c8ff29701a9d1f6960b2dc5e1039f0eea949c5a886ac367e1e38412102fdcae0e5a55b20c8d3cbdf451d39f6d47daa50f884ed0ffcf0ae0adfeec4abb9ffffffff4ceb6a2894b19b96fedd543750bf7307805a2f6ca189c8c42d1abbe2930235fa000000006a4730440220794c269d519b567aa694de6dcde1d09dffa30b69dc18a619ce9ea65f239899150220156394f70f405c0710851490b9f21dc8a23931fbdc8a70ea51f73e9b00274a5c412103b708cd0b3329cff03611b0155384d1d4f40cb3aa30f82d8f4a34da044c868058ffffffff15053ac5123a25e0adf0ed998dfb710fff827861ac1a4c6601be8034179350ab000000006a473044022020e7b448318fa44b977d557b639aaf3a9666cf6d8dd446bd7812e752ddfcd1d302207159d22c2e379b77b0514b8e0767d0e9fff7063a659c268d605be436f65703884121031a97eb1664ceffa32988f7ea7c6726d681f1385b9765be1a40d6083fba4e6c69ffffffff2e1fb2ad94461104b147ffe95d0534eb98495c45831547b70eae652ac6cf52d0000000006b483045022100b0ce5496d51673f82430eee24c57f7f2f2631e5b9b32c78bbd79e1cbf3f6297b02201c807ecfa86c1c493e83f1235a19e4426da651e8f76c2f4b41ceebf1222a9291412102e4aa3631fd0b4a877c7c0a040b8211636f743c392ce17e6f266beb1b62490af9ffffffff311368bcf1bac2ae2e906bd7e84e9b45da861a63154ae5c3d69840f65486ba86000000006b483045022100d5f63c5284604eefb942fa9710f8d5b5bccf431e63c496237a0c41eb5c6debf102202bda17f3b7406b9c41f44c7377261413cfa144489a70a40e9e9126b3e7f2fc734121032e413587a71814365b7912eac3a052d8ac0c5f2351d3d84863a02bafefd41f19ffffffff2e9e219c5a68079891a8d2b00bfcf3772fa605997773c2c516bb5ac99aa8ee06000000006a47304402207b6e0d96d0ce538fb54fcb1731a35632b6e40efde834ce45ee22f0c0f5baa886022009327de37e3fb657af29161d265db558869c09e295e84ddb2f686a492db0015a41210389c44f336f7c8cc3096f8f40bc5bdbffea24da9e26649dbe6b862d7d369698d0ffffffff0102b84f05000000001976a9145c52250125494685f133df34f47fb88799b2903588ac00000000' ) stream = BytesIO(raw_tx) tx = Tx.parse(stream) inputs = ( ('18Lk6CB2WSpc4BVbxWhZrxLaYaJA2XVtyU', 24285000), ('13xY6E2tnBC5eGFCkayAUdVVcuGkFPoebJ', 824730), ('1BjFmsA4StiDa9xjAwahFXNpzR6SfXxBFD', 7583000), ('1Nn5QirD9iFT5kSF35XN8E3SX3SJM1daPL', 13150000), ('1HE8AdXHkP2bbnKmgENET4iyCHncP7rd7G', 32850000), ('1J3BgNjoqeR5JhHzC2rgorzBXTmdbmYcau', 10422900), ) for i, data in enumerate(inputs): addr, value = data tx_in = tx.tx_ins[i] i += 1 h160 = decode_base58(addr) tx_in._value = value tx_in._script_pubkey = p2pkh_script(h160) self.assertTrue(tx.verify())
def sig_hash_preimage_bip143(self, input_index, hash_type): '''Returns the integer representation of the hash that needs to get signed for index input_index''' tx_in = self.tx_ins[input_index] # per BIP143 spec s = int_to_little_endian(self.version, 4) s += self.hash_prevouts() + self.hash_sequence() s += tx_in.prev_tx[::-1] + int_to_little_endian(tx_in.prev_index, 4) if tx_in.is_segwit(): h160 = tx_in.redeem_script()[-20:] ser = p2pkh_script(h160) else: ser = tx_in.script_pubkey().serialize() s += bytes([len(ser)]) + ser # script pubkey s += int_to_little_endian(tx_in.value(), 8) s += int_to_little_endian(tx_in.sequence, 4) s += self.hash_outputs() s += int_to_little_endian(self.locktime, 4) s += int_to_little_endian(hash_type | self.fork_id, 4) return s
def p2pkh_script(self, compressed=True): h160 = self.h160(compressed) return p2pkh_script(h160)
def test_long_p2pkh_script(self): h160 = unhexlify('c45f1b548d1bc074828c415639b207a19cea1b5d4a') expected = unhexlify( '76a915c45f1b548d1bc074828c415639b207a19cea1b5d4a88ac') self.assertEqual(p2pkh_script(h160), expected)
def test_p2pkh_script(self): h160 = unhexlify('74d691da1574e6b3c192ecfb52cc8984ee7b6c56') self.assertEqual(p2pkh_script(h160)[3:-2], h160)
tx_ins.append(TxIn( prev_tx=prev_tx, prev_index=0, script_sig=b'', sequence=0xffffffff, )) # Step 2 tx_outs = [] h160 = decode_base58(taddr1) print("t1") print(len(h160)) print(hexlify(h160)) tx_outs.append(TxOut( amount=int(t2*.97), script_pubkey=p2pkh_script(h160), )) h160 = decode_base58(taddr2) tx_outs.append(TxOut( amount=int(t2*.03), script_pubkey=p2pkh_script(h160), )) tx_obj = Tx(version=1, tx_ins=tx_ins, tx_outs=tx_outs, locktime=0, testnet=True) # Step 3 hash_type = SIGHASH_ALL z = tx_obj.sig_hash(0, hash_type) pk = PrivateKey(secret=privatekey) # sign with SIGHASH_ALL