Разработчик Кристоф Вердо рассказывает об онлайн-курсе ‘Mastering Web 3.0 with Waves’, который он недавно прошел.
Расскажите немного о себе. Чем вас заинтересовал этот курс?
Я занимаюсь веб-разработкой около 15 лет, в основном, как фрилансер.
Разрабатывая веб-приложение долгосрочного регистра для развивающихся стран по заказу одной банковской группы, я столкнулся с задачей интеграции в него блокчейн-сертификации. В то время я не очень много знал о блокчейн-сертификации, хоть уже и интересовался крипто-технологиями – в основном, как инвестор.
В итоге эта функция не была реализована, но, задумавшись о том, что организации и банки заинтересованы в таком решении для своих приложений, я занялся изучением вопроса и скоро запустил проект Signature Chain.
Я разработал его бета-версию, которая уже доступна в основной сети. В то время [языка программирования Waves] Ride еще не было, и я делал все простейшим способом, используя транзакции перевода с вложенным JSON. Но основная цель была в том, чтобы добавить более продвинутый функционал после запуска Ride. И это – главная причина, по которой я присоединился к курсу: следующая стадия развития проекта предусматривала создание децентрализованного приложения (dApp).
Какие аспекты курса показались вам наиболее простыми и какие наиболее сложными?
Самым простым было то, что у нас было достаточно времени на все задания. Смысл курса — в том, чтобы научиться чему-то, а не соревноваться между собой. Объяснения были очень доступными, а иллюстрации – простыми, но исчерпывающими. Это помогло визуализировать и понять разные темы.
При выполнении заданий нас подталкивали к тому, чтобы мыслить независимо и иногда что-то самостоятельно изучать. Это – наилучший способ научиться чему-то и разобраться в идеях, рассматриваемых на занятиях.
Несколько раз я не полностью понимал теоретическую часть до тех пор, пока не начинал писать код, выполняя задание. Нам не разрешалось делать ‘copy/paste’, весь код нужно было писать самим, и это тоже помогало лучше во всем разобраться.
Самым сложным было то, что вопросы в задании с несколькими вариантами ответа были не всегда понятны. Мой английский не идеален, и вопросы были написаны человеком, не являющимся носителем языка, поэтому порой возникало недопонимание.
Возможно, часть курса, посвященная оракулам и NFT могла бы быть более подробной. Но, в любом случае, основная задача курса – заинтересовать разработчиков. Потом, чтобы полностью понять все его аспекты, нужно будет, конечно, потратить какое-то время на то, чтобы поэкспериментировать и попрактиковаться.
Расскажите подробнее о решении, над которым вы работали в течение всего курса – ‘Coupon Bazaar’? Можно также увидеть примеры кода?
Да, мы работали над ‘Coupon Bazaar’, это – маркетплейс, где люди продают и покупают купоны, дающие право купить товары и услуги по более низкой цене. Каждый купон представлен цифровым ассетом, который предполагает специальную скидку от поставщика.
Нужно было разработать несколько компонентов приложения. Во-первых, нужно было создать систему для регистрации поставщиков и управления купонами. Затем нужна была функция верификации и возможность поиска купонов пользователями.
Во время курса мы также добавили несколько новых функций, включая систему голосования и функцию, позволяющую верифицировать и вносить в черный список поставщиков.
Сначала мы изучили разницу между смарт-ассетами, смарт-аккаунтами и dApp-аккаунтами и основы работы с функциями верификатора. Функции верификатора позволяют изменять поведение аккаунта, заданное по умолчанию. По умолчанию они проверяют подписи транзакций, но функция верификатора позволяет задавать другие «правила».
Затем мы начали добавлять купоны. Мы использовали одну из важнейших функций dApp, позволяющую записывать в блокчейн данные любого типа в виде пар «ключ-значение» – транзакцию данных. Мы объединили ее с новой транзакцией, invokeScript, использующейся для вызова вызываемой функции в dApp извне блокчейна.
Тип транзакций данных, который мы использовали во время прохождения курса, это добавление купонов на маркетплейс:
Для обработки этих данных функцией addItem и разработки функции покупки и других опций мы использовали вызываемую функцию, которую пользователь может вызвать извне блокчейна. В результате она может выполнять различные задачи, например, инициировать передачу средств, записывать или обновлять данные в хранилище данных dApp и т.д.
Вот пример вызываемой функции, используемой в функции addItem:
Позднее мы разработали систему голосования, позволяющую отдавать голоса за продвижение или удаление определенных продуктов. Чтобы не допустить влияния извне на процесс голосования, она использует схему ‘Commit-Reveal’.
Фаза «commit» используется для сбора зашифрованных голосов с помощью хэш-функции и «соли».
Фаза «reveal» используется для сбора зашифрованных голосов и сравнения их хэшей.
Вот пример вызываемой функции, используемой здесь:
Что еще вы узнали из курса?
Курс также включал в себя токенизацию и non-fungible токены (NFT) – токены, представляющие что-либо уникальное и поэтому не взаимозаменяемые.
Последнее занятие было посвящено оракулам. Поскольку блокчейн не может получать данные из внешнего мира, нам нужны оракулы для отправки в него этих данных.
Для нашего маркетплейса оракулы были нужны, чтобы верифицировать и, при необходимости, внести в черный список поставщика, который, например, не принял проданный купон.
Вот пример:
Что было для вас наиболее полезным?
Самая полезная часть – это задания. Благодаря им материал лекций становился понятнее, а только что полученные знания закреплялись методом проб и ошибок. Очень полезна была и практическая работа с IDE, эксплорером и oракулами.
Как вы планируете использовать то, чему научились, на практике?
С самого начала я ожидал, что курс поможет вывести мой проект на новый уровень. Идея состояла в том, чтобы теперь написать код sign-web.app на RIDE. Существующая версия уже имеет функции сертификации документов, но, благодаря RIDE, ее можно будет значительно улучшить. Новая версия будет более гибкой и понятной, в ней будет больше функций, включая сертификацию электронных писем, соглашений между несколькими сторонами и т.д.
Курс также дал пищу для размышлений, и у меня появилось много новых идей. Я уверен, что результаты проявятся и в будущем.
Расскажите немного о себе. Чем вас заинтересовал этот курс?
Я занимаюсь веб-разработкой около 15 лет, в основном, как фрилансер.
Разрабатывая веб-приложение долгосрочного регистра для развивающихся стран по заказу одной банковской группы, я столкнулся с задачей интеграции в него блокчейн-сертификации. В то время я не очень много знал о блокчейн-сертификации, хоть уже и интересовался крипто-технологиями – в основном, как инвестор.
В итоге эта функция не была реализована, но, задумавшись о том, что организации и банки заинтересованы в таком решении для своих приложений, я занялся изучением вопроса и скоро запустил проект Signature Chain.
Я разработал его бета-версию, которая уже доступна в основной сети. В то время [языка программирования 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)
])
}
}
Что было для вас наиболее полезным?
Самая полезная часть – это задания. Благодаря им материал лекций становился понятнее, а только что полученные знания закреплялись методом проб и ошибок. Очень полезна была и практическая работа с IDE, эксплорером и oракулами.
Как вы планируете использовать то, чему научились, на практике?
С самого начала я ожидал, что курс поможет вывести мой проект на новый уровень. Идея состояла в том, чтобы теперь написать код sign-web.app на RIDE. Существующая версия уже имеет функции сертификации документов, но, благодаря RIDE, ее можно будет значительно улучшить. Новая версия будет более гибкой и понятной, в ней будет больше функций, включая сертификацию электронных писем, соглашений между несколькими сторонами и т.д.
Курс также дал пищу для размышлений, и у меня появилось много новых идей. Я уверен, что результаты проявятся и в будущем.