Проблемы с обучением и прохождением курсов
Вчера в разговоре со знакомым аудитором речь зашла о возрасте аудиторов и их успехах на поприще поиска багов в конкурсах и баг баунти. Я жаловался, что не получается уделять больше 3-4 часов в день на изучение протоколов, так как помимо этого есть еще и другие дела ежедневно требующие внимания. Легко в этом плане некоторым молодым людям, до 25 лет, у которых еще нет стабильной работы, семьи, детей, и т.д. Они ищут себя, могут много учиться и уделять время тому, что действительно зажигает. Многих могут так или иначе поддерживать родители, и не нужно думать, где взять денег на оплату квартиры и еды.
Не хочу никого обидеть в возрастном плане или в жизненной ситуации, просто говорю, что, если у человека меньше повседневных забот, он может больше времени уделять своему обучению и профессии. Намного проще и быстрее стать хорошим аудитором или разработчиком, если можете без труда уделять 8-10 часов в день своему обучению или аудиту.
Мне повезло, что на момент своего переобучения в web3 я, во-первых, уже был разработчиком, и во-вторых, мог в течение года уделять достаточно времени обучению.
Но вчера я понял, что изучение Solidity/Foundry и чего-то еще может быть трудной задачей, когда ты работаешь на тяжелой (эмоционально и физически) работе, по паре часов тратишь время на дорогу, вечером нужно провести время с семьей, детьми или просто второй половинкой. К тому же постоянно приходят счета на оплату, случаются мелкие неприятности и т.д. И это все намного важнее web3 и порой "выбивает из времени и пространства"...
Я пишу посты на двух каналах и только сейчас задумался об этом.
Что могло бы помочь вам в обучении? Может какой-то формат постов, которые можно читать в метро или автобусе? Мелкие задания на закрепления материалов?
Если и делать далее какие-нибудь модули, то так, чтобы было удобно и практично в любой момент.
Можете поделиться своими способами обучения? Как вам удобнее всего изучать новый материал?
У нас тут большой канал с техническими постами, и, думаю, есть много участников, которые постоянно чему-то учатся. Буду рад услышать ваши лайфхаки.
#learn
Вчера в разговоре со знакомым аудитором речь зашла о возрасте аудиторов и их успехах на поприще поиска багов в конкурсах и баг баунти. Я жаловался, что не получается уделять больше 3-4 часов в день на изучение протоколов, так как помимо этого есть еще и другие дела ежедневно требующие внимания. Легко в этом плане некоторым молодым людям, до 25 лет, у которых еще нет стабильной работы, семьи, детей, и т.д. Они ищут себя, могут много учиться и уделять время тому, что действительно зажигает. Многих могут так или иначе поддерживать родители, и не нужно думать, где взять денег на оплату квартиры и еды.
Не хочу никого обидеть в возрастном плане или в жизненной ситуации, просто говорю, что, если у человека меньше повседневных забот, он может больше времени уделять своему обучению и профессии. Намного проще и быстрее стать хорошим аудитором или разработчиком, если можете без труда уделять 8-10 часов в день своему обучению или аудиту.
Мне повезло, что на момент своего переобучения в web3 я, во-первых, уже был разработчиком, и во-вторых, мог в течение года уделять достаточно времени обучению.
Но вчера я понял, что изучение Solidity/Foundry и чего-то еще может быть трудной задачей, когда ты работаешь на тяжелой (эмоционально и физически) работе, по паре часов тратишь время на дорогу, вечером нужно провести время с семьей, детьми или просто второй половинкой. К тому же постоянно приходят счета на оплату, случаются мелкие неприятности и т.д. И это все намного важнее web3 и порой "выбивает из времени и пространства"...
Я пишу посты на двух каналах и только сейчас задумался об этом.
Что могло бы помочь вам в обучении? Может какой-то формат постов, которые можно читать в метро или автобусе? Мелкие задания на закрепления материалов?
Если и делать далее какие-нибудь модули, то так, чтобы было удобно и практично в любой момент.
Можете поделиться своими способами обучения? Как вам удобнее всего изучать новый материал?
У нас тут большой канал с техническими постами, и, думаю, есть много участников, которые постоянно чему-то учатся. Буду рад услышать ваши лайфхаки.
#learn
🔥13❤4🤔2🙏2
Постфикс и префикс в Solidity
Продолжаю свои попытки в видео формат. В этот раз добавил субтитры, на случай если ролик будут смотреть без звука.
Сложно подобрать какие-либо визуальные выделения кода на видео (обводка функций, подчеркивание, увеличение "под лупу"). Одной программы не достаточно, а при нескольких переводов из одной программы в другую, сильно падает качество видео. И если, скажем, для съемок природы или кошко-девочки это будет не критично, то для отображения кода в редакторе - просто жесть...
Но это так, просто делюсь процессом и трудностями.
Если захотите покопаться в коде протокола с видео, то вот ссылка на контаркт:
https://github.com/code-423n4/2025-01-liquid-ron/blob/main/src/ValidatorTracker.sol#L36
Всем приятной пятницы и отличных выходных!
P.S. Буду также признателен комментариям по формату видео: что можно улучшить, что добавить или вообще убрать.
#video
Продолжаю свои попытки в видео формат. В этот раз добавил субтитры, на случай если ролик будут смотреть без звука.
Сложно подобрать какие-либо визуальные выделения кода на видео (обводка функций, подчеркивание, увеличение "под лупу"). Одной программы не достаточно, а при нескольких переводов из одной программы в другую, сильно падает качество видео. И если, скажем, для съемок природы или кошко-девочки это будет не критично, то для отображения кода в редакторе - просто жесть...
Но это так, просто делюсь процессом и трудностями.
Если захотите покопаться в коде протокола с видео, то вот ссылка на контаркт:
https://github.com/code-423n4/2025-01-liquid-ron/blob/main/src/ValidatorTracker.sol#L36
Всем приятной пятницы и отличных выходных!
P.S. Буду также признателен комментариям по формату видео: что можно улучшить, что добавить или вообще убрать.
#video
🔥10❤3
Обучающий модуль по Foundry?
Новый месяц, новые знания и цели!
Прежде всего, ниже будет еще один опрос для желающих пройти интенсив по работе с Foundry, и прошу всех, кто точно планирует зайти на него, проголосовать.
Если будет небольшое количество желающих, то мы перенесем его на более поздний срок. Если же группа наберется, то мы начнем уже со следующей неделе, а продажи откроем в эту среду.
Больше информации о самом интенсиве можно найти в этом посте:
https://news.1rj.ru/str/solidityset/1310
Я провожу опрос, чтобы распределить свою нагрузку на этот месяц: либо отменю часть работ и большую часть времени буду уделять ученикам и ответам на вопросы, либо сам больше буду принимать участие в bug bounty программах и конкурсах по аудиту, а на канале будем разбирать интересные темы с delegatecall.
Также напоминаю, что я еще веду параллельно небольшой канал по Defi:
https://news.1rj.ru/str/defisolset
Недавно мы закончили делать разбор протокола Torando Cash, а после рассмотрели темы процентной ставки AAVE V3 и Compound, а также ликвидации и залога. Сейчас знакомимся с Aave v3.
Это, скорее, канал для продвинутых разработчиков, которые уже знают Solidity, и которым интересна тема DeFi протоколов.
Всем приятной недели и легкого обучения!
#offtop
Новый месяц, новые знания и цели!
Прежде всего, ниже будет еще один опрос для желающих пройти интенсив по работе с Foundry, и прошу всех, кто точно планирует зайти на него, проголосовать.
Если будет небольшое количество желающих, то мы перенесем его на более поздний срок. Если же группа наберется, то мы начнем уже со следующей неделе, а продажи откроем в эту среду.
Больше информации о самом интенсиве можно найти в этом посте:
https://news.1rj.ru/str/solidityset/1310
Я провожу опрос, чтобы распределить свою нагрузку на этот месяц: либо отменю часть работ и большую часть времени буду уделять ученикам и ответам на вопросы, либо сам больше буду принимать участие в bug bounty программах и конкурсах по аудиту, а на канале будем разбирать интересные темы с delegatecall.
Также напоминаю, что я еще веду параллельно небольшой канал по Defi:
https://news.1rj.ru/str/defisolset
Недавно мы закончили делать разбор протокола Torando Cash, а после рассмотрели темы процентной ставки AAVE V3 и Compound, а также ликвидации и залога. Сейчас знакомимся с Aave v3.
Это, скорее, канал для продвинутых разработчиков, которые уже знают Solidity, и которым интересна тема DeFi протоколов.
Всем приятной недели и легкого обучения!
#offtop
🔥4
Foundry откладывается, но будет что-то интересное!
К сожалению, проголосовавших за участие в модуле не набралось достаточного количества, поэтому я принял решение немного повременить с данным интенсивом. Скорее всего, теперь он будет включен в большой Летний Практический модуль. Те, кто хотел зайти на него в этот раз, просто смогут докупить его отдельно.
При этом дела у нас всегда есть: на канале будут дальше выходить посты про Solidity, я по не многу буду записывать видео про всякие интересные штуки в коде, и подумываю сделать долгий цикл постов про создание dApp.
За все три года, что ведется этот канал, я никогда не поднимал тему, как создавать свои проекты, которые будут взаимодействовать с блокчейном: как написать сайт на react, как подключить регистрацию через кошелек, как делать вызовы в сеть и отслеживать результат, и т.д.
И решил, что было бы полезно написать цикл постов, в котором буду показывать как создать простой проект: от идеи до запуска. Мы будем обсуждать идеи, решения и проблемы безопасности. Вы увидите полный цикл создания dApp.
Основной идеей будет сделать так, чтобы все стало понятно новичку: самый базовый код JS, бэкенд и все остальное, чтобы вы могли по моим стопам делать свой собственный продукт.
Это цикл постов на полгода-год, так как буквально будет включать каждый этап разработки. Выходить посты будут по мере возможностей, так как делать их буду в свободное от основной работы время.
Пока как-то так! Возвращаемся в "задротное русло".
#offtop
К сожалению, проголосовавших за участие в модуле не набралось достаточного количества, поэтому я принял решение немного повременить с данным интенсивом. Скорее всего, теперь он будет включен в большой Летний Практический модуль. Те, кто хотел зайти на него в этот раз, просто смогут докупить его отдельно.
При этом дела у нас всегда есть: на канале будут дальше выходить посты про Solidity, я по не многу буду записывать видео про всякие интересные штуки в коде, и подумываю сделать долгий цикл постов про создание dApp.
За все три года, что ведется этот канал, я никогда не поднимал тему, как создавать свои проекты, которые будут взаимодействовать с блокчейном: как написать сайт на react, как подключить регистрацию через кошелек, как делать вызовы в сеть и отслеживать результат, и т.д.
И решил, что было бы полезно написать цикл постов, в котором буду показывать как создать простой проект: от идеи до запуска. Мы будем обсуждать идеи, решения и проблемы безопасности. Вы увидите полный цикл создания dApp.
Основной идеей будет сделать так, чтобы все стало понятно новичку: самый базовый код JS, бэкенд и все остальное, чтобы вы могли по моим стопам делать свой собственный продукт.
Это цикл постов на полгода-год, так как буквально будет включать каждый этап разработки. Выходить посты будут по мере возможностей, так как делать их буду в свободное от основной работы время.
Пока как-то так! Возвращаемся в "задротное русло".
#offtop
1👍13🔥5❤2❤🔥1😱1
Calldata Encoding
Знаете то чувство в процессе своего обучения, когда ты вроде бы понял тему и можешь ее рассказать, но спустя какое-то время возвращаешься к ней и пытаешься разобраться вновь?
У меня так происходит с некоторыми задачами (Ethernaut, DVD и другими). Вот я решил задачу, написал контракт, понял, как это делается, но вот что-то непонятное так и "не зацепилось". Сейчас я хочу с вами еще раз пройти одну тему и после разобрать задачу на видео. Может после этого, все сложится как надо.
Итак, у нас есть простая функция:
Вы знаете, как будут располагаться данные в аргументах функции? Если да - то вообще здорово, если нет - давайте разбираться.
В Solidity существуют статичные типы данных:
uint, int, address, bool, bytes - n, tuple
Они представлены в шестнадцатеричном формате, дополненные нулями, чтобы занять весь слот в 32 байта.
Например:
А также есть динамические типы данных:
string, bytes, array
Для них кодирование calldata будет выглядеть так:
- Первые 32 байта - смещение;
- Следующие 32 байта - длинна;
- Затем - значения;
Например, для байтов:
где:
Для строк:
где:
И для массивов:
где:
С примерами кода посты получаются большими, поэтому в следующем мы поговорим про offset.
#calldata
Знаете то чувство в процессе своего обучения, когда ты вроде бы понял тему и можешь ее рассказать, но спустя какое-то время возвращаешься к ней и пытаешься разобраться вновь?
У меня так происходит с некоторыми задачами (Ethernaut, DVD и другими). Вот я решил задачу, написал контракт, понял, как это делается, но вот что-то непонятное так и "не зацепилось". Сейчас я хочу с вами еще раз пройти одну тему и после разобрать задачу на видео. Может после этого, все сложится как надо.
Итак, у нас есть простая функция:
function flipSwitch(bytes memory _data) public onlyOff {
(bool success, ) = address(this).call(_data);
require(success, "call failed :(");
}Вы знаете, как будут располагаться данные в аргументах функции? Если да - то вообще здорово, если нет - давайте разбираться.
В Solidity существуют статичные типы данных:
uint, int, address, bool, bytes - n, tuple
Они представлены в шестнадцатеричном формате, дополненные нулями, чтобы занять весь слот в 32 байта.
Например:
Input: 23 (uint256)
Output:
0x0000000000000000000000000000000000000000000000000000000000000017
Input: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f (address of Uniswap)
Output:
0x000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f
А также есть динамические типы данных:
string, bytes, array
Для них кодирование calldata будет выглядеть так:
- Первые 32 байта - смещение;
- Следующие 32 байта - длинна;
- Затем - значения;
Например, для байтов:
Input: 0x123
Output:
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000
где:
offset:
0000000000000000000000000000000000000000000000000000000000000020
length(the value is 2 bytes length = 4 chrs):
0000000000000000000000000000000000000000000000000000000000000002
value(the value of string and bytes starts right after the length):
1234000000000000000000000000000000000000000000000000000000000000
Для строк:
Input: “GM Frens”
Output:
0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000008474d204672656e73000000000000000000000000000000000000000000000000
где:
offset:
0000000000000000000000000000000000000000000000000000000000000020
length:
0000000000000000000000000000000000000000000000000000000000000008
value(“GM Frens” in hex):
474d204672656e73000000000000000000000000000000000000000000000000
И для массивов:
Input: [1,3,42] → uint256 array
Output:
0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000002a
где:
offset:
0000000000000000000000000000000000000000000000000000000000000020
length (3 elements in the array):
0000000000000000000000000000000000000000000000000000000000000003
first element value(1):
0000000000000000000000000000000000000000000000000000000000000001
second element value(3):
0000000000000000000000000000000000000000000000000000000000000003
third element value(42):
000000000000000000000000000000000000000000000000000000000000002a
С примерами кода посты получаются большими, поэтому в следующем мы поговорим про offset.
#calldata
🔥8
Calldata Encoding. Часть 2
Что такое смещение - offset?
Смещение указывает на начало данных. Данные формируются из длины и значения. В нашем примере смещение было 20 в шестнадцатеричном формате, что равно 32 в десятичном. Это означает, что наши данные начинаются после первых 32 байт от начала кодировки.
Рассмотрим пример функции calldata, которая имеет как статические, так и динамические параметры:
Calldata в этом случае будет выглядеть так:
И ее можно разобрать на:
Как видно из этого примера, с помощью смещения можно переместить содержимое данных (длину и значение) после параметра адреса(to).
И такое формирование calldata может приводить к взлому вашего протокола!
Как? Постараюсь рассказать в ближайшем видео!
#calldata
Что такое смещение - offset?
Смещение указывает на начало данных. Данные формируются из длины и значения. В нашем примере смещение было 20 в шестнадцатеричном формате, что равно 32 в десятичном. Это означает, что наши данные начинаются после первых 32 байт от начала кодировки.
0000000000000000000000000000000000000000000000000000000000000020
^
| -> counting 32 bytes from here
0000000000000000000000000000000000000000000000000000000000000004
^
| so this is the actual start
20606e1500000000000000000000000000000000000000000000000000000000
Рассмотрим пример функции calldata, которая имеет как статические, так и динамические параметры:
pragma solidity 0.8.19;
contract Example {
function transfer(bytes memory data, address to) external;
}
data: 0x1234
to: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
Calldata в этом случае будет выглядеть так:
0xbba1b1cd00000000000000000000000000000000000000000000000000000000000000400000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000
И ее можно разобрать на:
0x
function selector (transfer):
Bba1b1cd
offset of the 'data' param (64 in decimal):
0000000000000000000000000000000000000000000000000000000000000040
address param 'to':
0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f
length of the 'data' param:
0000000000000000000000000000000000000000000000000000000000000002
value of the 'data' param:
1234000000000000000000000000000000000000000000000000000000000000
Как видно из этого примера, с помощью смещения можно переместить содержимое данных (длину и значение) после параметра адреса(to).
И такое формирование calldata может приводить к взлому вашего протокола!
Как? Постараюсь рассказать в ближайшем видео!
#calldata
👍6❤1🤯1
Проект на виду. Часть 1. Что по донатам?
На прошлой неделе я писал, что хочу, здесь на канале, создать web3 проект и показать весь процесс от и до: от идеи и до первой транзакции в сети. И сегодня первый пост в этом большом цикле.
Я долго думал, что же такое реализовать, чтобы было и интересно, и полезно, и показывало бы разработку с разных сторон, включая фронт, бек, смарт контракты, тестирование и т.д. У меня были как простые идеи, вроде, аукциона, и более сложные: полноценный DeFi протокол.
В первом случае, мне самому это было бы не интересно, во втором - я не так хорошо дружу с математикой, чтобы писать формулы, а копировать юнисваповский x*y=k как-то не хочется.
Решающую роль в выборе проекта сыграло мое увлечение настольной игрой ДНД.
Я подписан на канал одного прекрасного мастера, который постоянно делает контент с разборами механик и выкладывает кучу полезной информации по механикам игры. И в очередной раз, когда он выложил подборку своих файлов, я был очень впечатлен и в благодарность отправил ему донат. А потом вдруг понял...
Я регулярно поддерживаю нескольких авторов, которые постоянно делятся свои авторским контентом: ДНД, озвучка, психология, ВПН, игры и пару других. Это не большие суммы: от 100 до 500 рублей.
И я подумал, что через проект с донатом криптой я смогу также поддержать авторов и, кроме того, немного поспособствовать общему распространению знаний о web3.
Хочется создать что-то очень простое: чтобы авторы могли и без кошельков начать принимать донаты, и для других пользователей - отправить донат без долгих разборов в UI/UX сайта.
Кроме того, здесь не будет каких-то супер навороченных расчетов, но при этом присутствуют все этапы разработки, о которых писал выше: фронт, бек, смарт контракты и тестирование.
А что вы думаете про донаты и поддержку авторов? Есть ли у вас действующие подписки или поддерживали ли авторов когда-нибудь?
#openproject
На прошлой неделе я писал, что хочу, здесь на канале, создать web3 проект и показать весь процесс от и до: от идеи и до первой транзакции в сети. И сегодня первый пост в этом большом цикле.
Я долго думал, что же такое реализовать, чтобы было и интересно, и полезно, и показывало бы разработку с разных сторон, включая фронт, бек, смарт контракты, тестирование и т.д. У меня были как простые идеи, вроде, аукциона, и более сложные: полноценный DeFi протокол.
В первом случае, мне самому это было бы не интересно, во втором - я не так хорошо дружу с математикой, чтобы писать формулы, а копировать юнисваповский x*y=k как-то не хочется.
Решающую роль в выборе проекта сыграло мое увлечение настольной игрой ДНД.
Я подписан на канал одного прекрасного мастера, который постоянно делает контент с разборами механик и выкладывает кучу полезной информации по механикам игры. И в очередной раз, когда он выложил подборку своих файлов, я был очень впечатлен и в благодарность отправил ему донат. А потом вдруг понял...
Я регулярно поддерживаю нескольких авторов, которые постоянно делятся свои авторским контентом: ДНД, озвучка, психология, ВПН, игры и пару других. Это не большие суммы: от 100 до 500 рублей.
И я подумал, что через проект с донатом криптой я смогу также поддержать авторов и, кроме того, немного поспособствовать общему распространению знаний о web3.
Хочется создать что-то очень простое: чтобы авторы могли и без кошельков начать принимать донаты, и для других пользователей - отправить донат без долгих разборов в UI/UX сайта.
Кроме того, здесь не будет каких-то супер навороченных расчетов, но при этом присутствуют все этапы разработки, о которых писал выше: фронт, бек, смарт контракты и тестирование.
А что вы думаете про донаты и поддержку авторов? Есть ли у вас действующие подписки или поддерживали ли авторов когда-нибудь?
#openproject
🔥19❤4
Calldata Encoding. Часть 3
Вот и обещанное видео с решением одной из задач Ethernaut, для которой мы разбирали ранее вопросы с calldata.
Саму задачу можно найти по ссылке:
https://ethernaut.openzeppelin.com/level/29
А тест для нее вот:
Если вы хотели поэкспериментировать с передачей данных в виде calldata между контрактами, то это отличная возможность.
P.S. Буду рад комментариям и отзывам по видео. Все еще экспериментирую со стилем и созданием формата.
#calldata
Вот и обещанное видео с решением одной из задач Ethernaut, для которой мы разбирали ранее вопросы с calldata.
Саму задачу можно найти по ссылке:
https://ethernaut.openzeppelin.com/level/29
А тест для нее вот:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../src/Switch.sol";
import {Test, console} from "forge-std/Test.sol";
contract SwitchTest is Test {
Switch switchContract;
function setUp() public {
switchContract = new Switch();
}
function test_Switch() external {
bytes memory callData = hex"30c13ade0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000020606e1500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000476227e1200000000000000000000000000000000000000000000000000000000";
(bool success, ) = address(switchContract).call(callData);
require (success, "Call failed!");
assertTrue(switchContract.switchOn());
}
}
Если вы хотели поэкспериментировать с передачей данных в виде calldata между контрактами, то это отличная возможность.
P.S. Буду рад комментариям и отзывам по видео. Все еще экспериментирую со стилем и созданием формата.
#calldata
👍7
Solidity 0.8.29
Вчера выпустили новую версию Solidity, вот несколько ключевых изменений, а также пара ссылок.
1. В версии 0.8.29 появилась экспериментальная поддержка EVM Object Format (EOF). Обратите внимание, что эта функция может быть включена только при компиляции для версии EVM Osaka, которая еще не была развернута в mainnet или testnets.
Чуть больше об этом можно узнать тут:
https://x.com/uttam_singhk/status/1830526179105001771
В связи с экспериментальным характером функции, не все синтаксические различия покрываются проверками анализа на данный момент, и в некоторых случаях вы можете столкнуться с внутренними ошибками компилятора при попытке их использования.
Кроме того, компиляция в EOF может быть выполнена только через IR и только при включенном оптимизаторе. Текущая реализация, однако, не включает никаких низкоуровневых оптимизаций, что может привести к увеличению размера кода в некоторых случаях.
Чтобы опробовать ее на своем контракте, используйте --experimental-eof-version 1 в командной строке или settings.eofVersion: 1 в стандартном JSON и не забудьте выбрать версию EVM, которая ее поддерживает (--evm-version osaka/settings.evmVersion: «osaka»).
2. В этом выпуске появился синтаксис для перемещения переменных хранения контракта в произвольное место.
Поддержка указания местоположения хранилища - один из самых старых и обсуждаемых запросов в трекере проблем Solidity, но множество вариантов использования и потенциально противоречивые требования до сих пор не позволяли прийти к какому-то конкретному решению. С включением EIP-7702: Set EOA account code в обновление Pectra, это стало критичным для безопасной реализации абстракции учетных записей, и разработчики решили сделать этот вариант использования приоритетным.
В настоящее время синтаксис очень ограничен: базовое местоположение может быть только буквальным выражением и применяется ко всему дереву наследования.
Чуть больше о EIP7702 можно прочитать тут:
https://cantina.xyz/introduction/pectra-competition-resources/eip-7702
3. Начальная поддержка ethdebug. Этот релиз также представляет первый экспериментальный шаг к поддержке ethdebug - формата отладочных данных, подходящего для смарт-контрактов.
Текущая реализация поддерживает генерацию инструкций и диапазонов исходных текстов. Эта начальная версия поддерживает только неоптимизированную компиляцию через IR и все еще не имеет многих важных возможностей.
Если вы хотите попробовать, вы можете включить вывод ethdebug в командной строке с помощью команды:
Чтобы запросить артефакты ethdebug в стандартном JSON, добавьте
в settings.outputSelection (обратите внимание, что символ «*» не включает его). Также не забывайте, что settings.viaIR: true/--via-ir необходим для работы функции.
4. Также были исправлены несколько проблем с SMTChecker, Error Reporting, Yul Optimizer, а также перешил с C++17 на C++20.
#solidity
Вчера выпустили новую версию Solidity, вот несколько ключевых изменений, а также пара ссылок.
1. В версии 0.8.29 появилась экспериментальная поддержка EVM Object Format (EOF). Обратите внимание, что эта функция может быть включена только при компиляции для версии EVM Osaka, которая еще не была развернута в mainnet или testnets.
Чуть больше об этом можно узнать тут:
https://x.com/uttam_singhk/status/1830526179105001771
В связи с экспериментальным характером функции, не все синтаксические различия покрываются проверками анализа на данный момент, и в некоторых случаях вы можете столкнуться с внутренними ошибками компилятора при попытке их использования.
Кроме того, компиляция в EOF может быть выполнена только через IR и только при включенном оптимизаторе. Текущая реализация, однако, не включает никаких низкоуровневых оптимизаций, что может привести к увеличению размера кода в некоторых случаях.
Чтобы опробовать ее на своем контракте, используйте --experimental-eof-version 1 в командной строке или settings.eofVersion: 1 в стандартном JSON и не забудьте выбрать версию EVM, которая ее поддерживает (--evm-version osaka/settings.evmVersion: «osaka»).
2. В этом выпуске появился синтаксис для перемещения переменных хранения контракта в произвольное место.
contract C layout at 2**255 - 42 {
uint x;
}Поддержка указания местоположения хранилища - один из самых старых и обсуждаемых запросов в трекере проблем Solidity, но множество вариантов использования и потенциально противоречивые требования до сих пор не позволяли прийти к какому-то конкретному решению. С включением EIP-7702: Set EOA account code в обновление Pectra, это стало критичным для безопасной реализации абстракции учетных записей, и разработчики решили сделать этот вариант использования приоритетным.
В настоящее время синтаксис очень ограничен: базовое местоположение может быть только буквальным выражением и применяется ко всему дереву наследования.
Чуть больше о EIP7702 можно прочитать тут:
https://cantina.xyz/introduction/pectra-competition-resources/eip-7702
3. Начальная поддержка ethdebug. Этот релиз также представляет первый экспериментальный шаг к поддержке ethdebug - формата отладочных данных, подходящего для смарт-контрактов.
Текущая реализация поддерживает генерацию инструкций и диапазонов исходных текстов. Эта начальная версия поддерживает только неоптимизированную компиляцию через IR и все еще не имеет многих важных возможностей.
Если вы хотите попробовать, вы можете включить вывод ethdebug в командной строке с помощью команды:
--ethdebug/--ethdebug-runtime.
Чтобы запросить артефакты ethdebug в стандартном JSON, добавьте
evm.bytecode.ethdebug»/«evm.deployedBytecode.ethdebug
в settings.outputSelection (обратите внимание, что символ «*» не включает его). Также не забывайте, что settings.viaIR: true/--via-ir необходим для работы функции.
4. Также были исправлены несколько проблем с SMTChecker, Error Reporting, Yul Optimizer, а также перешил с C++17 на C++20.
#solidity
1🔥9❤1
Понимание метаданных смарт-контракта. Часть 1
Нашел интересную статью о метаданных в смарт контрактах. Я, вроде как, за три года ведения канала ни разу толком о них не писал, поэтому разберем эту тему на простых примерах.
Когда solidity генерирует байткод для развертываемого смарт-контракта, он добавляет метаданные о компиляции в конец байткода. Мы рассмотрим данные, содержащиеся в этом байткоде.
Давайте посмотрим на вывод компилятора простейшего смарт-контракта solidity:
Контракт буквально ничего не делает. Мы можем скомпилировать его, чтобы увидеть код инициализации с помощью
Мы получим следующий вывод:
Это кажется ужасно большим для контракта, который ничего не делает, верно? Давайте разберемся, что представляет собой весь этот байткод.
Когда мы компилируем код с помощью
solc --optimize-runs 1000 --bin --no-cbor-metadata contractFile.sol
мы получаем следующий результат:
Это гораздо меньше! Но что же это за дополнительная информация?
Метаданные Solidity
По умолчанию компилятор Solidity добавляет метаданные в конец «фактического» initcode, который сохраняется в блокчейне после завершения выполнения конструктора. Ниже приведен «дополнительный» код:
Последние два байта 0033 означают «посмотрите назад на 0x33 байта, это метаданные». Это относится ко всему коду между ведущим fe (который является операционным кодом INVALID) и конечным 0033. Мы можем проверить, что это действительно 0x33 байта.
Так что же это за строка 0x33 (51 decimal)?
Мы можем получить подсказку, если внесем в исходный код одно крошечное, казалось бы, несущественное изменение. Это изменение - буквально дополнительный комментарий:
На скриншоте выше показаны результаты до и после.
А как они расшифровываются, узнаем из следующего поста.
#metadata
Нашел интересную статью о метаданных в смарт контрактах. Я, вроде как, за три года ведения канала ни разу толком о них не писал, поэтому разберем эту тему на простых примерах.
Когда solidity генерирует байткод для развертываемого смарт-контракта, он добавляет метаданные о компиляции в конец байткода. Мы рассмотрим данные, содержащиеся в этом байткоде.
Давайте посмотрим на вывод компилятора простейшего смарт-контракта solidity:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Empty {
constructor() payable {}
}
Контракт буквально ничего не делает. Мы можем скомпилировать его, чтобы увидеть код инициализации с помощью
solc --optimize-runs 1000 --bin contractFile.sol
Мы получим следующий вывод:
======= contractFile.sol:Empty =======
Binary:
6080604052603e80600 f5f395ff3fe60806040525f80fdfea26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c63430008140033
Это кажется ужасно большим для контракта, который ничего не делает, верно? Давайте разберемся, что представляет собой весь этот байткод.
Когда мы компилируем код с помощью
solc --optimize-runs 1000 --bin --no-cbor-metadata contractFile.sol
мы получаем следующий результат:
======= contractFile.sol:Empty =======
Binary:
6080604052600880600 f5f395ff3fe60806040525f80fd
Это гораздо меньше! Но что же это за дополнительная информация?
Метаданные Solidity
По умолчанию компилятор Solidity добавляет метаданные в конец «фактического» initcode, который сохраняется в блокчейне после завершения выполнения конструктора. Ниже приведен «дополнительный» код:
fea26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c63430008140033
Последние два байта 0033 означают «посмотрите назад на 0x33 байта, это метаданные». Это относится ко всему коду между ведущим fe (который является операционным кодом INVALID) и конечным 0033. Мы можем проверить, что это действительно 0x33 байта.
# fe and 0033 are not included
>>>hex(len('a26469706673582212203082dbb4f4db7e5d53b235f44d3e38f839dc82075e2cda9df05b88e6585bca8164736f6c6343000814') // 2)
# '0x33'
Так что же это за строка 0x33 (51 decimal)?
Мы можем получить подсказку, если внесем в исходный код одно крошечное, казалось бы, несущественное изменение. Это изменение - буквально дополнительный комментарий:
//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
contract Empty {
// nothing
constructor() payable {}
}
На скриншоте выше показаны результаты до и после.
А как они расшифровываются, узнаем из следующего поста.
#metadata
1👍6❤1
Понимание метаданных смарт-контракта. Часть 2
Выходные прошли и пора возвращаться к рабочим ритмам.
С прошлым постом я забыл дать прикрепить ссылку к оригинальной статье, поэтому исправляюсь и выделяю ее отдельно:
https://www.rareskills.io/post/solidity-metadata
Вообще у RareSkills очень хороший всегда материал и, при изучении каакой-либо темы, рекомендую искать подборки там.
А сейчас мы продолжаем разговор о metadata.
Расшифровка metadata
Давайте посмотрим на гекс в синей рамке скрина из предыдущего поста:
Далее рассмотрим код в красном поле:
Это дает нам подсказку о том, что содержат эти данные: хэш IPFS и версию компилятора solidity.
Хэш IPFS
Раздел, подчеркнутый желтым, вместе с бирюзовой рамкой можно поместить в следующий python-скрипт (обратите внимание, что мы используем версию кода с комментарием // nothing):
Qm...RTEa - это IPFS-хэш файла метаданных, созданного компилятором. Этот участок кода (бирюзовый и желтый) кодируется иначе, чем поля выше. В частности, IPFS-хэш (бирюзовый и желтый) представляет собой закодированную в base58 версию шестнадцатеричных данных «1220...RTEa».
Это хэш IPFS, который вы получите, если поместите JSON-файл из компилятора Solidity на IPFS. На скрине этого поста файл JSON, о котором идет речь.
Мы можем сохранить JSON-файл как реальный файл, а затем проверить, что хэш совпадает с тем, который мы создали в python выше. Вам понадобится установленный инструмент командной строки ipfs (как установить).
Это совпадает с хэшем, полученным ранее.
Не приведет ли это к коллизиям хэшей?
Если два контракта с идентичным исходным кодом и конфигурацией компилятора хранят свой проверенный исходный код на IPFS, хэши IPFS будут сталкиваться (clash), но это желательно, потому что это экономит место storage. Смарт-контракты однозначно идентифицируются по комбинации идентификатора цепочки и их адреса, а не по содержимому IPFS.
Получение версии solidity
Наконец, если мы преобразуем секцию в оранжевой рамке, то получим версию solidity.
Зачем нужны метаданные смарт-контракта?
Эти метаданные добавляют дополнительные 53 байта к стоимости развертывания, что означает дополнительные 10 600 газа (200 на байткод) + стоимость calldata (16 газа на ненулевой байт, 4 газа на нулевой байт). Это означает до 848 дополнительных газа к стоимости calldata.
Так зачем это включать?
Это позволяет строго проверять код смарт-контракта. В метаданные JSON, которые выводит компилятор, входит хэш исходного кода. Поэтому если исходный код немного изменится, то изменится и JSON-файл метаданных, и его IPFS-хэш изменится.
Один странный трюк для снижения расхода газа через хэш IPFS
Один из очевидных способов оптимизировать затраты на газ во время развертывания - использовать опцию --no-cbor-metadata. Но если вам это нужно для проверки контракта, то вы все равно можете снизить стоимость газа, добывая хэши IPFS, в которых много нулевых байтов.
Когда контракт будет развернут, нулевые байты уменьшат стоимость calldata. Поскольку исходный код хэшируется, включая комментарии, это означает, что можно добывать комментарии, которые приводят к газоэффективным хэшам IPFS, которые будут добавлены к контракту. Обратите внимание, это означает, что мы хотим, чтобы в шестнадцатеричном представлении хэша были нули, а не в кодировке base58.
#metadata
Выходные прошли и пора возвращаться к рабочим ритмам.
С прошлым постом я забыл дать прикрепить ссылку к оригинальной статье, поэтому исправляюсь и выделяю ее отдельно:
https://www.rareskills.io/post/solidity-metadata
Вообще у RareSkills очень хороший всегда материал и, при изучении каакой-либо темы, рекомендую искать подборки там.
А сейчас мы продолжаем разговор о metadata.
Расшифровка metadata
Давайте посмотрим на гекс в синей рамке скрина из предыдущего поста:
>>> bytes.fromhex("69706673").decode("ASCII")
'ipfs'Далее рассмотрим код в красном поле:
>>> bytes.fromhex("736f6c63").decode("ASCII")
'solc'Это дает нам подсказку о том, что содержат эти данные: хэш IPFS и версию компилятора solidity.
Хэш IPFS
Раздел, подчеркнутый желтым, вместе с бирюзовой рамкой можно поместить в следующий python-скрипт (обратите внимание, что мы используем версию кода с комментарием // nothing):
import base58
hex_ipfs_hash = "12206a68b6b8bcc01ba559ec3adf7a387b6c4210a5dc69a05d038e9d17cae3fa373b"
bytes_str = bytes.fromhex(hex_ipfs_hash)
print(base58.b58encode(bytes_str).decode("utf-8"))
# QmVW2XyafSxDtiSqirJRauuT5SaQtGnQYsxxyYHrFmRTEa
Qm...RTEa - это IPFS-хэш файла метаданных, созданного компилятором. Этот участок кода (бирюзовый и желтый) кодируется иначе, чем поля выше. В частности, IPFS-хэш (бирюзовый и желтый) представляет собой закодированную в base58 версию шестнадцатеричных данных «1220...RTEa».
Это хэш IPFS, который вы получите, если поместите JSON-файл из компилятора Solidity на IPFS. На скрине этого поста файл JSON, о котором идет речь.
Мы можем сохранить JSON-файл как реальный файл, а затем проверить, что хэш совпадает с тем, который мы создали в python выше. Вам понадобится установленный инструмент командной строки ipfs (как установить).
mkdir out
solc --optimize-runs 1000 --bin --metadata C.sol --output-dir out
# Compiler run successful. Artifact(s) can be found in directory "out".
ipfs add -qr --only-hash out/Empty_meta.json
# QmVW2XyafSxDtiSqirJRauuT5SaQtGnQYsxxyYHrFmRTEa
Это совпадает с хэшем, полученным ранее.
Не приведет ли это к коллизиям хэшей?
Если два контракта с идентичным исходным кодом и конфигурацией компилятора хранят свой проверенный исходный код на IPFS, хэши IPFS будут сталкиваться (clash), но это желательно, потому что это экономит место storage. Смарт-контракты однозначно идентифицируются по комбинации идентификатора цепочки и их адреса, а не по содержимому IPFS.
Получение версии solidity
Наконец, если мы преобразуем секцию в оранжевой рамке, то получим версию solidity.
>>> 0x00 # solidity is version 0
0
>>> 0x08 # major version
8
>>> 0x14 # minor version
20
# correct, we used solidity 0.8.20
Зачем нужны метаданные смарт-контракта?
Эти метаданные добавляют дополнительные 53 байта к стоимости развертывания, что означает дополнительные 10 600 газа (200 на байткод) + стоимость calldata (16 газа на ненулевой байт, 4 газа на нулевой байт). Это означает до 848 дополнительных газа к стоимости calldata.
Так зачем это включать?
Это позволяет строго проверять код смарт-контракта. В метаданные JSON, которые выводит компилятор, входит хэш исходного кода. Поэтому если исходный код немного изменится, то изменится и JSON-файл метаданных, и его IPFS-хэш изменится.
Один странный трюк для снижения расхода газа через хэш IPFS
Один из очевидных способов оптимизировать затраты на газ во время развертывания - использовать опцию --no-cbor-metadata. Но если вам это нужно для проверки контракта, то вы все равно можете снизить стоимость газа, добывая хэши IPFS, в которых много нулевых байтов.
Когда контракт будет развернут, нулевые байты уменьшат стоимость calldata. Поскольку исходный код хэшируется, включая комментарии, это означает, что можно добывать комментарии, которые приводят к газоэффективным хэшам IPFS, которые будут добавлены к контракту. Обратите внимание, это означает, что мы хотим, чтобы в шестнадцатеричном представлении хэша были нули, а не в кодировке base58.
#metadata
👍2❤1
Проект на виду. Часть 2. Нейросети
Продолжаю делиться процессом создания проекта, о котором говорил в предыдущих постах - Пост 1 и Пост 2.
В последнее время я все чаще натыкался на посты/статьи/вопросы по нейросетям и редакторам кода на их основе. Очень долгое время я сопротивлялся этой технологии и специально игнорировал ее наличие...
И вот только две недели назад я установил свою первую нейросеть - DeepSeek. Во-первых, она была доступна для пользователей из РФ без ВПН, а во-вторых, не требовалась регистрация с телефоном.
Я поигрался в ней около недели и не совсем тогда понял, в чем прикол. Ну, в целом, я умею хорошо гуглить и искать нужную мне информацию и не понимал, что может дать мне простой чат.
На прошлой неделе я решил зайти еще чуть дальше и экспериментировал с остальными нейронками: ChatGPT, Claude, Grok 3, Gemini и даже скачивал редакторы кода: Cursor и Windsurf. Также смотрел много видео по этой теме: как писать промты, какие лимиты есть, для каких целей какие сети предназначены и т.д.
В итоге, после более-менее правильной работе с ними и адекватными запросами, я был впечатлен результатами. В особенности, их возможности объяснить код на разных языках.
И после этого, первым вопросом в моей голове было:
"Как лучше поступить с учениками на курсе: взять обещание не использовать нейронки хотя бы на первых модулях или наоборот: подсказать, как лучше работать с ними?"
Но это еще в процессе осознания...
А пока мне интересно было бы еще научиться самому работать с сетями и попробовать написать задуманный проект с ними.
Что бы вы понимали, в плане редакторов и кода я немного "динозавр" что ли... За все время, что я писал код (js, php) в своей карьере, я использовал Notepad++ - без плагинов и какой-никакой подсветки кода. Только за год-два до того как переключиться на Solidity, я писал проекты в VS Code.
Для меня знание кода и процесса его исполнения всегда было превыше плагинов-помощников. Зачем мне доп программы, когда можно просто посмотреть документацию или погуглить ответ на stackoverflow...
В этот раз будет по другому. Интересно будет посмотреть, сколько времени уйдет на фронтенд, бекэнд и много ли кода я буду исправлять.
В конечном итоге, если все получится, как задумываю, то базовые идеи/проекты можно будет выпускать буквально каждую неделю.
Будем практиковаться!
Также мне будет интересно узнать о вашем опыте работы с нейронками: лайфхаки, уроки, полезные ресурсы и т.д.
Всем приятного дня!
Продолжаю делиться процессом создания проекта, о котором говорил в предыдущих постах - Пост 1 и Пост 2.
В последнее время я все чаще натыкался на посты/статьи/вопросы по нейросетям и редакторам кода на их основе. Очень долгое время я сопротивлялся этой технологии и специально игнорировал ее наличие...
И вот только две недели назад я установил свою первую нейросеть - DeepSeek. Во-первых, она была доступна для пользователей из РФ без ВПН, а во-вторых, не требовалась регистрация с телефоном.
Я поигрался в ней около недели и не совсем тогда понял, в чем прикол. Ну, в целом, я умею хорошо гуглить и искать нужную мне информацию и не понимал, что может дать мне простой чат.
На прошлой неделе я решил зайти еще чуть дальше и экспериментировал с остальными нейронками: ChatGPT, Claude, Grok 3, Gemini и даже скачивал редакторы кода: Cursor и Windsurf. Также смотрел много видео по этой теме: как писать промты, какие лимиты есть, для каких целей какие сети предназначены и т.д.
В итоге, после более-менее правильной работе с ними и адекватными запросами, я был впечатлен результатами. В особенности, их возможности объяснить код на разных языках.
И после этого, первым вопросом в моей голове было:
"Как лучше поступить с учениками на курсе: взять обещание не использовать нейронки хотя бы на первых модулях или наоборот: подсказать, как лучше работать с ними?"
Но это еще в процессе осознания...
А пока мне интересно было бы еще научиться самому работать с сетями и попробовать написать задуманный проект с ними.
Что бы вы понимали, в плане редакторов и кода я немного "динозавр" что ли... За все время, что я писал код (js, php) в своей карьере, я использовал Notepad++ - без плагинов и какой-никакой подсветки кода. Только за год-два до того как переключиться на Solidity, я писал проекты в VS Code.
Для меня знание кода и процесса его исполнения всегда было превыше плагинов-помощников. Зачем мне доп программы, когда можно просто посмотреть документацию или погуглить ответ на stackoverflow...
В этот раз будет по другому. Интересно будет посмотреть, сколько времени уйдет на фронтенд, бекэнд и много ли кода я буду исправлять.
В конечном итоге, если все получится, как задумываю, то базовые идеи/проекты можно будет выпускать буквально каждую неделю.
Будем практиковаться!
Также мне будет интересно узнать о вашем опыте работы с нейронками: лайфхаки, уроки, полезные ресурсы и т.д.
Всем приятного дня!
🔥7❤4
Пара слов о Passkeys
Видео выше никак не связано с темой passkeys, просто меня однажды впечатлил баг с модификатором, и сегодня решил рассказать вам о потенциальной проблеме в смарт контрактах.
Сейчас часто встречаю статьи про технологию регистрации и логина на сайтах web2, которую назвали passkeys. Примечательно то, что она также использует систему приватных/публичных ключей, как и кошельки web3. А теперь, чуть подробнее.
Passkeys — это метод аутентификации пользователей, основанный на криптографии с открытым ключом. Вместо пароля используются:
1. Публичный ключ: хранится на сервере сервиса и не является конфиденциальным.
2. Приватный ключ: хранится на устройстве пользователя и защищается биометрической аутентификацией (например, отпечаток пальца или распознавание лица).
При входе в систему устройство пользователя подписывает запрос приватным ключом, а сервер проверяет подпись с помощью публичного ключа.
С одной стороны passkeys устраняет риски, связанные с утечкой, угадыванием или повторным использованием паролей, а также исключает случаи, когда пользователи просто забывают свои пароли и приходится проходить процесс их восстановления. А с другой - если девайс, на котором хранятся passkeys будет утерян, то восстановить доступ к услугам или сервисам станет сложной задачей.
Тут надо уточнить, что приватный ключ хранится в защищенных аппаратных компонентах, таких как Secure Enclave (Apple) или Trusted Platform Module (Windows), и может быть защищен биометрией. Именно поэтому потеря девайса - станет проблемой.
Формирование публичного и приватного ключей в системе passkeys базируется на принципах асимметричной криптографии, также известной как криптография с открытым ключом. Этот процесс выполняется автоматически на устройстве пользователя в момент регистрации passkey.
Как вообще происходит создание ключа и регистрация на сайте:
1. Когда пользователь регистрирует passkey на сайте или в приложении, сервис отправляет запрос на создание новой пары ключей через протокол WebAuthn (Web Authentication API).
2. Устройство пользователя генерирует пару ключей: приватный ключ и публичный ключ, который создается одновременно с первым и может быть передан серверу сервиса.
3. Публичный ключ отправляется на сервер сервиса, где он сохраняется для дальнейшей аутентификации. Он не является конфиденциальным и не может быть использован для доступа к аккаунту без соответствующего приватного ключа.
5. Сервер связывает публичный ключ с учетной записью пользователя.
6. Теперь, когда пользователь пытается войти в систему, сервер отправляет запрос на аутентификацию через WebAuthn.
7. Устройство пользователя использует приватный ключ для подписания запроса. Этот процесс требует подтверждения пользователя (например, с помощью биометрии или PIN-кода).
8. Сервер проверяет подпись с помощью публичного ключа, сохраненного при регистрации. Если подпись верна, доступ предоставляется.
В целом, довольно интересная технология. Будет забавно, если через год-два выйдут приложения, как web3 кошельки, которые будут предназначены только для авторизации на различных сайтах через passkeys.
#passkeys
Видео выше никак не связано с темой passkeys, просто меня однажды впечатлил баг с модификатором, и сегодня решил рассказать вам о потенциальной проблеме в смарт контрактах.
Сейчас часто встречаю статьи про технологию регистрации и логина на сайтах web2, которую назвали passkeys. Примечательно то, что она также использует систему приватных/публичных ключей, как и кошельки web3. А теперь, чуть подробнее.
Passkeys — это метод аутентификации пользователей, основанный на криптографии с открытым ключом. Вместо пароля используются:
1. Публичный ключ: хранится на сервере сервиса и не является конфиденциальным.
2. Приватный ключ: хранится на устройстве пользователя и защищается биометрической аутентификацией (например, отпечаток пальца или распознавание лица).
При входе в систему устройство пользователя подписывает запрос приватным ключом, а сервер проверяет подпись с помощью публичного ключа.
С одной стороны passkeys устраняет риски, связанные с утечкой, угадыванием или повторным использованием паролей, а также исключает случаи, когда пользователи просто забывают свои пароли и приходится проходить процесс их восстановления. А с другой - если девайс, на котором хранятся passkeys будет утерян, то восстановить доступ к услугам или сервисам станет сложной задачей.
Тут надо уточнить, что приватный ключ хранится в защищенных аппаратных компонентах, таких как Secure Enclave (Apple) или Trusted Platform Module (Windows), и может быть защищен биометрией. Именно поэтому потеря девайса - станет проблемой.
Формирование публичного и приватного ключей в системе passkeys базируется на принципах асимметричной криптографии, также известной как криптография с открытым ключом. Этот процесс выполняется автоматически на устройстве пользователя в момент регистрации passkey.
Как вообще происходит создание ключа и регистрация на сайте:
1. Когда пользователь регистрирует passkey на сайте или в приложении, сервис отправляет запрос на создание новой пары ключей через протокол WebAuthn (Web Authentication API).
2. Устройство пользователя генерирует пару ключей: приватный ключ и публичный ключ, который создается одновременно с первым и может быть передан серверу сервиса.
3. Публичный ключ отправляется на сервер сервиса, где он сохраняется для дальнейшей аутентификации. Он не является конфиденциальным и не может быть использован для доступа к аккаунту без соответствующего приватного ключа.
5. Сервер связывает публичный ключ с учетной записью пользователя.
6. Теперь, когда пользователь пытается войти в систему, сервер отправляет запрос на аутентификацию через WebAuthn.
7. Устройство пользователя использует приватный ключ для подписания запроса. Этот процесс требует подтверждения пользователя (например, с помощью биометрии или PIN-кода).
8. Сервер проверяет подпись с помощью публичного ключа, сохраненного при регистрации. Если подпись верна, доступ предоставляется.
В целом, довольно интересная технология. Будет забавно, если через год-два выйдут приложения, как web3 кошельки, которые будут предназначены только для авторизации на различных сайтах через passkeys.
#passkeys
🔥5❤1👍1🤔1
Перспективы для новичков в web3
Как вы знаете, последние две недели я активно интересуюсь темой нейронных сетей, агентами и всем тем, как это может быть связано с web3. Изучение зарубежных форумов и статей, также наталкивает меня на некоторые мысли по поводу перспектив для начинающих свой путь в блокчейне и смарт контрактах.
Прежде всего, работу новичкам станет найти легче.
Благодаря нейросейтям уже сейчас огромное количество web2 проектов пишутся в короткие сроки и с довольно хорошим кодом. Даже глава крупнейшего акселератора для стартапов YCombinator как-то в интервью говорил, что более 90% всех проектов у них в компании написаны с помощью нейронок.
Написать хороший web3 протокол с помощью промтов в ChatGPT можно будет уже в этом году. Из-за чего индустрия получит еще большее привлечение внимания: игры, биржи, обменники, стейкинги и т.д.
Но написать смарт контракт - одно дело, другое - поддерживать его работу. Всех сеньоров и мидлов разберут более устоявшиеся компании, а новички, с уверенным знанием языка, станут более востребованы.
При этом база знаний уровня "новичок" вырастет. Нужно будет знать и язык, и тестирование, и базовые аспекты безопасности, и нюансы блокчейн сетей и т.д. Это будет не только Solidity, но и сопутствующие программы, типа Foundry.
Плохая новость в том, что уровень безопасности в таких протоколах будет чуть выше нуля.
Да, нейронка может написать смарт контракт. Да, Slither может найти базовые проблемы. Но никто из них пока не научился находить сложные логические уязвимости.
Поэтому аудиторы также получат распространение. При этом аудиторы будут требоваться с уже подтвержденными находками на популярных конкурсных платформах.
В целом, я хочу сказать, что сфера web3 все также развивается, независимо от роста/падения биткойна и других криптовалют.
Начать свой путь в 2025 году все еще хорошая идея: обучающей информации больше, комьюнити шире, а сама крипта все больше входит в жизнь простых людей.
Такой вот понедельничный пост! Всем хорошей недели и приятного обучения!
#offtop
Как вы знаете, последние две недели я активно интересуюсь темой нейронных сетей, агентами и всем тем, как это может быть связано с web3. Изучение зарубежных форумов и статей, также наталкивает меня на некоторые мысли по поводу перспектив для начинающих свой путь в блокчейне и смарт контрактах.
Прежде всего, работу новичкам станет найти легче.
Благодаря нейросейтям уже сейчас огромное количество web2 проектов пишутся в короткие сроки и с довольно хорошим кодом. Даже глава крупнейшего акселератора для стартапов YCombinator как-то в интервью говорил, что более 90% всех проектов у них в компании написаны с помощью нейронок.
Написать хороший web3 протокол с помощью промтов в ChatGPT можно будет уже в этом году. Из-за чего индустрия получит еще большее привлечение внимания: игры, биржи, обменники, стейкинги и т.д.
Но написать смарт контракт - одно дело, другое - поддерживать его работу. Всех сеньоров и мидлов разберут более устоявшиеся компании, а новички, с уверенным знанием языка, станут более востребованы.
При этом база знаний уровня "новичок" вырастет. Нужно будет знать и язык, и тестирование, и базовые аспекты безопасности, и нюансы блокчейн сетей и т.д. Это будет не только Solidity, но и сопутствующие программы, типа Foundry.
Плохая новость в том, что уровень безопасности в таких протоколах будет чуть выше нуля.
Да, нейронка может написать смарт контракт. Да, Slither может найти базовые проблемы. Но никто из них пока не научился находить сложные логические уязвимости.
Поэтому аудиторы также получат распространение. При этом аудиторы будут требоваться с уже подтвержденными находками на популярных конкурсных платформах.
В целом, я хочу сказать, что сфера web3 все также развивается, независимо от роста/падения биткойна и других криптовалют.
Начать свой путь в 2025 году все еще хорошая идея: обучающей информации больше, комьюнити шире, а сама крипта все больше входит в жизнь простых людей.
Такой вот понедельничный пост! Всем хорошей недели и приятного обучения!
#offtop
❤18👍5🔥3🙏3🤔1
Все, что нужно знать об интеграции Chainlink. Часть 1
В комментариях спросили про деплой смарт контрактов мультисиг кошельком. Хорошая тема, которую мы не разбирали на канале. Я хочу собрать интересный материал на эту тему и в ближайшее время сделать несколько постов. А пока, давайте поговорим про интеграцию с Chainlink.
Очень часто в конкурсных аудитах проскальзывают репорты с какой-либо уязвимостью при использовании Chainlink сервисов, поэтому хотел бы рассказать о некоторых моментах, на которые стоит обращать внимание.
В документации Chainlink есть руководство по интеграции, включающее образец контракта. К сожалению, он недостаточен для большинства случаев использования.
Мы рассмотрим три основных нюанса безопасности, которые необходимо учитывать каждый раз, когда вы интегрируете Chainlink в свой проект.
Вот официальный образец контракта (отредактированный для краткости):
Он вызывает функцию latestRoundData() на dataFeed и возвращает ответ int256. Внимательные читатели заметят, что ответ технически может быть отрицательным.
Отрицательные цены активов не так часто встречаются, при этом они не невозможны: на фьючерсных рынках иногда наблюдается падение котировок ниже 0 при шоке спроса и предложения.
Работа с отрицательными и нулевыми ответами
Поскольку большинство приложений DeFi предполагают неотрицательную цену, мы должны привести ответ к значению uint256 и вернуть его. Как реагировать на ответ <= 0, зависит от ситуации.
Подсказка: Могут ли пользователи взаимодействовать с бесплатным активом (токеном), не испортив расчеты вашего протокола? Если да, то возвращайте 0 вместо отрицательных значений. Если нет, то лучше вернуться и дождаться корректного ответа от dataFeed.
Добавьте проверку на устаревшие данные
У Chainlink Feeds есть два параметра триггера, которые определяют, когда ответ должен быть обновлен. Они называются порог отклонения и сердцебиение - deviation threshold и heartbeat.
В приведенном выше на скрине примере, цены будут обновляться либо:
1. когда цена вне цепи изменяется более чем на ±0,5% по сравнению с последней опубликованной ценой, либо
2. если с момента последнего обновления прошло 24 часа.
Несмотря на эти правила, интеграторы не должны полагать, что сообщаемая цена находится в пределах 0,5% от цены off-chain или что она не более чем на 24 часа устарела.
Это связано с тем, что для записи обновления в этот feed требуется, чтобы на него ответили как минимум 11 из 16 поставщиков данных. Если кворум не соблюдается, максимальная застойность и отклонение последнего ответа feed теоретически неограниченны.
В комментариях спросили про деплой смарт контрактов мультисиг кошельком. Хорошая тема, которую мы не разбирали на канале. Я хочу собрать интересный материал на эту тему и в ближайшее время сделать несколько постов. А пока, давайте поговорим про интеграцию с Chainlink.
Очень часто в конкурсных аудитах проскальзывают репорты с какой-либо уязвимостью при использовании Chainlink сервисов, поэтому хотел бы рассказать о некоторых моментах, на которые стоит обращать внимание.
В документации Chainlink есть руководство по интеграции, включающее образец контракта. К сожалению, он недостаточен для большинства случаев использования.
Мы рассмотрим три основных нюанса безопасности, которые необходимо учитывать каждый раз, когда вы интегрируете Chainlink в свой проект.
Вот официальный образец контракта (отредактированный для краткости):
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract DegenDeFi {
AggregatorV3Interface internal constant dataFeed =
AggregatorV3Interface(
0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
);
function getLatestData() public view returns (int256) {
(
/* uint80 roundId */,
int256 answer,
/* uint256 startedAt */,
/* uint256 updatedAt */,
/* uint80 answeredInRound */
) = dataFeed.latestRoundData();
return answer;
}
}
Он вызывает функцию latestRoundData() на dataFeed и возвращает ответ int256. Внимательные читатели заметят, что ответ технически может быть отрицательным.
Отрицательные цены активов не так часто встречаются, при этом они не невозможны: на фьючерсных рынках иногда наблюдается падение котировок ниже 0 при шоке спроса и предложения.
Работа с отрицательными и нулевыми ответами
Поскольку большинство приложений DeFi предполагают неотрицательную цену, мы должны привести ответ к значению uint256 и вернуть его. Как реагировать на ответ <= 0, зависит от ситуации.
Подсказка: Могут ли пользователи взаимодействовать с бесплатным активом (токеном), не испортив расчеты вашего протокола? Если да, то возвращайте 0 вместо отрицательных значений. Если нет, то лучше вернуться и дождаться корректного ответа от dataFeed.
function getLatestData() public view returns (uint256) {
(
/* uint80 roundId */,
int256 answer,
/* uint256 startedAt */,
/* uint256 updatedAt */,
/* uint80 answeredInRound */
) = dataFeed.latestRoundData();
// ✨ added sanity check
if (answer <= 0) {
// Option 1 (Recommended): Assume something went wrong
revert InvalidAnswer(answer);
// Option 2: Treat it as a 0
// return 0;
}
return uint256(answer);
}
Добавьте проверку на устаревшие данные
У Chainlink Feeds есть два параметра триггера, которые определяют, когда ответ должен быть обновлен. Они называются порог отклонения и сердцебиение - deviation threshold и heartbeat.
В приведенном выше на скрине примере, цены будут обновляться либо:
1. когда цена вне цепи изменяется более чем на ±0,5% по сравнению с последней опубликованной ценой, либо
2. если с момента последнего обновления прошло 24 часа.
Несмотря на эти правила, интеграторы не должны полагать, что сообщаемая цена находится в пределах 0,5% от цены off-chain или что она не более чем на 24 часа устарела.
Это связано с тем, что для записи обновления в этот feed требуется, чтобы на него ответили как минимум 11 из 16 поставщиков данных. Если кворум не соблюдается, максимальная застойность и отклонение последнего ответа feed теоретически неограниченны.
👍2
Хотя мы не можем легко проверить отклонение, поскольку это потребовало бы наличия другого ценового оракула, мы можем, по крайней мере, контролировать застой. latestRoundData() удобно возвращает uint256 updatedAt, временную метку последнего обновления фида.
Теперь функция отклоняет ответ feed, если она была обновлена более 24 часов назад.
В пятницу мы продолжим разбирать эту тему.
#chainlink
function getLatestData() public view returns (uint256) {
(
/* uint80 roundId */,
int256 answer,
/* uint256 startedAt */,
uint256 updatedAt,
/* uint80 answeredInRound */
) = dataFeed.latestRoundData();
if (answer <= 0) {
revert InvalidAnswer(answer);
}
// ✨ added staleness check
uint256 staleness = block.timestamp - updatedAt;
if (staleness >= MAX_STALENESS) {
revert StaleAnswer(staleness);
}
return uint256(answer);
}Теперь функция отклоняет ответ feed, если она была обновлена более 24 часов назад.
В пятницу мы продолжим разбирать эту тему.
#chainlink
👍3
Все, что нужно знать об интеграции Chainlink. Часть 2
Продолжаем разбирать основные принцип работы с Chainlink.
Не думайте, что значение latestRoundData всегда будет получено
Большинство оракулов Chainlink могут быть с контролем доступа, например код агрегатора stETH / ETH. Вызовы view функций будут ревертиться, если вызывающий попал в черный список.
Есть вероятность, что в будущем доступ к оракулам Chainlink будет ограничен для платных клиентов (в настоящее время Chainlink субсидируется и не имеет модели монетизации для своих наиболее используемых фидов).
Если вы создаете неизменяемый протокол с резервным оракулом, имеет смысл окружить вызов latestRoundData() оператором try-catch, чтобы иметь возможность "варианта 2" на такой случай.
Проверяйте качество Feed
Chainlink подразделяет свои фиды на 6 категорий в зависимости от их назначения и стабильности. В идеальном случае вы должны включать в свой протокол только проверенные фиды, поскольку они имеют самую высокую гарантию долгосрочной надежности.
Новые пары ценовых фидов будут иметь статус Provisional в течение первых 90 дней после их выпуска, в течение которых их параметры могут измениться. Monitored Feeds - это фиды, «находящиеся на рассмотрении команды Chainlink Labs для поддержки стабильности широкой экосистемы», что означает, что они недавно стали нестабильными или менее ликвидными, чем хотелось бы.
Будьте особенно бдительны при интеграции пользовательских и специализированных фидов, поскольку они могут иметь различную семантику ответов, предположения о доверии и гарантии актуальности.
Категория Deprecating - это худшая категория, если вы создаете неизменяемый протокол, хотя ни один Chainlink Feed еще не был выведен из употребления.
Делайте форк осторожно
Если вы форкаете код, написанный в 2021 году или ранее, дважды проверьте, что в нем нет вызовов latestAnswer(). Этот метод уже устарел, и вам следует заменить вызовы latestAnswer() на latestRoundData().
Модель доверия
Всегда полезно проверить исходный код и состояние развернутых контрактов, связанных с фидом. Обычно это выглядит примерно так: EACAggregatorProxy (контракт, который вы вызываете через AggregatorV3Interface), принадлежащий мультисигу. Мультисиг может передавать право собственности и менять агрегатор. Агрегатор содержит такие интересные параметры, как:
1. transmitters - адреса, на которые разрешено отправлять ответы,
2. minAnswer и maxAnswer, определяющие, что считается правильным ответом,
3. decimals числа ответа.
Вот несколько выводов, которые я сделал во время написания этой статьи:
1. Фид цены Ethereum stETH / ETH считает допустимым ответ в диапазоне от 0,001ETH до 100ETH.
2. Мультисиг, используемый в фидах Optimism, имеет 20 подписантов, но порог выполнения составляет всего 3! У половины подписантов нет ETH и они никогда не совершали транзакций на Optimism. Такая же сомнительная система существует на нескольких альтернативных блокчейнах.
3. Цена LINK менее 0,1 доллара США считается недействительной благодаря фиду LINK / USD.
Убедитесь, что вы понимаете и принимаете предположения о доверии к фидам, прежде чем интегрировать их в свое приложение.
В понедельник разберем еще пару последних пунктов на эту тему.
#chainlink
Продолжаем разбирать основные принцип работы с Chainlink.
Не думайте, что значение latestRoundData всегда будет получено
Большинство оракулов Chainlink могут быть с контролем доступа, например код агрегатора stETH / ETH. Вызовы view функций будут ревертиться, если вызывающий попал в черный список.
Есть вероятность, что в будущем доступ к оракулам Chainlink будет ограничен для платных клиентов (в настоящее время Chainlink субсидируется и не имеет модели монетизации для своих наиболее используемых фидов).
Если вы создаете неизменяемый протокол с резервным оракулом, имеет смысл окружить вызов latestRoundData() оператором try-catch, чтобы иметь возможность "варианта 2" на такой случай.
function getLatestData() public view returns (uint256) {
try dataFeed.latestRoundData() returns (
/* uint80 roundId */,
int256 answer,
/* uint256 startedAt */,
uint256 updatedAt,
/* uint80 answeredInRound */
) {
// validate and return
} catch {
// use fallback oracle
}
}
Проверяйте качество Feed
Chainlink подразделяет свои фиды на 6 категорий в зависимости от их назначения и стабильности. В идеальном случае вы должны включать в свой протокол только проверенные фиды, поскольку они имеют самую высокую гарантию долгосрочной надежности.
Новые пары ценовых фидов будут иметь статус Provisional в течение первых 90 дней после их выпуска, в течение которых их параметры могут измениться. Monitored Feeds - это фиды, «находящиеся на рассмотрении команды Chainlink Labs для поддержки стабильности широкой экосистемы», что означает, что они недавно стали нестабильными или менее ликвидными, чем хотелось бы.
Будьте особенно бдительны при интеграции пользовательских и специализированных фидов, поскольку они могут иметь различную семантику ответов, предположения о доверии и гарантии актуальности.
Категория Deprecating - это худшая категория, если вы создаете неизменяемый протокол, хотя ни один Chainlink Feed еще не был выведен из употребления.
Делайте форк осторожно
Если вы форкаете код, написанный в 2021 году или ранее, дважды проверьте, что в нем нет вызовов latestAnswer(). Этот метод уже устарел, и вам следует заменить вызовы latestAnswer() на latestRoundData().
Модель доверия
Всегда полезно проверить исходный код и состояние развернутых контрактов, связанных с фидом. Обычно это выглядит примерно так: EACAggregatorProxy (контракт, который вы вызываете через AggregatorV3Interface), принадлежащий мультисигу. Мультисиг может передавать право собственности и менять агрегатор. Агрегатор содержит такие интересные параметры, как:
1. transmitters - адреса, на которые разрешено отправлять ответы,
2. minAnswer и maxAnswer, определяющие, что считается правильным ответом,
3. decimals числа ответа.
Вот несколько выводов, которые я сделал во время написания этой статьи:
1. Фид цены Ethereum stETH / ETH считает допустимым ответ в диапазоне от 0,001ETH до 100ETH.
2. Мультисиг, используемый в фидах Optimism, имеет 20 подписантов, но порог выполнения составляет всего 3! У половины подписантов нет ETH и они никогда не совершали транзакций на Optimism. Такая же сомнительная система существует на нескольких альтернативных блокчейнах.
3. Цена LINK менее 0,1 доллара США считается недействительной благодаря фиду LINK / USD.
Убедитесь, что вы понимаете и принимаете предположения о доверии к фидам, прежде чем интегрировать их в свое приложение.
В понедельник разберем еще пару последних пунктов на эту тему.
#chainlink
👍4