Solidity. Смарт контракты и аудит – Telegram
Solidity. Смарт контракты и аудит
2.62K subscribers
246 photos
7 videos
18 files
547 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Upgradeable ERC721. Часть 1

Отдельный урок про ERC721 у нас будет на следующей неделе, так как потребуется пара дней, чтобы научиться работать с ним. А сейчас мы, на его примере, рассмотрим, как работают обновляемые контракты.

Для начала нам нужно импортировать все необходимые обновляемые контракты с openzeppelin, а также прокси контракт Initializable.

Коммит по уроку можно посмотреть тут.

Так как конструкторы, как я понял из урока, в обновляемых контракта могут работать некорректно, было принято решение заменить его новой функцией initialize() с модификатором initializer. По правилам она вызывается только один раз при разворачивании контракта, поэтому ее можно как бы назвать неким конструктором обновляемых контрактов.

И уже в этой функции мы можем другие функции, с помощью которых можно установить владельца контракта или передать данные о токене, например, в ERC721.

Также необходимо функции, в которых используются обновляемые контракты, также обновить.

#proxy #upgradeable #transparent
👍1
Upgradeable ERC721. Часть 2

По умолчанию все обновляемые контракты используют transparent proxy. Для того, чтобы переключиться на UUPS proxy нам нужно сделать следующие действия.

1. Добавить в импортируемые файлы с openzeppelin строку

import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

2. Добавить наследование от UUPS в наш контракт;

3. В функции initialize() добавить функцию __UUPSUpgradeable_init(), чтобы при разворачивании система поняла, что мы используем именно UUPS;

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

function _authorizeUpgrade(address newImplementation) internal onlyOwner override {}

Этих действий будет достаточно, чтобы развернуть UUPS прокси к нашему контракту.

#proxy #upgradeable #uups
Деплой Upgradeable ERC721. Часть 3

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

В начале файла лектор подключает три импорта:

import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import { ethers, upgrades } from "hardhat";

С "chai" и "ethers" мы уже знакомы, поэтому остановлюсь на двух других.

"upgrades" - это плагин, который стал доступен, когда мы установили пакет hardhat-upgrades. Он помогает разворачивать и тестировать прокси контракты.

"loadFixture" - это также новый плагин, который был добавлен в toolbox. Лектор, говорит, что это новая фича в hardhat, но на момент, когда мы учились устанавливать среду разработки, он уже был доступен и я рассказывал, как его установить.

В данном тесте у нас нет обычной функции beforeEach(), которая вызывалась перед каждым тестом. В этом случае мы пишем отдельную функцию dep() (или деплой).

Также используем ethers.getSigners(), чтобы получить адрес пользователя, который разворачивает контракт, а также getContractFactory(), чтобы указать, с каким контрактом мы работаем.

И вот дальше мы используем плагин "upgrades", для деплоя прокси контракта, где в аргументах передаем разворачиваемый контракт, аргументы для функции initialize() в нашем контракте, если необходимо, и набор опций для прокси:

const token = await upgrades.deployProxy(NFTFactory, [], {
  initializer: 'initialize',
  kind: 'uups',
});

Если мы работаем с UUPS контрактами, то добавляем сюда kind: "uups". Если же с transparent proxy, то оставляем только initializer.

Из этой функции деплоя нам нужно вернуть контракт и адрес деплоера.

Далее в тестах, с помощью плагина loadFixture(), мы обращаемся к функции нашего деплоя, откуда получаем token (наш прокси) и deployer.

const { token, deployer } = await loadFixture(dep);

После этого можно писать тесты, как мы уже делали раньше.

Далее посмотрим, как работать с обновленным контрактом в тестах.

Для начала его также нужно получить через getContractFactory(), и уже потом использовать плагин upgrades, чтобы обновить прокси, передав в него адрес прокси и новый контракт.

const token2 = await upgrades.upgradeProxy(token.address, NFTFactoryv2);

После этого мы можем писать тесты уже для обновленного контакта. 

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

#proxy #upgradeable #transparent #uups #deploy
Урок 23 - Typechain и hardhat toolbox

