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

Пока занимался презентацией на грядущий стрим, дошел до раздела с рекомендациями, как можно использовать процесс аудита вашего dApp в маркетинге и рекламе. Полез в интернет за новыми и идеями, и немного обломался...

Несколько лет назад я сильно увлекался темой стартапов по всему миру: отслеживал инвестиции, разработки, приложения и сервисы, часами сидел на Product Hunt, читал литературу и т.д. И неизменно на пути каждого проекта вставал вопрос его продвижения и рекламы. Кому нужен ваш сногсшибательный проект, когда о нем никто не знает?..

99% всех советов и статей сводилось к паре идеи: ведите сети, прокачайте SEO, закупите рекламу в гугле или других соцсетях. При этом, в тех же 99% случаев это не будет работать.

Представьте себе, мы создали проект, завели для него сайт и соцсети, и хотим рекламироваться. Что у нас получится?

SEO настройка будет работать по релевантным запросам - т.е. если у нас на сайте будет информация по ключевым словам, которые будут искать пользователи. Но вместе с этим мы будем бороться с другими конкурентными сайтами в этом поле. Короче говоря, SEO начнет работать минимум через полгода-год, если у нас все будет настроено супер-правильно. А на каких страницах выдачи? Тут еще тоже очень спорный вопрос...

SEO делать надо, на полагаться на него, как на основной источник пользователей вообще не стоит.

Реклама в поисковых системах, типа Гугла, и в соцсетях работает. Но для регулярной отдачи нужно просчитывать множество параметров: ключевые и игнор слова, конверсии, трафик и т.д. При этом вы тратите уже свои деньги.

С ведением соцсетей вообще ахтунг! Мало того, что делать это надо регулярно, так еще нужно делать это правильно и, что самое главное, интересно и понятно. Да и форматы в них сильно отличаются по характеру и техническим параметрам: в Телеграме - какие-нибудь новостные и экспертные посты, в Инстаграме - сторител и лайфстаил, в Твиттере - короткие текстовые с основной идеей, на Реддит - приближенные к обычным людям... И невозможно один текст переложить одинаково хорошо на разные платформы, сохранив качество.

И получается, что чаще всего мы получаем "голые" соц страницы, слитый бюджет на рекламу и долгие результаты в SEO. И ни дай Бог вы пойдете спамить о своем проекте в чаты других груп или сообществ, это вообще поставит крест на любом продвижении.

И абсолютно также ситуация сейчас в web3.

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

Мне интересно узнать, какие способы продвижения своего протокола вы пробовали? Что получалось и что не особо?

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

Всем хорошей недели!

#marketing
👍4🤔31
Стрим на тему "Подготовка протокола к аудиту"

Официальное объявление о первом видео стриме на нашем канале. В этот четверг в 19:00 по московскому времени в Зуме будет небольшая, примерно на полчаса-час, встреча, где я расскажу вам о том, как правильно подготовить свой протокол к аудиту: соло, в компании, на конкурсной площадке и т.д.

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

Не могу сказать с уверенностью, что запись стрима будет, так как это мой самый первый стрим и многое может пойти не так, как планируется. Я вообще пишу гораздо лучше, чем говорю (по сути, потому я и веду канал в Телеграме, а не видео на Ютуб).

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

Итак:

Тема: "Подготовка протокола к аудиту"
Продолжительность: 30-60 минут
Дата: четверг, 12.09.2024
Время: 19:00 мск
Где: zoom

Приглашаю всех!

#video
🔥6👍31
Media is too big
VIEW IN TELEGRAM
Запись стрима "Подготовка протокола (dApp) к аудиту"

Прежде всего, спасибо всем, кто пришел меня поддержать вчера на стриме! Как я уже говорил, это был мой самый первый стрим лекция, я очень волновался и, как мне показалось, немного "тараторил". Однако, думаю, все получилось и вот выкладываю саму запись. Я также позже 0добавлю аудиозапись для тех, кто привык слушать лекции в формате подкастов (это одна из классных фишек Zoom, когда он выгружает и видео, и аудио после конференции).

Таймкоды:

