加密貨幣交易所 加密貨幣交易所
Ctrl+D 加密貨幣交易所
ads
首頁 > 幣贏 > Info

深入Solidity數據存儲位置——Storage_BSP:TOR

Author:

Time:1900/1/1 0:00:00

這是深入 Solidity 數據存儲位置系列的另一篇。在今天的文章中,我們將更詳細地介紹 EVM 中的一個重要數據位置:存儲(Storage)。

我們將看到合約存儲的布局是如何工作的,storage引用。我們還將使用OpenZeppelin和Compound中的一些合約來學習storage引用在實踐中如何工作,同時順便學習這些流行合約和協議背后的 Solidity 代碼。

存儲器的基礎知識

與存儲交互

函數參數中的存儲指針

函數體中的存儲指針

讀取存儲的成本。

結論

了解以太坊和基于 EVM 的鏈中的存儲模型對于良好的智能合約開發至關重要。

你可以在智能合約上永久地存儲數據,以便將來執行時可以訪問它。每個智能合約都在自己的永久存儲中保持其狀態。它就像*"智能合約的迷你數據庫 "*,但與其他數據庫不同,這個數據庫是可以公開訪問的。所有存儲在智能合約存儲器中的值可供外部免費讀取(通過靜態調用),無需向區塊鏈發送交易。

然而,向存儲空間寫入是相當昂貴的。事實上,就 Gas 成本而言,它是 EVM 中最昂貴的操作。存儲的內容可以通過sendTransaction調用來改變。這種調用會改變狀態。這就是為什么合約變量被稱為狀態變量的原因。

需要記住的一件事是,在以太坊和 EVM 的設計中,一個合約既不能讀也不能寫非自身定義的任何存儲。合約 A 可以從另一個合約 B 的存儲中讀取或寫入的唯一方法是當合約 B 暴露出使其能夠這樣做的函數。

智能合約的存儲是一個持久的可讀可寫的數據位置。意思是說,如果數據在一次交易中被寫入合約存儲,一旦交易完成,它就會持久存在。在這個交易之后,讀取合約存儲將檢索到之前這個交易所寫入/更新的數據。

每個合約都有自己的存儲,可以用以下規則來描述和綁定:

持有狀態變量

在交易和函數調用之間持久存在

讀取是免費的,但寫入是昂貴的

合約存儲在合約構建期間被預先分配。

駐留在存儲中的變量在 Solidity 中被稱為狀態變量。

你應該記住關于合約存儲的唯一事情是:

存儲是持久保存和昂貴的!

將數據保存到存儲中是 EVM 中需要最多的 Gas 的操作之一。

寫入存儲的實際成本是多少?

成本并不總是相同的,計算寫入存儲的 Gas 是相當復雜的公式,尤其是在最新的以太坊 2.0 升級后)。

作為一個簡單的總結,寫入存儲的成本如下:

初始化一個存儲槽(第一次,或如果該槽不包含任何值),從零到非零值,花費 20,000 gas

修改一個存儲槽的值需要 5,000 個 Gas

刪除存儲槽中的數值,需要退還 15,000 Gas。

讀取合約存儲真的是免費的嗎?

智能合約的存儲是免費的,可以從外部讀取(從 EOA),此時,不需要支付 Gas。

然而,如果讀取操作是修改該合約、另一個合約或區塊鏈上的狀態的交易的一部分,則必須支付 Gas。

一個合約可以讀取其他合約的存儲嗎?

默認情況下,一個智能只能在執行環境中讀取自己的存儲(通過SLOAD)。但是,如果一個智能合約在其公共接口(ABI)中公開了能夠從特定的狀態變量或存儲槽中讀取數據的函數,那么該智能合約也可以讀取其他智能合約的存儲。

正如OpenZeppelin 在他們的深入 EVM 第二部分文章中所解釋的那樣,智能合約的存儲是一個字長尋址空間。這與內存或調用數據相反,后者是線性數據位置(增長的字節數組),你通過偏移量(字節數組中的索引)訪問數據。

