Système de permission d'actifs
Le Système de Permission d'Actifs (APS) est l'une des fonctionnalités uniques de Ralph. Il stipule explicitement le flux des actifs au niveau du code, offrant ainsi confiance aux développeurs et aux utilisateurs des contrats intelligents que tous les transferts d'actifs se déroulent comme prévu. Associé au modèle UTXOs, il offre également une expérience utilisateur plus simple et plus sécurisée en éliminant les risques d'approbation de jetons dans des systèmes tels que l'EVM.
Alephium utilise le modèle sUTXO où les actifs, y compris le jeton natif ALPH et d'autres jetons, sont gérés par des UTXOs tandis que les contrats intelligents et leurs états sont gérés à l'aide d'un modèle basé sur les comptes.
Cela a quelques implications :
- Les transferts d'actifs simples entre utilisateurs ne nécessitent que des UTXOs, qui ont fait leurs preuves en matière de sécurité dans la gestion des actifs. Aucun contrat intelligent n'est impliqué ici.
- Lorsque les contrats intelligents ont besoin de transférer des actifs au nom des propriétaires, aucune transaction d'approbation séparée n'est requise. L'approbation est implicite dans le modèle UTXO: si l'entrée contenant un jeton particulier est autorisée à être dépensée dans la transaction, alors le propriétaire a déjà donné son consentement à l'utilisation de ce jeton dans le contexte de cette transaction, ce qui signifie que les contrats intelligents invoqués dans la même transaction peuvent potentiellement transférer le jeton.
Maintenant, la question est : dans la deuxième situation, comment pouvons-nous nous assurer que les actifs implicitement approuvés dans la transaction en utilisant le modèle UTXO peuvent être gérés en toute sécurité par les contrats intelligents ? La réponse est le Système de Permission d'Actifs (APS) de Ralph.
Flux des Actifs
Pour interagir avec les contrats intelligents dans Alephium, une
transaction doit exécuter un TxScript
. Dans l'exemple de transaction
suivant, il y a deux entrées, une sortie fixe et un TxScript
:
----------------
| |
| |
1 Jeton A | | 1 ALPH (sortie fixe)
================> | | ========================>
6.1 ALPHs | <TxScript> | ??? (sortie générée)
================> | | ========================>
| |
| |
| |
----------------
Deux choses valent la peine d'être notées ici :
- Bien qu'il n'y ait qu'une seule sortie fixe, il y aura plus de
sorties générées pour cette transaction. Les sorties générées
dépendent du résultat de l'exécution du
TxScript
. - Les actifs totaux disponibles pour le
TxScript
(y compris les contrats intelligents qu'il invoque) sont de5.1
ALPHs et de1
Token A, car nous devons soustraire le1
ALPH en sortie fixe.
Disons que le TxScript
ressemble à ceci :
TxScript ListNFT(
tokenAId: ByteVec,
price: U256,
marketPlace: NFTMarketPlace
) {
let listingFee = marketPlace.getListingFee()
let minimalAlphInContract = 1 alph
let approvedAlphAmount = listingFee + minimalAlphInContract
marketPlace.listNFT{callerAddress!() -> ALPH: approvedAlphAmount, tokenAId: 1}(tokenAId, price)
}
Comme vous l'avez peut-être deviné, Token A est un jeton NFT et le
but du TxScript
ci-dessus est de le mettre en vente via un contrat
intelligent de place de marché.
La ligne de code suivante est particulièrement intéressante:
Le code à l'intérieur des accolades approuve explicitement que approvedAlphAmount
ALPH
et 1
token A peuvent être dépensés dans la fonction marketPlace.listNFT
, même si le
montant total des actifs disponibles pour le TxScript
est de 5.1
et 1
pour ALPH et
token A respectivement.
Les scénarios suivants pourraient se produire:
- Si
approvedAlphAmount
s'avère être plus de5.1
ALPH, alors la transaction échoue avec une erreurNotEnoughBalance
. - Si
approvedAlphAmount
est inférieur à5.1
ALPH, disons1.1
ALPH, alors le montant maximum d'actifs quemarketPlace.listNFT
peut gérer est de1.1
ALPHs et 1 token A. marketPlace.listNFT n'a pas accès au reste des 4 ALPHs. - Si
marketPlace.listNFT
n'a pas dépensé la totalité des actifs approuvés, les actifs restants seront retournés à leur propriétaire lorsquemarketPlace.listNFT
retournera.
Jetons un coup d'œil de plus près à la fonction marketPlace.listNFT
:
Contract NFTMarketPlace(
nftListingTemplateId: ByteVec
) {
// Other code are omitted for brevity
pub fn getListingFee() -> U256 {
return 0.1 ALPH
}
@using(preapprovedAssets = true, assetsInContract = true, updateFields = false)
pub fn listNFT(
tokenId: ByteVec,
price: U256
) -> (Address) {
assert!(price > 0, ErrorCodes.NFTPriceIsZero)
// Only owner can list the NFT
let tokenOwner = callerAddress!()
let (encodeImmutableFields, encodeMutableFields) = NFTListing.encodeFields!(tokenId, tokenOwner, selfAddress!(), commissionRate, price)
// Create the listing contract
let nftListingContractId = copyCreateSubContract!{tokenOwner -> ALPH: 1 alph, tokenId: 1}(
tokenId, nftListingTemplateId, encodeImmutableFields, encodeMutableFields
)
// Charge the listing fee
transferTokenToSelf!(tokenOwner, ALPH, listingFee)
return contractIdToAddress!(nftListingContractId)
}
}
La première chose à remarquer est l'annotation pour la méthode listNFT
:
preapprovedAssets = true
indique au VM que la méthod listNFT
a l'intention
d'utiliser certains actifs et que l'appelant est censé approuver un ensemble
d'actifs nécessaires, sinon une erreur de compilation sera signalée. La compilation
échouera également si l'appelant essaie d'approuver des actifs pour une méthode
où preapprovedAssets = false
.
assetsInContract = true
indique au VM que la méthode listNFT
souhaite
mettre à jour l'actif du contrat NFTMarketPlace
. Le compilateur veillera à ce
que la méthode listNFT
fasse effectivement cela, sinon une erreur de compilation
sera signalée. Dans ce cas, listNFT
met à jour l'actif du contrat NFTMarketPlace
en transférant le listingFee
à celui-ci :
L'annotation updateFields
est hors de portée pour cette documentation.
La méthode marketPlace.listNFT
est invoquée par le TxScript
ListNFT
, comme indiqué ci-dessous :
Lorsque marketPlace.listNFT
est exécutée par le VM, elle est autorisée à
dépenser 1.1
ALPH et 1
jeton par l'appelant du script. Si marketPlace.listNFT
appelle
à son tour d'autres méthodes, elle peut approuver un sous-ensemble de ces actifs
approuvés pour cette méthode également. Par exemple, dans marketPlace.listNFT
,
nous avons le code suivant pour créer une liste NFT:
let nftListingContractId = copyCreateSubContract!{tokenOwner -> ALPH: 1 alph, tokenId: 1}(
tokenId, nftListingTemplateId, encodeImmutableFields, encodeMutableFields
)
Comme nous pouvons le voir, la méthode marketPlace.listNFT
approuve 1
ALPH
et 1
jeton A à la fonction intégrée copyCreateSubContract!
à partir de son
propre pool d'actifs approuvés (1.1
ALPH et 1
jeton A), avant d'envoyer le
listingFee
au contrat NFTMarketPlace
lui-même. Le flux des actifs est
illustré ci-dessous :
Appelant du TxScript
(6.1 ALPH; 1 Jeton A)
||
||
|| Soustrait les actifs dans les
|| sorties fixes
||
|| Approuve Approuve
\/ (1.1 ALPH; 1 Jeton A) (1 ALPH; 1 Jeton A)
(5.1 ALPH; 1 Jeton A) ========================> listNFT ========================> copyCreateSubContract!
||
||
|| À lui-même
||
\/
(0.1 ALPH)
Comme nous pouvons l'imaginer, si nous avons un arbre de méthodes d'appel plus grand, le fonds approuvé se propagera de la racine de l'arbre jusqu'aux feuilles comme de l'eau. Le Système de Permission d'Actifs rend ce flux du fonds tout au long des appels de méthode explicite et impose des contraintes à chacune des méthodes quant aux jetons et à la quantité pouvant être dépensée.
En revenant à la transaction, après l'exécution du TxScript
,
les sorties générées devraient ressembler à quelque chose comme ceci :
----------------
| |
| | 1 ALPH (sortie fixe)
1 Jeton A | | =========================================>
======================> | | 1 ALPH, 1 Token A (NFTListing contrat)
6.1 ALPHs | <TxScript> | =========================================>
======================> | | 0.1 ALPH (NFTMarketPlace contrat)
| | =========================================>
| | 4 ALPH - gaz (changer la sortie)
| | =========================================>
| |
----------------
Résumé
Le Système de Permission d'Actifs (APS) dicte le flux des actifs dans les contrats intelligents. L'approbation explicite des actifs pour chaque invocation de méthode garantit que les méthodes ne peuvent jamais dépenser plus que ce pour quoi elles sont autorisées. Associé au modèle UTXO, il offre une solution de gestion des actifs plus simple, plus fiable et plus sécurisée.