01.50 - введение
05.50 - читаемость кода
08.00 - комментарии
14.20 - документация к dApp
24.45 - самостоятельный аудит
42.30 - scope / out-of-scope / setup
53.38 - где искать аудиторов
57.06 - маркетинг dApp во время аудита

Ссылка на презентацию (Goggle Docs)

Стрим и презентация была создана специально для нашего канала - Solidity. Смарт контракты и аудит


Ссылки и ресурсы, которые упоминались в презентации:

1. Стилистика кода - Coinbase Solidity Style Guide

2. Стилистика кода - Inline Yul Style Guide

3. Программа для создания схем и диаграмм - tldraw

4. Программа для создания схем и диаграмм - Whimsical

5. Программа для создания схем и диаграмм - Draw.io

6. Практика с инвариантами - Categorizing_Properties

7. Практика с инвариантами - Properties

8. Практика с инвариантами - Thinking About Properties


Чеклисты:


1. Solodit checklist

2. The Ultimate 100+ Point Checklist

3. The ultimate security checklist

4. Development Guidelines


Примеры протоколов с хорошей документацией:

1. Basin protocol code

2. Panoptic code

3. Lens Protocol V2

4. Tangible Caviar

5. Panoptic

6. UniStaker Infrastructure

7. Ethena Labs

8. Ethereum Credit Guild

9. Ondo Finance

10. PoolTogether


Где искать аудиторов:

1. Code4rena leaderboard

2. CodeHawks leaderboard

3. Sherlock leaderboard

4. Immunefi leaderboard

5. Hat finance leaderboard

Всем приятного просмотра и безопасных протоколов!

#video
3🔥214
Solidity hints. Часть 24

Новая неделя, а значит новые посты про Solidity и разработку!

Спасибо всем за добрые отзывы по стриму! В целом, ничего страшного не произошло, поэтому, думаю, через недельку можно будет провести что-то новое, например, взять тему по безопасности смарт контрактов и типичных уязвимостях со стандартом EIP4626.

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

А пока что, пара пунктов из репо:

39. Public state variables can override external functions if the parameter and return types of the function matches the getter function of the variable. They themselves cannot be overriden

что в переводе:

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


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

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;

contract A
{
function f() external view virtual returns(uint) { return 5; }
}

contract B is A
{
uint public override f;
}


У нас есть два контракта. В первом - реализуется функция, которая возвращает параметр с определенным значением. Во втором - переменная состояния с таким же именем и типом данных.

Получается, что при вызове f во втором контракте, мы будем обращаться не к функции, а к переменной. Получается, что переменная, как бы переписывает значения функции.

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

А мы идем далее и следующий пункт:

40. Before the constructor code is executed, state variables are initialized to their specified value if you initialize them inline, or their default value if you do not.

что в переводе:

Перед выполнением кода конструктора переменные состояния инициализируются в указанное значение, если вы инициализируете их inline, или в значение по умолчанию, если вы этого не делаете.

Тут все просто и изучается на самых первых порах знакомства с Solidity.

Когда мы создаем переменные состояния в контракте, то у них уже по умолчанию есть некоторые значения. Например, у uint это 0, у bool - false.

И в пункте говорится, что до выполнения кода в конструкторе, все переменные состояния получают либо установленное разработчиком значение, либо свое дефолтное. А уже после исполнения конструктора, они записываются в код самого контракта.

#variables #state
👍32
Solidity hints. Часть 25

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

И в этом нам поможет следующий пункт:

41. The order in which the base classes are given in the is directive is important: You have to list the direct base contracts in the order from “most base-like” to “most derived”

что в переводе:

Порядок указания базовых классов в директиве is очень важен: вы должны перечислить прямые базовые контракты в порядке от «наиболее похожих на базовые» до «наиболее производных».

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

Языки, допускающие множественное наследование, сталкиваются с несколькими проблемами. Одна из них - Diamond Problem. Solidity похож на Python тем, что использует «C3-линеаризацию» для принудительного установления определенного порядка в направленном ациклическом графе (DAG) базовых классов (чтобы это не значило). Это приводит к желаемому свойству монотонности, но не позволяет использовать некоторые графы наследования.

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

