基于Vue开发的以太坊开源HD钱包Vuethwallet源码分析 – 作者:BUGX

前言

随着区块链越来越火热,数字货币钱包也随之被人重视。数字钱包的发展历程是从最初比特币的非确定性钱包,到确定性钱包,一直到我们现在最广为使用HD分层确定性钱包,而今天要分析的钱包就是现在最为流行的HD分层确定性钱包。

HD钱包的英文全称是:Hierarchical Deterministic 之所以叫分层确定性钱包是因为私钥的衍生结构是树状结构,父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。在创建钱包或者备份钱包的时候都会看到一堆英文单词(或者中文汉字),这些词就是助记词。

一、钱包介绍

1.1 功能

(1)Vuethwallet => 普通钱包,随机生成助记

(2)Seed Wallet => 自定义助记词钱包Import

(3)Wallet => 导入钱包(导入Keysotre) Value

(4)Transaction => 导入钱包并进行交易

1.2 特色

( 1 ) 该钱包的特点就是简单,只具备一个数字钱包最基本的功能:密钥管理(私钥的 生成 + 导入 + 备份)和交易。

密钥生成主要使用原生的bip-39库生成助记词(可自定义助记词或随机助记词)然后进一步生成私钥

( 2 ) 因为使用的是原生的库进行私钥生成,私钥生成过程会比较接触底层

备份使用Keystore进行保存

( 3 ) 以太坊的 keystore文件Linux 系统存储在/home_path/.ethereum/keystore或者Windows系统存储在C:\Users\Appdata/Roaming/Ethereum/keystore)是你独有的、用于签署交易的以太坊私钥的加密文件。如果你丢失了这个文件,你就丢失了私钥,意味着你失去了签署交易的能力,意味着你的资金被永久的锁定在了你的账户里。

这里是一个Keystore例子:

一个Keystore例子

交易使用 web3.jsAPI 进行交易

web3.js是以太坊提供的一个Javascript库,它封装了以太坊的JSON RPC API,提供了一系列与区块链交互的Javascript对象和函数,包括查看网络状态,查看本地账户、查看交易和区块、发送交易、编译/部署智能合约、调用智能合约等,该钱包交易功能比较简单,没有一些完备钱包所具有的功能比如余额查询,Gas价格查询等,但足以学习所用

二、钱包的代码架构

钱包的代码架构

主要文件

本文主要对钱包创建以及交易处理部分进行详细分析,其他代码有兴趣可自行深入:

(1)index.html ==> 主页,只有一个大框架,并无实际内容,靠js进行填充

(2)/src/views/main.js ==> 入口主程序,将App.vue插入到index.html

(3)/src/views/App.vue ==> 主要组件,响应用户点击并路由到相应的页面

(4)/src/view/Wallet.vue ==> 创建普通钱包

(5)/src/view/WalletSeed.vue ==> 创建带seed钱包

(6)/src/view/ImportKeystore.vue ==> 导入钱包(Keystore)

(7)/src/view/ValueTransaction.vue ==> 交易处理

(8)/util/confirmedTransaction.js ==> 交易确认逻辑

(9)/node_modlues/zxcvb ==> 密码强度校验(分数计算)

三、代码分析

3.1 /src/view/Wallet.vue ==> 创建普通钱包(随机助记词)

3.1 /src/view/Wallet.vue ==> 创建普通钱包(随机助记词)”></p>
<p><b>3.1.1 generate ==> 主函数:校验密码强度 + 生成私钥并返回 + 页面渲染 + keystore生成</b></p>
<p>主要函数</p>
<blockquote>
<p>(1)wallet.generate => 生成私钥并返回</p>
<p>(2)newAddress => 页面渲染+keystore生成</p>
</blockquote>
<p style=3.1.1 generate ==> 主函数:校验密码强度 + 生成私钥并返回 + 页面渲染 + keystore生成”></p>
<p><b>3.1.2 wallet.generate ==> 钱包私钥生成函数</b></p>
<p>私钥生成步骤</p>
<blockquote>
<p>(1)bip39.generateMnemonic() ==> 生成助记词(只是将私钥的进行可读化显示,并不是brainwallets)</p>
<p>(2)bip39.mnemonicToSeedHex(randomSeed) ==> 助记词生成根seed</p>
<p>(3)HDKey.fromMasterSeed(randomSeed) ==> 根seed生成私钥和chainCode</p>
</blockquote>
<p style=3.1.2 wallet.generate ==> 钱包私钥生成函数”></p>
<p>3.1.2.1 bip39.generateMnemonic()函数分析 ==> 生成助记词</p>
<p>助记词生成步骤:</p>
<blockquote>
<p>1.  创造一个128到256位的随机顺序(熵,熵的长度=> ENT);</p>
<p>2.  提出SHA256哈希前(ENT/32)位,就可以创造一个随机序列的校验和(校验和的长度为ENT/32);</p>
<p>3.  把校验和加在随机顺序的后面;</p>
<p>4.  把顺序分解成11位的不同集合,并用这些集合去和一个预先已经定义的2048个单词字典做对应;</p>
<p>5.  生成一个12至24个词的助记词。</p>
</blockquote>
<p style=3.1.2.1 bip39.generateMnemonic()函数分析 ==> 生成助记词”></p>
<p style=3.1.2.1 bip39.generateMnemonic()函数分析 ==> 生成助记词”></p>
<p>3.1.2.2 bip39.mnemonicToSeedHex(randomSeed)函数分析 ==> 助记词生成根seed</p>
<p>步骤:</p>
<blockquote>
<p>1. 若用户想使用密码来保护助记符,则可以提供password参数,该钱包默认为”;</p>
<p>2. 用带有用作密码的助记符句子(以UTF-8 NFKD表示)的PBKDF2函数和用作盐的字符串”助记符”+密码(再次以UTF-8 NFKD表示)。</p>
</blockquote>
<p>迭代计数设置为2048,HMAC-SHA512用作伪随机函数。派生密钥的长度为512位(64字节)。</p>
<p style=3.1.2.2 bip39.mnemonicToSeedHex(randomSeed)函数分析 ==> 助记词生成根seed”></p>
<p>3.1.2.3 HDKey.fromMasterSeed(randomSeed)函数分析 ==> 根seed生成私钥和chainCode</p>
<p style=

