Exemple #1
0
def main():
    # always remember to setup the network
    setup('testnet')

    priv1 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG")
    priv2 = PrivateKey("cR8AkcbL2pgBswrHp28AftEznHPPLA86HiTog8MpNCibxwrsUcZ4")
    
    p2sh_redeem_script = Script(
        ['OP_1', priv1.get_public_key().to_hex(), priv2.get_public_key().to_hex(),'OP_2', 'OP_CHECKMULTISIG'])

    fromAddress = P2wshAddress.from_script(p2sh_redeem_script)

    toAddress = P2wpkhAddress.from_address("tb1qtstf97nhk2gycz7vl37esddjpxwt3ut30qp5pn")

    # set values
    txid = '2042195c40a92353f2ffe30cd0df8d177698560e81807e8bf9174a9c0e98e6c2'
    vout = 0
    amount = 0.01

    # create transaction input from tx id of UTXO
    txin = TxInput(txid, vout)

    txOut1 = TxOutput(0.0001, toAddress.to_script_pub_key())
    txOut2 = TxOutput(0.0098, fromAddress.to_script_pub_key())

    tx = Transaction([txin], [txOut1, txOut2], has_segwit=True)

    sig1 = priv1.sign_segwit_input(tx, 0, p2sh_redeem_script, amount)
    tx.witnesses.append(Script(['OP_0', sig1, p2sh_redeem_script.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
    print("\nTxId:", tx.get_txid())
Exemple #2
0
def main():
    # always remember to setup the network
    setup('testnet')

    #
    # This script creates a P2SH address containing a P2PK script and sends
    # some funds to it
    #

    # create transaction input from tx id of UTXO (contained 0.1 tBTC)
    txin = TxInput(
        '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0)

    # address we are spending from
    from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')

    # secret key of address that we are trying to spent
    sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')

    #
    # create transaction output using P2SH scriptPubKey (locking script)
    # (the recipient will give us the final address  but for now we create it
    # for demonstration purposes)
    #

    # secret key corresponding to the pubkey needed for the P2SH (P2PK) transaction
    p2pk_sk = PrivateKey(
        'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
    p2pk_pk = p2pk_sk.get_public_key().to_hex()
    redeem_script = Script([p2pk_pk, 'OP_CHECKSIG'])
    txout = TxOutput(Decimal('0.09'), redeem_script.to_p2sh_script_pub_key())

    # no change address - the remaining 0.01 tBTC will go to miners)

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin], [txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signature for the txin
    sig = sk.sign_input(tx, 0, from_addr.to_script_pub_key())
    #print(sig)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
def main():
    # always remember to setup the network
    setup('testnet')

    # send 2 P2PKH inputs to 1 P2WPKH output

    # create transaction inputs from tx ids of UTXOs (contained 0.002 tBTC)
    txin = TxInput('eddfaa3d5a1c9a2a2961638aa4e28871b09ed9620f9077482248f368d46d8205', 1)
    txin2 = TxInput('cf4b2987c06b9dd2ba6770af31a4942a4ea3e7194c0d64e8699e9fda03f50551', 1)

    # create transaction output using P2WPKH scriptPubKey (locking script)
    addr = P2wpkhAddress('tb1qlffsz7cgzmyzhklleu97afru7vwjytux4z4zsl')
    txout = TxOutput(to_satoshis(0.0019), addr.to_script_pub_key())
    #txout = TxOutput(to_satoshis(0.0019), Script([0, addr.to_hash()]) )

    # create transaction from inputs/outputs -- default locktime is used
    # note that this is not a segwit transaction since we don't spend segwit
    tx = Transaction([txin, txin2], [txout]) #, has_segwit=True)

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private keys corresponding to the address that contains the
    # UTXOs we are trying to spend to sign the input
    sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
    sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt')

    # note that we pass the scriptPubkey as one of the inputs of sign_input
    # because it is used to replace the scriptSig of the UTXO we are trying to
    # spend when creating the transaction digest
    from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    sig = sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                       from_addr.to_hash160(), 'OP_EQUALVERIFY',
                                       'OP_CHECKSIG']) )
    from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
    sig2 = sk2.sign_input( tx, 1, from_addr2.to_script_pub_key() )

    # get public key as hex
    pk = sk.get_public_key().to_hex()
    pk2 = sk2.get_public_key().to_hex()

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    txin2.script_sig = Script([sig2, pk2])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
def main():
    # always remember to setup the network
    setup('regtest')

    #
    # This script creates a P2SH address containing a
    # CHECKLOCKTIMEVERIFY plus a P2PKH locking funds with a key
    # until a certain block_height is reached
    #

    # set values
    block_height = 140

    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, block_height)

    # secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction
    p2pkh_sk = PrivateKey('cSbKZh6a6wNUAQ8pr2KLKeZCQ4eJnFmN35wtReaoU4kCP97XQu6W')

    # get the address (from the public key)
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()

    # create the redeem script
    redeem_script = Script([seq.for_script(), 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'])

    # create a P2SH address from a redeem script
    addr = P2shAddress.from_script(redeem_script)
    print(addr.to_string())
Exemple #5
0
def main():
    # always remember to setup the network
    setup('testnet')

    #
    # This script creates a P2SH address containing a CHECKSEQUENCEVERIFY plus
    # a P2PKH locking funds with a key as well as for 20 blocks
    #

    # set values
    relative_blocks = 20

    seq = Sequence(TYPE_RELATIVE_TIMELOCK, relative_blocks)

    # secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction
    p2pkh_sk = PrivateKey(
        'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')

    # get the address (from the public key)
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()

    # create the redeem script
    redeem_script = Script([
        seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # create a P2SH address from a redeem script
    addr = P2shAddress.from_script(redeem_script)
    print(addr.to_string())
Exemple #6
0
class TestCreateP2shTransaction(unittest.TestCase):
    def setUp(self):
        setup('testnet')
        # values for testing create non std tx
        self.txin = TxInput("e2d08a63a540000222d6a92440436375d8b1bc89a2638dc5366833804287c83f", 1)
        self.to_addr = P2pkhAddress('msXP94TBncQ9usP6oZNpGweE24biWjJs2d')
        self.sk = PrivateKey('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA')
        self.txout = TxOutput( 0.9, Script(['OP_ADD', 'OP_5', 'OP_EQUAL']) )
        self.change_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
        self.change_txout = TxOutput( 2, self.change_addr.to_script_pub_key())
        self.create_non_std_tx_result = '02000000013fc8874280336836c58d63a289bcb1d87563434024a9d622020040a5638ad0e2010000006a47304402201febc032331342baaece4b88c7ab42d7148c586b9a48944cbebde95636ac7424022018f0911a4ba664ac8cc21457a58e3a1214ba92b84cb60e57f4119fe655b3a78901210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff02804a5d05000000000393558700c2eb0b000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'

        # values for testing create non std tx
        self.txin_spend = TxInput("4d9a6baf45d4b57c875fe83d5e0834568eae4b5ef6e61d13720ef6685168e663", 0)
        self.txin_spend.script_sig = Script(['OP_2', 'OP_3'])
        self.txout_spend = TxOutput( 0.8, self.change_addr.to_script_pub_key())
        self.spend_non_std_tx_result = '020000000163e6685168f60e72131de6f65e4bae8e5634085e3de85f877cb5d445af6b9a4d00000000025253ffffffff0100b4c404000000001976a914751e76e8199196d454941c45d1b3a323f1433bd688ac00000000'

    def test_send_to_non_std(self):
        tx = Transaction([self.txin], [self.txout, self.change_txout])
        from_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
        sig = self.sk.sign_input( tx, 0, from_addr.to_script_pub_key() )
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.create_non_std_tx_result)

    def test_spend_non_std(self):
        tx = Transaction([self.txin_spend], [self.txout_spend])
        self.assertEqual(tx.serialize(), self.spend_non_std_tx_result)
Exemple #7
0
def main():
    # always remember to setup the network
    setup('testnet')

    # create transaction input from tx id of UTXO (contained 0.4 tBTC)
    txin = TxInput(
        'fb48f4e23bf6ddf606714141ac78c3e921c8c0bebeb7c8abb2c799e9ff96ce6c', 0)

    # create transaction output using P2PKH scriptPubKey (locking script)
    addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    txout = TxOutput(
        Decimal('0.1'),
        Script([
            'OP_DUP', 'OP_HASH160',
            addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))

    # create another output to get the change - remaining 0.01 is tx fees
    # note that this time we used to_script_pub_key() to create the P2PKH
    # script
    change_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
    change_txout = TxOutput(Decimal('0.29'), change_addr.to_script_pub_key())
    #change_txout = TxOutput(Decimal('0.29'), Script(['OP_DUP', 'OP_HASH160',
    #                                     change_addr.to_hash160(),
    #                                     'OP_EQUALVERIFY', 'OP_CHECKSIG']))

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin], [txout, change_txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to sign the input
    sk = PrivateKey('cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')

    # note that we pass the scriptPubkey as one of the inputs of sign_input
    # because it is used to replace the scriptSig of the UTXO we are trying to
    # spend when creating the transaction digest
    from_addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e')
    sig = sk.sign_input(
        tx, 0,
        Script([
            'OP_DUP', 'OP_HASH160',
            from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))
    #print(sig)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
def main():
    # always remember to setup the network
    setup('testnet')

    priv0 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG")

    pub = priv0.get_public_key()
    fromAddress = pub.get_segwit_address()

    priv1 = PrivateKey("cN1XE3ESGgdvr4fWsB7L3BcqXncUauF8Fo8zzv4Sm6WrkiGrsxrG")

    # P2SH Script: OP_M <Public key 1> <Public key 2> ... OP_N OP_CHECKMULTISIG
    p2sh_redeem_script = Script(
        ['OP_1',
         priv1.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG'])

    toAddress = P2wshAddress.from_script(p2sh_redeem_script)

    # set values
    txid = 'd222d91e2da368ac38e84aa615c557e4caeacce02aa5dbca10d840fd460fc938'
    vout = 0
    amount = Decimal('0.01764912')

    # create transaction input from tx id of UTXO
    txin = TxInput(txid, vout)
    redeem_script1 = Script([
        'OP_DUP', 'OP_HASH160',
        priv0.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # create transaction output
    txOut1 = TxOutput(Decimal('0.0001'), toAddress.to_script_pub_key())
    txOut2 = TxOutput(Decimal('0.01744912'), fromAddress.to_script_pub_key())

    # create transaction
    tx = Transaction([txin], [txOut1, txOut2], has_segwit=True)

    print("\nRaw transaction:\n" + tx.serialize())

    sig1 = priv0.sign_segwit_input(tx, 0, redeem_script1, amount)
    tx.witnesses.append(Script([sig1, pub.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
    print("\nTxId:", tx.get_txid())
Exemple #9
0
class Id:
    """
    Helper class for handling identity related keys and addresses easily
    """
    def __init__(self, sk: str):
        self.sk = PrivateKey(secret_exponent=int(sk, 16))
        self.pk = self.sk.get_public_key()
        self.addr = self.pk.get_address().to_string()
        self.p2pkh = P2pkhAddress(self.addr).to_script_pub_key()
def main():
    # always remember to setup the network
    setup('testnet')

    priv = PrivateKey("cVdte9ei2xsVjmZSPtyucG43YZgNkmKTqhwiUA8M4Fc3LdPJxPmZ")

    pub = priv.get_public_key()

    fromAddress = pub.get_segwit_address()
    print(fromAddress.to_string())

    # amount is needed to sign the segwit input
    fromAddressAmount = 0.01

    # UTXO of fromAddress
    txid = '13d2d30eca974e8fa5da11b9608fa36905a22215e8df895e767fc903889367ff'
    vout = 0

    toAddress = P2pkhAddress('mrrKUpJnAjvQntPgz2Z4kkyr1gbtHmQv28')

    # create transaction input from tx id of UTXO
    txin = TxInput(txid, vout)
    # the redeem script for p2wpkh is the same as p2pkh
    redeem_script = Script([
        'OP_DUP', 'OP_HASH160',
        priv.get_public_key().to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # create transaction output
    txOut = TxOutput(0.009, toAddress.to_script_pub_key())

    # create transaction without change output
    tx = Transaction([txin], [txOut], has_segwit=True)

    print("\nRaw transaction:\n" + tx.serialize())

    sig = priv.sign_segwit_input(tx, 0, redeem_script, fromAddressAmount)
    tx.witnesses.append(Script([sig, pub.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
    print("\nTxId:", tx.get_txid())
def main():
    # always remember to setup the network
    setup('testnet')  # same params as regest, which the node should run

    # create transaction input from tx id of UTXO (contained 0.4 tBTC)
    txin = TxInput(
        'e2d08a63a540000222d6a92440436375d8b1bc89a2638dc5366833804287c83f', 1)

    # create transaction output using P2PKH scriptPubKey (locking script)
    addr = P2pkhAddress('msXP94TBncQ9usP6oZNpGweE24biWjJs2d')
    # locking script expects 2 numbers that when added equal 5 (silly example)
    txout = TxOutput(0.9, Script(['OP_ADD', 'OP_5', 'OP_EQUAL']))

    # create another output to get the change - remaining 0.01 is tx fees
    # note that this time we used to_script_pub_key() to create the P2PKH
    # script
    change_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
    change_txout = TxOutput(2, change_addr.to_script_pub_key())

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin], [txout, change_txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to sign the input
    sk = PrivateKey('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA')

    # note that we pass the scriptPubkey as one of the inputs of sign_input
    # because it is used to replace the scriptSig of the UTXO we are trying to
    # spend when creating the transaction digest
    from_addr = P2pkhAddress('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r')
    sig = sk.sign_input(
        tx, 0,
        Script([
            'OP_DUP', 'OP_HASH160',
            from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))
    #print(sig)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
def main():
    # always remember to setup the network
    setup('testnet')

    #
    # This script spends from a P2SH address containing a P2PK script
    #

    # create transaction input from tx id of UTXO (contained 0.1 tBTC)
    txin = TxInput(
        '7db363d5a7fabb64ccce154e906588f1936f34481223ea8c1f2c935b0a0c945b', 0)

    # secret key needed to spend P2PK that is wrapped by P2SH
    p2pk_sk = PrivateKey(
        'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
    p2pk_pk = p2pk_sk.get_public_key().to_hex()
    # create the redeem script - needed to sign the transaction
    redeem_script = Script([p2pk_pk, 'OP_CHECKSIG'])

    #TODELETE
    #txin_script_pub_key = redeem_script.to_p2sh_script_pub_key()

    to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    txout = TxOutput(Decimal('0.08'), to_addr.to_script_pub_key())

    # no change address - the remaining 0.01 tBTC will go to miners)

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin], [txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signature for the txin -
    # note that the redeem script is passed to replace the scriptSig
    sig = p2pk_sk.sign_input(tx, 0, redeem_script)
    #print(sig)

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, redeem_script.to_hex()])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
Exemple #13
0
def main():
    # always remember to setup the network
    setup('testnet')

    # the key that corresponds to the P2WPKH address
    priv = PrivateKey('cNho8fw3bPfLKT4jPzpANTsxTsP8aTdVBD6cXksBEXt4KhBN7uVk')
    pub = priv.get_public_key()

    # the p2sh script and the corresponding address
    redeem_script = pub.get_segwit_address().to_script_pub_key()
    p2sh_addr = P2shAddress.from_script(redeem_script)

    # the UTXO of the P2SH-P2WPKH that we are trying to spend
    inp = TxInput('95c5cac558a8b47436a3306ba300c8d7af4cd1d1523d35da3874153c66d99b09', 0)

    # exact amount of UTXO we try to spent
    amount = 0.0014

    # the address to send funds to
    to_addr = P2pkhAddress('mvBGdiYC8jLumpJ142ghePYuY8kecQgeqS')

    # the output sending 0.001 -- 0.0004 goes to miners as fee -- no change
    out = TxOutput(to_satoshis(0.001), to_addr.to_script_pub_key())

    # create a tx with at least one segwit input
    tx = Transaction([inp], [out], has_segwit=True)

    # script code is the script that is evaluated for a witness program type; each
    # witness program type has a specific template for the script code
    # script code that corresponds to P2WPKH (it is the classic P2PKH)
    script_code = pub.get_address().to_script_pub_key()

    # calculate signature using the appropriate script code
    # remember to include the original amount of the UTXO
    sig = priv.sign_segwit_input(tx, 0, script_code, to_satoshis(amount))

    # script_sig is the redeem script passed as a single element
    inp.script_sig = Script([redeem_script.to_hex()])

    # finally, the unlocking script is added as a witness
    tx.witnesses.append(Script([sig, pub.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
def main() :
    setup('testnet')
    
    relative_blocks = 20
    
    seq = Sequence(TYPE_RELATIVE_TIMELOCK, relative_blocks)
    
    p2pkh_sk = PrivateKey('cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
    
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()
    
    print("Address : " + p2pkh_addr.to_string())
    
    
    redeem_script = Script([seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160'
                            , p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'])
    
    
    addr = P2shAddress.from_script(redeem_script)
    
    
    print(addr.to_string())
def main():
    # always remember to setup the network
    setup('mainnet')

    # create a private key (deterministically)
    priv = PrivateKey(secret_exponent=1)

    # compressed is the default
    print("\nPrivate key WIF:", priv.to_wif(compressed=True))

    # could also instantiate from existing WIF key
    #priv = PrivateKey.from_wif('KwDiBf89qGgbjEhKnhxjUh7LrciVRzI3qYjgd9m7Rfu73SvHnOwn')

    # get the public key
    pub = priv.get_public_key()

    # compressed is the default
    print("Public key:", pub.to_hex(compressed=True))

    # get address from public key
    address = pub.get_address()

    # print the address and hash160 - default is compressed address
    print("Address:", address.to_string())
    print("Hash160:", address.to_hash160())

    print("\n--------------------------------------\n")

    # sign a message with the private key and verify it
    message = "The test!"
    signature = priv.sign_message(message)
    print("The message to sign:", message)
    print("The signature is:", signature)

    if PublicKey.verify_message(address.to_string(), signature, message):
        print("The signature is valid!")
    else:
        print("The signature is NOT valid!")
Exemple #16
0
    def tx_encf(self, vk_p, ct_c, user_conf_file_path):
        user_conf_file = open(user_conf_file_path)
        conf = json.load(user_conf_file)

        sk_u = conf['SK']
        sk_u = PrivateKey(secret_exponent=int(sk_u, 16))
        vk_u = sk_u.get_public_key()
        addr_u = vk_u.get_address().to_string()

        #txid = '826711590bb543028418d312cf2229eba1b4fbf295fa73dbc37654085e1fc925'
        #txid = '49ab8b8f6913d5fb97c067fe9466710f62e195bab5366e484d1b2334a5b5c0c8'
        #tx_index = 1
        txid = input(
            "Fund the address: {0} \nand insert the txid:\n".format(addr_u))
        tx_index = input("tx_index:\n")
        print("txid: ", txid)
        print("tx_index: ", tx_index)

        signed_tx_hex = self._tx_encf('04' + vk_p, ct_c, sk_u, txid,
                                      int(tx_index))
        #tx_hash = "88e602cc4766edd442ee99270f2e94bf6f7625a9b49721311fc9bba4dfe8defa"
        tx_hash = self.proxy.sendrawtransaction(signed_tx_hex)
        return tx_hash
def main():
    setup('testnet')

    txin = TxInput(
        '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0)

    from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')

    print("From Address  : ", from_addr)

    sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')

    p2pk_sk = PrivateKey(
        'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')

    p2pk_pk = p2pk_sk.get_public_key().to_hex()

    redeem_script = Script([p2pk_pk, 'OP_CHECKSIG'])

    txout = TxOutput(to_satoshis(0.09), redeem_script.to_p2sh_script_pub_key())

    tx = Transaction([txin], [txout])

    print("Raw transaction", tx.serialize())
 def test_public_key(self):
     p = PrivateKey(secret_exponent=1)
     self.assertEqual(p.get_public_key().to_bytes(), self.public_key_bytes)
Exemple #19
0
# 1. Setup the network.You can use either the mainnet or the testnet.
setup('testnet')

# 2. Create a private key. Do you all have the same private key?
#     private keys are from definition random numbers
priv = PrivateKey(secret_exponent=1)

# 3. What is the WIF (wallet import format) format (uncompressed) of the private key?
print("\nPrivate key WIF:", priv.to_wif(compressed=False))

# 4. What is the WIF format (compressed) of the private key?
print("\nPrivate key WIF:", priv.to_wif(compressed=True))

# 5. What is the corresponding public key? In uncompressed and compressed forms.
#    public keys are generated from private keys using ECDSA cryptographic function
pub = priv.get_public_key()

print("Public key:", pub.to_hex(compressed=False))
print("Public key:", pub.to_hex(compressed=True))

# 6. What is the corresponding address? Get address from public key
address = pub.get_address()
print("Address:", address.to_string())

# Q: What does the address start with? Why?
# The address starts with m (Base58 result prefix) because it is a Bitcoin testnet address

# 7. What is the hash160 representation of the address?
print("Hash160:", address.to_hash160())

# 8. What is the scriptPubKey (locking script) of the address?
def main():
    # always remember to setup the network
    setup('testnet')

    # create transaction input from tx id of UTXO (contained 0.39 tBTC)
    # 0.1 tBTC
    txin = TxInput(
        '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 0)
    # 0.29 tBTC
    txin2 = TxInput(
        '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 1)

    # create transaction output using P2PKH scriptPubKey (locking script)
    addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e')
    txout = TxOutput(
        0.3,
        Script([
            'OP_DUP', 'OP_HASH160',
            addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))

    # create another output to get the change - remaining 0.01 is tx fees
    change_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
    change_txout = TxOutput(
        0.08,
        Script([
            'OP_DUP', 'OP_HASH160',
            change_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]))

    # create transaction from inputs/outputs -- default locktime is used
    tx = Transaction([txin, txin2], [txout, change_txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    #
    # use the private keys corresponding to the addresses that contains the
    # UTXOs we are trying to spend to create the signatures
    #

    sk = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
    sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt')

    # we could have derived the addresses from the secret keys
    from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')

    # sign the first input
    sig = sk.sign_input(
        tx, 0,
        Script([
            'OP_DUP', 'OP_HASH160',
            from_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]), SIGHASH_ALL | SIGHASH_ANYONECANPAY)
    #print(sig)

    # sign the second input
    sig2 = sk2.sign_input(
        tx, 1,
        Script([
            'OP_DUP', 'OP_HASH160',
            from_addr2.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
        ]), SIGHASH_SINGLE | SIGHASH_ANYONECANPAY)
    #print(sig2)

    # get public key as hex
    pk = sk.get_public_key()
    pk = pk.to_hex()
    #print (pk)

    # get public key as hex
    pk2 = sk2.get_public_key()
    pk2 = pk2.to_hex()

    # set the scriptSig (unlocking script)
    txin.script_sig = Script([sig, pk])
    txin2.script_sig = Script([sig2, pk2])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
class TestCreateP2pkhTransaction(unittest.TestCase):
    def setUp(self):
        setup('testnet')
        # values for testing unsigned tx, signed tx all, signed tx with low s,
        # sighash none
        self.txin = TxInput('fb48f4e23bf6ddf606714141ac78c3e921c8c0bebeb7c8abb2c799e9ff96ce6c', 0)
        self.addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.txout = TxOutput(Decimal('0.1'), Script(['OP_DUP', 'OP_HASH160', self.addr.to_hash160(),
                                           'OP_EQUALVERIFY', 'OP_CHECKSIG']) )
        self.change_addr = P2pkhAddress('mytmhndz4UbEMeoSZorXXrLpPfeoFUDzEp')
        self.change_txout = TxOutput(Decimal('0.29'), self.change_addr.to_script_pub_key())
        self.change_low_s_addr = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
        self.change_low_s_txout = TxOutput(Decimal('0.29'), self.change_low_s_addr.to_script_pub_key())
        self.sk = PrivateKey('cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
        self.from_addr = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e')

        self.core_tx_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb0000000000ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a914c992931350c9ba48538003706953831402ea34ea88ac00000000'
        self.core_tx_signed_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006a473044022079dad1afef077fa36dcd3488708dd05ef37888ef550b45eb00cdb04ba3fc980e02207a19f6261e69b604a92e2bffdf6ddbed0c64f55d5003e9dfb58b874b07aef3d7012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a914c992931350c9ba48538003706953831402ea34ea88ac00000000'
        self.core_tx_signed_low_s_SIGALL_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006a473044022044ef433a24c6010a90af14f7739e7c60ce2c5bc3eab96eaee9fbccfdbb3e272202205372a617cb235d0a0ec2889dbfcadf15e10890500d184c8dda90794ecdf79492012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.core_tx_signed_low_s_SIGNONE_result = '02000000016cce96ffe999c7b2abc8b7bebec0c821e9c378ac41417106f6ddf63be2f448fb000000006b483045022100b4ef8ec12b39b21c4b5d57ce82c0c8762a8e9fbe5322a0f00bd5de0dba5152fe02203edb3128b6df0c891770e377fdc8be5b46a2eab16c63bf57507d075a98557236022103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708ffffffff0280969800000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac4081ba01000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.core_tx_signed_low_s_SIGNONE_txid = '76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f'

        # values for testing sighash single and sighash all/none/single with
        # anyonecanpay
        self.sig_txin1 = TxInput("76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f", 0)
        self.sig_txin2 = TxInput('76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f', 1)
        self.sig_from_addr1 = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.sig_from_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
        self.sig_sk1 = PrivateKey('cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
        self.sig_sk2 = PrivateKey('cVf3kGh6552jU2rLaKwXTKq5APHPoZqCP4GQzQirWGHFoHQ9rEVt')
        self.sig_to_addr1 = P2pkhAddress('myPAE9HwPeKHh8FjKwBNBaHnemApo3dw6e')
        self.sig_txout1 = TxOutput(Decimal('0.09'), Script(['OP_DUP', 'OP_HASH160',
                                                 self.sig_to_addr1.to_hash160(),
                                                 'OP_EQUALVERIFY',
                                                 'OP_CHECKSIG']) )
        self.sig_to_addr2 = P2pkhAddress('mmYNBho9BWQB2dSniP1NJvnPoj5EVWw89w')
        self.sig_txout2 = TxOutput(Decimal('0.009'), Script(['OP_DUP', 'OP_HASH160',
                                                   self.sig_to_addr2.to_hash160(),
                                                   'OP_EQUALVERIFY',
                                                   'OP_CHECKSIG']) )
        self.sig_sighash_single_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202cfd7077fe8adfc5a65fb3953fa3482cad1413c28b53f12941c1082898d4935102201d393772c47f0699592268febb5b4f64dabe260f440d5d0f96dae5bc2b53e11e032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_all_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100e30383d4006ef8b796ed397a81d2c55e6db3c05b370cb26179110816e57356e6022068fcd18a2a6984839a1fa7670693ed5c787da96589cd0f5ca81e3f11e613bd11012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402206b728374b8879fd7a10cbd4f347934d583f4301aa5d592211487732c235b85b6022030acdc07761f227c27010bd022df4b22eb9875c65a59e8e8a5722229bc7362f4012102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_none_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402202a2804048b7f84f2dd7641ec05bbaf3da9ae0d2a9f9ad476d376adfd8bf5033302205170fee2ab7b955d72ae2beac3bae15679d75584c37d78d82b07df5402605bab022102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022021a82914b002bd02090fbdb37e2e739e9ba97367e74db5e1de834bbab9431a2f02203a11f49a3f6ac03b1550ee04f9d84deee2045bc038cb8c3e70869470126a064d022102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_single_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006a47304402206118d21952932deb8608f772017fe76827ccdc8b750ead0f5636429ab5883a6802207f6ded77e22785b0e6c682c05260c2e073d1e1522d4c02fb78df6cdd2862e853032102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a47304402205012090ddf07ee2e7767020f09224001360243f8dbe05c5011c54eed9fb90d4802203358e227c891f609c3baf98d975d9ee72666fb511c808419d24ec5cccaf3938e032102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'
        self.sign_sighash_all_single_anyone_2in_2out_result = '02000000020f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b4830450221008837e1300f41566cbcd9649ea21a6c1574cce7bf4bc288b878b545e9370041ab022040d0abdd2a0945463b85553922f27a755492e4e2ba89ae68cb14079103072dbb812102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff0f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676010000006a473044022067943abe9fa7584ba9816fc9bf002b043f7f97e11de59155d66e0411a679ba2c02200a13462236fa520b80b4ed85c7ded363b4c9264eb7b2d9746200be48f2b6f4cb832102364d6f04487a71b5966eae3e14a4dc6f00dbe8e55e61bedd0b880766bfe72b5dffffffff0240548900000000001976a914c3f8e5b0f8455a2b02c29c4488a550278209b66988aca0bb0d00000000001976a91442151d0c21442c2b038af0ad5ee64b9d6f4f4e4988ac00000000'



    def test_unsigned_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_txout])
        self.assertEqual(tx.serialize(), self.core_tx_result)

    def test_signed_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_txout])
        sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                                self.from_addr.to_hash160(),
                                                'OP_EQUALVERIFY', 'OP_CHECKSIG']) )
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.core_tx_signed_result)

    def test_signed_low_s_SIGALL_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_low_s_txout])
        sig = self.sk.sign_input( tx, 0, self.from_addr.to_script_pub_key() )
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.core_tx_signed_low_s_SIGALL_result)

    def test_signed_low_s_SIGNONE_tx_1_input_2_outputs(self):
        tx = Transaction([self.txin], [self.txout, self.change_low_s_txout])
        sig = self.sk.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                         self.from_addr.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_NONE)
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        # check correct raw tx
        self.assertEqual(tx.serialize(),
                         self.core_tx_signed_low_s_SIGNONE_result)
        # check correct calculation of txid
        self.assertEqual(tx.get_txid(), self.core_tx_signed_low_s_SIGNONE_txid)

    def test_signed_low_s_SIGSINGLE_tx_1_input_2_outputs(self):
        tx = Transaction([self.sig_txin1], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input( tx, 0,
                                      self.sig_from_addr1.to_script_pub_key(),
                                     SIGHASH_SINGLE)
        pk = self.sig_sk1.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.sig_sighash_single_result)

    def test_signed_SIGALL_tx_2in_2_out(self):
        # note that this would have failed due to absurdly high fees but we
        # ignore it for our purposes
        tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input( tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr1.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_ALL)
        sig2 = self.sig_sk2.sign_input( tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr2.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_ALL)
        pk = self.sig_sk1.get_public_key().to_hex()
        pk2 = self.sig_sk2.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.sig_txin2.script_sig = Script([sig2, pk2])
        self.assertEqual(tx.serialize(), self.sign_sighash_all_2in_2out_result)

    def test_signed_SIGNONE(self):
        # note that this would have failed due to absurdly high fees but we
        # ignore it for our purposes
        tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input(tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                                   self.sig_from_addr1.to_hash160(),
                                                   'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                      SIGHASH_NONE)
        sig2 = self.sig_sk2.sign_input(tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                                    self.sig_from_addr2.to_hash160(),
                                                    'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                       SIGHASH_NONE)
        pk = self.sig_sk1.get_public_key().to_hex()
        pk2 = self.sig_sk2.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.sig_txin2.script_sig = Script([sig2, pk2])
        self.assertEqual(tx.serialize(), self.sign_sighash_none_2in_2out_result)

    def test_signed_SIGSINGLE_tx_2in_2_out(self):
        # note that this would have failed due to absurdly high fees but we
        # ignore it for our purposes
        tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input(tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr1.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                      SIGHASH_SINGLE)
        sig2 = self.sig_sk2.sign_input(tx, 1, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr2.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                      SIGHASH_SINGLE)
        pk = self.sig_sk1.get_public_key().to_hex()
        pk2 = self.sig_sk2.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.sig_txin2.script_sig = Script([sig2, pk2])
        self.assertEqual(tx.serialize(), self.sign_sighash_single_2in_2out_result)

    def test_signed_SIGALLSINGLE_ANYONEtx_2in_2_out(self):
        # note that this would have failed due to absurdly high fees but we
        # ignore it for our purposes
        tx = Transaction([self.sig_txin1, self.sig_txin2], [self.sig_txout1, self.sig_txout2] )
        sig = self.sig_sk1.sign_input(tx, 0, Script(['OP_DUP', 'OP_HASH160',
                                         self.sig_from_addr1.to_hash160(),
                                         'OP_EQUALVERIFY', 'OP_CHECKSIG']),
                                 SIGHASH_ALL|SIGHASH_ANYONECANPAY)
        sig2 = self.sig_sk2.sign_input(tx, 1,
                                       self.sig_from_addr2.to_script_pub_key(),
                                 SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)
        pk = self.sig_sk1.get_public_key().to_hex()
        pk2 = self.sig_sk2.get_public_key().to_hex()
        self.sig_txin1.script_sig = Script([sig, pk])
        self.sig_txin2.script_sig = Script([sig2, pk2])
        self.assertEqual(tx.serialize(),
                         self.sign_sighash_all_single_anyone_2in_2out_result)
Exemple #22
0
def main():

    #Connect to the regtest network
    setup('regtest')
    proxy = NodeProxy('user', 'bitcoin').get_proxy()

    #Accept absolute future block amount User
    current_blocks = proxy.getblockcount()
    absolute_blocks = int(
        input(
            f'\nPlease input the future block height. The current block height is: {current_blocks}.\nIt must match the one in the redeem script from which the P2SH address (with the locked funds) was derived\n'
        ))

    #Accept the Private Key from User
    sk = PrivateKey(
        input(
            '\nPlease enter your Private Key (used to create the address from which the P2SH Address was derived)\n'
        ))

    #Accept the P2SH Address with the funds
    p2sh_addr = input(
        '\nPlease enter the P2SH address which has the locked funds\n')

    #Import the address into the wallet
    proxy.importaddress(f'{p2sh_addr}')
    print(
        f'\nThe P2SH address {p2sh_addr} has been imported into the wallet.\n')

    #Get all UTXOs for this address
    all_utxos = proxy.listunspent(1, 9999999, [f'{p2sh_addr}'])
    print(f'\nAll the UTXO Objects for this address are:\n{all_utxos}\n')

    #Calculate total funds available. Aggregate all UTXO amounts.
    def totalFunds():
        total = Decimal(0)
        for utxo in all_utxos:
            total += Decimal(utxo["amount"])
        return total

    total_funds = totalFunds()
    print("Total funds available: ", total_funds)

    #Instantiate the timelock sequence
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, absolute_blocks)

    #Create an array of inputs from these UTXOs
    def getInputs():
        inputs = []
        count = 0
        for utxo in all_utxos:
            #create inputs and append them into an array
            #First, create an input
            utxo = all_utxos[count]
            txin = TxInput(utxo["txid"],
                           utxo["vout"],
                           sequence=seq.for_input_sequence())
            #then, append it to the array
            inputs.append(txin)
            ++count
        return inputs

    inputs = getInputs()

    print(f'The inputs created from these outputs are:\n {inputs}')

    #Use User's Secret Key (Accepted above) to recreate the Public Key
    pk = sk.get_public_key()

    #We recreate the P2PKH Addr to recreate the other half of the redeemScript
    p2pkh_addr = pk.get_address()

    #We recreate the redeem script
    redeem_script = Script([
        absolute_blocks, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    #Confirm that the P2SH address is the same one to which funds were sent by receating the P2SH from this redeem script
    addr = P2shAddress.from_script(redeem_script).to_string()
    print(
        f'\nCheck if this is the address with the locked funds:\n{addr} vs what you input above {p2sh_addr}'
    )

    #Accept the receiving P2PKH from User
    destination_addr = P2pkhAddress(
        input(
            '\nPlease enter the address you want to send the locked funds to:\n'
        ))

    #Calculate txn size to estimate fee from inputs only so we subtract it from funds
    tx_test = Transaction(inputs, [],
                          Locktime(absolute_blocks).for_transaction())
    tx_size = tx_test.get_size()
    # 0.0001 is an appropriate fee per byte so we use that
    est_tx_fee = tx_size / 1000 * 0.0001

    #Create a txout transferring total locked funds (minus estimated fees).
    txout = TxOutput(to_satoshis(total_funds - Decimal(est_tx_fee)),
                     destination_addr.to_script_pub_key())

    #Create Txn. Passing in the inputs, output, and the future absolute lock time
    tx = Transaction(inputs, [txout],
                     Locktime(absolute_blocks).for_transaction())

    #Print the newly created txn
    print(f'\nThe raw unsigned txn is: {tx.serialize()}\n')

    #Calulate the Appropriate Transaction Fee According to Txn Size.
    #First, get the fee estimate from network. Useful only for mainnet and testnet.
    def getFee():
        fee = proxy.estimatesmartfee(5, "ECONOMICAL")
        if fee["errors"]:
            print(
                'Network data not enough to calculate fee. Setting default fee: 0.0001 BTC'
            )
            return 0.0001
        else:
            return fee["feerate"]


#Then, calculate the size of our Txn and then multiply it by the per-byte fee

    est_fee = getFee()  #per byte
    tx_size = tx.get_size()
    print(f'\nThe transaction size is:\n{tx_size} bytes')
    tx_fee = tx_size / 1000 * est_fee
    print(f'\nThe recommended fee for this transaction is:\n{tx_fee}')

    #Need to sign all inputs
    def signInputs():
        input_index = 0
        for input in inputs:
            #Use the Secret Key corresponding to the P2SH to create the signature for the txn/ sign all inputs
            #Redeem script is passed to replace the scriptSig
            inputSig = sk.sign_input(tx, input_index, redeem_script)
            input.script_sig = Script(
                [inputSig, pk.to_hex(),
                 redeem_script.to_hex()])
            ++input_index

    signInputs()

    signed_tx = tx.serialize()

    #Print the signed raw txn, ready to be checked for validity
    print(f"\nRaw signed transaction:\n{signed_tx}")
    print(
        f"\nTransaction ready to be broadcast. Transaction Id: {tx.get_txid()}"
    )

    #Test for validity
    isValid = proxy.testmempoolaccept([f'{signed_tx}'])
    print(f'\nTransaction validity check result:\n{isValid}')

    #Broadcast txn
    #needs signed_tx
    if isValid[0]["allowed"]:
        if input('\nSend transaction to network? Y / N: ') == 'Y':
            sent_tx_id = proxy.sendrawtransaction(f'{signed_tx}')
            print(
                f'\n***The transaction with id {sent_tx_id} has been sent to the network***'
            )
        else:
            print(
                f'\nUser decided not to send the funds and exited the program.'
            )
            exit()
    else:
        reason = isValid[0]["reject-reason"]
        print(f'\nThe signed raw transaction is invalid. Reason: {reason}')
Exemple #23
0
def main():
    # always remember to setup the network
    setup('testnet')

    #
    # This script spends from a P2SH address containing a CSV+P2PKH script as
    # created from examples/create_p2sh_csv_p2pkh.py
    #
    # We assume that some 11.1 tBTC have been send to that address and that we know
    # the txid and the specific UTXO index (or vout).
    #

    # set values
    relative_blocks = 20
    txid = '76c102821b916a625bd3f0c3c6e35d5c308b7c23e78b8866b06a3a466041db0a'
    vout = 0

    seq = Sequence(TYPE_RELATIVE_TIMELOCK, relative_blocks)

    # create transaction input from tx id of UTXO (contained 11.1 tBTC)
    txin = TxInput(txid, vout, sequence=seq.for_input_sequence())

    # secret key needed to spend P2PKH that is wrapped by P2SH
    p2pkh_sk = PrivateKey(
        'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
    p2pkh_pk = p2pkh_sk.get_public_key().to_hex()
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()

    # create the redeem script - needed to sign the transaction
    redeem_script = Script([
        seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # to confirm that address is the same as the one that the funds were sent
    #addr = P2shAddress.from_script(redeem_script)
    #print(addr.to_address())

    # send/spend to any random address
    to_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
    txout = TxOutput(11, to_addr.to_script_pub_key())

    # no change address - the remaining 0.1 tBTC will go to miners)

    # create transaction from inputs/outputs
    tx = Transaction([txin], [txout])

    # print raw transaction
    print("\nRaw unsigned transaction:\n" + tx.serialize())

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signature for the txin -
    # note that the redeem script is passed to replace the scriptSig
    sig = p2pkh_sk.sign_input(tx, 0, redeem_script)
    #print(sig)

    # set the scriptSig (unlocking script) -- unlock the P2PKH (sig, pk) plus
    # the redeem script, since it is a P2SH
    txin.script_sig = Script([sig, p2pkh_pk, redeem_script.to_hex()])
    signed_tx = tx.serialize()

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + signed_tx)
    print("\nTxId:", tx.get_txid())
Exemple #24
0
def tip_or_withdrawFunc(update, ctx):
    # Initialise bitcoin.py
    setup('mainnet')
    query = update.callback_query
    chID = query.message.chat.id
    msgID = query.message.message_id
    query.answer()
    data = str(query.data).split(",")
    sender = str(query.from_user.id)
    if sender == data[3]:
        if data[4] == "t":
            target = data[1]
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                target_address = P2wpkhAddress(getAddress(target))
                sender_address = P2wpkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()["result"]
                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:

                    txout = []
                    txout.append(
                        TxOutput((amount - fee),
                                 target_address.to_script_pub_key()))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        txout.append(
                            TxOutput(txchange,
                                     sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

                    tx = Transaction(txin, txout, has_segwit=True)

                    tx.witnesses = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_segwit_input(
                            tx, i, script_code, value)
                        tx.witnesses.append(
                            Script([sig,
                                    sender_wif.get_public_key().to_hex()]))

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Success, sent @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}."
                    )
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"[View Transaction](https://sugar\\.wtf/esplora/tx/{str(txid)})",
                        parse_mode="MarkdownV2")
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text="You do not have enough funds to tip that amount")

            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                ctx.bot.send_message(
                    chat_id=chID,
                    text=
                    f"You declined sending @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}"
                )

        elif data[4] == "w":
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                sender_address = P2wpkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee
                target_address = P2wpkhAddress("sugar1q" + data[1])

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()['result']

                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:
                    txout = []

                    txout.append(
                        TxOutput((amount - fee),
                                 target_address.to_script_pub_key()))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        txout.append(
                            TxOutput(txchange,
                                     sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

                    tx = Transaction(txin, txout, has_segwit=True)

                    tx.witnesses = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_segwit_input(
                            tx, i, script_code, value)
                        tx.witnesses.append(
                            Script([sig,
                                    sender_wif.get_public_key().to_hex()]))

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Success, withdrew {data[2]} {config.coin['ticker']} to address {target_address.to_string()} "
                    )
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"[View Transaction](https://sugar\\.wtf/esplora/tx/{str(txid)})",
                        parse_mode="MarkdownV2")
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        "You do not have enough funds to withdraw the specified amount."
                    )
            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                ctx.bot.send_message(
                    chat_id=chID,
                    text=
                    f"You declined withdrawing {data[2]} {config.coin['ticker']} to address {'sugar1q' + data[1]}"
                )
Exemple #25
0
def tip_or_withdrawFunc(update, ctx):
    # Initialise bitcoin.py
    setup('mainnet')
    query = update.callback_query
    chID = query.message.chat.id
    msgID = query.message.message_id
    query.answer()
    data = str(query.data).split(",")
    sender = str(query.from_user.id)
    chatid = query.message.chat_id
    if sender == data[3]:
        if data[4] == "t":
            target = data[1]
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                #target_address = P2wpkhAddress(getAddress(target))
                target_address = P2pkhAddress(getAddress(target))
                #sender_address = P2wpkhAddress(getAddress(sender))
                sender_address = P2pkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()["result"]
                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:
                    txout = []
                    txout = (TxOutput((amount - fee),
                                      Script([
                                          'OP_DUP', 'OP_HASH160',
                                          target_address.to_hash160(),
                                          'OP_EQUALVERIFY', 'OP_CHECKSIG'
                                      ])))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        change_txout = (TxOutput(
                            txchange, sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

                    tx = Transaction(txin, [txout, change_txout])

                    # get public key as hex
                    pk = sender_wif.get_public_key().to_hex()

                    sigpk = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_input(
                            tx, i,
                            Script([
                                'OP_DUP', 'OP_HASH160',
                                sender_address.to_hash160(), 'OP_EQUALVERIFY',
                                'OP_CHECKSIG'
                            ]))
                        sigpk.append(Script([sig, pk]))
                        txin[i].script_sig = sigpk[i]

                    #signed_tx = tx.serialize()
                    #print("\nRaw signed transaction:\n" + signed_tx)
                    #exit(0)

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Успешно, отправлено @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}."
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[Детали транзакции](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Success, sent @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}."
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[View Transaction](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                else:
                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "У вас недостаточно средств, чтобы дать эту сумму чаевых"
                        )
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "You do not have enough funds to tip that amount")

            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                if checkRus(chatid):
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Вы отказались от отправки @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}"
                    )
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"You declined sending @{db.getUserName(data[1])} {data[2]} {config.coin['ticker']}"
                    )

        elif data[4] == "w":
            if data[0] == "Y":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)

                sender_wif = PrivateKey(db.getWIF(sender))
                fee = convertToSatoshis(Decimal(config.coin['minFee']))
                #sender_address = P2wpkhAddress(getAddress(sender))
                sender_address = P2pkhAddress(getAddress(sender))
                sender_balance = 0
                amount = convertToSatoshis(Decimal(data[2])) + fee
                #target_address = P2wpkhAddress("ytn1q" + data[1])
                #target = data[1]
                target_address = P2pkhAddress("Y" + data[1])

                unspent = requests.get(
                    f"{config.apiUrl}/unspent/{sender_address.to_string()}"
                ).json()['result']

                txin = []
                for i in range(0, len(unspent)):
                    sender_balance += unspent[i]['value']
                    txin.append(
                        TxInput(unspent[i]['txid'], unspent[i]['index']))

                if sender_balance >= amount:
                    txout = []

                    txout = (TxOutput((amount - fee),
                                      Script([
                                          'OP_DUP', 'OP_HASH160',
                                          target_address.to_hash160(),
                                          'OP_EQUALVERIFY', 'OP_CHECKSIG'
                                      ])))

                    txchange = sender_balance - amount
                    if txchange > 0:
                        change_txout = (TxOutput(
                            txchange, sender_address.to_script_pub_key()))

                    script_code = Script([
                        'OP_DUP', 'OP_HASH160',
                        sender_wif.get_public_key().to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'
                    ])

                    tx = Transaction(txin, [txout, change_txout])

                    # get public key as hex
                    pk = sender_wif.get_public_key().to_hex()

                    sigpk = []

                    for i in range(0, len(unspent)):
                        value = unspent[i]['value']
                        sig = sender_wif.sign_input(
                            tx, i,
                            Script([
                                'OP_DUP', 'OP_HASH160',
                                sender_address.to_hash160(), 'OP_EQUALVERIFY',
                                'OP_CHECKSIG'
                            ]))
                        sigpk.append(Script([sig, pk]))
                        txin[i].script_sig = sigpk[i]

                    #signed_tx = tx.serialize()
                    #print("\nRaw signed transaction:\n" + signed_tx)
                    #exit(0)

                    post_data = {'raw': tx.serialize()}

                    txid = requests.post(f"{config.apiUrl}/broadcast",
                                         data=post_data).json()['result']

                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Успех, сняли {data[2]} {config.coin['ticker']} to address {target_address.to_string()} "
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[Детали транзакции](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"Success, withdrew {data[2]} {config.coin['ticker']} to address {target_address.to_string()} "
                        )
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            f"[View Transaction](https://ytn.ccore.online/transaction/{str(txid)})",
                            parse_mode="MarkdownV2")
                else:
                    if checkRus(chatid):
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "У вас недостаточно средств для вывода указанной суммы."
                        )
                    else:
                        ctx.bot.send_message(
                            chat_id=chID,
                            text=
                            "You do not have enough funds to withdraw the specified amount."
                        )
            elif data[0] == "N":
                ctx.bot.delete_message(chat_id=chID, message_id=msgID)
                if checkRus(chatid):
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"Вы отказались снимать {data[2]} {config.coin['ticker']} to address {'Y' + data[1]}"
                    )
                else:
                    ctx.bot.send_message(
                        chat_id=chID,
                        text=
                        f"You declined withdrawing {data[2]} {config.coin['ticker']} to address {'Y' + data[1]}"
                    )
# // LAB: Relative Timelock Example //

# 0. What is the type of network you working on? (mainnet / testnet)
#    Always remember to setup the network before anything else.
setup('testnet')


# 1. Create a new private key
#    Use secret_exponent parameter to get a non random private key
priv = PrivateKey(secret_exponent=1)
priv.to_wif()
priv.to_bytes()  # 32 bytes = 32 * 8 bits = 256 bits

# 2a. Get the corresponding public Key
pub = priv.get_public_key()
pub.to_hex()
pub.to_hash160()
pub.to_bytes()

# 2b. Get the address that corresponds to that public key.
#     The string representation of this address starts with m on n, because it is a Bitcoin testnet address
address = priv.get_public_key().get_address()
address.to_string()
address.to_hash160()

address._is_address_valid(address.to_string())   # True
address._is_address_valid(address.to_hash160())  # False


# 3. Create an input sequence for a relative timelock of 10 blocks.
#
# Connect to testnet
#

setup( 'testnet' )
proxy = NodeProxy( USERNAME, PASSWORD_HASH ).get_proxy()


#
#  1) accept a future time, expressed either in block height or in UNIX Epoch time, 
#     and a private key (to recreate the redeem script as above and also use to unlock the P2PKH part)
#

from_privkey    = PrivateKey( 'cSyZjejfhK5gaVYoG9pgfdMrZzw7rXufpiG4oDaYShanJhwpqGcE' )
from_pubkey     = from_privkey.get_public_key()
from_address    = from_pubkey.get_address()
from_hash       = from_address.to_hash160()
redeem_script   = Script( [BLOCKHEIGHT, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160', from_hash, 'OP_EQUALVERIFY', 'OP_CHECKSIG'] )

#
#  2) accept a P2SH address to get the funds from (the one created by the first script)
#

from_p2sh       = P2shAddress.from_script( redeem_script )
print( "     source: " + from_p2sh.to_string() )


#
#  3) check if the P2SH address has any UTXOs to get funds from
#
Exemple #28
0
def create_p2sh():
    '''
    This method creates a P2SH address containing a CHECKLOCKTIMEVERIFY plus
    a P2PKH locking funds with a key up to specific blockchain height
    
    Arguments:
        pubKey: public key for the P2PKH part of the redeem script
        lockBlocks: absolute lock (set to blockchain height)
    Returns:        
        lock_block_height: the specific blockchain height lock (in blocks)
        new_addr_privk: the private key of created P2SH address
        p2sh_addr: the new P2SH address
    '''

    # Setup the network
    setup('regtest')

    # Initialize proxy for RPC calls
    rpcuser = "******"
    rpcpassword = "******"
    rpc_con = AuthServiceProxy("http://%s:%[email protected]:18443" %
                               (rpcuser, rpcpassword))

    # ***** Accept a public (or optionally a private) key for the P2PKH part of
    #       the redeem script

    # Create a new Bitcoin Address (P2PKH)
    # Call the node's getnewaddress JSON-RPC method
    # Returns the address' Public Key
    new_addr_pubk = rpc_con.getnewaddress()

    # ***** Accept a future time expressed either in block height or in UNIX
    #       Epoch time

    # Numbers of blockchain height corresponding to absolute lock time
    lock_block_height = 103

    # Get the corresponding private key from the wallet
    # Call the node's dumpprivkey JSON-RPC method
    new_addr_privk = rpc_con.dumpprivkey(new_addr_pubk)

    # Get information about current blockchain height
    # Call the node's getblockcount JSON-RPC method
    current_block_height = rpc_con.getblockcount()
    if (lock_block_height < current_block_height):
        print(
            '\n***BEWARE*** Given lock (%d blocks) is lower than current blockchain height (%d blocks)'
            % (lock_block_height, current_block_height))
    else:
        print('Current blockchain height: %d blocks' % current_block_height)
        print('Fund\'s lock is set to: %d blocks' % lock_block_height)

    # Setting up an appropriate sequence to provide the script
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, lock_block_height)

    # Secret key corresponding to the pubkey needed for the P2SH (P2PKH) transaction
    p2pkh_sk = PrivateKey(new_addr_privk)

    # Get the P2PKH address (from the public key)
    p2pkh_addr = p2pkh_sk.get_public_key().get_address()

    redeem_script = Script([
        seq.for_script(), 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # Create a P2SH address from a redeem script
    p2sh_addr = P2shAddress.from_script(redeem_script)

    # VERY IMPORTANT: I must insert P2SH address into my wallet
    rpc_con.importaddress(p2sh_addr.to_address())

    # ***** Display the P2SH address
    print(
        '\nNewly created P2SH address with absolute lock set to %d blockchain height:'
        % lock_block_height)
    print(p2sh_addr.to_address())

    return (lock_block_height, new_addr_privk, p2sh_addr.to_address())
Exemple #29
0
class TestCreateP2shTransaction(unittest.TestCase):
    def setUp(self):
        setup('testnet')
        self.txin = TxInput(
            "76464c2b9e2af4d63ef38a77964b3b77e629dddefc5cb9eb1a3645b1608b790f",
            0)
        self.from_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.sk = PrivateKey(
            'cTALNpTpRbbxTCJ2A5Vq88UxT44w1PE2cYqiB3n4hRvzyCev1Wwo')
        self.p2pk_sk = PrivateKey(
            'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
        self.p2pk_redeem_script = Script(
            [self.p2pk_sk.get_public_key().to_hex(), 'OP_CHECKSIG'])
        self.txout = TxOutput(to_satoshis(0.09),
                              self.p2pk_redeem_script.to_p2sh_script_pub_key())
        self.create_p2sh_and_send_result = '02000000010f798b60b145361aebb95cfcdedd29e6773b4b96778af33ed6f42a9e2b4c4676000000006b483045022100fd3a3fd4aeec5db0f3f9c5c5ef7f60f37920be7464a80edacbc3b6b9d0624173022031ce309330e60b19d39cec8c5597460c840adcdd66f7dbbf896eef3ec42b472f012102d82c9860e36f15d7b72aa59e29347f951277c21cd4d34822acdeeadbcff8a546ffffffff01405489000000000017a9142910fc0b1b7ab6c9789c5a67c22c5bcde5b903908700000000'

        self.txin_spend = TxInput(
            '7db363d5a7fabb64ccce154e906588f1936f34481223ea8c1f2c935b0a0c945b',
            0)
        # self.p2pk_sk , self.p2pk_redeem_script from above
        self.to_addr = self.from_addr
        self.txout2 = TxOutput(to_satoshis(0.08),
                               self.to_addr.to_script_pub_key())
        self.spend_p2sh_result = '02000000015b940c0a5b932c1f8cea231248346f93f18865904e15cecc64bbfaa7d563b37d000000006c47304402204984c2089bf55d5e24851520ea43c431b0d79f90d464359899f27fb40a11fbd302201cc2099bfdc18c3a412afb2ef1625abad8a2c6b6ae0bf35887b787269a6f2d4d01232103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af32708acffffffff0100127a00000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000'

        # P2SH(CSV+P2PKH)
        self.sk_csv_p2pkh = PrivateKey(
            'cRvyLwCPLU88jsyj94L7iJjQX5C2f8koG4G2gevN4BeSGcEvfKe9')
        self.seq = Sequence(TYPE_RELATIVE_TIMELOCK, 200)
        self.txin_seq = TxInput(
            'f557c623e55f0affc696b742630770df2342c4aac395e0ed470923247bc51b95',
            0,
            sequence=self.seq.for_input_sequence())
        self.another_addr = P2pkhAddress('n4bkvTyU1dVdzsrhWBqBw8fEMbHjJvtmJR')
        self.spend_p2sh_csv_p2pkh_result = '0200000001951bc57b24230947ede095c3aac44223df70076342b796c6ff0a5fe523c657f5000000008a483045022100c123775e69ec27094f7940facb9ad769c09f48a7fc88250a2fce67bd92c9b4cf02204ebdbed84af46e584fe6db9a23c420b7370879e883b555e119465f84bf34d82f012103a2fef1829e0742b89c218c51898d9e7cb9d51201ba2bf9d9e9214ebb6af327081e02c800b27576a914c3f8e5b0f8455a2b02c29c4488a550278209b66988acc80000000100ab9041000000001976a914fd337ad3bf81e086d96a68e1f8d6a0a510f8c24a88ac00000000'

    def test_signed_send_to_p2sh(self):
        tx = Transaction([self.txin], [self.txout])
        sig = self.sk.sign_input(tx, 0, self.from_addr.to_script_pub_key())
        pk = self.sk.get_public_key().to_hex()
        self.txin.script_sig = Script([sig, pk])
        self.assertEqual(tx.serialize(), self.create_p2sh_and_send_result)

    def test_spend_p2sh(self):
        tx = Transaction([self.txin_spend], [self.txout2])
        sig = self.p2pk_sk.sign_input(tx, 0, self.p2pk_redeem_script)
        self.txin_spend.script_sig = Script(
            [sig, self.p2pk_redeem_script.to_hex()])
        self.assertEqual(tx.serialize(), self.spend_p2sh_result)

    def test_spend_p2sh_csv_p2pkh(self):
        redeem_script = Script([
            self.seq.for_script(), 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP',
            'OP_DUP', 'OP_HASH160',
            self.sk_csv_p2pkh.get_public_key().to_hash160(), 'OP_EQUALVERIFY',
            'OP_CHECKSIG'
        ])
        txout = TxOutput(to_satoshis(11),
                         self.another_addr.to_script_pub_key())
        tx = Transaction([self.txin_seq], [txout])
        sig = self.sk_csv_p2pkh.sign_input(tx, 0, redeem_script)
        self.txin_seq.script_sig = Script([
            sig,
            self.sk_csv_p2pkh.get_public_key().to_hex(),
            redeem_script.to_hex()
        ])
        self.assertEqual(tx.serialize(), self.spend_p2sh_csv_p2pkh_result)
Exemple #30
0
def buy_lambo(key, lock, from_addr, to_addr):
    setup(os.getenv("BUY_LAMBO_BTC_NET", "regtest"))

    # Create a proxy to JSON-RPC api
    chain = NodeProxy(os.getenv("BUY_LAMBO_RPC_USER", "rpcuser"),
                      os.getenv("BUY_LAMBO_RPC_PASSWORD",
                                "rpcpassword")).get_proxy()

    # Try executing a command to see if node is running
    try:
        chain.getblockcount()
    except Exception:
        print("Error: Node isn't working!")
        return

    # Check addresses
    if not chain.validateaddress(from_addr)["isvalid"]:
        print("Error: `from_addr` is not a valid address!")
        return
    if not chain.validateaddress(to_addr)["isvalid"]:
        print("Error: `to_addr` is not a valid address!")
        return

    # Set lock sequence prefix
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, lock)

    # Get public key (found from private key)
    private_key = PrivateKey(key)
    public_key = private_key.get_public_key()

    # Add address to wallet so we can get utxos from bitcoin core
    chain.importaddress(from_addr)

    # Get UTXOs
    utxos = chain.listunspent(1, 9999999, [from_addr])

    # Create inputs
    txin = []
    total_btc = Decimal(0)
    for utxo in utxos:
        # Note that for each input we set the correct nSequence
        txin.append(
            TxInput(utxo["txid"],
                    utxo["vout"],
                    sequence=seq.for_input_sequence()))
        total_btc = total_btc + utxo["amount"]

    if total_btc == 0:
        return print("\nThere aren't any UTXOs :(.")

    # Create a fee-less output
    txout = TxOutput(total_btc - Decimal(0.1),
                     P2pkhAddress(to_addr).to_script_pub_key())

    # Create dummy transaction (to calculate size)
    tx = Transaction([TxInput.copy(inpt) for inpt in txin], [txout],
                     locktime=Locktime(lock).for_transaction())

    # create the redeem script - needed to sign the transaction
    redeem_script = Script([
        seq.for_script(),
        "OP_CHECKLOCKTIMEVERIFY",
        "OP_DROP",
        "OP_DUP",
        "OP_HASH160",
        public_key.get_address().to_hash160(),
        "OP_EQUALVERIFY",
        "OP_CHECKSIG",
    ])

    # use the private key corresponding to the address that contains the
    # UTXO we are trying to spend to create the signature for the txin -
    # note that the redeem script is passed to replace the scriptSig
    for ind, txinput in enumerate(tx.inputs):
        sig = private_key.sign_input(tx, ind, redeem_script)
        txinput.script_sig = Script(
            [sig, public_key.to_hex(),
             redeem_script.to_hex()])

    # Calculate fees
    sat_per_byte = requests.get(
        "https://bitcoinfees.earn.com/api/v1/fees/recommended").json(
        )["fastestFee"]
    fee = Decimal(
        max((len(bytes.fromhex(tx.serialize())) * sat_per_byte) /
            SATOSHIS_PER_BITCOIN, 0))
    if fee == 0:
        print("WARNING: There isn't enough balance to calculate fees.")

    # Create final tx with correct txout value
    txout = TxOutput(total_btc - fee,
                     P2pkhAddress(to_addr).to_script_pub_key())
    tx = Transaction([TxInput.copy(inpt) for inpt in tx.inputs], [txout],
                     locktime=Locktime(lock).for_transaction())
    for ind, txinput in enumerate(tx.inputs):
        sig = private_key.sign_input(tx, ind, redeem_script)
        txinput.script_sig = Script(
            [sig, public_key.to_hex(),
             redeem_script.to_hex()])
    signed_tx = tx.serialize()

    # print raw transaction
    print("\nRaw unsigned transaction:\n{}".format(
        Transaction(txin, [txout]).serialize()))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n{}".format(signed_tx))
    print("\nTxId: {}".format(tx.get_txid()))

    # Check if is valid and send it
    if chain.testmempoolaccept([signed_tx])[0]["allowed"]:
        chain.sendrawtransaction(signed_tx)
        print("\nSent to Block-chain! Have fun with those {} BTC.".format(
            total_btc - fee))
    else:
        print("\nCan't send (yet)!")
        print("Reason: `{}`".format(
            chain.testmempoolaccept([signed_tx])[0]["reject-reason"]))