В следующем коде Solidity выдаст ошибку «Linearization of inheritance graph impossible».


pragma solidity >=0.4.0 <0.9.0;

contract X {}
contract A is X {}

// This will not compile
contract C is A, X {}


Причина в том, что C просит X отменить A (указывая A, X в таком порядке), но A сама просит отменить X, что является противоречием, которое невозможно разрешить.

Из-за того, что вам придется явно переопределять функцию, которая наследуется от нескольких баз без уникального переопределения, линеаризация C3 не слишком важна на практике.

Одна из областей, где линеаризация наследования особенно важна и, возможно, не так очевидна, - это когда в иерархии наследования есть несколько конструкторов. Конструкторы всегда будут выполняться в линеаризованном порядке, независимо от того, в каком порядке их аргументы предоставляются в конструкторе наследуемого контракта. Например:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Base1 {
constructor() {}
}

contract Base2 {
constructor() {}
}

// Constructors are executed in the following order:
// 1 - Base1
// 2 - Base2
// 3 - Derived1
contract Derived1 is Base1, Base2 {
constructor() Base1() Base2() {}
}

// Constructors are executed in the following order:
// 1 - Base2
// 2 - Base1
// 3 - Derived2
contract Derived2 is Base2, Base1 {
constructor() Base2() Base1() {}
}

// Constructors are still executed in the following order:
// 1 - Base2
// 2 - Base1
// 3 - Derived3
contract Derived3 is Base2, Base1 {
constructor() Base1() Base2() {}
}


Теперь вы знаете чуть больше о линеаризация наследования... Или нет?

#inheritance
🔥4👍1
Продолжение курса: 3 модуль

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

Темы 3 модуля подходят для продолжающих свое обучение в Solidity: кто знает основные стандарты и умеет писать простые и среднесложные контракты.

Обучение займет весь октябрь.

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

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

Итак, темы модуля:

Неделя 1

1. Древо Меркла: общее
2. Подписи и стандарты
3. ecrecover и ECDSA
4. Безопасность подписей

Неделя 2

5. Прокси. Общее
6. Transparent и UUPS proxy
7. Beacon proxy, Diamond
8. Безопасность proxy

Неделя 3

9. Работа с памятью: code
10. Работа с памятью: storage
11. Работа с памятью: memory
12. Работа с памятью: calldata
13. Работа с памятью: stack

Неделя 4

14. Опкоды
15. Yul и assembly
16. Побитовые операции
17. Дебаггинг контрактов

Стоимость: 5000 рублей / 60 USDT
Ориентировочный старт: 30 сентября

Стоимость такая же, как и в начале этого года! В следующий раз будет дороже!

Продажи стартуют на следующей неделе!

Материалы с курса остаются с вами навсегда. Задания можно будет сдавать до Нового Года.

#курс
🔥10👍1
Кратко про третий, он же четвертый, модуль

В комментариях и в личных сообщениях спрашивали про 3 и другие модули курса: ведь зимой прошел 4 модуль, а сейчас последний - третий. Отвечаю на все вопросы сразу.

На первом потоке курса, который закончился этой зимой, было 4 модуля. На втором - текущем - потоке их 3, так как Летний модуль объединял в себя сразу второй и третий. И сейчас будет проходить последний модуль. Дальше уже возможный перезапуск в следующем году.

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

Получается, что темы новых модулей не будут востребованы. Да, и название курса звучит как: "Начинающий разработчик смарт контрактов на языке Solidity".

И вот с данным третьим модулем будет заканчиваться программа курса, так как эти темы обязательны для изучения и понимания специалиста web3, независимо от обозначенной выше профессии: аудитор, разработчик или тестировщик.

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

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

Текущий модуль займет весь октябрь. Работы можно будет сдавать до Нового года. Таким образом учиться можно будет в своем темпе.

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

#курс
6👌3👍1
Да кому вообще нужны прокси и assembly...

На фоне хайпа мемкоинов (типа pump fun) или различных тапалок, можно задать вполне резонный вопрос, а зачем нужны какие-то сложные темы в разработке, по типу прокси, assembly, подписей и некоторых других... Ведь для простого протокола знаний о том, как создавать токены ERC20 или NFT - ERC721 будет вполне достаточно...

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

