智能合約開發
函數可見性
可見性為每個函數回答一個問題:誰被允許呼叫它?Solidity 提供四個層級——public、external、internal 與 private——選錯往往是錯誤的來源,從不小心暴露管理函數,到對大型輸入白白燒掉 gas 都有。
public 函數可從合約內部,也可從外部透過交易或訊息呼叫;把狀態變數宣告為 public 也會自動為它產生一個 getter。external 函數只能從外部呼叫——對 external 函數的內部呼叫必須走 this.f(),那是一次帶有開銷的真實 CALL。internal 函數可從本合約以及任何繼承它的合約存取。private 函數只能從定義它的那個合約存取,連衍生合約都不行。這些層級形塑了合約的 ABI 以及分派器如何路由呼叫;它們並不會讓任何東西變成秘密。
兩個實務重點。關於 gas:external 函數能直接從 calldata 讀取陣列與 bytes 引數,而 public 函數會先把它們複製到記憶體,所以對大型輸入而言 external 較便宜。關於安全:internal 與 private 限制的是誰能呼叫程式碼,而非誰能讀取資料。所有合約儲存在鏈上對任何執行節點的人都是公開可讀的,因此「private」變數並不機密——切勿把秘密、密碼或金鑰材料存進合約狀態,妄想用可見性把它藏起來。
uint256 public totalSupply; // auto getter: totalSupply()
function _mint(address to) internal {} // this contract + heirs
function transfer(...) external {} // outside callers only選擇仍能運作的最窄可見性。
常見誤解:private 代表機密。並非如此。private 只是阻止其他 Solidity 程式碼呼叫它——任何人仍可直接從鏈上讀取底層的儲存槽。
另见