Le développeur Christophe Verdo parle du cours en ligne ‘’, qu'il a récemment suivi.

Parlez-nous un peu de vous. Qu'est-ce qui vous a attiré vers ce cours ?
Je fais du développement web depuis environ 15 ans, principalement en tant que freelance.
En développant une application web de registre à long terme pour les pays en développement pour le compte d'un groupe bancaire, j'ai été confronté à la tâche d'intégrer une certification par blockchain. À l'époque, je ne savais pas grand-chose sur la certification blockchain, même si je m'intéressais déjà aux technologies crypto - principalement en tant qu'investisseur.
Finalement, cette fonctionnalité n'a pas été réalisée, mais en réfléchissant au fait que des organisations et des banques seraient intéressées par une telle solution pour leurs applications, je me suis mis à étudier la question et j'ai rapidement lancé le projet .
J'ai développé sa version bêta, qui est déjà disponible sur le réseau principal. À l'époque, [le langage de programmation Waves] Ride n'existait pas encore, et je faisais tout de la manière la plus simple, en utilisant des transactions de transfert avec du JSON intégré. Mais l'objectif principal était d'ajouter des fonctionnalités plus avancées après le lancement de Ride. Et c'est la principale raison pour laquelle je me suis inscrit au cours : la prochaine étape du développement du projet prévoyait la création d'une application décentralisée (dApp).
Quels aspects du cours vous ont semblé les plus simples et lesquels les plus difficiles ?
Ce qui était le plus simple, c'est que nous avions suffisamment de temps pour toutes les tâches. Le sens du cours est d'apprendre quelque chose, et non de rivaliser les uns avec les autres. Les explications étaient très accessibles, et les illustrations – simples mais complètes. Cela a aidé à visualiser et à comprendre différents sujets.
Lors de l'exécution des tâches, nous étions encouragés à penser de manière indépendante et parfois à étudier quelque chose par nous-mêmes. C'est le meilleur moyen d'apprendre quelque chose et de comprendre les idées abordées en cours.
Plusieurs fois, je ne comprenais pas entièrement la partie théorique jusqu'à ce que je commence à écrire du code, en réalisant la tâche. Nous n'avions pas le droit de faire du ‘copier/coller’, tout le code devait être écrit par nous-mêmes, et cela aidait également à mieux comprendre l'ensemble.
La partie la plus difficile était que les questions à choix multiple n'étaient pas toujours claires. Mon anglais n'est pas parfait, et les questions étaient écrites par quelqu'un qui n'est pas un locuteur natif, donc il y avait parfois des malentendus.
Peut-être que la partie du cours consacrée aux oracles et aux NFT pourrait être plus détaillée. Mais, de toute façon, l'objectif principal du cours est d'intéresser les développeurs. Ensuite, pour comprendre tous ses aspects, il faudra bien sûr consacrer un certain temps à expérimenter et à pratiquer.
Parlez-nous davantage de la solution sur laquelle vous avez travaillé tout au long du cours – ‘Coupon Bazaar’? Pourrait-on aussi voir des exemples de code?
Oui, nous avons travaillé sur ‘Coupon Bazaar’, qui est un marché où les gens achètent et vendent des coupons donnant droit à des biens et services à un prix réduit. Chaque coupon est représenté comme un actif numérique, offrant une réduction spéciale de la part du fournisseur.

Nous devions développer plusieurs composants de l'application. Tout d'abord, nous devions créer un système d'enregistrement des fournisseurs et de gestion des coupons. Ensuite, une fonction de vérification et une possibilité de recherche des coupons par les utilisateurs étaient nécessaires.

