I’m learning how BTC works by writing a wallet.
The simplified code I got:
import hashlib
from embit import bech32
from binascii import b2a_base64, a2b_base64, hexlify, unhexlify
# List of sorted xpubs
sorted_xpubs = [
'02b713cc0d0fca02323d96e6538528215ca67b128ecdac4a56a43ac45ad937e988',
'038b00eba3c048cb9bd5e9d6d25065d2c86cfb45fe86f0c0f4093ccaf60a41234c',
'03b7a5fcf032765bf0b35e51c4974df0bbed8d099b79e8b15d293b876371906cf9'
]
# Function to create the witness script (sorted multi-sig 2-of-3)
def create_witness_script(sorted_xpubs):
# Convert sorted_xpubs to public keys (for simplicity using the raw sorted_xpubs here)
pubkeys = [bytes.fromhex(xpub) for xpub in sorted_xpubs]
# Construct the witness script: OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG
witness_script = b'\x52' # OP_2
witness_script += b''.join(pubkeys) # Public keys
witness_script += b'\x53' # OP_3
witness_script += b'\xae' # OP_CHECKMULTISIG
print(f"111 {hexlify(witness_script)}")
return witness_script
# Function to hash the witness script (SHA256)
def hash_witness_script(witness_script):
# First, compute SHA256 hash of the witness script
sha256_hash = hashlib.sha256(witness_script).digest()
return sha256_hash
# Function to generate the P2WSH address from the witness script
def generate_p2wsh_address(witness_script):
# Hash the witness script
script_hash = hash_witness_script(witness_script)
# Encode the script hash using Bech32 (for SegWit P2WSH)
# We use the 'bc' prefix (for Bitcoin) and version 0 (for P2WSH)
p2wsh_address = bech32.encode("bc", 0, script_hash)
return p2wsh_address
# Create the witness script
witness_script = create_witness_script(sorted_xpubs)
# Generate the P2WSH address
p2wsh_address = generate_p2wsh_address(witness_script)
# Print the result
print("Generated P2WSH SegWit Address:", p2wsh_address)
I got:
Generated P2WSH SegWit Address: bc1qgj3jyxugxm62whrzn7r6xrf7wtejzh2yxlv2cuzumltzpel9dcsssngq8t
When I checked with wallets like Sparrow or Specter, it should be
bc1q6rplrk6ykcrgwdh5shq78jhlupcpua5hed4jx4hahkljt0gwgwys8gyzp9
Could anyone point missing bits in the code?
Cheers