天天看點

Remix IDE報錯:This contract does not implement all functions and thus cannot be created. 淺談constructor

今天在Remix上部署合約時,遇到了這樣的問題:

Remix IDE報錯:This contract does not implement all functions and thus cannot be created. 淺談constructor

Deploy根本無法成功進行,但問題很明顯,是合約中有什麼函數出了問題,沒有正确地實作,于是我首先懷疑是函數的可見性出了問題,是以我先将所有函數的可見性都調整為public,這是最不安全的,但是也是門檻最低,最容易過Deploy的方式,然後果不其然,部署成功了,然後我又逐一改回,看看到底是哪個函數的可見性出了問題導緻的。

Remix IDE報錯:This contract does not implement all functions and thus cannot be created. 淺談constructor

原來是constructor的可見性出了問題,我将它改為之前寫的internal後,之前的問題又出現了,是以這裡寫public是可以的,當然什麼都不寫表示預設public也可以,但是會報警告,因為最好是養成每寫完一個函數就将可見性寫出來的習慣,即便是public也一樣,代碼會更加清晰。

注意,寫external更是萬萬不可,constructor隻能是internal或者public才可以,否則,就會出現如下的錯誤:

Remix IDE報錯:This contract does not implement all functions and thus cannot be created. 淺談constructor

可謂是需要處處小心了,我查閱了一下官方文檔,是這麼說constructor的,希望可以進一步解釋constructor可見性的使用方法:

Before the constructor code is executed, state variables are initialised to their specified value if you initialise them inline, or zero if you do not.

在構造函數執行前,狀态變量是會先初始化的,初始化的結果是你用内聯方式賦予的值,或者0。

A constructor is optional. Only one constructor is allowed, which means overloading is not supported.

構造函數的改寫是可選的,但一個合約隻允許寫一個構造函數,意味着構造函數不支援重載。

After the constructor has executed, the final code of the contract is deployed to the blockchain. This code includes all public and external functions and all functions that are reachable from there through function calls. The deployed code does not include the constructor code or internal functions only called from the constructor.

構造函數執行完畢後,合約的最終代碼就部署到了區塊鍊上,最終代碼包括所有的public和external函數,以及所有可以通過函數調用(call)通路到的函數。部署好的代碼是不包括構造函數或者隻有在構造函數中才調用到的可見性為internal的函數的。

Constructor functions can be either 

public

 or 

internal

. If there is no constructor, the contract will assume the default constructor, which is equivalent to 

constructor() public {}

構造函數可以是public或者internal的,如果沒有constructor,那麼合約就會假定為預設構造函數,相當于constructor() 

A constructor set as 

internal

 causes the contract to be marked as abstract.

一個可見性設定為internal的構造函數會使得合約被标記成抽象的合約。(這應該就是為什麼我寫internal不對了,一個被标記為抽象的合約,自然會認為你的所有函數都是沒有實作的,更不可能deploy了,是以寫public是很重要的)

那麼我們還是要想一下為什麼構造函數不能用external呢?其實很明顯,因為這是合約内部要用的函數,當然不能設成external了,但我們看了官方文檔應該對這個事有更深一步的了解:那就是因為我們部署在區塊鍊上的代碼,是不包含constructor的,在你要使用的時候,constructor已經不在了,那你想調用constructor,又隻能用外部調用,可是沒有部署到區塊鍊上,我們找不到啊,内部調用你也沒給我機會,是以就根本沒法用。

是以,遇到“This contract does not implement all functions and thus cannot be created.”這個錯誤時就去檢查一下你的constructor的可見性寫對了沒有吧~我們寫成public應該就可以了。

如果感覺有收獲,歡迎關注和點贊,如果有問題,歡迎和我繼續探讨,如果有錯誤,歡迎指正,哈哈~

繼續閱讀