可見性和Getters(Visibility and Getters)
Solidity可以了解兩種函數調用:
- “内部調用”,不建立一個真實的EVM調用,也稱為“消息調用”
- “外部調用”,要建立一個真實的EVM調用,
有四種的函數和狀态變量的可見性:
- 函數可以被定義為
,external
,public
或internal
,預設是private
。public
- 狀态變量不能為
,預設是external
。internal
external
: 外部函數是合約接口的一部分,這意味着它們可以從其他合約調用, 也可以通過事務調用。外部函數
f
不能被内部調用,即
f()
不執行,但
this.f()
執行。外部函數在接收大數組時更有效。
public
:公共函數是合約接口的一部分,可以通過内部調用或消息調用。對公共狀态變量而言,會自動生成
getter
函數。
internal
:内部的函數和狀态變量隻能内部通路,即目前合約或由它派生的合約,不使用關鍵字
this
。
private
:私有的函數和狀态變量隻能在所在的合約中可見, 在派生的合約中不可見。
注解 |
---|
合約内所有内容對于所有的外部觀察者可見。用 僅僅防止其他合約來通路和修改該合約中資訊, 但它對blockchain之外的整個世界仍然可見。 |
可見性修飾符放在在狀态變量的類型之後,或參數清單和函數傳回的參數清單之間。
pragma solidity ^;
contract C {
function f(uint a) private pure returns (uint b) { return a + ; }
function setData(uint a) internal { data = a; }
uint public data;
}
在下面的示例中,
D
可以調用
c.getData()
來檢索狀态存儲中的資料值,但不能調用
f
.。合約
E
是從
C
派生的,是以可以調用
compute
。
// 這段代碼無法編譯
pragma solidity ^;
contract C {
uint private data;
function f(uint a) private returns(uint b) { return a + ; }
function setData(uint a) public { data = a; }
function getData() public returns(uint) { return data; }
function compute(uint a, uint b) internal returns (uint) { return a+b; }
}
contract D {
function readData() public {
C c = new C();
uint local = c.f(); // error: member `f` is not visible
c.setData();
local = c.getData();
local = c.compute(, ); // error: member `compute` is not visible
}
}
contract E is C {
function g() public {
C c = new C();
uint val = compute(, ); // access to internal member (from derived to parent contract)
}
}
Getter函數(Getter Functions)
編譯器會自動為所有public狀态變量建立getter函數。對于下面的合約,編譯器将生成一個名為
data
的函數,該函數不接受任何參數,并傳回
uint
,即狀态變量
data
的值。狀态變量的初始化可以在聲明中完成。
pragma solidity ^;
contract C {
uint public data = ;
}
contract Caller {
C c = new C();
function f() public {
uint local = c.data();
}
}
getter函數具有外部可見性。
- 如果在内部通路符号(即不使用
關鍵字),則将其作為狀态變量。this.
- 如果它是外部通路的(即使用
),則将其作為函數。this.
下一個例子更複雜:
pragma solidity ^;
contract Complex {
struct Data {
uint a;
bytes3 b;
mapping (uint => uint) map;
}
mapping (uint => mapping(bool => Data[])) public data;
}
這會生成一個如下形式的函數:
function data(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b) {
a = data[arg1][arg2][arg3].a;
b = data[arg1][arg2][arg3].b;
}
注意:struct中的mapping被省略,因為沒有好的方法來提供mapping的key。
上一篇:深入了解Solidity——建立合約
下一篇:深入了解Solidity——函數修飾符