Solidity 中的 event 是一种特殊类型的日志,用于在区块链上记录特定事件的发生。事件在智能合约执行时触发,并在交易日志中保存。这使得外部监听器(例如 DApp 的前端)可以轻松地捕获和响应这些事件。event 的主要目的是提供一种高效的方式来记录合约的状态变化或重要的行为,并让外部应用程序能够监听这些变化。

Event 的定义与使用

1. 定义事件

首先,在智能合约中定义事件。事件类似于函数声明,但使用 event 关键字。

pragma solidity ^0.6.7;

contract ExampleContract {
    // 定义一个事件
    event NewZombie(uint zombieId, string name, uint dna);

    // 一个函数中触发事件
    function createZombie(uint _zombieId, string memory _name, uint _dna) public {
        // 触发事件
        emit NewZombie(_zombieId, _name, _dna);
    }
}

2. 触发事件

在合约中,通过 emit 关键字触发事件。在上面的示例中,当 createZombie 函数被调用时,NewZombie 事件被触发,记录了僵尸的 ID、名字和 DNA。

3. 监听事件

在 DApp 中使用 Web3.js 或其他以太坊库来监听和处理事件。例如,使用 Web3.js 监听 NewZombie 事件:

const contract = new web3.eth.Contract(abi, contractAddress);

contract.events.NewZombie()
.on("data", function(event) {
    let zombie = event.returnValues;
    console.log("一个新僵尸诞生了!", zombie.zombieId, zombie.name, zombie.dna);
}).on('error', console.error);

为什么使用事件

实际例子

假设我们有一个 CryptoZombies 合约,当新的僵尸被创建时,我们希望触发一个事件。

pragma solidity ^0.6.7;

contract CryptoZombies {
    event NewZombie(uint zombieId, string name, uint dna);

    struct Zombie {
        uint id;
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function createZombie(string memory _name, uint _dna) public {
        uint id = zombies.length;
        zombies.push(Zombie(id, _name, _dna));
        emit NewZombie(id, _name, _dna);
    }
}

在这个合约中,每当 createZombie 被调用时,NewZombie 事件会被触发,记录新僵尸的详细信息。

监听事件(JavaScript 示例)

以下是一个监听 NewZombie 事件的 JavaScript 示例:

const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

const abi = /* 合约的 ABI */;
const contractAddress = /* 部署的合约地址 */;
const contract = new web3.eth.Contract(abi, contractAddress);

// 监听 NewZombie 事件
contract.events.NewZombie()
.on("data", function(event) {
    let zombie = event.returnValues;
    console.log("一个新僵尸诞生了!", zombie.zombieId, zombie.name, zombie.dna);
}).on('error', console.error);

通过这种方式,前端应用可以实时监听智能合约中的事件,并在事件发生时更新用户界面或执行其他操作。

总结

事件提供了一种高效且经济的方法来记录和监听智能合约中的状态变化,使得智能合约和外部世界的交互更加顺畅。