Solidity語言學習筆記————21、函式的訪問許可權和可見性
在之前的文章中我們介紹了Solidity語言函式的一些基本語法。下面來繼續介紹作為一個分散式網路語言所特有的internal和external這兩種不同的函式呼叫方式,以及Solidity提供的對函式呼叫時的可見性控制語法。
呼叫方式
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{
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{
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
弄混。宣告只是意味著這個函式需要使用相對應的呼叫方式去呼叫。後續說明中會用以某某方式呼叫
,來強調
二、函式的可見性
Solidity為函式提供了四種可見性,external
,public
,internal
,private
。
external
- 宣告為
external
的可以從其它合約或通過Transaction
進行呼叫,所以宣告為external
的函式是合約對外介面的一部分。 - 不能以
internal
的方式進行呼叫。 - 有時在接收大的資料陣列時效能更好。
pragma solidity ^0.4.5;
contract FuntionTest{
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
的方式進行呼叫。
相關文章
- Solidity語言學習筆記————22、可見性和GettersSolid筆記
- Solidity語言學習筆記————19、函式可見性定義符、修飾符、保留字和語法Solid筆記函式
- Solidity語言學習筆記————18、字串和函式Solid筆記字串函式
- Solidity語言學習筆記————28、純函式Solid筆記函式
- Solidity語言學習筆記————26、回退函式Solid筆記函式
- Solidity之旅(十三)函式及其可見性和狀態可變性Solid函式
- Solidity語言學習筆記————23、函式呼叫和賦值Solid筆記函式賦值
- Solidity語言學習筆記————27、檢視函式Solid筆記函式
- Solidity語言學習筆記————30、函式過載Solid筆記函式
- Solidity語言學習筆記————20、函式修飾符Solid筆記函式
- PostgreSQL訪問許可權查詢函式彙總和使用舉例SQL訪問許可權函式
- MYSQL學習筆記13: DCL許可權控制(使用者許可權操作)MySql筆記
- PHP 手冊 (類與物件) 學習筆記六:訪問控制(可見性)PHP物件筆記
- Solidity語言學習筆記————1、初識Solidity語言Solid筆記
- ClickHouse學習系列之六【訪問許可權和賬戶管理】訪問許可權
- Solidity語言學習筆記————5、全域性變數Solid筆記變數
- 論Java訪問許可權控制的重要性Java訪問許可權
- Solidity語言學習筆記————42、提示和技巧Solid筆記
- Solidity語言學習筆記————7、單位和全域性變數Solid筆記變數
- Java入門筆記(六)——訪問許可權修飾符Java筆記訪問許可權
- Solidity語言學習筆記————38、Solidity彙編Solid筆記
- c語言學習筆記===函式C語言筆記函式
- Solidity語言學習筆記————36、 庫Solid筆記
- Solidity語言學習筆記————37、Using forSolid筆記
- Solidity語言學習筆記————4、常量Solid筆記
- Solidity語言學習筆記————11、隱式轉換和顯式轉換Solid筆記
- Solidity語言學習筆記————25、作用域和宣告Solid筆記
- public, private, protected 訪問許可權訪問許可權
- mongoDB 3.0 安全許可權訪問MongoDB
- Java 訪問許可權控制(6)Java訪問許可權
- Mysql學習筆記4--使用者許可權MySql筆記
- 友好訪問許可權篇:訪問語音、相簿、通訊錄----iOS訪問許可權iOS
- Solidity語言學習筆記————33、事件(Events)Solid筆記事件
- Solidity語言學習筆記————12、陣列Solid筆記陣列
- Solidity語言學習筆記————34、繼承Solid筆記繼承
- Solidity語言學習筆記————35、抽象合約和介面Solid筆記抽象
- Solidity語言學習筆記————26、Assert, Require, Revert 和 ExceptionsSolid筆記UIException
- C++中封裝和繼承的訪問許可權C++封裝繼承訪問許可權