Solidity
錯誤:交易恢復:對非合約賬戶的函式呼叫
在過去的兩天裡,我一直在嘗試調試它,這讓我發瘋了。測試契約時出現此錯誤:
Error: Transaction reverted: function call to a non-contract account
. 這是最簡單的合約和最簡單的函式呼叫。它當然適用於混音。這是錯誤
npx hardhat.test
:Factory 1) Should not throw error 0 passing (2s) 1 failing 1) Factory Should not throw error: Error: Transaction reverted: function call to a non-contract account at Factory.newToken (contracts/Factory.sol:13) at processTicksAndRejections (internal/process/task_queues.js:97:5) at HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1070:23) at HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:369:16) at EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1373:18) at HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:99:18) at EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
請有人幫忙。
這是我的設置:Factory.sol:
// @unsupported: ovm // SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "hardhat/console.sol"; contract Factory { function newToken() public { uint x = IERC20(0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa).balanceOf(address(this)); console.log(x); } }
Deploy_Factory.js
const fs = require('fs'); module.exports = async ({ getNamedAccounts, deployments, }) => { const { deploy, log, get } = deployments const { deployer } = await getNamedAccounts() const chainId = await getChainId() const factory = await deploy('Factory', { from: deployer, args: [], log: true }) } module.exports.tags = ['all', 'factory']
Factory_test.js
const { expect } = require('chai') describe('Factory', async function () { let factory beforeEach(async () => { await deployments.fixture(['mocks', 'factory']) const Factory = await deployments.get('Factory') factory = await ethers.getContractAt('Factory', Factory.address) }) it("Should not throw error", async function () { await factory.newToken(); }) })
安全帽配置文件
/** * @type import('hardhat/config').HardhatUserConfig */ require("@nomiclabs/hardhat-waffle") require("@nomiclabs/hardhat-ethers") require("@nomiclabs/hardhat-web3") require("@nomiclabs/hardhat-truffle5") require("@nomiclabs/hardhat-etherscan") require("hardhat-deploy") require('@openzeppelin/hardhat-upgrades'); require("./tasks/accounts") require("./tasks/balance") require("./tasks/fund-link") require("./tasks/block-number") require("./tasks/block-number") require("./tasks/random-number-consumer") require("./tasks/price-consumer") require("./tasks/api-consumer") require('dotenv').config() const MAINNET_RPC_URL = process.env.MAINNET_RPC_URL || process.env.ALCHEMY_MAINNET_RPC_URL || "https://eth-mainnet.alchemyapi.io/v2/your-api-key" const RINKEBY_RPC_URL = process.env.RINKEBY_RPC_URL || "https://eth-rinkeby.alchemyapi.io/v2/your-api-key" const KOVAN_RPC_URL = process.env.KOVAN_RPC_URL const MNEMONIC = process.env.MNEMONIC const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || "Your etherscan API key" // optional const PRIVATE_KEY = process.env.PRIVATE_KEY || "your private key" module.exports = { defaultNetwork: "hardhat", networks: { hardhat: { // // If you want to do some forking, uncomment this // forking: { // url: MAINNET_RPC_URL // } }, localhost: { }, kovan: { url: KOVAN_RPC_URL, // accounts: [PRIVATE_KEY], accounts: { mnemonic: MNEMONIC, }, saveDeployments: true, }, rinkeby: { url: RINKEBY_RPC_URL, // accounts: [PRIVATE_KEY], accounts: { mnemonic: MNEMONIC, }, saveDeployments: true, }, ganache: { url: 'http://localhost:8545', accounts: { mnemonic: MNEMONIC, } } }, etherscan: { // Your API key for Etherscan // Obtain one at https://etherscan.io/ apiKey: ETHERSCAN_API_KEY }, namedAccounts: { deployer: { default: 0, // here this will by default take the first account as deployer 1: 0 // similarly on mainnet it will take the first account as deployer. Note though that depending on how hardhat network are configured, the account 0 on one network can be different than on another }, feeCollector: { default: 1 } }, paths: { deploy: 'deploy', deployments: 'client/packages/contracts/src/deployments', artifacts: 'client/packages/contracts/src/deployments/artifacts', imports: 'imports' }, solidity: { compilers: [ { version: "0.6.6" }, { version: "0.6.12", settings: { optimizer: { enabled: true, runs: 200 } } }, { version: "0.4.24" } ], }, mocha: { timeout: 100000 } }
包.json
{ "name": "chainlink-hardhat-box", "version": "1.0.0", "description": "", "scripts": { "test": "hardhat test", "lint": "eslint .", "lint:fix": "eslint . --fix" }, "license": "MIT", "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.1", "@nomiclabs/hardhat-etherscan": "^2.1.1", "@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-web3": "^2.0.0", "chai": "^4.2.0", "ethereum-waffle": "^3.2.1", "ethers": "^5.0.24", "hardhat": "^2.0.6", "hardhat-deploy": "^0.7.0-beta.39" }, "dependencies": { "@chainlink/contracts": "0.1.6", "@chainlink/test-helpers": "0.0.5", "@chainlink/token": "^1.1.0", "@nomiclabs/hardhat-truffle5": "^2.0.0", "@openzeppelin/contracts": "3.4.0", "@openzeppelin/contracts-upgradeable": "3.4.0", "@openzeppelin/hardhat-upgrades": "^1.6.0", "@uniswap/v2-periphery": "1.1.0-beta.0", "dotenv": "6.2.0", "eslint": "^6.0.0" }, "mocha": { "timeout": 10000000 } }
這意味著,介面試圖呼叫一個不存在的合約。
契約中的以下行觸發了錯誤。
uint x = IERC20(0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa).balanceOf(address(this));
查看您的安全帽配置,您使用了一個新的本地開發網路,其中
0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa
可能是一個空帳戶,因為我看不到在該地址部署 ERC20 的任何其他邏輯。我猜你打算做一個主網分叉(文件)。但是這個地址
0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa
不是乙太坊主網上的ERC20合約,你確定這個地址是正確的嗎?如果你輸入了一個有效的 ERC20 合約地址,你就不會收到這個錯誤。