Aller au contenu

Évènements

Les événements sont des objets immuables et vérifiables émis par les contrats intelligents, stockés et servis par le nœud complet Alephium. Ils jouent un rôle critique dans la facilitation d'une communication efficace et transparente entre les contrats intelligents et les applications hors chaîne.

Il existe de nombreux cas d'utilisation pour les événements: un échange décentralisé (DEX) peut utiliser des événements pour suivre toutes les opérations d'échange se produisant dans une paire de jetons. Un marché de NFT peut utiliser des événements pour stocker toutes les offres de NFT. Un oracle peut utiliser des événements pour signaler les demandes de certaines informations hors chaîne provenant des contrats intelligents. Un pont peut utiliser des événements pour représenter certaines actions nécessitant un consensus de tous les opérateurs de pont, etc.


Objet Événement

Un objet événement dans Alephium se compose des attributs suivants:

Text Only
txId            : id de transaction
blockHash       : hachage de bloc
contractAddress : adresse du contrat où l'événement est émis / adresse spéciale pour les événements système
eventIndex      : index de l'événement émis par le contrat / index spécial pour les événements système
fields          : champs contenus dans l'événement

Il existe deux types d'événements dans Alephium : les événements de contrat et les événements système. Les sections suivantes les abordent respectivement, avec plus de détails sur les attributs contractAddress, eventIndex et fields attributes.


Événements de Contrat

Comme son nom l'indique, les événements de contrat sont des événements personnalisés émis par les contrats:

AdminUpdated
Rust
Contract Admin(mut admin: Address) {
  event AdminUpdated(previous: Address, new: Address)

  @using(updateFields = true)
  pub fn updateAdmin(newAdmin: Address) -> () {
      checkCaller!(callerAddress!() == admin, 0)

      admin = newAdmin
      emit AdminUpdated(admin, newAdmin)
  }
}

Dans cet exemple, un événement AdminUpdated est émis chaque fois que admin est mis à jour. Ces informations peuvent être écoutées par les applications hors chaîne pour mettre à jour leurs interfaces utilisateur ou pour l'audit.

Vous pouvez vous abonner à tous les événements émis par un contrat, ou à un événement spécifique émis par un contrat en utilisant le Web3 SDK d'Alephium :

AdminUpdatedEvent
TypeScript
// `adminInstance` est une instance de contrat du contrat Admin
adminInstance.subscribeAdminUpdatedEvent({
  pollingInterval: 500,
  messageCallback: (event: AdminTypes.AdminUpdatedEvent): Promise<void> => {
    console.log('got admin updated event:', event)
    return Promise.resolve()
  },
  errorCallback: (error: any, subscription): Promise<void> => {
    console.log(error)
    subscription.unsubscribe()
    return Promise.resolve()
  }
})

Dans l' objet événement AdminUpdated',contractAddress représente l'adresse du contrat de adminInstance, eventIndex est 0 puisque AdminUpdated est le premier événement défini dans le contrat Admin (indice basé sur 0). fields ccontient deux adresses: une pour l'admin précédent, l'autre pour le nouvel admin.


Événements Système

Comparés aux événements de contrat, qui sont émis explicitement par les contrats, les événements système sont émis automatiquement par le nœud complet Alephium. Actuellement, il existe deux événements système :

ContractCreatedEvent

ContractCreatedEvent est émis lorsqu'un nouveau contrat est créé:

Rust
TxScript Deploy(fooByteCode: ByteVec) {
  createContract!{callerAddress!() -> ALPH: 1 ALPH}(fooByteCode, #00, #00)
}

Dans l'exemple ci-dessus, le script de transaction Deploy crée un nouveau contrat Foo à partir de son bytecode de contrat. Le contrat Foo cn'a pas de champs de contrat, c'est pourquoi #00 est passé en tant qu'arguments à la fonction createContract. Un événement système ContractCreatedEvent est émis après la création du contrat Foo.

Le Web3 SDK d'Alephium fournit une fonction d'aide pour s'abonner à l'événement ContractCreatedEvent:

ContractCreatedEvent
TypeScript
subscribeContractCreatedEvent({
  pollingInterval: 500,
  messageCallback: (event: ContractCreatedEvent): Promise<void> => {
    console.log('got contract created event:', event)
    return Promise.resolve()
  },
  errorCallback: (error: any, subscription): Promise<void> => {
    console.log(error)
    subscription.unsubscribe()
    return Promise.resolve()
  }
})

Dans l' objet événement ContractCreatedEvent, eventIndex est défini sur -1, une valeur spécialement réservée pour l'événement ContractCreatedEvent. contractAddress est défini sur une valeur spéciale calculée en fonction de l'eventIndex et du groupe de contrat. fields contient l'adresse du contrat nouvellement créé ainsi que l'identifiant de son contrat parent s'il existe.

ContractDestroyedEvent

ContractDestroyedEvent est émis lorsqu'un contrat est détruit :

Rust
Contract Foo() {
  @using(assetsInContract = true)
  pub fn destroy() -> () {
    destroySelf!(callerAddress!())
  }
}

Dans l'exemple ci-dessus, après l'appel de la fonction destroy, le contrat Foo sera détruit et un événement système ContractDestroyedEvent sera émis par le nœud complet Alephium.

Le Web3 SDK d'Alephium fournit une fonction d'aide pour s'abonner à l'événement ContractDestroyedEvent:

ContractDestroyedEvent
TypeScript
subscribeContractDestroyedEvent({
  pollingInterval: 500,
  messageCallback: (event: ContractDestroyedEvent): Promise<void> => {
    console.log('got contract destroyed event:', event)
    return Promise.resolve()
  },
  errorCallback: (error: any, subscription): Promise<void> => {
    console.log(error)
    subscription.unsubscribe()
    return Promise.resolve()
  }
})

Dans l'objet événementContractDestroyedEvent, eventIndex est défini sur -2, , une valeur spécialement allouée pour l'événement ContractDestroyedEvent. contractAddress est défini sur une valeur spéciale calculée en fonction de l'eventIndex et du groupe de contrat. fields contient l'adresse du contrat détruit.


Configuration

Le nœud complet d'Alephium permet une configuration flexible de la manière dont les événements doivent être stockés et indexés. Par défaut, il ne stocke pas les événements pour maintenir le nœud complet léger.

Vous pouvez activer le stockage des événements en utilisant le drapeau suivant:

Text Only
alephium.node.event-log.enabled=true

Cela nous permet d'interroger les événement contrat et les événement systemé n fonction de l'adresse du contrat.

Pour permettre l'interrogation des événements en fonction de l'identifiant de transaction et du hachage de bloc, vous devez activer les drapeaux suivants :

Text Only
alephium.node.event-log.index-by-tx-id = true
alephium.node.event-log.index-by-block-hash = true

Par défaut, les événements émis par tous les contrats sont stockés. Mais si vous savez quels contrats vous intéressent pour obtenir des événements, vous pouvez utiliser la configuration suivante:

Text Only
alephium.node.event-log.contract-addresses = [$CONTRACT_ADDR_1, $CONTRACT_ADDR_2]

De cette manière, vous économiserez de l'espace disque car votre nœud complet ne stockera que les événements émis par les contrats spécifiés ici.


Lecture complémentaire

Les fonctions d'abonnement aux événements dans le Web3 SDK d'Alephium sont construites sur les API du nœud complet d'Alephium. Pour plus de détails sur les API, veuillez vous référer à la documentation OpenAPI.

En plus de ContractEvent et SystemEvent, il existe en fait un autre événement système (spécial) appeléDebugEvent, veuillez vous référer au débogage pour plus d'informations.