Ethers.js-StaticCall

可能失败的交易

在以太坊上发交易需要付昂贵的gas,并且有失败的风险,发送失败的交易并不会把gas返还给你。
如果你的交易将失败,小狐狸会告诉你this transaction may fail,当用户看到这个红字提示,就知道要取消这笔交易了
这是因为以太坊节点有一个eth_call方法,让用户可以模拟一笔交易,并返回可能的交易结果,但不真正在区块链上执行它(交易不上链)。

StaticCall

合约类的staticCall方法,在发送交易之前检查交易是否会失败,节省大量gas。
staticCall方法是属于ethers.Contract类的编写方法分析,同类的还有populateTransaction和estimateGas方法。
这相当于调用以太坊节点的 eth_call。这通常用于模拟状态改变函数的结果。如果函数调用成功,它将返回函数本身的返回值;如果函数调用失败,它将抛出异常

    const tx = await contract.callStatic.函数名( 参数, {
    
    override})
    console.log(`交易会成功吗?:`, tx)

用StaticCall模拟DAI转账

import {
    
     ethers } from "ethers";

const ALCHEMY_API_URL = "";
const provider = new ethers.providers.JsonRpcProvider(ALCHEMY_API_URL);

const main = async () => {
    
    
    const privateKey = "";
    const wallet = new ethers.Wallet(privateKey,provider);

   // DAI的ABI
    const abiDAI = [
    "function balanceOf(address) public view returns(uint)",
    "function transfer(address, uint) public returns (bool)",
    ];
    // DAI合约地址(主网)
    const addressDAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F' // DAI Contract
    // 创建DAI合约实例
    const contractDAI = new ethers.Contract(addressDAI, abiDAI, provider)

   // DAI的ABI
    const abiUSDT = [
        "function balanceOf(address) public view returns(uint)",
        "function transfer(address, uint) public returns (bool)",
    ];
    // USDT合约地址(主网)
    const addressUSDT = '0xdAC17F958D2ee523a2206206994597C13D831ec7' // USDT Contract
    // 创建USDT合约实例
    const contractUSDT = new ethers.Contract(addressUSDT, abiUSDT, provider)
    const address = await wallet.getAddress()
    console.log("\n1. 读取测试钱包的DAI余额")
    const balanceDAI = await contractDAI.balanceOf(address)
    console.log(`DAI持仓: ${
      
      ethers.utils.formatEther(balanceDAI)}\n`)
    console.log("\n2.  用staticCall尝试调用transfer转账1 DAI,msg.sender为Vitalik地址")
    // 发起交易
    const tx = await contractDAI.callStatic.transfer("vitalik.eth", ethers.utils.parseEther("1"), {
    
    from:  await provider.resolveName("vitalik.eth")})
    console.log(`交易会成功吗?:`, tx)
    console.log("\n3.  用staticCall尝试调用transfer转账10000 DAI,msg.sender为测试钱包地址")
    const tx2 = await contractDAI.callStatic.transfer("vitalik.eth", ethers.utils.parseEther("10000"), {
    
    from: address})
    console.log(`交易会成功吗?:`, tx2)
}
main();

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Geoffrey_Zhu/article/details/142953524