该文档提出了一个带有校验和的Base32格式“Bech32”,以及使用它的原生隔离见证输出地址的标准。Bech32格式旨在改善比特币地址的用户体验,提高错误检测能力,并优化QR码的效率。它通过使用优化的字符集和BCH码校验和来实现这些目标,适用于主网和测试网。
从 bitcoin/bips 派生
bip-anyprevout
搜索此仓库
/
复制路径
BlameMore 文件操作
BlameMore 文件操作
2019年7月18日
39a23b7 · 2019年7月18日
打开提交详情
405 行 (332 loc) · 19.9 KB
/
顶部
预览
代码
Blame
405 行 (332 loc) · 19.9 KB
复制原始文件
下载原始文件
大纲
编辑和原始操作
BIP: 173
Layer: Applications
Title: Base32 address format for native v0-16 witness outputs
Author: Pieter Wuille <pieter.wuille@gmail.com>
Greg Maxwell <greg@xiph.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0173
Status: Final
Type: Informational
Created: 2017-03-20
License: BSD-2-Clause
Replaces: 142
## 目录<br>永久链接:目录<br>- 引言 <br> - 摘要<br> - 版权<br> - 动机<br> - 示例<br>- 规范 <br> - Bech32<br> - Segwit 地址格式<br> - 兼容性<br>- 原理<br>- 参考实现<br>- 已注册的人类可读前缀<br>- 附录 <br> - 测试向量<br> - 校验和设计<br>- 致谢 |
本文档提出了一种带有校验和的 base32 格式 “Bech32”,以及使用它的原生隔离见证输出地址的标准。
此 BIP 基于 2-clause BSD 许可。
在大部分历史中,比特币依赖于带有截断的双 SHA256 校验和的 base58 地址。它们是最初软件的一部分,并且它们的范围在 BIP13 中针对 Pay-to-script-hash ( P2SH) 进行了扩展。然而,字符集和校验和算法都存在局限性:
隔离见证提议中包含了一类新的输出(见证程序,参见 BIP141),以及它的两个实例(“P2WPKH” 和 “P2WSH”,参见 BIP143)。通过嵌入到 P2SH 输出中,旧客户端可以间接使用它们的功能,但是为了获得最佳效率和安全性,最好直接使用它。在本文档中,我们提出了一种新的地址格式,用于原生见证输出(当前和未来版本)。
这取代了 BIP142,并且之前在 此处 进行了讨论(总结 在此处)。
所有示例都使用公钥 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
。P2WSH 示例使用 key OP_CHECKSIG
作为脚本。
bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx
bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3
tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7
我们首先描述通用的带有校验和的 base32[ 1] 格式,称为 Bech32,然后使用它来定义隔离见证地址。
一个 Bech32[ 2] 字符串最多 90 个字符,由以下组成:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
+0 | q | p | z | r | y | 9 | x | 8 |
+8 | g | f | 2 | t | v | d | w | 0 |
+16 | s | 3 | j | n | 5 | 4 | k | h |
+24 | c | e | 6 | m | u | a | 7 | l |
校验和
数据部分的最后六个字符构成校验和,并且不包含任何信息。有效的字符串必须通过以下 Python3 代码段指定的有效性标准。当参数为:
hrp
: 人类可读部分,作为字符串data
: 数据部分,作为整数列表,表示使用上表转换后的字符时,函数 bech32_verify_checksum
必须返回 true。
def bech32_polymod(values):
GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
chk = 1
for v in values:
b = (chk >> 25)
chk = (chk & 0x1ffffff) << 5 ^ v
for i in range(5):
chk ^= GEN[i] if ((b >> i) & 1) else 0
return chk
def bech32_hrp_expand(s):
return [ord(x) >> 5 for x in s] + [0] + [ord(x) & 31 for x in s]
def bech32_verify_checksum(hrp, data):
return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1
这实现了一个 BCH 码,保证检测到最多影响4个字符的任何错误,并且检测不到更多错误的可能性小于 1 in 109。有关属性的更多详细信息,请参见校验和设计附录。人类可读部分的处理方式是,首先将每个字符的 US-ASCII 值的高位输入到校验和计算中,然后是一个零,然后是每个字符的低位[ 5]。
要构造一个有效的校验和,给定人类可读部分和数据部分字符的(非校验和)值,可以使用以下代码:
def bech32_create_checksum(hrp, data):
values = bech32_hrp_expand(hrp) + data
polymod = bech32_polymod(values + [0,0,0,0,0,0]) ^ 1
return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
纠错
这些 BCH 码的属性之一是它们可用于纠错。纠错的一个不幸的副作用是它会削弱错误检测:纠正会将无效输入更改为有效输入,但是如果进行了多次错误,则有效输入可能不是正确的输入。使用不正确但有效的输入可能会导致资金无法挽回地丢失。因此,实现不应实现超出可能向用户建议在字符串中找到错误的位置的纠正,而不建议进行纠正。
大写/小写
小写形式用于确定字符的校验和目的值。
编码器必须始终输出全小写的 Bech32 字符串。 如果需要编码结果的大写版本(例如,为了演示目的或使用二维码),则可以在编码过程之外执行大写程序。
解码器不得接受某些字符为大写而某些字符为小写的字符串(此类字符串称为混合大小写字符串)。
为了演示,小写通常是首选,但是在二维码内部应使用大写,因为这些允许使用字母数字模式,该模式比普通的 字节模式 紧凑 45%。
一个 segwit 地址[ 6] 是以下内容的 Bech32 编码:
解码
解释 segwit 地址的软件:
解码器应强制执行对见证程序的已知长度限制。例如,BIP141 指定如果版本字节为 0,但见证程序既不是 20 字节也不是 32 字节,则脚本必须失败。
由于之前的规则,地址始终在 14 到 74 个字符之间,并且它们的长度模 8 不能为 0、3 或 5。 版本 0 见证地址始终为 42 或 62 个字符,但是实现必须允许使用任何版本。
在将地址转换为 scriptPubkey 时,实现应特别注意,其中见证版本 n 存储为 OP_n。OP_0 编码为 0x00,但 OP_1 到 OP_16 编码为 0x51 到 0x60(十进制 81 到 96)。如果将 bech32 地址转换为不正确的 scriptPubKey,则结果很可能变得无法花费或不安全。
只有新的软件才能使用这些地址,并且仅适用于具有启用 segwit 的新软件的接收者。在所有其他情况下,可以使用 P2SH 或 P2PKH 地址。
SatoshiLabs 维护着一个完整的已注册人类可读部分列表,用于其他加密货币:
以下字符串是有效的 Bech32:
A12UEL5L
a12uel5l
an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs
abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw
11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j
split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w
?1ezyfcl
警告:在转换为 US-ASCII 期间,某些编码器可能会将无法映射的字符设置为有效的 US-ASCII 字符,例如 “?”。例如:>>> bech32_encode('\x80'.encode('ascii', 'replace').decode('ascii'), [])
'?1ezyfcl'
以下字符串不是有效的 Bech32(带有无效原因):
1nwldj5
: HRP 字符超出范围1axkwrx
: HRP 字符超出范围1eym55h
: HRP 字符超出范围an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx
: 超过整体最大长度pzry9x0s0muk
: 没有分隔符字符1pzry9x0s0muk
: 空 HRPx1b4n0q5v
: 无效的数据字符li1dgmt3
: 校验和太短de1lg7wt
+ 0xFF: 校验和中的无效字符A1G7SGD8
: 使用 HRP 的大写形式计算的校验和10a06t8
: 空 HRP1qzzfhee
: 空 HRP以下列表给出了有效的 segwit 地址以及它们转换为十六进制的 scriptPubKey。
BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4
: 0014751e76e8199196d454941c45d1b3a323f1433bd6
tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7
: 00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262
bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx
: 5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6
BC1SW50QA3JX3S
: 6002751e
bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj
: 5210751e76e8199196d454941c45d1b3a323
tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy
: 0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433
以下列表给出了无效的 segwit 地址及其无效原因。
tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty
: 无效的人类可读部分bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5
: 无效的校验和BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2
: 无效的见证版本bc1rw5uspcuh
: 无效的程序长度bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90
: 无效的程序长度BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P
: 见证版本 0 的无效程序长度(根据 BIP141)tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7
: 混合大小写bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du
: 超过 4 位的零填充tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv
: 8 到 5 转换中的非零填充bc1gmk9yu
: 空数据段设计选择
BCH 码可以在任何素数幂字母表上构造,并且可以选择在大小和错误检测能力之间取得良好的权衡。尽管围绕 BCH 码的大多数工作都使用二进制字母表,但这不是必需的。这使得它们比 CRC 码 更适合我们的用例。与 [里德-所罗门码](https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_这里选择的具体代码是以下的结果:
由于朴素搜索将需要超过 6.5 * 1019 次校验和评估,因此使用了冲突搜索方法进行分析。该代码可以在这里找到。
属性
下表总结了检测失败的可能性(以十亿分之一的倍数表示)。
窗口长度 | 错误字符数 | ||||||
---|---|---|---|---|---|---|---|
长度 | 描述 | ≤4 | 5 | 6 | 7 | 8 | ≥9 |
8 | 最长检测 6 个错误 | 0 | 1.127 | 0.909 | n/a | ||
18 | 最长检测 5 个错误 | 0 | 0.965 | 0.929 | 0.932 | 0.931 | |
19 | 6 个错误的最坏情况 | 0 | 0.093 | 0.972 | 0.928 | 0.931 | |
39 | P2WPKH 地址的长度 | 0 | 0.756 | 0.935 | 0.932 | 0.931 | |
59 | P2WSH 地址的长度 | 0 | 0.805 | 0.933 | 0.931 | ||
71 | 40 字节程序地址的长度 | 0 | 0.830 | 0.934 | 0.931 | ||
89 | 最长检测 4 个错误 | 0 | 0.867 | 0.933 | 0.931 |
这意味着,当 5 个更改的字符随机分布在 P2WPKH 地址的 39 个字符中时,有 十亿分之 0.756 的可能性不会被检测到。当这 5 个更改随机发生在 19 个字符的窗口中时,该可能性会降至 十亿分之 0.093。随着错误数量的增加,该可能性收敛于 1/230 = 十亿分之 0.931。
即使选择的代码在多达 1023 个字符的情况下表现相当不错,但对于超过 89 个字符的长度,其他设计是更可取的(不包括分隔符)。
本文档的灵感来自 Rusty Russell 的地址提案、Mark Friedenbach 的 base32 提案,并得到了 Luke Dashjr、Johnson Lau、Eric Lombrozo、Peter Todd 和其他各种审阅者的投入。
- 原文链接: github.com/ajtowns/bips/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!