Solidity. Смарт контракты и аудит
2.62K subscribers
246 photos
7 videos
18 files
550 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Вот этот код, по своей сути, и разворачивает смарт-контракт в тестовой сети hardhat.

Пройдемся по коду:

beforeEach() - говорит о том, что нам нужно переразворачивать смарт-контракт перед каждым тестом, чтобы они были независимы друг от друга.

ethers.getSigners() - в этой функции мы говорим, какие аккаунты, и от каких переменных мы собираемся использовать. Вы же помните, как в Remix мы получали 20 аккаунтов для тестов? Вот и hardhat при разворачивании смарт-контракта выдает нам те же 20 аккаунтов для тестирования.

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

deloy() - разворачивание контракта, он же деплой.

deployed() - ожидание выполнения деплоя. Другими словами, мы ждем от hardhat, что контракт был развернут и все прошло хорошо.

#hardhat #deploy
👍1
Деплой 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
Деплой контракта в сеть 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 scripts\deploy.js --network localhost

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

#deploy #hardhat
Тесты с урока про Honeypot

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

Однако напомню для повторения.

В начале он импортирует loadFixture, expect и ethers для проведения тестов, а также type для использования typechain.

import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import { ethers } from "hardhat";
import type { Bank, Attack, Logger, Honeypot } from "../typechain-types";

Затем в деплое, вместо beforeEach, пишет функцию dep(), которая возвращает объекты для тестирования ниже.

И в тестах начинает работы с получения этих объектов через await loadFixture(dep).

На данный момент это стандарт работы с тестами в hardhat и их нужно знать.

#honeypot #deploy