Разработчикът Кристоф Вердо разказва за онлайн курса ‘’, който наскоро завърши.

Разкажете малко за себе си. Какво ви привлече към този курс?
Работя в уеб разработката около 15 години, основно като фрилансер.
Разработвайки уеб приложение за дългосрочна регистрация за развиващи се страни по поръчка на една банкова група, се сблъсках със задачата за интегриране на блокчейн сертификация. В този период не знаех много за блокчейн сертификацията, въпреки че се интересувах от крипто технологии – основно като инвеститор.
В крайна сметка тази функция не беше реализирана, но след като си помислих, че организациите и банките биха се заинтересували от таково решение за техните приложения, започнах да проучвам въпроса и скоро стартирах проект .
Разработих бета версията, която вече е налична в основната мрежа. По това време [язык програмирования Waves] Ride все още не беше наличен, и правех всичко по най-простия начин, използвайки транзакции с вложен JSON. Но основната цел беше да добавя по-напредничав функционал след старта на Ride. И това е основната причина, поради която се присъединих към курса: следващата фаза на развитие на проекта предвиждаше създаването на децентрализирано приложение (dApp).
Кои аспекти от курса ви се сториха най-лесни и кои най-трудни?
Най-лесното беше, че имахме достатъчно време за всички задания. Същността на курса е да се научим на нещо, а не да се състезаваме помежду си. Обясненията бяха много достъпни, а илюстрациите – простички, но изчерпателни. Това помогна да визуализираме и разберем различни теми.
При изпълнението на заданията ни насърчаваха да мислим независимо и понякога да проучваме нещо сами. Това е най-добрият начин да научите нещо и да разберете идеите, разглеждани в занятията.
Няколко пъти не разбирах напълно теоретичната част, докато не започнех да пиша код, изпълнявайки задачата. Не ни беше позволено да правим ‘copy/paste’, целият код трябваше да бъде написан от мен, и това също помагаше да разберем всичко по-добре.
Най-трудната част беше, че въпросите в задачата с множество варианти за отговор не винаги бяха ясни. Английският ми не е идеален и въпросите бяха написани от човек, който не е носител на езика, затова понякога имаше недоразумения.
Възможно е частта от курса, посветена на оракулите и NFT, да бъде по-подробна. Но всяка ситуация е различна и основната задача на курса – да привлече вниманието на разработчиците. След това, за да разберем напълно всички аспекти, ще трябва да прекараме известно време, експериментирайки и практикувайки.
Разкажете повече за решението, над което работихте през целия курс – 'Coupon Bazaar'? Може ли да видим и примери за код?
Да, работихме над 'Coupon Bazaar', това е маркетплейс, където хората продават и купуват купони, които дават право на закупуване на стоки и услуги на по-ниски цени. Всеки купон е представен като цифров актив, който предполага специална отстъпка от доставчика.

Беше необходимо да разработим няколко компонента на приложението. Първо, трябваше да създадем система за регистрация на доставчици и управление на купони. След това беше нужна функция за верификация и възможност за търсене на купони от потребителите.

