Interagir avec les contrats
Alephium fournit un ensemble d'APIs via son nœud complet pour interagir avec les contrats déployés. Ces interactions peuvent être divisées en deux catégories selon qu'elles ont l'intention de mettre à jour l'état de la blockchain: les appels de contrat sont des interactions en lecture seule qui sont sans frais de gaz, exécutées immédiatement avec le résultat renvoyé immédiatement à l'appelant. Les transactions TxScript, quant à elles, mettent à jour l'état de la blockchain, nécessitent du gaz, sont exécutées lorsque les transactions sont minées avec seulement les identifiants de transaction renvoyés à l'appelant.
Interagir directement avec les contrats via l'API du nœud complet peut être fastidieux. Le Web3 SDK d'Alephium abstrait de nombreux détails en générant du code d'enrobage pour les contrats et les scripts de transaction. Illustrons son utilité en utilisant le contrat TokenFaucet discuté dans le guide de démarrage:
token_faucet.ral
import "std/fungible_token_interface"
// Définit un contrat nommé TokenFaucet.
// Un contrat est une collection de champs (son état) et de fonctions.
// Une fois déployé, un contrat réside à une adresse spécifique sur la blockchain Alephium.
// Les champs du contrat sont stockés de manière permanente dans le stockage du contrat.
// Un contrat peut émettre une quantité initiale de jetons lors de son déploiement.
Contract TokenFaucet(
symbol: ByteVec,
name: ByteVec,
decimals: U256,
supply: U256,
mut balance: U256
) implements IFungibleToken {
// Les événements permettent de consigner les activités sur la blockchain.
// Les clients Alephium peuvent écouter les événements afin de réagir aux changements d'état des contrats.
event Withdraw(to: Address, amount: U256)
enum ErrorCodes {
InvalidWithdrawAmount = 0
}
// Une fonction publique qui renvoie l'approvisionnement initial du jeton du contrat.
// Remarquez que le champ doit être initialisé avec la quantité du jeton émis.
pub fn getTotalSupply() -> U256 {
return supply
}
// Une fonction publique qui renvoie le symbole du jeton.
pub fn getSymbol() -> ByteVec {
return symbol
}
// Une fonction publique qui renvoie le nom du jeton.
pub fn getName() -> ByteVec {
return name
}
// Une fonction publique qui renvoie le nombre de décimales du jeton.
pub fn getDecimals() -> U256 {
return decimals
}
// Une fonction publique qui renvoie le solde actuel du contrat.
pub fn balance() -> U256 {
return balance
}
// Une fonction publique qui transfère des jetons à quiconque l'appelle.
// La fonction est annotée avec `updateFields = true` car elle modifie les champs du contrat.
// La fonction est annotée comme utilisant les actifs du contrat car elle le fait.
@using(assetsInContract = true, updateFields = true, checkExternalCaller = false)
pub fn withdraw(amount: U256) -> () {
// Les événements de débogage peuvent être utiles pour l'analyse des erreurs.
emit Debug(`The current balance is ${balance}`)
// Assurez-vous que le montant est valide.
assert!(amount <= 2, ErrorCodes.InvalidWithdrawAmount)
// Les fonctions suffixées par `!` sont des fonctions intégrées.
transferTokenFromSelf!(callerAddress!(), selfTokenId!(), amount)
// Ralph n'autorise pas le débordement négatif.
balance = balance - amount
// Émettre l'événement défini précédemment.
emit Withdraw(callerAddress!(), amount)
}
}
Le contrat TokenFaucet
dispose de 5
onctions publiques qui ne font que
lire les états du contrat: getTotalSupply
, getSymbol
, getName
,
getDecimals
et balance
. Il dispose également d'une fonction appelée withdraw
,
qui non seulement met à jour l'état du contrat, mais transfère également des actifs.
Après la compilation du
contrat TokenFaucet
, une classe Typescript correspondante est générée.
Nous pouvons obtenir une instance de cette classe après l'avoir déployée sur devnet:
import { DUST_AMOUNT } from '@alephium/web3'
import { getSigner } from '@alephium/web3-test'
import { TokenFaucet, TokenFaucetTypes, Withdraw } from '../artifacts/ts'
const signer = await getSigner()
const deployResult = await TokenFaucet.deploy(signer, {
initialFields: {
symbol: stringToHex('TF'),
name: stringToHex('TokenFaucet'),
decimals: 18n,
supply: 10n ** 18n,
balance: 10n
}
})
const tokenFaucet = deployResult.contractInstance
Appel de contrat
À l'intérieur de la classe typescript TokenFaucet
e SDK d'Alephium génère des méthodes pour toutes les fonctions pures dans le contrat TokenFaucet
.
Elles peuvent être appelées comme des fonctions typescript régulières:
const getNameResult = await tokenFaucet.methods.getName()
console.log(`name: ${hexToString(getNameResult.returns)}`) // name: TokenFaucet
const getDecimalsResult = await tokenFaucet.methods.getDecimals()
console.log(`decimals: ${getDecimalsResult.returns)}`) // decimals: 18
Notez que les résultats des appels de contrat sont retournés immédiatement et qu'aucun gaz ou signature n'est requis.
Le SDK d'Alephium génère également du code pour appeler plusieurs fonctions pures en même temps, réduisant ainsi le nombre de requêtes réseau:
const result = await tokenFaucet.multicall({
getSymbol: {},
getName: {},
getDecimals: {},
getTotalSupply: {}
})
console.log(`name: ${hexToString(result.getName.returns)}`) // name: TokenFaucet
console.log(`symbole: ${hexToString(result.getSymbol.returns)}`) // symbole: TF
console.log(`décimales: ${result.getDecimals.returns}`) // décimales: 18
console.log(`offre totale: ${result.getTotalSupply.returns}`) // offre totale: 10
TxScript Transactions
Le contrat TokenFaucet
dispose également d'une fonction appelée withdraw
,
qui transfère le jeton du robinet au demandeur et met à jour le solde.
Lors de l'appel de la fonction withdraw
, nous devrons l'exécuter en tant que transaction à l'aide de TxScript:
TxScript Withdraw(token: TokenFaucet, amount: U256) {
// Appeler la fonction de retrait du contrat de jeton.
token.withdraw(amount)
}
Le SDK d'Alephium génère également une classe typescript correspondante pour le script de transaction
Withdraw
après la
compilation, que nous pouvons utiliser pour exécuter la transaction:
const signer = await getSigner()
const withdrawResult = await Withdraw.execute(signer, {
initialFields: { token: tokenFaucet.contractId, amount: 2n },
attoAlphAmount: DUST_AMOUNT * 2n
})
console.log(`tx id: ${withdrawResult.txId}`) // tx id: xxxx
Nous passons les initialFields
comme défini dans le script de transaction Withdraw
,
et suffisamment attoAlphAmount
pour couvrir le gaz ainsi que le
montant minimal pour recevoir les jetons.
Notez qu'un signer
est requis pour signer la transaction.
Le résultat de l'exécution du script Withdraw
contient un identifiant de transaction,
qui peut être utilisé pour interroger ultérieurement l'état de la transaction.
Certaines autres informations utiles dans le résultat d'exécution incluent:
unsignedTx
: Version sérialisée de la transaction non signéesignature
: Signature du signataire pour la transactiongasAmount
: Coût en gaz de la transaction
Les fonctions exécutées à partir de TxScript
ne peuvent pas renvoyer de valeur directement à l'appelant
car la transaction sera traitée ultérieurement et le résultat est non déterministe en fonction de l'état
futur de la blockchain lorsque la transaction est minée. Les Événements
sont plutôt souvent utilisés
pour obtenir des informations sur les activités du contrat.
Abonnement aux événements
The withdraw
function for TokenFaucet
contract emits a Withdraw
event, which contains the recipient and amount of the withdrawn token.
Des événements comme celui-ci sont très utiles pour les dApps afin de suivre les activités des contrats.
Le Web3 SDK d'Alephium fournit un ensemble de fonctions pour interagir
avec les événements des contrats. Voici comment nous pouvons nous abonner à l'événement Withdraw
émis
par la fonction de retrait dans le contrat TokenFaucet
:
// Subscribe to the `Withdraw` event in
tokenFaucet.subscribeWithdrawEvent({
pollingInterval: 500,
messageCallback: (event: TokenFaucetTypes.WithdrawEvent): Promise<void> => {
console.log('got withdraw event:', event)
return Promise.resolve()
},
errorCallback: (error: any, subscription): Promise<void> => {
console.log(error)
subscription.unsubscribe()
return Promise.resolve()
}
})
Si plusieurs événements sont émis par le contrat TokenFaucet
,
une fonction appelée subscribeAllEvents
sera également générée
pour s'abonner à tous les événements émis par le contrat.
Pour aller plus loin
Le Web3 SDK d'Alephium construit des abstractions conviviales pour les développeurs au-dessus des APIs du nœud complet d'Alephium. Pour plus de détails sur les APIs, veuillez consulter la documentation OpenAPI.
Veuillez lire une explication plus détaillée sur TxScript
ici, une fonctionnalité unique dans
Alephium qui est un moyen plus flexible et efficace de créer des transactions qui
interagissent avec les contrats intelligents.
Les événements sont cruciaux pour construire des dApps, plus d'informations peuvent être trouvées ici.