
Расскажите немного о себе. Чем вас заинтересовал этот курс?
Я занимаюсь веб-разработкой около 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, ее можно будет значительно улучшить. Новая версия будет более гибкой и понятной, в ней будет больше функций, включая сертификацию электронных писем, соглашений между несколькими сторонами и т.д.
Курс также дал пищу для размышлений, и у меня появилось много новых идей. Я уверен, что результаты проявятся и в будущем.
ссылка на оригинал статьи https://habr.com/ru/company/waves/blog/462831/
Добавить комментарий