上一篇提到了函式的作用域與合約的繼承,相信各位應該對 Solidity 有一定程度的了解了,這一篇將會介紹 Solidity 中蠻特殊的 event log ,讓我們繼續看下去~
簡單來說就是日誌,很多場景都會有 log 的應用,比如說伺服器的事件等,都會寫入 log 以便追查發生的事件,最典型的例子就是伺服器掛掉的時候要去看 程式寫得多糟 Error 發生在什麼地方。
在以太坊中也有提供這樣的功能,將 log 紀錄寫在 交易裡面 ,只不過 log 紀錄需要等到 交易處理完後 才能夠查詢到。這邊需要釐清一個觀念,當交易產生時,交易的相關資料就會建立,但這時候只有記錄 交易本身的相關資訊 ,像是: hash
、 input
等;當交易完成後,也就是被打包成區塊加到鏈中時,會產生所謂的 收據(Receipt) ,是用來記錄交易的執行結果,而我們的 log 就是記錄在這裡!
也許有人會思考說:智能合約本身就可以記錄東西了,為什麼還有 log 的功能?直接把要記錄的事件資料用個變數裝起來就好啦~
沒錯!寫在變數裡是一個方法,但年輕人終究還是年輕人,我們需要了解改變合約中的狀態變數需要花費的成本是很高的,如果都用這樣的方法儲存的話,其實開銷是很大的!如果只是要 儲存不必被更動的資料 ,如:交易明細等,就可以使用 log 的功能,因為 log 比改變狀態變數的成本低許,也因為 log 紀錄本身就是用來 記錄 的, 無法更改 log 中的資訊 ,所以適合儲存不被更動的資料,也可以當作回傳資料的一種方式。不過需要特別注意 log 有一個限制,就是 無法透過合約存取資料 。
在 Solidity 中, log 的撰寫方式簡單來說就是 事件的觸發 ,但必須要先定義事件的格式。下方的範例定義了 sign 事件,可以填入 string
與 uint
,在獲取 log 資訊時,將會用 name 與 money 作為資料的 key:
event sign(
string name,
uint money
);
定義完事件之後,就要來觸發事件,使用方法非常簡單,用 emit
來發送即可:
function signEvent() public {
emit sign("HAO", 10000);
}
這樣就完成了!很簡單吧!不過還是需要再提醒一次,如果要取得 log 的資料, 只能透過外部取得 。在開發需要高互動的 DApp 時, event log 可以說是十分常用的功能喔!後面的篇章會再教各位怎麼在 DApp 中取得 log 資訊!
了解在以太坊中 log 紀錄的存放時機、成本較低等特性,並透過 Solidity 撰寫事件來觸發記錄 log ,需要注意 log 只能從外部讀取!