Заканчиваем нашу ударную неделю в Solidity с изучением урока про typechain.

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

Как оказалось, использование loadFixture более современный метод деплоя, и уже можно не писать beforeEach(). Более того лектор немного ругается про плагин hardhat deploy, который они часто использовал ранее, обосновывая, что там есть ошибки, которые "ломают" npx.

Но о деплое мы поговорим еще на следующей неделе, а сегодня будут посты про typechain.

Видео урок про typechain и toolbox.

Для меня это тоже новая тема, поэтому буду писать, как я сам понимаю реализацию. Если среди вас есть те, кто уже работал с typenoscript, то буду рад комментариям или поправкам.

Приятного дня и легкого обучения!

#урок #typechain #toolbox
Немного о Typechain

Для начала нужно разобраться, а что такое typechain и зачем он нужен в hardhat?

Typechain - это решение, которое уже входит в hardhat toolbox и генерирует для наших смарт-контрактов специальные типы для typenoscript. Они помогают нам работать с объектами СК.

Попробую объяснить чуть понятнее.

До этого мы писали все тесты в файле с расширением js, т.е. javanoscript.

JavaScript потрясающий язык программирования, но в нем есть некоторые проблемы с типами данных. Напомню, что типы данных это string, uint, bool и т.д. Только в js не uint, а number.

Так вот, в работе с этими данными в некоторых случаях нужно было конкретно указывать js, что мы работаем, например, с числами, иначе могло получиться так, что "1+1" было бы равно "11", а не "2".

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

И как я понял из урока, typechain использует typenoscript для работы с объектами СК, а именно дает подсказки по функциям и типам данных в них.

Более того, немного покопавшись в других примерах разработки СК, я понял, что typechain более "крутой" и современный подход. И теперь нам нужно будет стараться учиться писать тесты, используя именно его.  

#урок #typechain
👍1
Начало работы с Typechain

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

Create a JavaScript project
Create a TypeScript project

Так вот сейчас нам нужно выбрать второй пункт.

Обратите внимание, что файл hardhat.config теперь имеет расширение ts, а не js, как было раньше.

Проверьте, чтобы в этом файле были подключены следующие импорты:

import { HardhatUserConfig } from "hardhat/config";
import "
@nomicfoundation/hardhat-toolbox";

Более того, теперь все тесты в папке test нам также следует называть с расширением ts. Иначе работать они не будут.

Далее нам нужно написать наш смарт контракт и скомпилировать его с помощью команды npx hardhat compile.

В папке проекта должна появиться новая папка typechain-types, где лежит файл с именем нашего контракта. И этот файл нам нужно подключить в файл теста, по примеру:

import { Sample } from "../typechain-types";

Также в функции деплоя контракта мы должны определить наш тип:

const SampleFactory = await ethers.getContractFactory("Sample");
const sample: Sample = await SampleFactory.deploy();

Именно то, что мы определили тип данных нашего контракта после знака ":", поможет нам работать с этим объектом далее в тестах.

После этих действий, когда в тестах нам потребуется вызвать какую-либо функцию объекта, typechain будет давать подсказки, включая необходимые аргументы функции.

#урок #typechain
Подключение к уже развернутому контракту с Typechain

Для подключение к развернутому контракту существует такая штука, как factories в папке typechain-types.

Тут можно найти abi контракта, его байткод и т.д.

И если в своих тестах вы хотите подключиться к контракту нет из под адреса деплоера, а из под другого адреса, то можно использовать функцию connect() из factories.

Для этого нужно в импорт typechain в начале файла добавить factories:

import { Sample, Sample__factory } from "../typechain-types";

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

const sampleAsUser = Sample__factory.connect(sample.address, user);

где первый параметр - это адрес контракта, а второй - адрес, к которому подключаемся.

#урок #typechain #connect
Урок 24 - ERC721 и NFT

Привет всем!

Надеюсь выходные вы провели не только праздно, но и с небольшой пользой, а именно до разбирали уроки прошлой недели.

Да, они были несколько сложные, но и мы уже не новички в Solidity.

