Solidity 事件對於智能合約開發人員來說是不可或缺的,它允許測試智能合約的特定變量、以自動化方式更改前端等等。一般來說,知道如何在Solidity 中使用事件會使智能合約開髮變得更加容易。
在這篇文章中,我們將研究 以太坊虛擬機 (EVM) 從智能合約開發人員的角度來看,涵蓋日誌記錄和事件的用途、索引事件以及如何在Hardhat 和Brownie 中使用日誌記錄和事件。
EVM 是以太坊和許多其他區塊鏈的動力。 EVM 有一個 日誌記錄 用於將數據“寫入”到智能合約之外的結構的功能。一個這樣重要的數據是 Solidity 事件. 事件使我們能夠以一種更可搜索和更高效的方式在區塊鏈上“打印”信息,而不僅僅是保存到我們智能合約中的公共存儲變量。
日誌是區塊鏈上一種特殊的數據結構。他們 智能合約無法訪問,並提供有關交易和區塊中發生的事情的信息。正是它們無法使用智能合約,這使得它們的排放成本更低。
您還可以在此處觀看有關事件和登錄Solidity 的視頻:
那麼,什麼是事件?
事件使我們能夠輕鬆查詢塊和交易中發生的“東西”。如果你運行一個區塊鏈節點,你可以通過以下方式“監聽”某些事件 訂閱 給他們。事實上,這是如何 鍊鍊網絡 工作原理:網絡訂閱特定地址的特定事件,並根據發出的事件的內容從現實世界返回數據。
什麼是事件?
現在,如果您不是Chainlink 或以太坊節點運營商,您可能會問這對您有何影響。通過Solidity 事件,您可以:
- 針對特定變量測試您的智能合約;
- 索引變量以重建存儲狀態;
- 監聽事件以改變前端;
- 創建 子圖 用於更快地讀取數據;
還有很多其他的東西。事件有各種各樣的用例,可以挽救您作為工程師的生命。事實上,事件是Chainlink 節點如何工作的核心部分之一! Chainlink 節點監聽數據請求和外部計算事件,這就是它們知道如何響應。
事件是什麼樣的?
這就是在Solidity 中定義事件的樣子:
javascript event storedNumber( uint256 indexed oldNumber, uint256 indexed newNumber, uint256 addedNumber, address sender );
您可以將其視為一種新的特殊類型。我們創建了一個名為“storedNumber”的事件“類型”。事件名稱稱為“storedNumber”,可以包含多個變量。在這一事件中有兩種參數:索引和非索引。索引參數也稱為“主題”,是事件中的可搜索參數。我們很快就會更多地討論這些。
然後我們可以發出這樣的事件:
javascript uint256 favoriteNumber; function store(uint256 _favoriteNumber) public { emit storedNumber( favoriteNumber, _favoriteNumber, _favoriteNumber + favoriteNumber, msg.sender ); favoriteNumber = _favoriteNumber; }
這是一個完整的示例合同:
javascript // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; contract SimpleStorage { uint256 favoriteNumber; event storedNumber( uint256 indexed oldNumber, uint256 indexed newNumber, uint256 addedNumber, address sender ); function store(uint256 _favoriteNumber) public { emit storedNumber( favoriteNumber, _favoriteNumber, _favoriteNumber + favoriteNumber, msg.sender ); favoriteNumber = _favoriteNumber; } function retrieve() public view returns (uint256) { return favoriteNumber; } }
現在,無論何時我們在這個例子中調用`store` 函數,它都會發出一個storedNumber 類型的事件。讓我們看一個示例交易,該交易以“1”的輸入調用“store”函數。我們可以看到交易 科萬·埃瑟斯坎.
滾動到交易的“日誌”部分,我們會看到下圖:
事件分解如下:
地址: 發出事件的合約或帳戶的地址。
話題: 事件的索引參數。
數據: 這 ABI 編碼 或“散列”事件的非索引參數。由於我們知道合約的ABI(因為我們在Etherscan 上驗證了合約),我們可以在“Dec”或“decoded”模式下查看它,或者以其原始“hex”、“Hexidecimal”或“Encoded”模式查看。如果我們沒有驗證合同,我們將無法看到解碼後的版本。
您可以在 Solidity 文檔. “日誌”和“事件”經常互換使用,因為作為智能合約開發人員,我們通常只關心記錄的“事件”。但是,從技術上講,日誌還包含“blockhash”、“address”以及通過調用返回的所有其他內容 `eth_getLogs` 到您的區塊鏈節點。您還可以閱讀更多關於 布隆過濾器,這就是這些事件很容易查詢的方式。
安全帽活動
現在我們已經了解了什麼是事件,讓我們學習如何在安全帽中訪問和使用它們。您可以克隆以下存儲庫並繼續操作:
git clone https://github.com/PatrickAlphaC/hardhat-events-logs cd hardhat-events-logs
你需要按照`README.md`來獲取 先決條件,其中包括Node、Yarn 和Git。
如果您按照“README.md”進行操作,您將能夠:
- 部署智能合約;
- 創建一個發出事件的事務;
- 查看這些事件的上下文。
如果您在此過程中遇到問題,請在 Github 倉庫!我們可以通過檢查`transactionReceipt` 對象的日誌屬性來查看日誌。
console.log(transactionReceipt.events[0].args.oldNumber.toString())
布朗尼的活動
布朗尼中的事件幾乎相同,因為合同完全相同。
您可以克隆以下存儲庫並繼續操作:
git clone https://github.com/PatrickAlphaC/brownie-events-logs cd brownie-events-logs
你需要按照`README.md`來獲取 先決條件,其中包括Node、Python、eth-brownie 和Git。
如果您按照“README.md”進行操作,您將能夠:
- 部署智能合約;
- 創建一個發出事件的事務;
- 查看這些事件的上下文。
如果您在此過程中遇到問題,請在 Github 倉庫!您將在這裡看到的主要區別在於我們使用print 語句打印出交易日誌:
print(tx.events[0]["oldNumber"])
概括
日誌和事件是智能合約開發的重要組成部分,也是Chainlink 和The Graph 等項目的關鍵基礎設施。要了解有關構建極其強大的智能合約(利用您的新事件技能)的更多信息,請務必前往 Chainlink 文檔 今天開始建設。