-
-
Save i0x0ff/b29b2307b4e9ce316a4d6533464cf7a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This example is based on Peter Todd's bitcoinlib: https://github.com/petertodd/python-bitcoinlib | |
The code is based directly out of the example script provided in bitcoinlib: https://github.com/petertodd/python-bitcoinlib/blob/master/examples/spend-p2wsh-txout.py | |
I'd like to understand what exactly am I doing wrong, every time the transaction gets broadcasted I get the following error: | |
{ | |
"code": -26, | |
"message": "non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation)", | |
} | |
""" | |
import hashlib | |
from bitcoin import SelectParams | |
from bitcoin.core import b2x, lx, COIN, COutPoint, CMutableTxOut, CMutableTxIn, CMutableTransaction, CTxInWitness, CTxWitness | |
from bitcoin.core.script import CScript, CScriptWitness, OP_0, OP_CHECKSIG, SignatureHash, SIGHASH_ALL, SIGVERSION_WITNESS_V0 | |
from bitcoin.wallet import CBitcoinSecret, CBitcoinAddress, P2WSHBitcoinAddress | |
SelectParams('signet') | |
# this is a passphrase of wallet tb1qhxy36055wje22qkxn4mtjl4k9vykcnq7avgtu3smnw6xpdxmw0qqjvywtn | |
# that currently holds 0.001 BTC on Signet | |
h = hashlib.sha256(b'asdf qnmioqa asdkln asdklj 12390u asddkln210ij kljnm1233iojfakjn ').digest() | |
seckey = CBitcoinSecret.from_secret_bytes(h) | |
txin_witnessScript = CScript([seckey.pub, OP_CHECKSIG]) | |
# https://explorer.bc-2.jp/tx/66f66e7f6aecde304560433ae29bbf73c096410757868203286a4916d7c0eb79 | |
txid = lx('66f66e7f6aecde304560433ae29bbf73c096410757868203286a4916d7c0eb79') | |
vout = 1 | |
# Specify the amount send to your P2WSH address. | |
amount = int(0.0001 * COIN) | |
# Calculate an amount for the upcoming new UTXO. Set a high fee (5%) to bypass | |
# bitcoind minfee setting. | |
amount_less_fee = amount * 0.95 | |
# Create the txin structure, which includes the outpoint. The scriptSig | |
# defaults to being empty as is necessary for spending a P2WSH output. | |
txin = CMutableTxIn(COutPoint(txid, vout)) | |
# Specify a destination address and create the txout. | |
destination_address = CBitcoinAddress('tb1qffmyyg5v9atg3zzvlafzzu22ht6cexj7xt8sx4yl0f6c3zktzqrq8hempj').to_scriptPubKey() | |
txout = CMutableTxOut(amount_less_fee, destination_address) | |
# Create the unsigned transaction. | |
tx = CMutableTransaction([txin], [txout]) | |
# Calculate the signature hash for that transaction. Note how the script we use is | |
# the witnessScript, not the redeemScript. | |
sighash = SignatureHash( | |
script=txin_witnessScript, | |
txTo=tx, | |
inIdx=0, | |
hashtype=SIGHASH_ALL, | |
amount=amount, | |
sigversion=SIGVERSION_WITNESS_V0, | |
) | |
# 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]) | |
# Construct a witness for this P2WSH transaction and add to tx. | |
witness = CScriptWitness([sig, txin_witnessScript]) | |
tx.wit = CTxWitness([CTxInWitness(witness)]) | |
# TODO: upgrade VerifyScript to support Segregated Witness and place verify the witness program here. | |
# Done! Print the transaction to standard output with the bytes-to-hex fn - this output has to be broadcasted manually | |
print(b2x(tx.serialize())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment