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

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

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

    # 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_segwit_address()

    # print the address and hash - default is compressed address
    print("Native Address:", address.to_string())
    segwit_hash = address.to_hash()
    print("Segwit Hash:", segwit_hash)
    print("Segwit Version:", address.get_type())

    # test to_string
    addr2 = P2wpkhAddress.from_hash(segwit_hash)
    print("Created P2wpkhAddress from Segwit Hash and calculate address:")
    print("Native Address:", addr2.to_string())

    #
    # display P2SH-P2WPKH
    #

    # create segwit address
    addr3 = PrivateKey.from_wif(
        'cTmyBsxMQ3vyh4J3jCKYn2Au7AhTKvqeYuxxkinsg6Rz3BBPrYKK').get_public_key(
        ).get_segwit_address()
    # wrap in P2SH address
    addr4 = P2shAddress.from_script(addr3.to_script_pub_key())
    print("P2SH(P2WPKH):", addr4.to_string())

    #
    # display P2WSH
    #
    p2wpkh_key = PrivateKey.from_wif(
        'cNn8itYxAng4xR4eMtrPsrPpDpTdVNuw7Jb6kfhFYZ8DLSZBCg37')
    script = Script([
        'OP_1',
        p2wpkh_key.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG'
    ])
    p2wsh_addr = P2wshAddress.from_script(script)
    print("P2WSH of P2PK:", p2wsh_addr.to_string())

    #
    # display P2SH-P2WSH
    #
    p2sh_p2wsh_addr = P2shAddress.from_script(p2wsh_addr.to_script_pub_key())
    print("P2SH(P2WSH of P2PK):", p2sh_p2wsh_addr.to_string())
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())
Example #3
0
def create_HODL_address(key, lock, is_priv=False):
    setup(os.getenv("BUY_LAMBO_BTC_NET", "regtest"))

    # Get public key (given or found from private key)
    public_key = PrivateKey(key).get_public_key() if is_priv else PublicKey(key)

    # Get address from public key
    address_from_key = public_key.get_address()

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

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

    # create a P2SH address from a redeem script
    addr = P2shAddress.from_script(redeem_script)
    print("Time-locked address: {}".format(addr.to_string()))
Example #4
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())
 def test_p2sh_p2wpkh_creation_pubkey(self):
     addr = PrivateKey.from_wif(
         'cTmyBsxMQ3vyh4J3jCKYn2Au7AhTKvqeYuxxkinsg6Rz3BBPrYKK'
     ).get_public_key().get_segwit_address()
     p2sh_addr = P2shAddress.from_script(addr.to_script_pub_key())
     self.assertTrue(p2sh_addr.to_string(),
                     self.correct_p2sh_p2wpkh_address)
Example #6
0
def create_spending_signed_trx(p2pkh_addr_to_str, priv_key_from_obj):
    """
    Gather related data and generate
    the single transation that transfers the btc value of the
    found UTXO transactions.

    """

    p2pkh_addr_to_obj = P2pkhAddress(p2pkh_addr_to_str)

    seq_number_in_hex = Common.get_seq_hex_from_conf(
        Common.get_relative_time_seconds_blocks())

    redeem_script = Common.get_redeem_script_from_conf(
        get_redeem_pub_key_obj())

    p2sh_paid_to_addr = P2shAddress.from_script(redeem_script).to_address()

    utxo_results = get_input_trx_from_utxo(priv_key_from_obj,
                                           p2sh_paid_to_addr, seq_number_in_hex, redeem_script)

    # No sense in creating a transaction with 0 UTXOs
    if utxo_results[0] > 0 and len(utxo_results[1]) > 0:

        signed_tx = get_signed_trx(utxo_results, p2pkh_addr_to_obj,
                                   priv_key_from_obj, redeem_script)

        # print raw signed transaction ready to be broadcasted
        print("\nSigned raw transaction:\n" + signed_tx)

        trasmit_finalized_trx(signed_tx)

    else:
        print("\nNo UTXOs found. Nothing to do!\n")
