前言本文通过Ethersjs库实现和智能合约的交互全流程流程;工具前端项目引入ethersjs库给浏览器安装一个钱包插件例如:MetaMaskopenzeppelin库编写合约合约部分合约//SPDX-License-Identifier:MITpragmasolid
本文通过Ethersjs库实现和智能合约的交互全流程流程;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken1 is ERC20 {
constructor() ERC20("Mock Token", "MTK") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
# 编译
# npx hardhat compile
module.exports = async ({getNamedAccounts,deployments})=>{
const getNamedAccount = (await getNamedAccounts()).firstAccount;
// const getNamedAccount = (await getNamedAccounts()).secondAccount;
console.log('getNamedAccount',getNamedAccount)
const TokenName = "ETHToken";
const TokenSymbol = "ETH";
const {deploy,log} = deployments;
const TokenC=await deploy("MyToken1",{
from:getNamedAccount,
args: [],//参数
log: true,
})
// await hre.run("verify:verify", {
// address: TokenC.address,
// constructorArguments: [TokenName, TokenSymbol],
// });
console.log('合约地址1',TokenC.address)
}
module.exports.tags = ["all", "token1"];
# 部署
# npx hardhat deploy
const {ethers,getNamedAccounts,deployments} = require("hardhat");
const { assert,expect } = require("chai");
describe("token", function() {
let Token1;
let owner,addr1,addr2;
beforeEach(async function(){
await deployments.fixture(["token1"]);
[owner,addr1,addr2]=await ethers.getSigners();
// firstAccount = (await getNamedAccounts()).firstAccount;
const Token1Deployment = await deployments.get("MyToken1");
Token1 = await ethers.getContractAt("MyToken1",Token1Deployment.address);//已经部署的合约交互
});
describe("测试",function(){
it("测试",async function(){
console.log('名字:',await Token1.name())
console.log('符号:',await Token1.symbol())
console.log('decimals:',await Token1.decimals())
console.log('totalSupply:',await Token1.totalSupply())
console.log("owner的额度:",await Token1.balanceOf(owner.address))
transfer = await Token1.transfer(addr1.address,100)
console.log('转账余额:',await Token1.balanceOf(addr1.address))
console.log('授权:',await Token1.approve(addr1.address,500))
console.log('授权额度:',await Token1.connect(addr1).transferFrom(owner.address,addr2.address,200))
console.log('addr2的额度:',await Token1.balanceOf(addr2.address))
console.log('addr1的额度:',await Token1.balanceOf(addr1.address))
})
})
})
# 测试
# npx hardhat test ./test/xxx.js
# 代码
import { ethers ,JsonRpcProvider,BrowserProvider} from "ethers";
import React,{useEffect, useState} from "react";
import tokenABI from '../json/MyToken1.json';//代币合约json文件获取abi
const initFn = async () => {
const provider = new BrowserProvider(window.ethereum);//浏览器端
// 读取钱包地址
const accounts = await provider.send("eth_requestAccounts", []);
const account = accounts[0]//获取余额
const balance = await provider.getBalance(account)// 读取chainid
const { chainId } = await provider.getNetwork()
// console.log(await provider.getNetwork())
// console.log(await provider.getBlockNumber())
// console.log(await provider.getTransactionCount('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'))
// console.log(await provider.getFeeData())
// console.log(await provider.getBlock(0))
// console.log(await provider.getCode("0xc778417e063141139fce010982780140aa0cd5ab"))
const signer =await provider.getSigner();//获取signer
// console.log('signer',signer)
let info={
chainid:chainId.toString(),
balance:ethers.formatUnits(balance),
account:account,
signer:signer
}
return info
}
let {chainid,balance,account,signer}=await initFn()
let account0='0x5D5Cfb244eD2fEA3138cbA5E6DdC11c8b6D92dD7'//钱包地址0
let acccout1='0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'//钱包地址1
let acccout2=`0x70997970C51812dc3A010C7d01b50e0d17dc79C8`//钱包地址2
let BalanceValue
let ContractAddress='0x8A791620dd6260079BF849Dc5567aDC3F2FdC318';//mtk合约地址
let ContractData=new ethers.Contract(ContractAddress,tokenABI.abi,signer);//合约实例
function Header() {
let [chainidv,setChainid]=useState('');//链id
let [balancev,setBalance]=useState('');//钱包余额
let [accountv,setAccount]=useState('');//钱包地址
let [signerv,setSigner]=useState('');//签名
let [txv,setTxv]=useState('');//实例
//代币
let [name,setName]=useState('');//MTK代币名称
let [symbol,setSymbol]=useState('');//MTK代币符号
let [totalSupply,setTotalSupply]=useState('');//MTK代币总供应量
let [balanceOf,setBalanceOf]=useState('');//MTK代币余额
let [address1,setAddress1]=useState('');//MTK代币地址1
let [address2,setAddress2]=useState('');//MTK代币地址2
//转账方法
const transfer=async ()=>{
const provider = new ethers.BrowserProvider(window.ethereum);//浏览器端
// const provider = new ethers.JsonRpcProvider();//浏览器端
const value = ethers.parseEther('100');
const signer =await provider.getSigner()
const tx = await signer.sendTransaction({
to: account0,
value: value//转换100eth
})
console.log(tx)
if(tx){
await tx.wait();
console.log('转账成功')
let Balance=await provider.getBalance(account0)
BalanceValue=ethers.formatUnits(Balance)
localStorage.setItem('BalanceValue',BalanceValue)
setTxv(BalanceValue)
}else{
console.log('失败')
}
}
//读取MTK合约信息
const getContractInfo=async ()=>{
setName(await ContractData.name())
setSymbol(await ContractData.symbol())
let totalSupply=ethers.formatUnits(await ContractData.totalSupply())
setTotalSupply(totalSupply)
}
//转账MYK代币合约
const mtktransfer=async ()=>{
console.log('转账',await ContractData.transfer(acccout2,ethers.parseEther('100')))
let addr1=ethers.formatUnits(await ContractData.balanceOf(acccout1))
console.log('address',addr1)
let addr2=ethers.formatUnits(await ContractData.balanceOf(acccout2))
setAddress1(addr1)
setAddress2(addr2)
console.log('address',addr2)
}
useEffect(()=>{
setChainid(chainid)
setBalance(balance)
setAccount(account)
setSigner(signer)
},[accountv])
useEffect(()=>{
setTxv(BalanceValue)
// console.log(BalanceValue)
// console.log(txv)
},[txv])
return (<>
{
window.ethereum===undefined?<div style={{color:'red'}}>
请按照要求安装metamask
</div> :<div style={{padding:'10px'}}>
<h4 style={{fontSize:'20px',lineHeight:'40px',fontWeight:'bold'}}>钱包信息</h4>
<p><strong>chainid</strong>: {chainidv}</p>
<p><strong>钱包余额:</strong> {balancev} ETH</p>
<p><strong>钱包地址:</strong> {accountv}</p>
<p><strong>signeraddress:</strong> {signerv.address}</p>
<p><strong>账号:</strong>{account0}<br/><strong>转账余额:</strong>{txv || localStorage.getItem('BalanceValue')}</p>
<button onClick={transfer} style={{background:'#065ae6cf',color:'#fff',padding:'10px 20px',borderRadius:'5px',margin:'10px 0'}}>转账按钮</button>
<div>
<h1 style={{fontWeight:'bold',fontSize:'20px',margin:"10px 0"}}>合约信息面板</h1>
<p><strong>代币名:</strong>{name}</p>
<p><strong>代币符号:</strong>{ symbol}</p>
<p><strong>代币总供应量:</strong>{ totalSupply} MTK</p>
<button onClick={getContractInfo} style={{background:'#065ae6cf',color:'#fff',padding:'10px 20px',borderRadius:'5px',margin:'10px 0'}}>读取信息</button>
<p><strong>address1余额:</strong>{ address1} MTK</p>
<p><strong>address2余额:</strong>{ address2} MTK</p>
<button onClick={mtktransfer} style={{background:'#065ae6cf',color:'#fff',padding:'10px 20px',borderRadius:'5px',margin:'10px 0'}}>转账</button>
</div>
</div>
}
</>)
}
export default Header;
钱包插件添加自定义网络<br/>
<!---->
# 会获取到20个账户,每个账户中有10000 ETH
npx hardhat node//获取节点账号
如图所示
2. 添加自定网络 <br>
步骤如下
把本地节点的私有粘贴到输入框中导入成功后可以获取一个含有10000ETH的账号
<!---->
npx hardhat deploy
说明:主要通过ethers中的Contract实现合约的交互
import { ethers ,JsonRpcProvider,BrowserProvider} from "ethers";
import tokenABI from '../json/MyToken1.json';//代币合约json文件获取abi
const provider = new BrowserProvider(window.ethereum);//浏览器端
const signer =await provider.getSigner();//获取signer 合约可读写
let ContractAddress='0x8A791620dd6260079BF849Dc5567aDC3F2FdC318';//mtk合约地址
let ContractData=new ethers.Contract(ContractAddress,tokenABI.abi,signer);//合约实例
//通过合约实例实现合约交互
//例如
let name await ContractData.name()//获取代币的name
以上就是简单的通过ethers和智能合约的交互全部流程,本地测试需要启动本地节点 npx hardhat node,编译部署合约,获取合约地址和abijson文件,把abi文件导入前端项目用来实现合约的交互;
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!