示例#1
0
 def test_exercise_4(self):
     prev_tx = bytes.fromhex(
         '75a1c4bc671f55f626dda1074c7725991e6f68b8fcefcfca7b64405ca3b45f1c')
     prev_index = 1
     target_address = 'miKegze5FQNCnGw6PKyqUbYUeBa4x2hFeM'
     target_amount = 0.01
     change_address = 'mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2'
     change_amount = 0.009
     secret = 8675309
     priv = PrivateKey(secret=secret)
     tx_ins = []
     tx_ins.append(TxIn(prev_tx, prev_index, Script([]), 0xffffffff))
     tx_outs = []
     h160 = decode_base58(target_address)
     script_pubkey = p2pkh_script(h160)
     target_satoshis = int(target_amount * 100000000)
     tx_outs.append(TxOut(target_satoshis, script_pubkey))
     h160 = decode_base58(change_address)
     script_pubkey = p2pkh_script(h160)
     change_satoshis = int(change_amount * 100000000)
     tx_outs.append(TxOut(change_satoshis, script_pubkey))
     tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     self.assertTrue(tx_obj.sign_input(0, priv))
     self.assertTrue(tx_obj.verify())
     want = '01000000011c5fb4a35c40647bcacfeffcb8686f1e9925774c07a1dd26f6551f67bcc4a175010000006b483045022100a08ebb92422b3599a2d2fcdaa11f8f807a66ccf33e7f4a9ff0a3c51f1b1ec5dd02205ed21dfede5925362b8d9833e908646c54be7ac6664e31650159e8f69b6ca539012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff0240420f00000000001976a9141ec51b3654c1f1d0f4929d11a1f702937eaf50c888ac9fbb0d00000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac00000000'
     self.assertEqual(tx_obj.serialize().hex(), want)
示例#2
0
    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=Script([]),
                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))
示例#3
0
 def test_example_6(self):
     tx_ins = []
     prev_tx = bytes.fromhex(
         '0d6fe5213c0b3291f208cba8bfb59b7476dffacc4e5cb66f6eb20a080843a299')
     prev_index = 13
     tx_ins.append(TxIn(prev_tx, prev_index, Script([]), 0xffffffff))
     tx_outs = []
     change_amount = int(0.33 * 100000000)
     change_h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2')
     change_script = p2pkh_script(change_h160)
     tx_outs.append(TxOut(amount=change_amount,
                          script_pubkey=change_script))
     target_amount = int(0.1 * 100000000)
     target_h160 = decode_base58('mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf')
     target_script = p2pkh_script(target_h160)
     tx_outs.append(TxOut(amount=target_amount,
                          script_pubkey=target_script))
     transaction = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     z = transaction.sig_hash(0)
     private_key = PrivateKey(secret=8675309)
     der = private_key.sign(z).der()
     sig = der + SIGHASH_ALL.to_bytes(1, 'big')
     sec = private_key.point.sec()
     transaction.tx_ins[0].script_sig = Script([sig, sec])
     want = '010000000199a24308080ab26e6fb65c4eccfadf76749bb5bfa8cb08f291320b3c21e56f0d0d0000006b4830450221008ed46aa2cf12d6d81065bfabe903670165b538f65ee9a3385e6327d80c66d3b502203124f804410527497329ec4715e18558082d489b218677bd029e7fa306a72236012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff02408af701000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac80969800000000001976a914507b27411ccf7f16f10297de6cef3f291623eddf88ac00000000'
     self.assertEqual(transaction.serialize().hex(), want)
def new_commitment_tx(node, current_channel, cost, secret_hash):

    remote_peer = current_channel.peer

    # Create input using the output from the funding tx
    tx_in = TxIn(bytes.fromhex(current_channel.funding_tx.id()), 0)

    # Create 3 outputs. 1 to nodeA and 1 to nodeB and 1 to an HTLC script
    script_1 = p2pkh_script(decode_base58(node.address))
    tx_out_1 = TxOut(amount=current_channel.local_amt - cost,
                     script_pubkey=script_1)

    script_2 = p2pkh_script(decode_base58(remote_peer.btc_addr.decode()))
    tx_out_2 = TxOut(amount=current_channel.remote_amt, script_pubkey=script_2)

    #script_3 HTLC
    script_3 = Script([
        99, 168, secret_hash, 136, 118, 169,
        hash160(remote_peer.public_key.sec()), 103,
        encode_varint(1000), 177, 117, 118, 169,
        hash160(node.public_key.sec()), 104, 136, 172
    ])
    tx_out_3 = TxOut(amount=cost, script_pubkey=script_3)

    # Construct the commitment tx object
    commitment_tx = Tx(1, [tx_in], [tx_out_1, tx_out_2, tx_out_3], 0, True)

    #sign it
    commitment_tx.tx_ins[0].script_sig = get_script_sig(
        commitment_tx, node.private_key)

    return commitment_tx
