def make_bare_tx(candidate, change_address, rs_asm, version=1): # <Tx> components spendables = [] ins = [] outs = [] # estimate the final (signed) bytesize per input based on the redeemscript redeem_script = tools.compile(rs_asm) in_size = estimate_input_size(redeem_script) # initialize size and amount counters in_amount = Decimal(0) est_size = TX_COMPONENTS.version + TX_COMPONENTS.out_count + TX_COMPONENTS.in_count # add output size est_size += OUTSIZE * 2 # iterate over unspents for utxo in candidate.utxos: value = Decimal(utxo.amount) * COIN in_amount += value script = h2b(utxo.script) # for now: test if the in_script we figured we would need, actually matches the in script :D # reverse that tx hash prevtx = h2b_rev(utxo.hash) # output index outnum = utxo.outpoint # create "spendable" spdbl = Spendable(value, script, prevtx, outnum) spendables.append(spdbl) # also create this as input as_input = spdbl.tx_in() as_input.sigs = [] ins.append(as_input) # add the estimated size per input est_size += in_size # calc fee and out amount fee = (Decimal(math.ceil(est_size / 1000)) * COIN * NETWORK_FEE) + FEE_MARGIN change_amount = Decimal( math.floor(in_amount - (candidate.amount * COIN) - fee)) # create outputs outs.append( TxOut(int(candidate.amount * COIN), make_payto(candidate.address))) outs.append(TxOut(int(change_amount), make_payto_script(change_address))) # create bare tx without sigs tx = Tx(version, ins, outs, 0, spendables) return tx
from pycoin.tx import Tx, tx_utils, Spendable, pay_to from pycoin import convention amount = convention.btc_to_satoshi(first_nondust['amount']) dustbtc = convention.btc_to_satoshi(DUST) feebtc = convention.btc_to_satoshi(FEE) unspent = Spendable( amount, standard_tx_out_script(first_address), \ serialize.h2b_rev(first_nondust['tx']), first_nondust['n'] ) txout = TxOut( dustbtc, standard_tx_out_script(bob_notif.address()) ) change = TxOut( amount - (dustbtc + feebtc), standard_tx_out_script(change_addresses.pop()) ) op_return_script = pay_to.ScriptNulldata(alice_masked_pcode_nosuffix) op_return_txout = TxOut(0, op_return_script.script()) notif_tx = Tx( 1, [unspent.tx_in()], [txout, change, op_return_txout], unspents=[unspent] ) tx_utils.sign_tx( notif_tx, [first_node.wif()] ) print "Signed Notification TX as hex:\n", notif_tx.as_hex() data = urlencode(dict( hex=notif_tx.as_hex() )) response = json.load( urlopen(url="http://tbtc.blockr.io/api/v1/tx/decode", data=data) ) print "Decoded:\n", pretty_json(response), '\n' alice_notif_exp = alice_notif.secret_exponent() bob_pcode_nodes = get_nodes(bob_wallet, GAP_LIMIT, pcode=True) bob_ephem_key = None for bob_pcode_node in bob_pcode_nodes.values(): pcode_pp = bob_pcode_node.public_pair() pcode_point = ellipticcurve.Point(curve, pcode_pp[0], pcode_pp[1])
def make_bare_tx(network, from_address, to_address, redeem_script, version=1): # <Tx> components spendables = [] ins = [] outs = [] # estimate the final (signed) bytesize per input based on the redeemscript in_size = estimate_input_size(redeem_script) # initialize size and amount counters in_amount = Decimal(0) est_size = TX_COMPONENTS.version + TX_COMPONENTS.out_count + TX_COMPONENTS.in_count # add output size (we"ll only have 1) est_size += TX_COMPONENTS.out_scriptlen + TX_COMPONENTS.out_scriptsize + TX_COMPONENTS.out_scriptlen unspent_response = sochain_get_unspents(network, from_address) unspents = unspent_response.get("txs", []) # iterate over unspents for tx in unspents: value = Decimal(tx.get("value")) * Decimal(1e8) in_amount += value script = h2b(tx.get("script_hex")) # for now: test if the in_script we figured we would need, actually matches the in script :D # reverse that tx hash txhex = tx.get("txid") prevtx = h2b_rev(txhex) # output index outnum = tx.get("output_no") # create "spendable" spdbl = Spendable(value, script, prevtx, outnum) spendables.append(spdbl) # also create this as input as_input = spdbl.tx_in() as_input.sigs = [] ins.append(as_input) # add the estimated size per input est_size += in_size # calc fee and out amount fee = Decimal(math.ceil( est_size / 1000.0)) * Decimal(1e8) * NETWORK_FEES.get(network) out_amount = in_amount - fee if (is_p2sh(to_address)): outscript = make_payto_script(to_address) else: outscript = make_payto_address(to_address) # create output outs.append(TxOut(out_amount, outscript)) # create bare tx without sigs tx = Tx(version, ins, outs, 0, spendables) return tx