На этой неделе я планирую закончить серию уроков продвинутого изучения Solidity, разобрав такие штуки как ERC721, NTF, деплой, МетаМаск, Honeypot (который был выпущен лектором вчера) и пара рекомендаций, включая вопросы к собеседованию часть 2.

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

А пока, вот видео урок про ERC721 и NFT.

Как я сам понял, в таких стандартах как ERC20, ERC721, ERC3475, важно понимать набор основных функций и переменных, чтобы уже на основе них создавать свои контракты.

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

Всем приятного дня и легкого обучения.

#урок #erc721 #nft
Описание контрактов ERC721 и NFT. Часть 1

Как обычно, для начала разберемся, что такое ERC721.

Стандарт ERC721, по своей сути, всего лишь регламентирует то, как наши NFT должны храниться в блокчейне, как их можно передавать друг другу, вводить в оборот и уничтожать. А уже в другом нашем контракте мы создаем (минтим) NFT на основе ERC721, добавляем имя, символ и ссылку, где он хранится.

Далее, давайте разберем подробнее контракт, который написал лектор в уроке. Кстати, файлы можно посмотреть тут.

В контракте ERC721.sol лектор подключает несколько импортов:

import "./ERC165.sol";
import "./IERC721.sol";
import "./IERC721Metadata.sol";
import "./Strings.sol";
import "./IERC721Receiver.sol";


IERC721.sol
- простой интерфейс со списком функций нашего контракта.

IERC721Metadata.sol - интерфейс, который добавляет функции имени, символа и ссылки на наш NFT.

Strings.sol - библиотека из openzeppelin, которая помогает переводить uint в string.

ERC165.sol - контракт, от которого мы наследуем в своем контракте функцию, которая как бы говорит, что наш контракт может принимать и работать с NFT. Другими словами, когда чужой контракт будет спрашивать наш, работает ли он с интерфейсом ERC721, то наш контракт ответит ему положительно.

IERC721Receiver.sol - реализует функцию onERC721Received(), которая проверяет, кто принимает наш NFT: контракт или адрес, и помогает получать ошибку. О нем поговорим подробнее ниже.

В уроке, получается, наш контракт ERC721 наследует от трех других:

contract ERC721 is ERC165, IERC721, IERC721Metadata

Далее рассмотрим переменные, конструктор и базовые функции контракта.

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 2

В начале контракта устанавливаются две переменные - имя и символ.

Далее, мы прописываем 4 mapping:

1. Первый, который будет рассказывать, сколько NFT на определенном адресе;
2. Второй - кто владеет данным NFT;
3. Третий - разрешение такому-то адресу управлять NFT с таким-то id, например, переводить его на другой адрес.
4. Четвертый показывает, что этот конкретный адрес может управлять всеми токенами на другом конкретном адресе.

После этого мы создаем новый модификатор, который будет проверять, а был ли вообще данный NFT создан ранее. Сюда мы пишем служебную функцию _exist(), которая проверяет, что данный токен не равен нулевому адресу. Если выполняется данное условие, то значит, что NFT с таким id все таки существует.

Затем мы пишем конструктор, в котором передаем имя и символ нашего токена и приравниваем их к переменным, созданным выше.

Думаю, тут же стоит обозначить несколько простых функций из контракта.

name() - возвращает имя токена;

symbol() - возвращает символ токена;

balanceOf() - принимает адрес и показывает баланс на нем, беря информацию из mapping;

ownerOf() - принимает id токена и возвращает адрес владельца, беря его из второго mapping;

getApproved() - принимает id токена и возвращает адрес, беря его из третьего mapping;

isApprovedForAll() - принимает id токена и возвращает булево значение, получая его из четвертого mapping;

burn() - принимает id токена, проверяет, может ли данный пользователь распоряжаться им, и передает в служебную функцию _burn(), которая, в свою очередь, получает владельца токена, уменьшает его баланс и удаляет информацию о токене из второго и третьего mapping;

_beforeTokenTransfer() и _afterTokenTransfer() - служебные пустые функции, которые используются уже в создании токена в другом контракте;

В следующей части поговорим о более сложных функциях контракта.

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 3

Далее пройдем по более сложным функциям контракта, оставив самые сложные на отдельный пост.

