def refund(self, contract): fundtx = self.find_transaction_to_address(contract.p2sh) print("Fund tx found in refund: ", fundtx) refundPubKey = self.find_refundAddr(contract) print('refundPubKey: {0}'.format(refundPubKey)) redeemScript = CScript(x(contract.redeemScript)) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, refundPubKey.to_scriptPubKey()) # Create the unsigned raw transaction. tx = CMutableTransaction([txin], [txout]) # Set nSequence and nLockTime txin.nSequence = 0 tx.nLockTime = contract.redeemblocknum sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) privkey = self.bitcoind.dumpprivkey(refundPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) # Sign without secret txin.scriptSig = CScript([sig, privkey.pub, OP_FALSE, redeemScript]) # txin.nSequence = 2185 txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey() print('Raw redeem transaction hex: {0}'.format(b2x(tx.serialize()))) res = VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,)) print("Script verified, sending raw transaction... (NOT)", res) txid = self.bitcoind.sendrawtransaction(tx) refund_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"refund_tx": refund_tx, "fund_tx": fund_tx}
def main(): ''' Our main function. ''' SelectParams('mainnet') decoded_transaction = eval(open('transaction_to_sign.txt').read()) # pylint: disable=eval-used txin_txid = lx(decoded_transaction['vin'][0]['txid']) txin_vout = 0 tx_in = CMutableTxIn(COutPoint(txin_txid, txin_vout)) tx_out = [] for idx in range(len(decoded_transaction['vout'])): satoshis = int(COIN * decoded_transaction['vout'][idx]['value']) script_pub_key = CScript(bytes.fromhex(decoded_transaction['vout'][idx]['scriptPubKey']['hex'])) tx_out.append(CMutableTxOut(satoshis, script_pub_key)) tx_to_spend = CMutableTransaction([tx_in], tx_out) priv_1 = CBitcoinSecret.from_secret_bytes(bytes.fromhex(PRIV_HEX_1)) priv_2 = CBitcoinSecret.from_secret_bytes(bytes.fromhex(PRIV_HEX_2)) txin_redeem_script = CScript(bytes.fromhex(decoded_transaction['vin'][0]['scriptSig']['hex'])) # Input 0 is fixed. sighash = SignatureHash(txin_redeem_script, tx_to_spend, 0, SIGHASH_ALL) signatures = [] for priv in [priv_1, priv_2]: signatures.append(priv.sign(sighash) + bytes([SIGHASH_ALL])) tx_in.scriptSig = CScript([CScriptOp(0x00), signatures[0], signatures[1], txin_redeem_script]) # script_pub_key Defined in cycle. VerifyScript(tx_in.scriptSig, txin_redeem_script, tx_to_spend, 0, (SCRIPT_VERIFY_P2SH,)) print(b2x(tx_to_spend.serialize()))
def make_unsigned(cls, outpoints, output_address, tx_fee=TRANSACTION_FEE, testnet=False, out_value=None): """ Build an unsigned transaction. Args: outpoints: A `list` of `dict` objects which contain a txid, vout, value, and scriptPubkey. output_address: The address to send the full value (minus the tx fee) of the inputs to. tx_fee: The Bitcoin network fee to be paid on this transaction. testnet: Should this transaction be built for testnet? out_value: used if you want to specify a specific output value otherwise the full value of the inputs (minus the tx fee) will be used. """ # build the inputs from the outpoints object SelectParams("testnet" if testnet else "mainnet") txins = [] in_value = 0 for outpoint in outpoints: in_value += outpoint["value"] txin = CMutableTxIn(COutPoint(lx(outpoint["txid"]), outpoint["vout"])) txin.scriptSig = CScript(x(outpoint["scriptPubKey"])) txins.append(txin) # build the output value = out_value if out_value is not None else (in_value - tx_fee) txout = CMutableTxOut(value, CBitcoinAddress(output_address).to_scriptPubKey()) # make the transaction tx = CMutableTransaction(txins, [txout]) return BitcoinTransaction(tx)
def redeem(proxy, redeemerGuy, contract, fundtx, secret): print('redeemPubKey', redeemerGuy['addr']) # TODO: Compare with script on blockchain? redeemScript = CScript(x(contract['redeemScript'])) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, redeemerGuy['addr'].to_scriptPubKey()) # Create the unsigned raw transaction. tx = CMutableTransaction([txin], [txout]) sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) # TODO: protect privkey better, separate signing from rawtx creation #privkey = self.bitcoind.dumpprivkey(self.redeemPubKey) sig = redeemerGuy['key'].sign(sighash) + bytes([SIGHASH_ALL]) preimage = secret.encode('utf-8') # preimage = x(secret) txin.scriptSig = CScript([sig, redeemerGuy['key'].pub, preimage, OP_TRUE, redeemScript]) # print("txin.scriptSig", b2x(txin.scriptSig)) txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey() print('Raw redeem transaction hex: ', b2x(tx.serialize())) VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,)) print("Script verified, sending raw transaction...") txid = proxy.sendrawtransaction(tx) fund_tx = str(fundtx['outpoint']) redeem_tx = b2x(lx(b2x(txid))) return {"redeem_tx": redeem_tx, "fund_tx": fund_tx}
def refund(proxy, refundGuy, contract): redeemScript = CScript(x(contract['redeemScript'])) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, refundGuy['addr'].to_scriptPubKey()) tx = CMutableTransaction([txin], [txout]) txin.nSequence = 0 tx.nLockTime = contract['redeemblocknum'] sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) sig = refundGuy['key'].sign(sighash) + bytes([SIGHASH_ALL]) txin.scriptSig = CScript([sig, refundGuy['key'].pub, OP_FALSE, redeemScript]) txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey() print('Raw redeem transaction hex: {0}'.format(b2x(tx.serialize()))) res = VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,)) print("Script verified, sending raw transaction... (NOT)", res) txid = proxy.sendrawtransaction(tx) refund_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"refund_tx": refund_tx, "fund_tx": fund_tx}
def build_crediting_tx(script_pubkey): tx = Transaction(version=1, locktime=0) txin = CMutableTxIn() txin.scriptSig = Script.from_human('0x00 0x00') tx.vin = [txin] txout = CMutableTxOut(0, script_pubkey) tx.vout = [txout] return tx
def test_json_roundtrip(self): VALUES = [ 42, 0, -42, 2100000000000000, -2100000000000000, "basic string", "\u1111Unicode", "\U00010000Wide Unicode", "\x00\n\t\r\nEscape codes", "\"'\"Quotes", "", None, b"\x00\x01\xFFBinary data", b"", CBase58Data.from_bytes(b'\x00\x01\xFF', 42), P2SHBitcoinAddress.from_bytes(b'\x00\x01\xFF'), P2PKHBitcoinAddress.from_bytes(b'\x00\x01\xFF'), CMutableTxIn(COutPoint(b'\x00' * 16 + b'\xFF' * 16, 42), CScript(b'\x00\x01\xFF'), 42), CMutableTxOut(42, CScript(b'\x00\x01\xFF')), CMutableTransaction([ CMutableTxIn(COutPoint(b'\x00' * 32, 42), CScript(b'\x00\x01\xFF'), 42), CMutableTxIn(COutPoint(b'\xFF' * 32, 42), CScript(b'\xFF\x01\x00'), 43) ], [ CMutableTxOut(42, CScript(b'\x00\x01\xFF')), CMutableTxOut(43, CScript(b'\xFF\x01\x00')) ], 42, 3), [ 1, b'\x00\x01\xFF', "List Test", ], { 'a': 1, 'key': b'\xFF\x01\x00', 1: 'Dictionary Test' }, [ { 3: [ 0, 1, 2, ], }, [ [ b'\xFFRecursion Test', ], ], ], ] for value in VALUES: self.assertEqual(from_json(to_json(value)), value)
def add_input(self, tx_input=None, input_index=None): """Add an input at input_index, or append one if input_index is None.""" if tx_input is None: tx_input = CMutableTxIn() elif tx_input.__class__ == CTxIn: tx_input = CMutableTxIn.from_txin(tx_input) if input_index is None: input_index = len(self.vin) self.beginInsertRows(QModelIndex(), input_index, input_index) self.vin.insert(input_index, tx_input) self.endInsertRows()
def redeem_contract(self, contract, secret): print("Parsing script for redeem_contract...") scriptarray = self.parse_script(contract.redeemScript) redeemblocknum = scriptarray[8] redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6])) refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13])) p2sh = contract.p2sh #checking there are funds in the address amount = self.check_funds(p2sh) if(amount == 0): print("address ", p2sh, " not funded") quit() fundtx = self.find_transaction_to_address(p2sh) amount = fundtx['amount'] / COIN # print("Found fund_tx: ", fundtx) p2sh = P2SHBitcoinAddress(p2sh) if fundtx['address'] == p2sh: print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh)) blockcount = self.bitcoind.getblockcount() print("\nCurrent blocknum at time of redeem on Zcash:", blockcount) if blockcount < int(redeemblocknum): print('redeemPubKey', redeemPubKey) zec_redeemScript = CScript(x(contract.redeemScript)) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey()) # Create the unsigned raw transaction. tx = CMutableTransaction([txin], [txout]) sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL) # TODO: protect privkey better, separate signing from rawtx creation privkey = self.bitcoind.dumpprivkey(redeemPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) preimage = secret.encode('utf-8') txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, zec_redeemScript]) # print("txin.scriptSig", b2x(txin.scriptSig)) txin_scriptPubKey = zec_redeemScript.to_p2sh_scriptPubKey() print('Raw redeem transaction hex: ', b2x(tx.serialize())) VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,)) print("Script verified, sending raw transaction...") txid = self.bitcoind.sendrawtransaction(tx) fund_tx = str(fundtx['outpoint']) redeem_tx = b2x(lx(b2x(txid))) return {"redeem_tx": redeem_tx, "fund_tx": fund_tx} else: print("nLocktime exceeded, refunding") print('refundPubKey', refundPubKey) txid = self.bitcoind.sendtoaddress(refundPubKey, fundtx['amount'] - FEE) fund_tx = str(fundtx['outpoint']) refund_tx = b2x(lx(b2x(txid))) return {"refund_tx": refund_tx, "fund_tx": fund_tx} else: print("No contract for this p2sh found in database", p2sh)
def redeem_after_timelock(contract): p2sh = contract.p2sh fundtx = find_transaction_to_address(p2sh) amount = fundtx['amount'] / COIN if (fundtx['address'].__str__() != p2sh): print("no fund transaction found to the contract p2sh address ", p2sh) quit() print("Found fundtx:", fundtx) # Parsing redeemblocknum from the redeemscript of the p2sh redeemblocknum = find_redeemblocknum(contract) blockcount = bitcoind.getblockcount() print("Current block:", blockcount, "Can redeem from block:", redeemblocknum) if (still_locked(contract)): print("too early for redeeming with timelock try again at block", redeemblocknum, "or later") return 0 print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh)) redeemPubKey = find_refundAddr(contract) print('refundPubKey', redeemPubKey) redeemScript = CScript(x(contract.redeemScript)) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey()) # Create the unsigned raw transaction. txin.nSequence = 0 tx = CMutableTransaction([txin], [txout]) tx.nLockTime = redeemblocknum sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) # TODO: figure out how to better protect privkey privkey = bitcoind.dumpprivkey(redeemPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) txin.scriptSig = CScript([sig, privkey.pub, OP_FALSE, redeemScript]) # exit() # print("txin.scriptSig", b2x(txin.scriptSig)) txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey() # print('Redeem txhex', b2x(tx.serialize())) VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH, )) print("script verified, sending raw tx") txid = bitcoind.sendrawtransaction(tx) print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid)))) return b2x(lx(b2x(txid)))
def make_unsigned(cls, outpoints, outputs, tx_fee=TRANSACTION_FEE, testnet=False, out_value=None): """ Build an unsigned transaction. Args: outpoints: A `list` of `dict` objects which contain a txid, vout, value, and scriptPubkey. outputs: If a single address the full value of the inputs (minus the tx fee) will be sent there. Otherwise it should be a `list` of `dict` objects containing address and value. tx_fee: The Bitcoin network fee to be paid on this transaction. testnet: Should this transaction be built for testnet? out_value: used if you want to specify a specific output value otherwise the full value of the inputs (minus the tx fee) will be used. """ # build the inputs from the outpoints object SelectParams("testnet" if testnet else "mainnet") txins = [] in_value = 0 for outpoint in outpoints: in_value += outpoint["value"] txin = CMutableTxIn( COutPoint(lx(outpoint["txid"]), outpoint["vout"])) txin.scriptSig = CScript(x(outpoint["scriptPubKey"])) txins.append(txin) # build the outputs txouts = [] if isinstance(outputs, list): for output in outputs: value = output["value"] address = output["address"] txouts.append( CMutableTxOut(value, CBitcoinAddress(address).to_scriptPubKey())) else: value = out_value if out_value is not None else (in_value - tx_fee) txouts.append( CMutableTxOut(value, CBitcoinAddress(outputs).to_scriptPubKey())) # make the transaction tx = CMutableTransaction(txins, txouts) return BitcoinTransaction(tx)
def create(url, mymoney, theirmoney, fees=10000): """Open a payment channel. After this method returns, a payment channel will have been established with the node identified by url, in which you can send mymoney satoshis and recieve theirmoney satoshis. Any blockchain fees involved in the setup and teardown of the channel should be collected at this time. """ bob = jsonrpcproxy.Proxy(url+'channel/') # Choose inputs and change output coins, change = select_coins(mymoney + 2 * fees) pubkey = get_pubkey() my_out_addr = g.bit.getnewaddress() # Tell Bob we want to open a channel transaction, redeem, their_out_addr = bob.open_channel( g.addr, theirmoney, mymoney, fees, coins, change, pubkey, my_out_addr) # Sign and send the anchor transaction = g.bit.signrawtransaction(transaction) assert transaction['complete'] transaction = transaction['tx'] g.bit.sendrawtransaction(transaction) # Set up the channel in the DB channel = Channel(url, CMutableTxIn(CMutableOutPoint(transaction.GetHash(), 0), AnchorScriptSig(1, b'', redeem)), CMutableTxOut(mymoney, my_out_addr), CMutableTxOut(theirmoney, their_out_addr)) # Exchange signatures for the inital commitment transaction channel.anchor.scriptSig.sig = \ bob.update_anchor(g.addr, transaction.GetHash(), channel.sig_for_them()) channel.put() # Event: channel opened CHANNEL_OPENED.send('channel', address=url)
def open_channel(address, mymoney, theirmoney, fees, their_coins, their_change, their_pubkey, their_out_addr): # pylint: disable=too-many-arguments """Open a payment channel.""" # Get inputs and change output coins, change = select_coins(mymoney + 2 * fees) # Make the anchor script anchor_output_script = anchor_script(get_pubkey(), their_pubkey) anchor_output_address = anchor_output_script.to_p2sh_scriptPubKey() # Construct the anchor utxo payment = CMutableTxOut(mymoney + theirmoney + 2 * fees, anchor_output_address) # Anchor tx transaction = CMutableTransaction( their_coins + coins, [payment, change, their_change]) # Half-sign transaction = g.bit.signrawtransaction(transaction)['tx'] # Create channel in DB channel = Channel(address, CMutableTxIn(CMutableOutPoint(transaction.GetHash(), 0), AnchorScriptSig(0, b'', anchor_output_script)), CMutableTxOut(mymoney, g.bit.getnewaddress()), CMutableTxOut(theirmoney, their_out_addr)) channel.put() # Event: channel opened CHANNEL_OPENED.send('channel', address=address) return (transaction, anchor_output_script, channel.our.scriptPubKey)
def spend_p2sh_mediator(redeemScript, txins_str, amounts, daddrs, sig, rein): txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txins_obj = [] for txin_str in txins_str.split(): txin_list = txin_str.split("-") txins_obj.append( CMutableTxIn(COutPoint(lx(txin_list[0]), int(txin_list[1])))) txouts = [] len_amounts = len(amounts) for i in range(0, len_amounts): txouts.append( CMutableTxOut( round(amounts[i], 8) * COIN, CBitcoinAddress(daddrs[i]).to_scriptPubKey())) tx = CMutableTransaction(txins_obj, txouts) seckey = CBitcoinSecret(rein.user.dkey) ntxins = len(txins_obj) sig_list = [] for s in sig.split(): sig_list.append(x(s)) sig2_str = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig2 = seckey.sign(sighash) + x("01") sig2_str += " " + b2x(sig2) txins_obj[i].scriptSig = CScript( [OP_0, sig2, sig_list[i], txin_redeemScript]) VerifyScript(txins_obj[i].scriptSig, txin_scriptPubKey, tx, i, (SCRIPT_VERIFY_P2SH, )) tx_bytes = tx.serialize() hash = sha256(sha256(tx_bytes).digest()).digest() txid = b2x(hash[::-1]) txid_causeway = broadcast_tx(b2x(tx_bytes), rein) return (txid, sig2_str[1:])
def set_tx(self, tx): """Reset the model to reflect tx.""" self.beginResetModel() self.vin = [] for i in tx.vin: self.vin.append(CMutableTxIn.from_txin(i)) self.endResetModel()
def bump_feerate(bitcoind, tx, feerate_add, prevouts_amount=None): """Bump the feerate of a CTransaction. :param bitcoind: The bitcoind RPC connection, to access the wallet. :param tx: The CTransaction which is to be bumped. :param feerate_add: How much to increase the feerate, in sat/vbyte. :param prevouts_amount: The sum of the value of all the consumed outputs. :return: (CTransaction) The modified transaction. """ # Work on a copy vin = [CMutableTxIn.from_txin(txin) for txin in tx.vin] vout = [CMutableTxOut.from_txout(txout) for txout in tx.vout] # FIXME: Add this to python-bitcoinlib wit = CTxWitness([ CTxInWitness.from_txinwitness(txinwit) for txinwit in tx.wit.vtxinwit ]) mut_tx = CMutableTransaction(vin, vout, witness=wit, nLockTime=tx.nLockTime, nVersion=tx.nVersion) fees = fees_to_add(bitcoind, mut_tx, feerate_add, prevouts_amount) if bitcoind.getbalance() * COIN > fees: return add_input(bitcoind, mut_tx, fees) raise Exception("Could not bump fees, no suitable utxo available!")
def as_tx(self): sum_in = sum(prevtx.nValue for _, prevtx, _ in self.prevouts) sig_size = sum(redeemer.spendbytes for _, _, redeemer in self.prevouts) tx_size = ( 4 + # version field 2 + # # of txins len(self.prevouts) * 41 + # txins, excluding sigs sig_size + # txins, sigs only 1 + # # of txouts 34 + # txout 4 # nLockTime field ) feerate = int(self.proxy._call('estimatefee', 1) * COIN) # satoshi's per KB if feerate <= 0: feerate = 10000 fees = int(tx_size * feerate / 1000) tx = CMutableTransaction( [CTxIn(outpoint, nSequence=0) for outpoint, _, _ in self.prevouts], [CTxOut(sum_in - fees, self.payto.to_scriptPubKey())], 0) for n, (_, _, redeemer) in enumerate(self.prevouts): redeemer.mutate_spend(tx, n) unsigned_tx = CTransaction.from_tx(tx) for n, (_, _, redeemer) in enumerate(self.prevouts): txin = CMutableTxIn.from_txin(tx.vin[n]) txin.scriptSig = redeemer.sign_spend(unsigned_tx, n) tx.vin[n] = CTxIn.from_txin(txin) print(b2x(tx.serialize()))
def as_tx(self): sum_in = sum(prevtx.nValue for _,prevtx,_ in self.prevouts) sig_size = sum(redeemer.spendbytes for _,_,redeemer in self.prevouts) tx_size = (4 + # version field 2 + # # of txins len(self.prevouts) * 41 + # txins, excluding sigs sig_size + # txins, sigs only 1 + # # of txouts 34 + # txout 4 # nLockTime field ) feerate = int(self.proxy._call('estimatefee', 1) * COIN) # satoshi's per KB if feerate <= 0: feerate = 10000 fees = int(tx_size * feerate / 1000) tx = CMutableTransaction( [CTxIn(outpoint, nSequence=0) for outpoint,_,_ in self.prevouts], [CTxOut(sum_in - fees, self.payto.to_scriptPubKey())], 0) for n,(_,_,redeemer) in enumerate(self.prevouts): redeemer.mutate_spend(tx, n) unsigned_tx = CTransaction.from_tx(tx) for n,(_,_,redeemer) in enumerate(self.prevouts): txin = CMutableTxIn.from_txin(tx.vin[n]) txin.scriptSig = redeemer.sign_spend(unsigned_tx, n) tx.vin[n] = CTxIn.from_txin(txin) print(b2x(tx.serialize()))
def build_spending_tx(script_sig, credit_tx): tx = Transaction(version=1, locktime=0) txin = CMutableTxIn(CMutableOutPoint(credit_tx.GetHash(), 0), script_sig) tx.vin = [txin] txout = CMutableTxOut(0, Script()) tx.vout = [txout] return tx
def __init__(self, address): self.address = address self.state = 'begin' self.anchor = CMutableTxIn() self.our = CMutableTxOut() self.their = CMutableTxOut() self.cmd_id = None
def fundrawtransaction(self, given_transaction, *args, **kwargs): """ Make up some inputs for the given transaction. """ # just use any txid here vintxid = lx("99264749804159db1e342a0c8aa3279f6ef4031872051a1e52fb302e51061bef") if isinstance(given_transaction, str): given_bytes = x(given_transaction) elif isinstance(given_transaction, CMutableTransaction): given_bytes = given_transaction.serialize() else: raise FakeBitcoinProxyException("Wrong type passed to fundrawtransaction.") # this is also a clever way to not cause a side-effect in this function transaction = CMutableTransaction.deserialize(given_bytes) for vout_counter in range(0, self._num_fundrawtransaction_inputs): txin = CMutableTxIn(COutPoint(vintxid, vout_counter)) transaction.vin.append(txin) # also allocate a single output (for change) txout = make_txout() transaction.vout.append(txout) transaction_hex = b2x(transaction.serialize()) return {"hex": transaction_hex, "fee": 5000000}
def create_transaction_input(input_): """ transform the unsigned transaction input :param input_: unsigned transaction input :return: input formatted as transaction hex code """ return CMutableTxIn(COutPoint(lx(input_['txid']), input_['index']))
def partial_spend_p2sh_mediator(redeemScript, rein, mediator_address, mediator_sig=False): txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) (txins, total_value) = unspent_txins(txin_p2sh_address, rein.testnet) if len(txins) == 0: raise ValueError('No unspent txins found') txins_str = "" txins_obj = [] for txid, vout in txins: txins_str += " " + txid + "-" + str(vout) txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout))) fee = 0.00025 amount = round(total_value - fee, 8) if amount <= 0: raise ValueError('Not enough value in the inputs') if mediator_sig: txout = CMutableTxOut( amount * COIN, CBitcoinAddress(mediator_address).to_scriptPubKey()) tx = CMutableTransaction(txins_obj, [txout]) seckey = CBitcoinSecret(rein.user.dkey) ntxins = len(txins_obj) sig = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig += " " + b2x(seckey.sign(sighash) + x("01")) return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address), sig[1:]) return (txins_str[1:], "{:.8f}".format(amount), str(mediator_address))
def redeem_with_secret(contract, secret): # How to find redeemScript and redeemblocknum from blockchain? print("Redeeming contract using secret", contract.__dict__) p2sh = contract.p2sh minamount = float(contract.amount) #checking there are funds in the address amount = check_funds(p2sh) if (amount < minamount): print("address ", p2sh, " not sufficiently funded") return false fundtx = find_transaction_to_address(p2sh) amount = fundtx['amount'] / COIN p2sh = P2SHBitcoinAddress(p2sh) if fundtx['address'] == p2sh: print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh)) redeemPubKey = find_redeemAddr(contract) print('redeemPubKey', redeemPubKey) redeemScript = CScript(x(contract.redeemScript)) txin = CMutableTxIn(fundtx['outpoint']) txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey()) # Create the unsigned raw transaction. tx = CMutableTransaction([txin], [txout]) sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) # TODO: figure out how to better protect privkey privkey = bitcoind.dumpprivkey(redeemPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) print("SECRET", secret) preimage = secret.encode('utf-8') txin.scriptSig = CScript( [sig, privkey.pub, preimage, OP_TRUE, redeemScript]) # exit() # print("txin.scriptSig", b2x(txin.scriptSig)) txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey() # print('Redeem txhex', b2x(tx.serialize())) VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH, )) print("script verified, sending raw tx") txid = bitcoind.sendrawtransaction(tx) print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid)))) return b2x(lx(b2x(txid))) else: print("No contract for this p2sh found in database", p2sh)
def maketx(tx): #txid from blockr. bitcoind does not support tx index! txid = lx(tx) vout = 0 outp = COutPoint(txid, vout) print("output: %s" % outp) # Create the txin structure, which includes the outpoint txin = CMutableTxIn(outp) print(txin) txin_scriptPubKey = CScript( [OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG]) print(txin_scriptPubKey) amount = 0.001 * COIN txout = CMutableTxOut(amount, CBitcoinAddress(a).to_scriptPubKey()) print(txout) # Create the unsigned transaction. newtx = CMutableTransaction([txin], [txout]) print(newtx) sighash = SignatureHash(txin_scriptPubKey, newtx, 0, SIGHASH_ALL) print(sighash) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL. sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) print(sig) # Set the scriptSig of our transaction input appropriately. txin.scriptSig = CScript([sig, seckey.pub]) try: VerifyScript(txin.scriptSig, txin_scriptPubKey, newtx, 0, (SCRIPT_VERIFY_P2SH, )) except: pass print('*' * 20) print(b2x(newtx.serialize())) """
def get_tx(self, redeem_script, address, amount, funding_tx, lock_time=0, vout=0): ''' Returns a raw transaction and it's signature hash that pays to address from funding_tx Options: vout -> which vout of funding_tx nLockTime -> set's transaction locktime ''' # Set P2SH funding tx in little-endian fx = lx(funding_tx) if lock_time > 0: nlock_time = lock_time else: nlock_time = 0 # nSequence must be any number less than 0xffffffff to enable nLockTime if (nlock_time != 0): txin = CMutableTxIn(COutPoint(fx, vout), nSequence=0) else: txin = CMutableTxIn(COutPoint(fx, vout)) # Convert amount to Satoshi's amount *= COIN # Create the txout to address script_pubkey = CBitcoinAddress(address).to_scriptPubKey() txout = CMutableTxOut(amount, script_pubkey) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout], nLockTime=nlock_time) # Calculte TX sig hash sighash = SignatureHash(CScript(redeem_script), tx, 0, SIGHASH_ALL) self.logger.info("get_tx: TX SIGHASH is %s", b2x(sighash)) return (tx.serialize(), sighash)
def add_input(): outpoint = CMutableOutPoint(n=0) new_input = CMutableTxIn(prevout=outpoint) self.inputs_tree.add_input(new_input) update_enabled_widgets() if len(self.inputs_tree.get_inputs()) > 0: self.inputs_tree.view.selectRow(self.inputs_tree.model.rowCount() - 1)
def maketx(tx): #txid from blockr. bitcoind does not support tx index! txid = lx(tx) vout = 0 outp = COutPoint(txid, vout) print ("output: %s"%outp) # Create the txin structure, which includes the outpoint txin = CMutableTxIn(outp) print (txin) txin_scriptPubKey = CScript([OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG]) print (txin_scriptPubKey) amount = 0.001*COIN txout = CMutableTxOut(amount, CBitcoinAddress(a).to_scriptPubKey()) print (txout) # Create the unsigned transaction. newtx = CMutableTransaction([txin], [txout]) print (newtx) sighash = SignatureHash(txin_scriptPubKey, newtx, 0, SIGHASH_ALL) print (sighash) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL. sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) print (sig) # Set the scriptSig of our transaction input appropriately. txin.scriptSig = CScript([sig, seckey.pub]) try: VerifyScript(txin.scriptSig, txin_scriptPubKey, newtx, 0, (SCRIPT_VERIFY_P2SH,)) except: pass print ('*'*20) print(b2x(newtx.serialize())) """
def commitment(self, ours=False): """Return an unsigned commitment transaction.""" first = CMutableTxOut(self.our_balance, self.our_addr.to_scriptPubKey()) second = CMutableTxOut(self.their_balance, self.their_addr.to_scriptPubKey()) if not ours: first, second = second, first return CMutableTransaction([CMutableTxIn(self.anchor_point)], [first, second])
def test_create_transaction_object_2(inputs_2, outputs_2): r = PaymentService.create_transaction_object(inputs=inputs_2, outputs=outputs_2) tx_in: List[CMutableTxIn] = [ CMutableTxIn(COutPoint(lx('4521418569de2f78d5d2d3c535567ac9c48c95314c53a67788d4dcdc9a8d915b'), 0)), CMutableTxIn(COutPoint(lx('0bb4abea99101197cf2ddf43a2af1e73f868887d5f4a3619241cbb67413a34e7'), 0)), ] pk1 = CBitcoinAddress('34s7MXyL5sEbgsto6SRdvV3YYUu8XVs4xg').to_scriptPubKey() pk2 = CBitcoinAddress('16moGJwkzWhNC1pfnfJptKj9G1ogQz16xd').to_scriptPubKey() pk3 = CBitcoinAddress('17A16QmavnUfCW11DAApiJxp7ARnxN5pGX').to_scriptPubKey() tx_out: List[CMutableTxOut] = [ CMutableTxOut(100000, pk1), CMutableTxOut(2000, pk2), CMutableTxOut(20000000, pk3), ] expected = CMutableTransaction(tx_in, tx_out) assert b2x(r.serialize()) == b2x(expected.serialize())
def generate_tx(self): tx_chain = self.get_next_tx_chain() txid = lx(tx_chain.current_unspent_tx) txins = [ CMutableTxIn(COutPoint(txid, 0)), CMutableTxIn(COutPoint(txid, 1)) ] txin_seckeys = [tx_chain.seckey, self._spent_to.seckey] amount_in = tx_chain.amount tx_chain.amount -= int(config.transaction_fee / 2) txout1 = CMutableTxOut( tx_chain.amount, CBitcoinAddress(tx_chain.address).to_scriptPubKey()) txout2 = CMutableTxOut( tx_chain.amount, CBitcoinAddress(self._spent_to.address).to_scriptPubKey()) tx = CMutableTransaction(txins, [txout1, txout2], nVersion=2) for i, txin in enumerate(txins): txin_scriptPubKey = CScript([ OP_DUP, OP_HASH160, Hash160(txin_seckeys[i].pub), OP_EQUALVERIFY, OP_CHECKSIG ]) sighash = SignatureHash(txin_scriptPubKey, tx, i, SIGHASH_ALL) sig = txin_seckeys[i].sign(sighash) + bytes([SIGHASH_ALL]) txin.scriptSig = CScript([sig, txin_seckeys[i].pub]) tx_serialized = tx.serialize() logging.debug('{} trying to sendrawtransaction' ' (in=2x{} out=2x{} fee={} bytes={})' ' using tx_chain number={}'.format( self._name, amount_in, txout1.nValue, (amount_in * 2) - (txout1.nValue * 2), len(tx_serialized), self._current_tx_chain_index)) tx_hash = self.execute_rpc('sendrawtransaction', b2x(tx_serialized)) tx_chain.current_unspent_tx = tx_hash logging.info( '{} sendrawtransaction was successful; tx got hash={}'.format( self._name, tx_hash))
def test_create_transaction_object_1(inputs_1, outputs_1): r = PaymentService.create_transaction_object(inputs=inputs_1, outputs=outputs_1) tx_in: List[CMutableTxIn] = [ CMutableTxIn(COutPoint(lx('4521418569de2f78d5d2d3c535567ac9c48c95314c53a67788d4dcdc9a8d915b'), 0))] pk = CBitcoinAddress('16moGJwkzWhNC1pfnfJptKj9G1ogQz16xd').to_scriptPubKey() tx_out: List[CMutableTxOut] = [CMutableTxOut(100000, pk)] expected = CMutableTransaction(tx_in, tx_out) assert b2x(r.serialize()) == b2x(expected.serialize())
def get_unsigned_tx(funding_tx, redeem_script, address, amount, lock_time=0, n_sequence=0, vout=0): """ Returns a raw transaction and it's signature hash that pays to address from funding_tx Arguments: funding_tx (str): the 'input' tx redeem_script (str): The redeem script address (str): The output address that would receive `amount` lock_time (int, optional): The time the tx should be locked to n_sequence (int, optional): The sequence number to use in tx vout (int, optional): The index of the output point of `funding_tx` Returns: A tuple containing: 1/ The serial tx 2/ The tx hash """ # Set P2SH funding tx in little-endian fx = lx(funding_tx) # nSequence must be any number less than 0xffffffff to enable nLockTime txin = CMutableTxIn(COutPoint(fx, vout), nSequence=n_sequence) # if(nlock_time != 0): # txin = CMutableTxIn(COutPoint(fx, vout), nSequence=n_sequence) # else: # txin = CMutableTxIn(COutPoint(fx, vout)) # Convert amount to Satoshi's amount *= COIN # Create the txout to address script_pubkey = CBitcoinAddress(address).to_scriptPubKey() txout = CMutableTxOut(amount, script_pubkey) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout], nLockTime=lock_time) # Calculte TX sig hash sighash = SignatureHash(CScript(redeem_script), tx, 0, SIGHASH_ALL) return (tx.serialize(), sighash)
def partial_spend_p2sh(redeemScript, rein, daddr=None, alt_amount=None, alt_daddr=None): if daddr is None: daddr = rein.user.daddr txin_redeemScript = CScript(x(redeemScript)) txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) (txins, total_value) = unspent_txins(txin_p2sh_address, rein.testnet) if len(txins) == 0: raise ValueError( 'Primary escrow is empty. Please inform client to add funds.') txins_str = "" txins_obj = [] for txid, vout in txins: txins_str += " " + txid + "-" + str(vout) txins_obj.append(CMutableTxIn(COutPoint(lx(txid), vout))) fee = float(PersistConfig.get(rein, 'fee', 0.001)) amount = round(total_value - fee, 8) if alt_amount: amount = round(amount - alt_amount, 8) if amount <= 0. or alt_amount > total_value - fee: click.echo("amount: " + str(amount) + " alt_amount: " + str(alt_amount) + " total_value: " + str(total_value)) raise ValueError( 'Primary escrow balance too low. Please inform client to add funds.' ) txouts = [] txout = CMutableTxOut(amount * COIN, CBitcoinAddress(daddr).to_scriptPubKey()) txouts.append(txout) if alt_amount: txout_alt = CMutableTxOut( round(alt_amount, 8) * COIN, CBitcoinAddress(alt_daddr).to_scriptPubKey()) txouts.append(txout_alt) tx = CMutableTransaction(txins_obj, txouts) ntxins = len(txins_obj) seckey = CBitcoinSecret(rein.user.dkey) sig = "" for i in range(0, ntxins): sighash = SignatureHash(txin_redeemScript, tx, i, SIGHASH_ALL) sig += " " + b2x(seckey.sign(sighash)) + "01" if alt_amount: return (txins_str[1:], "{:.8f}".format(amount), daddr, "{:.8f}".format(alt_amount), alt_daddr, sig[1:]) return (txins_str[1:], "{:.8f}".format(amount), daddr, sig[1:])
# You'll need to send some funds to it to create a txout to spend. txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) print('Pay to:',str(txin_p2sh_address)) # Same as the txid:vout the createrawtransaction RPC call requires # # lx() takes *little-endian* hex and converts it to bytes; in Bitcoin # transaction hashes are shown little-endian rather than the usual big-endian. # There's also a corresponding x() convenience function that takes big-endian # hex and converts it to bytes. txid = lx('bff785da9f8169f49be92fa95e31f0890c385bfb1bd24d6b94d7900057c617ae') vout = 0 # Create the txin structure, which includes the outpoint. The scriptSig # defaults to being empty. txin = CMutableTxIn(COutPoint(txid, vout)) # Create the txout. This time we create the scriptPubKey from a Bitcoin # address. txout = CMutableTxOut(0.0005*COIN, CBitcoinAddress('323uf9MgLaSn9T7vDaK1cGAZ2qpvYUuqSp').to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout]) # Calculate the signature hash for that transaction. Note how the script we use # is the redeemScript, not the scriptPubKey. That's because when the CHECKSIG # operation happens EvalScript() will be evaluating the redeemScript, so the # corresponding SignatureHash() function will use that same script when it # replaces the scriptSig in the transaction being hashed with the script being # executed. sighash = SignatureHash(txin_redeemScript, tx, 0, SIGHASH_ALL)
def make_transaction(sum_inputs, input_hashes, output_addr, seckey, mining_fee=0.00005): #TODO add change address? """all values in btc. input_hashes is a list of tuples (tx_hash, vout). output_addr is P2PKHBitcoinAddress""" # key = CBitcoinSecret("L4vB5fomsK8L95wQ7GFzvErYGht49JsCPJyJMHpB4xGM6xgi2jvG") # print(type(address), address) # print(address) # print (CBitcoinAddress(address).to_scriptPubKey()) # print(dir(seckey)) # print("Secret key: ", seckey) # print("Public key: ", base58.encode(seckey.pub)) # print(base58.encode(Hash160(seckey.pub))) # print('~',type(our_keys), our_keys) # print('~',type(seckey), seckey) # print('~',type(seckey.pub), seckey.pub) src_money = [] sum_of_src_money = 0 for tx_tup in input_hashes: # takes a transaction hash, like you would see on blockchain.info txid = lx(tx_tup[0]) # vout points at which address we are using, 0 for the first and 1 for the second vout = tx_tup[1] # Create the txin structure, which includes the outpoint. The scriptSig # defaults to being empty. txin = CMutableTxIn(COutPoint(txid, vout)) # print(COutPoint(txid, vout)) # print(dir(txin)) # print(txin) # print(txin.prevout) src_money.append(txin) # TODO add queries to blockcypher to get the sum_of_src_money #LOCKING SCRIPT # We also need the scriptPubKey of the output we're spending because # SignatureHash() replaces the transaction scriptSig's with it. # # Here we'll create that scriptPubKey from scratch using the pubkey that # corresponds to the secret key we generated above. txin_scriptPubKey = CScript([OP_DUP, OP_HASH160, output_addr, OP_EQUALVERIFY, OP_CHECKSIG]) # print(b2x(txin_scriptPubKey)) # Create the txout. This time we create the scriptPubKey from a Bitcoin # address. txout = CMutableTxOut((sum_inputs - mining_fee) * COIN,output_addr.to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction(src_money, [txout]) i = 0 while i < len(src_money): # Calculate the signature hash for that transaction. sighash = SignatureHash(txin_scriptPubKey, tx, i, SIGHASH_ALL) # print sighash in hex (2 ways) # import binascii # print('~', binascii.hexlify(sighash)) # import codecs # print(codecs.encode(sighash, 'hex')) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL. sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) # print(sig) # print(b2x(sig)) # for txin in src_money: # Set the scriptSig of our transaction input appropriately. txin = src_money[i] txin.scriptSig = CScript([sig, seckey.pub]) # Verify the signature worked. This calls EvalScript() and actually executes # the opcodes in the scripts to see if everything worked out. If it doesn't an # exception will be raised. VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, i, (SCRIPT_VERIFY_P2SH,)) i += 1 # Done! Print the transaction to standard output with the bytes-to-hex # function. # send the message printed out to other nodes and they will receive the transaction # print("Raw TX: ", b2x(tx.serialize())) # print("TX hash: ", b2lx(tx.GetHash())) return tx
# Create the (in)famous correct brainwallet secret key. h = hashlib.sha256(b'correct horse battery staple').digest() seckey = CBitcoinSecret.from_secret_bytes(h) # Same as the txid:vout the createrawtransaction RPC call requires # # lx() takes *little-endian* hex and converts it to bytes; in Bitcoin # transaction hashes are shown little-endian rather than the usual big-endian. # There's also a corresponding x() convenience function that takes big-endian # hex and converts it to bytes. txid = lx('7e195aa3de827814f172c362fcf838d92ba10e3f9fdd9c3ecaf79522b311b22d') vout = 0 # Create the txin structure, which includes the outpoint. The scriptSig # defaults to being empty. txin = CMutableTxIn(COutPoint(txid, vout)) # We also need the scriptPubKey of the output we're spending because # SignatureHash() replaces the transaction scriptSig's with it. # # Here we'll create that scriptPubKey from scratch using the pubkey that # corresponds to the secret key we generated above. txin_scriptPubKey = CScript([OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG]) # Create the txout. This time we create the scriptPubKey from a Bitcoin # address. txout = CMutableTxOut(0.001*COIN, CBitcoinAddress('1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8').to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout])