Bitcoin
Spending – Learn how to spend non-standard scripts. Mainnet. 25,000 sat
I configured this code in Python using chatgpt. I worked really hard to learn, but I just can’t figure out how to spend without errors. All data required to create a raw transaction is provided below. I tried to use the first op_if condition. Post my code here. If someone can do it (and write it), it means I have to learn more and harder. Final transaction in hexadecimal format:
import hashlib
import ecdsa
def dSHA256(raw):
return hashlib.sha256(hashlib.sha256(raw).digest()).digest()
def create_signature(private_key_hex, message):
try:
private_key_bytes = bytes.fromhex(private_key_hex)
signing_key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1)
signature = signing_key.sign_digest(message, sigencode=ecdsa.util.sigencode_der_canonize)
return signature # Do not append SIGHASH_ALL here
except Exception as e:
print(f"Error creating signature: e")
return None
# Transaction version
version = (2).to_bytes(4, byteorder="little", signed=False)
# Input transaction (Outpoint)
txid = (bytes.fromhex("a1b1b291b076d90232a32638ad74f00ffd65cc355ca7e77b833ea0728ea07aab"))(::-1)
index = (164).to_bytes(4, byteorder="little", signed=False)
outpoint = txid + index
# Hashed outpoint
hashPrevOut = dSHA256(outpoint)
# Sequence
sequence = (0xfffffffe).to_bytes(4, byteorder="little", signed=False) # Use a value less than 0xffffffff
hashSequence = dSHA256(sequence)
# Amount being spent
amount = (int(0.00025297 * 100000000)).to_bytes(8, byteorder="little", signed=True)
# Output to the specified address
value = (int(0.00005297 * 100000000)).to_bytes(8, byteorder="little", signed=True)
scriptPubKey_hex = "00206cadc53e5157ac4f0c8e98d0011fd8ccd14378b846b1b944478b3437324b992e"
scriptPubKey = bytes.fromhex(scriptPubKey_hex)
output = value + (len(scriptPubKey)).to_bytes(1, byteorder="little", signed=False) + scriptPubKey
# Hashed output
hashOutput = dSHA256(output)
# nLockTime
nLockTime = (820000).to_bytes(4, byteorder="little", signed=False)
# Sighash type
sighash = bytes.fromhex("01000000")
# Public and private keys
private_key_hex = "2BF933A3FC415D4BA19D07F3F5FF641E645D1BDF70CFE1674D54C0E66AAA681F"
verifying_key = ecdsa.SigningKey.from_string(bytes.fromhex(private_key_hex), curve=ecdsa.SECP256k1).get_verifying_key()
x_cor = bytes.fromhex(verifying_key.to_string().hex())(:32)
y_cor = bytes.fromhex(verifying_key.to_string().hex())(32:)
public_key = bytes.fromhex("02" + x_cor.hex()) if int.from_bytes(y_cor, byteorder="big", signed=True) % 2 == 0 else bytes.fromhex("03" + x_cor.hex())
# WitnessScript
witnessScript = bytes.fromhex("630320830cb17521024e24d2aff4e1c51eaf122e0e5a6dfe218f7b3b883d1eb537ce9a7e040b329ca5ac6703b0830cb17521030618b7d1a6747cb13bba78611646a8d08c3683e14a0d2a4483c877561e1416efac68")
scriptCode = witnessScript
# Transaction digest for signature
bip_143 = version + hashPrevOut + hashSequence + outpoint + scriptCode + amount + sequence + hashOutput + nLockTime + sighash
hashed_bip_143 = dSHA256(bip_143)
# Signature
signature = create_signature(private_key_hex, hashed_bip_143)
# Print the DER-encoded signature in hexadecimal form
print("Signature (DER-encoded) in hexadecimal form:", signature.hex())
# Append SIGHASH_ALL to the signature
signature += bytes.fromhex("01")
# Witness construction for the first branch of OP_IF
minimal_true = bytes.fromhex("01") # Minimal push of true
witness = (
bytes.fromhex("04") # Number of elements in the witness
+ (len(signature)).to_bytes(1, byteorder="little", signed=False) + signature
+ (len(public_key)).to_bytes(1, byteorder="little", signed=False) + public_key
+ (len(minimal_true)).to_bytes(1, byteorder="little", signed=False) + minimal_true
+ (len(witnessScript)).to_bytes(1, byteorder="little", signed=False) + witnessScript
)
# Transaction input and output counts
tx_in_count = (1).to_bytes(1, byteorder="little", signed=False)
tx_out_count = (1).to_bytes(1, byteorder="little", signed=False)
# Marker and Flag for SegWit
marker = bytes.fromhex("00")
flag = bytes.fromhex("01")
# Final transaction assembly
final_tx = (
version
+ marker
+ flag
+ tx_in_count
+ outpoint
+ (0).to_bytes(1, byteorder="little", signed=False) # ScriptSig is empty for SegWit inputs
+ sequence
+ tx_out_count
+ output
+ witness
+ nLockTime
)
# Print the final transaction hex
print("Final transaction in hexadecimal form:", final_tx.hex())