Итак, функция approve(), в которой мы принимаем адрес (кому мы одобряем использование нашего NFT) и сам id токена. В функции нам нужно получить адрес владельца данного токена, проверить, что msg.sender является либо владельцем, либо имеет разрешение на токен, и уже после добавить в mapping разрешение на данный токен данному адресу.

В функции setApprovalForAll() мы принимаем оператора (или адрес магазина) и булево значение, и сперва проверяем, что msg.sender не равен адресу магазина, так как нельзя выписывать права самому себе. Далее мы говорим, что даем разрешение данному оператору на управление нашими токенами.

Далее идут сразу две служебные функции _safeMint(), с разным количеством принимаемых аргументов. В первой мы получаем только адрес, куда следует отправить созданные токены, id токена, и перенаправляем ее во второй _safeMint() вместе с новым аргументом bytes.   

Во втором _safeMint() принимаем уже три агрумента: адрес, id и bytes. Внутри вызываем функцию _mint() и делаем проверку на получающего данный NFT с помощью служебной функции _checkOnERC721Received(), о которой поговорим позже.

В _mint() принимаем адрес и id токена, проверяем, чтобы данный адрес не был нулевым, а затем устанавливаем владельца токена в mapping и увеличиваем баланс владельца.

Если честно, я сам не понял, зачем создаются две функции _safeMint. Полагаю, что это было сделано на случай, если потребуются передать дополнительные аргументы (bytes). Если же нет - функция передает пустое значение.

У меня не так много опыта в выпуске NFT, но уверен, что когда в практике столкнусь с данной проблемой, то опишу ее подробнее на канале.

Также сейчас стоит упомянуть функцию supportsInterface(), которую мы получаем из наследуемого интерфейса IERC165. В ней мы просто говорим, что наш контракт работает с интерфейсом IERC721.

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 4

Особый интерес в этом контракте представляет функция _checkOnERC721Received().

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

С помощью условия "to.code.length > 0" мы проверяем, что "to" является все таки адресом контракта.

Далее, с помощью ранее подключенного интерфейса IERC721Receiver, на адрес получателя мы вызываем функцию onERC721Received() и передаем аргументы отправителя, получателя, id токена и данные.

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

В первом случае контракт получателя совсем не работает с NFT и нам возвращаются пустые данные. А во втором, контракт работает с NFT, но по каким-то причинам не может принять наш токен.

И вот в первом случае мы просто выводим ошибку и откатываем транзакцию, а во втором - принимаем ошибку с помощью assembly и также возвращаем NFT.

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 5

Также в нашем контракте есть служебные функции _safeTransfer() и _transfer().

В первой принимаются аргументы отправителя, получателя, номер токена и другие данные. Тут вызывается другая функция _transfer() и используется _checkOnERC721Received, чтобы проверить, можно ли отправлять токен.

А во второй проверяется владелец токена и адрес отправителя. В mapping добавляются и отнимаются балансы, а также присваивается токен новому владельцу. Все просто, как и в ERC20.

Ну и последние две функции это _baseURI() и tokenURI(), которые возвращают url нашего токена.

_baseURI() - просто возвращает адрес хранилища, если он есть, к которому после нужно добавить идентификатор токена в tokenURI().

Более того, в уроке приводится дополнительный контракт ERC721URIStorage.sol, который расширяет работу с url токена.

В нем создается отдельный mapping, где хранятся id токена и сами url.

Функция tokenURI() переопределяется, но по сути ничего не меняется в выдаче результатов.

Добавляется функция _setTokenURI(), которая устанавливает в mapping новый url токена, и функция _burn(), которая удаляет его оттуда. Надо заметить, что _burn() еще вызывает аналогичную функцию в родительском контракте. 

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 6

Ну, и в завершении нашего сегодняшнего изучения ERC721 стоить сказать пару слов о Enumerable контракте, о котором лектора спрашивают в уроке.

Enumerable, как и URIStorage, расширяют функционал основного контракта. В частности этот добавляет работу с токенами по индексу.

Здесь создаются mapping, которые хранят индексы всех токенов, индексы токенов на разных адресах и владельцы токенов по индексу.