Если уходить в разработку и целенаправленно искать работу в зарубежных компаниях - то лучше иметь полные знания Solidity, так как велика вероятность сложных вопросов на собеседованиях и последующей работе с уже написанным кодом. А там наверняка будут и "подписи" и "yul".

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

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

На группе вы сможете задавать вопросы сразу двум преподавателям и изучать материал в своем темпе. Не нужно будет "бегать" по чатам в телеграмме или форумам с вопросами: "а где почитать про это?" или "за что отвечает этот assembly?".

Материалы на курсе - это уроки в текстовом формате с домашними заданиями и дополнительными материалами. Лучший пример уроков можно найти на бесплатном курсе по Foundry, который я выкладывал в прошлом году - https://news.1rj.ru/str/solidityset/962

В общем, этот модуль подойдет для тех, кто хочет научиться полноценной разработке на Solidity, а не просто "писать тапалки" и мемкоинами.

Завтра открытие продаж! А старт курса на следующей неделе!

#курс
👍5
Обучение в группе или самому?

Знаете, почему мне всегда нравилось обучение в группе? Да, сообщество других учеников для общения - это, конечно, здорово, но больше всего мне нравилось ощущение того, что "это может закончиться"!

Сейчас уже третий год, как я сам непрерывно обучаюсь тем или иным штукам из web3 сферы: тестированию, поиску уязвимостей, defi математике и другому. И тут я понятия не имею, сколько у меня это займет и придет ли этому конец... Сложно искать информацию, улавливать основную суть, практиковаться и структурировать свои знания.

На курсах и обучениях все по другому.

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

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

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

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

Это и отличает групповое обучение от самостоятельного. А вы как думаете?

#курс
👍9👏1
Мы пройдем курс, а что дальше?

Резонный вопрос любого человека, перед покупкой какого-либо обучения.

Зачем мне этот курс? Что делать после? Получу ли новую работу? Что мне делать для дальнейшего продвижения? Помогут ли мне это знания для достижения моих целей?

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

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

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

Так что же делать после курса?

Как бы это не звучало, но - выбирать специализацию.

Этих трех модулей вполне достаточно, что "копнуть глубоко" в Solidity, научиться писать достойные смарт контракты, изучить базовую безопасность и создать свой первый протокол.

Далее вас по-любому заинтересует одно из направлений:

1. Погружаться в DeFi и пробовать создать свой финансовый протокол;
2. Заинтересоваться работой EVM и запустить свою ноду;
3. Уйти в тестирование и стать pro в этом;
4. Попробовать себя в конкурсных аудитах и заняться безопасностью;
5. Стать фуллстек разработчиком и писать тапалки или даже полноценные игры;
6. Или даже попробовать связать реальный мир с блокчейном;

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

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

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

В сообществе гораздо легче и развиваться и искать работу.

Программа курса

#курс
👍9🔥5
Merkle-Patricia Trees. Часть 1

Вот и закончилась неделя продаж курса и мы возвращаемся в свое привычное русло!

Когда я пересматривал уроки модуля, где есть темы Древа Меркла, то вспомнил, что уже давно хотел рассмотреть новую для себя тему: Merkle-Patricia Trees. Именно поэтому на канале мы немного "подушним" и разберем, что это такое, как работает и какие проблемы могут возникнуть! Итак, поехали:

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

Деревья Меркл-Патриция играют важную роль в различных решениях второго уровня, сайдчейнах и других вопросах масштабируемости. Например, решения второго уровня, такие как Rollups, Plasma chains и state channels, используют эти структуры для создания компактных доказательств доступности данных и переходов между состояниями. Аналогичным образом, побочные цепи, представляющие собой отдельные сети блокчейна, предназначенные для работы рядом с основной цепью, также используют деревья Меркл-Патриция для обеспечения согласованности данных и безопасного взаимодействия.

