Refactor xcat and zcash-xcat.py
This commit is contained in:
parent
3617edd788
commit
afc3451413
234
xcat.py
234
xcat.py
|
@ -12,203 +12,127 @@ import bitcoin
|
|||
import bitcoin.rpc
|
||||
from bitcoin import SelectParams
|
||||
from bitcoin.core import b2x, lx, b2lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
|
||||
from bitcoin.core.script import CScript, OP_DUP, OP_IF, OP_ELSE, OP_ENDIF, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL
|
||||
from bitcoin.core.script import OP_DROP, OP_CHECKLOCKTIMEVERIFY, OP_SHA256, OP_TRUE
|
||||
from bitcoin.core.script import CScript, OP_DUP, OP_IF, OP_ELSE, OP_ENDIF, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL, OP_FALSE, OP_DROP, OP_CHECKLOCKTIMEVERIFY, OP_SHA256, OP_TRUE
|
||||
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
|
||||
|
||||
import hashlib
|
||||
|
||||
# SelectParams('testnet')
|
||||
# To get transactions not in your wallet, must set -txindex=1
|
||||
SelectParams('regtest')
|
||||
proxy = bitcoin.rpc.Proxy()
|
||||
bitcoind = bitcoin.rpc.Proxy()
|
||||
FEE = 0.001*COIN
|
||||
|
||||
# The parameters needed for the htlc - hash preimage, sender/seller address, recipient/buyer address, num of blocks for timeout
|
||||
# ========================= BITCOIN ADDRESSES =========================
|
||||
alice_address = input("Enter alice bitcoin address: (type 'enter' for demo)")
|
||||
bob_address = input("Enter bob bitcoin address: (type 'enter' for demo)")
|
||||
alicepubkey = CBitcoinAddress('mshp4msfzc73ebg4VzwS6nAXj9t6KqX1wd')
|
||||
bobpubkey = CBitcoinAddress('myRh2T5Kg7QJfGLeRzriT5zs9aoek5Jbha')
|
||||
# bitcoind.getnewaddress() returns CBitcoinAddress
|
||||
# bobpubkey = bitcoind.getnewaddress()
|
||||
# alicepubkey = bitcoind.getnewaddress()
|
||||
print("alicepubkey", alicepubkey)
|
||||
print("bobpubkey", bobpubkey)
|
||||
# privkey of the bob, used to sign the redeemTx
|
||||
bob_seckey = bitcoind.dumpprivkey(bobpubkey)
|
||||
# privkey of alice, used to refund tx in case of timeout
|
||||
alice_seckey = bitcoind.dumpprivkey(alicepubkey)
|
||||
|
||||
# ========================= HASHLOCK SECRET PREIMAGE =========================
|
||||
secret = input("Alice: Enter secret to lock funds: (type 'enter' for demo)")
|
||||
# preimage = secret.encode('UTF-8')
|
||||
preimage = b'preimage'
|
||||
h = hashlib.sha256(preimage).digest()
|
||||
|
||||
# proxy.getnewaddress() returns CBitcoinAddress
|
||||
recipientpubkey = proxy.getnewaddress()
|
||||
senderpubkey = proxy.getnewaddress()
|
||||
# privkey of the recipient, used to sign the redeemTx
|
||||
seckey = proxy.dumpprivkey(recipientpubkey)
|
||||
|
||||
# ========================= LOCKTIME SCRIPT CREATION =========================
|
||||
lockduration = 10
|
||||
blocknum = proxy.getblockcount()
|
||||
blocknum = bitcoind.getblockcount()
|
||||
redeemblocknum = blocknum + lockduration
|
||||
# Create a htlc redeemScript. Similar to a scriptPubKey the redeemScript must be
|
||||
# satisfied for the funds to be spent.
|
||||
txin_redeemScript = CScript([OP_IF, OP_SHA256, h, OP_EQUALVERIFY,OP_DUP, OP_HASH160,
|
||||
recipientpubkey, OP_ELSE, redeemblocknum, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_DUP, OP_HASH160,
|
||||
senderpubkey, OP_ENDIF,OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
|
||||
print("redeem script:", b2x(txin_redeemScript))
|
||||
|
||||
# Create P2SH scriptPubKey from redeemScript.
|
||||
txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey()
|
||||
print("p2sh_scriptPubKey", b2x(txin_scriptPubKey))
|
||||
btc_redeemScript = CScript([OP_IF, OP_SHA256, h, OP_EQUALVERIFY,OP_DUP, OP_HASH160,
|
||||
alicepubkey, OP_ELSE, redeemblocknum, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_DUP, OP_HASH160,
|
||||
bobpubkey, OP_ENDIF,OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
print("Redeem script:", b2x(btc_redeemScript))
|
||||
|
||||
# ========================= TX1: CREATE BITCOIN P2SH FROM SCRIPT =========================
|
||||
txin_scriptPubKey = btc_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('Pay to:', p2sh)
|
||||
print('Bob -- Assuming Alice has created other tx on Zcash blockchain, send funds to this p2sh address:', p2sh)
|
||||
|
||||
## TODO: IMPORT ZCASH XCAT FUNCTIONS
|
||||
|
||||
|
||||
# AUTOMATE Send funds to p2sh
|
||||
# ========================= FUND BITCOIN P2SH =========================
|
||||
response = input("Bob -- Type 'enter' to allow zbxcat to fund the Bitcoin p2sh on your behalf:")
|
||||
send_amount = 1.0*COIN
|
||||
# sendtoaddress return the id of the created tx
|
||||
fund_tx = proxy.sendtoaddress(txin_p2sh_address, send_amount)
|
||||
|
||||
print('fund tx sent. Its id is:', b2x(lx(b2x(fund_tx))))
|
||||
|
||||
|
||||
# Import p2sh address and watch
|
||||
# proxy.importaddress(p2sh)
|
||||
# # Returns list of recently observed transaction, includes p2sh if imported and conf sets txindex=1
|
||||
# txs = proxy.listtransactions(p2sh, "*", 10, 10, True)
|
||||
# print('txs from listtransaction', txs)
|
||||
|
||||
# Now receiver receives txid and checks that it is on the blockchain to the right address
|
||||
txinfo = proxy.gettransaction(fund_tx)
|
||||
details = txinfo['details']
|
||||
print('details', details) # "details" is an array, for now we can assume it only has one destination address
|
||||
outputAddress = details[0]['address']
|
||||
print('outputAddress', outputAddress)
|
||||
# Let's check amount by importing address and inspecting
|
||||
proxy.importaddress(outputAddress)
|
||||
# Get amount in address
|
||||
output_amount = proxy.getreceivedbyaddress(outputAddress, 0)
|
||||
print('output amount', output_amount)
|
||||
fund_tx = bitcoind.sendtoaddress(txin_p2sh_address, send_amount)
|
||||
print('Alice -- Bitcoin fund tx was sent, please wait for confirmation. Txid:', b2x(lx(b2x(fund_tx))))
|
||||
|
||||
# ========================= PART 2: BITCOIN P2SH FUNDED, REDEEM OR REFUND =========================
|
||||
# Check that fund_tx is on the blockchain to the right address, then notify receiver
|
||||
# Importing address so we can watch it
|
||||
bitcoind.importaddress(p2sh)
|
||||
# Get details of funding transaction
|
||||
fund_txinfo = bitcoind.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 to wrong address!')
|
||||
print('Fund tx sent to wrong address! p2sh was {0}, funding tx was sent to {1}'.format(p2sh, outputAddress))
|
||||
quit()
|
||||
|
||||
# Check amount by inspecting imported address
|
||||
output_amount = bitcoind.getreceivedbyaddress(outputAddress, 0)
|
||||
if (output_amount < send_amount):
|
||||
print('fund tx to small!')
|
||||
print('Fund tx too small! Amount sent was {0}, amount expected was {1}'.format(output_amount, send_amount))
|
||||
quit()
|
||||
print("P2SH {0} successfully funded with {1}".format(p2sh, send_amount))
|
||||
|
||||
print('sender fund tx has been confirmed, now receiver making their fund tx......')
|
||||
print('Alice -- the fund tx has been confirmed, now you can redeem your Bitcoin with the secret!')
|
||||
|
||||
rec_fund_tx = proxy.sendtoaddress(txin_p2sh_address, send_amount)
|
||||
print('rec fund tx sent. Its id is:', b2x(lx(b2x(fund_tx))))
|
||||
|
||||
# Now sender checks if the lock time is passed, if so she redeems her own tx
|
||||
if(proxy.getblockcount()>=redeemblocknum):
|
||||
# ========================= CHECKLOCKIME FOR BITCOIN TX1 =========================
|
||||
# Mock the timeout period passing for tx1 (comment this out to proceed to redeemtx)
|
||||
# bitcoind.generate(20)
|
||||
|
||||
# ========================= BITCOIN REFUND CONDITION =========================
|
||||
# AFTER 24 HRS (by blocknum): If locktime for first tx has passed, tx1 is refunded to alice
|
||||
if(bitcoind.getblockcount() >= redeemblocknum):
|
||||
print("Bob -- Alice did not redeem within the timeout period, so refunding your bitcoin....... ")
|
||||
txin = CMutableTxIn(COutPoint(fund_tx, fund_vout))
|
||||
# The default nSequence of FFFFFFFF won't let you redeem when there's a CHECKTIMELOCKVERIFY
|
||||
txin.nSequence = 0
|
||||
# Create the txout. Pays out to recipient, so uses recipient's pubkey
|
||||
# Withdraw full amount minus fee
|
||||
default_fee = 0.001*COIN
|
||||
txout = CMutableTxOut(send_amount - default_fee, senderpubkey.to_scriptPubKey())
|
||||
txout = CMutableTxOut(send_amount - FEE, bobpubkey.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
|
||||
tx.nLockTime=redeemblocknum
|
||||
tx.nLockTime = redeemblocknum
|
||||
# Calculate the signature hash for that transaction. Note how the script we use
|
||||
# is the redeemScript, not the scriptPubKey. EvalScript() will be evaluating the redeemScript
|
||||
sighash = SignatureHash(txin_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, seckey.pub, OP_FALSE, txin_redeemScript])
|
||||
print("Time lock has passed, sender redeeming their own tx:")
|
||||
print("Redeem tx hex:", b2x(tx.serialize()))
|
||||
sighash = SignatureHash(btc_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = bob_seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, bob_seckey.pub, OP_FALSE, btc_redeemScript])
|
||||
print("Time lock has passed, Bob redeeming his own tx:")
|
||||
print("Refund tx hex:", b2x(tx.serialize()))
|
||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||
txid = proxy.sendrawtransaction(tx)
|
||||
print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
|
||||
txid = bitcoind.sendrawtransaction(tx)
|
||||
print("Txid of submitted refund tx: ", b2x(lx(b2x(txid))))
|
||||
quit()
|
||||
|
||||
#Otherwise, check that receiver fund tx is on blockchain to correct address with sufficient amount
|
||||
send_txinfo = proxy.gettransaction(rec_fund_tx)
|
||||
details = send_txinfo['details']
|
||||
print('details', details) # "details" is an array, for now we can assume it only has one destination address
|
||||
outputAddress = details[0]['address']
|
||||
print('outputAddress', outputAddress)
|
||||
# Let's check amount by importing address and inspecting
|
||||
proxy.importaddress(outputAddress)
|
||||
# Get amount in address
|
||||
output_amount = proxy.getreceivedbyaddress(outputAddress, 0)
|
||||
print('output amount', output_amount)
|
||||
|
||||
print('output amount', output_amount)
|
||||
if (outputAddress != p2sh):
|
||||
print('fund tx to wrong address!')
|
||||
quit()
|
||||
|
||||
if (output_amount < send_amount):
|
||||
print('fund tx to small!')
|
||||
quit()
|
||||
print('receiver fund tx confirmed, redeeming it with the hash preimage:')
|
||||
|
||||
# Create the txout. Pays out to recipient, so uses recipient's pubkey
|
||||
# Withdraw full amount minus fee
|
||||
default_fee = 0.001*COIN
|
||||
txout = CMutableTxOut(send_amount - default_fee, senderpubkey.to_scriptPubKey())
|
||||
# ========================= BITCOIN REDEEM CONDITION =========================
|
||||
# BEFORE 24 HRS (by blocknum): Alice redeems bitcoin tx bob funded
|
||||
print("Alice -- Redeeming tx.....")
|
||||
txin = CMutableTxIn(COutPoint(fund_tx, fund_vout))
|
||||
txout = CMutableTxOut(send_amount - FEE, alicepubkey.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
|
||||
tx.nLockTime=redeemblocknum
|
||||
sighash = SignatureHash(txin_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, seckey.pub, OP_FALSE, txin_redeemScript])
|
||||
tx.nLockTime = redeemblocknum
|
||||
sighash = SignatureHash(btc_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = alice_seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, alice_seckey.pub, preimage, OP_TRUE, btc_redeemScript])
|
||||
print("Redeem tx hex:", b2x(tx.serialize()))
|
||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||
txid = proxy.sendrawtransaction(tx)
|
||||
print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print('Now redeeming.........')
|
||||
|
||||
# AUTOMATE getting vout of funding tx
|
||||
txinfo = proxy.gettransaction(fund_tx)
|
||||
details = txinfo['details'][0] # what is the zero here
|
||||
vout = details['vout']
|
||||
|
||||
# Create the txin structure. scriptSig defaults to being empty.
|
||||
# The input is the p2sh funding transaction txid, vout is its index
|
||||
txin = CMutableTxIn(COutPoint(fund_tx, vout))
|
||||
|
||||
# Create the txout. Pays out to recipient, so uses recipient's pubkey
|
||||
# Withdraw full amount minus fee
|
||||
default_fee = 0.001*COIN
|
||||
txout = CMutableTxOut(send_amount - default_fee, recipientpubkey.to_scriptPubKey())
|
||||
|
||||
# Create the unsigned raw transaction.
|
||||
tx = CMutableTransaction([txin], [txout])
|
||||
|
||||
# Calculate the signature hash for that transaction. Note how the script we use
|
||||
# is the redeemScript, not the scriptPubKey. EvalScript() will be evaluating the redeemScript
|
||||
sighash = SignatureHash(txin_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
|
||||
# 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])
|
||||
|
||||
# Set the scriptSig of our transaction input appropriately.
|
||||
txin.scriptSig = CScript([ sig, seckey.pub, preimage, OP_TRUE, txin_redeemScript])
|
||||
|
||||
print("Redeem tx hex:", b2x(tx.serialize()))
|
||||
|
||||
# Verify the signature worked.
|
||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||
|
||||
print("Now sending redeem transaction.......")
|
||||
txid = proxy.sendrawtransaction(tx)
|
||||
txid = bitcoind.sendrawtransaction(tx)
|
||||
print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Based on spend-p2sh-txout.py from python-bitcoinlib.
|
||||
# Copyright (C) 2017 The Zcash developers
|
||||
|
||||
import sys
|
||||
if sys.version_info.major < 3:
|
||||
sys.stderr.write('Sorry, Python 3.x required by this example.\n')
|
||||
sys.exit(1)
|
||||
|
||||
import zcash
|
||||
import zcash.rpc
|
||||
from zcash import SelectParams
|
||||
from zcash.core import b2x, lx, b2lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160
|
||||
from zcash.core.script import CScript, OP_DUP, OP_IF, OP_ELSE, OP_ENDIF, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG, SignatureHash, SIGHASH_ALL, OP_FALSE, OP_DROP, OP_CHECKLOCKTIMEVERIFY, OP_SHA256, OP_TRUE
|
||||
from zcash.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||
from zcash.wallet import CBitcoinAddress, CBitcoinSecret
|
||||
import hashlib
|
||||
|
||||
# SelectParams('testnet')
|
||||
SelectParams('regtest')
|
||||
zcashd = zcash.rpc.Proxy()
|
||||
FEE = 0.001*COIN
|
||||
|
||||
# ========================= ZCASH ADDRESSES =========================
|
||||
alice_address = input("Enter alice zcash address: (type 'enter' for demo)")
|
||||
bob_address = input("Enter bob zcash address: (type 'enter' for demo)")
|
||||
# These mock addresses come from regtest on the server
|
||||
alicepubkey = CBitcoinAddress('tmFUm31B9wzHWJ9jGe9L9Qb549zfC7zFsEK')
|
||||
bobpubkey = CBitcoinAddress('tmFm8R6b22485uDYm6dryC4f8R6oXUTUe5i')
|
||||
# zcashd.getnewaddress() returns CBitcoinAddress
|
||||
# bobpubkey = zcashd.getnewaddress()
|
||||
# alicepubkey = zcashd.getnewaddress()
|
||||
print("alicepubkey", alicepubkey)
|
||||
print("bobpubkey", bobpubkey)
|
||||
# privkey of the bob, used to sign the redeemTx
|
||||
bob_seckey = zcashd.dumpprivkey(bobpubkey)
|
||||
# privkey of alice, used to refund tx in case of timeout
|
||||
alice_seckey = zcashd.dumpprivkey(alicepubkey)
|
||||
print("bob_seckey", bob_seckey)
|
||||
|
||||
# ======= secret from Alice, other file ====
|
||||
preimage = b'preimage'
|
||||
h = hashlib.sha256(preimage).digest()
|
||||
|
||||
# ========================= LOCKTIME SCRIPT CREATION =========================
|
||||
lockduration = 20 # Must be more than first tx
|
||||
blocknum = zcashd.getblockcount()
|
||||
redeemblocknum = blocknum + lockduration
|
||||
zec_redeemScript = CScript([OP_IF, OP_SHA256, h, OP_EQUALVERIFY,OP_DUP, OP_HASH160,
|
||||
bobpubkey, OP_ELSE, redeemblocknum, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_DUP, OP_HASH160,
|
||||
alicepubkey, OP_ENDIF,OP_EQUALVERIFY, OP_CHECKSIG])
|
||||
print("TX2 Redeem script on Zcash blockchain:", b2x(zec_redeemScript))
|
||||
|
||||
# ========================= 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
|
||||
output_amount = zcashd.getreceivedbyaddress(outputAddress, 0)
|
||||
if (output_amount < send_amount):
|
||||
print('Fund tx too small! Amount sent was {0}, amount expected was {1}'.format(output_amount, send_amount))
|
||||
quit()
|
||||
|
||||
print('Bob -- Alice Zcash funding tx confirmed, now send funds to the Bitcoin p2sh: (other file)')
|
||||
|
||||
# ========================= PART 2: ZCASH P2SH FUNDED, REDEEM OR REFUND =========================
|
||||
|
||||
# ================= AFTER 48 HRS: ALICE REFUNDS AFTER BOB TIMES OUT =========================
|
||||
# Mock passage of time -- comment out to test normal redeem condition
|
||||
# zcashd.generate(25)
|
||||
|
||||
if(zcashd.getblockcount() >= redeemblocknum):
|
||||
print("Alice -- Bob did not redeem the Zcash you put in escrow within the timeout period, so refunding you..... ")
|
||||
txin = CMutableTxIn(COutPoint(fund_tx, fund_vout))
|
||||
# The default nSequence of FFFFFFFF won't let you redeem when there's a CHECKTIMELOCKVERIFY
|
||||
txin.nSequence = 0
|
||||
txout = CMutableTxOut(send_amount - FEE, alicepubkey.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
|
||||
tx.nLockTime = redeemblocknum
|
||||
# Calculate the signature hash for that transaction. Note how the script we use
|
||||
# is the redeemScript, not the scriptPubKey. EvalScript() will be evaluating the redeemScript
|
||||
sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = alice_seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, alice_seckey.pub, OP_FALSE, zec_redeemScript])
|
||||
print("Time lock has passed, Alice redeeming her own tx:")
|
||||
print("Refund tx hex:", b2x(tx.serialize()))
|
||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||
txid = zcashd.sendrawtransaction(tx)
|
||||
print("Txid of submitted refund tx: ", b2x(lx(b2x(txid))))
|
||||
quit()
|
||||
|
||||
# ================= BEFORE 48 HRS: BOB REDEEMS WITH ALICE'S REVEALED SECRET =========================
|
||||
print("Bob -- Redeeming tx.....")
|
||||
txin = CMutableTxIn(COutPoint(fund_tx, fund_vout))
|
||||
txout = CMutableTxOut(send_amount - FEE, bobpubkey.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
|
||||
tx.nLockTime = redeemblocknum
|
||||
sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL)
|
||||
sig = bob_seckey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||
txin.scriptSig = CScript([sig, bob_seckey.pub, preimage, OP_TRUE, zec_redeemScript])
|
||||
print("Redeem tx hex:", b2x(tx.serialize()))
|
||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||
txid = bitcoind.sendrawtransaction(tx)
|
||||
print("Txid of submitted redeem tx: ", b2x(lx(b2x(txid))))
|
Loading…
Reference in New Issue