Beispiel #1
0
    def createFundingTx(self, funder_amount, funder_pubkey, fundee_pubkey, change_address=None):
        if not self.input_utxo_specified:
            sys.exit("Did not specify source of funds.")
        msig_addr, funding_redeem_script = createMultiSigAddress(funder_pubkey, fundee_pubkey, verbose=self.verbose)
        # create tx input
        tx_ins = [tb.make_legacy_input(outpoint=self.outpoint, stack_script=b"", redeem_script=self.scriptsig,
                                       sequence=0xFFFFFFFF)]
        if self.verbose: print("Input: ", tx_ins)
        tx_outs = [simple.output(address=msig_addr, value=funder_amount)]
        if self.verbose: print("Output: ", tx_outs)

        need_change_output = True if self.utxo_amount > funder_amount else False
        if need_change_output:
            change_output_amount = self.utxo_amount - funder_amount - self.network_fee
            tx_outs += [simple.output(address=self.change_address, value=change_output_amount)]

        if BITCOIN in self.network:
            unsigned_tx = simple.unsigned_legacy_tx(tx_ins, tx_outs)
        elif ZCASH in self.network:
            unsigned_tx = simple.unsigned_legacy_tx(tx_ins, tx_outs)

        script_code1 = b'\x19' + addresses.to_output_script(msig_addr)

        # TODO: computing sighash_all => verify that this is done correctly
        sighash = unsigned_tx.sighash_all(index=0, script=script_code1,
                                          prevout_value=utils.i2le_padded(funder_amount, 8))
        # NOTE: for dual-funded channel, funder_bal = funder_amount + fundee_amount
        funding_tx = {'funding_tx_id': unsigned_tx.tx_id.hex(), 'funding_bal': funder_amount,
                      'funding_address': str(msig_addr), 'funding_witness_script': funding_redeem_script}

        return funding_tx, unsigned_tx.hex()
Beispiel #2
0
def createCommitmentTransaction(funding_tx, cust_pubkey, rev_pubkey, merch_pubkey, cust_amount, merch_amount):
    funding_tx_id = funding_tx.get("funding_tx_id")
    funding_bal = funding_tx.get("funding_bal")
    funding_addr = funding_tx.get('funding_address')
    print("<= Create Commitment Transaction =>")
    # compute the funding tx outpoint
    funding_tx_outpoint = simple.outpoint(funding_tx_id, 0)
    # get the funding tx outpoint as the transaction input
    tx_ins = [simple.unsigned_input(funding_tx_outpoint)]
    # the commitment tx has two outputs: (1) customer and (2) merchant
    cust_redeem_script = ln_redeem_script.format(rev_pubkey=rev_pubkey,
                                                 merch_pubkey=merch_pubkey,
                                                 cust_pubkey=cust_pubkey,
                                                 timeout=uint32_to_bytes(1440)) # 1 day - timeout

    if debug: print("Cust redeem script: ", cust_redeem_script)

    cust_address = addresses.make_p2sh_address(cust_redeem_script)
    tx_out_1 = simple.output(cust_amount, cust_address)  # customer

    encoded_merch_pubkey = bytes.fromhex(merch_pubkey)
    merch_address = addresses.make_p2pkh_address(encoded_merch_pubkey)
    tx_out_2 = simple.output(merch_amount, merch_address)  # merchant

    unsigned_tx = simple.unsigned_legacy_tx(tx_ins, [tx_out_1, tx_out_2])

    # script code of prevout being spent (from funding tx)
    prevout_script_code = b'\x19' + addresses.to_output_script(funding_addr)
    sighash = unsigned_tx.sighash_all(index=0, script_code=prevout_script_code, prevout_value=utils.i2le_padded(funding_bal, 8))
    print("sighash hex: ", sighash.hex())

    return unsigned_tx.hex()
Beispiel #3
0
def output(value: int, address: str) -> tx.TxOut:
    '''
    int, str -> TxOut
    accepts base58 or bech32 addresses
    '''
    script = addr.to_output_script(address)
    value_bytes = utils.i2le_padded(value, 8)
    return tb._make_output(value_bytes, script)
def address_to_electrum_scripthash(address: str) -> str:
    '''Electrum is lame and uses backwards sha hashes of output scripts

    Args:
        address (str): a valid bitcoin address
    Returns:
        (str): the electrum-formatted scripthash in hex
    '''
    try:
        e = addr.to_output_script(address)
    except ValueError:
        raise
    scripthash = rutils.sha256(e)

    return scripthash[::-1].hex()
