Go-Ethereum

錯誤設置地址/添加數據,錯誤:“所需的氣體超過允許或總是失敗的交易並且該功能不起作用”

  • April 12, 2019

我正在嘗試用智能合約做一個數據訪問控制系統。我有 3 個實體:

  1. 客戶端:誰可以獲取Oracle的數據和設置地址
  2. Oracle:誰可以添加數據並擁有 getData() 函式
  3. RBAC:基於角色的訪問控制,誰管理權限

該系統還具有 2 個用於 Oracle 和 RBAC 的主要功能介面。當我在 JavaScript VM(在 Remix 上)上測試系統時,一切都很好,我沒有問題。但是當我試圖在我的私有區塊鏈上部署這個系統時,它不起作用。當我嘗試在客戶端契約中設置 Oracle 地址時,我遇到了問題:“所需的氣體超過了限額或總是失敗的交易並且該功能不起作用”。我檢查了我是否使用了正確的帳戶(這是一個只能由合約所有者呼叫的函式)並且沒問題。

這是我的 setOracleAddress() 函式程式碼(在客戶端契約中):

//data oracle  
address internal oracleAddr = 0x0000000000000000000000000000000000000000;
OracleInterface internal oracle = OracleInterface(oracleAddr); 

   function setOracleAddress(address _oracleAddress) external onlyOwner returns (bool) {
   oracleAddr = _oracleAddress;
   oracle = OracleInterface(oracleAddr);  
   return oracle.testConnection();
}

這是 testConnection() 程式碼(在 oracle 契約中):

/// @notice can be used by a client contract to ensure that they've connected to this contract interface successfully
/// @return true, unconditionally  
function testConnection() public pure returns (bool) {
   return true;  
}

在我的創世區塊鏈區塊中,我有以下氣體限制:

"gasLimit"   : "0x8000000",

以下是我獲取 Oracle 地址的方法:

/// @notice gets the address of this contract  
/// @return address  
function getAddress() public view returns (address) {
   return address(this);
}

修飾符 onlyOwner() 程式碼:

 /**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
   require(msg.sender == owner);
   _;
}

我試圖增加創世區塊中的gasLimit,以檢查正確的帳戶並更新軟體(松露、geth、web3)。

編輯: 我通過將行添加到創世文件中解決了設置地址的問題

"ByzantiumBlock":0

但是現在當我嘗試添加測試數據時,我得到了同樣的錯誤。

這是 addData() 函式的程式碼:

   /// @notice puts a new pending data into the blockchain  
/// @param name descriptive name for the data (e.g. House001)
/// @param otherInfo about something like address (e.g. "Via roma 6, Torino")
/// @param sensorData sensor data
/// @return the unique id of the newly created data  
function addData(string memory name, string memory otherInfo, uint sensorData,  uint permissionMin, uint date) onlyOwner public returns (bytes32) {

   assert(permissionMin < rbac.getNumRole());

   //hash the crucial info to get a unique id  
   bytes32 id = keccak256(abi.encodePacked(name,otherInfo,date));  

   //require that the data be unique (not already added)  
   require(!dataExists(id));

   //add data
   uint newIndex = data.push(Data(id, name, otherInfo, sensorData, permissionMin, date, false))-1;  
   dataIdToIndex[id] = newIndex+1;

   //return the unique id of the new data
   return id;
}

獲取 numRole() 函式程式碼:

uint numRole = 3;

function getNumRole() public view returns(uint){
    return numRole;
}

結構數據程式碼:

//defines a struct "Data"
struct Data {
   bytes32 id;
   string name;
   string otherInfo;
   uint sensorData;
   uint permission; 
   uint date;
   bool read;
}

addData() 範例:

   /// @notice for testing  
function addTestData() external onlyOwner {
   addData("House001", "via Roma 2, Milano", 0,1, 20190504);

強制執行時出錯

有什麼幫助嗎?謝謝!!

  1. 你的私有鏈在什麼上執行?你知道你可以訪問哪個版本的 Solidity 嗎?在相對較新的版本中進行跨合約函式呼叫存在已知錯誤——您可能需要找到一種方法來升級您的私有鏈的軟體。
  2. 看看幾個月前的這個答案:https ://stackoverflow.com/a/50951266/2128308 。如果您正在執行一個許可鏈並將 gas 價格設置為零,這可能會導致意外行為。
  3. Geth 的錯誤在很長一段時間內都是垃圾——如果require()檢查失敗,它看起來就像是一個 out of gas 錯誤。仔細檢查您實際上是契約的所有者,您的修改器可能會阻止您。

祝你好運!

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