Solidity
為什麼我的事件沒有發出正確的值?
在使用 Truffle 測試合約時,我發現事件發出的變數與傳遞給事件發出的值不匹配。為什麼事件不返回傳遞給它的確切值?
例如:
event ExampleEvent(string indexed myString); function eventTest() public { string memory strTest = "Hello, world!"; emit ExampleEvent(strTest); }
當
eventTest()
被呼叫時,事件會發出0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4
,而不是"Hello, world!"
。為什麼會這樣?
原因是因為發出的是索引動態變數,而不是靜態變數。Solidity 在索引動態變數時儲存 keccak256-hash,因此您得到的字元串
0xb6e...
是字元串“Hello, world!”的 keccack256-hash。更多資訊可以在 Solidity 文件中查看。有兩種方法可以處理此問題:
1)
indexed
從事件中刪除關鍵字。當一個值沒有被索引時,它返回真值,即使它是一個動態變數。如果這樣做,您的程式碼將如下所示:event ExampleEvent(string myString); function eventTest() public { string memory strTest = "Hello, world!"; emit ExampleEvent(strTest); }
在這種情況下,事件發射輸出將是
"Hello, world!"
。
- 通過獲取預期輸出的 keccack256-hash 處理鏈下事件發射。您可以通過使用 util, 來做到這一點
web3.utils.keccak256("Hello, world!")
。任何一種情況都是可以接受的,並且兩者都有其權衡。來自Solidity 文件:
對於動態長度類型,應用程序開發人員面臨在快速搜尋預定值(如果參數被索引)和任意值的易讀性(要求參數不被索引)之間的權衡。開發人員可以通過定義具有兩個參數的事件來克服這種折衷並實現高效搜尋和任意易讀性 - 一個有索引,一個沒有 - 旨在保持相同的值。