Также добавляются функции, которые возвращают общее количество всех токенов, которые были созданы, поиск токена по индексу и поиск владельца по индексу токена.

Переопределяется функция _beforeTokenTransfer(), и добавляются несколько служебных фукнций для управления mapping.

Добавление Enumerable контракта является более сложной организацией работы с NFT, которую используют крупные компании на мировом рынке. Для выпуска своего NFT будет достаточно базовых функций, которые мы сегодня прошли.

#erc721 #nft
Описание контрактов ERC721 и NFT. Часть 7

Забыл написать, про контракт, где реализуется ERC721.

В файлах он идет под названием MyToken.sol.

Итак, в нем мы подключаем три других контракта для наследования функций:

import "./ERC721.sol";
import "./ERC721Enumerable.sol";
import "./ERC721URIStorage.sol";

Далее создаем переменные для сохранения владельца и id токена.

В конструкторе вызываем контракт ERC721 и передаем туда имя токена и его символ, а внутри устанавливаем владельца.

Дальше, через функцию safeMint(), в которой принимаем адрес получателя и другие данные, создаем NFT через служебные функции _safeMint() и _setTokenURI(). В конце, увеличиваем id токена для последующего минта.

Также, с помощью supportsInterface() говорим, что поддерживаем интерфейсы ERC721 и ERC721Enumerable.

Устанавливаем url адрес в _baseURI() и  tokenURI().

И в конце, добавляем функцию для уничтожения нашего токена _burn().

Если вы все же решили использовать Enumerable контракты, то нужно переопределить функцию _beforeTokenTransfer(), вызывая в нем эту же функцию из контракта выше (используя super).

Вот и все!

ERC721 достаточно сложный контракт для тех, кто впервые столкнулся с ним. Однако, посидев с ним несколько часов, вы сможете лучше ориентироваться в коде и уже самостоятельно использовать новые контракты, которые смогут улучшиться ваш NFT.

#erc721 #nft
Урок 25 - Rinkeby, Etherscan, Alchemy

Всем привет!

И сразу к хорошим новостям! Еще не улеглись полученные знания после вчерашнего разбора ERC721, как лектор будет радовать нас новым крутым стримом по ERC1155, который призван заменить 721, и позволяет создавать уникальные и не уникальные токены!

Стрим будет 08 сентября в 19:00 по московскому времени на канале Ильи. Там вы сможете задать вопросы напрямую! Всем советую подключиться!

Ну, а мы сегодня продолжаем наше обучение и поговорим о деплое контрактов в тестовые сети, типа Rinkeby. Также рассмотрим один из популярных сервисов Alchemy.

Новый видео урок!

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

Именно поэтому данное видео будет интересно еще и со стороны поиска работы!

Всем приятного дня и легкого обучения!

#урок #rinkeby #etherscan #alchemy
Деплой контракта в сеть Hardhat

Вообще, как я понял из уроков, есть два типа деплоя контрактов:

1. Деплой в hardhat для проведения тестов с функциями контрактов;
2. Общий деплой в блокчейн;

Разница лишь в том, что для тестов мы разворачиваем контракт каждый раз для каждого теста, а в общем деплое - один раз. При этом за пределами hardhat, в тестовых сетях типа Rinkeby, контракт загружается по примеру mainnet - один раз и его нельзя уже редактировать или удалять.

Для деплоя контракта используется уже знакомый нам код:

async function main() {
  const [signer] = await hre.ethers.getSigners();
  const Lock = await hre.ethers.getContractFactory("Lock", signer);
  const lock = await Lock.deploy();

  await lock.deployed();

}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Нужно сказать, что чаще всего код для деплоя в сеть пишут в файле с таким же названием - deploy.js.

После этого, вам нужно скомпилировать ваш контракт с помощью команды npx hardhat compile, и далее развернуть его в сеть с помощью:

npx harhat run noscripts\deploy.js --network localhost

Все! Теперь можно создать другой файл, подключить в него ethers.js и проводить какие-либо работы с развернутым контрактом уже в сети hardhat.

#deploy #hardhat
Немного о сетях и сервисах

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

Ранее существовали популярные тестовые сети:

