11B ethereum hardhat : Создать задачу

— вводить

— асинхронная функция

— Требования к действиям задачи

— Определение параметров

— Ограничения на позиционные параметры

— Валидации типов

— Переопределение задач

— Подзадачи

— учебники по hardhat , hardhat 教程

— Контакт 联系方式

— введение

В этом руководстве мы рассмотрим создание задач в Hardhat, которые являются основным компонентом, используемым для автоматизации.

Задача — это асинхронная функция JavaScript с некоторыми связанными метаданными. Эти метаданные используются Hardhat для автоматизации некоторых действий. Разбор аргументов, валидация и справочные сообщения — все это берется на себя.

Все, что вы можете сделать в Hardhat, определяется как задача. Действия по умолчанию, которые поставляются из коробки, являются встроенными задачами, и они реализованы с использованием тех же API, которые доступны вам как пользователю.

Чтобы увидеть текущие задачи, доступные в вашем проекте, запустите npx hardhat:

$ npx hardhat
Hardhat version 2.9.10

Usage: hardhat [GLOBAL OPTIONS] <TASK> [TASK OPTIONS]

GLOBAL OPTIONS:

  --config              A Hardhat config file.
  --emoji               Use emoji in messages.
  --help                Shows this message, or a task's help if its name is provided
  --max-memory          The maximum amount of memory that Hardhat can use.
  --network             The network to connect to.
  --show-stack-traces   Show stack traces.
  --tsconfig            A TypeScript config file.
  --verbose             Enables Hardhat verbose logging
  --version             Shows hardhat's version.


AVAILABLE TASKS:

  check         Check whatever you need
  clean         Clears the cache and deletes all artifacts
  compile       Compiles the entire project, building all artifacts
  console       Opens a hardhat console
  flatten       Flattens and prints contracts and their dependencies
  help          Prints this message
  node          Starts a JSON-RPC server on top of Hardhat Network
  run           Runs a user-defined script after compiling the project
  test          Runs mocha tests

To get help for a specific task run: npx hardhat help [task]
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете создавать дополнительные задачи, которые будут появляться в этом списке. Например, вы можете создать задачу для сброса состояния среды разработки, или для взаимодействия с вашими контрактами, или для упаковки вашего проекта.

Давайте рассмотрим процесс создания задачи для взаимодействия с умным контрактом.

Задачи в Hardhat — это асинхронные функции JavaScript, которые получают доступ к среде выполнения Hardhat, которая раскрывает свою конфигурацию и параметры, а также программный доступ к другим задачам и любым объектам плагинов, которые могут быть внедрены.

Для нашего примера мы будем использовать @nomicfoundation/hardhat-toolbox, который включает библиотеку ethers.js для взаимодействия с нашими контрактами.

npm install --save-dev @nomicfoundation/hardhat-toolbox
Вход в полноэкранный режим Выход из полноэкранного режима

Код создания задач может находиться в hardhat.config.js, или как там называется ваш файл конфигурации. Это хорошее место для создания простых задач. Если ваша задача сложнее, то вполне допустимо разделить код на несколько файлов и требовать их из конфигурационного файла.

(Если вы пишете плагин для Hardhat, который добавляет задачу, их также можно создавать из отдельного пакета npm. Узнайте больше о создании задач с помощью плагинов в разделе Создание плагинов).

Конфигурационный файл всегда выполняется при запуске, прежде чем произойдет что-либо еще. Полезно помнить об этом. Мы загрузим набор инструментов Hardhat и добавим в него наш код создания задачи.

В этом учебнике мы создадим задачу для получения баланса счета из терминала. Это можно сделать с помощью API конфигурации Hardhat, который доступен в глобальной области видимости hardhat.config.js:

require("@nomicfoundation/hardhat-toolbox");

task("balance", "Prints an account's balance").setAction(async () => {});

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.9",
};
Войти в полноэкранный режим Выйти из полноэкранного режима

После сохранения файла вы должны иметь возможность увидеть задачу в Hardhat:

$ npx hardhat
Hardhat version 2.9.10

Usage: hardhat [GLOBAL OPTIONS] <TASK> [TASK OPTIONS]

GLOBAL OPTIONS:

  --config              A Hardhat config file.
  ...


AVAILABLE TASKS:

  balance               Prints an account's balance
  check                 Check whatever you need
  clean                 Clears the cache and deletes all artifacts
  ...

To get help for a specific task run: npx hardhat help [task]
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь давайте реализуем нужную нам функциональность. Нам нужно получить адрес учетной записи от пользователя. Мы можем сделать это, добавив параметр в нашу задачу:

