Remix
為什麼solidity會拋出“注意:如果您發送值,則應支付建構子。”,而問題顯然出在其他地方?
我正在Remix上編寫一份能夠部署和跟踪子契約的契約。
以下是2份契約:
pragma solidity ^0.5.0;
契約工廠
contract ContractFactory{ ChildContract[] public createdContracts; ChildContract public activeChild; function createChild() public{ ChildContract newChild = new ChildContract(); createdContracts.push(newChild); // if (address(activeChild) != address(0)){ activeChild.activate(false); // } activeChild = newChild; } }
兒童契約
contract ChildContract{ bool isActive; constructor() public{ isActive = true; } function activate(bool status) public{ isActive = status; } }
我部署了 ContractFactory,它是成功的。然後我嘗試呼叫該
createChild
函式。然後我收到以下錯誤:transact to ContractFactory.createChild errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The constructor should be payable if you send value. Debug the transaction to get more information.
從程式碼中可以明顯看出,如果我取消註釋函式
if condition
內部的註釋createChild
,該函式將毫無問題地執行。我的問題是 - 為什麼solidity會拋出這個誤導性錯誤,因為問題在於未設置的變數?
Solidity throwing
暗示這是一個編譯錯誤,這顯然不是這裡的情況。送出事務的 web3 客戶端(在您的情況下為 Remix)在執行時引發異常。
它被拋出是因為您屏蔽了該
if (address(activeChild) != address(0))
語句,因此嘗試呼叫activeChild.activate
(當activeChild
指向地址 0 時)會恢復事務。此資訊由 Remix 明確提供給您:
transact to ContractFactory.createChild errored: VM error: revert. revert The transaction has been reverted to the initial state.
關於建構子的註釋…好吧,它只是讓您了解所記錄的事實的註釋…
註釋掉檢查是失敗的原因。
activeChild
直到後來才成為有效實例。
activeChild = newChild;
但這條線似乎是在試圖停用前任。如果沒有前任怎麼辦?
activeChild.activate(false)
在第一次執行時,不會有 previous
activeChild
,所以檢查很重要,否則肯定會遇到麻煩。我可能會更明確地進行比較。
if(address(activeChild) != address(0)) { // carry on and deactivate it
正如其他評論員所提到的,執行時錯誤的可能原因只是一種猜測,而且常常具有誤導性。
希望能幫助到你。