<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      理解Solidity存儲布局

      最近在看OnchainID這套身份合約,里邊可升級特性部分用到了proxy模式,contract IdentityProxy里邊有如下的構造方法:

       //_implementationAuthority 存儲真正Identity實現合約地址的容器
       //initialManagementKey該身份合約的管理key
      constructor(address _implementationAuthority, address initialManagementKey) {
              require(_implementationAuthority != address(0), "invalid argument - zero address");
              require(initialManagementKey != address(0), "invalid argument - zero address");
      
              // 把_implementationAuthority地址存放在0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc
              assembly {
                  sstore(0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc, _implementationAuthority)
              }
              //從容器中得到實現合約的地址
              address logic = IImplementationAuthority(_implementationAuthority).getImplementation();
      
              //執行delegatecall,業務邏輯用logic也就是實現合約Identity的,數據存儲在當前合約IdentityProxy里
              (bool success,) = logic.delegatecall(abi.encodeWithSignature("initialize(address)", initialManagementKey));
              require(success, "Initialization failed.");
       }
      

      里邊的內聯匯編

      assembly {
           sstore(0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc, _implementationAuthority)
      }
      

      0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc直接指定這個而且是寫死的,一開始有些疑惑,這里有必要復習一下Solidity的存儲布局,結合EIP-1967的規定,就明白了。

      storage

      • 永久存儲(鏈上持久化)。
      • 每個合約地址下有自己的存儲空間。
      • Slot = 32 字節為單位,邏輯上是一個 mapping(uint256 => bytes32)。
      • 所有狀態變量、mapping、struct 最終都會映射到某個 slot 里。

      memory

      • 臨時存儲(函數執行時存在,執行完銷毀)。
      • 線性字節數組,從 0 地址往上擴展。
      • 用于函數內部的動態數組、string、臨時計算緩存等。

      calldata

      • 只讀、不可修改。
      • 存放函數參數(外部調用時 ABI 編碼的數據)。
      • 訪問成本比 memory 更低。

      storage存儲空間

      在EVM里,每個合約都會有自己的存儲空間,其storageLayout邏輯上是個無限大的mapping,比如:

      合約A -> Storage_A:mapping(uint256 => bytes32)
      合約B -> Storage_B:mapping(uint256 => bytes32)

      其中每一個映射key是uint256,一般也成為一個slot,合約里的每個storage類型的變量按照被定義的順序依次存在自己這個mapping的slot里,例如:

      contract C {
          uint256 a; // slot 0
          bool b;    // slot 1 (可能和別的小變量打包)
          mapping(uint => uint) m; // slot 2 (mapping不直接存值,只存“起點slot”)
      }
      

      為什么用0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc這個固定的slot

      回到之前的合約代碼,sstore(0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafc, _implementationAuthority)意思是把 _implementationAuthority這個地址存放在0x821f3e4d...這個slot中;
      sload(0x821f3e4d...)意思是從第0x821f3e4d3d679f19eacc940c87acf846ea6eae24a63058ea750304437a62aafcslot取32字節的值。那么這個大的key值是怎么來的呢?
      這是 EIP-1967 的約定:
      為了防止普通狀態變量“占用” proxy 的關鍵 slot(比如 implementation 地址、admin 地址),社區約定用這樣一個極難撞上的大 hash 值當 slot。
      比如計算規則:

      implementation slot = keccak256("eip1967.proxy.implementation") - 1
      admin slot = keccak256("eip1967.proxy.admin") - 1
      

      開發者在合約里自己定義的storage變量正常情況下是從0、1、2、3...這樣順序往上走的,只要不是故意很難碰撞到這個key。

      posted on 2025-09-05 17:08  肥兔子愛豆畜子  閱讀(15)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 四虎成人精品国产永久免费| 国产超碰无码最新上传| 亚洲色偷偷色噜噜狠狠99| 免费现黄频在线观看国产| 亚洲综合色一区二区三区| 亚洲啪啪精品一区二区的| 新丰县| 国产AV影片麻豆精品传媒| 亚洲精品日韩在线观看| 色爱综合另类图片av| 风韵丰满熟妇啪啪区老熟熟女| 中文字幕日韩区二区三区| 中文字幕无码不卡免费视频| 国产精品成人免费视频网站京东| 国产成人亚洲欧美二区综合| 仪征市| 亚洲AV日韩AV综合在线观看| 中文字幕亚洲制服在线看| 欧美极品少妇×xxxbbb| 久久国产精品99久久蜜臀| 国产999精品2卡3卡4卡| 污污内射在线观看一区二区少妇| 精品一区二区三区免费视频| 天天澡日日澡狠狠欧美老妇| 人妻中文字幕精品系列| 男女性高爱潮免费网站| 国产成人亚洲精品狼色在线 | 国内精品久久人妻无码不卡| 制服丝袜中文字幕在线| 精品久久久bbbb人妻| 国产美女高潮流白浆视频| 邓州市| 国产精品第一页中文字幕| 亚洲美免无码中文字幕在线| 无码国产69精品久久久久网站 | 无码人妻斩一区二区三区| 国产麻豆精品一区一区三区| 久久亚洲av综合悠悠色| 久久青青草原精品国产app| 羞羞影院午夜男女爽爽免费视频| 国产女人水真多18毛片18精品 |