相反,智能合約的存儲是一個鍵值映射(=數據庫),其中鍵對應于存儲中的一個槽號,而值是存儲在這個存儲槽中的實際值。

智能合約的存儲是由槽組成的,其中:

每個存儲槽可以包含長度不超過 32 字節的字。

存儲槽從位置 0 開始(就像數組索引)。

總共有 22?? 個存儲槽可用(用于讀/寫)。

現場 | 觀點:區塊鏈技術需要深入場景才能形成產業:金色財經現場報道,10月15日,華山論劍2020網絡安全大會于西安召開,在大會的區塊鏈安全與應用創新分論壇圓桌討論環節,

基石基金管理合伙人秦少博分享表示,區塊鏈創新型的業務需要承擔比較大的沉默成本,在區塊鏈領域創業需要考量自身能力。區塊鏈技術需要深入場景才能形成產業,過去5年由幣引發的熱潮已經越發理智。把區塊鏈作為技術、生產力討論更合適。不宜與太大的市場概念結合。

中國移動研究院安全技術研究所所長何申分享表示,從通信行業看待區塊鏈,會從系統工程高度去看,當區塊鏈從節點成網形成共識,需要考慮節點的安全。此外,可信是一種保障預期方案,區塊鏈是一種方案,兩種方案的協同,是通信領域的重點。對于區塊鏈透明性帶來的隱私問題可以通過隱私技術解決,但可能在公鏈場景里比較難實現。[2020/10/15]

綜上所述:

一個智能合約的存儲由 22?? 個槽組成,其中每個槽可以包含大小不超過 32 字節的值。

在底層,合約存儲是一個鍵值存儲,其中 256 位的鍵映射到 256 位的值。每個存儲槽的所有值最初都被設置為零,但也可以在合約部署期間(即 "構造函數")初始化為非零或一些特定的值,。

在他的文章中,Steve Marx將智能合約的存儲描述為 "一個天文數字的大數組,最初充滿了零,數組中的條目(索引)就是合約的存儲槽。" 。

這在現實世界中會是什么樣子?如何用我們可能最熟悉的東西來表示一個智能合約的存儲?

合約的存儲布局與貨架很相似。

從貨架上把東西拿出來。這相當于 EVM 在讀取狀態變量時的做法。

contract Owner {    address _owner;    function owner() public returns (address) {        return _owner;    }}在上面的合約中,只有一個架子(=一個槽)。EVM 從 "0 號架子 "上加載變量,并將其卸載(到堆棧上)以呈現給你。

Solidity 的主要開發者chriseth這樣描述合約的存儲:

"你可以把存儲看作是一個具有虛擬結構的大數組......一個在運行時不能改變的結構--它是由你合約中的狀態變量決定的"。

從上面的例子中,我們可以看到,Solidity 為你合約中的每一個定義的狀態變量分配了一個存儲槽。對于靜態大小的狀態變量,存儲槽是連續分配的,從 0 號槽開始,按照定義狀態變量的順序。

Chriseth 在這里的意思是: "存儲不能在函數調用中創建"。事實上,如果必須是永久存在,通過調用函數來創建新的存儲變量,也沒有什么意義(不過,映射的情況略有不同)。

智能合約的存儲是在合約構建過程中(在合約被部署時)預置的。這意味著合約存儲的布局在合約創建時就已經確定了。該布局是基于你的合約級變量聲明而 "成型 "的,并且這種布局不能被未來的方法調用所改變。

讓我們用solc命令行工具看看上一個合約的實際存儲布局,如果你運行下面的命令。

solc contracts/Owner.sol --storage-layout --pretty-json你將得到以下 JSON 輸出:

從上面的 JSON 輸出中,我們可以看到一個storage字段,它包含一個對象數組。這個數組中的每個對象都是指一個狀態變量名。我們還可以看到,每個變量都被映射到一個 插槽(slot),并有一個基本的 類型(type)。

