Тесты с урока про 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
Также хочу обратить ваше внимание, что лектор в уроке для проведения тестов с контрактами использует деплой с учетом последних обновлений 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
Solidity by Example
Сегодня, в ожидании стрима, на канале не будет уроков. Вместо этого я сделаю несколько полезных постов по работе с Solidity.
Я нашел один интересный сайт, где приводятся примеры кода Solidity, как шпаргалки.
Очень удобно, например, когда вы забыли какой-то урок или функцию, и хотите быстро по коду понять написание или использование.
Да, он на английском, но тем не менее очень понятен интуитивно.
Solidity by Example.
#links #hint
Сегодня, в ожидании стрима, на канале не будет уроков. Вместо этого я сделаю несколько полезных постов по работе с Solidity.
Я нашел один интересный сайт, где приводятся примеры кода Solidity, как шпаргалки.
Очень удобно, например, когда вы забыли какой-то урок или функцию, и хотите быстро по коду понять написание или использование.
Да, он на английском, но тем не менее очень понятен интуитивно.
Solidity by Example.
#links #hint
Статья с рекомендациями
Также нашел еще одну интересную статью с рекомендациями по написанию хорошего кода. Она на английском языке, поэтому в течение дня я сделаю несколько постов с переводом основных пунктов.
Советы достаточно интересные, и ничего подобного раньше в уроках или других видео я не встречал.
#link #hint
Также нашел еще одну интересную статью с рекомендациями по написанию хорошего кода. Она на английском языке, поэтому в течение дня я сделаю несколько постов с переводом основных пунктов.
Советы достаточно интересные, и ничего подобного раньше в уроках или других видео я не встречал.
#link #hint
Используйте модификаторы правильно
Интересное замечание, которое я не встречал еще в практике.
Не рекомендуется использовать модификаторы, в которых изменяются переменные состояния или реализуются внешние вызовы, например при наследовании, так как сами модификаторы исполняются до кода в функции.
contract Registry {
address owner;
function isVoter(address _addr) external returns(bool) {
// Code
}
}
contract Election {
Registry registry;
modifier isEligible(address _addr) {
require(registry.isVoter(_addr));
_;
}
function vote() isEligible(msg.sender) public {
// Code
}
}
Например, выше вы можете видеть НЕ правильное использование модификатора, так как контракт Registry может делать reentrancy атаку в другом контракте, вызывая Election.vote() внутри isVoter().
Модификаторы чаще всего используются, чтобы заменить дублирующийся код в функциях, по примеру проверки владельца isOwner().
#modifier #hint
Интересное замечание, которое я не встречал еще в практике.
Не рекомендуется использовать модификаторы, в которых изменяются переменные состояния или реализуются внешние вызовы, например при наследовании, так как сами модификаторы исполняются до кода в функции.
contract Registry {
address owner;
function isVoter(address _addr) external returns(bool) {
// Code
}
}
contract Election {
Registry registry;
modifier isEligible(address _addr) {
require(registry.isVoter(_addr));
_;
}
function vote() isEligible(msg.sender) public {
// Code
}
}
Например, выше вы можете видеть НЕ правильное использование модификатора, так как контракт Registry может делать reentrancy атаку в другом контракте, вызывая Election.vote() внутри isVoter().
Модификаторы чаще всего используются, чтобы заменить дублирующийся код в функциях, по примеру проверки владельца isOwner().
#modifier #hint
👍1
Аккуратнее с делением чисел
Solidity, на данный момент сентября 2022 года, не поддерживает числа с точкой, и при делении 5/2 будет показан результат "2". Т.е. вместе с откидыванием цифр после точки, он еще и округляет результат до меньшего числа.
Это действительно проблема для большинства разработчиков. И многие пытаются преодолеть ее через дополнительные библиотеки на openzeppelin или пишут свои "костыли".
В документации по Solidity пишут, что нужно использовать мультипликатор, как в примере:
uint multiplier = 10;
uint x = (5 * multiplier) / 2;
Из других статей я понял, что можно также выполнять все математические операции на фронтенде, чтобы все было точнее, а уже результат сохранять в Solidity.
Некоторые предлагают использовать decimals эфира, но я не видел хороших примеров.
#division #integer #hint
Solidity, на данный момент сентября 2022 года, не поддерживает числа с точкой, и при делении 5/2 будет показан результат "2". Т.е. вместе с откидыванием цифр после точки, он еще и округляет результат до меньшего числа.
Это действительно проблема для большинства разработчиков. И многие пытаются преодолеть ее через дополнительные библиотеки на openzeppelin или пишут свои "костыли".
В документации по Solidity пишут, что нужно использовать мультипликатор, как в примере:
uint multiplier = 10;
uint x = (5 * multiplier) / 2;
Из других статей я понял, что можно также выполнять все математические операции на фронтенде, чтобы все было точнее, а уже результат сохранять в Solidity.
Некоторые предлагают использовать decimals эфира, но я не видел хороших примеров.
#division #integer #hint
👍1
Интерфейсы и абстрактные контракты
Интерфейсы и абстрактные контракты призваны помочь с написанием кода нашего контракта и облегчить его.
Однако следует помнить, что интерфейсы не могут выполнять функции, не имеют доступа к storage и не могут наследовать от других интерфейсов.
При этом абстрактные контракты так делать могут, что делает их более универсальными. Но нужно помнить, что при наследовании нашим контрактом абстрактного, необходимо override его функции.
#abstract #interface #hint
Интерфейсы и абстрактные контракты призваны помочь с написанием кода нашего контракта и облегчить его.
Однако следует помнить, что интерфейсы не могут выполнять функции, не имеют доступа к storage и не могут наследовать от других интерфейсов.
При этом абстрактные контракты так делать могут, что делает их более универсальными. Но нужно помнить, что при наследовании нашим контрактом абстрактного, необходимо override его функции.
#abstract #interface #hint
👍1
Особенности fallback функций
Если fallback() указан как payable, то он может принимать Ether.
Особенность отправляющих Ether функций transfer и send в том, что у них есть ограничение - инициированная ими транзакция не должна расходовать больше, чем 2300 gas. Поэтому, если внутри fallback реализована какая-то сложная логика (вызвать еще какие-то функции, записать storage и т.д.) (при поступлении Ether с помощью transfer или send), то это будет стоить больше, чем 2300 и транзакция откатится.
Максимум на что хватит газа в такой ситуации внутри fallback - это на emit event.
При этом, если эфир отправляется с помощью call вызовов, то есть возможность повышения лимита газа, и тогда в fallback функция не откатит транзакцию.
Будьте аккуратны с этим, и всегда дополняйте fallback другими функциями, которые могут принимать деньги, например receive.
#hint #fallback #receive
Если fallback() указан как payable, то он может принимать Ether.
Особенность отправляющих Ether функций transfer и send в том, что у них есть ограничение - инициированная ими транзакция не должна расходовать больше, чем 2300 gas. Поэтому, если внутри fallback реализована какая-то сложная логика (вызвать еще какие-то функции, записать storage и т.д.) (при поступлении Ether с помощью transfer или send), то это будет стоить больше, чем 2300 и транзакция откатится.
Максимум на что хватит газа в такой ситуации внутри fallback - это на emit event.
При этом, если эфир отправляется с помощью call вызовов, то есть возможность повышения лимита газа, и тогда в fallback функция не откатит транзакцию.
Будьте аккуратны с этим, и всегда дополняйте fallback другими функциями, которые могут принимать деньги, например receive.
#hint #fallback #receive
Версия pragma Solidity
В начале каждого файла нашего контракта мы указываем версию pragma. Другими словами, мы сообщаем версию языка Solidity, с которой работали.
Так вот, не уверен, насколько этот совет из статьи актуален сейчас, однако звучит достаточно здраво: фиксируйте версию pragma для своего контракта.
Если вы заметили, то мы обычно пишем так: "pragma solidity ^0.8.0;". И вот этот значок "^" указывает на то, что для контракта могут подходить версии 0.8.0 и выше.
И данная рекомендация, предлагает писать без этого знака, как бы говоря, что мы работаем только с этой версией Solidity.
Это может стать актуальным если, скажем, версия 0.9.0 введет изменения в языке и функциях, и тогда наши контракты будут выдавать ошибки, если указан "^".
Повторяю, не знаю, насколько это правильно в текущих реалиях, но доля логики здесь есть.
#hint #pragma
В начале каждого файла нашего контракта мы указываем версию pragma. Другими словами, мы сообщаем версию языка Solidity, с которой работали.
Так вот, не уверен, насколько этот совет из статьи актуален сейчас, однако звучит достаточно здраво: фиксируйте версию pragma для своего контракта.
Если вы заметили, то мы обычно пишем так: "pragma solidity ^0.8.0;". И вот этот значок "^" указывает на то, что для контракта могут подходить версии 0.8.0 и выше.
И данная рекомендация, предлагает писать без этого знака, как бы говоря, что мы работаем только с этой версией Solidity.
Это может стать актуальным если, скажем, версия 0.9.0 введет изменения в языке и функциях, и тогда наши контракты будут выдавать ошибки, если указан "^".
Повторяю, не знаю, насколько это правильно в текущих реалиях, но доля логики здесь есть.
#hint #pragma
Используйте event для мониторинга
Иногда бывает, что контракт может принять деньги, но будет не понятно откуда и когда они пришли, как например при наследовании одного контракта другим.
contract Charity {
mapping(address => uint) balances;
function donate() payable public {
balances[msg.sender] += msg.value;
}
}
contract Game {
function buyCoins() payable public {
// 5% goes to charity
charity.donate.value(msg.value / 20)();
}
}
Когда контракт Game сделает вызов функции Charity.donate(), эта транзакция не отобразится во внешних транзакциях Charity. Именно для таких целей лучше всего использовать event, которые будут порождать события при совершении переводов.
#hint #event
Иногда бывает, что контракт может принять деньги, но будет не понятно откуда и когда они пришли, как например при наследовании одного контракта другим.
contract Charity {
mapping(address => uint) balances;
function donate() payable public {
balances[msg.sender] += msg.value;
}
}
contract Game {
function buyCoins() payable public {
// 5% goes to charity
charity.donate.value(msg.value / 20)();
}
}
Когда контракт Game сделает вызов функции Charity.donate(), эта транзакция не отобразится во внешних транзакциях Charity. Именно для таких целей лучше всего использовать event, которые будут порождать события при совершении переводов.
#hint #event
👍1
Аккуратнее со встроенными функциями
В Solidity существуют встроенные функции, которые доступны в написании контракта по умолчанию, как например revert() или selfdestruct().
Так вот, если вы работаете с контрактом, который наследует от другого (других) контракта, то вам следует проверять все функции, которые наследуются. Есть некоторый шанс, что вы наткнетесь на функции похожие на встроенные, но с другим исполнением.
contract PretendingToRevert {
function revert() internal {}
}
contract ExampleContract is PretendingToRevert {
function somethingBad() public {
revert();
}
}
В примере, вызов функции revert() выполнит не откат транзакции, как это должно быть, а условие из PretendingToRevert.
Будьте внимательны и всегда проверяйте исходный код наследуемых контрактов.
#hint #build-in
В Solidity существуют встроенные функции, которые доступны в написании контракта по умолчанию, как например revert() или selfdestruct().
Так вот, если вы работаете с контрактом, который наследует от другого (других) контракта, то вам следует проверять все функции, которые наследуются. Есть некоторый шанс, что вы наткнетесь на функции похожие на встроенные, но с другим исполнением.
contract PretendingToRevert {
function revert() internal {}
}
contract ExampleContract is PretendingToRevert {
function somethingBad() public {
revert();
}
}
В примере, вызов функции revert() выполнит не откат транзакции, как это должно быть, а условие из PretendingToRevert.
Будьте внимательны и всегда проверяйте исходный код наследуемых контрактов.
#hint #build-in
Избегайте tx.origin
Никогда не используйте tx.origin для проверок или авторизации, например так "require(tx.origin == owner)". В этом случае другой контракт (хакер) может получить доступ к вашему контракту и вывести все деньги.
Вместо этого используйте msg.sender.
Более того, tx.origin может быть выведен из языка в последующих обновлениях Solidity.
#hint #tx #tx.origin
Никогда не используйте tx.origin для проверок или авторизации, например так "require(tx.origin == owner)". В этом случае другой контракт (хакер) может получить доступ к вашему контракту и вывести все деньги.
Вместо этого используйте msg.sender.
Более того, tx.origin может быть выведен из языка в последующих обновлениях Solidity.
#hint #tx #tx.origin
Используйте адрес типа интерфейса вместо простого типа адреса
Для большей безопасности в контракте следует использовать interface type вместе обычного типа address в аргументах функции.
contract Validator {
function validate(uint) external returns(bool);
}
contract TypeSafeAuction {
// good
function validateBet(Validator _validator, uint _value) internal returns(bool) {
bool valid = _validator.validate(_value);
return valid;
}
}
contract TypeUnsafeAuction {
// bad
function validateBet(address _addr, uint _value) internal returns(bool) {
Validator validator = Validator(_addr);
bool valid = validator.validate(_value);
return valid;
}
}
#hint #tx #tx.origin
Для большей безопасности в контракте следует использовать interface type вместе обычного типа address в аргументах функции.
contract Validator {
function validate(uint) external returns(bool);
}
contract TypeSafeAuction {
// good
function validateBet(Validator _validator, uint _value) internal returns(bool) {
bool valid = _validator.validate(_value);
return valid;
}
}
contract TypeUnsafeAuction {
// bad
function validateBet(address _addr, uint _value) internal returns(bool) {
Validator validator = Validator(_addr);
bool valid = validator.validate(_value);
return valid;
}
}
#hint #tx #tx.origin
Урок 27 - ERC1155: NFT и взаимозаменяемые токены
Ну, вы, конечно, монстры! Я думал, что после вчерашнего залпа постов в течение дня, с канала отпишутся несколько человек. Но все на месте! Это очень круто!
Сегодня мы разберем вчерашний стрим от Ильи, а с этим и закончим проходить его уроки.
Да, вы можете заметить некоторое несоответствие в нумерации, типа у нас сейчас 27, а на канале уже 31. Объясняю: два урока однажды у нас проходили как один, видео с вопросами для собеседования вторая часть будет выложена завтра, как подведение итогов, и два видео про фронт Next я специально пропустил, так как позже будем отдельно разбираться с этой темой. Вот и выходит все 31 урок.
Новое видео про ERC1155.
Ну, что же, приятного просмотра и легкого обучения!
#урок #erc1155 #nft
Ну, вы, конечно, монстры! Я думал, что после вчерашнего залпа постов в течение дня, с канала отпишутся несколько человек. Но все на месте! Это очень круто!
Сегодня мы разберем вчерашний стрим от Ильи, а с этим и закончим проходить его уроки.
Да, вы можете заметить некоторое несоответствие в нумерации, типа у нас сейчас 27, а на канале уже 31. Объясняю: два урока однажды у нас проходили как один, видео с вопросами для собеседования вторая часть будет выложена завтра, как подведение итогов, и два видео про фронт Next я специально пропустил, так как позже будем отдельно разбираться с этой темой. Вот и выходит все 31 урок.
Новое видео про ERC1155.
Ну, что же, приятного просмотра и легкого обучения!
#урок #erc1155 #nft
YouTube
СТРИМ! Solidity и Ethereum, урок #31 | ERC1155: NFT и взаимозаменяемые токены
ХОЧЕШЬ СТАТЬ РАЗРАБОТЧИКОМ Solidity, узнать об Ethereum, блокчейне и многом другом ещё больше?! Мои друзья из MCS предлагают скидку на ВСЕ СВОИ БУТКЕМЫ ПО КРИПТЕ! Материалы этих буткемов подготовлены мной и другими специалистами: вы действительно узнаете…
👍1
Кратко о различиях ERC721 и ERC1155
Вчера я немного опоздал на стрим и пропустил момент, когда лектор рассказывал о различиях этих двух стандартов. И до сегодняшнего дня меня не покидало ощущение, что я что-то где-то "недогнал".
Пересматривая видео, и покопавшись позже в документации и статьях, я чуть лучше разобрался в этой теме.
Итак, по сути, ERC1155 - это просто улучшенная версия ERC721. Чтобы создать свой NFT в ERC721 нужно было каждый раз создавать новый контракт, при этом каждый токен мог быть исключительно в одном экземпляре.
В ERC1155 можно создавать много токенов в рамках одного контракта, при этом каждый отдельно взятый токен может быть в нескольких экземплярах.
Сейчас попробую описать это на примере.
Возьмем для примера игру Counter Strike. Это такая стрелялка, где команда спецназа борется с командой террористов, и там существует несколько видов огнестрельного оружия.
Так вот, в наши дни это оружие может иметь разный визуальный дизайн, или, как говорят, скин. Одно оружие и, например, 10 разнообразных видов, как оно может выглядеть.
Разработчики игры могут вводить эти скины в игру за дополнительную оплату. При этом, они могут выпустить всего 10 скинов - лимитировать спрос. И только 10 человек от всех игроков будут иметь их в своем арсенале. А могут выпустить и 1 уникальный легендарный скин, который может выкупить только один игрок, и потом хвастаться всем остальным, какой он уникальный.
Другими словами, в рамках ERC1155 мы можем выпускать как уникальные NFT в единственном экземпляре, так и NFT в 2, 5, 20 экземплярах и более. И все они будут управляться одним нашим контрактом!
Именно за свою гибкость и новый подход, ERC1155 уже пришел на смену ERC721.
Поэтому, если вы захотите создать свой NFT, то лучше писать его сразу на ERC1155.
#erc1155 #nft
Вчера я немного опоздал на стрим и пропустил момент, когда лектор рассказывал о различиях этих двух стандартов. И до сегодняшнего дня меня не покидало ощущение, что я что-то где-то "недогнал".
Пересматривая видео, и покопавшись позже в документации и статьях, я чуть лучше разобрался в этой теме.
Итак, по сути, ERC1155 - это просто улучшенная версия ERC721. Чтобы создать свой NFT в ERC721 нужно было каждый раз создавать новый контракт, при этом каждый токен мог быть исключительно в одном экземпляре.
В ERC1155 можно создавать много токенов в рамках одного контракта, при этом каждый отдельно взятый токен может быть в нескольких экземплярах.
Сейчас попробую описать это на примере.
Возьмем для примера игру Counter Strike. Это такая стрелялка, где команда спецназа борется с командой террористов, и там существует несколько видов огнестрельного оружия.
Так вот, в наши дни это оружие может иметь разный визуальный дизайн, или, как говорят, скин. Одно оружие и, например, 10 разнообразных видов, как оно может выглядеть.
Разработчики игры могут вводить эти скины в игру за дополнительную оплату. При этом, они могут выпустить всего 10 скинов - лимитировать спрос. И только 10 человек от всех игроков будут иметь их в своем арсенале. А могут выпустить и 1 уникальный легендарный скин, который может выкупить только один игрок, и потом хвастаться всем остальным, какой он уникальный.
Другими словами, в рамках ERC1155 мы можем выпускать как уникальные NFT в единственном экземпляре, так и NFT в 2, 5, 20 экземплярах и более. И все они будут управляться одним нашим контрактом!
Именно за свою гибкость и новый подход, ERC1155 уже пришел на смену ERC721.
Поэтому, если вы захотите создать свой NFT, то лучше писать его сразу на ERC1155.
#erc1155 #nft
👍1
Разбор контракта ERC1155. Часть 1
В принципе, если вы хорошо изучили предыдущие стандарты ERC21 и ERC721, то понимание данного контракта не должно составить каких-либо трудов.
Для начала здесь подключаются три интерфейса:
import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol";
Первый описывает функции нашего контракта, второй дополняет его с реализацией function uri(), которая возвращает ссылку на токен по его id, а третий - знакомый нам по ERC721, который помогает делать проверку другого контракта на возможность приема токенов.
Особенность данного стандарта в том, что тут есть функции, как для передачи одного токена, так и их группы (Batch).
Далее вводятся два mapping: одни - на проверку "какое количество данного токена есть на конкретном адресе", и второй - "который говорит, что тот или иной адрес (оператор) имеет право распоряжаться токенами на другом конкректом адресе".
И добавляем переменную string, которая будет хранить ссылку на все наши токены. Например, там будет храниться ссылка "https://alltokens.eth/myToken/...", и на месте троеточия будет подставляться id конкретного токена после.
Далее в конструкторе принимает строку ссылку и передает ее в функцию setURI(), которая устанавливает новою ссылку от разработчика.
Также есть простая функция uri(), которая просто возвращает саму ссылку.
balanceOf(), уже знакомая нам, показывает, сколько токенов на определенном адресе.
setApprovalForAll() - выдает разрешение на управление нашими токенами оператору через служебную функцию _setApprovalForAll() с дополнительными проверками на владельца, и isApprovedForAll(), соответственно, проверяет это разрешение.
Интерес тут представляет balanceOfBatch(), которая в качестве аргументов принимает массивы адресов и id токенов и возвращает массив с их количеством на адресе. Для этого делается проверка, что длина массива с аккаунтами равна длине с id токенов, так как, если, например, количество адресов будет больше, то где-то совершена ошибка.
Там же создается новый массив с фиксированной длинной. Мы же помним, что в memory можно создавать только такие массивы?
И через цикл мы прогоняем адреса, вызывая функцию balanceOf() для каждого адреса и id токена, записывая все в новый массив, который и возвращаем.
Еще нужно отметить, что в ERC1155 решили отказаться от обычной функции transferFrom(), и заменить ее safeTransferFrom(), которая выполняет дополнительные проверки перед пересылкой токенов.
#erc1155 #nft
В принципе, если вы хорошо изучили предыдущие стандарты ERC21 и ERC721, то понимание данного контракта не должно составить каких-либо трудов.
Для начала здесь подключаются три интерфейса:
import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol";
Первый описывает функции нашего контракта, второй дополняет его с реализацией function uri(), которая возвращает ссылку на токен по его id, а третий - знакомый нам по ERC721, который помогает делать проверку другого контракта на возможность приема токенов.
Особенность данного стандарта в том, что тут есть функции, как для передачи одного токена, так и их группы (Batch).
Далее вводятся два mapping: одни - на проверку "какое количество данного токена есть на конкретном адресе", и второй - "который говорит, что тот или иной адрес (оператор) имеет право распоряжаться токенами на другом конкректом адресе".
И добавляем переменную string, которая будет хранить ссылку на все наши токены. Например, там будет храниться ссылка "https://alltokens.eth/myToken/...", и на месте троеточия будет подставляться id конкретного токена после.
Далее в конструкторе принимает строку ссылку и передает ее в функцию setURI(), которая устанавливает новою ссылку от разработчика.
Также есть простая функция uri(), которая просто возвращает саму ссылку.
balanceOf(), уже знакомая нам, показывает, сколько токенов на определенном адресе.
setApprovalForAll() - выдает разрешение на управление нашими токенами оператору через служебную функцию _setApprovalForAll() с дополнительными проверками на владельца, и isApprovedForAll(), соответственно, проверяет это разрешение.
Интерес тут представляет balanceOfBatch(), которая в качестве аргументов принимает массивы адресов и id токенов и возвращает массив с их количеством на адресе. Для этого делается проверка, что длина массива с аккаунтами равна длине с id токенов, так как, если, например, количество адресов будет больше, то где-то совершена ошибка.
Там же создается новый массив с фиксированной длинной. Мы же помним, что в memory можно создавать только такие массивы?
И через цикл мы прогоняем адреса, вызывая функцию balanceOf() для каждого адреса и id токена, записывая все в новый массив, который и возвращаем.
Еще нужно отметить, что в ERC1155 решили отказаться от обычной функции transferFrom(), и заменить ее safeTransferFrom(), которая выполняет дополнительные проверки перед пересылкой токенов.
#erc1155 #nft
Разбор контракта ERC1155. Часть 2
Теперь самое интересное!
Есть две функции пересылки токенов _safeTransferFrom() и _safeBatchTransferFrom(), которые с небольшой разницей делают одно и тоже: порождают события о транзакции, вызывают дополнительные служебные функции, которые нам известны с прошлых стандартов, _beforeTokenTransfer() и _afterTokenTransfer(), а также вызывают новую функцию с длинным названием _doSafeTransferAcceptanceCheck().
Но сначала о небольшой разнице между _safeTransferFrom() и _safeBatchTransferFrom(), которая заключается в том, что во второй функции работа идет с массивами, а в первой их нет. И чтобы как-то унифицировать этот процесс, нам нужно аргументы из первой функции переделать в массивы.
Для этого используется служебная функция _asSingletonArray(). Простая, но очень полезная.
Она принимает число, как аргумент, и возвращает массив. Там просто создается новый массив через new result = uint[](1), так как нужна фиксированная длина, и записывается аргумент - result[0] = el
В этой функции, мы создаем уловие и проверяем получателя. Если это обычный адрес, то все ок. Если же адрес контракта, то мы через try-catch посылаем запросы.
В прошлых описаниях стандартов мы использовали assembly, чтобы получать ответ с ошибкой в try-catch. Но сейчас Solidity позволяет делать это своими средствами.
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns(bytes4 resp) {
if(resp != IERC1155Receiver.onERC1155Received.selector) {
revert("Rejected tokens!");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("Non-ERC1155 receiver!");
}
Если в ответе мы получаем селектор функции, которая равен тому, что мы отправили, то транзакция проходит без проблем. В остальных случаях мы ловим ошибку.
В рамках исполнения функции _doSafeTransferAcceptanceCheck() и _doSafeBatchTransferAcceptanceCheck() абсолютно одинаковые.
Вот и все! Теперь мы знаем еще и реализацию стандарта ERC1155.
#erc1155 #nft
Теперь самое интересное!
Есть две функции пересылки токенов _safeTransferFrom() и _safeBatchTransferFrom(), которые с небольшой разницей делают одно и тоже: порождают события о транзакции, вызывают дополнительные служебные функции, которые нам известны с прошлых стандартов, _beforeTokenTransfer() и _afterTokenTransfer(), а также вызывают новую функцию с длинным названием _doSafeTransferAcceptanceCheck().
Но сначала о небольшой разнице между _safeTransferFrom() и _safeBatchTransferFrom(), которая заключается в том, что во второй функции работа идет с массивами, а в первой их нет. И чтобы как-то унифицировать этот процесс, нам нужно аргументы из первой функции переделать в массивы.
Для этого используется служебная функция _asSingletonArray(). Простая, но очень полезная.
Она принимает число, как аргумент, и возвращает массив. Там просто создается новый массив через new result = uint[](1), так как нужна фиксированная длина, и записывается аргумент - result[0] = el
.
Далее переходим к той функции с длинным названием, в которой используется подключенный нами ранее интерфейс IERC1155Receiver.В этой функции, мы создаем уловие и проверяем получателя. Если это обычный адрес, то все ок. Если же адрес контракта, то мы через try-catch посылаем запросы.
В прошлых описаниях стандартов мы использовали assembly, чтобы получать ответ с ошибкой в try-catch. Но сейчас Solidity позволяет делать это своими средствами.
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns(bytes4 resp) {
if(resp != IERC1155Receiver.onERC1155Received.selector) {
revert("Rejected tokens!");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("Non-ERC1155 receiver!");
}
Если в ответе мы получаем селектор функции, которая равен тому, что мы отправили, то транзакция проходит без проблем. В остальных случаях мы ловим ошибку.
В рамках исполнения функции _doSafeTransferAcceptanceCheck() и _doSafeBatchTransferAcceptanceCheck() абсолютно одинаковые.
Вот и все! Теперь мы знаем еще и реализацию стандарта ERC1155.
#erc1155 #nft
Урок 28 - Вопросы к собеседованию. Часть 2
Вот и подошло к концу наше продвинутое обучение по Solidity. В последнем уроке этой части я предлагаю вам посмотреть на вопросы, которые могут задавать на собеседовании.
Если вы также проходили уроки, как и я, то можете смело искать работу на позиции Джуна, младшего разработчика. Полученных знаний будет достаточно, чтобы получить работу и начать зарабатывать.
Видео с вопросами для собеседования.
Завтра я соберу все пройденные уроки этой части обучения в один пост для более удобной навигации.
Конечно же, канал не закрывается и не прекращает обучение.
Думаю, на следующей неделе мы возьмем небольшую пазу от видео уроков. Я буду постить материалы и статьи, которые раскроют другие темы в обучении, типа uniswap, ipfs, solmate, openzeppelin и другие. Плюс в течение этой недели я постараюсь подготовить список уроков и направление для дальнейшего изучения языка.
Вы молодцы, что решили изучать новую перспективную тему в разработке web3. Только после всех этих уроков, я понимаю, насколько сложно новичкам вообще понимать некоторые моменты.
Я даже в начале не подозревал то, чтобы учить Solidity нужно уже иметь хорошие навыки работы с js, node, npm, а еще лучше с react.
Это очень круто, что вы взялись за это!
#урок #собеседование
Вот и подошло к концу наше продвинутое обучение по Solidity. В последнем уроке этой части я предлагаю вам посмотреть на вопросы, которые могут задавать на собеседовании.
Если вы также проходили уроки, как и я, то можете смело искать работу на позиции Джуна, младшего разработчика. Полученных знаний будет достаточно, чтобы получить работу и начать зарабатывать.
Видео с вопросами для собеседования.
Завтра я соберу все пройденные уроки этой части обучения в один пост для более удобной навигации.
Конечно же, канал не закрывается и не прекращает обучение.
Думаю, на следующей неделе мы возьмем небольшую пазу от видео уроков. Я буду постить материалы и статьи, которые раскроют другие темы в обучении, типа uniswap, ipfs, solmate, openzeppelin и другие. Плюс в течение этой недели я постараюсь подготовить список уроков и направление для дальнейшего изучения языка.
Вы молодцы, что решили изучать новую перспективную тему в разработке web3. Только после всех этих уроков, я понимаю, насколько сложно новичкам вообще понимать некоторые моменты.
Я даже в начале не подозревал то, чтобы учить Solidity нужно уже иметь хорошие навыки работы с js, node, npm, а еще лучше с react.
Это очень круто, что вы взялись за это!
#урок #собеседование
YouTube
Solidity и смарт-контракты Ethereum, урок #20 | Ещё 50 вопросов на собеседовании (ч. 2, посложнее)
ХОТИТЕ СТАТЬ РАЗРАБОТЧИКОМ Solidity, узнать об Ethereum, блокчейне и многом другом ещё больше?!
Мои друзья из GUIDE DAO (бывшая школа MCS) предлагают скидку 0,1 ETH на ВСЕ СВОИ БУТКЕМЫ ПО КРИПТЕ! Материалы этих буткемов подготовлены мной и другими специалистами:…
Мои друзья из GUIDE DAO (бывшая школа MCS) предлагают скидку 0,1 ETH на ВСЕ СВОИ БУТКЕМЫ ПО КРИПТЕ! Материалы этих буткемов подготовлены мной и другими специалистами:…
❤1🔥1
Продвинутое обучение Solidity
После изучение основ языка, необходимо знать и понимать, как он функционирует, какие паттерны существуют, и на что обращать внимание в коде, чтобы повысить его безопасность.
В этих уроках рассматривается огромный пласт Solidity, без которого дальнейшее обучение будет вызывать массу вопросов и проблем.
Если вы не успели пройти их все, то выделите время и закончите обучение перед тем, как двигаться дальше.
Урок 17 - Голландский аукцион
Урок 18 - ERC20
Урок 19 - MultiSig и Timelock
Урок 20 - Паттерн commit/reveal
Урок 21 - DAO и Governance
Урок 22 - Паттерн Proxy/Upgradeable: Transparent, UUPS
Урок 23 - Typechain и hardhat toolbox
Урок 24 - ERC721 и NFT
Урок 25 - Rinkeby, Etherscan, Alchemy
Урок 26 - Honeypot
Урок 27 - ERC1155: NFT и взаимозаменяемые токены
Урок 28 - Вопросы к собеседованию. Часть 2
Также, хочу напомнить, что, если вы забыли какой-то момент из урока, то на канале действует поиск по хеш-тегам. Например, поиск по #nft выдаст все посты, где была речь о нем.
Более того, напоминаю, что вы всегда можете задавать вопросы в чатах:
Чат от канала - https://news.1rj.ru/str/+CqKZNgqZ640wNDdi
Чат от лектора - https://news.1rj.ru/str/joinchat/MxYT6-01eeA1NTYy
Далее мы будем рассматривать темы с других видео на YouTube, а уроки Ильи мы будем проходить по мере их выпуска на его канале.
После изучение основ языка, необходимо знать и понимать, как он функционирует, какие паттерны существуют, и на что обращать внимание в коде, чтобы повысить его безопасность.
В этих уроках рассматривается огромный пласт Solidity, без которого дальнейшее обучение будет вызывать массу вопросов и проблем.
Если вы не успели пройти их все, то выделите время и закончите обучение перед тем, как двигаться дальше.
Урок 17 - Голландский аукцион
Урок 18 - ERC20
Урок 19 - MultiSig и Timelock
Урок 20 - Паттерн commit/reveal
Урок 21 - DAO и Governance
Урок 22 - Паттерн Proxy/Upgradeable: Transparent, UUPS
Урок 23 - Typechain и hardhat toolbox
Урок 24 - ERC721 и NFT
Урок 25 - Rinkeby, Etherscan, Alchemy
Урок 26 - Honeypot
Урок 27 - ERC1155: NFT и взаимозаменяемые токены
Урок 28 - Вопросы к собеседованию. Часть 2
Также, хочу напомнить, что, если вы забыли какой-то момент из урока, то на канале действует поиск по хеш-тегам. Например, поиск по #nft выдаст все посты, где была речь о нем.
Более того, напоминаю, что вы всегда можете задавать вопросы в чатах:
Чат от канала - https://news.1rj.ru/str/+CqKZNgqZ640wNDdi
Чат от лектора - https://news.1rj.ru/str/joinchat/MxYT6-01eeA1NTYy
Далее мы будем рассматривать темы с других видео на YouTube, а уроки Ильи мы будем проходить по мере их выпуска на его канале.
👍1
Solidity. Смарт контракты и аудит pinned «Продвинутое обучение Solidity После изучение основ языка, необходимо знать и понимать, как он функционирует, какие паттерны существуют, и на что обращать внимание в коде, чтобы повысить его безопасность. В этих уроках рассматривается огромный пласт Solidity…»