Go-Ethereum
錯誤設置地址/添加數據,錯誤:“所需的氣體超過允許或總是失敗的交易並且該功能不起作用”
我正在嘗試用智能合約做一個數據訪問控制系統。我有 3 個實體:
- 客戶端:誰可以獲取Oracle的數據和設置地址
- Oracle:誰可以添加數據並擁有 getData() 函式
- 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);
有什麼幫助嗎?謝謝!!
- 你的私有鏈在什麼上執行?你知道你可以訪問哪個版本的 Solidity 嗎?在相對較新的版本中進行跨合約函式呼叫存在已知錯誤——您可能需要找到一種方法來升級您的私有鏈的軟體。
- 看看幾個月前的這個答案:https ://stackoverflow.com/a/50951266/2128308 。如果您正在執行一個許可鏈並將 gas 價格設置為零,這可能會導致意外行為。
- Geth 的錯誤在很長一段時間內都是垃圾——如果
require()
檢查失敗,它看起來就像是一個 out of gas 錯誤。仔細檢查您實際上是契約的所有者,您的修改器可能會阻止您。祝你好運!