3.1.3 newAddress(password,callback) ==> 页面展示 + keystore文件生成

Keystore文件生成步骤:

用户传入password,使用密钥生成函数(:kdf => “scrypt”)计算加密密钥 => encryption key

利用加密密钥对私钥进行加密(:cipher => “aes-128-ctr”)得到私钥加密后密文 => ciphertext

通过加密密钥(左第二个字节起的16个字节)和ciphertext连接在一起进行哈希散列(SHA3-256)计算得出校验值 => mac

3.1.3 newAddress(password,callback) ==> 页面展示 + keystore文件生成”></p>
<p style=3.1.3 newAddress(password,callback) ==> 页面展示 + keystore文件生成”></p>
<p style=3.1.3 newAddress(password,callback) ==> 页面展示 + keystore文件生成”></p>
<p style=

3.2 /src/view/WalletSeed.vue ==> 创建钱包(自定义助记词)

3.2 /src/view/WalletSeed.vue ==> 创建钱包(自定义助记词)”></p>
<p>在/Wallet基础上多传入一个Seed参数并增加一个Seed检验参数,基本原理和无seed钱包相同,只是跳过了助记词自动生成的过程,这里不再赘述</p>
<p style=3.2 /src/view/WalletSeed.vue ==> 创建钱包(自定义助记词)”></p>
<p style=3.2 /src/view/WalletSeed.vue ==> 创建钱包(自定义助记词)”></p>
<h3>3.3 /src/view/ImportKeystore.vue ==> 导入Keystore 逻辑处理</h3>
<p>生成Keystore是将私钥利用加密密钥(kdf(password) => 加密密钥)将私钥加密的过程,而导入keystore是利用解密密钥(kdf(password) => 解密密钥) 将Keystore还原为私钥的过程,不再赘述</p>
<h3>3.4 /src/view/ValueTransaction.vue ==> 交易逻辑处理</h3>
<p>交易步骤</p>
<blockquote>
<p>(1)先导入Keystore(略)</p>
<p>(2)制造一笔交易并进行签名</p>
<p>(3)发送该笔已经签名的交易到网络</p>
<p>(4)确认交易</p>
</blockquote>
<p style=3.4 /src/view/ValueTransaction.vue ==> 交易逻辑处理”></p>
<p style=3.4 /src/view/ValueTransaction.vue ==> 交易逻辑处理”></p>
<p><b>3.4.1 签名交易函数分析</b></p>
<p style=3.4.1 签名交易函数分析

3.4.2 发送交易到网络函数分析

3.4.2 发送交易到网络函数分析

3.4.2 发送交易到网络函数分析

3.4.3 确认交易函数分析

3.4.3 确认交易函数分析

结语:本文主要对该钱包的一些主要功能(私钥生成,keystore,交易)进行代码分析以及对代码逻辑捋顺。因笔者水平有限,没有太深入底层代码的研究,但通过对该钱包的逻辑理解,若以后要进行更’丰富’钱包开发会对理解钱包开发的各种库的原理有一定的帮助。

四、参考

https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki

https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

http://web3.tryblockchain.org/Web3.js-api-refrence.html#toc_44

https://en.wikipedia.org/wiki/Key_derivation_function

https://ethfans.org/posts/what-is-an-ethereum-keystore-file

*本文作者:BUGX,转载请注明来自FreeBuf.COM

来源:freebuf.com 2018-10-30 19:00:26 by: BUGX

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论