ethers.js 简单demo

使用到的技术栈和工具

源码地址:github.com/luopeihai/e...

项目环境构建

  1. create-react-app 创建react项目 npx create-react-app ethers-example

  2. Hardhat 配置项目区块链开发环境 安装hardhat 依赖包npm install --save-dev hardhat

    配置启动hardhat的script并执行该指令

js 复制代码
// package.json
scripts:{
    "start:hardhat": "hardhat node"
}

运行 hardhat node 后生成文件:

  • hardhat.config.jshard配置文件
  • deploy.js部署智能契约文件
  • Lock.sol智能契约
  • Lock.js Lock.sol ut

再次运行npm run start:hardhat 启动 hardhat 服务并列出测试账号,拿到Private Key 导入Metamask账号

  1. ethers.js 引入和链接Metamask钱包 首先 npm install ethers --save 我安装的是 ethers.js v6的版本

链接 Metamask钱包

通过 ethers.js 链接 Metamask

js 复制代码
// app.js
import { ethers } from "ethers";
import "./App.css";

function App() {
  const connect = async () => {
    let signer = null;
    let provider;

    if (window.ethereum == null) {
      console.log("MetaMask not installed; using read-only defaults");
      provider = ethers.getDefaultProvider();
    } else {
      provider = new ethers.BrowserProvider(window.ethereum);
      signer = await provider.getSigner();
    }
    // 当前访问人address
    const addr = await signer.getAddress();
    console.log("addr", addr);
  };

  return (
    <div className="App">
      <p>
        <button onClick={connect}>connect wallet</button>
      </p>
    </div>
  );
}

export default App;

点击 "connect wallet" 链接钱包,授权成功后 控制台将打印出当前访问用户的address

调用Lock.sol智能合约

在Lock.sol添加 成员message 和 事件SetMessage代码

js 复制代码
// contracts/Lock.sol

    string public message = "hello world";
    event SetMessage(string new_msg);

    function setMessage(string memory _msg)external{
        message = _msg;
        emit SetMessage(_msg);
    }

修改完契约后需要依次执行compiledeploy操作, 先把对应script配置上

js 复制代码
 // package.json
 script:{
   ...
   "build:hardhat": "hardhat compile",
   "deploy:hardhat": "hardhat run ./scripts/deploy.js --network localhost"
 }
 

依次执行指令
npm run build:hardhat 生成编译文件artifacts , cache
npm run deploy:hardhat 将生成智能契约 address

app.js 中引入 compile 后的 Lock.json

js 复制代码
// app.js

import Lock from "../artifacts/contracts/Lock.sol/Lock.json";

react server将报错,

shell 复制代码
Module not found: Error: You attempted to import ../artifacts/contracts/Lock.sol/Lock.json which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project's node_modules/.

报错原因是 create-app-react 有效代码需要在 src目录下,那就设置hardhat.config.js编译后的文件导出到src/下,修改配置如下:

js 复制代码
// hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.19",
  paths: {
    artifacts: "./src/artifacts",
  },
};

保存修改,再次npm run build:hardhat npm run deploy:hardhat,运行成功后 src 中将多出契约编译后文件artifacts

app.js 中引入编译后的契约json信息

js 复制代码
// app.js

import Lock from "./artifacts/contracts/Lock.sol/Lock.json";

添加 readMessage读取Lock.sol中的成员messagesetMessage触发Lock.sol中 SetMessage事件

js 复制代码
// app.js

 const readMessage = async () => {
    const provider = new ethers.BrowserProvider(window.ethereum);
    
    const lock = new ethers.Contract(
      YOUR_DEPLOY_ADDRESS, 
      Lock.abi,
      provider
    );
    const message = await lock.message();
    alert(message);
  };

  const setMessage = async () => {
    const provider = new ethers.BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    let lock = new ethers.Contract(
      YOUR_DEPLOY_ADDRESS,
      Lock.abi,
      signer
    );
    let transaction = await lock
      .connect(signer)
      .setMessage("world hello!");
    let result = await transaction.wait();
    alert(result.logs[0].args);
  };
  

YOUR_DEPLOY_ADDRESS 为 npm run deploy:hardhat 发布成功后显示的 Lock.sol address

点击 readMessage按钮将alert "hello world"

点击 setMessage ,由于该方法为写入操作需要支付 "燃料",所以Metamask 将提示确认

点击"确认"后将alert "hello world"

相关推荐
Point5 分钟前
[LeetCode] 最长连续序列
前端·javascript·算法
rookiesx9 分钟前
安装本地python文件到site-packages
开发语言·前端·python
支撑前端荣耀10 分钟前
九、把异常当回事,代码才靠谱
前端
LotteChar18 分钟前
HTML:从 “小白” 到 “标签侠” 的修炼手册
前端·html
趣多多代言人20 分钟前
20分钟学会TypeScript
前端·javascript·typescript
90后的晨仔20 分钟前
⚙️ 《响应式原理》— Vue 是怎么做到自动更新的?
前端·vue.js
结城20 分钟前
深入掌握CSS Grid布局:每个属性详解与实战示例
前端·css
寒..26 分钟前
网络安全第三次作业
前端·css·html
90后的晨仔35 分钟前
🧮《计算属性》— 自动根据其它响应式数据得出结果
前端·vue.js
小白阿龙43 分钟前
如何实现缓存音频功能(App端详解)
前端·css·html5