這意味著變量_owner可以被改變為同一類型(在我們的例子中為地址)的任何有效值。然而,槽0是為這個變量保留的,并將永遠在那里。

現在讓我們來看看狀態變量是如何在存儲中布局的(進一步了解請看Solidity 文檔)。

考慮一下下面的 Solidity 代碼:

央行:加強科技支撐 深入開展“數字央行”建設:人民銀行2020年科技工作電視電話會議5月18日在北京召開。會議要求,加強科技支撐,深入開展“數字央行”建設,提升金融服務水平和金融監管能力;加強金融業網絡安全和信息化統籌指導,推動落實金融領域密碼應用與創新發展,筑牢金融網絡安全屏障;推動金融科技高質量發展,提升金融服務實體經濟能力;推進LEI應用,優化標準供給,提升金融標準治理水平。[2020/5/19]

pragma solidity ^0.8.0;contract StorageContract {    uint256 a = 10;    uint256 b = 20;}所有靜態大小的變量都是按照它們被定義的順序依次放入存儲槽的。

記住:每個存儲槽最多可以容納 32 字節長的值。

在我們上面的例子中,a和b是 32 字節長(因為它們的類型是uin256)。因此,它們被分配了自己的存儲槽。

在我們之前的例子中沒有什么特別之處。但是現在讓我們考慮這樣的情況:你有幾個不同大小的 uint 變量,如下所示:

我們已經寫了兩個基本的函數來讀取低級別的合約存儲槽。看一下輸出,我們得到以下結果:

Solidity 文檔中指出:

"如果可能的話,少于 32 字節的多個連續項目會被打包到一個存儲槽中...。

存儲槽中的第一個項目被低階對齊存儲

因此,當變量小于 32 字節時,Solidity 嘗試將一個以上的變量打包到一個存儲槽中,如果它們能被容納的話。因此,一個存儲槽可以容納一個以上的狀態變量。

如果一個基本類型不適合存儲槽的剩余空間,它將被移到下一個存儲槽。對于以下 Solidity 合約。

pragma solidity ^0.8.0;contract StorageContract {    uint256 a = 10;    uint64 b = 20;    uint128 c = 30;    uint128 d = 40;}它的存儲布局會是這樣的:

在存儲槽 0 處讀取 1 個值

讀取存儲槽 1 的數值.

讀取存儲槽 2 的值

讓我們看一個更具體的例子,一個流行的 Defi 協議: Aave。

例子: Aave Pool.sol 合約

AAVE 協議使用Pools 作為管理流動性的主要智能合約。這些是主要的 "面向用戶的合約"。用戶直接與 Aave pool 合約交互,以提供或借用流動性(通過 Solidity 的其他合約,或使用 web3/ethers 庫)。

定義在 Pool.sol 中的主要 Aave Pool 合約繼承了一個名字很有趣的合約,與本文的主題有關:PoolStorage。

來源:Aave v3 Protocol, Pool.sol

正如協議的 Aave v3 的 Natspec 注釋中所描述的,PoolStorage合約有一個目的:定義了Pool合約的存儲布局。

如果我們看一下PoolStorage合約的 Solidity 代碼,我們可以看到一些狀態變量由于其類型而被包裝在同一個存儲槽中。

下面的綠色部分:與閃電款有關的狀態變量(_flashLoanPremiumTotal和_flashLoanPremiumToProtocol)都是uint128。它們打包在一起占據了一整個存儲槽(槽號 6)。

下面是藍色部分:最后兩個狀態變量_maxStableRateBorrowSizePercent和_flashLoanPremiumToProtocol的類型是uint64和uint16。它們也都被裝在存儲槽(槽號 7)中,并在存儲槽中一起占據了 10 個字節。這就為潛在的其他狀態變量留下了一些空間(剩余的 22 個字節),可以和它們一起打包。

央行上海總部:深入推進金融科技創新監管試點:5月12日,央行上海總部發布通知稱,下一步將加強對金融科技應用創新試點工程的組織領導,并會同上海市地方金融監管局等單位,深入推進金融科技創新監管試點,提升金融科技支撐能力。中國人民銀行于2020年4月26日支持在上海等6市(區)擴大金融科技創新監管試點,這標志著金融科技創新監管工作正式在上海啟動,也為加快推進上海金融科技中心建設再添助力。