По време на курса добавихме и няколко нови функции, включително система за гласуване и функция, която позволява верификация и блокиране на доставчици.
Първо изучихме разликата между смарт активите, смарт акаунтите и dApp акаунтите, както и основите на работата с функциите на верификатора. Функциите на верификатора позволяват промяна на поведението на акаунта по подразбиране. По подразбиране те проверяват подписите на транзакциите, но функцията на верификатора позволява задаване на други „правила“.
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let ownerPublicKey = base58'H8ndsHjBha6oJBQQx33zqbP5wi8sQP7hwgjzWUv3q95M'
@Verifier(tx)
func verify() = {
match tx {
cases: SetScriptTransaction=> sigVerify(tx.bodyBytes, tx.proofs[0], ownerPublicKey)
case: DataTransaction=> true
case_ => false
}
}След това започнахме да добавяме купони. Използвахме една от най-важните функции на dApp, която позволява записване на данни в блокчейна от всякакъв тип под формата на пары „ключ-стойност“ – транзакция на данни. Сливахме я с нова транзакция, invokeScript, използваща се за извикване на функции в dApp от външната страна на блокчейна.
Типът данъчни транзакции, който използвахме по време на курса, е добавяне на купони на маркетплейса:
letdatajson = {
"title": "t-shirt with , vote 1",
"coupon_price": 10000000,
"old_price": 1000000000,
"new_price": 100000000,
"address": "Universe",
"description": "Искам да правите любов, а не война, знам, че сте го чули преди",
"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)
})За обработка на тези данни с функцията addItem и разработване на функция за покупка и други опции, използвахме извикваема функция, която потребителят може да извика извън блокчейна. В резултат тя може да изпълнява различни задачи, например иницииране на прехвърляне на средства, записване или обновяване на данни в хранилището на dApp и т.н.
Ето пример за извикваема функция, използвана във функцията addItem:
@Callable(i)
funcaddItem(title: String, price: Int, data: String) = {
letsupplierAddress = toBase58String(i.caller.bytes)
letitem = getKeyItem(supplierAddress, title)
if( price <= 0) thenthrow("сума за покупка не може да бъде по-малка от цената на артикула")
elseif( getValueItemSupplier(item) !=NONE ) thenthrow("арт. вече съществува")
else{
WriteSet([
DataEntry(getKeyItemSupplier(item), supplierAddress),
DataEntry(getKeyItemPrice(item), price),
DataEntry(getKeyItemData(item), data)
])
}
}По-късно разработихме система за гласуване, позволяваща даване на гласове за промоция или премахване на определени продукти. За да се избегне влияние извън процеса на гласуване, тя използва схема „Commit-Reveal”.
Фазата „commit” се използва за събиране на криптирани гласове чрез хеш-функция и „сол”.
Фазата „reveal” се използва за събиране на криптирани гласове и сравняване на техните хешове.
Ето пример за извикваема функция, използвана тук:
@Callable(i)
funcvoteCommit(item: String, hash: String) = {
letuser = toBase58String(i.caller.bytes)
letcommits = getValueCommitsCount(item)
letstatus = getValueItemStatus(item)
if( commits >=VOTERS) thenthrow("достигната е максималната бройка гласоподаватели")
elseif(getValueCommit(item, user) !=NONE) thenthrow("потребителят вече е участвал")
elseif(getKeyItemSupplier(item) ==NONE) thenthrow("арт. не съществува")
elseif(status !=NONE && status !=VOTING) thenthrow("гласуването не е възможно")
else{
WriteSet([
DataEntry(getKeyCommit(item, user), hash),
DataEntry(getKeyCommitsCount(item), commits +1),
DataEntry(getKeyItemStatus(item),if(commits ==VOTERS) thenREVEAL elseVOTING)
])
}
}
>Какво друго научихте от курса?
Курсът включваше токенизация и нефунгируеми токени (NFT) – токени, представляващи нещо уникално и поради това не заместващи се.
Последният урок беше посветен на оракулите. Понеже блокчейн не може да получава данни от външния свят, се нуждаем от оракулите, за да изпратим тези данни в него.
За нашия маркетплейс оракулите бяха нужни, за да верифицират и, при необходимост, да добавят в черния списък доставчик, който, например, не е приел продаден купон.
Ето един пример:
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)
])
}
}
Какво беше най-полезно за вас?
Най-полезната част бяха задачите. Благодарение на тях материалът от лекциите стана по-разбираем, а новооткритите знания се затвърдиха чрез проби и грешки. Много полезна беше и практическата работа с , и .
Как възнамерявате да приложите наученото на практика?
От самото начало очаквах курсът да помогне да изкарам моят проект на ново ниво. Идеята беше да напиша код на RIDE. Съществуващата версия вече има функции за сертифициране на документи, но благодарение на RIDE ще може да бъде значително подобрена. Новата версия ще бъде по-гъвкава и разбираема, ще има повече функции, включително сертифициране на електронни писма, споразумения между няколко страни и др.
Курсът също така подхрани мислите ми и получих много нови идеи. Уверен съм, че резултатите ще се проявят и в бъдеще.
Източник: habr.com
