Разработка и развертывание смарт-контрактов с помощью Foundry и Openzeppelin: руководство

Разработка и развертывание смарт-контрактов с помощью Foundry и Openzeppelin: руководство

29 ноября 2022 г.

Foundry — это невероятно быстрый, портативный и модульный инструментарий для разработки приложений Ethereum, написанный на Rust.

Foundry состоит из трех компонентов:

Forge: среда тестирования Ethereum (например, Truffle, Hardhat и DappTools).

Cast: интерфейс командной строки для взаимодействия со смарт-контрактами EVM, отправки транзакций и получения данных цепочки.

Anvil: локальный узел Ethereum, аналог Ganache или Hardhat Network.

Зачем нам это использовать?

  • Это быстро, больше не нужно тратить время на выполнение тестов.
  • Это позволяет писать тесты цельно, что сводит к минимуму переключение контекста.
  • Многие функции тестирования, такие как фаззинг, console.log и чит-коды, дают вам больше возможностей и гибкости.

Темы, которые мы собираемся раскрыть в этой статье

  1. Настройка проекта
  2. Как установить зависимости в Foundry (например, OpenZeppelin)
  3. Интеграция Foundry с VSCode
  4. Написание контракта и тестовых случаев с помощью Foundry
  5. Знакомство с трассировкой в ​​Foundry
  6. Создание отчета о газе с помощью Foundry
  7. Развертывание контракта с помощью Foundry

Установка

Установка Foundry подробно описана в книге Foundry. Ознакомьтесь с инструкциями здесь:

https://book.getfoundry.sh/getting-started/installation?embedable=true

Настройка проекта

После установки Foundry мы можем создать новый проект с помощью.

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

Установка зависимостей

Forge по умолчанию управляет зависимостями, используя подмодули git, что означает, что он работает с любой репозиторий GitHub, содержащий смарт-контракты.

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

forge install OpenZeppelin/openzeppelin-contracts
// forge install is command which is used for installing  dependencies
// <https://github.com/OpenZeppelin/openzeppelin-contracts>
// use {{username}}/{{repo_name}} from the github url

Интеграция Foundry с VSCode

После установки OpenZeppelin в качестве зависимости попробуйте импортировать что-нибудь из него в контракт (ваш контракт находится там в каталоге /src). Если вы используете VSCode, появится сообщение об ошибке.< /p>

Image Description

Чтобы исправить эту ошибку, выполните эту команду.

forge remappings > remappings.txt

Эта команда создает файл remappings.txt в корневом каталоге проекта.

На данный момент содержимое файла может выглядеть так:

ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/

Дополнительные сведения см. здесь https://book.getfoundry.sh/config/vscode

.

Составление контракта

Переименуйте файл src/Counter.solsrc/FDemo.sol; код нашего смарт-контракта ERC721 приведен ниже.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "openzeppelin-contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "openzeppelin-contracts/utils/Counters.sol";

contract FDemo is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenId;

    constructor() ERC721("FDemo", "FD") {}

    function mint(string memory tokenUri) external returns (uint256) {
        uint256 newTokenId = _tokenId.current();

        _mint(msg.sender, newTokenId);
        _setTokenURI(newTokenId, tokenUri);

        _tokenId.increment();

        return newTokenId;
    }
}

Тестирование контракта с помощью Foundry

Давайте начнем с переименования тестового файла, чтобы он соответствовал имени нашего контракта Counter.t.solFDemo.t.sol

Forge использует следующие ключевые слова в тестах:

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

function setUp() public {
    testNumber = 42;
}

* test: функции с префиксом test запускаются как тестовый пример.

function testNumberIs42() public {
  assertEq(testNumber, 42);
}

* testFail: инверсия префикса теста — если функция не возвращается, тест не пройден.

function testNumberIs42() public {
  assertEq(testNumber, 42);
}

Итак, прямо сейчас у нас есть только один метод mint, поэтому мы напишем тестовый пример для этого метода,

и это будет довольно просто.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/FDemo.sol";

contract FoundryDemoTest is Test {
    FDemo instance;

    function setUp() public { 
        instance = new FDemo();
    }

    function testMint() public { 
        string memory dummyTokenUri = "ipfs://metadata_url";
        uint256 tokenId = instance.mint(dummyTokenUri);

        assertEq(dummyTokenUri, instance.tokenURI(tokenId));
    }

}

Теперь, чтобы запустить этот тест, мы можем использовать команду forge test

Если мы хотим изучить больше деталей/событий/потока тестовых случаев, мы можем использовать трассировку, чтобы включить трассировку во время выполнения тестовых случаев, используя -vvv или -vvvv

На прикрепленном снимке экрана показаны результаты тестов с трассировкой и без нее.

Image Description

Подробнее о трассировках: https://book.getfoundry.sh/forge/traces

Создание отчета о газе с помощью Foundry

Чтобы создать отчет о газах, используйте — gas-report с тестовой командой.

forge test --gas-report

Image Description

Подробнее об отчете о газе здесь: https://book.getfoundry.sh/forge/gas-reports

Развертывание и проверка контрактов с Foundry

Forge может развернуть смарт-контракты в заданной сети с помощью команды forge create. р>

Некоторые параметры, которые мы можем использовать с forge create при развертывании контракта.

* —rpc-url: URL-адрес RPC сети, в которой мы хотим развернуть наш контракт (в нашем случае мы будем использовать URL-адрес RPC тестовой сети polygon Mumbai) * constructor-args: передать аргументы конструктору. * private-key: закрытый ключ кошелька развертывателя

При желании мы можем передать --verify &&--etherscan-api-key, если мы хотим проверить наш контракт.

$ forge create --rpc-url <your_rpc_url> 
    --constructor-args "ForgeUSD" "FUSD" 18 1000000000000000000000 
    --private-key <your_private_key> src/MyToken.sol:MyToken 
    --etherscan-api-key <your_etherscan_api_key> 
    --verify

Давайте развернем сейчас.

forge create --rpc-url <https://rpc.ankr.com/polygon_mumbai>
--private-key <your_private_key>  src/FDemo.sol:FDemo
--etherscan-api-key <your_etherscan_api_key>
--verify

Image Description

Полный код: GitHub

<цитата>

💡 Подписывайтесь на меня в Твиттере, чтобы не пропустить другие интересные материалы, подобные этой @pateldeep_eth Linkedin


Также опубликовано здесь


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE