📜 [專欄新文章] Solidity Data Collision
✍️ Wias Liaw
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
這是一篇關於 Proxy Contract 和 delegatecall 的注意事項。
Delegatecall
當 A 合約對 B 合約執行 delegatecall 時,B 合約的函式會被執行,但是對 storage 的操作都會作用在 A 合約上。舉例如下:
但是假如多加了一個 other 欄位在 _value 之前,執行合約之後反而是 other 欄位被更改了。
Storage Layout
了解上面的合約之前要先了解 Solidity 怎麼儲存 State Variables。Solidity Storage 以 Slot 為單位,每個 Slot 可以儲存 32 bytes 的資訊,一個 Contract 擁有 2**256 個 Slot。上述可以寫成一個映射關係 mapping(uint256 => bytes32) slots。
Solidity 會從 Slot Index 為零開始分配給 State Variable。
除了 mapping 和 dynamically-sized array,其他的 State Variable 會從 index 為零的 slot 開始被分配。
沒有宣告確切大小的 Array 會以 Slot Index 計算出一個雜湊值並將其作為 Slot Index。透過計算 keccak256(slot) 可以得知 _arr[0] 被存在哪裡,如果要取得 _arr[1] 則將計算出來的雜湊加上 Array 的 index 即可。
Mapping 則是以 Slot Index 和 Key 計算出一個雜湊值並將其作為 Slot Index。透過計算 keccak256(key, slot) 可以得到 mapping(key => value) 被存在哪。
Storage Collision
回到 DelegateExample_v2 的合約,對 B 來說, add 最後儲存加法的 Slot Index 為零,所以使用 A 的 Storage 執行 B 的函式結果自然會儲存在 A 的 other 裡,其 Slot Index 為 0。
這個問題也發生在 Proxy Contract,Layout 如下,當有需要更改 _owner 的操作,就會順帶把 _implementation 也更改了。
|Proxy |Implementation ||--------------------------|-------------------------||address _implementation |address _owner | <= collision|... |mapping _balances || |uint256 _supply || |... |
OpenZeppelin 處理的手法也很簡單,就是將 _implementation 換地方擺。以特定字串的雜湊值作為 Slot Index,儲存 Implementation 的地址。
|Proxy |Implementation ||--------------------------|-------------------------||... |address _owner ||... |mapping _balances ||... |uint256 _supply ||... |... ||address _implementation | | <= specified|... | |
openzeppelin-contracts/ERC1967Upgrade.sol at 83644fdb6a9f75a652d2fe2d96cb26073a14f6f8 · OpenZeppelin/openzeppelin-contracts
hardhat-storage-layout
如何知道合約的 Storage Layout 呢?這邊推薦一個 Hardhat Plugin,按照文件就能得到合約的 Storage Layout。
Ethereum development environment for professionals by Nomic Labs
Reference
Understanding Ethereum Smart Contract Storage
Collisions of Solidity Storage Layouts
Proxy Upgrade Pattern - OpenZeppelin Docs
Solidity Data Collision was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
「array key value」的推薦目錄:
- 關於array key value 在 Taipei Ethereum Meetup Facebook 的最佳貼文
- 關於array key value 在 Milton Goh Blog and Sermon Notes Facebook 的最佳解答
- 關於array key value 在 Taipei Ethereum Meetup Facebook 的最讚貼文
- 關於array key value 在 使用Array.map、Object.values 和Object.keys 處理一連串的資料 的評價
- 關於array key value 在 Best way to store a key=>value array in JavaScript? - Stack ... 的評價
- 關於array key value 在 JavaScript ES6 Features: Creating Key/Value Pairs with Maps 的評價
- 關於array key value 在 Best way to print key-value pairs: table, array or matrix? - TeX ... 的評價
- 關於array key value 在 How To Use Maps Effectively - JavaScript Tutorial 的評價
- 關於array key value 在 PHP - pass array(key-value pair) as an argument instead of ... 的評價
array key value 在 Milton Goh Blog and Sermon Notes Facebook 的最佳解答
Ever wondered why Satanic rituals are often depicted to require a sacrifice of blood and even semen? Demons don’t have the power to create something out of nothing. Magic takes from an existing source to transform it for a different purpose.
The Bible says that the life of the flesh is in the blood. Practitioners of the ‘deep things of Satan’ can use the life force (in Hebrew it is called “chayil”) that is in fresh blood and semen as a source of power to alter something in the natural world.
The blood of Jesus is one of your spiritual weapons which is overwhelmingly effective against Satan’s temptations, deceptions, distractions and intimidations?
Besides having a revelation of the value of Jesus’ blood, in my new Bible Study series “Silencing the Serpent”, you will also learn about other spiritual weapons in your array, such as the anointing oil, the tithe, the Lord’s Supper, the word of your testimony, praying in the spirit, the rhema word of God, and much more, not forgetting the whole armor of God.
We war against evil spirits, not against flesh and blood. God has given us powerful spiritual weapons since carnal weapons are useless against the Satanic forces. It is key to learn how to use them—they were given to you because you need them.
To receive the series and other rewards like my eBooks and daily devotionals by email, just become a “God Every Morning” tier or above patron on Patreon: http://Patreon.com/miltongohblog
Thank you for being a partner in our ministry, and the seeds you sow shall surely be multiplied back as an abundant harvest of provision for you!
#SilencingtheSerpent #PatreonRewards
array key value 在 Taipei Ethereum Meetup Facebook 的最讚貼文
📜 [專欄新文章] Solidity Weekly #9
✍️ mingderwang
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
什麼時候用 storage,什麼時候該用 memory?
其實這副標題,有可能又會誤導大家如何寫 solidity。簡單講它們是完全不一樣的東西。所以應該會用在不同的地方,做不同的事才對。
先簡單說明它們的原理:
storage 就是 smart contract 正常存放狀態 (state) 的地方,而這些地方就是用來呈現在區塊鏈裡狀態值的變更。所以一般來說,全域變數就會用 storage 來儲存。
它以 32 bytes 為單位類似 hash 的方式做 key/value 的查詢。所以即時key 1 跟 key 1000,所用的空間跟 key 1 跟 key 2 一樣。(所花的 gas 也應該相同)
另外,通常方程式帶入的變數或回傳值,會以 memory 方式表示,或有些 compiler 會用 stack 來儲存 (不花 gas)。若帶入變數內容來自於一個全域變數,它會複製一份 storage 裡的資料到 memory 做修改。但如果你在方程式帶入的變數前用 storage 保留字來描述,它就變成 passed by reference,把 storage 的位置直接傳給該方程式,因此所有的變動,都會直接改到 storage 裡的值。
而一般在方程式裡的本域變數 (local variables),也預設用 storage 來處理,除非你故意用 memory 保留字來定義它。但用 memory 來處理陣列會有點困難。不像 storage 的陣列,可以用 push。(如下錯誤範例)
function createRoom() public{ address[] memory adr; adr.push(msg.sender); // compiler error ...}
但為了節省 gas 的消耗,在方程式裡本域變數改用 memory 也是很常見的事。
links 分享;
Ethereum Solidity: Memory vs Storage & How to initialize an array inside a struct — (Georgios Konstantopoulos)
Solidity Introduction — (A very good Solidity tutorial from BitDegree)
New Features of Solidity 0.5.0 — (@Christian Reitwiessner)
Solidity Weekly #9 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
array key value 在 JavaScript ES6 Features: Creating Key/Value Pairs with Maps 的推薦與評價

JavaScript has always allowed you to work with key/value pairs through objects. The Maps collection made ... ... <看更多>
array key value 在 使用Array.map、Object.values 和Object.keys 處理一連串的資料 的推薦與評價
使用Array.map、Object.values 和Object.keys 處理「物件中有物件」和「陣列中有物件」的情況。 ... <看更多>