[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-10-upravlenie-stekom-huff-dup-swap":3},{"article":4,"author":55},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":35,"related_articles":36},"d0000000-0000-0000-0000-000000000210","a0000000-0000-0000-0000-000000000012","Deep EVM #10: Управление стеком в Huff — takes(), returns() и искусство dup\u002Fswap","deep-evm-10-upravlenie-stekom-huff-dup-swap","Освойте стековую машину EVM: визуализация состояния стека, эффективное использование dup1-16 и swap1-16, паттерны сохранения значений, ротации и очистки.","## Ментальная модель стековой машины\n\nEVM — стековая машина. Нет регистров, нет именованных переменных — только стек LIFO из 32-байтных слов, глубиной 1024 слота. Каждый опкод либо кладёт, либо снимает, либо переупорядочивает элементы на этом стеке. Если вы не можете удержать текущее состояние стека в голове — вы напишете ошибочный байткод. Эта статья посвящена построению такой ментальной модели.\n\n### Нотация\n\nВ этой статье (и в комментариях Huff) мы представляем состояние стека в квадратных скобках, где левый элемент — вершина:\n\n```\n\u002F\u002F [top, second, third, ..., bottom]\n0x01  \u002F\u002F [1]\n0x02  \u002F\u002F [2, 1]\nadd   \u002F\u002F [3]\n```\n\nКаждый макрос Huff должен иметь стековый комментарий после каждого опкода. Это не опционально — это единственный способ аудита корректности.\n\n## DUP: дублирование элементов стека\n\nEVM предоставляет `DUP1` — `DUP16`. `DUPn` копирует n-й элемент от вершины и кладёт его на стек. Стек растёт на 1.\n\n```huff\n\u002F\u002F Stack: [a, b, c, d]\ndup1   \u002F\u002F [a, a, b, c, d]       — копия вершины\ndup3   \u002F\u002F [c, a, a, b, c, d]    — копия 3-го от вершины\n```\n\nСтоимость газа: 3 газа для любого DUPn. Одна из самых дешёвых операций в EVM.\n\n### Когда использовать DUP\n\nDUP — инструмент для **неразрушающего чтения**. Многие опкоды потребляют аргументы (ADD снимает два, кладёт один), поэтому если значение понадобится позже — дублируйте его перед подачей в потребляющий опкод.\n\n```huff\n#define macro SAFE_SUB() = takes(2) returns(1) {\n    \u002F\u002F takes: [a, b] — вычислить a - b, revert если b > a\n    dup2 dup2       \u002F\u002F [a, b, a, b]\n    lt              \u002F\u002F [a \u003C b?, a, b]\n    revert_underflow jumpi  \u002F\u002F [a, b]\n    sub             \u002F\u002F [a - b]\n    done jump\n    revert_underflow:\n        0x00 0x00 revert\n    done:\n}\n```\n\nОбратите внимание на `dup2 dup2` — мы дублируем и `a`, и `b`, потому что `lt` их потребит, а оригиналы нужны для `sub`.\n\n## SWAP: перестановка элементов стека\n\nEVM предоставляет `SWAP1` — `SWAP16`. `SWAPn` меняет местами вершину с (n+1)-м элементом. Размер стека не меняется.\n\n```huff\n\u002F\u002F Stack: [a, b, c, d]\nswap1  \u002F\u002F [b, a, c, d]          — обмен вершины и 2-го\nswap3  \u002F\u002F [d, a, c, b]          — обмен вершины и 4-го\n```\n\nСтоимость: 3 газа для любого SWAPn.\n\n### Когда использовать SWAP\n\nSWAP переупорядочивает аргументы для опкодов, ожидающих определённый порядок. Например, `SUB` вычисляет `stack[0] - stack[1]`. Если значения в неправильном порядке:\n\n```huff\n\u002F\u002F Stack: [b, a]  — но нам нужно a - b\nswap1   \u002F\u002F [a, b]\nsub     \u002F\u002F [a - b]\n```\n\n## Ограничение глубины 16\n\nDUP и SWAP достигают только 16 уровней вглубь. Если значение на позиции 17 и глубже, его невозможно получить одним опкодом. Это жёсткое ограничение EVM.\n\n**Стратегии для глубоких стеков:**\n\n1. **Реструктуризация логики** — держите нужные значения ближе к вершине.\n2. **Использование памяти как scratch space.** Сохраните значение через `MSTORE`, получите позже через `MLOAD`. Стоит 3+3=6 газа вместо 3 для DUP, зато снимает ограничение глубины.\n3. **Разбиение макроса на меньшие макросы**, каждый из которых работает с меньшим числом стековых элементов.\n\n```huff\n#define macro STASH_TO_MEMORY() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    0x80 mstore     \u002F\u002F []  — сохраняем в 0x80 (scratch space)\n}\n\n#define macro RECALL_FROM_MEMORY() = takes(0) returns(1) {\n    0x80 mload      \u002F\u002F [value]\n}\n```\n\nВ MEV-контрактах мы часто резервируем `0x80..0xc0` как scratch-область для значений, которые иначе вытолкнули бы стек за предел 16.\n\n## Общие паттерны\n\n### Паттерн 1: сохранение значения через потребляющую операцию\n\nУ вас `[x]`, и нужно вызвать опкод, потребляющий `x`, но `x` ещё понадобится.\n\n```huff\n\u002F\u002F Хотим: вычислить хеш x, но сохранить x\n\u002F\u002F Stack: [x]\ndup1        \u002F\u002F [x, x]\n0x00 mstore \u002F\u002F [x]  — memory[0] = x\n0x20 0x00   \u002F\u002F [0, 32, x]\nkeccak256   \u002F\u002F [hash, x]\n```\n\n### Паттерн 2: ротация трёх элементов\n\nИмеем `[a, b, c]`, нужно `[c, a, b]`:\n\n```huff\nswap2       \u002F\u002F [c, b, a]\nswap1       \u002F\u002F [c, a, b]\n```\n\n2 опкода, 6 газа. В EVM нет ротации одним опкодом.\n\nИмеем `[a, b, c]`, нужно `[b, c, a]`:\n\n```huff\nswap1       \u002F\u002F [b, a, c]\nswap2       \u002F\u002F [b, c, a]\n```\n\n### Паттерн 3: очистка ненужных элементов стека\n\nПосле вычисления могут остаться лишние элементы. Используйте `pop` (2 газа):\n\n```huff\n\u002F\u002F Stack: [result, garbage1, garbage2]\nswap1 pop   \u002F\u002F [result, garbage2]\nswap1 pop   \u002F\u002F [result]\n```\n\n### Паттерн 4: дублирование пары\n\nНужно скопировать два верхних элемента:\n\n```huff\n\u002F\u002F Stack: [a, b]\ndup2        \u002F\u002F [b, a, b]\ndup2        \u002F\u002F [a, b, a, b]\n```\n\nОбратите внимание — DUP в обратном порядке. `dup2` сначала копирует `b` (позиция 2), затем `dup2` копирует `a` (теперь на позиции 2, так как стек вырос). Этот паттерн постоянно встречается в коде сравнения-перед-арифметикой.\n\n## Дисциплина визуализации стека\n\nПри написании Huff придерживайтесь дисциплины:\n\n1. **Комментируйте каждую строку** состоянием стека после исполнения.\n2. **Проверяйте takes\u002Freturns** — считайте элементы стека на входе и выходе.\n3. **Трассируйте каждую ветку** — при каждом JUMPI обе ветви (переход и проход) должны оставлять стек в валидном состоянии.\n4. **Следите за дрейфом стека** — если тело цикла не балансирует push\u002Fpop, стек будет расти или уменьшаться на каждой итерации.\n\n## Отладка стековых ошибок\n\nСамые частые баги в Huff:\n\n1. **Stack underflow** — pop из пустого стека. EVM ревертит в рантайме.\n2. **Дисбаланс стека на JUMP** — JUMPDEST, достигаемый из двух путей, ожидает разные состояния стека.\n3. **Off-by-one в DUP\u002FSWAP** — `dup3` вместо `dup4`, когда вы добавили лишний push раньше.\n\n`huffc` имеет флаг `--stack-check` для базового стекового анализа:\n\n```bash\nhuffc src\u002FContract.huff -r --stack-check\n```\n\nОн ловит очевидные underflow, но не может трассировать все динамические пути. Для сложных контрактов трассируйте исполнение вручную с `forge debug` или `evm-trace`.\n\n## Продвинутый подход: стек как регистровый файл\n\nОпытные Huff-разработчики воспринимают верхние ~8 позиций стека как регистровый файл:\n\n```\nПозиция 1 (вершина):  Рабочий регистр — текущее вычисление\nПозиции 2-3:          Регистры аргументов — входы следующей операции\nПозиции 4-6:          Локальные переменные — значения, нужные скоро\nПозиции 7-8:          Контекстные регистры — счётчики циклов\nПозиция 9+:           Область вытеснения — рассмотрите память\n```\n\nЭта ментальная модель помогает решить, когда использовать SWAP для перемещения значения на вершину, а когда — DUP, и когда выгружать в память.\n\n## Итоги\n\nУправление стеком — ключевой навык для разработки на Huff. DUP для неразрушающего чтения, SWAP для перестановки, память для значений за пределами глубины 16. Комментируйте каждую строку состоянием стека. Проверяйте каждую ветку. В следующей статье мы используем эти навыки для построения O(1) диспатчера функций с упакованными jump-таблицами.","\u003Ch2 id=\"\">Ментальная модель стековой машины\u003C\u002Fh2>\n\u003Cp>EVM — стековая машина. Нет регистров, нет именованных переменных — только стек LIFO из 32-байтных слов, глубиной 1024 слота. Каждый опкод либо кладёт, либо снимает, либо переупорядочивает элементы на этом стеке. Если вы не можете удержать текущее состояние стека в голове — вы напишете ошибочный байткод. Эта статья посвящена построению такой ментальной модели.\u003C\u002Fp>\n\u003Ch3>Нотация\u003C\u002Fh3>\n\u003Cp>В этой статье (и в комментариях Huff) мы представляем состояние стека в квадратных скобках, где левый элемент — вершина:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F [top, second, third, ..., bottom]\n0x01  \u002F\u002F [1]\n0x02  \u002F\u002F [2, 1]\nadd   \u002F\u002F [3]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Каждый макрос Huff должен иметь стековый комментарий после каждого опкода. Это не опционально — это единственный способ аудита корректности.\u003C\u002Fp>\n\u003Ch2 id=\"dup\">DUP: дублирование элементов стека\u003C\u002Fh2>\n\u003Cp>EVM предоставляет \u003Ccode>DUP1\u003C\u002Fcode> — \u003Ccode>DUP16\u003C\u002Fcode>. \u003Ccode>DUPn\u003C\u002Fcode> копирует n-й элемент от вершины и кладёт его на стек. Стек растёт на 1.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Stack: [a, b, c, d]\ndup1   \u002F\u002F [a, a, b, c, d]       — копия вершины\ndup3   \u002F\u002F [c, a, a, b, c, d]    — копия 3-го от вершины\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Стоимость газа: 3 газа для любого DUPn. Одна из самых дешёвых операций в EVM.\u003C\u002Fp>\n\u003Ch3>Когда использовать DUP\u003C\u002Fh3>\n\u003Cp>DUP — инструмент для \u003Cstrong>неразрушающего чтения\u003C\u002Fstrong>. Многие опкоды потребляют аргументы (ADD снимает два, кладёт один), поэтому если значение понадобится позже — дублируйте его перед подачей в потребляющий опкод.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro SAFE_SUB() = takes(2) returns(1) {\n    \u002F\u002F takes: [a, b] — вычислить a - b, revert если b &gt; a\n    dup2 dup2       \u002F\u002F [a, b, a, b]\n    lt              \u002F\u002F [a &lt; b?, a, b]\n    revert_underflow jumpi  \u002F\u002F [a, b]\n    sub             \u002F\u002F [a - b]\n    done jump\n    revert_underflow:\n        0x00 0x00 revert\n    done:\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Обратите внимание на \u003Ccode>dup2 dup2\u003C\u002Fcode> — мы дублируем и \u003Ccode>a\u003C\u002Fcode>, и \u003Ccode>b\u003C\u002Fcode>, потому что \u003Ccode>lt\u003C\u002Fcode> их потребит, а оригиналы нужны для \u003Ccode>sub\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"swap\">SWAP: перестановка элементов стека\u003C\u002Fh2>\n\u003Cp>EVM предоставляет \u003Ccode>SWAP1\u003C\u002Fcode> — \u003Ccode>SWAP16\u003C\u002Fcode>. \u003Ccode>SWAPn\u003C\u002Fcode> меняет местами вершину с (n+1)-м элементом. Размер стека не меняется.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Stack: [a, b, c, d]\nswap1  \u002F\u002F [b, a, c, d]          — обмен вершины и 2-го\nswap3  \u002F\u002F [d, a, c, b]          — обмен вершины и 4-го\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Стоимость: 3 газа для любого SWAPn.\u003C\u002Fp>\n\u003Ch3>Когда использовать SWAP\u003C\u002Fh3>\n\u003Cp>SWAP переупорядочивает аргументы для опкодов, ожидающих определённый порядок. Например, \u003Ccode>SUB\u003C\u002Fcode> вычисляет \u003Ccode>stack[0] - stack[1]\u003C\u002Fcode>. Если значения в неправильном порядке:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Stack: [b, a]  — но нам нужно a - b\nswap1   \u002F\u002F [a, b]\nsub     \u002F\u002F [a - b]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"16\">Ограничение глубины 16\u003C\u002Fh2>\n\u003Cp>DUP и SWAP достигают только 16 уровней вглубь. Если значение на позиции 17 и глубже, его невозможно получить одним опкодом. Это жёсткое ограничение EVM.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Стратегии для глубоких стеков:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Реструктуризация логики\u003C\u002Fstrong> — держите нужные значения ближе к вершине.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Использование памяти как scratch space.\u003C\u002Fstrong> Сохраните значение через \u003Ccode>MSTORE\u003C\u002Fcode>, получите позже через \u003Ccode>MLOAD\u003C\u002Fcode>. Стоит 3+3=6 газа вместо 3 для DUP, зато снимает ограничение глубины.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Разбиение макроса на меньшие макросы\u003C\u002Fstrong>, каждый из которых работает с меньшим числом стековых элементов.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro STASH_TO_MEMORY() = takes(1) returns(0) {\n    \u002F\u002F takes: [value]\n    0x80 mstore     \u002F\u002F []  — сохраняем в 0x80 (scratch space)\n}\n\n#define macro RECALL_FROM_MEMORY() = takes(0) returns(1) {\n    0x80 mload      \u002F\u002F [value]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>В MEV-контрактах мы часто резервируем \u003Ccode>0x80..0xc0\u003C\u002Fcode> как scratch-область для значений, которые иначе вытолкнули бы стек за предел 16.\u003C\u002Fp>\n\u003Ch2 id=\"\">Общие паттерны\u003C\u002Fh2>\n\u003Ch3>Паттерн 1: сохранение значения через потребляющую операцию\u003C\u002Fh3>\n\u003Cp>У вас \u003Ccode>[x]\u003C\u002Fcode>, и нужно вызвать опкод, потребляющий \u003Ccode>x\u003C\u002Fcode>, но \u003Ccode>x\u003C\u002Fcode> ещё понадобится.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Хотим: вычислить хеш x, но сохранить x\n\u002F\u002F Stack: [x]\ndup1        \u002F\u002F [x, x]\n0x00 mstore \u002F\u002F [x]  — memory[0] = x\n0x20 0x00   \u002F\u002F [0, 32, x]\nkeccak256   \u002F\u002F [hash, x]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Паттерн 2: ротация трёх элементов\u003C\u002Fh3>\n\u003Cp>Имеем \u003Ccode>[a, b, c]\u003C\u002Fcode>, нужно \u003Ccode>[c, a, b]\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">swap2       \u002F\u002F [c, b, a]\nswap1       \u002F\u002F [c, a, b]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>2 опкода, 6 газа. В EVM нет ротации одним опкодом.\u003C\u002Fp>\n\u003Cp>Имеем \u003Ccode>[a, b, c]\u003C\u002Fcode>, нужно \u003Ccode>[b, c, a]\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">swap1       \u002F\u002F [b, a, c]\nswap2       \u002F\u002F [b, c, a]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Паттерн 3: очистка ненужных элементов стека\u003C\u002Fh3>\n\u003Cp>После вычисления могут остаться лишние элементы. Используйте \u003Ccode>pop\u003C\u002Fcode> (2 газа):\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Stack: [result, garbage1, garbage2]\nswap1 pop   \u002F\u002F [result, garbage2]\nswap1 pop   \u002F\u002F [result]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Паттерн 4: дублирование пары\u003C\u002Fh3>\n\u003Cp>Нужно скопировать два верхних элемента:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">\u002F\u002F Stack: [a, b]\ndup2        \u002F\u002F [b, a, b]\ndup2        \u002F\u002F [a, b, a, b]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Обратите внимание — DUP в обратном порядке. \u003Ccode>dup2\u003C\u002Fcode> сначала копирует \u003Ccode>b\u003C\u002Fcode> (позиция 2), затем \u003Ccode>dup2\u003C\u002Fcode> копирует \u003Ccode>a\u003C\u002Fcode> (теперь на позиции 2, так как стек вырос). Этот паттерн постоянно встречается в коде сравнения-перед-арифметикой.\u003C\u002Fp>\n\u003Ch2 id=\"\">Дисциплина визуализации стека\u003C\u002Fh2>\n\u003Cp>При написании Huff придерживайтесь дисциплины:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Комментируйте каждую строку\u003C\u002Fstrong> состоянием стека после исполнения.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Проверяйте takes\u002Freturns\u003C\u002Fstrong> — считайте элементы стека на входе и выходе.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Трассируйте каждую ветку\u003C\u002Fstrong> — при каждом JUMPI обе ветви (переход и проход) должны оставлять стек в валидном состоянии.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Следите за дрейфом стека\u003C\u002Fstrong> — если тело цикла не балансирует push\u002Fpop, стек будет расти или уменьшаться на каждой итерации.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">Отладка стековых ошибок\u003C\u002Fh2>\n\u003Cp>Самые частые баги в Huff:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Stack underflow\u003C\u002Fstrong> — pop из пустого стека. EVM ревертит в рантайме.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Дисбаланс стека на JUMP\u003C\u002Fstrong> — JUMPDEST, достигаемый из двух путей, ожидает разные состояния стека.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Off-by-one в DUP\u002FSWAP\u003C\u002Fstrong> — \u003Ccode>dup3\u003C\u002Fcode> вместо \u003Ccode>dup4\u003C\u002Fcode>, когда вы добавили лишний push раньше.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>\u003Ccode>huffc\u003C\u002Fcode> имеет флаг \u003Ccode>--stack-check\u003C\u002Fcode> для базового стекового анализа:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">huffc src\u002FContract.huff -r --stack-check\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Он ловит очевидные underflow, но не может трассировать все динамические пути. Для сложных контрактов трассируйте исполнение вручную с \u003Ccode>forge debug\u003C\u002Fcode> или \u003Ccode>evm-trace\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"\">Продвинутый подход: стек как регистровый файл\u003C\u002Fh2>\n\u003Cp>Опытные Huff-разработчики воспринимают верхние ~8 позиций стека как регистровый файл:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Позиция 1 (вершина):  Рабочий регистр — текущее вычисление\nПозиции 2-3:          Регистры аргументов — входы следующей операции\nПозиции 4-6:          Локальные переменные — значения, нужные скоро\nПозиции 7-8:          Контекстные регистры — счётчики циклов\nПозиция 9+:           Область вытеснения — рассмотрите память\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Эта ментальная модель помогает решить, когда использовать SWAP для перемещения значения на вершину, а когда — DUP, и когда выгружать в память.\u003C\u002Fp>\n\u003Ch2 id=\"\">Итоги\u003C\u002Fh2>\n\u003Cp>Управление стеком — ключевой навык для разработки на Huff. DUP для неразрушающего чтения, SWAP для перестановки, память для значений за пределами глубины 16. Комментируйте каждую строку состоянием стека. Проверяйте каждую ветку. В следующей статье мы используем эти навыки для построения O(1) диспатчера функций с упакованными jump-таблицами.\u003C\u002Fp>\n","ru","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:23.640760Z","Deep EVM #10: Управление стеком в Huff — dup, swap и стековая дисциплина","Освойте управление стеком EVM в Huff: dup1-16, swap1-16, ограничение глубины 16, типичные паттерны и отладка стековых ошибок.","huff управление стеком evm",null,"index, follow",[22,27,31],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000017","Huff","huff","Блокчейн",[37,43,49],{"id":38,"title":39,"slug":40,"excerpt":41,"locale":12,"category_name":35,"published_at":42},"de000000-0000-0000-0000-000000000013","Уровень интероперабельности Ethereum: как 55+ L2 становятся одной сетью","uroven-interoperabelnosti-ethereum-kak-55-l2-stanovyatsya-odnoj-setyu","У Ethereum 55+ роллапов Layer 2, фрагментирующих ликвидность и пользовательский опыт. Уровень интероперабельности Ethereum — объединяющий кросс-роллап-мессаджинг, общие секвенсоры и based-роллапы — призван объединить их в единую компонуемую сеть.","2026-03-28T10:44:36.068675Z",{"id":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":35,"published_at":48},"de000000-0000-0000-0000-000000000012","ZK-доказательства за пределами роллапов: верифицируемый AI-инференс на Ethereum","zk-dokazatelstva-za-predelami-rollapov-verificiruemyj-ai-inferens-ethereum","Доказательства с нулевым разглашением — это уже не только инструмент масштабирования. В 2026 году zkML обеспечивает верифицируемый AI-инференс в блокчейне, ZK-копроцессоры переносят тяжёлые вычисления оффчейн с ончейн-верификацией, а новые системы доказательств SP1 и Jolt делают это практичным.","2026-03-28T10:44:36.026310Z",{"id":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":35,"published_at":54},"dd000000-0000-0000-0000-000000000013","EIP-7702 на практике: создание потоков смарт-аккаунтов после Pectra","eip-7702-na-praktike-sozdanie-potokov-smart-akkauntov-posle-pectra","EIP-7702 позволяет любому EOA Ethereum временно действовать как смарт-контракт в рамках одной транзакции. Вот как реализовать пакетные транзакции, спонсирование газа и социальное восстановление с помощью нового примитива абстракции аккаунтов.","2026-03-28T10:44:35.357227Z",{"id":13,"name":56,"slug":57,"bio":58,"photo_url":19,"linkedin":19,"role":59,"created_at":60,"updated_at":60},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]