以太坊钱包与签名器:ethers.js 4.0 使用指南

·

在以太坊生态系统中,钱包(Wallet)是管理私钥与公钥对的核心工具,用于对交易进行加密签名,并证明用户对账户和资产的所有权。ethers.js 库提供了一个功能完备的 Wallet 类,它实现了 Signer API,适用于所有需要签名的场景。

本文将深入介绍 ethers.js 4.0 中 Wallet 与 Signer 的使用方法,涵盖创建实例、签名操作、区块链交互以及加密存储等关键功能。

创建钱包实例

ethers.js 支持多种方式创建钱包实例,满足不同场景的需求。

从私钥创建

使用私钥字符串直接创建钱包实例,并可选择连接至一个 Provider:

let privateKey = "0x0123456789012345678901234567890123456789012345678901234567890123";
let wallet = new ethers.Wallet(privateKey);
// 连接至主网 Provider
let provider = ethers.getDefaultProvider();
let walletWithProvider = new ethers.Wallet(privateKey, provider);

创建随机钱包

使用 createRandom 方法生成一个全新的随机钱包。请务必妥善保管该钱包,一旦丢失将无法恢复

let randomWallet = ethers.Wallet.createRandom();

可选参数包括:

从助记词创建

基于 BIP-039 和 BIP-044 标准,从助记词生成钱包:

let mnemonic = "radar blur cabbage chef fix engine embark joy scheme fiction master release";
let wallet = ethers.Wallet.fromMnemonic(mnemonic);
// 使用自定义路径生成第二个账户
let path = "m/44'/60'/1'/0/0";
let secondWallet = ethers.Wallet.fromMnemonic(mnemonic, path);

ethers.js 支持多种语言助记词词表,包括英文、意大利文、日文、韩文、简体中文和繁体中文。

从加密 JSON 文件导入

解密来自 Geth、Parity 或其他工具的加密 JSON 钱包文件:

let data = { ... }; // JSON 钱包数据
let json = JSON.stringify(data);
let password = "foo";
ethers.Wallet.fromEncryptedJson(json, password).then(function(wallet) {
 console.log("地址: " + wallet.address);
});

钱包属性与方法

每个钱包实例都包含以下关键属性和方法:

基本属性

连接至新 Provider

使用 connect 方法创建连接至新 Provider 的钱包实例:

let newWallet = wallet.connect(newProvider);

签名操作

钱包的核心功能是对交易和消息进行签名。

交易签名

使用 sign 方法对交易进行签名:

let transaction = {
 nonce: 0,
 gasLimit: 21000,
 gasPrice: utils.bigNumberify("20000000000"),
 to: "0x88a5C2d9919e46F883EB62F7b8Dd9d0CC45bc290",
 value: utils.parseEther("1.0"),
 data: "0x",
 chainId: ethers.utils.getNetwork('homestead').chainId
};

wallet.sign(transaction).then((signedTransaction) => {
 console.log("已签名交易: " + signedTransaction);
});

👉 查看实时交易签名工具

消息签名

可以对文本消息或二进制数据进行签名:

文本消息签名:

wallet.signMessage("Hello World!").then((signature) => {
 console.log("签名结果: " + signature);
});

二进制数据签名:

let hash = "0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0";
let binaryData = ethers.utils.arrayify(hash);
wallet.signMessage(binaryData).then((signature) => {
 console.log("签名结果: " + signature);
});

区块链交互

连接 Provider 后,钱包可以进行各种区块链操作。

查询操作

// 查询余额
wallet.getBalance().then((balance) => {
 console.log("余额: " + balance.toString());
});

// 查询交易计数
wallet.getTransactionCount().then((nonce) => {
 console.log("交易次数: " + nonce);
});

// 估算gas费用
wallet.estimateGas(transaction).then((gasEstimate) => {
 console.log("预估Gas: " + gasEstimate.toString());
});

发送交易

使用 sendTransaction 方法发送交易,该方法会自动填充缺失的参数:

let tx = {
 to: "0x88a5c2d9919e46f883eb62f7b8dd9d0cc45bc290",
 value: ethers.utils.parseEther('1.0')
};

wallet.sendTransaction(tx).then((transaction) => {
 console.log("交易已发送: " + transaction.hash);
});

加密存储钱包

为了保护私钥安全,可以将钱包加密为 JSON 格式存储:

let password = "password123";
wallet.encrypt(password, function(progress) {
 console.log("加密进度: " + parseInt(progress * 100) + "%");
}).then(function(json) {
 console.log("加密后的JSON: " + json);
 // 可安全存储此JSON字符串
});

加密选项包括 salt、iv、uuid 和 scrypt 参数等,但通常不需要手动指定。

Signer API 简介

Signer API 是一个抽象类,为扩展和添加新签名器提供了基础框架。除了 Wallet 类外,JsonRpcSigner 和 Ledger 硬件钱包签名器等也都实现了此 API。

必须实现的属性和方法

👉 探索更多高级签名策略

常见问题

什么是以太坊钱包?

以太坊钱包是管理私钥和公钥对的工具,用于对交易进行加密签名并证明账户所有权。它不直接存储资产,而是存储访问和控制资产的密钥。

如何安全地存储钱包?

对于随机生成的钱包,务必离线备份私钥或助记词。推荐使用加密JSON文件结合强密码的方式存储,并将密码与备份分开保管。

助记词和私钥有什么区别?

助记词是一组易于记忆的单词,可以通过标准算法派生出一系列私钥和地址。私钥是直接用于签名的256位数字。助记词更方便备份多个账户,而私钥则针对单个账户。

什么时候需要连接 Provider?

当需要进行区块链查询(如获取余额、nonce)或发送交易时,需要连接 Provider。对于纯签名操作,可以不连接 Provider。

如何选择助记词语言?

英文助记词得到最广泛支持,但 ethers.js 也支持多种语言。选择时考虑兼容性和易记性,简体中文助记词适合中文用户记忆。

加密JSON钱包有哪些优势?

加密JSON钱包提供了安全性与便携性的平衡。通过强密码加密,即使文件泄露,没有密码也无法访问资金。同时方便在不同设备间迁移钱包。

通过掌握 ethers.js 的 Wallet 和 Signer API,开发者可以构建安全可靠的以太坊应用,有效管理数字资产和执行区块链操作。