近年來,人民銀行上海總部把大力發展金融科技作為推動上海國際金融中心和科技創新中心聯動發展的重要著力點,積極探索設計上海金融科技中心的建設與發展路徑,發布了《關于促進金融科技發展 支持上海建設金融科技中心的指導意見》(銀總部發〔2019〕67號)。

央行上海總部明確,下一步將以《發展規劃》為指引,加強對金融科技應用創新試點工程的組織領導,并會同上海市地方金融監管局等單位,深入推進金融科技創新監管試點,加大試點項目橫向交流和成果共享,深化金融市場科技應用,提升金融科技支撐能力,為把上海建設成為與國際金融中心地位相適應的金融科技中心提供有力支撐。(中新經緯APP)[2020/5/12]

來源:Aave v3, PoolStorage.sol

合約存儲的布局也是基于繼承的。如果一個合約繼承了其他合約,它的存儲布局就會遵循繼承的順序。

在最基礎的合約中定義的狀態變量從 0 槽開始。

在下面的派生合約中定義的狀態變量被放在次序槽中(槽 1、2、3,等等......)。

另外,請注意,與將狀態變量打包在一個存儲槽中的規則同樣適用。如果可以通過繼承,來自不同父子合約的狀態變量確實共享同一個存儲槽。

EVM 提供了兩個操作碼來與存儲進行交互:SLOAD來讀取,SSTORE來寫入存儲。這兩個操作碼只在內聯匯編中可用。Solidity 在編譯后將寫到狀態變量轉換為這些操作碼。

EVM 可以使用SLOAD操作碼讀取智能合約的存儲。SLOAD從存儲中加載一個字到棧中。

SLOAD操作碼在內聯匯編中可用。它可以用來輕松檢索存儲在特定存儲槽的整個字值。

function readStorageNb(uint256 slotNb)    public    view    returns (bytes32 result){    assembly {        result := sload(slotNb)    }}這就是 solidity 在幕后所做的事情。當通過 getter 函數讀取狀態變量時,它將自動使用SLOAD操作碼。例如,ERC20 中流行的name()或symbol()函數。這些函數除了返回狀態變量外,不做其他事情。請看下面來自 OpenZeppelin 的屏幕截圖。

來源:OpenZeppelin Github 代碼庫,ERC20.sol

如果你在 Remix 中查詢name()函數,并對 getter 進行調試,你會得到以下操作碼:

EVM 可以使用SSTORE操作碼寫入智能合約的存儲。SSTORE將一個字長保存到存儲空間。

使用內聯匯編,代碼將看起來像這樣:

function writeToStorageSlot(uint256 slotNb) public {string memory value = "All About Solidity";  assembly {        sstore(slotNb, value)    }}讓我們繼續之前的例子,即 OpenZeppelin 的 ERC20 代幣。如果我們部署 ERC20 代幣合約并使用 Remix 調試constructor,我們將得到以下操作代碼:

聲音 | 中國科學院院士王小云:密碼技術將深入融合5G、區塊鏈、人工智能等數字經濟領域:據中國國際貿易促進委員會四川省委員會官網消息,7月29日,第四屆中國網絡與信息安全大會在成都隆重召開。中國科學院院士王小云在題為《密碼技術與數字經濟高質量發展》的報告中指出,目前我國及世界已經進入到大數據應用和數字經濟高速發展的新時期,但是信息的惡意獲取、篡改、偽造和濫用,使得數字經濟的安全問題日趨嚴重。而密碼技術作為保障數字經濟高質量發展的一個重要技術手段,將深入融合5G、區塊鏈、人工智能、衛星性、物聯網、智慧城市等眾多數字經濟領域,助推智慧社會高速發展。[2019/7/31]

在 Remix 上試試,在部署 ERC20 代幣后調試交易。

這條推文很好地描述了操作碼SSTORE在 geth 客戶端的作用。

我們可以從 geth 客戶端的源代碼中看到,SSTORE從棧中彈出兩個值,棧頂第一個loc是存儲位置,棧頂第二個val是存儲中的值。

我們還可以看到,這兩個值在通過interpreter.evm.StateDB.SetState(...)寫入合約存儲時,都將從棧中取出的兩個項目轉換為bytes32值。

因此,我們可以直接從 geth 客戶端的源代碼中看到我們在存儲布局一節中的解釋:智能合約存儲將 bytes32 的 key 映射為 bytes32 的值,因此在 EVM 的底層下,所有東西都被當作 bytes32 的字長。

這里還有一張最后的圖,來自該推文的同一作者,詳細解釋了SSTORE操作碼的流程。

源于 faheel from Twitter.

storage關鍵字可以用于作為參數給函數傳遞復雜的變量。但這是如何實現的呢?

當storage在一個函數參數中被指定時,這意味著傳遞給函數的參數必須是一個狀態變量。

讓我們使用一個非常簡單的例子,仍然繼續使用 OpenZeppelin 庫。這也將幫助我們更好地理解其包中的合約和庫的一部分。

OpenZeppelin 提供了一個Timers庫,可以用來建立和處理 Solidity 合約中的定時器和時間點。看看下面的函數setDeadline(...)和reset(...)及其參數。

來源:OpenZeppelin Github 資源庫中的 Timer.sol

這兩個函數只接受存儲指針。這意味著什么呢?

讓我們創建一個 TimeWatch 合約來了解一下!

如果你嘗試在 Remix 上編譯這個合約,Solidity 編譯器應該抱怨以下錯誤:

調試存儲指針錯誤

這個錯誤是有道理的。來自Timers庫的setDeadline(..)函數只接受存儲指針。這意味著該函數參數需要是:

直接的狀態變量

或者對狀態變量的引用(另一個存儲引用,或者我喜歡稱之為存儲指針)。

然后讓我們重寫 TimeWatch,使其工作。我們還可以添加一個復位按鈕來使其工作:

我們已經看到了一個關于函數參數使用存儲指針的基本例子。讓我們通過一個更復雜的例子來深入了解函數參數的存儲指針。

當一個函數的參數是一個 "存儲"引用時,該函數可以直接接受一個狀態變量或對一個狀態變量的引用。

讓我們繼續TimeWatch的例子。使用Timers庫來建立一個比賽合約。使用合約可以減少對比賽組織者或任何可能不信任的第三方欺騙計時器和規則的信任程度。

下面是一個原型。該合約通過映射來跟蹤參與比賽的選手和他們的時間。請注意下面的startRacerTime(...)函數:

編譯可以通過,因為racerTimer指向racers的映射中的某個條目(合約存儲)。因此,由于這個變量是對合約存儲的引用,Timers庫中的setDeadline(...)函數將接受它作為一個有效的函數參數。

當變量為基本類型時,將存儲變量賦值給局部變量(在函數體中定義的)總是復制。

然而,對于復雜或動態類型,規則有所不同。,如果你不希望被克隆,你可以將關鍵字storage傳遞給一個值。

動態 | 區塊鏈等技術已經在平安銀行多項業務中深入運用:據人民網消息,據統計,平安集團每年都拿出營收的1%來投入科研,基于這樣的科技優勢,目前,互聯網、大數據、區塊鏈、人工智能、物聯網等前沿技術,在平安銀行的現金管理、互聯網支付結算、電子政務、貿易融資等產品和業務中都已有深入運用。此外,區塊鏈的應用降低了銀行的管理和運營成本和提高了風險控制能力。以平安銀行的供應鏈應收賬款服務平臺“SAS”為例,該平臺通過區塊鏈技術確認交易的真實性,從而給核心企業上游的中小企業發放貸款。[2018/11/6]

我們將這些變量描述為存儲指針或存儲引用類型的局部變量。

