使用 React+ethers.js 开发简单加密钱包(一)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 使用 React+ethers.js 开发简单加密钱包

最近在开发一个 NFT 二创平台,其中包含了很多概念和技术。我会更新一个系列的文章来总结和沉淀在这个过程中的一些知识与思考。

本文是对 ethers.js 进行一个全方位介绍,非常适合 web3 入门学习。


什么是 ethers.js?


Web3 中的各类 DApp,都需要与智能合约进行交互。如果用原生 JS 来做这些事会很麻烦。这时就需要使用专属的 SDK。

目前 JS 环境中有两个主流的库可以用来和智能合约进行交互,一个是 web3.js,另一个是 ethers.js。


ethers.js VS web3.js


web3.js 比 ethers.js 出现的更早。但是目前 ethers.js 更受欢迎。

主要原因有如下两点:

  1. 体积:ethers.js 体积仅有 116.5kb,web3.js 有 590.6kb。相差 5 倍左右。
  2. 设计理念:由于设计理念不同。web3.js 认为用户会在本地部署以太坊节点,私钥和网络连接状态由这个节点管理。但实际上大部分人都不会在本地部署以太坊节点。ethers.js 充分考虑了这一点,它是用 Provider 管理网络连接状态,用 Wallet 管理密钥,更加安全和灵活。而且原生支持 ENS。

ethers.js 基本使用介绍


节点即服务


由于在本地部署一个区块链节点的成本并不低,很少会有人真的部署一个节点,而是选择使用节点即服务。

这类服务有很多,比如老牌的 Alchemy、Infura、Moralis 以及今年估值 102 亿美金的新秀 Tenderly。

在这里我们选择 Alchemy,目前它的市场占有率是最高的。

alchemy 的网址在这:dashboard.alchemy.com/。具体的注册登陆就不讲了。

登陆之后我们创建一个 App。

image.png

Chain 选择 Ethereum,Network 选择 Goerli。

image.png

这样就成功创建了一个 App,点击后面的 view key,就可以查看 key。

image.png

我们把它复制下来,后面会用到。

image.png


构造合约


在对合约进行读取或交互之前,我们首先需要构造一个合约对象。

合约对象有三个构造参数,第一个是合约地址,是一个字符串。第二个是合约的 abi,可以是一个 JSON,第三个参数是 provider 对象,它用于管理网络连接状态。

下面的例子中就是使用 alchemy 提供的 JSON RPC 接口作为网络连接。


const rpc = `https://eth-goerli.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_API_KEY}`;
const provider = new ethers.providers.JsonRpcProvider(rpc);
const contract = new ethers.Contract(contractAddress, abi, provider)

除了 JsonRpcProvider 以外,ethers 还有 IpcProvider、InfuraProvider、AlchemyProvider、Web3Provider 等多种 Provider。


读取合约信息


abi 中的方法会直接挂载到 contract 对象上,我们可以直接调用。

不过需要注意,所有的操作都是异步的。


(async () => {
  const owner = await contract.owner();
  console.log(owner);
})();


连接钱包


由于和合约交互需要支付 gas 费用,所以必须有一个数字钱包。

钱包有很多种,比如 MetaMask、Rainbow、Coinbase Wallet 等。其中 MetaMask 是最常用的一种数字钱包。

这里主要介绍如何连接到 MetaMask。

MetaMask 有一个浏览器插件,如果用户安装了该插件,在 window 对象下会有一个 ethereum 对象。我们可以调用 ethereum.request 方法发起请求,参数是一个对象,对象的 method 描述该次请求的操作。

ethereum.request 方法是异步的,会返回一个数组,该数组是所有登陆钱包的账户地址字符串,第一个账户就是当前激活的账户。如果返回的数组长度为 0,则意味着没有登陆任何账户。


(async ()=> {
  const accounts = await ethereum.request({ method: 'eth_requestAccounts' })
  if(accounts.length === 0) {
    throw Error('未登录任何账户')
  }
  const activeAccount = accounts[0]
  console.log(activeAccount)
})()

我们还可以通过 ethereum.request 方法获取当前的网络状态。


(async ()=> {
  const chainId = await ethereum.request({ method: 'eth_chainId' })
  console.log(chainId)
})()

它会返回一个字符串。0x1 表示以太网主网;0x5 表示 Goerli 测试网,更多网络的 chainId 可以在这个网站查看:chainlist.org/

下面是使用 ethers.js 来连接 MetaMask 的代码。


(async ()=> {
  const provider = new ethers.providers.Web3Provider(window.ethereum)
  const accounts = await provider.send("eth_requestAccounts", [])
  const activeAccount = accounts[0]
})()

如果使用 MetaMask 作为 provider,那么就不需要再使用 alchemy 了。


钱包


在转账交易之前,我们需要创建一个 Wallet 实例,它的作用是对交易和消息进行签名。

