Разработчик Кристоф Вердо рассказывает об онлайн-курсе ‘
Расскажите немного о себе. Чем вас заинтересовал этот курс?
Я занимаюсь веб-разработкой около 15 лет, в основном, как фрилансер.
Разрабатывая веб-приложение долгосрочного регистра для развивающихся стран по заказу одной банковской группы, я столкнулся с задачей интеграции в него блокчейн-сертификации. В то время я не очень много знал о блокчейн-сертификации, хоть уже и интересовался крипто-технологиями – в основном, как инвестор.
В итоге эта функция не была реализована, но, задумавшись о том, что организации и банки заинтересованы в таком решении для своих приложений, я занялся изучением вопроса и скоро запустил проект
Я разработал его бета-версию, которая уже доступна в основной сети. В то время [языка программирования Waves] Ride еще не было, и я делал все простейшим способом, используя транзакции перевода с вложенным JSON. Но основная цель была в том, чтобы добавить более продвинутый функционал после запуска Ride. И это – главная причина, по которой я присоединился к курсу: следующая стадия развития проекта предусматривала создание децентрализованного приложения (dApp).
Какие аспекты курса показались вам наиболее простыми и какие наиболее сложными?
Самым простым было то, что у нас было достаточно времени на все задания. Смысл курса — в том, чтобы научиться чему-то, а не соревноваться между собой. Объяснения были очень доступными, а иллюстрации – простыми, но исчерпывающими. Это помогло визуализировать и понять разные темы.
При выполнении заданий нас подталкивали к тому, чтобы мыслить независимо и иногда что-то самостоятельно изучать. Это – наилучший способ научиться чему-то и разобраться в идеях, рассматриваемых на занятиях.
Несколько раз я не полностью понимал теоретическую часть до тех пор, пока не начинал писать код, выполняя задание. Нам не разрешалось делать ‘copy/paste’, весь код нужно было писать самим, и это тоже помогало лучше во всем разобраться.
Самым сложным было то, что вопросы в задании с несколькими вариантами ответа были не всегда понятны. Мой английский не идеален, и вопросы были написаны человеком, не являющимся носителем языка, поэтому порой возникало недопонимание.
Возможно, часть курса, посвященная оракулам и NFT могла бы быть более подробной. Но, в любом случае, основная задача курса – заинтересовать разработчиков. Потом, чтобы полностью понять все его аспекты, нужно будет, конечно, потратить какое-то время на то, чтобы поэкспериментировать и попрактиковаться.
Расскажите подробнее о решении, над которым вы работали в течение всего курса – ‘Coupon Bazaar’? Можно также увидеть примеры кода?
Да, мы работали над ‘Coupon Bazaar’, это – маркетплейс, где люди продают и покупают купоны, дающие право купить товары и услуги по более низкой цене. Каждый купон представлен цифровым ассетом, который предполагает специальную скидку от поставщика.
Нужно было разработать несколько компонентов приложения. Во-первых, нужно было создать систему для регистрации поставщиков и управления купонами. Затем нужна была функция верификации и возможность поиска купонов пользователями.
Во время курса мы также добавили несколько новых функций, включая систему голосования и функцию, позволяющую верифицировать и вносить в черный список поставщиков.
Сначала мы изучили разницу между смарт-ассетами, смарт-аккаунтами и dApp-аккаунтами и основы работы с функциями верификатора. Функции верификатора позволяют изменять поведение аккаунта, заданное по умолчанию. По умолчанию они проверяют подписи транзакций, но функция верификатора позволяет задавать другие «правила».
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
letownerPublicKey = base58'H8ndsHjBha6oJBQQx33zqbP5wi8sQP7hwgjzWUv3q95M'
@Verifier(tx)
funcverify() = {
matchtx {
cases: SetScriptTransaction=>sigVerify(tx.bodyBytes, tx.proofs[0], ownerPublicKey)
cased: 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": "I want you to make love, not war, i know you've heard it before",
"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("purchase amount cannot be less than item price")
elseif( getValueItemSupplier(item) !=NONE ) thenthrow("an item is already exist")
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("reached max num of voters")
elseif(getValueCommit(item, user) !=NONE) thenthrow("user has already participated")
elseif(getKeyItemSupplier(item) ==NONE) thenthrow("item does not exist")
elseif(status !=NONE && status !=VOTING) thenthrow("voting is not possible")
else{
WriteSet([
DataEntry(getKeyCommit(item, user), hash),
DataEntry(getKeyCommitsCount(item), commits +1),
DataEntry(getKeyItemStatus(item),if(commits ==VOTERS) thenREVEAL elseVOTING)
])
}
}
>
Что еще вы узнали из курса?
Курс также включал в себя токенизацию и non-fungible токены (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)
])
}
}
Что было для вас наиболее полезным?
Самая полезная часть – это задания. Благодаря им материал лекций становился понятнее, а только что полученные знания закреплялись методом проб и ошибок. Очень полезна была и практическая работа с
Как вы планируете использовать то, чему научились, на практике?
С самого начала я ожидал, что курс поможет вывести мой проект на новый уровень. Идея состояла в том, чтобы теперь написать код
Курс также дал пищу для размышлений, и у меня появилось много новых идей. Я уверен, что результаты проявятся и в будущем.
Источник: habr.com