以太坊钱包开发系列1 - 建立钱包帐号

本文首发于深刻浅出区块链社区 原文连接:使用 ethers.js 开发以太坊 Web 钱包 1 - 建立钱包帐号) 原文已更新,请读者前往原文阅读html

以太坊去中心化网页钱包开发系列,将从零开始开发出一个能够实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:建立钱包帐号帐号Keystore文件导入导出展现钱包信息及发起签名交易发送Token(代币),这是第一篇,主要介绍钱包将实现哪些功能及怎么建立钱包帐号,本钱包是基于ethers.js 进行开发。web

去中心化网页钱包

先明确一下定义,什么是去中心化钱包,帐号秘钥的管理,交易的签名,都是在客户端完成, 即私钥相关的信息都是在用户手中,钱包的开发者接触不到私钥信息。数组

对应的中心化钱包则是私钥由中心服务器托管,如交易所的钱包就是这种。浏览器

网页钱包,或者叫web钱包,是指钱包以网页的形式展示,去中心化网页钱包则交易的签名等操做是在浏览器里完成。 其余形式的钱包,如Android钱包或iOS钱包其开发思路和web钱包同样,所以文本对开发其余平台的钱包也有参考意义,不过本系列文章主要侧重在钱包功能的实现,并未过多考虑用户体验。服务器

钱包功能

一个钱包一般主要包含的功能有:dom

  • 帐号管理(主要是私钥的管理):建立帐号、帐号导入导出
  • 帐号信息展现:如以太币余额、Token(代币)余额。
  • 转帐功能:发送以太币及发送Token(代币)

这些功能将基于 ethers.js 进行开发, ethers.js 和web3.js 同样,也是一套和以太坊区块链进行交互的库,不只如此,ethers.js 还对BIP 39等相关的提案进行了实现,能够在这个连接阅读其文档。区块链

这些功能主要表现为钱包的两个界面,一个界面是:帐号管理,一个界面是进行帐号信息展现及转帐。下面逐个进行介绍加密

建立钱包帐号

读过上一篇文章理解开发HD 钱包涉及的 BIP3二、BIP4四、BIP39的同窗,会知道建立帐号,能够有两种方式:.net

  • 直接生成32个字节的数当成私钥
  • 经过助记词进行肯定性推导出私钥

使用随机数做为私钥建立钱包帐号

即方式一,可使用ethers.utils.randomBytes生成一个随机数,而后使用这个随机数来建立钱包,如代码:设计

var privateKey = ethers.utils.randomBytes(32);
var wallet = new ethers.Wallet(privateKey);
console.log("帐号地址: " + wallet.address);

上面代码的 wallet 是 ethers 中的一个钱包对象,它除了有代码中出现的.address 属性以外,还有如 获取余额、发送交易等方法,在后面的文章会进行介绍。

注意ethers.utils.randomBytes 生成的是一个字节数组,若是想用十六进制数显示出来表示,须要转化为BigNumber代码以下:

let keyNumber = ethers.utils.bigNumberify(privateKey);
console.log(randomNumber._hex);

如今咱们结合界面,完整的实现建立帐号,其效果图以下,加载私钥时建立帐号。

界面代码(HTML)代码以下(主要是在表格中定义个一个输入框及一个按钮):

<table>
                    <tr>
                        <th>私钥:</th>
                        <td><input type="text" placeholder="(private key)" id="select-privatekey" /></td>
                    </tr>
                    <tr>
                        <td> </td>
                        <td>
                            <div id="select-submit-privatekey" class="submit">加载私钥</div>
                        </td>
                    </tr>
                </table>

对应的逻辑代码(JavaScript)以下:

// 使用JQuery获取两个UI标签
    var inputPrivatekey = $('#select-privatekey');
    var submit = $('#select-submit-privatekey');

// 生成一个默认的私钥
    let randomNumber = ethers.utils.bigNumberify(ethers.utils.randomBytes(32));
    inputPrivatekey.val(randomNumber._hex);

// 点击“加载私钥”时, 建立对应的钱包
    submit.click(function() {
        var privateKey = inputPrivatekey.val();
        if (privateKey.substring(0, 2) !== '0x') { privateKey = '0x' + privateKey; }
       var wallet = new ethers.Wallet(privateKey));

    });

若是用户提供一个已有帐号的私钥,则会导入其原有帐号。

经过助记词方式建立钱包帐号

这是目前主流常见钱包的方式,关于助记词推导过程请阅读理解开发HD 钱包涉及的 BIP3二、BIP4四、BIP39

咱们须要先生成一个随机数,而后用随机数生成助记词,随后用助记词建立钱包帐号,设计到的API有:

var rand = ethers.utils.randomBytes(16);

// 生成助记词
var mnemonic = ethers.utils.HDNode.entropyToMnemonic(rand);

var path = "m/44'/60'/0'/0/0";

// 经过助记词建立钱包
ethers.Wallet.fromMnemonic(mnemonic, path);

如今咱们结合界面来实现一下经过助记词方式建立钱包帐号,其效果图以下:

界面代码(HTML)代码以下(主要是在表格中定义个两个输入框及一个按钮):

<table>
        <tr>
            <th>助记词:</th>
            <td><input type="text" placeholder="(mnemonic phrase)" id="select-mnemonic-phrase" /></td>
        </tr>
        <tr>
            <th>Path:</th>
            <td><input type="text" placeholder="(path)" id="select-mnemonic-path" value="m/44'/60'/0'/0/0" /></td>
        </tr>
        <tr>
            <td> </td>
            <td>
                <div id="select-submit-mnemonic" class="submit">推倒</div>
            </td>
        </tr>
    </table>

对应的逻辑代码(JavaScript)以下:

var inputPhrase = $('#select-mnemonic-phrase');
    var inputPath = $('#select-mnemonic-path');
    var submit = $('#select-submit-mnemonic');

// 生成助记词
    var mnemonic = ethers.utils.HDNode.entropyToMnemonic(ethers.utils.randomBytes(16));
    inputPhrase.val(mnemonic);

    submit.click(function() {
    // 检查助记词是否有效。
        if (!ethers.utils.HDNode.isValidMnemonic(inputPhrase.val())) {
            return;
        }

// 经过助记词建立钱包对象
       var wallet = ethers.Wallet.fromMnemonic(inputPhrase.val(), inputPath.val());
    });

一样用户能够提供一个其保存的助记词来导入其钱包,有一些遗憾的是,ethers.js 暂时不支持经过添加密码做为Salt来保护种子(也多是我没有找到,若是知道的同窗,但愿反馈下),若是须要此功能能够引入bip39 和 ethereumjs-wallet 库来实现,代码可参考理解开发HD 钱包涉及的 BIP3二、BIP4四、BIP39

小结

其实 ethers 还提供了一个更简单的方法来建立钱包:

// 直接建立一个随机钱包
   ethers.Wallet.createRandom();

https://my.oschina.net/u/3724910