W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
public
公共狀態(tài)變量與內(nèi)部變量的不同之處僅在于編譯器會自動為它們生成 getter 函數(shù),這允許其他合約讀取它們的值。當在同一個合約中使用時,外部訪問(例如this.x
)調(diào)用 getter,而內(nèi)部訪問(例如x
)直接從存儲中獲取變量值。不生成設置器函數(shù),因此其他合約無法直接修改它們的值。
internal
內(nèi)部狀態(tài)變量只能從它們在衍生合同中定義的合同中訪問。它們不能被外部訪問。這是狀態(tài)變量的默認可見性級別。
private
私有狀態(tài)變量類似于內(nèi)部變量,但它們在派生合約中不可見。
警告
制作某些東西private
或internal
僅阻止其他合約讀取或修改信息,但它仍然對區(qū)塊鏈之外的整個世界可見。
Solidity 知道兩種函數(shù)調(diào)用:確實創(chuàng)建實際 EVM 消息調(diào)用的外部函數(shù)調(diào)用和不創(chuàng)建實際 EVM 消息調(diào)用的內(nèi)部函數(shù)調(diào)用。此外,派生合約可能無法訪問內(nèi)部功能。這產(chǎn)生了四種類型的功能可見性。
external
外部函數(shù)是合約接口的一部分,這意味著它們可以從其他合約和交易中調(diào)用。f
不能在內(nèi)部調(diào)用外部函數(shù)(即f()
不工作,但this.f()
工作)。
public
公共函數(shù)是合約接口的一部分,可以在內(nèi)部調(diào)用,也可以通過消息調(diào)用。
internal
內(nèi)部函數(shù)只能從當前合約或從它派生的合約中訪問。它們不能被外部訪問。由于它們沒有通過合約的 ABI 暴露給外部,它們可以采用內(nèi)部類型的參數(shù),如映射或存儲引用。
private
私有函數(shù)類似于內(nèi)部函數(shù),但它們在派生合約中不可見。
警告
制作某些東西private
或internal
僅阻止其他合約讀取或修改信息,但它仍然對區(qū)塊鏈之外的整個世界可見。
可見性說明符在狀態(tài)變量的類型之后以及函數(shù)的參數(shù)列表和返回參數(shù)列表之間給出。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract C { function f(uint a) private pure returns (uint b) { return a + 1; } function setData(uint a) internal { data = a; } uint public data; }
在以下示例中D
, 可以調(diào)用c.getData()
以檢索 data
狀態(tài)存儲中的值,但不能調(diào)用f
。ContractE
派生自 C
,因此可以調(diào)用compute
.
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract C { uint private data; function f(uint a) private pure returns(uint b) { return a + 1; } function setData(uint a) public { data = a; } function getData() public view returns(uint) { return data; } function compute(uint a, uint b) internal pure returns (uint) { return a + b; } } // This will not compile contract D { function readData() public { C c = new C(); uint local = c.f(7); // error: member `f` is not visible c.setData(3); local = c.getData(); local = c.compute(3, 5); // error: member `compute` is not visible } } contract E is C { function g() public { C c = new C(); uint val = compute(3, 5); // access to internal member (from derived to parent contract) } }
編譯器會自動為所有公共狀態(tài)變量創(chuàng)建 getter 函數(shù)。對于下面給出的合約,編譯器將生成一個調(diào)用的函數(shù),該函數(shù)data
不接受任何參數(shù)并返回一個uint
狀態(tài)變量的值data
。狀態(tài)變量可以在聲明時進行初始化。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract C { uint public data = 42; } contract Caller { C c = new C(); function f() public view returns (uint) { return c.data(); } }
getter 函數(shù)具有外部可見性。如果符號在內(nèi)部被訪問(即沒有this.
),它的計算結果是一個狀態(tài)變量。如果它被外部訪問(即使用this.
),它的計算結果是一個函數(shù)。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.0 <0.9.0; contract C { uint public data; function x() public returns (uint) { data = 3; // internal access return this.data(); // external access } }
如果您有一個public
數(shù)組類型的狀態(tài)變量,那么您只能通過生成的 getter 函數(shù)檢索數(shù)組的單個元素。這種機制的存在是為了避免在返回整個陣列時產(chǎn)生高氣體成本。您可以使用參數(shù)來指定要返回的單個元素,例如 myArray(0)
. 如果要在一次調(diào)用中返回整個數(shù)組,則需要編寫一個函數(shù),例如:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.16 <0.9.0; contract arrayExample { // public state variable uint[] public myArray; // Getter function generated by the compiler /* function myArray(uint i) public view returns (uint) { return myArray[i]; } */ // function that returns entire array function getArray() public view returns (uint[] memory) { return myArray; } }
現(xiàn)在您可以使用getArray()
來檢索整個數(shù)組,而不是 myArray(i)
,它每次調(diào)用都返回一個元素。
下一個例子更復雜:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.4.0 <0.9.0; contract Complex { struct Data { uint a; bytes3 b; mapping (uint => uint) map; uint[3] c; uint[] d; bytes e; } mapping (uint => mapping(bool => Data[])) public data; }
它生成以下形式的函數(shù)。結構中的映射和數(shù)組(字節(jié)數(shù)組除外)被省略了,因為沒有很好的方法來選擇單個結構成員或為映射提供鍵:
function data(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b, bytes memory e) { a = data[arg1][arg2][arg3].a; b = data[arg1][arg2][arg3].b; e = data[arg1][arg2][arg3].e; }
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: