Ejemplo n.º 1
0
 def sign(self, private_keys):
     '''Signs the transaction. 
     prvkeys (list of PrivateKey items)'''
     for i, txin in enumerate(self._inputs):
         prvkeys = private_keys[i]
         if isinstance(prvkeys, PrivateKey):
             assert txin['nsigs'] == 1
             prvkeys = [prvkeys]
         elif isinstance(prvkeys, list):
             assert len(prvkeys) == txin['nsigs']
             # Sorting keys
             sorted_prvkeys = []
             for prvkey in prvkeys:
                 pubkey = PublicKey.from_prvkey(prvkey)
                 assert (pubkey in txin['pubkeys'])
                 sorted_prvkeys += [(txin['pubkeys'].index(pubkey), prvkey)]
             sorted_prvkeys.sort(key=lambda x: x[0])
             prvkeys = [k[1] for k in sorted_prvkeys]
         else:
             raise TransactionError('wrong type for private keys')
         if txin['type'] in ('p2pkh', 'p2sh'):
             prehash = dsha256(self.serialize_legacy_preimage(txin))
         elif txin['type'] in ('p2wpkh', 'p2wsh', 'p2sh-p2wpkh',
                               'p2sh-p2wsh'):
             prehash = dsha256(self.serialize_preimage(txin))
         hashtype = bytes([self.hashtype & 0xff]).hex()
         self._inputs[i]['signatures'] = [
             prvkey.sign(prehash, alg="ecdsa", strtype=True) + hashtype
             for prvkey in prvkeys
         ]
Ejemplo n.º 2
0
def construct_simple_transaction(wifkey, output_addr, locktime, prevout_txid,
                                 prevout_index, prevout_value):
    ''' Construct a Bitcoin Cash one-input / one-output transaction.
    wifkey (str) : private key (Wallet Import Format)
    output_addr (str) : recipient address (legacy or cash format)
    prevout_txid (str) : previous output transaction id
    prevout_index (int) : index of the output in the previous transaction
    prevout_value (int) : previous output value in satoshis'''

    # Private key
    prvkey = PrivateKey.from_wif(wifkey)

    # Public key and address (Public Key Hash)
    pubkey = PublicKey.from_prvkey(prvkey)
    input_address = Address.from_pubkey(pubkey)

    # Output address
    output_address = Address.from_string(output_addr)

    # Creation of the transaction
    txin = {}
    txin['address'] = input_address
    txin['txid'] = prevout_txid
    txin['index'] = prevout_index
    txin['value'] = prevout_value
    txin['sequence'] = Constants.SEQUENCE_NUMBER
    txin['pubkeys'] = [pubkey]
    txin['nsigs'] = 1

    tx = Transaction.from_inputs([txin], locktime)

    txsize = (tx.estimate_size() + 32 + 2 *
              (output_address.kind == Constants.CASH_P2PKH))
    fee = Constants.FEE_RATE * txsize
    txout = {}
    txout['address'] = output_address
    txout['value'] = prevout_value - fee
    tx.add_output(txout)

    prvkeys = [prvkey]
    tx.sign(prvkeys)
    rawtx = tx.serialize()

    fee = tx.get_fee()
    print("Input address", input_address.to_cash())
    print("Output address", output_address.to_cash())
    print("Amount sent (sat)", prevout_value - fee)
    print("Fee (sat)", fee)
    print()

    if tx.iscomplete:
        return rawtx, tx.txid(), fee
    else:
        return None
Ejemplo n.º 3
0
 def from_wifkey(self, wifkey):
     keypair = (wifkey, PublicKey.from_prvkey(wifkey,
                                              True).to_ser(strtype=True))
     return self(keypair)
Ejemplo n.º 4
0
    print()
    ''' My addresses '''
    print("ADDRESSES")
    print()

    # Claim private key
    #  mainnet: Kz2GqdB5f5JWEYn1znS8bk2aUqg4J8WXycs6uEnwCUobRsib6N2R
    #  testnet: cQPGJYAw68zmPzFHPCFFy4Xe74yTxacE3f1a1fFShbTbgckLz6dn
    # Claim address
    #  testnet: bchtest:qrtppnj5yk7ur6u2t0tagesvlyhycddgfq630lqqkh
    #           n12q2oecWxTmcaMmMShnqvtC4FL59LCaBE (legacy)
    claim_secret = 0x53a0e9e7894f4f77fba3cc62d9dcb82d61d085c34f7fa2a712e26d62ae4f42a3
    claim_prvkey = PrivateKey(claim_secret)
    print("Claim address")
    print(" privkey", claim_prvkey)
    claim_pubkey = PublicKey.from_prvkey(claim_prvkey)
    claim_address = Address.from_pubkey(claim_pubkey)
    print(" address (cash)", claim_address.to_full_cash())
    print(" address (legacy)", claim_address.to_legacy())
    print(" address (hex)", claim_address.h.hex())
    print()

    # Refund private key
    #  mainnet: L1MK6tz8mD9WRnr9RqsbDg9BYktUkUwd6ZWQRHgdHU1m6VbUPkdz
    #  testnet: cRiJZoyzCGqmbEKQpFgiazeFAzBtQw3KAbesXi98nafmMEgYAMDg
    # Refund address
    #  testnet: bchtest:qrref365h428zh4zvwpnnfzlp2tq4w9t8qnh0pzm5q
    #           myiEzYohqurvpghWrCaaafz5orGQinfEC9
    refund_secret = 0x7b42a6f4f75cb14d701965b9da9245940837b4b3d8073bd2cf228605c1f0fe40
    refund_prvkey = PrivateKey(refund_secret)
    print("Refund address")
Ejemplo n.º 5
0
    wifkey1 = "L239DGsGnzuvsDQcNDrkBk5WGNhMqQRkUkFSp3bCycWwR8i7Xvod"

    wifkeys_multisig = [
        "KzwQjFQPytv5x6w2cLdF4BSweGVCPEt8b8HbcuTi8e75LRQfw94L",
        "Ky4yk7uTBZ1EDbqyVfkvoZXURpWdRCxTpCERZb4gkn67fY8kK95R",
        "Kz3Htg8mSfC997qkBxpVCdxYhEoRcFj5ikUjE96ipVAJPou7MwRD"
    ]

    ## Bitcoin multisig the hard way - https://www.soroushjp.com/2014/12/20/bitcoin-multisig-the-hard-way-understanding-raw-multisignature-bitcoin-transactions/
    #wifkeys = ["5JruagvxNLXTnkksyLMfgFgf3CagJ3Ekxu5oGxpTm5mPfTAPez3",
    #"5JX3qAwDEEaapvLXRfbXRMSiyRgRSW9WjgxeyJQWwBugbudCwsk",
    #"5JjHVMwJdjPEPQhq34WMUhzLcEd4SD7HgZktEh8WHstWcCLRceV"]

    # Sorted public keys involved in the multisig address
    pubkeys = [PublicKey.from_prvkey(wk).to_ser() for wk in wifkeys_multisig]

    # Number of signatures required to unlock the multisig address
    nsigs = 2

    redeem_script = multisig_locking_script(pubkeys, nsigs)
    p2sh_addr = Address.from_script(redeem_script)

    # Transaction 1: p2pkh -> p2sh
    prvkey1 = PrivateKey.from_wif(wifkey1)
    pubkey1 = PublicKey.from_prvkey(prvkey1)
    input_address = Address.from_pubkey(pubkey1.to_ser()).to_string()
    output_address = p2sh_addr.to_cash()

    prevout_txid = "10e7ee10ecab3d16fcba5160792733dc2eeeb7270389d304832da3c9f5d31ef5"
    prevout_index = 1
Ejemplo n.º 6
0
from constants import Constants

if __name__ == '__main__':

    import sys
    if sys.version_info < (3, 5):
        sys.exit("Error: Must be using Python 3.5 or higher")

    wifkeys_multisig = [
        "KyLxarqt64ndG3ENbLYp2922HKoasdQqd2sZS3VaQD5BF2pJLCmL",
        "KzqYDqNMVTPVeku7nwdFv3zPAQLwD2BnfEwgYYWeryyKbMDGTzwX",
        "L2wtM9x3JTvGa1YN6dpkmv4EdRsWTELJzdxsB2291KmSNe8Nof6c"
    ]

    # Sorted public keys involved in the multisig address
    pubkeys = [PublicKey.from_prvkey(wk) for wk in wifkeys_multisig]

    # Number of signatures required to unlock the multisig address
    nsigs = 2

    redeem_script = multisig_locking_script(pubkeys, nsigs)
    p2sh_addr = Address.from_script(redeem_script)

    print("multisig addr", p2sh_addr.to_cash())
    print()

    output_addr = Address.from_string(
        "qz954pyuatjtyrf654ud2k55ykr6n7yl9ql8cvc955")

    # Transaction 1
    txin = {}