Обзор
В этом посте мы узнаем:
- Роли подписания —
payer
,proposer
иauthorizers
. - Что такое функция подписания и как ее создать
- Как подписать транзакцию с помощью одного из ваших кошельков
- Как подписать транзакцию своим закрытым ключом
Предисловие
Как только у нас есть кошелек или приватные ключи, мы можем начать подписывать транзакции. Ух ты!
Чтобы лучше понять, как это работает, вам понадобятся некоторые дополнительные знания.
Процесс подписания на Flow требует, чтобы транзакцию подписали 3 разные стороны:
💡Все эти роли может выполнять одна и та же учетная запись! Вам не нужно иметь 3 «актера» для подписания транзакции 😅.
Шаг 1 — Установка
Добавьте "@onflow/fcl": "1.0.0"
в качестве зависимости.
Шаг 2 — Установка
Как и в прошлый раз, мы импортируем необходимые методы и настроим FCL. На этот раз, однако, мы расширим нашу конфигурацию некоторыми новыми значениями, чтобы включить функцию Wallet Discovery.
FCL Wallet Discovery
позволяет вам подключиться ко всем известным и зарегистрированным кошелькам сразу! Если вы пришли из Ethereum, вы можете думать об этом как о Flow варианте WalletConnect без поддержки multichain 😅.
Обратите внимание, что мы используем немного другой способ указания конфига, передавая объект вместо вызова нескольких вызовов .put
:
// Import methods from FCL
import { query, config } from "@onflow/fcl";
// Configure FCL
config({
// Use Testnet Access Node
"accessNode.api": "https://rest-testnet.onflow.org",
// We will also specify the network as some of the FCL parts need it to properly do it's work
"flow.network": "testnet",
// This will be the title of our DApp
"app.detail.title": "Meow DApp",
// This is just a kitten photo, we will use for the icon
"app.detail.icon": "https://placekitten.com/g/200/200",
// Next two will define where Wallet Discovery is located
"discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn",
"discovery.authn.endpoint":
"https://fcl-discovery.onflow.org/api/testnet/authn",
// We will also set alias for the contract we will use in this example
"0xBasic": "0xafabe20e55e9ceb6"
});
Вы можете прочитать более подробную информацию об этих и других ключах конфигурации на странице документации FCL
Шаг 3 — Получение текущего состояния цепи
Мы развернули контракт Basic по адресу 0xafabe20e55e9ceb6
. Если вы нажмете на эту ссылку, она приведет вас к Flow View Source. Вы видите, что там есть одна публичная переменная counter
, которую мы можем прочитать, и пара методов для ее изменения. Давайте воспользуемся знаниями из предыдущих статей и прочитаем ее.
const readCounter = async () => {
const cadence = `
import Basic from 0xBasic
pub fun main():UInt{
return Basic.counter
}
`;
const counter = await query({ cadence });
console.log({ counter });
};
Этот простой запрос выглядит точно так же, как и те, что мы строили раньше, только на этот раз мы используем псевдоним 0xBasic
для адреса. FCL будет использовать значение, которое мы задали в конфигурации — 0xafabe20e55e9ceb6
— и заменит его. Мы делаем это таким образом, потому что мы будем обращаться к контракту и из нашей транзакции. Таким образом, у нас есть это значение в одном месте, и нам не нужно постоянно ссылаться на него или запоминать его 😉.
Вы должны увидеть в консоли вывод, похожий на этот (число может быть другим, так как есть несколько пользователей, которые захотят его изменить):
{counter: "19"}
Шаг 4 — Изменение счетчика
Для изменения состояния цепочки мы воспользуемся методом mutate
, предоставляемым пакетом FCL. В своей базовой форме mutate
очень похож на query
, но он использует некоторые скрытые механизмы для подписания транзакции (мы разберем их в следующей статье).
Давайте определим еще один метод shiftCounter
, который мы будем использовать для изменения значения counter
. Если вы вернетесь к контракту Basic
, то увидите, что в нем определены два метода. Мы будем использовать incrementCounterBy(_ step: UInt8)
.
Нам нужно будет передать значение UInt8
в качестве аргумента транзакции — мы сделаем это так же, как делали ранее, используя метод query
.
const shiftCounter = async (value) => {
// Our Cadence code. Notice we are using alias here as well
const cadence = `
import Basic from 0xBasic
transaction(shift: UInt8){
prepare(signer: AuthAccount){
Basic.incrementCounterBy(shift)
}
}
`;
// List of arguments
const args = (arg, t) => [
// We need to pass UInt8 value, but it should be a string, remember? :)
arg(value.toString(), t.UInt8)
];
// "mutate" method will return us transaction id
const txId = await mutate({
cadence,
args,
limit: 999
});
// We will use transaction id in order to "subscribe" to it's state change and get the details
// of the transaction
const txDetails = await tx(txId).onceSealed();
return txDetails
};
Подождите, а как же те роли, о которых мы упоминали выше. Видите ли, mutate
заполнит их все текущим аутентифицированным пользователем…
Это часть магии FCL и Wallet Discovery 🎇. Если вы не укажете никакой роли в методе mutate
, он попросит вас подключиться к кошельку, а затем использовать выбранную учетную запись в качестве текущего пользователя. Затем он будет использовать все необходимые параметры для заполнения ролей в этом взаимодействии. Довольно круто, да? 😎
Наконец
Давайте добавим IIFE в конец файла и заполним его методами, которые мы только что определили:
(async () => {
console.clear();
// You can [un]comment this line to toggle Wallet Discovery
unauthenticate();
// Let's read value, currently set on contract
await readCounter();
// Let's modify the state now
const txDetails = await shiftCounter(13);
console.log({ txDetails });
// Now we can check that value is actually changed
await readCounter();
})();
Когда код на странице будет выполнен, он представит вам всплывающее окно, позволяющее выбрать, какой кошелек использовать.
⚠️ Чтобы кошелек появился в списке, у вас должен быть установлен Lilico. О том, как установить и настроить Lilico, читайте в одной из наших предыдущих статей.
Если вы выберете Lilico
, перед вами откроется следующий процесс. Сначала вам будет предложено подключить кошелек к нашему dapp:
Затем попросит подтверждение. Вы можете развернуть/свернуть панель скриптов, чтобы проверить код транзакции.
💡 На самом деле, вы должны ВСЕГДА проверять, что вы подписываете. Даже в Testnet. Это хорошая привычка, которая поможет вам сделать ваше взаимодействие с Flow более безопасным 😉.
Blocto проведет вас через аналогичный процесс:
И у него также есть способ проверить код транзакции:
После всего сказанного и сделанного вы должны увидеть в консоли следующее (цифры могут меняться):
{ counter: "234" }
{ txDetails: Object }
{ counter: "247" }
Развернув txDetails
, вы получите больше информации о транзакции:
blockId: "ad7605f10f9846dd1c5603723b1d12995a3152b19a1ca24e47a3a2e28cee0641"
status: 4
statusString: "SEALED"
statusCode: 0
errorMessage: ""
events: Array(3)
До следующего раза! 👋
Ресурсы
- Полный исходный код — https://codesandbox.io/s/dev-to-part-13-modify-chain-state-1oy1l7
- FCL — метод
mutate
— https://docs.onflow.org/fcl/reference/api/#mutate - Cadence — транзакции — https://docs.onflow.org/cadence/language/transactions/
- Lilico Wallet — https://lilico.app/
Другие ресурсы, которые вы можете найти полезными:
- Flow Docs Site — https://docs.onflow.org/ — более подробная информация о блокчейне Flow и о том, как с ним взаимодействовать.
- Flow Portal — https://flow.com/ — ваша точка входа в Flow
- FCL JS — https://github.com/onflow/fcl-js — исходный код и возможность внести свой вклад в библиотеку FCL JS
- Cadence — https://docs.onflow.org/cadence/ — Введение в Cadence
- Codesandbox — https://codesandbox.io — удивительная браузерная IDE, позволяющая быстро создавать прототипы.