示例工程区块链【免费下载链接】Dapp-LearningDapp learning project for developers at all stages. Becoming and cultivating sovereign individuals. Nonprofit organization.项目地址https://gitcode.com/gh_mirrors/da/Dapp-Learning点击查看免费下载P2PKHPay-to-Public-Key-Hash支付到公钥哈希是比特币最早也是最常见的交易输出类型本指南围绕 BTC/Basic/payment/P2PKH.md 展开深入剖析 P2PKH 的锁定/解锁脚本结构、脚本执行流程、地址生成全过程并结合本仓库的 JavaScript 示例代码与配套文档进行源码级验证。读完本文你将能够理解 P2PKH 交易从地址生成、脚本构造到签名广播的完整链路并能动手运行仓库中的脚本亲手验证。一、P2PKH 是什么P2PKH 是比特币网络中最常用的一种交易类型设计用来将比特币支付到某个具体的公钥哈希Public Key Hash而不是直接支付到公钥本身。这种方式提供了更高的安全性和隐私保护比特币被发送到一个地址这个地址实际上是持有者公钥的哈希版本。P2PKH 地址通常以数字1开头。地址不仅简洁而且通过哈希公钥隐藏了公钥的实际内容增加了隐私保护层——在花费资金之前收款方的公钥不会暴露在区块链上只有签名那一刻公钥才被揭示。提示P2PKH 属于比特币地址体系中的传统类别。在 支付方式总览 中可以看到比特币地址家族还包括以 3 开头的 P2SH-P2PKH、以 bc1q 开头的 P2WPKH隔离见证以及以 bc1p 开头的 P2TRTaprootP2PKH 是理解所有这些格式的基础。二、锁定脚本 ScriptPubKey比特币的每一笔交易输出都包含一个锁定脚本ScriptPubKey它规定了谁可以花费这笔钱的条件。P2PKH 脚本模式包含一个公钥哈希该哈希和以下操作码共同构成锁定脚本// 模版 OP_DUP OP_HASH160 Public Key Hash OP_EQUALVERIFY OP_CHECKSIG OP_DUP // 复制栈顶的元素 OP_HASH160 // 弹出栈顶元素计算其SHA-256散列然后计算RIPEMD-160散列 OP_PUSHBYTES_20 // 推送20字节的公钥哈希到栈顶 18e1fad25b2983d5dbb2e2b96e3ce756a69b3bc2 // 公钥哈希 OP_EQUALVERIFY // 比较栈顶元素是否匹配 OP_CHECKSIG // 验证数字签名各操作码的职责OP_DUP复制栈顶元素这里是花费者提供的公钥。OP_HASH160弹出栈顶元素先计算其 SHA-256 散列再计算 RIPEMD-160 散列得到公钥哈希即 HASH160 RIPEMD160(SHA256(x))。OP_PUSHBYTES_20向栈中推送 20 字节的公钥哈希。OP_EQUALVERIFY比较栈顶的两个元素是否相等若不相等则整个脚本验证立即失败。OP_CHECKSIG验证数字签名是脚本的最终把关环节。注意这里的公钥哈希是18e1fad25b2983d5dbb2e2b96e3ce756a69b3bc2这是一个 20 字节40 个十六进制字符的 HASH160 值它来源于签名教程中同一个公钥的哈希计算与 签名文档 中的示例保持了一致性。三、解锁脚本 ScriptSig要解锁花费此脚本上面公钥的所有者需要提供原始公钥以及有效的签名由对应的私钥对交易内容签名生成// 模版 Singature Public Key OP_PUSHBYTES_72 // 推送72字节到栈顶 3045022100c233c3a8a510e03ad18b0a24694ef00c78101bfd5ac075b8c1037952ce26e91e02205aa5f8f88f29bb4ad5808ebc12abfd26bd791256f367b04c6d955f01f28a772401 // 签名数据 OP_PUSHBYTES_33 // 推送33字节到栈顶 03480b6822120e9936b43859d84c380583c3d0292409b21453ae962815090f8117 // 压缩公钥签名数据30450221...772401是一个DER 编码的 ECDSA 签名末尾的01是签名哈希类型SIGHASH_ALL表示签名覆盖交易的所有输出其结构可拆解如下详见 签名文档 的签名分析一节字节含义30序列SEQUENCE开始45整个签名结构的长度69 字节02第一个整数r 值开始21r 值长度33 字节含前导 0 表示正数00c233...e91er 值02第二个整数s 值开始20s 值长度32 字节5aa5f8...7724s 值01SIGHASH 类型公钥03480b6822...f8117是一个 33 字节的压缩公钥以03开头表示 Y 坐标为奇数。这里使用的是 ECDSA 签名算法——比特币早期的交易认证完全建立在 ECDSA 之上其私钥签名、公钥验签的数学原理基于 secp256k1 椭圆曲线可以参阅 ECDSA 教程。四、脚本执行过程1. 脚本合并验证时节点将 ScriptSig 放在前面、ScriptPubKey 放在后面合并执行Singature Public Key OP_DUP OP_HASH160 Public Key Hash OP_EQUALVERIFY OP_CHECKSIG2. 栈内执行OP_DUP从栈里取出公钥复制一份并做 HASH160SHA-256 → RIPEMD-160将哈希结果推入栈顶OP_EQUALVERIFY对比上一步的计算结果和 ScriptPubKey 中嵌入的 Public Key Hash二者必须完全一致OP_CHECKSIG校验数字签名——检查提供的签名是否由对应私钥对交易内容签名生成。如果通过则锁定脚本合法可以花费对应 UTXO如果不通过交易失败。整个过程可以概括为三步证明公钥匹配哈希 → 证明私钥匹配公钥 → 放行资金。五、地址生成从公钥到 1 开头的地址P2PKH 支付方式从公钥生成地址遵循以下详细步骤步骤 1计算公钥哈希HASH160计算公钥的 SHA-256 哈希值对公钥进行 SHA-256 哈希运算计算 RIPEMD-160 哈希值对 SHA-256 的结果再进行 RIPEMD-160 哈希运算。这两步哈希运算的结果称为公钥哈希PKH即 HASH160 RIPEMD160(SHA256(pubkey))。步骤 2添加版本字节在公钥哈希前添加一个版本字节比特币主网的 P2PKH 地址版本字节是0x00测试网是0x6f。这有助于钱包软件识别和处理不同类型的地址。步骤 3计算校验和双重 SHA-256 哈希对版本字节 公钥哈希进行两次 SHA-256 哈希运算取前四个字节从双重哈希的结果中取出前四个字节这部分称为校验和checksum用于检测地址输入或传输中的错误。步骤 4生成地址将版本字节、公钥哈希和校验和组合在一起整个结构为[version byte][public key hash][checksum]然后对整个字节串进行Base58 编码Base58Check生成最终的 P2PKH 地址。示例假设有一个公钥生成地址的完整过程如下公钥022c3ee7cdb92394e32e82ec5bc8860c8888df6a9910537e90c75079726a2a8469SHA-256 哈希计算结果98a21cf747c0fcd80845afffa2260feb64aa7cc2b73ac681407b25229bad3bbcRIPEMD-160 哈希计算结果999ff7726530ed0d0a7eb3b7442c5143f643f638添加版本字节00 [RIPEMD-160 哈希结果]计算校验和对上述结果执行两次 SHA-256取前四个字节Base58 编码将最终字节串转换为 Base58 编码1F1J22NAAgnNHXNojT7W8GfP9JSXXjTV8N编码细节深入Base58 字符集123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz特意移除了视觉上易混淆的0零、O大写 O、I大写 I、l小写 L同时不包含标点符号便于抄写与分享详见 Base58 教程。版本字节与首字符的对应关系0x00前缀经 Base58 编码后以1开头这正是P2PKH 地址以 1 开头的由来同理0x05→3P2SH0x80→K/L/5WIF 私钥详见 Base58 前缀表。Base58Check 三步流程① 给原始数据添加对应前缀② 对结果执行两次 SHA-256取前四个字节做校验和③ 拼接后整体进行 Base58 编码。钱包收到地址后先解码、重算校验和比对即可发现输入错误。六、从地址到交易P2PKH 的完整使用链路支付方式总览 以 P2PKH 为例描述了从收款地址到交易完成的完整链路收款地址的获取收款方提供一个以1开头的 P2PKH 地址它是经过 Base58Check 编码的、包含收款方公钥哈希的字符串Base58Check 解码付款方解码地址提取其中的公钥哈希构建锁定脚本用提取出的公钥哈希构建 ScriptPubKey即OP_DUP OP_HASH160 Public Key Hash OP_EQUALVERIFY OP_CHECKSIG构建交易将锁定脚本放入新的交易输出并指定转账金额交易还需包含至少一个输入来自付款方以前的交易输出提供足够资金覆盖转账金额与矿工费签名和广播付款方用私钥对交易签名证明其有权使用输入资金然后将交易广播到比特币网络由矿工验证合法性并打包上链。源码级验证用 bitcoinjs-lib 亲手生成 P2PKH 地址仓库中的 地址生成脚本 使用bitcoinjs-lib、ecpair和tiny-secp256k1实际演示了 P2PKHLegacy地址的生成import ecpair from ecpair; import * as tinysecp from tiny-secp256k1; import bitcoin from bitcoinjs-lib; const { ECPairFactory } ecpair; const ECPair ECPairFactory(tinysecp); bitcoin.initEccLib(tinysecp); // 生成比特币私钥对 const keyPair ECPair.makeRandom({ network: bitcoin.networks.bitcoin }); // P2PKHLegacy地址生成 const address bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: bitcoin.networks.bitcoin }).address; console.log(Legacy Address:, address);运行方式安装依赖npm install bitcoinjs-lib ecpair tiny-secp256k1依赖版本参考 签名模块 package.jsonbitcoinjs-lib ^6.1.5、ecpair ^2.1.0、tiny-secp256k1 ^2.2.3然后执行node address.js。输出示例Legacy Address: 18RKdzEVDe6oCxrdeiipZGtKYWxTXmaxh3bitcoin.payments.p2pkh({ pubkey })这一行在库内部完成了本文第五部分描述的完整流程HASH160 计算公钥哈希 → 拼接版本字节 → 双重 SHA-256 取校验和 → Base58Check 编码。同一脚本还演示了p2sh嵌套隔离见证、p2wpkh原生隔离见证和p2trTaproot的生成方式方便对比不同地址类型详见 钱包脚本说明。源码级验证ECDSA 签名与 P2PKH 交易构建签名是 P2PKH 解锁脚本的核心要素。仓库中的 ecdsa.js 演示了完整的生成密钥 → 对交易哈希签名 → 验签流程const keyPair ECPair.makeRandom(); // 模拟真实交易的哈希 const txHash crypto.randomBytes(32); // 用私钥签名 const signature keyPair.sign(txHash); // 用公钥验证 const isValid keyPair.verify(txHash, signature); console.log(signature is valid:, isValid);而 ecdsaTransaction.js 更进一步演示了构建一笔带 P2PKH 输入的真实交易创建交易、添加输入引用 UTXO 的交易哈希与索引、添加输出接收地址与以聪为单位的金额、用私钥计算签名哈希并签名、最后把[signature, publicKey]编译成解锁脚本bitcoin.script.compile写入输入输出交易的十六进制表示。如果使用 ecdsaPSBT.js还可以体验更现代的标准从 WIF 私钥恢复密钥对通过PSBT部分签名比特币交易添加输入输出、签名、finalize 后提取原始交易适合多签协作等场景。七、P2PKH 的定位与安全性总结安全性地址只暴露公钥的哈希在花费之前公钥不公开为持有者增加了一层隐私保护破解公钥哈希以反推公钥或私钥在计算上不可行。隐私性相比直接暴露公钥的早期交易模式P2PKP2PKH 隐藏了公钥的实际内容。兼容性作为最古老的支付方式P2PKH 地址被所有钱包、交易所和基础设施普遍支持适合作为学习比特币脚本与交易的入门模型。对比与演进P2PKH 将公钥哈希放在 ScriptPubKey 中而隔离见证时代的 P2WPKH文档将签名与公钥移至见证字段、用 Bech32 编码教程交易体积更小、手续费更低Taproot 时代的 P2TR文档则通过 Schnorr 签名与 MAST 进一步统一了密钥路径与脚本路径的隐私。理解 P2PKH是理解这条技术演进主线的最佳起点。延伸阅读支付方式总览与地址类型对比P2SH-P2PKH以 3 开头的嵌套脚本哈希地址P2WPKH隔离见证原生地址P2TRTaproot 地址Base58 与 Base58Check 编码详解Bech32 编码与 PolyMod 校验算法ECDSA 与 Schnorr 数字签名教程比特币地址生成脚本bitcoinjs-libHD 钱包与密钥派生赞分享示例工程区块链【免费下载链接】Dapp-LearningDapp learning project for developers at all stages. Becoming and cultivating sovereign individuals. Nonprofit organization.项目地址https://gitcode.com/gh_mirrors/da/Dapp-Learning点击查看免费下载相关推荐btcd chainhash 包全解析比特币哈希抽象层与 SHA-256 双重哈希实现指南btcd chainhash 包全解析比特币哈希抽象层与 SHA 256 双重哈希实现指南 chainhash 是 btcdGo 语言编写的比特币全节点实现区块链上一篇免费开源桌面分区神器NoFences让你的Windows桌面焕然一新下一篇Node.js v14.13.0Current发布详解CJS 命名导出静态分析、exports 通配符模式与 libuv 1.40 升级创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考