3.读取合约信息

148 阅读3分钟

3.读取合约信息

目标:

  • 了解什么是 Contract 、EVM字节码
  • 如何创建Contract实例,两种创建 contract 实例的方法
  • 读取链上合约信息
  • 认识以太坊浏览器

contract 类

ethers中,Contract类是部署在以太坊网络上的合约(EVM字节码)的抽象,通过它,开发者可以非常容易的对合约进行读取call和交易transcation并可以获得交易的结果和事件。以太坊强大的地方正是合约,所以对于合约的操作要熟练掌握。

创建Contract变量(实例)

Contract对象分为两类,只读和可读写。只读Contract只能读取链上合约信息,执行call操作,即调用合约中viewpure的函数,而不能执行交易transaction

  • 只读合约

只读Contract:参数分别是合约地址,合约abiprovider变量(只读)

const contract = new ethers.Contract(`address`, `abi`, `provider`);
  • 可读写合约

可读写Contract:参数分别是合约地址,合约abisigner变量。Signer签名者是ethers中的另一个类,用于签名交易,之后我们会讲到。

const contract = new ethers.Contract(`address`, `abi`, `signer`);

代码

  1. 创建 provider 实例
const provider = new ethers.providers.JsonRpcProvider(mainNetWork);
  1. 创建 contract 实例
  • 直接输入合约abi。你可以从remix的编译页面中复制,在本地编译合约时生成的artifact文件夹的json文件中得到,或者从etherscan开源合约的代码页面得到
// 1.1 创建合约实例
// 方法1. 直接输入合约abi
const addressWETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' // WETH Contract
const abi = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]'
const contractWETH = new ethers.Contract(addressWETH,abi, provider)
  • 由于abi可读性太差,ethers创新的引入了Human-Readable Abi(人类可读abi)。开发者可以通过function signatureevent signature来写abi
// 方法2.
const abiERC20 = [
	"function transfer(address, uint) returns (bool)",
  "function name() view returns (string)",
  "function symbol() view returns (string)",
  "function totalSupply() view returns (uint256)",
  "function balanceOf(address) view returns (uint)",
];
const addressDAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F' // DAI Contract
const contractDAI = new ethers.Contract(addressDAI, abiERC20, provider)
  1. 读取合约相关信息
// 2. 读取合约信息
const contractWETHName = await contractWETH.name()
const symbolWETH = await contractWETH.symbol()
const totalSupply = await contractWETH.totalSupply()
console.log('WETH的合约名字', contractWETHName)
console.log('WETH的合约代号', symbolWETH)
console.log('WETH的目前总供给量', )
// 调用合约中的函数
const balanceWETH = await contractWETH.balanceOf('vitalik.eth')
console.log('vitalik.eth 的持仓', ethers.utils.formatEther(balanceWETH))
console.log('-------------------------')
const contractDAIName = await contractDAI.name()
const contractDAISymbol = await contractDAI.symbol()
const contractDAITotalSupply = await contractDAI.totalSupply()
console.log('DAI合约的名字',contractDAIName)
console.log('DAI合约的代号',contractDAISymbol)
console.log('DAI合约的目前总供给量',ethers.utils.formatEther(contractDAITotalSupply))

// 调用合约中的函数
const balanceDAI = await contractDAI.balanceOf('vitalik.eth')
console.log('vitalik.eth 的持仓', ethers.utils.formatEther(balanceDAI))

通过以太坊浏览器查看合约信息

以太坊浏览器