Example #7
0
def main():

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

    #Accept a Public Key from User and derive a P2PKH address from it
    pk = PublicKey.from_hex(input('Please input your Public Key\n'))
    pk_p2pkh_addr = pk.get_address()

    #Accept future absolute block amount from User
    current_blocks = proxy.getblockcount()
    absolute_blocks = int(
        input(
            f'\nPlease input the future block height. The current block height is: {current_blocks}\n'
        ))

    #Set the timelock sequence and create a redeemScript accordingly

    redeem_script = Script([
        absolute_blocks, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        pk_p2pkh_addr.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    #Generate a P2SH Address from the redeemScript and show it
    p2sh_addr = P2shAddress.from_script(redeem_script)
    print(
        f'\nThe P2SH Address is:\n{p2sh_addr.to_string()} Now, go on and send some funds to it.\n'
    )
 def test_p2sh_p2wsh_creation_1multisig(self):
     p2wpkh_key = PrivateKey.from_wif(
         'cNn8itYxAng4xR4eMtrPsrPpDpTdVNuw7Jb6kfhFYZ8DLSZBCg37')
     script = Script([
         'OP_1',
         p2wpkh_key.get_public_key().to_hex(), 'OP_1', 'OP_CHECKMULTISIG'
     ])
     p2wsh_addr = P2wshAddress.from_script(script)
     p2sh_p2wsh_addr = P2shAddress.from_script(
         p2wsh_addr.to_script_pub_key())
     self.assertTrue(p2sh_p2wsh_addr.to_string(),
                     self.correct_p2sh_p2wsh_address)
Example #9
0
    def get_redeem_script_from_conf(cls, pub_key_obj):
        """
        Great when method name are self explanatory
        """
        csv_args = cls.get_relative_time_seconds_blocks()
        seq_number_in_hex = Sequence(TYPE_RELATIVE_TIMELOCK, csv_args)

        print("seconds to wait: " +
              str(csv_args[0]) + ", blocks to wait: " + str(csv_args[1]))
        print('sequence number in little endian format: ' + seq_number_in_hex)

        redeem_script = cls.get_redeem_script(seq_number_in_hex, pub_key_obj)

        to_P2SH_addr = P2shAddress.from_script(redeem_script)
        print('Redeem script generated P2SH addr: ' +
              to_P2SH_addr.to_address() + "\n")

        return redeem_script
Example #10
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())
Example #11
0
def csv_script(recreate=False):
    """ creates a P2SH address with a relative csv timelock script
    
    Attributes
    ----------
    recreate : boolean
        False (default) -> used when creating new p2sh addr (save and display)
        True -> used when spending from p2sh address (returns objects for TX)
    
    returns
    -------
    if recreate=False (default - used when creating new p2sh addres)
        returns nothing
        - writes p2sh address into data.json
        - displays p2sh address to the user
    if recreate=True (used to recreate script when spending form p2sh address)
        returns csv_script (Script Object), p2sh_addr (P2shAddress Object)
    """
    # load csv script data (pub_key_hash, timelock_period) from data.json
    data = tools.load_data_json(pub_hash=True, timelock_csv=True, 
        timelock_log=True)
    pub_key_hash = data['pub_key_hash']
    timelock_period = data['timelock_csv']
    timelock_str = data['timelock_log']

    # initiate script object
    csv_script = Script([timelock_period, 'OP_CHECKSEQUENCEVERIFY', 'OP_DROP',
        'OP_DUP', 'OP_HASH160', pub_key_hash, 'OP_EQUALVERIFY', 'OP_CHECKSIG'])
    # get P2SH address of csv_script
    p2sh_addr = P2shAddress.from_script(csv_script).to_address()
    csv_hash = csv_script.to_hex()

    if recreate:  # used when spending from p2sh
       return csv_script, p2sh_addr
    
    # used when creating initial p2sh
    # - writes p2sh address into data.json
    # - displays p2sh address (+details) to the user via terminal
    tools.update_data_json(outputs={'p2sh_address': p2sh_addr, 'csv_hash': csv_hash})
    print('\nNew p2sh address with CSV script created')
    print(' -> timelock period for:', timelock_str, 'blocks')
    print(' -> script_hash:', csv_hash)
    print(' -> p2sh_addr:', p2sh_addr, '\n')
Example #12
0
    def get_redeem_script_from_conf(cls, pub_key_obj):
        """
        Return a P2SH address for a redemption scription encaptulating 
            CHECKSEQUENCEVERIFY
                +
            P2PKH script with a paying to public address possibly locked up to
            x blocks read from program.conf [relative_blocks_to_wait] 
        """
        blocks_wait = Common.get_conf_wait_blocks()

        seq_number_in_hex = Sequence(TYPE_RELATIVE_TIMELOCK, blocks_wait)

        redeem_script = cls.get_redeem_csv_script(seq_number_in_hex,
                                                  pub_key_obj)

        to_P2SH_addr = P2shAddress.from_script(redeem_script)
        print('Redeem script generated P2SH addr: ' +
              to_P2SH_addr.to_string() + "\n")

        return redeem_script
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 as 
    # well as for an absolute amount of blocks or an absolute amount of seconds since the transaction. 
    #

    parser = argparse.ArgumentParser(
        description='Give the public key, a future time expressed either in block height or in UNIX Epoch time and '
                    'the P2SH address will be displayed') 
    parser.add_argument('pubkey', help="Add the public key.")
    parser.add_argument('-param', type=int, help="Add the number of blocks or the time expressed in seconds.")
    args = parser.parse_args()

    # set values
    key = args.pubkey
    absolute_param = args.param

    p2pkh_pk = PublicKey(key)

    # set Locktime
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, absolute_param)
    locktime = Locktime(absolute_param)

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

    # print("Public key: " + p2pkh_pk.to_hex(compressed=True))
    # print("P2PKH Address: " + p2pkh_addr.to_string())

    # 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("The P2SH address is : " + addr.to_string())
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())
Example #15
0
def create_p2sh(proxy, block_height=10, address_pubk=None):
    """
    Creates a P2SH address with an absolute block locktime.

        :param proxy: JSON RPC proxy for connecting to the network.
        :param block_height: Block height the lock is valid for. Default value is 10.
        :param address_pubk: Public key of the address locking the funds. If None, a new address will be created.
    """

    # if a public key is not specified, create a new address and display its keys for future use
    if not address_pubk:
        print('Public key not provided. Created a new address.')
        address = proxy.getnewaddress()
        print('Address:', address)
        address_privk = proxy.dumpprivkey(address)
        print('Private key:', address_privk)
        address_pubk = proxy.getaddressinfo(address)['pubkey']
        print('Public key:', address_pubk)
    # create the public key object
    p2pkh_pk = PublicKey(address_pubk)

    # create sequence for the redeem script
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, block_height)
    # create the redeem script
    redeem_script = Script([
        seq.for_script(), 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP',
        'OP_HASH160',
        p2pkh_pk.to_hash160(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'
    ])

    # create the P2SH address from the redeem script
    p2sh_addr = P2shAddress.from_script(redeem_script)
    # insert the P2SH address into the wallet
    proxy.importaddress(p2sh_addr.to_string())

    # display the P2SH address
    print('Created P2SH address:', p2sh_addr.to_string())
Example #16
0
def get_priv_key(address):
    # read master secret from hsm_secret
    hsm_secret = open(expanduser('~/.lightning/bitcoin/hsm_secret'),
                      'rb').read()
    # derive the bip32_seed
    salt = bytes([0]) or b'\x00'
    bip32_seed = Hkdf(salt, hsm_secret,
                      hash=hashlib.sha256).expand(b'bip32 seed')
    master = network.keys.bip32_seed(bip32_seed)
    index = 0
    while True:
        # derive an index
        subkey = master.subkey_for_path('0/0/' + str(index))
        setup('mainnet')
        # create segwit address
        segwit = PrivateKey.from_wif(
            subkey.wif()).get_public_key().get_segwit_address()
        # wrap in P2SH address
        wrapped_p2sh = P2shAddress.from_script(segwit.to_script_pub_key())
        if wrapped_p2sh.to_string() == address:
            break
        index += 1
    plugin.log('found the address at index {}'.format(index), level="info")
    return master.subkey_for_path('0/0/' + str(index))
Example #17
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())
#  Redeem script is a special type of script.
#  - The hash of the redeem script used to lock the outputs of a transaction.
#  - Then the redeem script used to unlock these UTXOs.

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

