Чтобы приведённое выше определение было принято, приходится добавлять неочевидное приведение типа к первому элементу массива:
Алгоритм вывода типов на основе ограничений в Core Solidity гораздо более общий и позволяет опустить такое приведение:
#core
uint256[3] memory a = [uint256(1), 2, 3];
Алгоритм вывода типов на основе ограничений в Core Solidity гораздо более общий и позволяет опустить такое приведение:
uint256[3] memory a = [1, 2, 3];
#core
👍4❤2
Погружение в Core Solidity. Часть 5
SAIL, десахаризация и стандартная библиотека
Помимо расширения поверхностного языка, переход на Core Solidity также введёт новый промежуточный язык среднего уровня, доступный пользователям: SAIL (Solidity Algebraic Intermediate Language — Алгебраический промежуточный язык Solidity). Это и есть «ядро» Core Solidity. SAIL представляет собой максимально упрощённый язык, на котором можно выразить всё разнообразие высокоуровневых конструкций, присутствующих в классической Solidity. Он состоит из следующих примитивных конструкций:
- Функции
- Контракты
- Блоки ассемблера (Yul)
- Объявление и присваивание переменных SAIL
- Выражение условного ветвления с коротким замыканием (if-then-else)
- Алгебраические типы данных и сопоставление с образцом
- Классы типов (type classes)
- Обобщения (generics)
Переменная SAIL концептуально похожа на переменную Yul: компилятор связывает её с ячейкой в стеке EVM. В SAIL существует единственный встроенный тип (word), диапазон значений которого совпадает с типами bytes32 или uint256 в классической Solidity и который семантически можно рассматривать как тип, соответствующий одному слоту стека EVM. Контракты в SAIL крайне низкоуровневы — по сути, это просто точки входа времени выполнения и инициализационного кода (initcode).
Хотя в текущей реализации SAIL используется Yul в качестве языка ассемблера, с теоретической точки зрения этот выбор в значительной степени произволен, и вместо него можно было бы использовать, например, ассемблер на основе RISC-V.
Мы уверены, что SAIL достаточно выразителен, чтобы реализовать все высокоуровневые функции и типы языка как комбинацию определений из стандартной библиотеки и проходов десахаризации — то есть синтаксических преобразований времени компиляции в примитивы SAIL. Core Solidity, таким образом, представляет собой SAIL, дополненный дополнительным «синтаксическим сахаром» и библиотеками. Он схож с Yul в своей двойной роли как промежуточного представления компилятора и низкоуровневого языка, доступного пользователю, и все примитивы SAIL будут непосредственно доступны при написании кода на Core Solidity. Подобный подход к построению языков широко применяется в других областях, требующих высокой надёжности (например, в системах автоматического доказательства теорем), и, по нашему мнению, он приносит существенные преимущества как для пользователей языка, так и для безопасности и корректности его реализации.
Мы ожидаем, что сможем создать исполняемую формальную семантику для SAIL. Это позволит нам математически гарантировать ключевые свойства системы типов Solidity, предоставить эталонную реализацию для дифференциального фаззинга, а также формально верифицировать как стандартную библиотеку, так и высокоуровневые языковые конструкции. Мы считаем, что это станет неотъемлемой частью нашей общей стратегии обеспечения корректности, особенно по мере роста сложности языка и масштабов систем, создаваемых с его помощью.
Авторы библиотек получат практически ту же выразительную мощность, что и разработчики языка, и смогут создавать абстракции, ощущающиеся как встроенные в сам язык («язык на основе библиотек»). Появится возможность определять и использовать альтернативные реализации стандартной библиотеки или полностью отключать стандартную библиотеку. При отключённой стандартной библиотеке можно будет писать код на Core Solidity с почти таким же уровнем контроля, как при использовании низкоуровневых ассемблерных языков вроде Yul или Huff, но при этом с современной и выразительной системой типов, основанной на математически строгих принципах.
SAIL, десахаризация и стандартная библиотека
Помимо расширения поверхностного языка, переход на Core Solidity также введёт новый промежуточный язык среднего уровня, доступный пользователям: SAIL (Solidity Algebraic Intermediate Language — Алгебраический промежуточный язык Solidity). Это и есть «ядро» Core Solidity. SAIL представляет собой максимально упрощённый язык, на котором можно выразить всё разнообразие высокоуровневых конструкций, присутствующих в классической Solidity. Он состоит из следующих примитивных конструкций:
- Функции
- Контракты
- Блоки ассемблера (Yul)
- Объявление и присваивание переменных SAIL
- Выражение условного ветвления с коротким замыканием (if-then-else)
- Алгебраические типы данных и сопоставление с образцом
- Классы типов (type classes)
- Обобщения (generics)
Переменная SAIL концептуально похожа на переменную Yul: компилятор связывает её с ячейкой в стеке EVM. В SAIL существует единственный встроенный тип (word), диапазон значений которого совпадает с типами bytes32 или uint256 в классической Solidity и который семантически можно рассматривать как тип, соответствующий одному слоту стека EVM. Контракты в SAIL крайне низкоуровневы — по сути, это просто точки входа времени выполнения и инициализационного кода (initcode).
Хотя в текущей реализации SAIL используется Yul в качестве языка ассемблера, с теоретической точки зрения этот выбор в значительной степени произволен, и вместо него можно было бы использовать, например, ассемблер на основе RISC-V.
Мы уверены, что SAIL достаточно выразителен, чтобы реализовать все высокоуровневые функции и типы языка как комбинацию определений из стандартной библиотеки и проходов десахаризации — то есть синтаксических преобразований времени компиляции в примитивы SAIL. Core Solidity, таким образом, представляет собой SAIL, дополненный дополнительным «синтаксическим сахаром» и библиотеками. Он схож с Yul в своей двойной роли как промежуточного представления компилятора и низкоуровневого языка, доступного пользователю, и все примитивы SAIL будут непосредственно доступны при написании кода на Core Solidity. Подобный подход к построению языков широко применяется в других областях, требующих высокой надёжности (например, в системах автоматического доказательства теорем), и, по нашему мнению, он приносит существенные преимущества как для пользователей языка, так и для безопасности и корректности его реализации.
Мы ожидаем, что сможем создать исполняемую формальную семантику для SAIL. Это позволит нам математически гарантировать ключевые свойства системы типов Solidity, предоставить эталонную реализацию для дифференциального фаззинга, а также формально верифицировать как стандартную библиотеку, так и высокоуровневые языковые конструкции. Мы считаем, что это станет неотъемлемой частью нашей общей стратегии обеспечения корректности, особенно по мере роста сложности языка и масштабов систем, создаваемых с его помощью.
Авторы библиотек получат практически ту же выразительную мощность, что и разработчики языка, и смогут создавать абстракции, ощущающиеся как встроенные в сам язык («язык на основе библиотек»). Появится возможность определять и использовать альтернативные реализации стандартной библиотеки или полностью отключать стандартную библиотеку. При отключённой стандартной библиотеке можно будет писать код на Core Solidity с почти таким же уровнем контроля, как при использовании низкоуровневых ассемблерных языков вроде Yul или Huff, но при этом с современной и выразительной системой типов, основанной на математически строгих принципах.
❤3
Кроме того, мы ожидаем, что появление SAIL существенно упростит расширение и улучшение языка. Во многих случаях достаточно будет внести глубокие улучшения простым пул-реквестом в стандартную библиотеку. Когда же потребуется новая синтаксическая конструкция или новый проход десахаризации, мы рассчитываем, что их будет значительно проще прототипировать и специфицировать на SAIL без необходимости глубокого понимания внутренностей компилятора. Мы надеемся, что SAIL и Core Solidity позволят нам перейти к процессу разработки изменений в высокоуровневый язык и стандартную библиотеку, основанному на сообществе и использующему RFC-подобную модель.
#core
#core
👍5
Погружение в Core Solidity. Часть 6
Пользовательский ABI-кодировщик в пользовательском пространстве
Рассмотрим, как SAIL можно использовать для реализации высокоуровневых возможностей Core Solidity. Функция abi.encode — сложная и чрезвычайно обобщённая; в классическом Solidity она предоставляется как встроенная в компилятор. Полноценную реализацию этой функции на самом языке Solidity создать невозможно из-за рекурсивной природы спецификации ABI и, как следствие, бесконечного множества выразимых типов. Представленная здесь реализация сравнительно компактна, однако использует некоторые более продвинутые шаблоны и возможности. Мы хотим подчеркнуть, что обычные пользователи Solidity смогут эффективно работать, опираясь на уже имеющиеся знания, и при этом им не придётся сталкиваться с подобными низкоуровневыми внутренними деталями. В то же время мы надеемся, что продвинутые разработчики и авторы библиотек обрадуются новым возможностям, которые открывают эти возможности.
В целях упрощения изложения ограничимся фрагментом, необходимым для кодирования типа uint256.
uint256
Для начала сконструируем тип uint256. В классическом Solidity определение этого типа и всех связанных с ним операций является встроенной языковой конструкцией. В SAIL же этот тип полностью определяется средствами самого языка как простая обёртка над значением типа word. Мы также определяем для него экземпляр Typedef:
Память и байты
Мы можем создавать типы, представляющие указатели на различные области данных EVM, путём обёртки значения типа word. Обратите внимание, что в приведённом фрагменте параметр типа у указателя memory является фантомным (phantom): он присутствует только в типе, но не упоминается ни в одном конструкторе значений. Такой подход широко используется в языках семейства ML, таких как Haskell или Rust, позволяя обеспечивать ограничения на этапе компиляции без каких-либо накладных расходов во время выполнения.
Тип bytes в классическом Solidity представляет собой плотно упакованный массив байтов, размер которого известен только во время выполнения. Классический Solidity всегда требует указания области данных для значений типа bytes, поэтому в Core Solidity мы определяем его как пустой тип без конструкторов значений. Пустые типы могут использоваться только для инстанцирования фантомных параметров типов. Это означает, что, как и в классическом Solidity, экземпляры типа bytes не могут находиться в стеке.
Заметьте, что в этой конструкции указателей и областей данных область данных привязана непосредственно к типу (в отличие от классического Solidity, где она привязана к переменной), что позволяет, например, определять структуры в памяти, содержащие ссылки на хранилище (storage).
#core
Пользовательский ABI-кодировщик в пользовательском пространстве
Рассмотрим, как SAIL можно использовать для реализации высокоуровневых возможностей Core Solidity. Функция abi.encode — сложная и чрезвычайно обобщённая; в классическом Solidity она предоставляется как встроенная в компилятор. Полноценную реализацию этой функции на самом языке Solidity создать невозможно из-за рекурсивной природы спецификации ABI и, как следствие, бесконечного множества выразимых типов. Представленная здесь реализация сравнительно компактна, однако использует некоторые более продвинутые шаблоны и возможности. Мы хотим подчеркнуть, что обычные пользователи Solidity смогут эффективно работать, опираясь на уже имеющиеся знания, и при этом им не придётся сталкиваться с подобными низкоуровневыми внутренними деталями. В то же время мы надеемся, что продвинутые разработчики и авторы библиотек обрадуются новым возможностям, которые открывают эти возможности.
В целях упрощения изложения ограничимся фрагментом, необходимым для кодирования типа uint256.
uint256
Для начала сконструируем тип uint256. В классическом Solidity определение этого типа и всех связанных с ним операций является встроенной языковой конструкцией. В SAIL же этот тип полностью определяется средствами самого языка как простая обёртка над значением типа word. Мы также определяем для него экземпляр Typedef:
data uint256 = uint256(word);
instance uint256:Typedef(word) {
function abs(w : word) -> uint256 {
return uint256(w);
}
function rep(x : uint256) -> word {
match x {
| uint256(w) => return w;
}
}
}
Память и байты
Мы можем создавать типы, представляющие указатели на различные области данных EVM, путём обёртки значения типа word. Обратите внимание, что в приведённом фрагменте параметр типа у указателя memory является фантомным (phantom): он присутствует только в типе, но не упоминается ни в одном конструкторе значений. Такой подход широко используется в языках семейства ML, таких как Haskell или Rust, позволяя обеспечивать ограничения на этапе компиляции без каких-либо накладных расходов во время выполнения.
data memory(T) = memory(word)
Тип bytes в классическом Solidity представляет собой плотно упакованный массив байтов, размер которого известен только во время выполнения. Классический Solidity всегда требует указания области данных для значений типа bytes, поэтому в Core Solidity мы определяем его как пустой тип без конструкторов значений. Пустые типы могут использоваться только для инстанцирования фантомных параметров типов. Это означает, что, как и в классическом Solidity, экземпляры типа bytes не могут находиться в стеке.
data bytes;
Заметьте, что в этой конструкции указателей и областей данных область данных привязана непосредственно к типу (в отличие от классического Solidity, где она привязана к переменной), что позволяет, например, определять структуры в памяти, содержащие ссылки на хранилище (storage).
#core
👍4
Погружение в Core Solidity. Часть 7
Тип Proxy
Последним элементом, необходимым для реализации abi.encode, является тип Proxy:
Как и в определении типа memory, параметр типа здесь является фантомным, однако, в отличие от memory, Proxy не несёт никакой дополнительной информации во время выполнения. Он существует исключительно как маркерный тип, позволяющий передавать информацию на этапе компиляции. Подобные типы полностью «бесплатны» с точки зрения производительности: они полностью элиминируются на этапе компиляции и вовсе не присутствуют в финальной скомпилированной программе.
Хотя Proxy может показаться довольно экзотическим инструментом, он чрезвычайно полезен и даёт нам значительный контроль над выводом типов и выбором экземпляров классов типов без необходимости передавать данные во время выполнения там, где они не нужны. Такой подход часто используется как в Haskell (где он тоже называется Proxy), так и в Rust (std::marker::PhantomData).
abi.encode
Теперь мы готовы реализовать функцию abi.encode из классического Solidity на языке SAIL. Начнём с определения класса типов для метаданных, связанных с ABI. Заметим, что поскольку этому классу не нужно знать фактическое значение передаваемого типа, мы используем Proxy, чтобы сделать реализацию максимально лёгкой.
Теперь определим ещё один класс, отвечающий за низкоуровневую запись в память. Приведённый здесь класс содержит некоторые дополнительные детали, необходимые для кодирования составных и динамических типов, которые не требуются для простого случая uint256, рассматриваемого сейчас. Мы показываем полную сложность, чтобы продемонстрировать, что наша система способна справляться и с более сложными случаями.
Наконец, мы можем определить высокоуровневую функцию abi_encode, которая занимается первоначальным выделением памяти и обновлением указателя на свободную память (реализация вспомогательных низкоуровневых функций get_free_memory и set_free_memory опущена для краткости):
#core
Тип Proxy
Последним элементом, необходимым для реализации abi.encode, является тип Proxy:
data Proxy(T) = Proxy;
Как и в определении типа memory, параметр типа здесь является фантомным, однако, в отличие от memory, Proxy не несёт никакой дополнительной информации во время выполнения. Он существует исключительно как маркерный тип, позволяющий передавать информацию на этапе компиляции. Подобные типы полностью «бесплатны» с точки зрения производительности: они полностью элиминируются на этапе компиляции и вовсе не присутствуют в финальной скомпилированной программе.
Хотя Proxy может показаться довольно экзотическим инструментом, он чрезвычайно полезен и даёт нам значительный контроль над выводом типов и выбором экземпляров классов типов без необходимости передавать данные во время выполнения там, где они не нужны. Такой подход часто используется как в Haskell (где он тоже называется Proxy), так и в Rust (std::marker::PhantomData).
abi.encode
Теперь мы готовы реализовать функцию abi.encode из классического Solidity на языке SAIL. Начнём с определения класса типов для метаданных, связанных с ABI. Заметим, что поскольку этому классу не нужно знать фактическое значение передаваемого типа, мы используем Proxy, чтобы сделать реализацию максимально лёгкой.
forall T . class T:ABIAttribs {
// how many bytes should be used for the head portion of the ABI encoding of `T`
function headSize(ty : Proxy(T)) -> word;
// whether or not `T` is a fully static type
function isStatic(ty : Proxy(T)) -> bool;
}
instance uint256:ABIAttribs {
function headSize(ty : Proxy(uint256)) -> word { return 32; }
function isStatic(ty : Proxy(uint256)) -> bool { return true; }
}Теперь определим ещё один класс, отвечающий за низкоуровневую запись в память. Приведённый здесь класс содержит некоторые дополнительные детали, необходимые для кодирования составных и динамических типов, которые не требуются для простого случая uint256, рассматриваемого сейчас. Мы показываем полную сложность, чтобы продемонстрировать, что наша система способна справляться и с более сложными случаями.
// types that can be abi encoded
forall T . T:ABIAttribs => class T:ABIEncode {
// abi encodes an instance of T into a memory region starting at basePtr
// offset gives the offset in memory from basePtr to the first empty byte of the head
// tail gives the position in memory of the first empty byte of the tail
function encodeInto(x : T, basePtr : word, offset : word, tail : word) -> word /* newTail */;
}
instance uint256:ABIEncode {
// a unit256 is written directly into the head
function encodeInto(x : uint256, basePtr : word, offset : word, tail : word) -> word {
let repx : word = Typedef.rep(x);
assembly { mstore(add(basePtr, offset), repx) }
return tail;
}
}
Наконец, мы можем определить высокоуровневую функцию abi_encode, которая занимается первоначальным выделением памяти и обновлением указателя на свободную память (реализация вспомогательных низкоуровневых функций get_free_memory и set_free_memory опущена для краткости):
// top level encoding function.
// abi encodes an instance of `T` and returns a pointer to the result
forall T . T:ABIEncode => function abi_encode(val : T) -> memory(bytes) {
let free = get_free_memory();
let headSize = ABIAttribs.headSize(Proxy : Proxy(T));
let tail = ABIEncode.encodeInto(val, free, 0, Add.add(free, headSize));
set_free_memory(tail);
return memory(free);
}
#core
👍2
Погружение в Core Solidity. Финал
Совместимость и взаимодействие
Внедрение столь масштабного пересмотра любого языка программирования — задача непростая. Хотя определённый уровень несовместимости неизбежен (и даже желателен), мы стремимся сделать переход максимально плавным и избежать раскола в языке.
Как и в предыдущих крупных обновлениях Solidity, совместимость на уровне ABI будет сохраняться между версиями. Это позволит отдельным контрактам, написанным на несовместимых версиях языка, взаимодействовать друг с другом и сосуществовать в рамках одного проекта (аналогичная стратегия применяется в Rust с их функцией «Editions»). Мы также изучаем возможность более глубокого взаимодействия, выходящего за рамки только ABI контрактов. Предполагается, что хотя бы свободные функции и определения интерфейсов можно будет совместно использовать между версиями языка.
Хотя изменения затронут как синтаксис, так и семантику, мы намерены свести их к минимуму и применять только в тех случаях, когда это строго необходимо или приносит существенные преимущества, оправдывающие затраты на миграцию. Мы ожидаем, что простой код без наследования будет выглядеть и ощущаться практически одинаково в обеих версиях языка, с лишь незначительными синтаксическими отличиями (в основном — переход от префиксной записи типов к постфиксной). Мы также рассматриваем возможность переработки или замены некоторых функций, которые на практике оказались проблемными или ограничивающими (например, try/catch, библиотеки, указатели на функции, области данных). Пользователи могут ожидать, что для адаптации кода, использующего эти возможности, потребуются умеренные изменения. Разумеется, код, активно использующий наследование, потребует наиболее значительных переделок.
Мы планируем изучить потенциал автоматической миграции и, если удастся создать надёжные и устойчивые инструменты, включим их в релиз.
Избежать раскола по типу «Python 2 → Python 3» — наша главная задача. Мы считаем, что обновления должны быть управляемыми и возможными для поэтапного внедрения.
Путь к использованию
В этом разделе излагается наше текущее видение достижения готовности к применению и стратегия безопасного внесения столь глубоких изменений в язык. Обратите внимание: это предварительный план, который может существенно измениться. На данный момент мы ещё не готовы называть конкретные сроки. Более подробная информация будет предоставлена по мере приближения к полноценной реализации.
У нас уже есть прототип, реализованный в отдельном репозитории: solcore. Мы можем выполнять проверку типов программ на SAIL и имеем конвейер генерации кода до уровня Yul. Однако до окончательной фиксации системы типов нам ещё предстоит реализовать как минимум вычисления на этапе компиляции и модульную систему. У нас есть базовая стандартная библиотека и достаточное количество этапов «десахаризации» (desugaring) для реализации самых фундаментальных возможностей классического Solidity. Мы уже можем генерировать контракты, совместимые по ABI, с поддержкой диспетчеризации, кодирования/декодирования ABI и доступа к хранилищу.
Тем не менее, на этапе прототипа ещё предстоит выполнить значительный объём работы, прежде чем можно будет приступить к полноценной реализации. Нам необходимо завершить разработку системы типов, расширить стандартную библиотеку и написать достаточно кода, чтобы убедиться в достаточности текущего подхода для поддержки всего необходимого функционала. Требуется тщательная документация системы типов и внутреннего устройства компилятора. Кроме того, мы планируем активно сотрудничать с опытными пользователями и авторами библиотек для получения обратной связи и внесения необходимых корректировок.
Как только мы убедимся в стабильности прототипа, работа разделится на два параллельных направления:
Совместимость и взаимодействие
Внедрение столь масштабного пересмотра любого языка программирования — задача непростая. Хотя определённый уровень несовместимости неизбежен (и даже желателен), мы стремимся сделать переход максимально плавным и избежать раскола в языке.
Как и в предыдущих крупных обновлениях Solidity, совместимость на уровне ABI будет сохраняться между версиями. Это позволит отдельным контрактам, написанным на несовместимых версиях языка, взаимодействовать друг с другом и сосуществовать в рамках одного проекта (аналогичная стратегия применяется в Rust с их функцией «Editions»). Мы также изучаем возможность более глубокого взаимодействия, выходящего за рамки только ABI контрактов. Предполагается, что хотя бы свободные функции и определения интерфейсов можно будет совместно использовать между версиями языка.
Хотя изменения затронут как синтаксис, так и семантику, мы намерены свести их к минимуму и применять только в тех случаях, когда это строго необходимо или приносит существенные преимущества, оправдывающие затраты на миграцию. Мы ожидаем, что простой код без наследования будет выглядеть и ощущаться практически одинаково в обеих версиях языка, с лишь незначительными синтаксическими отличиями (в основном — переход от префиксной записи типов к постфиксной). Мы также рассматриваем возможность переработки или замены некоторых функций, которые на практике оказались проблемными или ограничивающими (например, try/catch, библиотеки, указатели на функции, области данных). Пользователи могут ожидать, что для адаптации кода, использующего эти возможности, потребуются умеренные изменения. Разумеется, код, активно использующий наследование, потребует наиболее значительных переделок.
Мы планируем изучить потенциал автоматической миграции и, если удастся создать надёжные и устойчивые инструменты, включим их в релиз.
Избежать раскола по типу «Python 2 → Python 3» — наша главная задача. Мы считаем, что обновления должны быть управляемыми и возможными для поэтапного внедрения.
Путь к использованию
В этом разделе излагается наше текущее видение достижения готовности к применению и стратегия безопасного внесения столь глубоких изменений в язык. Обратите внимание: это предварительный план, который может существенно измениться. На данный момент мы ещё не готовы называть конкретные сроки. Более подробная информация будет предоставлена по мере приближения к полноценной реализации.
У нас уже есть прототип, реализованный в отдельном репозитории: solcore. Мы можем выполнять проверку типов программ на SAIL и имеем конвейер генерации кода до уровня Yul. Однако до окончательной фиксации системы типов нам ещё предстоит реализовать как минимум вычисления на этапе компиляции и модульную систему. У нас есть базовая стандартная библиотека и достаточное количество этапов «десахаризации» (desugaring) для реализации самых фундаментальных возможностей классического Solidity. Мы уже можем генерировать контракты, совместимые по ABI, с поддержкой диспетчеризации, кодирования/декодирования ABI и доступа к хранилищу.
Тем не менее, на этапе прототипа ещё предстоит выполнить значительный объём работы, прежде чем можно будет приступить к полноценной реализации. Нам необходимо завершить разработку системы типов, расширить стандартную библиотеку и написать достаточно кода, чтобы убедиться в достаточности текущего подхода для поддержки всего необходимого функционала. Требуется тщательная документация системы типов и внутреннего устройства компилятора. Кроме того, мы планируем активно сотрудничать с опытными пользователями и авторами библиотек для получения обратной связи и внесения необходимых корректировок.
Как только мы убедимся в стабильности прототипа, работа разделится на два параллельных направления:
1. Продакшн реализация: мы перепишем проверку типов, этапы десахаризации и генерацию Yul на системном языке (например, Rust, C++ или Zig) и интегрируем это в основной компилятор solc. Эта реализация будет ориентирована на корректность, производительность и обеспечение максимально качественных диагностических сообщений и ошибок.
2. Исполняемая формальная семантика: мы формализуем наше существующее описание на LaTeX в среде автоматического доказательства теорем (вероятно, Lean). Это позволит укрепить доверие как к данной реализации, так и к самой стандартной библиотеке и системе типов.
После того как такая реализация станет относительно стабильной, Core Solidity будет доступен как экспериментальная функция, но ещё не будет помечен как промышленно готовый. В этот период мы будем собирать реальную обратную связь от пользователей, продолжать фаззинг и вынесем стандартную библиотеку на внешний аудит. Как только мы убедимся, что новый фронтенд свободен от серьёзных ошибок, будет выпущена ломающая обратную совместимость версия solc, в которой Core станет версией языка по умолчанию.
#core
2. Исполняемая формальная семантика: мы формализуем наше существующее описание на LaTeX в среде автоматического доказательства теорем (вероятно, Lean). Это позволит укрепить доверие как к данной реализации, так и к самой стандартной библиотеке и системе типов.
После того как такая реализация станет относительно стабильной, Core Solidity будет доступен как экспериментальная функция, но ещё не будет помечен как промышленно готовый. В этот период мы будем собирать реальную обратную связь от пользователей, продолжать фаззинг и вынесем стандартную библиотеку на внешний аудит. Как только мы убедимся, что новый фронтенд свободен от серьёзных ошибок, будет выпущена ломающая обратную совместимость версия solc, в которой Core станет версией языка по умолчанию.
#core
👍2
Вышел Solidity 0.8.31
Команда Solidity объявила о выходе компилятора Solidity версии 0.8.31. Обновление приносит поддержку новых возможностей EVM, представленных в сетевом апгрейде Fusaka, расширяет функциональность спецификаторов раскладки хранилища и запускает первый этап отказа от устаревших возможностей, которые будут окончательно удалены в версии 0.9.0. Кроме того, теперь официально публикуются сборки компилятора для Linux на архитектуре ARM.
Одним из ключевых изменений стало то, что версия EVM с кодовым названием osaka теперь используется по умолчанию. При необходимости разработчики по-прежнему могут указать более старую версию виртуальной машины через настройки компилятора. В новой версии также добавлена поддержка опкода CLZ, реализующего стандарт EIP-7939. Эта инструкция позволяет считать количество ведущих нулей в 256-битном слове и открывает новые возможности для оптимизаций, битовых операций, алгоритмов сжатия и работы со структурами данных на уровне приложений.
В ближайшее время этот опкод найдет активное применение в популярных библиотеках, включая solady и OpenZeppelin, где сможет заменить существующие реализации вроде Math.clz(). Пока в самом компиляторе область применения CLZ ограничена, но команда изучает способы использовать его для будущих оптимизаций генерации байткода.
С точки зрения инфраструктуры релиза произошло важное обновление: начиная с этой версии, Solidity официально выпускается в виде бинарных сборок для Linux на ARM. Ранее такие версии существовали либо в виде сборок под macOS, либо в виде самостоятельной компиляции из исходников. Теперь ARM-билды встроены в систему CI и проходят тот же цикл тестирования, что и остальные платформы, гарантируя идентичность байткода и метаданных на всех архитектурах.
Также введён формат предварительных релизов. Если раньше существовали только ночные сборки и полноценные релизы, то теперь появились pre-release версии, позволяющие получать доступ к новым фичам раньше официального релиза. Именно в pre-release впервые стала доступна поддержка CLZ, и эта практика будет использоваться дальше для постепенного внедрения экспериментальных возможностей.
Одновременно команда начала оптимизировать каналы распространения компилятора. В частности, официально прекращена поддержка Ubuntu PPA, так как этот канал оказался маловостребованным. Docker-сборки пока сохраняются, но в будущем тоже могут быть убраны, если их использование останется незначительным. При этом контейнеры уже перенесены из DockerHub в реестр GitHub, и новые версии будут публиковаться именно там.
Наконец, версия 0.8.31 открывает фазу активной подготовки к релизу 0.9.0, который станет несовместимым с предыдущими версиями. В компилятор добавлены предупреждения об устаревании send() и transfer(), устаревшего ABI coder v1, виртуальных модификаторов, сравнений контрактов без явного приведения к адресу и специального комментария memory-safe-assembly. Всё это сигнализирует о переходе Solidity к более строгой типизации, более прозрачной семантике и сокращению исторически сложных и небезопасных конструкций, которые долгое время тянулись из ранних версий языка.
#solidity
Команда Solidity объявила о выходе компилятора Solidity версии 0.8.31. Обновление приносит поддержку новых возможностей EVM, представленных в сетевом апгрейде Fusaka, расширяет функциональность спецификаторов раскладки хранилища и запускает первый этап отказа от устаревших возможностей, которые будут окончательно удалены в версии 0.9.0. Кроме того, теперь официально публикуются сборки компилятора для Linux на архитектуре ARM.
Одним из ключевых изменений стало то, что версия EVM с кодовым названием osaka теперь используется по умолчанию. При необходимости разработчики по-прежнему могут указать более старую версию виртуальной машины через настройки компилятора. В новой версии также добавлена поддержка опкода CLZ, реализующего стандарт EIP-7939. Эта инструкция позволяет считать количество ведущих нулей в 256-битном слове и открывает новые возможности для оптимизаций, битовых операций, алгоритмов сжатия и работы со структурами данных на уровне приложений.
В ближайшее время этот опкод найдет активное применение в популярных библиотеках, включая solady и OpenZeppelin, где сможет заменить существующие реализации вроде Math.clz(). Пока в самом компиляторе область применения CLZ ограничена, но команда изучает способы использовать его для будущих оптимизаций генерации байткода.
С точки зрения инфраструктуры релиза произошло важное обновление: начиная с этой версии, Solidity официально выпускается в виде бинарных сборок для Linux на ARM. Ранее такие версии существовали либо в виде сборок под macOS, либо в виде самостоятельной компиляции из исходников. Теперь ARM-билды встроены в систему CI и проходят тот же цикл тестирования, что и остальные платформы, гарантируя идентичность байткода и метаданных на всех архитектурах.
Также введён формат предварительных релизов. Если раньше существовали только ночные сборки и полноценные релизы, то теперь появились pre-release версии, позволяющие получать доступ к новым фичам раньше официального релиза. Именно в pre-release впервые стала доступна поддержка CLZ, и эта практика будет использоваться дальше для постепенного внедрения экспериментальных возможностей.
Одновременно команда начала оптимизировать каналы распространения компилятора. В частности, официально прекращена поддержка Ubuntu PPA, так как этот канал оказался маловостребованным. Docker-сборки пока сохраняются, но в будущем тоже могут быть убраны, если их использование останется незначительным. При этом контейнеры уже перенесены из DockerHub в реестр GitHub, и новые версии будут публиковаться именно там.
Наконец, версия 0.8.31 открывает фазу активной подготовки к релизу 0.9.0, который станет несовместимым с предыдущими версиями. В компилятор добавлены предупреждения об устаревании send() и transfer(), устаревшего ABI coder v1, виртуальных модификаторов, сравнений контрактов без явного приведения к адресу и специального комментария memory-safe-assembly. Всё это сигнализирует о переходе Solidity к более строгой типизации, более прозрачной семантике и сокращению исторически сложных и небезопасных конструкций, которые долгое время тянулись из ранних версий языка.
#solidity
1👍8❤4
Vibe codding и ваши идеи
С текущим развитием нейронных сетей и различных сервисов на основе них стало очень просто быстро собирать и тестировать свои идеи. Не нужно искать команду, долго сидеть над дизайном или стараться настроить сервер, чтобы запустить простой проект.
Сегодня просто хочу поделиться своими заметками про такой подход.
Если вы когда-либо пытались вникнуть в сферу стартапов, то наверняка много раз попадали на статьи/книги/посты, в которых говорилось, что в начале своего пути нужно не "бесконечно разрабатывать свой проект, наполняя его разными сомнительными фичами", а быстро собрать минимально рабочую версию, выпустить на рынок и собрать обратную связь от пользователей. Это, конечно, очень утрированное утверждение, но смысл должен быть понятен. Скорость тестирования свои идеи и поиск нужных опций для проекта в короткий срок - то, как нужно правильно работать.
И в настоящее время можно очень быстро собирать такие минимальные продукты с минимумом знаний.
Например, недавно меня просто позабавила идея объединения крипто торговли и доски канбан (типа Trello). Я посчитал, что было бы забавно и просто для новичков, вместо отслеживания бесконечных графиков просто перетаскивать карточки с одного столбца в другой, и тем самым выполнять действия покупка/продажа крипты. В итоге, с помощью нескольких запросов в Lovable (ИИ сервис для генерации фронтенд) появился такой концепт:
Сайт CryptoBoard
Тут просто можно перетаскивать карточки с места нам место. Больше ничего.
Я прекрасно понимаю, что это вообще все очень далеко от настоящего трейдинга, что нужно намного больше информации и т.д. Здесь скорее была идея просто посмотреть как это будет выглядеть вместе.
Такие сайты как Lovable, Replit, Manus могут помочь быстро составить прототип вашей идеи. Вы также можете использовать LMArena и разные описания того, что вы хотите, для генерации страниц проекта разными нейронками, выбирая наиболее удачные варианты. Сохраните их в отдельную папку.
Затем в современных редакторах кода с ИИ (Cursor, Windsurf, Antigravity), создайте базовый проект и попросите нейронку перенести дизайн сгенерированный ранее, на ваш новый проект. Так потихоньку можно создать базовый фронтенд.
Далее подключайте backend. Спрашивайте нейронку как лучше собрать эту часть, составляйте план и следуйте ему. Будет вообще здорово, если вы пройдете быстрый курс онлайн (видео на ютуб или другие специализированные сервисы) по необходимым языкам и библиотекам, чтобы понимать, что делает нейронка с вашим проектом.
Так, для меня лучше всего сработали Python+FastAPY+Redis. По каждому из них я брал дополнительное обучение онлайн.
В итоге, у вас может получиться базовый проект на вашем компьютере, который вы можете тестировать сколько угодно.
Кроме того, в конце вы так же можете попросить модель, типа Claude 4.5, проанализировать ваш проект на безопасность. Да, возможно, это не закроет сайт от дыр, но сделает его намного безопаснее. Советы он дает достаточно хорошие по этому стеку.
Так вы сможете быстро научиться собирать свои проекты, ускоряясь с каждым разом. И вместо разработки в течение 3-6 месяцев, сможете запускать сайты в течение месяца.
Тут хочу сделать два важных замечания:
1. Никогда не запускайте свой крипто проект без внешнего аудита! Не смотря на то, что нейронки и статические анализаторы уже хороши сегодня, они недостаточны для безопасности! Аудит обязателен!
2. Уделяйте время безопасности и вашему собственному сайту и серверу, где он хранится. Фронтенд и бекенд сайтов проще править в продакшене, чем смарт контракты, но эффект от взлома может быть не меньше!
А вообще, пробуйте, учитесь, разрабатывайте. Объединяйте разные идеи - трейдинг и канбан, переводы крипты и чат в мессенджере, сообщества и сторис, вообще все, что взбредет в голову. Создавайте дизайны. Сейчас это проще, чем было!
#vibe
С текущим развитием нейронных сетей и различных сервисов на основе них стало очень просто быстро собирать и тестировать свои идеи. Не нужно искать команду, долго сидеть над дизайном или стараться настроить сервер, чтобы запустить простой проект.
Сегодня просто хочу поделиться своими заметками про такой подход.
Если вы когда-либо пытались вникнуть в сферу стартапов, то наверняка много раз попадали на статьи/книги/посты, в которых говорилось, что в начале своего пути нужно не "бесконечно разрабатывать свой проект, наполняя его разными сомнительными фичами", а быстро собрать минимально рабочую версию, выпустить на рынок и собрать обратную связь от пользователей. Это, конечно, очень утрированное утверждение, но смысл должен быть понятен. Скорость тестирования свои идеи и поиск нужных опций для проекта в короткий срок - то, как нужно правильно работать.
И в настоящее время можно очень быстро собирать такие минимальные продукты с минимумом знаний.
Например, недавно меня просто позабавила идея объединения крипто торговли и доски канбан (типа Trello). Я посчитал, что было бы забавно и просто для новичков, вместо отслеживания бесконечных графиков просто перетаскивать карточки с одного столбца в другой, и тем самым выполнять действия покупка/продажа крипты. В итоге, с помощью нескольких запросов в Lovable (ИИ сервис для генерации фронтенд) появился такой концепт:
Сайт CryptoBoard
Тут просто можно перетаскивать карточки с места нам место. Больше ничего.
Я прекрасно понимаю, что это вообще все очень далеко от настоящего трейдинга, что нужно намного больше информации и т.д. Здесь скорее была идея просто посмотреть как это будет выглядеть вместе.
Такие сайты как Lovable, Replit, Manus могут помочь быстро составить прототип вашей идеи. Вы также можете использовать LMArena и разные описания того, что вы хотите, для генерации страниц проекта разными нейронками, выбирая наиболее удачные варианты. Сохраните их в отдельную папку.
Затем в современных редакторах кода с ИИ (Cursor, Windsurf, Antigravity), создайте базовый проект и попросите нейронку перенести дизайн сгенерированный ранее, на ваш новый проект. Так потихоньку можно создать базовый фронтенд.
Далее подключайте backend. Спрашивайте нейронку как лучше собрать эту часть, составляйте план и следуйте ему. Будет вообще здорово, если вы пройдете быстрый курс онлайн (видео на ютуб или другие специализированные сервисы) по необходимым языкам и библиотекам, чтобы понимать, что делает нейронка с вашим проектом.
Так, для меня лучше всего сработали Python+FastAPY+Redis. По каждому из них я брал дополнительное обучение онлайн.
В итоге, у вас может получиться базовый проект на вашем компьютере, который вы можете тестировать сколько угодно.
Кроме того, в конце вы так же можете попросить модель, типа Claude 4.5, проанализировать ваш проект на безопасность. Да, возможно, это не закроет сайт от дыр, но сделает его намного безопаснее. Советы он дает достаточно хорошие по этому стеку.
Так вы сможете быстро научиться собирать свои проекты, ускоряясь с каждым разом. И вместо разработки в течение 3-6 месяцев, сможете запускать сайты в течение месяца.
Тут хочу сделать два важных замечания:
1. Никогда не запускайте свой крипто проект без внешнего аудита! Не смотря на то, что нейронки и статические анализаторы уже хороши сегодня, они недостаточны для безопасности! Аудит обязателен!
2. Уделяйте время безопасности и вашему собственному сайту и серверу, где он хранится. Фронтенд и бекенд сайтов проще править в продакшене, чем смарт контракты, но эффект от взлома может быть не меньше!
А вообще, пробуйте, учитесь, разрабатывайте. Объединяйте разные идеи - трейдинг и канбан, переводы крипты и чат в мессенджере, сообщества и сторис, вообще все, что взбредет в голову. Создавайте дизайны. Сейчас это проще, чем было!
#vibe
🔥9❤1
Весь курс по Solidity на одной платформе!
Скоро заканчивается год, но не объемы работы! В данный момент я, как и обещал ранее, нахожусь в стадии разработки сайта, где будут собраны все уроки со всех модулей курса. И этот скрин - первый демо-взгляд!
Всего, на момент запуска, будет представлено 5 модулей:
- 1 модуль - для начинающих;
- 2 модуль - для продолжающих;
- 3 модуль - низкоуровневые операции и прокси;
- 4 модуль - Foundry;
И будет добавлен 5 модуль, специально для тех, кто хочет научиться аудиты и поиску уязвимостей в смарт контрактах! Там уже собрана 71 задача из реальных проектов, в которых вам нужно будет найти баги. Это будет прекрасной тренировкой перед полноценными аудитами!
Кроме того, в 3 модуле будут обновлены и добавлены несколько уроков с учетом последних EIP в сети. А в Foundry войдут уроки с более сложными вариантами проведения тестов, в том числе - инвариант тестирование.
Все это будет в удобном формате с заданиями и материалами, которые можно скачать.
Также хочу отметить, что это будет полноценный самоучитель - т.е. проверка заданий и ежедневные ответы на вопросы не предусмотрены, как это было на курсах в группе. Тем не менее, вы все же сможете задавать свои вопросы в чате канала и получать ответы.
Сказать точную дату запуска пока не могу. Несмотря на достаточно быструю разработку сайта с помощью нейронок, мне самому нужно будет пересмотреть более 200 уроков и откорректировать их для платформы. Это займет очень много времени, и не думаю, что справлюсь до Нового года.
Работа кипит! Держу вас в курсе!
#solidity
Скоро заканчивается год, но не объемы работы! В данный момент я, как и обещал ранее, нахожусь в стадии разработки сайта, где будут собраны все уроки со всех модулей курса. И этот скрин - первый демо-взгляд!
Всего, на момент запуска, будет представлено 5 модулей:
- 1 модуль - для начинающих;
- 2 модуль - для продолжающих;
- 3 модуль - низкоуровневые операции и прокси;
- 4 модуль - Foundry;
И будет добавлен 5 модуль, специально для тех, кто хочет научиться аудиты и поиску уязвимостей в смарт контрактах! Там уже собрана 71 задача из реальных проектов, в которых вам нужно будет найти баги. Это будет прекрасной тренировкой перед полноценными аудитами!
Кроме того, в 3 модуле будут обновлены и добавлены несколько уроков с учетом последних EIP в сети. А в Foundry войдут уроки с более сложными вариантами проведения тестов, в том числе - инвариант тестирование.
Все это будет в удобном формате с заданиями и материалами, которые можно скачать.
Также хочу отметить, что это будет полноценный самоучитель - т.е. проверка заданий и ежедневные ответы на вопросы не предусмотрены, как это было на курсах в группе. Тем не менее, вы все же сможете задавать свои вопросы в чате канала и получать ответы.
Сказать точную дату запуска пока не могу. Несмотря на достаточно быструю разработку сайта с помощью нейронок, мне самому нужно будет пересмотреть более 200 уроков и откорректировать их для платформы. Это займет очень много времени, и не думаю, что справлюсь до Нового года.
Работа кипит! Держу вас в курсе!
#solidity
🔥30
Книга Mastering Ethereum: 2-е издание
Книга Mastering Ethereum — это один из тех редких ресурсов, которые действительно помогают понять, как работает Ethereum изнутри. Она не ограничивается базовыми примерами или быстрыми инструкциями, а показывает экосистему целиком: от структуры блоков до принципов работы смарт-контрактов. Благодаря этому книга остаётся полезной как новичкам, так и тем, кто уже давно пишет на Solidity.
Одним из самых сильных разделов является описание Ethereum Virtual Machine. Авторы доступно объясняют, что именно происходит при выполнении кода и почему контрактная логика работает так, как работает. Когда начинаешь понимать EVM, многие вещи в Solidity становятся понятнее, а ошибки — менее случайными.
Много внимания в книге уделено практической стороне разработки. Примеры контрактов разбираются подробно, объясняются типичные паттерны и моменты, на которые стоит обращать внимание с точки зрения безопасности. Это хороший способ получить крепкую основу, прежде чем погружаться в более сложные архитектуры или аудит.
Хотя некоторые инструменты и подходы с момента выхода книги изменились, её фундаментальная часть по-прежнему актуальна. Принципы устройства сети и логика протокола остаются такими же, поэтому материал продолжает быть надёжным источником знаний для разработчиков, инженеров и исследователей.
Особенно ценным является то, что весь текст доступен в открытом репозитории на GitHub. Это делает книгу живым ресурсом, который развивается вместе с сообществом. Можно читать главы онлайн, изучать примеры или даже предлагать правки.
Если вам хочется не просто писать смарт-контракты, а понимать, что происходит на уровне протокола, Mastering Ethereum — один из лучших путеводителей, который стоит добавить в свою библиотеку.
P.S. Для тех, кому сложно читать ее на английском, то нейронки помогут вам сделать очень качественный перевод.
#book
Книга Mastering Ethereum — это один из тех редких ресурсов, которые действительно помогают понять, как работает Ethereum изнутри. Она не ограничивается базовыми примерами или быстрыми инструкциями, а показывает экосистему целиком: от структуры блоков до принципов работы смарт-контрактов. Благодаря этому книга остаётся полезной как новичкам, так и тем, кто уже давно пишет на Solidity.
Одним из самых сильных разделов является описание Ethereum Virtual Machine. Авторы доступно объясняют, что именно происходит при выполнении кода и почему контрактная логика работает так, как работает. Когда начинаешь понимать EVM, многие вещи в Solidity становятся понятнее, а ошибки — менее случайными.
Много внимания в книге уделено практической стороне разработки. Примеры контрактов разбираются подробно, объясняются типичные паттерны и моменты, на которые стоит обращать внимание с точки зрения безопасности. Это хороший способ получить крепкую основу, прежде чем погружаться в более сложные архитектуры или аудит.
Хотя некоторые инструменты и подходы с момента выхода книги изменились, её фундаментальная часть по-прежнему актуальна. Принципы устройства сети и логика протокола остаются такими же, поэтому материал продолжает быть надёжным источником знаний для разработчиков, инженеров и исследователей.
Особенно ценным является то, что весь текст доступен в открытом репозитории на GitHub. Это делает книгу живым ресурсом, который развивается вместе с сообществом. Можно читать главы онлайн, изучать примеры или даже предлагать правки.
Если вам хочется не просто писать смарт-контракты, а понимать, что происходит на уровне протокола, Mastering Ethereum — один из лучших путеводителей, который стоит добавить в свою библиотеку.
P.S. Для тех, кому сложно читать ее на английском, то нейронки помогут вам сделать очень качественный перевод.
#book
👍20❤6
Про поиск работы в Web3
Я хотел бы еще раз поднять эту тему в преддверии Нового года, чтобы вы смогли правильно выстроить свою карьерную стратегию в 2026.
Много вопросов было и в чате, и в моих диалогах с восклицаниями, что сейчас трудно найти работу и новички никому не нужны. И в 99% ТАКИЕ новички действительно никому не нужны. Какие такие? Сейчас расскажу.
При первом же вопросе: "А что вы сделали, чтобы найти работу?", половина спрашивающих просто пропадает, еще половина говорит, что просматривали пару сайтов с вакансиями. И эти пара сайтов зачастую: Indeed, LinkedIn и еще пара тройка в первой выдаче гугла. И все. На этом весь поиск работы заканчивается.
Я уже долгое время твержу, что первую работу нужно "продавить" самому, в не ждать пока появится вакансия интерна, на которую кинутся сразу толпы со всего мира.
Для поиска работы нужно показать себя и свои знания. Не достаточно пройти курс обучения и создать свой токен в Ремиксе. Вероятно, это было ОК года 3-4 назад, но не сейчас.
Сейчас все строится на публичности, на том, сколько раз потенциальный работодатель сталкивался с вами в одном инфо пространстве.
Считайте, что нужно быть в трех сферах видимости: GitHub, Twitter/Blog, Public records.
Начнем с GitHub. Это то место, где молодой разработчик может показать свои знания и навыки. Если вы хотите получить работу, то у вас должно быть несколько публичных репо и "необычными проектами". Это могут быть не стандартные пути использования прокси, низкоуровневые паттерны, крутые тесты и т.д. Только ничего самого банального - типа токена ERC20, NFT, клона Unswap или Aave. Простая копипаста или базовый уровень видно сразу и никого не заинтересуют.
Спросите у нейронки, как сделать свой github профиль лучше и выделить его на фоне других. Тот же ChatGPT дает прекрасные советы.
Twitter/Blog вторая ступень. Достаточно пару раз в неделю вести свою страницу и делиться интересными постами (даже разбавляя их щитпостами), чтобы получить первую видимость. У вас может не быть подписчиков полгода или год, и это ок. Вы должны вести его не для себя, а для того, чтобы работодатель смог зайти на вашу страницу, посмотреть записи, узнать взаимных подписчиков и сложить а вас свое мнение.
Public records - публичные записи. Это любой контент, которых покажет, что вы "в теме". Для аудиторов это может быть результаты конкурсов или баг баунти, для разработчиков - участие в хакатонах, опенсорс проектах и т.д.
Все это работа в сообществе.
Без этого никто вас не будет искать. Даже если вы научитесь писать весь код на assembly, и проводить инвариант / fv тесты, то найти работу просто откликаясь на вакансии имеет крайне низкий шанс.
Если вы действительно хотите получить работу в web3, то параллельно с обучением развивайте эти три сферы. Тогда шансы на хорошую должность сильно возрастут.
#job
Я хотел бы еще раз поднять эту тему в преддверии Нового года, чтобы вы смогли правильно выстроить свою карьерную стратегию в 2026.
Много вопросов было и в чате, и в моих диалогах с восклицаниями, что сейчас трудно найти работу и новички никому не нужны. И в 99% ТАКИЕ новички действительно никому не нужны. Какие такие? Сейчас расскажу.
При первом же вопросе: "А что вы сделали, чтобы найти работу?", половина спрашивающих просто пропадает, еще половина говорит, что просматривали пару сайтов с вакансиями. И эти пара сайтов зачастую: Indeed, LinkedIn и еще пара тройка в первой выдаче гугла. И все. На этом весь поиск работы заканчивается.
Я уже долгое время твержу, что первую работу нужно "продавить" самому, в не ждать пока появится вакансия интерна, на которую кинутся сразу толпы со всего мира.
Для поиска работы нужно показать себя и свои знания. Не достаточно пройти курс обучения и создать свой токен в Ремиксе. Вероятно, это было ОК года 3-4 назад, но не сейчас.
Сейчас все строится на публичности, на том, сколько раз потенциальный работодатель сталкивался с вами в одном инфо пространстве.
Считайте, что нужно быть в трех сферах видимости: GitHub, Twitter/Blog, Public records.
Начнем с GitHub. Это то место, где молодой разработчик может показать свои знания и навыки. Если вы хотите получить работу, то у вас должно быть несколько публичных репо и "необычными проектами". Это могут быть не стандартные пути использования прокси, низкоуровневые паттерны, крутые тесты и т.д. Только ничего самого банального - типа токена ERC20, NFT, клона Unswap или Aave. Простая копипаста или базовый уровень видно сразу и никого не заинтересуют.
Спросите у нейронки, как сделать свой github профиль лучше и выделить его на фоне других. Тот же ChatGPT дает прекрасные советы.
Twitter/Blog вторая ступень. Достаточно пару раз в неделю вести свою страницу и делиться интересными постами (даже разбавляя их щитпостами), чтобы получить первую видимость. У вас может не быть подписчиков полгода или год, и это ок. Вы должны вести его не для себя, а для того, чтобы работодатель смог зайти на вашу страницу, посмотреть записи, узнать взаимных подписчиков и сложить а вас свое мнение.
Public records - публичные записи. Это любой контент, которых покажет, что вы "в теме". Для аудиторов это может быть результаты конкурсов или баг баунти, для разработчиков - участие в хакатонах, опенсорс проектах и т.д.
Все это работа в сообществе.
Без этого никто вас не будет искать. Даже если вы научитесь писать весь код на assembly, и проводить инвариант / fv тесты, то найти работу просто откликаясь на вакансии имеет крайне низкий шанс.
Если вы действительно хотите получить работу в web3, то параллельно с обучением развивайте эти три сферы. Тогда шансы на хорошую должность сильно возрастут.
#job
👍23❤8🔥3💯1
Передел на рынке аудита смарт контрактов
Несмотря на то, что аудиторы все также бьют себя в грудь и говорят, что ИИ их не заменит, на рынке аудита, на мой взгляд, идут значительные перемены. И виной тому не только нейросети.
На платформе CodeHawks, та которую запускала компания Патрика Колинса, создателя самого популярного англоязычного курса по Solidity, не было вообще никаких конкурсов с марта 2025 года. Другая платформа Hats Finance объявила о своем закрытии.
Да и общее количество конкурсных аудитов сильно сократилась, достаточно зайти на dailywarden, чтобы увидеть всего 4 проходящих в данных момент.
В компании Immunefi, крупнейшей площадке по баг баунти, также проходили недавно сокращения (по сообщениям в Твиттере. Тут не знаю, с чем все связано).
Площадки Code4rena и Шерлок обзавелись своими ИИ ботами для проверок смарт контрактов, вскоре к ним присоединится и Cantina. Другими словами, теперь вместе с конкурсами они будут прогонять своих клиентов через этих ботов и исключать найденные уязвимости из скоупа конкурса.
При всем при этом развиваются и сторонние программы, которые с помощью ИИ будут искать баги. Чуть ли не каждый месяц я сталкиваюсь с твитами-анонсами таких программ. Да я и сам буду готов в следующем месяце запустить бета-тесты своего mcp сервера...
Кроме того, разработчики за последнее время также научились пользоваться всеми доступными программами и проводить пре-аудит своих контрактов. Сайт Solodit - уже давно является тем местом, где разработчики изучают баги, которые встречались в проектах-аналогах.
"Золотой век" для аудиторов новичков и середнячков закончен. Уже нельзя заработать хорошие деньги на конкурсах с простыми багами, которые валидировались год-два назад. Сейчас будут зарабатывать только опытные аудиторы и белые хакеры, которые могут разбирать контракты на "атомы" и придумывать такие сценарии атак, которые еще не известны нейросетям.
Следующий год, возможно, станет годом резкого изменения условий для проведения аудита. Вместе с контрактами разработчики будут предоставлять отчет от ИИ программ о багах, которые они нашли и которые не должны быть включены в аудиторский отчет.
С удовольствием наблюдаю за происходящим!
#audit
Несмотря на то, что аудиторы все также бьют себя в грудь и говорят, что ИИ их не заменит, на рынке аудита, на мой взгляд, идут значительные перемены. И виной тому не только нейросети.
На платформе CodeHawks, та которую запускала компания Патрика Колинса, создателя самого популярного англоязычного курса по Solidity, не было вообще никаких конкурсов с марта 2025 года. Другая платформа Hats Finance объявила о своем закрытии.
Да и общее количество конкурсных аудитов сильно сократилась, достаточно зайти на dailywarden, чтобы увидеть всего 4 проходящих в данных момент.
В компании Immunefi, крупнейшей площадке по баг баунти, также проходили недавно сокращения (по сообщениям в Твиттере. Тут не знаю, с чем все связано).
Площадки Code4rena и Шерлок обзавелись своими ИИ ботами для проверок смарт контрактов, вскоре к ним присоединится и Cantina. Другими словами, теперь вместе с конкурсами они будут прогонять своих клиентов через этих ботов и исключать найденные уязвимости из скоупа конкурса.
При всем при этом развиваются и сторонние программы, которые с помощью ИИ будут искать баги. Чуть ли не каждый месяц я сталкиваюсь с твитами-анонсами таких программ. Да я и сам буду готов в следующем месяце запустить бета-тесты своего mcp сервера...
Кроме того, разработчики за последнее время также научились пользоваться всеми доступными программами и проводить пре-аудит своих контрактов. Сайт Solodit - уже давно является тем местом, где разработчики изучают баги, которые встречались в проектах-аналогах.
"Золотой век" для аудиторов новичков и середнячков закончен. Уже нельзя заработать хорошие деньги на конкурсах с простыми багами, которые валидировались год-два назад. Сейчас будут зарабатывать только опытные аудиторы и белые хакеры, которые могут разбирать контракты на "атомы" и придумывать такие сценарии атак, которые еще не известны нейросетям.
Следующий год, возможно, станет годом резкого изменения условий для проведения аудита. Вместе с контрактами разработчики будут предоставлять отчет от ИИ программ о багах, которые они нашли и которые не должны быть включены в аудиторский отчет.
С удовольствием наблюдаю за происходящим!
#audit
🤔6🔥3💯1
Как оформить свой профиль на GitHub?
Недавно я поставил себе задачу — создать визуально привлекательный и информативный профиль на GitHub: собрать ключевые проекты, структурированно описать опыт разработки, используемые технологии, а также контактную информацию. В качестве первого шага решил изучить вдохновляющие примеры уже существующих профилей.
Для тех, кто ещё не знаком с этой возможностью: профиль на GitHub представляет собой обычный репозиторий с названием, совпадающим с вашим никнеймом (например, username/username), содержащий единственный файл — README .md. Благодаря гибкости Markdown и креативному подходу, даже с помощью одного файла можно создать выразительную и профессионально оформленную витрину своих достижений.
Ниже — подборка профилей, которые показались мне наиболее интересными. Возможно, они послужат отправной точкой и для вас:
1. https://github.com/KenanGain
2. https://github.com/daria-stanilevici
3. https://github.com/Andrew6rant
4. https://github.com/thmsgbrt
5. https://github.com/ouuan
6. https://github.com/Shubhamsaboo
7. https://github.com/andyruwruw
8. https://github.com/DenverCoder1
9. https://github.com/MrStanDu33
10. https://github.com/0x3b33
Есть и более простые:
11. https://github.com/0xJuancito
12. https://github.com/Al-Qa-qa
P.S. Вы можете открывать их readme файлы и копировать интересующие вас блоки в свой файл.
А вы уже оформляли свой GitHub-профиль? Делитесь опытом — какие инструменты, подходы или решения вы использовали?
#github
Недавно я поставил себе задачу — создать визуально привлекательный и информативный профиль на GitHub: собрать ключевые проекты, структурированно описать опыт разработки, используемые технологии, а также контактную информацию. В качестве первого шага решил изучить вдохновляющие примеры уже существующих профилей.
Для тех, кто ещё не знаком с этой возможностью: профиль на GitHub представляет собой обычный репозиторий с названием, совпадающим с вашим никнеймом (например, username/username), содержащий единственный файл — README .md. Благодаря гибкости Markdown и креативному подходу, даже с помощью одного файла можно создать выразительную и профессионально оформленную витрину своих достижений.
Ниже — подборка профилей, которые показались мне наиболее интересными. Возможно, они послужат отправной точкой и для вас:
1. https://github.com/KenanGain
2. https://github.com/daria-stanilevici
3. https://github.com/Andrew6rant
4. https://github.com/thmsgbrt
5. https://github.com/ouuan
6. https://github.com/Shubhamsaboo
7. https://github.com/andyruwruw
8. https://github.com/DenverCoder1
9. https://github.com/MrStanDu33
10. https://github.com/0x3b33
Есть и более простые:
11. https://github.com/0xJuancito
12. https://github.com/Al-Qa-qa
P.S. Вы можете открывать их readme файлы и копировать интересующие вас блоки в свой файл.
А вы уже оформляли свой GitHub-профиль? Делитесь опытом — какие инструменты, подходы или решения вы использовали?
#github
🔥14
Solidity: версии 0.8.32 и 0.8.33
Вышли два обновления компилятора Solidity: версии 0.8.32 и 0.8.33. Это небольшие, но важные выпуски, которые исправляют несколько специфических проблем.
Первая версия, 0.8.32, исправляет редкую, но старую ошибку, связанную с работой с данными в блокчейн-хранилище. Она могла проявиться, только если разработчик намеренно создавал контракт с очень нестандартной и сложной структурой хранения данных, используя низкоуровневые инструменты. Для подавляющего большинства контрактов эта ошибка не была опасна.
Также в 0.8.32 починили удобную возможность: теперь можно корректно использовать модули для организации событий и ошибок. Раньше, если вы пытались вызвать событие Ev() из импортированного модуля M командой emit M.Ev(), компилятор выдавал внутреннюю ошибку. Теперь это работает, что делает код чище и лучше структурированным.
Однако, исправляя одну проблему, в 0.8.32 случайно добавили другую. В ней возникала ошибка компиляции, если в коде использовались автоматически созданные геттеры для константных переменных. Хотя это и не ломало уже работающие контракты, это мешало компилировать новый код с таким распространённым паттерном.
Поэтому практически сразу вышла версия 0.8.33 — это "горячее исправление" для только что описанной проблемы с геттерами. Разработчикам советуют сразу устанавливать версию 0.8.33, минуя 0.8.32, чтобы избежать ненужных сложностей с компиляцией.
Параллельно команда Solidity перенесла архив со всеми старыми версиями компилятора с серверов Amazon на Cloudflare. Для пользователей ничего не изменилось — файлы по-прежнему доступны по тому же адресу, но это помогает проекту снижать эксплуатационные расходы.
#solidity
Вышли два обновления компилятора Solidity: версии 0.8.32 и 0.8.33. Это небольшие, но важные выпуски, которые исправляют несколько специфических проблем.
Первая версия, 0.8.32, исправляет редкую, но старую ошибку, связанную с работой с данными в блокчейн-хранилище. Она могла проявиться, только если разработчик намеренно создавал контракт с очень нестандартной и сложной структурой хранения данных, используя низкоуровневые инструменты. Для подавляющего большинства контрактов эта ошибка не была опасна.
Также в 0.8.32 починили удобную возможность: теперь можно корректно использовать модули для организации событий и ошибок. Раньше, если вы пытались вызвать событие Ev() из импортированного модуля M командой emit M.Ev(), компилятор выдавал внутреннюю ошибку. Теперь это работает, что делает код чище и лучше структурированным.
Однако, исправляя одну проблему, в 0.8.32 случайно добавили другую. В ней возникала ошибка компиляции, если в коде использовались автоматически созданные геттеры для константных переменных. Хотя это и не ломало уже работающие контракты, это мешало компилировать новый код с таким распространённым паттерном.
Поэтому практически сразу вышла версия 0.8.33 — это "горячее исправление" для только что описанной проблемы с геттерами. Разработчикам советуют сразу устанавливать версию 0.8.33, минуя 0.8.32, чтобы избежать ненужных сложностей с компиляцией.
Параллельно команда Solidity перенесла архив со всеми старыми версиями компилятора с серверов Amazon на Cloudflare. Для пользователей ничего не изменилось — файлы по-прежнему доступны по тому же адресу, но это помогает проекту снижать эксплуатационные расходы.
#solidity
1👍8
Обучение аудитам с AI
Недавно, компания Патрика Колинса - Cyfrin, на своей платформе для конкурсных и обучающих аудитов запустила программу - AI First Flights, которая выглядит как очень логичный следующий шаг в их стремлении обучать пользователей и следовать мировым трендам. По сути, это практические аудиты, которые можно проходить в любое время и сразу получать разбор своих находок от AI, без ожидания дедлайнов и ручной проверки.
Почему это интересно именно сейчас? Рынок становится быстрее, конкуренция в аудитах растёт, а учиться на реальных кодовых базах нужно постоянно. Здесь вы берёте один из 10 аудитов разной сложности, анализируете код, оформляете репорт как в настоящем конкурсе и уже через несколько минут видите, где попали точно, что пропустили и как ваш уровень смотрится на фоне опытных аудиторов.
Это хорошо ложится в повседневную практику: можно разобрать аудит за вечер или выходные, не рискуя репутацией, но при этом работая в боевом формате. Мгновенная обратная связь сильно ускоряет прокачку паттернов и мышления, пока код ещё свеж в голове. Такое ощущение, что AI First Flights — это новый стандарт для регулярной практики и подготовки к реальным контестам, а не просто ещё один учебный продукт.
Если хотели "вкатиться" в аудиты с Нового года, то это прекрасная возможность начать без ожидания судейства и окончательных результатов.
Попробовать свои силы можно тут.
#audits
Недавно, компания Патрика Колинса - Cyfrin, на своей платформе для конкурсных и обучающих аудитов запустила программу - AI First Flights, которая выглядит как очень логичный следующий шаг в их стремлении обучать пользователей и следовать мировым трендам. По сути, это практические аудиты, которые можно проходить в любое время и сразу получать разбор своих находок от AI, без ожидания дедлайнов и ручной проверки.
Почему это интересно именно сейчас? Рынок становится быстрее, конкуренция в аудитах растёт, а учиться на реальных кодовых базах нужно постоянно. Здесь вы берёте один из 10 аудитов разной сложности, анализируете код, оформляете репорт как в настоящем конкурсе и уже через несколько минут видите, где попали точно, что пропустили и как ваш уровень смотрится на фоне опытных аудиторов.
Это хорошо ложится в повседневную практику: можно разобрать аудит за вечер или выходные, не рискуя репутацией, но при этом работая в боевом формате. Мгновенная обратная связь сильно ускоряет прокачку паттернов и мышления, пока код ещё свеж в голове. Такое ощущение, что AI First Flights — это новый стандарт для регулярной практики и подготовки к реальным контестам, а не просто ещё один учебный продукт.
Если хотели "вкатиться" в аудиты с Нового года, то это прекрасная возможность начать без ожидания судейства и окончательных результатов.
Попробовать свои силы можно тут.
#audits
🔥10
Последний пост этого года
Хочу подвести итоги этого года и зафиксировать его как рабочий, плотный и во многом переломный. Год начался с активного участия в аудит-конкурсах и bug bounty, где было много репортов, почти ноль выплат и полезный опыт трезвого взгляда на реальность аудита. Параллельно я системно развивал каналы, писал уроки, наполнял AuditProfile протоколами и задачами, пробовал разные форматы контента и обучения, не все из которых оказались удачными. Уже в первые месяцы стало понятно, что фокус постепенно смещается от точечных конкурсов к созданию собственных инструментов, курсов и инфраструктуры.
Весной и летом основное внимание ушло в образовательные проекты и эксперименты с автоматизацией анализа. Был полностью собран и проведён курс, проданы модули, переработаны десятки уроков, заданий и практикумов. Параллельно я глубоко ушёл в анализ аудиторских отчётов, обработку PDF, чанков уязвимостей, OCR, embedding-пайплайны и первые серьёзные попытки построить системы, которые реально помогают работать с большим объёмом знаний. Именно в этот период появилось понимание ограничений локальных моделей, иллюзий вокруг «быстрого ИИ» и необходимости аккуратной инженерии вместо магического мышления.
Вторая половина года прошла под знаком ML, RAG, статистики и собственных проектов. LazyAuditor, SoliditySet, эксперименты с обучением моделей, нормализация десятков тысяч уязвимостей, сбор датасетов, API, серверы, векторные базы — всё это делалось медленно, часто без внешней отдачи, но с чётким ощущением, что закладывается фундамент. Параллельно я много читал, доучивал математику и теорию вероятностей, осознанно отказывался от направлений, которые не давали результата, и перестраивал приоритеты.
Отдельно отмечу, что год был не только про работу. Были отпуска, дом, стройка, бытовые задачи, которые неожиданно хорошо балансировали голову и напоминали, что мир не ограничивается Solidity и багами. По каналам где-то был рост, где-то стагнация или откат, и это тоже нормальное отражение реального, а не маркетингового процесса.
В итоге этот год — про накопление. Про большое количество сделанной, но не всегда публичной работы. Про ошибки, переоценки и постепенное прояснение того, что действительно имеет смысл. Спасибо всем, кто читает, задаёт вопросы, критикует и остаётся здесь не ради хайпа, а ради понимания. В следующем году хочется меньше суеты, больше фокуса и довести начатое до состояния, за которое не стыдно.
Поздравляю вас с наступающим Новым годом. Желаю спокойной головы, интересных задач и устойчивого прогресса в том, чем вы занимаетесь. Немного выдыхаем, а к рабочему режиму возвращаемся с 12 января.
#summary
Хочу подвести итоги этого года и зафиксировать его как рабочий, плотный и во многом переломный. Год начался с активного участия в аудит-конкурсах и bug bounty, где было много репортов, почти ноль выплат и полезный опыт трезвого взгляда на реальность аудита. Параллельно я системно развивал каналы, писал уроки, наполнял AuditProfile протоколами и задачами, пробовал разные форматы контента и обучения, не все из которых оказались удачными. Уже в первые месяцы стало понятно, что фокус постепенно смещается от точечных конкурсов к созданию собственных инструментов, курсов и инфраструктуры.
Весной и летом основное внимание ушло в образовательные проекты и эксперименты с автоматизацией анализа. Был полностью собран и проведён курс, проданы модули, переработаны десятки уроков, заданий и практикумов. Параллельно я глубоко ушёл в анализ аудиторских отчётов, обработку PDF, чанков уязвимостей, OCR, embedding-пайплайны и первые серьёзные попытки построить системы, которые реально помогают работать с большим объёмом знаний. Именно в этот период появилось понимание ограничений локальных моделей, иллюзий вокруг «быстрого ИИ» и необходимости аккуратной инженерии вместо магического мышления.
Вторая половина года прошла под знаком ML, RAG, статистики и собственных проектов. LazyAuditor, SoliditySet, эксперименты с обучением моделей, нормализация десятков тысяч уязвимостей, сбор датасетов, API, серверы, векторные базы — всё это делалось медленно, часто без внешней отдачи, но с чётким ощущением, что закладывается фундамент. Параллельно я много читал, доучивал математику и теорию вероятностей, осознанно отказывался от направлений, которые не давали результата, и перестраивал приоритеты.
Отдельно отмечу, что год был не только про работу. Были отпуска, дом, стройка, бытовые задачи, которые неожиданно хорошо балансировали голову и напоминали, что мир не ограничивается Solidity и багами. По каналам где-то был рост, где-то стагнация или откат, и это тоже нормальное отражение реального, а не маркетингового процесса.
В итоге этот год — про накопление. Про большое количество сделанной, но не всегда публичной работы. Про ошибки, переоценки и постепенное прояснение того, что действительно имеет смысл. Спасибо всем, кто читает, задаёт вопросы, критикует и остаётся здесь не ради хайпа, а ради понимания. В следующем году хочется меньше суеты, больше фокуса и довести начатое до состояния, за которое не стыдно.
Поздравляю вас с наступающим Новым годом. Желаю спокойной головы, интересных задач и устойчивого прогресса в том, чем вы занимаетесь. Немного выдыхаем, а к рабочему режиму возвращаемся с 12 января.
#summary
🎉18❤5🔥4
Первый пост 2026 и ближайшие планы
Слишком быстро прошли все выходные дни и пора возвращаться к работе. А ведь я только перестал каждый день думать о работе, проектах, коде и т.д.
Чем вообще мы будем заниматься в ближайшее время?
Это был самый сложный вопрос в профессиональном плане. Хочется оставаться в рамках web3, но и развиваться в сфере AI. Кроме того, нельзя игнорировать все более нарастающие тренды вайбкодинга (мне и самому очень нравятся идеи быстрого тестирования гипотез/проектов на рынке). Вместе с этим, работа над своими собственными проектами подсветила проблемные зоны и недостаток знаний в некоторых областях полного цикла разработки приложений. Поэтому я хочу посвятить следующие пару месяцев вот чему:
1. Изучение, повторение и анализ различных алгоритмов в программировании: начиная с сfмых простых (например, сортировка данных) и заканчивая теми, что используются в разработки ИИ систем.
2. Изучение современных способов разработки фронтенда и бекенда приложений, а также их деплоя на сервер - работа с API, безопасность, JWT и т.д.
3. Изучение современных архитектур построения высоконагруженных приложений.
4. Изучение новых протоколов в web3 и нововведений в Solidity.
Почему именно так и в таком порядке?
Вообще в web3 можно было взять немного другие направления работы: изучение zk, тестов формальной верификации и, в конечном итоге, взяться за rust. Но это уже будет либо узкая специализация (в первых двух вариантах) или переход в альтернативную сферу (в случае с rust). Однако я, пока что, не вижу явных причин двигаться в эти сферы.
Сейчас актуальнее будет получить навыки "разумного вайбкодинга", когда ты понимаешь, как все устроено, что нужно сделать и, главное, как четко дать команду нейронке на выполнение задания. Кроме того, при разработке web3 приложений вы, скорее всего, так или иначе столкнетесь с проблемой создания полноценного сайта или приложения, и загрузки его на сервер вместе с загрузкой контрактов в блокчейн.
В итоге для "разумного вайбкодинга" нам потребуется целая область знаний, начиная с Solidity, заканчивая Python, JS, архитектурой и алгоритмами.
Последние, алгоритмы, будут актуальны практически в любом языке, и понимая их вы сможете лучше разбираться с написанным нейронкой кодом и направлять ее в нужном русле. Поэтому мы начнем с них.
Разбор систем и протоколов на Solidity будет происходить по мере того, как я буду встречать новую информацию, которой еще не было на канале.
Всех с началом нового рабочего года и ярких свершений!
#offtop
Слишком быстро прошли все выходные дни и пора возвращаться к работе. А ведь я только перестал каждый день думать о работе, проектах, коде и т.д.
Чем вообще мы будем заниматься в ближайшее время?
Это был самый сложный вопрос в профессиональном плане. Хочется оставаться в рамках web3, но и развиваться в сфере AI. Кроме того, нельзя игнорировать все более нарастающие тренды вайбкодинга (мне и самому очень нравятся идеи быстрого тестирования гипотез/проектов на рынке). Вместе с этим, работа над своими собственными проектами подсветила проблемные зоны и недостаток знаний в некоторых областях полного цикла разработки приложений. Поэтому я хочу посвятить следующие пару месяцев вот чему:
1. Изучение, повторение и анализ различных алгоритмов в программировании: начиная с сfмых простых (например, сортировка данных) и заканчивая теми, что используются в разработки ИИ систем.
2. Изучение современных способов разработки фронтенда и бекенда приложений, а также их деплоя на сервер - работа с API, безопасность, JWT и т.д.
3. Изучение современных архитектур построения высоконагруженных приложений.
4. Изучение новых протоколов в web3 и нововведений в Solidity.
Почему именно так и в таком порядке?
Вообще в web3 можно было взять немного другие направления работы: изучение zk, тестов формальной верификации и, в конечном итоге, взяться за rust. Но это уже будет либо узкая специализация (в первых двух вариантах) или переход в альтернативную сферу (в случае с rust). Однако я, пока что, не вижу явных причин двигаться в эти сферы.
Сейчас актуальнее будет получить навыки "разумного вайбкодинга", когда ты понимаешь, как все устроено, что нужно сделать и, главное, как четко дать команду нейронке на выполнение задания. Кроме того, при разработке web3 приложений вы, скорее всего, так или иначе столкнетесь с проблемой создания полноценного сайта или приложения, и загрузки его на сервер вместе с загрузкой контрактов в блокчейн.
В итоге для "разумного вайбкодинга" нам потребуется целая область знаний, начиная с Solidity, заканчивая Python, JS, архитектурой и алгоритмами.
Последние, алгоритмы, будут актуальны практически в любом языке, и понимая их вы сможете лучше разбираться с написанным нейронкой кодом и направлять ее в нужном русле. Поэтому мы начнем с них.
Разбор систем и протоколов на Solidity будет происходить по мере того, как я буду встречать новую информацию, которой еще не было на канале.
Всех с началом нового рабочего года и ярких свершений!
#offtop
4👍13🔥3
Алгоритмы. Big O.
Потихоньку начинаем разбирать алгоритмы в программировании, как я и писал ранее. Начнем с самых базовых для повторения и перейдем к более сложным и продвинутым. Я буду давать код алгоритмов на языке Python, так как более продвинутые решения удобнее писать именно на нем. На Solidity не все из них можно будет реализовать "без костылей", но вы сами вполне сможете поэкспериментировать с этим с помощью нейронок.
Понимание алгоритмов также качественно скажется на вашем понимании кода, который вы, возможно, будете писать с помощью редакторов со встроенными нейронными сетями, например Cursor. Итак, приступим!
Введение в алгоритмы и асимптотический (по сути означает "для больших значений") анализ начинается с понимания самой сути алгоритма. Алгоритм представляет собой последовательность четко определенных шагов для решения конкретной задачи, подобно кулинарному рецепту или инструкции по сборке. Например, алгоритм приготовления бутерброда можно описать так: взять два ломтика хлеба, намазать один из них маслом, положить сверху сыр и накрыть вторым ломтиком. Важно, что любой алгоритм предполагает некий набор инструкций, выполнение которых гарантированно приводит к результату.
Однако существует множество способов решить одну и ту же задачу. Рассмотрим процесс поиска нужного документа в архиве. Если документы не упорядочены, придется проверить каждый из них по очереди. Если же они систематизированы, например, в алфавитном порядке, поиск можно осуществить гораздо быстрее, применяя более эффективную стратегию. Эти разные стратегии и являются разными алгоритмами, и их эффективность становится критически важной при работе с большими объемами данных.
Скорость работы алгоритма напрямую зависит от количества обрабатываемых данных. Если в небольшом архиве из десяти дел поиск наугад займет всего несколько секунд, то в хранилище с миллионом документов такой подход потребует непозволительно много времени. Поэтому для оценки эффективности алгоритма используется понятие временной сложности, которая показывает, как количество необходимых операций растет с увеличением размера входных данных. Например, для поиска числа 9 в списке
Для универсального описания скорости алгоритмов используется О-нотация (Big O). Она позволяет классифицировать алгоритмы по их «аппетиту» к ресурсам, предоставляя асимптотическую оценку роста времени выполнения или потребляемой памяти. Основные классы сложности, от наиболее к наименее эффективным, выглядят следующим образом.
1. O(1) — постоянная сложность. Время выполнения не зависит от объема данных.
Операция получения первого символа строки всегда выполняется за одно действие, будь то имя «Аня» или «Александр».
2. O(n) — линейная сложность. Время выполнения растет прямо пропорционально размеру входных данных.
Это иллюстрирует простой линейный поиск, где в худшем случае необходимо проверить каждый элемент.
3. O(n²) — квадратичная сложность. Время выполнения пропорционально квадрату количества элементов, что характерно для алгоритмов с вложенными циклами.
Для массива из пяти элементов будет выполнено 25 итераций, а для тысячи — уже миллион.
4. O(log n) — логарифмическая сложность. Очень эффективный класс, где на каждом шаге объем обрабатываемых данных уменьшается вдвое. Яркий пример — бинарный поиск в отсортированном массиве.
Потихоньку начинаем разбирать алгоритмы в программировании, как я и писал ранее. Начнем с самых базовых для повторения и перейдем к более сложным и продвинутым. Я буду давать код алгоритмов на языке Python, так как более продвинутые решения удобнее писать именно на нем. На Solidity не все из них можно будет реализовать "без костылей", но вы сами вполне сможете поэкспериментировать с этим с помощью нейронок.
Понимание алгоритмов также качественно скажется на вашем понимании кода, который вы, возможно, будете писать с помощью редакторов со встроенными нейронными сетями, например Cursor. Итак, приступим!
Введение в алгоритмы и асимптотический (по сути означает "для больших значений") анализ начинается с понимания самой сути алгоритма. Алгоритм представляет собой последовательность четко определенных шагов для решения конкретной задачи, подобно кулинарному рецепту или инструкции по сборке. Например, алгоритм приготовления бутерброда можно описать так: взять два ломтика хлеба, намазать один из них маслом, положить сверху сыр и накрыть вторым ломтиком. Важно, что любой алгоритм предполагает некий набор инструкций, выполнение которых гарантированно приводит к результату.
Однако существует множество способов решить одну и ту же задачу. Рассмотрим процесс поиска нужного документа в архиве. Если документы не упорядочены, придется проверить каждый из них по очереди. Если же они систематизированы, например, в алфавитном порядке, поиск можно осуществить гораздо быстрее, применяя более эффективную стратегию. Эти разные стратегии и являются разными алгоритмами, и их эффективность становится критически важной при работе с большими объемами данных.
Скорость работы алгоритма напрямую зависит от количества обрабатываемых данных. Если в небольшом архиве из десяти дел поиск наугад займет всего несколько секунд, то в хранилище с миллионом документов такой подход потребует непозволительно много времени. Поэтому для оценки эффективности алгоритма используется понятие временной сложности, которая показывает, как количество необходимых операций растет с увеличением размера входных данных. Например, для поиска числа 9 в списке
[3, 7, 1, 9, 5] методом последовательного перебора потребовалось четыре шага. Для списка из ста элементов в худшем случае потребуется сто операций. Эта прямая зависимость описывается линейной сложностью.Для универсального описания скорости алгоритмов используется О-нотация (Big O). Она позволяет классифицировать алгоритмы по их «аппетиту» к ресурсам, предоставляя асимптотическую оценку роста времени выполнения или потребляемой памяти. Основные классы сложности, от наиболее к наименее эффективным, выглядят следующим образом.
1. O(1) — постоянная сложность. Время выполнения не зависит от объема данных.
def get_first_letter(name):
return name[0]
Операция получения первого символа строки всегда выполняется за одно действие, будь то имя «Аня» или «Александр».
2. O(n) — линейная сложность. Время выполнения растет прямо пропорционально размеру входных данных.
def find_element(arr, target):
steps = 0
for item in arr:
steps += 1
if item == target:
return True
return False
Это иллюстрирует простой линейный поиск, где в худшем случае необходимо проверить каждый элемент.
3. O(n²) — квадратичная сложность. Время выполнения пропорционально квадрату количества элементов, что характерно для алгоритмов с вложенными циклами.
def find_all_pairs(arr):
pairs = []
for i in arr:
for j in arr:
pairs.append((i, j))
return pairs
Для массива из пяти элементов будет выполнено 25 итераций, а для тысячи — уже миллион.
4. O(log n) — логарифмическая сложность. Очень эффективный класс, где на каждом шаге объем обрабатываемых данных уменьшается вдвое. Яркий пример — бинарный поиск в отсортированном массиве.
def binary_search(sorted_arr, target):
left, right = 0, len(sorted_arr) - 1
steps = 0
while left <= right:
steps += 1
mid = (left + right) // 2
if sorted_arr[mid] == target:
return mid
elif sorted_arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Поиск среди 16 отсортированных элементов займет не более 4 шагов.
Помимо временной, важна и пространственная сложность, которая оценивает объем дополнительной памяти, требуемой алгоритмом. Например, алгоритм нахождения максимума в массиве использует фиксированный объем памяти O(1), тогда как создание полной копии списка потребует памяти O(n).
Практическое значение асимптотического анализа становится очевидным при сравнении алгоритмов. Рассмотрим задачу поиска дубликатов. Наивный подход с двойным циклом имеет сложность O(n²):
def find_duplicates_slow(arr):
duplicates = []
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
if arr[i] == arr[j] and arr[i] not in duplicates:
duplicates.append(arr[i])
return duplicates
Более разумный подход с использованием хэш-множества имеет сложность O(n):
def find_duplicates_fast(arr):
seen = set()
duplicates = set()
for item in arr:
if item in seen:
duplicates.add(item)
else:
seen.add(item)
return list(duplicates)
На списке из тысячи элементов второй алгоритм окажется в сотни раз быстрее первого.
Для наглядности можно представить себе сводную таблицу сложностей. O(1) обозначает мгновенное выполнение, например доступ к элементу массива по индексу. O(log n) характерна для алгоритмов типа бинарного поиска. O(n) — для линейного прохода по данным. O(n log n) — это типичная сложность эффективных алгоритмов сортировки. O(n²) часто возникает при обработке матриц или использовании вложенных циклов. O(2ⁿ) — экстремально медленная сложность, присущая некоторым задачам полного перебора.
Понимание этих принципов позволяет делать осознанный выбор алгоритма, что является фундаментальным навыком в разработке эффективных программ.
#algorithm
👍9
Алгоритмы. Рекурсия
По предыдущему посту я понял, чтобы объяснить более менее детально какую-либо тему, приходится расписывать все куда детальнее, чем во многих гайдах и обзорах. Поэтому посты по алгоритмам будут большие, но оно того стоит. Сегодня мы поговорим о рекурсии простым языком.
Понятие рекурсии можно представить как образ из мира зеркал: когда одно зеркало отражается в другом, и это отражение, в свою очередь, находит своё отражение, создавая уходящую в бесконечность череду образов. В программировании рекурсия действует схожим образом — это техника, при которой функция для решения задачи вызывает сама себя. Хотя идея может показаться необычной, при правильном применении она становится мощным и элегантным инструментом.
Для корректной работы любой рекурсивной функции необходимы два фундаментальных компонента. Во-первых, это базовый случай — условие остановки, которое предотвращает бесконечный цикл вызовов. Его можно сравнить с последней ступенькой лестницы: достигнув её, вы прекращаете движение. Во-вторых, требуется рекурсивный шаг — вызов функцией самой себя, но с изменёнными входными данными, которые должны гарантированно приближать выполнение к базовому случаю. Это подобно каждому следующему шагу вниз по лестнице, который сокращает оставшееся до низа расстояние.
Рассмотрим простейшую иллюстрацию — функцию обратного отсчёта от заданного числа до единицы. Её логика наглядно демонстрирует оба принципа.
Вывод этой программы будет последовательным:
Внутри этого процесса происходит следующее: вызов
Классическим примером, раскрывающим суть рекурсивного мышления, является вычисление факториала числа n, обозначаемого как n!. По определению, факториал — это произведение всех натуральных чисел от 1 до n, при этом 0! и 1! равны 1 (вообще не так чтобы равны, просто принято такое равенство для удобства расчетов). Ключевое наблюдение здесь — рекурсивная природа операции: факториал любого числа n можно выразить через факториал меньшего числа, а именно n! = n * (n-1)!. Это и становится основой для алгоритма.
Пошаговое выполнение функции для
Эта же логика применима ко множеству других задач. Например, для вычисления суммы всех чисел от 1 до n.
Аналогично работает возведение числа в натуральную степень.
По предыдущему посту я понял, чтобы объяснить более менее детально какую-либо тему, приходится расписывать все куда детальнее, чем во многих гайдах и обзорах. Поэтому посты по алгоритмам будут большие, но оно того стоит. Сегодня мы поговорим о рекурсии простым языком.
Понятие рекурсии можно представить как образ из мира зеркал: когда одно зеркало отражается в другом, и это отражение, в свою очередь, находит своё отражение, создавая уходящую в бесконечность череду образов. В программировании рекурсия действует схожим образом — это техника, при которой функция для решения задачи вызывает сама себя. Хотя идея может показаться необычной, при правильном применении она становится мощным и элегантным инструментом.
Для корректной работы любой рекурсивной функции необходимы два фундаментальных компонента. Во-первых, это базовый случай — условие остановки, которое предотвращает бесконечный цикл вызовов. Его можно сравнить с последней ступенькой лестницы: достигнув её, вы прекращаете движение. Во-вторых, требуется рекурсивный шаг — вызов функцией самой себя, но с изменёнными входными данными, которые должны гарантированно приближать выполнение к базовому случаю. Это подобно каждому следующему шагу вниз по лестнице, который сокращает оставшееся до низа расстояние.
Рассмотрим простейшую иллюстрацию — функцию обратного отсчёта от заданного числа до единицы. Её логика наглядно демонстрирует оба принципа.
def count_down(n):
# Базовый случай: когда достигли 0, останавливаемся
if n == 0:
print("Готово!")
return
# Выводим текущее число
print(n)
# Рекурсивный шаг: вызываем функцию с n-1
count_down(n - 1)
count_down(5)
Вывод этой программы будет последовательным:
5
4
3
2
1
Готово!
Внутри этого процесса происходит следующее: вызов
count_down(5) приводит к выводу числа 5 и новому вызову count_down(4). Этот процесс вкладывается, подобно матрёшкам, пока вызов count_down(0) не достигнет базового случая, выведет "Готово!" и не начнёт возвращать управление обратно по цепочке предыдущих вызовов.Классическим примером, раскрывающим суть рекурсивного мышления, является вычисление факториала числа n, обозначаемого как n!. По определению, факториал — это произведение всех натуральных чисел от 1 до n, при этом 0! и 1! равны 1 (вообще не так чтобы равны, просто принято такое равенство для удобства расчетов). Ключевое наблюдение здесь — рекурсивная природа операции: факториал любого числа n можно выразить через факториал меньшего числа, а именно n! = n * (n-1)!. Это и становится основой для алгоритма.
def factorial(n):
# Базовый случай
if n == 0 or n == 1:
return 1
# Рекурсивный шаг
return n * factorial(n - 1)
print(factorial(5)) # 120
# Для значения 3
factorial(3)
│
├─ factorial(2) ← добавляется в стек
│ │
│ ├─ factorial(1) ← добавляется в стек
│ │ └─ возвращает 1 ← снимается со стека
│ │
│ └─ возвращает 2 ← снимается со стека
│
└─ возвращает 6 ← снимается со стека
# Стек вызовов для factorial(3):
Шаг 1: [factorial(3)]
Шаг 2: [factorial(3), factorial(2)]
Шаг 3: [factorial(3), factorial(2), factorial(1)]
Шаг 4: [factorial(3), factorial(2)] ← factorial(1) вернул результат
Шаг 5: [factorial(3)] ← factorial(2) вернул результат
Шаг 6: [] ← factorial(3) вернул результат
Пошаговое выполнение функции для
factorial(5) раскладывается в цепочку отложенных умножений: 5 * factorial(4), затем 5 * (4 * factorial(3)), и так далее, пока вычисление не дойдёт до базового случая factorial(1), который возвращает 1. После этого цепочка начинает сворачиваться, производя последовательные умножения: 2 * 1 = 2, 3 * 2 = 6, 4 * 6 = 24 и, наконец, 5 * 24 = 120.Эта же логика применима ко множеству других задач. Например, для вычисления суммы всех чисел от 1 до n.
def sum_numbers(n):
# Базовый случай
if n == 0:
return 0
# Рекурсивный шаг
return n + sum_numbers(n - 1)
print(sum_numbers(5)) # 15 (5+4+3+2+1)
Аналогично работает возведение числа в натуральную степень.