Содержание

События в Solidity

События позволяют удобно использовать EVM журнал (лог), который в свою очередь можно использовать для обратных вызовов Javascript в пользовательском интерфейсе децентрализованного приложения.

События — наследуемые члены контракта. Когда они вызываются, это приводит к тому, что аргументы сохраняются в журнале транзакций — специальной структуре данных в блокчейн. Эти журналы связаны с адресом контракта, и они будут включены в блокчейн. Журналы будут храниться в нем до тех пор, пока блок доступен (т.е. всегда в Frontier и Homestead, но в Serenity это можно изменить). Лог и данные из события не доступны изнутри контракта (и даже изнутри контракта, который создал данный контракт).

Для лога доступны SPV доказательства, поэтому, если внешний объект предоставляет контракт с таким доказательством, то он может проверить, что лог действительно существует внутри блокчейна. Но должны быть предоставлены заголовки этого блока, потому что контракт может видеть только последние 256 хэшей блока.

До трех параметров могут иметь атрибут indexed, который приведет к поиску соответствующих аргументов. Можно фильтровать по конкретным значениям indexed-аргументов в пользовательском интерфейсе.

Если массивы (включая string и bytes) используются в качестве indexed-аргументов, то их хэш keccak-256 вместо этого сохраняется как тема.

Хэш подписи события — одна из тем, кроме случаев, если события объявляется со спецификатором anonymous.

Это означает, что такое событие невозможно фильтровать по имени.

Все не indexed-аргументы размещаются в части журнала, где хранятся данные.

Примечание

Indexed-аргументы не могут хранить сами себя. Можно только искать по значению, но невозможно получить сами значения.

pragma solidity ^0.4.0;

contract ClientReceipt {
    event Deposit(
        address indexed _from,
        bytes32 indexed _id,
        uint _value
    );

    function deposit(bytes32 _id) public payable {
        // Любой вызов этой функции может быть виден
        // из JavaScript API путем фильтрации
        // `Deposit`.
        Deposit(msg.sender, _id, msg.value);
    }
}

Использование в Javascript API было бы следующим:

var abi = /* abi, сгенерированный компилятором */;
var ClientReceipt = web3.eth.contract(abi);
var clientReceipt = ClientReceipt.at("0x1234...ab67" /* address */);

var event = clientReceipt.Deposit();

// следить за изменениями
event.watch(function(error, result){
    // результат будет содержать различную информацию,
    // включая аргументы, передаваемые в вызов `Deposit`.
    if (!error)
        console.log(result);
});

// Или передать обратный вызов, чтобы сразу начать просмотр
var event = clientReceipt.Deposit(function(error, result) {
    if (!error)
        console.log(result);
});

Низкоуровневый интерфейс логов

Также, можно получить доступ к низкоуровневому механизму ведения логов через функции log0, log1, log2, log3 и log4. logi получают i + 1 параметр типа bytes32, где первый аргумент будет использован для части лога, где хранятся данные, а другие — в качестве тем. Вызов события в примере выше, может быть выполнен так же, как в следующем примере:

pragma solidity ^0.4.10;

contract C {
    function f() public payable {
        bytes32 _id = 0x420042;
        log3(
            bytes32(msg.value),
            bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
            bytes32(msg.sender),
            _id
        );
    }
}

Здесь длинное шестнадцатеричное число? равное keccak256(“Deposit(address,hash256,uint256)”) — это подпись события.

Материал был полезен? Поделитесь в соц. сетях:
Логотип echain.ru

Добавить комментарий

Ваш e-mail не будет опубликован.