def find_secret(p2sh, vinid): zcashd.importaddress(p2sh, '', True) # is this working? print ('vinid:', vinid) txs = zcashd.listtransactions() print ('LENNNNNNN2:', len(txs)) for tx in txs: # print("tx addr:", tx['address'], "tx id:", tx['txid']) # print(type(tx['address'])) # print(type(p2sh)) # print('type::',type(tx['txid'])) raw = zcashd.gettransaction(lx(tx['txid']))['hex'] decoded = zcashd.decoderawtransaction(raw) print ('fdsfdfds', decoded['vin'][0]) if 'txid' in decoded['vin'][0]: sendid = decoded['vin'][0]['txid'] print ('sendid:', sendid) if sendid == vinid: # print(type(tx['txid'])) # print(str.encode(tx['txid'])) print 'in if' return parse_secret(lx(tx['txid'])) print 'Redeem transaction with secret not found' return ''
def find_secret(p2sh, vinid): zcashd.importaddress(p2sh, "", True) # is this working? txs = zcashd.listtransactions() # print("==========================================LISTTT============", txs) # print() # print('LENNNNNNN:', len(txs)) # print('LENNNNNNN2:', len(txs)) for tx in txs: # print("tx addr:", tx['address'], "tx id:", tx['txid']) # print(type(tx['address'])) # print(type(p2sh)) # print('type::',type(tx['txid'])) raw = zcashd.gettransaction(lx(tx['txid']))['hex'] decoded = zcashd.decoderawtransaction(raw) # print("fdsfdfds", decoded['vin'][0]) if ('txid' in decoded['vin'][0]): sendid = decoded['vin'][0]['txid'] # print("sendid:", sendid) if (sendid == vinid): # print(type(tx['txid'])) # print(str.encode(tx['txid'])) return parse_secret(lx(tx['txid'])) print("Redeem transaction with secret not found") return ""
def redeem_contract(self, contract, secret): # How to find redeemScript and redeemblocknum from blockchain? 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)) # Where can you find redeemblocknum in the transaction? # redeemblocknum = find_redeemblocknum(contract) blockcount = self.zcashd.getblockcount() print("\nCurrent blocknum at time of redeem on Zcash:", blockcount) if blockcount < contract.redeemblocknum: # TODO: parse the script once, up front. redeemPubKey = self.find_redeemAddr(contract) 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: figure out how to better protect privkey privkey = self.zcashd.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, zec_redeemScript]) 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 redeem transaction...") txid = self.zcashd.sendrawtransaction(tx) redeem_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"redeem_tx": redeem_tx, "fund_tx": fund_tx} else: print("nLocktime exceeded, refunding") refundPubKey = self.find_refundAddr(contract) print('refundPubKey', refundPubKey) txid = self.zcashd.sendtoaddress(refundPubKey, fundtx['amount'] - FEE) refund_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"refund_tx": refund_tx, "fund_tx": fund_tx} else: print("No contract for this p2sh found in database", p2sh)
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 = zcashd.dumpprivkey(redeemPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) print ('SECRET', secret) # secret = get_secret() preimage = secret.encode('utf-8') txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, redeemScript]) # 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 = zcashd.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 find_secret(self, p2sh, fundtx_input): txs = self.zcashd.call('listtransactions', "*", 20, 0, True) for tx in txs: raw = self.zcashd.gettransaction(lx(tx['txid']))['hex'] decoded = self.zcashd.decoderawtransaction(raw) if ('txid' in decoded['vin'][0]): sendid = decoded['vin'][0]['txid'] if (sendid == fundtx_input): print("Found funding tx: ", sendid) return self.parse_secret(lx(tx['txid'])) print("Redeem transaction with secret not found") return
def redeem_after_timelock(contract): print(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 = zcashd.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 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 = zcashd.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 = zcashd.sendrawtransaction(tx) print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid)))) return b2x(lx(b2x(txid)))
def getrawtransaction(self, txid, verbose=False): """Return transaction with hash txid Raises IndexError if transaction not found. verbose - If true a dict is returned instead with additional information on the transaction. Note that if all txouts are spent and the transaction index is not enabled the transaction may not be available. """ try: r = self._call('getrawtransaction', b2lx(txid), 1 if verbose else 0) except InvalidAddressOrKeyError as ex: raise IndexError('%s.getrawtransaction(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) if verbose: r['tx'] = CTransaction.deserialize(unhexlify(r['hex'])) r['hex'] del r['txid'] del r['version'] del r['locktime'] del r['vin'] del r['vout'] r['blockhash'] = lx(r['blockhash']) if 'blockhash' in r else None else: r = CTransaction.deserialize(unhexlify(r)) return r
def getblockheader(self, block_hash, verbose=False): """Get block header <block_hash> verbose - If true a dict is returned with the values returned by getblockheader that are not in the block header itself (height, nextblockhash, etc.) Raises IndexError if block_hash is not valid. """ try: block_hash = b2lx(block_hash) except TypeError: raise TypeError( '%s.getblockheader(): block_hash must be bytes; got %r instance' % (self.__class__.__name__, block_hash.__class__)) try: r = self._call('getblockheader', block_hash, verbose) except InvalidAddressOrKeyError as ex: raise IndexError('%s.getblockheader(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code'])) if verbose: nextblockhash = None if 'nextblockhash' in r: nextblockhash = lx(r['nextblockhash']) return { 'confirmations': r['confirmations'], 'height': r['height'], 'mediantime': r['mediantime'], 'nextblockhash': nextblockhash, 'chainwork': x(r['chainwork']) } else: return CBlockHeader.deserialize(unhexlify(r))
def listunspent(self, minconf=0, maxconf=9999999, addrs=None): """Return unspent transaction outputs in wallet Outputs will have between minconf and maxconf (inclusive) confirmations, optionally filtered to only include txouts paid to addresses in addrs. """ r = None if addrs is None: r = self._call('listunspent', minconf, maxconf) else: addrs = [str(addr) for addr in addrs] r = self._call('listunspent', minconf, maxconf, addrs) r2 = [] for unspent in r: unspent['outpoint'] = COutPoint(lx(unspent['txid']), unspent['vout']) unspent['address'] = CBitcoinAddress(unspent['address']) unspent['scriptPubKey'] = CScript( unhexlify(unspent['scriptPubKey'])) unspent['amount'] = int(unspent['amount'] * COIN) r2.append(unspent) return r2
def redeem(self, contract, fundtx, secret): # TODO: parse the script once, up front. redeemPubKey = self.find_redeemAddr(contract) 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: figure out how to better protect privkey privkey = self.zcashd.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, zec_redeemScript]) 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 redeem transaction...") txid = self.zcashd.sendrawtransaction(tx) redeem_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"redeem_tx": redeem_tx, "fund_tx": fund_tx}
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 # Create the unsigned raw transaction. sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL) privkey = self.zcashd.dumpprivkey(refundPubKey) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) # Sign without secret txin.scriptSig = CScript([sig, privkey.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 = self.zcashd.sendrawtransaction(tx) refund_tx = b2x(lx(b2x(txid))) fund_tx = str(fundtx['outpoint']) return {"refund_tx": refund_tx, "fund_tx": fund_tx}
def fund_htlc(self, p2sh, amount): send_amount = float(amount) * COIN # Import addr at same time as you fund self.zcashd.importaddress(p2sh, "", False) fund_txid = self.zcashd.sendtoaddress(p2sh, send_amount) txid = b2x(lx(b2x(fund_txid))) return txid
def getrawmempool(self, verbose=False): """Return the mempool""" if verbose: return self._call('getrawmempool', verbose) else: r = self._call('getrawmempool') r = [lx(txid) for txid in r] return r
def getblockhash(self, height): """Return hash of block in best-block-chain at height. Raises IndexError if height is not valid. """ try: return lx(self._call('getblockhash', height)) except InvalidParameterError as ex: raise IndexError('%s.getblockhash(): %s (%d)' % (self.__class__.__name__, ex.error['message'], ex.error['code']))
def sendtoaddress(self, addr, amount, comment='', commentto='', subtractfeefromamount=False): """Send amount to a given address""" addr = str(addr) amount = float(amount) / COIN r = self._call('sendtoaddress', addr, amount, comment, commentto, subtractfeefromamount) return lx(r)
def sendrawtransaction(self, tx, allowhighfees=False): """Submit transaction to local node and network. allowhighfees - Allow even if fees are unreasonably high. """ hextx = hexlify(tx.serialize()) r = None if allowhighfees: r = self._call('sendrawtransaction', hextx, True) else: r = self._call('sendrawtransaction', hextx) return lx(r)
def find_recipient(self, contract): # make this dependent on actual fund tx to p2sh, not contract txid = contract.fund_tx raw = self.zcashd.gettransaction(lx(txid), True)['hex'] decoded = self.zcashd.decoderawtransaction(raw) scriptSig = decoded['vin'][0]['scriptSig'] print("Decoded", scriptSig) asm = scriptSig['asm'].split(" ") pubkey = asm[1] initiator = CBitcoinAddress(contract.initiator) fulfiller = CBitcoinAddress(contract.fulfiller) print("Initiator", b2x(initiator)) print("Fulfiller", b2x(fulfiller)) print('pubkey', pubkey) redeemPubkey = P2PKHBitcoinAddress.from_pubkey(x(pubkey)) print('redeemPubkey', redeemPubkey)
def sendmany(self, fromaccount, payments, minconf=1, comment='', subtractfeefromamount=[]): """Send amount to given addresses. payments - dict with {address: amount} """ json_payments = { str(addr): float(amount) / COIN for addr, amount in payments.items() } r = self._call('sendmany', fromaccount, json_payments, minconf, comment, subtractfeefromamount) return lx(r)
def gettxout(self, outpoint, includemempool=True): """Return details about an unspent transaction output. Raises IndexError if outpoint is not found or was spent. includemempool - Include mempool txouts """ r = self._call('gettxout', b2lx(outpoint.hash), outpoint.n, includemempool) if r is None: raise IndexError('%s.gettxout(): unspent txout %r not found' % (self.__class__.__name__, outpoint)) r['txout'] = CTxOut(int(r['value'] * COIN), CScript(unhexlify(r['scriptPubKey']['hex']))) del r['value'] del r['scriptPubKey'] r['bestblock'] = lx(r['bestblock']) return r
# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() print('scriptPubKey:', str(txin_scriptPubKey)) # Convert the P2SH scriptPubKey to a base58 zcash address and print it. # 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('tmKBPqa8qqKA7vrGq1AaXHSAr9vqa3GczzK').to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout])
def fund_htlc(p2sh, amount): send_amount = float(amount) * COIN fund_txid = zcashd.sendtoaddress(p2sh, send_amount) txid = b2x(lx(b2x(fund_txid))) return txid
# ========================= TX1: CREATE BITCOIN P2SH FROM SCRIPT ========================= txin_scriptPubKey = zec_redeemScript.to_p2sh_scriptPubKey() # Convert the P2SH scriptPubKey to a base58 Bitcoin address txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) p2sh = str(txin_p2sh_address) print('Alice -- send funds to this p2sh address to initiate atomic swap:', p2sh) response = input( "Alice -- Type 'enter' to allow zbxcat to fund the Zcash p2sh on your behalf:" ) send_amount = 10.0 * COIN fund_tx = zcashd.sendtoaddress(txin_p2sh_address, send_amount) print( 'Bob -- Alice send fund tx to the Zcash p2sh. Please wait for confirmation. Txid:', b2x(lx(b2x(fund_tx)))) # ========================= CONFIRM ZCASH FUNDING TX TO P2SH ========================= zcashd.importaddress(p2sh) fund_txinfo = zcashd.gettransaction(fund_tx) fund_details = fund_txinfo[ 'details'] # "fund_details" is an array, for now we can assume it only has one destination address outputAddress = fund_details[0]['address'] fund_vout = fund_details[0]['vout'] if (outputAddress != p2sh): print( 'Fund tx sent to wrong address! p2sh was {0}, funding tx was sent to {1}' .format(p2sh, outputAddress)) quit() # Get amount in address
def getbestblockhash(self): """Return hash of best (tip) block in longest block chain.""" return lx(self._call('getbestblockhash'))
from zcash.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH from zcash.wallet import CBitcoinAddress, CBitcoinSecret SelectParams('mainnet') # 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])
def auto_redeem(contract, secret): # How to find redeemScript and redeemblocknum from blockchain? print("Contract in auto redeem", contract.__dict__) p2sh = contract.p2sh #checking there are funds in the address amount = check_funds(p2sh) if (amount == 0): print("address ", p2sh, " not funded") quit() 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)) # Parsing redeemblocknum from the redeemscript of the p2sh redeemblocknum = find_redeemblocknum(contract) blockcount = zcashd.getblockcount() print("\nCurrent blocknum at time of redeem on Zcash chain:", blockcount) if blockcount < redeemblocknum: redeemPubKey = find_redeemAddr(contract) print('redeemPubKey', redeemPubKey) else: print("nLocktime exceeded, refunding") redeemPubKey = find_refundAddr(contract) print('refundPubKey', redeemPubKey) # redeemPubKey = CBitcoinAddress.from_scriptPubKey(redeemPubKey) # exit() 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]) # nLockTime needs to be at least as large as parameter of CHECKLOCKTIMEVERIFY for script to verify # TODO: these things like redeemblocknum should really be properties of a tx class... # Need: redeemblocknum, zec_redeemScript, secret (for creator...), txid, redeemer... if blockcount >= redeemblocknum: print("\nLocktime exceeded") tx.nLockTime = redeemblocknum sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL) # TODO: figure out how to better protect privkey privkey = zcashd.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, zec_redeemScript]) # exit() # print("txin.scriptSig", b2x(txin.scriptSig)) txin_scriptPubKey = zec_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)