创建以太坊钱包代码,从零开始掌握核心技术与实践

时间: 2026-03-19 5:51 阅读数: 18人阅读

在区块链世界中,以太坊钱包是用户与以太坊网络交互的核心工具,它不仅存储以太币(ETH),还管理各种代币和智能合约的访问权限,从技术角度看,创建以太坊钱包的核心是生成符合以太坊标准的账户对(公钥+私钥),并实现与以太坊节点的通信,本文将带你从零开始,通过代码实践深入理解以太坊钱包的创建原理与实现过程。

以太坊钱包的核心概念

在动手写代码前,我们需要先明确几个关键概念:

账户结构

以太坊账户分为外部账户(Externally Owned Account, EOA)合约账户,我们通常说的“钱包”指的是外部账户,由以下两部分组成:

  • 私钥(Private Key):32字节的随机数,相当于账户的“密码”,必须严格保密,私钥可以推导出公钥,进而生成地址,一旦丢失,账户中的资产将无法找回。
  • 随机配图
trong>公钥(Public Key):64字节,通过椭圆曲线算法(secp256k1)由私钥生成,公钥用于生成地址,但不会暴露私钥。
  • 地址(Address):20字节,由公钥通过哈希算法(Keccak-256)计算得出,相当于账户的“身份证”,可以公开分享用于接收资产。
  • 助记词(Mnemonic)

    为了方便用户备份私钥,以太坊遵循BIP39标准,将私钥转换为12或24个英文单词(如“witch collapse practice feed shame open despair creek road again ice least”),助记词可以还原出私钥,从而恢复整个钱包,是行业通用的备份方式。

    钱包文件(Keystore)

    为了保护私钥安全,钱包通常会将私钥加密后存储为JSON文件(如UTC文件),加密时需要用户设置密码,这种方式避免了明文存储私钥,但密码一旦丢失,文件也无法解密。

    开发环境准备

    在编写代码前,我们需要准备以下工具:

    开发语言与库

    本文使用JavaScript(Node.js)作为开发语言,借助ethers.js库(以太坊最流行的工具库之一)实现钱包创建功能,ethers.js提供了简洁的API,支持私钥、助记词、钱包文件的生成与解析,同时兼容以太坊节点交互。

    安装ethers.js:

    npm install ethers

    Node.js环境

    确保已安装Node.js(建议版本≥16.0),可通过以下命令检查:

    node -v
    npm -v

    创建以太坊钱包的代码实现

    我们将通过三种常见方式创建钱包:直接生成私钥、通过助记词生成、从Keystore文件导入。

    方式一:直接生成私钥并创建钱包

    这是最基础的方式,通过随机生成私钥,直接创建对应的钱包对象。

    const { ethers } = require("ethers");
    // 1. 生成随机私钥(32字节随机数,以0x开头)
    const privateKey = ethers.Wallet.createRandom().privateKey;
    console.log("私钥:", privateKey);
    // 2. 通过私钥创建钱包对象
    const wallet = new ethers.Wallet(privateKey);
    // 3. 获取钱包信息
    console.log("公钥:", wallet.publicKey);
    console.log("地址:", wallet.address);
    console.log("助记词:", wallet.mnemonic?.phrase); // 随机生成的钱包会自动关联助记词

    代码解析

    • ethers.Wallet.createRandom():生成一个随机钱包,内部会生成私钥、公钥、地址和助记词。
    • new ethers.Wallet(privateKey):通过已有私钥创建钱包对象,无需额外计算。

    方式二:通过助记词恢复钱包

    助记词是钱包备份的核心,用户可以通过助记词恢复任意已创建的钱包。

    const { ethers } = require("ethers");
    // 1. 定义助记词(假设用户已有助记词)
    const mnemonic = "witch collapse practice feed shame open despair creek road again ice least";
    // 2. 通过助记词创建钱包
    const wallet = ethers.Wallet.fromMnemonic(mnemonic);
    // 3. 获取钱包信息
    console.log("助记词:", mnemonic);
    console.log("私钥:", wallet.privateKey);
    console.log("地址:", wallet.address);
    // 4. 支持从指定路径派生地址(遵循BIP44标准,路径:m/44'/60'/0'/0/0)
    const walletFromPath = ethers.Wallet.fromMnemonic(mnemonic, "m/44'/60'/0'/0/0");
    console.log("派生地址:", walletFromPath.address);

    代码解析

    • ethers.Wallet.fromMnemonic(mnemonic):通过助记词创建默认路径的钱包(路径:m/44'/60'/0'/0/0)。
    • 支持自定义派生路径(如多账户管理),BIP44标准中,以太坊的币种类型为60',账户索引从0开始。

    方式三:从Keystore文件导入钱包

    Keystore文件是加密后的私钥存储方式,用户需要输入密码才能解密并导入钱包。

    (1)生成Keystore文件

    const { ethers } = require("ethers");
    // 1. 创建一个随机钱包(作为待加密的钱包)
    const wallet = ethers.Wallet.createRandom();
    const password = "MySecurePassword123!"; // 加密密码
    // 2. 导出为Keystore文件(JSON格式)
    const keystoreJson = wallet.encryptSync(password);
    console.log("Keystore文件:", JSON.stringify(keystoreJson, null, 2));

    (2)从Keystore文件导入钱包

    const { ethers } = require("ethers");
    // 1. 假设已有Keystore文件和密码
    const keystoreJson = {
      "address": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "version": 3,
      "Crypto": {
        "cipher": "aes-128-ctr",
        "ciphertext": "0x123...def",
        "cipherparams": { "iv": "0x456...abc" },
        "kdf": "scrypt",
        "kdfparams": {
          "dklen": 32,
          "n": 262144,
          "r": 8,
          "p": 1,
          "salt": "0x789...xyz"
        },
        "mac": "0xabc...def"
      }
    };
    const password = "MySecurePassword123!";
    // 2. 从Keystore文件导入钱包
    const importedWallet = await ethers.Wallet.fromEncryptedJson(keystoreJson, password);
    console.log("导入的地址:", importedWallet.address);
    console.log("导入的私钥:", importedWallet.privateKey);

    代码解析

    • wallet.encryptSync(password):同步生成Keystore文件,包含加密后的私钥和元数据。
    • ethers.Wallet.fromEncryptedJson(keystoreJson, password):异步解密Keystore文件,返回钱包对象(需提供正确密码)。

    钱包的进阶功能:签名与交易

    创建钱包后,核心功能是发送交易(如转账ETH或调用智能合约),下面以发送ETH为例,展示钱包的签名与交易过程。

    连接以太坊节点

    发送交易需要连接到以太坊节点,可以使用Infura(公共节点服务)或本地节点(如Geth)。

    const { ethers } = require("ethers");
    // 1. 创建钱包(假设已有)
    const privateKey = "0x你的私钥";
    const wallet = new ethers.Wallet(privateKey);
    // 2. 连接以太坊节点(以Infura为例)
    const provider = new ethers.providers.InfuraProvider("goerli", "你的Infura项目ID"); // goerli是测试网
    const connectedWallet = wallet.connect(provider);
    console.log("钱包地址:", connectedWallet.address);
    console.log("当前ETH余额:", await connectedWallet.getBalance());

    发送ETH交易

    const { ethers } = require("ethers");
    // 1. 钱包与节点连接(同上)
    const privateKey = "0x你的私钥";
    const provider = new ethers.providers.InfuraProvider("goerli", "你的Infura项目ID");
    const wallet = new ethers.Wallet(privateKey).connect(provider);
    // 2. 定义交易参数
    const recipientAddress = "0x接收方地址";
    const amount = ethers.utils.parseEther("0

    上一篇:

    下一篇: