实战2 接上实践1

  • 定义Provider
  • 实例化Web3
  • 实例化合约
  • 与合约交互

前端代码与以太坊交互分五步

  • 一个实例化的provider,可以是metamask,infura,truffle,ganache,或者搭建以太坊节点
  • 合约的abi,自己编写的合约通过编译后获得abi,链上的合约需要开源才能获得abi,erc20代币合约的abi都一样
  • 实例化web3.js或者ethers.js
  • 通过abi和合约地址将合约实例化
  • 调用合约方法,call或者send

创建一个计算合约部署到测试网 increase.sol
当编译完成后复制ABI到文本里 用于下面代码调取ABI

pragma solidity ^0.5.12;

contract Counter {
    uint256 public value;

    function increase(uint256 amount) public {
        value += amount;
    }
}

React代码
有些方法升级了版本 具体以Metamask提示为准可以进行升级

import React, { Component } from 'react';
import Web3 from "web3/dist/web3.min";
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  async componentDidMount() {
    //判断页面是否安装metamask
    if (typeof window.ethereum !== 'undefined') {
      const ethereum = window.ethereum
      //禁止自动刷新,metamask要求写的
      ethereum.autoRefreshOnNetworkChange = false

      try {
        //第一次链接Metamask
        //await 配合函数前加async
        const accounts = await ethereum.enable()
        // console.log(accounts)

        //初始化Provider
        const provider = window['ethereum']
        //输出Provider全部类方法可以在浏览器查看
        // console.log(provider)

        //获取网络ID
        // console.log(provider.chainId)

        //实例化web3
        const web3 = new Web3(provider)
        // console.log(web3)

        //导入abi文件
        const abi = require("./contract.abi.json")
        //console.log(abi)

        //定义合约地址
        const address = "0xB3abbE4009BCAd73d0fB8B539D4E5C33D250f022"

        //实例化合约
        window.myContract = new web3.eth.Contract(abi, address)
        console.log(window.myContract)

        // //获取加载钱包默认地址转换为小写
        window.defaultAccount = accounts[0].toLowerCase()
        console.log(window.defaultAccount)


        //账户切换监听
        ethereum.on('accountsChanged', function (accounts) {
          console.log("accountsChanged:" + accounts)
        })

        //网络切换监听
        ethereum.on('chainChanged', function (networkVersion) {
          console.log("chainChanged:" + networkVersion)
        })

      } catch (e) {

      }
    } else {
      console.log("没用安装mstamask")
    }
  }

  //调取合约变量
  Getter = () => {
    //value()是合约的public变量
    window.myContract.methods.value().call().then(value => {
      console.log(value)
      //赋值前端html
      this.setState({ value: value })

    })
  }

  //调取合约赋值
  Increase = () => {
    let num = 1;
    //使用window.defaultAccount地址发送合约
    window.myContract.methods.increase(num).send({from:window.defaultAccount})
    .on('transactionHash',(transactionHash) => {
      //获取交易哈希
      console.log('transactionHash',transactionHash)
    })
    .on('confirmation',(confirmationNumber,receipt)=>{
      //
      console.log({ confirmationNumber: confirmationNumber, receipt: receipt })
    })
    .on('receipt',(receipt)=>{
      console.log({ receipt: receipt })
    })
    .on('error',(error,receipt)=>{
      console.log({ error: error, receipt: receipt })
    })
  }


  render() {
return (</pre>
<div><b>{this.state.value}</b> <button> { this.Getter() }}&gt;Getter</button> <button> { this.Increase() }}&gt;Increase</button></div>
); } } export default App;