以太坊學習(9)關於geth搭建私有鏈下呼叫合約遇到require (false)會消耗完所有gas的解決方案【國內首發】
阿新 • • 發佈:2018-12-24
關於geth搭建私有鏈下呼叫合約遇到require (false)會消耗完所有gas的解決方案
如果你沒遇到過這個問題,你會覺得很奇怪,Solidity的關鍵字require,根據用法解釋:https://ethfans.org/posts/when-to-use-revert-assert-and-require-in-solidity 如果括號內條件為false,不是應該返還未消耗的gas嗎?
而個人遇到的是,遇到require(false) 反而消耗完了我的gas。
一、我按照網上的一般版本在geth上搭建私有鏈,創世區塊配置檔案genesis.json如下:
{
"config":{
"chainId":9,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0
},
"nonce":"0x0000000000000042",
"timestamp":"0x0",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData":"0x00000000",
"gasLimit":"0x80000000",
"difficulty":"0x100",
"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase":"0x3333333333333333333333333333333333333333",
"alloc": {}
}
二、在remix-ide編寫合約如下:
pragma solidity ^0.4.22; contract aPlusb{ function aPlusb(){} uint a=1; event happen(uint input,uint output); function plus(uint a,uint b) returns (uint){ require(a==2); happen(a,a+1); return a+1; } }
三、在remix-ide的虛擬機器測試合約,呼叫plus()方法,require正常返還gas
四、利用remix-ide連線我在geth搭建的私有鏈後,部署合約到私有鏈,再呼叫plus()方法,則會消耗完我所有的gas,如下:
五、國內查閱相關情況:無果。
六、google查閱相關資料:
- 發現有類似案例,但並沒有給出有效解決方案,參見:
- https://ethereum.stackexchange.com/questions/42725/modifier-consumes-all-gas
- https://ethereum.stackexchange.com/questions/58400/why-does-gas-rise-when-the-require-will-fail?rq=1
- 另外,這個require和revert是在拜占庭版本更新後才有效的
七、無奈之下,個人在 ethereum.stackexchange.com 提交問題,幸好有大神回覆如下:
八、解決方案
1、修改創世區塊檔案,在config選項中加入拜占庭版本的起始區塊,如果不設定,大概要挖到 4,370,000區塊,require才能正常使用。
新的創世區塊配置檔案如下:
{
"config":{
"chainId":9,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0,
"byzantiumBlock":0
},
"nonce":"0x0000000000000042",
"timestamp":"0x0",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData":"0x00000000",
"gasLimit":"0x80000000",
"difficulty":"0x100",
"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase":"0x3333333333333333333333333333333333333333",
"alloc": {}
}
2、重新部署
3、測試,require正確返回未消耗的gas。問題解決。