压缩比特币公钥地址转scriptPubKey?代码正确性验证求助
压缩比特币地址转scriptPubKey的问题与修正
问题描述
我想知道能否将压缩比特币地址转换为对应的scriptPubKey,以下是我用Python写的代码:
import base58 # Compressed public Bitcoin address addr = "1MY53uw7T3sLwL6FiGrM2LsiutSktmhSv2" # Decode Base58Check-encoded address to obtain public key hash decoded_addr = base58.b58decode_check(addr) pubkey_hash = decoded_addr[1:].hex() # Create script pubkey by adding prefix and suffix bytes prefix = "21" # Compressed public key prefix byte suffix = "ac" # P2PKH script suffix byte scriptpubkey = prefix + pubkey_hash + suffix # Print script pubkey in hexadecimal form print(scriptpubkey)
运行后输出:
210723a6c599ca6f0db6d95e6e33d6f961c4b4dbd5ac
我不确定代码是否有误,操作步骤如下:
- 解码Base58Check编码的地址:对地址"1MY53uw7T3sLwL6FiGrM2LsiutSktmhSv2"解码,得到21字节原始数据;
- 提取公钥哈希:首字节是版本字节(P2PKH地址应为0x00),后续20字节是公钥哈希
0723a6c599ca6f0db6d95e6e33d6f961c4b4dbd5; - 添加脚本前缀字节:加0x21(对应压缩公钥);
- 添加脚本后缀字节:加P2PKH脚本固定后缀0xac;
- 拼接得到scriptPubKey:
210723a6c599ca6f0db6d95e6e33d6f961c4b4dbd5ac。
请问操作是否有误?如何正确获取对应的scriptPubKey?
问题分析与修正
你的代码存在错误,核心问题是混淆了压缩公钥和公钥哈希的概念:
0x21是压缩公钥的长度标识(表示公钥为33字节),但P2PKH脚本的结构针对的是公钥哈希,而非原始公钥;- 正确的P2PKH scriptPubKey结构是:
OP_DUP OP_HASH160 <20-byte pubkey hash> OP_EQUALVERIFY OP_CHECKSIG,对应的十六进制格式为:76a914<20字节公钥哈希>88ac
修正后的代码
import base58 addr = "1MY53uw7T3sLwL6FiGrM2LsiutSktmhSv2" decoded_addr = base58.b58decode_check(addr) # 验证是否为P2PKH地址(版本字节应为0x00) if decoded_addr[0] != 0x00: raise ValueError("输入地址不是P2PKH格式") pubkey_hash = decoded_addr[1:].hex() # 拼接正确的P2PKH脚本结构 scriptpubkey = f"76a914{pubkey_hash}88ac" print(scriptpubkey)
输出解释
修正后的输出为:76a9140723a6c599ca6f0db6d95e6e33d6f961c4b4dbd588ac,对应的脚本指令含义:
76= OP_DUP:复制栈顶元素a9= OP_HASH160:对栈顶元素执行SHA-256+RIPEMD-160哈希运算14= 标记后续数据长度为20字节0723a6c599ca6f0db6d95e6e33d6f961c4b4dbd5= 提取出的公钥哈希88= OP_EQUALVERIFY:比较栈顶两个元素,相等则继续执行,否则终止ac= OP_CHECKSIG:验证签名有效性
原代码错误原因
你错误地将压缩公钥的长度标识用到了公钥哈希的脚本中。P2PKH脚本的结构是固定的,和公钥是否压缩无关——压缩公钥只是生成公钥哈希的原始输入不同,但最终P2PKH脚本都是基于公钥哈希的统一格式,不需要额外添加压缩公钥的前缀。
内容的提问来源于stack exchange,提问作者Melwyn
相关产品推荐
相关产品推荐