# Script code explanation:
# - add on top of the stack the relative_blocks number (10) and the check if this sequence have been verified, ie the locktime have been pass. (T/F)
# - drop the top element of the stack
# - duplicate the and get its hash
# - also get the address hash and check if are equal
# - then check if the signature is valid

# 5. What is the P2SH address for that script? (Get the hash from the redeem_script)
help(P2shAddress)
p2sh_addr = P2shAddress.from_script(redeem_script)
print(p2sh_addr.to_string())


# 6. Send some bitcoin to that P2SH address.

# / Important Notes /
# Until this point no interaction with bitcoin network have been made!
# At this time I have to start a regtest node and then I have to proceed with bitcoin transfer,
# either using cli (bitcoin-cli), either programmatically through python.

# Also note, that I need to already have an address and sufficient funds in order to send btc
# to this address or else I would get an error.

# To create a new address and get enough btc, I can execute the following commands:
# $ bitcoin-cli getnewaddress "temp"
#
#  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
#

# support multiple unknown funding transactions

utxos = {}
funds = Decimal(0)
txids = proxy.listreceivedbyaddress( 0, True, True, from_p2sh.to_string() )[0]['txids']

for txid in txids:
	tx = proxy.gettransaction( txid )
Example #20
0
 def test_p2shaddress_to_script_pub_key(self):
     script = Script([self.pub.to_hex(), 'OP_CHECKSIG'])
     fromScript = Script.to_p2sh_script_pub_key(script).to_hex()
     addr = P2shAddress.from_script(script)
     fromP2shAddress = addr.to_script_pub_key().to_hex()
     self.assertTrue(fromScript, fromP2shAddress)
