Solidity

松露測試 - 錯誤:契約尚未部署到檢測到的網路(網路/工件不匹配)

  • November 15, 2021

當我過度閱讀所有給出的文章並且沒有解決我的問題時,我正在打開這個文章。請不要認為每個測試都是有用的,因為我正在開發有用的測試。如前所述,它與*(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 testtruffle 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: &lt;indexed&gt; 0x9820BA3aCf2f2AadB6b4C704eb485C35a9328A3E (type: address),
     _exporter: &lt;indexed&gt; 0x9B7E32E202De7C64ad0d13d157A2D8425A1C7336 (type: address),
     _carrier: &lt;indexed&gt; 0xf5AD10f4dF3180d59046112708bFf9A23B34dc43 (type: address),
     _value: 10 (type: uint256)
   )


   ---------------------------
   2) ESCROW: Constructor test
   &gt; 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.&lt;anonymous&gt; (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.&lt;anonymous&gt; (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 compiletruffle 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 () =&gt; {
   deployer
     .deploy(Escrow, accounts[1], accounts[2], 10, {
       from: accounts[0],
     })
     .then((inst) =&gt; console.log(inst));
   deployer.deploy(Lc);
 });
};

您正在使用 Promise,但您永遠不會返回它,因此它永遠不會實現並且部署資訊永遠不會更新。

如果您希望保留承諾版本(不推薦),請切換到此版本(稍作修改的版本未部署我沒有的 LC 契約):

var Escrow = artifacts.require("Escrow");

   module.exports = function (deployer, network, accounts) {
     deployer.then(async () =&gt; {
       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 () =&gt; {
   await deployer.deploy(Escrow, accounts[1], accounts[2], 10, {from: accounts[0]})
 });
};

您的第一個測試仍然失敗,但您沒有提供完整的實現,所以我只驗證了部署是否成功。

我用這段程式碼測試過:

 it("ESCROW: Initial escrow contract test", async () =&gt; {
   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 () =&gt; {

   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”,您可以讀取公共變數的狀態。

在這些更改之後,我這邊一切正常。

引用自:https://ethereum.stackexchange.com/questions/113628