task("balance", "Prints an account's balance")
  .addParam("account", "The account's address")
  .setAction(async () => {});
Войти в полноэкранный режим Выйти из полноэкранного режима

Когда вы добавляете параметр к задаче, Hardhat будет обрабатывать ее справочные сообщения за вас:

$ npx hardhat help balance
Hardhat version 2.9.10

Usage: hardhat [GLOBAL OPTIONS] balance --account <STRING>

OPTIONS:

  --account     The account's address

balance: Prints an account's balance

For global options help run: hardhat help
Ввести полноэкранный режим Выход из полноэкранного режима

Теперь давайте узнаем баланс счета. Среда выполнения Hardhat будет доступна в глобальной области видимости. Используя плагин Hardhat ether.js, который входит в состав Hardhat Toolbox, мы получим доступ к экземпляру ethers.js:

task("balance", "Prints an account's balance")
  .addParam("account", "The account's address")
  .setAction(async (taskArgs) => {
    const balance = await ethers.provider.getBalance(taskArgs.account);

    console.log(ethers.utils.formatEther(balance), "ETH");
  });
Вход в полноэкранный режим Выйти из полноэкранного режима

Наконец, мы можем запустить его:

$ npx hardhat balance --account 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
10000.0 ETH
Войти в полноэкранный режим Выйти из полноэкранного режима

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

— асинхронная функция

Вы можете создавать свои собственные задачи в файле hardhat.config.js. API Config будет доступен в глобальной среде, с функциями для определения задач. Вы также можете импортировать API с помощью require("hardhat/config"), если вы предпочитаете сохранять явную форму и использовать преимущества автозаполнения вашего редактора.

Создание задачи осуществляется вызовом функции task. Она вернет объект TaskDefinition, который можно использовать для определения параметров задачи.

Самая простая задача, которую можно определить, это

task(
  "hello",
  "Prints 'Hello, World!'",
  async function (taskArguments, hre, runSuper) {
    console.log("Hello, World!");
  }
);
Войти в полноэкранный режим Выйти из полноэкранного режима

Первый аргумент task — это имя задачи. Второй — ее описание, которое используется для печати справочных сообщений в CLI. Третий — асинхронная функция, принимающая следующие аргументы:

  • taskArguments — объект с разобранными CLI аргументами задачи. В данном случае это пустой объект.

  • hre — среда выполнения Hardhat.

  • runSuper имеет значение только в том случае, если вы переопределяете существующую задачу, о чем мы узнаем далее. Его цель — позволить вам запустить действие исходной задачи.

Определение аргументов действия необязательно. Hardhat Runtime Environment и runSuper также будут доступны в глобальной области видимости. Мы можем переписать нашу задачу «hello» таким образом:

task("hello", "Prints 'Hello, World!'", async () => {
  console.log("Hello, World!");
});
Войти в полноэкранный режим Выйти из полноэкранного режима

— Требования к действиям задач

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

Это пример задачи, действие которой не удовлетворяет этому требованию:

task("BAD", "This task is broken", async () => {
  setTimeout(() => {
    throw new Error(
      "This task's action returned a promise that resolved before I was thrown"
    );
  }, 1000);
});
Войти в полноэкранный режим Выйти из полноэкранного режима

Эта другая задача использует Promise для ожидания таймаута:

task("delayed-hello", "Prints 'Hello, World!' after a second", async () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Hello, World!");
      resolve();
    }, 1000);
  });
});
Войти в полноэкранный режим Выход из полноэкранного режима

Ручное создание Promise может показаться сложным, но вам не придется этого делать, если вы будете придерживаться API на основе async/await и Promise. Например, вы можете использовать пакет npm delay для обещанной версии setTimeout.

— Определение параметров

Задачи Hardhat могут получать именованные параметры со значением (например, --parameter-name parameterValue), флаги без значения (например, --flag-name), позиционные параметры или вариативные параметры. Вариативные параметры действуют подобно остальным параметрам JavaScript. Функция Config API task возвращает объект с методами для определения всех этих параметров. После определения параметров Hardhat берет на себя контроль над разбором параметров, их проверкой и печатью справочных сообщений.

Добавление необязательного параметра к задаче hello может выглядеть следующим образом:

task("hello", "Prints a greeting'")
  .addOptionalParam("greeting", "The greeting to print", "Hello, World!")
  .setAction(async ({ greeting }) => console.log(greeting));
Войти в полноэкранный режим Выйти из полноэкранного режима

И будет выполняться с помощью npx hardhat hello --greeting Hola.