在一個函數中,任何存儲引用的變量總是指的是在合約的存儲上預先分配的一塊數據。換句話說,一個存儲引用總是指的是一個狀態變量。

讓我們看看一個非常流行的智能合約治理協議 Compound 的 Solidity 代碼,它被作為許多其他治理協議的基礎。

智能合約 "GovernorAlpha "在構建治理協議方面具有重要影響。這個合約不僅被用作 Compound,而且還被用作Uniswap或Indexed Finance的基礎治理。

讓我們來看看 GovernorAlpha的一個核心功能。函數propose(...)就像它的名字一樣,可以創建一個新的提議(例如:改變一個cToken的利率)。如果你看下面,你會看到我們之前解釋的兩個例子:

在第 153 行中,局部變量proposalId被分配到狀態變量proposalCount的值。由于這個局部變量是基本類型的(一個uint),這個值被從合約存儲(從狀態變量proposalCount)復制/克隆到局部變量(在堆棧上)。對本地變量的任何改變都不會傳播到合約存儲中。

在 Compound 中,這一行被用來在本地保存新的提案 ID(通過增加proposalCount第 152 行產生)。這也節省了一些 Gas。請看第 154 和 157 行。如果變量不是 proposalId,而是 proposalCount(實際的狀態變量),這將讀取兩次合約存儲。

第 154 行:使用新的proposalId,創建一個newProposal。由于newProposal變量是一個結構體(復雜類型),我們必須指定之后 EVM 操作和編輯這個變量時操作的數據位置,這里使用一個storage(存儲)引用。

是什么意思呢?newProposal指向合約存儲中的某個地方。

它指的是合約存儲中的哪個地方?它指的是 "proposals "映射中的一個 "Proposal"。

哪個 Proposal?該 Proposal 是由映射中的proposalId所引用。

那么這個storage關鍵字意味著什么?它意味著對newProposal變量的每一次修改都會導致向合約存儲區寫入數據。你可以看到從第 157 行開始,新提案的所有細節都通過Proposal結構成員一個接一個地寫入。每一行都寫到了合約存儲區。

一旦函數被執行,新的 Proposal(提案)將被保存在合約存儲中,并且這些變化將持續存在。

看一下下面的例子,類似的治理主題。它詳細說明了從存儲中復制 vs 使用存儲引用時使用的 EVM 操作碼。

第一個函數getVotesCount()從堆棧中復制值,然后返回它。我們可以看到,這個值是通過SLOAD從存儲空間加載到堆棧的。對變量currentVotesCount所做的任何改變都不會被傳回存儲空間。

相反的第二個例子包含一個storage的引用,給 Vote結構中的成員 hasVoted賦值,存儲就會被更新,我們可以通過操作碼 SSTORE看到。

這個例子顯示,給storage引用變量賦值會更新合約存儲。EVM 將此理解為執行SSTORE指令。

相反,如前面的例子所示,從存儲變量中賦值的基本類型變量并不會創建引用,而只是將值從存儲中復制到堆棧中。EVM 將此理解為一個可以簡單地執行SLOAD指令。

你可以通過指定一個存儲槽和存儲偏移量,在內聯匯編中讀寫合約存儲。

我們之前看到,存儲中的一些變量不一定占據一個完整的存儲槽,但有時會被擠在一起。

我們還看到,SLOAD作為一個操作碼只接受存儲槽號作為參數,并返回存儲在這個槽下的完整的bytes32值。

但是,如何讀取一個擠在同一個存儲槽中的狀態變量?

以下面的合約為例。

contract Storage {uint64 a;    uint64 b;    uint128 c;}Solidity 文檔解釋如下:

對于本地存儲變量或狀態變量,使用一個 Yul 標識符是不夠的,因為它們不一定占據一個完整的存儲槽。

因此,它們的 "地址 "是由一個槽和該槽內的一個字節偏移量組成。

因此,一個變量的 "地址"由兩個部分組成。

槽號:變量所在的位置。

變量開始的字節偏移量(在該槽內)。

