<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 狀態變量的存儲模型(Layout of State Variables in Storage) 大小固定的變量(除了`映射`,`變長數組`以外的所有類型)在存儲(storage)中是依次連續從位置`0`開始排列的。如果多個變量占用的大小少于32字節,會盡可能的打包到單個`storage`槽位里,具體規則如下: - 在storage槽中第一項是按低位對齊存儲(lower-order aligned)(譯者注:意味著是大端序了,因為是按書寫順序。)。 - 基本類型存儲時僅占用其實際需要的字節。 - 如果基本類型不能放入某個槽位余下的空間,它將被放入下一個槽位。 - `結構體`和`數組`總是使用一個全新的槽位,并占用整個槽(但在結構體內或數組內的每個項仍遵從上述規則) ## 優化建議 當使用的元素占用少于32字節,你的合約的gas使用也許更高。這是因為EVM每次操作32字節。因此,如果元素比這小,EVM需要更多操作來從32字節減少到需要的大小。 因為編譯器會將多個元素打包到一個`storage`槽位,這樣就可以將多次讀或寫組合進一次操作中,只有在這時,通過縮減變量大小來優化存儲結構才有意義。當操作函數參數和`memory`的變量時,因為編譯器不會這樣優化,所以沒有上述的意義。 最后,為了方便EVM進行優化,嘗試有意識排序`storage`的變量和結構體的成員,從而讓他們能打包得更緊密。比如,按這樣的順序定義,`uint128, uint128, uint256`,而不是`uint128, uint256, uint128`。因為后一種會占用三個槽位。 ## 非固定大小 結構體和數組里的元素按它們給定的順序存儲。 由于它們不可預知的大小。`映射`和`變長數組`類型,使用`Keccak-256`哈希運算來找真正數據存儲的起始位置。這些起始位置往往是完整的堆棧槽。 `映射`和`動態數組`根據上述規則在位置`p`占用一個未滿的槽位(對`映射`里嵌套`映射`,數組中嵌套數組的情況則遞歸應用上述規則)。對一個動態數組,位置`p`這個槽位存儲數組的元素個數(字節數組和字符串例外,見下文)。而對于`映射`,這個槽位沒有填充任何數據(但這是必要的,因為兩個挨著的`映射`將會得到不同的哈希值)。數組的原始數據位置是`keccak256(p)`;而`映射`類型的某個鍵`k`,它的數據存儲位置則是`keccak256(k . p)`,其中的`.`表示連接符號。如果定位到的值以是一個非基本類型,則繼續運用上述規則,是基于`keccak256(k . p)`的新的偏移`offset`。 `bytes`和`string`占用的字節大小如果足夠小,會把其自身長度和原始數據存在當前的槽位。具體來說,如果數據最多31位長,高位存數據(左對齊),低位存儲長度`lenght * 2`。如果再長一點,主槽位就只存`lenght * 2 + 1`。原始數據按普通規則存儲在`keccak256(slot)` 所以對于接下來的代碼片段: ``` pragma solidity ^0.4.4; contract C { struct s { uint a; uint b; } uint x; mapping(uint =&gt; mapping(uint =&gt; s)) data; } ``` 按上面的代碼來看,結構體從位置0開始,這里定義了一個結構體,但并沒有對應的結構體變量,故不占用空間。`uint x`實際是`uint256`,單個占32字節,占用槽位0,所以映射`data`將從槽位1開始。 `data[4][9].b`的位置在`keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1` 有人在這里嘗試直接讀取區塊鏈的存儲值,[https://github.com/ethereum/solidity/issues/1550](https://github.com/ethereum/solidity/issues/1550)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看