> For the complete documentation index, see [llms.txt](https://chihaolu.gitbook.io/all-in-one-solidity/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chihaolu.gitbook.io/all-in-one-solidity/part-ii-medium/chapter-10-shi-jian-event.md).

# | Chapter 10 | 事件 Event

在 Solidity 中，當一個 `event` 被 call 之後它的參數就會被置於區塊鏈之中。

事件是合約的可繼承成員，發出一個事件可以使用合約的地址訪問事件，生成的事件不能從合約內部訪問。

以下是我們使用事件的用途：

* 事件是一個合約跟外部前端 app（或說使用者 interface）溝通的方法，可以在前端聆聽（listening）合約裡的特定事件或者動作，當他們被啟動或者改變的時候。
* 同步於資料啟動某些動作
* 相同資料量的情況下，比儲存在 `storage` 更便宜
* 如果我們今天要 debug 或者測試的時候，也可以利用 `event` 來模擬一個 Javascript `console.log` 的功能。

```solidity
pragma solidity ^0.8.11;
contract EventExample {

    mapping(address => uint) public tokenBalance;

    constructor() public {
        tokenBalance[msg.sender] = 100;
    }

    function sendToken(address _to, uint _amount) public returns(bool) {
        require(tokenBalance[msg.sender] >= _amount, "Not enough tokens");
        assert(tokenBalance[_to] + _amount >= tokenBalance[_to]);
        assert(tokenBalance[msg.sender] - _amount <= tokenBalance[msg.sender]);
        tokenBalance[msg.sender] -= _amount;
        tokenBalance[_to] += _amount;

        return true;
    }

}
```

當我們呼叫了 `sendToken()` 這個函式，在不同的環境它會回傳不同的結果：

* 使用Javascript VM(Virtural Machine) 時：
  * &#x20;`sendToken()` returns `boolean: true`
  * 因為其是模擬一個「瀏覽器」環境
* 使用Injected Web3 時：
  * `sendToken()` 不會returns任何東西
  * 因為其是在真實的區塊鏈上運作&#x20;

這也就是說，如果我們希望在真實的區塊鏈上聆聽回傳結果，必須透過Event，並將其`emit`置於函數之中（記得要在函數`return`之前）。而Event也可以被像是MetaMask之類的Provider聆聽。

```solidity
pragma solidity ^0.8.11;
contract EventExample {

    mapping(address => uint) public tokenBalance;
    
    event TokenSent(address _from, address _to, uint _amount);

    constructor() public {
        tokenBalance[msg.sender] = 100;
    }

    function sendToken(address _to, uint _amount) public returns(bool) {
        require(tokenBalance[msg.sender] >= _amount, "Not enough tokens");
        assert(tokenBalance[_to] + _amount >= tokenBalance[_to]);
        assert(tokenBalance[msg.sender] - _amount <= tokenBalance[msg.sender]);
        tokenBalance[msg.sender] -= _amount;
        tokenBalance[_to] += _amount;
        
        emit TokenSent(msg.sender, _to, _amount);

        return true;
    }

}
```

在以上的例子之中當我們呼叫了具有`emit`的`sendToken()`，我們可以在**Transaction Information**中看見`logs`，而在`logs`中會看見我們`emit`的資訊。

Event 具有以下的性質：

* 應用程式可以透過Ethereum 客戶端的RPC interface，以`subscribe`來聆聽這些事件
* Events是作為合約的一部分是可繼承的
* 合約不可以存取自己Event被啟動之後的`logs`和任何相關data。
* 被標示`indexed`的Event 參數可以在未來被檢索


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chihaolu.gitbook.io/all-in-one-solidity/part-ii-medium/chapter-10-shi-jian-event.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
