
Разработка и развертывание смарт-контрактов с помощью Foundry и Openzeppelin: руководство
29 ноября 2022 г.Foundry — это невероятно быстрый, портативный и модульный инструментарий для разработки приложений Ethereum, написанный на Rust.
Foundry состоит из трех компонентов:
Forge: среда тестирования Ethereum (например, Truffle, Hardhat и DappTools).
Cast: интерфейс командной строки для взаимодействия со смарт-контрактами EVM, отправки транзакций и получения данных цепочки. р>
Anvil: локальный узел Ethereum, аналог Ganache или Hardhat Network.
Зачем нам это использовать?
- Это быстро, больше не нужно тратить время на выполнение тестов.
- Это позволяет писать тесты цельно, что сводит к минимуму переключение контекста.
- Многие функции тестирования, такие как фаззинг, console.log и чит-коды, дают вам больше возможностей и гибкости.
Темы, которые мы собираемся раскрыть в этой статье
- Настройка проекта
- Как установить зависимости в Foundry (например, OpenZeppelin)
- Интеграция Foundry с VSCode
- Написание контракта и тестовых случаев с помощью Foundry
- Знакомство с трассировкой в Foundry
- Создание отчета о газе с помощью Foundry
- Развертывание контракта с помощью Foundry
Установка
Установка Foundry подробно описана в книге Foundry. Ознакомьтесь с инструкциями здесь:
https://book.getfoundry.sh/getting-started/installation?embedable=true а>
Настройка проекта
После установки Foundry мы можем создать новый проект с помощью.
forge init foundry-demo // forge-demo is name of the project
После создания проекта используйте команды, чтобы проверить, все ли работает правильно.
cd foundry-demo && forge build
Установка зависимостей
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>
Чтобы исправить эту ошибку, выполните эту команду.
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.sol
→ src/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.sol
→ FDemo.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
На прикрепленном снимке экрана показаны результаты тестов с трассировкой и без нее.
Подробнее о трассировках: https://book.getfoundry.sh/forge/traces
Создание отчета о газе с помощью Foundry
Чтобы создать отчет о газах, используйте — gas-report с тестовой командой.
forge test --gas-report
Подробнее об отчете о газе здесь: 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
Полный код: GitHub
<цитата>💡 Подписывайтесь на меня в Твиттере, чтобы не пропустить другие интересные материалы, подобные этой @pateldeep_eth Linkedin
Также опубликовано здесь
Оригинал