From fe2f40252fa3c65d0be000b361ed938fd7bc3494 Mon Sep 17 00:00:00 2001 From: ygcl9698 Date: Sun, 13 Apr 2025 18:56:50 +0800 Subject: [PATCH 1/5] feat: Segwit --- BTC/Basic/SegWit/README.md | 121 +++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 BTC/Basic/SegWit/README.md diff --git a/BTC/Basic/SegWit/README.md b/BTC/Basic/SegWit/README.md new file mode 100644 index 000000000..b03322f3c --- /dev/null +++ b/BTC/Basic/SegWit/README.md @@ -0,0 +1,121 @@ +# 隔离见证 (SegWit) + +## 什么是隔离见证? + +隔离见证(Segregated Witness,简称SegWit)是比特币协议的一项重大升级,于2017年8月通过软分叉方式激活。这项技术通过将交易的签名数据(见证数据)与交易数据分离,解决了比特币网络中的一些关键问题,并为未来的扩展性改进奠定了基础。 + +## 隔离见证的工作原理 + +### 传统交易结构的问题 + +在SegWit之前,比特币交易的结构将交易数据和签名数据(见证数据)存储在同一区块内。这种设计存在几个问题: + +1. **交易延展性**:交易ID(txid)是根据整个交易数据(包括签名)计算的。由于签名数据可以在不改变交易有效性的情况下被修改,这就导致了交易ID可能在交易被确认前发生变化,称为"交易延展性"问题。 + +2. **区块空间效率低**:签名数据通常占据交易大小的很大一部分,但对于验证交易历史并不总是必需的。 + +### SegWit的解决方案 + +SegWit通过以下方式解决这些问题: + +1. **分离见证数据**:将签名数据(见证数据)从交易的主要部分移出,存储在交易结构的单独部分。 + +2. **新的交易ID计算方式**:引入了一个新的交易ID计算方式(wtxid),同时保留了向后兼容的txid计算方式。新的txid不包含签名数据,因此消除了交易延展性问题。 + +3. **区块权重计算**:引入了一个新的"区块权重"概念,使得见证数据在计算区块大小时的权重较低,从而有效增加了每个区块可以包含的交易数量。 + +## SegWit的主要优势 + +### 1. 解决交易延展性 + +通过将签名数据从交易ID计算中分离出来,SegWit彻底解决了交易延展性问题。这对于构建依赖于未确认交易的复杂交易链(如闪电网络)至关重要。 + +### 2. 增加区块容量 + +SegWit通过引入区块权重概念,使得每个区块可以包含更多的交易。理论上,SegWit可以将区块容量提高到约2.1MB到4MB,而不需要增加传统的1MB区块大小限制。 + +### 3. 降低交易费用 + +由于每个区块可以包含更多交易,网络拥堵情况得到缓解,从而降低了交易费用。使用SegWit地址的交易通常比传统地址的交易费用更低。 + +### 4. 为二层解决方案铺平道路 + +SegWit的实施为闪电网络等二层扩展解决方案的开发和部署创造了条件,这些解决方案可以显著提高比特币的交易吞吐量和用户体验。 + +### 5. 脚本版本控制 + +SegWit引入了脚本版本控制机制,使得未来可以更容易地引入新的脚本功能,如Taproot等高级功能。 + +## SegWit地址类型 + +SegWit引入了两种主要的地址类型: + +### 1. P2SH-P2WPKH(兼容地址) + +这种地址以"3"开头,与传统的P2SH地址外观相同。它是一种过渡性解决方案,允许旧钱包向SegWit地址发送交易,同时享受SegWit的部分好处。 + +### 2. P2WPKH(原生SegWit地址) + +这种地址以"bc1q"开头,使用Bech32编码格式。原生SegWit地址提供了SegWit的全部好处,包括更低的交易费用和更好的安全性。 + +## SegWit的采用情况 + +自2017年激活以来,SegWit的采用率稳步增长。截至2023年,超过80%的比特币交易使用了SegWit,这显著提高了网络的整体效率和容量。 + +## SegWit与闪电网络的关系 + +SegWit解决了交易延展性问题,这是实现闪电网络等二层解决方案的关键前提。闪电网络依赖于能够创建依赖于未确认交易的交易链,而没有SegWit,这将是不可靠的。 + +## 代码示例:创建SegWit地址和交易 + +以下是使用JavaScript和bitcoinjs-lib库创建SegWit地址和交易的简单示例: + +```javascript +const bitcoin = require('bitcoinjs-lib'); +const network = bitcoin.networks.bitcoin; // 主网 + +// 创建密钥对 +const keyPair = bitcoin.ECPair.makeRandom({ network }); + +// 创建P2WPKH(原生SegWit)地址 +const { address } = bitcoin.payments.p2wpkh({ + pubkey: keyPair.publicKey, + network +}); + +console.log('SegWit地址:', address); // 输出以bc1q开头的地址 + +// 构建SegWit交易(简化示例) +async function createSegWitTransaction(utxo, toAddress, amount, fee) { + const txb = new bitcoin.TransactionBuilder(network); + + // 添加输入(来自SegWit地址的UTXO) + txb.addInput(utxo.txid, utxo.vout); + + // 添加输出 + txb.addOutput(toAddress, amount); + + // 如果有找零,添加找零输出 + const change = utxo.value - amount - fee; + if (change > 0) { + txb.addOutput(address, change); + } + + // 签名交易(SegWit特有的签名方式) + txb.sign(0, keyPair, null, null, utxo.value); + + // 构建并返回交易 + const tx = txb.build(); + return tx.toHex(); +} +``` + +## 结论 + +隔离见证是比特币历史上最重要的技术升级之一,它不仅解决了交易延展性等关键问题,还提高了网络的交易容量和效率,同时为闪电网络等创新解决方案铺平了道路。随着越来越多的用户和服务采用SegWit,比特币网络的性能和可用性将继续提高。 + +## 参考资料 + +1. [BIP 141: Segregated Witness](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) +2. [BIP 143: Transaction Signature Verification for Version 0 Witness Program](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki) +3. [BIP 173: Base32 address format for native v0-16 witness outputs](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) From a533ffca8e3a0c7d56ab86ab86e3f03c619f3dcd Mon Sep 17 00:00:00 2001 From: ygcl9698 Date: Sun, 13 Apr 2025 19:15:28 +0800 Subject: [PATCH 2/5] feat: add example --- BTC/Basic/SegWit/README.md | 69 +++++----- BTC/Basic/SegWit/example.js | 247 ++++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 40 deletions(-) create mode 100644 BTC/Basic/SegWit/example.js diff --git a/BTC/Basic/SegWit/README.md b/BTC/Basic/SegWit/README.md index b03322f3c..374aeb38c 100644 --- a/BTC/Basic/SegWit/README.md +++ b/BTC/Basic/SegWit/README.md @@ -68,46 +68,35 @@ SegWit解决了交易延展性问题,这是实现闪电网络等二层解决 ## 代码示例:创建SegWit地址和交易 -以下是使用JavaScript和bitcoinjs-lib库创建SegWit地址和交易的简单示例: - -```javascript -const bitcoin = require('bitcoinjs-lib'); -const network = bitcoin.networks.bitcoin; // 主网 - -// 创建密钥对 -const keyPair = bitcoin.ECPair.makeRandom({ network }); - -// 创建P2WPKH(原生SegWit)地址 -const { address } = bitcoin.payments.p2wpkh({ - pubkey: keyPair.publicKey, - network -}); - -console.log('SegWit地址:', address); // 输出以bc1q开头的地址 - -// 构建SegWit交易(简化示例) -async function createSegWitTransaction(utxo, toAddress, amount, fee) { - const txb = new bitcoin.TransactionBuilder(network); - - // 添加输入(来自SegWit地址的UTXO) - txb.addInput(utxo.txid, utxo.vout); - - // 添加输出 - txb.addOutput(toAddress, amount); - - // 如果有找零,添加找零输出 - const change = utxo.value - amount - fee; - if (change > 0) { - txb.addOutput(address, change); - } - - // 签名交易(SegWit特有的签名方式) - txb.sign(0, keyPair, null, null, utxo.value); - - // 构建并返回交易 - const tx = txb.build(); - return tx.toHex(); -} +代码示例文件:[examples.js](./example.js) + +该示例文件包含以下功能: + +1. **创建不同类型的SegWit地址**: + - P2WPKH(原生SegWit)地址 - 以bc1q开头 + - P2SH-P2WPKH(兼容SegWit)地址 - 以3开头 + - P2WSH(原生SegWit脚本哈希)地址 + +2. **构建SegWit交易**: + - 支持原生SegWit和兼容SegWit交易 + - 处理输入、输出和找零 + +3. **计算SegWit交易ID**: + - 计算传统txid(不包含见证数据) + - 计算wtxid(包含见证数据) + +4. **估算SegWit交易的大小和费用**: + - 根据输入输出数量和地址类型估算交易大小 + - 计算建议的交易费用 + +5. **验证SegWit地址**: + - 检查地址是否为有效的SegWit地址 + - 识别地址类型(原生SegWit、兼容SegWit或传统地址) + +要使用这些示例,您需要安装bitcoinjs-lib库: + +```bash +npm install bitcoinjs-lib ``` ## 结论 diff --git a/BTC/Basic/SegWit/example.js b/BTC/Basic/SegWit/example.js new file mode 100644 index 000000000..4746e82f3 --- /dev/null +++ b/BTC/Basic/SegWit/example.js @@ -0,0 +1,247 @@ +/** + * SegWit (隔离见证) 代码示例 + * + * 本文件包含与比特币隔离见证(SegWit)相关的JavaScript代码示例, + * 使用bitcoinjs-lib库演示如何创建SegWit地址和交易。 + */ + +const bitcoin = require('bitcoinjs-lib'); +const network = bitcoin.networks.bitcoin; // 主网 + +/** + * 创建不同类型的SegWit地址 + */ +function createSegWitAddresses() { + // 创建密钥对 + const keyPair = bitcoin.ECPair.makeRandom({ network }); + const publicKey = keyPair.publicKey; + + // 1. 创建P2WPKH(原生SegWit)地址 - 以bc1q开头 + const p2wpkh = bitcoin.payments.p2wpkh({ + pubkey: publicKey, + network + }); + + // 2. 创建P2SH-P2WPKH(兼容SegWit)地址 - 以3开头 + const p2sh_p2wpkh = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({ pubkey: publicKey, network }), + network + }); + + // 3. 创建P2WSH(原生SegWit脚本哈希)地址 + // 创建一个2-of-3多签名赎回脚本 + const pubkeys = [ + bitcoin.ECPair.makeRandom({ network }).publicKey, + bitcoin.ECPair.makeRandom({ network }).publicKey, + bitcoin.ECPair.makeRandom({ network }).publicKey + ]; + + const p2ms = bitcoin.payments.p2ms({ + m: 2, // 需要2个签名 + pubkeys, + network + }); + + const p2wsh = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }); + + return { + privateKey: keyPair.privateKey.toString('hex'), + publicKey: publicKey.toString('hex'), + p2wpkh: { + address: p2wpkh.address, // 原生SegWit地址 + type: 'P2WPKH (Native SegWit)' + }, + p2sh_p2wpkh: { + address: p2sh_p2wpkh.address, // 兼容SegWit地址 + type: 'P2SH-P2WPKH (Compatible SegWit)' + }, + p2wsh: { + address: p2wsh.address, // 原生SegWit脚本哈希地址 + type: 'P2WSH (Native SegWit Script Hash)' + } + }; +} + +/** + * 构建SegWit交易 + * @param {Object} utxo - 未花费交易输出 + * @param {string} toAddress - 接收地址 + * @param {number} amount - 发送金额(聪) + * @param {number} fee - 交易费(聪) + * @param {Object} keyPair - 密钥对 + * @param {string} changeAddress - 找零地址 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh') + * @returns {string} 交易的十六进制表示 + */ +async function createSegWitTransaction(utxo, toAddress, amount, fee, keyPair, changeAddress, addressType = 'p2wpkh') { + const txb = new bitcoin.TransactionBuilder(network); + + // 添加输入(来自SegWit地址的UTXO) + txb.addInput(utxo.txid, utxo.vout); + + // 添加输出 + txb.addOutput(toAddress, amount); + + // 如果有找零,添加找零输出 + const change = utxo.value - amount - fee; + if (change > 0) { + txb.addOutput(changeAddress || utxo.address, change); + } + + // 根据地址类型签名交易 + if (addressType === 'p2wpkh') { + // 原生SegWit地址签名 + txb.sign(0, keyPair, null, null, utxo.value); + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit地址签名 + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network }); + txb.sign(0, keyPair, p2sh.redeem.output, null, utxo.value); + } + + // 构建并返回交易 + const tx = txb.build(); + return tx.toHex(); +} + +/** + * 计算SegWit交易的交易ID + * @param {string} txHex - 交易的十六进制表示 + * @returns {Object} 包含txid和wtxid的对象 + */ +function calculateSegWitTransactionId(txHex) { + const tx = bitcoin.Transaction.fromHex(txHex); + + // 计算传统txid(不包含见证数据) + const txid = tx.getId(); + + // 计算wtxid(包含见证数据) + const wtxid = tx.getHash(true).reverse().toString('hex'); + + return { + txid, + wtxid, + isSame: txid === wtxid + }; +} + +/** + * 估算SegWit交易的大小和费用 + * @param {number} inputCount - 输入数量 + * @param {number} outputCount - 输出数量 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh') + * @param {number} feeRate - 费率(聪/字节) + * @returns {Object} 包含大小和费用的对象 + */ +function estimateSegWitTransactionFee(inputCount, outputCount, addressType = 'p2wpkh', feeRate = 10) { + let txSize = 0; + + // 计算交易大小(近似值) + if (addressType === 'p2wpkh') { + // 原生SegWit (P2WPKH) 交易大小估算 + // 基本交易大小 + 输入大小 + 输出大小 + txSize = 10 + (inputCount * 67.75) + (outputCount * 31); + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit (P2SH-P2WPKH) 交易大小估算 + txSize = 10 + (inputCount * 91) + (outputCount * 31); + } else { + // 传统 (P2PKH) 交易大小估算 + txSize = 10 + (inputCount * 148) + (outputCount * 34); + } + + // 计算费用 + const fee = Math.ceil(txSize * feeRate); + + return { + estimatedSize: txSize, + estimatedFee: fee, + feeRate: feeRate + }; +} + +/** + * 验证地址是否为SegWit地址 + * @param {string} address - 比特币地址 + * @returns {Object} 包含验证结果的对象 + */ +function validateSegWitAddress(address) { + try { + // 尝试解析地址 + const result = bitcoin.address.fromBase58Check(address); + + // 检查是否为P2SH地址(可能是P2SH-P2WPKH) + if (result.version === network.scriptHash) { + return { + isValid: true, + type: 'P2SH (可能是P2SH-P2WPKH兼容SegWit)', + isSegWit: 'Compatible' + }; + } + + return { + isValid: true, + type: 'P2PKH (传统地址)', + isSegWit: false + }; + } catch (e) { + // 如果不是Base58地址,尝试Bech32 + try { + const result = bitcoin.address.fromBech32(address); + + if (result.version === 0) { + if (result.data.length === 20) { + return { + isValid: true, + type: 'P2WPKH (原生SegWit)', + isSegWit: 'Native' + }; + } else if (result.data.length === 32) { + return { + isValid: true, + type: 'P2WSH (原生SegWit脚本哈希)', + isSegWit: 'Native' + }; + } + } + + return { + isValid: true, + type: '未知的Bech32地址', + isSegWit: 'Unknown' + }; + } catch (e) { + return { + isValid: false, + type: '无效地址', + isSegWit: false + }; + } + } +} + +// 导出函数 +module.exports = { + createSegWitAddresses, + createSegWitTransaction, + calculateSegWitTransactionId, + estimateSegWitTransactionFee, + validateSegWitAddress +}; + +// 使用示例 +/* +// 创建SegWit地址 +const addresses = createSegWitAddresses(); +console.log('SegWit地址:', addresses); + +// 验证地址 +const addressValidation = validateSegWitAddress('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'); +console.log('地址验证结果:', addressValidation); + +// 估算交易费用 +const feeEstimation = estimateSegWitTransactionFee(2, 2, 'p2wpkh', 5); +console.log('费用估算:', feeEstimation); +*/ \ No newline at end of file From 07772723270c4eefb7067b9279a473a8e8563c53 Mon Sep 17 00:00:00 2001 From: ygcl9698 Date: Mon, 14 Apr 2025 15:40:26 +0800 Subject: [PATCH 3/5] feat: supplement README --- BTC/Basic/SegWit/README.md | 131 +++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/BTC/Basic/SegWit/README.md b/BTC/Basic/SegWit/README.md index 374aeb38c..e79a73b74 100644 --- a/BTC/Basic/SegWit/README.md +++ b/BTC/Basic/SegWit/README.md @@ -4,6 +4,8 @@ 隔离见证(Segregated Witness,简称SegWit)是比特币协议的一项重大升级,于2017年8月通过软分叉方式激活。这项技术通过将交易的签名数据(见证数据)与交易数据分离,解决了比特币网络中的一些关键问题,并为未来的扩展性改进奠定了基础。 +隔离见证的名称直接反映了其核心概念:将交易的"见证"(witness,即签名数据)从交易的主要部分"隔离"(segregate)出来。这种结构上的变化不仅解决了技术问题,还为比特币网络带来了显著的性能和安全性提升。 + ## 隔离见证的工作原理 ### 传统交易结构的问题 @@ -66,12 +68,28 @@ SegWit引入了两种主要的地址类型: SegWit解决了交易延展性问题,这是实现闪电网络等二层解决方案的关键前提。闪电网络依赖于能够创建依赖于未确认交易的交易链,而没有SegWit,这将是不可靠的。 +### 闪电网络如何依赖SegWit + +1. **交易延展性解决**:闪电网络需要创建相互依赖的交易链,如果交易ID可以被修改(延展性问题),整个交易链将失效。SegWit通过将签名数据分离,确保交易ID不受签名数据影响,从而解决了这个问题。 + +2. **通道资金交易**:闪电网络通道通常使用2-of-2多签名SegWit地址(P2WSH)来锁定资金。这种设计既提供了安全性,又享受了SegWit的费用优势。 + +3. **HTLC实现**:闪电网络中的哈希时间锁定合约(HTLC)依赖于SegWit提供的脚本版本控制功能,使得复杂的条件支付成为可能。 + +4. **通道关闭效率**:当闪电网络通道关闭时,最终结算交易会广播到比特币区块链。使用SegWit可以降低这些交易的费用,提高结算效率。 + +### 实际应用示例 + +本示例代码中的`createLightningChannelFundingTx`函数展示了如何创建一个与闪电网络兼容的通道资金交易,这是建立闪电网络通道的第一步。 + ## 代码示例:创建SegWit地址和交易 代码示例文件:[examples.js](./example.js) 该示例文件包含以下功能: +### 基础功能 + 1. **创建不同类型的SegWit地址**: - P2WPKH(原生SegWit)地址 - 以bc1q开头 - P2SH-P2WPKH(兼容SegWit)地址 - 以3开头 @@ -93,16 +111,129 @@ SegWit解决了交易延展性问题,这是实现闪电网络等二层解决 - 检查地址是否为有效的SegWit地址 - 识别地址类型(原生SegWit、兼容SegWit或传统地址) +### 高级功能 + +6. **批量生成SegWit地址**: + - 一次性生成多个SegWit地址 + - 支持不同类型的SegWit地址批量生成 + +7. **批量处理SegWit交易**: + - 处理多个输入和输出 + - 自动计算交易费用和找零 + +8. **创建SegWit多签名地址**: + - 支持m-of-n多签名方案 + - 支持原生P2WSH和兼容P2SH-P2WSH多签名地址 + +9. **创建闪电网络通道资金交易**: + - 创建与闪电网络兼容的2-of-2多签名SegWit地址 + - 构建通道资金交易 + 要使用这些示例,您需要安装bitcoinjs-lib库: ```bash npm install bitcoinjs-lib ``` +## SegWit的最佳实践 + +### 地址选择 + +1. **优先使用原生SegWit地址(bc1开头)**: + - 提供最低的交易费用 + - 最佳的安全性和性能 + - 适用于支持Bech32地址格式的现代钱包和交易所 + +2. **兼容性考虑**: + - 如果需要与旧钱包或服务兼容,可以使用P2SH-P2WPKH地址(3开头) + - 虽然费用优势略低于原生SegWit,但仍优于传统地址 + +3. **多签名场景**: + - 对于多签名钱包,P2WSH(原生)或P2SH-P2WSH(兼容)提供了更高的安全性和更低的费用 + - 复杂脚本应优先考虑SegWit版本,以获得费用优势 + +### 交易构建 + +1. **费用估算**: + - 使用`estimateSegWitTransactionFee`函数准确估算交易费用 + - SegWit交易的费用计算与传统交易不同,正确估算可避免支付过高费用 + +2. **批量处理**: + - 当需要处理多个交易时,使用`batchSegWitTransaction`函数可以更有效地管理UTXO + - 批量处理可以优化交易费用和UTXO集合管理 + +3. **与闪电网络集成**: + - 使用`createLightningChannelFundingTx`函数创建与闪电网络兼容的通道资金交易 + - 确保通道资金交易使用正确的多签名脚本格式 + +## 实际应用场景 + +### 1. 交易所集成 + +交易所可以通过实现SegWit来显著降低提款交易的费用,同时提高交易处理速度: + +```javascript +// 交易所批量处理提款示例 +const withdrawals = [ + { address: 'bc1q...', amount: 1000000 }, // 用户A提款 + { address: 'bc1q...', amount: 2500000 }, // 用户B提款 + // 更多提款... +]; + +const tx = batchSegWitTransaction(availableUTXOs, withdrawals, exchangeKeyPair, exchangeChangeAddress, 'p2wpkh'); +// 广播交易... +``` + +### 2. 钱包应用 + +钱包应用可以提供多种地址类型选择,并解释每种类型的优缺点: + +```javascript +// 为用户生成不同类型的地址 +const addressOptions = { + legacy: bitcoin.payments.p2pkh({ pubkey: userKeyPair.publicKey, network }).address, + segwitCompatible: bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({ pubkey: userKeyPair.publicKey, network }), + network + }).address, + segwitNative: bitcoin.payments.p2wpkh({ pubkey: userKeyPair.publicKey, network }).address +}; +``` + +### 3. 多签名钱包 + +企业和组织可以使用SegWit多签名地址来增强资金安全性: + +```javascript +// 创建3-of-5多签名企业钱包 +const corporateWallet = createSegWitMultisigAddress(3, 5, 'p2wsh'); +// 保存地址和赎回脚本信息... +``` + +### 4. 闪电网络节点 + +运行闪电网络节点的用户可以使用SegWit来创建通道资金交易: + +```javascript +// 开设新的闪电网络通道 +const channelFunding = createLightningChannelFundingTx( + selectedUTXO, + localNodePubkey, + remoteNodePubkey, + myChannelAmount, + theirChannelAmount, + myKeyPair, + estimatedFee +); +// 广播资金交易并等待确认... +``` + ## 结论 隔离见证是比特币历史上最重要的技术升级之一,它不仅解决了交易延展性等关键问题,还提高了网络的交易容量和效率,同时为闪电网络等创新解决方案铺平了道路。随着越来越多的用户和服务采用SegWit,比特币网络的性能和可用性将继续提高。 +通过本示例代码,开发者可以轻松实现SegWit的各种功能,从基本的地址生成到复杂的多签名和闪电网络集成。这些工具为构建现代、高效的比特币应用提供了坚实的基础。 + ## 参考资料 1. [BIP 141: Segregated Witness](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) From 8b0e5359766c72e86b5d6598400dfaa252267995 Mon Sep 17 00:00:00 2001 From: ygcl9698 Date: Thu, 17 Apr 2025 11:26:37 +0800 Subject: [PATCH 4/5] feat: add extend knowledge --- BTC/Basic/SegWit/README.md | 100 ++- BTC/Basic/SegWit/example-extended.js | 874 +++++++++++++++++++++++++++ 2 files changed, 969 insertions(+), 5 deletions(-) create mode 100644 BTC/Basic/SegWit/example-extended.js diff --git a/BTC/Basic/SegWit/README.md b/BTC/Basic/SegWit/README.md index e79a73b74..9c8b03c8c 100644 --- a/BTC/Basic/SegWit/README.md +++ b/BTC/Basic/SegWit/README.md @@ -64,15 +64,105 @@ SegWit引入了两种主要的地址类型: 自2017年激活以来,SegWit的采用率稳步增长。截至2023年,超过80%的比特币交易使用了SegWit,这显著提高了网络的整体效率和容量。 -## SegWit与闪电网络的关系 +### 采用率数据 -SegWit解决了交易延展性问题,这是实现闪电网络等二层解决方案的关键前提。闪电网络依赖于能够创建依赖于未确认交易的交易链,而没有SegWit,这将是不可靠的。 +| 年份 | 采用率 | +|------|--------| +| 2017 | ~10% | +| 2018 | ~30% | +| 2019 | ~50% | +| 2020 | ~65% | +| 2021 | ~75% | +| 2022 | ~80% | +| 2023 | ~85% | -### 闪电网络如何依赖SegWit +### 按地址类型分布 -1. **交易延展性解决**:闪电网络需要创建相互依赖的交易链,如果交易ID可以被修改(延展性问题),整个交易链将失效。SegWit通过将签名数据分离,确保交易ID不受签名数据影响,从而解决了这个问题。 +当前比特币网络中的地址类型分布大致如下: -2. **通道资金交易**:闪电网络通道通常使用2-of-2多签名SegWit地址(P2WSH)来锁定资金。这种设计既提供了安全性,又享受了SegWit的费用优势。 +- 原生SegWit地址 (P2WPKH/P2WSH): ~45% +- 兼容SegWit地址 (P2SH-P2WPKH): ~15% +- Taproot地址 (P2TR): ~25% +- 传统地址 (P2PKH/P2SH): ~15% + +这一趋势表明,比特币生态系统正在逐步迁移到更高效的地址类型,特别是随着Taproot的激活,更多用户开始采用这一基于SegWit v1的新技术。 + +### 性能数据对比 + +不同地址类型的交易大小和费用对比(假设费率为10聪/字节): + +| 交易类型 | 传统地址 (P2PKH) | 兼容SegWit (P2SH-P2WPKH) | 原生SegWit (P2WPKH) | Taproot (P2TR) | +|---------|-----------------|------------------------|-------------------|----------------| +| 1输入1输出 | 192字节 / 1,920聪 | 132字节 / 1,320聪 | 109字节 / 1,090聪 | 98字节 / 980聪 | +| 2输入2输出 | 374字节 / 3,740聪 | 254字节 / 2,540聪 | 208字节 / 2,080聪 | 186字节 / 1,860聪 | + +这些数据显示,与传统地址相比: +- 原生SegWit地址可节省约45%的交易费用 +- 兼容SegWit地址可节省约30%的交易费用 +- Taproot地址可节省约50%的交易费用 + +### 区块容量提升 + +- 传统区块:最大1MB,约容纳2,000笔交易 +- SegWit区块:最大可达4MB,约容纳4,000-8,000笔交易 + +这种容量提升使得比特币网络的吞吐量从传统的3-7 TPS (每秒交易数) 提高到了7-14 TPS。 + +## SegWit的技术实现细节 + +### 交易序列化格式 + +SegWit引入了一种新的交易序列化格式,这是理解其工作原理的关键。下面比较传统交易和SegWit交易的序列化格式: + +#### 传统交易格式 +``` +[4字节] 版本 +[变长] 输入数量 +[输入列表] 每个输入包含: + [32字节] 上一笔交易ID + [4字节] 输出索引 + [变长] 脚本长度 + [变长] 脚本(包含签名数据) + [4字节] 序列号 +[变长] 输出数量 +[输出列表] 每个输出包含: + [8字节] 金额 + [变长] 脚本长度 + [变长] 脚本 +[4字节] 锁定时间 +``` + +#### SegWit交易格式 +``` +[4字节] 版本 +[1字节] 标记 (0x00) +[1字节] 标志 (0x01) +[变长] 输入数量 +[输入列表] 每个输入包含: + [32字节] 上一笔交易ID + [4字节] 输出索引 + [变长] 脚本长度 + [变长] 脚本(不包含签名数据) + [4字节] 序列号 +[变长] 输出数量 +[输出列表] 每个输出包含: + [8字节] 金额 + [变长] 脚本长度 + [变长] 脚本 +[见证数据] 每个输入的见证数据: + [变长] 见证数据项数量 + [变长] 见证数据(签名、公钥等) +[4字节] 锁定时间 +``` + +关键区别: +1. SegWit交易添加了标记(0x00)和标志(0x01)字节 +2. 签名数据从输入脚本移到了交易末尾的见证数据部分 +3. 交易ID计算不包括见证数据,解决了交易延展性问题 + +### 区块权重计算 + +SegWit引入了"区块权重 3. **HTLC实现**:闪电网络中的哈希时间锁定合约(HTLC)依赖于SegWit提供的脚本版本控制功能,使得复杂的条件支付成为可能。 diff --git a/BTC/Basic/SegWit/example-extended.js b/BTC/Basic/SegWit/example-extended.js new file mode 100644 index 000000000..be43ff535 --- /dev/null +++ b/BTC/Basic/SegWit/example-extended.js @@ -0,0 +1,874 @@ +/** + * SegWit (隔离见证) 扩展代码示例 + * + * 本文件包含与比特币隔离见证(SegWit)相关的JavaScript代码示例, + * 使用bitcoinjs-lib库演示如何创建SegWit地址和交易,以及高级功能。 + */ + +const bitcoin = require('bitcoinjs-lib'); +const network = bitcoin.networks.bitcoin; // 主网 + +/** + * 创建不同类型的SegWit地址 + */ +function createSegWitAddresses() { + // 创建密钥对 + const keyPair = bitcoin.ECPair.makeRandom({ network }); + const publicKey = keyPair.publicKey; + + // 1. 创建P2WPKH(原生SegWit)地址 - 以bc1q开头 + const p2wpkh = bitcoin.payments.p2wpkh({ + pubkey: publicKey, + network + }); + + // 2. 创建P2SH-P2WPKH(兼容SegWit)地址 - 以3开头 + const p2sh_p2wpkh = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({ pubkey: publicKey, network }), + network + }); + + // 3. 创建P2WSH(原生SegWit脚本哈希)地址 + // 创建一个2-of-3多签名赎回脚本 + const pubkeys = [ + bitcoin.ECPair.makeRandom({ network }).publicKey, + bitcoin.ECPair.makeRandom({ network }).publicKey, + bitcoin.ECPair.makeRandom({ network }).publicKey + ]; + + const p2ms = bitcoin.payments.p2ms({ + m: 2, // 需要2个签名 + pubkeys, + network + }); + + const p2wsh = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }); + + return { + privateKey: keyPair.privateKey.toString('hex'), + publicKey: publicKey.toString('hex'), + p2wpkh: { + address: p2wpkh.address, // 原生SegWit地址 + type: 'P2WPKH (Native SegWit)', + witnessProgram: p2wpkh.output.toString('hex') // 见证程序(witness program) + }, + p2sh_p2wpkh: { + address: p2sh_p2wpkh.address, // 兼容SegWit地址 + type: 'P2SH-P2WPKH (Compatible SegWit)', + redeemScript: p2sh_p2wpkh.redeem.output.toString('hex') // 赎回脚本 + }, + p2wsh: { + address: p2wsh.address, // 原生SegWit脚本哈希地址 + type: 'P2WSH (Native SegWit Script Hash)', + witnessScript: p2ms.output.toString('hex') // 见证脚本 + } + }; +} + +/** + * 构建SegWit交易 + * @param {Object} utxo - 未花费交易输出 + * @param {string} toAddress - 接收地址 + * @param {number} amount - 发送金额(聪) + * @param {number} fee - 交易费(聪) + * @param {Object} keyPair - 密钥对 + * @param {string} changeAddress - 找零地址 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh') + * @returns {string} 交易的十六进制表示 + */ +async function createSegWitTransaction(utxo, toAddress, amount, fee, keyPair, changeAddress, addressType = 'p2wpkh') { + const txb = new bitcoin.TransactionBuilder(network); + + // 添加输入(来自SegWit地址的UTXO) + txb.addInput(utxo.txid, utxo.vout); + + // 添加输出 + txb.addOutput(toAddress, amount); + + // 如果有找零,添加找零输出 + const change = utxo.value - amount - fee; + if (change > 0) { + txb.addOutput(changeAddress || utxo.address, change); + } + + // 根据地址类型签名交易 + if (addressType === 'p2wpkh') { + // 原生SegWit地址签名 + txb.sign(0, keyPair, null, null, utxo.value); + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit地址签名 + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network }); + txb.sign(0, keyPair, p2sh.redeem.output, null, utxo.value); + } + + // 构建并返回交易 + const tx = txb.build(); + return tx.toHex(); +} + +/** + * 计算SegWit交易的交易ID + * @param {string} txHex - 交易的十六进制表示 + * @returns {Object} 包含txid和wtxid的对象 + */ +function calculateSegWitTransactionId(txHex) { + const tx = bitcoin.Transaction.fromHex(txHex); + + // 计算传统txid(不包含见证数据) + const txid = tx.getId(); + + // 计算wtxid(包含见证数据) + const wtxid = tx.getHash(true).reverse().toString('hex'); + + return { + txid, + wtxid, + isSame: txid === wtxid + }; +} + +/** + * 估算SegWit交易的大小和费用 + * @param {number} inputCount - 输入数量 + * @param {number} outputCount - 输出数量 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh') + * @param {number} feeRate - 费率(聪/字节) + * @returns {Object} 包含大小和费用的对象 + */ +function estimateSegWitTransactionFee(inputCount, outputCount, addressType = 'p2wpkh', feeRate = 10) { + let txSize = 0; + + // 计算交易大小(近似值) + if (addressType === 'p2wpkh') { + // 原生SegWit (P2WPKH) 交易大小估算 + // 基本交易大小 + 输入大小 + 输出大小 + txSize = 10 + (inputCount * 67.75) + (outputCount * 31); + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit (P2SH-P2WPKH) 交易大小估算 + txSize = 10 + (inputCount * 91) + (outputCount * 31); + } else { + // 传统 (P2PKH) 交易大小估算 + txSize = 10 + (inputCount * 148) + (outputCount * 34); + } + + // 计算费用 + const fee = Math.ceil(txSize * feeRate); + + return { + estimatedSize: txSize, + estimatedFee: fee, + feeRate: feeRate, + // 添加不同地址类型的大小比较 + sizeComparison: { + p2pkh: 10 + (inputCount * 148) + (outputCount * 34), + p2sh_p2wpkh: 10 + (inputCount * 91) + (outputCount * 31), + p2wpkh: 10 + (inputCount * 67.75) + (outputCount * 31), + }, + // 添加不同地址类型的费用比较 + feeComparison: { + p2pkh: Math.ceil((10 + (inputCount * 148) + (outputCount * 34)) * feeRate), + p2sh_p2wpkh: Math.ceil((10 + (inputCount * 91) + (outputCount * 31)) * feeRate), + p2wpkh: Math.ceil((10 + (inputCount * 67.75) + (outputCount * 31)) * feeRate), + }, + // 计算节省的费用百分比 + savingsPercentage: { + p2wpkh_vs_p2pkh: Math.round((1 - ((10 + (inputCount * 67.75) + (outputCount * 31)) / (10 + (inputCount * 148) + (outputCount * 34)))) * 100), + p2sh_p2wpkh_vs_p2pkh: Math.round((1 - ((10 + (inputCount * 91) + (outputCount * 31)) / (10 + (inputCount * 148) + (outputCount * 34)))) * 100) + } + }; +} + +/** + * 验证地址是否为SegWit地址 + * @param {string} address - 比特币地址 + * @returns {Object} 包含验证结果的对象 + */ +function validateSegWitAddress(address) { + try { + // 尝试解析地址 + const result = bitcoin.address.fromBase58Check(address); + + // 检查是否为P2SH地址(可能是P2SH-P2WPKH) + if (result.version === network.scriptHash) { + return { + isValid: true, + type: 'P2SH (可能是P2SH-P2WPKH兼容SegWit)', + isSegWit: 'Compatible' + }; + } + + return { + isValid: true, + type: 'P2PKH (传统地址)', + isSegWit: false + }; + } catch (e) { + // 如果不是Base58地址,尝试Bech32 + try { + const result = bitcoin.address.fromBech32(address); + + if (result.version === 0) { + if (result.data.length === 20) { + return { + isValid: true, + type: 'P2WPKH (原生SegWit)', + isSegWit: 'Native' + }; + } else if (result.data.length === 32) { + return { + isValid: true, + type: 'P2WSH (原生SegWit脚本哈希)', + isSegWit: 'Native' + }; + } + } else if (result.version === 1) { + return { + isValid: true, + type: 'P2TR (Taproot)', + isSegWit: 'v1' + }; + } + + return { + isValid: true, + type: '未知的Bech32地址', + isSegWit: 'Unknown' + }; + } catch (e) { + return { + isValid: false, + type: '无效地址', + isSegWit: false + }; + } + } +} + +/** + * 批量生成SegWit地址 + * @param {number} count - 要生成的地址数量 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh', 'p2wsh') + * @returns {Array} 地址数组 + */ +function batchGenerateSegWitAddresses(count, addressType = 'p2wpkh') { + const addresses = []; + + for (let i = 0; i < count; i++) { + const keyPair = bitcoin.ECPair.makeRandom({ network }); + const publicKey = keyPair.publicKey; + let address; + + if (addressType === 'p2wpkh') { + // 原生SegWit地址 + address = bitcoin.payments.p2wpkh({ pubkey: publicKey, network }).address; + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit地址 + address = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({ pubkey: publicKey, network }), + network + }).address; + } else if (addressType === 'p2wsh') { + // 创建一个简单的P2WSH地址(单签名) + const p2ms = bitcoin.payments.p2ms({ + m: 1, + pubkeys: [publicKey], + network + }); + + address = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }).address; + } + + addresses.push({ + privateKey: keyPair.privateKey.toString('hex'), + publicKey: publicKey.toString('hex'), + address: address, + type: addressType + }); + } + + return addresses; +} + +/** + * 批量处理SegWit交易 + * @param {Array} utxos - 未花费交易输出数组 + * @param {Array} outputs - 输出数组,每个包含address和amount + * @param {Object} keyPair - 密钥对 + * @param {string} changeAddress - 找零地址 + * @param {string} addressType - 地址类型 ('p2wpkh', 'p2sh-p2wpkh') + * @returns {string} 交易的十六进制表示 + */ +function batchSegWitTransaction(utxos, outputs, keyPair, changeAddress, addressType = 'p2wpkh') { + const txb = new bitcoin.TransactionBuilder(network); + + // 计算总输入金额 + const totalInput = utxos.reduce((sum, utxo) => sum + utxo.value, 0); + + // 计算总输出金额 + const totalOutput = outputs.reduce((sum, output) => sum + output.amount, 0); + + // 估算交易费用 + const feeEstimation = estimateSegWitTransactionFee(utxos.length, outputs.length + 1, addressType); + const fee = feeEstimation.estimatedFee; + + // 添加所有输入 + utxos.forEach(utxo => { + txb.addInput(utxo.txid, utxo.vout); + }); + + // 添加所有输出 + outputs.forEach(output => { + txb.addOutput(output.address, output.amount); + }); + + // 计算找零并添加找零输出 + const change = totalInput - totalOutput - fee; + if (change > 0) { + txb.addOutput(changeAddress, change); + } + + // 签名所有输入 + utxos.forEach((utxo, index) => { + if (addressType === 'p2wpkh') { + // 原生SegWit地址签名 + txb.sign(index, keyPair, null, null, utxo.value); + } else if (addressType === 'p2sh-p2wpkh') { + // 兼容SegWit地址签名 + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network }); + txb.sign(index, keyPair, p2sh.redeem.output, null, utxo.value); + } + }); + + // 构建并返回交易 + const tx = txb.build(); + return { + txHex: tx.toHex(), + txid: tx.getId(), + fee: fee, + changeAmount: change > 0 ? change : 0 + }; +} + +/** + * 创建SegWit多签名地址 + * @param {number} m - 需要的签名数量 + * @param {number} n - 公钥总数 + * @param {string} addressType - 地址类型 ('p2wsh', 'p2sh-p2wsh') + * @returns {Object} 多签名地址信息 + */ +function createSegWitMultisigAddress(m, n, addressType = 'p2wsh') { + // 生成n个密钥对 + const keyPairs = []; + const pubkeys = []; + + for (let i = 0; i < n; i++) { + const keyPair = bitcoin.ECPair.makeRandom({ network }); + keyPairs.push(keyPair); + pubkeys.push(keyPair.publicKey); + } + + // 创建多签名赎回脚本 + const p2ms = bitcoin.payments.p2ms({ + m, + pubkeys, + network + }); + + let address, redeemScript, witnessScript; + + if (addressType === 'p2wsh') { + // 原生SegWit多签名地址 + const p2wsh = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }); + + address = p2wsh.address; + witnessScript = p2ms.output; + } else if (addressType === 'p2sh-p2wsh') { + // 兼容SegWit多签名地址 + const p2wsh = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }); + + const p2sh = bitcoin.payments.p2sh({ + redeem: p2wsh, + network + }); + + address = p2sh.address; + redeemScript = p2wsh.output; + witnessScript = p2ms.output; + } + + return { + address, + m, + n, + type: addressType, + pubkeys: pubkeys.map(pubkey => pubkey.toString('hex')), + privateKeys: keyPairs.map(kp => kp.privateKey.toString('hex')), + redeemScript: redeemScript ? redeemScript.toString('hex') : null, + witnessScript: witnessScript.toString('hex') + }; +} + +/** + * 创建闪电网络通道资金交易 + * @param {Object} utxo - 未花费交易输出 + * @param {Buffer} localPubkey - 本地节点公钥 + * @param {Buffer} remotePubkey - 远程节点公钥 + * @param {number} localAmount - 本地节点出资金额(聪) + * @param {number} remoteAmount - 远程节点出资金额(聪) + * @param {Object} keyPair - 本地节点密钥对 + * @param {number} fee - 交易费(聪) + * @returns {Object} 通道资金交易信息 + */ +function createLightningChannelFundingTx(utxo, localPubkey, remotePubkey, localAmount, remoteAmount, keyPair, fee) { + const txb = new bitcoin.TransactionBuilder(network); + + // 添加输入 + txb.addInput(utxo.txid, utxo.vout); + + // 创建2-of-2多签名脚本 + const p2ms = bitcoin.payments.p2ms({ + m: 2, + pubkeys: [localPubkey, remotePubkey].sort((a, b) => a.compare(b)), // BIP-69要求公钥排序 + network + }); + + // 创建P2WSH地址(闪电网络通道使用P2WSH) + const p2wsh = bitcoin.payments.p2wsh({ + redeem: p2ms, + network + }); + + // 添加通道资金输出 + const channelAmount = localAmount + remoteAmount; + txb.addOutput(p2wsh.address, channelAmount); + + // 计算找零 + const change = utxo.value - channelAmount - fee; + if (change > 0) { + // 创建找零地址(使用P2WPKH) + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }); + txb.addOutput(p2wpkh.address, change); + } + + // 签名交易 + if (utxo.addressType === 'p2wpkh') { + txb.sign(0, keyPair, null, null, utxo.value); + } else if (utxo.addressType === 'p2sh-p2wpkh') { + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network }); + txb.sign(0, keyPair, p2sh.redeem.output, null, utxo.value); + } + + // 构建交易 + const tx = txb.build(); + + return { + txHex: tx.toHex(), + txid: tx.getId(), + channelAddress: p2wsh.address, + witnessScript: p2ms.output.toString('hex'), + localAmount, + remoteAmount, + totalAmount: channelAmount + }; +} + +/** + * 解析SegWit交易结构 + * @param {string} txHex - 交易的十六进制表示 + * @returns {Object} 解析后的交易结构 + */ +function parseSegWitTransaction(txHex) { + const tx = bitcoin.Transaction.fromHex(txHex); + + // 基本交易信息 + const result = { + txid: tx.getId(), + wtxid: tx.getHash(true).reverse().toString('hex'), + version: tx.version, + locktime: tx.locktime, + hasWitnesses: tx.hasWitnesses(), + virtualSize: tx.virtualSize(), + weight: tx.weight(), + byteLength: tx.byteLength(), + inputs: [], + outputs: [] + }; + + // 解析输入 + tx.ins.forEach((input, index) => { + const inputInfo = { + txid: Buffer.from(input.hash).reverse().toString('hex'), + vout: input.index, + sequence: input.sequence, + hasWitness: input.witness.length > 0, + scriptSig: input.script.toString('hex') + }; + + // 如果有见证数据,解析见证数据 + if (input.witness.length > 0) { + inputInfo.witness = input.witness.map(w => w.toString('hex')); + } + + result.inputs.push(inputInfo); + }); + + // 解析输出 + tx.outs.forEach((output, index) => { + const script = output.script; + let address = null; + let type = 'unknown'; + + // 尝试识别输出类型和地址 + try { + // 检查是否为P2PKH + if (bitcoin.payments.p2pkh({ output: script, network }).output) { + address = bitcoin.payments.p2pkh({ output: script, network }).address; + type = 'p2pkh'; + } + // 检查是否为P2SH + else if (bitcoin.payments.p2sh({ output: script, network }).output) { + address = bitcoin.payments.p2sh({ output: script, network }).address; + type = 'p2sh'; + } + // 检查是否为P2WPKH + else if (bitcoin.payments.p2wpkh({ output: script, network }).output) { + address = bitcoin.payments.p2wpkh({ output: script, network }).address; + type = 'p2wpkh'; + } + // 检查是否为P2WSH + else if (bitcoin.payments.p2wsh({ output: script, network }).output) { + address = bitcoin.payments.p2wsh({ output: script, network }).address; + type = 'p2wsh'; + } + } catch (e) { + // 无法识别的脚本类型 + } + + result.outputs.push({ + value: output.value, + scriptPubKey: script.toString('hex'), + type, + address + }); + }); + + return result; +} + +/** + * 比较SegWit与Taproot交易 + * @param {number} inputCount - 输入数量 + * @param {number} outputCount - 输出数量 + * @returns {Object} 比较结果 + */ +function compareSegWitWithTaproot(inputCount, outputCount) { + // 不同类型交易的大小估算(字节) + const sizes = { + p2pkh: 10 + (inputCount * 148) + (outputCount * 34), + p2sh_p2wpkh: 10 + (inputCount * 91) + (outputCount * 31), + p2wpkh: 10 + (inputCount * 67.75) + (outputCount * 31), + p2tr: 10 + (inputCount * 57.5) + (outputCount * 31) // Taproot (P2TR) + }; + + // 假设费率为10聪/字节 + const feeRate = 10; + + // 计算不同类型的费用 + const fees = { + p2pkh: Math.ceil(sizes.p2pkh * feeRate), + p2sh_p2wpkh: Math.ceil(sizes.p2sh_p2wpkh * feeRate), + p2wpkh: Math.ceil(sizes.p2wpkh * feeRate), + p2tr: Math.ceil(sizes.p2tr * feeRate) + }; + + // 计算相对于传统交易的节省百分比 + const savings = { + p2sh_p2wpkh_vs_p2pkh: Math.round((1 - (sizes.p2sh_p2wpkh / sizes.p2pkh)) * 100), + p2wpkh_vs_p2pkh: Math.round((1 - (sizes.p2wpkh / sizes.p2pkh)) * 100), + p2tr_vs_p2pkh: Math.round((1 - (sizes.p2tr / sizes.p2pkh)) * 100), + p2tr_vs_p2wpkh: Math.round((1 - (sizes.p2tr / sizes.p2wpkh)) * 100) + }; + + return { + transactionSizes: sizes, + fees, + savingsPercentage: savings, + comparison: { + inputCount, + outputCount, + feeRate, + notes: [ + "P2TR (Taproot) 提供了比 P2WPKH (SegWit) 更小的交易大小和更低的费用", + "Taproot 还提供了更好的隐私性和可扩展性", + "SegWit 是 Taproot 的基础,Taproot 是 SegWit v1" + ] + } + }; +} + +/** + * 获取SegWit采用率和性能数据 + * 注意:这里使用的是静态数据,实际应用中可以从API获取最新数据 + * @returns {Object} SegWit采用率和性能数据 + */ +function getSegWitAdoptionAndPerformanceData() { + // 静态数据,实际应用中可以从API获取最新数据 + return { + // SegWit采用率数据(截至2023年的近似值) + adoption: { + overallPercentage: 85, // 总体采用率 + byAddressType: { + p2sh_p2wpkh: 15, // 兼容SegWit地址采用率 + p2wpkh: 45, // 原生SegWit地址采用率 + p2tr: 25, // Taproot地址采用率 + legacy: 15 // 传统地址使用率 + }, + byYear: { + '2017': 10, + '2018': 30, + '2019': 50, + '2020': 65, + '2021': 75, + '2022': 80, + '2023': 85 + } + }, + // 性能数据 + performance: { + // 交易大小比较(字节) + transactionSize: { + // 1输入1输出的交易 + oneInOneOut: { + p2pkh: 192, // 传统地址 + p2sh_p2wpkh: 132, // 兼容SegWit + p2wpkh: 109, // 原生SegWit + p2tr: 98 // Taproot + }, + // 2输入2输出的交易 + twoInTwoOut: { + p2pkh: 374, + p2sh_p2wpkh: 254, + p2wpkh: 208, + p2tr: 186 + } + }, + // 交易费用比较(假设10聪/字节) + transactionFee: { + oneInOneOut: { + p2pkh: 1920, + p2sh_p2wpkh: 1320, + p2wpkh: 1090, + p2tr: 980 + }, + twoInTwoOut: { + p2pkh: 3740, + p2sh_p2wpkh: 2540, + p2wpkh: 2080, + p2tr: 1860 + } + }, + // 区块容量提升 + blockCapacity: { + legacy: '1MB(约2,000笔交易)', + withSegWit: '2.1-4MB(约4,000-8,000笔交易)' + }, + // 网络吞吐量(TPS) + throughput: { + legacy: '3-7 TPS', + withSegWit: '7-14 TPS' + } + }, + // 实际案例研究 + caseStudies: { + exchange: { + name: '某大型交易所', + before: { + avgFee: '15,000聪/交易', + dailyWithdrawals: 5000, + dailyFeeTotal: '0.75 BTC' + }, + after: { + avgFee: '6,000聪/交易', + dailyWithdrawals: 5000, + dailyFeeTotal: '0.3 BTC', + savings: '60%' + } + }, + wallet: { + name: '某热门钱包', + userAdoption: { + legacy: '15%', + segwitCompatible: '25%', + segwitNative: '45%', + taproot: '15%' + }, + avgFeeSavings: '55%' + } + } + }; +} + +/** + * 解释SegWit交易序列化格式 + * @returns {Object} SegWit交易序列化格式说明 + */ +function explainSegWitTransactionFormat() { + return { + format: { + legacy: [ + '4字节: 版本', + 'n个输入: [上一笔交易ID(32字节) + 输出索引(4字节) + 脚本长度(变长) + 脚本 + 序列号(4字节)]', + 'n个输出: [金额(8字节) + 脚本长度(变长) + 脚本]', + '4字节: 锁定时间' + ], + segwit: [ + '4字节: 版本', + '1字节: 标记(0x00)', + '1字节: 标志(0x01)', + 'n个输入: [上一笔交易ID(32字节) + 输出索引(4字节) + 脚本长度(变长) + 脚本 + 序列号(4字节)]', + 'n个输出: [金额(8字节) + 脚本长度(变长) + 脚本]', + 'n个见证数据: [见证数据数量(变长) + 见证数据]', + '4字节: 锁定时间' + ] + }, + differences: [ + 'SegWit交易添加了标记(0x00)和标志(0x01)字节', + 'SegWit交易将签名数据移到了交易的末尾(见证数据部分)', + 'SegWit交易的txid计算不包括见证数据,而wtxid包括见证数据', + 'SegWit交易引入了新的权重单位(weight units)来计算交易大小' + ], + weightCalculation: [ + '非见证字节的权重为4', + '见证字节的权重为1', + '区块权重限制为4,000,000单位(相当于传统的1MB区块大小)', + '最大区块大小可达到约4MB(如果全部是见证数据)' + ], + examples: { + p2wpkh: { + scriptPubKey: '0014{20字节公钥哈希}', + witnessData: '[签名, 公钥]' + }, + p2wsh: { + scriptPubKey: '0020{32字节脚本哈希}', + witnessData: '[签名1, 签名2, ..., 见证脚本]' + } + } + }; +} + +/** + * SegWit与Taproot的详细比较 + * @returns {Object} 比较结果 + */ +function compareSegWitAndTaproot() { + return { + overview: { + segwit: { + version: 'v0', + activationDate: '2017年8月', + bip: ['BIP141', 'BIP143', 'BIP144', 'BIP173'], + addressPrefix: ['bc1q (P2WPKH/P2WSH)'], + mainFeatures: ['交易延展性修复', '区块容量增加', '签名验证优化'] + }, + taproot: { + version: 'v1 (SegWit v1)', + activationDate: '2021年11月', + bip: ['BIP340', 'BIP341', 'BIP342'], + addressPrefix: ['bc1p (P2TR)'], + mainFeatures: ['Schnorr签名', '密钥聚合', 'MAST (默克尔抽象语法树)', '脚本增强'] + } + }, + technicalComparison: { + scriptExecution: { + segwit: '使用传统的CHECKSIG操作符验证签名', + taproot: '使用新的OP_CHECKSIGADD和Schnorr签名' + }, + privacyFeatures: { + segwit: '有限的隐私保护', + taproot: '增强的隐私保护(所有输出看起来相同,无法区分单签和多签)' + }, + multisigEfficiency: { + segwit: '每个签名都需要单独验证', + taproot: '使用密钥聚合,多个签名可以聚合为一个' + }, + scriptComplexity: { + segwit: '复杂脚本会增加交易大小', + taproot: '使用MAST,只有执行的脚本路径会被公开' + } + }, + performanceComparison: { + transactionSize: { + example: '2-of-3多签名交易', + segwit: '约222字节', + taproot: '约104字节', + improvement: '约53%' + }, + verificationSpeed: { + segwit: '基准', + taproot: '提高约2.5倍', + reason: 'Schnorr签名验证更快,批量验证更高效' + } + }, + evolutionPath: [ + 'SegWit (v0) 解决了交易延展性问题,为二层解决方案铺平道路', + 'Taproot (SegWit v1) 建立在SegWit的基础上,提供更高级的脚本功能和隐私保护', + '未来可能的SegWit v2将进一步扩展比特币的功能' + ] + }; +} + +// 导出函数 +module.exports = { + createSegWitAddresses, + createSegWitTransaction, + calculateSegWitTransactionId, + estimateSegWitTransactionFee, + validateSegWitAddress, + batchGenerateSegWitAddresses, + batchSegWitTransaction, + createSegWitMultisigAddress, + createLightningChannelFundingTx, + parseSegWitTransaction, + compareSegWitWithTaproot, + getSegWitAdoptionAndPerformanceData, + explainSegWitTransactionFormat, + compareSegWitAndTaproot +}; + +// 使用示例 +/* +// 创建SegWit地址 +const addresses = createSegWitAddresses(); +console.log('SegWit地址:', addresses); + +// 验证地址 +const addressValidation = validateSegWitAddress('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'); +console.log('地址验证结果:', addressValidation); + +// 估算交易费用 +const feeEstimation = estimateSegWitTransactionFee(2, 2, 'p2wpkh', 5); +console.log('费用估算:', feeEstimation); + +// 比较SegWit与Taproot +const comparison = compareSegWitWithTaproot(2, 2); +console.log('SegWit与Taproot比较:', comparison); + +// 获取SegWit采用率和性能数据 +const adoptionData = getSegWitAdoptionAndPerformanceData(); +console.log('SegWit采用率和性能数据:', adoptionData); +*/ \ No newline at end of file From bbd76417f602ae21907007f39b18e052faf7e861 Mon Sep 17 00:00:00 2001 From: ygcl9698 Date: Thu, 17 Apr 2025 11:27:15 +0800 Subject: [PATCH 5/5] feat: docs modify --- BTC/Basic/SegWit/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BTC/Basic/SegWit/README.md b/BTC/Basic/SegWit/README.md index 9c8b03c8c..bf5464c4a 100644 --- a/BTC/Basic/SegWit/README.md +++ b/BTC/Basic/SegWit/README.md @@ -174,9 +174,9 @@ SegWit引入了"区块权重 ## 代码示例:创建SegWit地址和交易 -代码示例文件:[examples.js](./example.js) +代码示例文件:[example.js](./example.js) 和 [example-extended.js](./example-extended.js) -该示例文件包含以下功能: +这些示例文件包含以下功能: ### 基础功能