1. Rinkeby
2. Ropsten
3. Kiln
4. Kovan

Так вот, они будут удалены  из-за слияния сетей Эфира в середине сентября 2022 года. Другими словами, их не нужно использовать вообще!

На их смену придут две новые сети:

1. Gorly
2. Sepolia

Они, вероятнее всего, станут основными тестовыми сетями для Эфира и всех токенов на его основе.

Поэтому в видео уроке необходимо взять общий принцип разворачивания СК, а не пример с Rinkeby.

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

1. Alchemy
2. Infura

Оба бесплатные, но с ограничениями. Для обучения подходят оба. Да и в вакансиях чаще всего встречаются только эти два.

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

Далее перейдем к деплою контракта и env.

#infura #rinkeby #ropsten #alchemy #gorly #sepolia
Настройка и использование .env

ENV (environment variables)
- это особые переменные рабочей среды. Другими словами, это некие глобальные значения, расположенные на уровне операционной системы, доступные программам, например настройки системы.

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

Устанавливается он при помощи команды в консоли:

npm install dotenv --save

Или как было показано в видео: через файл hardhat.config.json и команды в консоли после - npm install.

Затем в тот же файл hardhat.config добавляете строку подключения:

require('dotenv').config()

Далее вы заходите или создаете папку .env в корневом каталоге проекта и записываете переменные (в нашем случае ключи и доступы), например так:

S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"

Также проверьте, что в файле gitingnore есть запись ".env", чтобы случайно ваши пароли и ключи не попали в открытый доступ.

После всех этих действий, вы можете использовать созданные переменные в других файлах. Для этого, в месте, где хотите использовать env переменную, ставите фигурные скобки и записываете по примеру:

{process.env.API_KEY} - где API_KEY - имя вашей переменной.

Так легко и просто вы можете защищать свои данные на видео, в репозиториях, на слайдах и т.д.

#env
Пример деплоя контракта в сеть Goerli

И наконец, давайте попробуем загрузить наш контракт в тестовую сеть goerli.

Хочу уточнить, что после тестов мне больше понравился Alchemy, поэтому я буду использовать в примере его сервис.

Итак, на данный момент, вы должны были уже зарегистрироваться в Alchemy на официальном сайте и создать env файл.

Заходим в Alchemy и кликаем на кнопку Create App. Появляется окошко с полями. Там мы вводим название проекта, его описание, а также в поле Chain должен значиться Ethereum и в Network - Goerly.

С помощью Alchemy можно загружать контракты и в другие блокчейн сети, как Solana или Polygon, но мы работаем именно с Эфиром.

После этого создастся ваш проект. В рамках поля проекта ищите кнопку View key и нажимаете на нее. Копируете API key в свой env файл в новую переменную, например API_KEY.

Теперь заходим на сайт Метамаск и скачиваем приложение для Chrome.

Запишите, сохраните, сфотографируйте секретную фразу восстановления МетаМаск!!! Это очень важно! Если вдруг вы забудете пароль, это будет единственный способ восстановить доступ!

После установки и регистрации, открываете приложение и в самом верху выбираете "Тестовая сеть Goerly".

Рядом с названием вашего аккаунта будет меню (три точки), нажимаете их, выбираете реквизиты счета, экспорт закрытого ключа, вводите еще раз свой пароль, копируете свой закрытый ключ и вставляете его в новую переменную в env файле, например META_KEY.

Теперь идем в папку нашего проекта и открываем файл hardhat.config.json.

В раздел module.exports добавляем код networks, как в примере лектора в уроке или как представлено ниже, чтобы в итоге он выглядел так:

module.exports = {
  solidity: "0.8.9",
  networks: {
    goerli: {
      url:
https://eth-goerli.alchemyapi.io/v2/${process.env.API_KEY},
      accounts: [process.env.META_KEY]
    }
  }
};

И вот после всех этих действий, мы можем загрузить свой проект в goerly, выполнив команду в консоли:

npx harhat run noscripts\deploy.js --network goerly

В вашем проекте на Alchemy должен появиться новый контракт, если все прошло как надо.

#goerly #metamask #alchemy