智能合约开发笔记--html页面使用ethers.js与合约交互

本文提供一个例子,演示在html页面中如何使用ethers.js,并通过metamask钱包连接,与区块链进行交互。包含的内容有:

1.查询metamask钱包的账户地址,账户金额;

2.与样例合约 Greeter进行交互, 调用查询方法;调用修改状态变量的方法; 监听事件,对修改后的状态进行回调。

直接上代码:

示例合约: Greeter.sol #选用hardhat项目的默认示例,加了一个event

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Greeter {
    string private greeting;

    constructor(string memory _greeting) {
        console.log("Deploying a Greeter with greeting:", _greeting);
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
        greeting = _greeting;
        emit SetGreet(_greeting,msg.sender);
    }

    event SetGreet(string _greeting,address sender);
}

html页面代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>webapp</title>
  <style>
    body div {
      margin-bottom: 30px;

    }

    .wallet, .interact_to_contract{
      width: 450px;
      margin-top: 30px;

    }
    .wallet button{
      width: 100%;
    }


    .dogreet{
      width: 100%;
    }
  </style>
</head>

<body>
  <div class="wallet">
    <button onclick="connect_to_metamask()">连接metamask钱包</button><br /><br>
    账户地址:<span id="txt_curent_addr"></span><br /><br>
    账户余额:<span id="txt_balance"></span><br />
  </div>
  <hr style="border:solid #987cb9;" width="100%">

  <div class="interact_to_contract">
    <button onclick="doGreet()" class="dogreet">Greeter合约greet函数</button><br /><br>
    <input id="input_greeting"><button onclick="doSetGreeting()">Greeter合约setGreeting</button><br/><br>

    <span id="txt_greet_log"></span>
  </div>


</body>

</html>

<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>

<script>

  //创建一个Provider
  const provider = new ethers.providers.Web3Provider(window.ethereum)
  const greet_addr="0x5fbdb2315678afecb367f032d93f642f64180aa3";


  //Greeter合约的ABI
  const greetAbi= [
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "_greeting",
          "type": "string"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "_greeting",
          "type": "string"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        }
      ],
      "name": "SetGreet",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "greet",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "_greeting",
          "type": "string"
        }
      ],
      "name": "setGreeting",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]



  /**
   * 连接metamask钱包,获取余额
   */
  async function connect_to_metamask() {

    //向钱包发送授权请求
    const accounts = await provider.send("eth_requestAccounts", []);

    //获取账户余额信息
    if (accounts && accounts.length > 0) {
      let myAccountAddr = accounts[0];
      let balance = ethers.utils.formatEther(await provider.getBalance(myAccountAddr));
      let network = await provider.getNetwork();

      //显示在界面上;
      document.getElementById('txt_curent_addr').innerText = myAccountAddr;
      document.getElementById('txt_balance').innerText = balance;

      console.log("当前账户地址:", myAccountAddr);
      console.log("金额:", balance);
      console.log("Chain Info;", network.chainId, network.name);

    }
  }


  /**
   *访问合约的查询函数
   */
  async function doGreet(){

    const greet = new ethers.Contract(greet_addr, greetAbi, provider);

    //与合约交互;
    const wd = await greet.greet();
    document.getElementById("txt_greet_log").innerText='greeting:'+wd;

  }

  /*
    修改合约的状态变量
  */
  async function doSetGreeting(){

    let str=document.getElementById('input_greeting').value;
    console.log(str);

    const signer=provider.getSigner();
    const greet = new ethers.Contract(greet_addr, greetAbi, signer);

    //与合约交互;

  await  greet.setGreeting(str);

//监控事件,对结果进行处理
  greet.on("SetGreet",(greeting,sender)=>{
      if(greeting==str){
        console.log("修改完成!",sender,greeting);
        document.getElementById("txt_greet_log").innerText='greeting:'+greeting//"Greeting 已经修改成了:"+greeting+"</br>修改者:"+sender;
      }
    })

  }

</script>

演示方法说明:

1.使用hardhat 开启一个本地节点;  不熟悉的可以看我的上一篇hardhat使用入门

2.将上面的合约发布到本在环境;

3.在chrome中打开metamask 连接到本地环境;

4.将上面的html代码保存成html文件,放到本地web服务器根目录下,然后在chrome打开;  可以在页面中进行测试;

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海阔天空_cn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值