Как получить эфир для сети Goerli
Кстати, для все операций теперь в тестовой сети вам может потребоваться Эфир. Для этого в google вводите в строку поиска goerli faucet.
Например, у меня в поиске в первой ссылке был этот сайт. Можете зарегистрироваться там или поискать другие сайты, которые позволят получать эфир без регистрации.
Теперь нам нужно скопировать адрес нашего кошелька из МетаМаск. Заходим в браузере туда и нажимаем на название аккаунта, чтобы получить наш адрес.
Возвращаемся на сайт faucet (все они работают по одному и тому же принципу), и в поле вставляем наш адрес кошелька. Через пару минут проверяем его и убеждаемся, что теперь там доступно немного ETH.
Так можно делать на других сайтах и собрать чуть больше эфира на кошельке для тестов с контрактом.
Нужно отметить, что этот ETH не имеет никакой ценности и торговать им на бирже не получится. Он создан специально для работы в тестовых сетях.
#goerly #metamask #faucet
Кстати, для все операций теперь в тестовой сети вам может потребоваться Эфир. Для этого в google вводите в строку поиска goerli faucet.
Например, у меня в поиске в первой ссылке был этот сайт. Можете зарегистрироваться там или поискать другие сайты, которые позволят получать эфир без регистрации.
Теперь нам нужно скопировать адрес нашего кошелька из МетаМаск. Заходим в браузере туда и нажимаем на название аккаунта, чтобы получить наш адрес.
Возвращаемся на сайт faucet (все они работают по одному и тому же принципу), и в поле вставляем наш адрес кошелька. Через пару минут проверяем его и убеждаемся, что теперь там доступно немного ETH.
Так можно делать на других сайтах и собрать чуть больше эфира на кошельке для тестов с контрактом.
Нужно отметить, что этот ETH не имеет никакой ценности и торговать им на бирже не получится. Он создан специально для работы в тестовых сетях.
#goerly #metamask #faucet
Кратко о работе с Etherscan
Etherscan - это самый популярный сайт, где можно просматривать контракты, их код, abi и транзакции по ним.
И чтобы легче находить его и верифицировать свой контракт, можно использовать hardhat.
Для этого после регистрации на Etherscan в правом верхнем углу кликаем на аватар своего профиля и выбираем Api keys. Создаем свой ключ и копируем его в новую переменную в файле env, например ETH_KEY.
Затем снова открываем файл hardhat.config.json и в раздел module.exports добавляем:
etherscan: {
apiKey:
}
К слову сказать, у вас уже должен быть подключен новый пакет hardhat-etherscan (в toolbox он уже есть). Если нет, то сделать это можно командой в консоли:
npm install --save-dev @nomiclabs/hardhat-etherscan
и добавлением записи в hardhat.config.json:
require("@nomiclabs/hardhat-etherscan");
После этого в консоли вам станет доступна команда:
npx hardhat verify --network netName contractAddress
где netName - имя тестовой сети, куда вы загрузили свой контракт, а contractAddress - адрес вашего контракта.
Данная команда выдаст вам ссылку на etherscan, где вы можете получить всю информацию по вашему контракту в блокчейне.
#etherscan
Etherscan - это самый популярный сайт, где можно просматривать контракты, их код, abi и транзакции по ним.
И чтобы легче находить его и верифицировать свой контракт, можно использовать hardhat.
Для этого после регистрации на Etherscan в правом верхнем углу кликаем на аватар своего профиля и выбираем Api keys. Создаем свой ключ и копируем его в новую переменную в файле env, например ETH_KEY.
Затем снова открываем файл hardhat.config.json и в раздел module.exports добавляем:
etherscan: {
apiKey:
${process.env.ETH_KEY}}
К слову сказать, у вас уже должен быть подключен новый пакет hardhat-etherscan (в toolbox он уже есть). Если нет, то сделать это можно командой в консоли:
npm install --save-dev @nomiclabs/hardhat-etherscan
и добавлением записи в hardhat.config.json:
require("@nomiclabs/hardhat-etherscan");
После этого в консоли вам станет доступна команда:
npx hardhat verify --network netName contractAddress
где netName - имя тестовой сети, куда вы загрузили свой контракт, а contractAddress - адрес вашего контракта.
Данная команда выдаст вам ссылку на etherscan, где вы можете получить всю информацию по вашему контракту в блокчейне.
#etherscan
Урок 26 - Honeypot
Надеюсь у всех вчера получилось разобраться с деплоем контрактов в различные сети, а также с новым пакетом для скрытия важной информации в коде.
Сегодня же у нас достаточно легкий урок. В нем нужно не столько учиться каким-то фишкам или настройкам пакетов и конфигов, сколько понять общий принцип ловушки: как ее разглядеть в коде и как научиться переигрывать мошенников.
Также это будет полезно, если вы на досуге "играетесь" с криптовалютой, биржами и следите за выходом новых токенов.
Новый видео урок.
Также напоминаю, что завтра у нас будет стрим от Ильи в 19:00 по московскому времени на его канале. Можно будет узнать новую тему, которую мы будем разбирать в пятницу, и задать вопросы по Solidity.
Вероятнее всего, я завтра сделаю несколько простых постов по нюансам языка, дам несколько полезных ссылок и рекомендаций.
На этой неделе мы закончим продвинутое обучение и со следующей я расскажу вам о новых планах.
Всем легкого дня и быстрого обучения!
#урок #honeypot
Надеюсь у всех вчера получилось разобраться с деплоем контрактов в различные сети, а также с новым пакетом для скрытия важной информации в коде.
Сегодня же у нас достаточно легкий урок. В нем нужно не столько учиться каким-то фишкам или настройкам пакетов и конфигов, сколько понять общий принцип ловушки: как ее разглядеть в коде и как научиться переигрывать мошенников.
Также это будет полезно, если вы на досуге "играетесь" с криптовалютой, биржами и следите за выходом новых токенов.
Новый видео урок.
Также напоминаю, что завтра у нас будет стрим от Ильи в 19:00 по московскому времени на его канале. Можно будет узнать новую тему, которую мы будем разбирать в пятницу, и задать вопросы по Solidity.
Вероятнее всего, я завтра сделаю несколько простых постов по нюансам языка, дам несколько полезных ссылок и рекомендаций.
На этой неделе мы закончим продвинутое обучение и со следующей я расскажу вам о новых планах.
Всем легкого дня и быстрого обучения!
#урок #honeypot
YouTube
Solidity и смарт-контракты Ethereum, урок #30 | Безопасность: ловушка "honeypot", ловим хакеров
ХОТИТЕ СТАТЬ РАЗРАБОТЧИКОМ Solidity, узнать об Ethereum, блокчейне и многом другом ещё больше?!
Мои друзья из GUIDE DAO (бывшая школа MCS) предлагают скидку 0,1 ETH на ВСЕ СВОИ БУТКЕМЫ ПО КРИПТЕ! Материалы этих буткемов подготовлены мной и другими специалистами:…
Мои друзья из GUIDE DAO (бывшая школа MCS) предлагают скидку 0,1 ETH на ВСЕ СВОИ БУТКЕМЫ ПО КРИПТЕ! Материалы этих буткемов подготовлены мной и другими специалистами:…
Что такое Honeypot
И по традиции, давайте разберемся, что же такое этот Honeypot.
Honeypot (горшок с медом) - это некая ловушка для пользователей, которая основана на не самых очевидных моментах в коде. Чаще всего им пользуются мошенники, чтобы обманом продать токены, которые нельзя будет потом перепродать.
Допустим, по всем каналам в Телеграм и на популярных ресурсах кто-то делает посты о том, что он запускает крутые токены в оборот, что у него большие планы, и уже несколько крупных компаний поддерживают его инициативу. Конечно же, он предлагает всем пользователям купить его токены по бросовой цене в 0.1 $ и обещает, что через полгода их стоимость будет около 1 $ или даже 5 $. Доверчивые люди бросаются покупать токены в надежде заработать. Но через указанный промежуток времени, никакого роста токена нет, и пользователи решают продать его.
А не тут-то было! Токены продать больше нельзя, и мошенник уходит с деньгами создавать новый скам.
В этом уроке и обращают наше внимание на подобные нюансы в коде, как избежать обмана, и как перехитрить мошенника, если он захочет использовать уязвимость нашего контракта на reentrancy.
#honeypot
И по традиции, давайте разберемся, что же такое этот Honeypot.
Honeypot (горшок с медом) - это некая ловушка для пользователей, которая основана на не самых очевидных моментах в коде. Чаще всего им пользуются мошенники, чтобы обманом продать токены, которые нельзя будет потом перепродать.
Допустим, по всем каналам в Телеграм и на популярных ресурсах кто-то делает посты о том, что он запускает крутые токены в оборот, что у него большие планы, и уже несколько крупных компаний поддерживают его инициативу. Конечно же, он предлагает всем пользователям купить его токены по бросовой цене в 0.1 $ и обещает, что через полгода их стоимость будет около 1 $ или даже 5 $. Доверчивые люди бросаются покупать токены в надежде заработать. Но через указанный промежуток времени, никакого роста токена нет, и пользователи решают продать его.
А не тут-то было! Токены продать больше нельзя, и мошенник уходит с деньгами создавать новый скам.
В этом уроке и обращают наше внимание на подобные нюансы в коде, как избежать обмана, и как перехитрить мошенника, если он захочет использовать уязвимость нашего контракта на reentrancy.
#honeypot
👍1
Разбор Honeypot
Для того, чтобы вы понимали лучше разбор данного урока, я скидываю ссылку на комит урока от лектора. Лучше всего будет, если вы прочитаете пост, а затем еще раз сами просмотрите код контрактов.
Как я понял из урока, honeypot основан на подмене контракта для логирования событий в контракте банка. Вроде как, всем пользователям показывается первый обычный контракт Logger, который просто порождает событие для log, а на самом деле, наследование идет от другого контракта, который был как бы спрятан от глаз пользователей.
И если не разобраться, от кого идет наследование в ILogger public logger в контракте банка, то можно попасть на деньги.
Также в данном примере была использована уязвимость reentrancy (по сути, повторный возов функций кода) в контракте банка, чтобы заманить в ловушку потенциального хакера.
Хакер думает, что раз "balances[_initiator] = 0" вызывается после отправки средств на счет пользователя, то можно создать новый контракт для атаки, который будет вызывать функцию _withdraw каждый раз по новому пока на счету банка не останется средств.
И вот для того, чтобы обмануть хакера, который хочет обмануть нас, в контракте банка мы создаем новую переменную "bool resuming", чтобы запутать хакера, и в функции _withdraw принимаем дополнительный аргумент "uint _statusCode".
После этого, уже как бы мы сами создаем контракт honeypot и обновляем withdraw с новой bool переменной.
Т.е. изначально лектор показывал, что honeypot создал мошенник, чтобы обманывать пользователей, а позже honeypot создаем мы, чтобы обмануть мошенника.
Уже в нашем honeypot мы используем "_actionCode", чтобы определить, кто пытается вызвать withdraw.
Если обычный пользователь снимает свои деньги, то все проходит ок.
Если же мошенник пытается использовать уязвимость reentrancy и вызывать повторно withdraw, то через нее мы вызываем служебную _widthdraw с новым передаваемым аргументом "_statusCode", который на втором вызове меняет значение на "2". Теперь сам мошенник попадает в нашу ловушку honeypot, транзакция откачивается и он не может получить даже свои деньги.
Вот как-то так.
В 4 контрактах и 1 интерфейсе из урока легко запутаться, полагаю как и в данном посте при первом прочтении.
Тут главное понять, что в рамках урока мы действуем и как мошенник и как тот, кто хочет обмануть мошенника, поэтому один код работает сразу для двух примеров.
#honeypot
Для того, чтобы вы понимали лучше разбор данного урока, я скидываю ссылку на комит урока от лектора. Лучше всего будет, если вы прочитаете пост, а затем еще раз сами просмотрите код контрактов.
Как я понял из урока, honeypot основан на подмене контракта для логирования событий в контракте банка. Вроде как, всем пользователям показывается первый обычный контракт Logger, который просто порождает событие для log, а на самом деле, наследование идет от другого контракта, который был как бы спрятан от глаз пользователей.
И если не разобраться, от кого идет наследование в ILogger public logger в контракте банка, то можно попасть на деньги.
Также в данном примере была использована уязвимость reentrancy (по сути, повторный возов функций кода) в контракте банка, чтобы заманить в ловушку потенциального хакера.
Хакер думает, что раз "balances[_initiator] = 0" вызывается после отправки средств на счет пользователя, то можно создать новый контракт для атаки, который будет вызывать функцию _withdraw каждый раз по новому пока на счету банка не останется средств.
И вот для того, чтобы обмануть хакера, который хочет обмануть нас, в контракте банка мы создаем новую переменную "bool resuming", чтобы запутать хакера, и в функции _withdraw принимаем дополнительный аргумент "uint _statusCode".
После этого, уже как бы мы сами создаем контракт honeypot и обновляем withdraw с новой bool переменной.
Т.е. изначально лектор показывал, что honeypot создал мошенник, чтобы обманывать пользователей, а позже honeypot создаем мы, чтобы обмануть мошенника.
Уже в нашем honeypot мы используем "_actionCode", чтобы определить, кто пытается вызвать withdraw.
Если обычный пользователь снимает свои деньги, то все проходит ок.
Если же мошенник пытается использовать уязвимость reentrancy и вызывать повторно withdraw, то через нее мы вызываем служебную _widthdraw с новым передаваемым аргументом "_statusCode", который на втором вызове меняет значение на "2". Теперь сам мошенник попадает в нашу ловушку honeypot, транзакция откачивается и он не может получить даже свои деньги.
Вот как-то так.
В 4 контрактах и 1 интерфейсе из урока легко запутаться, полагаю как и в данном посте при первом прочтении.
Тут главное понять, что в рамках урока мы действуем и как мошенник и как тот, кто хочет обмануть мошенника, поэтому один код работает сразу для двух примеров.
#honeypot
Тесты с урока про 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