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)