创建 Wallet 对象的方法有三种。

通过 Wallet.createRandom 创建随机钱包

这种方式创建的是一个单机钱包,需要连接网络。


const wallet = ethers.Wallet.createRandom()
wallet.connect(provider)

通过助记词创建


const wallet = new ethers.Wallet.fromMnemonic(mnenonic.phrase)

通过私钥和 provider 创建


const wallet = new ethers.Wallet(privateKey, provider)


钱包信息


我们可以在创建好的钱包上面获取很多有用的信息,比如钱包地址、助记词、私钥、交易次数等。


console.log(wallet.address)
console.log(await wallet.getAddress())
console.log(wallet.mnemonic)
console.log(wallet.privateKey)
console.log(wallet.getTransactionCount())


转账


一旦又了钱包,我们就可以向其他人发起转账交易。

创建一个 tx 对象,它最少需要两个属性,to 和 value,分别表示接受钱包地址和转账额度。

然后使用 wallet.sendTransaction 方法发送转账,它会返回一个 receipt 对象。这个对象有一个异步的 wait 方法,当交易上链后会返回。


const tx = {
  to: address,
  value: ethers.utils.parseEther("0.1"),
}
console.log('开始转账')
const receipt = await wallet.sendTransaction(tx)
await receipt.wait()
console.log('完成转账')


通过合约转账交易


交易需要使用 Wallet 对象。再通过 wallet 作为合约的第三个构造参数创建 Contract 对象。

调用合约的 transfer 方法,进行转账交易。该方法需要两个参数,转入的钱包地址字符串和转入的数量。

transfer 会返回一个 tx 对象,该对象有一个异步的 wait 方法,会在交易完成后执行。


const wallet = new ethers.Wallet(privateKey, provider)
const contract = new ethers.Contract(contractAddress, abi, wallet)
(async ()=> {
  const tx = await contract.transfer(toAddress, ethers.utils.parseEther("1"))
  await tx.wait()
})()


通过 signer 进行转账


通常我们无法直接拿到 privateKey,但是可以通过 signer 对象间接使用 privateKey。只需要进行签名就可以进行交易。这也是最常用的交易方式。


const signer = walletProvider.getSigner();
const tx = {
  to,
  value,
};
const receipt = await signer.sendTransaction(tx);
await receipt.wait();


使用 React 和 ethers.js 开发加密钱包


接下来我们开发一个最简单的加密钱包,具备最基础的转账功能和查询余额功能。


创建项目


我们首先创建一个 Next.js 项目。


npx create-next-app

需要选择 TypeScript。


安装依赖


安装 ethers.js


npm i ethers


安装 tailwindcss


npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

修改 tailwind.cinfig.js。


/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

修改 styles/globals.css。


@tailwind base;
@tailwind components;
@tailwind utilities;


安装 headless-ui


npm install @headlessui/react

相关文章
|
4月前
|
前端开发 JavaScript API
React开发需要了解的10个库
本文首发于微信公众号“前端徐徐”,介绍了React及其常用库。React是由Meta开发的JavaScript库,用于构建动态用户界面,广泛应用于Facebook、Instagram等知名网站。文章详细讲解了Axios、Formik、React Helmet、React-Redux、React Router DOM、Dotenv、ESLint、Storybook、Framer Motion和React Bootstrap等库的使用方法和应用场景,帮助开发者提升开发效率和代码质量。
184 4
React开发需要了解的10个库
|
10天前
|
前端开发 JavaScript Java
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
57 13
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
|
11天前
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
57 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
9天前
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
47 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
13天前
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
57 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
3月前
|
前端开发 JavaScript 测试技术
React 中集成 Chart.js 图表库
本文介绍了如何在 React 项目中集成 Chart.js 创建动态图表,涵盖基础概念、安装步骤、代码示例及常见问题解决方法,帮助开发者轻松实现数据可视化。
78 11
|
3月前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
167 10
|
3月前
|
资源调度 前端开发 数据可视化
构建高效的数据可视化仪表板:D3.js与React的融合之道
【10月更文挑战第25天】在数据驱动的时代,将复杂的数据集转换为直观、互动式的可视化表示已成为一项至关重要的技能。本文深入探讨了如何结合D3.js的强大可视化功能和React框架的响应式特性来构建高效、动态的数据可视化仪表板。文章首先介绍了D3.js和React的基础知识,然后通过一个实际的项目案例,详细阐述了如何将两者结合使用,并提供了实用的代码示例。无论你是数据科学家、前端开发者还是可视化爱好者,这篇文章都将为你提供宝贵的洞见和实用技能。
105 5
|
4月前
|
前端开发 JavaScript 开发者
React 组件化开发最佳实践
【10月更文挑战第4天】React 组件化开发最佳实践
89 4
|
4月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
74 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    49
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    Node.js 中实现多任务下载的并发控制策略
    34
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    47
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    57
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    57
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    57