示例#5
0
文件: tx.py 项目: yeonuk44/bitcoinpy
def sig_hash_bip143(prev_tx, tx, txi, redeem_script=None, witness_script=None, testnet=False):
    """
    bip143
    1:04LE       version
    2:32         hash prevouts
    3:32         hash sequence
    4:32+4LE     outpoint
    5:*          script_code of the input
    6:08LE       value of output spent
    7:04LE       n_sequence of the input
    8:32         hash outputs
    9:4LE        n_locktime
    10:4LE       sighash
    """
    s = util.int_to_little_endian(tx["version"], 4)  # 1
    hash_all_prevouts, hash_all_sequence = hash_all_txis(tx)
    s += hash_all_prevouts + hash_all_sequence  # 2,3
    s += txi["txid"][::-1] + util.int_to_little_endian(txi["idx"], 4)  # 4

    # 5
    if witness_script:
        script_code = script.serialize(witness_script)
    elif redeem_script:
        script_code = script.serialize(script.p2pkh_script(redeem_script[1]))
    else:
        script_code = script.serialize(script.p2pkh_script(prev_tx["txos"][txi["idx"]]["script"][1]))
    s += script_code

    s += util.int_to_little_endian(prev_tx["txos"][txi["idx"]]["amount"], 8)  # 6
    s += util.int_to_little_endian(txi["seq.no"], 4)  # 7
    s += hash_all_txos(tx)  # 8
    s += util.int_to_little_endian(tx["locktime"], 4)  # 9
    s += util.int_to_little_endian(util.SIGHASH_ALL, 4)  # 10
    return int.from_bytes(util.hash256(s), 'big')
示例#6
0
 def test_example_1(self):
     tx_ins = []
     prev_tx = bytes.fromhex(
         '8be2f69037de71e3bc856a6627ed3e222a7a2d0ce81daeeb54a3aea8db274149')
     prev_index = 4
     tx_ins.append(TxIn(prev_tx, prev_index))
     tx_outs = []
     h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2')
     tx_outs.append(
         TxOut(
             amount=int(0.38 * 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_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     z = tx_obj.sig_hash(0)
     pk = PrivateKey(secret=8675309)
     der = pk.sign(z).der()
     sig = der + SIGHASH_ALL.to_bytes(1, 'big')
     sec = pk.point.sec()
     tx_obj.tx_ins[0].script_sig = Script([sig, sec])
     want = '0100000001494127dba8aea354ebae1de80c2d7a2a223eed27666a85bce371de3790f6e28b040000006b483045022100fa3032607b50e8cb05bedc9d43f986f19dedc22e61320b9765061c5cd9c66946022072d514ef637988515bfa59a660596206de68f0ed4090d0a398e70f4d81370dfb012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff0280d54302000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac80969800000000001976a914507b27411ccf7f16f10297de6cef3f291623eddf88ac00000000'
     self.assertEqual(tx_obj.serialize().hex(), want)
示例#7
0
 def sig_hash_bip143(self,
                     input_index,
                     redeem_script=None,
                     witness_script=None):
     '''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 witness_script:
         script_code = witness_script.serialize()
     elif redeem_script:
         script_code = p2pkh_script(redeem_script.cmds[1]).serialize()
     else:
         script_code = p2pkh_script(
             tx_in.script_pubkey(self.testnet).cmds[1]).serialize()
     s += script_code
     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(SIGHASH_ALL, 4)
     return int.from_bytes(hash256(s), 'big')
示例#8
0
def get_output_info(num_outputs, amount_available):
    tx_outs = []
    amount = amount_available

    for i in range(num_outputs):
        target_address = input("Enter address of recipient: ")
        target_h160 = decode_base58(target_address)
        valid_amount = False
        target_amount = int(float(input("How much would you like to pay them (in tBTC)?  ")) * sat_in_bit)

        while(valid_amount  == False):

            if(target_amount > amount):
                print("Insufficient Funds")
                target_amount = int(float(input("How much would you like to pay them (in tBTC)?  ")) * sat_in_bit)
            else:
                print("Sufficient Funds")
                valid_amount = True

        amount = amount - target_amount
        print(str(amount/sat_in_bit)+" tBTC remaining")

        if(target_address[0]=='2'):
            print("This recipient is a P2SH")
            target_script = p2sh_script(target_h160)
            tx_outs.append(TxOut(amount = target_amount, script_pubkey = target_script))
        else:
            print("This recipient is a P2PKH")
            target_script = p2pkh_script(target_h160)
            tx_outs.append(TxOut(amount = target_amount, script_pubkey = target_script))


    if(amount > 0):
        print("There is a remainder of "+str(amount/sat_in_bit)+" tBTC. Please fill in recipient details:")

        target_address = input("Enter address of recipient: ")
        target_h160 = decode_base58(target_address)
        target_amount = amount

        if(target_address[0]=='2'):
            print("This recipient is a P2SH")
            target_script = p2sh_script(target_h160)
            tx_outs.append(TxOut(amount = target_amount, script_pubkey = target_script))
        else:
            print("This recipient is a P2PKH")
            target_script = p2pkh_script(target_h160)
            tx_outs.append(TxOut(amount = target_amount, script_pubkey = target_script))

    return tx_outs
示例#9
0
 def test_exercise_5(self):
     prev_tx_1 = bytes.fromhex(
         '11d05ce707c1120248370d1cbf5561d22c4f83aeba0436792c82e0bd57fe2a2f')
     prev_index_1 = 1
     prev_tx_2 = bytes.fromhex(
         '51f61f77bd061b9a0da60d4bedaaf1b1fad0c11e65fdc744797ee22d20b03d15')
     prev_index_2 = 1
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     target_amount = 0.0429
     secret = 8675309
     priv = PrivateKey(secret=secret)
     tx_ins = []
     tx_ins.append(TxIn(prev_tx_1, prev_index_1, Script([]), 0xffffffff))
     tx_ins.append(TxIn(prev_tx_2, prev_index_2, Script([]), 0xffffffff))
     tx_outs = []
     h160 = decode_base58(target_address)
     script_pubkey = p2pkh_script(h160)
     target_satoshis = int(target_amount * 100000000)
     tx_outs.append(TxOut(target_satoshis, script_pubkey))
     tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     self.assertTrue(tx_obj.sign_input(0, priv))
     self.assertTrue(tx_obj.sign_input(1, priv))
     self.assertTrue(tx_obj.verify())
     want = '01000000022f2afe57bde0822c793604baae834f2cd26155bf1c0d37480212c107e75cd011010000006a47304402204cc5fe11b2b025f8fc9f6073b5e3942883bbba266b71751068badeb8f11f0364022070178363f5dea4149581a4b9b9dbad91ec1fd990e3fa14f9de3ccb421fa5b269012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff153db0202de27e7944c7fd651ec1d0fab1f1aaed4b0da60d9a1b06bd771ff651010000006b483045022100b7a938d4679aa7271f0d32d83b61a85eb0180cf1261d44feaad23dfd9799dafb02205ff2f366ddd9555f7146861a8298b7636be8b292090a224c5dc84268480d8be1012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff01d0754100000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     self.assertEqual(tx_obj.serialize().hex(), want)
 def test_exercise_4(self):
     last_block_hex = '000000000d65610b5af03d73ed67704713c9b734d87cf4b970d39a0416dd80f9'
     last_block = bytes.fromhex(last_block_hex)
     secret = little_endian_to_int(
         hash256(b'Jimmy Song Programming Blockchain'))
     private_key = PrivateKey(secret=secret)
     addr = private_key.point.address(testnet=True)
     h160 = decode_base58(addr)
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     self.assertEqual(addr, target_address)
     filter_size = 30
     filter_num_functions = 5
     filter_tweak = 90210  # FILL THIS IN
     target_h160 = decode_base58(target_address)
     target_script = p2pkh_script(target_h160)
     fee = 5000  # fee in satoshis
     node = SimpleNode('tbtc.programmingblockchain.com',
                       testnet=True,
                       logging=False)
     bf = BloomFilter(filter_size, filter_num_functions, filter_tweak)
     bf.add(h160)
     node.handshake()
     node.send(b'filterload', bf.filterload())
     getheaders_message = GetHeadersMessage(start_block=last_block)
     node.send(getheaders_message.command, getheaders_message.serialize())
     headers_envelope = node.wait_for_commands([HeadersMessage.command])
     stream = headers_envelope.stream()
     headers = HeadersMessage.parse(stream)
     get_data_message = GetDataMessage()
     for block in headers.blocks:
         self.assertTrue(block.check_pow())
         if last_block is not None:
             self.assertEqual(block.prev_block, last_block)
         last_block = block.hash()
         get_data_message.add_data(FILTERED_BLOCK_DATA_TYPE, last_block)
     node.send(get_data_message.command, get_data_message.serialize())
     prev_tx = None
     while prev_tx is None:
         envelope = node.wait_for_commands([b'merkleblock', b'tx'])
         stream = envelope.stream()
         if envelope.command == b'merkleblock':
             mb = MerkleBlock.parse(stream)
             self.assertTrue(mb.is_valid())
         else:
             prev = Tx.parse(stream, testnet=True)
             for i, tx_out in enumerate(prev.tx_outs):
                 if tx_out.script_pubkey.address(testnet=True) == addr:
                     prev_tx = prev.hash()
                     prev_index = i
                     prev_amount = tx_out.amount
                     break
     tx_in = TxIn(prev_tx, prev_index)
     output_amount = prev_amount - fee
     tx_out = TxOut(output_amount, target_script)
     tx_obj = Tx(1, [tx_in], [tx_out], 0, testnet=True)
     tx_obj.sign_input(0, private_key)
     self.assertEqual(
         tx_obj.serialize().hex(),
         '010000000194e631abb9e1079ec72a1616a3aa0111c614e65b96a6a4420e2cc6af9e6cc96e000000006a47304402203cc8c56abe1c0dd043afa9eb125dafbebdde2dd4cd7abf0fb1aae0667a22006e02203c95b74d0f0735bbf1b261d36e077515b6939fc088b9d7c1b7030a5e494596330121021cdd761c7eb1c90c0af0a5963e94bf0203176b4662778d32bd6d7ab5d8628b32ffffffff01f8829800000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     )
示例#11
0
 def test_exercise_6(self):
     last_block_hex = '000000000d65610b5af03d73ed67704713c9b734d87cf4b970d39a0416dd80f9'
     secret = little_endian_to_int(
         hash256(b'Jimmy Song Programming Blockchain'))
     private_key = PrivateKey(secret=secret)
     addr = private_key.point.address(testnet=True)
     h160 = decode_base58(addr)
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     self.assertEqual(addr, target_address)
     target_h160 = decode_base58(target_address)
     target_script = p2pkh_script(target_h160)
     fee = 5000
     node = SimpleNode('tbtc.programmingblockchain.com', testnet=True)
     bf = BloomFilter(30, 5, 90210)
     bf.add(h160)
     node.handshake()
     node.send(bf.filterload())
     start_block = bytes.fromhex(last_block_hex)
     getheaders = GetHeadersMessage(start_block=start_block)
     node.send(getheaders)
     headers = node.wait_for(HeadersMessage)
     last_block = None
     getdata = GetDataMessage()
     for b in headers.blocks:
         if not b.check_pow():
             raise RuntimeError('proof of work is invalid')
         if last_block is not None and b.prev_block != last_block:
             raise RuntimeError('chain broken')
         getdata.add_data(FILTERED_BLOCK_DATA_TYPE, b.hash())
         last_block = b.hash()
     node.send(getdata)
     prev_tx, prev_index, prev_tx_obj = None, None, None
     while prev_tx is None:
         message = node.wait_for(MerkleBlock, Tx)
         if message.command == b'merkleblock':
             if not message.is_valid():
                 raise RuntimeError('invalid merkle proof')
         else:
             message.testnet = True
             for i, tx_out in enumerate(message.tx_outs):
                 if tx_out.script_pubkey.address(testnet=True) == addr:
                     prev_tx = message.hash()
                     prev_index = i
                     prev_amount = tx_out.amount
                     self.assertEqual(
                         message.id(),
                         '6ec96c9eafc62c0e42a4a6965be614c61101aaa316162ac79e07e1b9ab31e694'
                     )
                     self.assertEqual(i, 0)
                     break
     tx_in = TxIn(prev_tx, prev_index)
     output_amount = prev_amount - fee
     tx_out = TxOut(output_amount, target_script)
     tx_obj = Tx(1, [tx_in], [tx_out], 0, testnet=True)
     tx_obj.sign_input(0, private_key)
     self.assertEqual(
         tx_obj.serialize().hex(),
         '010000000194e631abb9e1079ec72a1616a3aa0111c614e65b96a6a4420e2cc6af9e6cc96e000000006a47304402203cc8c56abe1c0dd043afa9eb125dafbebdde2dd4cd7abf0fb1aae0667a22006e02203c95b74d0f0735bbf1b261d36e077515b6939fc088b9d7c1b7030a5e494596330121021cdd761c7eb1c90c0af0a5963e94bf0203176b4662778d32bd6d7ab5d8628b32ffffffff01f8829800000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     )
示例#12
0
 def test_example_5(self):
     tx_ins = []
     prev_tx = bytes.fromhex('0d6fe5213c0b3291f208cba8bfb59b7476dffacc4e5cb66f6eb20a080843a299')
     prev_index = 13
     tx_ins.append(TxIn(prev_tx, prev_index, Script([]), 0xffffffff))
     tx_outs = []
     change_amount = int(0.33 * 100000000)
     change_h160 = decode_base58('mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2')
     change_script = p2pkh_script(change_h160)
     tx_outs.append(TxOut(change_amount, change_script))
     target_amount = int(0.1 * 100000000)
     target_h160 = decode_base58('mnrVtF8DWjMu839VW3rBfgYaAfKk8983Xf')
     target_script = p2pkh_script(target_h160)
     tx_outs.append(TxOut(target_amount, target_script))
     transaction = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     want = '010000000199a24308080ab26e6fb65c4eccfadf76749bb5bfa8cb08f291320b3c21e56f0d0d00000000ffffffff02408af701000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac80969800000000001976a914507b27411ccf7f16f10297de6cef3f291623eddf88ac00000000'
     self.assertEqual(transaction.serialize().hex(), want)
示例#13
0
 def sig_hash_bip143(self,
                     input_index,
                     redeem_script=None,
                     witness_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     tx_in = self.tx_ins[input_index]
     print("****** in sig_hash_bip143")
     # per BIP143 spec
     s = int_to_little_endian(self.version,
                              4)  # applicable to all tx_ins in this tx
     s += self.hash_prevouts() + self.hash_sequence(
     )  # applicable to all tx_ins in this tx
     s += tx_in.prev_tx[::-1] + int_to_little_endian(
         tx_in.prev_index, 4)  # specific to this tx_in
     #
     # Setting the script_code:
     #
     # If there is a witness_script, then the situation is either a p2wsh
     # or a p2sh-p2wsh.  Use the witnesss script to make the script_code:
     if witness_script:
         script_code = witness_script.serialize()
     # If there is a redeem_script, then the situation is a p2sh-p2wpkh.
     # Make the script_code from the hash in the redeem_script-which is the
     # 20-byte public key hash.
     elif redeem_script:
         script_code = p2pkh_script(redeem_script.cmds[1]).serialize()
     # If no witness_script or redeem_script, the situation is a straight
     # p2wpkh.  Use the 20 byte hash from the utxo script_pubkey.
     else:
         script_code = p2pkh_script(
             tx_in.script_pubkey(self.testnet).cmds[1]).serialize()
     s += script_code  # specific to this tx_ins
     s += int_to_little_endian(tx_in.value(), 8)  # specific to this tx_ins
     s += int_to_little_endian(tx_in.sequence, 4)  # specific to this tx_ins
     s += self.hash_outputs()  # applicable to all tx_ins in this tx
     s += int_to_little_endian(self.locktime,
                               4)  # applicable to all tx_ins in this tx
     s += int_to_little_endian(SIGHASH_ALL,
                               4)  # applicable to all tx_ins in this tx
     print("****** out sig_hash_bip143")
     return int.from_bytes(hash256(s), 'big')
示例#14
0
    def send(self, adddress, amount, fee=500):
        # collect inputs
        unspent = self.unspent()
        tx_ins = []
        input_sum = 0
        for utxo in unspent:
            if input_sum >= amount + fee:
                break
            input_sum += utxo.amount
            tx_in = TxIn(utxo.tx_id, utxo.index)
            tx_ins.append(tx_in)

        # make sure we have enough
        assert input_sum > amount + fee, 'not enough satoshis'

        # send output
        send_h160 = decode_base58(address)
        send_script = p2pkh_script(send_h160)
        send_output = TxOut(amount=amount, script_pubkey=send_script)

        # change output
        change_amount = input_sum - amount - fee
        change_h160 = decode_base58(self.address())
        change_script = p2pkh_script(change_h160)
        change_output = TxOut(amount=amount, script_pubkey=change_script)

        # construct
        tx = Tx(1, tx_ins, [send_output, change_output], 0, True)

        # sign
        for i in range(len(tx_ins)):
            utxo = unspent[i]
            assert tx.sign_input(i, self.private_key, utxo.script_pubkey)
            print(f'signed {i}')
        print(tx)

        # broadcast
        import bit
        tx_hex = tx.serialize().hex()
        print(tx_hex)
        # raises a ConnectionError if it fails
        print(bit.network.NetworkAPI.broadcast_tx_testnet(tx_hex))
示例#15
0
 def test_exercise_3_1(self):
     prev_tx = bytes.fromhex(
         'eb581753a4dbd6befeaaaa28a6f4576698ba13a07c03da693a65bce11cf9887a')
     prev_index = 1
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     target_amount = 0.04
     change_address = 'mzx5YhAH9kNHtcN481u6WkjeHjYtVeKVh2'
     fee = 50000
     secret = 8675309
     private_key = PrivateKey(secret=secret)
     tx_ins = []
     tx_ins.append(TxIn(prev_tx, prev_index))
     tx_outs = []
     h160 = decode_base58(target_address)
     script_pubkey = p2pkh_script(h160)
     target_satoshis = int(target_amount * 100000000)
     tx_outs.append(TxOut(target_satoshis, script_pubkey))
     h160 = decode_base58(change_address)
     script_pubkey = p2pkh_script(h160)
     prev_amount = tx_ins[0].value(testnet=True)
     change_satoshis = prev_amount - target_satoshis - fee
     tx_outs.append(TxOut(change_satoshis, script_pubkey))
     tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     tx_obj.sign_input(0, private_key)
     if private_key.point.address(testnet=True) != change_address:
         raise RuntimeError(
             'Private Key does not correspond to Change Address, check priv_key and change_address'
         )
     if tx_ins[0].script_pubkey(
             testnet=True).instructions[2] != decode_base58(change_address):
         raise RuntimeError(
             'Output is not something you can spend with this private key. Check that the prev_tx and prev_index are correct'
         )
     if tx_obj.fee() > 0.05 * 100000000 or tx_obj.fee() <= 0:
         raise RuntimeError(
             'Check that the change amount is reasonable. Fee is {}'.format(
                 tx_obj.fee()))
     self.assertEqual(
         tx_obj.serialize().hex(),
         '01000000017a88f91ce1bc653a69da037ca013ba986657f4a628aaaafebed6dba4531758eb010000006a47304402204ce6e3877ed2e18d2165276cbdba241507ce72b44d8df640eb6cb4d415eaaea002207dffd162da35593d86188ce87a1cbc9d3a5b26391870f19bf1764ca05b315ad9012103935581e52c354cd2f484fe8ed83af7a3097005b2f9c60bff71d35bd795f54b67ffffffff0200093d00000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac7077e401000000001976a914d52ad7ca9b3d096a38e752c2018e6fbc40cdf26f88ac00000000'
     )
示例#16
0
 def test_address(self):
     address_1 = '1BenRpVUFK65JFWcQSuHnJKzc4M8ZP8Eqa'
     h160 = decode_base58(address_1)
     p2pkh_script_pubkey = p2pkh_script(h160)
     self.assertEqual(p2pkh_script_pubkey.address(), address_1)
     address_2 = 'mrAjisaT4LXL5MzE81sfcDYKU3wqWSvf9q'
     self.assertEqual(p2pkh_script_pubkey.address(testnet=True), address_2)
     address_3 = '3CLoMMyuoDQTPRD3XYZtCvgvkadrAdvdXh'
     h160 = decode_base58(address_3)
     p2sh_script_pubkey = p2sh_script(h160)
     self.assertEqual(p2sh_script_pubkey.address(), address_3)
     address_4 = '2N3u1R6uwQfuobCqbCgBkpsgBxvr1tZpe7B'
     self.assertEqual(p2sh_script_pubkey.address(testnet=True), address_4)
示例#17
0
 def test_exercise_3_2(self):
     prev_tx_1 = bytes.fromhex(
         '89cbfe2eddaddf1eb11f5c4adf6adaa9bca4adc01b2a3d03f8dd36125c068af4')
     prev_index_1 = 0
     prev_tx_2 = bytes.fromhex(
         '19069e1304d95f70e03311d9d58ee821e0978e83ecfc47a30af7cd10fca55cf4')
     prev_index_2 = 0
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     fee = 50000
     secret = 61740721216174072121
     private_key = PrivateKey(secret=secret)
     tx_ins = []
     tx_ins.append(TxIn(prev_tx_1, prev_index_1))
     tx_ins.append(TxIn(prev_tx_2, prev_index_2))
     tx_outs = []
     h160 = decode_base58(target_address)
     script_pubkey = p2pkh_script(h160)
     target_satoshis = tx_ins[0].value(True) + tx_ins[1].value(True) - fee
     tx_outs.append(TxOut(target_satoshis, script_pubkey))
     tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     tx_obj.sign_input(0, private_key)
     tx_obj.sign_input(1, private_key)
     if tx_ins[0].script_pubkey(
             testnet=True).instructions[2] != decode_base58(
                 private_key.point.address(testnet=True)):
         raise RuntimeError(
             'Output is not something you can spend with this private key. Check that the prev_tx and prev_index are correct'
         )
     if tx_obj.fee() > 0.05 * 100000000 or tx_obj.fee() <= 0:
         raise RuntimeError(
             'Check that the change amount is reasonable. Fee is {}'.format(
                 tx_obj.fee()))
     self.assertEqual(
         tx_obj.serialize().hex(),
         '0100000002f48a065c1236ddf8033d2a1bc0ada4bca9da6adf4a5c1fb11edfaddd2efecb89000000006a47304402204b9ee431a2f5deaefb5282a34d7dcfdb47d55b1e3ce00cac4c6b6e6f0f0e8d58022062710e84786d2c6c89ddda5a149b45088b15230c6b825f0f21490f99bd74c81d012103f96f3a1efd31e1a8d7078118ee56bff7355d58907ce0f865f5f0b3dbe34e55befffffffff45ca5fc10cdf70aa347fcec838e97e021e88ed5d91133e0705fd904139e0619000000006a473044022073d7217b2d582e55978284c2628015a14e3490e835c76488eb29b63de15d17920220384e4b5282c911273efd4d98170e7092e10a729d142db17f4725c15364fa4ecc012103f96f3a1efd31e1a8d7078118ee56bff7355d58907ce0f865f5f0b3dbe34e55beffffffff01021f320a000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     )
示例#18
0
 def test_exercise_6(self):
     last_block_hex = '00000000000538d5c2246336644f9a4956551afb44ba47278759ec55ea912e19'
     secret = little_endian_to_int(
         hash256(b'Jimmy Song Programming Blockchain'))
     private_key = PrivateKey(secret=secret)
     addr = private_key.point.address(testnet=True)
     h160 = decode_base58(addr)
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     self.assertEqual(addr, target_address)
     target_h160 = decode_base58(target_address)
     target_script = p2pkh_script(target_h160)
     fee = 5000
     node = SimpleNode('tbtc.programmingblockchain.com', testnet=True)
     bf = BloomFilter(30, 5, 90210)
     bf.add(h160)
     node.handshake()
     node.send(b'filterload', bf.filterload())
     start_block = bytes.fromhex(last_block_hex)
     getheaders_message = GetHeadersMessage(start_block=start_block)
     node.send(getheaders_message.command, getheaders_message.serialize())
     headers_envelope = node.wait_for_commands({HeadersMessage.command})
     stream = headers_envelope.stream()
     headers = HeadersMessage.parse(stream)
     last_block = None
     get_data_message = GetDataMessage()
     for b in headers.blocks:
         if not b.check_pow():
             raise RuntimeError('proof of work is invalid')
         if last_block is not None and b.prev_block != last_block:
             raise RuntimeError('chain broken')
         get_data_message.add_data(FILTERED_BLOCK_DATA_TYPE, b.hash())
         last_block = b.hash()
     node.send(get_data_message.command, get_data_message.serialize())
     prev_tx, prev_index, prev_tx_obj = None, None, None
     while prev_tx is None:
         envelope = node.wait_for_commands({b'merkleblock', b'tx'})
         stream = envelope.stream()
         if envelope.command == b'merkleblock':
             mb = MerkleBlock.parse(stream)
             if not mb.is_valid():
                 raise RuntimeError('invalid merkle proof')
         else:
             prev_tx_obj = Tx.parse(stream, testnet=True)
             for i, tx_out in enumerate(prev_tx_obj.tx_outs):
                 if tx_out.script_pubkey.address(testnet=True) == addr:
                     prev_tx = prev_tx_obj.hash()
                     prev_index = i
                     self.assertEqual(
                         prev_tx_obj.id(),
                         'e3930e1e566ca9b75d53b0eb9acb7607f547e1182d1d22bd4b661cfe18dcddf1'
                     )
                     self.assertEqual(i, 0)
     tx_in = TxIn(prev_tx, prev_index, Script([]), 0xffffff)
     TxFetcher.cache[prev_tx] = prev_tx_obj
     tx_ins = [tx_in]
     total = prev_tx_obj.tx_outs[prev_index].amount
     tx_outs = [TxOut(total - fee, target_script)]
     tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
     tx_obj.sign_input(0, private_key)
     self.assertEqual(
         tx_obj.serialize().hex(),
         '0100000001f1dddc18fe1c664bbd221d2d18e147f50776cb9aebb0535db7a96c561e0e93e3000000006a473044022046a49962540a89e83da0636455b6c81c11c2844b7f3cd414c02e1a13741f4d15022006eed4eeda994d2bfebb9f1a494bfa3c8bab96e7e4c82623f4a29736dfe309e70121021cdd761c7eb1c90c0af0a5963e94bf0203176b4662778d32bd6d7ab5d8628b32ffffff0001a1629ef5000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     )
示例#19
0
def test_create_legacy_tx():
    # to_alice = total_amount - to_bob - fee

    txo_amount = 0.01750649
    tx_fee = 0.0005
    to_bob = 0.005

    sat_amount = int(txo_amount * 10 ** 8)
    sat_tx_fee = int(tx_fee * 10 ** 8)
    sat_to_bob = int(to_bob * 10 ** 8)
    sat_to_alice = sat_amount - sat_to_bob - sat_tx_fee

    # add txo: to alice
    alice = 'mxFMySFd6tkjnomB1LgGC85i5hvwGtaFiW'
    h160 = util.decode_base58(alice)
    print(h160.hex())
    lock_script = script.p2pkh_script(h160)
    txo_0 = {
        "amount": sat_to_alice,
        "script": lock_script
    }

    # add txo: to bob
    bob = "mtTt5dA1vbELiycUagedatkPQRm1QseoCa"
    h160 = util.decode_base58(bob)
    print(h160.hex())
    lock_script = script.p2pkh_script(h160)
    txo_1 = {
        "amount": sat_to_bob,
        "script": lock_script
    }

    # add_txi
    txid = "dd21423466a93ccca9ea5b548e0c19efcfc3aee41036a90102bca600cd9260fb"
    # "asm": "OP_DUP OP_HASH160 e4c8b088f49dbc6a2248400e5002d2a29aed6953 OP_EQUALVERIFY OP_CHECKSIG",

    # generate unlock script
    prev_tx = tx.fetch(bytes.fromhex(txid), True)
    print(prev_tx)
    for i, txo in enumerate(prev_tx['txos']):
        if script.is_p2pkh(txo['script']):
            print(i, "p2pkh")
        elif script.is_p2sh(txo['script']):
            print(i, "p2sh")
        elif script.is_p2wpkh(txo['script']):
            print(i, "p2wpkh")
        elif script.is_p2wsh(txo['script']):
            print(i, "pswsh")
    # lock_script: p2pkh

    txi_0 = {
        "txid": bytes.fromhex(txid),
        "idx": 1,
        "script": [],
        "seq.no": 0
    }

    tx_obj = {
        "version": 1,
        # "mark": None,
        # "flag": None,
        "txi.count": 1,
        "txis": [txi_0],
        "txo.count": 2,
        "txos": [txo_0, txo_1],
        # "wits": None,
        "locktime": 0
    }

    # alice's 'sec_key': 947605268396919657983759089664,
    sec_key = 947605268396919657983759089664
    z = tx.sig_hash(tx_obj, 0, prev_tx["txos"][1]["script"])
    print(z)

    sig = ecc.sig(sec_key, z)
    der = ecc.sig_der(sig)

    pub_key = ecc.ecc_mul(sec_key)
    sec = ecc.sec(pub_key[0], pub_key[1], False)
    print(sec)

    sig_with_type = der + util.SIGHASH_ALL.to_bytes(1, 'big')

    txi_0["script"] = [sig_with_type, sec]

    print(tx_obj)

    new_tx_bytes = tx.serialize(tx_obj)
    print(new_tx_bytes.hex())

    # tx verification
    stream = BytesIO(new_tx_bytes)
    tx_obj = tx.parse(stream)
    print(tx_obj)
    tx.verify(tx_obj, testnet=True)

    return new_tx_bytes
示例#20
0
# UTXO that we gonna receive

prev_tx = bytes.fromhex(
    '1ed5583812bda08b71a71c2fa1e6788dac956efa9d2c26b6c9fd10f6e885658f')
prev_index = 1

# create the txin with the output of the UTXO we have been given

tx_in = TxIn(prev_tx, prev_index)
tx_outs = []
change_amount = int(0.00003 * 100000000)

# output address that will receive the sat we have not spend

change_h160 = decode_base58('mvEg6eZ3sUApodedYQrkpEPMMALsr1K1k1')
change_script = p2pkh_script(change_h160)
change_output = TxOut(amount=change_amount, script_pubkey=change_script)

# output address that will receive our sat

target_amount = int(0.00006 * 100000000)
target_h160 = decode_base58('mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv')

target_script = p2pkh_script(target_h160)
target_output = TxOut(amount=target_amount, script_pubkey=target_script)
tx_obj = Tx(1, [tx_in], [change_output, target_output], 0, True)
#print(tx_obj).hex()

# now we sign the transaction

z = tx_obj.sig_hash(0)
示例#21
0
tx_previa = bytes.fromhex(
    'b685879f3939fa9531899b729394ed85edab8b6850b72a9e378ea31af96a304a')
index_tx_previa = 1

tx_inputs = []
tx_inputs.append(TxIn(tx_previa, index_tx_previa))

#OUPUTS
tx_outputs = []
destinatario = 'mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB'
monto = .00008
change_adress = ADDRESS
cambio = .00001
#SEND OUTPUT
h160 = decode_base58(destinatario)
script_pubkey = p2pkh_script(h160)
monto_satoshis = int(monto * 100_000_000)
tx_outputs.append(TxOut(monto_satoshis, script_pubkey))

#CHANGE OUPUT
h160 = decode_base58(change_adress)
script_pubkey = p2pkh_script(h160)
cambio_satoshis = int(cambio * 100_000_000)
tx_outputs.append(TxOut(cambio_satoshis, script_pubkey))

#TX BUILD
TX_BUILD = Tx(1, tx_inputs, tx_outputs, 0, testnet=True)

#SIGN
print(TX_BUILD.sign_input(0, PrivKey))
print(TX_BUILD.serialize().hex())
示例#22
0
 def pubkey_to_p2pkh_script(cls, pubkey):
     h160 = pubkey.hash160()
     return p2pkh_script(h160)
示例#23
0
pay_private_key = PrivateKey(pay_secret)
output_address = pay_private_key.point.address(testnet=True)
# out1_address resulting from the above pay_secret
# out1_address = 'mgbxvp8L3o5zbw8P81VWVv42gUj9eZNjAN'

change_secret = 9883161471906162552674337436001522581212416354973578695250248738884382136882
#secret = random.getrandbits(256)
change_private_key = PrivateKey(change_secret)
change_address = change_private_key.point.address(testnet=True)

paying_amount = prev_tx_obj.tx_outs[0].amount
paid_amount = math.floor(paying_amount * .1)
fee = math.floor(paid_amount * .1)
change_amount = paying_amount - paid_amount - fee

paid_script = p2pkh_script(decode_base58(output_address))
change_script = p2pkh_script(decode_base58(change_address))

tx_out_paid = TxOut(paid_amount, paid_script)

tx_out_change = TxOut(change_amount, change_script)

tx = Tx(1, [txi], [tx_out_paid, tx_out_change], 0, True)

print(tx)

print(tx.sign_input(input_index=0, private_key=input_private_key))
print(tx)
print("tx_in script...")
print(tx.tx_ins[0].script_sig)
print(tx.serialize().hex())
示例#24
0
def construct_tx_out(address, amount):
    h160 = decode_base58(address)
    script = p2pkh_script(h160)
    return TxOut(amount=amount, script_pubkey=script)
示例#25
0
    'df29440e796ff7e843d643380d00b79f0d6dab55c84a983849b04f9a8025f072')
prev_index1 = 0
prev_tx2 = bytes.fromhex(
    'df29440e796ff7e843d643380d00b79f0d6dab55c84a983849b04f9a8025f072')
prev_index2 = 0

# create the txin with the output of the UTXO we have been given

tx_in1 = TxIn(prev_tx1, prev_index1)
tx_in2 = TxIn(prev_tx1, prev_index1)
target_amount = int(9000)

# output address that will receive the sat we have not spend

target_h160 = decode_base58('mvEg6eZ3sUApodedYQrkpEPMMALsr1K1k1')
target_script = p2pkh_script(target_h160)
target_output = TxOut(amount=target_amount, script_pubkey=target_script)

# output address that will receive our sat

target_script = p2pkh_script(target_h160)
target_output = TxOut(amount=target_amount, script_pubkey=target_script)
tx_obj = Tx(1, [tx_in], [target_output], 0, True)
#print(tx_obj).hex()

# now we sign the transaction

z = tx_obj.sig_hash(0)
private_key = PrivateKey(little_endian_to_int(
    hash256(b'dat_test_private_key')))
der = private_key.sign(z).der()
示例#26
0
 def test_broadcast(self):
     from bloomfilter import BloomFilter
     last_block_hex = '00000000000000a03f9432ac63813c6710bfe41712ac5ef6faab093fe2917636'
     secret = little_endian_to_int(hash256(b'Jimmy Song'))
     private_key = PrivateKey(secret=secret)
     h160 = private_key.point.hash160()
     addr = private_key.point.address(testnet=True)
     target_address = 'mwJn1YPMq7y5F8J3LkC5Hxg9PHyZ5K4cFv'
     target_h160 = decode_base58(target_address)
     target_script = p2pkh_script(target_h160)
     fee = 5000  # fee in satoshis
     # connect to programmingblockchain.com in testnet mode
     node = SimpleNode('programmingblockchain.com', testnet=True)
     # create a bloom filter of size 30 and 5 functions. Add a tweak.
     bf = BloomFilter(30, 5, 90210)
     # add the h160 to the bloom filter
     bf.add(h160)
     # load the bloom filter with the filterload command
     node.send(bf.filterload())
     # set start block to last_block from above
     start_block = bytes.fromhex(last_block_hex)
     # send a getheaders message with the starting block
     getheaders = GetHeadersMessage(start_block=start_block)
     node.send(getheaders)
     # wait for the headers message
     headers = node.wait_for(HeadersMessage)
     block_hashes = [b.hash() for b in headers.blocks]
     # initialize prev_tx, prev_index and prev_amount to None
     prev_tx, prev_index, prev_amount = None, None, None
     for h, tx_obj in node.get_filtered_block_txs(block_hashes):
         self.assertEqual(h, tx_obj.hash())
         tx_obj.testnet = True
         # loop through the tx outs
         for i, tx_out in enumerate(tx_obj.tx_outs):
             # if our output has the same address as our address we found it
             if tx_out.script_pubkey.address(testnet=True) == addr:
                 # we found our utxo. set prev_tx, prev_index, and tx
                 prev_tx = h
                 prev_index = i
                 prev_amount = tx_out.amount
                 self.assertEqual(
                     h.hex(),
                     'b2cddd41d18d00910f88c31aa58c6816a190b8fc30fe7c665e1cd2ec60efdf3f'
                 )
                 self.assertEqual(i, 7)
                 break
         if prev_tx:
             break
     # create the TxIn
     tx_in = TxIn(prev_tx, prev_index)
     # calculate the output amount (previous amount minus the fee)
     output_amount = prev_amount - fee
     # create a new TxOut to the target script with the output amount
     tx_out = TxOut(output_amount, target_script)
     # create a new transaction with the one input and one output
     tx_obj = Tx(1, [tx_in], [tx_out], 0, testnet=True)
     # sign the only input of the transaction
     self.assertTrue(tx_obj.sign_input_p2pkh(0, private_key))
     # serialize and hex to see what it looks like
     want = '01000000013fdfef60ecd21c5e667cfe30fcb890a116688ca51ac3880f91008dd141ddcdb2070000006b483045022100ff77d2559261df5490ed00d231099c4b8ea867e6ccfe8e3e6d077313ed4f1428022033a1db8d69eb0dc376f89684d1ed1be75719888090388a16f1e8eedeb8067768012103dc585d46cfca73f3a75ba1ef0c5756a21c1924587480700c6eb64e3f75d22083ffffffff019334e500000000001976a914ad346f8eb57dee9a37981716e498120ae80e44f788ac00000000'
     self.assertEqual(tx_obj.serialize().hex(), want)
     # send this signed transaction on the network
     node.send_tx(tx_obj)
示例#27
0
 def output_from_address(cls, address, amount):
     # creates an output from the Base 58 Checksum string
     # the Base 58 Checksum string is what a payor would receive from the payee
     hash160_bytes = decode_base58(address)
     script_pub_key = p2pkh_script(hash160_bytes)
     return cls(amount, script_pub_key)