Создаем на Flow | Изучаем FCL — 9. Как передавать скриптам аргументы Options и аргументы Path
EgorMajj
Posted on July 1, 2022
Краткий обзор
В прошлый раз, когда мы рассказывали о том, как передавать аргументы в скриптах, мы намеренно опустили аргументы Optionals и Paths, чтобы снизить умственную нагрузку. Эти два аргумента по-прежнему важны и довольно часто встречаются, поэтому мы рассмотрим их в этом уроке.
После того, как вы выполните все примеры, описанные в этом посте, вы сможете:
- передавать любой аргумент Optional, независимо от его базового типа
- передавать Path аргументы
Но сначала давайте посмотрим, что это такое!
Теория
Optionals
- это что-то вроде кота Schroedinger в программировании: они могут представлять наличие или отсутствие значения, когда вы проверяете, что находится внутри. У опций есть два случая:
есть значение
есть nil
(ничего).
Один из примеров использования, где вы можете найти это полезным (который приходит мне на ум) - это когда вы хотите передать Dictionary {String: String?}
и хотите инициализировать некоторые строки пустыми значениями (по какой-либо причине 🤷♂️).
Paths
Аргументы могут быть использованы, когда вы хотите использовать или получить доступ к хранилищу учетных записей в своем скрипте или транзакции и не хотите жестко кодировать это значение, а хотите сделать его более гибким.
Рассмотрим некоторые распространенные Path /public/flowTokenVault
- это path к управлению доступом ресурса FLOW token Vault. С помощью этой специфической способности вы можете получить ссылку на этот ресурс, чтобы посмотреть его баланс или пополнить его токенами. Однако не все возможности одинаковы! Некоторые могут дать вам больше функциональности, а другие - меньше.
Вернемся к нашей функции. Если вы посмотрите на нее, то увидите, что она состоит из двух частей:
-
/public - это называется
domain
. - /flowTokenVault - а это идентификатор.
Технически символ /
является разделителем, но я думаю, что проще увидеть это так 😉.
Существует только три допустимых domain: storage
, private
и public
. Во всех скриптах вы будете использовать public
domain - поскольку он не позволит вам получить доступ к private
областям и областям storage
других учетных записей.
Давайте попробуем передать оба этих domain в некоторых скриптах! 💪
Шаг 1 - Установка
Добавьте "@onflow/fcl": "1.0.0"
в качестве зависимости
Шаг 2 - Настройка
Как и в прошлый раз импортируем необходимые методы и настраиваем FCL:
// Import methods from FCL
import { query, config } from "@onflow/fcl";
// Specify the API endpoint - this time we will use Mainnet
const api = "https://rest-mainnet.onflow.org";
// Configure FCL to use mainnet as the access node
config().put("accessNode.api", api);
Шаг 3 - Передача Path аргументов
Мы попытаемся передать 3 различных Path - PublicPath
, PrivatePath
и StoragePath
- каждый для соответствующего domain:
// Path Arguments
const passPathArgument = async () => {
const cadence = `
pub fun main(public: PublicPath, private: PrivatePath, storage: StoragePath): PrivatePath{
// we can return any value, but let's return one of the Paths to see
// how FCL decodes it into value
return private
}
`;
// Since we are not gonna use any of those for actual data access
// we can construct any paths we like
// this one will encode "/public/flowTokenVault"
const publicPath = {
domain: "public",
identifier: "flowTokenVault"
};
// encode "/private/flowTokenVault"
const privatePath = {
domain: "private",
identifier: "flowTokenVault"
};
// encode "/storage/flowTokenVault"
const storagePath = {
domain: "storage",
identifier: "flowTokenVault"
};
// Notice that t.Path is not a function, but a constant!
const args = (arg, t) => [
arg(publicPath, t.Path),
arg(privatePath, t.Path),
arg(storagePath, t.Path)
];
const result = await query({ cadence, args });
console.log({ result });
};
Обратите внимание, что t.Path
является постоянным, несмотря на то, что мы передаем объект 🤪.
Шаг 4 - Передача Optional целому числу
Чтобы передать Optional, нам нужно обернуть тип в вызов t.Optional()
. Вот и все 😊.
// Optionals
const passOptionalIntegers = async () => {
const cadence = `
pub fun main(a: Int?): Int?{
return a
}
`;
// We will set value of our Int argument to null to check that script works correctly
const a = null;
const args = (arg, t) => [arg(a, t.Optional(t.Int))];
const result = await query({ cadence, args });
console.log({ result });
};
Шаг 5 - Pass других Optional типов
По аналогии с нашей первоначальной статьей об аргументах, давайте передадим другие типы Optional все сразу:
const passMultiOptional = async () => {
const cadence = `
pub fun main(a: String?, b: Bool?, c: UFix64?, d: Address?): Address?{
return d
}
`;
// it's perfectly fine to pass non-nil values alongside "empty"
const a = "Hello";
const b = null;
const c = null;
const d = "0x01";
// Note the types are the same as we specify in Cadence code
const args = (arg, t) => [
arg(a, t.Optional(t.String)),
arg(b, t.Optional(t.Bool)),
arg(c, t.Optional(t.UFix64)),
arg(d, t.Optional(t.Address))
];
const result = await query({ cadence, args });
console.log({ result });
showResult("multiple", result);
};
Шаг 6 - Pass Optional Array и Array of Optionals
Разница между ними заключается в цели для обертки t.Optional().
Вот array of Optionals:
const passArrayOfOptinalStrings = async () => {
const cadence = `
pub fun main(a: [String?]): String?{
return a[0]
}
`;
const a = ["Hello", null];
// Type of the argument is composed of t.Array, t.Optional and t.String
const args = (arg, t) => [arg(a, t.Array(t.Optional(t.String)))];
const result = await query({ cadence, args });
console.log({ result }); //
};
А этот для опционального массива Strings:
const passOptionalArray = async () => {
const cadence = `
pub fun main(a: [String]?): String?{
if let arr = a {
return arr[0]
}
return nil
}
`;
const a = null;
// This time we will wrap our array in "t.Optional()" call
const args = (arg, t) => [arg(a, t.Optional(t.Array(t.String)))];
const optionalArray = await query({ cadence, args });
console.log({ optionalArray }); //
};
Шаг 7 - Передача Dictionary с Optional значениями
const passDictionaryOfOptionals = async () => {
// In this example we will pass a Cadence Dictionary as argument
// keys will be of type "String" and values will be Optionals of type "Int?"
const cadence = `
pub fun main(a: {String: Int?}): Int??{
return a["amount"]
}
`;
// Dictionaries should be represented as array of key/value pairs of respective types
// Note that we shall pass numeric value as string here
const a = [{ key: "amount", value: "42" }];
// Dictionary type is composed out of t.Dictionary, t.String and t.Int for our case
const args = (arg, t) => [
arg(a, t.Dictionary({ key: t.String, value: t.Optional(t.Int) }))
];
const result = await query({ cadence, args });
console.log({ result });
};
💡 Вы заметили, что скрипт в последнем примере возвращает Double Optional
Int(?)
. ? Это потому, что значение по ключуamount
может не существовать, поэтому он вернет намMaybe(Maybe(Int))
- вам нужно будет развернуть его дважды, если вы хотите использовать его позже в коде 😉
Заключение
Давайте добавим IIFE в конец файла и заполним его методами, которые мы только что определили:
(async () => {
console.clear();
// Path arguments
await passPathArgument();
// Optional arguments
await passOptionalIntegers();
await passMultiOptional();
await passArrayOfOptinalStrings();
await passOptionalArray();
await passDictionaryOfOptionals();
})();
Через несколько 🎇 мгновений после этого вы должны увидеть вывод в журнале консоли:
{result: Object}
result: {
domain: "private",
identifier: "flowTokenVault"
}
{result: null}
{result: "0x0000000000000001"}
{result: "Hello"}
{optionalArray: null}
{result: "42"}
Вы сделали это - теперь эти типы не являются для вас испытанием! 💪
Надеюсь, информация в этом посте будет полезной, и вы вернетесь за новыми материалами 😉.
До следующего раза! 👋
Информационные ресурсы
- Полный исходный код - https://codesandbox.io/s/dev-to-fcl-09-optional-arguments-vt0d11
- Cadence: Optionals - https://docs.onflow.org/cadence/language/values-and-types/#optionals
- *Cadence: Paths *- https://docs.onflow.org/cadence/language/accounts/#paths
- Cadence: Возможности - https://docs.onflow.org/cadence/language/capability-based-access-control
Другие источники, которые могут быть вам полезны:
- (ENG) | Документация Flow - https://docs.onflow.org/ - более детальная информации о блокчейне Flow и как взаимодействовать с ним
- (ENG) | Flow Portal - https://flow.com/ - your entry point to Flow
- (ENG) | FCL JS - https://github.com/onflow/fcl-js - Исходный код и возможность поучаствовать в разработке библиотеки FCL JS library
- (ENG) | Cadence - https://docs.onflow.org/cadence/ - Введение в язык программирования Cadence
- Codesandbox - https://codesandbox.io - Замечательная среда разработки и прототипирования прямо в вашем браузере
Posted on July 1, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.