Debug checklocktimeverify process, not complete
This commit is contained in:
parent
16826db42b
commit
59c2a1c37b
|
@ -10,7 +10,7 @@ import bitcoin.rpc
|
||||||
from bitcoin import SelectParams
|
from bitcoin import SelectParams
|
||||||
from bitcoin.core import b2x, lx, b2lx, x, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160, CTransaction
|
from bitcoin.core import b2x, lx, b2lx, x, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160, CTransaction
|
||||||
from bitcoin.base58 import decode
|
from bitcoin.base58 import decode
|
||||||
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.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, OP_FALSE
|
||||||
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||||
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret, P2SHBitcoinAddress, P2PKHBitcoinAddress
|
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret, P2SHBitcoinAddress, P2PKHBitcoinAddress
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ class bitcoinProxy():
|
||||||
print("Parsing script for redeem_contract...")
|
print("Parsing script for redeem_contract...")
|
||||||
scriptarray = self.parse_script(contract.redeemScript)
|
scriptarray = self.parse_script(contract.redeemScript)
|
||||||
redeemblocknum = scriptarray[8]
|
redeemblocknum = scriptarray[8]
|
||||||
redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6]))
|
self.redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6]))
|
||||||
refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13]))
|
refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13]))
|
||||||
p2sh = contract.p2sh
|
p2sh = contract.p2sh
|
||||||
#checking there are funds in the address
|
#checking there are funds in the address
|
||||||
|
@ -172,22 +172,23 @@ class bitcoinProxy():
|
||||||
else:
|
else:
|
||||||
print("No contract for this p2sh found in database", p2sh)
|
print("No contract for this p2sh found in database", p2sh)
|
||||||
|
|
||||||
def redeem(self, contract):
|
def redeem(self, contract, fundtx, secret):
|
||||||
print('redeemPubKey', redeemPubKey)
|
print('redeemPubKey', self.redeemPubKey)
|
||||||
zec_redeemScript = CScript(x(contract.redeemScript))
|
# TODO: Compare with script on blockchain?
|
||||||
|
redeemScript = CScript(x(contract.redeemScript))
|
||||||
txin = CMutableTxIn(fundtx['outpoint'])
|
txin = CMutableTxIn(fundtx['outpoint'])
|
||||||
txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey())
|
txout = CMutableTxOut(fundtx['amount'] - FEE, self.redeemPubKey.to_scriptPubKey())
|
||||||
# Create the unsigned raw transaction.
|
# Create the unsigned raw transaction.
|
||||||
tx = CMutableTransaction([txin], [txout])
|
tx = CMutableTransaction([txin], [txout])
|
||||||
sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL)
|
sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
|
||||||
# TODO: protect privkey better, separate signing from rawtx creation
|
# TODO: protect privkey better, separate signing from rawtx creation
|
||||||
privkey = self.bitcoind.dumpprivkey(redeemPubKey)
|
privkey = self.bitcoind.dumpprivkey(self.redeemPubKey)
|
||||||
sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
|
sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||||
preimage = secret.encode('utf-8')
|
preimage = secret.encode('utf-8')
|
||||||
txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, zec_redeemScript])
|
txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, redeemScript])
|
||||||
|
|
||||||
# print("txin.scriptSig", b2x(txin.scriptSig))
|
# print("txin.scriptSig", b2x(txin.scriptSig))
|
||||||
txin_scriptPubKey = zec_redeemScript.to_p2sh_scriptPubKey()
|
txin_scriptPubKey = redeemScript.to_p2sh_scriptPubKey()
|
||||||
print('Raw redeem transaction hex: ', b2x(tx.serialize()))
|
print('Raw redeem transaction hex: ', b2x(tx.serialize()))
|
||||||
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
|
||||||
print("Script verified, sending raw transaction...")
|
print("Script verified, sending raw transaction...")
|
||||||
|
@ -198,10 +199,31 @@ class bitcoinProxy():
|
||||||
|
|
||||||
def refund(self, contract):
|
def refund(self, contract):
|
||||||
fundtx = self.find_transaction_to_address(contract.p2sh)
|
fundtx = self.find_transaction_to_address(contract.p2sh)
|
||||||
# Refund self on other chain
|
print("Fund tx found in refund: ", fundtx)
|
||||||
refundPubKey = self.find_refundAddr(contract)
|
refundPubKey = self.find_refundAddr(contract)
|
||||||
logging.debug('refundPubKey: {0}'.format(refundPubKey))
|
print('refundPubKey: {0}'.format(refundPubKey))
|
||||||
txid = self.bitcoind.sendtoaddress(refundPubKey, fundtx['amount'] - FEE)
|
|
||||||
|
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])
|
||||||
|
tx.nLockTime = 2430
|
||||||
|
sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
|
||||||
|
privkey = self.bitcoind.dumpprivkey(refundPubKey)
|
||||||
|
sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||||
|
# Sign without secret
|
||||||
|
# OP_IF, OP_SHA256, commitment, OP_EQUALVERIFY,OP_DUP, OP_HASH160, redeemerAddr,
|
||||||
|
# OP_ELSE, redeemblocknum, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_DUP, OP_HASH160, funderAddr,
|
||||||
|
# OP_ENDIF,
|
||||||
|
# OP_EQUALVERIFY, OP_CHECKSIG
|
||||||
|
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)))
|
refund_tx = b2x(lx(b2x(txid)))
|
||||||
fund_tx = str(fundtx['outpoint'])
|
fund_tx = str(fundtx['outpoint'])
|
||||||
return {"refund_tx": refund_tx, "fund_tx": fund_tx}
|
return {"refund_tx": refund_tx, "fund_tx": fund_tx}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.version_info.major < 3:
|
||||||
|
sys.stderr.write('Sorry, Python 3.x required by this example.\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
import bitcoin
|
||||||
|
import bitcoin.rpc
|
||||||
|
from bitcoin import SelectParams
|
||||||
|
from bitcoin.core import b2x, lx, b2lx, x, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, Hash160, CTransaction
|
||||||
|
from bitcoin.base58 import decode
|
||||||
|
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, OP_FALSE
|
||||||
|
from bitcoin.core.scripteval import VerifyScript, SCRIPT_VERIFY_P2SH
|
||||||
|
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret, P2SHBitcoinAddress, P2PKHBitcoinAddress
|
||||||
|
|
||||||
|
from xcat.utils import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
FEE = 0.001*COIN
|
||||||
|
|
||||||
|
SelectParams('regtest')
|
||||||
|
bitcoind = bitcoin.rpc.Proxy()
|
||||||
|
|
||||||
|
# Simple CLTV test p2sh
|
||||||
|
blocknum = bitcoind.getblockcount()
|
||||||
|
print("Current blocknum on Bitcoin: ", blocknum)
|
||||||
|
redeemblocknum = blocknum + 1
|
||||||
|
print("Redeemblocknum on Bitcoin: ", redeemblocknum)
|
||||||
|
redeemScript = CScript([redeemblocknum, OP_CHECKLOCKTIMEVERIFY])
|
||||||
|
print("Redeem script for p2sh contract on Bitcoin blockchain: {0}".format(b2x(redeemScript)))
|
||||||
|
txin_scriptPubKey = 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)
|
||||||
|
# Import address at same time you create
|
||||||
|
bitcoind.importaddress(p2sh, "", False)
|
||||||
|
|
||||||
|
bitcoind.generate(3)
|
||||||
|
blocknum = bitcoind.getblockcount()
|
||||||
|
print("Current blocknum on Bitcoin 2: ", blocknum)
|
||||||
|
print("Redeemblocknum on Bitcoin 2: ", redeemblocknum)
|
||||||
|
|
||||||
|
send_amount = float(0.01) * COIN
|
||||||
|
# Import address at same time that you fund it
|
||||||
|
bitcoind.importaddress(p2sh, "", False)
|
||||||
|
fund_txid = bitcoind.sendtoaddress(p2sh, send_amount)
|
||||||
|
txid = b2x(lx(b2x(fund_txid)))
|
||||||
|
print("fund txid", txid)
|
||||||
|
|
||||||
|
# Find the fund tx...
|
||||||
|
txs = bitcoind.listunspent()
|
||||||
|
for tx in txs:
|
||||||
|
if tx['address'] == CBitcoinAddress(p2sh):
|
||||||
|
print("Found tx to p2sh: {0}".format(p2sh))
|
||||||
|
fundtx = tx
|
||||||
|
|
||||||
|
# redeemScript = CScript(x(redeemScript))
|
||||||
|
txin = CMutableTxIn(fundtx['outpoint'])
|
||||||
|
|
||||||
|
refundAddr = CBitcoinAddress('mvc56qCEVj6p57xZ5URNC3v7qbatudHQ9b')
|
||||||
|
txout = CMutableTxOut(fundtx['amount'] - FEE, refundAddr.to_scriptPubKey())
|
||||||
|
# Create the unsigned raw transaction.
|
||||||
|
tx = CMutableTransaction([txin], [txout])
|
||||||
|
# tx.nLockTime = 2430
|
||||||
|
sighash = SignatureHash(redeemScript, tx, 0, SIGHASH_ALL)
|
||||||
|
|
||||||
|
# privkey = bitcoind.dumpprivkey(refundPubKey)
|
||||||
|
# sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
|
||||||
|
# Sign without secret
|
||||||
|
# OP_IF, OP_SHA256, commitment, OP_EQUALVERIFY,OP_DUP, OP_HASH160, redeemerAddr,
|
||||||
|
# OP_ELSE, redeemblocknum, OP_CHECKLOCKTIMEVERIFY, OP_DROP, OP_DUP, OP_HASH160, funderAddr,
|
||||||
|
# OP_ENDIF,
|
||||||
|
# OP_EQUALVERIFY, OP_CHECKSIG
|
||||||
|
txin.scriptSig = CScript([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... ", res)
|
||||||
|
txid = bitcoind.sendrawtransaction(tx)
|
||||||
|
refund_tx = b2x(lx(b2x(txid)))
|
|
@ -262,10 +262,10 @@ def main():
|
||||||
tradeid = args.arguments[0]
|
tradeid = args.arguments[0]
|
||||||
checkBuyStatus(tradeid)
|
checkBuyStatus(tradeid)
|
||||||
elif command == "step3":
|
elif command == "step3":
|
||||||
generate(11)
|
generate(31)
|
||||||
tradeid = args.arguments[0]
|
tradeid = args.arguments[0]
|
||||||
checkSellStatus(tradeid)
|
checkSellStatus(tradeid)
|
||||||
elif command == "step4":
|
elif command == "step4":
|
||||||
generate(1)
|
# generate(1)
|
||||||
tradeid = args.arguments[0]
|
tradeid = args.arguments[0]
|
||||||
checkBuyStatus(tradeid)
|
checkBuyStatus(tradeid)
|
||||||
|
|
|
@ -105,21 +105,39 @@ class zcashProxy():
|
||||||
for tx in txs:
|
for tx in txs:
|
||||||
raw = self.zcashd.gettransaction(lx(tx['txid']))['hex']
|
raw = self.zcashd.gettransaction(lx(tx['txid']))['hex']
|
||||||
decoded = self.zcashd.decoderawtransaction(raw)
|
decoded = self.zcashd.decoderawtransaction(raw)
|
||||||
|
# print("TXINFO", decoded['vin'][0])
|
||||||
if('txid' in decoded['vin'][0]):
|
if('txid' in decoded['vin'][0]):
|
||||||
sendid = decoded['vin'][0]['txid']
|
sendid = decoded['vin'][0]['txid']
|
||||||
if (sendid == fundtx_input ):
|
if (sendid == fundtx_input ):
|
||||||
print("Found funding zcash tx: ", sendid)
|
print("Found funding tx: ", sendid)
|
||||||
res = self.parse_secret(lx(tx['txid']))
|
return self.parse_secret(lx(tx['txid']))
|
||||||
secret = res[0]
|
print("Redeem transaction with secret not found")
|
||||||
redeemPubkey = res[1]
|
|
||||||
if secret is None:
|
|
||||||
print("Secret not found")
|
|
||||||
res = self.validateaddress(redeemPubkey)
|
|
||||||
if res['ismine']:
|
|
||||||
print("Funding tx already refunded. Sent to your address {0}".format(redeemPubkey))
|
|
||||||
logging.debug("Redeem transaction with secret not found")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# def find_secret(self, p2sh, fundtx_input):
|
||||||
|
# print("In find secret zcashrpc")
|
||||||
|
# txs = self.zcashd.call('listtransactions', "*", 200, 0, True)
|
||||||
|
# for tx in txs:
|
||||||
|
# if tx['address'] == p2sh: # Only check txs involving imported p2sh
|
||||||
|
# raw = self.zcashd.gettransaction(lx(tx['txid']))['hex']
|
||||||
|
# decoded = self.zcashd.decoderawtransaction(raw)
|
||||||
|
# print('decoded', decoded)
|
||||||
|
# if('txid' in decoded['vin'][0]):
|
||||||
|
# sendid = decoded['vin'][0]['txid']
|
||||||
|
# print("sendid", sendid)
|
||||||
|
# if (sendid == fundtx_input ):
|
||||||
|
# print("Found funding zcash tx: ", sendid)
|
||||||
|
# res = self.parse_secret(lx(tx['txid']))
|
||||||
|
# secret = res[0]
|
||||||
|
# redeemPubkey = res[1]
|
||||||
|
# if secret is None:
|
||||||
|
# print("Secret not found")
|
||||||
|
# res = self.validateaddress(redeemPubkey)
|
||||||
|
# if res['ismine']:
|
||||||
|
# print("Funding tx already refunded. Sent to your address {0}".format(redeemPubkey))
|
||||||
|
# logging.debug("Redeem transaction with secret not found")
|
||||||
|
# return
|
||||||
|
|
||||||
def parse_secret(self, txid):
|
def parse_secret(self, txid):
|
||||||
raw = self.zcashd.gettransaction(txid, True)['hex']
|
raw = self.zcashd.gettransaction(txid, True)['hex']
|
||||||
decoded = self.zcashd.decoderawtransaction(raw)
|
decoded = self.zcashd.decoderawtransaction(raw)
|
||||||
|
@ -130,9 +148,9 @@ class zcashProxy():
|
||||||
secret = x2s(asm[2])
|
secret = x2s(asm[2])
|
||||||
except:
|
except:
|
||||||
secret = None
|
secret = None
|
||||||
redeemPubkey = P2PKHBitcoinAddress.from_pubkey(x(pubkey))
|
self.redeemPubkey = P2PKHBitcoinAddress.from_pubkey(x(pubkey))
|
||||||
print("redeemPubkey: ", redeemPubkey)
|
print("redeemPubkey: ", self.redeemPubkey)
|
||||||
return secret, redeemPubkey
|
return secret
|
||||||
|
|
||||||
def redeem_contract(self, contract, secret):
|
def redeem_contract(self, contract, secret):
|
||||||
# How to find redeemScript and redeemblocknum from blockchain?
|
# How to find redeemScript and redeemblocknum from blockchain?
|
||||||
|
|
Loading…
Reference in New Issue