Deweloper Christophe Verdo opowiada o kursie online ‘’, który niedawno ukończył.

Opowiedz trochę o sobie. Co sprawiło, że zainteresował cię ten kurs?
Zajmuję się tworzeniem stron internetowych od około 15 lat, głównie jako freelancer.
Pracując nad aplikacją internetową długoterminowego rejestru dla krajów rozwijających się na zlecenie jednej grupy bankowej, napotkałem problem integracji certyfikacji blockchain. W tamtym czasie nie miałem zbyt wiele wiedzy na temat certyfikacji blockchain, mimo że interesowałem się kryptotechnologiami — głównie jako inwestor.
Ostatecznie ta funkcja nie została zrealizowana, ale, myśląc o tym, że organizacje i banki są zainteresowane takim rozwiązaniem dla swoich aplikacji, postanowiłem badać temat i wkrótce uruchomiłem projekt .
Opracowałem jego wersję beta, która jest już dostępna w głównej sieci. W tamtym czasie [języka programowania Waves] Ride jeszcze nie było, a ja robiłem wszystko w najprostszy sposób, używając transakcji przesyłania z osadzonym JSON. Ale głównym celem było dodanie bardziej zaawansowanej funkcjonalności po uruchomieniu Ride. I to jest główny powód, dla którego dołączyłem do kursu: następny etap rozwoju projektu zakładał stworzenie zdecentralizowanej aplikacji (dApp).
Jakie aspekty kursu uznałeś za najłatwiejsze, a jakie za najtrudniejsze?
Najłatwiejsze było to, że mieliśmy wystarczająco dużo czasu na wszystkie zadania. Sens kursu polega na tym, aby się czegoś nauczyć, a nie rywalizować ze sobą. Wyjaśnienia były bardzo przystępne, a ilustracje — proste, ale wyczerpujące. To pomogło zwizualizować i zrozumieć różne tematy.
Podczas wykonywania zadań byliśmy zachęcani do niezależnego myślenia i czasami samodzielnego badania. To jest najlepszy sposób, aby nauczyć się czegoś i zrozumieć idee omawiane na zajęciach.
Kilka razy nie rozumiałem całkowicie części teoretycznej, dopóki nie zacząłem pisać kodu, wykonując zadanie. Nie wolno nam było robić ‘copy/paste’, cały kod musiał być napisany samodzielnie, co również Pomagało lepiej wszystko zrozumieć.
Najtrudniejsze było to, że pytania w zadaniu z wieloma odpowiedziami nie zawsze były zrozumiałe. Mój angielski nie jest idealny, a pytania były napisane przez osobę, która nie jest native speakerem, dlatego czasem występowało nieporozumienie.
Może część kursu dotycząca orakli i NFT mogłaby być bardziej szczegółowa. Niemniej jednak, głównym celem kursu jest zainteresowanie programistów. Następnie, aby w pełni zrozumieć wszystkie jego aspekty, należy poświęcić trochę czasu na eksperymentowanie i praktykę.
Opowiedz więcej o projekcie, nad którym pracowałeś przez cały kurs – ‚Coupon Bazaar’? Czy możesz również pokazać przykłady kodu?
Tak, pracowaliśmy nad ‚Coupon Bazaar’, to jest marketplace, gdzie ludzie sprzedają i kupują kupony, które dają prawo do zakupu towarów i usług po niższej cenie. Każdy kupon jest reprezentowany jako cyfrowy zasób, który oferuje specjalną zniżkę od dostawcy.

Musieliśmy opracować kilka komponentów aplikacji. Po pierwsze, trzeba było stworzyć system rejestracji dostawców i zarządzania kuponami. Następnie potrzebna była funkcja weryfikacji i możliwość wyszukiwania kuponów przez użytkowników.

