ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解决“function call to a non-contract account“问题

2021-12-11 18:01:49  阅读:246  来源: 互联网

标签:function non account sol codeHash address pair 合约 tokenA


    今天在运行UniswapV2合约调用getReserves()函数时,报"function call to a non-contract account"错误,如图(1)所示:

图(1) getReserve()函数调用的合约找不到

    出现这种情况的原因是:函数调用的合约找不到,可能的原因有:

  • 合约没有部署;
  • 合约地址错误;
  • api-key缺少访问权限;
  • codeHash没有配置;
  • 调用的合约在主网,而被调用的合约在测试网,即两合约没有在同一个网络。

    本例中,是由于UniswapV2Router02.sol里的pairFor()函数其codeHash没有更新,导致合约找不到。
UniswapV2Router02.sol 根据 factory、token0、token1、codeHash来生成pair地址,而codeHash使用的mainnet网络,应该使用本地网络的codeHash。
可通过web3.utils.keccak256(UniswapV2Pair.bytecode)计算codeHash,例子如下:

const Web3 = require('web3')
//配对合约的json文件
const UniswapV2Pair = require('../../artifacts/contracts/UniswapV2Factory.sol/UniswapV2Pair.json')
//设置网段 localhost、Rinkeby、mainnet
const web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"))

let initCodeHash = null
let data = UniswapV2Pair.bytecode
if (!data.startsWith('0x')) data = '0x' + data
console.info('INIT_CODE_HASH:', initCodeHash = web3.utils.keccak256(data))

    得到codehash如下:

INIT_CODE_HASH: 0x36da00333ba9396db7d539011cd1c469351d4c58d439e5e918c9a07228bf291c

    注意:这个codeHash是通过配对合约的bytecode进行keccak256()生成的。在添加流动性时,工厂合约会检测这个pair合约是否存在,若不存在,则调用createPair()创建pair合约。

    在FlashLoanOne.sol,或者UniswapV2Router02.sol的pairFor()函数里,修改codehash,然后重新编译、部署智能合约。
    //FlashLoanOne.sol

  // calculates the CREATE2 address for a pair without making any external calls
    // codehash要根据factory合约,进行修改
    function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
        (address token0, address token1) = sortTokens(tokenA, tokenB);
        pair = address(uint(keccak256(abi.encodePacked(
                hex'ff',
                factory,
                keccak256(abi.encodePacked(token0, token1)),
                hex'36da00333ba9396db7d539011cd1c469351d4c58d439e5e918c9a07228bf291c' //修改此处
            ))));
    }

    // fetches and sorts the reserves for a pair
    function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
        (address token0,) = sortTokens(tokenA, tokenB);
        (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }
## 编译智能合约
npx hardhat compile

## 部署智能合约
npx hardhat run script/deploy_flashloan.js

标签:function,non,account,sol,codeHash,address,pair,合约,tokenA
来源: https://blog.csdn.net/sanqima/article/details/121875309

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有