
Как построить проект NFT с Foundry & Figment DataHub
31 мая 2022 г.Репозиторий GitHub: - https://github.com/PradhumnaPancholi/Figbot
Всем привет! Некоторое время назад я изучал [Dapp Tools] (https://github.com/dapphub/dapptools), поскольку в нем есть фантастические инструменты для разработки и аудита смарт-контрактов. И хотя мне нравился этот опыт, я вскоре узнал, что он находится на стадии тайной разработки. Это означает, что случайные/индивидуальные пользователи не могут зависеть от сопровождающих в плане поддержки и обновлений.
Затем я наткнулся на Foundry. В нем есть все, что предлагает Dapp Tools, кроме встроенного символьного выполнения (что для меня не проблема, поскольку я использую Manticore от Trail of Bits). И это связано с аудитом, поэтому ни в коем случае не является препятствием для разработки смарт-контрактов.
Поработав некоторое время с Foundry, я получил удовольствие от этого опыта и захотел поделиться им с другими. Отсюда и эта статья.
В этой статье будут рассмотрены преимущества Foundry, процесс установки, разработка NFT (потому что все заинтересованы в этом), тестирование контракта и его развертывание с помощью [Figment Datahub] (https://datahub.figment.io/) .
Foundry — невероятно быстрый, портативный и модульный инструментарий для разработки приложений Ethereum, написанный на Rust.
Литейный завод состоит из трех компонентов:
- Forge: среда тестирования Ethereum (например, Truffle, Hardhat и Dapptools).
- Cast: Швейцарский армейский нож для взаимодействия со смарт-контрактами EVM, отправки транзакций и получения данных цепочки.
- Anvil: локальный узел Ethereum, похожий на Ganache, сеть Hardhat.
Сегодня мы сосредоточимся на Forge. Но в ближайшие недели я опубликую подробные статьи о Caste и Anvil.
Почему литейный цех:
Существует множество инструментов разработки смарт-контрактов, таких как Truffle, Hardhat и Brownie. Но одной из основных причин, по которой я обратил внимание на Dapp Tools, были нативные тесты Solidity. Написание смарт-контрактов несложно при переключении между такими фреймворками, как Hardhat и Brownie. И это невероятные инструменты с плагинами, но для проведения тестирования нужно хорошо разбираться в JavaScript/TypeScript и Python.
Foundry позволяет нам писать наши тесты в Solidity. Это экономит много времени на адаптации новых разработчиков и делает процесс более плавным. Из моего опыта помощи людям в разработке смарт-контрактов я узнал, что лучший и наиболее эффективный способ для младших разработчиков участвовать в проектах DAO/поддерживаемых сообществом — это написание тестов и изучение самой кодовой базы. Я помню, как Scupy Trooples однажды упомянули, что они использовали тот же подход при разработке Alchemix Finance для Bankless.
В дополнение к этому встроенный фаззинг, чит-коды, Cast и Anvil делают его надежным набором для тестирования смарт-контрактов. Скоро появятся более подробные статьи об этих компонентах. [Легко интегрируемый статический анализатор]
Давайте погрузимся и создадим проект NFT сейчас.
Монтаж:
Если вы работаете на Mac или Linux, все, что вам нужно сделать, это выполнить две команды:
```javascript
завиток -L https://foundry.paradigm.xyz | бить
литейный завод
Обязательно закройте терминал перед запуском foundryup
.
И вуаля! Вы все сделали.
Для Windows вам необходимо установить Rust, а затем:
грузовая установка --git https://github.com/foundry-rs/foundry --locked
Настройка проекта:
В этой статье мы создадим простой проект NFT под названием Figbots.
Начните с создания каталога под названием «Figbots». И запустите forge init
, как только вы окажетесь внутри каталога. Эта команда создаст для вас литейный проект с инициализированным git
.
Давайте кратко рассмотрим структуру папок. У вас есть три основные папки, а именно src, lib и test. Здесь многое говорит само за себя, вы пишете свои контракты в src
, тесты в test
, а lib
содержит все установленные вами библиотеки, например, OpenZeppelin. В дополнение к этому вы получаете foundry.toml
, который содержит все конфигурации точно так же, как hardhat.config.js
и brownie-config.yaml
, если вы использовали эти фреймворки. Еще одна приятная вещь — это .github, где вы можете писать свои действия Github. Я считаю, что это очень полезно для тестов при работе в команде.
Начнем строить! Мы создадим простой NFT под названием Figbot с ограниченным предложением, стоимостью (для майнинга) и выводом. При таком подходе мы можем покрыть ребра для разных тестов. Прежде всего, переименуйте «Contract.sol» и «test/Contract.t.sol» в «Figbot.sol» и «Figbot.t.sol» соответственно. Теперь мы не можем писать смарт-контракты без Openzeppelin, не так ли?
Установка библиотек с помощью Foundry немного отличается от установки Hardhat и Brownie. У нас нет пакетов npm или pip. Мы устанавливаем библиотеки прямо из исходного кода (репозиторий GitHub) в Foundry.
подделать установку Openzeppelin/openzeppelin-contracts
Теперь мы можем импортировать расширение ERC721URIStorage.sol для создания нашего NFT. Чтобы убедиться, что все в порядке, мы можем запустить команду forge build
, и она скомпилирует наш проект. Компилятор будет кричать на вас, если что-то не так. В противном случае вы получите успешную компиляцию.
Управление зависимостями
Как и любой другой менеджер пакетов, Forge позволяет вам использовать forge install
Давайте завершим контракт NFT:
Мы будем использовать три контракта от Openzeppelin. Счетчики, хранилище ERC721URIStorage и собственность. Пришло время загрузить наш актив в IPFS с помощью Pinata. Мы используем контракт Ownable, чтобы установить адрес развертывания «владелец» и иметь доступ к модификатору «onlyOwner», чтобы позволить только владельцу снимать средства. «Счетчики», чтобы помочь нам с идентификаторами токенов, и «ERC721URIStorage», чтобы упростить контракт NFT.
- Установка переменной состояния:
MAX_SUPPLY
до 100
СТОИМОСТЬ
до 0,69 эфира
TOKEN_URI
на CID, получаем от Пиньяты
- Использование счетчика для идентификатора токена:
использование счетчиков для счетчиков.Счетчик;
Counters.Counter private tokenIds;
- Конструктор ERC721:
конструктор() ERC721 («Фигбот», «ФБТ») {}
- Функция монетного двора:
- Проверьте, больше ли
msg.value
, чемCOST
- Проверьте, больше ли
tokenIds.current()
или равноMAX_SUPPLY
- Выполните
_safeMint
и_setTokenURI
- Функция снятия:
function removeFunds() external onlyOwner { uint256 balance = address(this).balance; require(баланс > 0, "Не осталось эфира для вывода"); (логический успех, ) = (msg.sender).call{значение: баланс}(""); требуют(успех, "Снятие не удалось"); выдать Снять (msg.sender, баланс); }
- Функция TotalSupply:
функция totalSupply() возвращает публичное представление (uint256) { return _tokenIds.current(); }
Тестирование контракта:
Как мы все знаем, тестирование наших смарт-контрактов действительно важно. В этом разделе мы напишем несколько тестов, чтобы получить четкое представление о forge test
и привыкнуть к написанию тестов в родной твердости. У нас будет три чит-кода Foundry (мне они нравятся!) для управления состоянием аккаунта в соответствии с нашим тестовым сценарием.
Мы будем тестировать следующие сценарии:
- Максимальный запас
- Успешный монетный двор
- Неудачный монетный двор из-за недостаточного баланса
- Снятие (владельцем)
Чит коды
Поскольку у нас может быть сложная логика в наших смарт-контрактах. И ожидается, что они будут вести себя по-разному в зависимости от состояния, учетной записи, используемой для вызова, времени и т. д. Чтобы справиться с такими сценариями, мы можем использовать чит-коды для управления состоянием блокчейна. Мы можем использовать эти чит-коды, используя экземпляр vm
, который является частью библиотеки Test
Foundry.
В наших тестах мы будем использовать три чит-кода:
startPrank
: устанавливаетmsg.sender
для всех последующих вызовов, пока не будет вызванstopPrank
.
стопШалость
:
Останавливает активный розыгрыш, запущенный startPrank
, сбрасывая msg.sender
и tx.origin
к значениям до вызова startPrank
.
Настраивать
Foundry поставляется со встроенной библиотекой тестирования. Мы начинаем с импорта этой тестовой библиотеки, нашего контракта (того, который мы хотим протестировать), определения теста, установки переменных и функции setUp
.
прочность прагмы ^0,8,13;
import"forge-std/Test.sol";
импортировать "../src/Figbot.sol";
контракт FigbotTest является тестом {
фигбот фигбот;
владелец адреса = адрес (0x1223);
адрес Алиса = адрес (0x1889);
адрес боб = адрес (0x1778);
функция setUp() общедоступная {
vm.startPrank(владелец);
фигбот = новый фигбот();
vm.stopPrank();
Для переменных состояния мы создаем переменную figbot типа figbot. Это также место, где мне нравится определять учетные записи пользователей. В Foundry вы можете описать адрес, используя синтаксис «адрес (0x1243)». для этого можно использовать любые четыре буквенно-цифровых символа. Я создал учетные записи с именами владельца, Алисы и Боба соответственно.
Теперь наша функция setUp
. Это требование для написания тестов в Foundry. Здесь мы делаем все развертывания и тому подобное. Я использовал чит-код startPrank, чтобы переключить пользователя на «владельца». По умолчанию Foundry использует определенный адрес для развертывания тестовых контрактов. Но это усложняет тестирование функций с особыми привилегиями, такими как withdrawFunds
. Следовательно, мы переключаемся на учетную запись «владельца» для этого развертывания.
Тест MaxSupply:
Начните с простого теста утверждений, чтобы изучить соглашение Foundry. По соглашению все тестовые функции должны иметь префикс test
. И мы используем assertEq
, чтобы проверить, равны ли два значения.
Мы вызываем нашу функцию «MaxSupply» и проверяем, равно ли значение результата 100, как мы описали в нашем контракте. И мы используем forge test
для запуска наших тестов.
И Вуаля!!! у нас есть пройденный тест.
Тестовый монетный двор:
Теперь, когда мы написали простой тест, давайте напишем его с чит-кодами. Основная функция нашего контракта.
- Переключите учетную запись пользователя на Алису.
- Установите баланс Алисы на 1 эфир
- Вызов функции монетного двора
- Проверьте, равен ли
balanceOf
Алисы 1
TestFail Mint:
У нас есть еще одна функция тестирования, используемая для тестов, которые, как мы ожидаем, не пройдут. Префикс, используемый для такого теста, — testFail. Мы проверим, возвращается ли функция «mint», если у вызывающего абонента недостаточно средств.
- Переключите учетную запись пользователя на Боба
- Установите баланс Боба на 0,5 эфира (наш NFT — 0,69 эфира)
- Вызовите функцию монетного двора (она будет отменена из-за нехватки средств)
- Проверьте, равен ли
balanceOf
Боба 1
Поскольку монетный двор не прошел, баланс Боба не будет равен 1. Следовательно, он потерпит неудачу, для чего мы и используем testFail
. Поэтому, когда вы запустите forge test
, он пройдет.
Пробный вывод средств:
Здесь мы протестируем функцию, которую может успешно выполнить только «владелец». Для этого теста мы:
- Переключить пользователя на Боба
- Передать аккаунту Боба баланс в 1 эфир.
- Выпустить Figbot со счета Боба (это даст контракту баланс в 0,69 эфира)
- Переключите пользователя на учетную запись владельца
- Выполните функцию
withdrawFunds
(в случае успеха она должна сделать баланс владельца 0,69 эфира)
- Для проверки утверждаем, что баланс владельца равен 0,69 эфира.
Развертывание:
Теперь, когда мы протестировали наш контракт, пришло время его развернуть. Нам нужны приватные ключи к кошельку (с тестом Rinkeby ETH) и URL-адрес RPC. В качестве URL-адреса RPC мы будем использовать [Figment DataHu] (https://datahub.figment.io).
Figment DataHub предоставляет нам инфраструктуру для разработки в Web 3. Он поддерживает несколько цепочек, таких как Ethereum, Celo, Solana, Terra и т. д.
Настройка Figment DataHub:
- Создайте учетную запись на [Figment DataHub] (https://datahub.figment.io/).
- Нажмите «Создать новое приложение».
- Введите имя приложения.
- Выберите «Staging» для среды.
- Выберите «Эфириум» из предложенных вариантов.
Вы можете получить URL-адрес RPC для Rinkeby на вкладке «Протоколы».
Откройте терминал, чтобы ввести обе эти вещи в качестве переменных среды.
```javascript
export FIG_RINKEBY_URL=<Ваша конечная точка RPC>
export PVT_KEY=<закрытый ключ вашего кошелька>
Когда у нас есть переменные среды, мы готовы к развертыванию.
создать Figbot --rpc-url=$FIG_RINKEBY_URL --private-key=$PVT_KEY
Подтверждение:
Мы почти закончили. На данный момент мы написали, протестировали и развернули смарт-контракт с Foundry и Figment DataHub. Но мы еще не совсем закончили. Сейчас мы проверим наш контракт. Для этого нам нужно будет настроить наш ключ API Etherscan.
export ETHERSCAN_API=<Ваш ключ API Etherscan>
И теперь мы можем проверить наш смарт-контракт.
forge verify-contract --chain-id <Chain-Id> --num-of-optimizations 200 --compiler-version <версия компилятора> src/<файл контракта>:<контракт> $ETHERSCAN_API
Поздравляем! Теперь вы можете писать, тестировать и развертывать смарт-контракты с помощью Foundry. Надеюсь, вам понравилась и вы узнали из этой статьи. Мне действительно понравилось писать это. Не стесняйтесь, дайте мне знать ваши мысли об этом.
Оригинал