Solidity

無法修復:AssertionError和RR一種小號小號和RT一世開_和RR一種小號小號和R噸一世這ñERR_ASSERTION: 指定的回調對象無效

  • February 1, 2022

我正在做我的第一個智能合約,這些錯誤可能不是 npm 而是版本問題。儘管進行了深入研究,但我找不到合適的方法來解決它。感謝您的幫助!

const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const { interface, bytecode} = require('../compile');

let accounts;
let inbox;

beforeEach(async() => {
   //get a list of all accounts
  accounts = await web3.eth.getAccounts();    
         
   //Use one of those accounts to deploy
   //the contract
   inbox = await new web3.eth.Contract(JSON.parse(interface))
       .deploy({ data: bytecode, arguments: ['Salve!'] })
       .send({ from: accounts[0], gas: '1000000'})

});

describe('Inbox', () => {
   it('deploys a contract', () => {
       console.log(inbox);

   });
});

這是 compile.js

const path = require("path");
const fs = require("fs");
const solc = require("solc");

const inboxPath = path.resolve(__dirname, "contracts", "Inbox.sol");
const source = fs.readFileSync(inboxPath, "utf8");

module.exports = solc.compile(source, 1).contracts[':Inbox']

;

和 package.json

{
 "name": "inbox",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
   "test": "mocha"
 },
 "author": "",
 "license": "ISC",
 "dependencies": {
   "ganache-cli": "^6.12.2",
   "mocha": "^9.1.3",
   "solc": "^0.8.9",
   "web3": "^1.6.0"
 }
}

收件箱.sol

pragma solidity ^0.4.7;

contract Inbox {
   string public message;
   
   function Inbox(string inititialMessage) public {
       message = inititialMessage;
   }
   
   function setMessage (string newMessage) public {
       message = newMessage;
       
   }
   
}

在測試中是一個呼叫函式。不需要交易。在您的範例中,您進行了交易。

您的答案有效,但對呼叫函式的測試返回 Assertion_Err。

做這個:

  1. 嘗試在您的 .sol 契約中使用一些文本設置變數*消息。*像這樣:
string public message = "my first hello!";
  1. 在您的 Inbox.test.js - 嘗試像這樣更改 it() 測試:
 it('has a default message', async () => {
       const message = await inbox.methods
                               .message()
                               .call();
       assert.equal(message,'my first hello!');

現在看,消息 == ‘我的第一個你好!’ 並通過測試,沒有任何應付函式,只有一個 call()。

我不明白為什麼部署(下面的程式碼)在區塊鏈上分配合約時沒有修改合約。

inbox = await new web3.eth.Contract(JSON.parse(interface))
       .deploy( { data: bytecode, arguments: ['Hello'], })
       .send( { from: accounts[0], gas: '1000000' });
   });

首先你會遇到一個問題,因為你的 solc 版本是 ^0.8.9 而你的智能合約 pragma 是 ^0.4.7。

因此,您應該將您的契約編譯指示更改為 ^0.8.9 以與您的 solc 版本兼容。


您的智能合約需要針對 v0.8.9 稍作修改:

我將您的函式名稱從 Inbox 更改為 myInbox 以避免與契約名稱衝突。我添加了字元串現在需要的記憶體/儲存關鍵字

pragma solidity ^0.8.9;

contract Inbox {
   string public message;

   function myInbox(string memory inititialMessage) public {
       message = inititialMessage;
   }

   function setMessage(string memory newMessage) public {
       message = newMessage;
   }
}

使用 solc v0.8.9 編譯您的契約與您根據目前文件所做的不同:

const path = require("path");
const fs = require("fs");
const solc = require("solc");

const inboxPath = path.resolve(__dirname, "contracts", "Inbox.sol");
const source = fs.readFileSync(inboxPath, "utf8");

let input = {
 language: "Solidity",
 sources: {
   [inboxPath]: {
     content: source,
   },
 },

 settings: {
   outputSelection: {
     "*": {
       "*": ["*"],
     },
   },
 },
};

var output = JSON.parse(solc.compile(JSON.stringify(input)));

module.exports = {
 abi: output.contracts[[inboxPath]]["Inbox"].abi,
 bytecode: output.contracts[[inboxPath]]["Inbox"].evm.bytecode.object,
};

最後你的測試文件幾乎沒有變化(除了介面變成abi,我添加了一個測試來呼叫setMessage函式):

const assert = require("assert");
const ganache = require("ganache-cli");
const Web3 = require("web3");
const web3 = new Web3(ganache.provider());
const { abi, bytecode } = require("../compile");

let accounts;
let inbox;

beforeEach(async () => {
 //get a list of all accounts
 accounts = await web3.eth.getAccounts();

 inbox = await new web3.eth.Contract(abi)
   .deploy({ data: bytecode, arguments: ["Salve!"] })
   .send({ from: accounts[0], gas: "1000000" });
});

describe("Inbox", () => {
 it("deploys a contract", () => {
   console.log(inbox);
 });

 it("sets the contract message", async () => {
   await inbox.methods
     .setMessage("test message")
     .send({ from: accounts[0], gas: "1000000" });
 });
});

並且測試正在通過。

無論如何,您通常會使用一個框架來處理所有這些問題,例如松露或其他任何東西。雖然它可能很有啟發性,但它肯定不值得你花時間一直重做。

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