Saltar al contenido principal

Publicar eventos desde un contrato de Rust

Un evento puede contener temas, además de los datos que está publicando. Los datos de los temas pueden ser cualquier valor o tipo que desees.

Whisk Cambios

Con el lanzamiento de Whisk, Protocolo 23, la sintaxis para publicar eventos de contratos inteligentes ha cambiado. Para proporcionar la información más actualizada, esta guía se ha actualizado para incluir los nuevos patrones. Encuentra información más detallada en la documentación del SDK de Rust.

La estrategia aquí es primero crear algunas structs que definirán cómo se estructuran nuestros eventos. Luego, dentro de la función del contrato, podemos crear y publicar esas structs.

// This event will be published with the following structure:
// `["COUNTER", "increment"], data = count: u32`
#[contractevent(topics = ["COUNTER", "increment"], data_format = "single-value")]
pub struct Increment {
count: u32,
}

// Events without explicit topics will use the struct name for the sole topic.
// By default, the event data will follow the struct shape.
// This event will be published with the following structure:
// `["borrow"], data = {addr: Address, amount: i128}`
#[contractevent]
pub struct Borrow {
addr: Address,
amount: i128,
}

// Event topics can also be noted in the struct, so they're dynamic.
// This event will be published with the following structure:
// `["deposit", addr: Address, token: Address], data = [amount: i128, time: u64]`
#[contractevent(data_format = "vec")]
pub struct Deposit {
#[topic]
addr: Address,
#[topic]
token: Address,
amount: i128,
time: u64,
}

// This function does nothing beside publish events.
pub fn events_function(env: Env, invoker: Address, token: Address) {
Increment {
count: 8675309,
}.publish(&env);

Borrow {
addr: invoker.clone(),
amount: 123_0000000,
}.publish(&env);

Deposit {
addr: invoker,
token: token,
amount: 321_0000000,
time: env.ledger().timestamp(),
}.publish(&env);
}

Un ejemplo más realista se puede encontrar en la forma en que funciona la interfaz de token. Por ejemplo, la interfaz requiere que se publique un evento cada vez que se invoca la función transfer, con la siguiente información:

#[contractevent(data_format = "single-value")]
pub struct Transfer {
#[topic]
from: Address,
#[topic]
to: Address,
amount: i128,
}

pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
// transfer logic omitted here
Transfer { from, to, amount }.publish(&env);
}