Example #21
0
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 as
    # well as for an absolute amount of blocks or an absolute amount of seconds since the transaction.
    #

    parser = argparse.ArgumentParser(
        description=
        'Give the private key, a future time expressed either in block height or in UNIX Epoch time and '
        'the P2SH address to send the funds')
    parser.add_argument('key', help="Add the private key.")
    parser.add_argument(
        '-param',
        type=int,
        help="Add the number of blocks or the time expressed in seconds.")
    parser.add_argument('-to_address',
                        type=str,
                        help="Add the adress that will sent/spend")
    args = parser.parse_args()

    # set values
    key = args.key
    absolute_param = args.param
    send_address = args.to_address

    # set Locktime
    seq = Sequence(TYPE_ABSOLUTE_TIMELOCK, absolute_param)
    locktime = Locktime(absolute_param)

    # set proxy
    username = "******"
    password = "******"
    proxy = NodeProxy(username, password).get_proxy()

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

    p2pkh_pk = p2pkh_sk.get_public_key()

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

    # print("Private key: " + p2pkh_sk. to_wif(compressed=True))
    # print("Public key: " + p2pkh_pk.to_hex(compressed=True))
    # print("P2PKH Address: " + p2pkh_addr.to_string())

    # 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'
    ])

    # accept a P2SH address to get the funds from
    addr = P2shAddress.from_script(redeem_script)
    print("The P2SH address to get the funds from is : " + addr.to_string())

    # check if the P2SH address has any UTXOs to get funds from

    proxy.importaddress(addr.to_string(), "P2SH to get the funds from")
    minconf = 0
    maxconf = 99999999
    my_list = proxy.listunspent(minconf, maxconf, [addr.to_string()])

    # Gather all funds that the P2SH address received to send to the P2PKH address provided

    txin_list = []
    btc_to_send = 0
    for i in my_list:
        txin = TxInput(i['txid'], i['vout'], sequence=seq.for_input_sequence())
        txin_list.append(txin)
        btc_to_send = btc_to_send + i['amount']

    if btc_to_send == 0:
        print("No btc found to send")
        quit()

    # accept a P2PKH address to send the funds to
    to_addr = P2pkhAddress(send_address)
    print("The P2PKH address to send the funds to is : " + to_addr.to_string())

    # calculate the appropriate fees with respect to the size of the transaction
    response = requests.get("https://mempool.space/api/v1/fees/recommended")
    fee_per_byte = response.json()['fastestFee']
    print("Fastest fee per byte is : %d " % fee_per_byte)

    # calculate transaction size as described at
    # https://bitcoin.stackexchange.com/questions/1195/how-to-calculate-transaction-size-before-sending-legacy-non-segwit-p2pkh-p2sh
    tx_size = len(my_list) * 180 + 34 + 10 + len(my_list)
    total_fees = tx_size * fee_per_byte / (1024 * 10**8)
    print('Total fees are : ', total_fees)

    # Calculate the final amount
    amount = btc_to_send - total_fees
    # print(amount)

    # Create transaction output
    txout = TxOutput(to_satoshis(amount), to_addr.to_script_pub_key())

    # Create transaction after the inputs and the outputs
    tx = Transaction(txin_list, [txout], locktime.for_transaction())

    # For each transaction - when dealing with multiple inputs, you will need to sign all of them
    for i, txin in enumerate(my_list):
        sig = p2pkh_sk.sign_input(tx, i, 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.to_hex(),
             redeem_script.to_hex()])

    # display the raw signed transaction, ready to be broadcasted
    signed_tx = tx.serialize()
    print("\nRaw signed transaction:\n" + signed_tx)

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

    # display the transaction id
    print("\nTxId:", tx.get_txid())

    # verify that the transaction is valid and will be accepted by the Bitcoin nodes
    # if the transaction is valid, send it to the blockchain

    is_valid = proxy.testmempoolaccept([signed_tx])
    # print(is_valid)
    if is_valid[0]['allowed']:
        print("Transaction is valid!")
        print("Sending transaction to blockchain..")
        proxy.sendrawtransaction(signed_tx)
    else:
        print("Transaction not valid")
        quit()