Но что такое деревья Меркл-Патриция и почему они так важны для этих систем? Для того, чтобы ответить на эти и другие вопросы, давайте разберем эту концепцию по частям, изучим их свойства, применение и значение для поддержания безопасности и целостности экосистем блокчейн.

Кратко вспомним, что такое Древо Меркла

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

Давайте разложим определение дерева Меркла на более простые части:

1. Что такое древо в вычислительной технике? Представьте себе семейное дерево, где «предки» находятся вверху, а «потомки» - внизу. Дерево в вычислительной технике похоже на это. Оно начинается с единственного «корневого» узла наверху, который разветвляется на «дочерние» узлы, а каждый из них может иметь свои «дочерние» узлы, и так далее. Узлы в самом низу, у которых нет дочерних узлов, называются «листьями».

2. Что такое криптографический хэш? Хэш - это способ получить любой объем входных данных (например, предложение, документ или целую книгу) и создать из него строку символов фиксированного размера, которая выглядит случайной. Его особенность заключается в том, что любое небольшое изменение входных данных полностью изменит хэш, и вы не сможете вернуться от хэша к исходным данным.
Криптографические хэш-функции - это особые типы хэш-функций, которые отличаются особой безопасностью, то есть их очень сложно перевернуть или найти коллизии (это когда два разных входа дают один и тот же хэш).

3. Как строится дерево Меркла? Вы начинаете с блоков данных в нижней части дерева в качестве «листьев». Каждый из этих блоков данных превращается в хэш. Затем каждая пара этих хэшей объединяется и снова хэшируется, чтобы получить хэш для узла, расположенного над ними. Этот процесс продолжается вверх по дереву, пока не получится один хэш на вершине, который и является «корнем» дерева.

4. Для чего используется дерево Меркла? Деревья Меркла используются там, где нужно быстро и безопасно проверить данные. Например, они используются в технологии блокчейн (которая лежит в основе таких криптовалют, как Bitcoin), чтобы гарантировать, что все транзакции действительны, без необходимости проверять каждую из них.

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

#merkle #patricia
3
Merkle-Patricia Trees. Часть 2

1. Основная терминология в дереве Меркла:

- Листовые узлы являются самыми нижними узлами в дереве (у них нет дочерних узлов) и представляют собой блоки данных.

- Родительские узлы помечены криптографическим хэшем их дочерних узлов.

- Корневой узел (верхний узел дерева) известен как корень Меркла.

2. Построение дерева Меркла:

Пусть у нас есть 4 блока данных - L1, L2, L3 и L4.

Шаг 1: Начнем с получения криптографических хэшей блоков данных.

HL1 = Hash(L1)

HL2 = Hash(L2)

HL3 = Hash(L3)

HL4 = Hash(L4)


Здесь 'Hash' может быть любой криптографической хэш-функцией, например SHA256.

Шаг 2: Хэши объединяются в пары и конкатенируются, после чего вычисляется хэш полученной строки.

HL12 = Hash(HL1 + HL2)

HL34 = Hash(HL3 + HL4)


Здесь '+' означает конкатенацию.

Шаг 3: Эти хэши снова конкатенируются и хэшируются для получения корня.

ROOT = Hash(HL12 + HL34)

Этот ROOT является корнем нашего дерева Меркла.

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

#merkle #patricia
1
Merkle-Patricia Trees. Часть 3

Что такое Trie?

Говоря простым языком, Trie - это особый тип дерева, используемый для хранения строк. То, что делает Trie интересным, так это то, как они организуют и хранят строки, позволяя быстро искать, вставлять и удалять их.

Как работает Trie?

Представьте, что у нас есть пустой Trie. Корень Trie не содержит никаких букв, но служит отправной точкой для хранения наших строк.

Начнем с первой строки «an».

1. Из корневого узла мы проверим, есть ли ветвь для первой буквы «a». В данном случае ее нет, поэтому мы создаем новый узел для «a».

2. Затем мы проверяем, есть ли ветвь для второй буквы «n», исходящая из узла «a». Поскольку ее нет, мы создаем еще один узел для «n».

Теперь наш Trie представляет слово «an».

Для того, чтобы добавить второе слово «ant», мы снова начинаем с корня:

