想知道更多關於區塊鏈技術知識,請百度【鏈客區塊鏈技術問答社區】 鏈客,有問必答!
下面來繼續介紹做爲一個分佈式網絡語言所特有的internal和external這兩種不一樣的函數調用方式,以及Solidity提供的對函數調用時的可見性控制語法。
1、 調用方式
Solidity封裝了兩種函數的調用方式internal和external。
internal
internal調用,實現時轉爲簡單的EVM跳轉,因此它能直接使用上下文環境中的數據,對於引用傳遞時將會變得很是高效(不用拷貝數據)。
在當前的代碼單元內,如對合約內函數,引入的庫函數,以及父類合約中的函數直接使用便是以internal方式的調用。咱們來看個簡單的例子:
pragma solidity ^0.4.0;數組
contract Test {網絡
function f(){} //以`internal`的方式調用 function callInternally(){ f(); }
}
在上述代碼中,callInternally()以internal的方式對f()函數進行了調用。
external
external調用,實現爲合約的外部消息調用。因此在合約初始化時不能external的方式調用自身函數,由於合約還未初始化完成。下面來看一個以external方式調用的例子:
pragma solidity ^0.4.0;分佈式
contract A{ide
function f(){}
}函數
contract B{性能
//以`external`的方式調用另外一合約中的函數 function callExternal(A a){ a.f(); }
}
雖然當前合約A和B的代碼放在一塊兒,但部署到網絡上後,它們是兩個徹底獨立的合約,它們之間的方法調用是經過消息調用。上述代碼中,在合約B中的callExternal()以external的方式調用了合約A的f()。
external調用時,實際是向目標合約發送一個消息調用。消息中的函數定義部分是一個24字節大小的消息體,20字節爲地址,4字節爲函數簽名。
this
咱們能夠在合約的調用函數前加this.來強制以external方式的調用。須要注意的是這裏的this的用法與大多數語言的都不一致。
pragma solidity ^0.4.0;區塊鏈
contract A{this
function f() internal{} function callInternally(){ f(); } //以`external`的方式調用 //f()只能以`internal`的方式調用 //Untitled3:7:9: Error: Member "f" not found or not visible after argument-dependent lookup in contract A function callExternally(){ //this.f(); }
}
調用方式說明
上面所提到的internal和external指的函數調用方式,請不要與後面的函數可見性聲明的external,public,internal,private弄混。聲明只是意味着這個函數須要使用相對應的調用方式去調用。後續說明中會用以某某方式調用,來強調是對調用方式的闡述以加以區分。
2、函數的可見性
Solidity爲函數提供了四種可見性,external,public,internal,private。
external
聲明爲external的能夠從其它合約或經過Transaction進行調用,因此聲明爲external的函數是合約對外接口的一部分。
不能以internal的方式進行調用。
有時在接收大的數據數組時性能更好。
pragma solidity ^0.4.5;spa
contract FuntionTest{code
function externalFunc() external{} function callFunc(){ //以`internal`的方式調用函數報錯 //Error: Undeclared identifier. //externalFunc(); //以`external`的方式調用函數 this.externalFunc(); }
}
聲明爲external的externalFunc()只能以external的方式進行調用,以internal的方式調用會報Error: Undeclared identifier.。
public
函數默認聲明爲public。
public的函數既容許以internal的方式調用,也容許以external的方式調用。
public的函數因爲被外部合約訪問,是合約對外接口的一部分。
pragma solidity ^0.4.5;
contract FuntionTest{
//默認是public函數 function publicFunc(){} function callFunc(){ //以`internal`的方式調用函數 publicFunc(); //以`external`的方式調用函數 this.publicFunc(); }
}
咱們能夠看到聲明爲public的publicFunc()容許兩種調用方式。
internal
在當前的合約或繼承的合約中,只容許以internal的方式調用。
pragma solidity ^0.4.5;
contract A{
//默認是public函數 function internalFunc() internal{} function callFunc(){ //以`internal`的方式調用函數 internalFunc(); }
}
contract B is A{
//子合約中調用 function callFunc(){ internalFunc(); }
}
上述例子中聲明爲internal的internalFunc()在定義合約,和子合約中均只能以internal的方式能夠進行調用。
private
只能在當前合約中被訪問(不可在被繼承的合約中訪問)。
即便聲明爲private,仍能被全部人查看到裏面的數據。訪問權限只是阻止了其它合約訪問函數或修改數據。
pragma solidity ^0.4.5;
contract A{
//默認是public函數 function privateFunc() private{} function callFunc(){ //以`internal`的方式調用函數 privateFunc(); }
}
contract B is A{
//不可調用`private` function callFunc(){ //privateFunc(); }
}上述例子中,聲明爲private的privateFunc()只能在定義的合約中以internal的方式進行調用。