— Ограничения позиционных параметров

Позиционным и переменным параметрам не обязательно присваивать имена, они имеют обычные ограничения языка программирования:

  • Позиционный параметр не может следовать за переменным.
  • Обязательные/необходимые параметры не могут следовать за необязательными.

Несоблюдение этих ограничений приведет к возникновению исключения при загрузке Hardhat.

— Валидации типов

Hardhat заботится о проверке и разборе значений, предоставленных для каждого параметра. Вы можете объявить тип параметра, и Hardhat получит строки CLI и преобразует их в нужный вам тип. Если преобразование не удастся, он выведет сообщение об ошибке, объясняющее причину.

Ряд типов доступен в API Config через объект types. Этот объект внедряется в глобальную область видимости перед обработкой вашего hardhat.config.js, но вы также можете импортировать его явно с помощью const { types } = require("hardhat/config") и воспользоваться преимуществами автозаполнения вашего редактора.

Примером задачи, определяющей тип для одного из своих параметров, может служить следующее

task("hello", "Prints 'Hello' multiple times")
  .addOptionalParam(
    "times",
    "The number of times to print 'Hello'",
    1,
    types.int
  )
  .setAction(async ({ times }) => {
    for (let i = 0; i < times; i++) {
      console.log("Hello");
    }
  });
Войти в полноэкранный режим Выйти из полноэкранного режима

Вызов этой задачи с npx hardhat hello --times notanumber приведет к ошибке.

— Переопределение задач

Определение задачи с тем же именем, что и существующая, отменяет существующую задачу. Это полезно для изменения или расширения поведения встроенных задач и задач, предоставляемых плагинами.

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

Порядок переопределения задач важен, поскольку действия могут вызывать только непосредственно переопределенное определение, используя функцию runSuper.

Переопределение встроенных задач — это отличный способ настройки и расширения Hardhat. Чтобы узнать, какие задачи следует переопределить, посмотрите на src/builtin-tasks.

— Функция runSuper

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

Эта функция работает подобно ключевому слову JavaScript super: она вызывает ранее определенное действие задачи.

Если задача не переопределяет предыдущее определение задачи, то вызов runSuper приведет к ошибке. Чтобы проверить, приведет ли вызов к ошибке, можно использовать поле boolean runSuper.isDefined.

Функция runSuper получает один необязательный аргумент: объект с аргументами задачи. Если этот аргумент не указан, будут использованы те же аргументы задачи, которые были получены вызывающим ее действием.

— Подзадачи

Создание задач с большим количеством логики затрудняет их расширение или настройку. Создание нескольких небольших и сфокусированных задач, вызывающих друг друга, — лучший способ расширения. Если вы разработаете свои задачи таким образом, пользователи, которые хотят изменить только небольшой аспект, смогут переопределить одну из ваших подзадач.

Например, задача compile реализована как конвейер из нескольких задач. Она просто вызывает такие подзадачи, как compile:get-source-paths, compile:get-dependency-graph и compile:build-artifacts. Мы рекомендуем обозначать промежуточные задачи префиксом их основной задачи и двоеточием.

Чтобы избежать загромождения справочных сообщений большим количеством промежуточных задач, вы можете определить их с помощью функции API конфигурации subtask. Функция subtask работает почти так же, как task. Единственное отличие заключается в том, что задачи, определенные с ее помощью, не будут включены в справочные сообщения.

Для запуска подзадачи или любой другой задачи можно использовать функцию run. Она принимает два аргумента: имя запускаемой задачи и объект с ее аргументами.

Это пример запуска подзадачи:

task("hello-world", "Prints a hello world message").setAction(
  async (taskArgs, hre) => {
    await hre.run("print", { message: "Hello, World!" });
  }
);

subtask("print", "Prints a message")
  .addParam("message", "The message to print")
  .setAction(async (taskArgs) => {
    console.log(taskArgs.message);
  });
Войти в полноэкранный режим Выйти из полноэкранного режима

— hardhat Tutorials , hardhat 教程

CN 中文 Github hardhat 教程 : github.com/565ee/hardhat_CN

CN 中文 CSDN hardhat 教程 : blog.csdn.net/wx468116118

EN 英文 Github hardhat Tutorials : github.com/565ee/hardhat_EN

— Контакт 联系方式

Домашняя страница : 565.ee

GitHub : github.com/565ee

Электронная почта : 565.eee@gmail.com

Facebook : facebook.com/565.ee

Twitter : twitter.com/565_eee

Telegram : t.me/ee_565

Оцените статью
devanswers.ru
Добавить комментарий