Example #22
0
pubkey = privkey.get_public_key()

#
# 2) accept a future time expressed either in block height or in UNIX Epoch time
#

blockheight = proxy.getblockcount() + 1
print("future time in absolute block height: " + str(blockheight))

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

# get hash of address
hash = address.to_hash160()

# create redeem script
script = Script([
    blockheight, 'OP_CHECKLOCKTIMEVERIFY', 'OP_DROP', 'OP_DUP', 'OP_HASH160',
    hash, 'OP_EQUALVERIFY', 'OP_CHECKSIG'
])
print("redeem script: " + str(script.get_script()))

# get P2SH address
P2SHaddress = P2shAddress.from_script(script)

#
# 3) display the P2SH address
#

print("p2sh address: " + P2SHaddress.to_string())
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 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'])

    #TESTE_SUZANA
    addressObj = P2shAddress.from_script(redeem_script)
    print("addressObj=" + addressObj.to_address())
    #TESTE_SUZANA

    # you can initially spend a specific UTXO that you know (e.g. with the txid after you send some funds to the address).  Then if everything works you can use the address to find all tx in that address and spend them. Make sure the timelock works and that you can spend the funds as expected.

    # The 2nd program should display the raw signed transaction that is to be sent to a bitcoin node plus _send_ the transaction to a node. The last part is not possible with the bitcoin-utils library since I have not impl. a node proxy yet. So you have to use another lib or finish with the cli commands (commented out of course) that I have to run in order to send the raw tx to a bitcoin node.
    # The P2SH addr could be recalculated in 2nd program since we have the redeem script! Providing the P2SH addr saves you from this small calculation and 'connects' the 2 programs :-)

    # Re fees, I would rather you calculate the 'appropriate' fee and explain in comments how/why you did it this way. Ideally, you would consult an online service to get an estimate of the appropriate fee. This is minor for assignment purposes but major for production systems.

    #https://bitcoin.stackexchange.com/questions/83650/how-does-nsequence-check-sequence-verify-work
    #The 2nd program requires a private key as well... that is what unlock the funds.

    ##### NAO PRECISA PARA O ASSIGNMENT DAQUI EM DIANTE #######

    # 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')

    #SUZANA ---- ASSINA COM P2SH do SCRIPT
    txout = TxOutput(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 test_p2sh_creation(self):
     script = Script([self.pub.to_hex(), 'OP_CHECKSIG'])
     addr = P2shAddress.from_script(script)
     self.assertTrue(addr.to_string(), self.p2sh_address)
Example #25
0
def generate():
    # Tells the library what network we are using
    setup()

    if not mnemonic_phrase:
        # Generate mnemonic from random 192-bit entropy
        entropy_bytes = Bip39EntropyGenerator(
            Bip39EntropyBitLen.BIT_LEN_192).Generate()
        mnemonic = Bip39MnemonicGenerator.FromEntropy(entropy_bytes)
        print("Generated random mnemonic:\n" + mnemonic)
    else:
        print("Using included mnemonic.")
        mnemonic = mnemonic_phrase

    # Get seed bytes from mnemonic
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
    bip44_mst = Bip44.FromSeed(
        seed_bytes, Bip44Coins.BITCOIN)  # Could add in multi currency support

    # Derive account 0 for Bitcoin: m/44'/0'/0'
    bip44_acc = bip44_mst.Purpose() \
                        .Coin()    \
                        .Account(0)

    # Derive the external chain: m/44'/0'/0'/0
    bip44_change = bip44_acc.Change(Bip44Changes.CHAIN_EXT)

    with open(output_dest, 'w') as output_file:  # Open the output file
        output_file.write("address, public_key" +
                          (", private_key" if privates else "") + "\n")
        # Go through each address
        for i in range(number):
            bip44_addr = bip44_change.AddressIndex(i)

            # create segwit address
            addr3 = PrivateKey.from_wif(bip44_addr.PrivateKey().ToWif(
            )).get_public_key().get_segwit_address()
            # wrap in P2SH address
            addr4 = P2shAddress.from_script(addr3.to_script_pub_key())

            if addr4.to_string() == compare:
                print("Found it!")
                print("Path: m/44'/0'/0'/0/" + str(i))
                break
            #print("P2SH(P2WPKH):", addr4.to_string())
            if (i % int(number / 10)) == 0:
                print('Finished {}'.format(i))

            out = "{0}, {1}".format(addr4.to_string(),
                                    bip44_addr.PublicKey().ToExtended()
                                    )  # Public addresses not including private
            if (privates):  # Include the private keys
                out = "{0}, {1}, {2}".format(
                    addr4.to_string(),
                    bip44_addr.PublicKey().RawCompressed().ToHex(),
                    bip44_addr.PrivateKey().ToWif())
                #bip44_addr.PublicKey().ToAddress() # This is the regular address (not P2SH(P2WPKH))

            # Print extended keys and address
            if (verbose):
                print(out)

            output_file.write(out + "\n")
Example #26
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}')
Example #27
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 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'])

    #TESTE_SUZANA
    addressObj = P2shAddress.from_script(redeem_script)
    print("addressObj=" + addressObj.to_address())
    #TESTE_SUZANA

    # 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')

    #SUZANA ---- ASSINA COM P2SH do SCRIPT
    txout = TxOutput(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())