Создавайте и развертывайте кошельки с временной блокировкой на основе смарт-контрактов на блокчейне Zilliqa.

Во второй части руководства мы создадим пользовательский интерфейс с помощью React.js для взаимодействия с блокчейном и смарт-контрактами. Если вы не читали первую часть, то сделайте это по этой ссылке.

Статья нацелена на то, чтобы охватить только важные функции, а не полный дизайн пользовательского интерфейса, но рабочий код доступен в этом репозитории GitHub.

Создание нового кошелька с временной блокировкой

Модальное окно CreateWallet имеет 2 поля ввода, то есть получателя и дату разблокировки. Если вы помните определение контракта TimeLockedWallet, у него есть 2 параметра, кроме владельца, который нам нужно ввести создателем кошелька.

contract TimeLockedWallet(owner: ByStr20, beneficiary: ByStr20, num_blocks: Uint32)

Контракт предполагает параметр num_blocks типа Uint32, но в нашем пользовательском интерфейсе у нас есть средство выбора даты и времени. Итак, давайте напишем функции для преобразования даты в соответствующий предполагаемый номер блока.

No. of Blocks = ( Difference between the selected date & current time (seconds) / No. of seconds it takes to mine a block )

Приведенная выше функция запрашивает у блокчейна частоту блоков, используя getTxBlockRate(), которая возвращает количество блоков в секунду.

Теперь мы можем рассчитать количество блоков, которое потребуется для достижения выбранной даты/времени (d1). Разница между выбранной датой и текущим временем в секундах, умноженная на частоту блоков, вернет расчетное количество блоков, необходимых для достижения определенной даты.

Обратите внимание, что вычисление даты и времени на самом деле является оценочным значением, поскольку нет возможности получить текущую временную метку в контрактах scilla из-за проблем безопасности, которые могут возникнуть, как описано в части 1 статьи.

Программное развертывание контракта

Как упоминалось в части 1, новый контракт будет развернут для каждого создания кошелька. Теперь, когда у нас есть параметры num_blocks, beneficiary и owner, необходимые для создания контракта, давайте развернем контракт из кода.

Массив инициализации должен иметь обязательное значение _scilla_version вместе с owner(taken from the react context set during the login) , beneficiary и num_blocks

Поскольку мы развертываем контракт из кода, scillaContractCode в файлеconstants.js инициализируется кодом scilla, который мы написали в части 1.

После того, как объект контракта создан, нам нужно вызвать deploy() со значениями газа и подождать, пока обещание не будет разрешено. Возвращенный массив [tx, ct] содержит транзакцию и развертываемый контракт. ct.address будет содержать адрес создаваемого нового контракта.

Обновление TimeLockedWalletsStore

Если развертывание контракта прошло успешно, теперь мы можем обновить контракт хранилища кошелька, который мы создали и развернули в части 1.

Функция upateWalletStore вызывает AddNewWallet переход контракта с вновь созданным адресом контракта и адресом получателя в соответствии с определением.

transition AddNewWallet(contract_addr: ByStr20, beneficiary: ByStr20)

Константа WALLETSTORE_CONTRACT_ADDR содержит адрес контракта TimeLockedWalletsStore.scilla, который мы изначально развернули в части 1. (Пример: https://viewblock.io/zilliqa/address/ zil13mh3yq8lnnwqd45f3kg8claflxpjvmhwvcrk2x?network=testnet)

Обратите внимание, что в обоих приведенных выше вызовах контракта TranID возвращается, но не запрашивается квитанция? Чтобы проверить получение вызова, вспомогательная функция ниже опрашивает получение каждые 4 секунды и возвращает подтверждение, когда обещание разрешается.

Пополнение кошелька

Теперь, когда мы создали кошелек с временной блокировкой, мы можем отправлять/пополнять средства в кошелек.

Поскольку мы имеем дело со смарт-контрактами, которые действуют как кошельки с временной блокировкой, мы не можем отправлять средства на адрес напрямую, как обычно делаем с обычными кошельками. По этой причине запись перехода DepositFunds с оператором accept в контракте TimeLockedWallet.

В приведенной выше функции развернутый контракт назначается walletStoreContract, и мы просто вызываем переход DepositFunds с пустым массивом, поскольку он не ожидает никаких параметров. Так как мы отправляем средства на контракт, нам нужно отправить введенную сумму ZIL в Qaединицах.

const amount = units.toQa(depositZilAmount, units.Units.Zil);

Обновить дату разблокировки

Обновление даты разблокировки на самом деле не является обязательной функцией для таких кошельков с временной блокировкой. Но в целях тестирования и в случае изменения среднего времени блокировки реализована возможность изменения даты разблокировки.

Как и в предыдущем вызове контракта, в этой функции мы вызываем переход ChangeTargeBlock с параметром new_num_blocks, чтобы установить новый номер блока разблокировки.

Поскольку мы вычисляем номер блока, соответствующий выбранной дате/времени, мы вызываем нашу вспомогательную функцию calculateNumBlocks, которую мы ранее написали, в событии onChange средства выбора даты/времени.

<input type='datetime-local' onChange={onDateChange}/>

Отображение кошельков

Мои бенефициары

Это кошельки, созданные авторизованным пользователем.

Эти данные запрашиваются из состояния контракта TimeLockedWalletsStore, который мы изначально развернули в части 1.

Вместо того, чтобы запрашивать все состояние контракта, можно вызвать getSubState(), чтобы получить только обязательные поля, в нашем случае wallet_infoMap.

Теперь, когда у нас есть сопоставления, мы можем отфильтровать карту, чтобы построить строки таблицы.

Функция также вызывает await window.zilPay.blockchain.getLatestTxBlock(); для получения информации о последнем блоке. Это необходимо для преобразования номера блока, хранящегося в контракте, обратно в дату/время для отображения.

Мои кошельки

Это кошельки, которые другие создали для вошедшего в систему пользователя.

Функции почти такие же, как и предыдущая функция, но карта wallet_info фильтруется по-другому, чтобы получить кошельки, созданные для вошедшего в систему пользователя.

И это завершение серии статей о создании кошельков с временной блокировкой с помощью Scilla на блокчейне Zilliqa. Теперь, когда мы рассмотрели все важные строительные блоки, осталось собрать их воедино.

Пожалуйста, обратитесь к полному рабочему коду из репозитория GitHub.

Демонстрация: https://timelocked-wallet-zilliqa-blockchain.vercel.app/ (работает только в тестовой сети)

Удачного программирования!!

Свяжитесь со мной в Twitter или LinkedIn, Ура!!

использованная литература

Github Repo — https://github.com/oshanfernando/timelocked-wallet-zilliqa-blockchain

Официальный сайт Zilliqa — https://www.zilliqa.com/

Сцилла — https://scilla.readthedocs.io/

Изучайте Scilla — https://learnscilla.com/

Программирование Scilla — https://www.youtube.com/c/IvanonTech/search?query=scilla

Руководство разработчика ZilPay — https://zilpay.github.io/zilpay-docs/

Zilliqa-js — https://github.com/Zilliqa/Zilliqa-JavaScript-Library

IDE Neo Savant — https://ide.zilliqa.com/#/

ZilPay — https://zilpay.io/