比特币钱包原理简介及开发实践
比特币是最早出现的也是目前规模最大的加密货币,通过比特币很多人了解到了区块链技术,以太坊就是在其基础上演进形成的。我们之前了解了以太坊,现在回过头来我们再来看看比特币钱包的一些相关技术细节。
钱包地址类型
比特币和以太坊有很多区别,首先在钱包地址上就不一样,以太坊钱包始终只有一种格式(不论是主网络还是测试网络),而比特币钱包有多种地址形式:
- 以
1开头的P2PKH(Pay-to-Public-Key-Hash)地址,顾名思义是基于公钥哈希进行交易的地址,它是基于公钥私钥的地址形式 - 以
3开头的P2SH(Pay-to-Script-Hash)地址,与P2PKH不同的是它是通过赎回脚本进行交易的,注意:这种地址可能是Segwit(隔离见证)也可能不是 - 以
bj开头的Segwit(隔离见证)地址,后面会详细介绍 - 以
m、n、2开头的地址,一般是测试网络上的地址
比特币社区推荐大家尽可能使用以3开头的地址,因为它比1开头的地址具备更多扩展性。
SegWit 隔离见证地址
隔离见证的英文是Segregated Witness,简称是SegWit,那隔离见证地址是为了解决什么问题呢?
随着区块链上的交易越来越多,交易的速度却变得越来越慢,有时候要等好长一段时间才能成功确认,如果矿工费用过低的话要等的时间更长。因为区块链上的区块容量有限,一个区块只能打包一定数量的交易,手续费高的交易优先打包,如果区块容量满了那么交易就只能放到下一个区块。
那隔离见证是怎么解决这个问题的呢?看过一个比喻隔离见证的例子比较生动,这里引用一下:
区块就像容量有限的客运车,每笔交易就像上车的乘客,乘客缴纳的乘车费越高可以越快上车,车满了未上车的乘客就只能等下一班。而 SegWit 就像给客运车加了一节车厢,但这个车厢是不能坐人的,只能用来放乘客的行李,乘客把行李都放到新的车厢里面去之后,原来的车厢空间就变大了,就可以容纳更多的乘客。
隔离见证还是让区块保留原来的容量——1M,但增加了 3M 的车厢,将交易中的交易地址、金额和认证资料等信息分开存放,这样就达到了扩容的目的了。
另外使用隔离见证地址还有一个好处,就是交易的矿工费用比普通地址要低。
HD 钱包
HD 钱包其实并不是指硬件钱包(Hardware Wallet),而是分层确定性(Hierarchical Deterministic)的缩写。分层就是一个主私钥对可以生成多个子私钥对,一个子私钥对又可以生成多个孙私钥对,从而形成了一个分层结构。
BIP
BIP 全名是 Bitcoin Improvement Proposals(比特币改进建议),类似开源项目中的RFC(Request for Comments)流程,任何人都可以向比特币提出改善建议,提交的交易会放到 BIP 网站 上进行公审。
BIP 网站上面罗列了迄今为止所有的 BIP 提议以及他们的类型和状态,状态为Final或Active的是已经经过公审并已纳入比特币标准的建议。
BIP32
HD——分层确定性最早就是通过 BIP32 提出来的,概括来说就是通过一个种子(seed)来生成一个私钥对的分层结构(见上面的图)。
更多 BIP32 的内容可以查看这里。
BIP39
由于种子是一长串随机字符串不便于记忆,所以 BIP39 提出了一种方法:通过助记词的方式来记录种子,助记词一般是由 3~24 个简单的字或单词组成,方便人们记忆和书写。
在这个网址 (https://iancoleman.io/bip39/) 可以进行 BIP39 助记词测试和获取。
目前 BIP39 支持 8 种语言的助记词,包括:英文、简体中文、繁体中文、日文、韩文、西班牙语、意大利语、法语。
更多 BIP39 的内容可以查看这里。
BIP44
BIP44 是在 BIP32 基础上进行功能扩展,让同一个种子可以支持多币种和多账户,其路径层级为:
m / purpose' / coin_type' / account' / change / address_index
- purpose:值是常量
44,表示使用的是 BIP44。 - coin_type:代表加密货币的种类,
0表示比特币,1表示比特币测试币,60表示以太币。 - 后面三个属性分别表示账号、链类型和索引,一般这几个属性的值都为
0。
更多 BIP44 的内容可以查看这里。
比特币区块链网络
比特币也有主网络和测试网络,但不同于以太坊的多种测试网络(Ropsten,Rinkeby,Kovan),比特币只有一种测试网络。
测试网络同样可以通过Faucet(水龙头)获取到比特币,请注意:测试链上的比特币是没有价值的。这里介绍 2 个水龙头地址:
钱包创建
下面我们使用 bitcoinjs-lib 来介绍一下比特币钱包是如何创建的。
PS: bitcoinjs-lib 的 master 分支代码已经是4.0.0,但从 npm 上下载的还是3.3.2版本,因此要看3.3.2的代码示例需要做如下修改:
1 | // 示例代码的 url 地址 |
创建 P2PKH 钱包
1 | // 创建钱包 |
私钥导入 P2PKH 钱包
1 | // 导入钱包 |
通过 P2SH 创建 SegWit 钱包
1 | // 导入 P2PKH 钱包 |
创建测试网络钱包
1 | // 测试网络 |
创建基于 BIP44 的 HD 钱包
1 | // 助记词 |
通过 HD 钱包创建 SegWit 钱包
1 | // child 为 HD 钱包,参见上面的例子 |
这样我们就可以得到有这样对应关系的钱包:助记词 –> 普通地址钱包(包含私钥)–> SegWit 地址钱包。
总结
比特币钱包相对于以太坊来说复杂了一些,我觉得是因为比特币钱包发展的较早,技术在完善的过程中做了一些矫正和弥补导致了形成多种解决方案,而以太坊是在比特币基础上发展起来的,所以就没有这些问题,但随着以后技术的发展,以太坊难免也会出现比特币的这种情况。