讓我們繼續看一些基本的匯編代碼,以便更好地理解。看看下面的合約和它的函數:

通過 Remix 運行這兩個函數可以得到以下輸出:

要檢索變量c所指向的槽,使用c.slot,要檢索字節偏移量,使用c.offset。僅使用c本身會導致錯誤:

function ReadVariableC() public view returns (uint64 value) {assembly {        value := sload(c)    }}上面的代碼將不會被編譯,并會出現以下錯誤

有一點也要提到的是,在內聯匯編中,你不能向存儲變量的.slot或.offset賦值:

function doesNotCompile() public {    assembly {        a.slot := 8        a.offset := 9    }}solc 編譯器的錯誤報告(截圖取自 Remix)

Yul 中存儲指針的偏移量的值是多少呢?在函數體中,一些變量可以是存儲指針/存儲引用。例如,這包括struct、array和mapping。對于這樣的變量,在 Yul 中.offset總是為零,因為這樣的變量總是占據了一個完整的存儲槽,不能與其他變量緊密地擠在一起存儲。

智能合約的存儲空間,無論是初始化還是修改里面的數據,都要付出高昂的代價。雖然從合約存儲中讀取數據是免費的,但如果這些讀取操作是改變狀態的交易的一部分,我們還是應該考慮到向智能合約的存儲讀取時的 Gas 成本。

由于對存儲的操作有很高的 Gas 成本,Solidity 文檔中指出了一個重要的考慮。

應該將你存儲在持久性存儲中的內容減少到合約運行所需的程度。

建議盡可能地將某些數據存儲在合約存儲之外,以減少相關的 Gas 成本。

深入以太坊 , Part 2

Solidity 文檔:狀態變量在儲存中的布局 g

openzeppelin-contracts/StorageSlot.sol

Solidity 中的數據表示

了解以太坊智能合約的存儲

解剖智能合約的結構--功能、數據和變量

譯文出自:登鏈翻譯計劃 譯者:翻譯小組 校對:Tiny 熊

本翻譯由 Duet Protocol 贊助支持。

原文鏈接: https://betterprogramming.pub/all-about-solidity-data-locations-part-i-storage-e50604bfc1ad

登鏈翻譯計劃: https://github.com/lbc-team/Pioneer

翻譯小組: https://learnblockchain.cn/people/412

Tiny 熊: https://learnblockchain.cn/people/15

深入Solidity數據存儲位置: https://learnblockchain.cn/article/4864

OpenZeppelin: https://docs.openzeppelin.com/

Compound: https://compound.finance/docs

OpenZeppelin在他們的深入 EVM 第二部分文章中: https://blog.openzeppelin.com/ethereum-in-depth-part-2-6339cf6bddb9/

在他的文章中,Steve Marx: https://programtheblockchain.com/posts/2018/03/09/understanding-ethereum-smart-contract-storage/

Solidity文檔: https://learnblockchain.cn/docs/solidity/internals/layout_in_storage.html

Pool: https://docs.aave.com/developers/core-contracts/pool

來源:Aave v3 Protocol, Pool.sol: https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/pool/Pool.sol

來源:Aave v3, PoolStorage.sol: https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/pool/PoolStorage.sol

來源:OpenZeppelin Github代碼庫,ERC20.sol: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol

在Remix上試試: https://remix.ethereum.org/?#code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC40OwoKaW1wb3J0ICJAb3BlbnplcHBlbGluL2NvbnRyYWN0c0A0LjcuMC90b2tlbi9FUkMyMC9FUkMyMC5zb2wiOwppbXBvcnQgIkBvcGVuemVwcGVsaW4vY29udHJhY3RzQDQuNy4wL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBNeVRva2VuIGlzIEVSQzIwLCBPd25hYmxlIHsKICAgIGNvbnN0cnVjdG9yKCkgRVJDMjAoIk15VG9rZW4iLCAiTVRLIikgewogICAgICAgIF9taW50KG1zZy5zZW5kZXIsIDEwMDAwICogMTAgKiogZGVjaW1hbHMoKSk7CiAgICB9CgogICAgZnVuY3Rpb24gbWludChhZGRyZXNzIHRvLCB1aW50MjU2IGFtb3VudCkgcHVibGljIG9ubHlPd25lciB7CiAgICAgICAgX21pbnQodG8sIGFtb3VudCk7CiAgICB9Cn0K&optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js

