Appearance
加法器 

在 Sepolia 网络上部署加法器合约,在前端 Dapp 页面上点击 Add 即向合约里的 counter + 1
操作步骤:
- 部署合约
- 创建 vue工程
- 引入 Web3.js依赖
- 前端连接区块链网络 - 连接钱包
- 与合约交互
 
技术准备 
| Nodejs v18.16.0 | Web3.js 1.8.0 | Vue 3 | 
|---|
合约部分 
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Counter {
    uint256 public count = 0;
    function add() public {
        count += 1;
    }
}作者已部署到 Sepolia 网络
bash
https://sepolia.etherscan.io/address/0x2383507348bfcce28ea9293a4ae3cd6cdfafd11f合约地址 0x2383507348BfCce28ea9293A4AE3cD6cDfaFd11F
创建 vue 工程 
bash
npm init vue@latest
将 src/App.vue 替换为
vue
<template></template>
<script></script>引入 Web3.js 依赖 
在 vue 项目根目录下输入
bash
npm i web3@1.8.0前端连接区块链网络 
与合约交互分为 读 和 写 两类。如果只是简单读取合约信息,则可以直接读取;如果是要修改合约上的数据(本例中的 counter + 1),则需要支付 gas,本质上这是 发送交易,因此需要先连接钱包
1. 连接钱包 
首先检查游览器是否安装 metamask,如果未安装则弹出警告,如果已安装则连接钱包
vue
<script>
import Web3 from "web3";
export default {
  data() {
    return {
      account: null,  // 用于存储连接的钱包地址
      web3: null,     // 用于存储Web3实例
    };
  },
  methods: {
    async connectWallet() {
      if (typeof window.ethereum !== 'undefined' || (typeof window.web3 !== 'undefined')) {
        // 使用MetaMask的Ethereum提供商
        this.web3 = new Web3(window.ethereum || window.web3.currentProvider);
        try {
          // 请求连接钱包
          const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
          this.account = accounts[0];  // 保存连接的账户
        } catch (error) {
          console.error("用户拒绝了连接请求");
        }
      } else {
        alert("请安装MetaMask钱包!");
      }
    }
  }
};
</script>2. 与合约交互 
通过合约 abi 已经合约 address 构造合约对象,进而与合约进行交互
- 获取 - counter的值js- async getCounter() { this.counter = await this.contract.methods.count().call() },
- Add逻辑js- async add() { try { let res = await this.contract.methods.add().send({ from: this.account, }); await this.getCounter(); // 交易完成后更新计数 this.hash = res.transactionHash } catch (error) { console.error('Transaction failed:', error); } }
完整代码 src/App.vue 
vue
<template>
  <h1>当前值: {{ counter }}</h1>
  <br>
  <h2>钱包地址: {{ account ? account : '请先连接钱包' }}</h2>
  <br><br>
  <button @click="connectWallet">连接钱包</button>
  <button @click="add">Add {{ hash ? hash : '' }}</button>
</template>
<script>
import Web3 from "web3";
export default {
  data() {
    return {
      account: null,  // 用于存储连接的钱包地址
      web3: null,     // 用于存储Web3实例
      contract: null,
      counter: '请先连接钱包',     // 计数器值
      hash: null    // 交易哈希
    };
  },
  methods: {
    // 获取 counter 值
    async getCounter() {
      this.counter = await this.contract.methods.count().call()
    },
    // 连接钱包
    async connectWallet() {
      if (typeof window.ethereum !== 'undefined' || (typeof window.web3 !== 'undefined')) {
        // 使用MetaMask的Ethereum提供商
        this.web3 = new Web3(window.ethereum || window.web3.currentProvider);
        try {
          // 请求连接钱包
          const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
          this.account = accounts[0];  // 保存连接的账户
        } catch (error) {
          console.error("用户拒绝了连接请求")
          return;
        }
      } else {
        alert("请安装MetaMask钱包!");
        return
      }
      // 钱包连接成功后,构造合约对象
      // 合约 abi
      let abi = [
        {
          "inputs": [],
          "name": "add",
          "outputs": [],
          "stateMutability": "nonpayable",
          "type": "function"
        },
        {
          "inputs": [],
          "name": "count",
          "outputs": [
            {
              "internalType": "uint256",
              "name": "",
              "type": "uint256"
            }
          ],
          "stateMutability": "view",
          "type": "function"
        }
      ]
      // 合约地址
      let address = '0x2383507348BfCce28ea9293A4AE3cD6cDfaFd11F'
      this.contract = new this.web3.eth.Contract(abi, address);
      this.getCounter()
    },
    // Add 按钮
    async add() {
      try {
        let res = await this.contract.methods.add().send({
          from: this.account,
        });
        await this.getCounter();  // 交易完成后更新计数
        this.hash = res.transactionHash
      } catch (error) {
        console.error('Transaction failed:', error);
      }
    }
  }
};
</script>