Bitcoin

Bitcoin Core – Verify P2WPKH using ECDSA

I’m trying to verify the P2WPKH input for a transaction. Here are the steps I figured out:

PKH verification has been completed using disclosure in the surveillance field. I’m having trouble verifying the signature (r,s) in the watch field. I wrote a Python script to verify signatures.

Here we created msg_hash which is wTxID and then verified it using ECDSA Python module.

Python code:

import hashlib
from ecdsa import VerifyingKey, SECP256k1, BadSignatureError

# Transaction data
txid = "47e49fb45d2940fd9e7a905cb76e42b51ce1e69d7b990ea3807e56d1c4bc8cd5"
version = 2
locktime = 0
vin = (
    
        "txid": "e221c00ae7e0f281186aba9ba95ba82decf4ed7fb9ca44cfaa55d8a565fa718a",
        "vout": 1,
        "prevout": 
            "scriptpubkey": "001402238ecb0e181baed0630e20c1d7792fec61ac51",
            "value": 935635,
        ,
        "sequence": 4294967293,
        "witness": (
            "3044022060df1324d76ab79f629fefc89649b55ff169dfcf29d14782df6df6b054a6434e022023c1f51d0799b65fea35263f4610f8872449f07a5d14190424ab51fd43e30ade01",
            "025a1154b245e08df4b7e17b70a35a79889329b9a296fb26b3b7f69e46998a3e2e",
        ),
    
)
vout = (
    "scriptpubkey": "0014b89a44fbd1f9229fb3ff8c4c86d5bd7e77ef9a27", "value": 43000,
    "scriptpubkey": "00142c9bcda388592e4ecae744e326a6c19a6cfca40b", "value": 889533,
)

# Serialize the transaction
serialized_tx = (
    bytes.fromhex(vin(0)("txid"))(::-1)
    + vin(0)("vout").to_bytes(4, byteorder="little")
    + bytes.fromhex(vin(0)("prevout")("scriptpubkey"))
    + vin(0)("sequence").to_bytes(4, byteorder="little")
    + vout(0)("value").to_bytes(8, byteorder="little")
    + bytes.fromhex(vout(0)("scriptpubkey"))
    + vout(1)("value").to_bytes(8, byteorder="little")
    + bytes.fromhex(vout(1)("scriptpubkey"))
    + locktime.to_bytes(4, byteorder="little")
)

# Calculate the transaction hash (msg_hash)
msg_hash = hashlib.sha256(serialized_tx).digest()

# Extract the signature and public key from the witness data
signature_hex = vin(0)("witness")(0)
public_key = bytes.fromhex(vin(0)("witness")(1))

# Extract the R and S values from the signature
r_hex = signature_hex(6:70)
s_hex = signature_hex(72:136)

# Create a VerifyingKey object
verifying_key = VerifyingKey.from_string(public_key, curve=SECP256k1)

# Verify the signature

if verifying_key.verify(
    bytes.fromhex(r_hex + s_hex),
    msg_hash,
    hashfunc=hashlib.sha256,
    sigdecode=bytes.fromhex,
):
    print("Signature is valid!")
else:
    print("Signature is invalid!")

The error displayed in the interpreter is:

p2wpkh_validation.py", line 57, in <module>
    if verifying_key.verify(
       ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/yuvraj/python.org/v3.11.5/lib/python3.11/site-packages/ecdsa/keys.py", line 685, in verify
    return self.verify_digest(signature, digest, sigdecode, allow_truncate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/yuvraj/python.org/v3.11.5/lib/python3.11/site-packages/ecdsa/keys.py", line 735, in verify_digest
    r, s = sigdecode(signature, self.pubkey.order)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: bytes.fromhex() takes exactly one argument (2 given)

Related Articles

Back to top button