Beispiel #5
0
def createSingleFundingTransaction(network, funder_outpoint, funder_amount, funder_pubkey, fundee_pubkey):
    """network -> bitcoin or zcash
       script -> { stack_script :
                 , redeem_script : if spending a P2SH, then this should be set }
       funder_outpoint -> specific tx output consisting of (txid, output-index)
       funder_amount -> amount from unspent tx
       funder_pubkey -> pub key for the funder
       fundee_pubkey -> pub key of the fundee (or counterparty)
    """
    # create the multi-signature address
    # fee = 10000

    msig_addr, funding_redeem_script = createMultiSigAddress(funder_pubkey, fundee_pubkey)
    print("Output address: ", msig_addr)
    print("Redeem script: ", funding_redeem_script) # for closing
    # create tx input
    _redeem_script = bytes.fromhex("48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184")
    #tx_ins = [simple.unsigned_input(outpoint=funder_outpoint, redeem_script=_redeem_script)]
    tx_ins = [tb.make_legacy_input(outpoint=funder_outpoint, stack_script=b"", redeem_script=_redeem_script, sequence=0xFFFFFFFF)]
    print("Input: ", tx_ins)
    tx_outs = [simple.output(address=msig_addr, value=funder_amount)]
    print("Output: ", tx_outs)

    if network == "bitcoin":
        unsigned_tx = simple.unsigned_legacy_tx(tx_ins, tx_outs)
    elif network == "zcash":
        unsigned_tx = simple.unsigned_legacy_tx(tx_ins, tx_outs)

    script_code1 = b'\x19' + addresses.to_output_script(msig_addr)

    # TODO: computing sighash_all => verify that this is done correctly
    sighash = unsigned_tx.sighash_all(index=0, script=script_code1, prevout_value=utils.i2le_padded(funder_amount, 8))
    # TODO: add signing of the sighash
    print("sighash hex: ", sighash.hex())

    # NOTE: for dual-funded channel, funder_bal = funder_amount + fundee_amount
    funding_tx = {'funding_tx_id': unsigned_tx.tx_id.hex(), 'funding_bal': funder_amount, 'funding_addr': str(msig_addr)}

    return funding_tx, unsigned_tx.hex(), funding_redeem_script
Beispiel #6
0
sender_output = simple.output(value=sender_value - fee, address=receiver_addr)

# OP_RETURN output
riemann_note = 'made with ❤ by riemann'.encode('utf-8')
op_return_output = tx_builder.make_op_return_output(riemann_note)

unsigned_tx = simple.unsigned_legacy_tx(
    tx_ins=[sender_input],
    tx_outs=[sender_output, op_return_output],
    version=version,
    lock_time=locktime)

sighash_all = 0x01
sighash = unsigned_tx.sighash_all(
    index=0,
    script=addr.to_output_script(sender_addr))

# Using instance of CKey from python-bitcoinlib to sign:
# sig = sender.sign(sighash) + bytes([sighash_all])
# sig = sig.hex()
sig = '30450221009e8c7f85d6491169df139f25d26633efe48e98738331a37a1694d655dccebdbd02201a6444cfb364e91279f8c9a8b09cdbdeb4bf6cc0f00f53b9356f852c3b3151dc01'    # noqa: E501

signed_input = simple.p2pkh_input(
    outpoint=sender_outpoint,
    sig=sig,
    pubkey=sender_pubkey,
    sequence=sequence)

tx_signed = unsigned_tx.copy(tx_ins=[signed_input])
print('tx_signed')
print(tx_signed.hex())
Beispiel #7
0
tx_out = simple.output(input_value - tx_fee, receiving_address)

# Completely optional memo
tx_return_output = tb.make_op_return_output(
    'made with ❤ by riemann'.encode('utf-8'))

# Generate Unsigned Tx

# Create unsigned transaction
tx = simple.unsigned_tx([tx_in], [tx_out, tx_return_output])

# Generate Signed Tx
# https://blockchain.info/tx/1e7acd3d4715054c8fb0fdea25c5c704986006d2c6f30b0782e9b36a7ee072ef

# With the p2pkh output script from address, create the the sighash to be signed
sighash = tx.sighash_all(index=0, script=addresses.to_output_script(address))

# Declare SIGHASH_ALL type
SIGHASH_ALL = 0x01

# Sign the tx with private key
# Assumes private_key is of type class bitcoin.wallet.CKey from python-bitcoinlib
sig = private_key.sign(sighash) + bytes([SIGHASH_ALL])

# Recreate tx input with script signature
tx_signed_input = simple.p2pkh_input(outpoint=tx_outpoint,
                                     sig=sig.hex(),
                                     pubkey=public_key,
                                     sequence=0xFFFFFFFE)

# Recreate tx with the signed tx input
Beispiel #8
0
import riemann
from riemann import simple, utils
from riemann.encoding import addresses as addr
from riemann.script import serialization as ser

riemann.select_network('zcash_sapling_main')

prevout_addr_1 = 't1S3kN4zusjHtDEwfdaCMgk132bqo9DaYW4'
prevout_addr_2 = 't1VQCUYzApF5eWf4UFAGdWwaFEpBfG2su1A'

# This is the script code of the prevout being spent
# We length prefix it
# Needed for sighash later
script_code_1 = b'\x19' + addr.to_output_script(prevout_addr_1)
script_code_2 = b'\x19' + addr.to_output_script(prevout_addr_2)

# Make inputs for our tx
# We're spending the 1st output of a45216...
#            And the 0th output of ae9ee9...
tx_in_1 = simple.unsigned_input(
    simple.outpoint(
        'a45216a60855f053d63eb78a91429f85c6218541e876be95b17f8743635a0d3e',
        1))  # noqa: E501
tx_in_2 = simple.unsigned_input(
    simple.outpoint(
        'ae9ee9ddeae0f0de07837f25b638ac8a723104753008d9c672e57b1d58e1c863',
        0))  # noqa: E501

# Make an output for our tx.
# Our prevouts are worth 0.01845001 and 0.00002 ZEC
# We want to pay 0.0001 ZEC