Mit Verträgen interagieren
Alephiums Full Node bietet eine Reihe von APIs zum Interagieren mit den bereitgestellten Verträgen. Diese Interaktionen können je nachdem, ob sie beabsichtigen, den Zustand der Blockchain zu aktualisieren, in zwei Kategorien unterteilt werden: Vertragsaufrufe sind schreibgeschützte Interaktionen, die gebührenfrei sind und sofort ausgeführt werden, wobei das Ergebnis sofort an den Aufrufer zurückgegeben wird. TxScript-Transaktionen hingegen aktualisieren den Zustand der Blockchain, erfordern Gas und werden ausgeführt, wenn Transaktionen abgebaut werden, wobei nur die Transaktions-IDs an den Aufrufer zurückgegeben werden.
Die direkte Interaktion mit Verträgen über die Full-Node-API kann mühsam sein. Alephiums Web3 SDK abstrahiert viele Details, indem es Wrapper-Code für Verträge und Transaktionsskripte generiert. Lassen Sie uns seine Nützlichkeit anhand des TokenFaucet Vertrags demonstrieren, der im Getting started-Leitfaden diskutiert wird:
token_faucet.ral
import "std/fungible_token_interface"
// Definiert einen Vertrag namens TokenFaucet.
// Ein Vertrag ist eine Sammlung von Feldern (sein Zustand) und Funktionen.
// Einmal bereitgestellt, befindet sich ein Vertrag an einer spezifischen Adresse auf der Alephium-Blockchain.
// Vertragsfelder werden dauerhaft im Vertragsspeicher gespeichert.
// Ein Vertrag kann bei seiner Bereitstellung eine anfängliche Menge an Token ausgeben.
Contract TokenFaucet(
symbol: ByteVec,
name: ByteVec,
decimals: U256,
supply: U256,
mut balance: U256
) implements IFungibleToken {
// Ereignisse ermöglichen das Protokollieren von Aktivitäten auf der Blockchain.
// Alephium-Clients können Ereignissen lauschen, um auf Änderungen des Vertragszustands zu reagieren.
event Withdraw(to: Address, amount: U256)
enum ErrorCodes {
InvalidWithdrawAmount = 0
}
// Eine öffentliche Funktion, die die anfängliche Versorgung mit dem Token des Vertrags zurückgibt.
// Beachten Sie, dass das Feld als Betrag des ausgegebenen Tokens initialisiert werden muss.
pub fn getTotalSupply() -> U256 {
return supply
}
// Eine öffentliche Funktion, die das Symbol des Tokens zurückgibt.
pub fn getSymbol() -> ByteVec {
return symbol
}
// Eine öffentliche Funktion, die den Namen des Tokens zurückgibt.
pub fn getName() -> ByteVec {
return name
}
// Eine öffentliche Funktion, die die Dezimalstellen des Tokens zurückgibt.
pub fn getDecimals() -> U256 {
return decimals
}
// Eine öffentliche Funktion, die den aktuellen Kontostand des Vertrags zurückgibt.
pub fn balance() -> U256 {
return balance
}
// Eine öffentliche Funktion, die Token an jeden überträgt, der sie aufruft.
// Die Funktion ist mit updateFields = true gekennzeichnet, da sie die Vertragsfelder ändert.
// Die Funktion ist als Verwendung von Vertragsvermögenswerten gekennzeichnet, da sie diese verwendet
@using(assetsInContract = true, updateFields = true, checkExternalCaller = false)
pub fn withdraw(amount: U256) -> () {
// Debug-Ereignisse können bei der Fehleranalyse hilfreich sein.
emit Debug(`The current balance is ${balance}`)
// Stellen Sie sicher, dass der Betrag gültig ist.
assert!(amount <= 2, ErrorCodes.InvalidWithdrawAmount)
// Funktionen mit dem Suffix ! sind integrierte Funktionen.
transferTokenFromSelf!(callerAddress!(), selfTokenId!(), amount)
// Ralph erlaubt keine Unterlauf.
balance = balance - amount
// Das zuvor definierte Ereignis auslösen.
emit Withdraw(callerAddress!(), amount)
}
}
Der VertragTokenFaucet
verfügt über 5
öffentliche Funktionen, die nur den
Vertragszustand lesen: getTotalSupply
, getSymbol
, getName
,
getDecimals
und balance
. Er hat auch eine Funktion namens withdraw
,
die nicht nur den Vertragszustand aktualisiert, sondern auch Vermögenswerte überträgt.
Nachdem der Vertrag TokenFaucet
kompiliert wurde,
wird eine entsprechende TypeScript-Klasse generiert. Wir können eine Instanz dieser Klasse erhalten,
nachdem wir sie auf dem Devnet bereitgestellt haben:
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
Contract Aufruf
Innerhalb der TokenFaucet
TypeScript-Klasse generiert das Alephium-SDK Methoden
für alle reinen Funktionen im TokenFaucet
-Vertrag. Sie können genau wie reguläre
TypeScript-Funktionen aufgerufen werden:
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
Beachten Sie, dass die Ergebnisse der Vertragsaufrufe sofort zurückgegeben werden und weder Gas noch Signaturen erforderlich sind.
Das Alephium-SDK generiert auch Code für das gleichzeitige Aufrufen mehrerer reiner Funktionen, was die Anzahl der Netzwerkanfragen reduziert:
const result = await tokenFaucet.multicall({
getSymbol: {},
getName: {},
getDecimals: {},
getTotalSupply: {}
})
console.log(`name: ${hexToString(result.getName.returns)}`) // name: TokenFaucet
console.log(`symbol: ${hexToString(result.getSymbol.returns)}`) // symbol: TF
console.log(`decimals: ${result.getDecimals.returns}`) // decimals: 18
console.log(`total supply: ${result.getTotalSupply.returns}`) // total supply: 10
TxScript Transaktionen
Der Vertrag TokenFaucet
hat auch eine Funktion namens withdraw
,
die das Token vom Faucet zum Aufrufer überträgt und den Kontostand aktualisiert.
Wenn wir die Funktion withdraw
aufrufen, müssen wir sie als Transaktion mit TxScript ausführen:
TxScript Withdraw(token: TokenFaucet, amount: U256) {
// Die Funktion withdraw des Token-Vertrags aufrufen.
token.withdraw(amount)
}
Das SDK von Alephium generiert auch eine entsprechende TypeScript-Klasse für das
Withdraw
-Transaktionsskript nach dem
compilation,
das wir verwenden können, um die Transaktion auszuführen:
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
Wir übergeben die initialFields
, wie sie im Withdraw
-Transaktionsskript definiert sind,
sowie genug attoAlphAmount
, um die Gasgebühren sowie den Staubbetrag
für den Erhalt von Token abzudecken.
Beachten Sie, dass ein signer
erforderlich ist, um die Transaktion zu signieren.
Das Ausführungsergebnis des Withdraw
-Skripts enthält eine Transaktions-ID, die später
verwendet werden kann, um den Status der Transaktion abzufragen. Einige andere nützliche
Informationen im Ausführungsergebnis sind:
unsignedTx
: Serialisierte Version der ungesignierten Transaktionsignature
: Signatur des Signierenden für die TransaktiongasAmount
: Gasgebühr der Transaktion
Eine Funktion, die aus einem TxScript
ausgeführt wird, kann dem Aufrufer keine
Werte direkt zurückgeben, da die Transaktion später verarbeitet wird und das
Ergebnis nicht deterministisch ist und vom zukünftigen Zustand der Blockchain
abhängt, wenn die Transaktion abgebaut wird. Stattdessen werden häufig Events
verwendet, um Einblicke in die Vertragsaktivitäten zu erhalten.
Events Subscription
Die withdraw
-Funktion für den TokenFaucet
-Vertrag löst ein Withdraw
-Ereignis aus,
das den Empfänger und den Betrag des abgehobenen Tokens enthält.
Ereignisse wie dieses sind für dApps sehr nützlich, um Vertragsaktivitäten zu verfolgen.
Alephiums Web3 SDK stellt eine Reihe von Funktionen zur Interaktion
mit den Ereignissen eines Vertrags bereit. Hier ist, wie wir das Withdraw
-Ereignis
abonnieren können, das von der withdraw
-Funktion im TokenFaucet
-Vertrag ausgelöst wird:
// Abonnieren Sie das `Withdraw`- Ereignis.
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()
}
})
Wenn mehr als ein Ereignis vom TokenFaucet
-Vertrag ausgelöst wird, wird auch eine
Funktion namens subscribeAllEvents
generiert, um sich für alle Ereignisse zu abonnieren,
die vom Vertrag ausgelöst werden.
Weiterführende Literatur
Alephiums Web3 SDK bietet benutzerfreundliche Abstraktionen über die APIs des vollständigen Knotens von Alephium. Weitere Informationen zu den APIs finden Sie in der OpenAPI Dokumentation.
Lesen Sie eine ausführlichere Erklärung zu TxScript
hier, , einem einzigartigen Merkmal in Alephium, das eine flexiblere und effizientere Möglichkeit bietet, Transaktionen zu erstellen, die mit Smart Contracts interagieren.
Ereignisse sind entscheidend für den Aufbau von dApps, weitere Informationen finden Sie hier.