|
| 1 | +Bech32是一种编码格式,最初由Pieter Wuille等人在比特币改进提案[BIP 173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)中提出,主要用于比特币SegWit地址的编码方式。Bech32编码的目的是提供一种更友好的用户界面,并减少在抄写和输入时出现错误的风险。 |
| 2 | + |
| 3 | +### 核心特性 |
| 4 | + |
| 5 | +**1. 错误检测能力:** |
| 6 | +Bech32地址包含一种错误检测代码,称为多项式校验码(PolyMod),可以检测并保护地址中最多4个错误的出现。 |
| 7 | + |
| 8 | +**2. 字符集:** |
| 9 | +Bech32只使用小写字母和数字(除了1、b、i、o之外的小写字母和所有数字),从而避免了字母大小写的混淆和某些字母和数字之间的视觉相似性。 |
| 10 | + |
| 11 | +**3. 限制长度:** |
| 12 | +一个Bech32编码的地址总是有一定的长度限制,比特币的SegWit地址最长为90个字符。 |
| 13 | + |
| 14 | +**4. 分隔符:** |
| 15 | +Bech32地址中使用"1"作为分隔符来分开人类可读的部分(HRP,Human-readable part)和数据部分。 |
| 16 | + |
| 17 | +### 编码格式 |
| 18 | + |
| 19 | +Bech32地址的结构如下: |
| 20 | + |
| 21 | +\[ \text{HRP} + "1" + \text{数据编码} + \text{校验码} \] |
| 22 | + |
| 23 | +- **HRP(Human-readable part):** 这部分是地址的前缀,用来指示地址所用的网络,例如比特币主网的`bc`和测试网的`tb`。 |
| 24 | +- **数据编码:** 使用的是一种叫做Base32的变种编码,将数据转换成32个字符集中的字符。 |
| 25 | +- **校验码:** 是一组校验码字符,用于保护整个地址不受随机错误的影响。 |
| 26 | + |
| 27 | +Bech32是一种用于编码和解码比特币SegWit地址的格式,具体方法由[BIP 173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)定义。编码和解码过程涉及多个步骤,包括数据的处理、转换以及校验。 |
| 28 | + |
| 29 | +在实际项目中可以使用JavaScript的常用库bech32实现的Bech32编码和解码。 |
| 30 | +**Bech32编码示例** |
| 31 | +```js |
| 32 | +const bech32 = require('bech32'); |
| 33 | + |
| 34 | +function encodeBech32(hrp, data) { |
| 35 | + const words = bech32.toWords(Buffer.from(data)); |
| 36 | + return bech32.encode(hrp, words); |
| 37 | +} |
| 38 | + |
| 39 | +// 示例使用 |
| 40 | +let hrp = "bc"; |
| 41 | +let data = "00112233445566778899aabbccddeeff"; // 假设这是要编码的数据 |
| 42 | +let encoded = encodeBech32(hrp, data); |
| 43 | +console.log("Encoded Bech32:", encoded); |
| 44 | +``` |
| 45 | + |
| 46 | +**Bech32解码示例** |
| 47 | +```js |
| 48 | +function decodeBech32(address) { |
| 49 | + let decoded = bech32.decode(address); |
| 50 | + decoded.data = Buffer.from(bech32.fromWords(decoded.words)).toString('hex'); |
| 51 | + return decoded; |
| 52 | +} |
| 53 | + |
| 54 | +// 使用之前编码的地址进行解码 |
| 55 | +let decoded = decodeBech32(encoded); |
| 56 | +console.log("Decoded Bech32:", decoded); |
| 57 | +``` |
| 58 | + |
| 59 | +### Bech32编码过程 |
| 60 | + |
| 61 | +编码过程涉及以下步骤: |
| 62 | + |
| 63 | +1. **确定人类可读部分(HRP)和数据部分:** |
| 64 | + - HRP表示网络,比如比特币主网的`bc`,测试网的`tb`。 |
| 65 | + - 数据部分包含经过编码的公钥或脚本哈希。 |
| 66 | + |
| 67 | +2. **将数据部分从8位字节转换为5位数组:** |
| 68 | + - Bech32使用Base32编码,这不同于传统的Base32。数据需要从其原始的8位字节形式(如在二进制文件中)转换为5位字节的数组。这种转换减少了数据的比特长度,并允许整个地址适应QR码等格式。 |
| 69 | + |
| 70 | +3. **计算校验码:** |
| 71 | + - 使用`PolyMod`算法计算出一个校验码,该算法可以提供错误检测功能。校验码计算依赖于HRP和转换后的数据。 |
| 72 | + - 校验码有助于保护整个地址不受随机错误的影响。 |
| 73 | + |
| 74 | +4. **组合最终的Bech32地址:** |
| 75 | + - 最终的Bech32地址由三部分组成:HRP、分隔符(`1`)、编码后的数据和校验码。 |
| 76 | + - 示例:`bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4` |
| 77 | + |
| 78 | + |
| 79 | +### Bech32解码过程 |
| 80 | + |
| 81 | +解码过程涉及以下步骤: |
| 82 | + |
| 83 | +1. **验证地址的校验码:** |
| 84 | + - 使用相同的`PolyMod`算法验证地址中的校验码是否正确。如果校验失败,则地址有错误。 |
| 85 | + |
| 86 | +2. **分离HRP和编码数据:** |
| 87 | + - 从地址中分离出HRP和编码后的数据部分。这两部分由分隔符`1`分开。 |
| 88 | + |
| 89 | +3. **从5位数组转换回8位字节:** |
| 90 | + - 将从Bech32地址中提取的5位数组数据转换回原始的8位字节形式。这通常涉及二进制数据的重新分组。 |
| 91 | + |
| 92 | +4. **解析数据部分以获取原始的哈希或密钥信息:** |
| 93 | + - 解码后的数据通常是某种形式的哈希值或公钥信息,这取决于具体的应用场景(如P2WPKH或P2WSH)。 |
| 94 | + |
| 95 | + |
| 96 | +`PolyMod`是一种特别设计用于Bech32编码系统中的多项式模运算算法。在Bech32地址格式中,`PolyMod`算法用于生成一个校验码,该校验码具有高错误检测能力,能够帮助确认地址在传输或书写过程中是否被错误修改。此算法是Bech32提案(BIP 173)的核心部分,对于保证地址的完整性和准确性至关重要。 |
| 97 | + |
| 98 | +### PolyMod算法的作用 |
| 99 | + |
| 100 | +在Bech32中,`PolyMod`算法的主要作用是计算一个校验码,这个校验码能够: |
| 101 | +- 检测到任何单一的错误。 |
| 102 | +- 检测到任何相邻字符的交换。 |
| 103 | +- 检测到最多四个错误的错误组合。 |
| 104 | + |
| 105 | +### PolyMod算法的实现步骤 |
| 106 | + |
| 107 | +`PolyMod`算法的计算可以分为以下几个步骤: |
| 108 | + |
| 109 | +1. **初始化**:设置一个初始变量`c`为1。 |
| 110 | + |
| 111 | +2. **处理HRP**:对于HRP(人类可读部分)中的每个字符,进行以下操作: |
| 112 | + - 将`c`向右移动5位。 |
| 113 | + - 将字符的值与`c`进行异或(XOR)运算。 |
| 114 | + - 对`c`进行一系列的模2多项式运算,通常这涉及到与几个固定的常数进行XOR运算,这些常数由Bech32规范定义。 |
| 115 | + |
| 116 | +3. **处理数据部分**:类似地处理数据部分中的每个5位值,包括: |
| 117 | + - 将`c`向右移动5位。 |
| 118 | + - 将数据值与`c`进行异或运算。 |
| 119 | + - 对`c`进行类似上述的模2多项式运算。 |
| 120 | + |
| 121 | +4. **生成校验码**:完成所有字符的处理后,将`c`与一个常数进行XOR运算,得到最终的校验码。这一步确保了校验码能够有效地反映整个地址的完整性。 |
| 122 | + |
| 123 | +** 示例代码 ** |
| 124 | +```js |
| 125 | +function polymod(values) { |
| 126 | + let generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]; |
| 127 | + let chk = 1; |
| 128 | + for (let value of values) { |
| 129 | + let top = chk >> 25; |
| 130 | + chk = (chk & 0x1ffffff) << 5 ^ value; |
| 131 | + for (let i = 0; i < 5; i++) { |
| 132 | + if ((top >> i) & 1) { |
| 133 | + chk ^= generator[i]; |
| 134 | + } |
| 135 | + } |
| 136 | + } |
| 137 | + return chk; |
| 138 | +} |
| 139 | + |
| 140 | +function hrpExpand(hrp) { |
| 141 | + let ret = []; |
| 142 | + for (let p = 0; p < hrp.length; p++) { |
| 143 | + ret.push(hrp.charCodeAt(p) >> 5); |
| 144 | + } |
| 145 | + ret.push(0); |
| 146 | + for (let p = 0; p < hrp.length; p++) { |
| 147 | + ret.push(hrp.charCodeAt(p) & 31); |
| 148 | + } |
| 149 | + return ret; |
| 150 | +} |
| 151 | + |
| 152 | +function createChecksum(hrp, data) { |
| 153 | + const values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]); |
| 154 | + const polymodValue = polymod(values) ^ 1; |
| 155 | + let checksum = []; |
| 156 | + for (let i = 0; i < 6; i++) { |
| 157 | + checksum.push((polymodValue >> 5 * (5 - i)) & 31); |
| 158 | + } |
| 159 | + return checksum; |
| 160 | +} |
| 161 | + |
| 162 | +// Example usage |
| 163 | +let hrp = "bc"; |
| 164 | +let data = [2, 3, 4, 5, 6]; // Example data part (this should be your actual converted data) |
| 165 | +let checksum = createChecksum(hrp, data); |
| 166 | +console.log("Checksum:", checksum); |
| 167 | +``` |
| 168 | + |
| 169 | +### 数学原理 |
| 170 | + |
| 171 | +`PolyMod`算法本质上是一个使用特定生成多项式的循环冗余校验(CRC)算法。这个生成多项式是经过选择的,能够最大化常见错误模式的检测能力,例如拼写错误、字符遗漏、错误插入等。 |
| 172 | + |
| 173 | + |
| 174 | +### 使用场景 |
| 175 | + |
| 176 | +Bech32地址主要用于比特币的SegWit交易,其中包括了P2WPKH(Pay to Witness Public Key Hash)和P2WSH(Pay to Witness Script Hash)类型的地址。这些地址类型通过减少交易大小来降低交易费用,同时提高交易的隐私性和效率。 |
| 177 | + |
| 178 | +### 优点 |
| 179 | + |
| 180 | +- **更高的错误检测能力:** Bech32的设计提供了强大的错误检测和纠正能力。 |
| 181 | +- **用户友好:** 地址全小写,易于阅读和抄写。 |
| 182 | +- **效率与兼容性:** 地址长度更短,适用于QR码等多种场景。 |
| 183 | + |
| 184 | +Bech32编码为比特币地址提供了一个更加安全和用户友好的格式,是比特币网络中SegWit技术的一个重要组成部分。 |
0 commit comments