1. Проверяем, есть ли ветвь для «a». На этот раз она уже существует, поэтому мы идем по ней.

2. Затем мы ищем ветвь для «n» от «a». Она также существует, поэтому мы идем по ней.

3. Наконец, мы ищем ответвление для «t» от «n». Ее не существует, поэтому мы добавляем новый узел для «t».

Теперь наша тройка содержит «an» и «ant».

1. Начиная с «dad», мы не находим ветви для «d» в корне, поэтому добавляем ее.

2. Мы не находим ветви для «a» от «d», поэтому добавляем ее.

3. Мы не находим ветви для «d» из «a», поэтому добавляем ее.

4. Для «do» у нас уже есть «d» в корне, поэтому мы следуем ему.

5. У нас нет ветви «o» от «d», поэтому мы добавляем ее.

Теперь наша тройка содержит «an», «ant», «dad» и «do».

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

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

Это базовое объяснение Trie. Продвинутые темы включают добавление маркера в конец каждого слова в Trie, чтобы различать, например, «an» и «ant» как отдельные слова.

#merkle #patricia
1
🔥 Популярный плагин для Solidity опасен?

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

https://x.com/LehmannLorenz/status/1841545179825942991

Пока еще отлеживаю информацию об этом, но, если вы вдруг используете его, то лучше отключить сейчас!

#vscode
😱6
Merkle-Patricia Trees. Часть 4

Что такое Patricia Trie?

Patricia Trie (также известная как Radix Tree или Compact Prefix Tree) - это тип Trie, в которую добавлены некоторые оптимизации для экономии места и потенциального повышения эффективности поиска. Название «Patricia» - это аббревиатура от «Практический алгоритм получения информации, закодированной в алфавитно-цифровом виде» (Practical Algorithm to Retrieve Information Coded in Alphanumeric).

Как работает Patricia Trie?

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

Давайте посмотрим, как Patricia Trie обрабатывает слова: romane, romanus, romulus, rubens, ruber, rubicon, rubicundus.

Мы начинаем с пустого корневого узла. Затем мы начинаем добавлять слова:

1. Вставка слова «romane»: Trie в данный момент пуста, поэтому мы создаем новый узел, ответвляющийся от корня, который содержит строку «romane».

2. Вставка «romanus»: Мы замечаем, что «romanus» имеет общий префикс, «roman», с «romane». Поэтому мы создаем узел, ответвляющийся от «roman», который содержит суффикс «us». Мы также обновим существующую ветвь «romane», чтобы она теперь начиналась от «roman» и содержала суффикс «e».

3. Вставка «romulus»: Это слово имеет общий префикс «rom» с существующими словами. Поэтому мы добавляем ветвь от «rom», содержащую «ulus».

4. Вставка «rubens»: Это слово не имеет общей приставки с существующими словами, поэтому оно ответвляется непосредственно от корня.

5. Вставка «ruber»: «ruber» имеет общий префикс rub с rubens, поэтому мы создаем узел, ответвляющийся от rub, который содержит er. Ветвь «rubens» теперь также начинается от «rub» и содержит суффикс «ens».

6. Вставка «rubicon»: «rubicon» имеет общий префикс rubi с ruber, поэтому мы создаем узел, ответвляющийся от rubi, который содержит con.

7. Вставка «rubicundus»: Это слово имеет общий префикс «rubi» с остальными. Мы ответвляем от «rubi» и добавляем узел с «cundus».

Теперь наша Patricia Trie содержит все семь слов, каждое из которых имеет свой уникальный путь от корня. Trie эффективна, компактна и, по сравнению с обычной Trie, гораздо проще в обходе. Обратите внимание, что Patricia Trie значительно сокращает количество узлов и, следовательно, делает операции более эффективными, сворачивая узлы, имеющие только одного ребенка.

#merkle #patricia
👍42
Merkle-Patricia Trees. Часть 5

Новая неделя и новые душные посты про Патрицию!

Понимаю, многим интересны будут, скорее, посты про что-то базовое из Solidity, но я хотел бы на канале порой дальше двигаться с "мясными" темами, которые сложно найти где-либо еще. Поэтому недели на две мы еще продолжим говорить про деревья Меркл-Патриция, захватывая темы верификации и уязвимостей. Итак, продолжим.

