松露測試 - 錯誤:契約尚未部署到檢測到的網路(網路/工件不匹配)
當我過度閱讀所有給出的文章並且沒有解決我的問題時,我正在打開這個文章。請不要認為每個測試都是有用的,因為我正在開發有用的測試。如前所述,它與*(network/artifact mismatch) 錯誤*有關。
在下面你會找到我的原始碼
./test/TestEscrow.js
文件/* @dev: web3 instance is available in each test */ // Contracts that need to be interacted within the test const TestEscrow = artifacts.require("../contracts/Escrow.sol"); contract("Testing Escrow SC", (accounts) => { const importer = accounts[0]; const exporter = accounts[1]; const carrier = accounts[2]; it("ESCROW: Initial escrow contract test", async () => { const escrow = await TestEscrow.deployed(); console.log(escrow); //checking if contract was properly deployed const escrowBalance = await escrow.getBalance.call(accounts[0]); console.log(escrowBalance); const escrowBalanceToNumber = await escrowBalance; console.log(escrowBalanceToNumber); assert.equal(escrowBalance, 100, "100 was not in the first account"); }); it("ESCROW: Constructor test", async () => { const escrow = await TestEscrow.deployed(); console.log(escrow); //checking if contract was properly deployed await escrow.new(carrier, exporter, 10, { from: accounts[0] }); assert.equal( escrow.owner, importer, "The importer is not the contract owner, which is accounts[0]." ); assert.equal(escrow.exporter, exporter, "The exporter is not accounts[1]."); assert.equal(escrow.carrier, carrier, "The carrier is not accounts[2]."); assert.equal( escrow.value, 10, "THe value of the ESCROW account is not 10." ); }); });
./contracts/Escrow.sol
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.10; contract Escrow{ address payable owner; address payable importer; address payable exporter; address carrier; uint value; State state; event EscrowCreated(address indexed _importer, address indexed _exporter, address indexed _carrier, uint _value); constructor (address payable _carrier, address payable _exporter, uint256 _value) { require(_carrier != address(0), "Carrier missing"); require(_exporter != address(0), "Exporter missing"); owner = payable(msg.sender); //we assume the impoert is the person calling importer = payable(msg.sender); carrier = _carrier; exporter = _exporter; value = _value; state = State.waitingForDeposit; emit EscrowCreated(msg.sender, _exporter, _carrier, _value); } }
./migrations/1_initial_migrations.js
var Migrations = artifacts.require("./Migrations.sol"); module.exports = function (deployer) { deployer.deploy(Migrations); };
./migrations/2_deploy_contracts.js
var Escrow = artifacts.require("../contracts/Escrow.sol"); var Lc = artifacts.require("../contracts/Lc.sol"); module.exports = function (deployer, network, accounts) { deployer.then(async () => { deployer .deploy(Escrow, accounts[1], accounts[2], 10, { from: accounts[0], }) .then((inst) => console.log(inst)); deployer.deploy(Lc); }); };
truffle-config.js
const path = require("path"); module.exports = { // See <http://truffleframework.com/docs/advanced/configuration> // to customize your Truffle configuration! // contracts_build_directory: path.join(__dirname, "client/src/contracts"), networks: { develop: { host: "127.0.0.1", port: 8545, network_id: "*", }, test: { host: "127.0.0.1", port: 8545, network_id: "*", }, }, compilers: { solc: { version: "^0.8.0", settings: { /* Optimizer is able to allocate assigned variables in a more efficient way. For example it adds up multiple uint64 to a whole uint256 block. */ optimizer: { enabled: true, runs: 200, }, }, }, }, };
所以現在的問題是,如果我正在跑步
truffle test
或truffle test --network develop
. 儘管編譯了合約並部署了初始合約,但因為它返回了EscrowCreated
事件(請參閱 參考資料Escrow.sol
),它仍然表示兩個測試都失敗了,並且在這兩種情況下都會發出 <(network/artifact mismatch)> 錯誤。請參閱下面的錯誤消息:Compiling your contracts... =========================== ✔ Fetching solc version list from solc-bin. Attempt #1 > Compiling .\contracts\Escrow.sol > Compiling .\contracts\Helpers.sol > Compiling .\contracts\Lc.sol > Compiling .\contracts\Migrations.sol ✔ Fetching solc version list from solc-bin. Attempt #1 > Artifacts written to C:\Users\andre\AppData\Local\Temp\test--34512-KTgIYcQedlwC > Compiled successfully using: - solc: 0.8.10+commit.fc410830.Emscripten.clang Contract: Testing Escrow SC 1) ESCROW: Initial escrow contract test ######################################################### ######## Wildcard for Smart Contract Information ######## ######################################################### Events emitted during test: --------------------------- Escrow.EscrowCreated( _importer: <indexed> 0x9820BA3aCf2f2AadB6b4C704eb485C35a9328A3E (type: address), _exporter: <indexed> 0x9B7E32E202De7C64ad0d13d157A2D8425A1C7336 (type: address), _carrier: <indexed> 0xf5AD10f4dF3180d59046112708bFf9A23B34dc43 (type: address), _value: 10 (type: uint256) ) --------------------------- 2) ESCROW: Constructor test > No events were emitted 0 passing (821ms) 2 failing 1) Contract: Testing Escrow SC ESCROW: Initial escrow contract test: Error: Escrow has not been deployed to detected network (network/artifact mismatch) at Object.checkNetworkArtifactMatch (C:\Users\andre\AppData\Roaming\nvm\v16.6.1\node_modules\truffle\build\webpack:\packages\contract\lib\utils\index.js:247:1) at Function.deployed (C:\Users\andre\AppData\Roaming\nvm\v16.6.1\node_modules\truffle\build\webpack:\packages\contract\lib\contract\constructorMethods.js:83:1) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Context.<anonymous> (test\TestEscrow.js:9:20) 2) Contract: Testing Escrow SC ESCROW: Constructor test: Error: Escrow has not been deployed to detected network (network/artifact mismatch) at Object.checkNetworkArtifactMatch (C:\Users\andre\AppData\Roaming\nvm\v16.6.1\node_modules\truffle\build\webpack:\packages\contract\lib\utils\index.js:247:1) at Function.deployed (C:\Users\andre\AppData\Roaming\nvm\v16.6.1\node_modules\truffle\build\webpack:\packages\contract\lib\contract\constructorMethods.js:83:1) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Context.<anonymous> (test\TestEscrow.js:20:20)
最後我正在使用
Truffle v5.4.5 (core: 5.4.5) Solidity - ^0.8.0 (solc-js) Node v16.6.1 Web3.js v1.5.1
希望有人可以向我解釋我的測試與工件不匹配到底發生了什麼。答案越詳細,我會學到的越多。期待你的回复!
親切的問候,安德烈亞斯
#2 已編輯(問題):分享一個想法:我認為我可能對遷移文件之間的關係有誤(因為我在那裡呼叫了 Escrow 構造的建構子及其參數)並且我認為實際的初始化在定義我的實際測試案例時,契約更有可能發生在測試文件中。期待您能澄清這個額外的問題/想法。
#3 已編輯(附加資訊):即使我刪除了
.build/contracts/
目錄中的所有文件,重新執行truffle compile
,truffle migrate --reset --network develop
錯誤仍然存在。#4 已編輯(問題):此外,我觀察到契約 ABI 在其參數中
./build/contracts/
不包含值。"networks": {}
這正常嗎?
你的問題在這裡:
var Escrow = artifacts.require("../contracts/Escrow.sol"); var Lc = artifacts.require("../contracts/Lc.sol"); module.exports = function (deployer, network, accounts) { deployer.then(async () => { deployer .deploy(Escrow, accounts[1], accounts[2], 10, { from: accounts[0], }) .then((inst) => console.log(inst)); deployer.deploy(Lc); }); };
您正在使用 Promise,但您永遠不會返回它,因此它永遠不會實現並且部署資訊永遠不會更新。
如果您希望保留承諾版本(不推薦),請切換到此版本(稍作修改的版本未部署我沒有的 LC 契約):
var Escrow = artifacts.require("Escrow"); module.exports = function (deployer, network, accounts) { deployer.then(async () => { return deployer.deploy(Escrow, accounts[1], accounts[2], 10, {from: accounts[0]}) }); };
或者您可以簡單地切換到您已經在其他地方使用的 async/await(推薦):
var Escrow = artifacts.require("Escrow"); module.exports = function (deployer, network, accounts) { deployer.then(async () => { await deployer.deploy(Escrow, accounts[1], accounts[2], 10, {from: accounts[0]}) }); };
您的第一個測試仍然失敗,但您沒有提供完整的實現,所以我只驗證了部署是否成功。
我用這段程式碼測試過:
it("ESCROW: Initial escrow contract test", async () => { const escrow = await TestEscrow.deployed(); //const escrowBalance = await escrow.getBalance.call(accounts[0]); //const escrowBalanceToNumber = await escrowBalance; //assert.equal(escrowBalance, 100, "100 was not in the first account"); });
鑑於您目前的契約程式碼,您的第二個測試將不起作用:
address payable owner; address payable importer; address payable exporter; address carrier; uint value; State state;
預設可見性
internal
因此無法從外部訪問。在需要時簡單地指定 public 將允許外部訪問您的公共變數(假設它們都需要是公共的):address payable public owner; address payable public importer; address payable public exporter; address public carrier; uint public value; State public state;
然後將第二個測試的程式碼更改為:
it("ESCROW: Constructor test", async () => { const escrow = await TestEscrow.new(carrier, exporter, 10, { from: accounts[0] }); assert.equal( await escrow.owner(), importer, "The importer is not the contract owner, which is accounts[0]." ); assert.equal(await escrow.exporter(), exporter, "The exporter is not accounts[1]."); assert.equal(await escrow.carrier(), carrier, "The carrier is not accounts[2]."); assert.equal( await escrow.value(), 10, "THe value of the ESCROW account is not 10." ); });
利用自動生成的“getter”,您可以讀取公共變數的狀態。
在這些更改之後,我這邊一切正常。