Skip to content

Latest commit

 

History

History
215 lines (169 loc) · 9.28 KB

File metadata and controls

215 lines (169 loc) · 9.28 KB

WTF Solidity 極簡入門:5. 變量數據儲存和作用域

重點內容

Note

storage、memory、calldata

隨筆

Tip

EVM Architecture 105/img1 參考來源

數據儲存位置

Solidity 數據儲存位置有三類:storagememorycalldata,不同儲存位置的 gas 成本不同。
storage 類型數據存在鏈上,類似計算機的硬碟,消耗 gas 多。
memorycalldata 類型的臨時存在內存裡,消耗 gas 少。

storage

合約裡的狀態變量默認都是 storage,儲存在鏈上

memory

函數裡的參數臨時變量一般用 memory,儲存在內存中不上鏈。
尤其是返回數據類型是變長的情況下,必須加 memory 修飾詞。
例如:stringbytesarray自訂義結構

calldata

memory 類似,儲存在內存中不上鏈。
memory 的不同點在於 calldata 變量不能修改 (immutable),一般用於函數的參數。
舉例:

  function fCalldata(uint[] calldata _x) public pure returns(uint[] calldata){
    // 參數為 calldata 陣列,不能被修改
    // _x[0] = 0 // 這樣修改會噴錯
    return(_x);
  }

數據位置和賦值規則

  • 以下兩種賦值本質上是創建引用指向本體,因此修改本體或者引用,變化會被同步

    • storage (合約的狀態變量) 賦值給本地 storage (函數裡) 時,會創建引用,改變新變量會影響原變量
      uint[] x = [1,2,3]; // 狀態變量:陣列 x
    
      function fStorage() public{
          //聲明storage的變量 xStorage,指向x。修改xStorage也會影響x
          uint[] storage xStorage = x;
          xStorage[0] = 100;
      }
    • memory 賦值給 memory,會創建引用,改變新變量會影響原變量
  • 其他狀況賦值創建的是本體的副本,二者之一的修改不會影響到另一方

變量的作用域

狀態變量

狀態變量的數據除存在鏈上,所有合約內部函數都可以訪問,gas 消耗高。
狀態變量在合約內函數外部聲明

  contract Variables {
    uint public x = 1;
    uint public y;
    string public z;
  }

局部變量

局部變量是僅在函數執行過程中有效的變量,函數退出後變量無效。
局部變量的數據儲存在內存裡,不上鏈gas 消耗低。
局部變量在函數內部聲明

  function bar() external pure returns(uint){
    uint xx = 1;
    uint yy = 3;
    uint zz = xx + yy;
    return(zz);
  }

全局變量

全局變量是全局範圍工作的變量,都是 solidity 預留的關鍵字。
可以在函數內不聲明直接使用

  function global() external view returns(address, uint, bytes memory){
    address sender = msg.sender;
    uint blockNum = block.number;
    bytes memory data = msg.data;
    return(sender, blockNum, data);
  }

常見的全局變量有 msg.senderblock.numbermsg.data

Tip

Cancun升级新增的全局變量
block.blobbasefee: (uint) 當前區塊的 blob 基礎費用。
blobhash(uint index): (bytes32) 返回跟當前交易關聯的第 index 個 blob的版本化哈希

以太單位和時間單位

以太單位

Solidity 中不存在小數點,以 0 代替小數點,來確保交易的精確度,並且防止精度的丟失

  • wei:1
  • gwei:1e9 = 1000000000
  • ether:1e18 = 1000000000000000000

時間單位

  • seconds:1
  • minutes:60 seconds = 60
  • hours:60 minutes = 3600
  • days:24 hours = 86400
  • weeks:7 days = 604800

題目練習

  1. Q: 問題?
    A: 回答

  2. Q: 問題?
    A: 回答

  3. Q: 問題?
    A: 回答

  4. Q: 問題?
    A: 回答

  5. Q: 問題?
    A: 回答