На прошлой неделе мы поняли, что Patricia tree (также известное как «Радиксное дерево» или «Trie») - это особый тип структуры данных, которая используется для хранения набора строк. Строки разбиваются на отдельные символы, и дерево строится путем создания пути для каждой строки, где каждый символ образует узел на пути. Patricia tree особенно полезны для наборов данных, в которых префиксы строк значительно пересекаются.

В дереве Меркла-Патриция Ethereum каждый счет с сопутствующей информацией (такой как баланс счета, nonce, код контракта, если это контрактный счет, и хранилище) образует строку, которую необходимо сохранить.

Основными компонентами дерева Патриция являются:

1. Узел: Каждый узел в дереве представляет собой символ строки. В контексте Ethereum узел может быть частью адреса счета или другой информации о счете.

2. Грани: это связь между узлами. Ребро соединяет узел с последующим узлом.

3. Ключ: Это символ (или, в случае Ethereum, ниббл (nibble), то есть половина байта), который представляет узел.

4. Путь/префикс: Это последовательность символов (ключей) от корня дерева до определенного узла.

5. Корневой узел: Это начальная точка дерева. Все пути в дереве начинаются от корневого узла.

6. Листовой узел: Это конечные точки каждого пути. В Ethereum узел листьев обычно содержит состояние счета.

Как работает древо?

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

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

В Ethereum для хранения состояния используется модифицированная версия дерева Патриция, называемая «деревом Меркл-Патриция». В этом случае каждый путь от корня до узла листа представляет собой адрес аккаунта, а узел листа содержит состояние этого аккаунта.

А дальше переходим к совсем сложным объяснениям...

#merkle #patricia
4
Merkle-Patricia Trees. Часть 6

Обход путей в Patricia Tree

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

Ключи узлов вдоль пути - это отдельные полубайты адреса счета. В случае Ethereum адреса имеют длину 20 байт, то есть их можно разбить на 40 полубайтов.

Например, если вы хотите найти состояние учетной записи с адресом 0xabcdef, вы начнете с корня и сначала перейдете к дочернему элементу, который соответствует полубайту 0xa. Оттуда вы перейдете к дочернему элементу, соответствующему 0xb, затем к 0xc, и так далее, пока не пройдете всю последовательность полубайтов 0xa, 0xb, 0xc, 0xd, 0xe, 0xf.

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

Patricia Tree в Ethereum различает два типа узлов: узлы листьев и узлы расширения. Кроме того, в этих узлах может храниться ключ с четным или нечетным количеством разрядов. Для указания типа и длины ключа используется двухбитный префикс. Возможными значениями префикса являются:

0x00: Узел расширения, четное количество полубайтов.

0x10: Узел расширения, нечетное количество полубайтов.

0x20: Листовой узел, четное количество полубайтов.

0x30: Листовой узел, нечетное количество полубайтов.

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

Четное и нечетное количество полубайтов связано с тем, как хранится ключ. Ниббл - это четырехбитное объединение, или половина октета (octet или октет - это 8-битный байт). Ключи в Patricia Tree Ethereum представлены в виде шестнадцатеричных строк, где каждый шестнадцатеричный символ представляет собой ниббл (4 бита).

Когда мы говорим о «четном» или «нечетном» количестве нибблов, мы имеем в виду длину пути от корневого узла до конкретного узла. Если число полубайтов в пути четное, узел имеет четный префикс (0x00 для расширения, 0x20 для листа), а если число полубайтов нечетное, узел имеет нечетный префикс (0x10 для расширения, 0x30 для листа).

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

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

#merkle #patricia
4👍3🤯3🥰1
Merkle-Patricia Trees. Часть 7

Значения, хранящиеся в узле

Каждый узел в Patricia tree содержит ключ - символ, который этот узел представляет. В Ethereum такими ключами являются ниблы из адресов счетов. Однако листовые узлы в Merkle-Patricia Trees Ethereum хранят не только ключи, но и состояние соответствующего счета.

Состояние счета Ethereum включает в себя:

1. Nonce: Это число, обозначающее количество транзакций, отправленных с адреса учетной записи. Оно используется для предотвращения атак повторного воспроизведения.

2. Баланс: Это количество Ether, которым располагает аккаунт.

3. Корень хранилища: Для аккаунтов смарт-контрактов это корень другого дерева Меркла-Патриция, в котором хранится содержимое смарт-контракта. Каждый путь в этом дереве соответствует ключу хранения, а соответствующий листовой узел содержит значение хранения для этого ключа.

4. Хэш кода: Для аккаунтов смарт-контрактов это хэш Keccak-256 байткода EVM, составляющего код смарт-контракта. Если аккаунт не является смарт-контрактом, это значение представляет собой хэш пустой строки.

Каждый из этих компонентов состояния счета хранится в листовых узлах Merkle-Patricia Trees в Ethereum.

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

#merkle #patricia
👍4
Merkle-Patricia Trees. Часть 8

Каждый узел в Merkle-Patricia Trees идентифицируется уникальным хэшем, который представляет собой хэш Keccak-256 кодировки RLP (Recursive Length Prefix) содержимого узла. Различные типы узлов в дереве Меркла-Патриция имеют разное содержимое:

1. Листовые узлы: Листовой узел в дереве Меркла-Патриция представляет собой структуру из двух элементов [ключ, значение]. Ключ - это адрес счета (точнее, его преобразованная в Patricia версия), а значение - это закодированное в RLP состояние счета. Состояние включает в себя nonce, баланс, корень хранилища и хэш кода, как упоминалось ранее.

2. Узлы ветвления: Узел ветвления - это структура из 17 элементов. Первые 16 элементов соответствуют 16 возможным символам (0-9 и a-f). Каждый элемент - это хэш дочернего узла, соответствующего этому узлу, или пустой, если такого дочернего узла нет. 17-й элемент - это значение, которое является состоянием счета, если этот узел представляет полный адрес счета, или пустой в противном случае.

3. Узлы расширения: Узел расширения - это двухэлементная структура [ключ, значение], аналогичная узлу листа. Ключ - это общая часть ключей его дочерних узлов, а значение - это хэш его единственного дочернего узла.

Таким образом, помимо пар ключ-значение (для узлов листьев и расширений) или хэшей дочерних узлов (для узлов ветвей), каждый узел неявно содержит свой собственный хэш, который вычисляется как хэш Keccak-256 кодировки RLP содержимого узла. Этот хэш не хранится в самом узле, но используется в качестве ссылки в его родительском узле.

#merkle #patricia
👍21
Merkle-Patricia Trees. Часть 9

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

Допустим, у вас есть родительский узел в дереве, и у него есть два дочерних узла. Когда создаются дочерние узлы, информация в каждом из них хэшируется с помощью криптографической хэш-функции (Keccak-256, в случае Ethereum). В результате получается уникальный результат (хэш) для каждого дочернего узла. Затем эти хэши хранятся в родительском узле.

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

Эта схема обеспечивает ряд существенных преимуществ:

1. Эффективность: Хранение только хэша, а не полных данных об узле, позволяет сохранить размер каждого узла, а также обеспечивает эффективную навигацию и обновление дерева.

2. Целостность: Поскольку хэш узла является уникальным отпечатком его содержимого, любое изменение данных узла приведет к изменению его хэша. Это, в свою очередь, приведет к изменению хэша родительского узла и, в конечном счете, корня. Таким образом, любая фальсификация данных может быть обнаружена путем проверки согласованности хэшей.

3. Доказательства: Связывание хэшей также позволяет использовать «доказательства Меркла». Доказательство Меркла позволяет доказать, что определенный листовой узел является частью дерева, не требуя для этого всего дерева. Это делается путем предоставления пути хэшей от корня до этого листа.

Итак, подведем итог: связь каждого узла с его дочерними узлами посредством хранения их хэшей - это критическая особенность, которая позволяет обходить, проверять целостность и доказывать включение в Merkle-Patricia Trees.

#merkle #patricia
👍51