以太坊使用React进行前端开发实践-2
实战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() }}>Getter</button> <button> { this.Increase() }}>Increase</button></div>
); } } export default App;