Beispiel #1
0
    def redeem_contract(self, contract, secret):
        print("Parsing script for redeem_contract...")
        scriptarray = self.parse_script(contract.redeemScript)
        redeemblocknum = scriptarray[8]
        self.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 Bitcoin:", blockcount)
            if blockcount < int(redeemblocknum):
                return self.redeem(contract, fundtx, secret)
            else:
                print("nLocktime exceeded, refunding")
                return self.refund(contract)
        else:
            print("No contract for this p2sh found in database", p2sh)
Beispiel #2
0
    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)
Beispiel #3
0
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)