etherjs快速入门,快速上手Dapp开发

etherjs封装了多个类型,分别处理不同的逻辑,主要有provider, signer, contract, contractFactory,interface

Provider

与node api交互的对象,不接触私钥,只能读链上信息

const INFURA_ID = ''
// 连接以太坊主网
const providerETH = new ethers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)
const blockNumber = await providerETH.getBlockNumber();
const txCount = await providerETH.getTransactionCount("vitalik.eth");

Signers

可以用来签名消息和交易,如将签名的交易发送到以太坊网络以执行状态更改的操作。

你会遇到的最常见的Signers有:

Wallet这是一个类,继承Signers,它有自己的私钥,可以用它执行任何操作
// 利用私钥和provider创建wallet对象
const privateKey = '0x227dbb8586117d55284e26620bc76534dfbd2394be34cf4a09cb775d593b6f2b'
const wallet = new ethers.Wallet(privateKey, provider)
const receipt = await wallet2.sendTransaction(tx) // 发送交易
const address1 = await wallet1.getAddress() // 获取地址
JsonRpcSigner它连接到[JsonRpcProvider(或子类),并使用getSigner获取
// wallet链接不同的provider
const wallet1WithProvider = wallet1.connect(provider)

Contract

可读abi,etherjs可以识别

const abiERC20 = [
    "function name() view returns (string)",
    "function symbol() view returns (string)",
    "function totalSupply() view returns (uint256)",
    "function balanceOf(address) view returns (uint)",

    "function deposit() public payable",
    "function transfer(address, uint) public returns (bool)",
    "function withdraw(uint) public"
];
只读合约
const contractDAI = new ethers.Contract(addressDAI, abiERC20, provider)
 // 1. 读取WETH合约的链上信息(WETH abi)
const nameWETH = await contractWETH.name()
const symbolWETH = await contractWETH.symbol()
const totalSupplyWETH = await contractWETH.totalSupply()
可读写合约

const tx = await contract.METHOD_NAME(args [, overrides]), args是方法的参数,overrides是选择数据

  • gasPrice:gas价格
  • gasLimit:gas上限
  • value:调用时传入的ether(单位是wei)
  • nonce:nonce
const contract = new ethers.Contract(addressDAI, abiERC20, signer)
const tx = await contractWETH.deposit({value: ethers.parseEther("0.001")}) //调用deposit
const tx2 = await contractWETH.transfer("vitalik.eth", ethers.parseEther("0.001")) // 调用transfer
模拟执行StaticCall
const tx = await contractWETH.deposit.StaticCall({value: ethers.parseEther("0.001")}) //调用deposit
检索合约event
// WETH ABI,只包含我们关心的Transfer事件
const abiWETH = [
    "event Transfer(address indexed from, address indexed to, uint amount)"
];
const contract = new ethers.Contract(addressWETH, abiWETH, provider)
const transferEvents = await contract.queryFilter('事件名', 起始区块, 结束区块) // 检索事件
contract.on("eventName", function) // 监听事件

contractFactory

方便开发者部署合约

const contractFactory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await contractFactory.deploy(args) // args是构造函数有参数,返回合约对象
console.log(contract) //合约地址
await contract.deployed()

接口类 Interface

生成interface
// WETH的ABI
const abiWETH = [
    "function balanceOf(address) public view returns(uint)",
    "function deposit() public payable",
];
const interface = ethers.Interface(abi) // 直接生成interface

// 直接从contract中获取
const contractWETH = new ethers.Contract(addressWETH, abiWETH, wallet)
const interface = contractWETH.interface
编码calldata,自己组装交易data
// 组装balanceOf调用的data
let param = interface.encodeFunctionData(
    "balanceOf",
    [address]
  );
// 创建交易
const tx1 = {
    to: addressWETH,
    data: param1
}
wallet.sendTransaction(tx1) // 调用合约的balanceOf方法
解码返回值
interface.decodeFunctionResult("balanceOf", resultData)

其他接口

interface.getSighash("balanceOf");// 获取balanceOf的函数选择器

etherJs封装好的常用工具utils

下面介绍eth交易签名过程,以及交易hash计算

const transaction = {
      type: 2,
      chainId: network.chainId,
      to: ZERO_ADDRESS,
      maxPriorityFeePerGas: targetGasFee,
      maxFeePerGas: targetGasFee,
      gasLimit: ethers.BigNumber.from("25000"),
      nonce: nonce,
      value: ethers.utils.parseEther("0"),
      data: stringToHex(callData),
    };
const rawTransaction = ethers.utils.serializeTransaction(transaction); // 序列化未签名交易
const transactionHash = ethers.utils.keccak256(rawTransaction); // 计算未签名交易hash
const signingKey = miner._signingKey();
const signature = signingKey.signDigest(transactionHash);// 对未签名交易hash进行签名
const recreatedSignature = ethers.utils.joinSignature(signature);
const predictedTransactionHash = ethers.utils.keccak256( // 计算前面后的交易hash(就是打包上链的交易hash)
      ethers.utils.serializeTransaction(transaction, recreatedSignature)
    );
本作品采用《CC 协议》,转载必须注明作者和本文链接
用过哪些工具?为啥用这个工具(速度快,支持高并发...)?底层如何实现的?
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!