📜 [專欄新文章] 智能合約 Storage 注意事項
✍️ Jun-You Liu
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
前言
前幾天在逛 Medium 的文章,意外看到這篇在討論如何利用 Ethereum Smart Contract Storage 實際行為跟預想的落差來攻擊。由於這個漏洞相較溢位等其他漏洞比較不會被注意到,決定記錄起來,如果大家未來在使用 Storage 時可以多注意一下。
Code
先來看看以下這個 contract:
這是一個幫助使用者 hodl Ether 的 smart contract。當使用者將 Ether 放進這個 contract 中,會被強制鎖定一段時間之後才能取出,在這段時間中使用者毋須擔心自己會受不了誘惑把錢拿去亂投資 ICO 導致血本無歸 (?)。
攻擊
問題出在 PayIn() 這個函式。當使用者想要存一些 Ether 進去,他會送出一筆存款的交易給這份 smart contract,但這筆存款交易其實不會記錄在使用者的 balance,而是會記錄到這份 smart contract owner 的 balance 中。
為什麼會這樣呢?
讓我們仔細看看 payIn() 在幹嘛,以下是他裡面在做的事:
HoldRecord newRecord;newRecord.amount += msg.value;newRecord.unlockTime = now + holdTime;balance[msg.sender] = newRecord;
問題出在第一行,在 EVM (Ethereum Virtual Machine) 中,當沒有指定 storage/memory 時,預設會使用 storage,所以 newRecord 會是 storage 的 pointer。而 newRecord 又沒有給定初始值,那麼 newRecord 就會指向 address(0),也就是這份 contract 最一開始的地方。詳細行為可以參照 Solidity 的文件。
那麼本來 newRecord 是希望指到 HoldRecord 的 struct,藉此存取
uint amount;uint unlockTime;
其實指到的是 contract 一開始的
uint ownerAmount;uint numberOfPayouts;
所以在 payIn() 的newRecord.amount += msg.value; 其實是加到 ownerAmount 中,也當然 numberOfPayouts 也被覆蓋掉了。然後 owner 就可以用 ownerWithdrawal() 來將剛剛使用者存入的錢偷走。
反攻擊
但這邊其實有個反攻擊的方法。在 payIn() 的第四行
balance[msg.sender] = newRecord;
如前面所說,newRecord 是指到 ownerAmount,所以這行其實是把 ownerAmount 指定給 msg.sender,使用者可以用一個很短的鎖定時間存一筆很小的 Ether,然後在到期後馬上使用 withdrawal() 將 owner 的所有錢提領出來。
結論
這個例子是要舉出在 smart contract 中 storage 預設行為的危險性。其實只要維持一個原則就可以避免這個問題。
養成明確定義使用 storage 還是 memory 的好習慣
一般來說,指定 storage 時就直接給初始值;而在 function 裡面需要用到的暫存器都用 memory,除非想要直接修改鏈上的值。現在 compiler 都會很聰明的提醒開發者要定義 storage 還是 memory,而當 storage pointer 沒有初始值時也會提醒開發者。
然而如果不是開發者只是使用者,其實在看 code 的時候很容易會忽略掉這部分的漏洞,所以在有更安全的選項出來前,就要多加注意了。
在此附上我的更改版,一批很純的Hodl (?)
如果覺得內容哪裡有誤,歡迎留言討論交流,然後別忘了分享給你所有很愛用預設參數的朋友 (?
智能合約 Storage 注意事項 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
同時也有1部Youtube影片,追蹤數超過12萬的網紅prasertcbs,也在其Youtube影片中提到,สาธิตการเขียนฟังก์ชันเพื่อแยกราคารวมของสินค้าออกเป็นราคาและภาษีมูลค่าเพิ่ม โดยแสดงให้เห็นถึงวิธีการเขียนฟังก์ชันโดยใช้ 1) pass by pointer 2) pass by r...
「struct pointer」的推薦目錄:
- 關於struct pointer 在 Taipei Ethereum Meetup Facebook 的最讚貼文
- 關於struct pointer 在 prasertcbs Youtube 的最佳解答
- 關於struct pointer 在 Segmentation fault: Struct Pointer - Stack Overflow 的評價
- 關於struct pointer 在 Pointer to Structure Variable - YouTube 的評價
- 關於struct pointer 在 Frida: How to read a struct or a struct pointer or a ... - GitHub Gist 的評價
- 關於struct pointer 在 Golang struct 教學與範例 的評價
- 關於struct pointer 在 struct - How to apply IDA structure to a pointer of a structure 的評價
struct pointer 在 prasertcbs Youtube 的最佳解答
สาธิตการเขียนฟังก์ชันเพื่อแยกราคารวมของสินค้าออกเป็นราคาและภาษีมูลค่าเพิ่ม โดยแสดงให้เห็นถึงวิธีการเขียนฟังก์ชันโดยใช้
1) pass by pointer
2) pass by reference
3) สร้าง struct โดยมี price และ vat เป็น member แล้วเขียนฟังก์ชันเพื่อให้ส่งค่ากลับมาเป็น struct
ดาวน์โหลดไฟล์ตัวอย่างได้ที่ ► https://goo.gl/qSfHSn
เชิญสมัครเป็นสมาชิกของช่องนี้ได้ที่ ► https://www.youtube.com/subscription_center?add_user=prasertcbs
playlist สอนภาษา C++ ► https://www.youtube.com/playlist?list=PLoTScYm9O0GEfZwqM2KyCBcPTVsc6cU_i
playlist สอนภาษา C เบื้องต้น ► https://www.youtube.com/playlist?list=PLoTScYm9O0GHHgz0S1tSyIl7vkG0y105z
playlist สอนภาษา C# ► https://www.youtube.com/playlist?list=PLoTScYm9O0GE4trr-XPozJRwaY7V9hx8K
playlist สอนภาษา Java ► https://www.youtube.com/playlist?list=PLoTScYm9O0GF26yW0zVc2rzjkygafsILN
playlist สอนภาษา Python ► https://www.youtube.com/playlist?list=PLoTScYm9O0GH4YQs9t4tf2RIYolHt_YwW
playlist สอนภาษาไพธอน Python OOP ► https://www.youtube.com/playlist?list=PLoTScYm9O0GEIZzlTKPUiOqkewkWmwadW
playlist สอน Python 3 GUI ► https://www.youtube.com/playlist?list=PLoTScYm9O0GFB1Y3cCmb9aPD5xRB1T11y
playlist สอนภาษา PHP เบื้องต้น ► https://www.youtube.com/playlist?list=PLoTScYm9O0GH_6LARFxozL_viEsXV2wgO
playlist สอนภาษา R เบื้องต้น ► https://www.youtube.com/playlist?list=PLoTScYm9O0GF6qjrRuZFSHdnBXD2KVICp
struct pointer 在 Pointer to Structure Variable - YouTube 的推薦與評價
C Programming: Pointer to Structure Variable in C Programming.Topics discussed:1) Accessing the members of structure variable using a ... ... <看更多>
struct pointer 在 Frida: How to read a struct or a struct pointer or a ... - GitHub Gist 的推薦與評價
Frida: How to read a struct or a struct pointer or a pointer of a struct pointer? - frida-struct-pointer-pointer.js. ... <看更多>
struct pointer 在 Segmentation fault: Struct Pointer - Stack Overflow 的推薦與評價
... <看更多>