KryptoCamp — Day26 — solidity — 7

Galen-Ting
廢物到工程師的一大步
5 min readMar 13, 2022

經過了幾天 DAO 智能合約研究後,發現其實還是有很多語法是沒見過的,因此趕快再回來補足一下 soildity 的基礎寫法,否則常常要花很多時間研究某個語法的意義,會大幅降低看程式碼的效率,也詳細了解一下 solidity 的運作方式。

以下內容參考自 all in one solidity,想要獲得更詳細的資訊建議可以購買書籍。

傳址 (call by reference) 或是傳值 (call by value)?

關於兩者的區別可以參考這裡

變數型態的參數(bool, uint, bytes, addres)會是以傳值(Call by Value)傳入函數,而非變數型態像是我們之後會介紹到的資料結構(array, struct, mapping, string)們,則是傳址(Call by Reference)。

簡單可以記成只要是資料結構形式的資料都為 call by reference ,其他非資料結構較為單純的資料則為 call by value,這個特性是與 JavaScript 一致的。

Storage、Memory、Calldata 的區別

  • Storage 該資料會在區塊鏈上永遠存在,函數可以更改它或是回傳它,修改它需要付 gas。
  • Memory 該資料經過生命週期後就會消失,函數可以修改他也可以回傳他,修改他不需要付 gas 。
  • Calldata 一個唯讀的參數,可見性為 external 的函數會被預設為這個形式。函數不能修改他但是可以回傳他。

錯誤處理 require、assert、revert、try catch

  • require 檢查輸入值是否符合條件,會退回 gas,可以帶錯誤訊息。
  • assert 是檢查完全不應該在合約裡面出現的情況,不會退回 gas,可以帶錯誤訊息。
  • revert 直接拋出錯誤,可帶入錯誤訊息。
  • try/catch 用於確認外部執行函數和合約建立時的錯誤,可以利用類條件式選擇來排除錯誤情況。

Event

當一個 event 被 call 之後它的參數就會被置於區塊鏈之中。意思是你將可以在 Transaction Information 中看見你自己觸發的事件以及相關的回傳值,觸發 event 是要耗費 gas 的,不過會比 storage 便宜。

沒有 event 時 log 沒有任何回傳值:

回傳 event 後 log 多了許多關於 event 的資料:

前端的應用程式可以藉由 Ethereum 的 RPC interface 來訂閱這些 event,進而即時知道某個 function 的執行結果,並對此作出反應。

event 的 indexed 、data、topic

indexed

event SomeEvent(address _from indexed, address _to)

被標註為 indexed 的參數將可以讓前端更輕易的找到 ,標記 indexed 的 event 參數將消耗更多 gas ,僅有當你想要某個 event 的參數可以被找到時才需要標記 indexed

一個 event 最多只能有三個 indexed 的參數。

data

當一個參數沒有 indexed 屬性時, 他們會被 ABI-encodedlogdata 部分。

topic

如果一個參數有 indexed 屬性,他們會被包含在 topics 裡面。

這段程式碼的 translation 結果的 log:

這段程式碼的 translation 結果的 log:

可以看到有標記 indexed 的交易的 topics 的部分比較多個,而把相對應的值 hash 解碼後就會得到 1 和 2,可以得知標記 indexed 的值會被寫入 topics 內,沒有標記的則被記錄在 data 裡面。不管是哪個都是實實在在寫在鏈上的資料,後續都可以針對此筆交易追蹤到該筆紀錄的 event 回傳值的。

anonymous (匿名) 事件

event AnonymousEvent (uint _a) anonymous;

在一個非匿名的 event 當中, topics[0] 會是 event 自己的 hash 值,但如果標注為匿名事件,則 topic[0] 將不再是 event 自己的 hash 值,同時前端也無法得知 event 的 name 是什麼,也就將無法監聽到它,想要得知這個 hash 值唯一的辦法就是取得 ABI,如果項目沒有開源或是你不是持有者那麼你將無法監聽匿名事件。

這段程式碼的 translation 結果的 log:

topics[0] 消失了,前端無從得知 name 是什麼,無法進行監聽。

--

--

Galen-Ting
廢物到工程師的一大步

學程式不無聊,無聊就不學程式,皮皮的學習好過死死的學習。