Создавайте и развертывайте кошельки с временной блокировкой на основе смарт-контрактов на блокчейне 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/