Solidity

VM錯誤:revert。如果您發送值,則呼叫的函式應該是應付的,並且您發送的值應該小於您目前的餘額

  • December 27, 2019

已經有一個類似的問題,但它對我沒有幫助。所以我再次問這個問題並期待一些有用的資訊。

AccessControl.sol兩個名為和的合約Judge.sol。我已經刪除了所有無關的程式碼,只留下了錯誤的函式並在呼叫它時得到了同樣的錯誤。

首先我部署Judge合約並獲取它的合約地址。然後我部署AccessControl合約,傳遞Judge合約地址。

最後我呼叫emitError函式AccessControl.sol並查看還原錯誤

處理 AccessControl.emitError 錯誤:VM 錯誤:還原。

revert 事務已恢復到初始狀態。

注意:如果您發送值並且您發送的值應該小於您目前的餘額,則呼叫的函式應該是應付的。調試事務以獲取更多資訊。

我不知道為什麼會這樣。這是簡化的程式碼。

訪問控制.sol

pragma solidity >=0.4.22 <0.6.0;

contract AccessControl{
   address   public owner;
   Judge     public jc;

   constructor(address _jc) public {
       owner = msg.sender;
       jc = Judge(_jc);
   }

   function emitError(address subject) public returns (uint penalty) {
       penalty = jc.misbehaviorJudge(subject, owner, "data", "read", "Too frequent access!", now);
   }

}


contract Judge {
   function misbehaviorJudge(address _subject, address _object, string memory _resource, string memory _action, string memory _misbehavior, uint _time) public returns (uint);
}

法官.sol

pragma solidity >=0.4.22 <0.6.0;

contract Judge {

   struct Misbehavior{
       address subject;   //subject who performed the misbehavior 
       address device;
       string resource;
       string action;   //action (e.g., "read","write","execute") of the misbehavior
       string misbehavior;
       uint time;   //block timestamp of the Misbehavior ocured
       uint penalty;   //penalty (number of minitues blocked)
   }

   mapping (address => Misbehavior[]) public MisbehaviorList;

   function misbeaviorJudge(
       address _subject, 
       address  _device, 
       string memory _resource,
       string memory _action,
       string memory _misbehavior,
       uint  _time) 
       public returns (uint  penalty) 
   {
       penalty = MisbehaviorList[_subject].length;
       MisbehaviorList[_subject].push(Misbehavior(_subject, _device, _resource, _action, _misbehavior, _time, penalty));
   }

   function getLatestMisbehavior(address _requester) public view 
       returns (address _subject, address _device, string memory _resource, string memory _action, string memory _misbehavior, uint _time)
   {
       uint latest = MisbehaviorList[_requester].length  - 1;
       _subject = MisbehaviorList[_requester][latest].subject;
       _device = MisbehaviorList[_requester][latest].device;
       _resource = MisbehaviorList[_requester][latest].resource;
       _action = MisbehaviorList[_requester][latest].action;
       _misbehavior = MisbehaviorList[_requester][latest].misbehavior;
       _time = MisbehaviorList[_requester][latest].time;
   }
}

你已經聲明了 function misbehaviorJudge

但是你已經實現了 function misbeaviorJudge

所以在我看來,你正試圖呼叫一個未實現的函式。


下次避免類似問題的幾種方法(更準確地說,將其從難以調查的執行時問題轉換為易於調查的編譯問題):

選項 #1 - 如果您不需要misbehaviorJudge在合約中呼叫函式Judge

文件IJudge.sol

interface IJudge {
   function misbehaviorJudge(...) external returns (uint);

文件Judge.sol

import "./IJudge.sol";

contract Judge is IJudge {
   ...
}

選項 #2 - 如果您確實需要misbehaviorJudge在合約中呼叫函式Judge

文件IJudge.sol

contract IJudge {
   function misbehaviorJudge(...) public returns (uint);

文件Judge.sol

import "./IJudge.sol";

contract Judge is IJudge {
   ...
}

然後(對於兩個選項),在 file 中AccessControl.sol,只需使用IJudge而不是Judge

import "./IJudge.sol";

contract AccessControl {
   IJudge public jc;
   ...
}

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