faheel from Twitter.: https://twitter.com/721Orbit/status/1511961744238948356?s=20&t=KDGCQ4OwQ47e2NACgQ8WWg

來源:OpenZeppelin Github資源庫中的Timer.sol: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Timers.sol

Uniswap: https://github.com/Uniswap/governance/blob/master/contracts/GovernorAlpha.sol

Indexed Finance: https://github.com/indexed-finance/governance/blob/master/contracts/governance/GovernorAlpha.sol

應該將你存儲在持久性存儲中的內容減少到合約運行所需的程度: https://learnblockchain.cn/docs/solidity/introduction-to-smart-contracts.html#index-10

深入以太坊 , Part 2: https://blog.openzeppelin.com/ethereum-in-depth-part-2-6339cf6bddb9/

Solidity 文檔:狀態變量在儲存中的布局g: https://learnblockchain.cn/docs/solidity/internals/layout_in_storage.html

openzeppelin-contracts/StorageSlot.sol: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/StorageSlot.sol

Solidity中的數據表示: https://ethdebug.github.io/solidity-279"     src="https://img.jinse.cn/5363788_image3.png"   >

白話區塊鏈

金色財經Maxwell

NFT中文社區

CoinDesk中文

達瓴智庫

去中心化金融社區

金色薦讀

肖颯lawyer

CT中文

ETH中文

ForesightNews

Beosin

Tags:BSPNBSSOLTORBSP價格NBS幣sol幣價格最新行情Berrystore

幣贏
NFT+共享經濟 企業數字化轉型新方向?_NFT:TAL

根據國家信息中心發布的《中國共享經濟發展報告2022》的定義,共享經濟指的是利用互聯網將分散資源進行優化配置,通過推動資產權屬、組織形態、就業模式和消費方式的創新.

1900/1/1 0:00:00
玩數字藏品圈 我目睹一場巨大泡沫_NFT:元宇宙數字虛擬人游戲

-1- nft(數字藏品)概念被炒熱的那一年,正是虛擬幣市場從風起云涌到妖魔亂舞的時候。新聞上說NBA某某球星以十幾萬美元的價格購買了一張頭像,看到這新聞的時候,我滿臉疑惑,只能感嘆一聲“美利堅.

1900/1/1 0:00:00
黃國平:數字人民幣發展的動因、機遇與挑戰_數字人:CBD

數字人民幣發展的動因是多方面多層次的,既有需求和供給方面的因素,也有金融監管和對沖私人貨幣無序發展方面的原因.

1900/1/1 0:00:00
Cosmos 2.0 淺析:比 2017 年的以太坊更成熟 備受各類基礎服務設施青睞_MOS:OSMO

Cosmos 是我見過的最完整的生態系統,對開發、合作、擴張和進化的進程讓我想起了 2017 年的以太坊,但它的成熟度更高.

1900/1/1 0:00:00
3分鐘了解 EIP 4337 (賬戶抽象)如何改善以太坊UX_以太坊:ETH

原文作者:biconomy研究員Nishil 以太坊的主要缺點之一是用戶體驗復雜,讓我們了解一下由nethermind以及opengsn 研究者提出的EIP 4337?是如何嘗試用賬戶.

1900/1/1 0:00:00
金色觀察丨加密KOL們這樣看FTX暴雷_FTX:ALA

過去48小時,一場因信任導致的“加密雷曼危機”正式爆發,整個加密貨幣行情受到影響,BTC 一度跌破 17000 美元,ETH也跌破 1300 美元,而處于漩渦最中心的FTT跌超90%,接近崩盤.

1900/1/1 0:00:00
ads