Podczas kursu dodaliśmy także kilka nowych funkcji, w tym system głosowania oraz funkcję umożliwiającą weryfikację i umieszczanie dostawców na czarnej liście.
Na początku omówiliśmy różnice między inteligentnymi zasobami, inteligentnymi kontami a kontami dApp oraz podstawy działania funkcji weryfikatora. Funkcje weryfikatora pozwalają na zmianę domyślnego zachowania konta. Domyślnie sprawdzają podpisy transakcji, ale funkcja weryfikatora pozwala ustalać inne „reguły”.
{-# 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
}
}Następnie zaczęliśmy dodawać kupony. Użyliśmy jednej z najważniejszych funkcji dApp, która pozwala na zapis danych dowolnego typu w blockchainie jako par „klucz-wartość” – transakcji danych. Połączyliśmy ją z nową transakcją, invokeScript, używaną do wywoływania funkcji z dApp z zewnątrz blockchaina.
Typ transakcji danych, który wykorzystaliśmy podczas kursu, to dodawanie kuponów do marketplace'u:
letdatajson = {
"title": "koszulka z , zagłosuj 1",
"coupon_price": 10000000,
"old_price": 1000000000,
"new_price": 100000000,
"address": "Wszechświat",
"description": "Chcę, żebyś kochał, a nie wojował, wiem, że już to słyszałeś",
"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)
})Aby przetworzyć te dane za pomocą funkcji addItem oraz opracować funkcję zakupu i inne opcje, wykorzystaliśmy funkcję wywoływaną, którą użytkownik może wywołać z zewnątrz blockchaina. W rezultacie może ona wykonywać różne zadania, takie jak inicjowanie transferu środków, zapisywanie lub aktualizowanie danych w magazynie danych dApp itp.
Oto przykład funkcji wywoływanej, używanej w funkcji addItem:
@Callable(i)
funcaddItem(title: String, price: Int, data: String) = {
letsupplierAddress = toBase58String(i.caller.bytes)
letitem = getKeyItem(supplierAddress, title)
if( price <= 0) thenthrow("kwota zakupu nie może być mniejsza niż cena przedmiotu")
elseif( getValueItemSupplier(item) !=NONE ) thenthrow("przedmiot już istnieje")
else{
WriteSet([
DataEntry(getKeyItemSupplier(item), supplierAddress),
DataEntry(getKeyItemPrice(item), price),
DataEntry(getKeyItemData(item), data)
])
}
}Później opracowaliśmy system głosowania, pozwalający na głosowanie na promowanie lub usunięcie określonych produktów. Aby zapobiec wpływowi zewnętrznemu na proces głosowania, wykorzystuje on schemat 'Commit-Reveal'.
Faza 'commit' służy do zbierania zaszyfrowanych głosów za pomocą funkcji hash oraz 'soli'.
Faza 'reveal' służy do zbierania zaszyfrowanych głosów i porównywania ich hashy.
Oto przykład funkcji wywoływanej, używanej tutaj:
@Callable(i)
funcvoteCommit(item: String, hash: String) = {
letuser = toBase58String(i.caller.bytes)
letcommits = getValueCommitsCount(item)
letstatus = getValueItemStatus(item)
if( commits >=VOTERS) thenthrow("osiągnięto maksymalną liczbę głosujących")
elseif(getValueCommit(item, user) !=NONE) thenthrow("użytkownik już uczestniczył")
elseif(getKeyItemSupplier(item) ==NONE) thenthrow("przedmiot nie istnieje")
elseif(status !=NONE && status !=VOTING) thenthrow("głosowanie nie jest możliwe")
else{
WriteSet([
DataEntry(getKeyCommit(item, user), hash),
DataEntry(getKeyCommitsCount(item), commits +1),
DataEntry(getKeyItemStatus(item),if(commits ==VOTERS) thenREVEAL elseVOTING)
])
}
}
>Czego jeszcze nauczyłeś się podczas kursu?
Kurs obejmował również tokenizację oraz tokeny niewymienialne (NFT) – tokeny reprezentujące coś unikalnego i dlatego niezamienne.
Ostatnia lekcja była poświęcona turze. Ponieważ blockchain nie może pobierać danych z zewnętrznego świata, potrzebujemy oświetlania do przesyłania tych danych.
Na naszej giełdzie potrzebne były tury, aby zweryfikować i, w razie potrzeby, dodać do czarnej listy dostawcę, który na przykład nie przyjął sprzedanego kuponu.
Oto przykład:
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)
])
}
}
Co było dla Ciebie najbardziej przydatne?
Najbardziej przydatną częścią były zadania. Dzięki nim materiał wykładów stawał się bardziej zrozumiały, a świeżo zdobyta wiedza utrwalała się metodą prób i błędów. Bardzo przydatna była także praktyczna praca z , i .
Jak planujesz wykorzystać to, czego się nauczyłeś, w praktyce?
Od samego początku oczekiwałem, że kurs pomoże wprowadzić mój projekt na nowy poziom. Idea polegała na tym, aby teraz napisać kod w RIDE. Istniejąca wersja ma już funkcje certyfikacji dokumentów, ale dzięki RIDE można ją znacznie poprawić. Nowa wersja będzie bardziej elastyczna i przejrzysta, będzie miała więcej funkcji, w tym certyfikację e-maili, umów między wieloma stronami itd.
Kurs również dał mi do myślenia i pojawiło mi się wiele nowych pomysłów. Jestem pewien, że efekty pojawią się także w przyszłości.
Źródło: habr.com