Au cours du programme, nous avons également ajouté plusieurs nouvelles fonctionnalités, y compris un système de vote et une fonction permettant de vérifier et de mettre sur liste noire les fournisseurs.
D'abord, nous avons étudié la différence entre les actifs intelligents, les comptes intelligents et les comptes d'applications décentralisées (dApp) ainsi que le fonctionnement des fonctions de vérificateur. Les fonctions de vérificateur permettent de modifier le comportement par défaut d'un compte. Par défaut, elles vérifient les signatures des transactions, mais la fonction de vérificateur permet d'établir d'autres « règles ».
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let ownerPublicKey = base58'H8ndsHjBha6oJBQQx33zqbP5wi8sQP7hwgjzWUv3q95M'
@Verifier(tx)
func verify() = {
match tx {
case: SetScriptTransaction=> sigVerify(tx.bodyBytes, tx.proofs[0], ownerPublicKey)
case: DataTransaction=> true
case_ => false
}
}Ensuite, nous avons commencé à ajouter des coupons. Nous avons utilisé l'une des fonctionnalités clés de la dApp, qui permet d'enregistrer dans la blockchain des données de tout type sous forme de paires « clé-valeur » – une transaction de données. Nous l'avons combinée avec une nouvelle transaction, invokeScript, utilisée pour appeler une fonction invoquée dans la dApp depuis l'extérieur de la blockchain.
Le type de transaction de données que nous avons utilisé pendant le cours est l'ajout de coupons sur le marketplace :
letdatajson = {
"title": "t-shirt avec, vote 1",
"coupon_price": 10000000,
"old_price": 1000000000,
"new_price": 100000000,
"address": "Univers",
"description": "Je veux que tu fasses l'amour, pas la guerre, je sais que tu l'as déjà entendu",
"image": "https://bit.ly/2EXTghg"
}
it('add item', asyncfunction(){
letts = invokeScript({
dApp: dappAddress,
call:{
function:"addItem",
args:[
{ type:"string", value: datajson.title },
{ type:"integer", value: datajson.coupon_price },
{ type:"string", value: JSON.stringify(datajson) }
]},
payment: []
}, accountSupplierSeed)
lettx = awaitbroadcast(ts)
awaitwaitForTx(tx.id)
})Pour traiter ces données avec la fonction addItem et développer la fonction d'achat ainsi que d'autres options, nous avons utilisé une fonction appelable que l'utilisateur peut invoquer en dehors de la blockchain. En conséquence, elle peut effectuer diverses tâches, comme initier un transfert de fonds, enregistrer ou mettre à jour des données dans le stockage de données dApp, etc.
Voici un exemple de fonction appelable utilisée dans la fonction addItem :
@Callable(i)
funcaddItem(title: String, price: Int, data: String) = {
letsupplierAddress = toBase58String(i.caller.bytes)
letitem = getKeyItem(supplierAddress, title)
if( price <= 0) thenthrow("le montant d'achat ne peut pas être inférieur au prix de l'article")
elseif( getValueItemSupplier(item) !=NONE ) thenthrow("un article existe déjà")
else{
WriteSet([
DataEntry(getKeyItemSupplier(item), supplierAddress),
DataEntry(getKeyItemPrice(item), price),
DataEntry(getKeyItemData(item), data)
])
}
}Plus tard, nous avons développé un système de vote permettant de voter pour la promotion ou la suppression de certains produits. Pour éviter toute influence extérieure sur le processus de vote, il utilise un schéma ‘Commit-Reveal’.
La phase « commit » est utilisée pour collecter les votes chiffrés à l'aide d'une fonction de hachage et d'un « sel ».
La phase « reveal » est utilisée pour collecter les votes chiffrés et comparer leurs hachages.
Voici un exemple de fonction appelable utilisée ici :
@Callable(i)
funcvoteCommit(item: String, hash: String) = {
letuser = toBase58String(i.caller.bytes)
letcommits = getValueCommitsCount(item)
letstatus = getValueItemStatus(item)
if( commits >=VOTERS) thenthrow("nombre maximum de votants atteint")
elseif(getValueCommit(item, user) !=NONE) thenthrow("l'utilisateur a déjà participé")
elseif(getKeyItemSupplier(item) ==NONE) thenthrow("l'article n'existe pas")
elseif(status !=NONE && status !=VOTING) thenthrow("le vote n'est pas possible")
else{
WriteSet([
DataEntry(getKeyCommit(item, user), hash),
DataEntry(getKeyCommitsCount(item), commits +1),
DataEntry(getKeyItemStatus(item), if(commits ==VOTERS) thenREVEAL elseVOTING)
])
}
}
>Qu'avez-vous appris d'autre dans le cours ?
Le cours incluait également la tokenisation et les jetons non fongibles (NFT) – des jetons représentant quelque chose d'unique et donc non interchangeables.
La dernière session était consacrée aux oracles. Puisque la blockchain ne peut pas obtenir de données du monde extérieur, nous avons besoin d'oracles pour y envoyer ces données.
Pour notre place de marché, des oracles étaient nécessaires pour vérifier et, si besoin, bloquer un fournisseur qui, par exemple, n'a pas accepté un coupon vendu.
Voici un exemple :
funcgetExtValueItemWhiteListStatus(item:String) = {
item +"_verifier_status"
}
letverifier = "3Mx9qgMyMhHt7WUZr6PsaXNfmydxMG7YMxv"
letVERIFIED = "verified"
letBLACKLISTED = "blacklist"
@Callable(i)
funcsetstatus(supplier: String, status: String) = {
letaccount = toBase58String(i.caller.bytes)
if( account !=verifier ) thenthrow("only oracle verifier are able to manage whitelist")
elseif( status !=VERIFIED && status !=BLACKLISTED) thenthrow("wrong status")
else{
WriteSet([
DataEntry(getExtValueItemWhiteListStatus(supplier), status)
])
}
}
Qu'est-ce qui vous a été le plus utile ?
La partie la plus utile était les devoirs. Grâce à eux, le contenu des cours devenait plus compréhensible, et les connaissances récemment acquises étaient ancrées par des méthodes d'essai et d'erreur. Le travail pratique avec , et .
Comment prévoyez-vous d'utiliser ce que vous avez appris dans la pratique ?
Depuis le début, je m'attendais à ce que le cours aide à faire passer mon projet à un niveau supérieur. L'idée était maintenant d'écrire du code dans RIDE. La version existante a déjà des fonctionnalités de certification de documents, mais grâce à RIDE, elle peut être considérablement améliorée. La nouvelle version sera plus flexible et compréhensible, avec davantage de fonctionnalités, y compris la certification des courriels, des accords entre plusieurs parties, etc.
Le cours a également nourri ma réflexion, et j'ai eu beaucoup de nouvelles idées. Je suis convaincu que les résultats se manifesteront également à l'avenir.
Source : habr.com
