Стоит знать
+ИИ агенты и относящиеся инструменты до сих пор находятся на ранних стадиях разработки и являются экспериментами, поэтому стоит их использовать с осторожностью.
+`nonce``
+
+`` — _Открывающий тег, который содержит фрагмент кода_
+
+nonce — _Непереводимый текст_
+
+`` — _Закрывающий тег_
+
+
+
+В исходном тексте также присутствуют сокращенные теги, которые содержат только цифры, что означает, что их функция не сразу понятна. Вы можете навести курсор на эти теги, чтобы увидеть, какую именно функцию они выполняют.
+
+В примере ниже вы можете видеть, что при наведении курсора на тег `<0>` он показывает, что представляет собой `` и содержит фрагмент кода, поэтому содержимое этих тегов не следует переводить.
+
+
+
+## Краткие и полные формы/сокращения {#short-vs-full-forms}
+
+На сайте используется много сокращений, например, dapps, NFT, DAO, DeFi и т. д. Эти аббревиатуры широко используются в английском языке и большинство посетителей сайта знакомы с ними.
+
+Поскольку они, как правило, не имеют устоявшихся переводов на другие языки, лучший способ использовать эти и подобные термины - дать описательный перевод полной формы и добавить английскую аббревиатуру в скобках.
+
+Не переводите эти аббревиатуры, поскольку большинство людей с ними не знакомы, а локализованные версии не будут иметь особого смысла для большинства читателей.
+
+Пример перевода dApps:
+
+- Децентрализованные приложения (dapps) → _Переведенная полная форма (английское сокращение в скобках)_
+
+## Термины без устоявшегося перевода {#terms-without-established-translations}
+
+Некоторые термины могут не иметь утвержденных переводов на другие языки и не быть широко известны под оригинальным английским определением. Такие термины, по большей части, включают в себя более новые понятия, такие как proof-of-work, proof-of-stake, Beacon Chain, staking и т.д.
+
+Несмотря на то, что перевод этих терминов может показаться неестественным, поскольку версия английского языка широко используется и в других языках, настоятельно рекомендуется их переводить.
+
+При переводе не стесняйтесь проявлять творческий подход, использовать описательные переводы или просто переводить их дословно.
+
+**Причина, по которой следует перевести большинство терминов, а не оставить некоторые на английском языке, заключается в том, что в будущем эта новая терминология станет более распространенной, поскольку все больше людей начнут использовать Ethereum и связанные с ним технологии. Если мы хотим привлечь в это пространство больше людей со всего мира, мы должны предоставить понятную терминологию на как можно большем количестве языков, даже если нам придется создавать ее самим.**
+
+## Кнопки и призывы к действию {#buttons-and-ctas}
+
+На сайте существует множество кнопок, которые должны быть переведены по-другому, в отличие от содержания.
+
+Текст кнопки можно определить, просмотрев контекстные скриншоты, связанные с большинством строк, или проверив контекст в редакторе, который включает фразу ''кнопка''.
+
+Переводы для кнопок должны быть как можно короче, чтобы избежать несовпадений в форматировании. Кроме того, перевод кнопок должен быть в повелительном наклонении, т. е. представлять собой команду или запрос.
+
+
+
+## Инклюзивный перевод {#translating-for-inclusivity}
+
+На Ethereum.org заходят люди со всего мира и с разным опытом. Поэтому язык на сайте должен быть нейтральным, дружелюбным и доступным для всех, а не эксклюзивным.
+
+Важным аспектом этого является гендерная нейтральность. Этого легко достичь, используя нейтральную форму обращения и избегая гендерно-окрашенных слов в переводах.
+
+Другая форма инклюзивности - попытка переводить для глобальной аудитории, не привязанной к какой-либо стране, расе или региону.
+
+Наконец, язык должен подходить для всех аудиторий и возрастов.
+
+## Переводы для конкретных языков {#language-specific-translations}
+
+При переводе важно соблюдать правила грамматики, общепринятые нормы и форматирование, которые используются в вашем языке; не следует копировать их из источника. Исходный текст соответствует английским грамматическим правилам и нормам, которые не применимы ко многим другим языкам.
+
+Вы должны знать правила вашего языка и переводить в соответствии с ними. Если вам требуется помощь, обратитесь к нам, и мы поможем вам найти ресурсы о том, как эти элементы должны использоваться в вашем языке.
+
+Некоторые примеры того, на что следует обратить особое внимание:
+
+### Пунктуация и форматирование {#punctuation-and-formatting}
+
+**Заглавные буквы**
+
+- В разных языках существует большая разница в заглавных буквах.
+- В английском языке принято писать с заглавной буквы все слова обозначающие названия и имена, месяцы и дни, названия языков, праздников и т.д. Во многих других языках это грамматически неверно, поскольку в них действуют другие правила заглавных букв.
+- В некоторых языках также существуют правила о написании заглавных букв в личных местоимениях, существительных и некоторых прилагательных, которые в английском языке не пишутся с заглавной буквы.
+
+**Интервалы**
+
+- Правила орфографии определяют использование пробелов для каждого языка. Поскольку пробелы используются повсеместно, эти правила одни из самых важных, а пробелы — одни из самых часто неправильно переводимых элементов.
+- Некоторые распространенные отличия в интервалах между английским и другими языками:
+ - Пробел перед единицами измерения и валютами (например, USD, EUR, kB, MB)
+ - Пробел перед знаками градусов (например, °C, ℉)
+ - Пробел перед некоторыми знаками препинания, особенно многоточием (…)
+ - Пробел перед и после слэшей (/)
+
+**Списки**
+
+- Каждый язык имеет разнообразный и сложный набор правил для написания списков. Они могут разительно отличаться от правил в английском.
+- В некоторых языках первое слово каждой новой строки должно быть написано с заглавной буквы, в других — новые строки должны начинаться со строчных букв. Во многих языках также существуют различные правила использования заглавных букв в списках, в зависимости от длины каждой строки.
+- То же самое относится и к пунктуации строк. В зависимости от языка в качестве завершающего знака препинания в списках может использоваться точка (.), запятая (,) или точка с запятой (;).
+
+**Кавычки**
+
+- В разных языках используются различные кавычки. Простое копирование английских кавычек из источника часто бывает неверным.
+- Одни из наиболее распространенных видов кавычек:
+ - „Пример текста“
+ - ‚Пример текста’
+ - »Пример текста«
+ - “Пример текста”
+ - ‘Пример текста’
+ - «Пример текста»
+
+**Дефисы и тире**
+
+- В английском языке дефис (-) используется для соединения слов и разных частей слова, а тире (–) используется для указания интервала или паузы.
+- Во многих языках существуют разные правила использования дефиса и тире, которые необходимо соблюдать.
+
+### Форматы {#formats}
+
+**Числа**
+
+- Главное отличие в написании чисел на разных языках - это разделитель, используемый для десятичных и тысячных. Для тысяч это может быть точка, запятая или пробел. Аналогично, в некоторых языках используется десятичная точка, а в других десятичная запятая.
+ - Некоторые примеры больших чисел:
+ - Английский — **1,000.50**
+ - Испанский — **1.000,50**
+ - Французский — **1 000,50**
+- Еще одним важным моментом при переводе чисел является знак процента. Может быть написано по-разному: **100%**, **100 %** или **%100**.
+- И наконец, отрицательные числа, в зависимости от конкретного языка, могут отображаться по-разному: -100, 100-, (100) или [100].
+
+**Даты**
+
+- При переводе дат, в зависимости от выбранного языка, учитываются некоторые факторы и особенности. Среди них - формат даты, разделитель, заглавные буквы и ведущие нули. Также существуют различия между полноформатными и числовыми датами.
+ - Примеры различных форматов записи даты:
+ - Британский английский (дд/мм/гггг) – 1 января, 2022
+ - Американский английский (мм/дд/гггг) – январь, 1 число, 2022
+ - Китайский (гггг-мм-дд) – 2022 год 1 месяц 1 число
+ - Французский (дд/мм/гггг) – 1 января 2022
+ - Итальянский (дд/мм/гггг) – 1 января 2022
+ - Немецкий (дд/мм/гггг) – 1. Января 2022
+
+**Валюты**
+
+- Перевод валют может быть непростой задачей из-за различий в форматах, условных обозначениях и конвертации. В основном, сохраняйте перевод валюты неизменным относительно исходного текста. Вы можете добавить местную валюту и конвертацию в скобках для удобства читателя.
+- Основные различия в написании валют в разных языках включают в себя расстановку символов, запятые или точки для десятичных дробей, пробелы и использование сокращений, или символов.
+ - Расположение символа: $100 или 100$
+ - Десятичные запятые или десятичные точки: 100,50$ или 100.50$
+ - Интервалы: 100$ или 100 $
+ - Аббревиатуры или символы: 100 $ или 100 USD
+
+**Единицы измерения**
+
+- Как правило, указывайте единицы измерения в соответствии с исходным вариантом. Если в вашей стране используется другая система, вы можете указать конвертацию в скобках.
+- Помимо локализации единиц измерения, важно обращать внимание на различия в том, как языки работают с этими единицами. Основное различие заключается в интервале между цифрой и единицей, который может быть разным в зависимости от языка. Примеры таких различий: 100kB и 100 kB или 50ºF и 50 ºF.
+
+## Заключение {#conclusion}
+
+Перевод ethereum.org - это замечательная возможность узнать о различных аспектах Ethereum.
+
+Старайтесь не торопиться при переводе. Расслабьтесь и получайте удовольствие!
+
+Благодарим Вас за участие в Программе Переводов и за то, что помогаете нам сделать веб-сайт доступным для более широкой аудитории. Ethereum является мировым сообществом и мы рады, что вы являетесь его частью!
diff --git a/public/content/translations/ru/dao/index.md b/public/content/translations/ru/dao/index.md
index b10d399452c..037778ab6a7 100644
--- a/public/content/translations/ru/dao/index.md
+++ b/public/content/translations/ru/dao/index.md
@@ -1,15 +1,16 @@
---
-title: Децентрализованные автономные организации (DAO)
-description: Обзор DAO на Ethereum
+title: "Что такое DAO?"
+metaTitle: "Что такое DAO? | Децентрализованная автономная организация"
+description: "Обзор DAO на Ethereum"
lang: ru
template: use-cases
emoji: ":handshake:"
sidebarDepth: 2
image: /images/use-cases/dao-2.png
-alt: Представление голосований DAO по предложению.
-summaryPoint1: Сообщества, принадлежащие его членам, без централизованного аппарата управления.
-summaryPoint2: Безопасный способ сотрудничества с незнакомцами в Интернете.
-summaryPoint3: Безопасное место для выделения средств на конкретную цель.
+alt: "Представление голосований DAO по предложению."
+summaryPoint1: "Сообщества, принадлежащие его членам, без централизованного аппарата управления."
+summaryPoint2: "Безопасный способ сотрудничества с незнакомцами в Интернете."
+summaryPoint3: "Безопасное место для выделения средств на конкретную цель."
---
## Что такое DAO? {#what-are-daos}
@@ -18,7 +19,7 @@ DAO — это организация, управляемая сообщест
DAO позволяют работать с единомышленниками по всему миру, не нуждаясь в руководителе для управления денежными средствами и операциями. Нет генерального директора, тратящего деньги по своей прихоти, или финансового директора, манипулирующего отчетностью. Вместо этого встроенные в код правила, основанные на блокчейне, определяют, как организация работает и тратит деньги.
-У них встроенные капиталы, к которым никто не имеет права доступа без согласия группы. Решения принимаются после предложений и голосования. Благодаря этому каждый в организации имеет право голоса и все [в блокчейне](/glossary/#on-chain) происходит прозрачно.
+У них встроенные капиталы, к которым никто не имеет права доступа без согласия группы. Решения принимаются на основе предложений и голосования, чтобы у каждого в организации было право голоса, и все происходило прозрачно [в сети (onchain)](/glossary/#onchain).
## Зачем нам нужны DAO? {#why-dao}
@@ -28,27 +29,27 @@ DAO позволяют работать с единомышленниками п
### Сравнение {#dao-comparison}
-| DAO | Традиционная организация |
-| -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
-| Обычно абсолютно демократичная, без иерархии. | Обычно иерархичная. |
-| Для внесения любых изменений требуется голосование. | В зависимости от структуры изменения могут запрашиваться одной стороной или предлагаться на основе голосования. |
-| Голоса подсчитываются, и результат реализуется автоматически без доверенного посредника. | Если голосование разрешено, голоса подсчитываются с помощью внутренних процедур, а результаты голосования должны обрабатываться вручную. |
+| DAO | Традиционная организация |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Обычно абсолютно демократичная, без иерархии. | Обычно иерархичная. |
+| Для внесения любых изменений требуется голосование. | В зависимости от структуры изменения могут запрашиваться одной стороной или предлагаться на основе голосования. |
+| Голоса подсчитываются, и результат реализуется автоматически без доверенного посредника. | Если голосование разрешено, голоса подсчитываются с помощью внутренних процедур, а результаты голосования должны обрабатываться вручную. |
| Предлагаемые услуги обрабатываются автоматически децентрализованным образом (например, распределение благотворительных средств). | Требуется вмешательство человека или централизованно управляемая автоматизация, подверженная манипуляциям. |
-| Вся деятельность является прозрачной и полностью доступной для публики. | Обычно деятельность конфиденциальна, а доступ публики к информации о ней ограничен. |
+| Вся деятельность является прозрачной и полностью доступной для публики. | Обычно деятельность конфиденциальна, а доступ публики к информации о ней ограничен. |
### Примеры DAO {#dao-examples}
Чтобы внести ясность, приведем несколько примеров возможного использования DAO.
-- **Благотворительность**. Вы можете принимать пожертвования от любого человека в мире и голосовать за цели, которые будете спонсировать.
-- **Коллективное владение**. Вы можете приобретать физические или цифровые активы, а участники голосовать за то, как их использовать.
-- **Венчурные инвестиции и гранты**. Вы можете создать венчурный фонд, который объединяет инвестиционный капитал и голосует за участие в венчурных проектах. Выплаченные деньги впоследствии можно будет перераспределить между участниками DAO.
+- **Благотворительность** — вы можете принимать пожертвования от кого угодно в мире и голосовать, какие инициативы финансировать.
+- **Коллективное владение** — вы можете приобретать физические или цифровые активы, а участники могут голосовать за то, как их использовать.
+- **Венчурные инвестиции и гранты** — вы можете создать венчурный фонд, который объединяет инвестиционный капитал и голосует за поддержку венчурных проектов. Выплаченные деньги впоследствии можно будет перераспределить между участниками DAO.
## Как работают DAO? {#how-daos-work}
-В основе DAO лежит [умный контракт](/glossary/#smart-contract), который определяет правила организации и хранит капитал группы. Как только контракт будет запущен на Ethereum, никто не сможет изменить правила без голосования. Если кто-то попытается сделать что-то, что не предусмотрено правилами и логикой кода, он потерпит неудачу. Управление капиталом также определяется умным контрактом. Это означает, что никто не может тратить деньги без одобрения группы. Это значит, что DAO не нуждается в центральных органах управления. Вместо этого группа принимает решения коллективно, и платежи автоматически авторизуются при голосовании.
+Основой DAO является ее [смарт-контракт](/glossary/#smart-contract), который определяет правила организации и хранит казну группы. Как только контракт будет запущен на Ethereum, никто не сможет изменить правила без голосования. Если кто-то попытается сделать что-то, что не предусмотрено правилами и логикой кода, он потерпит неудачу. Управление капиталом также определяется умным контрактом. Это означает, что никто не может тратить деньги без одобрения группы. Это значит, что DAO не нуждается в центральных органах управления. Вместо этого группа принимает решения коллективно, и платежи автоматически авторизуются при голосовании.
Это возможно, потому что после запуска на Ethereum умные контракты защищены от несанкционированного доступа. Вы не можете незаметно редактировать код (правила DAO), потому что все находится в открытом доступе.
@@ -71,7 +72,7 @@ Ethereum — идеальный фундамент для DAO по ряду п
#### Известный пример {#governance-example}
-[ENS](https://claim.ens.domains/delegate-ranking). Владельцы токенов ENS могут передать свои голоса активным участникам сообщества, которые будут представлять их.
+[ENS](https://claim.ens.domains/delegate-ranking) — владельцы ENS могут делегировать свои голоса активным участникам сообщества, которые будут их представлять.
### Автоматическое управление транзакциями {#governance-example}
@@ -79,19 +80,19 @@ Ethereum — идеальный фундамент для DAO по ряду п
#### Известный пример {#governance-example}
-[Nouns](https://nouns.wtf). В DAO Nouns транзакция автоматически подтверждается, если набран кворум голосов и большинство проголосовали утвердительно. Исключение составляют случаи, когда основатели DAO накладывают вето.
+[Nouns](https://nouns.wtf) — в Nouns DAO транзакция выполняется автоматически, если набран кворум голосов и большинство проголосовало «за», при условии, что основатели не наложили вето.
-### Управление по мультиподписи {#governance-example}
+### Управление при помощи мультиподписи {#governance-example}
-Несмотря на то, что в DAO может быть несколько тысяч участников с правом голоса, средствами [кошелька](/glossary/#wallet) могут распоряжаться 5–20 активных участников сообщества. Этим участникам доверяют, и обычно их данные выкладывают в открытый доступ. Их личности известны сообществу. После голосования владельцы [мультиподписи](/glossary/#multisig) исполняют волю сообщества.
+Хотя в DAO могут быть тысячи голосующих участников, средства могут храниться в общем [кошельке](/glossary/#wallet) для 5–20 активных и пользующихся доверием членов сообщества, чьи личности обычно раскрыты (известны сообществу). После голосования подписанты [мультиподписи](/glossary/#multisig) исполняют волю сообщества.
-## Законодательство, относящееся к DAO {#dao-laws}
+## Законы о DAO {#dao-laws}
В 1977 году в Вайоминге изобрели общество с ограниченной ответственностью (LLC), которое помогло защитить предпринимателей и ограничить их ответственность. Недавно в Вайоминге впервые приняли закон, который регулирует правовой статус DAO. На текущий момент законы, относящиеся к DAO, действуют в Вайоминге, Вермонте и на Американских Виргинских островах.
### Известный пример {#law-example}
-[CityDAO](https://citizen.citydao.io/). CityDAO использовал законодательство Вайоминга, касающееся DAO, чтобы приобрести 40 акров земли около Национального парка Йеллоустоун.
+[CityDAO](https://citizen.citydao.io/) — CityDAO использовал закон штата Вайоминг о DAO для покупки 40 акров земли недалеко от Йеллоустонского национального парка.
## Членство в DAO {#dao-membership}
@@ -99,15 +100,15 @@ Ethereum — идеальный фундамент для DAO по ряду п
### Членство на основе токенов {#token-based-membership}
-Обычно полностью [общедоступное](/glossary/#permissionless) (в зависимости от используемого токена). В основном такими управляющими токенами можно торговать без специальных разрешений на [децентрализованной бирже](/glossary/#dex). Другие должны быть заработаны через обеспечение ликвидности или другое «доказательство работы». В любом случае достаточно владеть токеном, чтобы получить доступ к голосованию.
+Обычно полностью [без разрешений](/glossary/#permissionless), в зависимости от используемого токена. В основном этими токенами управления можно торговать без разрешений на [децентрализованной бирже](/glossary/#dex). Другие должны быть заработаны через обеспечение ликвидности или другое «доказательство работы». В любом случае достаточно владеть токеном, чтобы получить доступ к голосованию.
_Обычно используется для управления обширными децентрализованными протоколами и/или самими токенами._
#### Известный пример {#token-example}
-[MakerDAO](https://makerdao.com). Токен MakerDAO, MKR, широко доступен на децентрализованных биржах, и любой может купить себе право голосовать за судьбу протокола Maker.
+[MakerDAO](https://makerdao.com) — токен MKR от MakerDAO широко представлен на децентрализованных биржах, и любой желающий может купить его, чтобы получить право голоса, определяющего будущее протокола Maker.
-### Членство на долевой основе {#share-based-membership}
+### Членство на основе долей {#share-based-membership}
Основанные на долевом участии DAO более ориентированы на разрешения с подтверждением прав, но все еще достаточно открыты. Любые потенциальные члены могут отправить предложение присоединиться к DAO. Обычно за это они предлагают токены или работу. Доли реализуют право прямого голосования и подтверждения собственности. Члены могут выйти в любой момент и забрать с собой свою долю имущества.
@@ -115,51 +116,53 @@ _Обычно используется для более сплоченных и
#### Известный пример {#share-example}
-[MolochDAO](http://molochdao.com/). MolochDAO ориентируется на финансирование проектов Ethereum. Они требуют подачи предложения о членстве, чтобы группа могла оценить, есть ли у вас необходимый опыт и капитал для вынесения обоснованных решений о потенциальных получателях грантов. Вы не можете просто купить доступ к DAO на открытом рынке.
+[MolochDAO](http://molochdao.com/) — MolochDAO специализируется на финансировании проектов Ethereum. Они требуют подачи предложения о членстве, чтобы группа могла оценить, есть ли у вас необходимый опыт и капитал для вынесения обоснованных решений о потенциальных получателях грантов. Вы не можете просто купить доступ к DAO на открытом рынке.
### Членство на основе репутации {#reputation-based-membership}
Репутация представляет собой доказательство участия и дает право голоса в DAO. В отличие от токена или членства, основанного на долевом участии, DAO на основе репутации не передают права собственности участникам. Репутация не может быть куплена, передана или делегирована; члены DAO должны заработать репутацию посредством участия. На он-чейн-голосование не требуется разрешение, и потенциальные члены могут свободно отправлять заявки на присоединение к DAO и запрашивать получение репутации и токенов в качестве вознаграждения за свой вклад.
-_Обычно используется для децентрализованной разработки протоколов и [децентрализованных приложений (dapps)](/glossary/#dapp) и управления ими, но также хорошо подходит для различных организаций, таких как благотворительные, рабочие коллективы, инвестиционные клубы и т. д._
+_Обычно используется для децентрализованной разработки и управления протоколами и [децентрализованными приложениями](/glossary/#dapp), но также хорошо подходит для самых разных организаций, таких как благотворительные фонды, рабочие коллективы, инвестиционные клубы и т. д._
#### Известный пример {#reputation-example}
-[DXdao](https://DXdao.eth.limo) — глобальный независимый коллектив, создающий децентрализованные протоколы и приложения и управляющий ими с 2019 года. Он использует управление на основе репутации и [голографический консенсус](/glossary/#holographic-consensus) для координации фондов и управления ими. Это означает, что никто не может купить себе право влиять на его будущее или управление.
+[DXdao](https://DXdao.eth.limo) — глобальный суверенный коллектив, который с 2019 года создает децентрализованные протоколы и приложения и управляет ими. Он использовал управление на основе репутации и [голографический консенсус](/glossary/#holographic-consensus) для координации и управления средствами. Это означает, что никто не мог купить себе право влиять на его будущее или управление.
-## Присоединение или запуск DAO {#join-start-a-dao}
+## Присоединиться к DAO или создать DAO {#join-start-a-dao}
-### Присоединитесь к DAO {#join-a-dao}
+### Присоединиться к DAO {#join-a-dao}
- [DAO сообщества Ethereum](/community/get-involved/#decentralized-autonomous-organizations-daos)
- [Список DAO от DAOHaus](https://app.daohaus.club/explore)
-- [Список DAO от Tally.xyz](https://www.tally.xyz)
+- [Список DAO от Tally.xyz](https://www.tally.xyz/explore)
+- [Список DAO от DeGov.AI](https://apps.degov.ai/)
-### Запуск DAO {#start-a-dao}
+### Создать DAO {#start-a-dao}
-- [Вызов DAO с DAOHaus](https://app.daohaus.club/summon)
-- [Запуск Governor DAO с Tally](https://www.tally.xyz/add-a-dao)
-- [Создать DAO на основе Aragon](https://aragon.org/product)
-- [Запуск колонии](https://colony.io/)
-- [Создать DAO с голографическим консенсусом DAOstack](https://alchemy.daostack.io/daos/create)
+- [Призовите DAO с DAOHaus](https://app.daohaus.club/summon)
+- [Запустите Governor DAO с помощью Tally](https://www.tally.xyz/get-started)
+- [Создайте DAO на базе Aragon](https://aragon.org/product)
+- [Запустить колонию](https://colony.io/)
+- [Создайте DAO с голографическим консенсусом от DAOstack](https://alchemy.daostack.io/daos/create)
+- [Запустите DAO с помощью DeGov Launcher](https://docs.degov.ai/integration/deploy)
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
### Статьи о DAO {#dao-articles}
- [Что такое DAO?](https://aragon.org/dao) — [Aragon](https://aragon.org/)
-- [Дом DAO](https://wiki.metagame.wtf/docs/great-houses/house-of-daos) — [Metagame](https://wiki.metagame.wtf/)
-- [Что такое DAO и для чего они?](https://daohaus.substack.com/p/-what-is-a-dao-and-what-is-it-for) — [DAOhaus](https://daohaus.club/)
+- [House of DAOs](https://wiki.metagame.wtf/docs/great-houses/house-of-daos) — [Metagame](https://wiki.metagame.wtf/)
+- [Что такое DAO и для чего она нужна?](https://daohaus.substack.com/p/-what-is-a-dao-and-what-is-it-for) — [DAOhaus](https://daohaus.club/)
- [Как создать цифровое сообщество на базе DAO](https://daohaus.substack.com/p/four-and-a-half-steps-to-start-a) — [DAOhaus](https://daohaus.club/)
- [Что такое DAO?](https://coinmarketcap.com/alexandria/article/what-is-a-dao) — [Coinmarketcap](https://coinmarketcap.com)
- [Что такое голографический консенсус?](https://medium.com/daostack/holographic-consensus-part-1-116a73ba1e1c) — [DAOstack](https://daostack.io/)
-- [DAO — не корпорации: когда децентрализация в автономных организациях имеет значение](https://vitalik.eth.limo/general/2022/09/20/daos.html)
-- [DAO, DAC, DA и другие: неполное руководство по терминологии](https://blog.ethereum.org/2014/05/06/daos-dacs-das-and-more-an-incomplete-terminology-guide) — [блог Ethereum](https://blog.ethereum.org)
+- [DAO — не корпорации: где важна децентрализация в автономных организациях](https://vitalik.eth.limo/general/2022/09/20/daos.html)
+- [DAO, DAC, DA и прочее: неполное руководство по терминологии](https://blog.ethereum.org/2014/05/06/daos-dacs-das-and-more-an-incomplete-terminology-guide) — [Блог Ethereum](https://blog.ethereum.org)
### Видео {#videos}
-- [Что такое DAO в криптовалютах?](https://youtu.be/KHm0uUPqmVE)
-- [Может ли DAO построить город?](https://www.ted.com/talks/scott_fitsimones_could_a_dao_build_the_next_great_city) – [TED](https://www.ted.com/)
+- [Что такое DAO в криптовалюте?](https://youtu.be/KHm0uUPqmVE)
+- [Может ли DAO построить город?](https://www.ted.com/talks/scott_fitsimones_could_a_dao_build_the_next_great_city) — [TED](https://www.ted.com/)
diff --git a/public/content/translations/ru/decentralized-identity/index.md b/public/content/translations/ru/decentralized-identity/index.md
index a3658b24b7a..57d9594bab4 100644
--- a/public/content/translations/ru/decentralized-identity/index.md
+++ b/public/content/translations/ru/decentralized-identity/index.md
@@ -1,14 +1,14 @@
---
-title: Децентрализованная идентичность
-description: Что такое децентрализованная идентичность и почему она важна?
+title: "Децентрализованная идентичность"
+description: "Что такое децентрализованная идентичность и почему она важна?"
lang: ru
template: use-cases
emoji: ":id:"
sidebarDepth: 2
image: /images/eth-gif-cat.png
-summaryPoint1: Традиционные идентификационные системы централизовали выдачу, обслуживание и контроль ваших идентификаторов.
-summaryPoint2: Децентрализованная идентификация устраняет зависимость от централизованных третьих лиц.
-summaryPoint3: Благодаря криптовалюте у пользователей теперь есть инструменты, позволяющие получать, хранить и контролировать свои собственные идентификаторы и аттестации.
+summaryPoint1: "Традиционные идентификационные системы централизовали выдачу, обслуживание и контроль ваших идентификаторов."
+summaryPoint2: "Децентрализованная идентификация устраняет зависимость от централизованных третьих лиц."
+summaryPoint3: "Благодаря криптовалюте у пользователей теперь есть инструменты, позволяющие получать, хранить и контролировать свои собственные идентификаторы и аттестации."
---
Сегодня идентификация лежит в основе практически всех аспектов вашей жизни. Использование онлайн-сервисов, открытие банковского счета, голосование на выборах, покупка собственности, обеспечивание занятости — все это требует подтверждения вашей личности.
@@ -39,53 +39,79 @@ summaryPoint3: Благодаря криптовалюте у пользоват
1. Децентрализованная идентификация увеличивает индивидуальный контроль над идентифицирующей информацией. Децентрализованные идентификаторы и аттестации можно проверять, не полагаясь на централизованные органы и сторонние службы.
-2. Децентрализованные решения для идентификации обеспечивают не требующий доверия, бесшовный и защищающий конфиденциальность метод проверки и управления идентификацией пользователей.
+2. Децентрализованные решения для идентификации обеспечивают не требующий доверия, бесшовный и защищающий конфиденциальность метод проверки и управления идентификацией пользователя.
3. Децентрализованная идентификация использует технологию блокчейна, которая создает доверие между различными сторонами и предоставляет криптографические гарантии для подтверждения действительности аттестаций.
4. Децентрализованная идентификация делает идентификационные данные переносимыми. Пользователи хранят аттестации и идентификаторы в мобильном кошельке и могут делиться ими с любой стороной по своему выбору. Децентрализованные идентификаторы и аттестации не фиксируются в базе данных организации-эмитента.
-5. Децентрализованная идентификация должна хорошо работать с новыми технологиями [с нулевым разглашением](/glossary/#zk-proof), которые позволят людям доказать, что они владеют чем-то или сделали что-то, не раскрывая деталей. Это может стать мощным способом объединения доверия и конфиденциальности для различных приложений, например для голосований.
+5. Децентрализованная идентификация должна хорошо работать с появляющимися [технологиями с нулевым разглашением](/glossary/#zk-proof), которые позволят людям доказать, что они владеют чем-то или сделали что-то, не раскрывая, что это такое. Это может стать мощным способом объединения доверия и конфиденциальности для различных приложений, например для голосований.
-6. Децентрализованная идентификация позволяет механизмам [противодействия атакам Сивиллы](/glossary/#anti-sybil) идентифицировать, когда один человек притворяется несколькими людьми, чтобы обмануть систему или распространить в ней спам.
+6. Децентрализованная идентификация позволяет механизмам [противодействия атакам Сивиллы](/glossary/#anti-sybil) идентифицировать, когда один человек притворяется несколькими людьми, чтобы обмануть какую-то систему или распространить в ней спам.
-## Варианты использования децентрализованной идентификации {#decentralized-identity-use-cases}
+## Примеры использования децентрализованной идентификации {#decentralized-identity-use-cases}
Децентрализованная идентификация имеет много потенциальных вариантов использования:
-### 1. Универсальные логины {#universal-dapp-logins}
+### 1. Универсальные входы в систему {#universal-dapp-logins}
Децентрализованная аутентификация может заменить вход по паролю. Поставщики услуг могут выдавать пользователям аттестаты, которые можно хранить в кошельке Ethereum. Примером аттестации может быть [NFT](/glossary/#nft), предоставляющий владельцу доступ к онлайн-сообществу.
-Затем функция [Войти с помощью Ethereum](https://siwe.xyz/) позволит серверам подтвердить учетную запись Ethereum пользователя и получить требуемое подтверждение с адреса его учетной записи. Это означает, что пользователи могут получать доступ к платформам и веб-сайтам, не запоминая длинные пароли, и улучшает работу пользователей в Интернете.
+Затем функция [«Войти с помощью Ethereum»](https://siwe.xyz/) позволит серверам подтвердить учетную запись Ethereum пользователя и получить требуемую аттестацию с адреса его учетной записи. Это означает, что пользователи могут получать доступ к платформам и веб-сайтам, не запоминая длинные пароли, и улучшает работу пользователей в Интернете.
-### 2. Аутентификация KYC {#kyc-authentication}
+### 2. KYC-аутентификация {#kyc-authentication}
Использование многих онлайн-сервисов требует от отдельных лиц предоставления свидетельств и учетных данных, таких как водительское удостоверение или национальный паспорт. Но этот подход проблематичен, поскольку личная информация пользователя может быть скомпрометирована, а поставщики услуг не могут проверить подлинность аттестации.
-Децентрализованная идентификация позволяет компаниям отказаться от традиционных процессов [«знай своего клиента» (KYC)](https://en.wikipedia.org/wiki/Know_your_customer) и аутентифицировать личность пользователя с помощью проверяемых учетных данных. Это снижает стоимость управления идентификацией и предотвращает использование поддельной документации.
+Децентрализованная идентификация позволяет компаниям отказаться от традиционных процессов [«Знай своего клиента» (KYC)](https://en.wikipedia.org/wiki/Know_your_customer) и аутентифицировать личность пользователя с помощью верифицируемых учетных данных. Это снижает стоимость управления идентификацией и предотвращает использование поддельной документации.
### 3. Голосование и онлайн-сообщества {#voting-and-online-communities}
-Онлайн-голосование и социальные сети — два новых приложения для децентрализованной идентификации. Схемы онлайн-голосования подвержены манипуляциям, особенно если злоумышленники создают ложные имена для голосования. Просьба к отдельным лицам представить аттестацию в сети может повысить честность процессов онлайн-голосования.
+Онлайн-голосование и социальные сети — два новых приложения для децентрализованной идентификации. Схемы онлайн-голосования подвержены манипуляциям, особенно если злоумышленники создают ложные имена для голосования. Требование к пользователям представлять он-чейн аттестации может повысить целостность процессов онлайн-голосования.
-Децентрализованная идентификация может помочь в создании онлайн-сообществ, свободных от поддельных учетных записей. Например, каждому пользователю может потребоваться аутентифицировать свою личность с помощью сетевой системы идентификации, такой как служба имен Ethereum, что снижает вероятность появления ботов.
+Децентрализованная идентификация может помочь в создании онлайн-сообществ, свободных от поддельных учетных записей. Например, каждому пользователю может потребоваться аутентифицировать свою личность с помощью он-чейн системы идентификации, такой как Ethereum Name Service, что снижает вероятность появления ботов.
### 4. Защита от атак Сивиллы {#sybil-protection}
-Приложения для предоставления грантов, использующие [квадратичное голосование](/glossary/#quadratic-voting), уязвимы для [атак Сивиллы](/glossary/#sybil-attack), так как ценность гранта увеличивается, когда за него голосует больше людей, что побуждает пользователей участвовать в работе системы под разными идентификаторами. Децентрализованные идентификаторы помогают предотвратить это, возлагая на каждого участника бремя доказывания того, что он действительно человек, хотя часто без необходимости раскрывать конкретную личную информацию.
+Приложения для предоставления грантов, использующие [квадратичное голосование](/glossary/#quadratic-voting), уязвимы для [атак Сивиллы](/glossary/#sybil-attack), поскольку ценность гранта увеличивается, когда за него голосует больше людей, что побуждает пользователей распределять свои вклады между множеством идентификаторов. Децентрализованные идентификаторы помогают предотвратить это, возлагая на каждого участника бремя доказывания того, что он действительно человек, хотя часто без необходимости раскрывать конкретную личную информацию.
+
+### 5. Национальные и государственные удостоверения личности {#national-and-government-id}
+
+Правительства могут использовать принципы децентрализованной идентификации для выпуска основных документов, удостоверяющих личность, — таких как национальные удостоверения личности, паспорта или водительские права, — в качестве верифицируемых учетных данных в Ethereum, обеспечивая надежные криптографические гарантии подлинности для снижения уровня мошенничества и подделок при проверке личности в Интернете. Граждане могут хранить эти аттестации в своем личном [кошельке](/wallets/) и использовать их для подтверждения своей личности, возраста или права голоса.
+
+Эта модель позволяет осуществлять выборочное раскрытие информации, особенно в сочетании с технологией конфиденциальности на основе [доказательств с нулевым разглашением (ZKP)](/zero-knowledge-proofs/). Например, гражданин может криптографически доказать, что ему больше 18 лет, чтобы получить доступ к услуге с возрастными ограничениями, не раскрывая точную дату своего рождения, что обеспечивает большую конфиденциальность, чем традиционное удостоверение личности.
+
+#### 💡Пример: Национальное цифровое удостоверение личности (NDI) Бутана на Ethereum {#case-study-bhutan-ndi}
+
+- Предоставляет доступ к верифицируемым учетным данным почти 800 000 граждан Бутана
+- Миграция из сети Polygon [в основную сеть Ethereum](https://www.bhutanndi.com/article/bhutan-adopts-ethereum-for-national-identity-a-new-chapter-in-digital-sovereignty_2d0c7ec2-5605-4c42-b258-bd9361ae8878) в октябре 2025 года
+- По состоянию на март 2025 года выпущено более [234 000 цифровых удостоверений личности](https://www.blockchain-council.org/blockchain/bhutan-uses-blockchain-in-digital-id-project/)
+
+Королевство Бутан [мигрировало свою систему национальных цифровых удостоверений личности (NDI)](https://www.bhutanndi.com/article/bhutan-adopts-ethereum-for-national-identity-a-new-chapter-in-digital-sovereignty_2d0c7ec2-5605-4c42-b258-bd9361ae8878) в Ethereum в октябре 2025 года. Построенная на принципах децентрализованной и суверенной идентичности, система NDI Бутана использует децентрализованные идентификаторы и верифицируемые учетные данные для выпуска учетных данных с цифровой подписью непосредственно в личный кошелек гражданина. Благодаря закреплению криптографических доказательств этих учетных данных в Ethereum система гарантирует, что они являются подлинными, защищенными от несанкционированного доступа и могут быть проверены любой стороной без обращения к центральному органу.
+
+Архитектура системы подчеркивает конфиденциальность за счет использования технологии [доказательств с нулевым разглашением (ZKP)](/zero-knowledge-proofs/). Эта реализация «выборочного раскрытия» позволяет гражданам доказывать определенные факты (например, «Мне больше 18 лет» или «Я гражданин») для доступа к услугам, не раскрывая лежащие в основе персональные данные, такие как полный номер удостоверения личности или точная дата рождения. Это демонстрирует мощное, реальное применение Ethereum для создания безопасной, ориентированной на пользователя и сохраняющей конфиденциальность национальной системы идентификации.
+
+#### 💡Пример: QuarkID города Буэнос-Айрес на [Уровне 2](/layer-2/) Ethereum ZKSync Era {#case-study-buenos-aires-quarkid}
+
+- При запуске выданы учетные данные децентрализованной идентификации более чем [3,6 миллионам пользователей](https://buenosaires.gob.ar/innovacionytransformaciondigital/miba-con-tecnologia-quarkid-la-ciudad-de-buenos-aires-incorporo)
+- QuarkID — это протокол с открытым исходным кодом, признанный [цифровым общественным благом](https://www.digitalpublicgoods.net/r/quarkid) в рамках Целей устойчивого развития ООН
+- Подчеркивает модель «[правительство как пользователь](https://buenosaires.gob.ar/innovacionytransformaciondigital/miba-con-tecnologia-quarkid-la-ciudad-de-buenos-aires-incorporo)», в которой город не владеет протоколом, предоставляя гражданам полное владение данными и конфиденциальность
+
+В 2024 году правительство города Буэнос-Айрес (GCBA) интегрировало QuarkID, «систему цифрового доверия» с открытым исходным кодом, созданную Секретариатом инноваций и цифровой трансформации GCBA, в miBA — официальное приложение города для доступа жителей к государственным услугам и официальным документам. При запуске всем более чем 3,6 миллионам пользователей miBA были выданы децентрализованные цифровые удостоверения личности, которые позволяют им управлять и обмениваться верифицируемыми цифровыми документами и сертификатами он-чейн, включая документы о гражданстве, свидетельства о рождении, браке и смерти, налоговые записи, записи о вакцинации и многое другое.
+
+Система QuarkID, построенная на сети Ethereum [Уровня 2](/layer-2/) ZKSync Era, использует технологию ZKP, чтобы позволить гражданам проверять личные учетные данные в одноранговой сети через свои мобильные устройства, не раскрывая ненужные персональные данные. Программа подчеркивает модель «правительство как пользователь», в которой GCBA выступает в качестве одного из пользователей протокола QuarkID с открытым исходным кодом и совместимостью, а не в качестве централизованного владельца. Эта архитектура с поддержкой ZKP обеспечивает ключевую функцию конфиденциальности: никакая третья сторона, даже GCBA, не может отслеживать, как, когда и почему гражданин использует свои учетные данные. Эта успешная программа предоставляет гражданам полную суверенную идентичность и контроль над своими конфиденциальными данными, и все это защищено глобально распределенной сетью Ethereum.
## Что такое аттестации? {#what-are-attestations}
Аттестация — это заявление, сделанное одним субъектом в отношении другого субъекта. Если вы живете в Соединенных Штатах, водительские права, выданные вам Департаментом транспортных средств (одним субъектом), подтверждают, что вам (другому субъекту) по закону разрешено водить автомобиль.
-Аттестации отличаются от идентификаторов. Аттестация _содержит_ идентификаторы для ссылки на конкретное удостоверение и делает заявление об атрибуте, связанном с этим удостоверением. Таким образом, ваше водительское удостоверение имеет идентификаторы (имя, дата рождения, адрес), но также является подтверждением вашего законного права на вождение.
+Аттестации отличаются от идентификаторов. Аттестация _содержит_ идентификаторы для ссылки на конкретную личность и делает заявление об атрибуте, связанном с этой личностью. Таким образом, ваше водительское удостоверение имеет идентификаторы (имя, дата рождения, адрес), но также является подтверждением вашего законного права на вождение.
### Что такое децентрализованные идентификаторы? {#what-are-decentralized-identifiers}
Традиционные идентификаторы, такие как ваше официальное имя или адрес электронной почты, полагаются на третьи стороны — правительства и поставщиков услуг электронной почты. Децентрализованные идентификаторы (DID) отличаются от традиционных — они не выдаются, не управляются и не контролируются какой-либо центральной организацией.
-Децентрализованные идентификаторы выпускаются, хранятся и контролируются отдельными лицами. [Учетная запись Ethereum](/glossary/#account) — это пример децентрализованного идентификатора. Вы можете создавать столько учетных записей, сколько хотите, без чьего-либо разрешения и без необходимости хранить их в центральном реестре.
+Децентрализованные идентификаторы выпускаются, хранятся и контролируются отдельными лицами. [Учетная запись Ethereum](/glossary/#account) — это пример децентрализованного идентификатора. Вы можете создавать столько учетных записей, сколько хотите, без чьего-либо разрешения и без необходимости хранить их в центральном реестре.
Децентрализованные идентификаторы хранятся в распределенных реестрах ([блокчейнах](/glossary/#blockchain)) или [одноранговых сетях](/glossary/#peer-to-peer-network). Это делает DID [глобально уникальными, разрешаемыми с высокой доступностью и криптографически верифицируемыми](https://w3c-ccg.github.io/did-primer/). Децентрализованный идентификатор может быть связан с различными объектами, включая людей, организации или государственные учреждения.
@@ -93,7 +119,7 @@ summaryPoint3: Благодаря криптовалюте у пользоват
### 1. Криптография с открытым ключом {#public-key-cryptography}
-Криптография с открытым ключом — это средство защиты информации, которое генерирует [открытый](/glossary/#public-key) и [ секретный](/glossary/#private-key) ключи для участника. [Криптография](/glossary/#cryptography) с открытым ключом используется в сетях блокчейн для аутентификации пользователей и подтверждения права собственности на цифровые активы.
+Криптография с открытым ключом — это средство защиты информации, которое генерирует [открытый ключ](/glossary/#public-key) и [приватный ключ](/glossary/#private-key) для участника. [Криптография](/glossary/#cryptography) с открытым ключом используется в сетях блокчейн для аутентификации личности пользователей и подтверждения права собственности на цифровые активы.
Некоторые децентрализованные идентификаторы, такие как учетная запись Ethereum, имеют открытый и закрытый ключи. Открытый ключ идентифицирует контроллер учетной записи, а закрытые ключи могут подписывать и расшифровывать сообщения для этой учетной записи. Криптография с открытым ключом предоставляет доказательства, необходимые для аутентификации участников и предотвращения выдачи себя за другое лицо и использования поддельных идентификаторов, используя [криптографические подписи](https://andersbrownworth.com/blockchain/public-private-keys/) для проверки всех утверждений.
@@ -107,7 +133,7 @@ summaryPoint3: Благодаря криптовалюте у пользоват
Децентрализованная идентификация — это идея о том, что информация, связанная с идентификацией, должна быть самоконтролируемой, конфиденциальной и переносимой, а децентрализованные идентификаторы и аттестации являются основными строительными блоками.
-В контексте децентрализованной идентификации аттестации (известные также как [проверяемые учетные данные](https://www.w3.org/TR/vc-data-model/)) являются защищенными от несанкционированного доступа криптографически проверяемыми заявлениями эмитента. Каждая аттестация (проверяемые учетные данные), которую субъект (например, организация) выдает, связана с их DID.
+В контексте децентрализованной идентификации аттестации (также известные как [верифицируемые учетные данные](https://www.w3.org/TR/vc-data-model/)) являются защищенными от несанкционированного доступа криптографически проверяемыми заявлениями эмитента. Каждая аттестация (проверяемые учетные данные), которую субъект (например, организация) выдает, связана с их DID.
Поскольку DID хранятся в блокчейне, любой может проверить действительность аттестации, перепроверив DID эмитента в Ethereum. По сути, блокчейн Ethereum действует как глобальный каталог, который позволяет проверять DID, связанные с определенными объектами.
@@ -115,77 +141,78 @@ summaryPoint3: Благодаря криптовалюте у пользоват
Децентрализованные идентификаторы также имеют решающее значение для защиты конфиденциальности личной информации посредством децентрализованной идентификации. Например, если физическое лицо представляет подтверждение аттестации (водительское удостоверение), проверяющей стороне не нужно проверять достоверность информации в подтверждении. Вместо этого верификатору нужны только криптографические гарантии подлинности аттестации и личности выдавшей организации, чтобы определить, действительно ли доказательство.
-## Виды аттестаций в децентрализованной идентификации {#types-of-attestations-in-decentralized-identity}
+## Типы аттестаций в децентрализованной идентификации {#types-of-attestations-in-decentralized-identity}
Способы хранения и извлечения аттестационной информации в экосистеме удостоверений на основе Ethereum отличаются от традиционного управления удостоверениями. Ниже приведен обзор различных подходов к выдаче, хранению и проверке аттестаций в децентрализованных системах идентификации.
-### Аттестации вне сети {#off-chain-attestations}
+### Офф-чейн аттестации {#offchain-attestations}
-Одна из проблем с хранением аттестаций в сети заключается в том, что они могут содержать информацию, которую люди хотят сохранить в тайне. Публичный характер блокчейна Ethereum делает непривлекательным хранение таких подтверждений.
+Одна из проблем с хранением он-чейн аттестаций заключается в том, что они могут содержать информацию, которую люди хотят сохранить в тайне. Публичный характер блокчейна Ethereum делает непривлекательным хранение таких подтверждений.
-Решение состоит в выдаче аттестаций, хранящихся пользователями вне сети в цифровых кошельках, но подписанных с помощью DID эмитента, хранящегося в сети. Эти аттестации кодируются как [веб-токены JSON](https://en.wikipedia.org/wiki/JSON_Web_Token) и содержат цифровую подпись эмитента, что позволяет легко проверять заявления вне сети.
+Решение состоит в выдаче аттестаций, которые хранятся пользователями офф-чейн в цифровых кошельках, но подписаны с помощью DID эмитента, хранящегося он-чейн. Эти аттестации кодируются как [веб-токены JSON](https://en.wikipedia.org/wiki/JSON_Web_Token) и содержат цифровую подпись эмитента, что позволяет легко проверять офф-чейн заявления.
-Вот гипотетический сценарий, объясняющий аттестации вне сети:
+Вот гипотетический сценарий, объясняющий офф-чейн аттестации:
1. Университет (эмитент) создает аттестат (цифровой академический сертификат), подписывает его своими ключами и выдает Бобу (владельцу удостоверения).
2. Боб подает заявление о приеме на работу и хочет подтвердить свою академическую квалификацию работодателю, поэтому он делится аттестацией со своего мобильного кошелька. Затем компания (верификатор) может подтвердить действительность аттестации, проверив DID эмитента (т. е. его открытый ключ в Ethereum).
-### Аттестации вне сети с постоянным доступом {#offchain-attestations-with-persistent-access}
+### Офф-чейн аттестации с постоянным доступом {#offchain-attestations-with-persistent-access}
-В этом случае аттестации преобразуются в файлы JSON и хранятся вне сети (в идеале на платформе [децентрализованного облачного хранилища](/developers/docs/storage/), например IPFS или Swarm). Однако [хэш](/glossary/#hash) файла JSON хранится в сети и связан с DID через реестр в сети. Связанный DID может принадлежать либо издателю аттестации, либо получателю.
+В этом случае аттестации преобразуются в файлы JSON и хранятся офф-чейн (в идеале на платформе [децентрализованного облачного хранилища](/developers/docs/storage/), например IPFS или Swarm). Однако [хэш](/glossary/#hash) JSON-файла хранится он-чейн и связан с DID через он-чейн реестр. Связанный DID может принадлежать либо издателю аттестации, либо получателю.
Этот подход позволяет аттестациям сохранять устойчивость на основе блокчейна, сохраняя при этом информацию о заявках в зашифрованном виде и поддающейся проверке. Это также позволяет выборочное раскрытие, поскольку владелец закрытого ключа может расшифровать информацию.
-### Аттестации в сети {#onchain-attestations}
+### Он-чейн аттестации {#onchain-attestations}
-Аттестации в сети проводятся в [смарт-контрактах](/glossary/#smart-contract) на блокчейне Ethereum. Смарт-контракт (действующий как реестр) сопоставит аттестацию с соответствующим децентрализованным идентификатором в сети (открытым ключом).
+Он-чейн аттестации хранятся в [смарт-контрактах](/glossary/#smart-contract) в блокчейне Ethereum. Смарт-контракт (действующий как реестр) сопоставит аттестацию с соответствующим он-чейн децентрализованным идентификатором (открытым ключом).
-Вот пример, показывающий, как аттестация в сети может работать на практике:
+Вот пример, показывающий, как он-чейн аттестации могут работать на практике:
1. Компания (XYZ Corp) планирует продать доли собственности с помощью смарт-контракта, но хочет, чтобы покупатели прошли проверку их данных.
-2. XYZ Corp может поручить компании проводить проверку их данных для выдачи аттестаций в сети Ethereum. Эта аттестация удостоверяет, что человек прошел проверку данных, не раскрывая никакой личной информации.
+2. XYZ Corp может поручить компании, проводящей проверку данных, выпустить он-чейн аттестации в Ethereum. Эта аттестация удостоверяет, что человек прошел проверку данных, не раскрывая никакой личной информации.
3. Смарт-контракт, продающий акции, может проверять договор реестра на предмет идентификации проверенных покупателей, что позволяет смарт-контракту определять, кому разрешено покупать акции, а кому нет.
-### Токены Soulbound и личность {#soulbound}
+### Токены Soulbound и идентичность {#soulbound}
-[Токены Soulbound](https://vitalik.eth.limo/general/2022/01/26/soulbound.html) ([непередаваемые NFT](/glossary/#nft)) можно использовать для сбора информации, уникальной для конкретного кошелька. Это эффективно создает уникальную идентификацию в сети, привязанную к конкретному адресу Ethereum, которая может включать токены, представляющие достижения (например, окончание определенного онлайн-курса или достижение порогового балла в игре) или участие в сообществе.
+[Токены Soulbound](https://vitalik.eth.limo/general/2022/01/26/soulbound.html) ([непередаваемые NFT](/glossary/#nft)) могут использоваться для сбора информации, уникальной для определенного кошелька. Это эффективно создает уникальную он-чейн-идентичность, привязанную к определенному адресу Ethereum, которая может включать токены, представляющие достижения (например, окончание определенного онлайн-курса или достижение порогового балла в игре) или участие в сообществе.
-## Используйте децентрализованную идентификацию {#use-decentralized-identity}
+## Использование децентрализованной идентификации {#use-decentralized-identity}
Есть много амбициозных проектов, использующих Ethereum в качестве основы для децентрализованной идентификации:
-- **[Служба имен Ethereum (ENS)](https://ens.domains/)** — _ децентрализованная система имен для сетевых, машиночитаемых идентификаторов, таких как адреса кошельков Ethereum, хэши контента и метаданные._
-- **[SpruceID](https://www.spruceid.com/)** — _проект децентрализованной идентификации, который позволяет пользователям контролировать цифровую идентификацию с помощью учетных записей Ethereum и профилей ENS, а не полагаться на сторонние службы._
-- **[Ethereum Attestation Service (EAS)](https://attest.sh/)** — _децентрализованный протокол и перепись для аттестаций любого назначения в цепочке и вне ее._
-- **[Proof of Humanity](https://www.proofofhumanity.id)** – _«доказательство человечества» (PoH) – это социальная система подтверждения личности, построенная на Ethereum._
-- **[BrightID](https://www.brightid.org/)** – _децентрализованная сеть социальной идентификации с открытым исходным кодом, стремящаяся реформировать проверку личности путем создания и анализа социального графа._
+- **[Ethereum Name Service (ENS)](https://ens.domains/)** — _децентрализованная система имен для он-чейн машиночитаемых идентификаторов, таких как адреса кошельков Ethereum, хэши контента и метаданные._
+- **[Войти с помощью Ethereum (SIWE)](https://siwe.xyz/)** — _открытый стандарт для аутентификации с помощью учетных записей Ethereum._
+- **[SpruceID](https://www.spruceid.com/)** — _проект децентрализованной идентификации, который позволяет пользователям контролировать цифровую идентификацию с помощью учетных записей Ethereum и профилей ENS, а не полагаться на сторонние службы._
+- **[Ethereum Attestation Service (EAS)](https://attest.org/)** — _децентрализованный реестр/протокол для создания он-чейн или офф-чейн аттестаций о чем угодно._
+- **[Proof of Humanity](https://www.proofofhumanity.id)** — _Proof of Humanity (или PoH) — это социальная система подтверждения личности, построенная на Ethereum._
+- **[BrightID](https://www.brightid.org/)** — _децентрализованная социальная сеть идентификации с открытым исходным кодом, стремящаяся реформировать проверку личности путем создания и анализа социального графа._
- **[walt.id](https://walt.id)** — _инфраструктура децентрализованной идентификации и кошелька с открытым исходным кодом, которая позволяет разработчикам и организациям использовать суверенную идентичность и NFT/SBT._
- **[Veramo](https://veramo.io/)** — _фреймворк JavaScript, который упрощает использование криптографически проверяемых данных в приложениях._
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
### Статьи {#articles}
-- [Примеры использования блокчейна: блокчейн в цифровой идентификации](https://consensys.net/blockchain-use-cases/digital-identity/) — _ConsenSys_
-- [Что такое Ethereum ERC725? Самостоятельное управление идентификацией в блокчейне](https://cryptoslate.com/what-is-erc725-self-sovereign-identity-management-on-the-blockchain/) — _Sam Town_
-- [Как блокчейн может решить проблему цифровой идентификации?](https://time.com/6142810/proof-of-humanity/) — _Эндрю Р. Чоу_
-- [Что такое децентрализованная идентификация и почему это должно волновать вас?](https://web3.hashnode.com/what-is-decentralized-identity) — _Эммануэль Авосика_
-- [Введение в децентрализованные идентификаторы](https://walt.id/white-paper/digital-identity) — _Доминик Берон_
+- [Сферы применения блокчейна: блокчейн в цифровой идентификации](https://consensys.net/blockchain-use-cases/digital-identity/) — _ConsenSys_
+- [Что такое Ethereum ERC725? [Управление суверенной идентичностью в блокчейне](https://cryptoslate.com/what-is-erc725-self-sovereign-identity-management-on-the-blockchain/) — _Сэм Таун_
+- [Как блокчейн может решить проблему цифровой идентификации](https://time.com/6142810/proof-of-humanity/) — _Эндрю Р. Чоу_
+- [Что такое децентрализованная идентификация и почему это важно?](https://web3.hashnode.com/what-is-decentralized-identity) — _Эммануэль Авосика_
+- [Введение в децентрализованную идентификацию](https://walt.id/white-paper/digital-identity) — _Доминик Берон_
### Видео {#videos}
-- [Децентрализованная идентификация (бонусная стрим-сессия)](https://www.youtube.com/watch?v=ySHNB1za_SE&t=539s) — _отличное видео о децентрализованной идентификации от Андреаса Антонополуса_
-- [Войти в систему с помощью Ethereum и децентрализованной идентификации с помощью Ceramic, IDX, React, и 3ID Connect](https://www.youtube.com/watch?v=t9gWZYJxk7c) — _Учебное пособие на YouTube по созданию системы управления идентификацией для создания, чтения и обновления профиля пользователя с использованием его кошелька Ethereum от Надер Дебит_
-- [BrightID — децентрализованная идентификация на Ethereum](https://www.youtube.com/watch?v=D3DbMFYGRoM) — _подкаст бесплатных версий, обсуждающий BrightID, децентрализованное решение для Ethereum_
-- [Презентация «Интернет вне сети»: децентрализованная идентификация и проверяемые полномочия](https://www.youtube.com/watch?v=EZ_Bb6j87mg) — EthDenver 2022 от Эвина МакМаллена
-- [Обьяснение проверяемых учетных данных](https://www.youtube.com/watch?v=ce1IdSr-Kig) — видео на YouTube с демонстрацией Тамино Бауманна
+- [Децентрализованная идентификация (бонусная прямая трансляция)](https://www.youtube.com/watch?v=ySHNB1za_SE&t=539s) — _Отличное поясняющее видео о децентрализованной идентификации от Андреаса Антонопулоса_
+- [Вход с помощью Ethereum и децентрализованная идентификация с Ceramic, IDX, React и 3ID Connect](https://www.youtube.com/watch?v=t9gWZYJxk7c) — _учебное пособие на YouTube от Надера Дабита по созданию системы управления идентификацией для создания, чтения и обновления профиля пользователя с использованием его кошелька Ethereum_
+- [BrightID — децентрализованная идентификация в Ethereum](https://www.youtube.com/watch?v=D3DbMFYGRoM) — _эпизод подкаста Bankless, в котором обсуждается BrightID, решение для децентрализованной идентификации в Ethereum_
+- [Офф-чейн интернет: децентрализованная идентификация и верифицируемые учетные данные](https://www.youtube.com/watch?v=EZ_Bb6j87mg) — _презентация Эвин Макмаллен на EthDenver 2022_
+- [Объяснение верифицируемых учетных данных](https://www.youtube.com/watch?v=ce1IdSr-Kig) — _объясняющее видео на YouTube с демонстрацией от Тамино Бауманна_
### Сообщества {#communities}
-- [ERC-725 Альянс на GitHab](https://github.com/erc725alliance) — _сторонники стандарта ERC725 для управления идентификацией на блокчейне Ethereum_
-- [Сервер EthID Discord](https://discord.com/invite/ZUyG3mSXFD) — _сообщество для энтузиастов и разработчиков, работающих над регистрацией в Ethereum_
-- [Veramo Labs](https://discord.gg/sYBUXpACh4) — _сообщество разработчиков, содействующих созданию фреймворка для проверяемых данных для приложений_
-- [walt.id](https://discord.com/invite/AW8AgqJthZ) — _сообщество разработчиков, работающих над вариантами использования децентрализованных идентификаторов в различных отраслях_
+- [Альянс ERC-725 на GitHub](https://github.com/erc725alliance) — _сторонники стандарта ERC725 для управления идентификацией в блокчейне Ethereum_
+- [Сервер EthID в Discord](https://discord.com/invite/ZUyG3mSXFD) — _сообщество энтузиастов и разработчиков, работающих над «Войти с помощью Ethereum» и протоколом Ethereum Follow_
+- [Veramo Labs](https://discord.gg/sYBUXpACh4) — _сообщество разработчиков, которые вносят свой вклад в создание фреймворка для верифицируемых данных для приложений_
+- [walt.id](https://discord.com/invite/AW8AgqJthZ) — _сообщество разработчиков и создателей, работающих над вариантами использования децентрализованной идентификации в различных отраслях_
diff --git a/public/content/translations/ru/defi/index.md b/public/content/translations/ru/defi/index.md
index e3fc8f94c33..39963a800f7 100644
--- a/public/content/translations/ru/defi/index.md
+++ b/public/content/translations/ru/defi/index.md
@@ -1,15 +1,16 @@
---
-title: Децентрализованные финансы (DeFi)
-description: Обзор DeFi на Ethereum
+title: "Децентрализованные финансы (DeFi)"
+metaTitle: "Что такое DeFi? | Преимущества и пользование децентрализованными финансами"
+description: "Обзор DeFi на Ethereum"
lang: ru
template: use-cases
emoji: ":money_with_wings:"
image: /images/use-cases/defi.png
-alt: Логотип Eth, составленный из деталей Лего.
+alt: "Логотип Eth, составленный из деталей Лего."
sidebarDepth: 2
-summaryPoint1: Глобальная открытая альтернатива существующей финансовой системе.
-summaryPoint2: Продукты, которые позволяют вам заимствовать, сберегать, инвестировать, торговать и не только.
-summaryPoint3: На основе технологии с открытым исходным кодом, с которой программировать может каждый.
+summaryPoint1: "Глобальная открытая альтернатива существующей финансовой системе."
+summaryPoint2: "Продукты, которые позволяют вам заимствовать, сберегать, инвестировать, торговать и не только."
+summaryPoint3: "На основе технологии с открытым исходным кодом, с которой программировать может каждый."
---
DeFi — это открытая глобальная финансовая система, созданная для эпохи Интернета. Это альтернатива непрозрачной системе со строгим контролем, базирующейся на используемых десятилетиями процессах и инфраструктуре. Она дает вам возможность контролировать и видеть ваши деньги. DeFi открывает пользователю глобальные рынки, создает альтернативы национальным валютам и стандартным банковским продуктам. Продукты DeFi открывают доступ к финансовым сервисам всем, у кого есть доступ к Интернету. Они в значительной степени принадлежат самим пользователям, которые и обеспечивают их функционирование. К настоящему времени через DeFi уже прошло криптовалютных транзакций на десятки миллиардов долларов, и этот объем растет с каждым днем.
@@ -37,25 +38,25 @@ DeFi — это обобщенный термин для финансовых п
### Сравнение {#defi-comparison}
-| DeFi | Традиционные финансы |
-| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
-| Вы держите ваши активы. | Ваши активы держат компании. |
-| Вы контролируете, куда идут ваши деньги и как они тратятся. | Вы должны доверять компаниям и верить, что они не злоупотребят вашими деньгами, давая их взаймы рискованным заемщикам. |
-| Перевод активов происходит в считанные минуты. | Платежи могут занять несколько дней из-за дополнительных проверок. |
-| Транзакционная деятельность носит псевдонимный характер. | Транзакционная деятельность носит личный характер. |
-| Система DeFi открыта для каждого. | Вы должны подать заявку на использование финансовых услуг. |
-| Рынки всегда открыты. | Рынки закрываются, потому что сотрудникам нужны перерывы. |
+| DeFi | Традиционные финансы |
+| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Вы держите ваши активы. | Ваши активы держат компании. |
+| Вы контролируете, куда идут ваши деньги и как они тратятся. | Вы должны доверять компаниям и верить, что они не злоупотребят вашими деньгами, давая их взаймы рискованным заемщикам. |
+| Перевод активов происходит в считанные минуты. | Платежи могут занять несколько дней из-за дополнительных проверок. |
+| Транзакционная деятельность носит псевдонимный характер. | Транзакционная деятельность носит личный характер. |
+| Система DeFi открыта для каждого. | Вы должны подать заявку на использование финансовых услуг. |
+| Рынки всегда открыты. | Рынки закрываются, потому что сотрудникам нужны перерывы. |
| Все построено на прозрачности: любой может просмотреть данные транзакции и проверить, как работает система. | Активность финансовых учреждений скрыта: вы не можете просмотреть их кредитную историю, сведения об их активах и так далее. |
- Взглянуть на приложения DeFi
+ Изучите приложения DeFi
## Все началось с Bitcoin... {#bitcoin}
Биткоин во многих отношениях был первым приложением DeFi. Биткоин позволяет вам действительно владеть валютой, контролировать ее и отправлять в любую точку мира. Это достигается за счет предоставления возможности большому числу людей, которые не доверяют друг другу, согласовывать реестр без необходимости в доверенном посреднике. Биткоин открыт для всех, и никто не имеет полномочий изменять его правила. Правила Bitcoin, такие как его дефицит и открытость, прописаны в технологии. Это не похоже на традиционные финансы, где правительства могут печатать деньги, которые обесценивают ваши сбережения, а компании могут закрыть рынки.
-Ethereum построен на этом. Как и в Bitcoin, правила не могут измениться, у всех есть доступ. Но здесь за счет [смарт-контрактов](/glossary/#smart-contract) эти цифровые деньги можно программировать, так что средства можно не только хранить и отправлять.
+Ethereum построен на этом. Как и в Bitcoin, правила не могут измениться, у всех есть доступ. Но это также делает эти цифровые деньги программируемыми с помощью [смарт-контрактов](/glossary/#smart-contract), что позволяет выйти за рамки простого хранения и отправки ценности.
@@ -65,10 +66,10 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
-
+
Изучите наши предложения по приложениям DeFi, если вы только осваиваетесь в Ethereum.
- Взглянуть на приложения DeFi
+ Изучите приложения DeFi
@@ -80,12 +81,12 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
- [Отправка денег по всему миру](#send-money)
- [Потоковая передача денег по всему миру](#stream-money)
- [Доступ к стабильным валютам](#stablecoins)
-- [Заем средств с залогом](#lending)
+- [Заем средств под залог](#lending)
- [Заем средств без залога](#flash-loans)
-- [Накопления в криптовалюте](#saving)
+- [Начните сберегать в криптовалюте](#saving)
- [Торговля токенами](#swaps)
- [Увеличение своего портфеля](#investing)
-- [Финансирование своих идей](#crowdfunding)
+- [Финансирование ваших идей](#crowdfunding)
- [Покупка страховки](#insurance)
- [Управление своим портфелем](#aggregators)
@@ -93,33 +94,33 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
### Быстрая отправка денег по всему миру {#send-money}
-В качестве блокчейна Ethereum предназначен для отправки транзакций безопасным и глобальным путем. Как и Bitcoin, Ethereum делает перевод денег по всему миру таким же простым, как и отправка электронной почты. Просто введите [имя ENS](/glossary/#ens) получателя (например, bob.eth) или адрес его счета в своем кошельке, и ваш платеж поступит непосредственно к нему в течение (как правило) нескольких минут. Чтобы отправлять или получать платежи, вам понадобится [кошелек](/wallets/).
+В качестве блокчейна Ethereum предназначен для отправки транзакций безопасным и глобальным путем. Как и Bitcoin, Ethereum делает перевод денег по всему миру таким же простым, как и отправка электронной почты. Просто введите [имя ENS](/glossary/#ens) получателя (например, bob.eth) или адрес его счета из вашего кошелька, и ваш платеж поступит непосредственно ему в течение нескольких минут (обычно). Чтобы отправлять или получать платежи, вам понадобится [кошелек](/wallets/).
- Посмотреть платежные децентрализованные приложения
+ Посмотрите платежные децентрализованные приложения
#### Передавайте деньги по всему миру... {#stream-money}
Вы также можете передавать деньги через Ethereum. Это позволяет вам выплачивать кому-то зарплату за секунду, предоставляя доступ к деньгам, когда им это нужно. Или арендовать что-нибудь за секунду, например склад или электросамокат.
-Если вы не хотите отправлять или передавать [ETH](/glossary/#ether) из-за их высокой волатильности, на Ethereum есть альтернативные валюты: [стейблкоины](/glossary/#stablecoin).
+А если вы не хотите отправлять или передавать [ETH](/glossary/#ether) из-за его высокой волатильности, то в Ethereum есть альтернативные валюты: [стейблкоины](/glossary/#stablecoin).
-### Получите доступ к стабильным валютам {#stablecoins}
+### Доступ к стабильным валютам {#stablecoins}
Неустойчивость криптовалют является проблемой для многих финансовых продуктов и общих расходов. Сообщество DeFi решило это с помощью стейблкойнов. Их стоимость привязана к другому активу, обычно к популярной валюте, такой как доллар.
Монеты, такие как Dai или USDC, имеют стоимость, которая остается в пределах нескольких центов от доллара. Это делает их идеальными для заработка или розничной торговли. Многие жители Латинской Америки использовали стейблкойны в качестве средства защиты своих сбережений во время значительной неопределенности по отношению к валютам, выпускаемым правительствами.
- Подробнее о стейблкойнах
+Подробнее о стейблкоинах
-### Займы {#lending}
+### Заимствование {#lending}
Заем денег от децентрализованных поставщиков происходит в двух основных вариантах.
@@ -127,16 +128,16 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
- Основанный на пуле (Pool-based): кредиторы предоставляют средства (ликвидность), из которых берут в долг заемщики.
- Посмотреть децентрализованные приложения для займа
+ Посмотрите децентрализованные приложения для займов
Существует множество преимуществ использования децентрализованных кредитов...
-#### Заимствование с сохранением приватности {#borrowing-privacy}
+#### Конфиденциальное заимствование {#borrowing-privacy}
Сегодня кредитование и заимствование денег вращаются вокруг лиц, вовлеченных в эту деятельность. Банкам необходимо знать, сможете ли вы погасить кредит, прежде чем выдавать его.
-Децентрализованное кредитование работает без необходимости идентификации любой из сторон. Вместо этого заемщик должен предоставить залог, который кредитор автоматически получит, если его кредит не будет погашен. Некоторые кредиторы даже принимают [NFT](/glossary/#nft) в качестве обеспечения. NFT — это уникальный актив, например картина. [Подробнее об NFT](/nft/)
+Децентрализованное кредитование работает без необходимости идентификации любой из сторон. Вместо этого заемщик должен предоставить залог, который кредитор автоматически получит, если его кредит не будет погашен. Некоторые кредиторы даже принимают [NFT](/glossary/#nft) в качестве залога. NFT — это уникальный актив, например картина. [Подробнее об NFT](/nft/)
Это позволяет вам занимать деньги без проверки кредитоспособности или передачи личной информации.
@@ -144,11 +145,11 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
Когда вы используете децентрализованного кредитора, у вас есть доступ к средствам со всего мира, а не только к средствам, находящимся на хранении в выбранном вами банке или учреждении. Это делает кредиты более доступными и улучшает процентные ставки.
-#### Оптимизация налогов {#tax-efficiencies}
+#### Налоговая эффективность {#tax-efficiencies}
-Заем может дать вам доступ к интересующим вас средствам, не требующим продажи ETH (облагаемого налогом действия). Вместо этого вы можете использовать ETH в качестве залога для займа стейблкоинов. Это дает необходимый вам приток денег и позволяет сохранить ETH. Стейблкойны — это токены, которые гораздо лучше для тех, кто нуждается в наличных деньгах, так как они не меняются в цене, в отличие от ETH. [Подробнее о стейблкойнах](#stablecoins)
+Заем может дать вам доступ к интересующим вас средствам, не требующим продажи ETH (облагаемого налогом действия). Вместо этого вы можете использовать ETH в качестве залога для займа стейблкоинов. Это дает необходимый вам приток денег и позволяет сохранить ETH. Стейблкойны — это токены, которые гораздо лучше для тех, кто нуждается в наличных деньгах, так как они не меняются в цене, в отличие от ETH. [Подробнее о стейблкоинах](#stablecoins)
-#### Мгновенные займы {#flash-loans}
+#### Срочные займы {#flash-loans}
Мгновенные займы — это более экспериментальная форма децентрализованного кредитования, позволяющая заимствовать без залога или предоставления любой личной информации.
@@ -183,13 +184,13 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
Вы можете получать проценты от своей криптовалюты, предоставляя ее в долг, и видеть, как ваши средства растут в режиме реального времени. Прямо сейчас процентные ставки намного выше, чем то, что вы, вероятно, получите в вашем местном банке (если вам повезло и вы сможете получить к нему доступ). Приведем пример.
-- Вы одалживаете свои 100 Dai (это [стейблкойн](/stablecoins/)) платформе вроде Aave.
+- Вы одалживаете свои 100 Dai, [стейблкоин](/stablecoins/), такому продукту, как Aave.
- Вы получаете 100 Aave Dai (aDai), что являет собой токен, представляющий ваш одолженный Dai.
-- Ваш aDai будет увеличиваться в зависимости от процентной ставки, и вы сможете увидеть рост баланса в вашем кошельке. В зависимости от [годовой процентной ставки](/glossary/#apr), через несколько дней или даже часов баланс вашего кошелька будет выглядеть примерно так: 100,1234.
+- Ваш aDai будет увеличиваться в зависимости от процентной ставки, и вы сможете увидеть рост баланса в вашем кошельке. В зависимости от [годовой процентной ставки (APR)](/glossary/#apr), баланс вашего кошелька через несколько дней или даже часов будет составлять примерно 100,1234!
- Вы можете вывести сумму обычного Dai, равную вашему балансу aDai, в любое время.
- Посмотреть кредитные децентрализованные приложения
+ Посмотрите децентрализованные приложения для вкладов
#### Беспроигрышные лотереи {#no-loss-lotteries}
@@ -205,7 +206,7 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
Призовой фонд формируется за счет всех процентов, полученных от предоставления депозитов за билеты, как в приведенном выше примере кредитования.
- Попробовать PoolTogether
+ Попробуйте PoolTogether
@@ -217,7 +218,7 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
Например, если вы хотите использовать беспроигрышную лотерею PoolTogether (описанную выше), вам понадобится токен, такой как Dai или USDC. DEX позволяют обменивать ваши ETH на эти токены и обратно, когда вы закончите.
- Смотреть биржи токенов
+ Посмотрите биржи токенов
@@ -229,24 +230,24 @@ Ethereum построен на этом. Как и в Bitcoin, правила н
Когда вы используете централизованную биржу, вы должны внести свои активы перед торговлей и доверить бирже заботу о них. Пока ваши активы депонированы, они подвержены риску, поскольку централизованные биржи являются привлекательными целями для хакеров.
- Посмотреть торговые децентрализованные приложения
+ Посмотрите торговые децентрализованные приложения
-### Увеличение своего портфеля {#investing}
+### Рост вашего портфеля {#investing}
На Ethereum есть продукты для управления фондами, которые будут стараться развивать ваш портфель на основе выбранной вами стратегии. Это происходит автоматически, открыто для всех и не требует участия менеджера, получающего долю от вашей прибыли.
-Хорошим примером является фонд [ DeFi Pulse Index (DPI)](https://defipulse.com/blog/defi-pulse-index/). Он выполняет автоматическую ребалансировку, чтобы ваш портфель всегда включал лучшие по рыночной капитализации токены DeFi. Вам не придется управлять мелочами, и вы сможете выйти из фонда, когда захотите.
+Хорошим примером является [индексный фонд DeFi Pulse (DPI)](https://defipulse.com/blog/defi-pulse-index/). Он выполняет автоматическую ребалансировку, чтобы ваш портфель всегда включал лучшие по рыночной капитализации токены DeFi. Вам не придется управлять мелочами, и вы сможете выйти из фонда, когда захотите.
- Смотреть инвестиционные децентрализованные приложения
+ Посмотрите инвестиционные децентрализованные приложения
-### Финансирование своих идей {#crowdfunding}
+### Финансирование ваших идей {#crowdfunding}
Ethereum является идеальной платформой для краудфандинга:
@@ -255,14 +256,14 @@ Ethereum является идеальной платформой для кра
- Сборщики средств могут настроить автоматический возврат, если, например, есть определенный срок и минимальная сумма, которые не были соблюдены.
- Посмотреть краудфандинговые децентрализованные приложения
+ Посмотрите краудфандинговые децентрализованные приложения
#### Квадратичное финансирование {#quadratic-funding}
-Ethereum — это программное обеспечение с открытым исходным кодом, и большая часть работы до сих пор финансируется сообществом. Это привело к развитию новой интересной модели сбора средств: квадратичного финансирования. Это может улучшить способ финансирования всех видов общественных благ в будущем.
+Ethereum — это программное обеспечение с открытым исходным кодом, и большая часть работы до сих пор финансируется сообществом. Это привело к развитию новой интересной модели сбора средств: квадратичного финансирования. И может улучшить способ финансирования всех видов общественных благ в будущем.
-Квадратичное финансирование гарантирует, что проекты, получившие наибольшее финансирование, будут наиболее востребованы. Иными словами, проекты, способствующие улучшению жизни большинства людей. Это работает так:
+Квадратичное финансирование гарантирует, что наибольшее финансирование получают проекты, спрос на которые наиболее уникален. Иными словами, проекты, способствующие улучшению жизни большинства людей. Это работает так:
1. Есть соответствующий пул пожертвованных средств.
2. Начинается раунд публичного финансирования.
@@ -281,10 +282,10 @@ Ethereum — это программное обеспечение с откры
Децентрализованное страхование направлено на то, чтобы сделать страхование более дешевым, ускорить выплаты и увеличить прозрачность. Благодаря большей автоматизации страхование становится более доступным, а выплаты производятся намного быстрее. Данные, используемые для принятия решения по вашей претензии, полностью прозрачны.
-Продукты Ethereum, как и любое программное обеспечение, могут страдать от ошибок и эксплойтов. Так что прямо сейчас многие страховые продукты сосредоточены на защите своих пользователей от потери средств. Однако уже есть проекты, которые начинают страховать все, с чем мы можем столкнуться в реальной жизни. Хорошим примером этого является страхование урожая Etherisc, цель которого — [защитить мелких фермеров в Кении от засух и наводнений](https://blog.etherisc.com/etherisc-teams-up-with-chainlink-to-deliver-crop-insurance-in-kenya-137e433c29dc). Децентрализованное страхование может обеспечить более дешевую страховку для фермеров, цены на которую часто выходят за рамки в традиционном страховании.
+Продукты Ethereum, как и любое программное обеспечение, могут страдать от ошибок и эксплойтов. Так что прямо сейчас многие страховые продукты сосредоточены на защите своих пользователей от потери средств. Однако уже есть проекты, которые начинают страховать все, с чем мы можем столкнуться в реальной жизни. Хорошим примером этого является Crop Cover от Etherisc, целью которого является [защита мелких фермеров в Кении от засух и наводнений](https://blog.etherisc.com/etherisc-teams-up-with-chainlink-to-deliver-crop-insurance-in-kenya-137e433c29dc). Децентрализованное страхование может обеспечить более дешевую страховку для фермеров, цены на которую часто выходят за рамки в традиционном страховании.
- Смотреть страховые децентрализованные приложения
+ Посмотрите страховые децентрализованные приложения
@@ -294,7 +295,7 @@ Ethereum — это программное обеспечение с откры
Среди прочего, вам потребуется способ отслеживания всех ваших инвестиций, займов и сделок. Есть множество продуктов, которые позволяют вам управлять всеми вашими действиями с DeFi из одной программы. В этом прелесть открой архитектуры DeFi. Команды могут создавать интерфейсы, в которых вы можете не только просматривать балансы активов, но также использовать их функции. Это может оказаться полезным во время изучения DeFi.
- Посмотреть децентрализованные приложения для портфелей
+ Посмотрите децентрализованные приложения для портфелей
@@ -303,7 +304,7 @@ Ethereum — это программное обеспечение с откры
DeFi использует криптовалюты и умные контракты для предоставления услуг, не требующих посредников. В современном финансовом мире финансовые учреждения выступают в качестве гарантов сделок. Это дает этим учреждениям огромную власть, потому что через них текут ваши деньги. Кроме того, у миллиардов людей по всему миру может даже не быть доступа к банковскому счету.
-В DeFi смарт-контракт заменяет финансовое учреждение в сделке. Смарт-контракт — это тип учетной записи Ethereum, на котором могут храниться средства и который может отправлять и возвращать их на определенных условиях. Никто не может изменить этот смарт-контракт после его запуска: он всегда будет работать так, как был запрограммирован.
+В DeFi умный контракт заменяет финансовое учреждение в сделке. Смарт-контракт — это тип учетной записи Ethereum, на котором могут храниться средства и который может отправлять и возвращать их на определенных условиях. Никто не может изменить этот смарт-контракт после его запуска: он всегда будет работать так, как был запрограммирован.
Контракт, предназначенный для выплаты пособий или карманных денег, может быть запрограммирован на отправку денег со счета A на счет B каждую пятницу. И он будет делать это до тех пор, пока на счете А есть необходимые средства. Никто не может изменить контракт и добавить аккаунт C в качестве получателя для кражи средств.
@@ -323,41 +324,42 @@ Ethereum — идеальная основа для DeFi по ряду прич
Вы можете разделить DeFi на слои:
1. Блокчейн: Ethereum содержит историю транзакций и состояние счетов.
-2. Активы: [ETH](/what-is-ether/) и другие токены (валюты).
-3. Протоколы — [умные контракты](/glossary/#smart-contract), которые предоставляют функциональные возможности, например сервис, позволяющий децентрализовать кредитование активов.
-4. [Приложения](/apps/): продукты, которые мы используем для управления и доступа к протоколам.
+2. Активы — [ETH](/what-is-ether/) и другие токены (валюты).
+3. Протоколы — [смарт-контракты](/glossary/#smart-contract), которые обеспечивают функциональность, например сервис, позволяющий децентрализованно кредитовать активы.
+4. [Приложения](/apps/) — продукты, которые мы используем для управления протоколами и доступа к ним.
-Примечание. Большая часть DeFi-сервисов использует [стандарт ERC-20](/glossary/#erc-20). Приложения в DeFi используют обертку для ETH под названием Wrapped Ether (WETH). [Подробнее о Wrapped Ether](/wrapped-eth).
+Примечание: многие DeFi-сервисы используют [стандарт ERC-20](/glossary/#erc-20). Приложения в DeFi используют обертку для ETH под названием Wrapped Ether (WETH). [Подробнее о Wrapped Ether](/wrapped-eth).
-## Формирование DeFi {#build-defi}
+## Разработка в DeFi {#build-defi}
DeFi — это движение с открытым исходным кодом. Все протоколы и приложения DeFi открыты для ваших исследований, разветвлений и инноваций. Благодаря этому многоуровневому стеку (все они используют один и тот же блокчейн и активы) протоколы можно смешивать и сопоставлять, чтобы открыть уникальные комбинированные возможности.
- Подробнее о децентрализованных приложениях
+ Подробнее о создании децентрализованных приложений
-## Дополнительная литература {#further-reading}
+## Дополнительные материалы {#further-reading}
-### Данные о DeFi {#defi-data}
+### Данные DeFi {#defi-data}
- [DeFi Prime](https://defiprime.com/)
- [DeFi Llama](https://defillama.com/)
### Статьи о DeFi {#defi-articles}
-- [Руководство по DeFi для начинающих](https://blog.coinbase.com/a-beginners-guide-to-decentralized-finance-defi-574c68ff43c4) — _Сид Коэльо-Прабху, 6 января 2020 г._
+- [Руководство по DeFi для начинающих](https://blog.coinbase.com/a-beginners-guide-to-decentralized-finance-defi-574c68ff43c4) — _Сид Коэльо-Прабху, 6 января 2020 г._
+- [Руководство EEA по оценке рисков в DeFi](https://entethalliance.org/specs/defi-risks/) — обзор, подготовленный при поддержке представителей отрасли, о том, как выявлять и оценивать ключевые риски в протоколах DeFi.
### Видео {#videos}
-- [Finematics — децентрализованное финансовое образование](https://finematics.com/) — _Видео о DeFi_
-- [The Defiant](https://www.youtube.com/playlist?list=PLaDcID4s1KronHMKojfjwiHL0DdQEPDcq) — _Основы DeFi: все, что нужно знать, чтобы начать работу в этом иногда непонятном пространстве._
+- [Finematics — обучение децентрализованным финансам](https://finematics.com/) — _Видео о DeFi_
+- [The Defiant](https://www.youtube.com/playlist?list=PLaDcID4s1KronHMKojfjwiHL0DdQEPDcq) — _Основы DeFi: все, что вам нужно знать, чтобы начать работу в этой порой озадачивающей области._
- [Whiteboard Crypto](https://youtu.be/17QRFlml4pA) _Что такое DeFi?_
### Сообщества {#communities}
-- [DeFi Llama, сервер Discord](https://discord.defillama.com/)
-- [DeFi Pulse, сервер Discord](https://discord.gg/Gx4TCTk)
+- [Discord-сервер DeFi Llama](https://discord.defillama.com/)
+- [Discord-сервер DeFi Pulse](https://discord.gg/Gx4TCTk)
diff --git a/public/content/translations/ru/desci/index.md b/public/content/translations/ru/desci/index.md
index 78836d03ea3..17bedbb50ed 100644
--- a/public/content/translations/ru/desci/index.md
+++ b/public/content/translations/ru/desci/index.md
@@ -1,15 +1,15 @@
---
-title: Децентрализованная наука (DeSci)
-description: Обзор о децентрализованной науке на основе Ethereum
+title: "Децентрализованная наука (DeSci)"
+description: "Обзор о децентрализованной науке на основе Ethereum"
lang: ru
template: use-cases
emoji: ":microscope:"
sidebarDepth: 2
image: /images/future_transparent.png
alt: ""
-summaryPoint1: Глобальная открытая альтернатива существующей научной системе.
-summaryPoint2: Технология, позволяющая ученым привлекать финансирование, проводить эксперименты, делиться данными, распределять идеи и т. д.
-summaryPoint3: Основан на движении за открытую науку.
+summaryPoint1: "Глобальная открытая альтернатива существующей научной системе."
+summaryPoint2: "Технология, позволяющая ученым привлекать финансирование, проводить эксперименты, делиться данными, распределять идеи и т. д."
+summaryPoint3: "Основан на движении за открытую науку."
---
## Что такое децентрализованная наука (DeSci)? {#what-is-desci}
diff --git a/public/content/translations/ru/developers/docs/accounts/index.md b/public/content/translations/ru/developers/docs/accounts/index.md
index 1453b112b48..45a0a2f00ef 100644
--- a/public/content/translations/ru/developers/docs/accounts/index.md
+++ b/public/content/translations/ru/developers/docs/accounts/index.md
@@ -1,28 +1,28 @@
---
-title: Аккаунты Ethereum
-description: Объяснение аккаунтов Ethereum, их структур данных и их связи с криптографической парой ключей.
+title: "Аккаунты Ethereum"
+description: "Объяснение аккаунтов Ethereum, их структур данных и их связи с криптографической парой ключей."
lang: ru
---
-Аккаунт Ethereum — это сущность с балансом эфира (ETH), которая может отправлять транзакции в Ethereum. Аккаунты могут управляться пользователем или развертываться как умные контракты.
+Аккаунт Ethereum - это сущность с балансом эфира (ETH), которая может отправлять сообщения в сети Ethereum. Аккаунты могут управляться пользователем или развертываться как умные контракты.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Чтобы лучше понять эту страницу, мы советуем вам вначале прочитать наше [введение в Ethereum](/developers/docs/intro-to-ethereum/).
+Чтобы вы лучше поняли эту страницу, мы рекомендуем вам сначала прочитать наше [введение в Ethereum](/developers/docs/intro-to-ethereum/).
## Типы аккаунтов {#types-of-account}
В Ethereum есть два типа аккаунтов:
- Внешняя учетная запись (EOA) – управляется кем-либо с помощью приватных ключей.
-- Аккаунт контракта – смарт-контракт, развернутый в сети и управляемый кодом. Подробнее об [умных контрактах](/developers/docs/smart-contracts/)
+- Аккаунт контракта – смарт-контракт, развернутый в сети и управляемый кодом. Узнайте об [умных контрактах](/developers/docs/smart-contracts/)
Оба типа аккаунтов имеют возможность:
- Получать, удерживать и отправлять ETH и токены
- Взаимодействовать с развернутыми умными контрактами
-### Основные отличия {#key-differences}
+### Ключевые различия {#key-differences}
**Внешний**
@@ -34,20 +34,21 @@ lang: ru
**Контракт**
- Создание контракта имеет свою цену, потому что вы используете сетевое хранилище
-- Может отправлять транзакции только в ответ на получение транзакции
+- Может отправлять сообщения только в ответ на получение транзакции
- Транзакции с внешнего аккаунта на аккаунт контракта могут запустить код, который может выполнить множество различных действий, таких как передача токенов или даже создание нового контракта
- У аккаунтов контракта нет приватных ключей. Вместо этого они управляются логикой кода смарт-контракта.
-## Аккаунт проверен {#an-account-examined}
+## Изучение аккаунта {#an-account-examined}
У аккаунтов Ethereum есть четыре поля:
-- `nonce` – счетчик с указанием количества транзакций, переданных с внешней учетной записи, или количества контрактов, созданных в контрактном аккаунте. Только одна транзакция с заданным значением nonce может быть выполнена для каждого аккаунта, что защищает от атак повтора, в которых неоднократно транслируются и повторно выполняются подписанные транзакции.
-- `balance` — количество wei, принадлежащих этому адресу. Wei — это часть ЕТН, один ETH равен 1e+18 Wei.
-- `codeHash` — этот хэш ссылается на _код_ учетной записи на виртуальной машине Ethereum (EVM). Аккаунты контракта имеют запрограммированные фрагменты кода, которые могут выполнять различные операции. Этот EVM-код запускается при вызове аккаунта. Изменить это нельзя, в отличие от других полей аккаунта. Все фрагменты кода содержатся в базе состояний под соответствующими хэшами для последующего извлечения. Это значение хэша известно как codeHash. Для внешних аккаунтов поле codeHash — это хэш пустой строки.
-- `storageRoot` — также известен как хэш хранилища. 256-битный хэш корня «дерева Меркла Патрисии», кодирующего содержимое хранилища аккаунта, кодируется в дереве как отображение из 256-битного хэша Keccak 256-битных целых ключей в 256-битные значения RLP. Дерево кодирует хэш хранилища этого аккаунта и по умолчанию пусто.
+- `nonce` — счетчик, который указывает на количество транзакций, отправленных с внешнего аккаунта, или на количество контрактов, созданных аккаунтом контракта. Только одна транзакция с заданным значением nonce может быть выполнена для каждого аккаунта, что защищает от атак повтора, в которых неоднократно транслируются и повторно выполняются подписанные транзакции.
+- `balance` — количество wei, принадлежащих этому адресу. Wei — это часть ETH, один ETH равен 1e+18 Wei.
+- `codeHash` — этот хэш ссылается на _код_ аккаунта в виртуальной машине Ethereum (EVM). Аккаунты контракта имеют запрограммированные фрагменты кода, которые могут выполнять различные операции. Этот EVM-код запускается при вызове аккаунта. Изменить это нельзя, в отличие от других полей аккаунта. Все фрагменты кода содержатся в базе состояний под соответствующими хэшами для последующего извлечения. Это значение хэша известно как codeHash. Для внешних аккаунтов поле codeHash — это хэш пустой строки.
+- `storageRoot` — также известен как хэш хранилища. 256-битный хэш корневого узла [дерева Меркла — Патрисии](/developers/docs/data-structures-and-encoding/patricia-merkle-trie/), кодирующий содержимое хранилища аккаунта (сопоставление 256-битных целочисленных значений). В дереве он закодирован как сопоставление 256-битного хэша Keccak от 256-битных целочисленных ключей с 256-битными целочисленными значениями, закодированными по RLP. Дерево кодирует хэш хранилища этого аккаунта и по умолчанию пусто.
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Диаграмма адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
## Внешние аккаунты и пары ключей {#externally-owned-accounts-and-key-pairs}
@@ -67,36 +68,36 @@ lang: ru
`fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036415f`
-Публичный ключ генерируется из приватного ключа с помощью [цифрового алгоритма подписи эллиптических кривых](https://wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm). Для получения публичного адреса своего аккаунта берутся последние 20 байтов хэша Keccak-256 публичного ключа и добавляется `0x` в начало.
+Публичный ключ генерируется из приватного ключа с помощью [алгоритма цифровой подписи на эллиптических кривых](https://wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm). Для получения публичного адреса своего аккаунта возьмите последние 20 байтов хэша Keccak-256 от публичного ключа и добавьте `0x` в начало.
-Это означает, что внешняя учетная запись (EOA) имеет 42-значный адрес (20-байтовый сегмент, состоящий из 40 шестнадцатеричных символов и префикса `0x`).
+Это означает, что внешний аккаунт (EOA) имеет 42-символьный адрес (20-байтовый сегмент, который состоит из 40 шестнадцатеричных символов и префикса `0x`).
Пример:
`0x5e97870f263700f46aa00d967821199b9bc5a120`
-Следующий пример показывает, как использовать инструмент подписи под названием [Clef](https://geth.ethereum.org/docs/tools/clef/introduction), чтобы создать новый аккаунт. Clef — это утилита для управления аккаунтом и подписями, идущая в комплекте с клиентом Ethereum — [Geth](https://geth.ethereum.org). Команда `clef newaccount` создает новую пару ключей и сохраняет их в зашифрованном хранилище ключей.
+В следующем примере показано, как с помощью инструмента для подписи под названием [Clef](https://geth.ethereum.org/docs/tools/clef/introduction) создать новый аккаунт. Clef — это инструмент для управления аккаунтами и создания подписей, который поставляется в комплекте с клиентом Ethereum, [Geth](https://geth.ethereum.org). Команда `clef newaccount` создает новую пару ключей и сохраняет их в зашифрованном хранилище ключей.
```
> clef newaccount --keystore
-Please enter a password for the new account to be created:
+Введите пароль для создаваемого аккаунта:
>
------------
-INFO [10-28|16:19:09.156] Your new key was generated address=0x5e97870f263700f46aa00d967821199b9bc5a120
-WARN [10-28|16:19:09.306] Please backup your key file path=/home/user/go-ethereum/data/keystore/UTC--2022-10-28T15-19-08.000825927Z--5e97870f263700f46aa00d967821199b9bc5a120
-WARN [10-28|16:19:09.306] Please remember your password!
-Generated account 0x5e97870f263700f46aa00d967821199b9bc5a120
+INFO [10-28|16:19:09.156] Ваш новый ключ сгенерирован address=0x5e97870f263700f46aa00d967821199b9bc5a120
+WARN [10-28|16:19:09.306] Пожалуйста, создайте резервную копию файла ключа path=/home/user/go-ethereum/data/keystore/UTC--2022-10-28T15-19-08.000825927Z--5e97870f263700f46aa00d967821199b9bc5a120
+WARN [10-28|16:19:09.306] Пожалуйста, запомните ваш пароль!
+Сгенерированный аккаунт 0x5e97870f263700f46aa00d967821199b9bc5a120
```
[Документация Geth](https://geth.ethereum.org/docs)
-Возможно получение новых публичных ключей из вашего приватного ключа, но получить приватный ключ, зная публичные, нельзя. Крайне важно хранить секретные ключи в безопасности и как следует из названия **В СЕКРЕТЕ**.
+Возможно получить новые публичные ключи из вашего приватного ключа, но невозможно получить приватный ключ из публичных ключей. Крайне важно хранить ваши приватные ключи в безопасности и, как следует из названия, **ПРИВАТНЫМИ**.
Для подписи сообщений и транзакций, которые выводят подпись, необходим приватный ключ. Затем другие пользователи могут проверить подлинность подписи с помощью вашего публичного ключа. В своем приложении вы можете использовать библиотеку JavaScript для отправки транзакций в сеть.
-## Аккаунты контракта {#contract-accounts}
+## Аккаунты контрактов {#contract-accounts}
Аккаунты контракта также имеют шестнадцатеричный адрес из 42 символов:
@@ -112,11 +113,11 @@ Generated account 0x5e97870f263700f46aa00d967821199b9bc5a120
[Подробнее о ключах валидатора](/developers/docs/consensus-mechanisms/pos/keys/).
-## Заметка о кошельках {#a-note-on-wallets}
+## Примечание о кошельках {#a-note-on-wallets}
Аккаунт не является кошельком. Кошелек — это интерфейс или приложение, которое позволяет взаимодействовать с аккаунтом Ethereum, внешним аккаунтом или аккаунтом контракта.
-## Визуализация {#a-visual-demo}
+## Наглядная демонстрация {#a-visual-demo}
Посмотрите, как Остин описывает хэш-функции и пары ключей.
@@ -124,13 +125,13 @@ Generated account 0x5e97870f263700f46aa00d967821199b9bc5a120
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Что такое аккаунты Ethereum](https://info.etherscan.com/understanding-ethereum-accounts/) — etherscan
+- [Понимание аккаунтов Ethereum](https://info.etherscan.com/understanding-ethereum-accounts/) — etherscan
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Умные контракты](/developers/docs/smart-contracts/)
- [Транзакции](/developers/docs/transactions/)
diff --git a/public/content/translations/ru/developers/docs/apis/backend/index.md b/public/content/translations/ru/developers/docs/apis/backend/index.md
new file mode 100644
index 00000000000..07f06607be8
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/apis/backend/index.md
@@ -0,0 +1,211 @@
+---
+title: "Бэкенд API библиотек"
+description: "Введение в API клиента Ethereum, с помощью которых можно взаимодействовать с блокчейном из своего приложения."
+lang: ru
+---
+
+Чтобы приложение могло взаимодействовать с блокчейном Ethereum (т. е. считывать данные блокчейна и/или проводить транзакции в сети), оно должно подключиться к узлу Ethereum.
+
+Для этой цели каждый клиент Ethereum реализует спецификацию [JSON-RPC](/developers/docs/apis/json-rpc/), поэтому существует единый набор [методов](/developers/docs/apis/json-rpc/#json-rpc-methods), на которые могут полагаться приложения.
+
+Если вы хотите использовать определенный язык программирования для подключения к узлу Ethereum, в экосистеме существует множество удобных библиотек, которые значительно это упрощают. С помощью этих библиотек разработчики могут писать интуитивные, однострочные методы для инициализации запросов JSON-RPC (под капотом), которые взаимодействуют с Ethereum.
+
+## Предварительные условия {#prerequisites}
+
+Может быть полезно разобраться в [стеке Ethereum](/developers/docs/ethereum-stack/) и [клиентах Ethereum](/developers/docs/nodes-and-clients/).
+
+## Зачем использовать библиотеки? {#why-use-a-library}
+
+Использование библиотеки помогает абстрагироваться от сложности при общении с узлом Ethereum напрямую. Они также предоставляют полезные функции (например, конвертирование ETH в Gwei), позволяя вам, как разработчику, тратить меньше времени на тонкости работы с клиентами Ethereum, и сосредоточиться на уникальных функциях своего приложения.
+
+## Доступные библиотеки {#available-libraries}
+
+### Инфраструктура и сервисы узлов {#infrastructure-and-node-services}
+
+**Alchemy —** **_платформа для разработки на Ethereum._**
+
+- [alchemy.com](https://www.alchemy.com/)
+- [Документация](https://www.alchemy.com/docs/)
+- [GitHub](https://github.com/alchemyplatform)
+- [Discord](https://discord.com/invite/alchemyplatform)
+
+**All That Node -** **_Узел как услуга._**
+
+- [All That Node.com](https://www.allthatnode.com/)
+- [Документация](https://docs.allthatnode.com)
+- [Discord](https://discord.gg/GmcdVEUbJM)
+
+**Blast от Bware Labs -** **_Децентрализованные API для основной сети и тестовых сетей Ethereum._**
+
+- [blastapi.io](https://blastapi.io/)
+- [Документация](https://docs.blastapi.io)
+- [Discord](https://discord.gg/SaRqmRUjjQ)
+
+**BlockPi -** **_Предоставление более эффективных и быстрых RPC-сервисов_**
+
+- [blockpi.io](https://blockpi.io/)
+- [Документация](https://docs.blockpi.io/)
+- [GitHub](https://github.com/BlockPILabs)
+- [Discord](https://discord.com/invite/xTvGVrGVZv)
+
+**Cloudflare Ethereum Gateway.**
+
+- [cloudflare-eth.com](https://www.cloudflare.com/application-services/products/web3/)
+
+**Etherscan - Обозреватель блоков и API для транзакций**
+
+- [Документация](https://docs.etherscan.io/)
+
+**Blockscout - Обозреватель блоков с открытым исходным кодом**
+
+- [Документация](https://docs.blockscout.com/)
+
+**GetBlock-** **_Блокчейн как услуга для разработки Web3_**
+
+- [GetBlock.io](https://getblock.io/)
+- [Документация](https://docs.getblock.io/)
+
+**Infura -** **_API Ethereum как услуга._**
+
+- [infura.io](https://infura.io)
+- [Документация](https://docs.infura.io/api)
+- [GitHub](https://github.com/INFURA)
+
+**Node RPC - _Экономичный провайдер EVM JSON-RPC_**
+
+- [noderpc.xyz](https://www.noderpc.xyz/)
+- [Документация](https://docs.noderpc.xyz/node-rpc)
+
+**NOWNodes - _Полные узлы и обозреватели блоков._**
+
+- [NOWNodes.io](https://nownodes.io/)
+- [Документация](https://nownodes.gitbook.io/documentation)
+
+**QuickNode -** **_Инфраструктура блокчейна как услуга._**
+
+- [quicknode.com](https://quicknode.com)
+- [Документация](https://www.quicknode.com/docs/welcome)
+- [Discord](https://discord.gg/quicknode)
+
+**Rivet -** **_API Ethereum и Ethereum Classic как сервис, основанный на программном обеспечении с открытым исходным кодом._**
+
+- [rivet.cloud](https://rivet.cloud)
+- [Документация](https://rivet.cloud/docs/)
+- [GitHub](https://github.com/openrelayxyz/ethercattle-deployment)
+
+**Zmok -** **_Ориентированные на скорость узлы Ethereum в виде API JSON-RPC/WebSockets._**
+
+- [zmok.io](https://zmok.io/)
+- [GitHub](https://github.com/zmok-io)
+- [Документация](https://docs.zmok.io/)
+- [Discord](https://discord.gg/fAHeh3ka6s)
+
+### Инструменты для разработчиков {#development-tools}
+
+**ethers-kt —** **_асинхронная, высокопроизводительная библиотека на Kotlin/Java/Android для блокчейнов на основе EVM._**
+
+- [GitHub](https://github.com/Kr1ptal/ethers-kt)
+- [Примеры](https://github.com/Kr1ptal/ethers-kt/tree/master/examples)
+- [Discord](https://discord.gg/rx35NzQGSb)
+
+**Nethereum -** **_Библиотека интеграции .NET с открытым исходным кодом для блокчейна._**
+
+- [GitHub](https://github.com/Nethereum/Nethereum)
+- [Документация](http://docs.nethereum.com/en/latest/)
+- [Discord](https://discord.com/invite/jQPrR58FxX)
+
+**Python Tooling -** **_Разнообразные библиотеки для взаимодействия с Ethereum через Python._**
+
+- [py.ethereum.org](https://snakecharmers.ethereum.org/)
+- [web3.py на GitHub](https://github.com/ethereum/web3.py)
+- [Чат web3.py](https://gitter.im/ethereum/web3.py)
+
+**Tatum -** **_Лучшая платформа для разработки на блокчейне._**
+
+- [Tatum](https://tatum.io/)
+- [GitHub](https://github.com/tatumio/)
+- [Документация](https://docs.tatum.io/)
+- [Discord](https://discord.gg/EDmW3kjTC9)
+
+**web3j -** **_Библиотека интеграции Java/Android/Kotlin/Scala для Ethereum._**
+
+- [GitHub](https://github.com/web3j/web3j)
+- [Документация](https://docs.web3j.io/)
+- [Gitter](https://gitter.im/web3j/web3j)
+
+### Блокчейн-сервисы {#blockchain-services}
+
+**BlockCypher -** **_Веб-API для Ethereum._**
+
+- [blockcypher.com](https://www.blockcypher.com/)
+- [Документация](https://www.blockcypher.com/dev/ethereum/)
+
+**Chainbase -** **_Универсальная инфраструктура данных Web3 для Ethereum._**
+
+- [chainbase.com](https://chainbase.com/)
+- [Документация](https://docs.chainbase.com/)
+- [Discord](https://discord.gg/Wx6qpqz4AF)
+
+**Chainstack -** **_Гибкие и выделенные узлы Ethereum как услуга._**
+
+- [chainstack.com](https://chainstack.com)
+- [Документация](https://docs.chainstack.com/)
+- [Справочник по API Ethereum](https://docs.chainstack.com/reference/ethereum-getting-started)
+
+**Coinbase Cloud Node -** **_API инфраструктуры блокчейна._**
+
+- [Coinbase Cloud Node](https://www.coinbase.com/developer-platform)
+- [Документация](https://docs.cdp.coinbase.com/)
+
+**DataHub от Figment -** **_Сервисы API Web3 для основной и тестовых сетей Ethereum._**
+
+- [DataHub](https://www.figment.io/)
+- [Документация](https://docs.figment.io/)
+
+**Moralis -** **_Поставщик EVM API корпоративного уровня._**
+
+- [moralis.io](https://moralis.io)
+- [Документация](https://docs.moralis.io/)
+- [GitHub](https://github.com/MoralisWeb3)
+- [Discord](https://moralis.io/joindiscord/)
+- [Форум](https://forum.moralis.io/)
+
+**NFTPort -** **_API для данных и минтинга Ethereum._**
+
+- [nftport.xyz](https://www.nftport.xyz/)
+- [Документация](https://docs.nftport.xyz/)
+- [GitHub](https://github.com/nftport/)
+- [Discord](https://discord.com/invite/K8nNrEgqhE)
+
+**Tokenview -** **_Универсальная API-платформа для различных блокчейнов._**
+
+- [services.tokenview.io](https://services.tokenview.io/)
+- [Документация](https://services.tokenview.io/docs?type=api)
+- [GitHub](https://github.com/Tokenview)
+
+**Watchdata -** **_Предоставляет простой и надежный API-доступ к блокчейну Ethereum._**
+
+- [Watchdata](https://watchdata.io/)
+- [Документация](https://docs.watchdata.io/)
+- [Discord](https://discord.com/invite/TZRJbZ6bdn)
+
+**Covalent -** **_Расширенные API для более чем 200 блокчейнов._**
+
+- [covalenthq.com](https://www.covalenthq.com/)
+- [Документация](https://www.covalenthq.com/docs/api/)
+- [GitHub](https://github.com/covalenthq)
+- [Discord](https://www.covalenthq.com/discord/)
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
+- [Фреймворки для разработки](/developers/docs/frameworks/)
+
+## Связанные руководства {#related-tutorials}
+
+- [Настройка Web3js для использования блокчейна Ethereum в JavaScript](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/) _— инструкции по настройке Web3js в вашем проекте._
+- [Вызов умного контракта из JavaScript](/developers/tutorials/calling-a-smart-contract-from-javascript/) _— на примере токена DAI вы увидите, как вызывать функции контрактов с помощью JavaScript._
diff --git a/public/content/translations/ru/developers/docs/apis/javascript/index.md b/public/content/translations/ru/developers/docs/apis/javascript/index.md
new file mode 100644
index 00000000000..1b14a85bccc
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/apis/javascript/index.md
@@ -0,0 +1,289 @@
+---
+title: "Библиотеки JavaScript API"
+description: "Введение в клиентские библиотеки JavaScript, позволяющие взаимодействовать с блокчейном из Вашего приложения."
+lang: ru
+---
+
+Чтобы веб-приложение могло взаимодействовать с блокчейном Ethereum (т. е. читать данные блокчейна и/или отправлять транзакции в сеть), оно должно подключиться к узлу Ethereum.
+
+Для этой цели каждый клиент Ethereum реализует спецификацию [JSON-RPC](/developers/docs/apis/json-rpc/), так что существует единый набор [методов](/developers/docs/apis/json-rpc/#json-rpc-methods), на которые могут полагаться приложения.
+
+Если вы используете JavaScript для того чтобы подключиться к узлу Ethereum, можно воспользоваться vanilla JavaScript, но существует также несколько удобных библиотек внутри экосистемы которые упрощают эту задачу. С помощью этих библиотек разработчики могут писать интуитивные, однострочные методы для инициализации запросов JSON-RPC (под капотом), которые взаимодействуют с Ethereum.
+
+Обратите внимание, что после [Слияния](/roadmap/merge/) для запуска узла требуются две связанные части программного обеспечения Ethereum — клиент исполнения и клиент консенсуса. Убедитесь, что у вашего узла есть как клиент исполнения, так и клиент консенсуса. Если ваш узел находится не на локальном компьютере (например, работает на инстансе AWS), соответственно обновите IP-адреса в руководстве. Для получения дополнительной информации см. нашу страницу о [запуске узла](/developers/docs/nodes-and-clients/run-a-node/).
+
+## Предварительные условия {#prerequisites}
+
+Помимо понимания JavaScript, может быть полезно разобраться в [стеке Ethereum](/developers/docs/ethereum-stack/) и [клиентах Ethereum](/developers/docs/nodes-and-clients/).
+
+## Зачем использовать библиотеки? {#why-use-a-library}
+
+Использование библиотеки помогает абстрагироваться от сложности при общении с узлом Ethereum напрямую. Они также предоставляют полезные функции (например, конвертирование ETH в Gwei), позволяя вам, как разработчику, тратить меньше времени на тонкости работы с клиентами Ethereum, и сосредоточиться на уникальных функциях своего приложения.
+
+## Функции библиотеки {#library-features}
+
+### Подключение к узлам Ethereum {#connect-to-ethereum-nodes}
+
+Используя провайдеров, эти библиотеки позволяют вам подключаться к Ethereum и считывать его данные, будь то через JSON-RPC, INFURA, Etherscan, Alchemy или MetaMask.
+
+> **Предупреждение:** Web3.js был заархивирован 4 марта 2025 г. [Прочтите объявление](https://blog.chainsafe.io/web3-js-sunset/). Для новых проектов рассмотрите возможность использования альтернативных библиотек, таких как [ethers.js](https://ethers.org) или [viem](https://viem.sh).
+
+**Пример эфиров**
+
+```js
+// BrowserProvider является оболочкой для стандартного провайдера Web3, который
+// MetaMask внедряет в каждую страницу как window.ethereum
+const provider = new ethers.BrowserProvider(window.ethereum)
+
+// Плагин MetaMask также позволяет подписывать транзакции для
+// отправки эфира и оплаты для изменения состояния в блокчейне.
+// Для этого нам нужен подписант аккаунта...
+const signer = provider.getSigner()
+```
+
+**Web3js примеры**
+
+```js
+var web3 = new Web3("http://localhost:8545")
+// or
+var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
+
+// change provider
+web3.setProvider("ws://localhost:8546")
+// or
+web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546"))
+
+// Using the IPC provider in node.js
+var net = require("net")
+var web3 = new Web3("/Users/myuser/Library/Ethereum/geth.ipc", net) // mac os path
+// or
+var web3 = new Web3(
+ new Web3.providers.IpcProvider("/Users/myuser/Library/Ethereum/geth.ipc", net)
+) // mac os path
+// on windows the path is: "\\\\.\\pipe\\geth.ipc"
+// on linux the path is: "/users/myuser/.ethereum/geth.ipc"
+```
+
+После настройки вы сможете запросить блокчейн для:
+
+- номер блока
+- прогноз газа
+- события смарт-контракта
+- идентификатор сети
+- и многое другое...
+
+### Функциональность кошелька {#wallet-functionality}
+
+Эти библиотеки позволяют создавать кошельки, управлять ключами и подписывать транзакции.
+
+Вот примеры с эфиров
+
+```js
+// Создание экземпляра кошелька из мнемонической фразы...
+mnemonic =
+ "announce room limb pattern dry unit scale effort smooth jazz weasel alcohol"
+walletMnemonic = Wallet.fromPhrase(mnemonic)
+
+// ...или из приватного ключа
+walletPrivateKey = new Wallet(walletMnemonic.privateKey)
+
+walletMnemonic.address === walletPrivateKey.address
+// true
+
+// Адрес в виде Promise согласно API подписывающей стороны (Signer)
+walletMnemonic.getAddress()
+// { Promise: '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1' }
+
+// Адрес кошелька также доступен синхронно
+walletMnemonic.address
+// '0x71CB05EE1b1F506fF321Da3dac38f25c0c9ce6E1'
+
+// Внутренние криптографические компоненты
+walletMnemonic.privateKey
+// '0x1da6847600b0ee25e9ad9a52abbd786dd2502fa4005dd5af9310b7cc7a3b25db'
+walletMnemonic.publicKey
+// '0x04b9e72dfd423bcf95b3801ac93f4392be5ff22143f9980eb78b3a860c4843bfd04829ae61cdba4b3b1978ac5fc64f5cc2f4350e35a108a9c9a92a81200a60cd64'
+
+// Мнемоника кошелька
+walletMnemonic.mnemonic
+// {
+// locale: 'en',
+// path: 'm/44\'/60\'/0\'/0/0',
+// phrase: 'announce room limb pattern dry unit scale effort smooth jazz weasel alcohol'
+// }
+
+// Примечание: кошелек, созданный с помощью приватного ключа, не
+// имеет мнемоники (это предотвращается выводом)
+walletPrivateKey.mnemonic
+// null
+
+// Подписание сообщения
+walletMnemonic.signMessage("Hello World")
+// { Promise: '0x14280e5885a19f60e536de50097e96e3738c7acae4e9e62d67272d794b8127d31c03d9cd59781d4ee31fb4e1b893bd9b020ec67dfa65cfb51e2bdadbb1de26d91c' }
+
+tx = {
+ to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
+ value: utils.parseEther("1.0"),
+}
+
+// Подписание транзакции
+walletMnemonic.signTransaction(tx)
+// { Promise: '0xf865808080948ba1f109551bd432803012645ac136ddd64dba72880de0b6b3a7640000801ca0918e294306d177ab7bd664f5e141436563854ebe0a3e523b9690b4922bbb52b8a01181612cec9c431c4257a79b8c9f0c980a2c49bb5a0e6ac52949163eeb565dfc' }
+
+// Метод connect возвращает новый экземпляр
+// кошелька, подключенного к провайдеру
+wallet = walletMnemonic.connect(provider)
+
+// Запрос к сети
+wallet.getBalance()
+// { Promise: { BigNumber: "42" } }
+wallet.getTransactionCount()
+// { Promise: 0 }
+
+// Отправка эфира
+wallet.sendTransaction(tx)
+```
+
+[Прочесть полную документацию](https://docs.ethers.io/v5/api/signer/#Wallet)
+
+После настройки вы сможете:
+
+- создать аккаунт
+- отправить Транзакцию
+- подписать транзакцию
+- и многое другое...
+
+### Взаимодействие с функциями смарт-контрактов {#interact-with-smart-contract-functions}
+
+Клиентские библиотеки JavaScript позволяют Вашему приложению вызывать функции смарт-контрактов, считывая двоичный интерфейс приложения (ABI) скомпилированного контракта.
+
+ABI, по сути, объясняет функции контракта в формате JSON и позволяет использовать его как обычный объект JavaScript.
+
+Таким образом, выглядит Solidity контракт:
+
+```solidity
+contract Test {
+ uint a;
+ address d = 0x12345678901234567890123456789012;
+
+ constructor(uint testInt) { a = testInt;}
+
+ event Event(uint indexed b, bytes32 c);
+
+ event Event2(uint indexed b, bytes32 c);
+
+ function foo(uint b, bytes32 c) returns(address) {
+ Event(b, c);
+ return d;
+ }
+}
+```
+
+Приведет к следующему JSON:
+
+```json
+[{
+ "type":"constructor",
+ "payable":false,
+ "stateMutability":"nonpayable"
+ "inputs":[{"name":"testInt","type":"uint256"}],
+ },{
+ "type":"function",
+ "name":"foo",
+ "constant":false,
+ "payable":false,
+ "stateMutability":"nonpayable",
+ "inputs":[{"name":"b","type":"uint256"}, {"name":"c","type":"bytes32"}],
+ "outputs":[{"name":"","type":"address"}]
+ },{
+ "type":"event",
+ "name":"Event",
+ "inputs":[{"indexed":true,"name":"b","type":"uint256"}, {"indexed":false,"name":"c","type":"bytes32"}],
+ "anonymous":false
+ },{
+ "type":"event",
+ "name":"Event2",
+ "inputs":[{"indexed":true,"name":"b","type":"uint256"},{"indexed":false,"name":"c","type":"bytes32"}],
+ "anonymous":false
+}]
+```
+
+Вы сможете:
+
+- Отправить транзакцию к умному контракту и выполнить его метод
+- Сделать вызов для оценки газа, который будет выполняться при запуске в EVM
+- Развернуть контракт
+- И другое...
+
+### Вспомогательные функции {#utility-functions}
+
+Утилитные функции дают вам удобные shortcuts, которые делают строительство с Ethereum немного проще.
+
+Значения ETH находятся в Wei по умолчанию. 1 ETH = 1,000,000,000,000,000,000 WEI – это означает, что вы имеете дело с большим количеством чисел! `web3.utils.toWei` конвертирует для вас эфир в Wei.
+
+И в эфире он выглядит так:
+
+```js
+// Get the balance of an account (by address or ENS name)
+balance = await provider.getBalance("ethers.eth")
+// { BigNumber: "2337132817842795605" }
+
+// Often you will need to format the output for the user
+// which prefer to see values in ether (instead of wei)
+ethers.utils.formatEther(balance)
+// '2.337132817842795605'
+```
+
+- [Вспомогательные функции Web3js](https://docs.web3js.org/api/web3-utils)
+- [Вспомогательные функции Ethers](https://docs.ethers.org/v6/api/utils/)
+
+## Доступные библиотеки {#available-libraries}
+
+**Web3.js -** **_API Ethereum для JavaScript._**
+
+- [Документация](https://docs.web3js.org)
+- [GitHub](https://github.com/ethereum/web3.js)
+
+**Ethers.js -** **_Полная реализация кошелька Ethereum и утилиты на JavaScript и TypeScript._**
+
+- [Домашняя страница Ethers.js](https://ethers.org/)
+- [Документация](https://docs.ethers.io)
+- [GitHub](https://github.com/ethers-io/ethers.js)
+
+**The Graph -** **_Протокол для индексирования данных Ethereum и IPFS и их запроса с помощью GraphQL._**
+
+- [The Graph](https://thegraph.com)
+- [Обозреватель Graph](https://thegraph.com/explorer)
+- [Документация](https://thegraph.com/docs)
+- [GitHub](https://github.com/graphprotocol)
+- [Discord](https://thegraph.com/discord)
+
+**Alchemy SDK -** **_Оболочка для Ethers.js с расширенными API._**
+
+- [Документация](https://www.alchemy.com/docs)
+- [GitHub](https://github.com/alchemyplatform/alchemy-sdk-js)
+
+**viem -** **_Интерфейс TypeScript для Ethereum._**
+
+- [Документация](https://viem.sh)
+- [GitHub](https://github.com/wagmi-dev/viem)
+
+**Drift -** **_Метабиблиотека TypeScript со встроенным кешированием, хуками и тестовыми заглушками._**
+
+- [Документация](https://ryangoree.github.io/drift/)
+- [GitHub](https://github.com/ryangoree/drift/)
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
+- [Фреймворки для разработки](/developers/docs/frameworks/)
+
+## Связанные руководства {#related-tutorials}
+
+- [Настройка Web3js для использования блокчейна Ethereum в JavaScript](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/) _— инструкции по настройке Web3js в вашем проекте._
+- [Вызов умного контракта из JavaScript](/developers/tutorials/calling-a-smart-contract-from-javascript/) _— на примере токена DAI вы увидите, как вызывать функции контрактов с помощью JavaScript._
+- [Отправка транзакций с помощью web3 и Alchemy](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) _– пошаговое руководство по отправке транзакций с бэкенда._
diff --git a/public/content/translations/ru/developers/docs/apis/json-rpc/index.md b/public/content/translations/ru/developers/docs/apis/json-rpc/index.md
new file mode 100644
index 00000000000..ec7eec7dddd
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/apis/json-rpc/index.md
@@ -0,0 +1,1896 @@
+---
+title: JSON-RPC API
+description: "Облегченный stateless протокол удаленного вызова процедур (RPC) для клиентов Ethereum."
+lang: ru
+---
+
+Для того чтобы программное приложение могло взаимодействовать с блокчейном Эфириум, считывая данные блокчейна или отправляя транзакции в сеть, оно должно подключиться к узлу Эфириум.
+
+Для этой цели каждый [клиент Ethereum](/developers/docs/nodes-and-clients/#execution-clients) реализует [спецификацию JSON-RPC](https://github.com/ethereum/execution-apis), поэтому существует единый набор методов, на которые приложения могут полагаться независимо от конкретной реализации узла или клиента.
+
+[JSON-RPC](https://www.jsonrpc.org/specification) — это легковесный протокол удаленного вызова процедур (RPC) без сохранения состояния. Он определяет несколько структур данных и правила их обработки. Это транспортная агностика, в которой понятия могут использоваться в рамках одного и того же процесса, через сокеты, через HTTP или во многих различных средах передачи сообщений. В качестве формата данных используется JSON (RFC 4627).
+
+## Реализации клиентов {#client-implementations}
+
+Каждый клиент Ethereum может использовать разные языки программирования при реализации спецификации JSON-RPC. Дополнительную информацию о конкретных языках программирования смотрите в [документации отдельных клиентов](/developers/docs/nodes-and-clients/#execution-clients). Мы рекомендуем проверять документацию каждого клиента для получения последней информации о поддержке API.
+
+## Библиотеки для удобства {#convenience-libraries}
+
+Хотя вы можете напрямую взаимодействовать с клиентами Ethereum через JSON-RPC API, для разработчиков децентрализованных приложений часто есть более простые варианты. Существует множество библиотек [JavaScript](/developers/docs/apis/javascript/#available-libraries) и [API для бэкенда](/developers/docs/apis/backend/#available-libraries), которые предоставляют оболочки поверх JSON-RPC API. С помощью этих библиотек разработчики могут писать интуитивно понятные однострочные методы на выбранном ими языке программирования для инициализации запросов JSON-RPC (под капотом), которые взаимодействуют с Ethereum.
+
+## API клиентов консенсуса {#consensus-clients}
+
+Эта страница посвящена в основном JSON-RPC API, используемому клиентами-исполнителями Эфириум. Однако консенсус-клиенты также имеют RPC API, который позволяет пользователям запрашивать информацию об узле, блоки Beacon, состояние Beacon и другую информацию, связанную с консенсусом, непосредственно с узла. Этот API документирован на [веб-странице Beacon API](https://ethereum.github.io/beacon-APIs/#/).
+
+Внутренний API также используется для межклиентского взаимодействия внутри узла, то есть он позволяет консенсус-клиенту и клиенту-исполнителю обмениваться данными. Это называется «Engine API», а спецификации доступны на [GitHub](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md).
+
+## Спецификация клиента исполнения {#spec}
+
+[Прочитайте полную спецификацию JSON-RPC API на GitHub](https://github.com/ethereum/execution-apis). Этот API документирован на [веб-странице Execution API](https://ethereum.github.io/execution-apis/) и включает в себя Inspector для тестирования всех доступных методов.
+
+## Соглашения {#conventions}
+
+### Кодирование шестнадцатеричных значений {#hex-encoding}
+
+Два ключевых типа данных передаются через JSON: неформатированные массивы байтов и величины. Оба передаются с шестнадцатеричной кодировкой, но с различными требованиями к форматированию.
+
+#### Величины {#quantities-encoding}
+
+При кодировании величин (целых чисел, цифр): кодирование как шестнадцатеричный, префикс с "0x", самое компактное представление (небольшое исключение: ноль должен быть представлен как "0x0").
+
+Вот несколько примеров:
+
+- 0x41 (65 в десятичной системе)
+- 0x400 (1024 в десятичной системе)
+- НЕВЕРНО: 0x (всегда должна быть по крайней мере одна цифра - ноль равен "0x0")
+- НЕВЕРНО: 0x0400 (нули в начале не допускаются)
+- НЕВЕРНО: ff (должен быть префикс 0x)
+
+### Неформатированные данные {#unformatted-data-encoding}
+
+При кодировании неформатированных данных (массивов байтов, адресов аккаунтов, хэш, массивов байт-кодов): кодируйте как шестнадцатеричный, префикс с "0x", две шестнадцатеричные цифры на байт.
+
+Вот несколько примеров:
+
+- 0x41 (размер 1, "A")
+- 0x004200 (размер 3, "0B0")
+- 0x (размер 0, "")
+- НЕВЕРНО: 0xf0f0f (должно быть четное количество цифр)
+- НЕВЕРНО: 004200 (должен быть префикс 0x)
+
+### Параметр блока {#block-parameter}
+
+Следующие методы имеют параметр блока:
+
+- [eth_getBalance](#eth_getbalance)
+- [eth_getCode](#eth_getcode)
+- [eth_getTransactionCount](#eth_gettransactioncount)
+- [eth_getStorageAt](#eth_getstorageat)
+- [eth_call](#eth_call)
+
+Когда делаются запросы, которые опрашивают состояние Ethereum, предоставленный параметр блока определяет высоту блока.
+
+Для параметра блока возможны следующие опции:
+
+- `HEX String` — целочисленный номер блока
+- `String "earliest"` для самого раннего/генезис-блока
+- `String "latest"` — для последнего предложенного блока
+- `String "safe"` — для последнего безопасного головного блока
+- `String "finalized"` — для последнего финализированного блока
+- `String "pending"` — для состояния/транзакций в ожидании
+
+## Примеры программ
+
+На этой странице мы приводим примеры того, как использовать отдельные конечные точки JSON_RPC API с помощью инструмента командной строки [curl](https://curl.se). Эти отдельные примеры конечных точек находятся ниже в разделе [Примеры Curl](#curl-examples). Далее на странице мы также приводим [сквозной пример](#usage-example) для компиляции и развертывания смарт-контракта с использованием узла Geth, JSON_RPC API и curl.
+
+## Примеры Curl {#curl-examples}
+
+Ниже приведены примеры использования JSON_RPC API путем выполнения запросов [curl](https://curl.se) к узлу Ethereum. Каждый пример включает в себя описание конкретного эндпоинта, его параметров, возвращаемого типа и пример использованя.
+
+Запросы curl могут возвращать сообщение об ошибке, относящееся к типу содержимого. Это связано с тем, что опция `--data` устанавливает тип содержимого на `application/x-www-form-urlencoded`. Если ваш узел жалуется на это, установите заголовок вручную, поместив `-H "Content-Type: application/json"` в начало вызова. Примеры также не включают комбинацию URL/IP и порта, которая должна быть последним аргументом, передаваемым в curl (например, `127.0.0.1:8545`). Полный запрос curl, включающий эти дополнительные данные, выглядит так:
+
+```shell
+curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}' 127.0.0.1:8545
+```
+
+## Gossip, Состояние, История {#gossip-state-history}
+
+Несколько основных методов JSON-RPC требуют данных из сети Ethereum и четко делятся на три основные категории: _Gossip, Состояние и История_. Воспользуйтесь ссылками в этих разделах, чтобы перейти к каждому из методов, или воспользуйтесь оглавлением, чтобы посмотреть список всех методов.
+
+### Gossip-методы {#gossip-methods}
+
+> Эти методы отслеживают голову цепочки. С их помощью транзакции распространяются по сети, группируются в блоки и клиенты узнают о новых блоках.
+
+- [eth_blockNumber](#eth_blocknumber)
+- [eth_sendRawTransaction](#eth_sendrawtransaction)
+
+### Методы состояния {#state_methods}
+
+> Методы, которые сообщают о текущем состоянии всех сохраненных данных. "Состояние" похоже на один большой разделяемый фрагмент оперативной памяти и включает в себя балансы аккаунтов, данные контрактов и оценки расхода газа.
+
+- [eth_getBalance](#eth_getbalance)
+- [eth_getStorageAt](#eth_getstorageat)
+- [eth_getTransactionCount](#eth_gettransactioncount)
+- [eth_getCode](#eth_getcode)
+- [eth_call](#eth_call)
+- [eth_estimateGas](#eth_estimategas)
+
+### Методы истории {#history_methods}
+
+> Извлекает исторические записи о каждом блоке вплоть до генезис блока. Это похоже на большой файл, к которому можно лишь добавлять новую информацию, и включает в себя все заголовки блоков, тела блоков, блоков-дядей и результаты транзакций.
+
+- [eth_getBlockTransactionCountByHash](#eth_getblocktransactioncountbyhash)
+- [eth_getBlockTransactionCountByNumber](#eth_getblocktransactioncountbynumber)
+- [eth_getUncleCountByBlockHash](#eth_getunclecountbyblockhash)
+- [eth_getUncleCountByBlockNumber](#eth_getunclecountbyblocknumber)
+- [eth_getBlockByHash](#eth_getblockbyhash)
+- [eth_getBlockByNumber](#eth_getblockbynumber)
+- [eth_getTransactionByHash](#eth_gettransactionbyhash)
+- [eth_getTransactionByBlockHashAndIndex](#eth_gettransactionbyblockhashandindex)
+- [eth_getTransactionByBlockNumberAndIndex](#eth_gettransactionbyblocknumberandindex)
+- [eth_getTransactionReceipt](#eth_gettransactionreceipt)
+- [eth_getUncleByBlockHashAndIndex](#eth_getunclebyblockhashandindex)
+- [eth_getUncleByBlockNumberAndIndex](#eth_getunclebyblocknumberandindex)
+
+## Песочница JSON-RPC API
+
+Вы можете использовать [инструмент-песочницу](https://ethereum-json-rpc.com), чтобы изучить и опробовать методы API. Он также показывает, какие методы и сети поддерживаются различными поставщиками узлов.
+
+## Методы JSON-RPC API {#json-rpc-methods}
+
+### web3_clientVersion {#web3_clientversion}
+
+Возвращает текущую версию клиента.
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`String` — текущая версия клиента
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}'
+// Результат
+{
+ "id":67,
+ "jsonrpc":"2.0",
+ "result": "Geth/v1.12.1-stable/linux-amd64/go1.19.1"
+}
+```
+
+### web3_sha3 {#web3_sha3}
+
+Возвращает Keccak-256 (а _не_ стандартизированный SHA3-256) для предоставленных данных.
+
+**Параметры**
+
+1. `DATA` — данные для преобразования в хэш SHA3
+
+```js
+params: ["0x68656c6c6f20776f726c64"]
+```
+
+**Возвращает**
+
+`DATA` — результат SHA3 для данной строки.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f20776f726c64"],"id":64}'
+// Результат
+{
+ "id":64,
+ "jsonrpc": "2.0",
+ "result": "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad"
+}
+```
+
+### net_version {#net_version}
+
+Возвращает идентификатор текущей сети.
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`String` — идентификатор текущей сети.
+
+Полный список текущих идентификаторов сетей доступен на [chainlist.org](https://chainlist.org). Наиболее распространённые из них:
+
+- `1`: основная сеть Ethereum
+- `11155111`: тестовая сеть Sepolia
+- `560048`: тестовая сеть Hoodi
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":67}'
+// Результат
+{
+ "id":67,
+ "jsonrpc": "2.0",
+ "result": "3"
+}
+```
+
+### net_listening {#net_listening}
+
+Возвращает `true`, если клиент активно прослушивает сетевые подключения.
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`Boolean` — `true` при прослушивании, в противном случае `false`.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"net_listening","params":[],"id":67}'
+// Результат
+{
+ "id":67,
+ "jsonrpc":"2.0",
+ "result":true
+}
+```
+
+### net_peerCount {#net_peercount}
+
+Возвращает количество соседних узлов, подключённых к клиенту в текущий момент.
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`QUANTITY` — целочисленное количество подключенных пиров.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":74}'
+// Результат
+{
+ "id":74,
+ "jsonrpc": "2.0",
+ "result": "0x2" // 2
+}
+```
+
+### eth_protocolVersion {#eth_protocolversion}
+
+Возвращает текущую версию протокола Эфириум. Обратите внимание, что этот метод [недоступен в Geth](https://github.com/ethereum/go-ethereum/pull/22064#issuecomment-788682924).
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`String` — текущая версия протокола Ethereum
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_protocolVersion","params":[],"id":67}'
+// Результат
+{
+ "id":67,
+ "jsonrpc": "2.0",
+ "result": "54"
+}
+```
+
+### eth_syncing {#eth_syncing}
+
+Возвращает объект с данными о статусе синхронизации или `false`.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+Точные возвращаемые данные различаются в разных реализациях клиентов. Все клиенты возвращают `False`, когда узел не синхронизируется, и все клиенты возвращают следующие поля.
+
+`Object|Boolean`, объект с данными о статусе синхронизации или `FALSE`, когда нет синхронизации:
+
+- `startingBlock`: `QUANTITY` — блок, с которого начался импорт (будет сброшен только после того, как синхронизация достигнет его головы)
+- `currentBlock`: `QUANTITY` — текущий блок, то же, что и eth_blockNumber
+- `highestBlock`: `QUANTITY` — предполагаемый самый высокий блок
+
+Однако отдельные клиенты могут также предоставлять дополнительные данные. Например, Geth возвращает следующее:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "currentBlock": "0x3cf522",
+ "healedBytecodeBytes": "0x0",
+ "healedBytecodes": "0x0",
+ "healedTrienodes": "0x0",
+ "healingBytecode": "0x0",
+ "healingTrienodes": "0x0",
+ "highestBlock": "0x3e0e41",
+ "startingBlock": "0x3cbed5",
+ "syncedAccountBytes": "0x0",
+ "syncedAccounts": "0x0",
+ "syncedBytecodeBytes": "0x0",
+ "syncedBytecodes": "0x0",
+ "syncedStorage": "0x0",
+ "syncedStorageBytes": "0x0"
+ }
+}
+```
+
+В то время как Besu возвращает:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 51,
+ "result": {
+ "startingBlock": "0x0",
+ "currentBlock": "0x1518",
+ "highestBlock": "0x9567a3",
+ "pulledStates": "0x203ca",
+ "knownStates": "0x200636"
+ }
+}
+```
+
+За более подробной информацией обратитесь к документации вашего конкретного клиента.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": {
+ startingBlock: '0x384',
+ currentBlock: '0x386',
+ highestBlock: '0x454'
+ }
+}
+// Или когда не синхронизируется
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": false
+}
+```
+
+### eth_coinbase {#eth_coinbase}
+
+Возвращает текущий адрес coinbase.
+
+
+ Попробовать конечную точку в песочнице
+
+
+> **Примечание:** этот метод был признан устаревшим в версии **v1.14.0** и больше не поддерживается. Попытка использовать этот метод приведет к ошибке «Method not supported».
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`DATA`, 20 байт — текущий адрес coinbase.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_coinbase","params":[],"id":64}'
+// Результат
+{
+ "id":64,
+ "jsonrpc": "2.0",
+ "result": "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
+}
+```
+
+### eth_chainId {#eth_chainId}
+
+Возвращает идентификатор сети, используемый для подписи защищённых от повторения транзакций.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`chainId`, шестнадцатеричное значение в виде строки, представляющее собой целое число — идентификатор текущей цепи.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":67}'
+// Результат
+{
+ "id":67,
+ "jsonrpc": "2.0",
+ "result": "0x1"
+}
+```
+
+### eth_mining {#eth_mining}
+
+Возвращает `true`, если клиент активно майнит новые блоки. Этот метод может вернуть `true` только для сетей с доказательством работы и может быть недоступен в некоторых клиентах после [Слияния](/roadmap/merge/).
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`Boolean` — возвращает `true`, если клиент занимается майнингом, в противном случае `false`.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_mining","params":[],"id":71}'
+//
+{
+ "id":71,
+ "jsonrpc": "2.0",
+ "result": true
+}
+```
+
+### eth_hashrate {#eth_hashrate}
+
+Возвращает количество хешей в секунду, с которым узел майнит. Этот метод может вернуть `true` только для сетей с доказательством работы и может быть недоступен в некоторых клиентах после [Слияния](/roadmap/merge/).
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`QUANTITY` — количество хэшей в секунду.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_hashrate","params":[],"id":71}'
+// Результат
+{
+ "id":71,
+ "jsonrpc": "2.0",
+ "result": "0x38a"
+}
+```
+
+### eth_gasPrice {#eth_gasprice}
+
+Возвращает оценку текущей цены за газ в wei. Например, клиент Besu по умолчанию проверяет последние 100 блоков и возвращает медианную цену за единицу газа.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`QUANTITY` — целочисленное значение текущей цены на газ в wei.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}'
+// Результат
+{
+ "id":73,
+ "jsonrpc": "2.0",
+ "result": "0x1dfd14000" // 8049999872 Wei
+}
+```
+
+### eth_accounts {#eth_accounts}
+
+Возвращает список адресов, принадлежащих клиенту.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`Массив DATA`, 20 байт — адреса, принадлежащие клиенту.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]
+}
+```
+
+### eth_blockNumber {#eth_blocknumber}
+
+Возвращает номер самого последнего блока.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+Нет
+
+**Возвращает**
+
+`QUANTITY` — целочисленное значение номера текущего блока, на котором находится клиент.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}'
+// Результат
+{
+ "id":83,
+ "jsonrpc": "2.0",
+ "result": "0x4b7" // 1207
+}
+```
+
+### eth_getBalance {#eth_getbalance}
+
+Возвращает баланс счета по заданному адресу.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 20 байт — адрес для проверки баланса.
+2. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+```js
+params: ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]
+```
+
+**Возвращает**
+
+`QUANTITY` — целочисленное значение текущего баланса в wei.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x0234c8a3397aab58" // 158972490234375000
+}
+```
+
+### eth_getStorageAt {#eth_getstorageat}
+
+Возвращает значение из ячейки хранилища по указанному адресу.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 20 байт — адрес хранилища.
+2. `QUANTITY` — целое число, обозначающее позицию в хранилище.
+3. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+**Возвращает**
+
+`DATA` — значение в этой позиции хранилища.
+
+**Пример**
+Вычисление правильной позиции зависит от извлекаемого хранилища. Рассмотрим следующий контракт, развернутый по адресу `0x295a70b2de5e3953354a6a8344e616ed314d7251` с адреса `0x391694e7e0b0cce554cb130d723a9d27458f9298`.
+
+```
+contract Storage {
+ uint pos0;
+ mapping(address => uint) pos1;
+ constructor() {
+ pos0 = 1234;
+ pos1[msg.sender] = 5678;
+ }
+}
+```
+
+Получить значение pos0 просто:
+
+```js
+curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"], "id": 1}' localhost:8545
+{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000004d2"}
+```
+
+Извлечь элемент из хеш-таблицы (mapping) сложнее. Позиция элемента в mapping вычисляется так:
+
+```js
+keccak(LeftPad32(key, 0), LeftPad32(map position, 0))
+```
+
+Это означает, что, чтобы извлечь значение хранилища pos1["0x391694e7e0b0cce554cb130d723a9d27458f9298"], нам необходимо посчитать позицию при помощи:
+
+```js
+keccak(
+ decodeHex(
+ "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" +
+ "0000000000000000000000000000000000000000000000000000000000000001"
+ )
+)
+```
+
+Консоль geth, идущая с библиотекой web3, может быть использована для вычисления:
+
+```js
+> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"
+undefined
+> web3.sha3(key, {"encoding": "hex"})
+"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9"
+```
+
+Теперь, чтобы извлечь значение из хранилища:
+
+```js
+curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9", "latest"], "id": 1}' localhost:8545
+{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"}
+```
+
+### eth_getTransactionCount {#eth_gettransactioncount}
+
+Возвращает количество транзакций, _отправленных_ с адреса.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 20 байт — адрес.
+2. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+```js
+params: [
+ "0x407d73d8a49eeb85d32cf465507dd71d507100c1",
+ "latest", // состояние на последнем блоке
+]
+```
+
+**Возвращает**
+
+`QUANTITY` — целочисленное значение количества транзакций, отправленных с этого адреса.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x1" // 1
+}
+```
+
+### eth_getBlockTransactionCountByHash {#eth_getblocktransactioncountbyhash}
+
+Возвращает количество транзакций в блоке из блока с заданным хешем.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш блока
+
+```js
+params: ["0xd03ededb7415d22ae8bac30f96b2d1de83119632693b963642318d87d1bece5b"]
+```
+
+**Возвращает**
+
+`QUANTITY` — целое число, обозначающее количество транзакций в этом блоке.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByHash","params":["0xd03ededb7415d22ae8bac30f96b2d1de83119632693b963642318d87d1bece5b"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x8b" // 139
+}
+```
+
+### eth_getBlockTransactionCountByNumber {#eth_getblocktransactioncountbynumber}
+
+Возвращает количество транзакций в блоке с заданным номером блока.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `QUANTITY|TAG` — целое число, номер блока или строка `"earliest"`, `"latest"`, `"pending"`, `"safe"` или `"finalized"`, как в [параметре блока](/developers/docs/apis/json-rpc/#block-parameter).
+
+```js
+params: [
+ "0x13738ca", // 20396234
+]
+```
+
+**Возвращает**
+
+`QUANTITY` — целое число, обозначающее количество транзакций в этом блоке.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockTransactionCountByNumber","params":["0x13738ca"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x8b" // 139
+}
+```
+
+### eth_getUncleCountByBlockHash {#eth_getunclecountbyblockhash}
+
+Возвращает количество блоков-дядей для блока с данным хешем.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш блока
+
+```js
+params: ["0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2"]
+```
+
+**Возвращает**
+
+`QUANTITY` — количество дядей в этом блоке.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockHash","params":["0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x1" // 1
+}
+```
+
+### eth_getUncleCountByBlockNumber {#eth_getunclecountbyblocknumber}
+
+Возвращает количество блоков-дядей для блока с данным номером.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+```js
+params: [
+ "0xe8", // 232
+]
+```
+
+**Возвращает**
+
+`QUANTITY` — количество дядей в этом блоке.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleCountByBlockNumber","params":["0xe8"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x0" // 0
+}
+```
+
+### eth_getCode {#eth_getcode}
+
+Возвращает код по заданному адресу.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 20 байт — адрес
+2. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+```js
+params: [
+ "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
+ "0x5daf3b", // 6139707
+]
+```
+
+**Возвращает**
+
+`DATA` — код по заданному адресу.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0x5daf3b"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029"
+}
+```
+
+### eth_sign {#eth_sign}
+
+Метод sign вычисляет специфичную для Ethereum подпись с помощью: `sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))`.
+
+Добавление префикса к сообщению позволяет распознать подпись как специфичную для Эфириум. Это предотвращает неправомерное использование, когда вредоносное децентрализованное приложение может подписывать произвольные данные (например, транзакцию) и использовать подпись для выдачи себя за жертву.
+
+Примечание: адрес для подписи должен быть разблокирован.
+
+**Параметры**
+
+1. `DATA`, 20 байт — адрес
+2. `DATA`, N байт — сообщение для подписи
+
+**Возвращает**
+
+`DATA`: подпись
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sign","params":["0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", "0xdeadbeaf"],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b"
+}
+```
+
+### eth_signTransaction {#eth_signtransaction}
+
+Подписывает транзакцию, которая может быть позже отправлена в сеть с помощью [eth_sendRawTransaction](#eth_sendrawtransaction).
+
+**Параметры**
+
+1. `Object` — объект транзакции
+
+- `type`:
+- `from`: `DATA`, 20 байт — адрес, с которого отправляется транзакция.
+- `to`: `DATA`, 20 байт — (необязательно при создании нового контракта) адрес, на который направлена транзакция.
+- `gas`: `QUANTITY` — (необязательно, по умолчанию: 90000) целое число, обозначающее количество газа, предоставленного на выполнение транзакции. Неиспользованный газ будет возвращён.
+- `gasPrice`: `QUANTITY` — (необязательно, по умолчанию: будет определено) целое число, обозначающее gasPrice для каждой затраченной единицы газа, в Wei.
+- `value`: `QUANTITY` — (необязательно) целое число, обозначающее значение, отправленное вместе с этой транзакцией, в Wei.
+- `data`: `DATA` — скомпилированный код контракта ИЛИ хэш сигнатуры вызываемой функции и закодированные параметры.
+- `nonce`: `QUANTITY` — (необязательно) целое число одноразового номера. Это позволяет перезаписать ваши незавершённые транзакции, использовав один и тот же одноразовый номер.
+
+**Возвращает**
+
+`DATA`, объект транзакции, закодированный в RLP и подписанный указанным аккаунтом.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"id": 1,"jsonrpc": "2.0","method": "eth_signTransaction","params": [{"data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675","from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155","gas": "0x76c0","gasPrice": "0x9184e72a000","to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567","value": "0x9184e72a"}]}'
+// Результат
+{
+ "id": 1,
+ "jsonrpc": "2.0",
+ "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b"
+}
+```
+
+### eth_sendTransaction {#eth_sendtransaction}
+
+Создает новую транзакцию с вызовом сообщения или созданием контракта, если поле data содержит код, и подписывает ее с помощью аккаунта, указанного в `from`.
+
+**Параметры**
+
+1. `Object` — объект транзакции
+
+- `from`: `DATA`, 20 байт — адрес, с которого отправляется транзакция.
+- `to`: `DATA`, 20 байт — (необязательно при создании нового контракта) адрес, на который направлена транзакция.
+- `gas`: `QUANTITY` — (необязательно, по умолчанию: 90000) целое число, обозначающее количество газа, предоставленного на выполнение транзакции. Неиспользованный газ будет возвращён.
+- `gasPrice`: `QUANTITY` — (необязательно, по умолчанию: будет определено) целое число, обозначающее gasPrice для каждой затраченной единицы газа.
+- `value`: `QUANTITY` — (необязательно) целое число, обозначающее значение, отправленное вместе с этой транзакцией.
+- `input`: `DATA` — скомпилированный код контракта ИЛИ хэш сигнатуры вызываемой функции и закодированные параметры.
+- `nonce`: `QUANTITY` — (необязательно) целое число одноразового номера. Это позволяет перезаписать ваши незавершённые транзакции, использовав один и тот же одноразовый номер.
+
+```js
+params: [
+ {
+ from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
+ to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ gas: "0x76c0", // 30400
+ gasPrice: "0x9184e72a000", // 10000000000000
+ value: "0x9184e72a", // 2441406250
+ input:
+ "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
+ },
+]
+```
+
+**Возвращает**
+
+`DATA`, 32 байта — хэш транзакции или нулевой хэш, если транзакция еще недоступна.
+
+Используйте [eth_getTransactionReceipt](#eth_gettransactionreceipt), чтобы получить адрес контракта после того, как транзакция была предложена в блоке, когда вы создавали контракт.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{see above}],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
+}
+```
+
+### eth_sendRawTransaction {#eth_sendrawtransaction}
+
+Создаёт новую транзакцию с вызовом или развертывает контракт, используя подписанную транзакцию.
+
+**Параметры**
+
+1. `DATA`, подписанные данные транзакции.
+
+```js
+params: [
+ "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
+]
+```
+
+**Возвращает**
+
+`DATA`, 32 байта — хэш транзакции или нулевой хэш, если транзакция еще недоступна.
+
+Используйте [eth_getTransactionReceipt](#eth_gettransactionreceipt), чтобы получить адрес контракта после того, как транзакция была предложена в блоке, когда вы создавали контракт.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[{see above}],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
+}
+```
+
+### eth_call {#eth_call}
+
+Немедленно выполняет новый вызов сообщения без создания транзакции в блокчейне. Часто используется для выполнения функций смарт-контрактов, доступных только для чтения, например, `balanceOf` для контракта ERC-20.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `Object` — объект вызова транзакции
+
+- `from`: `DATA`, 20 байт — (необязательно) адрес, с которого отправляется транзакция.
+- `to`: `DATA`, 20 байт — адрес, на который направлена транзакция.
+- `gas`: `QUANTITY` — (необязательно) целое число, обозначающее количество газа, предоставленного на выполнение транзакции. eth_call не потребляет газ, но этот параметр может быть необходим некоторым контрактам.
+- `gasPrice`: `QUANTITY` — (необязательно) целое число, обозначающее gasPrice для каждой затраченной единицы газа
+- `value`: `QUANTITY` — (необязательно) целое число, обозначающее значение, отправленное вместе с этой транзакцией
+- `input`: `DATA` — (необязательно) хэш сигнатуры метода и закодированные параметры. Для получения подробной информации см. [ABI контракта Ethereum в документации Solidity](https://docs.soliditylang.org/en/latest/abi-spec.html).
+
+2. `QUANTITY|TAG` — целочисленный номер блока или строка `"latest"`, `"earliest"`, `"pending"`, `"safe"` или `"finalized"`, см. [параметр блока](/developers/docs/apis/json-rpc/#block-parameter)
+
+**Возвращает**
+
+`DATA` — возвращаемое значение исполненного контракта.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{see above}],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x"
+}
+```
+
+### eth_estimateGas {#eth_estimategas}
+
+Генерирует и возвращает оценку того, сколько газа необходимо для выполнения транзакции. Транзакция не будет добавлена в блокчейн. Обратите внимание, что оценочное значение может быть значительно больше, чем количество газа, фактически использованного транзакцией, по целому ряду причин, включая особенности EVM и производительность узла.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+См. параметры [eth_call](#eth_call), за исключением того, что все свойства являются необязательными. Если лимит газа не указан, geth использует лимит газа блока из ожидающего рассмотрения блока в качестве верхней границы. В результате возвращенной оценки может оказаться недостаточно для выполнения вызова/транзакции, когда количество газа превышает лимит газа в ожидающем блоке.
+
+**Возвращает**
+
+`QUANTITY` — количество использованного газа.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_estimateGas","params":[{see above}],"id":1}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x5208" // 21000
+}
+```
+
+### eth_getBlockByHash {#eth_getblockbyhash}
+
+Возвращает информацию о блоке по хэшу.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш блока.
+2. `Boolean` — если `true`, возвращает полные объекты транзакций, если `false` — только хэши транзакций.
+
+```js
+params: [
+ "0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae",
+ false,
+]
+```
+
+**Возвращает**
+
+`Object` — объект блока или `null`, если блок не найден:
+
+- `number`: `QUANTITY` — номер блока. `null`, когда блок находится в состоянии ожидания.
+- `hash`: `DATA`, 32 байта — хэш блока. `null`, когда блок находится в состоянии ожидания.
+- `parentHash`: `DATA`, 32 байта — хэш родительского блока.
+- `nonce`: `DATA`, 8 байт — хэш сгенерированного доказательства выполнения работы. `null`, когда блок находится в состоянии ожидания, `0x0` для блоков с доказательством доли владения (после Слияния).
+- `sha3Uncles`: `DATA`, 32 байта — SHA3 данных о блоках-дядях в этом блоке.
+- `logsBloom`: `DATA`, 256 байт — фильтр Блума для журналов блока. `null`, когда блок находится в состоянии ожидания.
+- `transactionsRoot`: `DATA`, 32 байта — корень дерева транзакций блока.
+- `stateRoot`: `DATA`, 32 байта — корень конечного дерева состояний блока.
+- `receiptsRoot`: `DATA`, 32 байта — корень дерева квитанций блока.
+- `miner`: `DATA`, 20 байт — адрес получателя, которому были переданы вознаграждения за блок.
+- `difficulty`: `QUANTITY` — целое число, обозначающее сложность этого блока.
+- `totalDifficulty`: `QUANTITY` — целое число, обозначающее общую сложность цепи до этого блока.
+- `extraData`: `DATA` — поле «дополнительные данные» этого блока.
+- `size`: `QUANTITY` — целое число, размер этого блока в байтах.
+- `gasLimit`: `QUANTITY` — максимальное количество газа, разрешенное в этом блоке.
+- `gasUsed`: `QUANTITY` — общее количество газа, использованное всеми транзакциями в этом блоке.
+- `timestamp`: `QUANTITY` — временная метка unix, когда блок был сопоставлен.
+- `transactions`: `Массив` — массив объектов транзакций или 32-байтных хэшей транзакций в зависимости от последнего заданного параметра.
+- `uncles`: `Массив` — массив хэшей дядей.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByHash","params":["0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae", false],"id":1}'
+// Результат
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "difficulty": "0x4ea3f27bc",
+ "extraData": "0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32",
+ "gasLimit": "0x1388",
+ "gasUsed": "0x0",
+ "hash": "0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae",
+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "miner": "0xbb7b8287f3f0a933474a79eae42cbca977791171",
+ "mixHash": "0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843",
+ "nonce": "0x689056015818adbe",
+ "number": "0x1b4",
+ "parentHash": "0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54",
+ "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+ "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
+ "size": "0x220",
+ "stateRoot": "0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d",
+ "timestamp": "0x55ba467c",
+ "totalDifficulty": "0x78ed983323d",
+ "transactions": [
+ ],
+ "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
+ "uncles": [
+ ]
+ }
+}
+```
+
+### eth_getBlockByNumber {#eth_getblockbynumber}
+
+Возвращает информацию о блоке по его номеру.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `QUANTITY|TAG` — целое число, номер блока или строка `"earliest"`, `"latest"`, `"pending"`, `"safe"` или `"finalized"`, как в [параметре блока](/developers/docs/apis/json-rpc/#block-parameter).
+2. `Boolean` — если `true`, возвращает полные объекты транзакций, если `false` — только хэши транзакций.
+
+```js
+params: [
+ "0x1b4", // 436
+ true,
+]
+```
+
+**Возвращает**
+См. [eth_getBlockByHash](#eth_getblockbyhash)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}'
+```
+
+Результат см. в [eth_getBlockByHash](#eth_getblockbyhash)
+
+### eth_getTransactionByHash {#eth_gettransactionbyhash}
+
+Возвращает информацию о транзакции по её хешу.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш транзакции
+
+```js
+params: ["0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"]
+```
+
+**Возвращает**
+
+`Object` — объект транзакции или `null`, если транзакция не найдена:
+
+- `blockHash`: `DATA`, 32 байта — хэш блока, в котором находилась эта транзакция. `null`, когда она находится в состоянии ожидания.
+- `blockNumber`: `QUANTITY` — номер блока, в котором находилась эта транзакция. `null`, когда она находится в состоянии ожидания.
+- `from`: `DATA`, 20 байт — адрес отправителя.
+- `gas`: `QUANTITY` — газ, предоставленный отправителем.
+- `gasPrice`: `QUANTITY` — цена на газ, предоставленная отправителем в Wei.
+- `hash`: `DATA`, 32 байта — хэш транзакции.
+- `input`: `DATA` — данные, отправленные вместе с транзакцией.
+- `nonce`: `QUANTITY` — количество транзакций, совершенных отправителем до этой.
+- `to`: `DATA`, 20 байт — адрес получателя. `null`, когда это транзакция создания контракта.
+- `transactionIndex`: `QUANTITY` — целое число, обозначающее позицию индекса транзакций в блоке. `null`, когда она находится в состоянии ожидания.
+- `value`: `QUANTITY` — переданное значение в Wei.
+- `v`: `QUANTITY` — идентификатор восстановления ECDSA
+- `r`: `QUANTITY` — подпись ECDSA r
+- `s`: `QUANTITY` — подпись ECDSA s
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"],"id":1}'
+// Результат
+{
+ "jsonrpc":"2.0",
+ "id":1,
+ "result":{
+ "blockHash":"0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
+ "blockNumber":"0x5daf3b", // 6139707
+ "from":"0xa7d9ddbe1f17865597fbd27ec712455208b6b76d",
+ "gas":"0xc350", // 50000
+ "gasPrice":"0x4a817c800", // 20000000000
+ "hash":"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b",
+ "input":"0x68656c6c6f21",
+ "nonce":"0x15", // 21
+ "to":"0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb",
+ "transactionIndex":"0x41", // 65
+ "value":"0xf3dbb76162000", // 4290000000000000
+ "v":"0x25", // 37
+ "r":"0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea",
+ "s":"0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c"
+ }
+}
+```
+
+### eth_getTransactionByBlockHashAndIndex {#eth_gettransactionbyblockhashandindex}
+
+Возвращает информацию о транзакции по хешу блока и индексу транзакции в блоке.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш блока.
+2. `QUANTITY` — целое число, обозначающее позицию индекса транзакции.
+
+```js
+params: [
+ "0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
+ "0x0", // 0
+]
+```
+
+**Возвращает**
+См. [eth_getTransactionByHash](#eth_gettransactionbyhash)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockHashAndIndex","params":["0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2", "0x0"],"id":1}'
+```
+
+Результат см. в [eth_getTransactionByHash](#eth_gettransactionbyhash)
+
+### eth_getTransactionByBlockNumberAndIndex {#eth_gettransactionbyblocknumberandindex}
+
+Возвращает информацию о транзакции по номеру блока и индексу транзакции в блоке.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `QUANTITY|TAG` — номер блока или строка `"earliest"`, `"latest"`, `"pending"`, `"safe"` или `"finalized"`, как в [параметре блока](/developers/docs/apis/json-rpc/#block-parameter).
+2. `QUANTITY` — целочисленное значение индекса транзакции.
+
+```js
+params: [
+ "0x9c47cf", // 10241999
+ "0x24", // 36
+]
+```
+
+**Возвращает**
+См. [eth_getTransactionByHash](#eth_gettransactionbyhash)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByBlockNumberAndIndex","params":["0x9c47cf", "0x24"],"id":1}'
+```
+
+Результат см. в [eth_getTransactionByHash](#eth_gettransactionbyhash)
+
+### eth_getTransactionReceipt {#eth_gettransactionreceipt}
+
+Возвращает квитанцию транзакции по хешу транзакции.
+
+**Примечание:** квитанция недоступна для транзакций, находящихся в состоянии ожидания.
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш транзакции
+
+```js
+params: ["0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5"]
+```
+
+**Возвращает**
+`Object` — объект квитанции транзакции или `null`, если квитанция не найдена:
+
+- `transactionHash `: `DATA`, 32 байта — хэш транзакции.
+- `transactionIndex`: `QUANTITY` — целое число, обозначающее позицию индекса транзакций в блоке.
+- `blockHash`: `DATA`, 32 байта — хэш блока, в котором находилась эта транзакция.
+- `blockNumber`: `QUANTITY` — номер блока, в котором находилась эта транзакция.
+- `from`: `DATA`, 20 байт — адрес отправителя.
+- `to`: `DATA`, 20 байт — адрес получателя. null, когда это транзакция развёртывания контракта.
+- `cumulativeGasUsed` : `QUANTITY ` — общее количество газа, использованного при выполнении этой транзакции в блоке.
+- `effectiveGasPrice` : `QUANTITY` — сумма базовой комиссии и чаевых, уплаченных за единицу газа.
+- `gasUsed `: `QUANTITY ` — количество газа, использованное только этой конкретной транзакцией.
+- `contractAddress `: `DATA`, 20 байт — созданный адрес контракта, если транзакция была созданием контракта, в противном случае `null`.
+- `logs`: `Массив` — массив объектов журнала, которые сгенерировала эта транзакция.
+- `logsBloom`: `DATA`, 256 байт — фильтр Блума для легких клиентов для быстрого извлечения связанных журналов.
+- `type`: `QUANTITY` — целое число, тип транзакции, `0x0` для устаревших транзакций, `0x1` для типов списков доступа, `0x2` для динамических комиссий.
+
+Он также возвращает _один из_ :
+
+- `root` : `DATA` 32 байта корня состояния после транзакции (до Византии)
+- `status`: `QUANTITY` либо `1` (успех), либо `0` (неудача)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5"],"id":1}'
+// Результат
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "blockHash":
+ "0xa957d47df264a31badc3ae823e10ac1d444b098d9b73d204c40426e57f47e8c3",
+ "blockNumber": "0xeff35f",
+ "contractAddress": null, // строка адреса, если он был создан
+ "cumulativeGasUsed": "0xa12515",
+ "effectiveGasPrice": "0x5a9c688d4",
+ "from": "0x6221a9c005f6e47eb398fd867784cacfdcfff4e7",
+ "gasUsed": "0xb4c8",
+ "logs": [{
+ // журналы, возвращаемые getFilterLogs и т. д.
+ }],
+ "logsBloom": "0x00...0", // 256-байтовый фильтр блума
+ "status": "0x1",
+ "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
+ "transactionHash":
+ "0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5",
+ "transactionIndex": "0x66",
+ "type": "0x2"
+ }
+}
+```
+
+### eth_getUncleByBlockHashAndIndex {#eth_getunclebyblockhashandindex}
+
+Возвращает информацию о дяде блока по хэшу и позиции индекса дяди.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `DATA`, 32 байта — хэш блока.
+2. `QUANTITY` — позиция индекса дяди.
+
+```js
+params: [
+ "0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
+ "0x0", // 0
+]
+```
+
+**Возвращает**
+См. [eth_getBlockByHash](#eth_getblockbyhash)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockHashAndIndex","params":["0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2", "0x0"],"id":1}'
+```
+
+Результат см. в [eth_getBlockByHash](#eth_getblockbyhash)
+
+**Примечание**: дядя не содержит отдельных транзакций.
+
+### eth_getUncleByBlockNumberAndIndex {#eth_getunclebyblocknumberandindex}
+
+Возвращает информацию о дяде блока по номеру и позиции индекса дяди.
+
+
+ Попробовать конечную точку в песочнице
+
+
+**Параметры**
+
+1. `QUANTITY|TAG` — номер блока или строка `"earliest"`, `"latest"`, `"pending"`, `"safe"` или `"finalized"`, как в [параметре блока](/developers/docs/apis/json-rpc/#block-parameter).
+2. `QUANTITY` — индекс блока-дяди.
+
+```js
+params: [
+ "0x29c", // 668
+ "0x0", // 0
+]
+```
+
+**Возвращает**
+См. [eth_getBlockByHash](#eth_getblockbyhash)
+
+**Примечание**: дядя не содержит отдельных транзакций.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getUncleByBlockNumberAndIndex","params":["0x29c", "0x0"],"id":1}'
+```
+
+Результат см. в [eth_getBlockByHash](#eth_getblockbyhash)
+
+### eth_newFilter {#eth_newfilter}
+
+Создает объект фильтра на основе параметров фильтра для уведомления об изменении состояния (логи).
+Чтобы проверить, изменилось ли состояние, вызовите [eth_getFilterChanges](#eth_getfilterchanges).
+
+**Примечание по указанию фильтров тем:**
+Темы зависят от порядка. Транзакция с логом с темами [A, B] будет подходить под следующие фильтры тем:
+
+- `[]` «что угодно»
+- `[A]` «A на первой позиции (и что угодно после)»
+- `[null, B]` «что угодно на первой позиции И B на второй позиции (и что угодно после)»
+- `[A, B]` «A на первой позиции И B на второй позиции (и что угодно после)»
+- `[[A, B], [A, B]]` «(A ИЛИ B) на первой позиции И (A ИЛИ B) на второй позиции (и что угодно после)»
+- **Параметры**
+
+1. `Object` — параметры фильтра:
+
+- `fromBlock`: `QUANTITY|TAG` — (необязательно, по умолчанию: `"latest"`) целочисленный номер блока или `"latest"` для последнего предложенного блока, `"safe"` для последнего безопасного блока, `"finalized"` для последнего финализированного блока, или `"pending"`, `"earliest"` для транзакций, еще не включенных в блок.
+- `toBlock`: `QUANTITY|TAG` — (необязательно, по умолчанию: `"latest"`) целочисленный номер блока или `"latest"` для последнего предложенного блока, `"safe"` для последнего безопасного блока, `"finalized"` для последнего финализированного блока, или `"pending"`, `"earliest"` для транзакций, еще не включенных в блок.
+- `address`: `DATA|Массив`, 20 байт — (необязательно) адрес контракта или список адресов, из которых должны исходить журналы.
+- `topics`: `Массив DATA` — (необязательно) массив 32-байтных `DATA` тем. Темы зависят от порядка. Каждая тема может также быть массивом данных с параметрами "or".
+
+```js
+params: [
+ {
+ fromBlock: "0x1",
+ toBlock: "0x2",
+ address: "0x8888f1f195afa192cfee860698584c030f4c9db1",
+ topics: [
+ "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ null,
+ [
+ "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ "0x0000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc",
+ ],
+ ],
+ },
+]
+```
+
+**Возвращает**
+`QUANTITY` — идентификатор фильтра.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"topics":["0x12341234"]}],"id":73}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x1" // 1
+}
+```
+
+### eth_newBlockFilter {#eth_newblockfilter}
+
+Создает фильтр в узле, который уведомляет о достижении нового блока.
+Чтобы проверить, изменилось ли состояние, вызовите [eth_getFilterChanges](#eth_getfilterchanges).
+
+**Параметры**
+Нет
+
+**Возвращает**
+`QUANTITY` — идентификатор фильтра.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newBlockFilter","params":[],"id":73}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x1" // 1
+}
+```
+
+### eth_newPendingTransactionFilter {#eth_newpendingtransactionfilter}
+
+Создает фильтр в узле, который уведомляет о поступлении новых ожидающих подтверждения транзакций.
+Чтобы проверить, изменилось ли состояние, вызовите [eth_getFilterChanges](#eth_getfilterchanges).
+
+**Параметры**
+Нет
+
+**Возвращает**
+`QUANTITY` — идентификатор фильтра.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":73}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": "0x1" // 1
+}
+```
+
+### eth_uninstallFilter {#eth_uninstallfilter}
+
+Удаляет фильтр с заданным идентификатором. Всегда следует вызывать, когда наблюдение больше не нужно.
+Кроме того, время ожидания фильтров истекает, если они не запрашиваются с помощью [eth_getFilterChanges](#eth_getfilterchanges) в течение определенного периода времени.
+
+**Параметры**
+
+1. `QUANTITY` — идентификатор фильтра.
+
+```js
+params: [
+ "0xb", // 11
+]
+```
+
+**Возвращает**
+`Boolean` — `true`, если фильтр был успешно удален, в противном случае `false`.
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_uninstallFilter","params":["0xb"],"id":73}'
+// Результат
+{
+ "id":1,
+ "jsonrpc": "2.0",
+ "result": true
+}
+```
+
+### eth_getFilterChanges {#eth_getfilterchanges}
+
+Метод опроса фильтра, возвращающий массив логов, которые произошли с момента последнего опроса.
+
+**Параметры**
+
+1. `QUANTITY` — идентификатор фильтра.
+
+```js
+params: [
+ "0x16", // 22
+]
+```
+
+**Возвращает**
+`Массив` — массив объектов журнала или пустой массив, если с момента последнего опроса ничего не изменилось.
+
+- Для фильтров, созданных с помощью `eth_newBlockFilter`, возвращаются хэши блоков (`DATA`, 32 байта), например, `["0x3454645634534..."]`.
+
+- Для фильтров, созданных с помощью `eth_newPendingTransactionFilter `, возвращаются хэши транзакций (`DATA`, 32 байта), например, `["0x6345343454645..."]`.
+
+- Для фильтров, созданных с помощью `eth_newFilter`, журналы являются объектами со следующими параметрами:
+ - `removed`: `TAG` — `true`, когда журнал был удален из-за реорганизации цепи. `false`, если это действительный журнал.
+ - `logIndex`: `QUANTITY` — целое число, обозначающее позицию индекса журнала в блоке. `null`, когда журнал находится в состоянии ожидания.
+ - `transactionIndex`: `QUANTITY` — целое число, обозначающее позицию индекса транзакций, из которой был создан журнал. `null`, когда журнал находится в состоянии ожидания.
+ - `transactionHash`: `DATA`, 32 байта — хэш транзакций, из которых был создан этот журнал. `null`, когда журнал находится в состоянии ожидания.
+ - `blockHash`: `DATA`, 32 байта — хэш блока, в котором находился этот журнал. `null`, когда она находится в состоянии ожидания. `null`, когда журнал находится в состоянии ожидания.
+ - `blockNumber`: `QUANTITY` — номер блока, в котором находился этот журнал. `null`, когда она находится в состоянии ожидания. `null`, когда журнал находится в состоянии ожидания.
+ - `address`: `DATA`, 20 байт — адрес, из которого возник этот журнал.
+ - `data`: `DATA` — неиндексированные данные журнала переменной длины. (В _solidity_: ноль или более 32-байтных неиндексированных аргументов журнала.)
+ - `topics`: `Массив DATA` — массив от 0 до 4 32-байтных `DATA` индексированных аргументов журнала. (В _solidity_: первая тема — это _хэш_ подписи события (например, `Deposit(address,bytes32,uint256)`), за исключением случаев, когда вы объявили событие с помощью спецификатора `anonymous`.)
+
+- **Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x16"],"id":73}'
+// Результат
+{
+ "id":1,
+ "jsonrpc":"2.0",
+ "result": [{
+ "logIndex": "0x1", // 1
+ "blockNumber":"0x1b4", // 436
+ "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d",
+ "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf",
+ "transactionIndex": "0x0", // 0
+ "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d",
+ "data":"0x0000000000000000000000000000000000000000000000000000000000000000",
+ "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"]
+ },{
+ ...
+ }]
+}
+```
+
+### eth_getFilterLogs {#eth_getfilterlogs}
+
+Возвращает массив всех логов, соответствующих фильтру с заданным идентификатором.
+
+**Параметры**
+
+1. `QUANTITY` — идентификатор фильтра.
+
+```js
+params: [
+ "0x16", // 22
+]
+```
+
+**Возвращает**
+См. [eth_getFilterChanges](#eth_getfilterchanges)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterLogs","params":["0x16"],"id":74}'
+```
+
+Результат см. в [eth_getFilterChanges](#eth_getfilterchanges)
+
+### eth_getLogs {#eth_getlogs}
+
+Возвращает массив всех логов, соответствующих заданному объекту фильтра.
+
+**Параметры**
+
+1. `Object` — параметры фильтра:
+
+- `fromBlock`: `QUANTITY|TAG` — (необязательно, по умолчанию: `"latest"`) целочисленный номер блока или `"latest"` для последнего предложенного блока, `"safe"` для последнего безопасного блока, `"finalized"` для последнего финализированного блока, или `"pending"`, `"earliest"` для транзакций, еще не включенных в блок.
+- `toBlock`: `QUANTITY|TAG` — (необязательно, по умолчанию: `"latest"`) целочисленный номер блока или `"latest"` для последнего предложенного блока, `"safe"` для последнего безопасного блока, `"finalized"` для последнего финализированного блока, или `"pending"`, `"earliest"` для транзакций, еще не включенных в блок.
+- `address`: `DATA|Массив`, 20 байт — (необязательно) адрес контракта или список адресов, из которых должны исходить журналы.
+- `topics`: `Массив DATA` — (необязательно) массив 32-байтных `DATA` тем. Темы зависят от порядка. Каждая тема может также быть массивом данных с параметрами "or".
+- `blockHash`: `DATA`, 32 байта — (необязательно, **будет в будущем**) с добавлением EIP-234, `blockHash` станет новым параметром фильтра, который ограничивает возвращаемые журналы одним блоком с 32-байтным хэшем `blockHash`. Использование `blockHash` эквивалентно `fromBlock` = `toBlock` = номеру блока с хэшем `blockHash`. Если `blockHash` присутствует в критериях фильтра, то ни `fromBlock`, ни `toBlock` не допускаются.
+
+```js
+params: [
+ {
+ topics: [
+ "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
+ ],
+ },
+]
+```
+
+**Возвращает**
+См. [eth_getFilterChanges](#eth_getfilterchanges)
+
+**Пример**
+
+```js
+// Запрос
+curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":74}'
+```
+
+Результат см. в [eth_getFilterChanges](#eth_getfilterchanges)
+
+## Пример использования {#usage-example}
+
+### Развертывание контракта с использованием JSON_RPC {#deploying-contract}
+
+Этот раздел включает демонстрацию того, как развернуть контракт, используя только RPC интерфейс. Существуют альтернативные способы развертывания контрактов, где эта сложность абстрагирована, — например, с использованием библиотек, построенных поверх интерфейса RPC, таких как [web3.js](https://web3js.readthedocs.io/) и [web3.py](https://github.com/ethereum/web3.py). Эти абстракции, как правило, более легкие для понимания и менее подвержены ошибкам, но все равно полезно понимать, что происходит под капотом.
+
+Ниже приведен простой смарт-контракт под названием `Multiply7`, который будет развернут с использованием интерфейса JSON-RPC на узле Ethereum. Это руководство предполагает, что читатель уже использует узел Geth. Дополнительную информацию об узлах и клиентах можно найти [здесь](/developers/docs/nodes-and-clients/run-a-node). Пожалуйста, обратитесь к документации отдельного [клиента](/developers/docs/nodes-and-clients/), чтобы узнать, как запустить HTTP JSON-RPC для клиентов, отличных от Geth. Большинство клиентов по умолчанию обслуживают на `localhost:8545`.
+
+```javascript
+contract Multiply7 {
+ event Print(uint);
+ function multiply(uint input) returns (uint) {
+ Print(input * 7);
+ return input * 7;
+ }
+}
+```
+
+Первое, что нужно сделать, это убедиться, что HTTP RPC интерфейс включен. Это означает, что мы предоставляем Geth флаг `--http` при запуске. В этом примере мы используем узел Geth в закрытой цепочке разработки. Используя этот подход, мы не нуждаемся в эфире, как в реальной сети.
+
+```bash
+geth --http --dev console 2>>geth.log
+```
+
+Это запустит интерфейс HTTP RPC на `http://localhost:8545`.
+
+Мы можем убедиться, что интерфейс работает, получив адрес coinbase (получив первый адрес из массива аккаунтов) и баланс с помощью [curl](https://curl.se). Пожалуйста, обратите внимание, что данные в этих примерах будут отличаться на Вашем локальном узле. Если Вы хотите попробовать эти команды, замените параметры во втором curl запросе на результат, возвращенный из первого.
+
+```bash
+curl --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[], "id":1}' -H "Content-Type: application/json" localhost:8545
+{"id":1,"jsonrpc":"2.0","result":["0x9b1d35635cc34752ca54713bb99d38614f63c955"]}
+
+curl --data '{"jsonrpc":"2.0","method":"eth_getBalance", "params": ["0x9b1d35635cc34752ca54713bb99d38614f63c955", "latest"], "id":2}' -H "Content-Type: application/json" localhost:8545
+{"id":2,"jsonrpc":"2.0","result":"0x1639e49bba16280000"}
+```
+
+Поскольку цифры закодированы в шестнадцатеричном формате, баланс будет возвращен в wei, как шестнадцатеричная строка. Если мы хотим иметь баланс в эфире, как число, мы можем использоватьWeb3 из консоли Geth.
+
+```javascript
+web3.fromWei("0x1639e49bba16280000", "ether")
+// "410"
+```
+
+Теперь, когда на нашей приватной цепочке развития есть немного эфира, мы можем развернуть контракт. Первый шаг - компиляция контракта Multiply7 в байт-код, который может быть отправлен на EVM. Чтобы установить solc, компилятор Solidity, следуйте [документации Solidity](https://docs.soliditylang.org/en/latest/installing-solidity.html). (Возможно, вы захотите использовать более старый выпуск `solc`, чтобы соответствовать [версии компилятора, используемой в нашем примере](https://github.com/ethereum/solidity/releases/tag/v0.4.20).)
+
+Следующий шаг — скомпилировать контракт Multiply7 в байт-код, который можно отправить в EVM.
+
+```bash
+echo 'pragma solidity ^0.4.16; contract Multiply7 { event Print(uint); function multiply(uint input) public returns (uint) { Print(input * 7); return input * 7; } }' | solc --bin
+
+======= :Multiply7 =======
+Binary:
+6060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb0029
+```
+
+Теперь, когда мы имеем скомпилированный код, нам нужно определить, сколько газа стоит его развертывание. Интерфейс RPC имеет метод `eth_estimateGas`, который даст нам оценку.
+
+```bash
+curl --data '{"jsonrpc":"2.0","method": "eth_estimateGas", "params": [{"from": "0x9b1d35635cc34752ca54713bb99d38614f63c955", "data": "0x6060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb0029"}], "id": 5}' -H "Content-Type: application/json" localhost:8545
+{"jsonrpc":"2.0","id":5,"result":"0x1c31e"}
+```
+
+И, наконец, развернем контракт.
+
+```bash
+curl --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0x9b1d35635cc34752ca54713bb99d38614f63c955", "gas": "0x1c31e", "data": "0x6060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb0029"}], "id": 6}' -H "Content-Type: application/json" localhost:8545
+{"id":6,"jsonrpc":"2.0","result":"0xe1f3095770633ab2b18081658bad475439f6a08c902d0915903bafff06e6febf"}
+```
+
+Транзакция принимается узлом, и хэш транзакции возвращается. Этот хэш может быть использован для отслеживания транзакции. Следующий шаг - определение адреса, где наш контракт развернут. Каждая выполненная транзакция создаст квитанцию. Эта квитанция содержит различную информацию о транзакции, например, в какой блок транзакция была включена и сколько газа было использовано EVM. Если транзакция создает контракт, она также будет содержать адрес контракта. Мы можем получить квитанцию с помощью метода RPC `eth_getTransactionReceipt`.
+
+```bash
+curl --data '{"jsonrpc":"2.0","method": "eth_getTransactionReceipt", "params": ["0xe1f3095770633ab2b18081658bad475439f6a08c902d0915903bafff06e6febf"], "id": 7}' -H "Content-Type: application/json" localhost:8545
+{"jsonrpc":"2.0","id":7,"result":{"blockHash":"0x77b1a4f6872b9066312de3744f60020cbd8102af68b1f6512a05b7619d527a4f","blockNumber":"0x1","contractAddress":"0x4d03d617d700cf81935d7f797f4e2ae719648262","cumulativeGasUsed":"0x1c31e","from":"0x9b1d35635cc34752ca54713bb99d38614f63c955","gasUsed":"0x1c31e","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0xe1f3095770633ab2b18081658bad475439f6a08c902d0915903bafff06e6febf","transactionIndex":"0x0"}}
+```
+
+Наш контракт был создан по адресу `0x4d03d617d700cf81935d7f797f4e2ae719648262`. Результат null вместо квитанции означает, что транзакция еще не была включена в блок. Подождите немного, проверьте, запущен ли ваш клиент консенсуса, и повторите попытку.
+
+#### Взаимодействие со смарт-контрактами {#interacting-with-smart-contract}
+
+В этом примере мы отправим транзакцию с помощью `eth_sendTransaction` в метод `multiply` контракта.
+
+`eth_sendTransaction` требует несколько аргументов, в частности `from`, `to` и `data`. `From` — это публичный адрес нашего аккаунта, а `to` — это адрес контракта. Аргумент `data` содержит полезную нагрузку, которая определяет, какой метод должен быть вызван и с какими аргументами. Именно здесь в игру вступает [ABI (двоичный интерфейс приложения)](https://docs.soliditylang.org/en/latest/abi-spec.html). ABI - это JSON файл, который устанавливает, как определять и кодировать данные для EVM.
+
+Байты полезной нагрузки определяют, какой метод в контракте вызван. Это первые 4 байта из хэша Keccak от имени функции и ее типов аргументов, закодированные в шестнадцатеричной форме. Функция multiply принимает значение uint, которое является псевдонимом uint256. Это оставляет нам:
+
+```javascript
+web3.sha3("multiply(uint256)").substring(0, 10)
+// "0xc6888fa1"
+```
+
+Следующим шагом является кодирование аргументов. Существует только один uint256, скажем, значение 6. ABI имеет раздел, который определяет, как кодировать типы uint256.
+
+`int: enc(X)` — это кодирование X в прямом порядке байтов с дополнением до двух, дополненное со стороны старшего разряда (слева) значением 0xff для отрицательных X и нулевыми байтами для положительных X, так что длина становится кратной 32 байтам.
+
+Это кодируется в `0000000000000000000000000000000000000000000000000000000000000006`.
+
+Объединив селектор функции и закодированный аргумент, мы получим данные `0xc6888fa10000000000000000000000000000000000000000000000000000000000000006`.
+
+Теперь это может быть отправлено на узел:
+
+```bash
+curl --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", "to": "0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d", "data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}], "id": 8}' -H "Content-Type: application/json" localhost:8545
+{"id":8,"jsonrpc":"2.0","result":"0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74"}
+```
+
+Так как транзакция была отправлена, был возвращен хэш транзакции. Получение квитанции дает:
+
+```javascript
+{
+ blockHash: "0xbf0a347307b8c63dd8c1d3d7cbdc0b463e6e7c9bf0a35be40393588242f01d55",
+ blockNumber: 268,
+ contractAddress: null,
+ cumulativeGasUsed: 22631,
+ gasUsed: 22631,
+ logs: [{
+ address: "0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d",
+ blockHash: "0xbf0a347307b8c63dd8c1d3d7cbdc0b463e6e7c9bf0a35be40393588242f01d55",
+ blockNumber: 268,
+ data: "0x000000000000000000000000000000000000000000000000000000000000002a",
+ logIndex: 0,
+ topics: ["0x24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"],
+ transactionHash: "0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74",
+ transactionIndex: 0
+ }],
+ transactionHash: "0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74",
+ transactionIndex: 0
+}
+```
+
+Квитанция содержит журнал регистрации. Этот журнал был сгенерирован EVM при выполнении транзакции и включен в квитанцию. Функция `multiply` показывает, что событие `Print` было вызвано с входным значением, умноженным на 7. Поскольку аргументом для события `Print` был uint256, мы можем декодировать его в соответствии с правилами ABI, что даст нам ожидаемое десятичное число 42. Помимо данных, стоит отметить, что темы могут быть использованы для определения того, какое событие создало журнал:
+
+```javascript
+web3.sha3("Print(uint256)")
+// "24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"
+```
+
+Это было всего лишь краткое введение в некоторые наиболее распространенные задачи, демонстрирующее непосредственное использование JSON-RPC.
+
+## Смежные темы {#related-topics}
+
+- [Спецификация JSON-RPC](http://www.jsonrpc.org/specification)
+- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
+- [API JavaScript](/developers/docs/apis/javascript/)
+- [API для бэкенда](/developers/docs/apis/backend/)
+- [Клиенты исполнения](/developers/docs/nodes-and-clients/#execution-clients)
diff --git a/public/content/translations/ru/developers/docs/blocks/index.md b/public/content/translations/ru/developers/docs/blocks/index.md
index d843a2b8907..e31ff79b08d 100644
--- a/public/content/translations/ru/developers/docs/blocks/index.md
+++ b/public/content/translations/ru/developers/docs/blocks/index.md
@@ -1,20 +1,21 @@
---
-title: Блоки
-description: 'Обзор блоков в блокчейне Ethereum: их структура данных, почему они необходимы и как сделаны.'
+title: "Блоки"
+description: "Обзор блоков в блокчейне Ethereum: их структура данных, почему они необходимы и как сделаны."
lang: ru
---
Блок — это набор транзакций с хешем от предыдущего блока. Блоки связаны между собой (в цепочку — блокчейн), так как хэши вычисляются криптографически на основе данных каждого блока. Это предотвращает мошенничество, потому что любое изменение в любом прошлом блоке делает все следующие блоки недействительными, так как это изменит их хэши и все пользователи с запущенным блокчейном легко это заметят.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Блоки — простая тема для новичков. Но чтобы помочь вам лучше понять эту страницу, мы рекомендуем сначала прочитать наше [введение в Ethereum](/developers/docs/intro-to-ethereum/), а так же разделы [Аккаунты](/developers/docs/accounts/) и [Транзакции](/developers/docs/transactions/).
+Блоки — простая тема для новичков. Чтобы помочь вам лучше понять эту страницу, мы рекомендуем сначала ознакомиться с разделами [«Аккаунты»](/developers/docs/accounts/), [«Транзакции»](/developers/docs/transactions/) и нашим [введением в Ethereum](/developers/docs/intro-to-ethereum/).
## Зачем нужны блоки? {#why-blocks}
Чтобы удостовериться, что все участники сети Ethereum находятся в синхронизированном состоянии и согласны с точной историей транзакций, мы объединяем наборы транзакций в блоки. Это означает, что десятки (или сотни) транзакций запрашиваются, проверяются и синхронизируются одновременно.
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Диаграмма адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
Учитывая все обязательства, мы предоставляем всем участникам сети достаточно времени, чтобы прийти к консенсусу: даже если запросы с транзакциями происходят десятки раз в секунду, блоки создаются и утверждаются в Ethereum только раз в 12 секунд.
@@ -24,7 +25,7 @@ lang: ru
Как только блок собран случайно выбранным валидатором в сети, он распространяется на всю сеть. Все узлы добавляют этот блок в конец своих цепочек блоков (блокчейнов), а новый выбранный валидатор создает следующий блок. Точный процесс сборки блоков и процесс подтверждения/консенсуса в настоящее время определяются протоколом доказательства владения Ethereum.
-## Протокол доказательства владения {#proof-of-work-protocol}
+## Протокол доказательства доли владения {#proof-of-stake-protocol}
Доказательство владения (proof-of-stake) работает следующим образом:
@@ -33,59 +34,59 @@ lang: ru
- Другие валидаторы, узнавшие о новом блоке, выполняют транзакции повторно, чтобы убедиться, что они согласны с предложенным изменением глобального состояния. Убедившись, что блок действительный, они добавляют его в свою собственную базу данных.
- Если валидатор узнает о двух конфликтующих блоках в одном и том же слоте, он использует алгоритм выбора ответвления, чтобы взять цепочку, которую поддержали голосами с большим количеством ETH.
-[Подробнее о proof-of-stake](/developers/docs/consensus-mechanisms/pos)
+[Подробнее о доказательстве доли владения](/developers/docs/consensus-mechanisms/pos)
## Что входит в блок? {#block-anatomy}
В блоке содержится много разной информации. На самом высоком уровне блок содержит следующие поля:
| Поле | Описание |
-|:---------------- |:-------------------------------------------------- |
+| :--------------- | :------------------------------------------------- |
| `ячейка` | слот, к которому относится блок |
| `proposer_index` | ID валидатора, который предлагает блок |
| `parent_root` | хэш предыдущего блока |
| `state_root` | корневой хэш объекта состояния |
| `содержание` | объект, содержащий несколько полей, описанных ниже |
-Блок `body` содержит в себе несколько собственных полей:
+Тело блока `body` содержит несколько собственных полей:
| Поле | Описание |
-|:-------------------- |:--------------------------------------------------------------- |
+| :------------------- | :-------------------------------------------------------------- |
| `randao_reveal` | значение, используемое для выбора следующего предлагающего блок |
| `eth1_data` | информация о депозитном контракте |
-| `граффити` | случайные данные, используемые для пометки блоков |
+| `graffiti` | случайные данные, используемые для пометки блоков |
| `proposer_slashings` | список валидаторов, которые будут удалены |
| `attester_slashings` | лист свидетелей, которые будут удалены |
-| `аттестации` | список свидетельств в пользу текущего блока |
+| `аттестации` | список аттестаций, сделанных для предыдущих слотов |
| `депозиты` | список новых депозитов в депозитный контракт |
| `voluntary_exits` | список валидаторов, покидающих сеть |
| `sync_aggregate` | подгруппа валидаторов, обслуживающая легкие клиенты |
| `execution_payload` | транзакции, выпущенные из клиента-исполнителя |
-Поле `attestations` содержит список всех свидетельств в блоке. У свидетельств есть собственный тип данных, который содержит несколько частичек данных. Каждое свидетельство содержит следующее:
+Поле `attestations` содержит список всех аттестаций в блоке. У свидетельств есть собственный тип данных, который содержит несколько частичек данных. Каждое свидетельство содержит следующее:
-| Поле | Описание |
-|:------------------ |:--------------------------------------------------------- |
-| `aggregation_bits` | список валидаторов, участвовавших в этом свидетельстве |
-| `данные` | контейнер с несколькими подполями |
-| `подпись` | агрегированная подпись всех свидетельствующих валидаторов |
+| Поле | Описание |
+| :----------------- | :--------------------------------------------------------- |
+| `aggregation_bits` | список валидаторов, участвовавших в этом свидетельстве |
+| `данные` | контейнер с несколькими подполями |
+| `подпись` | агрегированная подпись набора валидаторов для части `data` |
-Поле `data` в свидетельстве `attestation` содержит следующие данные:
+Поле `data` в `аттестации` содержит следующее:
| Поле | Описание |
-|:------------------- |:----------------------------------------------------------- |
+| :------------------ | :---------------------------------------------------------- |
| `ячейка` | слот, к которому относится свидетельство |
-| `index` | индексы свидетельствующих валидаторов |
-| `beacon_block_root` | корневой хэш блока Beacon, в котором содержится этот объект |
+| `индекс` | индексы свидетельствующих валидаторов |
+| `beacon_block_root` | корневой хэш блока Beacon, рассматриваемого как голова цепи |
| `источник` | последняя обоснованная контрольная точка |
| `target` | пограничный блок последней эпохи |
-Выполнение транзакций в `execution_payload` обновляет глобальное состояние. Все клиенты перезапускают транзакции в `execution_payload`, чтобы убедиться, что новое состояние совпадает с полем `state_root` нового блока. Так клиенты могут убедиться, что новый блок действителен и можно безопасно добавлять его в свою цепочку блоков. `execution payload` — это объект, содержащий несколько полей. Также есть `execution_payload_header`, в котором находится важная обобщенная информация о данных исполнения. Эти структуры данных организованы следующим образом:
+Выполнение транзакций в `execution_payload` обновляет глобальное состояние. Все клиенты повторно выполняют транзакции в `execution_payload`, чтобы убедиться, что новое состояние соответствует значению в поле `state_root` нового блока. Так клиенты могут убедиться, что новый блок действителен и можно безопасно добавлять его в свою цепочку блоков. Сам `execution payload` является объектом с несколькими полями. Также существует `execution_payload_header`, который содержит важную сводную информацию о данных исполнения. Эти структуры данных организованы следующим образом:
`execution_payload_header` содержит следующие поля:
| Поле | Описание |
-|:------------------- |:----------------------------------------------------------------------- |
+| :------------------ | :---------------------------------------------------------------------- |
| `parent_hash` | хэш родительского блока |
| `fee_recipient` | адрес аккаунта для оплаты комиссий за транзакции |
| `state_root` | корневой хэш глобального состояния после внесения изменений в этот блок |
@@ -95,58 +96,58 @@ lang: ru
| `block_number` | номер текущего блока |
| `gas_limit` | максимум газа, доступного в этом блоке |
| `gas_used` | количество газа, использованного в этом блоке |
-| `временная отметка` | время блока |
+| `timestamp` | время блока |
| `extra_data` | дополнительные случайные данные в виде необработанных байтов |
| `base_fee_per_gas` | значение базового уровня комиссии |
| `block_hash` | хэш блока исполнения |
| `transactions_root` | корневой хэш транзакций в полезной нагрузке |
| `withdrawal_root` | корневой хэш выводов в полезной нагрузке |
-Сама по себе проверочная строка `execution_payload` содержит следующие данные (заметьте, что она идентична заголовку, если не учитывать, что, в отличие корневого хэша транзакций, она включает текущий список транзакций и информации о выводах):
-
-| Поле | Описание |
-|:------------------- |:----------------------------------------------------------------------- |
-| `parent_hash` | хэш родительского блока |
-| `fee_recipient` | адрес аккаунта для оплаты комиссий за транзакции |
-| `state_root` | корневой хэш глобального состояния после внесения изменений в этот блок |
-| `receipts_root` | хэш дерева чеков о транзакциях |
-| `logs_bloom` | структура данных, содержащая журналы событий |
-| `prev_randao` | значение, используемое для случайного выбора валидатора |
-| `block_number` | номер текущего блока |
-| `gas_limit` | максимум газа, доступного в этом блоке |
-| `gas_used` | количество газа, использованного в этом блоке |
-| `временная отметка` | время блока |
-| `extra_data` | дополнительные случайные данные в виде необработанных байтов |
-| `base_fee_per_gas` | значение базового уровня комиссии |
-| `block_hash` | хэш блока исполнения |
-| `транзакции` | список транзакций, которые должны быть исполнены |
-| `вывод средств` | список объектов на вывод средств |
-
-Список `withdrawals` содержит объекты вывода `withdrawal`, структурированные следующим образом:
+Сам `execution_payload` содержит следующее (обратите внимание, что он идентичен заголовку, за исключением того, что вместо корневого хэша транзакций он включает фактический список транзакций и информацию о выводе средств):
+
+| Поле | Описание |
+| :----------------- | :---------------------------------------------------------------------- |
+| `parent_hash` | хэш родительского блока |
+| `fee_recipient` | адрес аккаунта для оплаты комиссий за транзакции |
+| `state_root` | корневой хэш глобального состояния после внесения изменений в этот блок |
+| `receipts_root` | хэш дерева чеков о транзакциях |
+| `logs_bloom` | структура данных, содержащая журналы событий |
+| `prev_randao` | значение, используемое для случайного выбора валидатора |
+| `block_number` | номер текущего блока |
+| `gas_limit` | максимум газа, доступного в этом блоке |
+| `gas_used` | количество газа, использованного в этом блоке |
+| `timestamp` | время блока |
+| `extra_data` | дополнительные случайные данные в виде необработанных байтов |
+| `base_fee_per_gas` | значение базового уровня комиссии |
+| `block_hash` | хэш блока исполнения |
+| `транзакции` | список транзакций, которые должны быть исполнены |
+| `вывод средств` | список объектов на вывод средств |
+
+Список `withdrawals` содержит объекты `withdrawal`, структурированные следующим образом:
| Поле | Описание |
-|:---------------- |:--------------------------------------------- |
-| `address` | адрес аккаунта, с которого производится вывод |
-| `amount` | сумма вывода |
-| `index` | значение индекса вывода |
+| :--------------- | :-------------------------------------------- |
+| `адрес` | адрес аккаунта, с которого производится вывод |
+| `сумма` | сумма вывода |
+| `индекс` | значение индекса вывода |
| `validatorIndex` | значение индекса валидатора |
## Время блока {#block-time}
Интервал (или время) блока — это время, разделяющее блоки. В Ethereum время разделено на единицы по 12 секунд, называемые «слотами». В каждом слоте выбирается один валидатор, который будет предлагать блок. Предположим, что все валидаторы онлайн и работают исправно, добавляя блок в каждый слот. Тогда интервал блока составит 12 секунд. Тем не менее, некоторые валидаторы могут быть офлайн, когда от них требуется предложить блок, так что иногда слоты могут оставаться пустыми.
-Такая реализация отличается от доказательства работы, где время блока лишь предполагаемое и определяется целевой сложностью майнинга в протоколе. [Средний интервал блока](https://etherscan.io/chart/blocktime) в Ethereum — это замечательный пример того, что переход с доказательства работы на доказательство владения четко прослеживается по равномерному появлению новых блоков каждые 12 секунд.
+Такая реализация отличается от доказательства работы, где время блока лишь предполагаемое и определяется целевой сложностью майнинга в протоколе. [Среднее время блока](https://etherscan.io/chart/blocktime) в Ethereum является прекрасным примером этого, поскольку переход от доказательства работы к доказательству доли владения можно четко проследить по стабильному новому времени блока в 12 секунд.
## Размер блока {#block-size}
Последнее важное примечание — сами блоки ограничены по размеру. Каждый блок имеет целевой размер в 30 миллионов единиц газа, но размер блоков будет увеличиваться или уменьшаться в соответствии с загруженностью сети до предела блока в 60 миллионов единиц газа (двукратный размер от целевого блока). Лимит газа блока можно увеличивать или уменьшать на коэффициент 1/1024 от лимита газа предыдущего блока. В результате валидаторы могут изменять лимит газа блока посредством процедуры консенсуса. Общее количество газа, израсходованного всеми транзакциями в блоке, должно быть меньше, чем предел газа в блоке. Это гарантирует, что блоки не могут быть произвольно большими. Если бы блоки могли быть произвольно большими, то менее производительные полные узлы со временем не смогли бы поддерживать сеть в связи с требованиями к пространству и скорости. Чем больше блок, тем больше вычислительных мощностей нужно, чтобы обработать блоки вовремя к следующему слоту. Это централизующая сила, сопротивление которой достигается путем ограничения размера блоков.
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Транзакции](/developers/docs/transactions/)
- [Газ](/developers/docs/gas/)
-- [Доказательство владения (PoS)](/developers/docs/consensus-mechanisms/pos)
+- [Доказательство владения](/developers/docs/consensus-mechanisms/pos)
diff --git a/public/content/translations/ru/developers/docs/bridges/index.md b/public/content/translations/ru/developers/docs/bridges/index.md
new file mode 100644
index 00000000000..5098a8c69fb
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/bridges/index.md
@@ -0,0 +1,138 @@
+---
+title: "Мосты"
+description: "Обзор мостов для разработчиков"
+lang: ru
+---
+
+С распространением блокчейнов L1 и решений для [масштабирования](/developers/docs/scaling/) L2, наряду с постоянно растущим числом децентрализованных приложений, работающих в разных цепочках, потребность в обмене данными и перемещении активов между блокчейнами стала неотъемлемой частью сетевой инфраструктуры. Существуют различные типы мостов, которые помогают сделать это возможным.
+
+## Потребность в мостах {#need-for-bridges}
+
+Мосты существуют для соединения блокчейн сетей. Они обеспечивают подключение и функциональную совместимость между блокчейнами.
+
+Блокчейны существуют в изолированных средах, это означает, что блокчейны не имеют возможности для торговли и коммуникаций с другими блокчейнами напрямую, т.н. естественным образом. В результате, несмотря на то, что в экосистеме может быть значительная активность и инновации, она ограничена отсутствием связи и совместимости с другими экосистемами.
+
+Мосты предлагают способ для изолированных сред блокчейна соединяться друг с другом. Они устанавливают транспортный маршрут между блокчейнами, по которому токены, сообщения, произвольные данные и даже вызовы [умных контрактов](/developers/docs/smart-contracts/) могут передаваться из одной цепочки в другую.
+
+## Преимущества мостов {#benefits-of-bridges}
+
+Проще говоря, мосты открывают множество вариантов использования, позволяя сетям блокчейнов обмениваться данными и перемещать активы между ними.
+
+Блокчейны обладают уникальными сильными и слабыми сторонами, а также подходами к построению приложений (таких, как скорость, пропускная способность, дороговизна и т. д.). Мосты помогают развитию всей криптоэкосистемы, позволяя блокчейнам использовать инновации друг друга.
+
+Для разработчиков, мосты обеспечивают следующие возможности:
+
+- Передача любых данных, информации и активов между сетями.
+- Разблокировка новых функций и вариантов использования протоколов в качестве мостов, расширяет возможности проектирования для того, что могут предложить протоколы. Например, протокол "yield farming", первоначально развернутый в основной сети Ethereum, может предлагать пулы ликвидности во всех сетях, совместимых с EVM.
+- Возможность использовать сильные стороны различных блокчейнов. Например, разработчики могут извлечь выгоду из более низких комиссий, предлагаемых различными решениями L2, путем развертывания своих децентрализованных приложений через rollups, а сайдчейны и пользователи могут соединяться посредством их.
+- Сотрудничество между разработчиками из различных блокчейн-экосистем для создания новых продуктов.
+- Привлечение пользователей и сообществ из различных экосистем в свои децентрализованные приложения.
+
+## Как работают мосты? {#how-do-bridges-work}
+
+Хотя существует множество [типов конструкций мостов](https://li.fi/knowledge-hub/blockchain-bridges-and-classification/), выделяются три способа облегчения межсетевой передачи активов:
+
+- **Блокировка и минт —** блокировка активов в исходной сети и минт активов в сети назначения.
+- **Сжигание и минт —** сжигание активов в исходной сети и минт активов в сети назначения.
+- **Атомарные свопы —** обмен активов в исходной сети на активы в сети назначения с другой стороной.
+
+## Типы мостов {#bridge-types}
+
+Мосты обычно можно классифицировать одним из следующих сегментов:
+
+- **Нативные мосты —** эти мосты обычно создаются для начальной загрузки ликвидности на определенном блокчейне, что упрощает пользователям перевод средств в экосистему. Например, [мост Arbitrum](https://bridge.arbitrum.io/) создан для того, чтобы пользователям было удобно переходить из основной сети Ethereum в Arbitrum. Другие подобные мосты включают Polygon PoS Bridge, [шлюз Optimism](https://app.optimism.io/bridge) и т. д.
+- **Мосты на основе валидаторов или оракулов —** эти мосты полагаются на внешний набор валидаторов или оракулов для проверки межсетевых переводов. Примеры: Multichain и Across.
+- **Универсальные мосты для передачи сообщений —** эти мосты могут передавать активы, а также сообщения и произвольные данные между сетями. Примеры: Axelar, LayerZero, и Nomad.
+- **Сети ликвидности —** эти мосты в основном ориентированы на передачу активов из одной сети в другую посредством атомарных свопов. Как правило, они не поддерживают передачу сообщений между сетями. Примеры: Connext и Hop.
+
+## Компромиссы, которые следует учесть {#trade-offs}
+
+С мостами нет идеальных решений. Скорее, есть только компромиссы, сделанные для достижения цели. Разработчики и пользователи могут оценивать мосты на основе следующих факторов:
+
+- **Безопасность —** кто проверяет систему? Мосты, защищенные внешними валидаторами, обычно менее безопасны, чем мосты, которые локально или изначально защищены валидаторами блокчейна.
+- **Удобство —** сколько времени требуется для завершения транзакции и сколько транзакций должен подписать пользователь? Сколько времени занимает у разработчика интеграция моста и насколько сложен этот процесс?
+- **Возможности подключения —** к каким различным сетям назначения может подключаться мост (т. е. роллапы, сайдчейны, другие блокчейны уровня 1 и т. д.), и насколько сложно интегрировать новый блокчейн?
+- **Возможность передавать более сложные данные —** может ли мост обеспечивать передачу сообщений и более сложных произвольных данных между сетями или он поддерживает только межсетевую передачу активов?
+- **Экономичность —** сколько стоит передача активов между сетями через мост? Как правило, мосты взимают фиксированную или переменную комиссию в зависимости от стоимости газа и ликвидности конкретных маршрутов. Также очень важно оценить экономическую эффективность моста на основе капитала, необходимого для обеспечения его безопасности.
+
+На высшем уровне, мосты можно разделить на доверенные и недоверенные.
+
+- **Доверенные —** доверенные мосты проходят внешнюю проверку. Они используют внешний набор верификаторов (федерации с мультиподписями, многосторонними вычислительными системами, сетью оракулов) для отправки данных по сетям. В результате они могут предложить отличные возможности подключения и обеспечить полностью обобщенную передачу сообщений по сетям. Также они, как правило, хорошо работают с точки зрения скорости и экономической эффективности. Это достигается за счет обеспечения безопасности, так как пользователи должны полагаться на безопасность моста.
+- **Бездоверительные —** эти мосты для передачи сообщений и токенов полагаются на блокчейны, которые они соединяют, и их валидаторов. Они «недоверенные», потому что не добавляют новых предположений о доверии (в дополнение к блокчейнам). Как результат, недоверенные мосты считаются более безопасными, чем доверенные.
+
+Чтобы оценить недоверенные мосты на основе других факторов, мы должны разбить их на обобщенные мосты передачи сообщений и сети ликвидности.
+
+- **Универсальные мосты для передачи сообщений —** эти мосты отличаются высокой безопасностью и возможностью передавать более сложные данные между сетями. Как правило, они также являются экономически эффективными. Однако эти преимущества, как правило, достигаются за счет ухудшения связности для мостов с легкими клиентами (например, IBC) и снижения скорости для оптимистичных мостов (например, Nomad), использующих доказательства мошенничества.
+- **Сети ликвидности —** эти мосты используют атомарные свопы для передачи активов и являются локально верифицируемыми системами (т. е. для проверки транзакций они используют валидаторов базовых блокчейнов). В результате они отличаются высокой безопасностью и скоростью. Более того, они считаются сравнительно экономичными и обеспечивают хорошую связность. Однако их главный недостаток — неспособность передавать более сложные данные, поскольку они не поддерживают межсетевую передачу сообщений.
+
+## Риски, связанные с мостами {#risk-with-bridges}
+
+На долю мостов приходятся три крупнейших [взлома в сфере DeFi](https://rekt.news/leaderboard/), и они все еще находятся на ранней стадии разработки. Использование любого моста сопряжено со следующими рисками:
+
+- **Риск, связанный с умными контрактами —** хотя многие мосты успешно прошли аудиты, достаточно одной уязвимости в умном контракте, чтобы активы оказались под угрозой взлома (например, [мост Wormhole для Solana](https://rekt.news/wormhole-rekt/)).
+- **Системные финансовые риски —** многие мосты используют обернутые активы для минтинга канонических версий исходного актива в новой сети. Это подвергает экосистему системному риску, поскольку мы уже видели случаи эксплуатации уязвимостей в обернутых версиях токенов.
+- **Контрагентский риск —** некоторые мосты используют доверенную конструкцию, которая требует от пользователей исходить из предположения, что валидаторы не вступят в сговор с целью кражи средств пользователей. Необходимость доверять этим третьим сторонам подвергает пользователей таким рискам, как раг-пуллы, цензура и другие злонамеренные действия.
+- **Открытые вопросы —** учитывая, что мосты находятся на начальных этапах разработки, существует много вопросов без ответов, касающихся того, как мосты будут работать в различных рыночных условиях, например, во время перегрузки сети и при непредвиденных событиях, таких как атаки на уровне сети или откаты состояния. Эта неопределенность порождает определенные риски, степень которых до сих пор неизвестна.
+
+## Как децентрализованные приложения могут использовать мосты? {#how-can-dapps-use-bridges}
+
+Вот несколько практических применений, которые разработчики могут рассмотреть в отношении мостов и переноса своих децентрализованных приложений в другие сети:
+
+### Интеграция мостов {#integrating-bridges}
+
+У разработчиков есть множество способов добавить поддержку мостов:
+
+1. **Создание собственного моста —** создание безопасного и надежного моста — непростая задача, особенно если вы выбираете путь с минимизацией доверия. Более того, это требует многолетнего опыта и технических знаний в области исследований масштабируемости и совместимости. Кроме того, потребуется специальная команда для обслуживания моста и привлечения достаточной ликвидности для обеспечения его рентабельности.
+
+2. **Предложение пользователям нескольких вариантов мостов —** многие [децентрализованные приложения](/developers/docs/dapps/) требуют от пользователей наличия своего нативного токена для взаимодействия с ними. Чтобы предоставить пользователям доступ к своим токенам, они предлагают на своем веб-сайте различные варианты мостов. Однако этот метод является лишь временным решением проблемы, поскольку он уводит пользователя из интерфейса децентрализованного приложения и по-прежнему требует взаимодействия с другими децентрализованными приложениями и мостами. Это усложняет процесс адаптации и увеличивает вероятность совершения ошибок.
+
+3. **Интеграция моста —** это решение не требует, чтобы децентрализованное приложение отправляло пользователей на внешние интерфейсы моста и DEX. Это позволяет децентрализованным приложениям улучшить процесс адаптации пользователей. Однако у этого подхода есть свои ограничения:
+
+ - Оценка и обслуживание мостов — это сложный и трудоемкий процесс.
+ - Выбор одного моста создает единую точку отказа и зависимость.
+ - Децентрализованное приложение ограничено возможностями моста.
+ - Одних лишь мостов может быть недостаточно. Децентрализованным приложениям могут потребоваться DEX для предоставления дополнительных функций, таких как межсетевые свопы.
+
+4. **Интеграция нескольких мостов —** это решение устраняет многие проблемы, связанные с интеграцией одного моста. Однако у него также есть ограничения, поскольку интеграция нескольких мостов требует больших ресурсов и создает технические и коммуникационные накладные расходы для разработчиков — самого дефицитного ресурса в криптоиндустрии.
+
+5. **Интеграция агрегатора мостов —** еще один вариант для децентрализованных приложений — интеграция решения для агрегации мостов, которое дает им доступ к нескольким мостам. Агрегаторы мостов наследуют сильные стороны всех мостов и, таким образом, не ограничены возможностями какого-либо одного моста. Примечательно, что агрегаторы мостов обычно поддерживают интеграции мостов, что избавляет децентрализованное приложение от необходимости заниматься техническими и операционными аспектами интеграции моста.
+
+Однако у агрегаторов мостов тоже есть ограничения. Так, например, несмотря на то, что они могут предложить большее количество мостов, на рынке неизбежно будет присутствовать намного больше мостов, чем может предложить агрегатор. Более того, как и мосты, агрегаторы мостов также подвержены рискам, связанным со смарт-контрактами и технологиями (больше смарт-контрактов = больше рисков).
+
+Если децентрализованное приложение выбирает путь интеграции моста или агрегатора, существуют различные варианты в зависимости от предполагаемой глубины интеграции. Например, если это всего лишь интеграция на уровне фронтенда для улучшения процесса адаптации пользователя, децентрализованное приложение может интегрировать виджет. Однако если интеграция предназначена для использования более сложных межсетевых стратегий, таких как стейкинг, доходное фермерство и т. д., децентрализованное приложение интегрирует SDK или API.
+
+### Развертывание децентрализованного приложения в нескольких сетях {#deploying-a-dapp-on-multiple-chains}
+
+Чтобы развернуть децентрализованное приложение в нескольких сетях, разработчики могут использовать такие платформы для разработки, как [Alchemy](https://www.alchemy.com/), [Hardhat](https://hardhat.org/), [Moralis](https://moralis.io/) и т. д. Как правило, эти платформы поставляются с компонуемыми плагинами, которые могут позволить децентрализованным приложениям работать в нескольких сетях. Например, разработчики могут использовать детерминированный прокси-сервер развертывания, предлагаемый [плагином hardhat-deploy](https://github.com/wighawag/hardhat-deploy).
+
+#### Примеры:
+
+- [Как создавать межсетевые децентрализованные приложения](https://moralis.io/how-to-build-cross-chain-dapps/)
+- [Создание межсетевого NFT-маркетплейса](https://youtu.be/WZWCzsB1xUE)
+- [Moralis: создание межсетевых NFT-приложений](https://www.youtube.com/watch?v=ehv70kE1QYo)
+
+### Мониторинг активности контрактов в разных сетях {#monitoring-contract-activity-across-chains}
+
+Для мониторинга активности контрактов в разных сетях разработчики могут использовать субграфы и платформы для разработчиков, такие как Tenderly, для наблюдения за умными контрактами в режиме реального времени. Такие платформы также имеют инструменты, которые предлагают более широкие функциональные возможности мониторинга данных для межсетевых действий, например, проверку [событий, генерируемых контрактами](https://docs.soliditylang.org/en/v0.8.14/contracts.html?highlight=events#events), и т. д.
+
+#### Инструменты
+
+- [The Graph](https://thegraph.com/en/)
+- [Tenderly](https://tenderly.co/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Блокчейн-мосты](/bridges/) — ethereum.org
+- [Система оценки рисков мостов от L2Beat](https://l2beat.com/bridges/summary)
+- [Блокчейн-мосты: создание сетей криптосетей](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) — 8 сентября 2021 г. — Дмитрий Берензон
+- [Трилемма совместимости](https://blog.connext.network/the-interoperability-trilemma-657c2cf69f17) — 1 октября 2021 г. — Арджун Бхуптани
+- [Кластеры: как доверенные и минимизирующие доверие мосты формируют мультисетевой ландшафт](https://blog.celestia.org/clusters/) — 4 октября 2021 г. — Мустафа аль-Бассам
+- [LI.FI: в мостах доверие — это спектр](https://blog.li.fi/li-fi-with-bridges-trust-is-a-spectrum-354cd5a1a6d8) — 28 апреля 2022 г. — Арджун Чанд
+- [Состояние решений для совместимости роллапов](https://web.archive.org/web/20250428015516/https://research.2077.xyz/the-state-of-rollup-interoperability) — 20 июня 2024 г. — Алекс Хук
+- [Использование общей безопасности для защищенной межсетевой совместимости: комитеты состояний Lagrange и не только](https://web.archive.org/web/20250125035123/https://research.2077.xyz/harnessing-shared-security-for-secure-blockchain-interoperability) — 12 июня 2024 г. — Эммануэль Авосика
+
+Кроме того, вот несколько содержательных презентаций [Джеймса Прествича](https://twitter.com/_prestwich), которые помогут глубже понять, что такое мосты:
+
+- [Строим мосты, а не огороженные сады](https://youtu.be/ZQJWMiX4hT0)
+- [Разбираем мосты](https://youtu.be/b0mC-ZqN8Oo)
+- [Почему горят мосты](https://youtu.be/c7cm2kd20j8)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/index.md
index 7a6a1760cb4..27ebaf5de7b 100644
--- a/public/content/translations/ru/developers/docs/consensus-mechanisms/index.md
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/index.md
@@ -1,43 +1,42 @@
---
-title: Механизмы консенсуса
-description: Объяснение протоколов консенсуса в распределенных системах и роль, которую они играют в Ethereum.
+title: "Механизмы консенсуса"
+description: "Объяснение протоколов консенсуса в распределенных системах и роль, которую они играют в Ethereum."
lang: ru
-incomplete: true
---
-Когда дело доходит до блокчейнов, таких как Ethereum, которые по сути являются распределенными базами данных, то узлы сети должны быть готовы достичь согласия относительно текущего состояния системы. Это достигается благодаря использованию механизмов консенсуса.
+Термин 'механизм консенсуса' часто используется в разговорной речи для обозначения 'proof-of-stake', 'proof-of-work' или 'proof-of-authority' протоколов. Однако это всего лишь компоненты в механизмах консенсуса, которые защищают от [атак Сибиллы](/glossary/#sybil-attack). Механизмы консенсуса - это полный набор идей, протоколов и стимулов, позволяющих распределённому набору узлов договариваться о состоянии блокчейна.
-Хотя механизмы консенсуса не связаны напрямую с созданием децентрализованного приложения, их понимание проливает свет на концепции, относящиеся к вашему опыту и опыту ваших пользователей, такие как цены на газ и время транзакции.
+## Предварительные условия {#prerequisites}
-## Прежде чем начать {#prerequisites}
-
-Для лучшего понимания этой страницы мы рекомендуем сначала прочитать [введение в Ethereum](/developers/docs/intro-to-ethereum/).
+Для лучшего понимания этой страницы мы рекомендуем вам сначала прочитать [введение в Ethereum](/developers/docs/intro-to-ethereum/).
## Что такое консенсус? {#what-is-consensus}
-Под консенсусом мы подразумеваем достижение общего согласия. Рассмотрим группу людей, идущих в кино. Если нет разногласий по выбранному фильму, то достигается консенсус. В противном случае эта группа разойдется.
+Под консенсусом мы подразумеваем достижение общего согласия. Рассмотрим группу людей, идущих в кино. Если нет разногласия по предлагаемому выбору фильма, то консенсус достигнут. Если есть разногласия, то группа должна иметь способ для решения, какой фильм смотреть. В крайних случаях группа в конце концов разделится.
-Что касается блокчейна, достижение консенсуса означает, что по крайней мере 51 % узлов в сети согласны со следующим глобальным состоянием сети.
+Что касается блокчейна Ethereum, этот процесс формализован, и достижение консенсуса означает, что не менее 66 % узлов в сети согласны с глобальным состоянием сети.
## Что такое механизм консенсуса? {#what-is-a-consensus-mechanism}
-Механизмы консенсуса (также известные как консенсусные протоколы или алгоритмы консенсуса) позволяют распределенным системам (сетям компьютеров) работать вместе и оставаться в безопасности.
+Термин механизм консенсуса относится ко всему стеку протоколов, стимулам и идеям, позволяющим сети узлов согласовывать состояние блокчейна.
+
+Ethereum использует механизм консенсуса, основанный на proof-of-stake, который является следствием своей криптовалютной экономической безопасности от набора вознаграждений и штрафов, применяемых к капиталу, закрытому для дольщиков. Эта структура стимулов поощряет отдельных дольщиков быть честными валидаторами, наказывает тех, кто ими не является, и значительно усложняет атаку на сеть.
-На протяжении десятилетий эти механизмы используются для достижения консенсуса между узлами баз данных, серверами прикладных программ и другими инфраструктурами предприятий. В последние годы были изобретены новые механизмы консенсуса, позволяющие криптоэкономическим системам, таким как Ethereum, согласовывать состояние сети.
+Кроме этого, имеется протокол, который управляет процессом выбора честных валидаторов для предложения или валидации блоков, обработки транзакций и голосования за главу цепочки. В редких ситуациях, когда несколько блоков находится в одном и том же положении вблизи главы цепочки, применяется механизм выбора ветки, который выбирает блоки, составляющие "самую тяжелую" цепочку по результатам измерений ряда валидаторов, голосовавших за блоки с учетом их баланса эфира.
-Консенсусный механизм в криптоэкономической системе также помогает предотвратить определенные экономические атаки. Теоретически нападающий может скомпрометировать консенсус, контролируя 51 % сети. Механизмы консенсуса призваны сделать такую «атаку 51 %» нецелесообразной. Для решения этой проблемы безопасности разработаны различные механизмы.
+Некоторые концепции, явно не определенные в коде, важны для консенсуса, например, дополнительная безопасность, обеспечиваемая потенциальной внеполосной социальной координацией, в виде последней линии защиты от атак на сеть.
-
+Эти компоненты вместе образуют механизм консенсуса.
-## Виды алгоритмов консенсуса {#types-of-consensus-mechanisms}
+## Типы механизмов консенсуса {#types-of-consensus-mechanisms}
-### Доказательство работы (PoW) {#proof-of-work}
+### Доказательство работы {#proof-of-work}
-Ethereum, как и Bitcoin, в настоящее время использует протокол консенсуса **«Доказательство работы» (Proof-of-Work, PoW)**.
+Подобно Биткоину, Ethereum когда-то использовал протокол консенсуса, основанный на **доказательстве работы (PoW)**.
#### Создание блока {#pow-block-creation}
-Доказательство работы выполняется [майнерами](/developers/docs/consensus-mechanisms/pow/mining/), которые конкурируют за создание новых блоков, которые полны обработанными транзакциями. Победитель делится новым блоком с остальной сетью и зарабатывает свежевыпущенные ETH. Гонку выигрывает тот, чей компьютер быстрее всех решает математическую задачу — создает криптографическую связь между текущим блоком и предыдущим. Решение этой задачи — это и есть работа в системе с доказательством работы.
+Майнеры соревнуются за создание новых блоков, заполненных обработанными транзакциями. Победитель делится новым блоком с остальной сетью и зарабатывает свежевыпущенные ETH. Гонка выиграна компьютером, который способен всех быстрее решить математическую головоломку. Это порождает криптографическую связь между текущим блоком и предыдущим блоком. Решение этой задачи — это и есть работа в системе с доказательством работы. Затем каноническая цепочка определяется правилом выбора форка, выбирающим набор блоков, для майнинга которых было проделано больше всего работы.
#### Безопасность {#pow-security}
@@ -45,17 +44,17 @@ Ethereum, как и Bitcoin, в настоящее время используе
Подробнее о [доказательстве работы](/developers/docs/consensus-mechanisms/pow/)
-### Доказательство владения (PoS) {#proof-of-stake}
+### Доказательство владения {#proof-of-stake}
-Ethereum планируется перевести на консенсусный протокол **«Доказательство владения» (Proof-of-Stake, PoS)**.
+Сейчас Ethereum использует протокол консенсуса, основанный на **доказательстве владения (PoS)**.
#### Создание блока {#pos-block-creation}
-Доказательством владения занимаются валидаторы, которые поставили свои ЕТН для участия в системе. Валидатор выбирается случайно, чтобы создавать новые блоки, делиться ими с сетью и получать награды. Вместо выполнения интенсивной вычислительной работы вам просто нужно разместить свои ETH в сети. Именно это стимулирует здоровое поведение в сети.
+Валидаторы создают блоки. Один валидатор, выбранный случайным образом в каждом слоте в качестве предлагающего блоков. Их консенсусные клиенты требуют объединения транзакций в 'исполняемую полезную нагрузку' от своего парного клиента исполнения. Они оборачивают ”полезную нагрузку на выполнение" в согласованные данные, чтобы сформировать блок, который они отправляют другим узлам сети Ethereum. Производство этого блока награждается в ETH. В редких случаях, когда в одном слоте имеется несколько возможных блоков-кандидатов или если узлы получают информацию о блоке в разное время, алгоритм выбора вилки выбирает блок, который образует цепочку с наибольшим весом подтверждения (где вес - это количество валидаторов, масштабированное по их балансу ETH).
#### Безопасность {#pos-security}
-Система с доказательством владения защищена тем фактом, что вам понадобится 51 % от общего количества ETH для компрометации этой цепочки. И что ваша ставка аннулируется за злонамеренное поведение.
+A proof-of-stake system is secure crypto-economically because an attacker attempting to take control of the chain must destroy a massive amount of ETH. Система вознаграждений побуждает отдельных игроков вести себя честно, а штрафы не позволяют действовать злонамеренно.
Подробнее о [доказательстве владения](/developers/docs/consensus-mechanisms/pos/)
@@ -67,27 +66,27 @@ Ethereum планируется перевести на консенсусный
### Устойчивость к атаке Сибиллы и выбор цепи {#sybil-chain}
-Технически доказательство работы и доказательство владения сами по себе не являются протоколами консенсуса, но их часто называют таковыми для простоты. На самом деле они являются механизмами сопротивления атаке Сибиллы и селекторами авторов блоков. Они позволяют решить, кто является автором последнего блока. Именно этот механизм устойчивости к атаке Сибиллы в сочетании с правилом выбора цепи составляет истинный механизм консенсуса.
-
-**Устойчивость к атакам Сибиллы** показывает, насколько хорошо протокол противостоит [атаке Сибиллы](https://wikipedia.org/wiki/Sybil_attack). Атаки Сибиллы — это попытки одного пользователя или группы выдать себя за множество пользователей. Устойчивость к этому типу атак имеет важное значение для децентрализованного блокчейна и позволяет майнерам и валидаторам получать одинаковое вознаграждение в зависимости от вложенных ресурсов. Доказательство работы и доказательство владения защищают от этого, заставляя пользователей тратить много энергии или вносить большой залог. Эти средства защиты являются экономическим сдерживающим фактором для атак Сибиллы.
+Доказательство работы(PoW) и доказательство владения(PoS) не являются протоколами консенсуса, но они часто называются ими для простоты восприятия. На самом деле они являются механизмами сопротивления атаке Сибиллы и селекторами авторов блоков. Они позволяют решить, кто является автором последнего блока. Другой важнейший компонент это алгоритм выбора цепочки (выбора ветвления), позволяющий узлам выбрать последний корректный блок в цепи, в которой существует несколько блоков в одной позиции.
-**Правило выбора цепи** используется, чтобы решить, какая цепочка является «правильной». Ethereum и Bitcoin в настоящее время используют правило «самой длинной цепи», поэтому самый длинный из блокчейнов оставшиеся узлы и будут принимать за действительный, выбирая его для работы. Для цепей с доказательством работы самая длинная цепочка определяется общей совокупной сложностью выполненной работы.
+**Устойчивость к атаке Сибиллы** показывает, насколько хорошо протокол противостоит атаке Сибиллы. Устойчивость к этому типу атак имеет важное значение для децентрализованного блокчейна и позволяет майнерам и валидаторам получать одинаковое вознаграждение в зависимости от вложенных ресурсов. Доказательство работы и доказательство владения защищают от этого, заставляя пользователей тратить много энергии или вносить большой залог. Эти средства защиты являются экономическим сдерживающим фактором для атак Сибиллы.
-Комбинация принципа доказательства работы и самой длинной цепочки известна как «консенсус Накамото».
+**Правило выбора цепи** используется, чтобы решить, какая цепь является "правильной". Биткоин использует правильно "самой длинной цепи", которое означает что самая длинная цепочка в сети будет принята за действительную и остальные узлы будут обрабатывать её. Для цепей с доказательством работы самая длинная цепочка определяется общей совокупной сложностью выполненной работы. Эфириум, так же использует правило самой длинной цепи. Однако сейчас, Эфириум перешёл на доказательство владения(PoS) и принял обновленный алгоритм ветвления выбора, который измеряет "вес" цепи. Вес - это сумма голосов валидаторов, которая выражается в размере их владения токенами Ethereum(Eth).
-[Сеть Beacon Chain](/roadmap/beacon-chain/) использует механизм консенсуса под названием [Casper the Friendly Finality Gadget](https://arxiv.org/abs/1710.09437), основанный на доказательстве владения.
+Ethereum использует механизм консенсуса, известный как [Gasper](/developers/docs/consensus-mechanisms/pos/gasper/), который сочетает [доказательство владения Casper FFG](https://arxiv.org/abs/1710.09437) с [правилом выбора форка GHOST](https://arxiv.org/abs/2003.03052).
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Что такое алгоритм консенсуса блокчейна?](https://academy.binance.com/en/articles/what-is-a-blockchain-consensus-algorithm)
+- [Что такое алгоритм консенсуса в блокчейне?](https://academy.binance.com/en/articles/what-is-a-blockchain-consensus-algorithm)
- [Что такое консенсус Накамото? Полное руководство для начинающих](https://blockonomi.com/nakamoto-consensus/)
- [Как работает Casper?](https://medium.com/unitychain/intro-to-casper-ffg-9ed944d98b2d)
- [О безопасности и производительности блокчейнов с доказательством работы](https://eprint.iacr.org/2016/555.pdf)
+- [Византийская ошибка](https://en.wikipedia.org/wiki/Byzantine_fault)
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
-- [Доказательство работы (PoW)](/developers/docs/consensus-mechanisms/pow/)
+- [Доказательство работы](/developers/docs/consensus-mechanisms/pow/)
- [Майнинг](/developers/docs/consensus-mechanisms/pow/mining/)
-- [Доказательство владения (PoS)](/developers/docs/consensus-mechanisms/pos/)
+- [Доказательство владения](/developers/docs/consensus-mechanisms/pos/)
+- [Доказательство полномочий](/developers/docs/consensus-mechanisms/poa/)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/poa/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/poa/index.md
new file mode 100644
index 00000000000..80c68a54e59
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/poa/index.md
@@ -0,0 +1,80 @@
+---
+title: "Доказательство полномочий (PoA)"
+description: "Объяснение протокола консенсуса «доказательство полномочий» и его роли в экосистеме блокчейна."
+lang: ru
+---
+
+**Доказательство полномочий (PoA)** — это алгоритм консенсуса на основе репутации, который является модифицированной версией [доказательства доли владения](/developers/docs/consensus-mechanisms/pos/). Он в основном используется в частных цепях, тестовых сетях и локальных сетях разработки. PoA — это основанный на репутации алгоритм консенсуса, который требует доверия к набору авторизованных подписантов для создания блоков, вместо механизма на основе долей в PoS.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем предварительно прочесть, что такое [транзакции](/developers/docs/transactions/), [блоки](/developers/docs/blocks/), и [механизмы консенсуса](/developers/docs/consensus-mechanisms/).
+
+## Что такое доказательство полномочий (PoA)? {#what-is-poa}
+
+Доказательство полномочий — это модифицированная версия **[доказательства доли владения](/developers/docs/consensus-mechanisms/pos/) (PoS)**. Это алгоритм консенсуса, основанный на репутации, в отличие от механизма на основе долей в PoS. Этот термин был впервые представлен в 2017 году Гэвином Вудом, и этот алгоритм консенсуса в основном используется в частных цепях, тестовых сетях и локальных сетях для разработки, поскольку он устраняет необходимость в высококачественных ресурсах, как в PoW, и решает проблемы масштабируемости PoS за счет того, что небольшое подмножество узлов хранит блокчейн и производит блоки.
+
+Доказательство полномочий требует доверия к набору авторизованных подписантов, которые заданы в [первоначальном блоке](/glossary/#genesis-block). В большинстве текущих реализаций все авторизованные подписанты сохраняют равные полномочия и привилегии при определении консенсуса в цепи. Идея стейкинга на основе репутации заключается в том, что каждый авторизованный валидатор хорошо известен всем благодаря таким процедурам, как «знай своего клиента» (KYC), или потому, что единственным валидатором является известная организация — таким образом, если валидатор сделает что-то не так, его личность будет известна.
+
+Существует несколько реализаций PoA, но стандартной реализацией Ethereum является **clique**, которая реализует [EIP-225](https://eips.ethereum.org/EIPS/eip-225). Clique — это удобный для разработчиков и простой в реализации стандарт, поддерживающий все типы синхронизации клиентов. Другие реализации включают [IBFT 2.0](https://besu.hyperledger.org/private-networks/concepts/poa) и [Aura](https://openethereum.github.io/Chain-specification).
+
+## Как это работает {#how-it-works}
+
+В PoA для создания новых блоков выбирается набор авторизованных подписантов. Подписанты выбираются на основе их репутации, и только им разрешено создавать новые блоки. Подписанты выбираются по круговому принципу, и каждому подписанту разрешается создавать блок в определенный промежуток времени. Время создания блока фиксировано, и подписанты должны создать блок в течение этого промежутка времени.
+
+Репутация в данном контексте — это не количественная величина, а скорее репутация известных корпораций, таких как Microsoft и Google. Следовательно, способ выбора доверенных подписантов не является алгоритмическим, а представляет собой обычный человеческий акт _доверия_, когда некая организация, например, Microsoft, создает частную сеть PoA между сотнями или тысячами стартапов и сама выступает в роли единственного доверенного подписанта с возможностью добавления в будущем других известных подписантов, таких как Google. Стартапы, без сомнения, будут доверять Microsoft, что она будет всегда действовать честно, и будут использовать эту сеть. Это решает проблему необходимости стейкинга в различных небольших/частных сетях, которые были созданы для разных целей, чтобы поддерживать их децентрализацию и функционирование, а также устраняет потребность в майнерах, что потребляет много энергии и ресурсов. Некоторые частные сети, такие как VeChain, используют стандарт PoA, а некоторые, например, Binance, модифицируют его, используя [PoSA](https://academy.binance.com/en/glossary/proof-of-staked-authority-posa), который является специальной модифицированной версией PoA и PoS.
+
+Процесс голосования осуществляется самими подписантами. Каждый подписант голосует за добавление или удаление другого подписанта в своем блоке при создании нового блока. Голоса подсчитываются узлами, и подписанты добавляются или удаляются в зависимости от того, достигли ли голоса определенного порога `SIGNER_LIMIT`.
+
+Может возникнуть ситуация, когда происходят небольшие форки; сложность блока зависит от того, был ли блок подписан в свою очередь или вне очереди. Блоки, подписанные «в свою очередь», имеют сложность 2, а блоки, подписанные «вне очереди», — сложность 1. В случае небольших форков цепь, в которой большинство подписантов заверяют блоки «в свою очередь», наберет наибольшую сложность и победит.
+
+## Векторы атаки {#attack-vectors}
+
+### Злонамеренные подписанты {#malicious-signers}
+
+Злонамеренный пользователь может быть добавлен в список подписантов, или ключ/машина для подписи могут быть скомпрометированы. В таком сценарии протокол должен быть в состоянии защитить себя от реорганизаций и спама. Предлагаемое решение заключается в том, что при наличии списка из N авторизованных подписантов, любой подписант может создавать только 1 блок из каждых K. Это гарантирует, что ущерб будет ограничен, а оставшиеся валидаторы смогут проголосовать за исключение злонамеренного пользователя.
+
+### Цензура {#censorship-attack}
+
+Еще один интересный вектор атаки — это если подписант (или группа подписантов) попытается подвергнуть цензуре блоки, в которых голосуют за его удаление из списка авторизации. Чтобы обойти это, разрешенная частота создания блоков для подписантов ограничена до 1 из N/2. Это гарантирует, что злонамеренным подписантам потребуется контролировать не менее 51% аккаунтов для подписи, после чего они фактически станут новым источником истины для цепи.
+
+### Спам {#spam-attack}
+
+Еще один небольшой вектор атаки — злонамеренные подписанты, которые вставляют новые предложения для голосования в каждый создаваемый ими блок. Поскольку узлам необходимо подсчитывать все голоса для создания фактического списка авторизованных подписантов, они должны записывать все голоса с течением времени. Без ограничения окна для голосования этот список может расти медленно, но неограниченно. Решение состоит в том, чтобы установить _скользящее_ окно в W блоков, по истечении которого голоса считаются устаревшими. _Разумным окном может быть 1–2 эпохи._
+
+### Одновременные блоки {#concurrent-blocks}
+
+В сети PoA при наличии N авторизованных подписантов, каждому подписанту разрешается создавать 1 блок из K, что означает, что N-K+1 валидаторов могут создавать блоки в любой момент времени. Чтобы эти валидаторы не соревновались за блоки, каждый подписант должен добавлять небольшое случайное «смещение» ко времени выпуска нового блока. Хотя этот процесс гарантирует, что небольшие форки редки, случайные форки все же могут происходить, как и в основной сети. Если обнаружится, что подписант злоупотребляет своими полномочиями и вызывает хаос, другие подписанты могут проголосовать за его исключение.
+
+Если, например, есть 10 авторизованных подписантов, и каждому подписанту разрешено создавать 1 блок из 20, то в любой момент времени 11 валидаторов могут создавать блоки. Чтобы они не соревновались за создание блоков, каждый подписант добавляет небольшое случайное «смещение» ко времени выпуска нового блока. Это уменьшает возникновение небольших форков, но все же допускает случайные форки, как это видно в основной сети Ethereum. Если подписант злоупотребляет своими полномочиями и вызывает сбои, его могут исключить из сети путем голосования.
+
+## Преимущества и недостатки {#pros-and-cons}
+
+| Преимущества | Недостатки |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Более масштабируемый, чем другие популярные механизмы, такие как PoS и PoW, поскольку основан на ограниченном количестве подписантов блоков. | Сети PoA обычно имеют сравнительно маленькое количество валидирующих узлов. Это делает сети PoA более централизованными. |
+| Блокчейны PoA невероятно дешевы в эксплуатации и обслуживании. | Стать авторизованным подписантом обычно недоступно для обычного человека, поскольку блокчейн требует наличия организаций с устоявшейся репутацией. |
+| Транзакции подтверждаются очень быстро, время может быть менее 1 секунды, поскольку для валидации новых блоков требуется лишь ограниченное число подписантов. | Злонамеренные подписанты могут проводить реорганизацию, осуществлять двойные траты, подвергать цензуре транзакции в сети; эти атаки смягчены, но все еще возможны. |
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-225](https://eips.ethereum.org/EIPS/eip-225) _Стандарт Clique_
+- [Исследование доказательства полномочий](https://github.com/cryptoeconomics-study/website/blob/master/docs/sync/2.4-lecture.md) _Криптоэкономика_
+- [Что такое доказательство полномочий](https://forum.openzeppelin.com/t/proof-of-authority/3577) _OpenZeppelin_
+- [Объяснение доказательства полномочий](https://academy.binance.com/en/articles/proof-of-authority-explained) _binance_
+- [PoA в блокчейне](https://medium.com/techskill-brew/proof-of-authority-or-poa-in-blockchain-part-11-blockchain-series-be15b3321cba)
+- [Объяснение Clique](https://medium.com/@Destiner/clique-cross-client-proof-of-authority-algorithm-for-ethereum-8b2a135201d)
+- [Устаревшая спецификация PoA, Aura](https://openethereum.github.io/Chain-specification)
+- [IBFT 2.0, еще одна реализация PoA](https://besu.hyperledger.org/private-networks/concepts/poa)
+
+### Больше увлекаетесь визуализацией? {#visual-learner}
+
+Посмотрите визуальное объяснение доказательства полномочий:
+
+
+
+## Смежные темы {#related-topics}
+
+- [Доказательство работы](/developers/docs/consensus-mechanisms/pow/)
+- [Доказательство владения](/developers/docs/consensus-mechanisms/pos/)
+
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md
new file mode 100644
index 00000000000..f11716769e4
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md
@@ -0,0 +1,166 @@
+---
+title: "Атаки и защита в Ethereum с доказательством владения"
+description: "Узнайте об известных векторах атак на Ethereum с доказательством владения и о том, как от них защищаются."
+lang: ru
+---
+
+Воры и саботажники постоянно ищут возможности для атаки на клиентское программное обеспечение Ethereum. На этой странице описаны известные векторы атак на уровне консенсуса Ethereum и как можно от них защититься. Информация на этой странице адаптирована из [более длинной версии](https://mirror.xyz/jmcook.eth/YqHargbVWVNRQqQpVpzrqEQ8IqwNUJDIpwRP7SS5FXs).
+
+## Предварительные условия {#prerequisites}
+
+Требуются некоторые базовые знания о [доказательстве доли владения](/developers/docs/consensus-mechanisms/pos/). Кроме того, будет полезно иметь базовое представление об [уровне стимулирования](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties) Ethereum и алгоритме выбора форка [LMD-GHOST](/developers/docs/consensus-mechanisms/pos/gasper).
+
+## Чего хотят злоумышленники? {#what-do-attackers-want}
+
+Распространенное заблуждение заключается в том, что успешный злоумышленник может генерировать новый эфир или выводить эфир из произвольных учетных записей. Ни то, ни другое невозможно, поскольку все транзакции выполняются всеми клиентами-исполнителями в сети. Они должны удовлетворять основным условиям валидности (например, транзакции подписаны приватным ключом отправителя, у отправителя достаточный баланс и т. д.), иначе они просто отменяются. Существует три класса результатов, на которые злоумышленник может нацелиться: реорганизации, двойная финализация или задержка финализации.
+
+**«Реорганизация»** — это перестановка блоков в новом порядке, возможно, с добавлением или удалением блоков в канонической цепи. Злонамеренная реорганизация может привести к включению или исключению определенных блоков, что позволит проводить двойные траты или извлекать ценность с помощью фронт-раннинга и бек-раннинга транзакций (MEV). Реорганизации также могут быть использованы для предотвращения включения определенных транзакций в каноническую цепочку — форма цензуры. Наиболее экстремальной формой реорганизации является “откат финализации”, который удаляет или заменяет блоки, которые ранее были финализированы. Это возможно только в том случае, если злоумышленник уничтожит более ⅓ от общего количества застейканного эфира — эта гарантия известна как “экономическая финальность” — подробнее об этом позже.
+
+**Двойная финальность** — это маловероятное, но серьезное состояние, при котором два форка могут финализироваться одновременно, создавая постоянный раскол в цепи. Теоретически это возможно сделать злоумышленнику, готовому рискнуть 34% от общего количества застейканного эфира. Сообщество будет вынуждено координировать свои действия вне цепи и прийти к соглашению о том, какой цепи следовать, что потребует единства на социальном уровне.
+
+**Атака с задержкой финальности** не позволяет сети достичь необходимых условий для завершения участков цепи. Без финализации трудно доверять финансовым приложениям, построенным поверх Эфириума. Целью атаки с задержкой финализации, скорее всего, является просто разрушение Эфириума, а не получение прямой прибыли, если только у злоумышленника нет каких-либо стратегических коротких позиций.
+
+Атака на социальный слой может быть направлена на подрыв общественного доверия к Эфириуму, снижение цены на эфир, сокращение использования сети или ослабление сообщества Эфириума, чтобы затруднить координацию.
+
+Теперь, когда понятно, почему злоумышленники могут атаковать Ethereum, перейдём к тому, как они могут это сделать.
+
+## Методы атаки {#methods-of-attack}
+
+### Атаки на уровне 0 {#layer-0}
+
+Прежде всего, люди, которые не принимают активного участия в Эфириум (не имеющие запущенного клиентского программного обеспечения), могут атаковать, нацелившись на социальный уровень (уровень 0). Нулевой слой — это фундамент, на котором построен Эфириум, и он представляет собой потенциальную поверхность для атак с последствиями, которые могут распространиться на остальную часть сети. Некоторые примеры:
+
+- Кампания по дезинформации, которая может подорвать доверие сообщества к дорожной карте Эфириум, командам разработчиков, приложениям и т. д. Тогда это могло бы уменьшить число людей, желающих участвовать в обеспечении безопасности сети, что привело бы к снижению как децентрализации, так и криптоэкономической безопасности.
+
+- Целенаправленные атаки и/или запугивание, направленные против сообщества разработчиков. Это может привести к добровольному уходу разработчиков и замедлить прогресс Эфириума.
+
+- Чрезмерное регулирование также может рассматриваться как атака на уровень 0, поскольку оно может быстро лишить стимулов к участию в развитии сети и внедрению Эфириума в жизнь.
+
+- Проникновение осведомленных, но злонамеренных субъектов в сообщество разработчиков, целью которых является замедление прогресса путем затягивания дискуссий, откладывания ключевых решений, создания спама и т. д.
+
+- Взятки, даваемые ключевым игрокам экосистемы Эфириум, чтобы повлиять на принятие решений.
+
+Что делает эти атаки особенно опасными, так это то, что во многих случаях требуется очень мало капитала или технических знаний. Атака 0 слоя может быть мультипликатором криптоэкономической атаки. Например, если цензура или отмена финализации были достигнуты злонамеренным большинством валидаторов, подрыв социального слоя может затруднить координацию ответных мер сообщества.
+
+Защита от атак 0 слоя, вероятно, не является простой, но некоторые базовые принципы могут быть установлены. Одним из них является поддержание общего высокого уровня качества общедоступной информации об Эфириуме, созданной и распространяемой честными членами сообщества через блоги, серверы discord, аннотированные спецификации, книги, подкасты и Youtube. Здесь, в ethereum.org мы прилагаем все усилия, чтобы сохранить точную информацию и перевести ее на как можно большее количество языков. Наполнение пространства высококачественной информацией и мемами — эффективная защита от дезинформации.
+
+Еще одним важным средством защиты от атак на социальные слои является четкое заявление о миссии сообщества и протокол управления. Эфириум позиционирует себя как чемпиона по децентрализации и безопасности среди сетей с умными контрактами первого слоя, а также как протокол, высоко ценящий масштабируемость и устойчивость. Какие бы разногласия ни возникали в сообществе Эфириума, эти основные принципы подвергаются минимальному риску. Согласие с этими основными принципами, и их обсуждение через EIP (предложений по улучшению Эфириума) могут помочь сообществу отличить хороших участников от плохих и ограничить возможности злоумышленников влиять на будущее направление развития сети.
+
+Наконец, крайне важно, чтобы сообщество Эфириума оставалось открытым и гостеприимным для всех участников. Сообщество с привратниками и эксклюзивностью особенно уязвимо для социальных атак, потому что в нем легко создать нарративы “мы и они”. Трайбализм и токсичный максимализм вредят сообществу и подрывают уровень безопасности нулевого слоя. Пользователи Эфириума, заинтересованные в безопасности сети, должны рассматривать свое поведение онлайн и в офлайн как непосредственный вклад в безопасность нулевого слоя Эфириума.
+
+### Атака на протокол {#attacking-the-protocol}
+
+Любой желающий может запустить клиентское программное обеспечение Эфириума. Чтобы добавить валидатор к клиенту, пользователь должен внести 32 эфира в депозитный контракт. Валидатор позволяет пользователю активно участвовать в обеспечении сетевой безопасности Эфириума, предлагая и аттестируя новые блоки. У валидатора есть голос, который он может использовать, чтобы влиять на будущее содержимое блокчейна: он может делать это честно и увеличивать свой запас эфира за счет вознаграждений, или он может попытаться манипулировать процессом в своих интересах, рискуя суммой своего эфира в стейкинге. Один из способов организовать атаку — накопить большую долю от общего количества эфира в стейкинге, а затем использовать ее для того, чтобы перевесить голосами честных валидаторов. Чем большую долю общей суммы эфира в стейкинге контролирует злоумышленник, тем больше у него право голоса, особенно на определенных экономических этапах, которые мы рассмотрим позже. Однако большинство злоумышленников не смогут накопить достаточное количество эфира для атаки таким образом, поэтому вместо этого им приходится использовать тонкие методы, чтобы манипулировать честным большинством, заставляя его действовать определенным образом.
+
+По сути, все атаки с небольшим количеством эфира в стейкинге представляют собой тонкие вариации двух типов неправильного поведения валидатора: недостаточная активность (неспособность аттестации/предложения блока или слишком поздное исполнение этих действий) или чрезмерная активность (аттестация/предложение слишком много раз в одну ячейку). В своих наиболее простых формах эти действия легко обрабатываются алгоритмом выбора форка и уровнем стимулирования, но существуют хитроумные способы использовать систему в интересах злоумышленника.
+
+### Атаки с использованием небольшого количества ETH {#attacks-by-small-stakeholders}
+
+#### Реорганизации {#reorgs}
+
+В нескольких статьях объяснялись атаки на Эфириум, которые приводят к реорганизации или задержке финализации лишь с небольшой долей от общего объема застейканного эфира. Эти атаки обычно основаны на том, что злоумышленник утаивает некоторую информацию от других валидаторов, а затем раскрывает ее каким-либо тонким способом и/или в какой-то подходящий момент. Обычно они направлены на замену какого-либо честного блока (блоков) из канонической цепочки. В работе [Neuder et al 2020](https://arxiv.org/pdf/2102.02247.pdf) показано, как атакующий валидатор может создать и аттестовать блок (`B`) для определенного слота `n+1`, но воздержаться от его распространения на другие узлы в сети. Вместо этого он удерживает этот аттестованный блок до следующего слота `n+2`. Честный валидатор предлагает блок (`C`) для слота `n+2`. Почти одновременно злоумышленник может опубликовать свой удержанный блок (`B`) и удержанные аттестации для него, а также аттестовать `B` как голову цепи своими голосами за слот `n+2`, фактически отрицая существование честного блока `C`. Когда публикуется честный блок `D`, алгоритм выбора форка видит, что `D`, построенный поверх `B`, имеет больший вес, чем `D`, построенный на `C`. Таким образом, злоумышленнику удалось удалить честный блок `C` в слоте `n+2` из канонической цепи с помощью одноблочной ex-ante реорганизации. [Злоумышленник с 34 %](https://www.youtube.com/watch?v=6vzXwwk12ZE) доли имеет очень хороший шанс на успех в этой атаке, как объясняется [в этой заметке](https://notes.ethereum.org/plgVdz-ORe-fGjK06BZ_3A#Fork-choice-by-block-slot-pair). Теоретически, однако, эту атаку можно было бы предпринять с меньшим количеством эфира. В работе [Neuder et al 2020](https://arxiv.org/pdf/2102.02247.pdf) эта атака описывается как работающая при 30-процентной доле, но позже была показана ее осуществимость при [2 % от общей доли](https://arxiv.org/pdf/2009.04987.pdf), а затем и для [одного валидатора](https://arxiv.org/abs/2110.10086#) с использованием техник балансировки, которые мы рассмотрим в следующем разделе.
+
+
+
+Концептуальная схема одноблочной атаки на реорганизацию, описанной выше (адаптирована из https://notes.ethereum.org/plgVdz-ORe-fGjK06BZ_3A#Fork-choice-by-block-slot-pair)
+
+Более изощренная атака может разделить набор честных валидаторов на отдельные группы, которые имеют разные представления о голове цепочки. Это известно как **атака балансировки**. Атакующий ждет своего шанса предложить блок, и когда он появляется, атакующий предлагает два. Он отправляет один блок половине набора честных валидаторов, а другой блок — другой половине. Двойственность была бы обнаружена алгоритмом выбора форка, и предлагающий блок был бы урезан и удален из сети, но два блока все еще существовали бы и имели бы примерно половину набора валидаторов, подтверждающих каждый из форков. Тем временем остальные злонамеренные валидаторы воздерживаются от своих аттестаций. Затем, выборочно передавая подтверждения в пользу того или иного форка достаточному количеству валидаторов, в момент, как только выполняется алгоритм выбора форка, они склоняют накопленный вес аттестаций в пользу того или иного форка. Это может продолжаться бесконечно, при этом атакующие валидаторы поддерживают равномерное распределение валидаторов по двум форкам. Поскольку ни один из форков не может привлечь 2/3 всех голосов, сеть не будет финализированна.
+
+**Атаки отскока** похожи. Атакующие валидаторы снова удерживают свои голоса. Вместо того чтобы выпускать голоса, сохраняя равномерное распределение между двумя форками, они используют свои голоса в подходящие моменты для обоснования контрольных точек, которые различаются между форками A и B. Это переключение обоснования между двумя форками предотвращает наличие пар обоснованных исходных и целевых контрольных точек, которые могут быть завершены в любой из цепочек, что останавливает финализацию.
+
+
+
+Как отскакивающие, так и уравновешивающие атаки основаны на том, что злоумышленник очень точно контролирует время передачи сообщений по сети, что маловероятно. Тем не менее, в протокол встроены средства защиты в виде дополнительного взвешивания быстрых сообщений по сравнению с медленными. Это известно как [proposer-weight boosting](https://github.com/ethereum/consensus-specs/pull/2730). Для защиты от атак отскока алгоритм выбора форка был обновлен так, что последняя обоснованная контрольная точка может переключиться на контрольную точку альтернативной цепи только в течение [первой трети слотов в каждой эпохе](https://ethresear.ch/t/prevention-of-bouncing-attack-on-ffg/6114). Это условие не позволяет злоумышленнику накапливать голоса для последующей их выдачи: алгоритм выбора форка просто остается верным контрольной точке, которую он выбрал в первую 1/3 эпохи, в течение которой проголосовали бы большинство честных валидаторов.
+
+В совокупности эти меры создают сценарий, в котором честный предлагающий блок выдает свой блок очень быстро после начала ячейки, а затем наступает период ~1/3 ячейки (4 секунды), в течение которого этот новый блок может привести к переключению алгоритма выбора форка на другую цепочку. По истечении этого же срока подтверждения, поступающие от медленных валидаторов аттестации, имеют пониженный вес по сравнению с теми, которые поступили ранее. Это в значительной степени благоприятствует оперативным действиям валидаторов при определении головы цепочки и существенно снижает вероятность успешной уравновешивающей или отскакивающей атаки.
+
+Стоит отметить, что сам по себе proposer boosting защищает только от «дешевых реорганизаций», то есть тех, которые пытается совершить злоумышленник с небольшой долей. На самом деле, proposer-boosting сам по себе может быть использован более крупными стейкерами. Авторы [этой публикации](https://ethresear.ch/t/change-fork-choice-rule-to-mitigate-balancing-and-reorging-attacks/11127) описывают, как злоумышленник с 7-процентной долей может стратегически использовать свои голоса, чтобы обманом заставить честных валидаторов строить блоки на его форке, исключая честный блок из цепи путем реорганизации. Эта атака была придумана с учетом идеальных условий задержки, которые очень маловероятны. Шансы атакующего по-прежнему очень велики, и чем больше количество эфира в стейкинге у злоумышленника, тем больше риск для капитала и тем больше экономический сдерживающий фактор.
+
+Также была предложена [атака балансировки, специально нацеленная на правило LMD](https://ethresear.ch/t/balancing-attack-lmd-edition/11853), которая, как предполагалось, была осуществима, несмотря на proposer boosting. Злоумышленник создает две конкурирующие цепочки, предлагая разные блоки каждой половине сети и устанавливая приблизительный баланс между форками. Затем валидаторы в сговоре отправляют противоречивые голоса, рассчитывая время так, чтобы половина сети сначала получила их голоса за форк `A`, а другая половина — за форк `B`. Поскольку правило LMD отбрасывает вторую аттестацию и сохраняет только первую для каждого валидатора, половина сети видит голоса за `A` и ни одного за `B`, а другая половина видит голоса за `B` и ни одного за `A`. Авторы пишут, что правило LMD даёт противнику “поразительную силу” для проведения уравновешивающей атаки.
+
+Этот вектор атаки на LMD был закрыт путем [обновления алгоритма выбора форка](https://github.com/ethereum/consensus-specs/pull/2845) таким образом, что он полностью исключает валидаторов, отправляющих противоречивые голоса, из рассмотрения при выборе форка. Двуликие валидаторы также теряют свое будущее влияние с помощью алгоритма выбора форка. Это предотвращает описанную выше уравновешивающую атаку, одновременно сохраняя устойчивость к лавинным атакам.
+
+Другой класс атак, названный [**лавинными атаками**](https://ethresear.ch/t/avalanche-attack-on-proof-of-stake-ghost/11854/3), был описан в [статье от марта 2022 года](https://arxiv.org/pdf/2203.01315.pdf). Чтобы организовать лавинную атаку, злоумышленнику необходимо контролировать несколько последовательных предлагающих блок валидаторов. В каждой из ячеек предложения блока злоумышленник не отправляет свой блок, собирая цепочку до тех пор, пока честная цепочка не достигнет веса поддерева, равного весу удерживаемых блоков. Затем удерживаемые блоки освобождаются таким образом, чтобы они были максимально двойственными с настоящей цепочкой. Авторы предполагают, что proposer boosting — основная защита от уравновешивающих и подскакивающих атак не защищает от некоторых вариантов лавинной атаки. Однако авторы также продемонстрировали атаку только на сильно идеализированнуой версии алгоритма выбора форка Эфириума (они использовали GHOST без LMD).
+
+Лавинная атака ослабляется с помощью LMD-части алгоритма выбора форка LMD-GHOST. LMD означает “управляемый последними сообщениями” и относится к таблице, хранящейся каждым валидатором, содержащей последнее сообщение, полученное от других валидаторов. Это поле обновляется только в том случае, если новое сообщение получено из более поздней ячейки, чем та, которая уже есть в таблице для конкретного валидатора. На практике это означает, что в каждой ячейке первым полученным сообщением является то, которое было принято, а любые дополнительные сообщения являются двусмысленностями, которые следует игнорировать. Иными словами, консенсус-клиенты не учитывают двусмысленности — они используют первое поступившее сообщение от каждого проверяющего, и двусмысленности просто отбрасываются, предотвращая лавинные атаки.
+
+Существует несколько других потенциальных будущих обновлений правила выбора форка, которые могли бы повысить безопасность, обеспечиваемую proposer-boost. Один из них — [view-merge](https://ethresear.ch/t/view-merge-as-a-replacement-for-proposer-boost/13739), при котором аттестующие замораживают свое видение выбора форка за `n` секунд до начала слота, а автор блока затем помогает синхронизировать видение цепи по всей сети. Другим потенциальным обновлением является [финальность за один слот](https://notes.ethereum.org/@vbuterin/single_slot_finality), которая защищает от атак, основанных на времени доставки сообщений, путем финализации цепи всего за один слот.
+
+#### Задержка финальности {#finality-delay}
+
+[В той же статье](https://econcs.pku.edu.cn/wine2020/wine2020/Workshop/GTiB20_paper_8.pdf), где впервые была описана недорогая атака с реорганизацией одного блока, также была описана атака с задержкой финальности (также известная как «сбой живучести»), которая основана на том, что злоумышленник является автором блока на границе эпох. Это важно, потому что эти блоки границ эпох становятся контрольными точками, которые Casper FFG использует для финализации частей цепочки. Злоумышленник просто удерживает свой блок до тех пор, пока достаточное количество честных валидаторов не использует свои голоса FFG в пользу предыдущего блока, граничащего с эпохой, в качестве текущей цели финализации. Затем он освобождает свой удержанный блок. Они голосуюь за свой блок, и остальные честные валидаторы делают то же самое, создавая форки с разными целевыми контрольными точками. Если злоумышленник правильно рассчитал время, он сможет предотвратить финализацию, потому что не будет перевеса в 2/3 голосов, подтверждающего ни ту, ни другую развилку. Чем меньше эфира в стейкинге, тем более точным должен быть выбор времени, поскольку злоумышленник напрямую контролирует меньшее количество аттестаций и тем ниже вероятность того, что злоумышленник, контролирующий валидатора, будет предлагающим блок, граничащий с эпохой.
+
+#### Атаки на большом расстоянии {#long-range-attacks}
+
+Существует также класс атак, специфичных для блокчейнов с доказательством владения, в которых валидатор, участвовавший в блоке genesis, поддерживает отдельный форк блокчейна рядом с честным, в конечном итоге убеждая честный набор валидаторов переключиться на него в подходящее время гораздо позже. Этот тип атаки невозможен в Эфириум из-за устройства финализации, которая гарантирует, что все валидаторы согласовывают состояние настоящей цепочки через регулярные промежутки времени (“контрольные точки”). Этот простой механизм нейтрализует злоумышленников, ориентирующихся на длинные дистанции, потому что клиенты Эфириум просто не будут переупорядочивать завершенные блоки. Новые узлы, присоединяющиеся к сети, делают это, находя доверенный хэш недавнего состояния (контрольную точку «[слабой субъективности](https://blog.ethereum.org/2014/11/25/proof-stake-learned-love-weak-subjectivity/)») и используя его в качестве псевдо-генезис блока для дальнейшего построения цепи. Это создает "шлюз доверия" для нового узла, входящего в сеть, прежде чем он сможет начать самостоятельно проверять информацию.
+
+#### Отказ в обслуживании {#denial-of-service}
+
+Механизм доказательства владения Эфириума выбирает одного валидатора из общего набора валидаторов, который будет предлагать блок в каждой ячейке. Это может быть вычислено с использованием общеизвестной функции, и злоумышленник может идентифицировать следующего предлагающего блок немного раньше, чем его предложение блока. Затем злоумышленник может отправить спам предлагающему блок, чтобы помешать ему обмениваться информацией со своими соседними узлами. Для остальной части сети могло бы показаться, что предлагающий блок находится в автономном режиме, и ячейка просто опустела бы. Это может быть формой цензуры в отношении конкретных валидаторов, препятствующей им добавлять информацию в блокчейн. Внедрение выборов единого секретного лидера (SSLE) или выборов не единого секретного лидера снизит риски DoS, поскольку только тот, кто предлагает блок, знает, что он был выбран для этой цели. Это еще не реализовано, но является активной областью [исследований и разработок](https://ethresear.ch/t/secret-non-single-leader-election/11789).
+
+Все это указывает на то, что очень сложно успешно атаковать Эфириум с небольшим количеством эфиров в стейкинге. Атаки, которые были описаны здесь, требуют идеализированного алгоритма выбора форка, невероятных условий работы сети, или векторы атак уже были закрыты относительно незначительными исправлениями клиентского программного обеспечения. Это, конечно, не исключает возможности существования уязвимостей нулевых дней, но это демонстрирует чрезвычайно высокую планку технических способностей, знаний на уровне консенсуса и необходимости удачи, необходимых для того, чтобы атакующий с малым количеством эфира в стейкинге был эффективным. С точки зрения злоумышленника, его лучшим выбором может быть накопить как можно больше эфира и вернуться вооруженным большей долей от общей суммы в стейкинге.
+
+### Злоумышленники, использующие >= 33 % от общей доли {#attackers-with-33-stake}
+
+Все атаки, упомянутые ранее в этой статье, с большей вероятностью увенчаются успехом, когда у злоумышленника будет больше эфира для голосования и больше валидаторов, которые могут быть выбраны для предложения блоков в каждой из ячеек. Таким образом, злонамеренный валидатор может стремиться контролировать как можно больше эфира в стейкинге.
+
+33% всего застейканного эфира является ориентиром для злоумышленника, потому что при наличии большего количества, чем эта сумма, у него есть возможность предотвратить финализации цепочки без необходимости точно контролировать действия других валидаторов. Они могут просто исчезнуть все вместе. Если 1/3 или более размещенного эфира неправильно аттестует или не аттестует вовсе, то превосходство честных валидаторов в 2/3 не может существовать, и цепочка не может завершиться. Защитой от этого является утечка неактивности. Утечка неактивности идентифицирует тех валидаторов, которые либо не могут аттестовать, либо аттестуют вопреки мнению большинства. Застейканный эфир, принадлежащий этим неподтверждающим валидаторам, постепенно истощается, пока, в конечном счете, в совокупности он не составит менее 1/3 от общего количества, так что цепочка сможет снова финализироваться.
+
+Цель утечки неактивности состоит в том, чтобы снова начать финализировать цепочку. Однако злоумышленник также теряет часть своего застейканного эфира. Постоянное бездействие валидаторов, составляющих 33% от общего объема застейканного эфира, обходится очень дорого, даже несмотря на то, что валидаторы не урезаются.
+
+Если предположить, что сеть Ethereum асинхронна (т. е. существуют задержки между отправкой и получением сообщений), злоумышленник, контролирующий 34 % от общей доли, может вызвать двойную финальность. Это связано с тем, что злоумышленник может уклониться от ответа, когда его выберут в качестве предлагающего блок, а затем дважды проголосовать со всеми своими валидаторами. Это создает ситуацию, когда существует форк блокчейна, за каждое ответвление из которого голосует 34% размещенного эфира. Каждый форк требует, чтобы только 50% оставшихся валидаторов проголосовали за него, чтобы оба форка были поддержаны подавляющим большинством, и в этом случае обе цепочки могут финализироваться (потому что 34% валидаторов атакующих + половина оставшихся 66% = 67% на каждом форке). Каждый конкурирующий блок должен был бы быть получен примерно 50% честных валидаторов, поэтому эта атака жизнеспособна только тогда, когда злоумышленник имеет некоторую степень контроля над временем распространения сообщений по сети, так что он может подтолкнуть половину честных валидаторов к каждой из цепочек. Злоумышленник обязательно уничтожил бы всю свою сумму в стейкинге (34% от ~10 миллионов эфиров с сегодняшним набором валидаторов), чтобы достичь этой двойной финализации, потому что 34% его валидаторов голосовали бы дважды одновременно — нарушение, урезаемое с максимальным штрафом. Защитой от этой атаки является очень большая стоимость уничтожения 34% от общего количества эфира в стейкинге. Восстановление после этой атаки потребовало бы от сообщества Эфириум координации и соглашения следовать одному из форков и игнорировать другой.
+
+### Злоумышленники, использующие ~50 % от общей доли {#attackers-with-50-stake}
+
+Имея 50% застейканного эфира, группа злонамеренных валидаторов теоретически могла бы разделить цепочку на два форка одинакового размера, а затем просто использовать всю свою 50%-ную долю для голосования вопреки набору честных валидаторов, тем самым сохранив две вилки и предотвратив финализованность. Утечка неактивности на обоих форках в конечном итоге привела бы к финализации обеих цепочек. К этому моменту единственным вариантом будет вернуться к социальному восстановлению.
+
+Очень маловероятно, что враждебная группа валидаторов сможет постоянно контролировать ровно 50 % от общей доли, учитывая некоторую изменчивость числа честных валидаторов, сетевую задержку и т. д. Огромная стоимость организации такой атаки в сочетании с низкой вероятностью успеха представляется сильным сдерживающим фактором для рационального злоумышленника, особенно когда небольшие дополнительные инвестиции для получения _более_ 50 % открывают гораздо больше возможностей.
+
+При доле >50 % от общей злоумышленник сможет доминировать в алгоритме выбора форка. В этом случае злоумышленник смог бы подтвердить это большинством голосов, что дало бы ему достаточный контроль для проведения коротких реорганизаций без необходимости обманывать честных клиентов. Честные валидаторы последовали бы примеру, потому что их алгоритм выбора форка также рассматривал бы цепочку злоумышленника как самую тяжелую, чтобы цепочка могла финализироваться. Это позволяет злоумышленнику подвергать цензуре определенные транзакции, выполнять кратковременные реорганизации и извлекать максимальный MEV, переупорядочивая блоки в свою пользу. Защитой от этого является огромная стоимость более чем половины эфира в стейкинге (в настоящее время чуть менее 19 миллиардов долларов США), которая подвергается риску со стороны злоумышленника, поскольку социальный слой, скорее всего, вмешается и примет честный форк меньшинства, резко обесценивая активы злоумышленника.
+
+### Злоумышленники, использующие >= 66 % от общей доли {#attackers-with-66-stake}
+
+Злоумышленник, у которого 66% или более от общего количества застейканного эфира, может финализировать свою предпочтительную цепочку без необходимости принуждать каких-либо честных валидаторов. Злоумышленник может просто проголосовать за предпочитаемый им форк, а затем финализировать его просто потому, что он может голосовать большинством голосов. Будучи наиболее заинтересованной стороной, злоумышленник всегда будет контролировать содержимое финализированных блоков, имея право тратить, перематывать историю и тратить снова, подвергать цензуре определенные транзакции и перестраивать цепочку по своему усмотрению. Приобретая дополнительный эфир для контроля 66 %, а не 51 %, злоумышленник фактически покупает возможность проводить ex post реорганизации и отмены финальности (т. е. изменять прошлое, а также контролировать будущее). Единственными реальными средствами защиты здесь являются огромная стоимость 66% от общего объема застейканного эфира и возможность обратиться к социальному слою для координации принятия альтернативного форка. Мы можем рассмотреть это более подробно в следующем разделе.
+
+## Люди: последняя линия обороны {#people-the-last-line-of-defense}
+
+Если нечестным валидаторам удастся финализировать предпочитаемую ими версию цепочки, сообщество Эфириум окажется в сложной ситуации. Каноническая цепочка включает в себя нечестный раздел, вписанный в ее историю, в то время как честные валидаторы могут в конечном итоге быть наказаны за подтверждение альтернативной (честной) цепочки. Обратите внимание, что финализированная, но неправильная цепочка также может возникнуть из-за ошибки в клиенте большинства. В конце концов, единственный запасной вариант — положиться на социальный, нулевой слой, для разрешения ситуации.
+
+Одна из сильных сторон консенсуса PoS в Ethereum заключается в том, что существует [ряд оборонительных стратегий](https://youtu.be/1m12zgJ42dI?t=1712), которые сообщество может применить в случае атаки. Минимальным ответом могло бы стать принудительное отключение валидаторов-злоумышленников от сети без каких-либо дополнительных штрафных санкций. Чтобы повторно войти в сеть, злоумышленнику пришлось бы присоединиться к очереди активации, которая гарантирует постепенный рост набора валидаторов. Например, добавление достаточного количества валидаторов, чтобы удвоить количество застейканного, занимает около 200 дней, фактически покупая честным валидаторам 200 дней до того, как злоумышленник сможет предпринять еще одну атаку 51%. Однако сообщество также может принять решение наказать злоумышленника более сурово, отменив предыдущие вознаграждения или удалив часть (до 100%) их вложенного капитала.
+
+Каким бы ни было наказание, наложенное на злоумышленника, сообщество также должно сообща решить, является ли нечестная цепочка, несмотря на то, что она является предпочтительной для алгоритма выбора форка, закодированного в клиентах Эфириум, на самом деле недействительной и что сообщество должно вместо этого опираться на честную цепочку. Честные валидаторы могли бы коллективно договориться о создании принятого сообществом форка блокчейна Эфириум, который мог бы, например, отделиться от канонической цепочки до начала атаки или принудительно удалить валидаторов злоумышленников. Честные валидаторы получили бы стимул развивать эту цепочку, потому что они избежали бы штрафов, применяемых к ним за то, что они не смогли (правильно) подтвердить цепочку злоумышленника. Биржи, онлайн-сервисы и приложения, построенные на Эфириуме, предположительно предпочли бы быть в честной цепочке и последовали бы за честными валидаторами в честный блокчейн.
+
+Однако это стало бы серьезным испытанием в области управления. Некоторые пользователи и валидаторы, несомненно, проиграют в результате возврата к честной цепочке, транзакции в блоках, проверенные после атаки, потенциально могут быть откачены, нарушая работу слоя приложений, и это просто подрывает этику некоторых пользователей, которые склонны полагать, что “код — это закон”. Биржи и приложения, скорее всего, связали офчейн-действия с ончейн-транзакциями, которые теперь могут быть отменены, что запустит каскад отзывов и исправлений, которые будет трудно справедливо распутать, особенно если незаконно полученные доходы были смешаны, депонированы в DeFi или другие деривативы со вторичными эффектами для честных пользователей. Несомненно, некоторые пользователи, возможно, даже институциональные, уже извлекли бы выгоду из нечестной цепочки либо благодаря своей проницательности, либо по счастливой случайности, и могли бы выступить против форка, чтобы защитить свою прибыль. Звучали призывы отрепетировать реакцию сообщества на атаки >51 %, чтобы можно было быстро осуществить разумные скоординированные меры по смягчению последствий. Полезное обсуждение от Виталика есть на ethresear.ch [здесь](https://ethresear.ch/t/timeliness-detectors-and-51-attack-recovery-in-blockchains/6925) и [здесь](https://ethresear.ch/t/responding-to-51-attacks-in-casper-ffg/6363), а также в Twitter [здесь](https://twitter.com/skylar_eth/status/1551798684727508992?s=20&t=oHZ1xv8QZdOgAXhxZKtHEw). Целью скоординированного социального реагирования должно быть очень целенаправленное и конкретное наказание злоумышленника и минимизация последствий для других пользователей.
+
+Управление и без того является сложной темой. Управление экстренным реагированием на уровне 0 на нечестную финализирующую цепь, несомненно, будет сложной задачей для сообщества Ethereum, но это [случалось](/ethereum-forks/#dao-fork-summary) в истории Ethereum — [дважды](/ethereum-forks/#tangerine-whistle)).
+
+Тем не менее, есть что-то довольно приятное в последнем запасном варианте, который находится в нашем мире. В конечном счете, даже с таким феноменальным набором технологий, если когда-нибудь случится худшее, реальным людям придётся координировать свои действия, чтобы выбраться из ситуации.
+
+## Сводка {#summary}
+
+На этой странице были рассмотрены некоторые способы, с помощью которых злоумышленники могут попытаться атаковать протокол консенсуса доказательство владения Эфириума. Были изучены атаки реорганизаций и задержки финализаций для злоумышленников с увеличением их доли общего количества застейканного эфира. В целом, более богатый злоумышленник имеет больше шансов на успех, потому что его эфир в стейкинге выражается в праве голоса, который он может использовать для влияния на содержимое будущих блоков. При определенном количестве застейканного эфира сила атакующего повышается:
+
+33 %: задержка финальности
+
+34 %: задержка финальности, двойная финальность
+
+51 %: задержка финальности, двойная финальность, цензура, контроль над будущим блокчейна
+
+66 %: задержка финальности, двойная финальность, цензура, контроль над будущим и прошлым блокчейна
+
+Существует также ряд более изощренных атак, которые требуют небольшого количества застейканного эфира, но полагаются на очень изощренного злоумышленника, имеющего точный контроль над временем отправки сообщений, чтобы склонить честных валидаторов в свою пользу.
+
+В целом, несмотря на потенциальные векторы атаки, риск успешной атаки низок, особенно по сравнению с эквивалентами proof-of-work. Это связано с огромной стоимостью заложенного эфира, подвергающегося риску атакующего, стремящегося перегрузить честных валидаторов своей избирательной силой. Встроенный слой стимулирования "кнут и пряник" защищает от большинства злоупотреблений, особенно для атакующих с низкими ставками. Более тонкие атаки с отскоком и балансировкой также маловероятны, потому что реальные сетевые условия делают очень сложным точное управление доставкой сообщений конкретным подмножествам валидаторов, а команды разработчиков быстро закрывают известные векторы атак с отскоком, балансировкой и лавинными атаками с помощью простых исправлений.
+
+Атаки с долей в 34%, 51% или 66% вероятно потребуют внесетевой социальной координации для разрешения. Хотя это, вероятно, будет болезненным для сообщества, способность сообщества реагировать вне сети обеспечивает сильное отпугивающее воздействие на атакующего. Социальный слой Ethereum - это крайняя мера - технически успешная атака все еще может быть нейтрализована путем согласия сообщества принять честный форк. Начнется гонка между злоумышленником и сообществом Ethereum — миллиарды долларов, потраченные на 66-процентную атаку, вероятно, будут уничтожены успешной атакой социальной координации, если она будет проведена достаточно быстро, оставив злоумышленника с огромным количеством неликвидного застейканного эфира на заведомо нечестной цепи, игнорируемой сообществом Ethereum. Вероятность того, что это окажется прибыльным для злоумышленника, достаточно низка, чтобы служить эффективным сдерживающим фактором. Вот почему так важны инвестиции в поддержание сплоченного социального уровня с тесно согласованными ценностями.
+
+## Дополнительные материалы {#further-reading}
+
+- [Более подробная версия этой страницы](https://mirror.xyz/jmcook.eth/YqHargbVWVNRQqQpVpzrqEQ8IqwNUJDIpwRP7SS5FXs)
+- [Виталик об окончательности расчетов](https://blog.ethereum.org/2016/05/09/on-settlement-finality/)
+- [Статья о LMD GHOST](https://arxiv.org/abs/2003.03052)
+- [Документ Casper-FFG](https://arxiv.org/abs/1710.09437)
+- [Документ Gasper](https://arxiv.org/pdf/2003.03052.pdf)
+- [Спецификации консенсуса Proposer weight boosting](https://github.com/ethereum/consensus-specs/pull/2730)
+- [Атаки отскока на ethresear.ch](https://ethresear.ch/t/prevention-of-bouncing-attack-on-ffg/6114)
+- [Исследование SSLE](https://ethresear.ch/t/secret-non-single-leader-election/11789)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attestations/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attestations/index.md
new file mode 100644
index 00000000000..c89cdab057b
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/attestations/index.md
@@ -0,0 +1,92 @@
+---
+title: "Аттестации"
+description: "Описание аттестаций на Ethereum с доказательством владения."
+lang: ru
+---
+
+Ожидается, что валидатор будет создавать, подписывать и транслировать аттестацию в течение каждой эпохи. На этой странице описано, как выглядят эти аттестации и как они обрабатываются и передаются между клиентами консенсуса.
+
+## Что такое аттестация? {#what-is-an-attestation}
+
+Каждую [эпоху](/glossary/#epoch) (6,4 минуты) валидатор предлагает аттестацию в сеть. Аттестация проводится для определенной ячейки в эпохе. Цель аттестации — проголосовать в пользу представления валидатором цепочки, в частности, за самый последний обоснованный блок и первый блок в текущей эпохе (известные как контрольные точки `source` и `target`). Эта информация объединяется для всех участвующих валидаторов, позволяя сети достичь консенсуса относительно состояния блокчейна.
+
+Аттестация содержит следующие компоненты:
+
+- `aggregation_bits`: битовый список валидаторов, в котором позиция сопоставляется с индексом валидатора в их комитете; значение (0/1) указывает, подписал ли валидатор `data` (т. е. активен ли он и согласен ли с создателем блока)
+- `data`: сведения, относящиеся к аттестации, как определено ниже
+- `signature`: подпись BLS, которая объединяет подписи отдельных валидаторов
+
+Первая задача для аттестующего валидатора — собрать `data`. `data` содержит следующую информацию:
+
+- `slot`: номер слота, к которому относится аттестация
+- `index`: номер, который определяет, к какому комитету принадлежит валидатор в данном слоте
+- `beacon_block_root`: корневой хэш блока, который валидатор видит во главе цепочки (результат применения алгоритма выбора форка)
+- `source`: часть голосования за окончательность, указывающая, какой блок валидаторы считают последним обоснованным блоком
+- `target`: часть голосования за окончательность, указывающая, какой блок валидаторы считают первым блоком в текущей эпохе
+
+Как только `data` собраны, валидатор может изменить бит в `aggregation_bits`, соответствующий индексу своего валидатора, с 0 на 1, чтобы показать, что он участвовал.
+
+Наконец, валидатор подписывает аттестацию и транслирует её в сеть.
+
+### Агрегированная аттестация {#aggregated-attestation}
+
+Существуют значительные трудности с передачей этих данных по сети для каждого валидатора. Поэтому аттестации от отдельных валидаторов агрегируются внутри подсетей, прежде чем передаваться более широко. Это включает в себя агрегирование подписей, чтобы транслируемая аттестация содержала данные консенсуса (`data`) и одну подпись, сформированную путем объединения подписей всех валидаторов, которые согласны с этими `data`. Это можно проверить с помощью `aggregation_bits`, поскольку они предоставляют индекс каждого валидатора в его комитете (идентификатор которого указан в `data`), который можно использовать для запроса отдельных подписей.
+
+В каждую эпоху 16 валидаторов в каждой подсети выбираются в качестве `агрегаторов`. Агрегаторы собирают все аттестации, о которых они узнают по gossip-сети и которые содержат `data`, эквивалентные их собственным. Отправитель каждой совпадающей аттестации записывается в `aggregation_bits`. Затем агрегаторы транслируют аттестационную совокупность в более широкую сеть.
+
+Когда валидатор выбирается в качестве предлагающего блок, он упаковывает совокупные аттестации из подсетей вплоть до последней ячейки в новом блоке.
+
+### Жизненный цикл включения аттестации {#attestation-inclusion-lifecycle}
+
+1. Генерация
+2. Распространение
+3. Объединение в совокупность
+4. Распространение
+5. Включение
+
+Жизненный цикл аттестации представлен на схеме ниже:
+
+
+
+## Вознаграждения {#rewards}
+
+Валидаторы получают вознаграждение за отправку аттестаций. Вознаграждение за аттестацию зависит от флагов участия (источник, цель и голова), базового вознаграждения и коэффициента участия.
+
+Каждый из флагов участия может быть истинным или ложным, в зависимости от предоставленной аттестации и задержки ее включения.
+
+Наилучший сценарий возникает, когда все три флага истинны, и в этом случае валидатор получает (за каждый правильный флаг):
+
+`reward += base reward * flag weight * flag attesting rate / 64`
+
+Коэффициент аттестации флага измеряется как сумма эффективных балансов всех аттестующих валидаторов для данного флага в сравнении с общим активным эффективным балансом.
+
+### Базовое вознаграждение {#base-reward}
+
+Базовое вознаграждение рассчитывается в соответствии с количеством аттестующих валидаторов и их эффективными балансами застейканного эфира:
+
+`base reward = validator effective balance x 2^6 / SQRT(Effective balance of all active validators)`
+
+#### Задержка включения {#inclusion-delay}
+
+В тот момент, когда валидаторы голосовали за голову цепи (`блок n`), `блок n+1` еще не был предложен. Поэтому аттестации естественным образом включаются **на один блок позже**, так что все аттестации, в которых `блок n` был выбран головой цепи, включаются в `блок n+1`, а **задержка включения** составляет 1. Если задержка вхождения удваивается до двух ячеек, вознаграждение за аттестацию уменьшается вдвое, поскольку для расчета вознаграждения за аттестацию базовое вознаграждение умножается на величину, обратную задержке вхождения.
+
+### Сценарии аттестации {#attestation-scenarios}
+
+#### Отсутствующий голосующий валидатор {#missing-voting-validator}
+
+У валидаторов есть максимум 1 эпоха для предоставления своей аттестации. Если аттестация была пропущена в эпоху 0, они могут отправить ее с задержкой вхождения в эпоху 1.
+
+#### Отсутствующий агрегатор {#missing-aggregator}
+
+Всего на каждую эпоху приходится 16 агрегаторов. Кроме того, случайные валидаторы подписываются на **две подсети на 256 эпох** и служат резервной копией на случай отсутствия агрегаторов.
+
+#### Отсутствующий создатель блока {#missing-block-proposer}
+
+Обратите внимание, что в некоторых случаях удачливый агрегатор также может стать предлагающим блок. Если аттестация не была включена из-за того, что предлагающий блок пропал, следующий предлагающий блок валидатор подберет агрегированную аттестацию и включит ее в следующий блок. Однако **задержка включения** увеличится на единицу.
+
+## Дополнительные материалы {#further-reading}
+
+- [Аттестации в аннотированной спецификации консенсуса от Виталика](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#attestationdata)
+- [Аттестации на eth2book.info](https://eth2book.info/capella/part3/containers/dependencies/#attestationdata)
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/block-proposal/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/block-proposal/index.md
new file mode 100644
index 00000000000..80370191d42
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/block-proposal/index.md
@@ -0,0 +1,69 @@
+---
+title: "Предложение блока"
+description: "Объяснение того, как предлагаются блоки в Эфириуме с доказательством владения."
+lang: ru
+---
+
+Блоки являются фундаментальными единицами блокчейна. Блоки — это отдельные единицы информации, которые передаются между узлами, согласовываются и добавляются в базу данных каждого узла. На этой странице объясняется, как они производятся.
+
+## Предварительные условия {#prerequisites}
+
+Предложение блока — часть протокола доказательства владения. Чтобы лучше понять эту страницу, мы рекомендуем вам прочитать о [доказательстве владения (proof-of-stake)](/developers/docs/consensus-mechanisms/pos/) и [архитектуре блоков](/developers/docs/blocks/).
+
+## Кто предлагает блоки? Кто создает блоки? {#who-produces-blocks}
+
+Аккаунты валидаторов предлагают блоки. Аккаунты валидаторов управляются операторами узлов, которые запускают программы валидаторов в рамках своих клиентов исполнения и консенсуса. Также для этого операторы узлов должны иметь не менее 32 ETH, внесённых в депозитный контракт. Однако каждый валидатор лишь периодически предлагает блок. Эфириум измеряет время в ячейках и эпохах. Каждая ячейка длится 12 секунд, а 32 ячейки (6,4 минуты) составляют одну эпоху. Каждая ячейка является возможностью добавить новый блок в сеть.
+
+### Случайный выбор {#random-selection}
+
+В каждой ячейке псевдослучайно выбирается один валидатор, чтобы предложить блок. В блокчейне нет такого понятия, как истинная случайность, так как если бы каждый из узлов сети сам генерировал по-настоящему случайные числа, узлы не могли бы прийти к консенсусу. Вместо этого, цель — сделать процесс выбора валидатора непредсказуемым. Случайность в Эфириуме достигается при помощи алгоритма RANDAO, который смешивает хеш от инициатора блока с некоторым семенем (seed), обновляющимся каждый блок. Это значение используется для выбора определённого валидатора из общего их набора. Выбор валидатора фиксируется за две эпохи для защиты от определенных видов манипуляций с семенами.
+
+Хотя валидаторы и делают дополнения к значению RANDAO в каждой ячейке, глобальное значение RANDAO обновляется лишь раз за эпоху. Чтобы вычислить индекс следующего инициатора блока, значение RANDAO смешивается с номерами ячеек для получения уникального значения в каждой из них. Вероятность того, что будет выбран отдельный валидатор, не равна `1/N` (где `N` = общее количество активных валидаторов). Вместо этого, она является взвешенной для каждого валидатора в соответствии с его эффективным балансом ETH. Максимальный эффективный баланс составляет 32 ETH (это означает, что `balance < 32 ETH` приводит к меньшему весу, чем `balance == 32 ETH`, но `balance > 32 ETH` не приводит к большему весу, чем `balance == 32 ETH`).
+
+Только один инициатор блока выбирается в каждой ячейке. При нормальных условиях, один производитель блока создаёт и выпускает один блок в свою выделенную ячейку. Создание двух блоков для одной и той же ячейки является нарушением, известным как "неоднозначность", из-за которого может пройти наказание валидатора.
+
+## Как создаётся блок? {#how-is-a-block-created}
+
+Инициатор блока должен передать подписанный блок beacon, который строится поверх самого последнего заголовка цепочки в соответствии с представлением его собственного локально запущенного алгоритма выбора форка. Алгоритм выбора форка применяет все стоящие в очереди подтверждения, оставшиеся от предыдущей ячейки, а затем находит блок с наибольшим накопленным весом подтверждений за всю его историю. Этот блок становится родителем нового блока, созданного инициатором.
+
+Инициатор блока создаёт блок, собирая данные из своей локальной базы данных и просматривая сеть. Содержимое блока показано во фрагменте ниже:
+
+```rust
+class BeaconBlockBody(Container):
+ randao_reveal: BLSSignature
+ eth1_data: Eth1Data
+ graffiti: Bytes32
+ proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
+ attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS]
+ attestations: List[Attestation, MAX_ATTESTATIONS]
+ deposits: List[Deposit, MAX_DEPOSITS]
+ voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
+ sync_aggregate: SyncAggregate
+ execution_payload: ExecutionPayload
+```
+
+Поле `randao_reveal` принимает проверяемое случайное значение, которое инициатор блока получает, подписывая номер текущей эпохи. `eth1_data` — это голос за представление инициатора блока о депозитном контракте, включающий корень дерева Меркла депозитов и общее количество депозитов, которое позволяет проверять новые депозиты. `graffiti` — это необязательное поле, которое можно использовать для добавления сообщения в блок. `proposer_slashings` и `attester_slashings` — это поля, содержащие доказательство того, что определённые валидаторы совершили наказуемые нарушения, в соответствии с представлением инициатора о цепочке. `deposits` — это список новых депозитов валидаторов, о которых известно инициатору блока, а `voluntary_exits` — это список валидаторов, желающих выйти, о чём инициатор блока узнал в gossip-сети уровня консенсуса. `sync_aggregate` — это вектор, показывающий, какие валидаторы были ранее назначены в комитет синхронизации (подмножество валидаторов, обслуживающее данные легких клиентов) и участвовали в подписи данных.
+
+`execution_payload` позволяет передавать информацию о транзакциях между клиентом исполнения и клиентом консенсуса. `execution_payload` — это блок данных исполнения, который вкладывается в Beacon-блок. Поля внутри `execution_payload` отражают структуру блоков, описанную в Жёлтой книге Ethereum, за исключением того, что в ней нет оммеров и `prev_randao` существует вместо `difficulty`. Клиент-исполнитель имеет доступ к локальному пулу транзакций, о которых он узнал из собственной сети gossip. Эти транзакции выполняются локально для генерации обновленного состояния, известного как post-state. Транзакции включены в `execution_payload` в виде списка с названием `transactions`, а пострезультативное состояние предоставляется в поле `state-root`.
+
+Все эти данные собираются в блоке beacon, подписываются и передаются узлам-соседям инициатора, которые распространяют их своим соседям и т. д.
+
+Узнайте больше об [анатомии блоков](/developers/docs/blocks/).
+
+## Что происходит с блоком? {#what-happens-to-blocks}
+
+Блок добавляется на локальную базу данных инициатора и передаётся соседним узлам через gossip сеть консенсус-леера. Когда валидатор получает блок, он проверяет данные внутри него, включая проверку правильности родителя блока, принадлежности к правильной ячейке, корректности индекса инициатора, правильности раскрытия RANDAO и того, что инициатор не наказан сокращением. `execution_payload` распаковывается, и клиент исполнения валидатора повторно выполняет транзакции из списка, чтобы проверить предложенное изменение состояния. Если блок проходит все эти проверки, каждый валидатор добавляет его в свою собственную каноническую цепочку. Затем процесс начинается снова в следующей ячейке.
+
+## Награды за блок {#block-rewards}
+
+Инициатор блока получает плату за свою работу. Существует `base_reward`, рассчитываемая как функция от количества активных валидаторов и их эффективных балансов. Затем инициатор блока получает долю от `base_reward` за каждую действительную аттестацию, включенную в блок; чем больше валидаторов подтверждают блок, тем больше вознаграждение инициатора блока. Также существует вознаграждение за сообщение о валидаторах, подлежащих слэшингу, равное `1/512 * effective balance` за каждого валидатора, подвергнутого слэшингу.
+
+[Подробнее о вознаграждениях и штрафах](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties)
+
+## Дополнительные материалы {#further-reading}
+
+- [Введение в блоки](/developers/docs/blocks/)
+- [Введение в доказательство доли владения](/developers/docs/consensus-mechanisms/pos/)
+- [Спецификации консенсуса Ethereum](https://github.com/ethereum/consensus-specs)
+- [Введение в Gasper](/developers/docs/consensus-mechanisms/pos/gasper/)
+- [Обновление Ethereum](https://eth2book.info/)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/faqs/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/faqs/index.md
new file mode 100644
index 00000000000..a44208380ee
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/faqs/index.md
@@ -0,0 +1,172 @@
+---
+title: "Часто задаваемые вопросы"
+description: "Часто задаваемые вопросы о доказательстве доли владения Ethereum."
+lang: ru
+---
+
+## Что такое доказательство доли владения {#what-is-proof-of-stake}
+
+Proof-of-stake - это класс алгоритма, который обеспечивает безопасность блокчейна, гарантируя, что активы не будут потеряны из-за действий злоумышленников, действующих недобросовестно. Системы Proof-of-stake требуют, чтобы набор валидаторов предоставил некоторый актив, который будет уничтожен, если валидатор совершит какое-то нечестное действие. Ethereum использует механизм proof-of-stake для защиты блокчейна.
+
+## Чем proof-of-stake отличается от proof-of-work? {#comparison-to-proof-of-work}
+
+И доказательство работы, и доказательство доли владения — это механизмы, которые экономически препятствуют злоумышленникам рассылать спам или обманывать сеть. В обоих случаях узлы, активно участвующие в консенсусе, вносят в сеть некий актив, который они потеряют, если будут плохо себя вести.
+
+В механизме доказательства работы этим активом является энергия. Узел, известный как майнер, запускает алгоритм, цель которого - вычислить значение быстрее, чем любой другой узел. Самый быстрый узел имеет право предложить блок для добавления в цепь. Чтобы изменить историю цепи или доминировать в предложении блоков, майнер должен обладать такой большой вычислительной мощностью, чтобы всегда побеждать в гонке. Это непомерно дорого и трудновыполнимо, что защищает цепь от атак. Энергия, необходимая для «майнинга» с использованием доказательства работы, — это реальный актив, за который платят майнеры.
+
+Доказательство доли владения требует, чтобы узлы, известные как валидаторы, явно отправляли криптоактив в смарт-контракт. Если валидатор поведет себя ненадлежащим образом, этот криптоактив может быть уничтожен, потому что он «ставит» свои активы непосредственно в цепь, а не косвенно через затраты энергии.
+
+Доказательство работы намного более энергозатратно, потому что в процессе майнинга сжигается электричество. Доказательство доли владения, с другой стороны, требует очень малого количества энергии — валидаторы Ethereum могут работать даже на маломощных устройствах, таких как Raspberry Pi. Считается, что механизм доказательства доли владения Ethereum более безопасен, чем доказательство работы, потому что стоимость атаки выше, а последствия для атакующего более серьезны.
+
+Доказательство работы в сравнении с доказательством доли владения — это спорная тема. [Блог Виталика Бутерина](https://vitalik.eth.limo/general/2017/12/31/pos_faq.html#what-are-the-benefits-of-proof-of-stake-as-opposed-to-proof-of-work) и дебаты между Джастином Дрейком и Лин Олден дают хорошее резюме аргументов.
+
+
+
+## Является ли доказательство доли владения энергоэффективным? {#is-pos-energy-efficient}
+
+Да. Узлы в сети с доказательством доли владения используют незначительное количество энергии. Стороннее исследование пришло к выводу, что вся сеть Ethereum с доказательством доли владения потребляет около 0,0026 ТВтч/год, что примерно в 13 000 раз меньше, чем потребляют видеоигры только в США.
+
+[Подробнее об энергопотреблении Ethereum](/energy-consumption/).
+
+## Безопасно ли доказательство доли владения? {#is-pos-secure}
+
+Доказательство доли владения Ethereum очень безопасно. Механизм тщательно исследовался, разрабатывался и тестировался на протяжении восьми лет, прежде чем был запущен в работу. Гарантии безопасности отличаются от блокчейнов на основе доказательства работы. В механизме доказательства доли владения злонамеренные валидаторы могут быть активно наказаны («подвергнуты слэшингу») и исключены из набора валидаторов, что будет стоить им значительной суммы ETH. В рамках доказательства работы атакующий может повторять свою атаку, пока у него достаточно хэш-мощности. Также дороже проводить эквивалентные атаки на Ethereum с доказательством доли владения, чем на Ethereum с доказательством работы. Чтобы повлиять на жизнеспособность цепи, требуется не менее 33% от общего количества поставленного эфира в сети (за исключением случаев очень сложных атак с чрезвычайно низкой вероятностью успеха). Для контроля над содержимым будущих блоков требуется не менее 51 % от общего количества поставленных ETH, а для переписывания истории — более 66 % от общей доли. Протокол Ethereum уничтожит эти активы в сценариях атаки 33% или 51% и по социальному консенсусу в сценарии атаки 66%.
+
+- [Подробнее о защите Ethereum с доказательством доли владения от злоумышленников](/developers/docs/consensus-mechanisms/pos/attack-and-defense)
+- [Подробнее о дизайне доказательства доли владения](https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51)
+
+## Делает ли доказательство доли владения Ethereum дешевле? {#does-pos-make-ethereum-cheaper}
+
+Нет. Стоимость отправки транзакции (комиссия за газ) определяется динамическим рынком комиссий, который растет с увеличением спроса в сети. Механизм консенсуса не оказывает на это прямого влияния.
+
+[Подробнее о газе](/developers/docs/gas).
+
+## Кто такие узлы, клиенты и валидаторы? {#what-are-nodes-clients-and-validators}
+
+Узлы - это компьютеры, подключенные к сети Ethereum. Клиенты - это программное обеспечение, которое они запускают, чтобы превратить свой компьютер в узел. Существует два типа клиентов: клиенты исполнения и клиенты консенсуса. Оба необходимы, чтобы создать узел. Валидатор — это дополнительный компонент клиента консенсуса, который позволяет узлу участвовать в консенсусе на основе доказательства доли владения. Это означает создание и предложение блоков при выборе, а также аттестацию блоков, о которых они узнают в сети. Чтобы запустить валидатор, оператор узла должен внести 32 ETH в депозитный контракт.
+
+- [Подробнее об узлах и клиентах](/developers/docs/nodes-and-clients)
+- [Подробнее о стейкинге](/staking)
+
+## Является ли доказательство доли владения новой идеей? {#is-pos-new}
+
+Нет. В 2011 году пользователь на форуме BitcoinTalk [предложил базовую идею доказательства доли владения](https://bitcointalk.org/index.php?topic=27787.0) в качестве обновления для Bitcoin. Прошло одиннадцать лет, прежде чем он был готов к внедрению в основной сети Ethereum. Некоторые другие цепи внедрили доказательство доли владения раньше, чем Ethereum, но не специфичный механизм Ethereum (известный как Gasper).
+
+## В чем особенность доказательства доли владения в Ethereum? {#why-is-ethereum-pos-special}
+
+Механизм доказательства доли владения Ethereum уникален по своей конструкции. Это был не первый механизм доказательства доли владения, который был разработан и внедрен, но он является самым надежным. Механизм доказательства доли владения известен как «Casper». Casper определяет, как выбираются валидаторы для предложения блоков, как и когда делаются аттестации, как подсчитываются аттестации, вознаграждения и штрафы для валидаторов, условия слэшинга, отказоустойчивые механизмы, такие как утечка из-за неактивности, и условия для «финальности». Финальность — это условие, согласно которому для того, чтобы блок считался постоянной частью канонической цепи, за него должны проголосовать не менее 66% от общего количества поставленных ETH в сети. Исследователи разработали Casper специально для Ethereum, и Ethereum — это первый и единственный блокчейн, который его внедрил.
+
+В дополнение к Casper, доказательство доли владения Ethereum использует алгоритм выбора форка под названием LMD-GHOST. Это необходимо на случай возникновения ситуации, когда для одного и того же слота существуют два блока. Это создает два форка блокчейна. LMD-GHOST выбирает тот, у которого наибольший «вес» аттестаций. Вес — это количество аттестаций, взвешенное по эффективному балансу валидаторов. LMD-GHOST уникален для Ethereum.
+
+Сочетание Casper и LMD_GHOST известно как Gasper.
+
+[Подробнее о Gasper](/developers/docs/consensus-mechanisms/pos/gasper/)
+
+## Что такое слэшинг? {#what-is-slashing}
+
+Слэшинг — это термин, обозначающий уничтожение части доли валидатора и его исключение из сети. Сумма ETH, теряемая при слэшинге, масштабируется в зависимости от количества подвергшихся слэшингу валидаторов — это означает, что вступившие в сговор валидаторы наказываются строже, чем отдельные лица.
+
+[Подробнее о слэшинге](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties#slashing)
+
+## Зачем валидаторам 32 ETH? {#why-32-eth}
+
+Валидаторы должны ставить ETH в стейкинг, чтобы им было что терять в случае неправомерных действий. Причина, по которой они должны ставить в стейкинг именно 32 ETH, заключается в том, чтобы позволить узлам работать на скромном оборудовании. Если бы минимальное количество ETH на валидатора было ниже, то количество валидаторов и, следовательно, количество сообщений, которые необходимо обрабатывать в каждом слоте, увеличилось бы, что означало бы, что для запуска узла потребовалось бы более мощное оборудование.
+
+## Как выбирают валидаторов? {#how-are-validators-selected}
+
+Единственный валидатор выбирается псевдослучайно для предложения блока в каждом слоте с помощью алгоритма под названием RANDAO, который смешивает хэш от предлагающего блок с начальным числом, которое обновляется каждый блок. Это значение используется для выбора определённого валидатора из общего их набора. Выбор валидатора фиксируется за две эпохи вперед.
+
+[Подробнее о выборе валидаторов](/developers/docs/consensus-mechanisms/pos/block-proposal)
+
+## Что такое стейк-грайндинг? {#what-is-stake-grinding}
+
+Стейк-грайндинг — это категория атаки на сети с доказательством доли владения, при которой злоумышленник пытается повлиять на алгоритм выбора валидаторов в пользу своих собственных валидаторов. Атаки стейк-грайндинга на RANDAO требуют около половины от общего количества поставленных ETH.
+
+[Подробнее о стейк-грайндинге](https://eth2book.info/altair/part2/building_blocks/randomness/#randao-biasability)
+
+## Что такое социальный слэшинг? {#what-is-social-slashing}
+
+Социальный слэшинг — это способность сообщества координировать форк блокчейна в ответ на атаку. Это позволяет сообществу восстановиться после того, как злоумышленник финализировал нечестную цепь. Социальный слэшинг также может использоваться против атак цензуры.
+
+- [Подробнее о социальном слэшинге](https://ercwl.medium.com/the-case-for-social-slashing-59277ff4d9c7)
+- [Виталик Бутерин о социальном слэшинге](https://vitalik.eth.limo/general/2017/12/31/pos_faq.html#what-is-proof-of-stake)
+
+## Подвергнусь ли я слэшингу? {#will-i-get-slashed}
+
+Как валидатору, очень трудно подвергнуться слэшингу, если вы намеренно не совершаете злонамеренных действий. Слэшинг применяется только в очень специфических сценариях, когда валидаторы предлагают несколько блоков для одного и того же слота или противоречат сами себе в своих аттестациях — возникновение таких ситуаций случайно очень маловероятно.
+
+[Подробнее об условиях слэшинга](https://eth2book.info/altair/part2/incentives/slashing)
+
+## Что такое проблема отсутствия доли? {#what-is-nothing-at-stake-problem}
+
+Проблема отсутствия доли — это концептуальная проблема некоторых механизмов доказательства доли владения, где есть только вознаграждения и нет штрафов. Если на кону ничего не стоит, прагматичный валидатор с одинаковым удовольствием будет аттестовать любой или даже несколько форков блокчейна, так как это увеличивает его вознаграждения. Ethereum обходит эту проблему, используя условия финальности и слэшинг для обеспечения одной канонической цепи.
+
+[Подробнее о проблеме отсутствия доли](https://vitalik.eth.limo/general/2017/12/31/pos_faq.html#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed)
+
+## Что такое алгоритм выбора форка? {#what-is-a-fork-choice-algorithm}
+
+Алгоритм выбора форка реализует правила, определяющие, какая цепь является канонической. В оптимальных условиях нет необходимости в правиле выбора форка, потому что на каждый слот приходится только один предлагающий блок и один блок для выбора. Однако иногда несколько блоков для одного и того же слота или поздно поступившая информация приводят к нескольким вариантам организации блоков в начале цепи. В этих случаях все клиенты должны одинаково реализовывать некоторые правила, чтобы убедиться, что все они выбирают правильную последовательность блоков. Алгоритм выбора форка кодирует эти правила.
+
+Алгоритм выбора форка Ethereum называется LMD-GHOST. Он выбирает форк с наибольшим весом аттестаций, то есть тот, за который проголосовало большинство поставленных ETH.
+
+[Подробнее о LMD-GHOST](/developers/docs/consensus-mechanisms/pos/gasper/#fork-choice)
+
+## Что такое финальность в доказательстве доли владения? {#what-is-finality}
+
+Финальность в доказательстве доли владения — это гарантия того, что данный блок является постоянной частью канонической цепи и не может быть отменен, если не произойдет сбой консенсуса, при котором злоумышленник сожжет 33% от общего количества поставленного эфира. Это «криптоэкономическая» финальность, в отличие от «вероятностной финальности», которая актуальна для блокчейнов с доказательством работы. При вероятностной финальности для блоков нет явных финализированных/нефинализированных состояний — просто становится все менее и менее вероятным, что блок может быть удален из цепи по мере его старения, и пользователи сами определяют, когда они достаточно уверены, что блок «безопасен». При криптоэкономической финальности за пары контрольных блоков должны проголосовать 66% поставленного эфира. Если это условие выполнено, блоки между этими контрольными точками явно «финализируются».
+
+[Подробнее о финальности](/developers/docs/consensus-mechanisms/pos/#finality)
+
+## Что такое «слабая субъективность»? {#what-is-weak-subjectivity}
+
+Слабая субъективность — это особенность сетей с доказательством доли владения, где социальная информация используется для подтверждения текущего состояния блокчейна. Новым узлам или узлам, возвращающимся в сеть после длительного отсутствия, может быть предоставлено недавнее состояние, чтобы узел мог немедленно увидеть, находится ли он на правильной цепи. Эти состояния известны как «контрольные точки слабой субъективности», и их можно получить от других операторов узлов по внешним каналам, из обозревателей блоков или из нескольких общедоступных конечных точек.
+
+[Подробнее о слабой субъективности](/developers/docs/consensus-mechanisms/pos/weak-subjectivity)
+
+## Устойчиво ли доказательство доли владения к цензуре? {#is-pos-censorship-resistant}
+
+Устойчивость к цензуре в настоящее время трудно доказать. Однако, в отличие от доказательства работы, доказательство доли владения предлагает возможность координировать слэшинги для наказания валидаторов, применяющих цензуру. Грядут изменения в протоколе, которые разделяют создателей блоков и предлагающих блоки и вводят списки транзакций, которые создатели должны включать в каждый блок. Это предложение известно как разделение предлагающего и создателя и помогает предотвратить цензуру транзакций со стороны валидаторов.
+
+[Подробнее о разделении предлагающего и создателя](https://notes.ethereum.org/@fradamt/H1TsYRfJc#Original-basic-scheme)
+
+## Может ли система доказательства доли владения Ethereum подвергнуться атаке 51%? {#pos-51-attack}
+
+Да. Доказательство доли владения уязвимо для атак 51%, так же как и доказательство работы. Вместо того чтобы требовать 51% хэш-мощности сети, злоумышленнику требуется 51% от общего количества поставленных ETH. Злоумышленник, накопивший 51% от общей доли, получает контроль над алгоритмом выбора форка. Это позволяет злоумышленнику цензурировать определенные транзакции, проводить краткосрочные реорганизации и извлекать MEV, переупорядочивая блоки в свою пользу.
+
+[Подробнее об атаках на доказательство доли владения](/developers/docs/consensus-mechanisms/pos/attack-and-defense)
+
+## Что такое социальная координация и зачем она нужна? {#what-is-social-coordination}
+
+Социальная координация — это последняя линия защиты для Ethereum, которая позволила бы восстановить честную цепь после атаки, финализировавшей нечестные блоки. В этом случае сообществу Ethereum пришлось бы координироваться «по внешним каналам» и договориться об использовании честного миноритарного форка, подвергнув при этом слэшингу валидаторов злоумышленника. Это также потребует от приложений и бирж признания честного форка.
+
+[Подробнее о социальной координации](/developers/docs/consensus-mechanisms/pos/attack-and-defense#people-the-last-line-of-defense)
+
+## Становятся ли богатые богаче при доказательстве доли владения? {#do-rich-get-richer}
+
+Чем больше ETH кто-то может поставить в стейкинг, тем больше валидаторов он может запустить и тем больше вознаграждений может получить. Вознаграждения масштабируются линейно с суммой поставленных ETH, и каждый получает одинаковый процентный доход. Доказательство работы обогащает богатых больше, чем доказательство доли владения, потому что более богатые майнеры, покупающие оборудование в больших масштабах, выигрывают от экономии на масштабе, что означает, что связь между богатством и вознаграждением нелинейна.
+
+## Является ли доказательство доли владения более централизованным, чем доказательство работы? {#is-pos-decentralized}
+
+Нет, доказательство работы стремится к централизации, потому что затраты на майнинг растут и вытесняют сначала отдельных лиц, затем небольшие компании и так далее. Текущая проблема с доказательством доли владения — это влияние деривативов ликвидного стейкинга (LSD). Это токены, представляющие ETH, поставленные некоторым провайдером, которые любой может обменять на вторичных рынках без фактического вывода ETH из стейкинга. LSD позволяют пользователям делать ставки менее чем на 32 ETH, но они также создают риск централизации, когда несколько крупных организаций могут в конечном итоге контролировать большую часть доли. Вот почему [соло-стейкинг](/staking/solo) — лучший вариант для Ethereum.
+
+[Подробнее о централизации долей в LSD](https://notes.ethereum.org/@djrtwo/risks-of-lsd)
+
+## Почему я могу ставить в стейкинг только ETH? {#why-can-i-only-stake-eth}
+
+ETH – это внутренняя валюта Ethereum. Крайне важно иметь единую валюту, в которой номинированы все доли, как для учета эффективных балансов для взвешивания голосов, так и для безопасности. Сам ETH является фундаментальным компонентом Ethereum, а не смарт-контрактом. Включение других валют значительно увеличило бы сложность и снизило бы безопасность стейкинга.
+
+## Является ли Ethereum единственным блокчейном с доказательством доли владения? {#is-ethereum-the-only-pos-blockchain}
+
+Нет, существует несколько блокчейнов с доказательством доли владения. Ни один из них не идентичен Ethereum; механизм доказательства доли владения Ethereum уникален.
+
+## Что такое слияние? {#what-is-the-merge}
+
+Слияние — это момент, когда Ethereum отключил свой механизм консенсуса на основе доказательства работы и включил механизм консенсуса на основе доказательства доли владения. Слияние произошло 15 сентября 2022 года.
+
+[Подробнее о Слиянии](/roadmap/merge)
+
+## Что такое жизнеспособность и безопасность? {#what-are-liveness-and-safety}
+
+Жизнеспособность и безопасность — это две фундаментальные проблемы безопасности для блокчейна. Жизнеспособность — это доступность финализирующей цепи. Если цепь перестает финализироваться или пользователи не могут легко получить к ней доступ, это сбои жизнеспособности. Чрезвычайно высокая стоимость доступа также может считаться сбоем жизнеспособности. Безопасность относится к тому, насколько сложно атаковать цепь, т. е. финализировать конфликтующие контрольные точки.
+
+[Читайте подробнее в документе Casper](https://arxiv.org/pdf/1710.09437.pdf)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/gasper/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/gasper/index.md
new file mode 100644
index 00000000000..fa2d2928168
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/gasper/index.md
@@ -0,0 +1,52 @@
+---
+title: Gasper
+description: "Объяснение механизма доказательства владения Gasper."
+lang: ru
+---
+
+Gasper — это комбинация гаджета Casper the Friendly Finality (Casper-FFG) и алгоритма выбора форка LMD-GHOST. Вместе эти компоненты формируют механизм консенсуса, обеспечивающий безопасность Ethereum с использованием доказательства владения. Casper — это механизм, который обновляет определенные блоки до "завершенных", чтобы новые участники сети могли быть уверены, что они синхронизируются с канонической цепочкой. Алгоритм выбора форка использует накопленные голоса, чтобы гарантировать, что узлы могут легко выбрать правильную цепочку, когда в блокчейне возникают форки.
+
+**Обратите внимание**, что первоначальное определение Casper-FFG было немного обновлено для включения в Gasper. На этой странице мы рассмотрим обновленную версию.
+
+## Прежде чем начать
+
+Чтобы понять этот материал, необходимо прочитать вводную страницу о [доказательстве владения](/developers/docs/consensus-mechanisms/pos/).
+
+## Роль Gasper {#role-of-gasper}
+
+Gasper находится на вершине блокчейна с доказательством владения, где узлы предоставляют эфир в качестве залога, который может быть уничтожен, если они бездействуют или действуют нечестно при предложении или проверке блоков. Gasper — это механизм, определяющий, как валидаторы получают вознаграждение или наказание, решают, какие блоки принимать или отклонять и на какой форк блокчейна опираться.
+
+## Что такое окончательность? {#what-is-finality}
+
+Окончательность — это свойство определенных блоков, которое означает, что эти блоки не могут быть отменены, если только не произошел критический сбой консенсуса и злоумышленник не уничтожил по крайней мере 1/3 от общего количества застейканного эфира. Завершенные блоки можно рассматривать как информацию, в отношении которой блокчейн уверен. Чтобы блок был признан окончательным, он должен пройти двухэтапную процедуру обновления:
+
+1. Валидаторы по крайней мере чем с двумя третями от общего количества застейканного эфира должны проголосовать за включение этого блока в каноническую цепочку. Это условие обновляет блок до "справедливого". Маловероятно, что справедливые блоки могут быть отменены, но при определенных условиях это возможно.
+2. Когда другой блок становится справедливым поверх этого справедливого блока, последний обновляется до "окончательного". Обновление блока до окончательного — это обязательство включить блок в каноническую цепочку. Он не может быть отменен, если только злоумышленник не уничтожит миллионы эфиров (миллиарды $USD).
+
+Эти обновления блоков происходят не в каждой ячейке. Вместо этого справедливыми и окончательными могут быть только блоки, находящиеся на границе эпох. Эти блоки известны как "контрольные точки". При обновлении учитываются пары контрольных точек. Между двумя последовательными контрольными точками должна существовать «связь подавляющего большинства» (т. е. две трети от общего количества эфира в стейкинге проголосовали за то, что контрольная точка Б является правильным потомком контрольной точки А), чтобы обновить менее свежую контрольную точку до финализированной, а более свежий блок — до обоснованного.
+
+Поскольку для окончательности требуется согласие двух третей всего застейканного эфира о том, что блок является каноническим, злоумышленник не сможет создать альтернативную завершенную цепочку без:
+
+1. Владения двумя третями всего застейканного эфира или манипулирования ими.
+2. Уничтожения по меньшей мере трети всего застейканного эфира.
+
+Первое условие возникает потому, что для завершения цепочки требуется две трети всего застейканного эфира. Второе условие возникает потому, что бы две трети от общего застейканного эфира проголосовали за два форка, то как минимум одна его треть должна была проголосовать сразу за оба. Двойное голосование — это наказуемое урезанием условие, от которого одна треть от общего количества застейканного эфира была бы уничтожена. На момент мая 2022 года для этого злоумышленнику потребуется сжечь эфира на сумму около 10 миллиардов долларов. Алгоритм, который обосновывает и финализирует блоки в Gasper, представляет собой немного измененную форму [Casper the Friendly Finality Gadget (Casper-FFG)](https://arxiv.org/pdf/1710.09437.pdf).
+
+### Стимулы и Tallant {#incentives-and-slashing}
+
+Валидаторы получают вознаграждение за честные предложение и проверку блоков. Они получают эфир, который добавляется к сумме их стейкинга. С другой стороны, валидаторы, которые отсутствуют и не действуют по требованию сети, пропускают эти вознаграждения и иногда теряют небольшую часть своих застейканных эфиров. Однако штрафы за пребывание в автономном режиме невелики и в большинстве случаев равны потерям от отсутствия вознаграждений. Однако некоторые действия валидатора очень трудно выполнить случайно и они указывают на какой-либо злой умысел, например, предложение нескольких блоков для одного в одной и той же ячейке, подтверждение нескольких блоков в одной и той же ячейке или противоречие предыдущим голосованиям за контрольные точки. Это "урезаемое" поведение, которое наказывается более сурово — наказание урезанием приводит к уничтожению некоторой части эфира в стейкинге валидатора и удалению валидатора из сети. Этот процесс занимает 36 дней. В первый день взимается первоначальный штраф в размере до 1 ETH. Затем эфир урезанного валидатора медленно расходуется в течение периода выхода, а на 18-й день он получает "штраф за корреляцию", который увеличивается, когда примерно в одно и то же время урезаются другие валидаторы. Максимальный штраф — это вся сумма валидатора в стейкинге. Эти вознаграждения и штрафы предназначены для стимулирования честных валидаторов и предотвращения атак на сеть.
+
+### Утечка из-за неактивности {#inactivity-leak}
+
+Помимо безопасности, Gasper также обеспечивает "убеждаемую живучесть". Это условие заключается в том, что до тех пор, пока две трети от общего количества застейканного эфира голосуют честно и следуют протоколу, цепочка сможет становиться окончательной независимо от любой другой активности (например, атак, проблем с задержкой или урезаний). Иными словами, одна треть от общего объема застейканного эфира должна быть каким-то образом скомпрометирована, чтобы предотвратить завершение становление цепочки окончательной. В Gasper существует дополнительная защита от сбоев в работе, известная как "утечка неактивности". Этот механизм активируется всякий раз, когда цепочка не становится окончательной в течение более, чем более четырех эпох. У валидаторов, которые активно не подтверждают цепочку большинства, постепенно уменьшается количество их застейканного эфира до тех пор, пока большинство не вернет себе две трети от общей доли, гарантируя, что сбои в работе будут лишь временными.
+
+### Выбор форка {#fork-choice}
+
+Первоначальное определение Casper-FFG включало алгоритм выбора форка, который устанавливал правило: `следовать за цепочкой, содержащей обоснованную контрольную точку с наибольшей высотой`, где высота определяется как наибольшее расстояние от генезис-блока. В Gasper оригинальное правило выбора форка устарело в пользу более сложного алгоритма под названием LMD-GHOST. Важно понимать, что при обычных условиях правило выбора форка не требуется: для каждой ячейки существует один предлагающий блок валидатор, а другие честные валидаторы подтверждают это. Только в случаях большой асинхронности сети или когда недобросовестный валидатор, предлагающий блок, дал двусмысленные показания, требуется алгоритм выбора форка. Однако, когда такие случаи действительно возникают, алгоритм выбора форка является критической защитой, которая гарантирует правильность цепочки.
+
+LMD-GHOST расшифровывается и дословно переводится как "движимое последним сообщением жадное самое тяжелое наблюдаемое поддерево". Это перегруженный жаргоном способ определения алгоритма, который выбирает ответвление с наибольшим накопленным весом подтверждений валидаторов в качестве канонического (жадное поддерево с наибольшим весом) и, если от валидатора получено несколько сообщений, учитывает только самое последнее (движимое последними сообщениями). Прежде чем добавить блок с наибольшим весом в свою каноническую цепочку, каждый валидатор оценивает каждый блок, используя это правило.
+
+## Дополнительные материалы {#further-reading}
+
+- [Gasper: Объединение GHOST и Casper](https://arxiv.org/pdf/2003.03052.pdf)
+- [Casper the Friendly Finality Gadget](https://arxiv.org/pdf/1710.09437.pdf)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/index.md
index d72c713e215..5131ff1238e 100644
--- a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/index.md
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/index.md
@@ -1,6 +1,6 @@
---
-title: Доказательство владения (PoS)
-description: Объяснение протокола доказательства владения и его роли в Ethereum.
+title: "Доказательство владения (PoS)"
+description: "Объяснение протокола доказательства владения и его роли в Ethereum."
lang: ru
incomplete: true
---
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/keys/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/keys/index.md
new file mode 100644
index 00000000000..b47de59fbf6
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/keys/index.md
@@ -0,0 +1,100 @@
+---
+title: "Ключи в Эфириум с доказательством владения"
+description: "Объяснение ключей, используемых в механизме консенсуса доказательстве владения в Эфириум"
+lang: ru
+---
+
+Ethereum защищает пользовательские активы с помощью криптографии с открытым и закрытым ключами. Публичный ключ используется в качестве основы для адреса Эфириум, то есть он виден широкой публике и используется в качестве уникального идентификатора. Приватный (или "секретный") ключ должен быть доступен только владельцу аккаунта. Приватный ключ используется для "подписи" транзакций и данных, чтобы криптографически можно было доказать, что владелец аккаунта одобряет какое-либо действие определенного приватного ключа.
+
+Ключи Ethereum генерируются с использованием [криптографии на эллиптических кривых](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography).
+
+Однако когда Ethereum перешел с [доказательства работы](/developers/docs/consensus-mechanisms/pow) на [доказательство владения](/developers/docs/consensus-mechanisms/pos), в Ethereum был добавлен новый тип ключа. Первоначальные ключи по-прежнему работают точно так же, как и раньше — не было никаких изменений для ключей на основе эллиптических кривых, защищающих аккаунты. Однако пользователям требовался ключ нового типа для участия в доказательстве владения путем стейкинга ETH и запуска валидаторов. Эта потребность возникла из-за проблем с масштабируемостью, связанных с передачей большого количества сообщений между большим числом валидаторов, что требовало криптографического метода, который можно было бы легко агрегировать, чтобы уменьшить объем обмена данными, необходимый сети для достижения консенсуса.
+
+Этот новый тип ключа использует схему подписи [**Boneh-Lynn-Shacham (BLS)**](https://wikipedia.org/wiki/BLS_digital_signature). BLS обеспечивает очень эффективную агрегацию подписей, но также допускает извлечение отдельных агрегированных ключей валидаторов и идеально подходит для управления действиями между валидаторами.
+
+## Два типа ключей валидатора {#two-types-of-keys}
+
+До перехода на доказательство владения у пользователей Эфириум был только один закрытый ключ на основе эллиптической кривой для доступа к своим средствам. С введением доказательства владения пользователям, которые хотели стать соло-стейкерами, также требовались **ключ валидатора** и **ключ для вывода средств**.
+
+### Ключ валидатора {#validator-key}
+
+Ключ подписи валидатора состоит из двух элементов:
+
+- **Приватный** ключ валидатора
+- **Публичный** ключ валидатора
+
+Назначение приватного ключа валидатора — подписывать он-чейн операции, такие как предложения блоков и аттестации. В связи с этим эти ключи должны храниться в горячем кошельке.
+
+Преимущество такой гибкости заключается в том, что ключи подписи валидатора можно очень быстро перемещать с одного устройства на другое, однако, если они потеряны или украдены, вор может **действовать злонамеренно** несколькими способами:
+
+- Добиться урезания валидатора:
+ - Будучи предлагающим блок, подписать два разных блока beacon для одной и той же ячейки
+ - Будучи аттестатором, подписать аттестацию, которая "окружает" другую
+ - Будучи аттестатором, подписать две разные аттестации, имеющие одну и ту же цель
+- Сделать добровольный выход, который выводит валидатора из стейкинга и предоставляет доступ к его балансу ETH владельцу ключа вывода средств
+
+**Публичный ключ валидатора** включается в данные транзакции, когда пользователь вносит ETH в депозитный контракт стейкинга. Эти данные известны как _данные о депозите_ и позволяют Ethereum идентифицировать валидатора.
+
+### Учетные данные для вывода средств {#withdrawal-credentials}
+
+Каждый валидатор имеет свойство, известное как _учетные данные для вывода средств_. Это 32-байтное поле начинается либо с `0x00`, представляющего учетные данные для вывода средств BLS, либо с `0x01`, представляющего учетные данные, указывающие на адрес исполнения.
+
+Валидаторы с `0x00` BLS-ключами должны обновить эти учетные данные, чтобы они указывали на адрес исполнения, для активации выплат избыточного баланса или полного вывода средств из стейкинга. Это можно сделать, указав адрес исполнения в данных депозита во время первоначальной генерации ключа, _ИЛИ_ использовав ключ для вывода средств позже для подписи и трансляции сообщения `BLSToExecutionChange`.
+
+### Ключ для вывода средств {#withdrawal-key}
+
+Ключ вывода средств потребуется для обновления данных для вывода средств, чтобы указать адрес для выполнения, если он не был задан при первоначальном депозите. Это позволит начать обработку платежей с избыточным балансом, а также позволит пользователям полностью вывести свои зайстейканные ETH.
+
+Как и ключи валидаторов, ключи для вывода средств также состоят из двух компонентов:
+
+- **Приватный** ключ для вывода средств
+- **Публичный** ключ для вывода средств
+
+Потеря этого ключа до обновления учетных данных для вывода средств до типа `0x01` означает потерю доступа к балансу валидатора. Валидатор по-прежнему может подписывать аттестации и блоки, поскольку для этих действий требуется закрытый ключ валидатора, однако в случае утери ключей для снятия средств стимул к этому отсутствует.
+
+Отделение ключей валидатора от ключей аккаунта Эфириум позволяет одному пользователю запускать несколько валидаторов.
+
+
+
+**Примечание**: Выход из стейкинга и вывод баланса валидатора в настоящее время требуют подписания [сообщения о добровольном выходе (VEM)](https://mirror.xyz/ladislaus.eth/wmoBbUBes2Wp1_6DvP6slPabkyujSU7MZOFOC3QpErs&1) с помощью ключа валидатора. Однако [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) — это предложение, которое в будущем позволит пользователю инициировать выход валидатора и вывести его баланс путем подписания сообщений о выходе с помощью ключа для вывода средств. Это снизит требования к доверию, позволив стейкерам, делегирующим ETH [поставщикам услуг стейкинга](/staking/saas/#what-is-staking-as-a-service), сохранять контроль над своими средствами.
+
+## Получение ключей из кодовой фразы {#deriving-keys-from-seed}
+
+Если бы для каждых застейканных 32 ETH требовался новый набор из 2 полностью независимых ключей, управление ключами быстро стало бы громоздким, особенно для пользователей, у которых запущено несколько валидаторов. Вместо этого несколько ключей валидатора могут быть получены из одной общей сид-фразы, и хранение этой единственной сид-фразы обеспечивает доступ к нескольким ключам валидатора.
+
+[Мнемоники](https://en.bitcoinwiki.org/wiki/Mnemonic_phrase) и пути — это важные функции, с которыми пользователи часто сталкиваются при [доступе](https://ethereum.stackexchange.com/questions/19055/what-is-the-difference-between-m-44-60-0-0-and-m-44-60-0) к своим кошелькам. Мнемоническая фраза — это последовательность слов, которые действуют как сид для закрытого ключа. В сочетании с дополнительными данными мнемоническая фраза генерирует хэш, известный как "мастер-ключ". Это можно рассматривать как корень дерева. Ветви от этого корня затем могут быть получены с использованием иерархического пути, так что дочерние узлы могут существовать как комбинации хеша их родительского узла и их индекса в дереве. Прочтите о стандартах [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) и [BIP-19](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) для генерации ключей на основе мнемоники.
+
+Эти пути имеют следующую структуру, которая будет знакома пользователям, взаимодействовавшим с аппаратными кошельками:
+
+```
+m/44'/60'/0'/0`
+```
+
+Косые черты в этом пути разделяют компоненты приватного ключа следующим образом:
+
+```
+master_key / purpose / coin_type / account / change / address_index
+```
+
+Эта логика позволяет пользователям присоединять как можно больше валидаторов к одной **мнемонической фразе**, поскольку корень дерева может быть общим, а различие может происходить на уровне ветвей. Пользователь может **получить любое количество ключей** из мнемонической фразы.
+
+```
+ [m / 0]
+ /
+ /
+[m] - [m / 1]
+ \
+ \
+ [m / 2]
+```
+
+Каждая ветвь разделена символом `/`, поэтому `m/2` означает, что нужно начать с мастер-ключа и следовать по ветви 2. На приведенной ниже схеме одна мнемоническая фраза используется для хранения трех ключей вывода средств, каждый из которых имеет два связанных валидатора.
+
+
+
+## Дополнительные материалы {#further-reading}
+
+- [Запись в блоге Ethereum Foundation от Карла Бекхейзена](https://blog.ethereum.org/2020/05/21/keys/)
+- [EIP-2333: генерация ключей BLS12-381](https://eips.ethereum.org/EIPS/eip-2333)
+- [EIP-7002: выходы, инициируемые на уровне исполнения](https://web.archive.org/web/20250125035123/https://research.2077.xyz/eip-7002-unpacking-improvements-to-staking-ux-post-merge)
+- [Масштабное управление ключами](https://docs.ethstaker.cc/ethstaker-knowledge-base/scaled-node-operators/key-management-at-scale)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/pos-vs-pow/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/pos-vs-pow/index.md
new file mode 100644
index 00000000000..078e6611964
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/pos-vs-pow/index.md
@@ -0,0 +1,69 @@
+---
+title: "Proof-of-stake против proof-of-work"
+description: "Сравнение между механизмом консенсуса proof-of-stake и proof-of-work в сети Ethereum"
+lang: ru
+---
+
+Когда Ethereum был запущен, механизм доказательства владения (proof-of-stake) все еще требовал большого количества исследований и разработок, прежде чем ему можно было доверить обеспечение безопасности Ethereum. Механизм доказательства работы (proof-of-work) был более простым механизмом, который уже был проверен биткоином. Это означало, что основные разработчики могли немедленно реализовать его для запуска Ethereum. Потребовалось еще восемь лет, чтобы довести механизм доказательства владения (proof-of-stake) до такого состояния, чтобы его можно было реализовать.
+
+На этой странице объясняются причины перехода Ethereum с механизма доказательства работы (proof-of-work) на механизм доказательства владения (proof-of-stake), а также связанные с этим компромиссы.
+
+## Безопасность {#security}
+
+Исследователи Ethereum считают механизм proof-of-stake более безопасным, чем proof-of-work. Однако, он совсем недавно был внедрён в основную сеть Ethereum и не прошел достаточную проверку временем, как proof-of-work. В этом разделе рассматриваются плюсы и минусы модели безопасности механизма proof-of-stake по сравнению с proof-of-work.
+
+### Стоимость атаки {#cost-to-attack}
+
+При proof-of-stake, валидаторы обязаны задепонировать ("застейкать") как минимум 32 ETH в смарт-контракте. Сеть Ethereum оставляет за собой право уничтожить застейканый эфир, чтобы наказать валидаторов за несоблюдение правил. Чтобы добиться консенсуса, как минимум 66% от всего застейканого эфира должны проголосовать за определённый набор блоков. Блоки, за которые проголосовали >=66% от общей доли, становятся "финализированными", то есть их нельзя удалить или реорганизовать.
+
+Атака на сеть может означать предотвращение финализации цепочки или обеспечение определенной организации блоков в канонической цепи, что каким-то образом выгодно атакующему. Для этого злоумышленнику необходимо отклонить путь честного консенсуса либо путем накопления большого количества эфира и прямого голосования с его помощью, либо обманом заставить честных валидаторов проголосовать определенным образом. Помимо сложных, маловероятных атак, которые обманывают честных валидаторов, стоимость атаки на Ethereum — это стоимость доли, которую злоумышленник должен накопить, чтобы повлиять на консенсус в свою пользу.
+
+Минимальная стоимость атаки составляет >33% от общей доли. Злоумышленник, владеющий >33% от общей доли, может вызвать задержку финализации, просто отключившись от сети. Это относительно незначительная проблема для сети, поскольку существует механизм, известный как "утечка из-за неактивности", который выводит долю из оффлайн-валидаторов до тех пор, пока онлайн-большинство не будет составлять 66% доли и не сможет снова финализировать цепочку. Теоретически также возможно, что злоумышленник вызовет двойную финализацию, имея чуть более 33% от общей доли, создав два блока вместо одного, когда его попросят стать производителем блока, а затем дважды проголосовав всеми своими валидаторами. Каждый форк требует, чтобы 50% оставшихся честных валидаторов сначала увидели каждый блок, поэтому, если им удастся правильно рассчитать время отправки своих сообщений, они смогут финализировать оба форка. Вероятность успеха этого мала, но если бы злоумышленник смог вызвать двойную финализацию, сообществу Ethereum пришлось бы решить, какому форку следовать, и в этом случае валидаторы злоумышленника обязательно были бы подвергнуты слэшингу на другом форке.
+
+Имея >33% от общей доли, злоумышленник имеет шанс оказать незначительное (задержка финализации) или более серьезное (двойная финализация) влияние на сеть Ethereum. При наличии более 14 000 000 ETH в стейкинге в сети и репрезентативной цене 1000 долларов США за ETH минимальная стоимость проведения этих атак составляет `1000 x 14 000 000 x 0,33 = 4 620 000 000 долларов США`. Злоумышленник потеряет эти деньги в результате слэшинга и будет исключен из сети. Чтобы атаковать снова, им придется (снова) накопить >33% доли и (снова) сжечь ее. Каждая попытка атаки на сеть будет стоить >4,6 миллиарда долларов (при цене 1000 долларов за ETH и 14 млн ETH в стейкинге). Злоумышленник также исключается из сети, когда его валидаторы подвергаются слэшингу, и для повторного присоединения он должен встать в очередь активации. Это означает, что скорость повторной атаки ограничивается не только скоростью, с которой злоумышленник может накопить >33% от общей доли, но и временем, которое требуется для подключения всех его валидаторов к сети. Каждый раз, когда злоумышленник атакует, он становится намного беднее, а остальная часть сообщества становится богаче благодаря возникающему шоку предложения.
+
+Другие атаки, такие как атаки 51% или отмена финализации с 66% общей доли, требуют значительно больше ETH и являются гораздо более дорогостоящими для злоумышленника.
+
+Сравните это с механизмом доказательства работы. Стоимость атаки на Ethereum с механизмом доказательства работы (proof-of-work) была равна стоимости постоянного владения >50% общего хешрейта сети. Это сводилось к затратам на оборудование и эксплуатационным расходам на достаточную вычислительную мощность, чтобы постоянно опережать других майнеров в вычислении решений для доказательства работы. Ethereum в основном майнился с использованием GPU, а не ASIC, что снижало затраты (хотя, если бы Ethereum остался на механизме доказательства работы, майнинг на ASIC мог бы стать более популярным). Злоумышленнику пришлось бы приобрести много оборудования и оплатить электроэнергию для его работы, чтобы атаковать сеть Ethereum на основе механизма доказательства работы, но общая стоимость была бы меньше, чем стоимость, необходимая для накопления достаточного количества ETH для начала атаки. Атака 51% на ~[20 раз дешевле](https://youtu.be/1m12zgJ42dI?t=1562) при использовании механизма доказательства работы (proof-of-work), чем при использовании механизма доказательства владения (proof-of-stake). Если бы атака была обнаружена, а в цепи был проведен хардфорк для удаления внесенных изменений, злоумышленник мог бы многократно использовать то же самое оборудование для атаки на новый форк.
+
+### Сложность {#complexity}
+
+Механизм доказательства владения (proof-of-stake) намного сложнее, чем механизм доказательства работы (proof-of-work). Это можно считать аргументом в пользу механизма доказательства работы (proof-of-work), поскольку в более простые протоколы сложнее случайно внести ошибки или непреднамеренные эффекты. Однако сложность была преодолена благодаря многолетним исследованиям и разработкам, симуляциям и внедрениям в тестовых сетях. Протокол доказательства владения (proof-of-stake) был независимо реализован пятью отдельными командами (на каждом из уровней исполнения и консенсуса) на пяти языках программирования, что обеспечивает устойчивость к ошибкам клиентов.
+
+Для безопасной разработки и тестирования логики консенсуса на основе доказательства владения (proof-of-stake) сеть Beacon Chain была запущена за два года до внедрения этого механизма в основной сети Ethereum. Сеть Beacon Chain выступала в роли "песочницы" для тестирования механизма доказательства владения (proof-of-stake), поскольку это был действующий блокчейн, реализующий логику консенсуса на основе доказательства владения, но не затрагивающий реальные транзакции Ethereum — по сути, он просто приходил к консенсусу относительно самого себя. Как только эта система проработала стабильно и без ошибок достаточное время, Beacon Chain была "объединена" с основной сетью Ethereum. Все это способствовало укрощению сложности механизма доказательства владения (proof-of-stake) до такой степени, что риск непреднамеренных последствий или ошибок клиента стал очень низким.
+
+### Поверхность атаки {#attack-surface}
+
+Механизм доказательства владения (proof-of-stake) сложнее, чем механизм доказательства работы (proof-of-work), а это означает, что существует больше потенциальных векторов атак, которые необходимо учитывать. Вместо одной одноранговой сети, соединяющей клиентов, есть две, каждая из которых реализует отдельный протокол. Предварительный выбор одного конкретного валидатора для предложения блока в каждом слоте создает потенциал для атак типа «отказ в обслуживании», когда большие объемы сетевого трафика выводят этого конкретного валидатора из строя.
+
+Существуют также способы, с помощью которых злоумышленники могут тщательно рассчитывать время выпуска своих блоков или аттестаций, чтобы их получала определенная часть честной сети, влияя на их голосование определенным образом. Наконец, злоумышленник может просто накопить достаточно ETH для стейкинга и доминировать в механизме консенсуса. Для каждого из этих [векторов атак существуют соответствующие средства защиты](/developers/docs/consensus-mechanisms/pos/attack-and-defense), но в механизме доказательства работы (proof-of-work) они не существуют, чтобы от них защищаться.
+
+## Децентрализация {#decentralization}
+
+Механизм доказательства владения (proof-of-stake) более децентрализован, чем механизм доказательства работы (proof-of-work), потому что гонка вооружений в области оборудования для майнинга, как правило, вытесняет с рынка частных лиц и небольшие организации. Хотя технически любой может начать майнинг на скромном оборудовании, вероятность получения какого-либо вознаграждения ничтожно мала по сравнению с институциональными майнинговыми операциями. При использовании механизма доказательства владения (proof-of-stake) стоимость стейкинга и процентная доходность от этой доли одинаковы для всех. В настоящее время запуск валидатора стоит 32 ETH.
+
+С другой стороны, изобретение деривативов ликвидного стейкинга вызвало опасения по поводу централизации, поскольку несколько крупных провайдеров управляют большими объемами ETH в стейкинге. Это проблематично и требует скорейшего исправления, но в то же время здесь больше нюансов, чем кажется. Централизованные провайдеры стейкинга не обязательно имеют централизованный контроль над валидаторами — часто это просто способ создать центральный пул ETH, который многие независимые операторы узлов могут использовать для стейкинга, не требуя от каждого участника наличия собственных 32 ETH.
+
+Лучший вариант для Ethereum — это запуск валидаторов локально на домашних компьютерах, что максимизирует децентрализацию. Вот почему Ethereum сопротивляется изменениям, которые увеличивают требования к оборудованию для запуска узла/валидатора.
+
+## Устойчивость {#sustainability}
+
+Механизм доказательства владения (proof-of-stake) — это способ обеспечения безопасности блокчейна с низким уровнем выбросов углерода. В рамках механизма доказательства работы (proof-of-work) майнеры соревнуются за право добыть блок. Майнеры более успешны, когда они могут выполнять вычисления быстрее, что стимулирует инвестиции в оборудование и потребление энергии. Это наблюдалось в Ethereum до его перехода на механизм доказательства владения (proof-of-stake). Незадолго до перехода на механизм доказательства владения (proof-of-stake) Ethereum потреблял примерно 78 ТВтч/год — столько же, сколько небольшая страна. Однако переход на механизм доказательства владения (proof-of-stake) сократил эти энергозатраты примерно на 99,98%. Механизм доказательства владения (proof-of-stake) сделал Ethereum энергоэффективной платформой с низким уровнем выбросов углерода.
+
+[Подробнее об энергопотреблении Ethereum](/energy-consumption)
+
+## Эмиссия {#issuance}
+
+Ethereum с механизмом доказательства владения (proof-of-stake) может платить за свою безопасность, выпуская гораздо меньше монет, чем Ethereum с механизмом доказательства работы (proof-of-work), поскольку валидаторам не нужно платить высокие затраты на электроэнергию. В результате инфляция ETH может снизиться или даже стать дефляционной, когда сжигаются большие объемы ETH. Более низкие уровни инфляции означают, что безопасность Ethereum обходится дешевле, чем при использовании механизма доказательства работы (proof-of-work).
+
+## Больше увлекаетесь визуализацией? {#visual-learner}
+
+Посмотрите, как Джастин Дрейк объясняет преимущества механизма доказательства владения (proof-of-stake) по сравнению с механизмом доказательства работы (proof-of-work):
+
+
+
+## Дополнительные материалы {#further-reading}
+
+- [Философия дизайна доказательства владения (proof-of-stake) от Виталика](https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51)
+- [Часто задаваемые вопросы о доказательстве владения (proof-of-stake) от Виталика](https://vitalik.eth.limo/general/2017/12/31/pos_faq.html#what-is-proof-of-stake)
+- [Видео "Просто о сложном" о PoS против PoW](https://www.youtube.com/watch?v=M3EFi_POhps)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md
new file mode 100644
index 00000000000..c1d7286c1ce
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md
@@ -0,0 +1,91 @@
+---
+title: "Вознаграждения и штрафы (PoS)"
+description: "Узнайте о внутрипротокольных стимулах в Ethereum на основе Proof-of-Stake."
+lang: ru
+---
+
+Для обеспечения безопасности Ethereum используется его родная криптовалюта - эфир (ETH). Операторы узлов, желающие участвовать в проверке блоков и определении заголовка цепи, вносят эфир (ether) в [депозитный контракт](/staking/deposit-contract/) в сети Ethereum. Затем они получают вознаграждение в эфире (ether) за запуск программного обеспечения валидатора, которое проверяет действительность новых блоков, полученных по одноранговой сети, и применяет алгоритм выбора форка для определения заголовка цепи.
+
+У валидатора есть две основные роли: 1) проверка новых блоков и их "аттестация" (подтверждение), если они действительны, 2) предложение новых блоков при случайном выборе из общего пула валидаторов. Если валидатор не выполняет одну из этих задач, когда это требуется, он лишается выплаты в эфире (ether). Валидаторам также иногда поручается агрегация подписей и участие в комитетах синхронизации.
+
+Однако некоторые действия очень трудно выполнить случайно и они указывают на какой-либо злой умысел, например, предложение нескольких блоков в одной и той же ячейке, или аттестация сразу нескольких блоков в одной и той же ячейке. Это наказуемое слэшингом поведение, в результате которого у валидатора сжигается определенное количество эфира (до 1 ETH), прежде чем валидатор будет удален из сети, что занимает 36 дней. Эфир валидатора, подвергшегося слэшингу, медленно списывается в течение периода выхода, но на 18-й день он получает "корреляционный штраф", который увеличивается, когда примерно в одно и то же время слэшингу подвергаются другие валидаторы. Таким образом, структура стимулов механизма консенсуса вознаграждает за честность и наказывает недобросовестных участников.
+
+Все вознаграждения и штрафы применяются один раз в эпоху.
+
+Читайте далее, чтобы узнать подробнее...
+
+## Вознаграждения и штрафы {#rewards}
+
+### Вознаграждения {#rewards}
+
+Валидаторы получают вознаграждения, когда их голоса совпадают с голосами большинства других валидаторов, когда они предлагают блоки и когда они участвуют в комитетах синхронизации. Размер вознаграждений в каждой эпохе рассчитывается на основе `base_reward`. Это базовая единица, на основе которой рассчитываются другие вознаграждения. `base_reward` представляет собой среднее вознаграждение, получаемое валидатором при оптимальных условиях за эпоху. Оно рассчитывается на основе эффективного баланса валидатора и общего числа активных валидаторов следующим образом:
+
+```
+base_reward = effective_balance * (base_reward_factor / (base_rewards_per_epoch * sqrt(sum(active_balance))))
+```
+
+где `base_reward_factor` равен 64, `base_rewards_per_epoch` равен 4, а `sum(active balance)` — это общая сумма эфира в стейкинге у всех активных валидаторов.
+
+Это означает, что базовое вознаграждение пропорционально эффективному балансу валидатора и обратно пропорционально количеству валидаторов в сети. Чем больше валидаторов, тем выше общая Эмиссия (как `sqrt(N)`), но тем меньше `base_reward` на одного валидатора (как `1/sqrt(N)`). Эти факторы влияют на годовую процентную ставку (APR) для узла стейкинга. Обоснование этого читайте в [заметках Виталика](https://notes.ethereum.org/@vbuterin/rkhCgQteN?type=view#Base-rewards).
+
+Общее вознаграждение рассчитывается как сумма пяти компонентов, каждый из которых имеет вес, определяющий, сколько каждый компонент добавляет к общему вознаграждению. Вот их перечень:
+
+```
+1. голосование за источник: валидатор своевременно проголосовал за правильную исходную контрольную точку
+2. голосование за цель: валидатор своевременно проголосовал за правильную целевую контрольную точку
+3. голосование за заголовок: валидатор своевременно проголосовал за правильный заголовочный блок
+4. вознаграждение комитета синхронизации: валидатор участвовал в комитете синхронизации
+5. вознаграждение предложившего: валидатор предложил блок в правильном слоте
+```
+
+Весовые коэффициенты для каждого компонента следующие:
+
+```
+TIMELY_SOURCE_WEIGHT uint64(14)
+TIMELY_TARGET_WEIGHT uint64(26)
+TIMELY_HEAD_WEIGHT uint64(14)
+SYNC_REWARD_WEIGHT uint64(2)
+PROPOSER_WEIGHT uint64(8)
+```
+
+Их сумма составляет 64. Вознаграждение рассчитывается как сумма применимых весов, деленная на 64. Валидатор, который своевременно проголосовал за источник, цель и заголовок, предложил блок и участвовал в комитете синхронизации, может получить `64/64 * base_reward == base_reward`. Однако валидатор обычно не является автором блока, поэтому его максимальное вознаграждение составляет `64-8 /64 * base_reward == 7/8 * base_reward`. Валидаторы, которые не являются ни авторами блоков, ни членами комитета синхронизации, могут получить `64-8-2 / 64 * base_reward == 6.75/8 * base_reward`.
+
+Для стимулирования быстрых аттестаций добавляется дополнительное вознаграждение. Это `inclusion_delay_reward`. Его значение равно `base_reward`, умноженному на `1/delay`, где `delay` — это количество слотов между предложением блока и аттестацией. Например, если аттестация отправлена в течение одного слота после предложения блока, аттестующий получает `base_reward * 1/1 == base_reward`. Если аттестация поступает в следующем слоте, аттестующий получает `base_reward * 1/2` и так далее.
+
+Авторы блоков получают `8 / 64 * base_reward` за **каждую действительную аттестацию**, включенную в блок, поэтому фактический размер вознаграждения масштабируется в зависимости от количества аттестующих валидаторов. Авторы блоков также могут увеличить свое вознаграждение, включив в предложенный блок доказательства неправомерного поведения других валидаторов. Эти вознаграждения — «пряники», поощряющие честность валидаторов. Автор блока, который включает слэшинг, будет вознагражден `slashed_validators_effective_balance / 512`.
+
+### Штрафы {#penalties}
+
+До сих пор мы рассматривали идеально работающих валидаторов, но что насчет валидаторов, которые не голосуют своевременно за заголовок, источник и цель или делают это медленно?
+
+Штрафы за пропуск голосов за цель и источник равны вознаграждениям, которые аттестующий получил бы, если бы отправил их. Это означает, что вместо добавления вознаграждения к их балансу с их баланса списывается эквивалентная сумма. За пропуск голосования за заголовок штраф не предусмотрен (т. е. голосование за заголовок только вознаграждается, но никогда не наказывается). Штрафа, связанного с `inclusion_delay`, не существует — вознаграждение просто не будет добавлено на баланс валидатора. Также нет штрафа за неспособность предложить блок.
+
+Подробнее о вознаграждениях и штрафах читайте в [спецификациях консенсуса](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md). Вознаграждения и штрафы были скорректированы в обновлении Bellatrix — посмотрите, как Дэнни Райан и Виталик обсуждают это в видео [Peep an EIP](https://www.youtube.com/watch?v=iaAEGs1DMgQ).
+
+## Слэшинг {#slashing}
+
+Слэшинг — это более суровое действие, которое приводит к принудительному удалению валидатора из сети и сопутствующей потере его эфира в стейкинге. Существует три способа, которыми валидатор может быть подвергнут слэшингу, все они сводятся к нечестному предложению или аттестации блоков:
+
+- Предложение и подписание двух разных блоков для одного и того же слота
+- Аттестация блока, который "окружает" другой блок (фактически изменяя историю)
+- "Двойное голосование" путем аттестации двух кандидатов на один и тот же блок
+
+При обнаружении этих действий валидатор подвергается слэшингу. Это означает, что 0,0078125 немедленно сжигается для валидатора с 32 ETH (масштабируется линейно с активным балансом), затем начинается 36-дневный период удаления. В течение этого периода удаления доля валидатора постепенно уменьшается. В середине периода (на 18-й день) применяется дополнительный штраф, размер которого зависит от общей суммы эфира в стейкинге всех валидаторов, подвергшихся слэшингу за 36 дней до события слэшинга. Это означает, что чем больше валидаторов подвергается слэшингу, тем больше размер слэшинга. Максимальный слэшинг — это полный эффективный баланс всех валидаторов, подвергшихся слэшингу (т. е. если слэшингу подвергается много валидаторов, они могут потерять всю свою долю). С другой стороны, единичный, изолированный случай слэшинга сжигает лишь небольшую часть доли валидатора. Этот срединный штраф, который масштабируется в зависимости от количества валидаторов, подвергшихся слэшингу, называется "корреляционным штрафом".
+
+## Утечка из-за неактивности {#inactivity-leak}
+
+Если уровень консенсуса не финализировался более четырех эпох, активируется экстренный протокол под названием "утечка из-за неактивности". Конечная цель утечки из-за неактивности — создать условия, необходимые для восстановления финализации цепи. Как объяснялось выше, для финализации требуется, чтобы 2/3 большинства от общего объема эфира в стейкинге согласовали исходную и целевую контрольные точки. Если валидаторы, составляющие более 1/3 от общего числа, уходят в оффлайн или не предоставляют корректные аттестации, то супербольшинство в 2/3 не сможет финализировать контрольные точки. Утечка из-за неактивности приводит к тому, что доля неактивных валидаторов постепенно уменьшается, пока они не будут контролировать менее 1/3 от общей доли, что позволяет оставшимся активным валидаторам финализировать цепь. Независимо от размера пула неактивных валидаторов, оставшиеся активные валидаторы в конечном итоге будут контролировать >2/3 доли. Потеря доли является сильным стимулом для неактивных валидаторов как можно скорее возобновить работу! Сценарий утечки из-за неактивности произошел в тестовой сети Medalla, когда менее 66 % активных валидаторов смогли достичь консенсуса по поводу текущего заголовка блокчейна. Была активирована утечка из-за неактивности, и в конечном итоге финализация была восстановлена!
+
+Дизайн вознаграждений, штрафов и слэшинга в механизме консенсуса поощряет отдельных валидаторов вести себя корректно. Однако из этих проектных решений возникает система, которая сильно стимулирует равномерное распределение валидаторов между несколькими клиентами и должна сильно препятствовать доминированию одного клиента.
+
+## Дополнительные материалы {#further-reading}
+
+- [Обновление Ethereum: уровень стимулов](https://eth2book.info/altair/part2/incentives)
+- [Стимулы в гибридном протоколе Casper в Ethereum](https://arxiv.org/pdf/1903.04205.pdf)
+- [Аннотированная спецификация от Виталика](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#rewards-and-penalties-1)
+- [Советы по предотвращению слэшинга в Eth2](https://medium.com/prysmatic-labs/eth2-slashing-prevention-tips-f6faa5025f50)
+- [Анализ штрафов за слэшинг в рамках EIP-7251](https://ethresear.ch/t/slashing-penalty-analysis-eip-7251/16509)
+
+_Источники_
+
+- _[https://benjaminion.xyz/eth2-annotated-spec/phase0/beacon-chain/](https://benjaminion.xyz/eth2-annotated-spec/phase0/beacon-chain/)_
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md
new file mode 100644
index 00000000000..89c4c065683
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md
@@ -0,0 +1,39 @@
+---
+title: "Слабая субъективность"
+description: "Объяснение понятия слабой субъективности и её роли в пункте продажи Ethereum."
+lang: ru
+---
+
+Субъективностью в Блокчейне называется зависимость от коллективной информации при оценке текущего состояния. Несколько вариантов развития событий могут быть выбрано, основываясь на информации, полученной от других равноправных участников сети. Обратное понятие — объективность, которая используется в таких цепочках, что обязаны принять только одну цепочку в качестве единственной возможной правильной цепочки, используя заранее заданные правила. Существует также и третье состояние, которое известно как слабая субъективность. Так обозначается состояние цепочки, которая может развиваться объективно после того, как начальная информация была получена коллективно.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы понять эту страницу, необходимо сначала разобраться в основах [доказательства владения](/developers/docs/consensus-mechanisms/pos/).
+
+## Какие проблемы решает слабая субъективность? {#problems-ws-solves}
+
+Субъективность присуща блокчейнам с доказательством доли владения, так как выбор правильной цепочки из нескольких ветвлений осуществляется путем подсчета исторических голосов. Это делает блокчейн уязвимым для многочисленных атак, включая атаки на большие расстояния. В них узлы, участвовующие в цепочке на ранних этапах, поддерживают альтернативное ветвление, которое они выпускают позже в свою пользу. В качестве альтернативы, если 33% валидаторов отзовут свою долю, но продолжат подтверждать и создавать блоки, они могут сгенерировать альтернативное ветвление, которое будет конфликтовать с канонической цепочкой. Новые узлы или узлы, которые долгое время были отключены, могут не знать, что данные атакующие валидаторы отозвали свои средства, поэтому злоумышленники могут обманом заставить их следовать по неверной цепочке. Ethereum может устранить данные атаки, налагая ограничения, которые сведут субъективный механизм (и, следовательно, предположения о доверии) к абсолютному минимуму.
+
+## Контрольные точки слабой субъективности {#ws-checkpoints}
+
+Слабая субъективность реализована в доказательстве владения Ethereum с помощью «контрольных точек слабой субъективности». Это состояние подтверждает, что все узлы в сети принадлежат к канонической цепочке. Они выполняют ту же функцию «универсальной истины», что и первые блоки, не находясь на данном блокчейне. Алгоритм ветвления доверяет факту, что состояние блокчейна, в данной контрольной точке, является правильным, и что он независимо и объективно проверяет его в дальнейшем. Контрольные точки действуют как «лимиты возврата», так как блоки, расположенные перед контрольными точками слабой субъективности, не могут быть изменены. Это дискредитирует атаки, заведомо определяя их как недействительные части механизма. Контрольные точки, разделенные меньшим периодом, в сравнении с периодом вывода средств валидатором, гарантируют факт того, что валидатор, который разветвляет цепочку, сократит пороговую сумму, прежде чем он сможет вывести свою долю, и что новые участники не будут обмануты и не будут переведены на неправильные ветвления валидаторами, чья доля была выведена.
+
+## Разница между контрольными точками слабой субъективности и завершенными блоками {#difference-between-ws-and-finalized-blocks}
+
+Завершенные блоки и слабые контрольные точки обрабатываются узлами Ethereum по-разному. Если узел осведомлен о двух конкурирующих завешенных блоках, то он разрывается между ними — у него нет возможности автоматически определить, какой из них является каноническим ответвлением. Это следствие отсутствия консенсуса. Напротив, узел просто отклоняет любой блок, который конфликтует с его слабой контрольной точкой. С точки зрения узла, слабая контрольная точка представляет собой абсолютную истину, которая не может быть подорвана новой информацией.
+
+## Насколько слаба слабость? {#how-weak-is-weak}
+
+Субъективным доказательством владения долей Ethereum является наличие контрольной точки (настоящих предпосылок) из доверенного источника для его синхронизации. Риск получения плохой, контрольной точки очень низок, поскольку ее можно проверить с помощью нескольких независимых общедоступных источников, таких как обозреватели блоков или узлами. Тем не менее, для запуска любого программного приложения всегда требуется определенная степень доверия, например, уверенность в том, что разработчики программного обеспечения создали честное программное обеспечение.
+
+Контрольная точка может быть и частью клиентского программного обеспечения. Вероятно, злоумышленник может повредить контрольную точку в программном обеспечении, а также может повредить и само программное обеспечение. Не существует реального криптоэкономического способа обойти эту проблему, однако влияние некачественных разработчиков в Ethereum сведено к минимуму за счет наличия нескольких независимых команд, каждая из которых создает эквивалентное программное обеспечение на разных языках, и все они заинтересованы в поддержании доверительной цепочки. Исследователи блоков также могут предоставлять контрольные точки или способ перекрестной ссылки на контрольные точки, полученные из других источников, с дополнительным источником.
+
+В конечном итоге, контрольные точки можно запрашивать из других узлов. Возможно, другой пользователь Ethereum, управляющий полным узлом, может предоставить контрольную точку, которую валидаторы затем смогут сверить с данными из обозревателя блоков. В целом, доверие к поставщику контрольной точки можно считать столь же проблематичным, как и доверие к разработчикам. Низкий общий уровень доверия. Важно отметить, что эти факты действительны только в том случае, если большинство валидаторов согласяться создать альтернативную ветку блокчейна. При любых других обстоятельствах можно выбирать только из одной цепочки Ethereum.
+
+## Дополнительные материалы {#further-reading}
+
+- [Слабая субъективность в Eth2](https://notes.ethereum.org/@adiasg/weak-subjectvity-eth2)
+- [Виталик: как я полюбил слабую субъективность](https://blog.ethereum.org/2014/11/25/proof-stake-learned-love-weak-subjectivity/)
+- [Слабая субъективность (документация Teku)](https://docs.teku.consensys.io/concepts/weak-subjectivity)
+- [Руководство по слабой субъективности для Phase-0](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/weak-subjectivity.md)
+- [Анализ слабой субъективности в Ethereum 2.0](https://github.com/runtimeverification/beacon-chain-verification/blob/master/weak-subjectivity/weak-subjectivity-analysis.pdf)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/index.md
index 06d1afadf65..d2203d8dcf0 100644
--- a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/index.md
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/index.md
@@ -1,6 +1,6 @@
---
-title: Доказательство работы (PoW)
-description: Объяснение протокола доказательства работы и его роли в Ethereum.
+title: "Доказательство работы (PoW)"
+description: "Объяснение протокола доказательства работы и его роли в Ethereum."
lang: ru
incomplete: true
---
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/index.md
index 57ce5a1fb91..11a190bf8cc 100644
--- a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/index.md
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/index.md
@@ -1,79 +1,86 @@
---
-title: Майнинг
-description: Объяснение того, как работает майнинг Ethereum и как он помогает сохранять безопасность и децентрализованность Ethereum.
+title: "Секс с гомосексуалистами"
+description: "Объяснение того как работает майнинг на Ethereum."
lang: ru
-incomplete: true
---
-## Прежде чем начать {#prerequisites}
-
-Для лучшего понимания этой страницы мы рекомендуем сначала почитать о [транзакциях](/developers/docs/transactions/), [блоках](/developers/docs/blocks/) и [доказательстве работы](/developers/docs/consensus-mechanisms/pow/).
-
-## Что такое майнинг в Ethereum? {#what-is-ethereum-mining}
-
-Майнинг — это процесс создания блоков транзакций, которые будут добавлены в блокчейн Ethereum.
-
-Сейчас Ethereum, как и Bitcoin, использует механизм консенсуса [«Доказательство работы» (proof-of-work, PoW)](/developers/docs/consensus-mechanisms/pow/). Майнинг — это ключевая составляющая в системе доказательства работы. Майнеры Ethereum (компьютеры с работающим программным обеспечением) используют свою вычислительную мощность для обработки транзакций и создания блоков.
-
- Доказательство владения заменит майнинг и доказательство работы в течение следующего года. Вы можете начать ставить свои ETH уже сегодня. [Подробнее о стейкинге](/staking/)
+Доказательство работы(PoW) больше не является механизмом консенсуса Ethereum, это означает что майнинг отключен. Вместо этого, Ethereum обеспечен и защищен валидаторами, которые поставляют ETH. Вы можете начать ставить свои ETH уже сегодня. Узнайте больше о Слиянии, доказательстве владения и вкладах. Эта страница здесь ради исторического интереса.
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочитать о [транзакциях](/developers/docs/transactions/), [блоках](/developers/docs/blocks/) и [доказательстве работы](/developers/docs/consensus-mechanisms/pow/).
+
+## Что такое майнинг в Ethereum? {#what-is-ethereum-mining}
+
+Майнинг - это процесс создания блока транзакций, который будет добавлен в блокчейн Ethereum в на данный момент устаревшей архитектуре proof-of-work.
+
+Слово "майнинг" пришло в криптовалюты, в контексте аналогии с добычей золота. Золото или драгоценные металлы являются редкими, так же и цифровые активы и есть только один способ увеличить их количество - с помощью добычи или "майнинга". В консенсусе доказательства работы(PoW) Ethereum, "майнинг" - был единственным способом эмиссии. Однако, в отличие от золота или драгоценных металлов, майнинг Ethereum также является способом защиты сети путем создания, проверки, публикации и распространения блоков в блокчейне.
+
+Майнинг эфира = защита сети
+
+Майнинг - это источник жизненной силы любого proof-of-work блокчейна. Ethereum майнеры - компьютеры, на которых запущено программное обеспечение - до перехода к proof-of-stake использовали свое время и вычислительную мощность для обработки транзакций и производства блоков.
+
## Зачем нужны майнеры? {#why-do-miners-exist}
-В децентрализованных системах, таких как Ethereum, требуется, чтобы все были согласны с порядком транзакций. Майнеры помогают в этом, решая вычислительно сложную задачу создания блоков и таким образом защищая сеть от атак.
+В децентрализованных системах, таких как Ethereum, требуется, чтобы все были согласны с порядком транзакций. Майнеры помогли этому произойти, решая вычислительно сложные головоломки для производства блоков, защищая сеть от атак.
[Подробнее о доказательстве работы](/developers/docs/consensus-mechanisms/pow/)
-## Кто может стать майнером Ethereum? {#who-can-become-a-miner}
-
-Технически любой может добывать Ethereum, используя свой компьютер. Однако не каждый может добывать эфир (ETH) с прибылью. В большинстве случаев майнеры должны покупать специальное компьютерное оборудование для майнинга с прибылью. Хотя любой может запустить программное обеспечение для майнинга на своем компьютере, маловероятно, что средний компьютер добудет достаточно награды для покрытия расходов, связанных со стоимостью майнинга.
+Раньше любой имел возможность майнить в сети Ethereum, используя свой компьютер. Однако не каждый может выгодно майнить ether (ETH). В большинстве случаев майнерам приходилось приобретать специальное компьютерное оборудование и иметь доступ к недорогим источникам энергии. Среднестатистический компьютер вряд ли заработал бы достаточное вознаграждение за блок, чтобы покрыть затраты, связанные с майнингом.
-### Затраты на майнинг {#cost-of-mining}
+### Стоимость майнинга {#cost-of-mining}
- Потенциальные затраты на оборудование, необходимое для сборки и обслуживания майнинговой фермы
- Затраты на электричество для майнинговой фермы
-- Если dы занимаетесь майнингом в пуле, обычно майнинг-пулы взимают фиксированную комиссию в % от каждого блока, добытого пулом
+- Если бы вы занимались майнингом в пуле, эти пулы обычно взимают фиксированную плату в размере % за каждый блок, сгенерированный пулом
- Потенциальные затраты на дополнительное оборудование для поддержки майнинговой фермы (вентиляция, мониторинг потребления электроэнергии, электропроводка и т. д.)
-Для оценки прибыльности майнинга используйте калькулятор майнинга, такой как [Etherscan](https://etherscan.io/ether-mining-calculator).
+Чтобы подробнее изучить прибыльность майнинга, воспользуйтесь калькулятором майнинга, например, таким, который предоставляет [Etherscan](https://etherscan.io/ether-mining-calculator).
-## Как добываются (майнятся) транзакции Ethereum {#how-ethereum-transactions-are-mined}
+## Как майнились транзакции Ethereum {#how-ethereum-transactions-were-mined}
-1. Пользователь составляет запрос на [транзакцию](/developers/docs/transactions/) и подписывает ее с помощью приватного ключа некоторого [аккаунта](/developers/docs/accounts/).
-2. Пользователь транслирует запрос транзакции в сеть Ethereum через некоторый [узел](/developers/docs/nodes-and-clients/).
+Ниже приведен обзор того, как транзакции были добыты в Ethereum proof-of-work. Аналогичное описание этого процесса для Ethereum с доказательством владения (proof-of-stake) можно найти [здесь](/developers/docs/consensus-mechanisms/pos/#transaction-execution-ethereum-pos).
+
+1. Пользователь создает и подписывает запрос на [транзакцию](/developers/docs/transactions/) с помощью приватного ключа некоторого [аккаунта](/developers/docs/accounts/).
+2. Пользователь транслирует запрос на транзакцию во всю сеть Ethereum с какого-либо [узла](/developers/docs/nodes-and-clients/).
3. Получив новый запрос на транзакцию, каждый узел сети Ethereum добавляет его в свой мемпул — локальный список всех полученных запросов на транзакции, которые еще не вошли ни в один блок блокчейна.
-4. В какой-то момент узел собирает несколько десятков или сотен запросов на транзакции в потенциальный [блок](/developers/docs/blocks/) таким образом, чтобы максимизировать сумму [трансакционных комиссий](/developers/docs/gas/), которые узел заработает, но в пределах лимита газа для блока. Затем узел майнинга делает следующее:
- 1. Проверяет валидность каждого запроса на транзакцию (проверяет наличие подписи и ее соответствие запросу, целостность запроса и т. д.), а затем выполняет код запроса, изменяя состояние своей локальной копии EVM. Комиссию за каждую такую транзакцию майнер направляет на свой счет.
+4. В определенный момент майнинг-узел объединяет несколько десятков или сотен запросов на транзакции в потенциальный [блок](/developers/docs/blocks/) таким образом, чтобы максимизировать получаемые [комиссии за транзакции](/developers/docs/gas/), оставаясь при этом в пределах лимита газа блока. Затем узел майнинга делает следующее:
+ 1. Проверяет действительность каждого запроса на транзакцию (т. е. что никто не пытается перевести эфир (ether) со счета, не предоставив подпись, что запрос не искажен и т. д.), а затем выполняет код запроса, изменяя состояние своей локальной копии EVM. Комиссию за каждую такую транзакцию майнер направляет на свой счет.
2. Как только все запросы на транзакции в блоке будут проверены и выполнены на локальной копии EVM майнер начинает процесс создания «сертификата законности» доказательства работы для этого потенциального блока.
5. В конце концов, какой-то майнер создаст блок с соответствующим сертификатом для блока, который включает в себя наш запрос на транзакцию. Затем майнер транслирует в сеть завершенный блок, а так же его сертификат и контрольную сумму нового состояния EVM.
6. Другие узлы узнают о новом блоке. Они проверяют сертификат, выполняют все операции в блоке (в том числе транзакцию нашего пользователя) и убеждаются в том, что контрольная сумма их нового состояния EVM после выполнения всех транзакций соответствует контрольной сумме, заявленной майнером этого блока. Только после этого они добавляют этот блок к хвосту блокчейна и принимают новое состояние EVM в качестве канонического состояния.
7. Каждый узел удаляет все транзакции нового блока из локального пула невыполненных запросов на транзакции.
8. Новые узлы, присоединяющиеся к сети, скачивают все блоки по очереди, в том числе блок, содержащий конкретно нашу транзакцию. Они инициализируют локальную копию EVM с пустым состоянием, а затем выполняют каждую транзакцию каждого блока на их локальной копии EVM, проверяя контрольные суммы состояний в каждом блоке на всем пути.
-Каждая транзакция добывается (включается в новый блок и распространяется) только один раз, но выполняется и проверяется каждым участником в процессе изменений канонического состояния EVM. Это подсвечивает одну из центральных идей блокчейна: **не доверяй, проверяй**.
+Каждая транзакция добывается (включается в новый блок и распространяется) только один раз, но выполняется и проверяется каждым участником в процессе изменений канонического состояния EVM. Это подчеркивает один из центральных принципов блокчейна: **не доверяй, проверяй**.
+
+## Оммер-блоки (блоки-дяди) {#ommer-blocks}
+
+Майнинг блоков на основе доказательства работы, была вероятностной, то есть, иногда два правильных блока публиковались одновременно из-за сетевой задержки. В этом случае протокол должен был определить самую длинную (и, следовательно, наиболее "действительную") цепь, обеспечивая при этом честность по отношению к майнерам за счет частичного вознаграждения предложенного невключенного блока с невключенным предложенным блоком. Это способствовало дальнейшей децентрализации сети, поскольку более мелкие майнеры, которые могли сталкиваться с большей задержкой, все равно могли получать доход через вознаграждения за [ommer](/glossary/#ommer)-блоки.
+
+Термин «ommer» является предпочтительным нейтральным с гендерной точки зрения термином для обозначения брата или сестры родительского блока, но его также иногда называют «дядей». **После перехода Ethereum на доказательство владения оммер-блоки больше не майнятся**, поскольку в каждом слоте выбирается только один создатель блока (proposer). Вы можете увидеть это изменение, просмотрев [исторический график](https://ycharts.com/indicators/ethereum_uncle_rate) добытых оммер-блоков.
-## Визуализация {#a-visual-demo}
+## Наглядная демонстрация {#a-visual-demo}
-Посмотрите, как Остин рассказывает о майнинге и блокчейнах с доказательством работы.
+Посмотрите, как Остин рассказывает о майнинге и о блокчейне с доказательством работы.
-## Дополнительные ресурсы {#further-reading}
+## Алгоритм майнинга {#mining-algorithm}
-## Связанные инструменты {#related-tools}
+Основная сеть Ethereum всегда использовала только один алгоритм майнинга — ['Ethash'](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/). Ethash стал преемником оригинального R&D-алгоритма, известного как ['Dagger-Hashimoto'](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/).
-- [Лучшие майнеры Ethereum](https://etherscan.io/stat/miner?range=7&blocktype=blocks)
-- [Калькулятор майнинга Etherscan](https://etherscan.io/ether-mining-calculator)
-- [Калькулятор майнинга Minerstat](https://minerstat.com/coin/ETH)
+[Подробнее об алгоритмах майнинга](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/).
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Газ](/developers/docs/gas/)
- [EVM](/developers/docs/evm/)
-- [Доказательство работы (PoW)](/developers/docs/consensus-mechanisms/pow/)
+- [Доказательство работы](/developers/docs/consensus-mechanisms/pow/)
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md
new file mode 100644
index 00000000000..5726f89c579
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md
@@ -0,0 +1,329 @@
+---
+title: Dagger-Hashimoto
+description: "Подробный обзор алгоритма Dagger-Hashimoto."
+lang: ru
+---
+
+Dagger-Hashimoto был изначальной исследовательской реализацией и спецификацией алгоритма майнинга Ethereum. Dagger-Hashimoto был заменен на [Ethash](#ethash). Майнинг был полностью отключен во время [Слияния](/roadmap/merge/) 15 сентября 2022 года. С тех пор безопасность Ethereum обеспечивается с помощью механизма [доказательства доли владения](/developers/docs/consensus-mechanisms/pos). Эта страница представляет исторический интерес — информация на ней больше не актуальна для Ethereum после Слияния.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала ознакомиться с [консенсусом на основе доказательства выполнения работы](/developers/docs/consensus-mechanisms/pow), [майнингом](/developers/docs/consensus-mechanisms/pow/mining) и [алгоритмами майнинга](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms).
+
+## Dagger-Hashimoto {#dagger-hashimoto}
+
+Dagger-Hashimoto нацелен на достижение двух целей:
+
+1. **Устойчивость к ASIC**: преимущество от создания специализированного оборудования для этого алгоритма должно быть как можно меньшим
+2. **Верифицируемость легким клиентом**: блок должен эффективно верифицироваться легким клиентом.
+
+С дополнительной модификацией мы также указываем, как при желании достичь третьей цели, но за счет дополнительной сложности:
+
+**Полное хранение цепочки**: майнинг должен требовать хранения полного состояния блокчейна (из-за нерегулярной структуры дерева состояний Ethereum мы предполагаем, что будет возможно некоторое усечение, в частности, некоторых часто используемых контрактов, но мы хотим свести это к минимуму).
+
+## Генерация DAG {#dag-generation}
+
+Код алгоритма будет определен на Python ниже. Сначала приведем `encode_int` для маршалинга беззнаковых целых чисел указанной точности в строки. Также приведена обратная функция:
+
+```python
+NUM_BITS = 512
+
+def encode_int(x):
+ "Кодирует целое число x в виде строки из 64 символов с использованием схемы с прямым порядком байтов"
+ o = ''
+ for _ in range(NUM_BITS / 8):
+ o = chr(x % 256) + o
+ x //= 256
+ return o
+
+def decode_int(s):
+ "Декодирует целое число x из строки с использованием схемы с прямым порядком байтов"
+ x = 0
+ for c in s:
+ x *= 256
+ x += ord(c)
+ return x
+```
+
+Далее мы предполагаем, что `sha3` — это функция, которая принимает и возвращает целое число, а `dbl_sha3` — это функция двойного sha3; при преобразовании этого эталонного кода в реализацию используйте:
+
+```python
+from pyethereum import utils
+def sha3(x):
+ if isinstance(x, (int, long)):
+ x = encode_int(x)
+ return decode_int(utils.sha3(x))
+
+def dbl_sha3(x):
+ if isinstance(x, (int, long)):
+ x = encode_int(x)
+ return decode_int(utils.sha3(utils.sha3(x)))
+```
+
+### Параметры {#parameters}
+
+Для алгоритма используются следующие параметры:
+
+```python
+SAFE_PRIME_512 = 2**512 - 38117 # Наибольшее безопасное простое число, меньшее, чем 2**512
+
+params = {
+ "n": 4000055296 * 8 // NUM_BITS, # Размер набора данных (4 гигабайта); ДОЛЖЕН БЫТЬ КРАТЕН 65536
+ "n_inc": 65536, # Приращение значения n за период; ДОЛЖНО БЫТЬ КРАТНО 65536
+ # при epochtime=20000 дает прирост 882 МБ в год
+ "cache_size": 2500, # Размер кэша легкого клиента (может быть выбран легким клиентом; не является частью спецификации алгоритма)
+ "diff": 2**14, # Сложность (корректируется во время оценки блока)
+ "epochtime": 100000, # Длительность эпохи в блоках (как часто обновляется набор данных)
+ "k": 1, # Количество родителей узла
+ "w": w, # Используется для хэширования модульным возведением в степень
+ "accesses": 200, # Количество обращений к набору данных во время хэширования
+ "P": SAFE_PRIME_512 # Безопасное простое число для хэширования и генерации случайных чисел
+}
+```
+
+В данном случае `P` является простым числом, выбранным таким образом, чтобы `log₂(P)` был незначительно меньше 512, что соответствует 512 битам, которые мы использовали для представления наших чисел. Обратите внимание, что фактически необходимо хранить только вторую половину DAG, поэтому фактическое требование к ОЗУ начинается с 1 ГБ и увеличивается на 441 МБ в год.
+
+### Построение графа Dagger {#dagger-graph-building}
+
+Примитив построения графа Dagger определяется следующим образом:
+
+```python
+def produce_dag(params, seed, length):
+ P = params["P"]
+ picker = init = pow(sha3(seed), params["w"], P)
+ o = [init]
+ for i in range(1, length):
+ x = picker = (picker * init) % P
+ for _ in range(params["k"]):
+ x ^= o[x % i]
+ o.append(pow(x, params["w"], P))
+ return o
+```
+
+По сути, он начинает граф с одного узла `sha3(seed)`, а затем последовательно добавляет другие узлы на основе случайных предыдущих узлов. При создании нового узла вычисляется модульная степень начального числа для случайного выбора некоторых индексов, меньших `i` (с использованием `x % i` выше), и значения узлов по этим индексам используются в вычислении для генерации нового значения `x`, которое затем подается в небольшую функцию доказательства выполнения работы (на основе XOR) для окончательной генерации значения графа по индексу `i`. Обоснование этого конкретного дизайна заключается в том, чтобы принудить к последовательному доступу к DAG; следующее значение DAG, к которому будет осуществлен доступ, не может быть определено, пока не станет известно текущее значение. Наконец, модульное возведение в степень далее хэширует результат.
+
+Этот алгоритм опирается на несколько результатов из теории чисел. См. обсуждение в приложении ниже.
+
+## Оценка легкого клиента {#light-client-evaluation}
+
+Приведенная выше конструкция графа предназначена для того, чтобы каждый узел в графе можно было реконструировать путем вычисления поддерева из небольшого числа узлов и требуя лишь небольшого количества вспомогательной памяти. Обратите внимание, что при k=1 поддерево представляет собой лишь цепочку значений, ведущую к первому элементу в DAG.
+
+Вычислительная функция легкого клиента для DAG работает следующим образом:
+
+```python
+def quick_calc(params, seed, p):
+ w, P = params["w"], params["P"]
+ cache = {}
+
+ def quick_calc_cached(p):
+ if p in cache:
+ pass
+ elif p == 0:
+ cache[p] = pow(sha3(seed), w, P)
+ else:
+ x = pow(sha3(seed), (p + 1) * w, P)
+ for _ in range(params["k"]):
+ x ^= quick_calc_cached(x % p)
+ cache[p] = pow(x, w, P)
+ return cache[p]
+
+ return quick_calc_cached(p)
+```
+
+По сути, это просто переписанный вышеуказанный алгоритм, который удаляет цикл вычисления значений для всего DAG и заменяет предыдущий поиск узла рекурсивным вызовом или поиском в кэше. Обратите внимание, что для `k=1` кэш не нужен, хотя дальнейшая оптимизация фактически предварительно вычисляет первые несколько тысяч значений DAG и сохраняет их в качестве статического кэша для вычислений; см. приложение для реализации этого кода.
+
+## Двойной буфер DAG {#double-buffer}
+
+В полном клиенте используется [_двойной буфер_](https://wikipedia.org/wiki/Multiple_buffering) из 2 DAG, созданных по приведенной выше формуле. Идея заключается в том, что DAG создаются каждые `epochtime` блоков в соответствии с приведенными выше параметрами. Вместо того чтобы клиент использовал последний созданный DAG, он использует предыдущий. Преимущество этого заключается в том, что это позволяет заменять DAG со временем без необходимости включать шаг, на котором майнеры должны внезапно пересчитывать все данные. В противном случае существует вероятность резкого временного замедления обработки цепочки через равные промежутки времени и резкого усиления централизации. Таким образом, в течение тех нескольких минут, пока все данные не будут пересчитаны, возникают риски атаки 51 %.
+
+Алгоритм, используемый для генерации набора DAG, который, в свою очередь, используется для вычисления работы для блока, следующий:
+
+```python
+def get_prevhash(n):
+ from pyethereum.blocks import GENESIS_PREVHASH
+ from pyethereum import chain_manager
+ if n <= 0:
+ return hash_to_int(GENESIS_PREVHASH)
+ else:
+ prevhash = chain_manager.index.get_block_by_number(n - 1)
+ return decode_int(prevhash)
+
+def get_seedset(params, block):
+ seedset = {}
+ seedset["back_number"] = block.number - (block.number % params["epochtime"])
+ seedset["back_hash"] = get_prevhash(seedset["back_number"])
+ seedset["front_number"] = max(seedset["back_number"] - params["epochtime"], 0)
+ seedset["front_hash"] = get_prevhash(seedset["front_number"])
+ return seedset
+
+def get_dagsize(params, block):
+ return params["n"] + (block.number // params["epochtime"]) * params["n_inc"]
+
+def get_daggerset(params, block):
+ dagsz = get_dagsize(params, block)
+ seedset = get_seedset(params, block)
+ if seedset["front_hash"] <= 0:
+ # Создание резервного буфера невозможно, создается только передний буфер
+ return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz),
+ "block_number": 0}}
+ else:
+ return {"front": {"dag": produce_dag(params, seedset["front_hash"], dagsz),
+ "block_number": seedset["front_number"]},
+ "back": {"dag": produce_dag(params, seedset["back_hash"], dagsz),
+ "block_number": seedset["back_number"]}}
+```
+
+## Hashimoto {#hashimoto}
+
+Идея оригинального Hashimoto заключается в использовании блокчейна в качестве набора данных, выполняя вычисление, которое выбирает N индексов из блокчейна, собирает транзакции по этим индексам, выполняет операцию XOR над этими данными и возвращает хэш результата. Оригинальный алгоритм Таддеуша Дрии, переведенный на Python для согласованности, следующий:
+
+```python
+def orig_hashimoto(prev_hash, merkle_root, list_of_transactions, nonce):
+ hash_output_A = sha256(prev_hash + merkle_root + nonce)
+ txid_mix = 0
+ for i in range(64):
+ shifted_A = hash_output_A >> i
+ transaction = shifted_A % len(list_of_transactions)
+ txid_mix ^= list_of_transactions[transaction] << i
+ return txid_mix ^ (nonce << 192)
+```
+
+К сожалению, хотя Hashimoto считается сложным для ОЗУ, он опирается на 256-битную арифметику, что влечет за собой значительные вычислительные накладные расходы. Однако для решения этой проблемы Dagger-Hashimoto использует только младшие 64 бита при индексации своего набора данных.
+
+```python
+def hashimoto(dag, dagsize, params, header, nonce):
+ m = dagsize / 2
+ mix = sha3(encode_int(nonce) + header)
+ for _ in range(params["accesses"]):
+ mix ^= dag[m + (mix % 2**64) % m]
+ return dbl_sha3(mix)
+```
+
+Использование двойного SHA3 позволяет осуществлять своего рода почти мгновенную предварительную верификацию с нулевыми данными, проверяя только то, что было предоставлено правильное промежуточное значение. Этот внешний уровень доказательства выполнения работы очень дружелюбен к ASIC и довольно слаб, но существует для того, чтобы еще больше усложнить DDoS-атаки, поскольку этот небольшой объем работы должен быть выполнен для создания блока, который не будет немедленно отклонен. Вот версия для легкого клиента:
+
+```python
+def quick_hashimoto(seed, dagsize, params, header, nonce):
+ m = dagsize // 2
+ mix = sha3(nonce + header)
+ for _ in range(params["accesses"]):
+ mix ^= quick_calc(params, seed, m + (mix % 2**64) % m)
+ return dbl_sha3(mix)
+```
+
+## Майнинг и верификация {#mining-and-verifying}
+
+Давайте соберём это всё в алгоритм майнинга:
+
+```python
+def mine(daggerset, params, block):
+ from random import randint
+ nonce = randint(0, 2**64)
+ while 1:
+ result = hashimoto(daggerset, get_dagsize(params, block),
+ params, decode_int(block.prevhash), nonce)
+ if result * params["diff"] < 2**256:
+ break
+ nonce += 1
+ if nonce >= 2**64:
+ nonce = 0
+ return nonce
+```
+
+И в алгоритм верификации:
+
+```python
+def verify(daggerset, params, block, nonce):
+ result = hashimoto(daggerset, get_dagsize(params, block),
+ params, decode_int(block.prevhash), nonce)
+ return result * params["diff"] < 2**256
+```
+
+Верификация, дружественная к легким клиентам:
+
+```python
+def light_verify(params, header, nonce):
+ seedset = get_seedset(params, block)
+ result = quick_hashimoto(seedset["front_hash"], get_dagsize(params, block),
+ params, decode_int(block.prevhash), nonce)
+ return result * params["diff"] < 2**256
+```
+
+Также обратите внимание, что Dagger-Hashimoto накладывает дополнительные требования на заголовок блока:
+
+- Чтобы двухслойная верификация работала, заголовок блока должен содержать как nonce, так и промежуточное значение до применения sha3.
+- Где-то в заголовке блока должен храниться sha3 текущего набора начальных чисел
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Приложение {#appendix}
+
+Как отмечалось выше, ГСЧ, используемый для генерации DAG, основывается на некоторых результатах теории чисел. Во-первых, мы даем гарантию, что ГСЧ Лемера, который лежит в основе переменной `picker`, имеет большой период. Во-вторых, мы показываем, что `pow(x,3,P)` не отобразит `x` в `1` или `P-1` при условии, что `x` изначально находится в диапазоне `[2,P-2]`. Наконец, мы показываем, что `pow(x,3,P)` имеет низкий уровень коллизий при использовании в качестве хэш-функции.
+
+### Генератор случайных чисел Лемера {#lehmer-random-number}
+
+Хотя функция `produce_dag` не обязана генерировать несмещенные случайные числа, потенциальная угроза заключается в том, что `seed**i % P` принимает лишь небольшое количество значений. Это может дать преимущество майнерам, распознающим закономерность, перед теми, кто ее не распознает.
+
+Чтобы избежать этого, используется результат из теории чисел. [_Безопасное простое число_](https://en.wikipedia.org/wiki/Safe_prime) определяется как простое число `P`, такое что `(P-1)/2` также является простым числом. _Порядок_ члена `x` [мультипликативной группы](https://en.wikipedia.org/wiki/Multiplicative_group_of_integers_modulo_n) `ℤ/nℤ` определяется как минимальное `m`, такое что xᵐ mod P ≡ 1
+Учитывая эти определения, мы имеем:
+
+> Наблюдение 1. Пусть `x` — член мультипликативной группы `ℤ/Pℤ` для безопасного простого числа `P`. Если `x mod P ≠ 1 mod P` и `x mod P ≠ P-1 mod P`, то порядок `x` равен либо `P-1`, либо `(P-1)/2`.
+
+_Доказательство_. Поскольку `P` — безопасное простое число, то по [теореме Лагранжа][lagrange] мы имеем, что порядок `x` равен либо `1`, `2`, `(P-1)/2`, либо `P-1`.
+
+Порядок `x` не может быть `1`, поскольку по Малой теореме Ферма мы имеем:
+
+xP-1 mod P ≡ 1
+
+Следовательно, `x` должен быть мультипликативной единицей `ℤ/nℤ`, которая является уникальной. Поскольку мы по предположению приняли, что `x ≠ 1`, это невозможно.
+
+Порядок `x` не может быть `2`, если `x ≠ P-1`, поскольку это нарушило бы тот факт, что `P` является простым числом.
+
+Из приведенного выше утверждения мы можем заключить, что итерация `(picker * init) % P` будет иметь длину цикла не менее `(P-1)/2`. Это связано с тем, что мы выбрали `P` как безопасное простое число, приблизительно равное высокой степени двойки, а `init` находится в интервале `[2,2**256+1]`. Учитывая величину `P`, мы не должны ожидать цикла от модульного возведения в степень.
+
+Когда мы присваиваем значение первой ячейке в DAG (переменная с меткой `init`), мы вычисляем `pow(sha3(seed) + 2, 3, P)`. На первый взгляд, это не гарантирует, что результат не будет равен ни `1`, ни `P-1`. Однако, поскольку `P` является безопасным простым числом, у нас есть следующая дополнительная гарантия, которая является следствием Наблюдения 1:
+
+> Наблюдение 2. Пусть `x` — член мультипликативной группы `ℤ/Pℤ` для безопасного простого числа `P`, и пусть `w` будет натуральным числом. Если `x mod P ≠ 1 mod P` и `x mod P ≠ P-1 mod P`, а также `w mod P ≠ P-1 mod P` и `w mod P ≠ 0 mod P`, то `xʷ mod P ≠ 1 mod P` и `xʷ mod P ≠ P-1 mod P`
+
+### Модульное возведение в степень как хэш-функция {#modular-exponentiation}
+
+Для определенных значений `P` и `w` функция `pow(x, w, P)` может иметь много коллизий. Например, `pow(x,9,19)` принимает только значения `{1,18}`.
+
+Учитывая, что `P` является простым числом, подходящее `w` для хэш-функции модульного возведения в степень может быть выбрано с использованием следующего результата:
+
+> Наблюдение 3. Пусть `P` — простое число; `w` и `P-1` взаимно просты тогда и только тогда, когда для всех `a` и `b` в `ℤ/Pℤ` выполняется следующее: `aʷ mod P ≡ bʷ mod P` тогда и только тогда, когда `a mod P ≡ b mod P`
+
+Таким образом, учитывая, что `P` является простым числом, а `w` взаимно просто с `P-1`, мы имеем, что `|{pow(x, w, P) : x ∈ ℤ}| = P`, что означает, что хэш-функция имеет минимально возможную частоту коллизий.
+
+В частном случае, когда `P` является выбранным нами безопасным простым числом, `P-1` имеет только множители 1, 2, `(P-1)/2` и `P-1`. Поскольку `P` > 7, мы знаем, что 3 взаимно просто с `P-1`, следовательно, `w=3` удовлетворяет вышеприведенному утверждению.
+
+## Более эффективный алгоритм оценки на основе кэша {#cache-based-evaluation}
+
+```python
+def quick_calc(params, seed, p):
+ cache = produce_dag(params, seed, params["cache_size"])
+ return quick_calc_cached(cache, params, p)
+
+def quick_calc_cached(cache, params, p):
+ P = params["P"]
+ if p < len(cache):
+ return cache[p]
+ else:
+ x = pow(cache[0], p + 1, P)
+ for _ in range(params["k"]):
+ x ^= quick_calc_cached(cache, params, x % p)
+ return pow(x, params["w"], P)
+
+def quick_hashimoto(seed, dagsize, params, header, nonce):
+ cache = produce_dag(params, seed, params["cache_size"])
+ return quick_hashimoto_cached(cache, dagsize, params, header, nonce)
+
+def quick_hashimoto_cached(cache, dagsize, params, header, nonce):
+ m = dagsize // 2
+ mask = 2**64 - 1
+ mix = sha3(encode_int(nonce) + header)
+ for _ in range(params["accesses"]):
+ mix ^= quick_calc_cached(cache, params, m + (mix & mask) % m)
+ return dbl_sha3(mix)
+```
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md
new file mode 100644
index 00000000000..9c8466a2586
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md
@@ -0,0 +1,1021 @@
+---
+title: Ethash
+description: "Подробный обзор алгоритма Ethash."
+lang: ru
+---
+
+
+
+
+
+ Ethash был алгоритмом майнинга Ethereum с доказательством работы. Доказательство работы теперь **полностью отключено**, и Ethereum теперь защищен с помощью [доказательства владения](/developers/docs/consensus-mechanisms/pos/) . Подробнее о [Слиянии](/roadmap/merge/), [доказательстве владения](/developers/docs/consensus-mechanisms/pos/) и [стейкинге](/staking/). В этой статье много чего интересного!
+
+
+
+
+Ethash — это модифицированная версия алгоритма [Dagger-Hashimoto](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto). Алгоритм доказательства работы Ethash [требователен к памяти](https://wikipedia.org/wiki/Memory-hard_function), что, как считалось, делает его устойчивым к ASIC. В конечном итоге были разработаны Ethash ASIC, но майнинг на графическом процессоре все еще оставался жизнеспособным вариантом, пока не было отключено доказательство работы. Ethash по-прежнему используется для майнинга других монет в других не-Ethereum сетях доказательства работы.
+
+## Как работает Ethash? {#how-does-ethash-work}
+
+Требовательность к памяти достигается с помощью алгоритма доказательства работы, который требует выбора подмножеств фиксированного ресурса в зависимости от нонса и заголовка блока. Этот ресурс (размером в несколько гигабайт) называется DAG. DAG изменяется каждые 30 000 блоков, то есть в ~125-часовое окно, называемое эпохой (примерно 5,2 дня), и для его генерации требуется некоторое время. Поскольку DAG зависит только от высоты блока, его можно сгенерировать заранее, но если этого не сделать, клиенту придется дождаться окончания этого процесса, чтобы создать блок. Если клиенты не генерируют и не кэшируют DAG заранее, в сети может возникнуть значительная задержка блоков при каждом переходе между эпохами. Обратите внимание, что DAG не нужно генерировать для проверки доказательства работы, что по сути позволяет проводить проверку при низкой загрузке ЦП и небольшом объеме памяти.
+
+Общая схема работы алгоритма следующая:
+
+1. Существует **начальное значение (сид)**, которое можно вычислить для каждого блока путем сканирования заголовков блоков до этого момента.
+2. Из сида можно вычислить **псевдослучайный кэш размером 16 МБ**. Легкие клиенты хранят кэш.
+3. Из кэша мы можем сгенерировать **набор данных размером 1 ГБ** со свойством, что каждый элемент в наборе данных зависит только от небольшого числа элементов из кэша. Полные клиенты и майнеры хранят набор данных. Набор данных растет линейно со временем.
+4. Майнинг включает в себя получение случайных срезов набора данных и их совместное хэширование. Проверку можно выполнить с небольшим объемом памяти, используя кэш для восстановления необходимых частей набора данных, поэтому вам нужно хранить только кэш.
+
+Большой набор данных обновляется каждые 30 000 блоков, поэтому подавляющее большинство усилий майнера будет направлено на чтение набора данных, а не на внесение в него изменений.
+
+## Определения {#definitions}
+
+Мы используем следующие определения:
+
+```
+WORD_BYTES = 4 # байт в слове
+DATASET_BYTES_INIT = 2**30 # байт в наборе данных при генезисе
+DATASET_BYTES_GROWTH = 2**23 # прирост набора данных за эпоху
+CACHE_BYTES_INIT = 2**24 # байт в кэше при генезисе
+CACHE_BYTES_GROWTH = 2**17 # прирост кэша за эпоху
+CACHE_MULTIPLIER=1024 # Размер DAG относительно кэша
+EPOCH_LENGTH = 30000 # блоков за эпоху
+MIX_BYTES = 128 # ширина mix
+HASH_BYTES = 64 # длина хэша в байтах
+DATASET_PARENTS = 256 # количество родителей каждого элемента набора данных
+CACHE_ROUNDS = 3 # количество раундов при создании кэша
+ACCESSES = 64 # количество обращений в цикле hashimoto
+```
+
+### Использование SHA3 {#sha3}
+
+Разработка Ethereum совпала с разработкой стандарта SHA3, и в процессе стандартизации в последний момент было внесено изменение в дополнение (padding) финального алгоритма хэширования, так что хэши Ethereum
+«sha3_256» и «sha3_512» не являются стандартными хэшами SHA3, а вариантом, который в других контекстах часто называют
+«Keccak-256» и «Keccak-512». См. обсуждение, например, [здесь](https://eips.ethereum.org/EIPS/eip-1803), [здесь](http://ethereum.stackexchange.com/questions/550/which-cryptographic-hash-function-does-ethereum-use) или [здесь](http://bitcoin.stackexchange.com/questions/42055/what-is-the-approach-to-calculate-an-ethereum-address-from-a-256-bit-private-key/42057#42057).
+
+Пожалуйста, имейте это в виду, поскольку хэши "sha3" упоминаются в описании алгоритма ниже.
+
+## Параметры {#parameters}
+
+Параметры кэша и набора данных Ethash зависят от номера блока. Размеры кэша и набора данных растут линейно; однако мы всегда берем наибольшее простое число ниже линейно растущего порога, чтобы снизить риск случайных закономерностей, ведущих к циклическому поведению.
+
+```python
+def get_cache_size(block_number):
+ sz = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number // EPOCH_LENGTH)
+ sz -= HASH_BYTES
+ while not isprime(sz / HASH_BYTES):
+ sz -= 2 * HASH_BYTES
+ return sz
+
+def get_full_size(block_number):
+ sz = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number // EPOCH_LENGTH)
+ sz -= MIX_BYTES
+ while not isprime(sz / MIX_BYTES):
+ sz -= 2 * MIX_BYTES
+ return sz
+```
+
+Таблицы со значениями размеров набора данных и кэша приведены в приложении.
+
+## Генерация кэша {#cache-generation}
+
+Теперь мы определим функцию для создания кэша:
+
+```python
+def mkcache(cache_size, seed):
+ n = cache_size // HASH_BYTES
+
+ # Последовательно создаем начальный набор данных
+ o = [sha3_512(seed)]
+ for i in range(1, n):
+ o.append(sha3_512(o[-1]))
+
+ # Используем версию randmemohash с малым количеством раундов
+ for _ in range(CACHE_ROUNDS):
+ for i in range(n):
+ v = o[i][0] % n
+ o[i] = sha3_512(map(xor, o[(i-1+n) % n], o[v]))
+
+ return o
+```
+
+Процесс создания кэша включает в себя сначала последовательное заполнение 32 МБ памяти, а затем выполнение двух проходов алгоритма _RandMemoHash_ Серджио Демиана Лернера из [_«Strict Memory Hard Hashing Functions»_ (2014)](http://www.hashcash.org/papers/memohash.pdf). Результатом является набор из 524 288 64-байтовых значений.
+
+## Функция агрегирования данных {#date-aggregation-function}
+
+В некоторых случаях мы используем алгоритм, вдохновленный [хэшем FNV](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function), в качестве неассоциативной замены для XOR. Обратите внимание, что мы умножаем простое число на полный 32-битный ввод, в отличие от спецификации FNV-1, которая поочередно умножает простое число на один байт (октет).
+
+```python
+FNV_PRIME = 0x01000193
+
+def fnv(v1, v2):
+ return ((v1 * FNV_PRIME) ^ v2) % 2**32
+```
+
+Обратите внимание, что, хотя в Yellow Paper для fnv указано v1\*(FNV_PRIME ^ v2), все текущие реализации последовательно используют приведенное выше определение.
+
+## Вычисление полного набора данных {#full-dataset-calculation}
+
+Каждый 64-байтовый элемент в полном наборе данных размером 1 ГБ вычисляется следующим образом:
+
+```python
+def calc_dataset_item(cache, i):
+ n = len(cache)
+ r = HASH_BYTES // WORD_BYTES
+ # инициализируем mix
+ mix = copy.copy(cache[i % n])
+ mix[0] ^= i
+ mix = sha3_512(mix)
+ # применяем к нему fnv с большим количеством случайных узлов кэша на основе i
+ for j in range(DATASET_PARENTS):
+ cache_index = fnv(i ^ j, mix[j % r])
+ mix = map(fnv, mix, cache[cache_index % n])
+ return sha3_512(mix)
+```
+
+По сути, мы объединяем данные из 256 псевдослучайно выбранных узлов кэша и хэшируем их для вычисления узла набора данных. Затем весь набор данных генерируется с помощью:
+
+```python
+def calc_dataset(full_size, cache):
+ return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)]
+```
+
+## Основной цикл {#main-loop}
+
+Теперь мы опишем основной цикл, подобный «hashimoto», в котором мы агрегируем данные из полного набора данных, чтобы получить конечное значение для определенного заголовка и нонса. В приведенном ниже коде `header` представляет собой _хэш_ SHA3-256 от RLP-представления _усеченного_ заголовка блока, то есть заголовка, исключающего поля **mixHash** и **nonce**. `nonce` — это восемь байт 64-битного беззнакового целого числа в порядке от старшего к младшему (big-endian). Таким образом, `nonce[::-1]` — это восьмибайтовое представление этого значения в порядке от младшего к старшему (little-endian):
+
+```python
+def hashimoto(header, nonce, full_size, dataset_lookup):
+ n = full_size / HASH_BYTES
+ w = MIX_BYTES // WORD_BYTES
+ mixhashes = MIX_BYTES / HASH_BYTES
+ # объединяем header+nonce в 64-байтовый сид
+ s = sha3_512(header + nonce[::-1])
+ # начинаем mix с реплицированного s
+ mix = []
+ for _ in range(MIX_BYTES / HASH_BYTES):
+ mix.extend(s)
+ # подмешиваем случайные узлы набора данных
+ for i in range(ACCESSES):
+ p = fnv(i ^ s[0], mix[i % w]) % (n // mixhashes) * mixhashes
+ newdata = []
+ for j in range(MIX_BYTES / HASH_BYTES):
+ newdata.extend(dataset_lookup(p + j))
+ mix = map(fnv, mix, newdata)
+ # сжимаем mix
+ cmix = []
+ for i in range(0, len(mix), 4):
+ cmix.append(fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3]))
+ return {
+ "mix digest": serialize_hash(cmix),
+ "result": serialize_hash(sha3_256(s+cmix))
+ }
+
+def hashimoto_light(full_size, cache, header, nonce):
+ return hashimoto(header, nonce, full_size, lambda x: calc_dataset_item(cache, x))
+
+def hashimoto_full(full_size, dataset, header, nonce):
+ return hashimoto(header, nonce, full_size, lambda x: dataset[x])
+```
+
+По сути, мы поддерживаем «mix» шириной 128 байт, и многократно последовательно извлекаем 128 байт из полного набора данных и используем функцию `fnv` для их объединения с mix. 128 байт последовательного доступа используются для того, чтобы каждый раунд алгоритма всегда извлекал полную страницу из ОЗУ, минимизируя промахи буфера ассоциативной трансляции (TLB), которых теоретически могли бы избежать ASIC.
+
+Если результат работы этого алгоритма ниже желаемого целевого значения, то нонс считается действительным. Обратите внимание, что дополнительное применение `sha3_256` в конце гарантирует существование промежуточного нонса, который можно предоставить для доказательства того, что была проделана хотя бы небольшая работа; эта быстрая внешняя проверка PoW может использоваться для защиты от DDoS-атак. Это также служит для статистической гарантии того, что результат является несмещенным 256-битным числом.
+
+## Майнинг {#mining}
+
+Алгоритм майнинга определяется следующим образом:
+
+```python
+def mine(full_size, dataset, header, difficulty):
+ # дополняем нулями target, чтобы сравнивать с хэшем одинаковой длины
+ target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
+ from random import randint
+ nonce = randint(0, 2**64)
+ while hashimoto_full(full_size, dataset, header, nonce) > target:
+ nonce = (nonce + 1) % 2**64
+ return nonce
+```
+
+## Определение хэша сида {#seed-hash}
+
+Чтобы вычислить хэш сида, который будет использоваться для майнинга поверх данного блока, мы используем следующий алгоритм:
+
+```python
+ def get_seedhash(block):
+ s = '\x00' * 32
+ for i in range(block.number // EPOCH_LENGTH):
+ s = serialize_hash(sha3_256(s))
+ return s
+```
+
+Обратите внимание, что для бесперебойного майнинга и проверки мы рекомендуем предварительно вычислять будущие хэши сидов и наборы данных в отдельном потоке.
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Приложение {#appendix}
+
+Следующий код следует добавить в начало, если вы хотите запустить приведенную выше спецификацию на Python как код.
+
+```python
+import sha3, copy
+
+# Предполагается порядок битов от младшего к старшему (little-endian), как в архитектурах Intel
+def decode_int(s):
+ return int(s[::-1].encode('hex'), 16) if s else 0
+
+def encode_int(s):
+ a = "%x" % s
+ return '' if s == 0 else ('0' * (len(a) % 2) + a).decode('hex')[::-1]
+
+def zpad(s, length):
+ return s + '\x00' * max(0, length - len(s))
+
+def serialize_hash(h):
+ return ''.join([zpad(encode_int(x), 4) for x in h])
+
+def deserialize_hash(h):
+ return [decode_int(h[i:i+WORD_BYTES]) for i in range(0, len(h), WORD_BYTES)]
+
+def hash_words(h, sz, x):
+ if isinstance(x, list):
+ x = serialize_hash(x)
+ y = h(x)
+ return deserialize_hash(y)
+
+def serialize_cache(ds):
+ return ''.join([serialize_hash(h) for h in ds])
+
+serialize_dataset = serialize_cache
+
+# хэш-функция sha3, выводит 64 байта
+def sha3_512(x):
+ return hash_words(lambda v: sha3.sha3_512(v).digest(), 64, x)
+
+def sha3_256(x):
+ return hash_words(lambda v: sha3.sha3_256(v).digest(), 32, x)
+
+def xor(a, b):
+ return a ^ b
+
+def isprime(x):
+ for i in range(2, int(x**0.5)):
+ if x % i == 0:
+ return False
+ return True
+```
+
+### Размеры данных {#data-sizes}
+
+Следующие справочные таблицы содержат примерно 2048 табличных эпох с размерами данных и кэша.
+
+```python
+def get_datasize(block_number):
+ return data_sizes[block_number // EPOCH_LENGTH]
+
+def get_cachesize(block_number):
+ return cache_sizes[block_number // EPOCH_LENGTH]
+
+data_sizes = [
+1073739904, 1082130304, 1090514816, 1098906752, 1107293056,
+1115684224, 1124070016, 1132461952, 1140849536, 1149232768,
+1157627776, 1166013824, 1174404736, 1182786944, 1191180416,
+1199568512, 1207958912, 1216345216, 1224732032, 1233124736,
+1241513344, 1249902464, 1258290304, 1266673792, 1275067264,
+1283453312, 1291844992, 1300234112, 1308619904, 1317010048,
+1325397376, 1333787776, 1342176128, 1350561664, 1358954368,
+1367339392, 1375731584, 1384118144, 1392507008, 1400897408,
+1409284736, 1417673344, 1426062464, 1434451072, 1442839168,
+1451229056, 1459615616, 1468006016, 1476394112, 1484782976,
+1493171584, 1501559168, 1509948032, 1518337664, 1526726528,
+1535114624, 1543503488, 1551892096, 1560278656, 1568669056,
+1577056384, 1585446272, 1593831296, 1602219392, 1610610304,
+1619000192, 1627386752, 1635773824, 1644164224, 1652555648,
+1660943488, 1669332608, 1677721216, 1686109312, 1694497664,
+1702886272, 1711274624, 1719661184, 1728047744, 1736434816,
+1744829056, 1753218944, 1761606272, 1769995904, 1778382464,
+1786772864, 1795157888, 1803550592, 1811937664, 1820327552,
+1828711552, 1837102976, 1845488768, 1853879936, 1862269312,
+1870656896, 1879048064, 1887431552, 1895825024, 1904212096,
+1912601216, 1920988544, 1929379456, 1937765504, 1946156672,
+1954543232, 1962932096, 1971321728, 1979707264, 1988093056,
+1996487552, 2004874624, 2013262208, 2021653888, 2030039936,
+2038430848, 2046819968, 2055208576, 2063596672, 2071981952,
+2080373632, 2088762752, 2097149056, 2105539712, 2113928576,
+2122315136, 2130700672, 2139092608, 2147483264, 2155872128,
+2164257664, 2172642176, 2181035392, 2189426048, 2197814912,
+2206203008, 2214587264, 2222979712, 2231367808, 2239758208,
+2248145024, 2256527744, 2264922752, 2273312128, 2281701248,
+2290086272, 2298476672, 2306867072, 2315251072, 2323639168,
+2332032128, 2340420224, 2348808064, 2357196416, 2365580416,
+2373966976, 2382363008, 2390748544, 2399139968, 2407530368,
+2415918976, 2424307328, 2432695424, 2441084288, 2449472384,
+2457861248, 2466247808, 2474637184, 2483026816, 2491414144,
+2499803776, 2508191872, 2516582272, 2524970368, 2533359232,
+2541743488, 2550134144, 2558525056, 2566913408, 2575301504,
+2583686528, 2592073856, 2600467328, 2608856192, 2617240448,
+2625631616, 2634022016, 2642407552, 2650796416, 2659188352,
+2667574912, 2675965312, 2684352896, 2692738688, 2701130624,
+2709518464, 2717907328, 2726293376, 2734685056, 2743073152,
+2751462016, 2759851648, 2768232832, 2776625536, 2785017728,
+2793401984, 2801794432, 2810182016, 2818571648, 2826959488,
+2835349376, 2843734144, 2852121472, 2860514432, 2868900992,
+2877286784, 2885676928, 2894069632, 2902451584, 2910843008,
+2919234688, 2927622784, 2936011648, 2944400768, 2952789376,
+2961177728, 2969565568, 2977951616, 2986338944, 2994731392,
+3003120256, 3011508352, 3019895936, 3028287104, 3036675968,
+3045063808, 3053452928, 3061837696, 3070228352, 3078615424,
+3087003776, 3095394944, 3103782272, 3112173184, 3120562048,
+3128944768, 3137339264, 3145725056, 3154109312, 3162505088,
+3170893184, 3179280256, 3187669376, 3196056704, 3204445568,
+3212836736, 3221224064, 3229612928, 3238002304, 3246391168,
+3254778496, 3263165824, 3271556224, 3279944576, 3288332416,
+3296719232, 3305110912, 3313500032, 3321887104, 3330273152,
+3338658944, 3347053184, 3355440512, 3363827072, 3372220288,
+3380608384, 3388997504, 3397384576, 3405774208, 3414163072,
+3422551936, 3430937984, 3439328384, 3447714176, 3456104576,
+3464493952, 3472883584, 3481268864, 3489655168, 3498048896,
+3506434432, 3514826368, 3523213952, 3531603584, 3539987072,
+3548380288, 3556763264, 3565157248, 3573545344, 3581934464,
+3590324096, 3598712704, 3607098752, 3615488384, 3623877248,
+3632265856, 3640646528, 3649043584, 3657430144, 3665821568,
+3674207872, 3682597504, 3690984832, 3699367808, 3707764352,
+3716152448, 3724541056, 3732925568, 3741318016, 3749706368,
+3758091136, 3766481536, 3774872704, 3783260032, 3791650432,
+3800036224, 3808427648, 3816815488, 3825204608, 3833592704,
+3841981568, 3850370432, 3858755968, 3867147904, 3875536256,
+3883920512, 3892313728, 3900702592, 3909087872, 3917478784,
+3925868416, 3934256512, 3942645376, 3951032192, 3959422336,
+3967809152, 3976200064, 3984588416, 3992974976, 4001363584,
+4009751168, 4018141312, 4026530432, 4034911616, 4043308928,
+4051695488, 4060084352, 4068472448, 4076862848, 4085249408,
+4093640576, 4102028416, 4110413696, 4118805632, 4127194496,
+4135583104, 4143971968, 4152360832, 4160746112, 4169135744,
+4177525888, 4185912704, 4194303616, 4202691968, 4211076736,
+4219463552, 4227855488, 4236246656, 4244633728, 4253022848,
+4261412224, 4269799808, 4278184832, 4286578048, 4294962304,
+4303349632, 4311743104, 4320130432, 4328521088, 4336909184,
+4345295488, 4353687424, 4362073472, 4370458496, 4378852736,
+4387238528, 4395630208, 4404019072, 4412407424, 4420790656,
+4429182848, 4437571456, 4445962112, 4454344064, 4462738048,
+4471119232, 4479516544, 4487904128, 4496289664, 4504682368,
+4513068416, 4521459584, 4529846144, 4538232704, 4546619776,
+4555010176, 4563402112, 4571790208, 4580174464, 4588567936,
+4596957056, 4605344896, 4613734016, 4622119808, 4630511488,
+4638898816, 4647287936, 4655675264, 4664065664, 4672451968,
+4680842624, 4689231488, 4697620352, 4706007424, 4714397056,
+4722786176, 4731173248, 4739562368, 4747951744, 4756340608,
+4764727936, 4773114496, 4781504384, 4789894784, 4798283648,
+4806667648, 4815059584, 4823449472, 4831835776, 4840226176,
+4848612224, 4857003392, 4865391488, 4873780096, 4882169728,
+4890557312, 4898946944, 4907333248, 4915722368, 4924110976,
+4932499328, 4940889728, 4949276032, 4957666432, 4966054784,
+4974438016, 4982831488, 4991221376, 4999607168, 5007998848,
+5016386432, 5024763776, 5033164672, 5041544576, 5049941888,
+5058329728, 5066717056, 5075107456, 5083494272, 5091883904,
+5100273536, 5108662144, 5117048192, 5125436032, 5133827456,
+5142215296, 5150605184, 5158993024, 5167382144, 5175769472,
+5184157568, 5192543872, 5200936064, 5209324928, 5217711232,
+5226102656, 5234490496, 5242877312, 5251263872, 5259654016,
+5268040832, 5276434304, 5284819328, 5293209728, 5301598592,
+5309986688, 5318374784, 5326764416, 5335151488, 5343542144,
+5351929472, 5360319872, 5368706944, 5377096576, 5385484928,
+5393871232, 5402263424, 5410650496, 5419040384, 5427426944,
+5435816576, 5444205952, 5452594816, 5460981376, 5469367936,
+5477760896, 5486148736, 5494536832, 5502925952, 5511315328,
+5519703424, 5528089984, 5536481152, 5544869504, 5553256064,
+5561645696, 5570032768, 5578423936, 5586811264, 5595193216,
+5603585408, 5611972736, 5620366208, 5628750464, 5637143936,
+5645528192, 5653921408, 5662310272, 5670694784, 5679082624,
+5687474048, 5695864448, 5704251008, 5712641408, 5721030272,
+5729416832, 5737806208, 5746194304, 5754583936, 5762969984,
+5771358592, 5779748224, 5788137856, 5796527488, 5804911232,
+5813300608, 5821692544, 5830082176, 5838468992, 5846855552,
+5855247488, 5863636096, 5872024448, 5880411008, 5888799872,
+5897186432, 5905576832, 5913966976, 5922352768, 5930744704,
+5939132288, 5947522432, 5955911296, 5964299392, 5972688256,
+5981074304, 5989465472, 5997851008, 6006241408, 6014627968,
+6023015552, 6031408256, 6039796096, 6048185216, 6056574848,
+6064963456, 6073351808, 6081736064, 6090128768, 6098517632,
+6106906496, 6115289216, 6123680896, 6132070016, 6140459648,
+6148849024, 6157237376, 6165624704, 6174009728, 6182403712,
+6190792064, 6199176064, 6207569792, 6215952256, 6224345216,
+6232732544, 6241124224, 6249510272, 6257899136, 6266287744,
+6274676864, 6283065728, 6291454336, 6299843456, 6308232064,
+6316620928, 6325006208, 6333395584, 6341784704, 6350174848,
+6358562176, 6366951296, 6375337856, 6383729536, 6392119168,
+6400504192, 6408895616, 6417283456, 6425673344, 6434059136,
+6442444672, 6450837376, 6459223424, 6467613056, 6476004224,
+6484393088, 6492781952, 6501170048, 6509555072, 6517947008,
+6526336384, 6534725504, 6543112832, 6551500672, 6559888768,
+6568278656, 6576662912, 6585055616, 6593443456, 6601834112,
+6610219648, 6618610304, 6626999168, 6635385472, 6643777408,
+6652164224, 6660552832, 6668941952, 6677330048, 6685719424,
+6694107776, 6702493568, 6710882176, 6719274112, 6727662976,
+6736052096, 6744437632, 6752825984, 6761213824, 6769604224,
+6777993856, 6786383488, 6794770816, 6803158144, 6811549312,
+6819937664, 6828326528, 6836706176, 6845101696, 6853491328,
+6861880448, 6870269312, 6878655104, 6887046272, 6895433344,
+6903822208, 6912212864, 6920596864, 6928988288, 6937377152,
+6945764992, 6954149248, 6962544256, 6970928768, 6979317376,
+6987709312, 6996093824, 7004487296, 7012875392, 7021258624,
+7029652352, 7038038912, 7046427776, 7054818944, 7063207808,
+7071595136, 7079980928, 7088372608, 7096759424, 7105149824,
+7113536896, 7121928064, 7130315392, 7138699648, 7147092352,
+7155479168, 7163865728, 7172249984, 7180648064, 7189036672,
+7197424768, 7205810816, 7214196608, 7222589824, 7230975104,
+7239367552, 7247755904, 7256145536, 7264533376, 7272921472,
+7281308032, 7289694848, 7298088832, 7306471808, 7314864512,
+7323253888, 7331643008, 7340029568, 7348419712, 7356808832,
+7365196672, 7373585792, 7381973888, 7390362752, 7398750592,
+7407138944, 7415528576, 7423915648, 7432302208, 7440690304,
+7449080192, 7457472128, 7465860992, 7474249088, 7482635648,
+7491023744, 7499412608, 7507803008, 7516192384, 7524579968,
+7532967296, 7541358464, 7549745792, 7558134656, 7566524032,
+7574912896, 7583300992, 7591690112, 7600075136, 7608466816,
+7616854912, 7625244544, 7633629824, 7642020992, 7650410368,
+7658794112, 7667187328, 7675574912, 7683961984, 7692349568,
+7700739712, 7709130368, 7717519232, 7725905536, 7734295424,
+7742683264, 7751069056, 7759457408, 7767849088, 7776238208,
+7784626816, 7793014912, 7801405312, 7809792128, 7818179968,
+7826571136, 7834957184, 7843347328, 7851732352, 7860124544,
+7868512384, 7876902016, 7885287808, 7893679744, 7902067072,
+7910455936, 7918844288, 7927230848, 7935622784, 7944009344,
+7952400256, 7960786048, 7969176704, 7977565312, 7985953408,
+7994339968, 8002730368, 8011119488, 8019508096, 8027896192,
+8036285056, 8044674688, 8053062272, 8061448832, 8069838464,
+8078227328, 8086616704, 8095006592, 8103393664, 8111783552,
+8120171392, 8128560256, 8136949376, 8145336704, 8153726848,
+8162114944, 8170503296, 8178891904, 8187280768, 8195669632,
+8204058496, 8212444544, 8220834176, 8229222272, 8237612672,
+8246000768, 8254389376, 8262775168, 8271167104, 8279553664,
+8287944064, 8296333184, 8304715136, 8313108352, 8321497984,
+8329885568, 8338274432, 8346663296, 8355052928, 8363441536,
+8371828352, 8380217984, 8388606592, 8396996224, 8405384576,
+8413772672, 8422161536, 8430549376, 8438939008, 8447326592,
+8455715456, 8464104832, 8472492928, 8480882048, 8489270656,
+8497659776, 8506045312, 8514434944, 8522823808, 8531208832,
+8539602304, 8547990656, 8556378752, 8564768384, 8573154176,
+8581542784, 8589933952, 8598322816, 8606705024, 8615099264,
+8623487872, 8631876992, 8640264064, 8648653952, 8657040256,
+8665430656, 8673820544, 8682209152, 8690592128, 8698977152,
+8707374464, 8715763328, 8724151424, 8732540032, 8740928384,
+8749315712, 8757704576, 8766089344, 8774480768, 8782871936,
+8791260032, 8799645824, 8808034432, 8816426368, 8824812928,
+8833199488, 8841591424, 8849976448, 8858366336, 8866757248,
+8875147136, 8883532928, 8891923328, 8900306816, 8908700288,
+8917088384, 8925478784, 8933867392, 8942250368, 8950644608,
+8959032704, 8967420544, 8975809664, 8984197504, 8992584064,
+9000976256, 9009362048, 9017752448, 9026141312, 9034530688,
+9042917504, 9051307904, 9059694208, 9068084864, 9076471424,
+9084861824, 9093250688, 9101638528, 9110027648, 9118416512,
+9126803584, 9135188096, 9143581312, 9151969664, 9160356224,
+9168747136, 9177134464, 9185525632, 9193910144, 9202302848,
+9210690688, 9219079552, 9227465344, 9235854464, 9244244864,
+9252633472, 9261021824, 9269411456, 9277799296, 9286188928,
+9294574208, 9302965888, 9311351936, 9319740032, 9328131968,
+9336516736, 9344907392, 9353296768, 9361685888, 9370074752,
+9378463616, 9386849408, 9395239808, 9403629184, 9412016512,
+9420405376, 9428795008, 9437181568, 9445570688, 9453960832,
+9462346624, 9470738048, 9479121536, 9487515008, 9495903616,
+9504289664, 9512678528, 9521067904, 9529456256, 9537843584,
+9546233728, 9554621312, 9563011456, 9571398784, 9579788672,
+9588178304, 9596567168, 9604954496, 9613343104, 9621732992,
+9630121856, 9638508416, 9646898816, 9655283584, 9663675776,
+9672061312, 9680449664, 9688840064, 9697230464, 9705617536,
+9714003584, 9722393984, 9730772608, 9739172224, 9747561088,
+9755945344, 9764338816, 9772726144, 9781116544, 9789503872,
+9797892992, 9806282624, 9814670464, 9823056512, 9831439232,
+9839833984, 9848224384, 9856613504, 9865000576, 9873391232,
+9881772416, 9890162816, 9898556288, 9906940544, 9915333248,
+9923721088, 9932108672, 9940496512, 9948888448, 9957276544,
+9965666176, 9974048384, 9982441088, 9990830464, 9999219584,
+10007602816, 10015996544, 10024385152, 10032774016, 10041163648,
+10049548928, 10057940096, 10066329472, 10074717824, 10083105152,
+10091495296, 10099878784, 10108272256, 10116660608, 10125049216,
+10133437312, 10141825664, 10150213504, 10158601088, 10166991232,
+10175378816, 10183766144, 10192157312, 10200545408, 10208935552,
+10217322112, 10225712768, 10234099328, 10242489472, 10250876032,
+10259264896, 10267656064, 10276042624, 10284429184, 10292820352,
+10301209472, 10309598848, 10317987712, 10326375296, 10334763392,
+10343153536, 10351541632, 10359930752, 10368318592, 10376707456,
+10385096576, 10393484672, 10401867136, 10410262144, 10418647424,
+10427039104, 10435425664, 10443810176, 10452203648, 10460589952,
+10468982144, 10477369472, 10485759104, 10494147712, 10502533504,
+10510923392, 10519313536, 10527702656, 10536091264, 10544478592,
+10552867712, 10561255808, 10569642368, 10578032768, 10586423168,
+10594805632, 10603200128, 10611588992, 10619976064, 10628361344,
+10636754048, 10645143424, 10653531776, 10661920384, 10670307968,
+10678696832, 10687086464, 10695475072, 10703863168, 10712246144,
+10720639616, 10729026688, 10737414784, 10745806208, 10754190976,
+10762581376, 10770971264, 10779356288, 10787747456, 10796135552,
+10804525184, 10812915584, 10821301888, 10829692288, 10838078336,
+10846469248, 10854858368, 10863247232, 10871631488, 10880023424,
+10888412032, 10896799616, 10905188992, 10913574016, 10921964672,
+10930352768, 10938742912, 10947132544, 10955518592, 10963909504,
+10972298368, 10980687488, 10989074816, 10997462912, 11005851776,
+11014241152, 11022627712, 11031017344, 11039403904, 11047793024,
+11056184704, 11064570752, 11072960896, 11081343872, 11089737856,
+11098128256, 11106514816, 11114904448, 11123293568, 11131680128,
+11140065152, 11148458368, 11156845696, 11165236864, 11173624192,
+11182013824, 11190402688, 11198790784, 11207179136, 11215568768,
+11223957376, 11232345728, 11240734592, 11249122688, 11257511296,
+11265899648, 11274285952, 11282675584, 11291065472, 11299452544,
+11307842432, 11316231296, 11324616832, 11333009024, 11341395584,
+11349782656, 11358172288, 11366560384, 11374950016, 11383339648,
+11391721856, 11400117376, 11408504192, 11416893568, 11425283456,
+11433671552, 11442061184, 11450444672, 11458837888, 11467226752,
+11475611776, 11484003968, 11492392064, 11500780672, 11509169024,
+11517550976, 11525944448, 11534335616, 11542724224, 11551111808,
+11559500672, 11567890304, 11576277376, 11584667008, 11593056128,
+11601443456, 11609830016, 11618221952, 11626607488, 11634995072,
+11643387776, 11651775104, 11660161664, 11668552576, 11676940928,
+11685330304, 11693718656, 11702106496, 11710496128, 11718882688,
+11727273088, 11735660416, 11744050048, 11752437376, 11760824704,
+11769216128, 11777604736, 11785991296, 11794381952, 11802770048,
+11811157888, 11819548544, 11827932544, 11836324736, 11844713344,
+11853100928, 11861486464, 11869879936, 11878268032, 11886656896,
+11895044992, 11903433088, 11911822976, 11920210816, 11928600448,
+11936987264, 11945375872, 11953761152, 11962151296, 11970543488,
+11978928512, 11987320448, 11995708288, 12004095104, 12012486272,
+12020875136, 12029255552, 12037652096, 12046039168, 12054429568,
+12062813824, 12071206528, 12079594624, 12087983744, 12096371072,
+12104759936, 12113147264, 12121534592, 12129924992, 12138314624,
+12146703232, 12155091584, 12163481216, 12171864704, 12180255872,
+12188643968, 12197034112, 12205424512, 12213811328, 12222199424,
+12230590336, 12238977664, 12247365248, 12255755392, 12264143488,
+12272531584, 12280920448, 12289309568, 12297694592, 12306086528,
+12314475392, 12322865024, 12331253632, 12339640448, 12348029312,
+12356418944, 12364805248, 12373196672, 12381580928, 12389969024,
+12398357632, 12406750592, 12415138432, 12423527552, 12431916416,
+12440304512, 12448692352, 12457081216, 12465467776, 12473859968,
+12482245504, 12490636672, 12499025536, 12507411584, 12515801728,
+12524190592, 12532577152, 12540966272, 12549354368, 12557743232,
+12566129536, 12574523264, 12582911872, 12591299456, 12599688064,
+12608074624, 12616463488, 12624845696, 12633239936, 12641631616,
+12650019968, 12658407296, 12666795136, 12675183232, 12683574656,
+12691960192, 12700350592, 12708740224, 12717128576, 12725515904,
+12733906816, 12742295168, 12750680192, 12759071872, 12767460736,
+12775848832, 12784236928, 12792626816, 12801014656, 12809404288,
+12817789312, 12826181504, 12834568832, 12842954624, 12851345792,
+12859732352, 12868122496, 12876512128, 12884901248, 12893289088,
+12901672832, 12910067584, 12918455168, 12926842496, 12935232896,
+12943620736, 12952009856, 12960396928, 12968786816, 12977176192,
+12985563776, 12993951104, 13002341504, 13010730368, 13019115392,
+13027506304, 13035895168, 13044272512, 13052673152, 13061062528,
+13069446272, 13077838976, 13086227072, 13094613632, 13103000192,
+13111393664, 13119782528, 13128157568, 13136559232, 13144945024,
+13153329536, 13161724288, 13170111872, 13178502784, 13186884736,
+13195279744, 13203667072, 13212057472, 13220445824, 13228832128,
+13237221248, 13245610624, 13254000512, 13262388352, 13270777472,
+13279166336, 13287553408, 13295943296, 13304331904, 13312719488,
+13321108096, 13329494656, 13337885824, 13346274944, 13354663808,
+13363051136, 13371439232, 13379825024, 13388210816, 13396605056,
+13404995456, 13413380224, 13421771392, 13430159744, 13438546048,
+13446937216, 13455326848, 13463708288, 13472103808, 13480492672,
+13488875648, 13497269888, 13505657728, 13514045312, 13522435712,
+13530824576, 13539210112, 13547599232, 13555989376, 13564379008,
+13572766336, 13581154432, 13589544832, 13597932928, 13606320512,
+13614710656, 13623097472, 13631477632, 13639874944, 13648264064,
+13656652928, 13665041792, 13673430656, 13681818496, 13690207616,
+13698595712, 13706982272, 13715373184, 13723762048, 13732150144,
+13740536704, 13748926592, 13757316224, 13765700992, 13774090112,
+13782477952, 13790869376, 13799259008, 13807647872, 13816036736,
+13824425344, 13832814208, 13841202304, 13849591424, 13857978752,
+13866368896, 13874754688, 13883145344, 13891533184, 13899919232,
+13908311168, 13916692096, 13925085056, 13933473152, 13941866368,
+13950253696, 13958643584, 13967032192, 13975417216, 13983807616,
+13992197504, 14000582272, 14008973696, 14017363072, 14025752192,
+14034137984, 14042528384, 14050918016, 14059301504, 14067691648,
+14076083584, 14084470144, 14092852352, 14101249664, 14109635968,
+14118024832, 14126407552, 14134804352, 14143188608, 14151577984,
+14159968384, 14168357248, 14176741504, 14185127296, 14193521024,
+14201911424, 14210301824, 14218685056, 14227067264, 14235467392,
+14243855488, 14252243072, 14260630144, 14269021568, 14277409408,
+14285799296, 14294187904, 14302571392, 14310961792, 14319353728,
+14327738752, 14336130944, 14344518784, 14352906368, 14361296512,
+14369685376, 14378071424, 14386462592, 14394848128, 14403230848,
+14411627392, 14420013952, 14428402304, 14436793472, 14445181568,
+14453569664, 14461959808, 14470347904, 14478737024, 14487122816,
+14495511424, 14503901824, 14512291712, 14520677504, 14529064832,
+14537456768, 14545845632, 14554234496, 14562618496, 14571011456,
+14579398784, 14587789184, 14596172672, 14604564608, 14612953984,
+14621341312, 14629724288, 14638120832, 14646503296, 14654897536,
+14663284864, 14671675264, 14680061056, 14688447616, 14696835968,
+14705228416, 14713616768, 14722003328, 14730392192, 14738784128,
+14747172736, 14755561088, 14763947648, 14772336512, 14780725376,
+14789110144, 14797499776, 14805892736, 14814276992, 14822670208,
+14831056256, 14839444352, 14847836032, 14856222848, 14864612992,
+14872997504, 14881388672, 14889775744, 14898165376, 14906553472,
+14914944896, 14923329664, 14931721856, 14940109696, 14948497024,
+14956887424, 14965276544, 14973663616, 14982053248, 14990439808,
+14998830976, 15007216768, 15015605888, 15023995264, 15032385152,
+15040768384, 15049154944, 15057549184, 15065939072, 15074328448,
+15082715008, 15091104128, 15099493504, 15107879296, 15116269184,
+15124659584, 15133042304, 15141431936, 15149824384, 15158214272,
+15166602368, 15174991232, 15183378304, 15191760512, 15200154496,
+15208542592, 15216931712, 15225323392, 15233708416, 15242098048,
+15250489216, 15258875264, 15267265408, 15275654528, 15284043136,
+15292431488, 15300819584, 15309208192, 15317596544, 15325986176,
+15334374784, 15342763648, 15351151744, 15359540608, 15367929728,
+15376318336, 15384706432, 15393092992, 15401481856, 15409869952,
+15418258816, 15426649984, 15435037568, 15443425664, 15451815296,
+15460203392, 15468589184, 15476979328, 15485369216, 15493755776,
+15502146944, 15510534272, 15518924416, 15527311232, 15535699072,
+15544089472, 15552478336, 15560866688, 15569254528, 15577642624,
+15586031488, 15594419072, 15602809472, 15611199104, 15619586432,
+15627975296, 15636364928, 15644753792, 15653141888, 15661529216,
+15669918848, 15678305152, 15686696576, 15695083136, 15703474048,
+15711861632, 15720251264, 15728636288, 15737027456, 15745417088,
+15753804928, 15762194048, 15770582656, 15778971008, 15787358336,
+15795747712, 15804132224, 15812523392, 15820909696, 15829300096,
+15837691264, 15846071936, 15854466944, 15862855808, 15871244672,
+15879634816, 15888020608, 15896409728, 15904799104, 15913185152,
+15921577088, 15929966464, 15938354816, 15946743424, 15955129472,
+15963519872, 15971907968, 15980296064, 15988684928, 15997073024,
+16005460864, 16013851264, 16022241152, 16030629248, 16039012736,
+16047406976, 16055794816, 16064181376, 16072571264, 16080957824,
+16089346688, 16097737856, 16106125184, 16114514816, 16122904192,
+16131292544, 16139678848, 16148066944, 16156453504, 16164839552,
+16173236096, 16181623424, 16190012032, 16198401152, 16206790528,
+16215177344, 16223567744, 16231956352, 16240344704, 16248731008,
+16257117824, 16265504384, 16273898624, 16282281856, 16290668672,
+16299064192, 16307449216, 16315842176, 16324230016, 16332613504,
+16341006464, 16349394304, 16357783168, 16366172288, 16374561664,
+16382951296, 16391337856, 16399726208, 16408116352, 16416505472,
+16424892032, 16433282176, 16441668224, 16450058624, 16458448768,
+16466836864, 16475224448, 16483613056, 16492001408, 16500391808,
+16508779648, 16517166976, 16525555328, 16533944192, 16542330752,
+16550719616, 16559110528, 16567497088, 16575888512, 16584274816,
+16592665472, 16601051008, 16609442944, 16617832064, 16626218624,
+16634607488, 16642996096, 16651385728, 16659773824, 16668163712,
+16676552576, 16684938112, 16693328768, 16701718144, 16710095488,
+16718492288, 16726883968, 16735272832, 16743661184, 16752049792,
+16760436608, 16768827008, 16777214336, 16785599104, 16793992832,
+16802381696, 16810768768, 16819151744, 16827542656, 16835934848,
+16844323712, 16852711552, 16861101952, 16869489536, 16877876864,
+16886265728, 16894653056, 16903044736, 16911431296, 16919821696,
+16928207488, 16936592768, 16944987776, 16953375616, 16961763968,
+16970152832, 16978540928, 16986929536, 16995319168, 17003704448,
+17012096896, 17020481152, 17028870784, 17037262208, 17045649536,
+17054039936, 17062426496, 17070814336, 17079205504, 17087592064,
+17095978112, 17104369024, 17112759424, 17121147776, 17129536384,
+17137926016, 17146314368, 17154700928, 17163089792, 17171480192,
+17179864192, 17188256896, 17196644992, 17205033856, 17213423488,
+17221811072, 17230198912, 17238588032, 17246976896, 17255360384,
+17263754624, 17272143232, 17280530048, 17288918912, 17297309312,
+17305696384, 17314085504, 17322475136, 17330863744, 17339252096,
+17347640192, 17356026496, 17364413824, 17372796544, 17381190016,
+17389583488, 17397972608, 17406360704, 17414748544, 17423135872,
+17431527296, 17439915904, 17448303232, 17456691584, 17465081728,
+17473468288, 17481857408, 17490247552, 17498635904, 17507022464,
+17515409024, 17523801728, 17532189824, 17540577664, 17548966016,
+17557353344, 17565741184, 17574131584, 17582519168, 17590907008,
+17599296128, 17607687808, 17616076672, 17624455808, 17632852352,
+17641238656, 17649630848, 17658018944, 17666403968, 17674794112,
+17683178368, 17691573376, 17699962496, 17708350592, 17716739968,
+17725126528, 17733517184, 17741898112, 17750293888, 17758673024,
+17767070336, 17775458432, 17783848832, 17792236928, 17800625536,
+17809012352, 17817402752, 17825785984, 17834178944, 17842563968,
+17850955648, 17859344512, 17867732864, 17876119424, 17884511872,
+17892900224, 17901287296, 17909677696, 17918058112, 17926451072,
+17934843776, 17943230848, 17951609216, 17960008576, 17968397696,
+17976784256, 17985175424, 17993564032, 18001952128, 18010339712,
+18018728576, 18027116672, 18035503232, 18043894144, 18052283264,
+18060672128, 18069056384, 18077449856, 18085837184, 18094225792,
+18102613376, 18111004544, 18119388544, 18127781248, 18136170368,
+18144558976, 18152947328, 18161336192, 18169724288, 18178108544,
+18186498944, 18194886784, 18203275648, 18211666048, 18220048768,
+18228444544, 18236833408, 18245220736]
+
+cache_sizes = [
+16776896, 16907456, 17039296, 17170112, 17301056, 17432512, 17563072,
+17693888, 17824192, 17955904, 18087488, 18218176, 18349504, 18481088,
+18611392, 18742336, 18874304, 19004224, 19135936, 19267264, 19398208,
+19529408, 19660096, 19791424, 19922752, 20053952, 20184896, 20315968,
+20446912, 20576576, 20709184, 20840384, 20971072, 21102272, 21233216,
+21364544, 21494848, 21626816, 21757376, 21887552, 22019392, 22151104,
+22281536, 22412224, 22543936, 22675264, 22806464, 22935872, 23068096,
+23198272, 23330752, 23459008, 23592512, 23723968, 23854912, 23986112,
+24116672, 24247616, 24378688, 24509504, 24640832, 24772544, 24903488,
+25034432, 25165376, 25296704, 25427392, 25558592, 25690048, 25820096,
+25951936, 26081728, 26214208, 26345024, 26476096, 26606656, 26737472,
+26869184, 26998208, 27131584, 27262528, 27393728, 27523904, 27655744,
+27786688, 27917888, 28049344, 28179904, 28311488, 28441792, 28573504,
+28700864, 28835648, 28966208, 29096768, 29228608, 29359808, 29490752,
+29621824, 29752256, 29882816, 30014912, 30144448, 30273728, 30406976,
+30538432, 30670784, 30799936, 30932672, 31063744, 31195072, 31325248,
+31456192, 31588288, 31719232, 31850432, 31981504, 32110784, 32243392,
+32372672, 32505664, 32636608, 32767808, 32897344, 33029824, 33160768,
+33289664, 33423296, 33554368, 33683648, 33816512, 33947456, 34076992,
+34208704, 34340032, 34471744, 34600256, 34734016, 34864576, 34993984,
+35127104, 35258176, 35386688, 35518528, 35650624, 35782336, 35910976,
+36044608, 36175808, 36305728, 36436672, 36568384, 36699968, 36830656,
+36961984, 37093312, 37223488, 37355072, 37486528, 37617472, 37747904,
+37879232, 38009792, 38141888, 38272448, 38403392, 38535104, 38660672,
+38795584, 38925632, 39059264, 39190336, 39320768, 39452096, 39581632,
+39713984, 39844928, 39974848, 40107968, 40238144, 40367168, 40500032,
+40631744, 40762816, 40894144, 41023552, 41155904, 41286208, 41418304,
+41547712, 41680448, 41811904, 41942848, 42073792, 42204992, 42334912,
+42467008, 42597824, 42729152, 42860096, 42991552, 43122368, 43253696,
+43382848, 43515712, 43646912, 43777088, 43907648, 44039104, 44170432,
+44302144, 44433344, 44564288, 44694976, 44825152, 44956864, 45088448,
+45219008, 45350464, 45481024, 45612608, 45744064, 45874496, 46006208,
+46136768, 46267712, 46399424, 46529344, 46660672, 46791488, 46923328,
+47053504, 47185856, 47316928, 47447872, 47579072, 47710144, 47839936,
+47971648, 48103232, 48234176, 48365248, 48496192, 48627136, 48757312,
+48889664, 49020736, 49149248, 49283008, 49413824, 49545152, 49675712,
+49807168, 49938368, 50069056, 50200256, 50331584, 50462656, 50593472,
+50724032, 50853952, 50986048, 51117632, 51248576, 51379904, 51510848,
+51641792, 51773248, 51903296, 52035136, 52164032, 52297664, 52427968,
+52557376, 52690112, 52821952, 52952896, 53081536, 53213504, 53344576,
+53475776, 53608384, 53738816, 53870528, 54000832, 54131776, 54263744,
+54394688, 54525248, 54655936, 54787904, 54918592, 55049152, 55181248,
+55312064, 55442752, 55574336, 55705024, 55836224, 55967168, 56097856,
+56228672, 56358592, 56490176, 56621888, 56753728, 56884928, 57015488,
+57146816, 57278272, 57409216, 57540416, 57671104, 57802432, 57933632,
+58064576, 58195264, 58326976, 58457408, 58588864, 58720192, 58849984,
+58981696, 59113024, 59243456, 59375552, 59506624, 59637568, 59768512,
+59897792, 60030016, 60161984, 60293056, 60423872, 60554432, 60683968,
+60817216, 60948032, 61079488, 61209664, 61341376, 61471936, 61602752,
+61733696, 61865792, 61996736, 62127808, 62259136, 62389568, 62520512,
+62651584, 62781632, 62910784, 63045056, 63176128, 63307072, 63438656,
+63569216, 63700928, 63831616, 63960896, 64093888, 64225088, 64355392,
+64486976, 64617664, 64748608, 64879424, 65009216, 65142464, 65273792,
+65402816, 65535424, 65666752, 65797696, 65927744, 66060224, 66191296,
+66321344, 66453056, 66584384, 66715328, 66846656, 66977728, 67108672,
+67239104, 67370432, 67501888, 67631296, 67763776, 67895104, 68026304,
+68157248, 68287936, 68419264, 68548288, 68681408, 68811968, 68942912,
+69074624, 69205568, 69337024, 69467584, 69599168, 69729472, 69861184,
+69989824, 70122944, 70253888, 70385344, 70515904, 70647232, 70778816,
+70907968, 71040832, 71171648, 71303104, 71432512, 71564992, 71695168,
+71826368, 71958464, 72089536, 72219712, 72350144, 72482624, 72613568,
+72744512, 72875584, 73006144, 73138112, 73268672, 73400128, 73530944,
+73662272, 73793344, 73924544, 74055104, 74185792, 74316992, 74448832,
+74579392, 74710976, 74841664, 74972864, 75102784, 75233344, 75364544,
+75497024, 75627584, 75759296, 75890624, 76021696, 76152256, 76283072,
+76414144, 76545856, 76676672, 76806976, 76937792, 77070016, 77200832,
+77331392, 77462464, 77593664, 77725376, 77856448, 77987776, 78118336,
+78249664, 78380992, 78511424, 78642496, 78773056, 78905152, 79033664,
+79166656, 79297472, 79429568, 79560512, 79690816, 79822784, 79953472,
+80084672, 80214208, 80346944, 80477632, 80608576, 80740288, 80870848,
+81002048, 81133504, 81264448, 81395648, 81525952, 81657536, 81786304,
+81919808, 82050112, 82181312, 82311616, 82443968, 82573376, 82705984,
+82835776, 82967744, 83096768, 83230528, 83359552, 83491264, 83622464,
+83753536, 83886016, 84015296, 84147776, 84277184, 84409792, 84540608,
+84672064, 84803008, 84934336, 85065152, 85193792, 85326784, 85458496,
+85589312, 85721024, 85851968, 85982656, 86112448, 86244416, 86370112,
+86506688, 86637632, 86769344, 86900672, 87031744, 87162304, 87293632,
+87424576, 87555392, 87687104, 87816896, 87947968, 88079168, 88211264,
+88341824, 88473152, 88603712, 88735424, 88862912, 88996672, 89128384,
+89259712, 89390272, 89521984, 89652544, 89783872, 89914816, 90045376,
+90177088, 90307904, 90438848, 90569152, 90700096, 90832832, 90963776,
+91093696, 91223744, 91356992, 91486784, 91618496, 91749824, 91880384,
+92012224, 92143552, 92273344, 92405696, 92536768, 92666432, 92798912,
+92926016, 93060544, 93192128, 93322816, 93453632, 93583936, 93715136,
+93845056, 93977792, 94109504, 94240448, 94371776, 94501184, 94632896,
+94764224, 94895552, 95023424, 95158208, 95287744, 95420224, 95550016,
+95681216, 95811904, 95943872, 96075328, 96203584, 96337856, 96468544,
+96599744, 96731072, 96860992, 96992576, 97124288, 97254848, 97385536,
+97517248, 97647808, 97779392, 97910464, 98041408, 98172608, 98303168,
+98434496, 98565568, 98696768, 98827328, 98958784, 99089728, 99220928,
+99352384, 99482816, 99614272, 99745472, 99876416, 100007104,
+100138048, 100267072, 100401088, 100529984, 100662592, 100791872,
+100925248, 101056064, 101187392, 101317952, 101449408, 101580608,
+101711296, 101841728, 101973824, 102104896, 102235712, 102366016,
+102498112, 102628672, 102760384, 102890432, 103021888, 103153472,
+103284032, 103415744, 103545152, 103677248, 103808576, 103939648,
+104070976, 104201792, 104332736, 104462528, 104594752, 104725952,
+104854592, 104988608, 105118912, 105247808, 105381184, 105511232,
+105643072, 105774784, 105903296, 106037056, 106167872, 106298944,
+106429504, 106561472, 106691392, 106822592, 106954304, 107085376,
+107216576, 107346368, 107478464, 107609792, 107739712, 107872192,
+108003136, 108131392, 108265408, 108396224, 108527168, 108657344,
+108789568, 108920384, 109049792, 109182272, 109312576, 109444928,
+109572928, 109706944, 109837888, 109969088, 110099648, 110230976,
+110362432, 110492992, 110624704, 110755264, 110886208, 111017408,
+111148864, 111279296, 111410752, 111541952, 111673024, 111803456,
+111933632, 112066496, 112196416, 112328512, 112457792, 112590784,
+112715968, 112852672, 112983616, 113114944, 113244224, 113376448,
+113505472, 113639104, 113770304, 113901376, 114031552, 114163264,
+114294592, 114425536, 114556864, 114687424, 114818624, 114948544,
+115080512, 115212224, 115343296, 115473472, 115605184, 115736128,
+115867072, 115997248, 116128576, 116260288, 116391488, 116522944,
+116652992, 116784704, 116915648, 117046208, 117178304, 117308608,
+117440192, 117569728, 117701824, 117833024, 117964096, 118094656,
+118225984, 118357312, 118489024, 118617536, 118749632, 118882112,
+119012416, 119144384, 119275328, 119406016, 119537344, 119668672,
+119798464, 119928896, 120061376, 120192832, 120321728, 120454336,
+120584512, 120716608, 120848192, 120979136, 121109056, 121241408,
+121372352, 121502912, 121634752, 121764416, 121895744, 122027072,
+122157632, 122289088, 122421184, 122550592, 122682944, 122813888,
+122945344, 123075776, 123207488, 123338048, 123468736, 123600704,
+123731264, 123861952, 123993664, 124124608, 124256192, 124386368,
+124518208, 124649024, 124778048, 124911296, 125041088, 125173696,
+125303744, 125432896, 125566912, 125696576, 125829056, 125958592,
+126090304, 126221248, 126352832, 126483776, 126615232, 126746432,
+126876608, 127008704, 127139392, 127270336, 127401152, 127532224,
+127663552, 127794752, 127925696, 128055232, 128188096, 128319424,
+128449856, 128581312, 128712256, 128843584, 128973632, 129103808,
+129236288, 129365696, 129498944, 129629888, 129760832, 129892288,
+130023104, 130154048, 130283968, 130416448, 130547008, 130678336,
+130807616, 130939456, 131071552, 131202112, 131331776, 131464384,
+131594048, 131727296, 131858368, 131987392, 132120256, 132250816,
+132382528, 132513728, 132644672, 132774976, 132905792, 133038016,
+133168832, 133299392, 133429312, 133562048, 133692992, 133823296,
+133954624, 134086336, 134217152, 134348608, 134479808, 134607296,
+134741056, 134872384, 135002944, 135134144, 135265472, 135396544,
+135527872, 135659072, 135787712, 135921472, 136052416, 136182848,
+136313792, 136444864, 136576448, 136707904, 136837952, 136970048,
+137099584, 137232064, 137363392, 137494208, 137625536, 137755712,
+137887424, 138018368, 138149824, 138280256, 138411584, 138539584,
+138672832, 138804928, 138936128, 139066688, 139196864, 139328704,
+139460032, 139590208, 139721024, 139852864, 139984576, 140115776,
+140245696, 140376512, 140508352, 140640064, 140769856, 140902336,
+141032768, 141162688, 141294016, 141426496, 141556544, 141687488,
+141819584, 141949888, 142080448, 142212544, 142342336, 142474432,
+142606144, 142736192, 142868288, 142997824, 143129408, 143258944,
+143392448, 143523136, 143653696, 143785024, 143916992, 144045632,
+144177856, 144309184, 144440768, 144570688, 144701888, 144832448,
+144965056, 145096384, 145227584, 145358656, 145489856, 145620928,
+145751488, 145883072, 146011456, 146144704, 146275264, 146407232,
+146538176, 146668736, 146800448, 146931392, 147062336, 147193664,
+147324224, 147455936, 147586624, 147717056, 147848768, 147979456,
+148110784, 148242368, 148373312, 148503232, 148635584, 148766144,
+148897088, 149028416, 149159488, 149290688, 149420224, 149551552,
+149683136, 149814976, 149943616, 150076352, 150208064, 150338624,
+150470464, 150600256, 150732224, 150862784, 150993088, 151125952,
+151254976, 151388096, 151519168, 151649728, 151778752, 151911104,
+152042944, 152174144, 152304704, 152435648, 152567488, 152698816,
+152828992, 152960576, 153091648, 153222976, 153353792, 153484096,
+153616192, 153747008, 153878336, 154008256, 154139968, 154270912,
+154402624, 154533824, 154663616, 154795712, 154926272, 155057984,
+155188928, 155319872, 155450816, 155580608, 155712064, 155843392,
+155971136, 156106688, 156237376, 156367424, 156499264, 156630976,
+156761536, 156892352, 157024064, 157155008, 157284416, 157415872,
+157545536, 157677248, 157810496, 157938112, 158071744, 158203328,
+158334656, 158464832, 158596288, 158727616, 158858048, 158988992,
+159121216, 159252416, 159381568, 159513152, 159645632, 159776192,
+159906496, 160038464, 160169536, 160300352, 160430656, 160563008,
+160693952, 160822208, 160956352, 161086784, 161217344, 161349184,
+161480512, 161611456, 161742272, 161873216, 162002752, 162135872,
+162266432, 162397888, 162529216, 162660032, 162790976, 162922048,
+163052096, 163184576, 163314752, 163446592, 163577408, 163707968,
+163839296, 163969984, 164100928, 164233024, 164364224, 164494912,
+164625856, 164756672, 164887616, 165019072, 165150016, 165280064,
+165412672, 165543104, 165674944, 165805888, 165936832, 166067648,
+166198336, 166330048, 166461248, 166591552, 166722496, 166854208,
+166985408, 167116736, 167246656, 167378368, 167508416, 167641024,
+167771584, 167903168, 168034112, 168164032, 168295744, 168427456,
+168557632, 168688448, 168819136, 168951616, 169082176, 169213504,
+169344832, 169475648, 169605952, 169738048, 169866304, 16999552,
+170131264, 170262464, 170393536, 170524352, 170655424, 170782016,
+170917696, 171048896, 171179072, 171310784, 171439936, 171573184,
+171702976, 171835072, 171966272, 172097216, 172228288, 172359232,
+172489664, 172621376, 172747712, 172883264, 173014208, 173144512,
+173275072, 173407424, 173539136, 173669696, 173800768, 173931712,
+174063424, 174193472, 174325696, 174455744, 174586816, 174718912,
+174849728, 174977728, 175109696, 175242688, 175374272, 175504832,
+175636288, 175765696, 175898432, 176028992, 176159936, 176291264,
+176422592, 176552512, 176684864, 176815424, 176946496, 177076544,
+177209152, 177340096, 177470528, 177600704, 177731648, 177864256,
+177994816, 178126528, 178257472, 178387648, 178518464, 178650176,
+178781888, 178912064, 179044288, 179174848, 179305024, 179436736,
+179568448, 179698496, 179830208, 179960512, 180092608, 180223808,
+180354752, 180485696, 180617152, 180748096, 180877504, 181009984,
+181139264, 181272512, 181402688, 181532608, 181663168, 181795136,
+181926592, 182057536, 182190016, 182320192, 182451904, 182582336,
+182713792, 182843072, 182976064, 183107264, 183237056, 183368384,
+183494848, 183631424, 183762752, 183893824, 184024768, 184154816,
+184286656, 184417984, 184548928, 184680128, 184810816, 184941248,
+185072704, 185203904, 185335616, 185465408, 185596352, 185727296,
+185859904, 185989696, 186121664, 186252992, 186383552, 186514112,
+186645952, 186777152, 186907328, 187037504, 187170112, 187301824,
+187429184, 187562048, 187693504, 187825472, 187957184, 188087104,
+188218304, 188349376, 188481344, 188609728, 188743616, 188874304,
+189005248, 189136448, 189265088, 189396544, 189528128, 189660992,
+189791936, 189923264, 190054208, 190182848, 190315072, 190447424,
+190577984, 190709312, 190840768, 190971328, 191102656, 191233472,
+191364032, 191495872, 191626816, 191758016, 191888192, 192020288,
+192148928, 192282176, 192413504, 192542528, 192674752, 192805952,
+192937792, 193068608, 193198912, 193330496, 193462208, 193592384,
+193723456, 193854272, 193985984, 194116672, 194247232, 194379712,
+194508352, 194641856, 194772544, 194900672, 195035072, 195166016,
+195296704, 195428032, 195558592, 195690304, 195818176, 195952576,
+196083392, 196214336, 196345792, 196476736, 196607552, 196739008,
+196869952, 197000768, 197130688, 197262784, 197394368, 197523904,
+197656384, 197787584, 197916608, 198049472, 198180544, 198310208,
+198442432, 198573632, 198705088, 198834368, 198967232, 199097792,
+199228352, 199360192, 199491392, 199621696, 199751744, 199883968,
+200014016, 200146624, 200276672, 200408128, 200540096, 200671168,
+200801984, 200933312, 201062464, 201194944, 201326144, 201457472,
+201588544, 201719744, 201850816, 201981632, 202111552, 202244032,
+202374464, 202505152, 202636352, 202767808, 202898368, 203030336,
+203159872, 203292608, 203423296, 203553472, 203685824, 203816896,
+203947712, 204078272, 204208192, 204341056, 204472256, 204603328,
+204733888, 204864448, 204996544, 205125568, 205258304, 205388864,
+205517632, 205650112, 205782208, 205913536, 206044736, 206176192,
+206307008, 206434496, 206569024, 206700224, 206831168, 206961856,
+207093056, 207223616, 207355328, 207486784, 207616832, 207749056,
+207879104, 208010048, 208141888, 208273216, 208404032, 208534336,
+208666048, 208796864, 208927424, 209059264, 209189824, 209321792,
+209451584, 209582656, 209715136, 209845568, 209976896, 210106432,
+210239296, 210370112, 210501568, 210630976, 210763712, 210894272,
+211024832, 211156672, 211287616, 211418176, 211549376, 211679296,
+211812032, 211942592, 212074432, 212204864, 212334016, 212467648,
+212597824, 212727616, 212860352, 212991424, 213120832, 213253952,
+213385024, 213515584, 213645632, 213777728, 213909184, 214040128,
+214170688, 214302656, 214433728, 214564544, 214695232, 214826048,
+214956992, 215089088, 215219776, 215350592, 215482304, 215613248,
+215743552, 215874752, 216005312, 216137024, 216267328, 216399296,
+216530752, 216661696, 216790592, 216923968, 217054528, 217183168,
+217316672, 217448128, 217579072, 217709504, 217838912, 217972672,
+218102848, 218233024, 218364736, 218496832, 218627776, 218759104,
+218888896, 219021248, 219151936, 219281728, 219413056, 219545024,
+219675968, 219807296, 219938624, 220069312, 220200128, 220331456,
+220461632, 220592704, 220725184, 220855744, 220987072, 221117888,
+221249216, 221378368, 221510336, 221642048, 221772736, 221904832,
+222031808, 222166976, 222297536, 222428992, 222559936, 222690368,
+222820672, 222953152, 223083968, 223213376, 223345984, 223476928,
+223608512, 223738688, 223869376, 224001472, 224132672, 224262848,
+224394944, 224524864, 224657344, 224788288, 224919488, 225050432,
+225181504, 225312704, 225443776, 225574592, 225704768, 225834176,
+225966784, 226097216, 226229824, 226360384, 226491712, 226623424,
+226754368, 226885312, 227015104, 227147456, 227278528, 227409472,
+227539904, 227669696, 227802944, 227932352, 228065216, 228196288,
+228326464, 228457792, 228588736, 228720064, 228850112, 228981056,
+229113152, 229243328, 229375936, 229505344, 229636928, 229769152,
+229894976, 230030272, 230162368, 230292416, 230424512, 230553152,
+230684864, 230816704, 230948416, 231079616, 231210944, 231342016,
+231472448, 231603776, 231733952, 231866176, 231996736, 232127296,
+232259392, 232388672, 232521664, 232652608, 232782272, 232914496,
+233043904, 233175616, 233306816, 233438528, 233569984, 233699776,
+233830592, 233962688, 234092224, 234221888, 234353984, 234485312,
+234618304, 234749888, 234880832, 235011776, 235142464, 235274048,
+235403456, 235535936, 235667392, 235797568, 235928768, 236057152,
+236190272, 236322752, 236453312, 236583616, 236715712, 236846528,
+236976448, 237108544, 237239104, 237371072, 237501632, 237630784,
+237764416, 237895232, 238026688, 238157632, 238286912, 238419392,
+238548032, 238681024, 238812608, 238941632, 239075008, 239206336,
+239335232, 239466944, 239599168, 239730496, 239861312, 239992384,
+240122816, 240254656, 240385856, 240516928, 240647872, 240779072,
+240909632, 241040704, 241171904, 241302848, 241433408, 241565248,
+241696192, 241825984, 241958848, 242088256, 242220224, 242352064,
+242481856, 242611648, 242744896, 242876224, 243005632, 243138496,
+243268672, 243400384, 243531712, 243662656, 243793856, 243924544,
+244054592, 244187072, 244316608, 244448704, 244580032, 244710976,
+244841536, 244972864, 245104448, 245233984, 245365312, 245497792,
+245628736, 245759936, 245889856, 246021056, 246152512, 246284224,
+246415168, 246545344, 246675904, 246808384, 246939584, 247070144,
+247199552, 247331648, 247463872, 247593536, 247726016, 247857088,
+247987648, 248116928, 248249536, 248380736, 248512064, 248643008,
+248773312, 248901056, 249036608, 249167552, 249298624, 249429184,
+249560512, 249692096, 249822784, 249954112, 250085312, 250215488,
+250345792, 250478528, 250608704, 250739264, 250870976, 251002816,
+251133632, 251263552, 251395136, 251523904, 251657792, 251789248,
+251919424, 252051392, 252182464, 252313408, 252444224, 252575552,
+252706624, 252836032, 252968512, 253099712, 253227584, 253361728,
+253493056, 253623488, 253754432, 253885504, 254017216, 254148032,
+254279488, 254410432, 254541376, 254672576, 254803264, 254933824,
+255065792, 255196736, 255326528, 255458752, 255589952, 255721408,
+255851072, 255983296, 256114624, 256244416, 256374208, 256507712,
+256636096, 256768832, 256900544, 257031616, 257162176, 257294272,
+257424448, 257555776, 257686976, 257818432, 257949632, 258079552,
+258211136, 258342464, 258473408, 258603712, 258734656, 258867008,
+258996544, 259127744, 259260224, 259391296, 259522112, 259651904,
+259784384, 259915328, 260045888, 260175424, 260308544, 260438336,
+260570944, 260700992, 260832448, 260963776, 261092672, 261226304,
+261356864, 261487936, 261619648, 261750592, 261879872, 262011968,
+262143424, 262274752, 262404416, 262537024, 262667968, 262799296,
+262928704, 263061184, 263191744, 263322944, 263454656, 263585216,
+263716672, 263847872, 263978944, 264108608, 264241088, 264371648,
+264501184, 264632768, 264764096, 264895936, 265024576, 265158464,
+265287488, 265418432, 265550528, 265681216, 265813312, 265943488,
+266075968, 266206144, 266337728, 266468032, 266600384, 266731072,
+266862272, 266993344, 267124288, 267255616, 267386432, 267516992,
+267648704, 267777728, 267910592, 268040512, 268172096, 268302784,
+268435264, 268566208, 268696256, 268828096, 268959296, 269090368,
+269221312, 269352256, 269482688, 269614784, 269745856, 269876416,
+270007616, 270139328, 270270272, 270401216, 270531904, 270663616,
+270791744, 270924736, 271056832, 271186112, 271317184, 271449536,
+271580992, 271711936, 271843136, 271973056, 272105408, 272236352,
+272367296, 272498368, 272629568, 272759488, 272891456, 273022784,
+273153856, 273284672, 273415616, 273547072, 273677632, 273808448,
+273937088, 274071488, 274200896, 274332992, 274463296, 274595392,
+274726208, 274857536, 274988992, 275118656, 275250496, 275382208,
+275513024, 275643968, 275775296, 275906368, 276037184, 276167872,
+276297664, 276429376, 276560576, 276692672, 276822976, 276955072,
+277085632, 277216832, 277347008, 277478848, 277609664, 277740992,
+277868608, 278002624, 278134336, 278265536, 278395328, 278526784,
+278657728, 278789824, 278921152, 279052096, 279182912, 279313088,
+279443776, 279576256, 279706048, 279838528, 279969728, 280099648,
+280230976, 280361408, 280493632, 280622528, 280755392, 280887104,
+281018176, 281147968, 281278912, 281411392, 281542592, 281673152,
+281803712, 281935552, 282066496, 282197312, 282329024, 282458816,
+282590272, 282720832, 282853184, 282983744, 283115072, 283246144,
+283377344, 283508416, 283639744, 283770304, 283901504, 284032576,
+284163136, 284294848, 284426176, 284556992, 284687296, 284819264,
+284950208, 285081536]
+```
diff --git a/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/index.md b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/index.md
new file mode 100644
index 00000000000..23a34de6a03
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/index.md
@@ -0,0 +1,42 @@
+---
+title: "Алгоритмы майнинга"
+description: "Детальный обзор алгоритмов майнинга Ethereum."
+lang: ru
+---
+
+
+
+
+
+Доказательство работы(PoW) больше не является механизмом консенсуса Ethereum, это означает что майнинг отключен. Вместо этого, Ethereum обеспечен и защищен валидаторами, которые поставляют ETH. Вы можете начать ставить свои ETH уже сегодня. Узнайте больше о Слиянии, доказательстве владения и вкладах. Эта страница здесь ради исторического интереса.
+
+
+
+
+Для майнинга Ethereum использовался алгоритм, известный как Ethash. Основная идея алгоритма заключается в том, что майнер пытается найти ввод nonce с помощью грубой силы, чтобы полученный хэш был меньше порога, определяемого вычисленной сложностью. Этот уровень сложности можно динамически регулировать, что позволяет производить блоки через регулярные промежутки времени.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала ознакомиться с [консенсусом на основе доказательства работы](/developers/docs/consensus-mechanisms/pow) и [майнингом](/developers/docs/consensus-mechanisms/pow/mining).
+
+## Dagger Hashimoto {#dagger-hashimoto}
+
+Dagger Hashimoto был предшественником исследовательского алгоритма добычи Ethereum, который заменил Ethash. Это было объединение двух разных алгоритмов: Dagger и Hashimoto. Это была всего лишь исследовательская реализация, и к моменту запуска основной сети Ethereum его заменил Ethash.
+
+[Dagger](http://www.hashcash.org/papers/dagger.html) предполагает создание [направленного ациклического графа](https://en.wikipedia.org/wiki/Directed_acyclic_graph), случайные фрагменты которого затем хешируются вместе. Основной принцип заключается в том, что для каждого nonce требуется лишь небольшая часть большого общего дерева данных. Перерасчет поддерева для каждого одноразового номера в майнинге невозможен — следовательно, необходимо хранить дерево — но это нормально для проверки ценности одного одноразового номера. Dagger был разработан как альтернатива существующим алгоритмам, таким как Scrypt, которые требовательны к памяти, но их трудно проверить, когда их жесткость памяти увеличивается до действительно безопасного уровня. Однако Dagger был уязвим для аппаратного ускорения общей памяти, и поэтому ему пришлось отказаться от других направлений исследований.
+
+[Hashimoto](http://diyhpl.us/%7Ebryan/papers2/bitcoin/meh/hashimoto.pdf) — это алгоритм, обеспечивающий устойчивость к ASIC за счет привязки к операциям ввода-вывода (т. е. чтение из памяти является ограничивающим фактором в процессе майнинга). Теория состоит в том, что оперативная память более доступна, чем вычисления; исследования стоимостью в миллиарды долларов уже направлены на оптимизацию оперативной памяти для различных вариантов использования, которые часто включают шаблоны почти произвольного доступа (отсюда и «оперативная память»). В результате существующая оперативная память, вероятно, будет умеренно близка к оптимальной для оценки алгоритма. Hashimoto использует блокчейн в качестве источника данных, одновременно удовлетворяя (1) и (3) выше.
+
+Dagger-Hashimoto использовал измененные версии алгоритмов Dagger и Hashimoto. Разница между Dagger Hashimoto и Hashimoto заключается в том, что вместо использования блокчейна в качестве источника данных Dagger Hashimoto использует специально созданный набор данных, который обновляется на основе данных блока каждые N блоков. Набор данных генерируется с помощью алгоритма Dagger, что позволяет эффективно вычислять подмножество, специфичное для каждого nonce, для алгоритма верификации легкого клиента. Разница между Dagger Hashimoto и Dagger заключается в том, что, в отличие от оригинального Dagger, набор данных, используемый для запроса блока, является полупостоянным, обновляясь лишь время от времени (например, раз в неделю). Это означает, что доля усилий по созданию набора данных близка к нулю, поэтому аргументы Серджио Лернера относительно ускорения за счет общей памяти становятся незначительными.
+
+Подробнее о [Dagger-Hashimoto](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto).
+
+## Ethash {#ethash}
+
+Ethash — это алгоритм майнинга, который фактически использовался в основной сети Ethereum в рамках ныне устаревшей архитектуры доказательства выполнения работы. Ethash — это, по сути, новое название, данное определенной версии Dagger-Hashimoto после того, как алгоритм был значительно обновлен, при этом он унаследовал основные принципы своего предшественника. В основной сети Ethereum всегда использовался только Ethash — Dagger Hashimoto был версией алгоритма майнинга для исследований и разработок (R&D), которая была заменена до начала майнинга в основной сети Ethereum.
+
+[Подробнее об Ethash](/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash).
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/dapps/index.md b/public/content/translations/ru/developers/docs/dapps/index.md
index 1622dc9a40e..2151da8efac 100644
--- a/public/content/translations/ru/developers/docs/dapps/index.md
+++ b/public/content/translations/ru/developers/docs/dapps/index.md
@@ -1,96 +1,96 @@
---
-title: Введение в децентрализованные приложения
+title: "Техническое введение в децентрализованные приложения"
description:
lang: ru
---
-Децентрализованное приложение (dapp) — это приложение, построенное на децентрализованной сети, сочетающей в себе [умный контракт](/developers/docs/smart-contracts/) и клиентскую сторону пользовательского интерфейса. Отметим, что в Ethereum умные контракты общедоступны и прозрачны (как открытые API), поэтому ваше приложение может содержать в себе умные контракты, которые были написаны другими людьми.
+Децентрализованное приложение (dapp) — это приложение, созданное в децентрализованной сети, которое сочетает в себе [смарт-контракт](/developers/docs/smart-contracts/) и клиентский пользовательский интерфейс. Отметим, что в Ethereum умные контракты общедоступны и прозрачны (как открытые API), поэтому ваше приложение может содержать в себе умные контракты, которые были написаны другими людьми.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Перед изучением децентрализованных приложений вам следует прочитать об [основах блокчейна](/developers/docs/intro-to-ethereum/), а также о сети Ethereum и о том, как она децентрализована.
+Прежде чем изучать децентрализованные приложения, вам следует ознакомиться с [основами блокчейна](/developers/docs/intro-to-ethereum/) и прочитать о сети Ethereum и о том, как она децентрализована.
-## Что такое децентрализованное приложение {#definition-of-a-dapp}
+## Определение децентрализованного приложения {#definition-of-a-dapp}
У децентрализованного приложения есть бэкенд-код, который работает в децентрализованной одноранговой сети. Сравните это с приложением, бэкенд-код которого работает на централизованных серверах.
-Децентрализованное приложение может иметь фронтенд-код и пользовательский интерфейс на любом языке (как и обычное приложение) для запросов к бэкенду. Более того, фронтенд может быть размещен в децентрализованном хранилище, таком как [IPFS](https://ipfs.io/).
+Децентрализованное приложение может иметь фронтенд-код и пользовательский интерфейс на любом языке (как и обычное приложение) для запросов к бэкенду. Кроме того, его фронтенд можно разместить в децентрализованном хранилище, таком как [IPFS](https://ipfs.io/).
-- **Децентрализованные**: децентрализованные приложения работают в Ethereum — на открытой публичной децентрализованной платформе, над которой ни одно лицо или группа не имеет контроля
-- **Детерминированные**: децентрализованные приложения выполняют ту же функцию независимо от среды, в которой они выполняются
-- **Полные по Тьюрингу**: децентрализованные приложения могут выполнять любые действия при наличии необходимых ресурсов
-- **Изолированные**: децентрализованные приложения выполняются в виртуальной среде, известной как Ethereum Virtual Machine, и ошибка в умном контракте не помешает нормальному функционированию блокчейн-сети
+- **Децентрализованные**: децентрализованные приложения работают на Ethereum, открытой публичной децентрализованной платформе, где ни один человек или группа не имеют контроля
+- **Детерминированные**: децентрализованные приложения выполняют одну и ту же функцию независимо от среды, в которой они выполняются.
+- **Полные по Тьюрингу**: децентрализованные приложения могут выполнять любое действие при наличии необходимых ресурсов.
+- **Изолированные**: децентрализованные приложения выполняются в виртуальной среде, известной как виртуальная машина Ethereum, так что, если в смарт-контракте есть ошибка, это не помешает нормальной работе сети блокчейна.
-### Умные контракты {#on-smart-contracts}
+### О смарт-контрактах {#on-smart-contracts}
-Чтобы внедрить децентрализованные приложения, нам нужно ввести умные контракты (можно сказать, что это бэкенд децентрализованного приложения). Чтобы получить подробный обзор, перейдите в наш раздел, посвященный [умным контрактам](/developers/docs/smart-contracts/).
+Чтобы внедрить децентрализованные приложения, нам нужно ввести умные контракты (можно сказать, что это бэкенд децентрализованного приложения). Для получения подробного обзора перейдите в наш раздел о [смарт-контрактах](/developers/docs/smart-contracts/).
Умный контракт — это код, который существует в блокчейне Ethereum и работает в точности так, как он был запрограммирован. После того, как умные контракты развернуты в сети, вы не сможете их изменить. Приложения dapp являются децентрализованными, так как они контролируются алгоритмом, записанным в контракте, а не частным лицом или компанией. Это также означает, что необходимо крайне осторожно разрабатывать контракты и тщательно их тестировать.
-## Преимущества разработки dapp {#benefits-of-dapp-development}
+## Преимущества разработки децентрализованных приложений {#benefits-of-dapp-development}
-- **Нулевое время простоя**. После развертывания умного контракта в блокчейне сеть в целом всегда сможет обслуживать клиентов, желающих взаимодействовать с контрактом. Следовательно, злоумышленники не смогут запускать атаки типа «отказ в обслуживании», направленные на отдельные децентрализованные приложения.
-- **Конфиденциальность**. Вам не нужно предоставлять свой реальные личные данные для использования или взаимодействия с dapp.
-- **Устойчивость к цензуре**. Абсолютно никто в сети не может блокировать отправку транзакций пользователями, написание ими децентрализованных приложений или чтение данных из блокчейна.
-- **Обеспечение неприкосновенности данных**. Данные, хранящиеся в блокчейне, неизменны и неоспоримы благодаря криптографическим примитивам. Злоумышленники не могут подделывать транзакции или другие данные, которые уже были опубликованы.
-- **Вычисления, не требующие доверия, и проверяемое поведение**. Умные контракты можно анализировать, и они гарантированно будут выполняться предсказуемым образом без необходимости доверять центральному органу. В традиционных моделях все обстоит иначе: например, при использовании системы онлайн-банкинга мы за неимением выбора должны доверять тому, что финансовые учреждения не будут злоупотреблять нашими финансовыми данными, изменять записи или взламывать наши аккаунты.
+- **Отсутствие простоев** — как только смарт-контракт развернут в блокчейне, сеть в целом всегда сможет обслуживать клиентов, желающих взаимодействовать с контрактом. Следовательно, злоумышленники не смогут запускать атаки типа «отказ в обслуживании», направленные на отдельные децентрализованные приложения.
+- **Конфиденциальность** — вам не нужно предоставлять реальные личные данные для развертывания децентрализованного приложения или взаимодействия с ним.
+- **Устойчивость к цензуре** — ни одна сущность в сети не может заблокировать пользователей от отправки транзакций, развертывания децентрализованных приложений или чтения данных из блокчейна.
+- **Полная целостность данных** — данные, хранящиеся в блокчейне, неизменны и неоспоримы благодаря криптографическим примитивам. Злоумышленники не могут подделывать транзакции или другие данные, которые уже были опубликованы.
+- **Вычисления без доверия/проверяемое поведение** — смарт-контракты можно анализировать, и они гарантированно будут выполняться предсказуемым образом без необходимости доверять центральному органу. В традиционных моделях все обстоит иначе: например, при использовании системы онлайн-банкинга мы за неимением выбора должны доверять тому, что финансовые учреждения не будут злоупотреблять нашими финансовыми данными, изменять записи или взламывать наши аккаунты.
-## Недостатки разработки dapp {#drawbacks-of-dapp-development}
+## Недостатки разработки децентрализованных приложений {#drawbacks-of-dapp-development}
-- **Обслуживание**. Могут возникать трудности с поддержкой и обслуживанием децентрализованных приложений, так как код и данные, опубликованные в блокчейне, сложнее изменить. Разработчикам сложно обновлять свои децентрализованные приложения (или базовые данные, хранящиеся в децентрализованном приложении) после их развертывания, даже если в старой версии обнаружены ошибки или угрозы безопасности.
-- **Расходы на производительность**. Накладные расходы на производительность огромны, и масштабирование действительно затруднено. Чтобы достичь уровня безопасности, честности, прозрачности и надежности, к которому стремится Ethereum, каждый узел запускает и хранит каждую транзакцию. Кроме того, консенсус с доказательством владения также требует времени.
-- **Перегрузка сети**. Когда одно децентрализованное приложение использует слишком много вычислительных ресурсов, создается резервная копия всей сети. На текущий момент сеть может обрабатывать только около 10-15 транзакций в секунду; если транзакции отправляются быстрее, чем может обработать сеть, пул неподтвержденных транзакций может быстро увеличиться.
-- **Удобство пользователя**. Может быть сложнее добиться удобства пользователя, потому что среднестатическому пользователю может быть слишком сложно настроить стек инструментов, необходимый для действительно безопасного взаимодействия с блокчейном.
-- **Централизация**. Удобные для пользователя и разработчика решения, построенные на основе базового уровня Ethereum, в любом случае могут оказаться похожими на централизованные службы. Например, такие службы могут хранить ключи или другую важную информацию на стороне сервера, обслуживать интерфейс с использованием централизованного сервера или запускать важную бизнес-логику на централизованном сервере перед записью в блокчейн. Централизация сводит на нет многие (если не все) преимущества блокчейна в сравнении с традиционной моделью.
+- **Обслуживание** — децентрализованные приложения может быть сложнее обслуживать, потому что код и данные, опубликованные в блокчейне, сложнее изменить. Разработчикам сложно обновлять свои децентрализованные приложения (или базовые данные, хранящиеся в децентрализованном приложении) после их развертывания, даже если в старой версии обнаружены ошибки или угрозы безопасности.
+- **Накладные расходы на производительность** — существуют огромные накладные расходы на производительность, а масштабирование очень затруднено. Чтобы достичь уровня безопасности, честности, прозрачности и надежности, к которому стремится Ethereum, каждый узел запускает и хранит каждую транзакцию. Кроме того, консенсус с доказательством владения также требует времени.
+- **Перегрузка сети** — когда одно децентрализованное приложение использует слишком много вычислительных ресурсов, вся сеть перегружается. На текущий момент сеть может обрабатывать только около 10-15 транзакций в секунду; если транзакции отправляются быстрее, чем может обработать сеть, пул неподтвержденных транзакций может быстро увеличиться.
+- **Пользовательский опыт** — может быть сложнее создать удобный для пользователя интерфейс, поскольку среднестатистическому конечному пользователю может показаться слишком сложным настроить набор инструментов, необходимый для взаимодействия с блокчейном действительно безопасным способом.
+- **Централизация** — удобные для пользователя и разработчика решения, построенные поверх базового уровня Ethereum, в конечном итоге все равно могут выглядеть как централизованные сервисы. Например, такие службы могут хранить ключи или другую важную информацию на стороне сервера, обслуживать интерфейс с использованием централизованного сервера или запускать важную бизнес-логику на централизованном сервере перед записью в блокчейн. Централизация сводит на нет многие (если не все) преимущества блокчейна в сравнении с традиционной моделью.
-## Больше любите видео? {#visual-learner}
+## Больше увлекаетесь визуализацией? {#visual-learner}
## Инструменты для создания децентрализованных приложений {#dapp-tools}
-**Scaffold-ETH — _быстрый опыт использования Solidity с помощью интерфейса, который адаптируется к вашему умному контракту._**
+**Scaffold-ETH _- Быстро экспериментируйте с Solidity, используя фронтенд, который адаптируется к вашему смарт-контракту._**
- [GitHub](https://github.com/scaffold-eth/scaffold-eth-2)
-- [Пример dapp](https://punkwallet.io/)
+- [Пример децентрализованного приложения](https://punkwallet.io/)
-**Создание приложения Eth — _создавайте приложения на базе Ethereum с помощью одной команды._**
+**Create Eth App _- Создавайте приложения на базе Ethereum с помощью одной команды._**
- [GitHub](https://github.com/paulrberg/create-eth-app)
-**One Click Dapp _— FOSS-инструмент для создания интерфейсов dapp с [ABI](/glossary/#abi)._**
+**One Click Dapp _- Инструмент FOSS для создания фронтендов децентрализованных приложений из [ABI](/glossary/#abi)._**
- [oneclickdapp.com](https://oneclickdapp.com)
- [GitHub](https://github.com/oneclickdapp/oneclickdapp-v1)
-**Etherflow — _FOSS-инструмент для разработчиков Ethereum, позволяющий тестировать свои узлы, а также составлять и отлаживать RPC-вызовы из браузера._**
+**Etherflow _- Инструмент FOSS для разработчиков Ethereum, позволяющий тестировать их узел, а также составлять и отлаживать RPC-вызовы из браузера._**
- [etherflow.quiknode.io](https://etherflow.quiknode.io/)
- [GitHub](https://github.com/abunsen/etherflow)
-**thirdweb _– SDK на каждом языке, смарт-контракты, инструменты и инфраструктура для разработки Web3._**
+**thirdweb _- SDK для всех языков, смарт-контракты, инструменты и инфраструктура для разработки web3._**
-- [Официальный веб-сайт](https://thirdweb.com/)
+- [Домашняя страница](https://thirdweb.com/)
- [Документация](https://portal.thirdweb.com/)
- [GitHub](https://github.com/thirdweb-dev/)
-**Crossmint _— платформа разработки Web3 корпоративного уровня для развертывания смарт-контрактов, платежей по кредитным картам и кроссчейн-платежей, а также создания, распространения, продажи, хранения и редактирования NFT посредством API._**
+**Crossmint _- Платформа для разработки web3 корпоративного уровня для развертывания смарт-контрактов, приема платежей по кредитным картам и кроссчейн-платежей, а также использования API для создания, распространения, продажи, хранения и редактирования NFT._**
- [crossmint.com](https://www.crossmint.com)
- [Документация](https://docs.crossmint.com)
- [Discord](https://discord.com/invite/crossmint)
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Просмотреть децентрализованные приложения](/apps)
-- [Архитектура приложения Web 3.0](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) — _Прити Касиредди_
-- [Руководство 2021 года по децентрализованным приложениям](https://limechain.tech/blog/what-are-dapps-the-2021-guide/) — _LimeChain_
+- [Изучить децентрализованные приложения](/apps)
+- [Архитектура Web 3.0-приложения](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) — _Preethi Kasireddy_
+- [Руководство по децентрализованным приложениям 2021 года](https://limechain.tech/blog/what-are-dapps-the-2021-guide/) — _LimeChain_
- [Что такое децентрализованные приложения?](https://www.gemini.com/cryptopedia/decentralized-applications-defi-dapps) — _Gemini_
- [Популярные децентрализованные приложения](https://www.alchemy.com/dapps) — _Alchemy_
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
-## Похожие темы {#related-topics}
+## Связанные темы {#related-topics}
- [Введение в стек Ethereum](/developers/docs/ethereum-stack/)
-- [Среды разработки](/developers/docs/frameworks/)
+- [Фреймворки для разработки](/developers/docs/frameworks/)
diff --git a/public/content/translations/ru/developers/docs/data-and-analytics/block-explorers/index.md b/public/content/translations/ru/developers/docs/data-and-analytics/block-explorers/index.md
new file mode 100644
index 00000000000..9807829ac9c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-and-analytics/block-explorers/index.md
@@ -0,0 +1,254 @@
+---
+title: "Обозреватели блоков"
+description: "Введение в обозреватели блоков, ваш портал в мир данных блокчейна, где вы можете запрашивать информацию о транзакциях, счетах, контрактах и многое другое."
+lang: ru
+sidebarDepth: 3
+---
+
+Обозреватели блоков это ваш портал к данным Ethereum. Вы можете использовать их для просмотра данных о блоках, транзакциях, валидаторах, аккаунтах и другой ончейн-активности в режиме реального времени.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны понимать основные понятия Ethereum, чтобы вы могли понять данные, которые вам дают обозреватели блоков. Начните со [введения в Ethereum](/developers/docs/intro-to-ethereum/).
+
+## Сервисы {#services}
+
+- [Etherscan](https://etherscan.io/) – _также доступен на китайском, корейском, русском и японском языках_
+- [3xpl](https://3xpl.com/ethereum)
+- [Beaconcha.in](https://beaconcha.in/)
+- [Blockchair](https://blockchair.com/ethereum) – _также доступен на испанском, французском, итальянском, голландском, португальском, русском, китайском и фарси_
+- [Blockscout](https://eth.blockscout.com/)
+- [Chainlens](https://www.chainlens.com/)
+- [Обозреватель блоков DexGuru](https://ethereum.dex.guru/)
+- [Etherchain](https://www.etherchain.org/)
+- [Ethplorer](https://ethplorer.io/) – _также доступен на китайском, испанском, французском, турецком, русском, корейском и вьетнамском языках_
+- [EthVM](https://www.ethvm.com/)
+- [OKLink](https://www.oklink.com/eth)
+- [Ethseer](https://ethseer.io)
+
+## Инструменты с открытым исходным кодом {#open-source-tools}
+
+- [Otterscan](https://otterscan.io/)
+- [lazy-etherscan](https://github.com/woxjro/lazy-etherscan)
+
+## Данные {#data}
+
+Ethereum прозрачен по своей конструкции, поэтому все поддается проверке. Обозреватели блоков предоставляют интерфейс для получения этой информации. И это касается как основной сети Ethereum, так и тестовых сетей, если вам нужны эти данные. Данные делятся на данные о выполнении и данные о консенсусе. Данные о выполнении относятся к транзакциям, которые были выполнены в конкретном блоке. Данные о консенсусе относятся к самим блокам и предложившим их валидаторам.
+
+Вот сводка типов данных, которые вы можете получить из обозревателя блоков.
+
+### Данные уровня исполнения {#execution-data}
+
+Новые блоки добавляются в сети Ethereum каждые 12 секунд (за исключением случаев, когда инициаторы блока пропускают свою очередь), так что поток данных, получаемых обозревателями блоков, практически непрерывен. Блоки содержат много важных данных, которые могут оказаться полезными:
+
+**Стандартные данные**
+
+- Высота блока - номер блока и длина блокчейна (в блоках) на момент создания текущего блока
+- Временная метка - время, когда был предложен блок
+- Транзакции - количество транзакций, включенных в блок
+- Получатель комиссии - адрес, на который поступила плата за газ в результате транзакций
+- Вознаграждение за блок - количество ETH, начисленное валидатору, предложившему блок
+- Размер - размер данных в блоке (измеряется в байтах)
+- Количество использованного газ - общее количество единиц газа, использованного всем и транзакциями в блоке
+- Лимит газа - максимальный суммарный лимит газа, установленный для всех транзакций в блоке
+- Базовая комиссия за газ - минимальная комиссия за газ, необходимая для включения транзакции в блок
+- Сгоревшая комиссия - сколько ETH сгорело в блоке
+- Дополнительные данные - любые дополнительные данные, которые создатель включил в блок
+
+**Дополнительные данные**
+
+- Хеш - криптографический хеш заголовка блока (уникального идентификатора блока)
+- Хеш родительского блока - хеш блока, предшествующего текущему блоку
+- StateRoot - корневой хеш дерева Меркла, в котором хранится все состояние системы
+
+### Газ {#gas}
+
+Обозреватели блоков не только предоставят вам данные об использовании газа в транзакциях и блоках, но и некоторые из них предоставят вам информацию о текущих ценах на газ в сети. Это поможет вам понять расходы сети в данный момент, отправить безопасные транзакции и не перерасходовать газ. Ознакомьтесь с API, которые могут помочь вам получить эту информацию в интерфейсе вашего продукта. Данные о газе:
+
+- Расчетные единицы газа, необходимые для безопасной, но медленной транзакции (+ расчетная цена и продолжительность)
+- Расчетные единицы потребляемого газа для средней сделки (+ расчетная цена и продолжительность)
+- Расчетные единицы газа, необходимые для быстрой сделки (+ расчетная цена и продолжительность)
+- Среднее время подтверждения, основанное на цене газа
+- Контракты, потребляющие газ, другими словами, популярные продукты на сети, которыми активно пользуются
+- Аккаунты, тратящие газ, или, иначе говоря, наиболее активные пользователи сети
+
+### Транзакции {#transactions}
+
+Обозреватели блоков стали общим местом для отслеживания прогресса их транзакций. Это потому, что уровень детализации позволяет получить дополнительную уверенность. Данные транзакции включают:
+
+**Стандартные данные**
+
+- Хеш транзакции - хеш, сгенерированный при отправке транзакции
+- Статус - индикатор состояния транзакции, указывающий ожидает ли она обработки, прошла успешно или нет
+- Блок - номер блока, в который была включена транзакция
+- Временная отметка – время, когда транзакция была включена в блок, предложенный валидатором.
+- От кого - адрес кошелька, отправившего транзакцию
+- Кому - адрес получателя или смарт-контракта, с которым происходит взаимодействие
+- Отправленные токены - список токенов, которые были отправлены в рамках транзакции
+- Стоимость - суммарное количество ETH, которое было отправлено
+- Комиссия за транзакцию — это сумма уплачиваемая валидатору за обработку транзакции (рассчитывается как цена газа\*количество использованного газа)
+
+**Дополнительные данные**
+
+- Лимит газа - максимальное количество газа, которое может быть потреблено транзакцией
+- Количество использованного газа - реальное количество газа, использованного транзакцией
+- Цена газа - цена за единицу газа
+- Нонс – номер транзакции для адреса `from` (помните, что нумерация начинается с 0, поэтому нонс `100` на самом деле будет 101-й транзакцией, отправленной этим аккаунтом).
+- Входные данные - любая дополнительная информация, требуемая транзакцией
+
+### Аккаунты {#accounts}
+
+Существует множество данных об аккаунте, к которым вы можете получить доступ. Поэтому часто рекомендуется использовать несколько аккаунтов, чтобы было сложнее отслеживать ваши активы и их стоимость. Существуют также решения, позволяющие сделать транзакции и данные об активностях аккаунта более конфиденциальными. Но вот данные, которые доступны для аккаунтов:
+
+**Аккаунты пользователей**
+
+- Адрес аккаунта - публичный адрес, на который можно отправлять средства
+- Баланс ETH - количество ETH, привязанное к данному аккаунту
+- Общая стоимость ETH - стоимость ETH
+- Токены - токены привязанные к аккаунту и их стоимость
+- История транзакций - список всех транзакций, в которых данный аккаунт выступал в качестве отправителя или получателя
+
+**Умные контракты**
+
+Аккаунты смарт-контрактов содержат все те же данные, что и пользовательские аккаунты, но некоторые обозреватели блоков могут даже показать немного информации о коде контракта. В качестве примеров можно привести:
+
+- Создатель контракта - адрес, с которого контракт был отправлен в сеть
+- Транзакция создания контракта - транзакция, при помощи которой контракт был опубликован в сети
+- Исходный код - solidity или vyper код смарт-контракта
+- ABI контракта или Application Binary Interface контракта - обращения контракта к сети и получаемые данные
+- Код создания контракта - скомпилированный байткод смарт-контракта, созданный при компиляции смарт-контракта, написанного на Solidity, Vyper и т. д.
+- Действия контракта - история функций, вызванных в смарт-контракте, или по сути, способ увидеть, как и как часто используется контракт.
+
+### Токены {#tokens}
+
+Токены являются разновидностью контрактов, поэтому они будут иметь данные, схожие с данными смарт-контрактов. Но поскольку они имеют ценность и могут торговаться, они располагают дополнительными данными, а именно:
+
+- Тип - будь то ERC-20, ERC-721 или какой-то другой стандарт токенов
+- Цена - в случае ERC-20 токенов, будет указана текущая рыночная стоимость
+- Рыночная капитализация - в случае ERC-20 токенов, будет указана текущая рыночная капитализация (рассчитанная как цена \* общее предложение)
+- Общее предложение - количество токенов, находящихся в обращении
+- Владельцы - количество адресов, на которых находится токен
+- Переводы - количество раз, когда токен был переведен между аккаунтами
+- История транзакций - история всех транзакций, включавших токен
+- Адрес контракта - адрес контракта выпуска токена на сети
+- Десятичные знаки - токены ERC-20 являются делимыми и могут иметь какое-то количество знаков после запятой
+
+### Сеть {#network}
+
+Некоторые данные отражают состояние сети Ethereum в целом.
+
+- Общее количество транзакций - число транзакций с момента запуска Ethereum
+- Количество транзакций в секунду - число транзакций, обрабатываемых в течение одной секунды
+- Цена ETH - текущая стоимость 1 ETH
+- Общее количество ETH - число ETH в обращении, но помните, дополнительное количество ETH появляется с каждым блоком в качестве вознаграждения
+- Рыночная капитализация - рассчитывается как цена \* общее количество ETH
+
+## Данные уровня консенсуса {#consensus-layer-data}
+
+### Эпоха {#epoch}
+
+В целях безопасности в конце каждой эпохи (каждые 6,4 минуты) создаются рандомизированные комитеты валидаторов. Данные по эпохе включают:
+
+- Номер эпохи
+- Статус завершенности - завершена ли эпоха (Да/Нет)
+- Время - время окончания эпохи
+- Аттестации - количество аттестаций в эпохе (голоса за блоки в определенной ячейке)
+- Депозиты - количество депозитов ETH в эпохе (валидаторы должны застейкать ETH, чтобы быть валидаторами)
+- Слэшинг – количество штрафов, наложенных на предлагающих блоки или аттестаторов.
+- Участие в голосовании – количество ETH в стейкинге, используемое для аттестации блоков.
+- Валидаторы - количество валидаторов, активных в каждой эпохе
+- Средний баланс валидатора – средний баланс для активных валидаторов
+- Ячейки - количество ячеек, включенных в эпоху (ячейки включают по одному валидированному блоку)
+
+### Слот {#slot}
+
+Ячейки - это возможности для создания блоков, данные, относящиеся к каждой ячейки, включают:
+
+- Эпоха - эпоха, в которой ячейка действительна
+- Номер ячейки
+- Статус - статус ячейки (Предложено/Пропущено)
+- Время - временная метка ячейки
+- Инициатор - валидатор, который предлагает блок в ячейке
+- Корень блока – хэш-корень BeaconBlock.
+- Родительский корень – хэш предыдущего блока.
+- Корень состояния – хэш-корень BeaconState.
+- Подпись
+- Выявление RanDAO
+- Графити - инициатор блока может добавить к нему сообщение длиной до 32 байтов
+- Исполнительные данные
+ - Хеш блока
+ - Количество депозитов
+ - Корень депозита
+- Аттестации - количество аттестаций блока в ячейке
+- Депозиты - количество депозитов в этой ячейке
+- Добровольные выходы - количество валидаторов, покинувших ячейку
+- Слэшинг – количество штрафов, наложенных на предлагающих блоки или аттестаторов.
+- Голоса - валидаторы, которые проголосовали за блок в ячейке
+
+### Блоки {#blocks-1}
+
+Доказательство владения разделяет время на ячейки и эпохи. Значит будут новые данные!
+
+- Претендент – валидатор, который был алгоритмически выбран для предложения нового блока
+- Эпоха – эпоха, в которой был предложен блок
+- Ячейка – ячейка, в которой был предложен блок
+- Аттестации – количество аттестаций, включенных в слот. Аттестации подобны голосам, указывающим, что блок готов для добавления в сеть Beacon.
+
+### Валидаторы {#validators}
+
+Валидаторы отвечают за предложение блоков и их аттестацию в ячейках.
+
+- Номер валидатора – уникальный номер, представляющий валидатора
+- Текущий баланс – баланс валидатора, включая награды
+- Действующий баланс – баланс валидатора, который используется для стейкинга
+- Доход – награды или штрафы, полученные валидатором
+- Статус – является ли валидатор в настоящее время активным или нет
+- Эффективность аттестации – среднее время, необходимое для включения аттестаций валидатора в цепочку
+- Право на активацию – дата (и эпоха), когда валидатор стал доступен для проверки
+- Действует с – дата (и эпоха), когда валидатор стал активным
+- Предложенные блоки – предлагаемый валидатором блок
+- Аттестации – аттестации, предоставленные валидатором
+- Депозиты – адрес отправителя, хэш транзакции, номер блока, время и статус размещения депозита, сделанного валидатором
+
+### Аттестации {#attestations}
+
+Аттестации - это голоса «да», чтобы включить блоки в цепочку. Их данные касаются записи аттестации и валидаторов, которые подтвердили ее
+
+- Ячейка – ячейка, в которой проходила аттестация
+- Индекс комитета – индекс комитета в данной ячейке
+- Биты объединения – представляет объединенную аттестацию всех участвующих в аттестации валидаторов
+- Валидаторы – валидаторы, обеспечившие аттестацию
+- Корень Beacon block – указывает на блок, на который аттестуют валидаторы
+- Исходник – указывает на последнюю истинную эпоху
+- Цель – указывает на границу последней эпохи
+- Подпись
+
+### Сеть {#network-1}
+
+Данные верхнего уровня консенсуса включают следующее:
+
+- Текущая эпоха
+- Текущая ячейка
+- Активные валидаторы - количество активных валидаторов
+- Ожидающие валидаторы - количество валидаторов, ожидающих стать активными
+- Застейканый ETH - количество ETH застейканного на сети
+- Средний баланс - средний баланс ETH валидаторов
+
+## Обозреватели блоков {#block-explorers}
+
+- [Etherscan](https://etherscan.io/) – обозреватель блоков, который можно использовать для получения данных из основной сети Ethereum и тестовой сети.
+- [3xpl](https://3xpl.com/ethereum) – обозреватель Ethereum с открытым исходным кодом без рекламы, который позволяет загружать наборы данных.
+- [Beaconcha.in](https://beaconcha.in/) – обозреватель блоков с открытым исходным кодом для основной сети Ethereum и тестовой сети.
+- [Blockchair](https://blockchair.com/ethereum) – самый конфиденциальный обозреватель Ethereum. Также для сортировки и фильтрации (mempool) данных
+- [Etherchain](https://www.etherchain.org/) – обозреватель блоков для основной сети Ethereum.
+- [Ethplorer](https://ethplorer.io/) – обозреватель блоков с фокусом на токенах для основной сети Ethereum и тестовой сети Kovan.
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Транзакции](/developers/docs/transactions/)
+- [Аккаунты](/developers/docs/accounts/)
+- [Сети](/developers/docs/networks/)
diff --git a/public/content/translations/ru/developers/docs/data-and-analytics/index.md b/public/content/translations/ru/developers/docs/data-and-analytics/index.md
new file mode 100644
index 00000000000..f1f876753a9
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-and-analytics/index.md
@@ -0,0 +1,72 @@
+---
+title: "Данные и аналитика"
+description: "Как получить ончейн-аналитику и данные для использования в ваших децентрализованных приложениях"
+lang: ru
+---
+
+## Введение {#Introduction}
+
+По мере роста использования сети все больший объем ценной информации будет содержаться в ончейн-данных. Поскольку объем данных быстро увеличивается, вычисление и агрегирование этой информации для составления отчетов или управления приложением может стать трудоемкой задачей.
+
+Использование существующих поставщиков данных может ускорить разработку, обеспечить более точные результаты и сократить текущие расходы на обслуживание. Это позволит команде сконцентрироваться на основных функциях, которые пытается предоставить их проект.
+
+## Предварительные условия {#prerequisites}
+
+Вам следует ознакомиться с основной концепцией [обозревателей блоков](/developers/docs/data-and-analytics/block-explorers/), чтобы лучше понять их использование в контексте анализа данных. Кроме того, ознакомьтесь с понятием [индекса](/glossary/#index), чтобы понять преимущества, которые он дает при проектировании системы.
+
+С точки зрения основ архитектуры, необходимо хотя бы в теории понимать, что такое [API](https://www.wikipedia.org/wiki/API) и [REST](https://www.wikipedia.org/wiki/Representational_state_transfer).
+
+## Обозреватели блоков {#block-explorers}
+
+Многие [обозреватели блоков](/developers/docs/data-and-analytics/block-explorers/) предлагают шлюзы [RESTful](https://www.wikipedia.org/wiki/Representational_state_transfer) [API](https://www.wikipedia.org/wiki/API), которые предоставляют разработчикам доступ к данным о блоках, транзакциях, валидаторах, аккаунтах и другой ончейн-активности в режиме реального времени.
+
+Затем разработчики могут обрабатывать и преобразовывать эти данные, чтобы предоставить своим пользователям уникальные аналитические сведения и возможности взаимодействия с [блокчейном](/glossary/#blockchain). Например, [Etherscan](https://etherscan.io) и [Blockscout](https://eth.blockscout.com) предоставляют данные исполнения и консенсуса для каждого 12-секундного слота.
+
+## The Graph {#the-graph}
+
+[The Graph](https://thegraph.com/) — это протокол индексирования, который предоставляет простой способ запрашивать данные из блокчейна через открытые API, известные как подграфы.
+
+С The Graph разработчики получают следующие преимущества:
+
+- Децентрализованное индексирование: позволяет индексировать данные блокчейна с помощью нескольких индексаторов, что устраняет любую единую точку отказа
+- Запросы GraphQL: предоставляет мощный интерфейс GraphQL для запроса индексированных данных, что делает их извлечение очень простым
+- Настройка: определяйте собственную логику для преобразования и хранения данных блокчейна и повторно используйте подграфы, опубликованные другими разработчиками в сети The Graph
+
+Следуйте этому [руководству по быстрому запуску](https://thegraph.com/docs/en/quick-start/), чтобы создать, развернуть и отправить запрос к подграфу в течение 5 минут.
+
+## Разнообразие клиентов {#client-diversity}
+
+[Разнообразие клиентов](/developers/docs/nodes-and-clients/client-diversity/) важно для общего состояния сети Ethereum, поскольку оно обеспечивает устойчивость к ошибкам и эксплойтам. Сейчас существует несколько панелей мониторинга разнообразия клиентов, включая [clientdiversity.org](https://clientdiversity.org/), [rated.network](https://www.rated.network), [supermajority.info](https://supermajority.info//) и [Ethernodes](https://ethernodes.org/).
+
+## Dune Analytics {#dune-analytics}
+
+[Dune Analytics](https://dune.com/) предварительно обрабатывает данные блокчейна в таблицы реляционной базы данных (DuneSQL), позволяет пользователям запрашивать данные блокчейна с помощью SQL и создавать панели мониторинга на основе результатов запросов. Ончейн-данные организованы в 4 таблицы с необработанными данными: `blocks`, `transactions`, `logs` (журналы событий) и `traces` (трассировки вызовов). Популярные контракты и протоколы были декодированы, и каждый имеет свой собственный набор таблиц событий и вызовов. Эти таблицы событий и вызовов подвергаются дальнейшей обработке и организуются в абстрактные таблицы по типу протоколов, например, dex, кредитование, стейблкоины и т.д.
+
+## SQD {#sqd}
+
+[SQD](https://sqd.dev/) — это децентрализованная, гипермасштабируемая платформа данных, оптимизированная для обеспечения эффективного и не требующего разрешений доступа к большим объемам данных. В настоящее время она предоставляет исторические ончейн-данные, включая журналы событий, квитанции о транзакциях, трассировки и изменения состояния для каждой транзакции. SQD предлагает мощный набор инструментов для создания пользовательских конвейеров извлечения и обработки данных, достигающий скорости индексации до 150 тыс. блоков в секунду.
+
+Чтобы начать, посетите [документацию](https://docs.sqd.dev/) или посмотрите [примеры для EVM](https://github.com/subsquid-labs/squid-evm-examples), чтобы узнать, что можно создать с помощью SQD.
+
+## SubQuery Network {#subquery-network}
+
+[SubQuery](https://subquery.network/) — это ведущий индексатор данных, который предоставляет разработчикам быстрые, надежные, децентрализованные и настраиваемые API для их Web3-проектов. SubQuery предоставляет разработчикам из более чем 165 экосистем (включая Ethereum) доступ к обширным индексированным данным для создания интуитивно понятного и иммерсивного пользовательского опыта. Сеть SubQuery обеспечивает работу ваших неостанавливаемых приложений с помощью устойчивой и децентрализованной инфраструктурной сети. Используйте набор инструментов для разработчиков блокчейн-приложений от SubQuery для создания Web3-приложений будущего, не тратя время на создание пользовательского бэкенда для обработки данных.
+
+Для начала ознакомьтесь с [руководством по быстрому запуску для Ethereum](https://academy.subquery.network/quickstart/quickstart_chains/ethereum-gravatar.html), чтобы за считанные минуты начать индексировать данные блокчейна Ethereum в локальной среде Docker для тестирования, прежде чем запустить в [управляемом сервисе SubQuery](https://managedservice.subquery.network/) или в [децентрализованной сети SubQuery](https://app.subquery.network/dashboard).
+
+## Язык запросов EVM {#evm-query-language}
+
+Язык запросов EVM (EQL) — это SQL-подобный язык, предназначенный для отправки запросов к сетям на основе EVM (виртуальной машины Ethereum). Конечная цель EQL — поддержка сложных реляционных запросов к объектам первого класса сетей на базе EVM (блокам, аккаунтам и транзакциям) и предоставление разработчикам и исследователям эргономичного синтаксиса для повседневного использования. С помощью EQL разработчики могут извлекать данные блокчейна, используя знакомый SQL-подобный синтаксис, и избавиться от необходимости в сложном шаблонном коде. EQL поддерживает стандартные запросы данных блокчейна (например, получение нонса и баланса аккаунта в Ethereum или получение размера и временной отметки текущего блока) и постоянно добавляет поддержку более сложных запросов и наборов функций.
+
+## Дополнительные материалы {#further-reading}
+
+- [Изучение криптоданных, часть I: архитектуры потоков данных](https://web.archive.org/web/20250125012042/https://research.2077.xyz/exploring-crypto-data-1-data-flow-architectures)
+- [Обзор сети The Graph](https://thegraph.com/docs/en/about/)
+- [Песочница для запросов The Graph](https://thegraph.com/explorer/subgraph/graphprotocol/graph-network-mainnet?version=current)
+- [Примеры кода API на EtherScan](https://etherscan.io/apis#contracts)
+- [Документация по API на Blockscout](https://docs.blockscout.com/devs/apis)
+- [Beaconcha.in — обозреватель Beacon Chain](https://beaconcha.in)
+- [Основы Dune](https://docs.dune.com/#dune-basics)
+- [Руководство по быстрому запуску SubQuery для Ethereum](https://academy.subquery.network/indexer/quickstart/quickstart_chains/ethereum-gravatar.html)
+- [Обзор сети SQD](https://docs.sqd.dev/)
+- [Язык запросов EVM](https://eql.sh/blog/alpha-release-notes)
diff --git a/public/content/translations/ru/developers/docs/data-availability/blockchain-data-storage-strategies/index.md b/public/content/translations/ru/developers/docs/data-availability/blockchain-data-storage-strategies/index.md
new file mode 100644
index 00000000000..ade6c0018ad
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-availability/blockchain-data-storage-strategies/index.md
@@ -0,0 +1,118 @@
+---
+title: "Стратегии хранения данных в блокчейне"
+description: "Существует несколько способов хранения данных с помощью блокчейна. В этой статье мы сравним различные стратегии, их стоимость и преимущества, а также требования к безопасному использованию."
+lang: ru
+---
+
+Существует множество способов хранить информацию либо непосредственно на блокчейне, либо защитив её с помощью блокчейна:
+
+- Блобы EIP-4844
+- Calldata
+- Офчейн с механизмами L1
+- «Код» контракта
+- Мероприятия
+- Хранилище EVM
+
+Выбор метода основывается на нескольких критериях:
+
+- Источник информации. Информация в calldata не может поступать напрямую из самого блокчейна.
+- Назначение информации. Calldata доступна только в транзакции, которая ее включает. События совершенно недоступны ончейн.
+- Какой уровень сложности является приемлемым? Компьютеры, на которых запущен полный узел, могут выполнять больше обработки, чем легкий клиент в приложении, работающем в браузере.
+- Необходимо ли обеспечивать легкий доступ к информации с каждого узла?
+- Требования к безопасности.
+
+## Требования к безопасности {#security-requirements}
+
+В целом информационная безопасность состоит из трех атрибутов:
+
+- _Конфиденциальность_: неавторизованные субъекты не могут читать информацию. Это важно во многих случаях, но не в этом. _В блокчейне не существует секретов_. Блокчейны работают, потому что любой может проверить переходы состояний, поэтому их невозможно использовать для прямого хранения секретов. Существуют способы хранения конфиденциальной информации в блокчейне, но все они используют какой-либо офф-чейн-компонент для хранения как минимум одного ключа.
+
+- _Целостность_: информация корректна, она не может быть изменена неавторизованными субъектами или неавторизованными способами (например, передача [токенов ERC-20](https://eips.ethereum.org/EIPS/eip-20#events) без события `Transfer`). В блокчейне каждый узел проверяет каждое изменение состояния, что обеспечивает целостность.
+
+- _Доступность_, информация доступна любому уполномоченному лицу. В блокчейне это обычно достигается за счет того, что информация доступна в каждом [полном узле](https://ethereum.org/developers/docs/nodes-and-clients#full-node).
+
+Все представленные здесь решения обладают превосходной целостностью, поскольку хэши публикуются на L1. Однако у них разные гарантии доступности.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны хорошо понимать [основы блокчейна](/developers/docs/intro-to-ethereum/). Эта страница также предполагает, что читатель знаком с [блоками](/developers/docs/blocks/), [транзакциями](/developers/docs/transactions/) и другими соответствующими темами.
+
+## Блобы EIP-4844 {#eip-4844-blobs}
+
+Начиная с [хардфорка Dencun](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md), блокчейн Ethereum включает [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844), который добавляет в Ethereum блобы данных с ограниченным сроком хранения (изначально около [18 дней](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/p2p-interface.md#configuration)). Стоимость этих блобов рассчитывается отдельно от [газа за исполнение](/developers/docs/gas), хотя и с использованием похожего механизма. Это дешевый способ публикации временных данных.
+
+Основной вариант использования блобов EIP-4844 — это публикация транзакций роллапами. [Оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups) должны публиковать транзакции в своих блокчейнах. Эти транзакции должны быть доступны любому в течение [периода оспаривания](https://docs.optimism.io/connect/resources/glossary#challenge-period), чтобы [валидаторы](https://docs.optimism.io/connect/resources/glossary#validator) могли исправить ошибку, если [секвенсор](https://docs.optimism.io/connect/resources/glossary#sequencer) ролл-апа публикует некорректный корень состояния.
+
+Однако, как только период оспаривания пройдет и корень состояния будет финализирован, оставшаяся цель хранения этих транзакций заключается в воспроизведении текущего состояния сети. Это состояние также доступно на узлах сети и требует гораздо меньшей обработки. Поэтому информация о транзакциях все равно должна сохраняться в нескольких местах, таких как [обозреватели блоков](/developers/docs/data-and-analytics/block-explorers), но нет необходимости платить за тот уровень устойчивости к цензуре, который предоставляет Ethereum.
+
+[Ролл-апы с нулевым разглашением](/developers/docs/scaling/zk-rollups/#data-availability) также публикуют данные своих транзакций, чтобы другие узлы могли воспроизводить существующее состояние и проверять доказательства достоверности, но это опять же краткосрочное требование.
+
+На момент написания статьи публикация в EIP-4844 стоит один wei (10-18 ETH) за байт, что ничтожно мало по сравнению со [стоимостью в 21 000 единиц газа за исполнение, которые требуются для любой транзакции, включая ту, что публикует блобы](https://eth.blockscout.com/tx/0xf6cfaf0431c73dd1d96369a5e6707d64f463ccf477a4131265397f1d81466929?tab=index). Вы можете увидеть текущую цену EIP-4844 на [blobscan.com](https://blobscan.com/blocks).
+
+Вот адреса, по которым можно увидеть блобы, опубликованные некоторыми известными роллапами.
+
+| Накопительные пакеты - это общий подход к масштабированию открытых контрактов, то есть контрактов, которые каждый может видеть и с которыми может взаимодействовать. При накоплении транзакции записываются в Ethereum (как calldata), но фактические вычисления и хранение контракта выполняются вне сети. Кто-то (валидатор) публикует в цепочке утверждение (также известное как блок Rollup) о том, что будет делать контракт - список действий, предпринятых контрактом, таких как произведенные платежи, и криптографический хеш его состояния после контракта. выполнил вызовы, которые уже были размещены в сети. Мы можем думать об утверждении как о «объединении» всех вызовов и их результатов в одну транзакцию в цепочке.Системы объединения отличаются тем, как они обеспечивают правильность утверждений | Адрес почтового ящика |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
+| [Optimism](https://www.optimism.io/) | [`0xFF00000000000000000000000000000000000010`](https://blobscan.com/address/0xFF00000000000000000000000000000000000010) |
+| [Arbitrum](https://arbitrum.io/) | [`0x1c479675ad559DC151F6Ec7ed3FbF8ceE79582B6`](https://blobscan.com/address/0x1c479675ad559DC151F6Ec7ed3FbF8ceE79582B6) |
+| [Base](https://base.org/) | [`0xFF00000000000000000000000000000000008453`](https://blobscan.com/address/0xFF00000000000000000000000000000000008453) |
+
+## Calldata {#calldata}
+
+Calldata — это байты, отправляемые в составе транзакции. Она хранится как часть постоянной записи блокчейна в блоке, который включает эту транзакцию.
+
+Это самый дешевый метод для постоянного размещения данных в блокчейне. Стоимость за байт составляет либо 4 единицы газа за исполнение (если байт нулевой), либо 16 единиц газа (любое другое значение). Если данные сжаты, что является стандартной практикой, то каждое значение байта равновероятно, поэтому средняя стоимость составляет примерно 15,95 единиц газа за байт.
+
+На момент написания статьи цены составляют 12 gwei за газ и 2300 $ за ETH, что означает стоимость примерно 45 центов за килобайт. Поскольку это был самый дешевый метод до EIP-4844, роллапы использовали его для хранения информации о транзакциях, которая должна быть доступна для [оспаривания ошибок](https://docs.optimism.io/stack/protocol/overview#fault-proofs), но не требует прямого доступа ончейн.
+
+Вот адреса, по которым можно увидеть транзакции, опубликованные некоторыми известными роллапами.
+
+| Накопительные пакеты - это общий подход к масштабированию открытых контрактов, то есть контрактов, которые каждый может видеть и с которыми может взаимодействовать. При накоплении транзакции записываются в Ethereum (как calldata), но фактические вычисления и хранение контракта выполняются вне сети. Кто-то (валидатор) публикует в цепочке утверждение (также известное как блок Rollup) о том, что будет делать контракт - список действий, предпринятых контрактом, таких как произведенные платежи, и криптографический хеш его состояния после контракта. выполнил вызовы, которые уже были размещены в сети. Мы можем думать об утверждении как о «объединении» всех вызовов и их результатов в одну транзакцию в цепочке.Системы объединения отличаются тем, как они обеспечивают правильность утверждений | Адрес почтового ящика |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| [Optimism](https://www.optimism.io/) | [`0xFF00000000000000000000000000000000000010`](https://eth.blockscout.com/address/0xFF00000000000000000000000000000000000010) |
+| [Arbitrum](https://arbitrum.io/) | [`0x1c479675ad559DC151F6Ec7ed3FbF8ceE79582B6`](https://eth.blockscout.com/address/0x1c479675ad559DC151F6Ec7ed3FbF8ceE79582B6) |
+| [Base](https://base.org/) | [`0xFF00000000000000000000000000000000008453`](https://eth.blockscout.com/address/0xFF00000000000000000000000000000000008453) |
+
+## Офчейн с механизмами L1 {#offchain-with-l1-mechs}
+
+В зависимости от ваших компромиссов в области безопасности, может быть приемлемо размещать информацию в другом месте и использовать механизм, который обеспечивает доступность данных при необходимости. Для этого необходимо выполнить два требования:
+
+1. Опубликовать [хэш](https://en.wikipedia.org/wiki/Cryptographic_hash_function) данных в блокчейне, называемый _обязательством по входным данным_. Это может быть одно 32-байтное слово, поэтому это недорого. Пока доступно обязательство по входным данным, целостность гарантирована, потому что невозможно найти другие данные, которые бы хэшировались в то же значение. Поэтому если будут предоставлены неверные данные, это можно будет обнаружить.
+
+2. Иметь механизм, обеспечивающий доступность. Например, в [Redstone](https://redstone.xyz/docs/what-is-redstone) любой узел может подать запрос на проверку доступности. Если секвенсор не ответит ончейн до установленного срока, обязательство по входным данным отбрасывается, и информация считается никогда не опубликованной.
+
+Это приемлемо для оптимистического ролл-апа, потому что мы уже полагаемся на наличие хотя бы одного честного верификатора для корня состояния. Такой честный верификатор также убедится, что у него есть данные для обработки блоков, и отправит запрос на проверку доступности, если информация недоступна офф-чейн. Этот тип оптимистического ролл-апа называется [plasma](/developers/docs/scaling/plasma/).
+
+## Код контракта {#contract-code}
+
+Информация, которая должна быть записана только один раз, никогда не перезаписывается и должна быть доступна на блокчейне, может храниться в виде кода контракта. Это означает, что мы создаем «смарт-контракт» с данными, а затем используем [`EXTCODECOPY`](https://www.evm.codes/#3c?fork=shanghai) для чтения информации. Преимущество в том, что копирование кода относительно дешево.
+
+Помимо стоимости расширения памяти, `EXTCODECOPY` стоит 2600 единиц газа за первый доступ к контракту (когда он «холодный») и 100 единиц газа за последующие копирования из того же контракта плюс 3 единицы газа за 32-байтовое слово. По сравнению с calldata, которая стоит 15,95 за байт, это дешевле, начиная примерно с 200 байт. Согласно [формуле стоимости расширения памяти](https://www.evm.codes/about#memoryexpansion), пока вам не нужно более 4 МБ памяти, стоимость расширения памяти меньше стоимости добавления calldata.
+
+Конечно, это только стоимость _чтения_ данных. Создание контракта стоит примерно 32 000 единиц газа + 200 единиц газа/байт. Этот метод экономичен только тогда, когда одна и та же информация должна быть прочитана много раз в разных транзакциях.
+
+Код контракта может быть бессмысленным, пока он не начинается с `0xEF`. Контракты, начинающиеся с `0xEF`, интерпретируются как [формат объектов Ethereum](https://notes.ethereum.org/@ipsilon/evm-object-format-overview), который имеет гораздо более строгие требования.
+
+## События {#events}
+
+[События](https://docs.alchemy.com/docs/solidity-events) генерируются смарт-контрактами и считываются офф-чейн программным обеспечением.
+Их преимущество в том, что офф-чейн код может прослушивать события. Стоимость составляет [газ](https://www.evm.codes/#a0?fork=cancun): 375 плюс 8 единиц газа за байт данных. При цене 12 gwei за газ и 2300 $ за ETH это составляет один цент плюс 22 цента за килобайт.
+
+## Хранилища {#storage}
+
+Смарт-контракты имеют доступ к [постоянному хранилищу](https://docs.alchemy.com/docs/smart-contract-storage-layout#what-is-storage-memory). Однако его использование очень дорого. Запись 32-байтного слова в ранее пустую ячейку хранилища может [стоить 22 100 единиц газа](https://www.evm.codes/#55?fork=cancun). При цене 12 gwei за газ и 2300 $ за ETH это составляет около 61 цента за операцию записи, или 19,5 $ за килобайт.
+
+Это самая дорогая форма хранения в Ethereum.
+
+## Сводка {#summary}
+
+В этой таблице кратко изложены различные варианты, их преимущества и недостатки.
+
+| Тип хранилища | Источник данных | Гарантия доступности | Доступность ончейн | Дополнительные ограничения |
+| ----------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | -------------------------------------------------------------------------- |
+| Блобы EIP-4844 | Офф-чейн | Гарантия Ethereum на [~18 дней](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/p2p-interface.md#configuration) | Доступен только хэш | |
+| Calldata | Офф-чейн | Гарантия Ethereum навсегда (часть блокчейна) | Доступно только при записи в контракт и в рамках этой транзакции | |
+| Офчейн с механизмами L1 | Офф-чейн | Гарантия «одного честного верификатора» в течение периода оспаривания | Только хэш | Гарантируется механизмом оспаривания, только в течение периода оспаривания |
+| Код контракта | Ончейн или офф-чейн | Гарантия Ethereum навсегда (часть блокчейна) | Да | Записывается на «случайный» адрес, не может начинаться с `0xEF` |
+| Мероприятия | Ончейн | Гарантия Ethereum навсегда (часть блокчейна) | Нет | |
+| Хранилище | Ончейн | Гарантия Ethereum навсегда (часть блокчейна и текущего состояния до перезаписи) | Да | |
diff --git a/public/content/translations/ru/developers/docs/data-availability/index.md b/public/content/translations/ru/developers/docs/data-availability/index.md
new file mode 100644
index 00000000000..005b06a3073
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-availability/index.md
@@ -0,0 +1,84 @@
+---
+title: "Доступность данных"
+description: "Обзор проблем и решений, связанных с доступностью данных в Ethereum"
+lang: ru
+---
+
+«Не доверяй, проверяй» — довольно распространенный принцип Ethereum. Идея состоит в том, что ваш узел в любом случае проверяет правильность получаемой информации, выполняя все транзакции в блоках, которые он получает от узлов, чтобы гарантировать, что предлагаемые изменения точно соответствуют изменениям, вычисленным узлом независимо. Это означает, что узлам не нужно верить в честность отправителей блока. Это невозможно при отсутствии данных.
+
+**Доступность данных** означает уверенность пользователя в том, что данные, необходимые для проверки блока, действительно доступны всем участникам сети. Для полных узлов на уровне 1 Ethereum это относительно просто: полный узел загружает копию всех данных в каждом блоке — данные _должны_ быть доступны, чтобы их можно было загрузить. Блок с отсутствующими данными будет отброшен, а не добавлен в блокчейн. Это «ончейн-доступность данных», и это особенность монолитных блокчейнов. Полные узлы невозможно обманом заставить принять недействительные транзакции, поскольку они загружают и выполняют каждую транзакцию самостоятельно. Однако для модульных блокчейнов, накопительных пакетов уровня 2 и легких клиентов ситуация с доступностью данных более сложна и требует более сложных процедур проверки.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны хорошо понимать [основы блокчейна](/developers/docs/intro-to-ethereum/), особенно [механизмы консенсуса](/developers/docs/consensus-mechanisms/). Эта страница также предполагает, что читатель знаком с [блоками](/developers/docs/blocks/), [транзакциями](/developers/docs/transactions/), [узлами](/developers/docs/nodes-and-clients/), [решениями для масштабирования](/developers/docs/scaling/) и другими соответствующими темами.
+
+## Проблема доступности данных {#the-data-availability-problem}
+
+Проблема доступности данных заключается в необходимости доказать всей сети, что обобщенная форма некоторых данных транзакций, добавляемых в блокчейн, действительно представляет собой набор действительных транзакций, но при этом не требуется, чтобы все узлы загружали все данные. Полные данные транзакций необходимы для независимой проверки блоков, но требование ко всем узлам загружать все данные транзакций является препятствием для масштабирования. Решения проблемы доступности данных призваны гарантировать, что полные данные транзакций были доступны для проверки участникам сети, которые не загружают и не хранят данные для себя.
+
+[Легкие узлы](/developers/docs/nodes-and-clients/light-clients) и [ролл-апы уровня 2](/developers/docs/scaling/) являются важными примерами участников сети, которым требуются надежные гарантии доступности данных, но которые не могут самостоятельно загружать и обрабатывать данные транзакций. Избегание загрузки данных транзакций — вот что делает легкие узлы легкими и позволяет объединениям быть эффективными решениями для масштабирования.
+
+Доступность данных также является критически важной проблемой для будущих [«несохраняющих состояние»](/roadmap/statelessness) клиентов Ethereum, которым не нужно загружать и хранить данные о состоянии для проверки блоков. Несохраняющие состояние клиенты все равно должны быть уверены, что данные доступны _где-то_ и что они были правильно обработаны.
+
+## Решения для обеспечения доступности данных {#data-availability-solutions}
+
+### Сэмплирование доступности данных (DAS) {#data-availability-sampling}
+
+Выборка доступности данных (DAS) — это способ проверки доступности данных в сети без слишком большой нагрузки на какой-либо отдельный узел. Каждый узел (включая узлы, не участвующие в стейкинге) загружает небольшое, случайно выбранное подмножество общих данных. Успешная загрузка выборки с высокой степенью уверенности подтверждает доступность всех данных. Это основано на кодировании со стиранием данных, которое расширяет заданный набор данных избыточной информацией (это делается путем подбора к данным функции, известной как _полином_, и вычисления этого полинома в дополнительных точках). Это позволяет при необходимости восстановить исходные данные из избыточных данных. Следствием такого создания данных является то, что если _любая часть_ исходных данных недоступна, _половина_ расширенных данных также будет отсутствовать! Количество выборок данных, загружаемых каждым узлом, можно настроить так, чтобы было _чрезвычайно_ вероятно, что хотя бы один из фрагментов данных, выбранных каждым клиентом, будет отсутствовать, _если_ в действительности доступно менее половины данных.
+
+DAS будет использоваться, чтобы операторы ролл-апов обеспечивали доступность данных своих транзакций после внедрения [полного Danksharding](/roadmap/danksharding/#what-is-danksharding). Узлы Ethereum будут случайным образом выбирать данные транзакций, предоставленные в виде больших двоичных объектов, используя описанную выше схему избыточности, чтобы гарантировать существование всех данных. Тот же метод можно также использовать, чтобы гарантировать, что производители блоков делают все свои данные доступными для защиты легких клиентов. Аналогично, при [разделении предлагающего и сборщика](/roadmap/pbs) только сборщик блока должен будет обработать весь блок, а другие валидаторы будут выполнять проверку с помощью сэмплирования доступности данных.
+
+### Комитеты по доступности данных {#data-availability-committees}
+
+Комитеты доступности данных (DAC) — это доверенные стороны, которые обеспечивают или подтверждают доступность данных. DAC могут использоваться вместо DAS [или в сочетании с ним](https://hackmd.io/@vbuterin/sharding_proposal#Why-not-use-just-committees-and-not-DAS). Гарантии безопасности, предоставляемые комитетам, зависят от конкретной структуры. Например, Ethereum использует случайно выбранные подмножества валидаторов для подтверждения доступности данных для легких узлов.
+
+DAC также используются некоторыми валидиумами. DAC — это доверенный набор узлов, который хранит копии данных в автономном режиме. DAC обязан предоставлять доступ данных в случае возникновения спора. Члены DAC также публикуют ончейн-аттестации, чтобы доказать, что указанные данные действительно доступны. Некоторые валидиумы заменяют DAC системой валидации «доказательство владения» (PoS). Здесь любой желающий может стать валидатором и хранить данные оффчейн. Однако они должны предоставить «связь», заложенную в смарт-контракте. В случае злонамеренного поведения, например, сокрытия данных валидатором, связь может быть сокращена. Комитеты по доступности данных на основе доказательства владенния значительно более безопасны, чем обычные DAC, поскольку они стимулируют честное поведение напрямую.
+
+## Доступность данных и легкие узлы {#data-availability-and-light-nodes}
+
+[Легкие узлы](/developers/docs/nodes-and-clients/light-clients) должны проверять правильность заголовков блоков, которые они получают, не загружая данные блока. Платой за эту легкость является невозможность независимо проверять заголовки блоков путем локального повторного выполнения транзакций, как это делают полные узлы.
+
+Легкие узлы Ethereum доверяют случайным наборам из 512 валидаторов, которые были назначены в _комитет синхронизации_. Комитет синхронизации выступает как DAC, который с помощью криптографической подписи сигнализирует легким клиентам о том, что данные в заголовке верны. Каждый день комитет синхронизации обновляется. Каждый заголовок блока оповещает легкие узлы о том, какие валидаторы должны подписать _следующий_ блок, поэтому их нельзя обманом заставить доверять злонамеренной группе, выдающей себя за настоящий комитет синхронизации.
+
+Однако что произойдет, если злоумышленнику каким-то образом _все-таки_ удастся передать вредоносный заголовок блока легким клиентам и убедить их, что он был подписан честным комитетом синхронизации? В этом случае злоумышленник может включить недействительные транзакции, и легкий клиент будет слепо их принимать, поскольку он не проверяет отдельно все изменения состояния, суммированные в заголовке блока. Чтобы защититься от этого, легкий клиент может использовать доказательства мошенничества.
+
+Принцип работы этих доказательств мошенничества заключается в том, что полный узел, видя, что по сети распространяются слухи о недопустимом переходе состояния, может быстро сгенерировать небольшой фрагмент данных, демонстрирующий, что предлагаемый переход состояния не может возникнуть в результате заданного набора транзакций, и передать эти данные одноранговым узлам. Легкие узлы могут собирать эти доказательства мошенничества и использовать их для удаления заголовков плохих блоков, гарантируя, что они останутся в той же честной цепочке, что и полные узлы.
+
+Процесс зависит от того, что полные узлы имеют доступ ко всем данным транзакций. Злоумышленник, который передает плохой заголовок блока, а также не предоставляет доступ к данным транзакции, сможет помешать полным узлам генерировать доказательства мошенничества. Полные узлы могли бы подать сигнал предупреждения о плохом блоке, но они не смогли бы подкрепить свое предупреждение доказательством, потому что у них нет доступа к этим данным!
+
+Решением этой проблемы доступности данных является DAS. Легкие узлы загружают очень небольшие случайные фрагменты полных данных о состоянии и используют образцы для проверки доступности полного набора данных. Фактическую вероятность неверного предположения о полной доступности данных после загрузки N случайных фрагментов можно рассчитать ([для 100 фрагментов шанс составляет 10^-30](https://dankradfeist.de/ethereum/2019/12/20/data-availability-checks.html), т. е. это невероятно маловероятно).
+
+Даже в этом сценарии атаки, которые удерживают всего несколько байтов, могут остаться незамеченными для клиентов, выполняющих случайные запросы данных. Стирающая кодировка исправляет это, восстанавливая небольшие недостающие фрагменты данных, которые можно использовать для проверки предполагаемых изменений состояния. Затем можно построить доказательство мошенничества с использованием реконструированных данных, предотвращая принятие легкими узлами неверных заголовков.
+
+**Примечание:** DAS и доказательства мошенничества еще не реализованы для легких клиентов Ethereum с доказательством владения (proof-of-stake), но они есть в дорожной карте и, скорее всего, будут реализованы в форме доказательств на основе ZK-SNARK. Сегодняшние легкие клиенты полагаются на своего рода DAC: они проверяют личность комитета синхронизации, а затем доверяют полученным подписанным заголовкам блоков.
+
+## Доступность данных и ролл-апы уровня 2 {#data-availability-and-layer-2-rollups}
+
+[Решения для масштабирования уровня 2](/layer-2/), такие как [ролл-апы](/glossary/#rollups), снижают стоимость транзакций и увеличивают пропускную способность Ethereum за счет обработки транзакций оффчейн. Транзакции ролл-апов сжимаются и публикуются в Ethereum пакетами. Пакеты представляют собой тысячи отдельных оффчейн-транзакций в рамках одной транзакции в Ethereum. Это уменьшает перегрузку на базовом уровне и снижает плату для пользователей.
+
+Однако доверять «сводным» транзакциям, опубликованным в Ethereum, можно только в том случае, если предлагаемое изменение состояния может быть независимо проверено и подтверждено как результат применения всех отдельных оффчейн-транзакций. Если операторы ролл-апов не предоставляют данные транзакций для этой проверки, они могут отправить неверные данные в Ethereum.
+
+[Оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups/) публикуют сжатые данные транзакций в Ethereum и ожидают некоторое время (обычно 7 дней), чтобы независимые верификаторы могли проверить данные. Если кто-либо обнаружит проблему, он может создать доказательство мошенничества и использовать его для оспаривания ролл-апа. Это приведет к откату цепочки и пропуску недопустимого блока. Это возможно только при наличии данных. В настоящее время существует два способа, которыми оптимистические ролл-апы публикуют данные транзакций на уровень 1. Некоторые ролл-апы делают данные постоянно доступными как `CALLDATA`, которые постоянно хранятся ончейн. С внедрением EIP-4844 некоторые ролл-апы вместо этого публикуют данные своих транзакций в более дешевое blob-хранилище. Это не постоянное хранилище. Независимые верификаторы должны запрашивать blob-объекты и выдвигать свои оспаривания в течение ~18 дней, прежде чем данные будут удалены с уровня 1 Ethereum. Доступность данных гарантируется протоколом Ethereum только в течение этого короткого фиксированного окна. После этого ответственность за него переходят к другим субъектам экосистемы Ethereum. Любой узел может проверить доступность данных с помощью DAS, т. е. путем загрузки небольших случайных выборок blob-данных.
+
+[Ролл-апам с 0-знанием (ZK)](/developers/docs/scaling/zk-rollups) не нужно публиковать данные транзакций, поскольку [доказательства действительности с 0-знанием](/glossary/#zk-proof) гарантируют правильность переходов состояния. Однако доступность данных по-прежнему остается проблемой, поскольку мы не можем гарантировать функциональность ролл-апа ZK (или взаимодействовать с ним) без доступа к данным о его состоянии. Например, пользователи не смогут узнать свои балансы, если оператор скрывает информацию о состоянии ролл-апа. Кроме того, они не могут выполнять обновления состояния, используя информацию, содержащуюся в недавно добавленном блоке.
+
+## Доступность данных в сравнении с возможностью их извлечения {#data-availability-vs-data-retrievability}
+
+Доступность данных отличается от возможности их извлечения. Доступность данных — это гарантия того, что полные узлы смогут получить доступ и проверить полный набор транзакций, связанных с конкретным блоком. Из этого не обязательно следует, что данные доступны навсегда.
+
+Возможность извлечения данных — это способность узлов извлекать _историческую информацию_ из блокчейна. Эти исторические данные не нужны для проверки новых блоков, они необходимы только для синхронизации полных узлов из исходного блока или обслуживания определенных исторических запросов.
+
+Основной протокол Ethereum в первую очередь касается доступности данных, а не возможности их извлечения. Возможность извлечения данных может обеспечиваться небольшой группой архивных узлов, управляемых третьими лицами, или она может быть распределена по сети с использованием децентрализованного файлового хранилища, такого как [Portal Network](https://www.ethportal.net/).
+
+## Дополнительные материалы {#further-reading}
+
+- [WTF is Data Availability?](https://medium.com/blockchain-capital-blog/wtf-is-data-availability-80c2c95ded0f)
+- [Что такое доступность данных?](https://coinmarketcap.com/academy/article/what-is-data-availability)
+- [Краткое руководство по проверкам доступности данных](https://dankradfeist.de/ethereum/2019/12/20/data-availability-checks.html)
+- [Объяснение предложения по шардингу и DAS](https://hackmd.io/@vbuterin/sharding_proposal#ELI5-data-availability-sampling)
+- [Заметка о доступности данных и кодировании со стиранием](https://github.com/ethereum/research/wiki/A-note-on-data-availability-and-erasure-coding#can-an-attacker-not-circumvent-this-scheme-by-releasing-a-full-unavailable-block-but-then-only-releasing-individual-bits-of-data-as-clients-query-for-them)
+- [Комитеты по доступности данных.](https://medium.com/starkware/data-availability-e5564c416424)
+- [Комитеты по доступности данных на основе доказательства владения (proof-of-stake).](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf)
+- [Решения проблемы извлечения данных](https://notes.ethereum.org/@vbuterin/data_sharding_roadmap#Who-would-store-historical-data-under-sharding)
+- [Доступность данных, или: как ролл-апы научились не волноваться и полюбили Ethereum](https://web.archive.org/web/20250515194659/https://web.archive.org/web/20241108192208/https/research.2077.xyz/data-availability-or-how-rollups-learned-to-stop-worrying-and-love-ethereum)
+- [EIP-7623: увеличение стоимости Calldata](https://web.archive.org/web/20250515194659/https://research.2077.xyz/eip-7623-increase-calldata-cost)
diff --git a/public/content/translations/ru/developers/docs/data-structures-and-encoding/index.md b/public/content/translations/ru/developers/docs/data-structures-and-encoding/index.md
new file mode 100644
index 00000000000..b5d3ef8ff75
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-structures-and-encoding/index.md
@@ -0,0 +1,32 @@
+---
+title: "Структуры данных и кодирование"
+description: "Обзор фундаментальных структур данных Ethereum."
+lang: ru
+sidebarDepth: 2
+---
+
+Ethereum создает, хранит и передает большие объемы данных. Эти данные должны быть отформатированы стандартизированным и экономящим память способом, чтобы позволить любому человеку [запустить узел](/run-a-node/) на относительно скромном оборудовании потребительского класса. Для этого на стэке Ethereum используются несколько определенных структур данных.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны понимать основы Ethereum и [клиентского программного обеспечения](/developers/docs/nodes-and-clients/). Рекомендуется ознакомиться с сетевым уровнем и [«Белой книгой» Ethereum](/whitepaper/).
+
+## Структуры данных {#data-structures}
+
+### Деревья Меркла-Патриции {#patricia-merkle-tries}
+
+Деревья Меркла-Патриции — это структуры, которые кодируют пары «ключ-значение» в детерминированное и криптографически заверенное префиксное дерево. Они широко используются на уровне исполнения Ethereum.
+
+[Подробнее о деревьях Меркла-Патриции](/developers/docs/data-structures-and-encoding/patricia-merkle-trie)
+
+### Рекурсивный префикс длины {#recursive-length-prefix}
+
+Рекурсивный префикс длины (RLP) — это метод сериализации, который широко используется на уровне исполнения Ethereum.
+
+[Подробнее о RLP](/developers/docs/data-structures-and-encoding/rlp)
+
+### Простая сериализация {#simple-serialize}
+
+Простая сериализация (SSZ) — это доминирующий формат сериализации на уровне консенсуса Ethereum из-за его совместимости с меркелизацией.
+
+[Подробнее о SSZ](/developers/docs/data-structures-and-encoding/ssz)
diff --git a/public/content/translations/ru/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md b/public/content/translations/ru/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md
new file mode 100644
index 00000000000..b3c5723c63c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md
@@ -0,0 +1,266 @@
+---
+title: "Дерево Меркла-Патрисии"
+description: "Введение в дерево Меркла-Патрисии."
+lang: ru
+sidebarDepth: 2
+---
+
+Состояние Ethereum (совокупность всех аккаунтов, балансов и смарт-контрактов) кодируется в специальную версию структуры данных, известной в информатике как дерево Меркла. Эта структура полезна для многих приложений в криптографии, поскольку она создает проверяемую связь между всеми отдельными фрагментами данных, объединенными в дереве, в результате чего получается одно **корневое** значение, которое можно использовать для доказательства утверждений о данных.
+
+Структура данных Ethereum — это «модифицированное дерево Меркла-Патрисии», названное так потому, что оно заимствует некоторые функции PATRICIA (практического алгоритма для извлечения информации, закодированной в буквенно-цифровом виде), а также потому, что оно предназначено для эффективного извлечения (re**trie**val) элементов, составляющих состояние Ethereum.
+
+Дерево Меркла-Патрисии является детерминированным и криптографически верифицируемым: единственный способ сгенерировать корень состояния — это вычислить его из каждой отдельной части состояния, а идентичность двух состояний можно легко доказать, сравнив корневой хэш и хэши, которые к нему привели (_доказательство Меркла_). И наоборот, невозможно создать два разных состояния с одним и тем же корневым хэшем, и любая попытка изменить состояние с другими значениями приведет к другому корневому хэшу. Теоретически, эта структура обеспечивает «святой Грааль» эффективности `O(log(n))` для вставок, поиска и удалений.
+
+В ближайшем будущем Ethereum планирует перейти на структуру [дерева Веркла](/roadmap/verkle-trees), что откроет много новых возможностей для будущих улучшений протокола.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, было бы полезно иметь базовые знания о [хэшах](https://en.wikipedia.org/wiki/Hash_function), [деревьях Меркла](https://en.wikipedia.org/wiki/Merkle_tree), [префиксных деревьях (tries)](https://en.wikipedia.org/wiki/Trie) и [сериализации](https://en.wikipedia.org/wiki/Serialization). Эта статья начинается с описания базового [radix-дерева](https://en.wikipedia.org/wiki/Radix_tree), а затем постепенно вводит модификации, необходимые для более оптимизированной структуры данных Ethereum.
+
+## Базовые radix-деревья {#basic-radix-tries}
+
+В базовом radix-дереве каждый узел выглядит следующим образом:
+
+```
+ [i_0, i_1 ... i_n, value]
+```
+
+Где `i_0 ...` `i_n` представляют собой символы алфавита (часто двоичные или шестнадцатеричные), `value` — это конечное значение в узле, а значения в `i_0, i_1 ...` ячейках `i_n` — это либо `NULL`, либо указатели на (в нашем случае, хэши) другие узлы. Это формирует базовое хранилище `(ключ, значение)`.
+
+Допустим, вы хотите использовать структуру данных radix-дерева для сохранения порядка в наборе пар «ключ-значение». Чтобы найти значение, сопоставленное в данный момент с ключом `dog` в дереве, сначала нужно преобразовать `dog` в буквы алфавита (получив `64 6f 67`), а затем спускаться по дереву по этому пути, пока не найдете значение. То есть вы начинаете с поиска корневого хэша в плоской базе данных «ключ/значение», чтобы найти корневой узел дерева. Он представлен в виде массива ключей, указывающих на другие узлы. Вы бы использовали значение по индексу `6` в качестве ключа и искали бы его в плоской базе данных «ключ/значение», чтобы получить узел на один уровень ниже. Затем выберите индекс `4` для поиска следующего значения, затем выберите индекс `6` и так далее, пока, пройдя по пути: `корень -> 6 -> 4 -> 6 -> 15 -> 6 -> 7`, вы не найдете значение узла и не вернете результат.
+
+Существует разница между поиском чего-либо в «дереве» (trie) и в базовой плоской «БД» (DB) «ключ/значение». Оба они определяют сопоставления «ключ/значение», но базовая БД может выполнять традиционный одношаговый поиск ключа. Поиск ключа в дереве требует нескольких обращений к базовой БД для получения конечного значения, как описано выше. Чтобы устранить двусмысленность, будем называть последнее `путем` (path).
+
+Операции обновления и удаления для radix-деревьев можно определить следующим образом:
+
+```python
+ def update(node_hash, path, value):
+ curnode = db.get(node_hash) if node_hash else [NULL] * 17
+ newnode = curnode.copy()
+ if path == "":
+ newnode[-1] = value
+ else:
+ newindex = update(curnode[path[0]], path[1:], value)
+ newnode[path[0]] = newindex
+ db.put(hash(newnode), newnode)
+ return hash(newnode)
+
+ def delete(node_hash, path):
+ if node_hash is NULL:
+ return NULL
+ else:
+ curnode = db.get(node_hash)
+ newnode = curnode.copy()
+ if path == "":
+ newnode[-1] = NULL
+ else:
+ newindex = delete(curnode[path[0]], path[1:])
+ newnode[path[0]] = newindex
+
+ if all(x is NULL for x in newnode):
+ return NULL
+ else:
+ db.put(hash(newnode), newnode)
+ return hash(newnode)
+```
+
+Radix-дерево Меркла строится путем связывания узлов с помощью детерминированно сгенерированных криптографических хэш-дайджестов. Эта адресация по содержимому (в БД «ключ/значение» `key == keccak256(rlp(value))`) обеспечивает криптографическую гарантию целостности хранимых данных. Если корневой хэш данного дерева общеизвестен, то любой, у кого есть доступ к базовым листовым данным, может построить доказательство того, что дерево включает данное значение по определенному пути, предоставив хэши каждого узла, соединяющего конкретное значение с корнем дерева.
+
+Злоумышленник не может предоставить доказательство для пары `(путь, значение)`, которой не существует, поскольку корневой хэш в конечном счете основан на всех хэшах, находящихся под ним. Любое базовое изменение изменило бы корневой хэш. Вы можете думать о хэше как о сжатом представлении структурной информации о данных, защищенном устойчивостью хэш-функции к нахождению прообраза.
+
+Атомарную единицу radix-дерева (например, один шестнадцатеричный символ или 4-битное двоичное число) мы будем называть «ниббл» (полубайт). При обходе пути по одному нибблу за раз, как описано выше, узлы могут ссылаться максимум на 16 дочерних элементов, но при этом включают элемент `value`. Следовательно, мы представляем их в виде массива длиной 17. Мы называем эти 17-элементные массивы «ветвящимися узлами».
+
+## Дерево Меркла-Патрисии {#merkle-patricia-trees}
+
+У radix-деревьев есть одно серьезное ограничение: они неэффективны. Если вы хотите сохранить одну привязку `(путь, значение)`, где путь, как в Ethereum, имеет длину 64 символа (количество нибблов в `bytes32`), нам потребуется более килобайта дополнительного пространства для хранения одного уровня на символ, и каждый поиск или удаление займет все 64 шага. Дерево Патрисии, представленное далее, решает эту проблему.
+
+### Оптимизация {#optimization}
+
+Узел в дереве Меркла-Патрисии является одним из следующих:
+
+1. `NULL` (представленный в виде пустой строки)
+2. `branch` (ветвь) — узел из 17 элементов `[ v0 ...` v15, vt ]`
+3. `leaf` (лист) — узел из 2 элементов `[ encodedPath, value ]`
+4. `extension` (расширение) — узел из 2 элементов `[ encodedPath, key ]`
+
+При 64-символьных путях неизбежно, что после прохождения первых нескольких уровней дерева вы достигнете узла, в котором не существует расходящегося пути, по крайней мере, на части оставшегося спуска. Чтобы избежать необходимости создавать до 15 разреженных `NULL` узлов на пути, мы сокращаем спуск, устанавливая узел `extension` (расширение) вида `[ encodedPath, key ]`, где `encodedPath` содержит «частичный путь» для пропуска вперед (с использованием компактного кодирования, описанного ниже), а `key` — для следующего поиска в БД.
+
+Для `листового` узла, который может быть помечен флагом в первом ниббле `encodedPath`, путь кодирует все фрагменты пути предыдущих узлов, и мы можем напрямую найти `значение`.
+
+Однако описанная выше оптимизация вносит неоднозначность.
+
+При обходе путей по нибблам мы можем получить нечетное количество нибблов для обхода, но поскольку все данные хранятся в формате `байтов` (bytes). Невозможно различить, например, ниббл `1` и нибблы `01` (оба должны храниться как `<01>`). Чтобы указать нечетную длину, частичный путь снабжается префиксом-флагом.
+
+### Спецификация: компактное кодирование шестнадцатеричной последовательности с необязательным терминатором {#specification}
+
+Маркировка как _нечетной/четной длины оставшегося частичного пути_, так и _листового/расширяющего узла_, как описано выше, находится в первом ниббле частичного пути любого узла из 2 элементов. Это приводит к следующему:
+
+| шестн. символ | биты | тип узла/частичный | длина пути |
+| ----------------------------- | ---- | ---------------------------------- | ---------- |
+| 0 | 0000 | расширение | четная |
+| 1 | 0001 | расширение | нечетная |
+| 2 | 0010 | конечный (лист) | четная |
+| 3 | 0011 | конечный (лист) | нечетная |
+
+Для четной оставшейся длины пути (`0` или `2`) всегда будет следовать еще один «заполняющий» ниббл `0`.
+
+```python
+ def compact_encode(hexarray):
+ term = 1 if hexarray[-1] == 16 else 0
+ if term:
+ hexarray = hexarray[:-1]
+ oddlen = len(hexarray) % 2
+ flags = 2 * term + oddlen
+ if oddlen:
+ hexarray = [flags] + hexarray
+ else:
+ hexarray = [flags] + [0] + hexarray
+ # hexarray now has an even length whose first nibble is the flags.
+ o = ""
+ for i in range(0, len(hexarray), 2):
+ o += chr(16 * hexarray[i] + hexarray[i + 1])
+ return o
+```
+
+Примеры:
+
+```python
+ > [1, 2, 3, 4, 5, ...]
+ '11 23 45'
+ > [0, 1, 2, 3, 4, 5, ...]
+ '00 01 23 45'
+ > [0, f, 1, c, b, 8, 10]
+ '20 0f 1c b8'
+ > [f, 1, c, b, 8, 10]
+ '3f 1c b8'
+```
+
+Вот расширенный код для получения узла в дереве Меркла-Патрисии:
+
+```python
+ def get_helper(node_hash, path):
+ if path == []:
+ return node_hash
+ if node_hash == "":
+ return ""
+ curnode = rlp.decode(node_hash if len(node_hash) < 32 else db.get(node_hash))
+ if len(curnode) == 2:
+ (k2, v2) = curnode
+ k2 = compact_decode(k2)
+ if k2 == path[: len(k2)]:
+ return get(v2, path[len(k2) :])
+ else:
+ return ""
+ elif len(curnode) == 17:
+ return get_helper(curnode[path[0]], path[1:])
+
+ def get(node_hash, path):
+ path2 = []
+ for i in range(len(path)):
+ path2.push(int(ord(path[i]) / 16))
+ path2.push(ord(path[i]) % 16)
+ path2.push(16)
+ return get_helper(node_hash, path2)
+```
+
+### Пример дерева {#example-trie}
+
+Предположим, мы хотим создать дерево, содержащее четыре пары «путь/значение»: `('do', 'глагол')`, `('dog', 'щенок')`, `('doge', 'монеты')`, `('horse', 'жеребец')`.
+
+Сначала мы преобразуем и пути, и значения в `байты`. Ниже фактические байтовые представления для _путей_ обозначаются через `\<>`, хотя _значения_ все еще показаны как строки, обозначаемые `''`, для облегчения понимания (они тоже на самом деле были бы `байтами`):
+
+```
+ <64 6f> : 'глагол'
+ <64 6f 67> : 'щенок'
+ <64 6f 67 65> : 'монеты'
+ <68 6f 72 73 65> : 'жеребец'
+```
+
+Теперь мы строим такое дерево со следующими парами «ключ/значение» в базовой БД:
+
+```
+ rootHash: [ <16>, hashA ]
+ hashA: [ <>, <>, <>, <>, hashB, <>, <>, <>, [ <20 6f 72 73 65>, 'жеребец' ], <>, <>, <>, <>, <>, <>, <>, <> ]
+ hashB: [ <00 6f>, hashC ]
+ hashC: [ <>, <>, <>, <>, <>, <>, hashD, <>, <>, <>, <>, <>, <>, <>, <>, <>, 'глагол' ]
+ hashD: [ <17>, [ <>, <>, <>, <>, <>, <>, [ <35>, 'монеты' ], <>, <>, <>, <>, <>, <>, <>, <>, <>, 'щенок' ] ]
+```
+
+Когда один узел ссылается на другой, включается `keccak256(rlp.encode(node))`, если `len(rlp.encode(node)) >= 32`, иначе `node`, где `rlp.encode` — это функция кодирования [RLP](/developers/docs/data-structures-and-encoding/rlp).
+
+Обратите внимание, что при обновлении дерева необходимо сохранять пару «ключ/значение» `(keccak256(x), x)` в постоянной таблице поиска, _если_ вновь созданный узел имеет длину >= 32. Однако, если узел короче, ничего хранить не нужно, так как функция f(x) = x обратима.
+
+## Деревья в Ethereum {#tries-in-ethereum}
+
+Все деревья Меркла на уровне исполнения Ethereum используют дерево Меркла-Патрисии.
+
+В заголовке блока есть 3 корня от 3 из этих деревьев.
+
+1. stateRoot
+2. transactionsRoot
+3. receiptsRoot
+
+### Дерево состояний {#state-trie}
+
+Существует одно глобальное дерево состояний, и оно обновляется каждый раз, когда клиент обрабатывает блок. В нем `path` всегда равен `keccak256(ethereumAddress)`, а `value` всегда равен `rlp(ethereumAccount)`. Более конкретно, `аккаунт` Ethereum — это массив из 4 элементов: `[nonce, balance, storageRoot, codeHash]`. Здесь стоит отметить, что этот `storageRoot` является корнем другого дерева Патрисии:
+
+### Дерево хранилища {#storage-trie}
+
+В дереве хранилища находятся _все_ данные контракта. Для каждого аккаунта существует отдельное дерево хранилища. Для извлечения значений в определенных позициях хранилища по заданному адресу требуются адрес хранилища, целочисленная позиция хранимых данных в хранилище и ID блока. Затем они могут быть переданы в качестве аргументов в `eth_getStorageAt`, определенный в JSON-RPC API, например, для извлечения данных в слоте хранилища 0 для адреса `0x295a70b2de5e3953354a6a8344e616ed314d7251`:
+
+```bash
+curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"], "id": 1}' localhost:8545
+
+{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000004d2"}
+
+```
+
+Извлечение других элементов в хранилище немного сложнее, потому что сначала необходимо вычислить позицию в дереве хранилища. Позиция вычисляется как хэш `keccak256` от адреса и позиции в хранилище, причем оба значения дополняются нулями слева до длины 32 байта. Например, позиция для данных в слоте хранилища 1 для адреса `0x391694e7e0b0cce554cb130d723a9d27458f9298` такова:
+
+```python
+keccak256(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"))
+```
+
+В консоли Geth это можно рассчитать следующим образом:
+
+```
+> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"
+undefined
+> web3.sha3(key, {"encoding": "hex"})
+"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9"
+```
+
+`path` (путь) поэтому равен `keccak256(<6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9>)`. Теперь это можно использовать для извлечения данных из дерева хранилища, как и раньше:
+
+```bash
+curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9", "latest"], "id": 1}' localhost:8545
+
+{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"}
+```
+
+Примечание: `storageRoot` для аккаунта Ethereum по умолчанию пуст, если это не аккаунт контракта.
+
+### Дерево транзакций {#transaction-trie}
+
+Для каждого блока существует отдельное дерево транзакций, снова хранящее пары `(ключ, значение)`. Здесь путь — это `rlp(transactionIndex)`, который представляет ключ, соответствующий значению, определяемому следующим образом:
+
+```python
+if legacyTx:
+ value = rlp(tx)
+else:
+ value = TxType | encode(tx)
+```
+
+Более подробную информацию об этом можно найти в документации [EIP 2718](https://eips.ethereum.org/EIPS/eip-2718).
+
+### Дерево квитанций {#receipts-trie}
+
+У каждого блока есть свое дерево квитанций. Здесь `path` (путь) — это `rlp(transactionIndex)`. `transactionIndex` — это его индекс в блоке, в который он был включен. Дерево квитанций никогда не обновляется. Подобно дереву транзакций, существуют текущие и устаревшие квитанции. Для запроса конкретной квитанции в дереве квитанций требуются индекс транзакции в ее блоке, полезная нагрузка квитанции и тип транзакции. Возвращенная квитанция может быть типа `Receipt`, который определяется как конкатенация `TransactionType` и `ReceiptPayload`, или типа `LegacyReceipt`, который определяется как `rlp([status, cumulativeGasUsed, logsBloom, logs])`.
+
+Более подробную информацию об этом можно найти в документации [EIP 2718](https://eips.ethereum.org/EIPS/eip-2718).
+
+## Дополнительные материалы {#further-reading}
+
+- [Модифицированное дерево Меркла-Патрисии — как Ethereum сохраняет состояние](https://medium.com/codechain/modified-merkle-patricia-trie-how-ethereum-saves-a-state-e6d7555078dd)
+- [Мерклизация в Ethereum](https://blog.ethereum.org/2015/11/15/merkling-in-ethereum/)
+- [Понимание дерева Ethereum](https://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/)
diff --git a/public/content/translations/ru/developers/docs/data-structures-and-encoding/rlp/index.md b/public/content/translations/ru/developers/docs/data-structures-and-encoding/rlp/index.md
new file mode 100644
index 00000000000..12d730daa3c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-structures-and-encoding/rlp/index.md
@@ -0,0 +1,163 @@
+---
+title: "Recursive-length prefix (RLP) кодирование"
+description: "Описание кодирования RLP в слое выполнения Ethereum."
+lang: ru
+sidebarDepth: 2
+---
+
+Сериализация с помощью рекурсивной длинны префикса (RLP) обширно используется в клиентах сети Ethereum. RLP стандартизирует передачу данных между узлами в пространственно эффективном формате. Цель RLP - кодировать произвольное количество вложенных массивов двоичных данных. RLP - это метод первичной кодировки, используемый для сериализации объектов в исполнительном слое Ethereum. Основное предназначение RLP — кодировать структуру; за исключением положительных целых чисел, RLP делегирует кодирование определенных типов данных (например, строк, чисел с плавающей запятой) протоколам более высокого порядка. Положительные целые числа должны быть представлены в двоичном виде с прямым порядком байтов без ведущих нулей (таким образом, целочисленное значение ноль эквивалентно пустому байтовому массиву). Десериализованные положительные целые числа с ведущими нулями должны рассматриваться как недействительные любым протоколом более высокого порядка, использующим RLP.
+
+Больше информации в [Желтой книге Ethereum (Приложение B)](https://ethereum.github.io/yellowpaper/paper.pdf#page=19).
+
+Для использования RLP при кодировании словаря предлагаются следующие две канонические формы:
+
+- используйте `[[k1,v1],[k2,v2]...]` с ключами в лексикографическом порядке
+- использовать более высокоуровневую кодировку Patricia Tree как Ethereum
+
+## Определение {#definition}
+
+Функция кодирования RLP принимает один из элементов. Элемент определяется следующим образом:
+
+- строка (т. е. массив байтов) является элементом
+- список элементов - элемент
+- положительное целое число является элементом
+
+Например, все следующие пункты - элементы:
+
+- пустая строка;
+- строка, содержащая слово "cat";
+- список, содержащий любое количество строк;
+- и более сложные структуры данных, такие как `["cat", ["puppy", "cow"], "horse", [[]], "pig", [""], "sheep"]`.
+- число `100`
+
+Обратите внимание, что в контексте остальной части этой страницы «строка» означает «определенное количество байтов двоичных данных»; никакие специальные кодировки не используются и никакие сведения о содержании строк не подразумеваются (за исключением случаев, когда это требуется правилом, запрещающим неминимальные положительные целые числа).
+
+Кодирование RLP определяется следующим образом:
+
+- Для положительного целого числа оно преобразуется в кратчайший байтовый массив, интерпретация которого с прямым порядком байтов (big-endian) является целым числом, а затем кодируется как строка в соответствии с приведенными ниже правилами.
+- Для одного байта, значение которого находится в диапазоне `[0x00, 0x7f]` (десятичное `[0, 127]`), этот байт является своей собственной RLP-кодировкой.
+- В противном случае, если строка имеет длину 0–55 байтов, кодировка RLP состоит из одного байта со значением **0x80** (десятичное 128) плюс длина строки, за которой следует сама строка. Таким образом, диапазон первого байта: `[0x80, 0xb7]` (десятичное `[128, 183]`).
+- Если строка длиннее 55 байтов, кодировка RLP состоит из одного байта со значением **0xb7** (десятичное 183) плюс длина в байтах длины строки в двоичной форме, за которой следует длина строки, а затем сама строка. Например, строка длиной 1024 байта будет закодирована как `\xb9\x04\x00` (десятичное `185, 4, 0`), за которой следует сама строка. Здесь `0xb9` (183 + 2 = 185) — это первый байт, за которым следуют 2 байта `0x0400` (десятичное 1024), которые обозначают длину фактической строки. Таким образом, диапазон первого байта: `[0xb8, 0xbf]` (десятичное `[184, 191]`).
+- Если строка имеет длину 2^64 байтов или больше, ее нельзя закодировать.
+- Если общая полезная нагрузка списка (т. е. общая длина всех его RLP-кодированных элементов) составляет 0–55 байт, кодировка RLP состоит из одного байта со значением **0xc0** плюс длина полезной нагрузки, за которой следует конкатенация RLP-кодировок элементов. Таким образом, диапазон первого байта: `[0xc0, 0xf7]` (десятичное `[192, 247]`).
+- Если общая полезная нагрузка списка превышает 55 байт, кодировка RLP состоит из одного байта со значением **0xf7** плюс длина в байтах длины полезной нагрузки в двоичной форме, за которой следует длина полезной нагрузки, а затем — конкатенация RLP-кодировок элементов. Таким образом, диапазон первого байта: `[0xf8, 0xff]` (десятичное `[248, 255]`).
+
+В коде это выражается как:
+
+```python
+def rlp_encode(input):
+ if isinstance(input,str):
+ if len(input) == 1 and ord(input) < 0x80:
+ return input
+ return encode_length(len(input), 0x80) + input
+ elif isinstance(input, list):
+ output = ''
+ for item in input:
+ output += rlp_encode(item)
+ return encode_length(len(output), 0xc0) + output
+
+def encode_length(L, offset):
+ if L < 56:
+ return chr(L + offset)
+ elif L < 256**8:
+ BL = to_binary(L)
+ return chr(len(BL) + offset + 55) + BL
+ raise Exception("слишком длинные входные данные")
+
+def to_binary(x):
+ if x == 0:
+ return ''
+ return to_binary(int(x / 256)) + chr(x % 256)
+```
+
+## Примеры: {#examples}
+
+- строка "dog" = [ 0x83, 'd', 'o', 'g' ]
+- список [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]`
+- пустая строка ('null') = `[ 0x80 ]`
+- пустой список = `[ 0xc0 ]`
+- целое число 0 = `[ 0x80 ]`
+- байт '\\x00' = `[ 0x00 ]`
+- байт '\\x0f' = `[ 0x0f ]`
+- байты '\\x04\\x00' = `[ 0x82, 0x04, 0x00 ]`
+- [теоретико-множественное представление](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) числа три, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]`
+- строка "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ...` , 'e', 'l', 'i', 't' ]`
+
+## Декодирование RLP {#rlp-decoding}
+
+В соответствии с правилами и процессами RLP кодирования, входными данными RLP декодирования является массив с бинарными данными. Процесс декодирования RLP следующий:
+
+1. в соответствии с первым байтом (т. е. префиксом) входных данных и декодирования типа данных, длины фактических данных и смещения;
+
+2. в соответствии с типом и смещением данных соответствующим образом декодируйте данные, соблюдая правило минимального кодирования для положительных целых чисел;
+
+3. продолжить декодирование остальных входных данных;
+
+Правила декодирования типов данных и смещения следующие:
+
+1. данные являются строкой, если диапазон первого байта (т. е. префикса) — [0x00, 0x7f], и строка — это в точности сам первый байт;
+
+2. данные являются строкой если значение первого байта (т.е. префикса) находится в промежутке [0x80, 0xb7] и последующей строкой, длина которой равно значению первого байта минус 0x80;
+
+3. данные являются строкой, если значение первого байта (т.е. префикса) находится в промежутке [0xb8, 0xbf] и длина строки чья длина в байтах равна значению первого байта минус 0xb7 после первого байта и последующая строка;
+
+4. данные являются списком, если значение первого байта находится в промежутке [0xc0, 0xf7], и конкатенация RLP кодирований всех элементов списка, следующего за первым байтом, равна значению первого байта минус 0xc0;
+
+5. данные являются списком, если диапазон первого байта — [0xf8, 0xff], и общая полезная нагрузка списка, длина которого равна значению первого байта минус 0xf7, следует за первым байтом, и конкатенация RLP-кодировок всех элементов списка следует за общей полезной нагрузкой списка;
+
+В коде это выражается как:
+
+```python
+def rlp_decode(input):
+ if len(input) == 0:
+ return
+ output = ''
+ (offset, dataLen, type) = decode_length(input)
+ if type is str:
+ output = instantiate_str(substr(input, offset, dataLen))
+ elif type is list:
+ output = instantiate_list(substr(input, offset, dataLen))
+ output += rlp_decode(substr(input, offset + dataLen))
+ return output
+
+def decode_length(input):
+ length = len(input)
+ if length == 0:
+ raise Exception("входные данные — null")
+ prefix = ord(input[0])
+ if prefix <= 0x7f:
+ return (0, 1, str)
+ elif prefix <= 0xb7 and length > prefix - 0x80:
+ strLen = prefix - 0x80
+ return (1, strLen, str)
+ elif prefix <= 0xbf and length > prefix - 0xb7 and length > prefix - 0xb7 + to_integer(substr(input, 1, prefix - 0xb7)):
+ lenOfStrLen = prefix - 0xb7
+ strLen = to_integer(substr(input, 1, lenOfStrLen))
+ return (1 + lenOfStrLen, strLen, str)
+ elif prefix <= 0xf7 and length > prefix - 0xc0:
+ listLen = prefix - 0xc0;
+ return (1, listLen, list)
+ elif prefix <= 0xff and length > prefix - 0xf7 and length > prefix - 0xf7 + to_integer(substr(input, 1, prefix - 0xf7)):
+ lenOfListLen = prefix - 0xf7
+ listLen = to_integer(substr(input, 1, lenOfListLen))
+ return (1 + lenOfListLen, listLen, list)
+ raise Exception("входные данные не соответствуют формату кодировки RLP")
+
+def to_integer(b):
+ length = len(b)
+ if length == 0:
+ raise Exception("входные данные — null")
+ elif length == 1:
+ return ord(b[0])
+ return ord(substr(b, -1)) + to_integer(substr(b, 0, -1)) * 256
+```
+
+## Дополнительные материалы {#further-reading}
+
+- [RLP в Ethereum](https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-recursive-length-prefix-rlp-encoding-decoding-d1016832f919)
+- [Ethereum изнутри: RLP](https://medium.com/coinmonks/ethereum-under-the-hood-part-3-rlp-decoding-df236dc13e58)
+- [Coglio, A. (2020). Ethereum's Recursive Length Prefix in ACL2. arXiv preprint arXiv:2009.13769.](https://arxiv.org/abs/2009.13769)
+
+## Смежные темы {#related-topics}
+
+- [Дерево Меркла — Патриции](/developers/docs/data-structures-and-encoding/patricia-merkle-trie)
diff --git a/public/content/translations/ru/developers/docs/data-structures-and-encoding/ssz/index.md b/public/content/translations/ru/developers/docs/data-structures-and-encoding/ssz/index.md
new file mode 100644
index 00000000000..bec07335190
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-structures-and-encoding/ssz/index.md
@@ -0,0 +1,150 @@
+---
+title: "Простая сериализация"
+description: "Объяснение формата SSZ в Ethereum."
+lang: ru
+sidebarDepth: 2
+---
+
+**Простая сериализация (SSZ)** — это метод сериализации, используемый в сети Beacon. Она заменяет сериализацию RLP, используемую на уровне исполнения, везде на уровне консенсуса, за исключением протокола обнаружения пиров. Чтобы узнать больше о сериализации RLP, см. [Префикс рекурсивной длины (RLP)](/developers/docs/data-structures-and-encoding/rlp/). SSZ разработан, чтобы быть детерминированным, а также эффективно мерклизировать данные. SSZ можно рассматривать как состоящий из двух компонентов: схемы сериализации и схемы мерклизации, которая предназначена для эффективной работы с сериализованной структурой данных.
+
+## Как работает SSZ? {#how-does-ssz-work}
+
+### Сериализация {#serialization}
+
+SSZ — это схема сериализации, которая не является самоописываемой, а полагается на схему, которая должна быть известна заранее. Цель сериализации SSZ — представить объекты произвольной сложности в виде строк байтов. Для "базовых типов" это очень простой процесс. Элемент просто преобразуется в шестнадцатеричные байты. К базовым типам относятся:
+
+- целые числа без знака
+- логические значения
+
+Для сложных "составных" типов сериализация сложнее, поскольку составной тип содержит несколько элементов, которые могут иметь разные типы, разные размеры или и то, и другое. Если все эти объекты имеют фиксированную длину (т. е. размер элементов всегда будет постоянным независимо от их фактических значений), сериализация — это просто преобразование каждого элемента составного типа, упорядоченного в байтовые строки little-endian. Эти байтовые строки соединяются вместе. Сериализованный объект имеет представление в виде списка байтов элементов фиксированной длины в том же порядке, в котором они появляются в десериализованном объекте.
+
+Для типов с переменной длиной фактические данные заменяются значением "смещения" в позиции этого элемента в сериализованном объекте. Фактические данные добавляются в «кучу» (heap) в конце сериализованного объекта. Значение смещения — это индекс начала фактических данных в куче, действующий как указатель на соответствующие байты.
+
+Приведенный ниже пример иллюстрирует, как работает смещение для контейнера с элементами как фиксированной, так и переменной длины:
+
+```Rust
+
+ struct Dummy {
+
+ number1: u64,
+ number2: u64,
+ vector: Vec,
+ number3: u64
+ }
+
+ dummy = Dummy{
+
+ number1: 37,
+ number2: 55,
+ vector: vec![1,2,3,4],
+ number3: 22,
+ }
+
+ serialized = ssz.serialize(dummy)
+
+```
+
+`serialized` будет иметь следующую структуру (здесь дополнено до 4 бит, в реальности дополняется до 32 бит, а для ясности сохранено представление `int`):
+
+```
+[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]
+------------ ----------- ----------- ----------- ----------
+ | | | | |
+ число1 число2 смещение для число3 значение для
+ вектора вектора
+
+```
+
+для ясности разделено по строкам:
+
+```
+[
+ 37, 0, 0, 0, # кодирование `number1` в формате little-endian.
+ 55, 0, 0, 0, # кодирование `number2` в формате little-endian.
+ 16, 0, 0, 0, # "Смещение", которое указывает, где начинается значение `vector` (16 в формате little-endian).
+ 22, 0, 0, 0, # кодирование `number3` в формате little-endian.
+ 1, 2, 3, 4, # Фактические значения в `vector`.
+]
+```
+
+Это все еще упрощение: целые числа и нули в приведенных выше схемах на самом деле будут храниться в виде списков байтов, вот так:
+
+```
+[
+ 10100101000000000000000000000000 # кодирование `number1` в формате little-endian
+ 10110111000000000000000000000000 # кодирование `number2` в формате little-endian.
+ 10010000000000000000000000000000 # "Смещение", которое указывает, где начинается значение `vector` (16 в формате little-endian).
+ 10010110000000000000000000000000 # кодирование `number3` в формате little-endian.
+ 10000001100000101000001110000100 # Фактическое значение поля `bytes`.
+]
+```
+
+Таким образом, фактические значения для типов переменной длины хранятся в куче в конце сериализованного объекта, а их смещения хранятся на своих правильных позициях в упорядоченном списке полей.
+
+Существуют также некоторые особые случаи, требующие специальной обработки, например, тип `BitList`, который требует добавления ограничения длины во время сериализации и удаления во время десериализации. Полная информация доступна в [спецификации SSZ](https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md).
+
+### Десериализация {#deserialization}
+
+Для десериализации этого объекта требуется схема. Схема определяет точную компоновку сериализованных данных, так что каждый конкретный элемент может быть десериализован из большого двоичного объекта (blob) байтов в некий осмысленный объект с элементами, имеющими правильный тип, значение, размер и положение. Именно схема сообщает десериализатору, какие значения являются фактическими, а какие — смещениями. Все имена полей исчезают при сериализации объекта, но восстанавливаются при десериализации в соответствии со схемой.
+
+Смотрите [ssz.dev](https://www.ssz.dev/overview) для интерактивного объяснения этого.
+
+## Мерклизация {#merkleization}
+
+Затем этот сериализованный объект SSZ может быть мерклизирован, то есть преобразован в представление тех же данных в виде дерева Меркла. Сначала определяется количество 32-байтовых фрагментов в сериализованном объекте. Это "листья" дерева. Общее количество листьев должно быть степенью двойки, чтобы хеширование листьев в конечном итоге дало один корневой хэш дерева. Если это не так, добавляются дополнительные листья, содержащие 32 байта нулей. Схематично:
+
+```
+ корневой хэш дерева
+ / \
+ / \
+ / \
+ / \
+ хэш листьев хэш листьев
+ 1 и 2 3 и 4
+ / \ / \
+ / \ / \
+ / \ / \
+ лист1 лист2 лист3 лист4
+```
+
+Также бывают случаи, когда листья дерева естественным образом распределяются не так равномерно, как в примере выше. Например, лист 4 может быть контейнером с несколькими элементами, которые требуют добавления дополнительной "глубины" в дерево Меркла, создавая неровное дерево.
+
+Вместо того, чтобы называть эти элементы дерева «лист X», «узел X» и т. д., мы можем дать им обобщенные индексы, начиная с корня = 1 и считая слева направо на каждом уровне. Это обобщенный индекс, объясненный выше. Каждый элемент в сериализованном списке имеет обобщенный индекс, равный `2**depth + idx`, где idx — это его позиция с нулевым индексом в сериализованном объекте, а глубина — это количество уровней в дереве Меркла, которое можно определить как двоичный логарифм количества элементов (листьев).
+
+## Обобщенные индексы {#generalized-indices}
+
+Обобщенный индекс — это целое число, которое представляет узел в двоичном дереве Меркла, где каждый узел имеет обобщенный индекс `2 ** depth + index in row`.
+
+```
+ 1 --глубина = 0 2**0 + 0 = 1
+ 2 3 --глубина = 1 2**1 + 0 = 2, 2**1+1 = 3
+ 4 5 6 7 --глубина = 2 2**2 + 0 = 4, 2**2 + 1 = 5...
+
+```
+
+Это представление дает индекс узла для каждого фрагмента данных в дереве Меркла.
+
+## Мультидоказательства {#multiproofs}
+
+Предоставление списка обобщенных индексов, представляющих конкретный элемент, позволяет нам проверить его по корневому хэшу дерева. Этот корень является нашей принятой версией реальности. Любые предоставленные нам данные могут быть проверены на соответствие этой реальности путем вставки их в нужное место в дереве Меркла (определяемое его обобщенным индексом) и наблюдения за тем, что корень остается постоянным. В спецификации [здесь](https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md#merkle-multiproofs) есть функции, которые показывают, как вычислить минимальный набор узлов, необходимый для проверки содержимого определенного набора обобщенных индексов.
+
+Например, чтобы проверить данные в индексе 9 в дереве ниже, нам нужен хэш данных в индексах 8, 9, 5, 3, 1.
+Хэш (8,9) должен быть равен хэшу (4), который хешируется с 5 для получения 2, который хешируется с 3 для получения корня дерева 1. Если для 9 были предоставлены неверные данные, корень изменится — мы обнаружим это, и проверка ветви не удастся.
+
+```
+* = данные, необходимые для генерации доказательства
+
+ 1*
+ 2 3*
+ 4 5* 6 7
+8* 9* 10 11 12 13 14 15
+
+```
+
+## Дополнительные материалы {#further-reading}
+
+- [Обновление Ethereum: SSZ](https://eth2book.info/altair/part2/building_blocks/ssz)
+- [Обновление Ethereum: мерклизация](https://eth2book.info/altair/part2/building_blocks/merkleization)
+- [Реализации SSZ](https://github.com/ethereum/consensus-specs/issues/2138)
+- [Калькулятор SSZ](https://simpleserialize.com/)
+- [SSZ.dev](https://www.ssz.dev/)
diff --git a/public/content/translations/ru/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md b/public/content/translations/ru/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md
new file mode 100644
index 00000000000..6fbb05b7cd5
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md
@@ -0,0 +1,195 @@
+---
+title: "Определение секретного хранилища Web3"
+description: "Формальное определение для секретного хранилища web3"
+lang: ru
+sidebarDepth: 2
+---
+
+Чтобы ваше приложение работало на Ethereum, вы можете использовать объект web3, предоставляемый библиотекой web3.js. Под капотом он взаимодействует с локальным узлом через вызовы RPC. [web3](https://github.com/ethereum/web3.js/) работает с любым узлом Ethereum, который предоставляет уровень RPC.
+
+`web3` содержит объект `eth` — web3.eth.
+
+```js
+var fs = require("fs")
+var recognizer = require("ethereum-keyfile-recognizer")
+
+fs.readFile("keyfile.json", (err, data) => {
+ var json = JSON.parse(data)
+ var result = recognizer(json)
+})
+
+/** result
+ * [ 'web3', 3 ] файл ключей web3 (v3)
+ * [ 'ethersale', undefined ] файл ключей Ethersale
+ * null недействительный файл ключей
+ */
+```
+
+Этот документ описывает **версию 3** определения секретного хранилища Web3.
+
+## Определение {#definition}
+
+Фактическое кодирование и декодирование файла в значительной степени не изменилось по сравнению с версией 1, за исключением того, что криптоалгоритм больше не привязан к AES-128-CBC (теперь минимальным требованием является AES-128-CTR). Большинство значений/алгоритм похожи на версию 1, за исключением `mac`, который задается как SHA3 (keccak-256) от конкатенации вторых слева 16 байт производного ключа вместе с полным `ciphertext`.
+
+Файлы секретных ключей хранятся непосредственно в `~/.web3/keystore` (для Unix-подобных систем) и `~/AppData/Web3/keystore` (для Windows). Им можно давать любые имена, но хорошим соглашением является `.json`, где `` — это 128-битный UUID, присвоенный секретному ключу (прокси, сохраняющий конфиденциальность, для адреса секретного ключа).
+
+Все такие файлы имеют связанный с ними пароль. Чтобы получить секретный ключ из заданного `.json`-файла, сначала получите ключ шифрования файла; это делается путем получения пароля файла и его передачи через функцию получения ключа, как описано ключом `kdf`. Статические и динамические параметры, зависящие от KDF, для функции KDF описаны в ключе `kdfparams`.
+
+PBKDF2 должен поддерживаться всеми минимально совместимыми реализациями, что обозначается через:
+
+- `kdf`: `pbkdf2`
+
+Для PBKDF2 kdfparams включают:
+
+- `prf`: должен быть `hmac-sha256` (может быть расширен в будущем);
+- `c`: количество итераций;
+- `salt`: соль, передаваемая в PBKDF;
+- `dklen`: длина производного ключа. Должно быть >= 32.
+
+После получения ключа файла его следует проверить путем выведения MAC. MAC должен быть вычислен как хэш SHA3 (keccak-256) массива байтов, образованного путем конкатенации вторых слева 16 байт производного ключа с содержимым ключа `ciphertext`, т. е.:
+
+```js
+KECCAK(DK[16..31] ++ )
+```
+
+(где `++` — это оператор конкатенации)
+
+Это значение следует сравнить с содержимым ключа `mac`; если они отличаются, следует запросить другой пароль (или отменить операцию).
+
+После проверки ключа файла шифротекст (ключ `ciphertext` в файле) может быть расшифрован с помощью алгоритма симметричного шифрования, указанного ключом `cipher` и параметризованного через ключ `cipherparams`. Если размер производного ключа и размер ключа алгоритма не совпадают, в качестве ключа для алгоритма следует использовать крайние правые байты производного ключа, дополненные нулями.
+
+Все минимально совместимые реализации должны поддерживать алгоритм AES-128-CTR, что обозначается через:
+
+- `cipher: aes-128-ctr`
+
+Этот шифр принимает следующие параметры, указанные в качестве ключей для ключа cipherparams:
+
+- `iv`: 128-битный вектор инициализации для шифра.
+
+Ключ для шифра представляет собой крайние левые 16 байт производного ключа, т. е. `DK[0..15]`
+
+Создание/шифрование секретного ключа должно быть, по сути, обратным этим инструкциям. Убедитесь, что `uuid`, `salt` и `iv` действительно случайны.
+
+В дополнение к полю `version`, которое должно выступать в качестве «жесткого» идентификатора версии, реализации могут также использовать `minorversion` для отслеживания небольших, некритичных изменений в формате.
+
+## Тестовые векторы {#test-vectors}
+
+Подробности:
+
+- `Адрес`: `008aeeda4d805471df9b2a5b0f38a0c3bcba786b`
+- `ICAP`: `XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67`
+- `UUID`: `3198bc9c-6672-5ab3-d9954942343ae5b6`
+- `Пароль`: `testpassword`
+- `Секрет`: `7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d`
+
+### PBKDF2-SHA-256 {#PBKDF2-SHA-256}
+
+Тестовый вектор с использованием `AES-128-CTR` и `PBKDF2-SHA-256`:
+
+Содержимое файла `~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json`:
+
+```json
+{
+ "crypto": {
+ "cipher": "aes-128-ctr",
+ "cipherparams": {
+ "iv": "6087dab2f9fdbbfaddc31a909735c1e6"
+ },
+ "ciphertext": "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46",
+ "kdf": "pbkdf2",
+ "kdfparams": {
+ "c": 262144,
+ "dklen": 32,
+ "prf": "hmac-sha256",
+ "salt": "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd"
+ },
+ "mac": "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2"
+ },
+ "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
+ "version": 3
+}
+```
+
+**Промежуточные значения**:
+
+`Производный ключ`: `f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551`
+`Тело MAC`: `e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46`
+`MAC`: `517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2`
+`Ключ шифра`: `f06d69cdc7da0faffb1008270bca38f5`
+
+### Scrypt {#scrypt}
+
+Тестовый вектор с использованием AES-128-CTR и Scrypt:
+
+```json
+{
+ "crypto": {
+ "cipher": "aes-128-ctr",
+ "cipherparams": {
+ "iv": "740770fce12ce862af21264dab25f1da"
+ },
+ "ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2",
+ "kdf": "scrypt",
+ "kdfparams": {
+ "dklen": 32,
+ "n": 262144,
+ "p": 1,
+ "r": 8,
+ "salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034"
+ },
+ "mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c"
+ },
+ "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
+ "version": 3
+}
+```
+
+**Промежуточные значения**:
+
+`Производный ключ`: `7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d`
+`Тело MAC`: `edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2`
+`MAC`: `337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c`
+`Ключ шифра`: `7446f59ecc301d2d79bc3302650d8a5c`
+
+## Изменения по сравнению с версией 1 {#alterations-from-v2}
+
+Эта версия исправляет несколько несоответствий с версией 1, опубликованной [здесь](https://github.com/ethereum/homestead-guide/blob/master/old-docs-for-reference/go-ethereum-wiki.rst/Passphrase-protected-key-store-spec.rst). Вкратце это:
+
+- Использование заглавных букв необоснованно и непоследовательно (scrypt в нижнем регистре, Kdf в смешанном регистре, MAC в верхнем регистре).
+- Адрес не является необходимым и нарушает конфиденциальность.
+- `Salt` по своей сути является параметром функции получения ключа и заслуживает того, чтобы быть связанным с ней, а не с криптографией в целом.
+- _SaltLen_ не является необходимым (просто получите его из Salt).
+- Функция получения ключа задана, однако криптографический алгоритм жестко задан.
+- `Version` по своей сути является числом, но при этом является строкой (структурированное управление версиями было бы возможно со строкой, но это можно считать выходящим за рамки редко меняющегося формата файла конфигурации).
+- `KDF` и `cipher` условно являются родственными понятиями, но организованы по-разному.
+- `MAC` вычисляется с помощью данных, не зависящих от пробелов (!)
+
+В формат были внесены изменения, чтобы получить следующий файл, функционально эквивалентный примеру, приведенному на ранее упомянутой странице:
+
+```json
+{
+ "crypto": {
+ "cipher": "aes-128-cbc",
+ "ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b",
+ "cipherparams": {
+ "iv": "16d67ba0ce5a339ff2f07951253e6ba8"
+ },
+ "kdf": "scrypt",
+ "kdfparams": {
+ "dklen": 32,
+ "n": 262144,
+ "p": 1,
+ "r": 8,
+ "salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91"
+ },
+ "mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd",
+ "version": 1
+ },
+ "id": "0498f19a-59db-4d54-ac95-33901b4f1870",
+ "version": 2
+}
+```
+
+## Изменения по сравнению с версией 2 {#alterations-from-v2}
+
+Версия 2 была ранней реализацией на C++ с рядом ошибок. Все основные элементы остались без изменений.
diff --git a/public/content/translations/ru/developers/docs/design-and-ux/dex-design-best-practice/index.md b/public/content/translations/ru/developers/docs/design-and-ux/dex-design-best-practice/index.md
new file mode 100644
index 00000000000..1262787dc0f
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/design-and-ux/dex-design-best-practice/index.md
@@ -0,0 +1,220 @@
+---
+title: "Лучшие практики дизайна децентрализованных бирж (DEX)"
+description: "Руководство по UX/UI-решениям для обмена токенами."
+lang: ru
+---
+
+С момента запуска Uniswap в 2018 году появились сотни децентрализованных бирж на десятках различных блокчейнов.
+Многие из них внедрили новые элементы либо добавили свои характерные особенности, однако, в целом интерфейс остался неизменным.
+
+Одной из причин этого является [Закон Якоба](https://lawsofux.com/jakobs-law/):
+
+> Пользователи проводят большую часть своего времени на других сайтах. Это означает, что пользователи предпочитают, чтобы ваш сайт работал так же, как другие, которые они уже знают.
+
+Благодаря ранним инноваторам, таким как Uniswap, Pancakeswap, и Sushiswap, пользователи DeFi имеют общее представление о том, как должна выглядеть децентрализованная биржа.
+В связи с этим начали появляться определенные «лучшие практики». Мы все чаще встречаем дизайнерские решения, стандартизируемые на разных сайтах. Эволюцию DEX можно рассматривать как масштабный пример тестирования этих практик в реальном времени. То, что срабатывало, осталось, а то, что не работало, было исключено. Несмотря на то, что еще остались возможности для персонализации сайта, существуют определенные стандарты, которым должна соответствовать децентрализованная биржа.
+
+Данная статья является кратким обобщением следующих тем:
+
+- что следует включить
+- как сделать сайт максимально удобным в использовании
+- каковы основные способы кастоматизации дизайна
+
+Все рассматриваемые каркасные примеры были созданы специально для этой статьи, хотя все они базируются на основе реальных проектов.
+
+В конце публикации вы также найдете комплект Figma — не стесняйтесь использовать его, чтобы ускорить создание собственных каркасных сайтов!
+
+## Анатомия DEX {#basic-anatomy-of-a-dex}
+
+Пользовательский интерфейс (UI) обычно состоит из трех элементов:
+
+1. Основная форма
+2. Кнопка
+3. Панель описания
+
+
+
+## Вариации {#variations}
+
+В этой статье мы еще несколько раз вернемся к теме того, что элементы могут быть организованы различными способами. «Панель описания» может находиться:
+
+- Над кнопкой
+- Под кнопкой
+- Быть скрытой в панели-аккордеоне
+- И/или находиться в модальном окне «предварительного просмотра»
+
+Примечание. Модальное окно «предварительного просмотра» является опциональным, но необходимым в случае, когда основной интерфейс отображает очень мало деталей.
+
+## Структура основной формы {#structure-of-the-main-form}
+
+Это именно то поле, в котором вы выбираете токен для обмена. Компонент состоит из поля ввода и небольшой кнопки, расположенных в одной строке.
+
+На децентрализованных биржах дополнительные детали обычно отображаются одной строкой выше и одной строкой ниже, хотя этот параметр может быть настроен иным образом.
+
+
+
+## Вариации {#variations2}
+
+Здесь показаны два варианта интерфейса: один без границ, что создает открытый дизайн, и один, где строка ввода имеет границу, что акцентирует внимание на этом элементе.
+
+
+
+Эта базовая структура позволяет отображать в дизайне **четыре ключевых элемента информации**: по одному в каждом углу. В случае, когда предусмотрена только одна строка сверху/снизу, будут доступны только два элемента.
+
+В ходе эволюции DeFi сюда было включено множество различных вещей.
+
+## Ключевая информация, требующая добавления {#key-info-to-include}
+
+- Баланс кошелька
+- Кнопка «Максимум»
+- Эквивалент в фиатной валюте
+- Влияние цены на сумму «получения»
+
+На заре DeFi фиатный эквивалент часто отсутствовал. Если вы создаете какой-либо проект Web3, крайне важно, чтобы отображался фиатный эквивалент. Пользователи по-прежнему мыслят в категориях местных валют, поэтому, чтобы соответствовать реальным ментальным моделям, это следует включить.
+
+Во втором поле (где вы выбираете токен, на который обмениваете) вы также можете указать влияние на цену рядом с суммой в фиатной валюте, рассчитав разницу между вводимой суммой и предполагаемой выходной суммой. Это довольно полезная деталь для включения.
+
+Кнопки с процентами (например, 25%, 50%, 75%) могут быть полезной функцией, но они занимают больше места, добавляют больше призывов к действию и увеличивают умственную нагрузку. То же самое с процентными ползунками. Некоторые из этих решений по пользовательскому интерфейсу будут зависеть от вашего бренда и типа пользователя.
+
+Дополнительные детали могут быть показаны под основной формой. Поскольку подобная информация в основном предназначена для опытных пользователей, имеет смысл либо:
+
+- свести её количество к минимуму, или;
+- скрыть её в панели-аккордеоне
+
+
+
+## Дополнительная информация, требующая добавления {#extra-info-to-include}
+
+- Ценой токена
+- Проскальзывание
+- Полученный минимум
+- Ожидаемая сумма получения
+- Влияние на цену
+- Предполагаемая стоимость газа
+- Другие комиссии
+- Маршрутизация ордера
+
+Возможно, некоторые из этих деталей могут быть необязательными.
+
+Маршрутизация ордеров интересна, но для большинства пользователей не имеет большого значения.
+
+Некоторые другие детали — это просто изложение одного и того же разными способами. Например, «минимально полученное» и «проскальзывание» — это две стороны одной медали. Если у вас установлено проскальзывание в 1%, то минимальная сумма, которую вы можете ожидать получить = ожидаемый результат - 1%. Некоторые пользовательские интерфейсы будут показывать ожидаемую сумму, минимальную сумму и проскальзывание… Что полезно, но, возможно, излишне.
+
+Большинство пользователей в любом случае оставят проскальзывание по умолчанию.
+
+«Влияние на цену» часто указывается в скобках рядом с фиатным эквивалентом в поле «кому». Это отличная деталь UX для добавления, но если она показана здесь, нужно ли ее снова показывать ниже? А затем снова на экране предварительного просмотра?
+
+Многие пользователи (особенно те, кто обменивает небольшие суммы) не будут обращать внимания на эти детали; они просто введут число и нажмут кнопку "Обменять".
+
+
+
+То, какие именно детали будут показаны, будет зависеть от вашей аудитории и того, какое ощущение вы хотите, чтобы ваше приложение вызывало.
+
+Если вы включаете допуск проскальзывания в панель сведений, вы также должны сделать его редактируемым непосредственно отсюда. Это хороший пример «ускорителя»; изящный UX-трюк, который может ускорить рабочие процессы опытных пользователей, не влияя на общую юзабилити приложения.
+
+
+
+Хорошая идея — тщательно продумать не только один конкретный фрагмент информации на одном экране, но и весь процесс:
+Ввод чисел в основной форме → сканирование деталей → переход к экрану предварительного просмотра (если у вас есть экран предварительного просмотра).
+Должна ли панель сведений быть видна постоянно, или пользователю нужно нажать на нее, чтобы развернуть?
+Стоит ли создавать трение, добавляя экран предварительного просмотра? Это заставляет пользователя замедлиться и обдумать свою сделку, что может быть полезно. Но хотят ли они снова видеть ту же самую информацию? Что для них наиболее полезно в данный момент?
+
+## Варианты дизайна {#design-options}
+
+Как уже упоминалось, многое зависит от вашего личного стиля
+Кто ваш пользователь?
+Какой у вас бренд?
+Вы хотите «профессиональный» интерфейс, показывающий каждую деталь, или вы хотите быть минималистом?
+Даже если вы нацелены на профессиональных пользователей, которые хотят получить всю возможную информацию, вы все равно должны помнить мудрые слова Алана Купера:
+
+> Каким бы красивым, каким бы крутым ни был ваш интерфейс, было бы лучше, если бы его было меньше.
+
+### Структура {#structure}
+
+- токены слева или токены справа
+- 2 строки или 3
+- детали над или под кнопкой
+- детали развернуты, свернуты или не показаны
+
+### Стиль компонентов {#component-style}
+
+- пустой
+- подчеркнутый
+- заполненный
+
+С точки зрения чистого UX, стиль пользовательского интерфейса имеет меньшее значение, чем вы думаете. Визуальные тренды приходят и уходят циклически, и многие предпочтения субъективны.
+
+Самый простой способ прочувствовать это — и подумать о различных конфигурациях — это взглянуть на некоторые примеры, а затем поэкспериментировать самостоятельно.
+
+Прилагаемый набор Figma содержит пустые, контурные и заполненные компоненты.
+
+Взгляните на приведенные ниже примеры, чтобы увидеть различные способы, которыми вы можете все это собрать:
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Но с какой стороны должен быть токен? {#but-which-side-should-the-token-go-on}
+
+Суть в том, что, вероятно, это не имеет большого значения для удобства использования. Однако есть несколько моментов, которые могут склонить вас в ту или иную сторону.
+
+Было довольно интересно наблюдать, как мода меняется со временем. Изначально в Uniswap токен располагался слева, но затем его переместили вправо. Sushiswap также внес это изменение во время апгрейда дизайна. Большая часть протоколов (если не все) с тех пор поступили также.
+
+Финансовые соглашения традиционно предписывают ставить символ валюты перед числом, например, $50, €50, £50, но мы _говорим_ 50 долларов, 50 евро, 50 фунтов.
+
+Для обычного пользователя — особенно для того, кто читает слева направо, сверху вниз, — название токена справа, скорее всего, кажется более естественным.
+
+
+
+Размещение токена слева, а всех чисел справа выглядит довольно симметрично, что является плюсом, но у такого интерфейса есть и другой минус.
+
+Закон близости гласит, что предметы, расположенные близко друг к другу, воспринимаются как связанные. Соответственно, мы хотим размещать связанные элементы рядом друг с другом. Баланс токена напрямую связан с самим токеном и будет меняться при выборе нового токена. Поэтому имеет немного больше смысла, чтобы баланс токена находился рядом с кнопкой выбора токена. Его можно было бы переместить под токен, но это нарушает симметрию макета.
+
+В конечном счете, у обоих вариантов есть свои плюсы и минусы, но интересно, как тенденция, по-видимому, склоняется к токену справа.
+
+## Поведение кнопки {#button-behavior}
+
+Не создавайте отдельную кнопку для подтверждения. Также не делайте отдельный клик для подтверждения. Пользователь хочет обменять, поэтому просто напишите «обменять» на кнопке и инициируйте подтверждение как первый шаг. Модальное окно может показывать прогресс с помощью пошагового индикатора или простого уведомления «транзакция 1 из 2 — подтверждение».
+
+
+
+
+
+### Кнопка как контекстная помощь {#button-as-contextual-help}
+
+Кнопка может выполнять двойную функцию — быть предупреждением!
+
+На самом деле это довольно необычный шаблон проектирования за пределами Web3, но он стал стандартом внутри него. Это хорошая инновация, так как она экономит место и удерживает внимание.
+
+Если основное действие — ОБМЕН — недоступно из-за ошибки, причину можно объяснить с помощью кнопки, например:
+
+- сменить сеть
+- подключить кошелек
+- различные ошибки
+
+Кнопку также можно **привязать к действию**, которое необходимо выполнить. Например, если пользователь не может совершить обмен, потому что он находится в неправильной сети, кнопка должна гласить «переключиться на Ethereum», и когда пользователь нажимает на кнопку, она должна переключать сеть на Ethereum. Это значительно ускоряет поток пользователя.
+
+
+
+
+
+## Создайте свой собственный с помощью этого файла Figma {#build-your-own-with-this-figma-file}
+
+Благодаря усердной работе множества протоколов дизайн DEX значительно улучшился. Мы знаем, какая информация нужна пользователю, как мы должны ее показывать и как сделать поток максимально плавным.
+Надеемся, эта статья дает основательный обзор принципов UX.
+
+Если вы хотите поэкспериментировать, не стесняйтесь использовать набор каркасов Figma. Он максимально прост, но обладает достаточной гибкостью для построения базовой структуры различными способами.
+
+[Набор каркасов Figma](https://www.figma.com/community/file/1393606680816807382/dex-wireframes-kit)
+
+DeFi будет продолжать развиваться, и всегда есть место для улучшений.
+
+Удачи!
diff --git a/public/content/translations/ru/developers/docs/design-and-ux/heuristics-for-web3/index.md b/public/content/translations/ru/developers/docs/design-and-ux/heuristics-for-web3/index.md
new file mode 100644
index 00000000000..91b50945522
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/design-and-ux/heuristics-for-web3/index.md
@@ -0,0 +1,138 @@
+---
+title: "7 эвристик для дизайна интерфейса Web3"
+description: "Принципы для улучшения юзабилити Web3"
+lang: ru
+---
+
+Эвристики юзабилити — это общие «практические правила», которые можно использовать для оценки юзабилити вашего сайта.
+Приведенные здесь 7 эвристик специально адаптированы для Web3 и должны использоваться вместе с [10 общими принципами интерактивного дизайна](https://www.nngroup.com/articles/ten-usability-heuristics/) Якоба Нильсена.
+
+## Семь эвристик юзабилити для Web3 {#seven-usability-heuristics-for-web3}
+
+1. Обратная связь следует за действием
+2. Безопасность и доверие
+3. Наиболее важная информация очевидна
+4. Понятная терминология
+5. Действия должны быть как можно короче
+6. Подключения к сети должны быть видимыми и гибкими
+7. Управление из приложения, а не из кошелька
+
+## Определения и примеры {#definitions-and-examples}
+
+### 1. Обратная связь следует за действием {#feedback-follows-action}
+
+**Если что-то происходит или уже произошло, это должно быть очевидно.**
+
+Пользователи принимают решение о следующих шагах, основываясь на результатах предыдущих. Поэтому очень важно, чтобы они были в курсе статуса, в котором пребывает система. Это особенно важно для Web3, поскольку транзакции в блокчейне иногда подтверждаются за очень короткое время. Если пользователи не видят обратной связи, информирующей о необходимости подождать, они могут быть не уверены в том, что их действие было успешно или что что-либо вообще происходит на фоне.
+
+**Подсказки:**
+
+- Информируйте пользователя с помощью сообщений, уведомлений и других оповещений.
+- Четко информируйте о времени ожидания.
+- Если действие займет больше нескольких секунд, покажите пользователю таймер или анимацию, чтобы он знал, что что-то происходит.
+- Если процесс состоит из нескольких этапов, покажите каждый из них.
+
+**Пример:**
+Показывая информацию о каждом шаге транзакции, вы даёте пользователям знать, на каком этапе процесса они находятся. Соответствующие значки позволяют пользователю узнать статус своих действий.
+
+
+
+### 2. Безопасность и доверие встроены по умолчанию {#security-and-trust-are-backed-in}
+
+Безопасность должна быть в приоритете, и на этом следует делать акцент для пользователя.
+Людям очень важны их личные данные. Безопасность часто является основной проблемой для пользователей, поэтому ее следует учитывать на всех уровнях дизайна. Вы всегда должны стремиться завоевать доверие пользователей, но путь к достижению этой цели может быть совершенно разным в зависимости от приложения. Она не должна быть "последышем", а должна быть продумана от начала до конца. Укрепляйте доверие на протяжении всего пользовательского опыта, включая социальные сети и документацию, а также в конечном пользовательском интерфейсе. Такие вещи, как уровень децентрализации, статус мультиподписи казначейства и то, раскрыла ли команда свои личности, — все это влияет на доверие пользователей
+
+**Подсказки:**
+
+- С гордостью перечисляйте свои аудиты
+- Проведите несколько аудитов
+- Рекламируйте любые разработанные вами функции безопасности
+- Подчеркивайте возможные риски, включая базовые интеграции
+- Информируйте о сложности стратегий
+- Учитывайте проблемы, не связанные с пользовательским интерфейсом, которые могут повлиять на восприятие безопасности вашими пользователями
+
+**Пример:**
+Добавьте список ваших аудитов в нижний колонтитул, большим шрифтом.
+
+
+
+### 3. Самая важная информация очевидна {#the-most-important-info-is-obvious}
+
+Для сложных систем показывайте только самые релевантные данные. Определите, что является наиболее важным, и выведите на самое видное место.
+Слишком много информации перегружает пользователя, и при принятии решения он обычно опирается лишь на одну часть доступной информации. В DeFi это, скорее всего, будет годовая процентная ставка (APR) в доходных приложениях и соотношение кредита к стоимости (LTV) в приложениях для кредитования.
+
+**Подсказки:**
+
+- Исследование пользовательской аудитории позволит выявить наиболее важную метрику
+- Сделайте ключевую информацию большой, а остальные детали - маленькими и ненавязчивыми
+- Люди не читают, они сканируют; убедитесь, что ваш дизайн легко сканируется
+
+**Пример:** крупные полноцветные токены легко найти при сканировании. Годовая процентная ставка (APR) написана крупно и выделена акцентным цветом.
+
+
+
+### 4. Понятная терминология {#clear-terminology}
+
+Терминология должна быть понятной и подходящей.
+Технический жаргон может стать серьезным препятствием, поскольку он требует построения совершенно новой ментальной модели. Пользователи не могут соотнести дизайн со словами, фразами и концепциями, которые они уже знают. Все кажется запутанным и незнакомым, и нужно пройти сложный путь обучения, прежде чем они смогут хотя бы попытаться начать им пользоваться. Пользователь может обратиться в DeFi, желая сэкономить немного денег, но сталкивается с такими терминами как майнинг, фермерство, стэйкинг, эмиссия, взятки, сейфы, локеры, ve-токены, вестирование, эпохи, децентрализованные алгоритмы, ликвидность, принадлежащую протоколу…
+Старайтесь использовать простые термины, которые будут понятны самому широкому кругу людей. Не придумывайте собственных терминов для своего проекта.
+
+**Подсказки:**
+
+- Используйте простую и последовательную терминологию
+- Используйте существующий язык как можно чаще
+- Не придумывайте собственных терминов
+- Следуйте появляющимся соглашениям
+- Обучайте пользователей настолько, насколько это возможно
+
+**Пример:**
+“Ваши награды” — общепонятный нейтральный термин, а не новое слово, выдуманное специально для вашего проекта. Вознаграждения номинированы в долларах США, чтобы соответствовать ментальным моделям реального мира, даже если сами вознаграждения выплачиваются в другом токене.
+
+
+
+### 5. Действия должны быть как можно короче {#actions-are-as-short-as-possible}
+
+Ускорьте взаимодействие с пользователем, группируя поддействия.
+Это можно сделать как на уровне смарт-контракта, так и в пользовательском интерфейсе. Пользователю не нужно переходить из одной части системы в другую или полностью покидать систему для выполнения обычного действия.
+
+**Подсказки:**
+
+- По возможности объединяйте "Одобрить" с другими действиями
+- Группируйте этапы подписания как можно ближе друг к другу
+
+**Пример:** объединение «добавления ликвидности» и «стейкинга» — это простой пример ускорителя, который экономит пользователю и время, и газ.
+
+
+
+### 6. Подключения к сети должны быть видимыми и гибкими {#network-connections-are-visible-and-flexible}
+
+Информируйте пользователя о том, к какой сети он подключен, и предоставьте ему возможность с лёгкостью сменить её.
+Это особенно важно для приложений, которые доступны сразу на нескольких сетях. Основные функции приложения должны оставаться видимыми при отключении кошелька или подключении к неподдерживаемой сети.
+
+**Подсказки:**
+
+- Дайте неподключившемуся пользователю как можно больше доступа к приложению
+- Покажите, к какой сети подключен пользователь
+- Не заставляйте пользователя переходить в кошелёк, чтобы сменить сеть
+- Если приложение требует, чтобы пользователь сменил сеть, предложите это действие из основного призыва к действию
+- Если приложение содержит рынки или хранилища для нескольких сетей, четко укажите, какой набор пользователь сейчас просматривает
+
+**Пример:** покажите пользователю, к какой сети он подключен, и разрешите ему изменить ее на панели приложения.
+
+
+
+### 7. Управление из приложения, а не из кошелька {#control-from-the-app-not-the-wallet}
+
+Пользовательский интерфейс должен сообщать пользователю все, что ему нужно знать, и давать ему контроль над всем, что нужно сделать.
+В Web3 есть действия, которые вы выполняете в пользовательском интерфейсе, и действия, которые вы выполняете в кошельке. Обычно вы инициируете действие в пользовательском интерфейсе, а затем подтверждаете его в кошельке. Пользователи могут чувствовать себя некомфортно, если эти два потока не будут тщательно интегрированы.
+
+**Подсказки:**
+
+- Информируйте пользователя о статусе системы через обратную связь в пользовательском интерфейсе
+- Ведите учёт транзакций
+- Предоставляйте ссылки на обозреватели блоков для старых транзакций
+- Предоставьте быстрый доступ для смены сетей.
+
+**Пример:** ненавязчивый контейнер показывает пользователю, какие релевантные токены есть в его кошельке, а основной призыв к действию предоставляет быстрый способ сменить сеть.
+
+
diff --git a/public/content/translations/ru/developers/docs/design-and-ux/index.md b/public/content/translations/ru/developers/docs/design-and-ux/index.md
new file mode 100644
index 00000000000..8cde6c6646d
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/design-and-ux/index.md
@@ -0,0 +1,86 @@
+---
+title: "Дизайн и UX в Web3"
+description: "Введение в UX-дизайн и исследования в пространстве Web3 и Ethereum"
+lang: ru
+---
+
+Вы новичок в дизайне для Ethereum? Вы в правильном месте. Сообщество Ethereum подготовило ресурсы, чтобы познакомить вас с основами дизайна и исследований в Web3. Вы узнаете об основных концепциях, которые могут отличаться от дизайна других знакомых вам приложений.
+
+Для начала нужно получить более общее представление о Web3? Загляните в [**учебный центр**](/learn/).
+
+## Начните с исследования пользователей {#start-with-user-research}
+
+Эффективный дизайн выходит за рамки создания визуально привлекательных пользовательских интерфейсов. Он подразумевает глубокое понимание потребностей, целей и мотивов пользователя. Поэтому мы настоятельно рекомендуем всем дизайнерам применять определенный процесс проектирования, например [**модель «двойного алмаза»**](https://en.wikipedia.org/wiki/Double_Diamond_\(design_process_model\)), чтобы их работа была целенаправленной и осмысленной.
+
+- [Web3 нужны UX-исследователи и дизайнеры](https://blog.akasha.org/akasha-conversations-9-web3-needs-more-ux-researchers-and-designers) — обзор текущей зрелости дизайна
+- [Простое руководство по UX-исследованиям в Web3](https://uxplanet.org/a-complete-guide-to-ux-research-for-web-3-0-products-d6bead20ebb1) — простое руководство по проведению исследований
+- [Как принимать UX-решения в Web3](https://archive.devcon.org/archive/watch/6/data-empathy-how-to-approach-ux-decisions-in-web3/) — краткий обзор количественных и качественных исследований и различий между ними (видео, 6 мин)
+- [Как быть UX-исследователем в Web3](https://medium.com/@georgia.rakusen/what-its-like-being-a-user-researcher-in-web3-6a4bcc096849) — личный взгляд на то, каково это — быть UX-исследователем в Web3
+
+## Исследования в Web3 {#research-in-web3}
+
+Это отобранный список исследований пользователей в Web3, который может помочь в принятии решений по дизайну и продукту или послужить источником вдохновения для проведения собственного исследования.
+
+| Область исследования | Имя |
+| :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Адаптация в криптосфере | [The Reown Pulse 2024: настроения и использование криптотехнологий потребителями](https://reown.com/blog/unveiling-walletconnects-consumer-crypto-report) |
+| Адаптация в криптосфере | [CRADL: UX в криптовалюте](https://docs.google.com/presentation/d/1s2OPSH5sMJzxRYaJSSRTe8W2iIoZx0PseIV-WeZWD1s/edit?usp=sharing) |
+| Адаптация в криптосфере | [CRADL: адаптация в криптовалюте](https://docs.google.com/presentation/d/1R9nFuzA-R6SxaGCKhoMbE4Vxe0JxQSTiHXind3LVq_w/edit?usp=sharing) |
+| Адаптация в криптосфере | [Отчет по UX в Bitcoin](https://github.com/patestevao/BitcoinUX-report/blob/master/report.md) |
+| Адаптация в криптосфере | [ConSensys: восприятие Web3 в мире в 2023 году](https://consensys.io/insight-report/web3-and-crypto-global-survey-2023) |
+| Адаптация в криптосфере | [NEAR: ускорение пути к внедрению](https://drive.google.com/file/d/1VuaQP4QSaQxR5ddQKTMGI0b0rWdP7uGn/view) |
+| Стейкинг | [OpenUX: UX оператора узла Rocket Pool](https://storage.googleapis.com/rocketpool/RocketPool-NodeOperator-UX-Report-Jan-2024.pdf) |
+| Стейкинг | [Стейкинг: ключевые тренды, выводы и прогнозы — Eth Staker](https://lookerstudio.google.com/u/0/reporting/cafcee00-e1af-4148-bae8-442a88ac75fa/page/p_ja2srdhh2c?s=hmbTWDh9hJo) |
+| Стейкинг | [Стейкинг в нескольких приложениях](https://github.com/threshold-network/UX-User-Research/blob/main/Multi-App%20Staking%20\(MAS\)/iterative-user-study/MAS%20Iterative%20User%20Study.pdf) |
+| DAO | [Обновление исследования DAO за 2022 год: что нужно создателям DAO?](https://blog.aragon.org/2022-dao-research-update/) |
+| DeFi | [Пулы покрытия](https://github.com/threshold-network/UX-User-Research/tree/main/Keep%20Coverage%20Pool) |
+| DeFi | [ConSensys: отчет об исследовании пользователей DeFi за 2022 год](https://cdn2.hubspot.net/hubfs/4795067/ConsenSys%20Codefi-Defi%20User%20ResearchReport.pdf) |
+| Метавселенная | [Метавселенная: отчет об исследовании пользователей](https://www.politico.com/f/?id=00000187-7685-d820-a7e7-7e85d1420000) |
+| Метавселенная | [Сафари: исследование пользователей в метавселенной](https://archive.devcon.org/archive/watch/6/going-on-safari-researching-users-in-the-metaverse/?tab=YouTube) (видео, 27 мин) |
+
+## Дизайн для Web3 {#design-for-web3}
+
+- [Руководство по UX-дизайну для Web3](https://web3ux.design/) — практическое руководство по разработке дизайна приложений для Web3
+- [Принципы дизайна в Web3](https://medium.com/@lyricalpolymath/web3-design-principles-f21db2f240c1) — набор правил UX для децентрализованных приложений на основе блокчейна
+- [Принципы дизайна для блокчейна](https://medium.com/design-ibm/blockchain-design-principles-599c5c067b6e) — уроки, извлеченные командой по дизайну для блокчейна в IBM
+- [Neueux.com](https://neueux.com/apps) — библиотека UI пользовательских сценариев с различными вариантами фильтрации
+- [Кризис юзабилити Web3: что вам НУЖНО знать!](https://www.youtube.com/watch?v=oBSXT_6YDzg) — панельная дискуссия о ловушках при создании проектов, ориентированных на разработчиков (видео, 34 мин)
+
+## Начало работы {#getting-started}
+
+- [Эвристика для Web3](/developers/docs/design-and-ux/heuristics-for-web3/) — 7 эвристик для дизайна интерфейса Web3
+- [Лучшие практики дизайна DEX](/developers/docs/design-and-ux/dex-design-best-practice/) — руководство по дизайну децентрализованных бирж
+
+## Примеры дизайна в Web3 {#design-case-studies}
+
+- [Deep Work Studio](https://www.deepwork.studio/case-studies)
+- [Продажа NFT на OpenSea](https://builtformars.com/case-studies/opensea)
+- [Анализ UX кошельков: как должны измениться кошельки](https://www.youtube.com/watch?v=oTpuxYj8JWI&ab_channel=ETHDenver) (видео, 20 мин)
+
+## Вознаграждения за дизайн {#bounties}
+
+- [Dework](https://app.dework.xyz/bounties)
+- [Хакатоны Buildbox](https://app.buidlbox.io/)
+- [Хакатоны ETHGlobal](https://ethglobal.com/)
+
+## Дизайнерские DAO и сообщества {#design-daos-and-communities}
+
+Присоединяйтесь к профессиональным организациям, управляемым сообществом, или вступайте в группы дизайнеров, чтобы обсуждать с другими участниками темы и тенденции, связанные с дизайном и исследованиями.
+
+- [Vectordao.com](https://vectordao.com/)
+- [Deepwork.studio](https://www.deepwork.studio/)
+- [We3.co](https://we3.co/)
+- [Openux.xyz](https://openux.xyz/)
+
+## Системы дизайна и другие ресурсы для дизайнеров {#design-systems-and-resources}
+
+- [Дизайн Optimism](https://www.figma.com/@optimism) (Figma)
+- [Система дизайна Ethereum.org](https://www.figma.com/@ethdotorg) (Figma)
+- [Finity, система дизайна от Polygon](https://www.figma.com/community/file/1073921725197233598/finity-design-system) (Figma)
+- [Система дизайна Kleros](https://www.figma.com/community/file/999852250110186964/kleros-design-system) (Figma)
+- [Система дизайна Safe](https://www.figma.com/community/file/1337417127407098506/safe-design-system) (Figma)
+- [Система дизайна ENS](https://thorin.ens.domains/)
+- [Система дизайна Mirror](https://degen-xyz.vercel.app/)
+
+**Статьи и проекты, перечисленные на этой странице, не являются официальной рекомендацией** и предоставлены исключительно в информационных целях.
+Мы добавляем ссылки на эту страницу в соответствии с критериями, изложенными в нашей [политике размещения материалов](/contributing/design/adding-design-resources). Если вы хотите, чтобы мы добавили проект или статью, отредактируйте эту страницу на [GitHub](https://github.com/ethereum/ethereum-org-website/blob/dev/public/content/developers/docs/design-and-ux/index.md).
diff --git a/public/content/translations/ru/developers/docs/development-networks/index.md b/public/content/translations/ru/developers/docs/development-networks/index.md
new file mode 100644
index 00000000000..4e77712fd8a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/development-networks/index.md
@@ -0,0 +1,71 @@
+---
+title: "Сети разработки"
+description: "Обзор сетей разработки и инструментов для помощи в создании приложений Ethereum."
+lang: ru
+---
+
+При создании приложения Ethereum со смарт-контрактами, вы захотите запустить его в локальной сети, чтобы перед развертыванием увидеть, как оно работает.
+
+Подобно тому, как вы можете запустить локальный сервер для веб-разработки на вашем компьютере, вы можете использовать сеть разработки для создания локального блокчейна для тестирования вашего dapp. Эти сети разработки Ethereum предоставляют возможности, которые позволяют значительно чаще итерировать, чем публичная тестовая сеть (например, вам не нужно иметь дело с получением ETH из testnet).
+
+## Предварительные условия {#prerequisites}
+
+Вам следует изучить [основы стека Ethereum](/developers/docs/ethereum-stack/) и [сети Ethereum](/developers/docs/networks/), прежде чем погружаться в сети для разработки.
+
+## Что такое сеть разработки? {#what-is-a-development-network}
+
+Сети разработки по сути являются клиентами Ethereum (реализации Ethereum), специально разработанными для локального развития.
+
+**Почему бы просто не запускать стандартный узел Ethereum локально?**
+
+Вы _могли бы_ [запустить узел](/developers/docs/nodes-and-clients/#running-your-own-node), но поскольку сети для разработки созданы специально для этих целей, они часто поставляются с удобными функциями, такими как:
+
+- Детерминированное заполнение вашего локального блокчейна данными (например, аккаунты с балансом в ETH)
+- Мгновенное создание блоков при получении каждой транзакции, по порядку и без задержки
+- Расширенные возможности отладки и логирования
+
+## Доступные инструменты {#available-projects}
+
+**Примечание**: большинство [фреймворков для разработки](/developers/docs/frameworks/) включают в себя встроенную сеть для разработки. Мы рекомендуем начать с фреймворка, чтобы [настроить локальную среду разработки](/developers/local-environment/).
+
+### Сеть Hardhat {#hardhat-network}
+
+Локальная сеть Ethereum, предназначенная для разработки. Он позволяет вам развернуть контракты, запустить тесты и отладить код.
+
+Hardhat Network встроена в Hardhat, среду разработки Ethereum для профессионалов.
+
+- [Веб-сайт](https://hardhat.org/)
+- [GitHub](https://github.com/NomicFoundation/hardhat)
+
+### Локальные сети Beacon {#local-beacon-chains}
+
+Некоторые консенсус-клиенты имеют встроенные инструменты для запуска локальных цепочек Beacon для тестирования. Доступны инструкции для Lighthouse, Nimbus и Lodestar:
+
+- [Локальная тестовая сеть с использованием Lodestar](https://chainsafe.github.io/lodestar/contribution/advanced-topics/setting-up-a-testnet#post-merge-local-testnet/)
+- [Локальная тестовая сеть с использованием Lighthouse](https://lighthouse-book.sigmaprime.io/setup.html#local-testnets)
+
+### Публичные тестовые сети Ethereum {#public-beacon-testchains}
+
+Также существуют две поддерживаемые публичные тестовые реализации Ethereum: Sepolia и Hoodi. Рекомендуемой тестовой сетью с долгосрочной поддержкой является Hoodi, где любой желающий может стать валидатором. В Sepolia используется закрытый набор валидаторов. Это значит, что новые валидаторы не могут свободно присоединиться к этой тестовой сети.
+
+- [Лаунчпад для стейкинга Hoodi](https://hoodi.launchpad.ethereum.org/)
+
+### Пакет Kurtosis для Ethereum {#kurtosis}
+
+Kurtosis — это система сборки для многоконтейнерных тестовых сред, которая позволяет разработчикам локально разворачивать воспроизводимые экземпляры сетей блокчейна.
+
+Пакет Kurtosis для Ethereum можно использовать для быстрого создания параметризуемой, высокомасштабируемой и частной тестовой сети Ethereum на базе Docker или Kubernetes. Пакет поддерживает все основные клиенты уровня исполнения (EL) и уровня консенсуса (CL). Kurtosis корректно обрабатывает все сопоставления локальных портов и сервисные соединения для репрезентативной сети, которая будет использоваться в рабочих процессах валидации и тестирования, связанных с основной инфраструктурой Ethereum.
+
+- [Сетевой пакет Ethereum](https://github.com/kurtosis-tech/ethereum-package)
+- [Веб-сайт](https://www.kurtosis.com/)
+- [GitHub](https://github.com/kurtosis-tech/kurtosis)
+- [Документация](https://docs.kurtosis.com/)
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Фреймворки для разработки](/developers/docs/frameworks/)
+- [Настройка локальной среды разработки](/developers/local-environment/)
diff --git a/public/content/translations/ru/developers/docs/ethereum-stack/index.md b/public/content/translations/ru/developers/docs/ethereum-stack/index.md
new file mode 100644
index 00000000000..c6c23adc514
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/ethereum-stack/index.md
@@ -0,0 +1,61 @@
+---
+title: "Введение в стек Ethereum"
+description: "Пошаговое руководство по различным слоям стека Ethereum и их взаимодействие."
+lang: ru
+---
+
+Как и любой программный стек, комплектация "стека Ethereum" будет варьироваться от проекта к проекту в зависимости от ваших целей.
+
+Однако существуют основные компоненты Ethereum, которые помогают сформировать концептуальную модель того, как программные приложения взаимодействуют с блокчейном Ethereum. Понимание слоев стека поможет вам понять различные способы интеграции Ethereum в программные проекты.
+
+## Уровень 1: Виртуальная машина Ethereum {#ethereum-virtual-machine}
+
+[Виртуальная машина Ethereum (EVM)](/developers/docs/evm/) — это среда выполнения для умных контрактов на Ethereum. Все умные контракты и изменения состояния в блокчейне Ethereum выполняются [транзакциями](/developers/docs/transactions/). EVM обрабатывает все транзакций в сети Ethereum.
+
+Как и любая виртуальная машина, EVM создает уровень абстракции между кодом и вычислительной машиной (узлом Ethereum). В настоящее время EVM работает на тысячах узлов, распределенных по всему миру.
+
+EVM использует набор инструкций кода операции для выполнения определенных задач. Эти (140 уникальных) кодов операций позволяют EVM быть [полной по Тьюрингу](https://en.wikipedia.org/wiki/Turing_completeness), что означает, что EVM способна вычислить практически все что угодно при наличии достаточных ресурсов.
+
+Как разработчику децентрализованных приложений, вам не нужно много знать о EVM, кроме того, что она существует и надежно обеспечивает работу всех приложений на Ethereum без простоев.
+
+## Уровень 2: Умные контракты {#smart-contracts}
+
+[Умные контракты](/developers/docs/smart-contracts/) — это исполняемые программы, работающие на блокчейне Ethereum.
+
+Умные контракты пишутся с использованием специальных [языков программирования](/developers/docs/smart-contracts/languages/), которые компилируются в байт-код EVM (низкоуровневые машинные инструкции, называемые кодами операций).
+
+Смарт-контракты — это не только библиотеки с открытым исходным кодом, это, по сути, открытые службы API, которые всегда работают и не могут быть отключены. Умные контракты предоставляют публичные функции, с которыми пользователи и приложения ([децентрализованные приложения](/developers/docs/dapps/)) могут взаимодействовать без получения разрешения. Любое приложение может интегрироваться с развернутыми умными контрактами для создания функциональности, например для добавления [каналов данных](/developers/docs/oracles/) или для поддержки обмена токенов. Кроме того, любой желающий может развернуть новые умные контракты в Ethereum, чтобы добавить пользовательскую функциональность в соответствии с потребностями своего приложения.
+
+Разработчику dapp, нужно будет писать смарт-контракты только в том случае, если вы хотите совместить уникальные пользовательские функции с блокчейном Ethereum. Вы можете обнаружить, что можете удовлетворить большую часть или все потребности своего проекта, просто интегрировав его с существующими смарт-контрактами, например, если вы хотите поддерживать платежи в стейблкоинах или включить децентрализованный обмен токенами.
+
+## Уровень 3: Узлы Ethereum {#ethereum-nodes}
+
+Чтобы приложение могло взаимодействовать с блокчейном Ethereum, оно должно подключиться к [узлу Ethereum](/developers/docs/nodes-and-clients/). Подключение к узлу позволяет читать данные блокчейна и/или отправлять транзакции в сеть.
+
+Узлы Ethereum — это компьютеры, на которых запущено программное обеспечение — клиент Ethereum. Клиент — это реализация Ethereum, которая проверяет все транзакции в каждом блоке, обеспечивая безопасность сети и точность данных. **Узлы Ethereum — это и есть блокчейн Ethereum**. Они коллективно хранят блокчейн Ethereum и достигают консенсуса по транзакциям, чтобы изменить состояние блокчейна.
+
+Подключив ваше приложение к узлу Ethereum (через [JSON-RPC API](/developers/docs/apis/json-rpc/)), оно сможет считывать данные из блокчейна (например, балансы счетов пользователей), а также транслировать новые транзакции в сеть (например, перевод ETH между счетами пользователей или выполнение функций умных контрактов).
+
+## Уровень 4: Клиентские API Ethereum {#ethereum-client-apis}
+
+Многие вспомогательные библиотеки (созданные и поддерживаемые сообществом разработчиков ПО с открытым исходным кодом Ethereum) позволяют вашим приложениям подключаться к блокчейну Ethereum и взаимодействовать с ним.
+
+Если ваше приложение, ориентированное на пользователя, — это веб-приложение, вы можете установить [JavaScript API](/developers/docs/apis/javascript/) с помощью `npm install` непосредственно во фронтенде. Или, возможно, вы решите реализовать эту функциональность на стороне сервера, используя API для [Python](/developers/docs/programming-languages/python/) или [Java](/developers/docs/programming-languages/java/).
+
+Хотя эти API-интерфейсы не являются необходимой частью стека, они упрощают прямое взаимодействия с узлом Ethereum. Они также предоставляют вспомогательные функции (например, конвертацию ETH в Gwei), поэтому как разработчик вы можете тратить меньше времени на тонкости работы с клиентами Ethereum и больше времени уделять функциональности, специфичной для вашего приложения.
+
+## Уровень 5: Приложения для конечных пользователей {#end-user-applications}
+
+На верхнем уровне стека находятся приложения, ориентированные на пользователя. Это стандартные приложения, которые вы регулярно используете сегодня: в основном веб-приложения и мобильные приложения.
+
+Разработка интерфейса, не изменилась. Часто пользователям не обязательно знать, что приложение, которое они используют, построено с использованием блокчейна.
+
+## Готовы выбрать свой стек? {#ready-to-choose-your-stack}
+
+Ознакомьтесь с нашим руководством по [настройке локальной среды разработки](/developers/local-environment/) для вашего приложения Ethereum.
+
+## Дополнительные материалы {#further-reading}
+
+- [Архитектура Web 3.0-приложения](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) — _Preethi Kasireddy_
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/evm/index.md b/public/content/translations/ru/developers/docs/evm/index.md
index 67defb36a60..85b3888f709 100644
--- a/public/content/translations/ru/developers/docs/evm/index.md
+++ b/public/content/translations/ru/developers/docs/evm/index.md
@@ -1,78 +1,88 @@
---
-title: Виртуальная машина Ethereum (EVM)
-description: Введение в работу виртуальной машины Ethereum и как она связана с состоянием сети, транзакциями и умными контрактами.
+title: "Виртуальная машина Ethereum (EVM)"
+description: "Введение в работу виртуальной машины Ethereum и как она связана с состоянием сети, транзакциями и умными контрактами."
lang: ru
---
-Виртуальная машина Ethereum (EVM) — это децентрализованная виртуальная среда, которая стабильно и безопасно исполняет код на всех узлах Ethereum. Узлы запускают EVM для выполнения смарт-контрактов, используя [газ](/gas/) для измерения вычислительных затрат, необходимых для выполнения [операций](/developers/docs/evm/opcodes/), обеспечивая эффективное распределение ресурсов и безопасность сети.
+Виртуальная машина Ethereum (EVM) — это децентрализованная виртуальная среда, которая стабильно и безопасно исполняет код на всех узлах Ethereum. Узлы запускают EVM для выполнения смарт-контрактов, используя "[газ](/developers/docs/gas/)" для измерения вычислительных усилий, необходимых для [операций](/developers/docs/evm/opcodes/), обеспечивая эффективное распределение ресурсов и безопасность сети.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Некоторые базовые знания в информатике, например термины [байт](https://wikipedia.org/wiki/Byte), [память](https://wikipedia.org/wiki/Computer_memory) и [стек](https://wikipedia.org/wiki/Stack_(abstract_data_type)), необходимы для понимания работы EVM. Также было бы полезно ознакомиться с такими понятиями криптографии и блокчейна, как [хэш-функции](https://wikipedia.org/wiki/Cryptographic_hash_function) и [дерево Меркла](https://wikipedia.org/wiki/Merkle_tree).
+Для понимания EVM необходимо базовое знакомство с общепринятой терминологией в информатике, такой как [байты](https://wikipedia.org/wiki/Byte), [память](https://wikipedia.org/wiki/Computer_memory) и [стек](https://wikipedia.org/wiki/Stack_\(abstract_data_type\)). Также было бы полезно ознакомиться с такими понятиями криптографии и блокчейна, как [хеш-функции](https://wikipedia.org/wiki/Cryptographic_hash_function) и [дерево Меркла](https://wikipedia.org/wiki/Merkle_tree).
## От реестра к машине состояний {#from-ledger-to-state-machine}
Аналогия с «распределенным реестром» часто используется для описания таких блокчейнов, как Биткойн, которые позволяют децентрализовать валюту с использованием фундаментальных инструментов криптографии. Реестр содержит запись о деятельности, которая должна соответствовать набору правил, регулирующих, что кто-то может и не может сделать для изменения реестра. Например, биткойн-адрес не может потратить больше биткойнов, чем получил ранее. Эти правила лежат в основе всех транзакций во многих блокчейнах, включая Биткойн.
-Хотя у Ethereum есть собственная криптовалюта (Эфир), которая следует почти точно таким же интуитивным правилам, она также обеспечивает гораздо более мощную функцию: [умные контракты](/developers/docs/smart-contracts/). Для этой более сложной функции требуется более сложная аналогия. Вместо распределенного реестра Ethereum представляет собой распределенную [машину состояний](https://wikipedia.org/wiki/Finite-state_machine). Состояние Ethereum — это большая структура данных, в которой хранятся не только все счета и балансы, но и _состояние машины_, которая может изменяться от блока к блоку в соответствии с заранее определенным набором правил и которая может выполнять произвольный машинный код. Конкретные правила изменения состояния от блока к блоку определяются EVM.
+Хотя у Ethereum есть собственная криптовалюта (эфир), которая следует почти тем же интуитивно понятным правилам, он также предоставляет гораздо более мощную функцию: [смарт-контракты](/developers/docs/smart-contracts/). Для этой более сложной функции требуется более сложная аналогия. Вместо распределенного реестра Ethereum представляет собой распределенную [машину состояний](https://wikipedia.org/wiki/Finite-state_machine). Состояние Ethereum — это большая структура данных, в которой хранятся не только все аккаунты и балансы, но и _состояние машины_, которое может изменяться от блока к блоку в соответствии с заранее определенным набором правил и которое может выполнять произвольный машинный код. Конкретные правила изменения состояния от блока к блоку определяются EVM.
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Схема адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
-## Функция перехода состояния Ethereum {#the-ethereum-state-transition-function}
+## Функция перехода состояний Ethereum {#the-ethereum-state-transition-function}
-EVM ведет себя как математическая функция: при вводе данных производится детерминированный вывод. Поэтому весьма полезно более формально описать Ethereum как имеющий функцию **перехода между состояниями**:
+EVM ведет себя как математическая функция: при вводе данных производится детерминированный вывод. Поэтому будет полезно более формально описать Ethereum как имеющий **функцию перехода состояний**:
```
Y(S, T)= S'
```
-Учитывая старое допустимое состояние `(S)` и новый набор действительных транзакций `(T)`, функция перехода состояния Ethereum `Y(S, T)` создает новое допустимое состояние вывода `S'`
+Для старого валидного состояния `(S)` и нового набора валидных транзакций `(T)` функция перехода состояний Ethereum `Y(S, T)` создает новое валидное выходное состояние `S'`
### Состояние {#state}
-В контексте Ethereum состояние — это огромная структура данных, называемая [модифицированным деревом Меркла вида Patricia](/developers/docs/data-structures-and-encoding/patricia-merkle-trie/), в котором все [аккаунты](/developers/docs/accounts/) связаны хэшами и сводятся к одному корневому хэшу, хранящемуся в блокчейне.
+В контексте Ethereum состояние — это огромная структура данных, называемая [модифицированным деревом Меркла-Патриции](/developers/docs/data-structures-and-encoding/patricia-merkle-trie/), в которой все [аккаунты](/developers/docs/accounts/) связаны хешами и сводятся к одному корневому хешу, хранящемуся в блокчейне.
### Транзакции {#transactions}
Транзакции — это криптографически подписанные инструкции от аккаунтов. Есть два типа транзакций: те, которые приводят к вызовам сообщений, и те, которые приводят к созданию контракта.
-В результате создания контракта создается новый аккаунт контракта, содержащий скомпилированный байткод [умного контракта](/developers/docs/smart-contracts/anatomy/). Всякий раз, когда другая учетная запись выполняет вызов сообщения для этого контракта, она выполняет свой байткод.
+Создание контракта приводит к созданию нового аккаунта контракта, содержащего скомпилированный байт-код [смарт-контракта](/developers/docs/smart-contracts/anatomy/). Всякий раз, когда другая учетная запись выполняет вызов сообщения для этого контракта, она выполняет свой байткод.
## Инструкции EVM {#evm-instructions}
-EVM работает как [стековая машина](https://wikipedia.org/wiki/Stack_machine), вмещающая 1024 элементов. Каждый элемент стека — это 256-битное слово, выбранное для удобства использования в 256-битной криптографии (например, хэши Keccak-256 или подписи secp256k1).
+EVM выполняется как [стековая машина](https://wikipedia.org/wiki/Stack_machine) с глубиной стека в 1024 элемента. Каждый элемент стека — это 256-битное слово, выбранное для удобства использования в 256-битной криптографии (например, хэши Keccak-256 или подписи secp256k1).
-Во время работы EVM использует временную область _памяти_ (в виде байтового массива с адресацией по словам), которая не сохраняется между транзакциями.
+Во время выполнения EVM поддерживает временную _память_ (в виде массива байтов с пословной адресацией), которая не сохраняется между транзакциями.
-Однако контракты содержат _хэш-дерево_ Меркла вида Patricia (в виде массива слов с адресацией по словам), связанное с аккаунтом и рассматриваемое как часть глобального состояния.
+### Временное хранилище
-Скомпилированный байт-код умного контракта исполняется как последовательность [машинных кодов](/developers/docs/evm/opcodes) EVM, таких как стандартные машинные операции `XOR`, `AND`, `ADD`, `SUB`, и т. д. В стековой машине EVM также есть и специальные блокчейновые опкоды, такие как `ADDRESS`, `BALANCE`, `BLOCKHASH` и т. д.
+Временное хранилище — это хранилище типа «ключ — значение» для каждой транзакции, доступ к которому осуществляется с помощью опкодов `TSTORE` и `TLOAD`. Оно сохраняется во всех внутренних вызовах в рамках одной транзакции, но очищается в конце транзакции. В отличие от памяти, временное хранилище моделируется как часть состояния EVM, а не фрейма исполнения, однако оно не фиксируется в глобальном состоянии. Временное хранилище обеспечивает эффективный с точки зрения расхода газа временный совместный доступ к состоянию между внутренними вызовами во время транзакции.
- _Источник адаптированных диаграмм: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+### Хранилище
+
+Контракты содержат дерево Меркла-Патриции _хранилища_ (в виде массива слов с пословной адресацией), связанное с соответствующим аккаунтом и являющееся частью глобального состояния. Это постоянное хранилище отличается от временного хранилища, которое доступно только на время одной транзакции и не является частью дерева постоянного хранилища аккаунта.
+
+### Машинный код
+
+Скомпилированный байт-код смарт-контракта исполняется как набор [опкодов](/developers/docs/evm/opcodes) EVM, которые выполняют стандартные стековые операции, такие как `XOR`, `AND`, `ADD`, `SUB` и т. д. EVM также реализует ряд специфичных для блокчейна стековых операций, таких как `ADDRESS`, `BALANCE`, `BLOCKHASH` и т. д. Набор опкодов также включает `TSTORE` и `TLOAD`, которые предоставляют доступ к временному хранилищу.
+
+
+_Схемы адаптированы из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
## Реализации EVM {#evm-implementations}
Все реализации EVM должны соответствовать спецификации, описанной в Желтой книге Ethereum.
-За девятилетнюю историю Ethereum EVM претерпела несколько пересмотров, и существует несколько реализаций EVM на различных языках программирования.
+За десятилетнюю историю Ethereum EVM претерпела несколько изменений, и существует несколько реализаций EVM на различных языках программирования.
-[Клиенты-исполнители Ethereum](/developers/docs/nodes-and-clients/#execution-clients) включают реализацию EVM. Кроме того, существует несколько автономных реализаций, включая:
+[Клиенты исполнения Ethereum](/developers/docs/nodes-and-clients/#execution-clients) включают в себя реализацию EVM. Кроме того, существует несколько автономных реализаций, включая:
-- [Py-EVM](https://github.com/ethereum/py-evm) — _Python_
-- [evmone](https://github.com/ethereum/evmone) — _C++_
-- [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) — _JavaScript_
-- [revm](https://github.com/bluealloy/revm) — _Rust_
+- [Py-EVM](https://github.com/ethereum/py-evm) - _Python_
+- [evmone](https://github.com/ethereum/evmone) - _C++_
+- [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) - _JavaScript_
+- [revm](https://github.com/bluealloy/revm) - _Rust_
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
- [Желтая книга Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf)
-- [Jellopaper (или KEVM): семантика EVM в K](https://jellopaper.org/)
+- [Jellopaper, также известная как KEVM: семантика EVM в K](https://jellopaper.org/)
- [Бежевая книга](https://github.com/chronaeon/beigepaper)
-- [Машинные коды виртуальной машины Ethereum](https://www.ethervm.io/)
-- [Интерактивный справочник по кодам операций виртуальной машины Ethereum](https://www.evm.codes/)
-- [Краткое введение в документацию по Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#index-6)
-- [Освоение Ethereum — виртуальная машина Ethereum](https://github.com/ethereumbook/ethereumbook/blob/openedition/13evm.asciidoc)
+- [Опкоды виртуальной машины Ethereum](https://www.ethervm.io/)
+- [Интерактивный справочник по опкодам виртуальной машины Ethereum](https://www.evm.codes/)
+- [Краткое введение в документации Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#index-6)
+- [Осваиваем Ethereum — виртуальная машина Ethereum](https://github.com/ethereumbook/ethereumbook/blob/openedition/13evm.asciidoc)
-## Похожие темы {#related-topics}
+## Связанные темы {#related-topics}
- [Газ](/developers/docs/gas/)
diff --git a/public/content/translations/ru/developers/docs/evm/opcodes/index.md b/public/content/translations/ru/developers/docs/evm/opcodes/index.md
index 435850ef303..679a8d7fc03 100644
--- a/public/content/translations/ru/developers/docs/evm/opcodes/index.md
+++ b/public/content/translations/ru/developers/docs/evm/opcodes/index.md
@@ -1,174 +1,177 @@
---
-title: Коды операций для EVM
-description: Список всех доступных кодов операций для виртуальной машины Ethereum.
+title: "Коды операций для EVM"
+description: "Список всех доступных кодов операций для виртуальной машины Ethereum."
lang: ru
---
## Обзор {#overview}
-Это обновленная версия справочной страницы по EVM по адресу [wolflo/evm-opcodes](https://github.com/wolflo/evm-opcodes). Информация также взята из [Желтой книги](https://ethereum.github.io/yellowpaper/paper.pdf), [Книги Jello](https://jellopaper.org/evm/) и реализации [geth](https://github.com/ethereum/go-ethereum). Предполагается, что этот справочник доступен, но не очень строг. Если вы хотите быть уверены в правильности и знать о каждом крайнем случае, рекомендуется использовать Книгу Jello или клиентскую реализацию.
+Это обновленная версия справочной страницы по EVM на [wolflo/evm-opcodes](https://github.com/wolflo/evm-opcodes).
+Также использованы материалы из [«Желтой книги»](https://ethereum.github.io/yellowpaper/paper.pdf), [Jello Paper](https://jellopaper.org/evm/) и реализации [geth](https://github.com/ethereum/go-ethereum).
+Предполагается, что этот справочник доступен, но не очень строг.
+Если вы хотите быть уверены в правильности и знать о каждом крайнем случае, рекомендуется использовать Книгу Jello или клиентскую реализацию.
-Ищете интерактивный справочник? Посетите [evm.codes](https://www.evm.codes/).
+Ищете интерактивный справочник? Ознакомьтесь с [evm.codes](https://www.evm.codes/).
-Для операций с динамическими ценами газа смотрите раздел [gas.md](https://github.com/wolflo/evm-opcodes/blob/main/gas.md).
+Информацию об операциях с динамической стоимостью газа см. в [gas.md](https://github.com/wolflo/evm-opcodes/blob/main/gas.md).
-💡 Небольшой совет: чтобы посмотреть строки целиком, используйте `[shift] + scroll` для горизонтальной прокрутки экрана.
+💡 Быстрый совет: чтобы просмотреть строки целиком, используйте `[shift] + scroll` для горизонтальной прокрутки на настольном компьютере.
-| Стек | Имя | Газ | Исходный стек | Итоговый стек | Память/хранилище | Примечания |
-|:-----:|:------------------------------------------------------------------------------------------------- |:-----------------------------------------------------------------------------------------------:|:------------------------------------------------ |:-------------------------------------------- |:----------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| 00 | Приостановка выполнения | 0 | | | | halt execution |
-| 01 | Добавление | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 |
-| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 |
-| 03 | Вычитание | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 |
-| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division |
-| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division |
-| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus |
-| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus |
-| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N |
-| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N |
-| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 |
-| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes |
-| 0C-0F | _invalid_ | | | | | |
-| 10 | Меньше, чем сравниваемое | 3 | `a, b` | `a < b` | | uint256 less-than |
-| 11 | Больше, чем сравниваемое | 3 | `a, b` | `a > b` | | uint256 greater-than |
-| 12 | Подписано меньше, чем сравниваемое | 3 | `a, b` | `a < b` | | int256 less-than |
-| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than |
-| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality |
-| 15 | Просто НЕ оператор | 3 | `a` | `a == 0` | | (u)int256 iszero |
-| 16 | Побитовое И операция | 3 | `a, b` | `a && b` | | bitwise AND |
-| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR |
-| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR |
-| 19 | Побитовое НЕ операция | 3 | `a` | `~a` | | bitwise NOT |
-| 1А | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left |
-| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left |
-| 1C | Сместиться вправо | 3 | `shift, val` | `val >> shift` | | logical shift right |
-| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right |
-| 1E-1F | _invalid_ | | | | | |
-| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 |
-| 21-2F | _invalid_ | | | | | |
-| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract |
-| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei |
-| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx |
-| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender |
-| 34 | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение | 2 | `.` | `уточнить сумму` | | msg value, in wei |
-| 35 | Получить входные данные текущей среды | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` |
-| 36 | Получить размер входных данных текущей среды | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes |
-| 37 | Скопировать входных данные текущей среды | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data |
-| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes |
-| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode |
-| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) |
-| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes |
-| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` |
-| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes |
-| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call |
-| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `хэш` | | hash = addr.exists ? keccak256(addr.code) : 0 |
-| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | |
-| 41 | COINBASE | 2 | `.` | `block.coinbase` | | адрес предлагающего текущий блок |
-| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block |
-| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block |
-| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon |
-| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block |
-| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack |
-| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei |
-| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block |
-| 49 | Получить хэш одного из последних завершённых 256 блоков | 3 | `idx` | `tx.blob_versioned_hashes[idx]` | | [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) |
-| 4A | BLOBBASEFEE | 2 | `.` | `block.blobbasefee` | | blob base fee of current block ([EIP-7516](https://eips.ethereum.org/EIPS/eip-7516)) |
-| 4B-4F | _invalid_ | | | | | |
-| 50 | удалить слово из стека | 2 | `_anon` | `.` | | remove item from top of stack and discard it |
-| 51 | Загрузить слово из памяти | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` |
-| 52 | Сохранить слово в память | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory |
-| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory |
-| 54 | Загрузить слово из хранилища | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage |
-| 55 | Сохранить слово в хранилище | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage |
-| 56 | Изменить счетчик команд | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest |
-| 57 | Условно изменить счетчик команд | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` |
-| 58 | PC | 2 | `.` | `$pc` | | program counter |
-| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes |
-| 5A | Получить количество доступного газа, включая соответсвующее сокращение количества доступного газа | 2 | `.` | `gasRemaining` | | |
-| 5B | Отметить допустимое место для прыжков | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data |
-| 5C | TLOAD | 100 | `key` | `tstorage[key]` | | read word from transient storage ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) |
-| 5D | TSTORE | 100 | `key, val` | `.` | tstorage[key] := val | write word to transient storage ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) |
-| 5E | MCOPY | 3+3\*words+[A0](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `dstOst, ost, len` | `.` | mem[dstOst] := mem[ost:ost+len] | copy memory from one area to another ([EIP-5656](https://eips.ethereum.org/EIPS/eip-5656)) |
-| 5F | PUSH0 | 2 | `.` | `uint8` | | добавить постоянное значение 0 в стек |
-| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack |
-| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack |
-| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack |
-| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack |
-| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack |
-| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack |
-| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack |
-| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack |
-| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack |
-| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack |
-| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack |
-| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack |
-| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack |
-| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack |
-| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack |
-| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack |
-| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack |
-| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack |
-| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack |
-| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack |
-| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack |
-| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack |
-| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack |
-| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack |
-| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack |
-| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack |
-| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack |
-| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack |
-| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack |
-| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack |
-| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack |
-| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack |
-| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack |
-| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack |
-| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack |
-| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack |
-| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack |
-| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack |
-| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack |
-| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack |
-| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack |
-| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack |
-| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack |
-| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack |
-| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack |
-| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack |
-| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack |
-| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack |
-| 90 | SWAP1 | 3 | `a, b` | `b, a` | | |
-| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | |
-| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | |
-| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | |
-| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | |
-| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | |
-| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) |
-| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) |
-| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG2(memory[ost:ost+len-1], topic0, topic1) |
-| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG3(memory[ost:ost+len-1], topic0, topic1, topic2) |
-| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) |
-| A5-EF | _invalid_ | | | | | |
-| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) |
-| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | |
-| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value |
-| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] |
-| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | |
-| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] |
-| F6-F9 | _invalid_ | | | | | |
-| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | |
-| FB-FC | _invalid_ | | | | | |
-| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) |
-| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | |
-| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | sends all ETH to `addr`; if executed in the same transaction as a contract was created it destroys the contract |
+| Стек | Имя | Газ | Исходный стек | Итоговый стек | Память/хранилище | Примечания | |
+| :---: | :------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
+| 00 | Приостановка выполнения | 0 | | | | остановка выполнения | |
+| 01 | Добавление | 3 | `a, b` | `a + b` | | сложение (u)int256 по модулю 2\*\*256 | |
+| 02 | MUL | 5 | `a, b` | `a * b` | | умножение (u)int256 по модулю 2\*\*256 | |
+| 03 | Вычитание | 3 | `a, b` | `a - b` | | вычитание (u)int256 по модулю 2\*\*256 | |
+| 04 | DIV | 5 | `a, b` | `a // b` | | деление uint256 | |
+| 05 | SDIV | 5 | `a, b` | `a // b` | | деление int256 | |
+| 06 | MOD | 5 | `a, b` | `a % b` | | остаток от деления uint256 | |
+| 07 | SMOD | 5 | `a, b` | `a % b` | | остаток от деления int256 | |
+| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | сложение (u)int256 по модулю N | |
+| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | умножение (u)int256 по модулю N | |
+| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | возведение в степень uint256 по модулю 2\*\*256 | |
+| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [знаковое расширение](https://wikipedia.org/wiki/Sign_extension) `x` с `(b+1)` байт до 32 байт | |
+| 0C-0F | _недопустимо_ | | | | | | |
+| 10 | Меньше, чем сравниваемое | 3 | `a, b` | `a < b` | | uint256 меньше чем | |
+| 11 | Больше, чем сравниваемое | 3 | `a, b` | `a > b` | | uint256 больше чем | |
+| 12 | Подписано меньше, чем сравниваемое | 3 | `a, b` | `a < b` | | int256 меньше чем | |
+| 13 | SGT | 3 | `a, b` | `a > b` | | int256 больше чем | |
+| 14 | EQ | 3 | `a, b` | `a == b` | | равенство (u)int256 | |
+| 15 | Просто НЕ оператор | 3 | `a` | `a == 0` | | проверка на ноль (u)int256 | |
+| 16 | Побитовое И операция | 3 | `a, b` | `a && b` | | побитовое И | |
+| 17 | OR | 3 | `a, b` | `a \\|\\| b` | | побитовое ИЛИ | |
+| 18 | XOR | 3 | `a, b` | `a ^ b` | | побитовое исключающее ИЛИ | |
+| 19 | Побитовое НЕ операция | 3 | `a` | `~a` | | побитовое НЕ | |
+| 1А | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`-й байт (u)int256 `x`, слева | |
+| 1B | SHL | 3 | `shift, val` | `val << shift` | | сдвиг влево | |
+| 1C | Сместиться вправо | 3 | `shift, val` | `val >> shift` | | логический сдвиг вправо | |
+| 1D | SAR | 3 | `shift, val` | `val >> shift` | | арифметический сдвиг вправо | |
+| 1E-1F | _недопустимо_ | | | | | | |
+| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | |
+| 21-2F | _недопустимо_ | | | | | | |
+| 30 | ADDRESS | 2 | `.` | `address(this)` | | адрес исполняемого контракта | |
+| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | баланс, в wei | |
+| 32 | ORIGIN | 2 | `.` | `tx.origin` | | адрес, инициировавший транзакцию | |
+| 33 | CALLER | 2 | `.` | `msg.sender` | | адрес отправителя сообщения (msg) | |
+| 34 | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение | 2 | `.` | `уточнить сумму` | | значение сообщения (msg), в wei | |
+| 35 | Получить входные данные текущей среды | 3 | `idx` | `msg.data[idx:idx+32]` | | прочитать слово из данных сообщения (msg) по индексу `idx` | |
+| 36 | Получить размер входных данных текущей среды | 2 | `.` | `len(msg.data)` | | длина данных сообщения (msg), в байтах | |
+| 37 | Скопировать входных данные текущей среды | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | копировать данные сообщения (msg) | |
+| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | длина кода исполняемого контракта, в байтах | |
+| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | копировать байт-код исполняемого контракта |
+| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | цена газа транзакции, в wei за единицу газа [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | |
+| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | размер кода по адресу (addr), в байтах | |
+| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | копировать код из `addr` | |
+| 3D | RETURNDATASIZE | 2 | `.` | `size` | | размер возвращенных данных из последнего внешнего вызова, в байтах | |
+| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | копировать возвращенные данные из последнего внешнего вызова | |
+| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `хэш` | | хэш = addr.exists ? keccak256(addr.code) : 0 | |
+| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | |
+| 41 | COINBASE | 2 | `.` | `block.coinbase` | | адрес предлагающего текущий блок | |
+| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | временная метка текущего блока | |
+| 43 | NUMBER | 2 | `.` | `block.number` | | номер текущего блока | |
+| 44 | PREVRANDAO | 2 | `.` | `маяк случайности` | | маяк случайности | |
+| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | лимит газа текущего блока | |
+| 46 | CHAINID | 2 | `.` | `chain_id` | | поместить текущий [ID сети](https://eips.ethereum.org/EIPS/eip-155) в стек | |
+| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | баланс исполняемого контракта, в wei | |
+| 48 | BASEFEE | 2 | `.` | `block.basefee` | | базовая комиссия текущего блока | |
+| 49 | Получить хэш одного из последних завершённых 256 блоков | 3 | `idx` | `tx.blob_versioned_hashes[idx]` | | [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) | |
+| 4A | BLOBBASEFEE | 2 | `.` | `block.blobbasefee` | | базовая комиссия за BLOB-объект текущего блока ([EIP-7516](https://eips.ethereum.org/EIPS/eip-7516)) | |
+| 4B-4F | _недопустимо_ | | | | | | |
+| 50 | удалить слово из стека | 2 | `_anon` | `.` | | удалить элемент с вершины стека и отбросить его | |
+| 51 | Загрузить слово из памяти | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | прочитать слово из памяти по смещению `ost` | |
+| 52 | Сохранить слово в память | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | записать слово в память | |
+| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | записать один байт в память | |
+| 54 | Загрузить слово из хранилища | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | прочитать слово из хранилища | |
+| 55 | Сохранить слово в хранилище | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | записать слово в хранилище | |
+| 56 | Изменить счетчик команд | 8 | `dst` | `.` | | `$pc := dst` указывает, что `pc` присваивается, только если `dst` является допустимым местом назначения перехода | |
+| 57 | Условно изменить счетчик команд | 10 | `dst, condition` | `.` | | `$pc := condition ?` dst : $pc + 1` | |
+| 58 | PC | 2 | `.` | `$pc` | | счетчик команд | |
+| 59 | MSIZE | 2 | `.` | `len(mem)` | | размер памяти в текущем контексте выполнения, в байтах | |
+| 5A | Получить количество доступного газа, включая соответсвующее сокращение количества доступного газа | 2 | `.` | `gasRemaining` | | | |
+| 5B | Отметить допустимое место для прыжков | 1 | | | отметить допустимое место назначения перехода | допустимое место назначения перехода, например, место назначения перехода не внутри данных push-команды | |
+| 5C | TLOAD | 100 | `key` | `tstorage[key]` | | прочитать слово из временного хранилища ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) | |
+| 5D | TSTORE | 100 | `key, val` | `.` | tstorage[key] := val | записать слово во временное хранилище ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) | |
+| 5E | MCOPY | 3+3\*words+[A0](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `dstOst, ost, len` | `.` | mem[dstOst] := mem[ost:ost+len] | копировать память из одной области в другую ([EIP-5656](https://eips.ethereum.org/EIPS/eip-5656)) | |
+| 5F | PUSH0 | 2 | `.` | `uint8` | | добавить постоянное значение 0 в стек | |
+| 60 | PUSH1 | 3 | `.` | `uint8` | | поместить 1-байтовое значение в стек | |
+| 61 | PUSH2 | 3 | `.` | `uint16` | | поместить 2-байтовое значение в стек | |
+| 62 | PUSH3 | 3 | `.` | `uint24` | | поместить 3-байтовое значение в стек | |
+| 63 | PUSH4 | 3 | `.` | `uint32` | | поместить 4-байтовое значение в стек | |
+| 64 | PUSH5 | 3 | `.` | `uint40` | | поместить 5-байтовое значение в стек | |
+| 65 | PUSH6 | 3 | `.` | `uint48` | | поместить 6-байтовое значение в стек | |
+| 66 | PUSH7 | 3 | `.` | `uint56` | | поместить 7-байтовое значение в стек | |
+| 67 | PUSH8 | 3 | `.` | `uint64` | | поместить 8-байтовое значение в стек | |
+| 68 | PUSH9 | 3 | `.` | `uint72` | | поместить 9-байтовое значение в стек | |
+| 69 | PUSH10 | 3 | `.` | `uint80` | | поместить 10-байтовое значение в стек | |
+| 6A | PUSH11 | 3 | `.` | `uint88` | | поместить 11-байтовое значение в стек | |
+| 6B | PUSH12 | 3 | `.` | `uint96` | | поместить 12-байтовое значение в стек | |
+| 6C | PUSH13 | 3 | `.` | `uint104` | | поместить 13-байтовое значение в стек | |
+| 6D | PUSH14 | 3 | `.` | `uint112` | | поместить 14-байтовое значение в стек | |
+| 6E | PUSH15 | 3 | `.` | `uint120` | | поместить 15-байтовое значение в стек | |
+| 6F | PUSH16 | 3 | `.` | `uint128` | | поместить 16-байтовое значение в стек | |
+| 70 | PUSH17 | 3 | `.` | `uint136` | | поместить 17-байтовое значение в стек | |
+| 71 | PUSH18 | 3 | `.` | `uint144` | | поместить 18-байтовое значение в стек | |
+| 72 | PUSH19 | 3 | `.` | `uint152` | | поместить 19-байтовое значение в стек | |
+| 73 | PUSH20 | 3 | `.` | `uint160` | | поместить 20-байтовое значение в стек | |
+| 74 | PUSH21 | 3 | `.` | `uint168` | | поместить 21-байтовое значение в стек | |
+| 75 | PUSH22 | 3 | `.` | `uint176` | | поместить 22-байтовое значение в стек | |
+| 76 | PUSH23 | 3 | `.` | `uint184` | | поместить 23-байтовое значение в стек | |
+| 77 | PUSH24 | 3 | `.` | `uint192` | | поместить 24-байтовое значение в стек | |
+| 78 | PUSH25 | 3 | `.` | `uint200` | | поместить 25-байтовое значение в стек | |
+| 79 | PUSH26 | 3 | `.` | `uint208` | | поместить 26-байтовое значение в стек | |
+| 7A | PUSH27 | 3 | `.` | `uint216` | | поместить 27-байтовое значение в стек | |
+| 7B | PUSH28 | 3 | `.` | `uint224` | | поместить 28-байтовое значение в стек | |
+| 7C | PUSH29 | 3 | `.` | `uint232` | | поместить 29-байтовое значение в стек | |
+| 7D | PUSH30 | 3 | `.` | `uint240` | | поместить 30-байтовое значение в стек | |
+| 7E | PUSH31 | 3 | `.` | `uint248` | | поместить 31-байтовое значение в стек | |
+| 7F | PUSH32 | 3 | `.` | `uint256` | | поместить 32-байтовое значение в стек | |
+| 80 | DUP1 | 3 | `a` | `a, a` | | клонировать 1-е значение в стеке | |
+| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | клонировать 2-е значение в стеке | |
+| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | клонировать 3-е значение в стеке | |
+| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | клонировать 4-е значение в стеке | |
+| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | клонировать 5-е значение в стеке | |
+| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | клонировать 6-е значение в стеке | |
+| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | клонировать 7-е значение в стеке | |
+| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | клонировать 8-е значение в стеке | |
+| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | клонировать 9-е значение в стеке | |
+| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | клонировать 10-е значение в стеке | |
+| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | клонировать 11-е значение в стеке | |
+| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | клонировать 12-е значение в стеке | |
+| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | клонировать 13-е значение в стеке | |
+| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | клонировать 14-е значение в стеке | |
+| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | клонировать 15-е значение в стеке | |
+| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | клонировать 16-е значение в стеке | |
+| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | |
+| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | |
+| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | |
+| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | |
+| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | |
+| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | |
+| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | |
+| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG2(memory[ost:ost+len-1], topic0, topic1) | |
+| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG3(memory[ost:ost+len-1], topic0, topic1, topic2) | |
+| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | |
+| A5-EF | _недопустимо_ | | | | | | |
+| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | |
+| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | |
+| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | то же, что и DELEGATECALL, но не передает исходные msg.sender и msg.value | |
+| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | вернуть mem[ost:ost+len-1] | |
+| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | |
+| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | |
+| F6-F9 | _недопустимо_ | | | | | | |
+| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | |
+| FB-FC | _недопустимо_ | | | | | | |
+| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | отменить(mem[ost:ost+len-1]) | |
+| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | обозначенный недействительный опкод - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | |
+| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | отправляет все ETH на `addr`; если выполняется в той же транзакции, в которой был создан контракт, уничтожает контракт | |
diff --git a/public/content/translations/ru/developers/docs/frameworks/index.md b/public/content/translations/ru/developers/docs/frameworks/index.md
new file mode 100644
index 00000000000..f279e73149e
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/frameworks/index.md
@@ -0,0 +1,153 @@
+---
+title: "Фреймворки для разработки Dapp"
+description: "Изучите преимущества фреймворков и сравните их доступные варианты."
+lang: ru
+---
+
+## Введение во фреймворки {#introduction-to-frameworks}
+
+Для создания полноценного децентрализованного приложения требуются разные технологии. Программные фреймворки включают в себя многие из необходимых функций или предоставляют простые системы плагинов для выбора нужных вам инструментов.
+
+Фреймворки обладают множеством готовых функций, например:
+
+- Функции для запуска локального экземпляра блокчейна.
+- Утилиты для составления и тестирования ваших смарт-контрактов.
+- Дополнения для разработки клиентской части, позволяющие создавать пользовательское приложение
+ в том же проекте/репозитории.
+- Конфигурация для подключения к сетям Ethereum и развертывания
+ контрактов как в локально запущенном экземпляре, так и в одной из
+ публичных сетей Ethereum.
+- Распространение децентрализованных приложений — интеграция с такими вариантами хранилищ,
+ как IPFS.
+
+## Предварительные условия {#prerequisites}
+
+Прежде чем углубляться во фреймворки, мы рекомендуем сначала прочитать наше введение в [децентрализованные приложения](/developers/docs/dapps/) и [стек Ethereum](/developers/docs/ethereum-stack/).
+
+## Доступные фреймворки {#available-frameworks}
+
+**Foundry** — **_сверхбыстрый, портативный и модульный набор инструментов для разработки приложений на Ethereum_**
+
+- [Установить Foundry](https://book.getfoundry.sh/)
+- [Книга по Foundry](https://book.getfoundry.sh/)
+- [Чат сообщества Foundry в Telegram](https://t.me/foundry_support)
+- [Awesome Foundry](https://github.com/crisgarner/awesome-foundry)
+
+**Hardhat —** **_среда разработки Ethereum для профессионалов._**
+
+- [hardhat.org](https://hardhat.org)
+- [GitHub](https://github.com/nomiclabs/hardhat)
+
+**Ape —** **_инструмент для разработки умных контрактов для Python-разработчиков, специалистов по анализу данных и специалистов по безопасности._**
+
+- [Документация](https://docs.apeworx.io/ape/stable/)
+- [GitHub](https://github.com/ApeWorX/ape)
+
+**Web3j —** **_платформа для разработки блокчейн-приложений на JVM._**
+
+- [Домашняя страница](https://www.web3labs.com/web3j-sdk)
+- [Документация](https://docs.web3j.io)
+- [GitHub](https://github.com/web3j/web3j)
+
+**ethers-kt —** **_асинхронная, высокопроизводительная библиотека на Kotlin/Java/Android для блокчейнов на основе EVM._**
+
+- [GitHub](https://github.com/Kr1ptal/ethers-kt)
+- [Примеры](https://github.com/Kr1ptal/ethers-kt/tree/master/examples)
+- [Discord](https://discord.gg/rx35NzQGSb)
+
+**Create Eth App —** **_создавайте приложения на базе Ethereum одной командой. Поставляется с широким выбором фреймворков пользовательского интерфейса и шаблонов DeFi._**
+
+- [GitHub](https://github.com/paulrberg/create-eth-app)
+- [Шаблоны](https://github.com/PaulRBerg/create-eth-app/tree/develop/templates)
+
+**Scaffold-Eth —** **_компоненты и хуки Ethers.js + Hardhat + React для web3: все, что вам нужно для начала создания децентрализованных приложений на основе умных контрактов._**
+
+- [GitHub](https://github.com/scaffold-eth/scaffold-eth-2)
+
+**Tenderly —** **_платформа для разработки Web3, которая позволяет разработчикам блокчейн-приложений создавать, тестировать, отлаживать, отслеживать и управлять умными контрактами и улучшать UX децентрализованных приложений._**
+
+- [Веб-сайт](https://tenderly.co/)
+- [Документация](https://docs.tenderly.co/)
+
+**The Graph —** **_The Graph для эффективного запроса данных из блокчейна._**
+
+- [Веб-сайт](https://thegraph.com/)
+- [Руководство](/developers/tutorials/the-graph-fixing-web3-data-querying/)
+
+**Alchemy —** **_платформа для разработки на Ethereum._**
+
+- [alchemy.com](https://www.alchemy.com/)
+- [GitHub](https://github.com/alchemyplatform)
+- [Discord](https://discord.com/invite/alchemyplatform)
+
+**NodeReal —** **_платформа для разработки на Ethereum._**
+
+- [Nodereal.io](https://nodereal.io/)
+- [GitHub](https://github.com/node-real)
+- [Discord](https://discord.gg/V5k5gsuE)
+
+**thirdweb SDK —** **_создавайте web3-приложения, которые могут взаимодействовать с вашими умными контрактами, используя наши мощные SDK и CLI._**
+
+- [Документация](https://portal.thirdweb.com/sdk/)
+- [GitHub](https://github.com/thirdweb-dev/)
+
+**Chainstack —** **_платформа для разработки Web3 (Ethereum и другие)._**
+
+- [chainstack.com](https://www.chainstack.com/)
+- [GitHub](https://github.com/chainstack)
+- [Discord](https://discord.gg/BSb5zfp9AT)
+
+**Crossmint —** **_платформа для разработки web3 корпоративного уровня, которая позволяет создавать NFT-приложения на всех основных EVM-сетях (и других)._**
+
+- [Веб-сайт](https://www.crossmint.com)
+- [Документация](https://docs.crossmint.com)
+- [Discord](https://discord.com/invite/crossmint)
+
+**Brownie —** **_среда разработки и фреймворк для тестирования на Python._**
+
+- [Документация](https://eth-brownie.readthedocs.io/en/latest/)
+- [GitHub](https://github.com/eth-brownie/brownie)
+- **В настоящее время Brownie не поддерживается**
+
+**OpenZeppelin SDK —** **_лучший набор инструментов для умных контрактов: набор инструментов, которые помогут вам разрабатывать, компилировать, обновлять, развертывать умные контракты и взаимодействовать с ними._**
+
+- [OpenZeppelin Defender SDK](https://docs.openzeppelin.com/defender/sdk)
+- [GitHub](https://github.com/OpenZeppelin/openzeppelin-sdk)
+- [Форум сообщества](https://forum.openzeppelin.com/c/support/17)
+- **Разработка OpenZeppelin SDK прекращена**
+
+**Catapulta —** **_мультисетевой инструмент для развертывания умных контрактов, который автоматизирует верификацию в обозревателях блоков, отслеживает развернутые умные контракты, позволяет делиться отчетами о развертывании, plug-n-play для проектов Foundry и Hardhat._**
+
+- [Веб-сайт](https://catapulta.sh/)
+- [Документация](https://catapulta.sh/docs)
+- [Github](https://github.com/catapulta-sh)
+
+**GoldRush (на базе Covalent) —** **_GoldRush предлагает самый полный набор API-интерфейсов для данных из блокчейна для разработчиков, аналитиков и предприятий. Независимо от того, создаете ли вы панель DeFi, кошелек, торгового бота, ИИ-агента или платформу для обеспечения соответствия, API-интерфейсы данных предоставляют быстрый, точный и удобный для разработчиков доступ к необходимым вам ончейн-данным_**
+
+- [Веб-сайт](https://goldrush.dev/)
+- [Документация](https://goldrush.dev/docs/chains/ethereum)
+- [GitHub](https://github.com/covalenthq)
+- [Discord](https://www.covalenthq.com/discord/)
+
+**Wake —** **_универсальный фреймворк на Python для тестирования контрактов, фаззинга, развертывания, сканирования уязвимостей и навигации по коду._**
+
+- [Домашняя страница](https://getwake.io/)
+- [Документация](https://ackeeblockchain.com/wake/docs/latest/)
+- [GitHub](https://github.com/Ackee-Blockchain/wake)
+- [Расширение для VS Code](https://marketplace.visualstudio.com/items?itemName=AckeeBlockchain.tools-for-solidity)
+
+**Veramo —** **_модульный и агностический фреймворк с открытым исходным кодом, который позволяет разработчикам децентрализованных приложений легко встраивать децентрализованные удостоверения и проверяемые учетные данные в свои приложения._**
+
+- [Домашняя страница](https://veramo.io/)
+- [Документация](https://veramo.io/docs/basics/introduction)
+- [GitHub](https://github.com/uport-project/veramo)
+- [Discord](https://discord.com/invite/FRRBdjemHV)
+- [Пакет NPM](https://www.npmjs.com/package/@veramo/core)
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Настройка локальной среды разработки](/developers/local-environment/)
diff --git a/public/content/translations/ru/developers/docs/gas/index.md b/public/content/translations/ru/developers/docs/gas/index.md
index ea4ef5bfd4b..eae01242954 100644
--- a/public/content/translations/ru/developers/docs/gas/index.md
+++ b/public/content/translations/ru/developers/docs/gas/index.md
@@ -1,14 +1,15 @@
---
-title: Газ и комиссии
-description:
+title: "Газ и комиссии"
+metaTitle: "Газ и комиссии в Ethereum: технический обзор"
+description: "Узнайте о комиссиях за газ в Ethereum, о том, как они рассчитываются, и об их роли в безопасности сети и обработке транзакций."
lang: ru
---
Газ необходим сети Ethereum. Это топливо, которое поддерживает его работу, словно бензин для автомобиля.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Чтобы лучше понять эту страницу, мы рекомендуем вам сначала ознакомиться с [транзакциями](/developers/docs/transactions/) и [EVM](/developers/docs/evm/).
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочесть о [транзакциях](/developers/docs/transactions/) и [EVM](/developers/docs/evm/).
## Что такое газ? {#what-is-gas}
@@ -16,80 +17,85 @@ lang: ru
Поскольку каждая транзакция в Ethereum требует вычислительных ресурсов для исполнения, эти ресурсы должны быть оплачены, чтобы убедиться, что Ethereum устойчив к спаму и не застрянет в бесконечном цикле вычислений. Плата за вычисления происходит в виде комиссии за газ.
-Комиссия за газ — это **количество газа, необходимое для выполнения операции, умноженное на стоимость единицы газа**. Комиссия платится независимо от того, состоится транзакция или провалится.
+Комиссия за газ — это **количество газа, использованного для выполнения определенной операции, умноженное на стоимость единицы газа**. Комиссия платится независимо от того, состоится транзакция или провалится.
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Схема адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
Газ должен оплачиваться базовой валютой в Ethereum — эфиром (ETH). Зачастую цена газа называется в gwei, что является деноминацией ETH. Одна единица gwei — это одна миллиардная часть от целого ETH (0,000000001 ETH, 10-9 ETH).
Например, вместо того, чтобы говорить, что ваш газ стоит 0,000000001 эфира, вы можете сказать, что ваш газ стоит 1 gwei.
-Слово gwei происходит от слова giga-wei, то есть «миллиард wei». Один gwei равен миллиарду wei. Сам wei (названный в честь [Вэй Дая](https://wikipedia.org/wiki/Wei_Dai), создателя [b-money](https://www.investopedia.com/terms/b/bmoney.asp)) является самой маленькой единицей ETH.
+Слово gwei происходит от слова giga-wei, то есть «миллиард wei». Один gwei равен миллиарду wei. Сам Wei (назван в честь [Вэй Дая](https://wikipedia.org/wiki/Wei_Dai), создателя [b-money](https://www.investopedia.com/terms/b/bmoney.asp)) — это наименьшая единица ETH.
## Как вычислить комиссию за газ? {#how-are-gas-fees-calculated}
Вы можете указать количество газа, который хотите заплатить, когда отправляете транзакцию. Предлагая определенное количество газа, вы делаете ставку на то, что ваша транзакция будет включена в следующий блок. Если вы предложите слишком мало, валидаторы с малой долей вероятности предпочтут включать эту транзакцию в блок, так что она может быть включена позже или даже никогда. Если вы предложите слишком много, то потратите какое-то количество ETH зря. Так как же узнать, сколько нужно заплатить?
-Общее количество выплачиваемого газа делится на два компонента: `base fee` (базовая комиссия) и `priority fee` (приоритетная комиссия, чаевые).
+Общая сумма газа, которую вы платите, делится на две составляющие: `базовая комиссия` и `комиссия за приоритет` (чаевые).
-Величина `base fee` устанавливается протоколом — вы должны оплатить газ как минимум в этом количестве, чтобы ваша транзакция считалась действительной. Значение `priority fee` — это чаевые, которые вы прибавляете к базовой комиссии, чтобы сделать транзакцию привлекательной для валидаторов, а они в первую очередь стремились включить ее в следующий блок.
+`Базовая комиссия` устанавливается протоколом — вы должны заплатить как минимум эту сумму, чтобы ваша транзакция считалась действительной. `Комиссия за приоритет` — это чаевые, которые вы добавляете к базовой комиссии, чтобы сделать вашу транзакцию привлекательной для валидаторов, чтобы они выбрали ее для включения в следующий блок.
-Транзакция, при которой выплачивается только `base fee`, технически действительна, но ее включение в блок маловероятно, потому что валидаторы будут выбирать ее в самую последнюю очередь. Правильно посчитать `priority fee` можно, глядя на загруженность сети в момент отправки транзакции. Если спрос большой, рекомендуется поднять `priority fee` повыше, а когда спрос маленький — добавлять можно меньше.
+Транзакция, которая оплачивает только `базовую комиссию`, технически действительна, но вряд ли будет включена, поскольку не дает валидаторам стимула выбирать ее вместо любой другой транзакции. «Правильная» `комиссия за приоритет` определяется загруженностью сети в момент отправки транзакции — если спрос большой, вам, возможно, придется установить более высокую `комиссию за приоритет`, но когда спрос меньше, вы можете платить меньше.
Например, Джордан хочет отправить Тэйлору 1 ETH. Трансфер ETH занимает в блоке 21 000 единиц газа, а базовая комиссия за газ — 10 gwei. Джордан добавляет чаевые в виде 2 gwei.
В итоге комиссия будет рассчитана таким образом:
-`количество использованного газа * (базовая комиссия + приоритетная комиссия),`
+`единиц использованного газа * (базовая комиссия + комиссия за приоритет)`
-где `base fee` — это значение, установленное протоколом, а `priority fee` — значение, установленное пользователем в качестве чаевых валидатору.
+где `базовая комиссия` — это значение, устанавливаемое протоколом, а `комиссия за приоритет` — это значение, устанавливаемое пользователем в качестве чаевых валидатору.
-Например, `21 000 * (10 + 2) = 252 000 gwei` (0,000252 ETH).
+например, `21 000 * (10 + 2) = 252 000 gwei` (0,000252 ETH).
-Когда Джордан отправляет деньги, 1,000252 ETH будет списано со счета Джордана. Тэйлору будет начислено 1,0000 ETH. Валидатор получит чаевые в размере 0,000042 ETH. Базовая комиссия `base fee` в размере 0,00021 ETH будет сожжена.
+Когда Джордан отправляет деньги, 1,000252 ETH будет списано со счета Джордана. Тэйлору будет начислено 1,0000 ETH. Валидатор получит чаевые в размере 0,000042 ETH. `Базовая комиссия` в размере 0,00021 ETH сжигается.
### Базовая комиссия {#base-fee}
-У каждого блока есть базовая комиссия, которая действует как стартовая цена. Чтобы иметь право на включение в блок, предлагаемая цена за газ должна быть по крайней мере равна базовой комиссии. Базовая комиссия рассчитывается независимо от текущего блока, вместо этого она определяется предыдущими блоками, что делает комиссии за транзакции более предсказуемыми для пользователей. Когда создается блок, **базовая комиссия «сжигается»** и исключается из обращения.
+У каждого блока есть базовая комиссия, которая действует как стартовая цена. Чтобы иметь право на включение в блок, предлагаемая цена за газ должна быть по крайней мере равна базовой комиссии. Базовая комиссия рассчитывается независимо от текущего блока и вместо этого определяется предыдущими блоками, что делает комиссии за транзакции более предсказуемыми для пользователей. Когда блок создается, эта **базовая комиссия «сжигается»**, выводя ее из обращения.
-Базовая комиссия рассчитывается по формуле, которая сравнивает размер предыдущего блока (количество газа, использованного для всех транзакций) с целевым размером. Базовая комиссия увеличится максимум на 12,5 % за блок, если размер целевого блока превышен. Этот экспоненциальный рост делает экономически нецелесообразным, чтобы размер блока оставался высоким на неопределенный срок.
+Базовая комиссия рассчитывается по формуле, которая сравнивает размер предыдущего блока (количество газа, использованного для всех транзакций) с целевым размером (половина лимита газа). Базовая комиссия будет увеличиваться или уменьшаться максимум на 12,5% за блок, если целевой размер блока больше или меньше целевого, соответственно. Этот экспоненциальный рост делает экономически нецелесообразным, чтобы размер блока оставался высоким на неопределенный срок.
| Номер блока | Включенный газ | Увеличение комиссии | Текущая базовая комиссия |
-| ----------- | --------------:| -------------------:| ------------------------:|
-| 1 | 15 млн | 0 % | 100 gwei |
-| 2 | 30 млн | 0 % | 100 gwei |
-| 3 | 30 млн | 12,5 % | 112,5 gwei |
-| 4 | 30 млн | 12,5 % | 126,6 gwei |
-| 5 | 30 млн | 12,5 % | 142,4 gwei |
-| 6 | 30 млн | 12,5 % | 160,2 gwei |
-| 7 | 30 млн | 12,5 % | 180,2 gwei |
-| 8 | 30 млн | 12,5 % | 202,7 gwei |
-
-Согласно приведенной выше таблице для создании транзакции в блоке номер 9 кошелек позволит пользователю понять, что максимальная базовая комиссия **maximum base fee**, которая будет добавлена к следующему блоку, составляет текущую базовую комиссию `current base fee * 112,5 %`, или `202,7 gwei * 112,5 % = 228,1 gwei`.
+| ----------- | -------------: | ------------------: | -----------------------: |
+| 1 | 18 млн | 0% | 100 gwei |
+| 2 | 36 млн | 0% | 100 gwei |
+| 3 | 36 млн | 12,5 % | 112,5 gwei |
+| 4 | 36 млн | 12,5 % | 126,6 gwei |
+| 5 | 36 млн | 12,5 % | 142,4 gwei |
+| 6 | 36 млн | 12,5 % | 160,2 gwei |
+| 7 | 36 млн | 12,5 % | 180,2 gwei |
+| 8 | 36 млн | 12,5 % | 202,7 gwei |
+
+В таблице выше показан пример с использованием лимита газа в 36 миллионов. Следуя этому примеру, чтобы создать транзакцию в блоке номер 9, кошелек с уверенностью сообщит пользователю, что **максимальная базовая комиссия**, которая будет добавлена в следующий блок, составляет `текущая базовая комиссия * 112,5%` или `202,7 gwei * 112,5% = 228,1 gwei`.
Также важно отметить, что сильные всплески серий полных блоков маловероятны из-за скорости, с которой базовая комиссия увеличивается перед полным блоком.
-| Номер блока | Включенный газ | Увеличение комиссии | Текущая базовая комиссия |
-| ----------- | --------------:| -------------------:| ------------------------:|
-| 30 | 30 млн | 12,5 % | 2705,6 gwei |
-| ... | ... | 12,5 % | ... |
-| 50 | 30 млн | 12,5 % | 28531,3 gwei |
-| ... | ... | 12,5 % | ... |
-| 100 | 30 млн | 12,5 % | 10302608,6 gwei |
+| Номер блока | Включенный газ | Увеличение комиссии | Текущая базовая комиссия |
+| --------------------------------------------------- | --------------------------------------------------: | ------------------: | --------------------------------------------------: |
+| 30 | 36 млн | 12,5 % | 2705,6 gwei |
+| ... | ... | 12,5 % | ... |
+| 50 | 36 млн | 12,5 % | 28531,3 gwei |
+| ... | ... | 12,5 % | ... |
+| 100 | 36 млн | 12,5 % | 10302608,6 gwei |
-### Приоритетная комиссия (чаевые) {#priority-fee}
+### Комиссия за приоритет (чаевые) {#priority-fee}
-Приоритетная комиссия (чаевые) мотивирует валидаторов включить транзакцию в блок. Без чаевых валидаторы сочтут экономически выгодным создавать пустые блоки, потому что они все равно будут получать награду того же размера. Небольшие чаевые дают валидаторам минимальный стимул включить транзакцию. Для транзакций, которые нуждаются в приоритетном исполнении перед другими в том же блоке, можно добавить повышенные чаевые, чтобы попробовать обойти конкурирующие транзакции.
+Комиссия за приоритет (чаевые) стимулирует валидаторов максимизировать количество транзакций в блоке, ограниченное только лимитом газа в блоке. Без чаевых рациональный валидатор мог бы включать меньше транзакций — или даже ноль — без каких-либо прямых штрафов на уровне исполнения или уровне консенсуса, поскольку вознаграждения за стейкинг не зависят от количества транзакций в блоке. Кроме того, чаевые позволяют пользователям предлагать более высокую цену, чем другие, за приоритет в том же блоке, что фактически сигнализирует о срочности.
### Максимальная комиссия {#maxfee}
-Чтобы исполнить транзакцию в сети, пользователи могут указать максимальный лимит, который они готовы заплатить за исполнение своей транзакции. Этот необязательный параметр называется максимальной комиссией за газ — `maxFeePerGas`. Для исполнения транзакции максимальная комиссия должна превышать сумму базовой комиссии и чаевых. Отправителю транзакции возвращается разница между максимальной комиссией и совокупностью базовой комиссии и чаевых.
+Чтобы исполнить транзакцию в сети, пользователи могут указать максимальный лимит, который они готовы заплатить за исполнение своей транзакции. Этот необязательный параметр известен как `maxFeePerGas`. Для исполнения транзакции максимальная комиссия должна превышать сумму базовой комиссии и чаевых. Отправителю транзакции возвращается разница между максимальной комиссией и совокупностью базовой комиссии и чаевых.
+
+### Размер блока {#block-size}
-### Размер блоков {#block-size}
+Каждый блок имеет целевой размер, равный половине текущего лимита газа, но размер блоков будет увеличиваться или уменьшаться в соответствии со спросом в сети, пока не будет достигнут лимит блока (в 2 раза больше целевого размера блока). Протокол достигает равновесного среднего размера блока на целевом уровне с помощью процесса _tâtonnement_. Это означает, что если размер блока больше, чем целевой, протокол увеличит базовую комиссию для следующего блока. Аналогичным образом протокол уменьшит базовую комиссию, если размер блока меньше, чем целевой.
-Каждый блок имеет целевой размер 30 миллионов газа, но размер блоков будет увеличиваться или уменьшаться в соответствии со спросом в сети вплоть до предела блока в 60 миллионов газа (в 2 раза больше целевого размера блока). Протокол достигает равновесного размера блока в 30 миллионов в среднем через процесс _tâtonnement_. Это означает, что если размер блока больше, чем целевой, протокол увеличит базовую комиссию для следующего блока. Аналогичным образом протокол уменьшит базовую комиссию, если размер блока меньше, чем целевой. Сумма, на которую корректируется базовая комиссия, пропорциональна тому, насколько текущий размер блока отличается от целевого. [Подробнее о блоках](/developers/docs/blocks/).
+Сумма, на которую корректируется базовая комиссия, пропорциональна тому, насколько текущий размер блока отличается от целевого. Это линейный расчет от -12,5% для пустого блока, 0% при целевом размере и до +12,5% для блока, достигающего лимита газа. Лимит газа может со временем колебаться в зависимости от сигналов валидаторов, а также в результате обновлений сети. Вы можете [посмотреть изменения лимита газа с течением времени здесь](https://eth.blockscout.com/stats/averageGasLimit?interval=threeMonths).
-### Расчет стоимости газа на практике {#calculating-fees-in-practice}
+[Подробнее о блоках](/developers/docs/blocks/)
+
+### Расчет комиссий за газ на практике {#calculating-fees-in-practice}
Вы можете точно установить, сколько хотите заплатить за выполнение вашей транзакции. Однако многие поставщики кошельков автоматически устанавливают рекомендованную комиссию за транзакцию (базовая + рекомендованная приоритетная комиссия), чтобы упростить жизнь своим пользователям.
@@ -97,42 +103,49 @@ lang: ru
Если коротко, комиссия за газ помогает поддерживать безопасность сети Ethereum. Требуя плату за каждое вычисление, выполняемое в сети, мы не позволяем злоумышленникам рассылать по ней спам. Чтобы избежать случайных или умышленных бесконечных циклов и других вычислительных потерь в коде, каждой транзакции требуется установить ограничение на количество вычислительных шагов выполнения кода, которые она может использовать. Основной единицей вычислений является «газ».
-Хотя транзакция включает лимит, любой газ, не использованный в транзакции, возвращается пользователю (т. е. возвращается `максимальная комиссия – (базовая комиссия + чаевые)`).
+Хотя транзакция включает в себя лимит, любой газ, не использованный в транзакции, возвращается пользователю (например, возвращается `максимальная комиссия - (базовая комиссия + чаевые)`).
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Схема адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
## Что такое лимит газа? {#what-is-gas-limit}
-Лимит газа — это максимальное количество газа, которое вы хотите израсходовать на транзакцию. Более сложные транзакции с использованием [смарт-контрактов](/developers/docs/smart-contracts/) требуют больше вычислительной работы, поэтому им требуется более высокий лимит газа, чем простому платежу. Для стандартного перевода ETH предусматривается лимит в 21 000 единиц газа.
+Лимит газа — это максимальное количество газа, которое вы хотите израсходовать на транзакцию. Более сложные транзакции с участием [смарт-контрактов](/developers/docs/smart-contracts/) требуют больше вычислительной работы, поэтому для них требуется более высокий лимит газа, чем для простого платежа. Для стандартного перевода ETH предусматривается лимит в 21 000 единиц газа.
-Например, если вы установите лимит газа в 50 000 для простого перевода ETH, EVM использует 21 000, а вам вернутся оставшиеся 29 000. Однако если вы укажете слишком мало газа, например лимит в 20 000 для простого перевода ETH, EVM израсходует ваши 20 000 единиц газа при попытке выполнить транзакцию, но не завершит ее. EVM отменит все изменения, но так как валидатор уже использовал 20 тысяч единиц газа для работы, этот газ будет считаться потраченным.
+Например, если вы установите лимит газа в 50 000 для простого перевода ETH, EVM использует 21 000, а вам вернутся оставшиеся 29 000. Однако, если вы укажете слишком мало газа, например, лимит газа в 20 000 для простого перевода ETH, транзакция не пройдет этап проверки. Она будет отклонена до включения в блок, и газ не будет потреблен. С другой стороны, если во время выполнения в транзакции закончится газ (например, смарт-контракт израсходует весь газ на полпути), EVM отменит все изменения, но весь предоставленный газ все равно будет израсходован на выполненную работу.
## Почему комиссия за газ может быть такой высокой? {#why-can-gas-fees-get-so-high}
Высокая комиссия за газ связана с популярностью Ethereum. Если спрос слишком высок, пользователи могут предложить большие чаевые, чтобы попытаться обойти транзакции других пользователей в очереди. Чем выше чаевые, тем выше вероятность того, что ваша транзакция попадет в следующий блок. Кроме того, более сложные приложения со смарт-контрактами требуют проводить множество операций для выполнения своих функций, что делает их крупными потребителями газа.
-## Инициативы по снижению затрат газа {#initiatives-to-reduce-gas-costs}
+## Инициативы по снижению затрат на газ {#initiatives-to-reduce-gas-costs}
+
+[Обновления для масштабируемости](/roadmap/) Ethereum должны в конечном итоге решить некоторые проблемы с комиссией за газ, что, в свою очередь, позволит платформе обрабатывать тысячи транзакций в секунду и масштабироваться в глобальном масштабе.
-[Обновления масштабируемости](/roadmap/) Ethereum должны в конечном итоге решить некоторые проблемы с платой за газ, что, в свою очередь, позволит платформе обрабатывать тысячи транзакций в секунду и глобально масштабироваться.
+Масштабирование на слое 2 — это основная инициатива, направленная на значительное снижение затрат газа, удобство работы пользователей и масштабируемость.
-Масштабирование на слое 2 — это основная инициатива, направленная на значительное снижение затрат газа, удобство работы пользователей и масштабируемость. [Подробнее о масштабировании на слое 2](/developers/docs/scaling/#layer-2-scaling).
+[Подробнее о масштабировании второго уровня](/developers/docs/scaling/#layer-2-scaling)
-## Отслеживание комиссий за газ {#monitoring-gas-fees}
+## Мониторинг комиссий за газ {#monitoring-gas-fees}
Если вы хотите отслеживать цены на газ, чтобы отправлять ETH дешевле, то можете использовать множество различных инструментов, включая следующее:
-- [Etherscan](https://etherscan.io/gastracker) — _средство оценки газовых цен на транзакции._
-- [Blocknative ETH Gas Estimator](https://chrome.google.com/webstore/detail/blocknative-eth-gas-estim/ablbagjepecncofimgjmdpnhnfjiecfm) — _расширение Chrome для оценки газа, поддерживающее как устаревшие транзакции типа 0, так и транзакции типа 2 EIP-1559._
-- [Калькулятор комиссий за газ Cryptoneur](https://www.cryptoneur.xyz/gas-fees-calculator) — _рассчитывает комиссии за газ в местной валюте для различных типов транзакций в основной сети, Arbitrum и Polygon._
+- [Etherscan](https://etherscan.io/gastracker) _Оценщик цены газа для транзакций_
+- [Blockscout](https://eth.blockscout.com/gas-tracker) _Оценщик цены газа для транзакций с открытым исходным кодом_
+- [ETH Gas Tracker](https://www.ethgastracker.com/) _Мониторинг и отслеживание цен на газ в Ethereum и L2 для снижения комиссий за транзакции и экономии денег_
+- [Blocknative ETH Gas Estimator](https://chrome.google.com/webstore/detail/blocknative-eth-gas-estim/ablbagjepecncofimgjmdpnhnfjiecfm) _Расширение Chrome для оценки газа, поддерживающее как устаревшие транзакции типа 0, так и транзакции типа 2 EIP-1559._
+- [Калькулятор комиссий за газ Cryptoneur](https://www.cryptoneur.xyz/gas-fees-calculator) _Рассчитывайте комиссии за газ в вашей местной валюте для различных типов транзакций в Mainnet, Arbitrum и Polygon._
-## Сопутствующие инструменты {#related-tools}
+## Связанные инструменты {#related-tools}
-- [Газовая платформа Blocknative](https://www.blocknative.com/gas) — _API для оценки газа на основе глобальных данных мемпула Blocknative._
+- [Газовая платформа Blocknative](https://www.blocknative.com/gas) _API для оценки газа на основе глобальной платформы данных мемпула Blocknative_
+- [Gas Network](https://gas.network) Ончейн-оракулы газа. Поддержка более 35 сетей.
-## Дополнительная литература {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Объяснение газа в Ethereum](https://defiprime.com/gas)
-- [Снижение потребления газа в ваших умных контрактах](https://medium.com/coinmonks/8-ways-of-reducing-the-gas-consumption-of-your-smart-contracts-9a506b339c0a)
+- [Разъяснение о газе в Ethereum](https://defiprime.com/gas)
+- [Снижение потребления газа вашими смарт-контрактами](https://medium.com/coinmonks/8-ways-of-reducing-the-gas-consumption-of-your-smart-contracts-9a506b339c0a)
- [Стратегии оптимизации газа для разработчиков](https://www.alchemy.com/overviews/solidity-gas-optimization)
-- [Документация EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
+- [Документация по EIP-1559](https://eips.ethereum.org/EIPS/eip-1559).
- [Ресурсы по EIP-1559 от Тима Бейко](https://hackmd.io/@timbeiko/1559-resources)
+- [EIP-1559: отделение механизмов от мемов](https://web.archive.org/web/20241126205908/https://research.2077.xyz/eip-1559-separating-mechanisms-from-memes)
diff --git a/public/content/translations/ru/developers/docs/ides/index.md b/public/content/translations/ru/developers/docs/ides/index.md
new file mode 100644
index 00000000000..290a85f2df6
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/ides/index.md
@@ -0,0 +1,64 @@
+---
+title: "Интегрированные среды разработки (IDE)"
+description: "Узнайте о веб- и настольных IDE для разработки на Ethereum, включая Remix, VS Code и популярные плагины."
+lang: ru
+---
+
+Когда дело доходит до настройки [интегрированной среды разработки (IDE)](https://wikipedia.org/wiki/Integrated_development_environment), программирование приложений на Ethereum аналогично программированию любого другого программного проекта. Существует много вариантов на выбор, но по итогу, выбирайте IDE или редактор кода, который лучше всего соответствует вашим предпочтениям. Скорее всего, лучший выбор IDE для разработки Ethereum — это IDE, которую вы уже используете для разработки программного обеспечения.
+
+## Веб-IDE {#web-based-ides}
+
+Если вы хотите повозиться с кодом, прежде чем [настроить локальную среду разработки](/developers/local-environment/), эти веб-приложения созданы специально для разработки смарт-контрактов Ethereum.
+
+**[Remix](https://remix.ethereum.org/)** - **_Веб-IDE со встроенным статическим анализом и тестовой виртуальной машиной блокчейна_**
+
+- [Документация](https://remix-ide.readthedocs.io/en/latest/#)
+- [Gitter](https://gitter.im/ethereum/remix)
+
+**[ChainIDE](https://chainide.com/)** - **_Облачная мультичейн-IDE_**
+
+- [Документация](https://chainide.gitbook.io/chainide-english-1/)
+- [Форум поддержки](https://forum.chainide.com/)
+
+**[Replit (Solidity Starter - Beta)](https://replit.com/@replit/Solidity-starter-beta)** - **_Настраиваемая среда разработки для Ethereum с горячей перезагрузкой, проверкой ошибок и первоклассной поддержкой тестовой сети_**
+
+- [Документация](https://docs.replit.com/)
+
+**[Tenderly Sandbox](https://sandbox.tenderly.co/)** - **_Быстрая среда для прототипирования, в которой вы можете писать, выполнять и отлаживать смарт-контракты в браузере с использованием Solidity и JavaScript_**
+
+**[EthFiddle](https://ethfiddle.com/)** - **_Веб-IDE, позволяющая писать, компилировать и отлаживать смарт-контракты_**
+
+- [Gitter](https://gitter.im/loomnetwork/ethfiddle)
+
+## Настольные IDE {#desktop-ides}
+
+Большинство известных IDE создали плагины для улучшения опыта разработки Ethereum. Как минимум, они предоставляют подсветку синтаксиса для [языков смарт-контрактов](/developers/docs/smart-contracts/languages/).
+
+**Visual Studio Code -** **_Профессиональная кроссплатформенная IDE с официальной поддержкой Ethereum_**
+
+- [Visual Studio Code](https://code.visualstudio.com/)
+- [Примеры кода](https://github.com/Azure-Samples/blockchain/blob/master/blockchain-workbench/application-and-smart-contract-samples/readme.md)
+- [GitHub](https://github.com/microsoft/vscode)
+
+**JetBrains IDE (IntelliJ IDEA, и т. д.) -** **_Основные инструменты для разработчиков программного обеспечения и команд_**
+
+- [JetBrains](https://www.jetbrains.com/)
+- [GitHub](https://github.com/JetBrains)
+- [IntelliJ Solidity](https://github.com/intellij-solidity/intellij-solidity/)
+
+**Remix Desktop -** **_Используйте Remix IDE на своем локальном компьютере_**
+
+- [Скачать](https://github.com/ethereum/remix-desktop/releases)
+- [GitHub](https://github.com/ethereum/remix-desktop)
+
+## Плагины и расширения {#plugins-extensions}
+
+- [solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) - язык Ethereum Solidity для Visual Studio Code
+- [Solidity + Hardhat for VS Code](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) - поддержка Solidity и Hardhat от команды Hardhat
+- [Prettier Solidity](https://github.com/prettier-solidity/prettier-plugin-solidity) - форматировщик кода, использующий Prettier
+
+## Дополнительные материалы {#further-reading}
+
+- [Ethereum IDEs](https://www.alchemy.com/list-of/web3-ides-on-ethereum) _- список IDE для Ethereum от Alchemy_
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/index.md b/public/content/translations/ru/developers/docs/index.md
index 4597599fdcb..10cbd47bd82 100644
--- a/public/content/translations/ru/developers/docs/index.md
+++ b/public/content/translations/ru/developers/docs/index.md
@@ -1,18 +1,18 @@
---
-title: Документация по разработке Ethereum
-description: Представление документации для разработчиков ethereum.org.
+title: "Документация по разработке Ethereum"
+description: "Представление документации для разработчиков ethereum.org."
lang: ru
---
Эта документация предназначена для помощи в сборке на Ethereum. Она охватывает Ethereum как концепцию, объясняет технический стек Ethereum и документирует более тонкие темы для сложных приложений и вариантов использования.
-Это проект сообщества с открытым исходным кодом, поэтому не стесняйтесь предлагать новые темы, добавлять новый контент и приводить примеры везде, где, по вашему мнению, это может быть полезно. Всю документацию можно редактировать через GitHub. Если вы не знаете, как это сделать, [следуйте этим инструкциям](https://github.com/ethereum/ethereum-org-website/blob/dev/docs/editing-markdown.md).
+Это проект сообщества с открытым исходным кодом, поэтому не стесняйтесь предлагать новые темы, добавлять новый контент и приводить примеры везде, где, по вашему мнению, это может быть полезно. Всю документацию можно редактировать через GitHub — если вы не знаете, как это сделать, [следуйте этим инструкциям](https://github.com/ethereum/ethereum-org-website/blob/dev/docs/editing-markdown.md).
-## Модули разработки {#development-modules}
+## Модули для разработки {#development-modules}
Если это ваша первая попытка разработки Ethereum, мы рекомендуем начинать с самого начала и продвигаться вперед, как по книге.
-### Базовые темы {#foundational-topics}
+### Основополагающие темы {#foundational-topics}
@@ -20,6 +20,6 @@ lang: ru
-### Дополнительно {#advanced}
+### Для продвинутых {#advanced}
diff --git a/public/content/translations/ru/developers/docs/intro-to-ether/index.md b/public/content/translations/ru/developers/docs/intro-to-ether/index.md
index 96dd35e2fc7..a6a22d21a27 100644
--- a/public/content/translations/ru/developers/docs/intro-to-ether/index.md
+++ b/public/content/translations/ru/developers/docs/intro-to-ether/index.md
@@ -1,12 +1,12 @@
---
-title: Введение в эфир
-description: Знакомство разработчика с криптовалютой эфир.
+title: "Техническое введение в эфир"
+description: "Знакомство разработчика с криптовалютой эфир."
lang: ru
---
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Чтобы помочь вам лучше понять эту страницу, мы рекомендуем сначала прочитать [Введение в Ethereum](/developers/docs/intro-to-ethereum/).
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочитать [Введение в Ethereum](/developers/docs/intro-to-ethereum/).
## Что такое криптовалюта? {#what-is-a-cryptocurrency}
@@ -18,17 +18,17 @@ lang: ru
## Что такое эфир? {#what-is-ether}
-**Эфир (ETH)** — это криптовалюта, используемая для различных целей в сети Ethereum. По сути, это единственная приемлемая форма выплаты комиссий за транзакции, а после [слияния](/roadmap/merge) эфир также требуется для проверки и предложения блоков в основной сети. Эфир также используется в качестве основной формы обеспечения на кредитных рынках [DeFi](/defi), в качестве расчетной единицы на торговых площадках NFT, в качестве оплаты, получаемой за оказание услуг или продажу реальных товаров, и многого другого.
+**Эфир (ETH)** — это криптовалюта, используемая для многих целей в сети Ethereum. По сути, это единственная приемлемая форма оплаты комиссий за транзакции, и после [Слияния](/roadmap/merge) эфир требуется для проверки и предложения блоков в основной сети. Эфир также используется в качестве основной формы обеспечения на кредитных рынках [DeFi](/defi), в качестве расчетной единицы на торговых площадках NFT, в качестве оплаты, получаемой за оказание услуг или продажу реальных товаров, и многого другого.
-Ethereum позволяет разработчикам создавать [**децентрализованные приложения (dapp)**](/developers/docs/dapps), которые используют общий пул вычислительных мощностей. Этот общий пул ограничен, поэтому Ethereum нужен механизм, чтобы определить, кто может его использовать. В противном случае децентрализованное приложение может случайно или злонамеренно использовать все сетевые ресурсы, что заблокирует доступ к пулу другим.
+Ethereum позволяет разработчикам создавать [**децентрализованные приложения (dapps)**](/developers/docs/dapps), которые используют общий пул вычислительных мощностей. Этот общий пул ограничен, поэтому Ethereum нужен механизм, чтобы определить, кто может его использовать. В противном случае децентрализованное приложение может случайно или злонамеренно использовать все сетевые ресурсы, что заблокирует доступ к пулу другим.
-Криптовалюта эфир поддерживает механизм ценообразования вычислительной мощности Ethereum. Когда пользователи хотят совершить транзакцию, они должны заплатить эфир, чтобы их транзакция была признана в блокчейне. Эти затраты на использование известны как [комиссия за газ](/developers/docs/gas/). Плата зависит от объема вычислительной мощности, необходимой для выполнения транзакции, и спроса на вычислительную мощность в сети в данный момент.
+Криптовалюта эфир поддерживает механизм ценообразования вычислительной мощности Ethereum. Когда пользователи хотят совершить транзакцию, они должны заплатить эфир, чтобы их транзакция была признана в блокчейне. Эти затраты на использование известны как [комиссия за газ](/developers/docs/gas/), и комиссия за газ зависит от объема вычислительной мощности, необходимой для выполнения транзакции, и спроса на вычислительную мощность в сети в данный момент.
Следовательно, даже если вредоносное dapp отправит бесконечную петлю, транзакция в конечном итоге исчерпает эфир на счету и завершится, позволяя сети вернуться в нормальное состояние.
-[Обычно](https://www.reuters.com/article/us-crypto-currencies-lending-insight-idUSKBN25M0GP#:~:text=price%20of%20ethereum) Ethereum и эфир [смешивают](https://www.cnn.com/2021/03/14/tech/nft-art-buying/index.html#:~:text=price%20of%20ethereum) [вместе](https://abcnews.go.com/Business/bitcoin-slumps-week-low-amid-renewed-worries-chinese/story?id=78399845#:~:text=cryptocurrencies%20including%20ethereum): когда люди ссылаются на «цену Ethereum», они говорят о цене эфира.
+[Часто путают](https://abcnews.go.com/Business/bitcoin-slumps-week-low-amid-renewed-worries-chinese/story?id=78399845) Ethereum и эфир — когда люди говорят о "цене Ethereum", они имеют в виду цену эфира.
-## Чеканка эфира {#minting-ether}
+## Выпуск эфира {#minting-ether}
Чеканка — это процесс создания нового эфира в реестре Ethereum. Базовый протокол Ethereum создает новый эфир, а пользователь не может его создать.
@@ -38,15 +38,15 @@ Ethereum позволяет разработчикам создавать [**д
Помимо создания эфира за счет вознаграждения за блок эфир может быть уничтожен в процессе, называемом «сжиганием». Когда эфир сжигается, он навсегда выводится из обращения.
-Сжигание эфира происходит при каждой транзакции в Ethereum. Когда пользователи платят за транзакции, базовая газовая комиссия, установленная сетью в зависимости от спроса, уничтожается. Этот механизм в совокупности с переменной длиной блока и максимальной газовой комиссией упрощает вычисление комиссий за транзакцию в Ethereum. Когда нагрузка на сеть большая, [блоки](https://etherscan.io/block/12965263) могут сжигать больше эфира, чем они создают, эффективно контролируя выпуск эфира.
+Сжигание эфира происходит при каждой транзакции в Ethereum. Когда пользователи платят за транзакции, базовая газовая комиссия, установленная сетью в зависимости от спроса, уничтожается. Этот механизм в совокупности с переменной длиной блока и максимальной газовой комиссией упрощает вычисление комиссий за транзакцию в Ethereum. Когда спрос в сети высок, [блоки](https://eth.blockscout.com/block/22580057) могут сжигать больше эфира, чем выпускать, эффективно компенсируя эмиссию эфира.
-Сжигание базовой комиссии мешает создателям блоков манипулировать транзакциями. Например, если создатели блоков получали бы базовую комиссию, они могли бы бесплатно включать свои собственные транзакции и повысить базовая комиссию для всех остальных. Или они могли бы возвращать базовую комиссию некоторым пользователям за пределами блокчейна, что привело бы к непрозрачному и запутанному рынку комиссий.
+Сжигание базовой комиссии мешает создателям блоков манипулировать транзакциями. Например, если создатели блоков получали бы базовую комиссию, они могли бы бесплатно включать свои собственные транзакции и повысить базовая комиссию для всех остальных. В качестве альтернативы, они могли бы возвращать базовую комиссию некоторым пользователям оффчейн, что привело бы к более непрозрачному и сложному рынку комиссий за транзакции.
## Номиналы эфира {#denominations}
Поскольку стоимость многих сделок в Ethereum невелика, эфир имеет несколько номиналов, которые могут быть упомянуты как более мелкие единицы счета. Из этих наименований особенно важны Wei и gwei.
-Wei — это наименьшее возможное количество эфира, поэтому многие технические реализации, такие как [Желтая книга Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf), будут основывать все вычисления на Wei.
+Wei — это наименьшее возможное количество эфира, и в результате многие технические реализации, такие как [Желтая книга Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf), будут основывать все вычисления на Wei.
Gwei (сокращение от giga-wei) часто используется для описания стоимости газа в Ethereum.
@@ -55,24 +55,24 @@ Gwei (сокращение от giga-wei) часто используется д
| Wei | 10–18 | Технические реализации |
| Gwei | 10–9 | Плата за газ, понятная для человека |
-## Передача эфира {#transferring-ether}
+## Перевод эфира {#transferring-ether}
-Каждая транзакция в Ethereum содержит поле `value`, в котором указывается количество эфира, которое необходимо передать, выраженное в wei, для отправки с адреса отправителя на адрес получателя.
+Каждая транзакция в Ethereum содержит поле `value`, в котором указывается количество эфира для перевода, выраженное в wei, для отправки с адреса отправителя на адрес получателя.
-Когда в качестве адреса получателя используется [умный контракт](/developers/docs/smart-contracts/), этот переданный эфир может использоваться для оплаты газа во время выполнения умным контрактом своего кода.
+Когда адрес получателя является [смарт-контрактом](/developers/docs/smart-contracts/), этот переведенный эфир может использоваться для оплаты газа при выполнении кода смарт-контракта.
[Подробнее о транзакциях](/developers/docs/transactions/)
## Запрос баланса эфира {#querying-ether}
-Пользователи могут запросить баланс эфира любого [аккаунта](/developers/docs/accounts/), проверив в нем поле `balance`, в котором показаны активы эфира, выраженные в wei.
+Пользователи могут запрашивать баланс эфира любого [аккаунта](/developers/docs/accounts/), проверяя поле `balance` аккаунта, в котором отображаются активы в эфире, выраженные в wei.
-[Etherscan](https://etherscan.io) — популярный инструмент для проверки баланса на адресах через веб-приложение. Например, на [этой странице Etherscan](https://etherscan.io/address/0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae) показан баланс Ethereum Foundation. Балансы учетных записей могут также запрашиваться с помощью кошельков или непосредственно путем направления запросов узлам.
+[Etherscan](https://etherscan.io) и [Blockscout](https://eth.blockscout.com) — популярные инструменты для проверки балансов адресов через веб-приложения. Например, [эта страница Blockscout](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) показывает баланс Ethereum Foundation. Балансы учетных записей могут также запрашиваться с помощью кошельков или непосредственно путем направления запросов узлам.
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Определение эфира и Ethereum](https://www.cmegroup.com/education/courses/introduction-to-ether/defining-ether-and-ethereum.html) — _CME Group_
-- [Белая книга Ethereum](/whitepaper/) — первоначальное предложение по Ethereum. Этот документ включает описание эфира и цели его создания.
+- [Определение эфира и Ethereum](https://www.cmegroup.com/education/courses/introduction-to-ether/defining-ether-and-ethereum.html) – _CME Group_
+- [Вайтпейпер Ethereum](/whitepaper/): первоначальное предложение для Ethereum. Этот документ включает описание эфира и цели его создания.
- [Калькулятор Gwei](https://www.alchemy.com/gwei-calculator): используйте этот калькулятор gwei, чтобы легко конвертировать wei, gwei и эфир. Просто впишите любое количество wei, gwei или ETH и автоматически рассчитаете конвертацию.
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/intro-to-ethereum/index.md b/public/content/translations/ru/developers/docs/intro-to-ethereum/index.md
index e65ec094ab1..aa888bb0c9d 100644
--- a/public/content/translations/ru/developers/docs/intro-to-ethereum/index.md
+++ b/public/content/translations/ru/developers/docs/intro-to-ethereum/index.md
@@ -1,6 +1,6 @@
---
-title: Введение в Ethereum
-description: Введение разработчика децентрализованных приложений в основные концепции Ethereum.
+title: "Техническое введение в Ethereum"
+description: "Введение разработчика децентрализованных приложений в основные концепции Ethereum."
lang: ru
---
@@ -14,7 +14,7 @@ lang: ru
Каждый компьютер в сети должен согласовать каждый новый блок и цепочку в целом. Такие компьютеры называют «узлами». Узлы гарантируют, что все, кто взаимодействует с блокчейном, имеют одни и те же данные. Чтобы достигнуть этого распределенного соглашения, блокчейну требуется механизм консенсуса.
-Ethereum использует механизм консенсуса, [основанный на доказательстве владения](/developers/docs/consensus-mechanisms/pos/). Любой, кто хочет добавить новые блоки в цепочку, должен использовать в стейкинге ЕТН — нативную валюту Ethereum — в качестве залога и запустить программное обеспечение валидатора. Эти «валидаторы» затем могут быть случайным образом выбраны, чтобы предложить блоки, которые другие валидаторы проверяют, и добавить их в блокчейн. Существует система вознаграждений и наказаний, которая сильно стимулирует участников быть честными и оставаться онлайн как можно больше.
+Ethereum использует [механизм консенсуса на основе доказательства владения](/developers/docs/consensus-mechanisms/pos/). Любой, кто хочет добавить новые блоки в цепочку, должен использовать в стейкинге ETH — нативную валюту Ethereum — в качестве залога и запустить программное обеспечение валидатора. Эти «валидаторы» затем могут быть случайным образом выбраны, чтобы предложить блоки, которые другие валидаторы проверяют, и добавить их в блокчейн. Существует система вознаграждений и наказаний, которая сильно стимулирует участников быть честными и оставаться онлайн как можно больше.
Если вы хотите увидеть, как данные блокчейна хэшируются, а затем добавляются к истории ссылок на блоки, то обязательно посмотрите [это демо](https://andersbrownworth.com/blockchain/blockchain) от Андерса Браунворта и сопровождающее видео ниже.
@@ -34,17 +34,17 @@ Ethereum — это блокчейн со встроенным в него ко
## Что такое эфир? {#what-is-ether}
-**Эфир (ETH)** — это нативная криптовалюта Ethereum. Целью ЕТН является создание рынка для вычислений. Такой рынок обеспечивает участникам экономический стимул для проверки и выполнения транзакционных запросов и предоставления сети вычислительных ресурсов.
+**Эфир (ETH)** — это нативная криптовалюта Ethereum. Целью ETH является создание рынка для вычислений. Такой рынок обеспечивает участникам экономический стимул для проверки и выполнения транзакционных запросов и предоставления сети вычислительных ресурсов.
-Любой участник, который передает запрос на транзакцию, должен также предложить сети некоторую сумму ЕТН в качестве награды. Сеть сожжет часть этой награды, а оставшейся частью наградит того, кто в конечном итоге сделает работу по проверке этой транзакции, выполнению, фиксации в блокчейне и передачи информации о ней в сеть.
+Любой участник, который передает запрос на транзакцию, должен также предложить сети некоторую сумму ETH в качестве награды. Сеть сожжет часть этой награды, а оставшейся частью наградит того, кто в конечном итоге сделает работу по проверке этой транзакции, выполнению, фиксации в блокчейне и передачи информации о ней в сеть.
-Количество ЕТН соответствует ресурсам, необходимым для проведения расчетов. Эти награды также предотвращают преднамеренное засорение сети злоумышленниками, требующими выполнения бесконечных вычислений или других ресурсоемких сценариев, поскольку эти участники должны будут платить за вычислительные ресурсы.
+Количество ETH соответствует ресурсам, необходимым для проведения расчетов. Эти награды также предотвращают преднамеренное засорение сети злоумышленниками, требующими выполнения бесконечных вычислений или других ресурсоемких сценариев, поскольку эти участники должны будут платить за вычислительные ресурсы.
-ЕТН также используется для обеспечения криптоэкономической безопасности сети тремя основными способами: 1) он используется в качестве средства поощрения валидаторов, которые предлагают блоки или заявляют о нечестном поведении других валидаторов; 2) он используется валидаторами в стейкинге в качестве залога на случай недобросовестного поведения: если валидаторы попытаются повести себя нечестно, их ЕТН могут быть уничтожены; З) он используется для взвешивания голосов за вновь предложенные блоки, подпитывая часть механизма консенсуса, отвечающую за выбор ответвления.
+ETH также используется для обеспечения криптоэкономической безопасности сети тремя основными способами: 1) он используется в качестве средства поощрения валидаторов, которые предлагают блоки или заявляют о нечестном поведении других валидаторов; 2) он используется валидаторами в стейкинге в качестве залога на случай недобросовестного поведения: если валидаторы попытаются повести себя нечестно, их ETH могут быть уничтожены; З) он используется для взвешивания голосов за вновь предложенные блоки, подпитывая часть механизма консенсуса, отвечающую за выбор ответвления.
## Что такое умные контракты? {#what-are-smart-contracts}
-На практике участники не пишут новый код каждый раз, когда хотят запросить вычисление в EVM. Вместо этого разработчики приложений загружают программы (многократно используемые фрагменты кода) в структуру EVM, а пользователи делают запросы на выполнение этих фрагментов кода с различными параметрами. Мы называем такие программы, загруженные и выполняемые сетью, умными (или «смарт-») контрактами.
+На практике участники не пишут новый код каждый раз, когда хотят запросить вычисление в EVM. Вместо этого разработчики приложений загружают программы (многократно используемые фрагменты кода) в структуру EVM, а пользователи делают запросы на выполнение этих фрагментов кода с различными параметрами. Мы называем программы, загруженные в сеть и выполняемые ею, "умными контрактами".
На самом простом уровне можно представить смарт-контракт как своего рода торговый автомат: сценарий, который при вызове определенных параметров и соблюдении нужных условий выполняет некоторые действия или вычисления. Например, простой умный контракт поставщика может создать и передать право собственности на цифровой актив, если запрашивающий транзакцию отправляет ETH определенному получателю.
@@ -60,7 +60,7 @@ Ethereum — это блокчейн со встроенным в него ко
### ETH {#eth}
-**Эфир (ETH)** — это собственная криптовалюта Ethereum. Пользователи платят ETH другим пользователям за выполнение их запросов на выполнение кода.
+**Эфир (ETH)** — это нативная криптовалюта Ethereum. Пользователи платят ETH другим пользователям за выполнение их запросов на выполнение кода.
[Подробнее об ETH](/developers/docs/intro-to-ether/)
@@ -68,7 +68,7 @@ Ethereum — это блокчейн со встроенным в него ко
Виртуальная машина Ethereum — это глобальный виртуальный компьютер, состояние которого хранит (и с которым согласуется) каждый участник сети Ethereum. Любой участник может запросить выполнение произвольного кода в EVM; выполнение кода изменяет состояние EVM.
-[Подробнее об EVM](/developers/docs/evm/)
+[Подробнее о EVM](/developers/docs/evm/)
### Узлы {#nodes}
@@ -100,17 +100,25 @@ Ethereum — это блокчейн со встроенным в него ко
### Умные контракты {#smart-contracts}
-Многократно используемый фрагмент кода (программа), который разработчик публикует в структуре EVM. Кто угодно может запросить выполнение кода умного контракта, сделав запрос транзакции. Поскольку разработчики могут создавать произвольные исполняемые приложения в EVM (игры, торговые площадки, финансовые инструменты и т. д.) путем публикации умных контрактов, их часто также называют [децентрализованными приложениями (или dapp)](/developers/docs/dapps/).
+Многократно используемый фрагмент кода (программа), который разработчик публикует в структуре EVM. Кто угодно может запросить выполнение кода умного контракта, сделав запрос транзакции. Поскольку разработчики могут писать произвольные исполняемые приложения в EVM (игры, торговые площадки, финансовые инструменты и т. д.) путем публикации умных контрактов, их часто также называют [dapps, или децентрализованными приложениями](/developers/docs/dapps/).
[Подробнее об умных контрактах](/developers/docs/smart-contracts/)
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
- [Белая книга Ethereum](/whitepaper/)
-- [Как вообще работает Ethereum?](https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369) — _Preethi Kasireddy_ (**обратите внимание**: этот ресурс по-прежнему ценен, но появился он до [слияния](/roadmap/merge), следовательно, он по-прежнему ссылается на механизм доказательства выполнения работы Ethereum, но сейчас Ethereum защищен с помощью [доказательства доли владения](/developers/docs/consensus-mechanisms/pos))
+- [Как вообще работает Ethereum?](https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369) — _Preethi Kasireddy_ (**Примечание:** этот ресурс по-прежнему ценен, но имейте в виду, что он был создан до [«Слияния»](/roadmap/merge), и поэтому в нем упоминается механизм доказательства работы Ethereum. На самом деле сейчас Ethereum защищен с помощью [доказательства владения](/developers/docs/consensus-mechanisms/pos)).
+
+### Больше увлекаетесь визуализацией? {#visual-learner}
+
+Эта серия видео предлагает подробное исследование основополагающих тем:
+
+
+
+[Плейлист «Основы Ethereum»](https://youtube.com/playlist?list=PLqgutSGloqiJyyoL0zvLVFPS-GMD2wKa5&si=kZTf5I7PKGTXDsOZ)
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
## Связанные руководства {#related-tutorials}
-- [Руководство разработчика по Ethereum, часть 1](/developers/tutorials/a-developers-guide-to-ethereum-part-one/) _— знакомство с Ethereum для начинающих с использованием Python и web3.py_
+- [Руководство разработчика по Ethereum, часть 1](/developers/tutorials/a-developers-guide-to-ethereum-part-one/) _— Знакомство с Ethereum для начинающих с использованием Python и web3.py_
diff --git a/public/content/translations/ru/developers/docs/mev/index.md b/public/content/translations/ru/developers/docs/mev/index.md
new file mode 100644
index 00000000000..6343cede192
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/mev/index.md
@@ -0,0 +1,221 @@
+---
+title: "Максимальная извлекаемая ценность (MEV)"
+description: "Введение в максимальную извлекаемую ценность (MEV)"
+lang: ru
+---
+
+Maximal extractable value (MEV) — это максимальное значение, которое может быть извлечено сверх стандартного вознаграждения за производство блока и платы за газ, путем включения, исключения и изменения порядка транзакций в блоке.
+
+## Максимальная извлекаемая ценность {#maximal-extractable-value}
+
+Максимальная извлекаемая ценность была впервые применена в контексте [доказательства работы](/developers/docs/consensus-mechanisms/pow/) и изначально называлась «извлекаемая майнером ценность». Это связано с тем, что при Proof-of-Work, майнеры контролируют включение, исключение и порядок транзакций. Однако после перехода на доказательство владения в результате [«Слияния»](/roadmap/merge) эти роли стали выполнять валидаторы, а майнинг больше не является частью протокола Ethereum. Однако методы извлечения ценности все еще существуют, поэтому теперь вместо этого используется термин "Максимальная извлекаемая ценность".
+
+## Предварительные условия {#prerequisites}
+
+Убедитесь, что вы знакомы с [транзакциями](/developers/docs/transactions/), [блоками](/developers/docs/blocks/), [доказательством владения](/developers/docs/consensus-mechanisms/pos) и [газом](/developers/docs/gas/). Также будет полезно знакомство с [децентрализованными приложениями](/apps/) и [DeFi](/defi/).
+
+## Извлечение MEV {#mev-extraction}
+
+Теоретически MEV полностью начисляется валидаторам, поскольку они являются единственной стороной, которая может гарантировать реализацию прибыльной возможности MEV. На практике, однако, большая часть MEV извлекается независимыми участниками сети, называемыми "искателями". Поиски используют сложные алгоритмы по данным блокчейна для выявления выгодных возможностей MEV и обеспечения ботов для автоматической передачи этих прибыльных транзакций в сеть.
+
+Валидаторы в любом случае получают часть от полной суммы MEV, потому что искатели готовы платить высокие комиссии за газ (которые достаются валидатору) в обмен на более высокую вероятность включения их прибыльных транзакций в блок. Если предположить, что искатели экономически рациональны, то комиссия за газ, которую искатель готов заплатить, составит сумму до 100% от MEV искателя (потому что если комиссия за газ будет выше, искатель понесет убытки).
+
+При этом для некоторых высококонкурентных возможностей MEV, таких как [арбитраж на DEX](#mev-examples-dex-arbitrage), искателям, возможно, придется заплатить 90% или даже больше своего общего дохода от MEV в виде платы за газ валидатору, поскольку многие хотят провести ту же прибыльную арбитражную сделку. Это связано с тем, что единственный способ гарантировать выполнение их арбитражной транзакции — это отправить транзакцию с самой высокой ценой на газ.
+
+### Газовый гольф {#mev-extraction-gas-golfing}
+
+Эта динамика сделала умение "играть в газовый гольф" — программирование транзакций таким образом, чтобы они использовали наименьшее количество газа — конкурентным преимуществом, поскольку это позволяет искателям устанавливать более высокую цену на газ, сохраняя при этом общую комиссию за газ постоянной (поскольку комиссия за газ = цена газа \* использованный газ).
+
+Некоторые известные методы газового гольфа включают в себя: использование адресов, начинающихся с длинной строки нулей (например, [0x0000000000C521824EaFf97Eac7B73B084ef9306](https://eth.blockscout.com/address/0x0000000000C521824EaFf97Eac7B73B084ef9306)), поскольку они занимают меньше места (и, следовательно, газа) для хранения; и оставление небольших балансов токенов [ERC-20](/developers/docs/standards/tokens/erc-20/) в контрактах, поскольку инициализация слота хранения (в случае, если баланс равен 0) стоит больше газа, чем обновление слота хранения. Поиск новых методов снижения расхода газа — активная область исследований среди искателей.
+
+### Обобщенные опережающие боты {#mev-extraction-generalized-frontrunners}
+
+Вместо программирования сложных алгоритмов для обнаружения прибыльных возможностей MEV некоторые искатели запускают обобщенных опережающих ботов. Обобщенные опережающие боты — это боты, которые отслеживают мемпул для обнаружения прибыльных транзакций. Опережающий бот скопирует код потенциально прибыльной транзакции, заменит адреса на адрес опережающего бота и запустит транзакцию локально, чтобы перепроверить, что измененная транзакция приносит прибыль на адрес опережающего бота. Если транзакция действительно прибыльна, опережающий бот отправит измененную транзакцию с замененным адресом и более высокой ценой на газ, "опережая" исходную транзакцию и получая MEV первоначального искателя.
+
+### Flashbots {#mev-extraction-flashbots}
+
+Flashbots — это независимый проект, который расширяет клиенты исполнения сервисом, позволяющим искателям отправлять MEV-транзакции валидаторам, не раскрывая их в публичном мемпуле. Это предотвращает опережение транзакций обобщенными опережающими ботами.
+
+## Примеры MEV {#mev-examples}
+
+MEV появляется в блокчейне несколькими способами.
+
+### Арбитраж на DEX {#mev-examples-dex-arbitrage}
+
+Арбитраж на [децентрализованных биржах](/glossary/#dex) (DEX) — это самая простая и наиболее известная возможность MEV. В результате он также является наиболее конкурентоспособным.
+
+Это работает так: если две DEX предлагают токен по двум разным ценам, кто-то может купить токен на DEX с более низкой ценой и продать его на DEX с более высокой ценой в одной, атомарной транзакции. Благодаря механике блокчейна это настоящий безрисковый арбитраж.
+
+[Вот пример](https://eth.blockscout.com/tx/0x5e1657ef0e9be9bc72efefe59a2528d0d730d478cfc9e6cdd09af9f997bb3ef4) прибыльной арбитражной транзакции, в которой искатель превратил 1000 ETH в 1045 ETH, воспользовавшись разницей в ценах на пару ETH/DAI на Uniswap и Sushiswap.
+
+### Ликвидации {#mev-examples-liquidations}
+
+Ликвидации в протоколах кредитования представляют собой еще одну известную возможность MEV.
+
+Протоколы кредитования, такие как Maker и Aave, требуют от пользователей внесения некоторого залога (например, ETH). Затем этот внесенный залог используется для предоставления займов другим пользователям.
+
+Затем пользователи могут заимствовать активы и токены у других в зависимости от своих потребностей (например, вы можете занять MKR, если хотите проголосовать за предложение по управлению в MakerDAO) в пределах определенного процента от внесенного ими залога. Например, если сумма займа составляет максимум 30%, пользователь, который вносит в протокол 100 DAI, может занять другой актив на сумму до 30 DAI. Протокол определяет точный процент покупательной способности.
+
+По мере колебания стоимости залога заемщика, меняется и его покупательная способность. Если из-за рыночных колебаний стоимость заимствованных активов превышает, скажем, 30 % от стоимости их залога (опять же, точный процент определяется протоколом), протокол обычно позволяет любому ликвидировать залог, мгновенно расплачиваясь с кредиторами (это похоже на то, как работают [маржинальные требования](https://www.investopedia.com/terms/m/margincall.asp) в традиционных финансах). В случае ликвидации заемщик обычно должен заплатить крупную комиссию за ликвидацию, часть которой достается ликвидатору — именно здесь и появляется возможность MEV.
+
+Искатели соревнуются в том, чтобы как можно быстрее проанализировать данные блокчейна, чтобы определить, каких заемщиков можно ликвидировать, и первыми отправить транзакцию ликвидации и забрать комиссию за ликвидацию себе.
+
+### Сэндвич-атаки {#mev-examples-sandwich-trading}
+
+Сэндвич-атаки — это еще один распространенный метод извлечения MEV.
+
+Для сэндвич-атаки искатель будет отслеживать мемпул на предмет крупных сделок на DEX. Например, предположим, кто-то хочет купить 10 000 UNI за DAI на Uniswap. Сделка такого масштаба окажет существенное влияние на пару UNI/DAI, потенциально значительно повысив цену UNI по отношению к DAI.
+
+Искатель может рассчитать приблизительный эффект от этой крупной сделки на цену пары UNI/DAI и исполнить оптимальный ордер на покупку непосредственно _перед_ крупной сделкой, дешево купив UNI, а затем исполнить ордер на продажу сразу _после_ крупной сделки, продав UNI по более высокой цене, вызванной крупным ордером.
+
+Однако сэндвич-атаки более рискованны, поскольку они не являются атомарными (в отличие от арбитража на DEX, описанного выше) и подвержены [атаке сальмонеллой](https://github.com/Defi-Cartel/salmonella).
+
+### MEV в NFT {#mev-examples-nfts}
+
+MEV в NFT — новое явление, и оно не всегда приносит прибыль.
+
+Однако, поскольку транзакции NFT происходят в том же блокчейне, который используется для всех остальных транзакций Ethereum, искатели могут использовать на рынке NFT те же методы, что и для традиционных возможностей MEV.
+
+Например, если происходит популярный дроп NFT и искатель хочет получить определенный NFT или набор NFT, он может запрограммировать транзакцию так, чтобы быть первым в очереди на покупку NFT, или он может купить весь набор NFT за одну транзакцию. Или, если NFT [ошибочно выставлен по низкой цене](https://www.theblockcrypto.com/post/113546/mistake-sees-69000-cryptopunk-sold-for-less-than-a-cent), искатель может опередить других покупателей и приобрести его по дешевке.
+
+Один из ярких примеров NFT MEV произошел, когда искатель потратил 7 миллионов долларов, чтобы [купить](https://eth.blockscout.com/address/0x650dCdEB6ecF05aE3CAF30A70966E2F395d5E9E5?tab=txs) каждый Cryptopunk по минимальной цене. Исследователь блокчейна [объяснил в Твиттере](https://twitter.com/IvanBogatyy/status/1422232184493121538), как покупатель работал с поставщиком MEV, чтобы сохранить свою покупку в тайне.
+
+### Длинный хвост {#mev-examples-long-tail}
+
+Арбитраж на DEX, ликвидации и сэндвич-атаки — все это очень известные возможности MEV, которые вряд ли будут прибыльными для новых искателей. Однако существует длинный хвост менее известных возможностей MEV (NFT MEV, возможно, является одной из таких возможностей).
+
+Искатели, которые только начинают, могут добиться большего успеха, ища MEV в этом длинном хвосте. [Доска вакансий MEV](https://github.com/flashbots/mev-job-board) от Flashbots перечисляет некоторые новые возможности.
+
+## Последствия MEV {#effects-of-mev}
+
+MEV не так уж плох — у MEV есть как положительные, так и отрицательные последствия для Ethereum.
+
+### Положительные стороны {#effects-of-mev-the-good}
+
+Многие проекты DeFi полагаются на экономически рациональных участников для обеспечения полезности и стабильности своих протоколов. Например, арбитраж на DEX гарантирует, что пользователи получают лучшие и самые правильные цены на свои токены, а протоколы кредитования полагаются на быстрые ликвидации, когда заемщики опускаются ниже коэффициентов обеспечения, чтобы кредиторы получили свои деньги обратно.
+
+Без рациональных искателей, которые ищут и исправляют экономические неэффективности и используют экономические стимулы протоколов, протоколы DeFi и децентрализованные приложения в целом могут быть не такими надежными, как сегодня.
+
+### Отрицательные стороны {#effects-of-mev-the-bad}
+
+На уровне приложений некоторые формы MEV, такие как сэндвич-атаки, однозначно ухудшают пользовательский опыт. Пользователи, подвергшиеся сэндвич-атаке, сталкиваются с повышенным проскальзыванием и худшим исполнением своих сделок.
+
+На сетевом уровне обобщенные опережающие боты и аукционы цен на газ, в которых они часто участвуют (когда два или более опережающих бота конкурируют за включение своей транзакции в следующий блок, постепенно повышая цену на газ для своих транзакций), приводят к перегрузке сети и высоким ценам на газ для всех остальных, кто пытается выполнить обычные транзакции.
+
+Помимо того, что происходит _внутри_ блоков, MEV может иметь пагубные последствия и _между_ блоками. Если MEV, доступный в блоке, значительно превышает стандартную награду за блок, валидаторы могут быть заинтересованы в реорганизации блоков и захвате MEV для себя, что вызовет реорганизацию блокчейна и нестабильность консенсуса.
+
+Эта возможность реорганизации блокчейна была [ранее исследована на блокчейне Bitcoin](https://dl.acm.org/doi/10.1145/2976749.2978408). По мере того как награда за блок Bitcoin уменьшается вдвое, а комиссии за транзакции составляют все большую часть награды за блок, возникают ситуации, когда для майнеров становится экономически рациональным отказаться от награды за следующий блок и вместо этого перемайнить прошлые блоки с более высокими комиссиями. С ростом MEV подобная ситуация может возникнуть и в Ethereum, угрожая целостности блокчейна.
+
+## Состояние MEV {#state-of-mev}
+
+Извлечение MEV резко возросло в начале 2021 года, что привело к чрезвычайно высоким ценам на газ в первые несколько месяцев года. Появление MEV-ретранслятора от Flashbots снизило эффективность обобщенных опережающих ботов и вывело аукционы цен на газ в офчейн, снизив цены на газ для обычных пользователей.
+
+Хотя многие искатели по-прежнему хорошо зарабатывают на MEV, по мере того как возможности становятся более известными и все больше искателей конкурируют за одну и ту же возможность, валидаторы будут получать все большую и большую долю от общего дохода MEV (потому что те же самые аукционы газа, что и описанные выше, также происходят во Flashbots, хотя и в частном порядке, и валидаторы будут получать полученный доход от газа). MEV также не является уникальным для Ethereum, и по мере того, как возможности на Ethereum становятся более конкурентными, искатели переходят на альтернативные блокчейны, такие как Binance Smart Chain, где существуют аналогичные возможности MEV, как и на Ethereum, но с меньшей конкуренцией.
+
+С другой стороны, переход от доказательства работы к доказательству владения и продолжающиеся усилия по масштабированию Ethereum с использованием роллапов меняют ландшафт MEV таким образом, который все еще не совсем ясен. Пока не до конца понятно, как наличие гарантированных создателей блоков, известных заранее, меняет динамику извлечения MEV по сравнению с вероятностной моделью в proof-of-work, или как это будет нарушено, когда будут реализованы [выборы единственного секретного лидера](https://ethresear.ch/t/secret-non-single-leader-election/11789) и [технология распределенных валидаторов](/staking/dvt/). Аналогичным образом, еще предстоит выяснить, какие возможности MEV будут существовать, когда большая часть активности пользователей будет перенесена с Ethereum на его роллапы и шарды уровня 2.
+
+## MEV в Ethereum с Proof-of-Stake (PoS) {#mev-in-ethereum-proof-of-stake}
+
+Как уже объяснялось, MEV имеет негативные последствия для общего пользовательского опыта и безопасности уровня консенсуса. Но переход Ethereum на консенсус proof-of-stake (получивший название "Слияние") потенциально несет в себе новые риски, связанные с MEV:
+
+### Централизация валидаторов {#validator-centralization}
+
+В Ethereum после «Слияния» валидаторы (внесшие залог в размере 32 ETH) достигают консенсуса относительно действительности блоков, добавляемых в Beacon Chain. Поскольку 32 ETH могут быть недоступны для многих, [присоединение к пулу для стейкинга](/staking/pools/) может быть более реальным вариантом. Тем не менее, здоровое распределение [одиночных стейкеров](/staking/solo/) является идеальным, поскольку это смягчает централизацию валидаторов и повышает безопасность Ethereum.
+
+Однако считается, что извлечение MEV способно ускорить централизацию валидаторов. Частично это связано с тем, что, поскольку валидаторы [зарабатывают меньше за предложение блоков](/roadmap/merge/issuance/#how-the-merge-impacts-ETH-supply), чем раньше майнеры, извлечение MEV сильно [повлияло на доходы валидаторов](https://github.com/flashbots/eth2-research/blob/main/notebooks/mev-in-eth2/eth2-mev-calc.ipynb) после [«Слияния»](/roadmap/merge/).
+
+У более крупных пулов для стейкинга, вероятно, будет больше ресурсов для инвестирования в необходимые оптимизации для получения возможностей MEV. Чем больше MEV извлекают эти пулы, тем больше у них ресурсов для улучшения своих возможностей по извлечению MEV (и увеличения общего дохода), что по сути создает [экономию от масштаба](https://www.investopedia.com/terms/e/economiesofscale.asp#).
+
+При меньшем количестве ресурсов в их распоряжении одиночные стейкеры могут оказаться не в состоянии получать прибыль от возможностей MEV. Это может усилить давление на независимых валидаторов, чтобы они присоединялись к мощным пулам для стейкинга для увеличения своих доходов, снижая децентрализацию в Ethereum.
+
+### Закрытые мемпулы {#permissioned-mempools}
+
+В ответ на сэндвич-атаки и опережающие атаки трейдеры могут начать заключать офчейн-сделки с валидаторами для обеспечения конфиденциальности транзакций. Вместо того чтобы отправлять потенциальную MEV-транзакцию в публичный мемпул, трейдер отправляет ее напрямую валидатору, который включает ее в блок и делит прибыль с трейдером.
+
+"Темные пулы" — это более крупная версия этой схемы, которая функционирует как закрытые мемпулы с ограниченным доступом, открытые для пользователей, готовых платить определенные сборы. Эта тенденция уменьшит открытость и отсутствие необходимости в доверии в Ethereum и потенциально превратит блокчейн в механизм "плати, чтобы играть", который отдает предпочтение тому, кто больше заплатит.
+
+Закрытые мемпулы также ускорят риски централизации, описанные в предыдущем разделе. Крупные пулы, управляющие несколькими валидаторами, скорее всего, получат выгоду от предложения конфиденциальности транзакций трейдерам и пользователям, увеличивая свои доходы от MEV.
+
+Борьба с этими проблемами, связанными с MEV, в Ethereum после «Слияния» является основной областью исследований. На сегодняшний день два предложенных решения для уменьшения негативного влияния MEV на децентрализацию и безопасность Ethereum после «Слияния» — это [**разделение создателя и предложившего блок (PBS)**](/roadmap/pbs/) и [**API для создателей блоков**](https://github.com/ethereum/builder-specs).
+
+### Разделение предложившего и создателя блока {#proposer-builder-separation}
+
+Как в proof-of-work, так и в proof-of-stake, узел, который строит блок, предлагает его для добавления в цепь другим узлам, участвующим в консенсусе. Новый блок становится частью канонической цепи после того, как другой майнер построит блок поверх него (в PoW) или он получит аттестации от большинства валидаторов (в PoS).
+
+Сочетание ролей производителя блока и предложившего блок является причиной большинства проблем, связанных с MEV, описанных ранее. Например, узлы консенсуса заинтересованы в запуске реорганизаций цепи в [атаках «бандита времени»](https://www.mev.wiki/attack-examples/time-bandit-attack) для максимизации доходов от MEV.
+
+[Разделение предложившего и создателя блока](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) (PBS) предназначено для смягчения влияния MEV, особенно на уровне консенсуса. Главной особенностью PBS является разделение ролей производителя блока и предложившего блок. Валидаторы по-прежнему несут ответственность за предложение и голосование по блокам, но новый класс специализированных субъектов, называемых **создателями блоков**, отвечает за упорядочивание транзакций и создание блоков.
+
+В рамках PBS создатель блока создает пакет транзакций и делает ставку на его включение в блок Beacon Chain (в качестве "полезной нагрузки исполнения"). Валидатор, выбранный для предложения следующего блока, затем проверяет различные ставки и выбирает пакет с самой высокой комиссией. PBS по сути создает аукционный рынок, на котором создатели блоков ведут переговоры с валидаторами, продающими пространство в блоках.
+
+Текущие проекты PBS используют [схему фиксации-раскрытия](https://gitcoin.co/blog/commit-reveal-scheme-on-ethereum/), в которой создатели блоков публикуют только криптографическое обязательство по содержимому блока (заголовок блока) вместе со своими ставками. После принятия выигрышной ставки предложивший блок создает подписанное предложение блока, которое включает заголовок блока. Ожидается, что создатель блока опубликует полное тело блока после того, как увидит подписанное предложение блока, и оно также должно получить достаточное количество [аттестаций](/glossary/#attestation) от валидаторов, прежде чем будет финализировано.
+
+#### Как разделение предложившего и создателя блока смягчает влияние MEV? {#how-does-pbs-curb-mev-impact}
+
+Внутрипротокольное разделение предложившего и создателя блока уменьшает влияние MEV на консенсус, выводя извлечение MEV из сферы деятельности валидаторов. Вместо этого создатели блоков, использующие специализированное оборудование, будут в дальнейшем использовать возможности MEV.
+
+Однако это не исключает валидаторов полностью из доходов, связанных с MEV, поскольку создатели блоков должны делать высокие ставки, чтобы их блоки были приняты валидаторами. Тем не менее, поскольку валидаторы больше не сосредоточены напрямую на оптимизации дохода от MEV, угроза атак «бандита времени» снижается.
+
+Разделение предложившего и создателя блока также снижает риски централизации MEV. Например, использование схемы фиксации-раскрытия устраняет необходимость для создателей блоков доверять валидаторам в том, что они не украдут возможность MEV и не раскроют ее другим создателям блоков. Это снижает барьер для одиночных стейкеров для получения выгоды от MEV, в противном случае создатели блоков будут склоняться к предпочтению крупных пулов с офчейн-репутацией и заключению с ними офчейн-сделок.
+
+Аналогично, валидаторам не нужно доверять создателям блоков в том, что они не будут скрывать тела блоков или публиковать недействительные блоки, поскольку оплата является безусловной. Комиссия валидатора все равно обрабатывается, даже если предложенный блок недоступен или объявлен недействительным другими валидаторами. В последнем случае блок просто отбрасывается, что заставляет создателя блока терять все комиссии за транзакции и доход от MEV.
+
+### API для создателей блоков {#builder-api}
+
+Хотя разделение предложившего и создателя блока обещает уменьшить последствия извлечения MEV, его реализация требует изменений в протоколе консенсуса. В частности, необходимо будет обновить правило [выбора форка](/developers/docs/consensus-mechanisms/pos/#fork-choice) в Beacon Chain. [API для создателей блоков](https://github.com/ethereum/builder-specs) — это временное решение, направленное на предоставление рабочей реализации разделения предложившего и создателя блока, хотя и с более высокими допущениями о доверии.
+
+API для создателей блоков — это модифицированная версия [API движка](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md), используемая клиентами уровня консенсуса для запроса полезных нагрузок исполнения у клиентов уровня исполнения. Как указано в [спецификации честного валидатора](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/validator.md), валидаторы, выбранные для выполнения обязанностей по предложению блоков, запрашивают пакет транзакций у подключенного клиента исполнения, который они включают в предлагаемый блок Beacon Chain.
+
+API для создателей блоков также действует как промежуточное ПО между валидаторами и клиентами уровня исполнения; но оно отличается тем, что позволяет валидаторам на Beacon Chain получать блоки от внешних субъектов (вместо того чтобы создавать блок локально с помощью клиента исполнения).
+
+Ниже представлен обзор того, как работает API для создателей блоков:
+
+1. API для создателей блоков подключает валидатора к сети создателей блоков, работающих с клиентами уровня исполнения. Как и в PBS, создатели блоков — это специализированные стороны, которые инвестируют в ресурсоемкое создание блоков и используют различные стратегии для максимизации дохода, получаемого от MEV и приоритетных вознаграждений.
+
+2. Валидатор (работающий с клиентом уровня консенсуса) запрашивает полезные нагрузки исполнения вместе со ставками из сети создателей блоков. Ставки от создателей блоков будут содержать заголовок полезной нагрузки исполнения — криптографическое обязательство по содержимому полезной нагрузки — и комиссию, подлежащую уплате валидатору.
+
+3. Валидатор просматривает входящие ставки и выбирает полезную нагрузку исполнения с самой высокой комиссией. Используя API для создателей блоков, валидатор создает "слепое" предложение блока Beacon, которое включает только его подпись и заголовок полезной нагрузки исполнения, и отправляет его создателю блоков.
+
+4. Ожидается, что создатель блоков, использующий API для создателей блоков, ответит полной полезной нагрузкой исполнения, увидев слепое предложение блока. Это позволяет валидатору создать "подписанный" блок Beacon, который они распространяют по сети.
+
+5. Ожидается, что валидатор, использующий API для создателей блоков, все равно будет создавать блок локально на случай, если создатель блока не ответит вовремя, чтобы не упустить награду за предложение блока. Однако валидатор не может создать другой блок, используя либо уже раскрытые транзакции, либо другой набор, поскольку это будет равносильно _двойной подписи_ (подписанию двух блоков в одном и том же слоте), что является нарушением, наказуемым слэшингом.
+
+Примером реализации API для создателей блоков является [MEV Boost](https://github.com/flashbots/mev-boost) — усовершенствование [аукционного механизма Flashbots](https://docs.flashbots.net/Flashbots-auction/overview), предназначенное для сдерживания негативных внешних эффектов MEV в Ethereum. Аукцион Flashbots позволяет валидаторам в proof-of-stake передавать работу по созданию прибыльных блоков специализированным сторонам, называемым **искателями**.
+
+
+Искатели ищут выгодные возможности MEV и отправляют пакеты транзакций предложившим блок вместе с [закрытой ценовой ставкой](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction) для включения в блок. Валидатору, работающему на mev-geth, форкнутой версии клиента go-ethereum (Geth), нужно только выбрать пакет с наибольшей прибылью и включить его в новый блок. Для защиты предложивших блок (валидаторов) от спама и недействительных транзакций пакеты транзакций проходят через **ретрансляторы** для проверки, прежде чем попасть к предложившему.
+
+MEV Boost сохраняет тот же принцип работы, что и оригинальный аукцион Flashbots, хотя и с новыми функциями, разработанными для перехода Ethereum на proof-of-stake. Искатели по-прежнему находят прибыльные MEV-транзакции для включения в блоки, но новый класс специализированных сторон, называемых **создателями**, отвечает за агрегирование транзакций и пакетов в блоки. Создатель блоков принимает закрытые ценовые ставки от искателей и запускает оптимизации для поиска наиболее прибыльного порядка.
+
+Ретранслятор по-прежнему отвечает за проверку пакетов транзакций перед их передачей предложившему. Однако MEV Boost вводит **эскроу**, отвечающие за обеспечение [доступности данных](/developers/docs/data-availability/), храня тела блоков, отправленные создателями, и заголовки блоков, отправленные валидаторами. Здесь валидатор, подключенный к ретранслятору, запрашивает доступные полезные нагрузки исполнения и использует алгоритм упорядочивания MEV Boost для выбора заголовка полезной нагрузки с самой высокой ставкой и вознаграждениями за MEV.
+
+#### Как API для создателей блоков смягчает влияние MEV? {#how-does-builder-api-curb-mev-impact}
+
+Основное преимущество API для создателей блоков заключается в его потенциале демократизировать доступ к возможностям MEV. Использование схем фиксации-раскрытия устраняет допущения о доверии и снижает барьеры входа для валидаторов, стремящихся извлечь выгоду из MEV. Это должно снизить давление на одиночных стейкеров, вынуждающее их интегрироваться с крупными пулами для стейкинга с целью увеличения прибыли от MEV.
+
+Широкое внедрение API для создателей блоков будет способствовать большей конкуренции среди создателей блоков, что повышает устойчивость к цензуре. Поскольку валидаторы рассматривают ставки от нескольких создателей блоков, создатель блоков, намеревающийся цензурировать одну или несколько транзакций пользователей, должен перебить ставки всех остальных нецензурирующих создателей блоков, чтобы добиться успеха. Это резко увеличивает стоимость цензурирования пользователей и препятствует такой практике.
+
+Некоторые проекты, такие как MEV Boost, используют API для создателей блоков как часть общей структуры, предназначенной для обеспечения конфиденциальности транзакций для определенных сторон, например, для трейдеров, пытающихся избежать атак с опережением или сэндвич-атак. Это достигается путем предоставления частного канала связи между пользователями и создателями блоков. В отличие от ранее описанных закрытых мемпулов, этот подход выгоден по следующим причинам:
+
+1. Наличие на рынке нескольких создателей блоков делает цензуру непрактичной, что выгодно пользователям. В отличие от этого, существование централизованных и основанных на доверии темных пулов сконцентрировало бы власть в руках нескольких создателей блоков и увеличило бы возможность цензуры.
+
+2. Программное обеспечение API для создателей блоков является открытым, что позволяет любому предлагать услуги по созданию блоков. Это означает, что пользователи не вынуждены использовать какого-либо конкретного создателя блоков, и это улучшает нейтралитет и открытость Ethereum. Более того, трейдеры, ищущие MEV, не будут непреднамеренно способствовать централизации, используя частные каналы транзакций.
+
+## Связанные ресурсы {#related-resources}
+
+- [Документация Flashbots](https://docs.flashbots.net/)
+- [GitHub Flashbots](https://github.com/flashbots/pm)
+- [mevboost.org](https://www.mevboost.org/) - _Трекер со статистикой в реальном времени для ретрансляторов MEV-Boost и создателей блоков_
+
+## Дополнительные материалы {#further-reading}
+
+- [Что такое извлекаемая майнером ценность (MEV)?](https://blog.chain.link/what-is-miner-extractable-value-mev/)
+- [MEV и я](https://www.paradigm.xyz/2021/02/mev-and-me)
+- [Ethereum — темный лес](https://www.paradigm.xyz/2020/08/ethereum-is-a-dark-forest/)
+- [Побег из темного леса](https://samczsun.com/escaping-the-dark-forest/)
+- [Flashbots: опережая кризис MEV](https://medium.com/flashbots/frontrunning-the-mev-crisis-40629a613752)
+- [Темы о MEV от @bertcmiller](https://twitter.com/bertcmiller/status/1402665992422047747)
+- [MEV-Boost: архитектура Flashbots, готовая к «Слиянию»](https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177)
+- [Что такое MEV Boost](https://www.alchemy.com/overviews/mev-boost)
+- [Зачем запускать mev-boost?](https://writings.flashbots.net/writings/why-run-mevboost/)
+- [Автостопом по Ethereum](https://members.delphidigital.io/reports/the-hitchhikers-guide-to-ethereum)
diff --git a/public/content/translations/ru/developers/docs/networking-layer/index.md b/public/content/translations/ru/developers/docs/networking-layer/index.md
new file mode 100644
index 00000000000..ebc6a0557b1
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/networking-layer/index.md
@@ -0,0 +1,155 @@
+---
+title: "Сетевой уровень"
+description: "Введение в сетевой уровень Ethereum."
+lang: ru
+sidebarDepth: 2
+---
+
+Ethereum - это одноуровневая сеть с тысячами узлов, которые должны быть в состоянии общаться друг с другом с помощью стандартизированных протоколов. "Сетевой уровень" - это набор протоколов, который позволяет этим узлам находить друг друга и обмениваться информацией. Это включает в себя информацию о "беседе" (один ко многим коммуникациям) по сети, а также обмен запросами и ответами между конкретными узлами (один к одной коммуникации). Каждый узел должен соблюдать определенные сетевые правила, чтобы убедиться, что они посылают и получают правильную информацию.
+
+Клиентское программное обеспечение состоит из двух частей (клиентов исполнения и клиентов консенсуса), у каждой из которых есть свой собственный сетевой стек. Помимо общения с другими узлами Ethereum клиенты должны взаимодействовать друг с другом. На этой странице приведено вступительное объяснение протоколов, обеспечивающих эту связь.
+
+Клиенты исполнения распространяют транзакции по одноранговой сети уровня исполнения. Это требует зашифрованной связи между аутентифицированными узлами. Когда валидатор выбран для предложения блока, транзакции из локального пула транзакций узла передаются клиентам консенсуса через локальное RPC-соединение и упаковываются в блоки Beacon. Затем клиенты консенсуса распространяют блоки Beacon по своей p2p-сети. Для этого требуются две отдельные p2p-сети: одна соединяет клиентов исполнения для распространения транзакций, а другая — клиентов консенсуса для распространения блоков.
+
+## Предварительные условия {#prerequisites}
+
+Некоторые знания об [узлах и клиентах](/developers/docs/nodes-and-clients/) Ethereum будут полезны для понимания этой страницы.
+
+## Уровень исполнения {#execution-layer}
+
+Сетевые протоколы уровня исполнения разделены на два стека:
+
+- стек обнаружения: создан на основе UDP и позволяет новому узлу находить другие узлы для подключения
+
+- стек DevP2P: работает поверх TCP и позволяет узлам обмениваться информацией
+
+Оба стека работают параллельно. Стек обнаружения добавляет новых участников в сеть, а стек DevP2P обеспечивает их взаимодействие.
+
+### Обнаружение {#discovery}
+
+Обнаружение — это процесс поиска других узлов в сети. Этот процесс запускается с помощью небольшого набора начальных узлов (bootnodes) — узлов, чьи адреса [жестко закодированы](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go) в клиенте, чтобы их можно было немедленно найти и подключить клиента к другим узлам. Эти начальные узлы существуют только для того, чтобы представить новый узел набору других узлов — это их единственная цель, они не участвуют в обычных задачах клиента, таких как синхронизация цепи, и они используются только при самом первом запуске клиента.
+
+Протокол, используемый для взаимодействия узлов с начальными узлами, представляет собой модифицированную форму [Kademlia](https://medium.com/coinmonks/a-brief-overview-of-kademlia-and-its-use-in-various-decentralized-platforms-da08a7f72b8f), которая использует [распределенную хеш-таблицу](https://en.wikipedia.org/wiki/Distributed_hash_table) для обмена списками узлов. Каждый узел имеет версию этой таблицы, содержащую информацию, необходимую для подключения к ближайшим узлам. Эта «близость» не является географической: расстояние определяется сходством идентификатора узла. Таблица каждого узла регулярно обновляется в целях безопасности. Например, в протоколе обнаружения [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5) узлы также могут отправлять «объявления», в которых отображаются подпротоколы, поддерживаемые клиентом, что позволяет узлам договариваться о протоколах, которые они оба могут использовать для связи.
+
+Обнаружение начинается с игры в PING-PONG. Успешный PING-PONG «связывает» новый узел с начальным узлом. Первоначальное сообщение, которое предупреждает начальный узел о появлении нового узла в сети, — это `PING`. Этот `PING` включает в себя хешированную информацию о новом узле, начальном узле и временную метку истечения срока действия. Начальный узел получает `PING` и возвращает `PONG`, содержащий хеш `PING`. Если хеши `PING` и `PONG` совпадают, соединение между новым узлом и начальным узлом проверяется, и считается, что они «связаны».
+
+После связывания новый узел может отправить запрос `FIND-NEIGHBOURS` начальному узлу. Данные, возвращаемые начальным узлом, включают список других узлов, к которым может подключиться новый узел. Если узлы не связаны, запрос `FIND-NEIGHBOURS` завершится неудачно, и новый узел не сможет войти в сеть.
+
+Как только новый узел получает список соседей от начального узла, он начинает обмен PING-PONG с каждым из них. Успешные обмены PING-PONG связывают новый узел с его соседями, обеспечивая обмен сообщениями.
+
+```
+запуск клиента --> подключение к начальному узлу --> связывание с начальным узлом --> поиск соседей --> связывание с соседями
+```
+
+Клиенты исполнения в настоящее время используют протокол обнаружения [Discv4](https://github.com/ethereum/devp2p/blob/master/discv4.md), и ведется активная работа по переходу на протокол [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5).
+
+#### ENR: Записи узлов Ethereum {#enr}
+
+[Запись узла Ethereum (ENR)](/developers/docs/networking-layer/network-addresses/) — это объект, содержащий три основных элемента: подпись (хеш содержимого записи, созданный в соответствии с некоторой согласованной схемой идентификации), порядковый номер, который отслеживает изменения в записи, и произвольный список пар «ключ-значение». Это перспективный формат, который упрощает обмен идентифицирующей информацией между новыми узлами и является предпочтительным форматом [сетевого адреса](/developers/docs/networking-layer/network-addresses) для узлов Ethereum.
+
+#### Почему обнаружение построено на UDP? {#why-udp}
+
+UDP не поддерживает проверку ошибок, повторную отправку неудачных пакетов или динамическое открытие и закрытие соединений — вместо этого он просто отправляет непрерывный поток информации цели, независимо от того, успешно ли он получен. Эта минимальная функциональность также приводит к минимальным накладным расходам, что делает этот вид соединения очень быстрым. Для обнаружения, когда узел просто хочет заявить о своем присутствии, чтобы затем установить формальное соединение с другим узлом, UDP достаточно. Однако для остальной части сетевого стека UDP не подходит. Обмен информацией между узлами довольно сложен и поэтому требует более полнофункционального протокола, который может поддерживать повторную отправку, проверку ошибок и т. д. Дополнительные накладные расходы, связанные с TCP, стоят дополнительной функциональности. Поэтому большая часть P2P-стека работает поверх TCP.
+
+### DevP2P {#devp2p}
+
+DevP2P сам по себе представляет собой целый стек протоколов, которые Ethereum реализует для создания и поддержания одноранговой сети. После того как новые узлы входят в сеть, их взаимодействие регулируется протоколами стека [DevP2P](https://github.com/ethereum/devp2p). Все они работают поверх TCP и включают транспортный протокол RLPx, проводной протокол и несколько подпротоколов. [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md) — это протокол, управляющий инициацией, аутентификацией и поддержанием сеансов между узлами. RLPx кодирует сообщения с использованием RLP (Recursive Length Prefix), что является очень эффективным с точки зрения занимаемого пространства методом кодирования данных в минимальную структуру для отправки между узлами.
+
+Сеанс RLPx между двумя узлами начинается с первоначального криптографического рукопожатия. Это включает в себя отправку узлом сообщения аутентификации, которое затем проверяется другим узлом. При успешной проверке другой узел генерирует сообщение с подтверждением аутентификации для возврата узлу-инициатору. Это процесс обмена ключами, который позволяет узлам обмениваться данными конфиденциально и безопасно. Успешное криптографическое рукопожатие затем заставляет оба узла отправить друг другу сообщение «hello» «по каналу связи». Проводной протокол инициируется успешным обменом сообщениями «hello».
+
+Сообщения «hello» содержат:
+
+- версию протокола
+- ID клиента
+- порт
+- ID узла
+- список поддерживаемых подпротоколов
+
+Это информация, необходимая для успешного взаимодействия, поскольку она определяет, какие возможности являются общими для обоих узлов, и настраивает связь. Существует процесс согласования подпротоколов, в ходе которого сравниваются списки подпротоколов, поддерживаемых каждым узлом, и те, которые являются общими для обоих узлов, могут использоваться в сеансе.
+
+Наряду с сообщениями «hello» проводной протокол также может отправлять сообщение «disconnect», которое предупреждает другой узел о том, что соединение будет закрыто. Проводной протокол также включает сообщения PING и PONG, которые периодически отправляются для поддержания сеанса открытым. Таким образом, обмены по протоколам RLPx и проводному протоколу закладывают основы для связи между узлами, обеспечивая каркас для обмена полезной информацией в соответствии с конкретным подпротоколом.
+
+### Подпротоколы {#sub-protocols}
+
+#### Проводной протокол {#wire-protocol}
+
+После подключения узлов и запуска сеанса RLPx проводной протокол определяет, как узлы обмениваются данными. Изначально проводной протокол определял три основные задачи: синхронизация цепи, распространение блоков и обмен транзакциями. Однако, когда Ethereum перешел на proof-of-stake, распространение блоков и синхронизация цепи стали частью уровня консенсуса. Обмен транзакциями по-прежнему входит в компетенцию клиентов исполнения. Обмен транзакциями означает обмен ожидающими транзакциями между узлами, чтобы сборщики блоков могли выбрать некоторые из них для включения в следующий блок. Подробная информация об этих задачах доступна [здесь](https://github.com/ethereum/devp2p/blob/master/caps/eth.md). Клиенты, поддерживающие эти подпротоколы, предоставляют к ним доступ через [JSON-RPC](/developers/docs/apis/json-rpc/).
+
+#### les (легкий подпротокол Ethereum) {#les}
+
+Это минимальный протокол для синхронизации легких клиентов. Традиционно этот протокол использовался редко, потому что полные узлы должны обслуживать данные для легких клиентов без стимулирования. Поведение по умолчанию клиентов исполнения не предполагает обслуживание данных легких клиентов по протоколу les. Более подробную информацию можно найти в [спецификации](https://github.com/ethereum/devp2p/blob/master/caps/les.md) les.
+
+#### Snap {#snap}
+
+[Протокол snap](https://github.com/ethereum/devp2p/blob/master/caps/snap.md#ethereum-snapshot-protocol-snap) — это необязательное расширение, которое позволяет узлам обмениваться снимками недавних состояний, что позволяет им проверять данные учетных записей и хранилища без необходимости загружать промежуточные узлы дерева Меркла.
+
+#### Wit (протокол свидетелей) {#wit}
+
+[Протокол свидетелей (wit)](https://github.com/ethereum/devp2p/blob/master/caps/wit.md#ethereum-witness-protocol-wit) — это необязательное расширение, которое позволяет обмениваться свидетелями состояния между узлами, помогая синхронизировать клиентов с вершиной цепи.
+
+#### Whisper {#whisper}
+
+Whisper был протоколом, целью которого была доставка защищенных сообщений между узлами без записи какой-либо информации в блокчейн. Он был частью проводного протокола DevP2P, но теперь устарел. Существуют и другие [связанные проекты](https://wakunetwork.com/) с похожими целями.
+
+## Уровень консенсуса {#consensus-layer}
+
+Клиенты консенсуса участвуют в отдельной одноранговой сети с другой спецификацией. Клиентам консенсуса необходимо участвовать в распространении блоков, чтобы они могли получать новые блоки от других узлов и транслировать их, когда наступает их очередь предлагать блок. Подобно уровню исполнения, это сначала требует протокола обнаружения, чтобы узел мог находить другие узлы и устанавливать безопасные сеансы для обмена блоками, аттестациями и т. д.
+
+### Обнаружение {#consensus-discovery}
+
+Подобно клиентам исполнения, клиенты консенсуса используют [discv5](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-discovery-domain-discv5) поверх UDP для поиска других узлов. Реализация discv5 на уровне консенсуса отличается от реализации на уровне клиентов исполнения только тем, что она включает адаптер, подключающий discv5 к стеку [libP2P](https://libp2p.io/), что делает DevP2P устаревшим. Сеансы RLPx уровня исполнения устарели в пользу рукопожатия защищенного канала libP2P.
+
+### ENR {#consensus-enr}
+
+ENR для узлов консенсуса включает публичный ключ узла, IP-адрес, порты UDP и TCP и два специфичных для консенсуса поля: битовое поле подсети аттестации и ключ `eth2`. Первое упрощает узлам поиск других узлов, участвующих в конкретных подсетях распространения аттестаций. Ключ `eth2` содержит информацию о том, какую версию форка Ethereum использует узел, обеспечивая подключение узлов к правильной сети Ethereum.
+
+### libP2P {#libp2p}
+
+Стек libP2P поддерживает все коммуникации после обнаружения. Клиенты могут подключаться и прослушивать IPv4 и/или IPv6, как определено в их ENR. Протоколы на уровне libP2P можно подразделить на домены gossip и req/resp.
+
+### Gossip {#gossip}
+
+Домен gossip включает всю информацию, которая должна быстро распространяться по сети. Сюда входят блоки Beacon, доказательства, аттестации, выходы и слэшинги. Это передается с использованием libP2P gossipsub v1 и зависит от различных метаданных, хранящихся локально на каждом узле, включая максимальный размер полезной нагрузки gossip для приема и передачи. Подробная информация о домене gossip доступна [здесь](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub).
+
+### Запрос-ответ {#request-response}
+
+Домен запроса-ответа содержит протоколы для клиентов, запрашивающих конкретную информацию у других узлов. Примеры включают запрос определенных блоков Beacon, соответствующих определенным корневым хешам или находящихся в диапазоне слотов. Ответы всегда возвращаются в виде байтов, закодированных с помощью SSZ и сжатых с помощью snappy.
+
+## Почему клиент консенсуса предпочитает SSZ, а не RLP? {#ssz-vs-rlp}
+
+SSZ расшифровывается как простая сериализация (simple serialization). Он использует фиксированные смещения, которые позволяют легко декодировать отдельные части закодированного сообщения без необходимости декодировать всю структуру, что очень полезно для клиента консенсуса, поскольку он может эффективно извлекать определенные фрагменты информации из закодированных сообщений. Он также специально разработан для интеграции с протоколами Меркла, с соответствующим повышением эффективности для мерклизации. Поскольку все хеши на уровне консенсуса являются корнями Меркла, это приводит к значительному улучшению. SSZ также гарантирует уникальное представление значений.
+
+## Подключение клиентов исполнения и консенсуса {#connecting-clients}
+
+Клиенты консенсуса и исполнения работают параллельно. Они должны быть соединены, чтобы клиент консенсуса мог давать инструкции клиенту исполнения, а клиент исполнения мог передавать пакеты транзакций клиенту консенсуса для включения в блоки Beacon. Связь между двумя клиентами может быть достигнута с помощью локального RPC-соединения. API, известный как ['Engine-API'](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md), определяет инструкции, передаваемые между двумя клиентами. Поскольку оба клиента находятся за единой сетевой идентификацией, они совместно используют ENR (запись узла Ethereum), которая содержит отдельный ключ для каждого клиента (ключ eth1 и ключ eth2).
+
+Ниже приведено краткое описание потока управления с указанием соответствующего сетевого стека в скобках.
+
+### Когда клиент консенсуса не является производителем блока: {#when-consensus-client-is-not-block-producer}
+
+- Клиент консенсуса получает блок по протоколу распространения блоков (консенсус p2p)
+- Клиент консенсуса предварительно проверяет блок, т. е. убеждается, что он получен от действительного отправителя с правильными метаданными
+- Транзакции в блоке отправляются на уровень исполнения в качестве полезной нагрузки исполнения (локальное RPC-соединение)
+- Уровень исполнения выполняет транзакции и проверяет состояние в заголовке блока (т. е. проверяет совпадение хешей)
+- Уровень исполнения передает данные проверки обратно на уровень консенсуса, теперь блок считается проверенным (локальное RPC-соединение)
+- Уровень консенсуса добавляет блок в начало своего блокчейна и аттестует его, транслируя аттестацию по сети (консенсус p2p)
+
+### Когда клиент консенсуса является производителем блока: {#when-consensus-client-is-block-producer}
+
+- Клиент консенсуса получает уведомление о том, что он является следующим производителем блока (консенсус p2p)
+- Уровень консенсуса вызывает метод `create block` в клиенте исполнения (локальный RPC)
+- Уровень исполнения обращается к мемпулу транзакций, который был заполнен по протоколу распространения транзакций (исполнение p2p)
+- Клиент исполнения объединяет транзакции в блок, выполняет транзакции и генерирует хеш блока
+- Клиент консенсуса получает транзакции и хеш блока от клиента исполнения и добавляет их в блок Beacon (локальный RPC)
+- Клиент консенсуса транслирует блок по протоколу распространения блоков (консенсус p2p)
+- Другие клиенты получают предложенный блок по протоколу распространения блоков и проверяют его, как описано выше (консенсус p2p)
+
+После того как блок был аттестован достаточным количеством валидаторов, он добавляется в начало цепи, подтверждается и в конечном итоге финализируется.
+
+\n
+
+Схема сетевого уровня для клиентов консенсуса и исполнения, с [ethresear.ch](https://ethresear.ch/t/eth1-eth2-client-relationship/7248)
+
+## Дополнительные материалы {#further-reading}
+
+[DevP2P](https://github.com/ethereum/devp2p)\n[LibP2p](https://github.com/libp2p/specs)\n[Спецификации сети уровня консенсуса](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure)\n[от Kademlia к discv5](https://vac.dev/kademlia-to-discv5)\n[статья о Kademlia](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf)\n[введение в p2p Ethereum](https://p2p.paris/en/talks/intro-ethereum-networking/)\n[взаимосвязь eth1/eth2](http://ethresear.ch/t/eth1-eth2-client-relationship/7248)\n[видео о Слиянии и деталях клиента eth2](https://www.youtube.com/watch?v=zNIrIninMgg)
diff --git a/public/content/translations/ru/developers/docs/networking-layer/network-addresses/index.md b/public/content/translations/ru/developers/docs/networking-layer/network-addresses/index.md
new file mode 100644
index 00000000000..4b66dbd66f8
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/networking-layer/network-addresses/index.md
@@ -0,0 +1,39 @@
+---
+title: "Сетевые адреса"
+description: "Введение в сетевые адреса."
+lang: ru
+sidebarDepth: 2
+---
+
+Узлы Ethereum должны идентифицировать себя с помощью некоторой базовой информации для подключения к пирам. Чтобы гарантировать, что любой потенциальный пир сможет интерпретировать эту информацию, она передается в одном из трех стандартизированных форматов, которые может понять любой узел Ethereum: multiaddr, enode или Ethereum Node Records (ENR). ENR являются текущим стандартом для сетевых адресов Ethereum.
+
+## Предварительные условия {#prerequisites}
+
+Для понимания этой страницы требуется некоторое понимание [сетевого уровня](/developers/docs/networking-layer/) Ethereum.
+
+## Multiaddr {#multiaddr}
+
+Первоначальным форматом адреса узла Ethereum был 'multiaddr' (сокращение от 'multi-addresses' — «мультиадреса»). Multiaddr — это универсальный формат, разработанный для одноранговых сетей. Адреса представлены в виде пар «ключ-значение», где ключи и значения разделены косой чертой. Например, multiaddr для узла с IPv4-адресом `192.168.22.27`, прослушивающего TCP-порт `33000`, выглядит так:
+
+`/ip4/192.168.22.27/tcp/33000`
+
+Для узла Ethereum multiaddr содержит идентификатор узла (хэш его публичного ключа):
+
+`/ip4/192.168.22.27/tcp/33000/p2p/5t7Nv7dG2d6ffbvAiewVsEwWweU3LdebSqX2y1bPrW8br`
+
+## Enode {#enode}
+
+Enode — это способ идентификации узла Ethereum с использованием формата URL-адреса. Шестнадцатеричный идентификатор узла кодируется в части URL-адреса, отведенной для имени пользователя, и отделяется от хоста знаком @. Имя хоста может быть указано только в виде IP-адреса; имена DNS не допускаются. Порт в разделе имени хоста — это порт прослушивания TCP. Если порты TCP и UDP (обнаружения) различаются, порт UDP указывается в качестве параметра запроса "discport".
+
+В следующем примере URL-адрес узла описывает узел с IP-адресом `10.3.58.6`, портом TCP `30303` и портом обнаружения UDP `30301`.
+
+`enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301`
+
+## Записи узла Ethereum (ENR) {#enr}
+
+Записи узла Ethereum (ENR) — это стандартизированный формат для сетевых адресов в Ethereum. Они заменяют multiaddr и enode. Они особенно полезны, поскольку позволяют осуществлять более широкий обмен информацией между узлами. ENR содержит подпись, порядковый номер и поля, подробно описывающие схему идентификации, используемую для создания и проверки подписей. ENR также может быть заполнена произвольными данными, организованными в виде пар «ключ-значение». Эти пары «ключ-значение» содержат IP-адрес узла и информацию о субпротоколах, которые узел может использовать. Клиенты консенсуса используют [определенную структуру ENR](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure) для идентификации загрузочных узлов, а также включают поле `eth2`, содержащее информацию о текущем форке Ethereum и подсети распространения аттестаций (которая соединяет узел с определенным набором пиров, аттестации которых агрегируются вместе).
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-778: Записи узла Ethereum (ENR)](https://eips.ethereum.org/EIPS/eip-778)
+- [LibP2P: Multiaddr-Enode-ENR?!](https://consensys.net/diligence/blog/2020/09/libp2p-multiaddr-enode-enr/)
diff --git a/public/content/translations/ru/developers/docs/networking-layer/portal-network/index.md b/public/content/translations/ru/developers/docs/networking-layer/portal-network/index.md
new file mode 100644
index 00000000000..5871bd2164c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/networking-layer/portal-network/index.md
@@ -0,0 +1,89 @@
+---
+title: "Портальная сеть"
+description: "Обзор Портальной сети — сети в стадии разработки, предназначенной для поддержки клиентов с низкими ресурсами."
+lang: ru
+---
+
+Ethereum — это сеть, состоящая из компьютеров, на которых работает клиентское программное обеспечение Ethereum. Каждый из этих компьютеров называется «узлом». Клиентское программное обеспечение позволяет узлу отправлять и получать данные в сети Ethereum, а также проверять данные на соответствие правилам протокола Ethereum. Узлы хранят большой объем исторических данных в своем дисковом хранилище и пополняют его, когда получают от других узлов в сети новые пакеты информации, известные как блоки. Это необходимо для постоянной проверки того, что узел располагает информацией, соответствующей остальной части сети. Это означает, что для запуска узла может потребоваться много места на диске. Некоторые операции узла также могут требовать много оперативной памяти.
+
+Чтобы обойти эту проблему с дисковым хранилищем, были разработаны «легкие» узлы, которые запрашивают информацию у полных узлов вместо того, чтобы хранить все данные самостоятельно. Однако это означает, что легкий узел не проверяет информацию самостоятельно, а доверяет другому узлу. Это также означает, что полным узлам требуется выполнять дополнительную работу по обслуживанию этих легких узлов.
+
+Портальная сеть — это новый сетевой дизайн для Ethereum, который призван решить проблему доступности данных для "легких" узлов без необходимости доверять полным узлам или создавать на них дополнительную нагрузку путем распределения необходимых данных небольшими фрагментами по всей сети.
+
+Подробнее об [узлах и клиентах](/developers/docs/nodes-and-clients/)
+
+## Зачем нам нужна Портальная сеть {#why-do-we-need-portal-network}
+
+Узлы Ethereum хранят свою собственную полную или частичную копию блокчейна Ethereum. Эта локальная копия используется для проверки транзакций и для гарантии того, что узел следует правильной цепочке. Эти локально хранящиеся данные позволяют узлам самостоятельно проверять, что входящие данные действительны и верны, без необходимости доверять какой-либо другой сущности.
+
+Эта локальная копия блокчейна и связанные с ней данные о состоянии и квитанциях занимают много места на жестком диске узла. Например, для запуска узла с использованием [Geth](https://geth.ethereum.org) в паре с клиентом консенсуса рекомендуется жесткий диск на 2 ТБ. При использовании быстрой синхронизации (snap sync), которая хранит только данные цепи из относительно недавнего набора блоков, Geth обычно занимает около 650 ГБ дискового пространства, но растет примерно на 14 ГБ в неделю (вы можете периодически сокращать размер узла до 650 ГБ).
+
+Это означает, что запуск узлов может быть дорогостоящим, поскольку большой объем дискового пространства должен быть выделен для Ethereum. В дорожной карте Ethereum есть несколько решений этой проблемы, включая [истечение срока действия истории](/roadmap/statelessness/#history-expiry), [истечение срока действия состояния](/roadmap/statelessness/#state-expiry) и [отсутствие состояния](/roadmap/statelessness/). Однако до их реализации, скорее всего, еще несколько лет. Существуют также [легкие узлы](/developers/docs/nodes-and-clients/light-clients/), которые не сохраняют собственную копию данных цепи, они запрашивают необходимые данные у полных узлов. Однако это означает, что легкие узлы должны доверять полным узлам в предоставлении честных данных, а также создает нагрузку на полные узлы, которые должны обслуживать данные, необходимые легким узлам.
+
+Портальная сеть призвана предоставить легким узлам альтернативный способ получения данных, который не требует доверия или значительного увеличения работы, выполняемой полными узлами. Это будет сделано путем внедрения нового способа обмена данными между узлами Ethereum в сети.
+
+## Как работает Портальная сеть? {#how-does-portal-network-work}
+
+Узлы Ethereum имеют строгие протоколы, которые определяют, как они взаимодействуют друг с другом. Клиенты исполнения обмениваются данными, используя набор подпротоколов, известных как [DevP2P](/developers/docs/networking-layer/#devp2p), в то время как клиенты консенсуса используют другой стек подпротоколов, называемый [libP2P](/developers/docs/networking-layer/#libp2p). Они определяют типы данных, которые могут передаваться между узлами.
+
+
+
+Узлы также могут обслуживать определенные данные через [JSON-RPC API](/developers/docs/apis/json-rpc/), с помощью которого приложения и кошельки обмениваются информацией с узлами Ethereum. Однако ни один из этих протоколов не является идеальным для обслуживания данных легких клиентов.
+
+Легкие клиенты в настоящее время не могут запрашивать определенные фрагменты данных цепи через DevP2P или libP2P, поскольку эти протоколы предназначены только для синхронизации цепи и распространения (gossiping) блоков и транзакций. Легкие клиенты не хотят загружать эту информацию, потому что тогда они перестанут быть "легкими".
+
+JSON-RPC API также не является идеальным выбором для запросов данных от легких клиентов, поскольку он зависит от подключения к определенному полному узлу или централизованному RPC-провайдеру, который может обслуживать данные. Это означает, что легкий клиент должен доверять честности этого конкретного узла/провайдера, а полный узел может быть вынужден обрабатывать множество запросов от многих легких клиентов, что увеличивает его требования к пропускной способности.
+
+Смысл Портальной сети заключается в том, чтобы переосмыслить всю конструкцию, создавая ее специально для легковесности, вне рамок проектных ограничений существующих клиентов Ethereum.
+
+Основная идея Портальной сети заключается в том, чтобы взять лучшие элементы текущего сетевого стека, предоставив возможность обслуживать информацию, необходимую легким клиентам, такую как исторические данные и идентификатор текущего заголовка цепи, через легковесную децентрализованную одноранговую сеть в стиле DevP2P с использованием [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) (по аналогии с Bittorrent).
+
+Идея состоит в том, чтобы добавить к каждому узлу небольшие части общих исторических данных Ethereum и некоторые определенные обязанности узла. Затем запросы обслуживаются путем поиска узлов, хранящих запрошенные конкретные данные, и получения их от этих узлов.
+
+Это переворачивает обычную модель, в которой легкие узлы находят один узел и запрашивают у него фильтрацию и обслуживание больших объемов данных; вместо этого они быстро фильтруют большую сеть узлов, каждый из которых обрабатывает небольшие объемы данных.
+
+Цель состоит в том, чтобы позволить децентрализованной сети легковесных клиентов Портальной сети:
+
+- отслеживать заголовок цепи
+- синхронизировать свежие и исторические данные цепи
+- получать данные о состоянии
+- транслировать транзакции
+- исполнять транзакции с использованием [EVM](/developers/docs/evm/)
+
+Преимущества такой сетевой архитектуры:
+
+- уменьшение зависимости от централизованных провайдеров
+- Снижение использования пропускной способности Интернета
+- Минимизированная или нулевая синхронизация
+- Доступность для устройств с ограниченными ресурсами (\<1 ГБ ОЗУ, \<100 МБ на диске, 1 ЦП)
+
+В таблице ниже показаны функции существующих клиентов, которые могут быть реализованы Портальной сетью, что позволяет пользователям получать доступ к этим функциям на устройствах с очень низкими ресурсами.
+
+### Портальные сети
+
+| Легкий клиент сети Beacon | Сеть состояния | Распространение (gossip) транзакций | Сеть истории |
+| ------------------------- | -------------------------------- | ------------------------------------------------------ | ------------ |
+| Легкий клиент сети Beacon | Хранилище аккаунтов и контрактов | Легковесный мемпул | Заголовки |
+| Данные протокола | | | Тела блоков |
+| | | | Квитанции |
+
+## Разнообразие клиентов по умолчанию {#client-diversity-as-default}
+
+Разработчики Портальной сети также приняли проектное решение создавать с первого дня четыре отдельных клиента Портальной сети.
+
+Клиенты The Portal Network:
+
+- [Trin](https://github.com/ethereum/trin): написан на Rust
+- [Fluffy](https://fluffy.guide): написан на Nim
+- [Ultralight](https://github.com/ethereumjs/ultralight): написан на Typescript
+- [Shisui](https://github.com/zen-eth/shisui): написан на Go
+
+Наличие нескольких независимых реализаций клиентов повышает отказоустойчивость и децентрализацию сети Ethereum.
+
+Если в одном клиенте возникают проблемы или уязвимости, другие клиенты могут продолжать бесперебойно работать, что предотвращает возникновение единой точки отказа. Кроме того, разнообразие реализаций клиентов способствует инновациям и конкуренции, стимулируя усовершенствования и снижая риск монокультуры в экосистеме.
+
+## Дополнительные материалы {#further-reading}
+
+- [Портальная сеть (Пайпер Мерриам на Devcon в Боготе)](https://www.youtube.com/watch?v=0stc9jnQLXA).
+- [Discord-сервер Портальной сети](https://discord.gg/CFFnmE7Hbs)
+- [Сайт Портальной сети](https://www.ethportal.net/)
diff --git a/public/content/translations/ru/developers/docs/networks/index.md b/public/content/translations/ru/developers/docs/networks/index.md
index 7984eb3de0c..6c20357d802 100644
--- a/public/content/translations/ru/developers/docs/networks/index.md
+++ b/public/content/translations/ru/developers/docs/networks/index.md
@@ -1,6 +1,6 @@
---
-title: Сети
-description: Обзор сетей Ethereum и где взять эфир (ETH) тестовой сети для тестирования вашего приложения.
+title: "Сети"
+description: "Обзор сетей Ethereum и где взять эфир (ETH) тестовой сети для тестирования вашего приложения."
lang: ru
---
@@ -8,21 +8,21 @@ lang: ru
Ваш аккаунт Ethereum будет доступен во всех сетях, но баланс и история транзакций не будут копироваться из основной сети Ethereum. Полезно знать, какие сети доступны для тестирования и как заполучить ETH для тестовой сети, чтобы поэкспериментировать. Как правило, в целях безопасности не рекомендуется использовать аккаунт из основной сети в тестовой и наоборот.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Вы должны понимать [основы Ethereum](/developers/docs/intro-to-ethereum/), прежде чем изучать разные сети. Тестовые сети предоставят вам бесплатную, безопасную версию Ethereum для разработки.
+Вам следует ознакомиться с [основами Ethereum](/developers/docs/intro-to-ethereum/), прежде чем читать о различных сетях, поскольку тестовые сети предоставят вам дешевую и безопасную версию Ethereum для экспериментов.
## Публичные сети {#public-networks}
Публичные сети доступны любому человеку в мире, у которого есть подключение к Интернету. Кто угодно может читать или создавать транзакции в публичной цепочке блоков (блокчейне) и проверять выполняемые транзакции. Консенсус среди пиров определяет, какие включать транзакции и как выглядит текущее состояние сети.
-### Основная сеть Ethereum (Mainnet) {#ethereum-mainnet}
+### Основная сеть Ethereum {#ethereum-mainnet}
Основная сеть — это основной публичный производственный блокчейн Ethereum, в котором транзакции с фактической стоимостью происходят в распределенном реестре.
Когда люди и биржи обсуждают цены на ETH, они говорят об ETH в основной сети.
-### Тестовые сети Ethereum (Testnet) {#ethereum-testnets}
+### Тестовые сети Ethereum {#ethereum-testnets}
Помимо основной сети существуют публичные тестовые сети. Это сети, используемые разработчиками протоколов или разработчиками умных контрактов для тестирования как обновлений протокола, так и потенциальных умных контрактов в производственной среде перед развертыванием в основной сети. Их можно представить как аналог производственных и промежуточных серверов.
@@ -34,19 +34,15 @@ lang: ru
#### Какую тестовую сеть мне использовать?
-Две общедоступные тестовые сети, которые в настоящее время поддерживают разработчики клиентов, — это Sepolia и Hoodi. Sepolia — это сеть для разработчиков контрактов и приложений для тестирования своих приложений. Сеть Hoodi позволяет разработчикам протоколов тестировать обновления сети, а заинтересованным сторонам — тестировать работающие валидаторы.
+Две публичные тестовые сети, которые в настоящее время поддерживают разработчики клиентов, — это Sepolia и Hoodi. Sepolia — это сеть для разработчиков контрактов и приложений для тестирования своих приложений. Сеть Hoodi позволяет разработчикам протоколов тестировать обновления сети, а стейкерам — тестировать работающие валидаторы.
#### Sepolia {#sepolia}
-**Sepolia — это рекомендуемая тестовая сеть по умолчанию для разработки приложений**. Сеть Sepolia использует группу валидаторов с разрешениями. Она довольно нова, а потому состояние и история сети еще довольно малы. Это значит, что сеть быстро синхронизируется, и запуск узла требует меньше места в хранилище. Это удобно для пользователей, которые хотят быстро запустить узел и взаимодействовать с сетью напрямую.
-
-- Закрытая группа валидаторов, управляемая клиентом и командами тестировщиков
-- Новая тестовая сеть, меньше развернутых приложений в сравнении с другими
-- Быстрая синхронизация, запуск узла требует минимального места на диске
+**Sepolia — это рекомендуемая тестовая сеть по умолчанию для разработки приложений**. Сеть Sepolia использует набор валидаторов с ограниченным доступом, который контролируется командами клиентов и тестирования.
##### Ресурсы
-- [Вебсайт](https://sepolia.dev/)
+- [Веб-сайт](https://sepolia.dev/)
- [GitHub](https://github.com/eth-clients/sepolia)
- [Otterscan](https://sepolia.otterscan.io/)
- [Etherscan](https://sepolia.etherscan.io)
@@ -54,20 +50,20 @@ lang: ru
##### Краны
-- [Кран QuickNode Sepolia](https://faucet.quicknode.com/drip)
+- [Кран Alchemy Sepolia](https://www.alchemy.com/faucets/ethereum-sepolia)
+- [Кран Chain Platform Sepolia](https://faucet.chainplatform.co/faucets/ethereum-sepolia/)
+- [Кран Chainstack Sepolia](https://faucet.chainstack.com/sepolia-testnet-faucet)
+- [Кран экосистемы Ethereum](https://www.ethereum-ecosystem.com/faucets/ethereum-sepolia)
+- [Кран ethfaucet.com Sepolia](https://ethfaucet.com/networks/ethereum)
+- [Кран Google Cloud Web3 Sepolia](https://cloud.google.com/application/web3/faucet/ethereum/sepolia)
- [Grabteeth](https://grabteeth.xyz/)
-- [Кран PoW](https://sepolia-faucet.pk910.de/)
-- [Кран кошелька Coinbase | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet)
-- [Кран Alchemy Sepolia](https://sepoliafaucet.com/)
- [Кран Infura Sepolia](https://www.infura.io/faucet)
-- [Кран Chainstack Sepolia](https://faucet.chainstack.com/sepolia-testnet-faucet)
-- [Кран Ethereum Ecosystem](https://www.ethereum-ecosystem.com/faucets/ethereum-sepolia)
+- [Кран PoW](https://sepolia-faucet.pk910.de/)
+- [Кран QuickNode Sepolia](https://faucet.quicknode.com/ethereum/sepolia)
#### Hoodi {#hoodi}
-_Обратите внимание: [тестовая сеть Goerli является устаревшей](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) и была заменена на Hoodi. Подумайте о переносе ваших приложений в Sepolia._
-
-Hoodi — тестовая сеть для проверки валидации и стейкинга. Сеть Hoodi открыта для пользователей, желающих запустить валидатор в тестовой сети. Поэтому стейкерам, желающим протестировать обновления протокола до его развертывания в главной сети, следует использовать Hoodi.
+Hoodi — это тестовая сеть для тестирования валидации и стейкинга. Сеть Hoodi открыта для пользователей, желающих запустить валидатор в тестовой сети. Поэтому стейкерам, желающим протестировать обновления протокола до его развертывания в основной сети, следует использовать Hoodi.
- Открытый набор валидаторов, стейкеры могут тестировать обновления сети
- Состояние большого размера, полезно для тестирования сложных взаимодействий со смарт-контрактами
@@ -75,69 +71,146 @@ Hoodi — тестовая сеть для проверки валидации
##### Ресурсы
-- [Сайт](https://hoodi.ethpandaops.io/)
+- [Веб-сайт](https://hoodi.ethpandaops.io/)
- [GitHub](https://github.com/eth-clients/hoodi)
-- [Explorer](https://explorer.hoodi.ethpandaops.io/)
-- [Checkpoint Sync](https://checkpoint-sync.hoodi.ethpandaops.io/)
+- [Обозреватель](https://explorer.hoodi.ethpandaops.io/)
+- [Синхронизация по контрольным точкам](https://checkpoint-sync.hoodi.ethpandaops.io/)
+- [Otterscan](https://hoodi.otterscan.io/)
+- [Etherscan](https://hoodi.etherscan.io/)
##### Краны
+- [Кран Chain Platform Hoodi](https://faucet.chainplatform.co/faucets/ethereum-hoodi/)
- [Кран Hoodi](https://hoodi.ethpandaops.io/)
+- [Кран PoW](https://hoodi-faucet.pk910.de/)
+
+#### Ephemery {#ephemery}
+
+Ephemery — это уникальный вид тестовой сети, которая полностью сбрасывается каждый месяц. Состояние исполнения и консенсуса возвращается к генезису каждые 28 дней, что означает, что все, что происходит в тестовой сети, является эфемерным. Это делает ее идеальной для краткосрочного тестирования, быстрой начальной загрузки узлов и приложений типа «hello world», которые не требуют постоянства.
+
+- Всегда свежее состояние, краткосрочное тестирование валидаторов и приложений
+- Включает только базовый набор контрактов
+- Открытый набор валидаторов и легкий доступ к большим суммам средств
+- Самые низкие требования к узлу и самая быстрая синхронизация, в среднем <5 ГБ
-Чтобы стать валидатором в тестовой сети Hoodi, используйте [панель запуска Hoodi](https://hoodi.launchpad.ethereum.org/en/).
+##### Ресурсы
+
+- [Веб-сайт](https://ephemery.dev/)
+- [Github](https://github.com/ephemery-testnet/ephemery-resources)
+- [Чат сообщества](https://matrix.to/#/#staker-testnet:matrix.org)
+- [Blockscout](https://explorer.ephemery.dev/)
+- [Otterscan](https://otter.bordel.wtf/)
+- [Обозреватель Beacon Chain](https://beaconlight.ephemery.dev/)
+- [Синхронизация по контрольным точкам](https://checkpoint-sync.ephemery.ethpandaops.io)
+- [Панель запуска](https://launchpad.ephemery.dev/)
+
+#### Краны
+
+- [Кран Bordel](https://faucet.bordel.wtf/)
+- [Кран Pk910 PoW](https://ephemery-faucet.pk910.de/)
+
+#### Holesky (устарело) {#holesky}
+
+Тестовая сеть Holesky устарела с сентября 2025 года. Вместо этого операторам стейкинга и поставщикам инфраструктуры следует использовать Hoodi для тестирования валидаторов.
+
+- [Объявление о прекращении работы тестовой сети Holesky](https://blog.ethereum.org/2025/09/01/holesky-shutdown-announcement) — _блог EF, 1 сентября 2025 г._
+- [Обновления тестовых сетей Holesky и Hoodi](https://blog.ethereum.org/en/2025/03/18/hoodi-holesky) — _блог EF, 18 марта 2025 г._
### Тестовые сети уровня 2 {#layer-2-testnets}
-[Уровень 2 (L2)](/layer-2/) — это общий термин для описания определенного набора решений для масштабирования Ethereum. Уровень 2 является отдельным блокчейном, который расширяет Ethereum и наследует гарантии безопасности Ethereum. Тестовые сети уровня 2 обычно тесно связаны с публичными тестовыми сетями Ethereum.
+[Уровень 2 (L2)](/layer-2/) — это собирательный термин для описания определенного набора решений для масштабирования Ethereum. Уровень 2 является отдельным блокчейном, который расширяет Ethereum и наследует гарантии безопасности Ethereum. Тестовые сети уровня 2 обычно тесно связаны с публичными тестовыми сетями Ethereum.
#### Arbitrum Sepolia {#arbitrum-sepolia}
Тестовая сеть для [Arbitrum](https://arbitrum.io/).
+##### Ресурсы
+
+- [Etherscan](https://sepolia.arbiscan.io/)
+- [Blockscout](https://sepolia-explorer.arbitrum.io/)
+
##### Краны
-- [Кран Chainlink](https://faucets.chain.link/arbitrum-sepolia)
-- [Кран Alchemy](https://www.alchemy.com/faucets/arbitrum-sepolia)
+- [Кран Alchemy Arbitrum Sepolia](https://www.alchemy.com/faucets/arbitrum-sepolia)
+- [Кран Chainlink Arbitrum Sepolia](https://faucets.chain.link/arbitrum-sepolia)
+- [Кран ethfaucet.com Arbitrum Sepolia](https://ethfaucet.com/networks/arbitrum)
+- [Кран QuickNode Arbitrum Sepolia](https://faucet.quicknode.com/arbitrum/sepolia)
#### Optimistic Sepolia {#optimistic-sepolia}
Тестовая сеть для [Optimism](https://www.optimism.io/).
+##### Ресурсы
+
+- [Etherscan](https://sepolia-optimistic.etherscan.io/)
+- [Blockscout](https://optimism-sepolia.blockscout.com/)
+
##### Краны
-- [Кран Chainlink](https://faucets.chain.link/optimism-sepolia)
- [Кран Alchemy](https://www.alchemy.com/faucets/optimism-sepolia)
+- [Кран Chainlink](https://faucets.chain.link/optimism-sepolia)
+- [Кран ethfaucet.com Optimism Sepolia](https://ethfaucet.com/networks/optimism)
+- [Кран тестовой сети](https://docs.optimism.io/builders/tools/build/faucets)
#### Starknet Sepolia {#starknet-sepolia}
Тестовая сеть для [Starknet](https://www.starknet.io).
+##### Ресурсы
+
+- [Starkscan](https://sepolia.starkscan.co/)
+
##### Краны
- [Кран Alchemy](https://www.alchemy.com/faucets/starknet-sepolia)
+- [Кран Blast Starknet Sepolia](https://blastapi.io/faucets/starknet-sepolia-eth)
+- [Кран Starknet](https://starknet-faucet.vercel.app/)
## Частные сети {#private-networks}
-Сеть Ethereum представляет собой частную сеть, если ее узлы не подключены к общедоступной сети (т. е. к основной или тестовой сети). В этом контексте «частная» означает только «зарезервированная» или «изолированная», а не «защищенная» или «безопасная».
+Сеть Ethereum является частной сетью, если ее узлы не подключены к публичной сети (т. е. к основной сети или тестовой сети). В этом контексте «частная» означает только «зарезервированная» или «изолированная», а не «защищенная» или «безопасная».
-### Сети разработки {#development-networks}
+### Сети для разработки {#development-networks}
При разработке приложения Ethereum вам нужно запустить его в частной сети и увидеть, как оно работает, прежде чем развертывать. Подобно тому, как вы создаете локальный сервер на своем компьютере для веб-разработки, вы можете создать локальный экземпляр блокчейна для тестирования своего децентрализованного приложения. Это позволяет повторять итерации намного быстрее, чем в общедоступной тестовой сети.
-Существуют проекты и инструменты, которые могут помочь в этом. Узнайте больше о [сетях для разработки](/developers/docs/development-networks/).
+Существуют проекты и инструменты, которые могут помочь в этом. Подробнее о [сетях для разработки](/developers/docs/development-networks/).
-### Сети консорциума {#consortium-networks}
+### Консорциумные сети {#consortium-networks}
Процесс консенсуса контролируется заранее определенным набором доверенных узлов. Например, частная сеть известных академических учреждений, каждое из которых управляет одним узлом, а блоки проверяются пороговым числом подписантов внутри сети.
Если общедоступная сеть Ethereum похожа на общедоступный интернет, то сеть консорциума похожа на частный интранет.
+## Почему тестовые сети Ethereum называют в честь станций метро? {#why-naming}
+
+Многие тестовые сети Ethereum названы в честь реальных станций метро или железнодорожных вокзалов. Эта традиция наименования зародилась на раннем этапе и отражает города мира, где жили или работали участники. Это символично, запоминается и практично. Так же, как тестовые сети изолированы от основной сети Ethereum, линии метро проходят отдельно от наземного транспорта.
+
+### Часто используемые и устаревшие тестовые сети {#common-and-legacy-testnets}
+
+- **Sepolia** — район в Афинах (Греция), связанный с метро. В настоящее время используется для тестирования смарт-контрактов и децентрализованных приложений.
+- **Hoodi** — названа в честь станции метро Hoodi в Бангалоре, Индия. Используется для тестирования валидаторов и обновлений протокола.
+- **Goerli** _(устарело)_ — названа в честь вокзала Гёрлицер в Берлине, Германия.
+- **Rinkeby** _(устарело)_ — названа в честь пригорода Стокгольма со станцией метро.
+- **Ropsten** _(устарело)_ — названа в честь района и бывшего паромного/метро-терминала в Стокгольме.
+- **Kovan** _(устарело)_ — названа в честь станции сингапурского метрополитена.
+- **Morden** _(устарело)_ — названа в честь станции лондонского метро. Первая публичная тестовая сеть Ethereum.
+
+### Другие специализированные тестовые сети {#other-testnets}
+
+Некоторые тестовые сети были созданы для краткосрочного тестирования или тестирования конкретных обновлений и не обязательно связаны с тематикой метро:
+
+- **Holesky** _(устарело)_ — названа в честь станции Голешовице в Праге. Использовалась для тестирования валидаторов; устарела в 2025 году.
+- **Kiln**, **Zhejiang**, **Shandong**, **Prater**, **Pyrmont**, **Olympic** _(все устарели)_ и **Ephemery** — специально созданы для симуляции обновлений, таких как Слияние, Шанхай, или для экспериментов с валидаторами. Некоторые названия являются региональными или тематическими, а не связанными с метро.
+
+Использование названий станций метро помогает разработчикам быстро определять и запоминать тестовые сети, не полагаясь на числовые идентификаторы сетей. Это также отражает культуру Ethereum: практичную, глобальную и ориентированную на человека.
+
## Связанные инструменты {#related-tools}
-- [Chainlist](https://chainlist.org/) — _список сетей EVM для подключения кошельков и поставщиков услуг к соответствующим идентификаторам цепочки и сети._
-- [Цепочки на основе EVM](https://github.com/ethereum-lists/chains) — _репозиторий GitHub с метаданными цепочки, на которых основан Chainlist._
+- [Chainlist](https://chainlist.org/) — _список сетей EVM для подключения кошельков и провайдеров к соответствующим идентификаторам Chain ID и Network ID_
+- [Сети на основе EVM](https://github.com/ethereum-lists/chains) — _репозиторий GitHub с метаданными сетей, на котором работает Chainlist_
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Предложение: предсказуемый жизненный цикл тестовых сетей Ethereum](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17)
+- [Предложение: прогнозируемый жизненный цикл тестовой сети Ethereum](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17)
- [Эволюция тестовых сетей Ethereum](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/)
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/archive-nodes/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/archive-nodes/index.md
new file mode 100644
index 00000000000..9bc88c20523
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/archive-nodes/index.md
@@ -0,0 +1,81 @@
+---
+title: "Архивный узел Эфириума"
+description: "Обзор архивных узлов"
+lang: ru
+sidebarDepth: 2
+---
+
+Архивный узел - это пример клиента Эфириума, настроенного на архивирование всех статусов истории. Архивный узел представляет собой полезный инструмент для определенных сценариев использования, но его настройка и запуск могут быть сложнее, чем у полного узла.
+
+## Предварительные условия {#prerequisites}
+
+Вам следует понимать концепцию [узла Ethereum](/developers/docs/nodes-and-clients/), [его архитектуру](/developers/docs/nodes-and-clients/node-architecture/), [стратегии синхронизации](/developers/docs/nodes-and-clients/#sync-modes), практики [запуска](/developers/docs/nodes-and-clients/run-a-node/) и [использования их](/developers/docs/apis/json-rpc/).
+
+## Что такое архивный узел
+
+Чтобы понять важность архивного узла, давайте уточним понятие "статуса." Ethereum можно назвать _машиной состояний на основе транзакций_. Она состоит из счетов и приложений, выполняющих транзакции, которые изменяют их статус. Глобальные данные с информацией о каждом счёте и контракте хранятся в древе базы данных, которые называются "статусами". Они обрабатываются клиентом исполнительного уровня (EL) и включают:
+
+- Остатки по счетам и одноразовые номера
+- Код контракта и место хранения
+- Данные, связанные с консенсусом, например, депозитный контракт для стейкинга
+
+Для взаимодействия с сетью, проверки и создания новых блоков, клиенты Эфириум должны быть в курсе самых последних изменений (конец цепи) и, следовательно, текущего статуса. Клиент уровня исполнения, настроенный как полный узел, проверяет и отслеживает последнее состояние сети, но кэширует только несколько прошлых состояний, например, состояние, связанное с последними 128 блоками, чтобы он мог обрабатывать реорганизации цепочки и предоставлять быстрый доступ к последним данным. Последний статус - это информация, необходимая всем клиентам для проверки входящих транзакций и использования сети.
+
+Можно представить статус, как мгновенный сетевой снимок определённого блока, а архив, как воспроизведение истории.
+
+Статусы истории могут быть безопасно удалены, так как они не требуются для работы сети, а для клиента хранение всех устаревших данных было бы избыточным и бесполезным. Состояния, которые существовали до недавнего блока (например, за 128 блоков до текущего), по сути, отбрасываются. Полные узлы хранят только данные истории блокчейна (блоки и транзакции) и случайные снимки истории, которые они могут использовать для восстановления старых статусов по запросу. Они делают это путем повторного исполнения прошлых транзакций в виртуальной машине Эфириума (EVM), что может требовать больших вычислительных ресурсов, когда желаемый статус далёк от ближайшего снимка.
+
+Тем не менее это означает, что на полном узле доступ к статусу из истории потребляет большое количество вычислительных ресурсов. Клиенту может потребоваться выполнить все прошлые транзакции и вычислить статус из истории от самого начала. Архивные узлы решают эту проблему, сохраняя не только самые последние статусы, но и все, созданные после каждого блока, статусы истории. По сути, это создает компромисс с требованиями к большим объёмам дискового пространства.
+
+Важно отметить, что сеть не зависит от архивных узлов для хранения и предоставления всех данных истории. Как уже упоминалось выше, все промежуточные статусы истории могут быть получены на полном узле. Транзакции хранятся на любом полном узле (в настоящее время менее 400 Г) и могут быть повторно исполнены для создания всего архива.
+
+### Примеры использования
+
+Обычное использование Эфириума для отправки транзакций, развертывания контрактов, проверки соглашения и т. д., не требует доступа к статусам истории. Для стандартного взаимодействия с сетью пользователям никогда не требуется архивный узел.
+
+Основным преимуществом архивирования статусов является быстрый доступ к запросам статусов из истории. Например, архивный узел быстро выдаёт результаты:
+
+- _Какой баланс ETH у аккаунта 0x1337... в блоке 15537393?_
+- _Каков баланс токена 0x в контракте 0x в блоке 1920000?_
+
+Как описано выше, полному узлу нужно будет сгенерировать эти данные, запустив EVM, который использует процессор и занимает время. Архивные узлы получают доступ к ним на диске и немедленно предоставляют ответы. Это полезная функция для определенных частей инфраструктуры, например:
+
+- Поставщики услуг, такие как обозреватели блоков
+- Исследователи
+- Аналитики безопасности
+- Разработчики децентрализованных приложений
+- Контроль и соответствие
+
+Существуют различные бесплатные [сервисы](/developers/docs/nodes-and-clients/nodes-as-a-service/), которые также предоставляют доступ к архивным данным. Поскольку запуск архивного узла требует больше усилий, этот доступ в основном ограничен и работает только для одноразового доступа. Если вашему проекту требуется постоянный доступ к данным истории, следует запустить его самостоятельно.
+
+## Реализация и использование
+
+В этом контексте под архивными узлами подразумеваются данные, которые предоставляются клиентам уровня исполнения пользователем, поскольку они обрабатывают базы данных статусов и предоставляют конечные точки протокола удаленного вызова процедур (JSON-RPC). Параметры конфигурации, время синхронизации и размер базы данных могут различаться в зависимости от клиента. Для получения подробной информации, обратитесь к документации, предоставленной вашим заказчиком.
+
+Прежде чем запускать собственный архивный узел, изучите различия между клиентами и особенно различные [требования к оборудованию](/developers/docs/nodes-and-clients/run-a-node/#requirements). Большинство клиентов не оптимизированы для этой функции, и их архивы требуют более 12 ТБ пространства. С другой стороны, такие реализации, как Erigon, могут хранить те же данные менее чем в 3ТБ, что делает их наиболее эффективным способом запуска архивного узла.
+
+## Рекомендации по практическому применению
+
+Помимо общих [рекомендаций по запуску узла](/developers/docs/nodes-and-clients/run-a-node/), архивный узел может быть более требовательным к оборудованию и обслуживанию. Учитывая [ключевые особенности](https://github.com/ledgerwatch/erigon#key-features) Erigon, наиболее практичным подходом является использование реализации клиента [Erigon](/developers/docs/nodes-and-clients/#erigon).
+
+### Аппаратное обеспечение
+
+Всегда проверяйте требования к оборудованию для данного режима в документации клиента.
+Самым большим требованием для архивных узлов является дисковое пространство. В зависимости от клиента, оно колеблется от 3ТБ до 12ТБ. Несмотря на то, что HDD могут считаться лучшим решением для хранения массивных объёмов данных, для постоянной синхронизации и обновления конца цепи потребуются SSD накопители. Диски [SATA](https://www.cleverfiles.com/help/sata-hard-drive.html) достаточно хороши, но они должны быть надежного качества, по крайней мере [TLC](https://blog.synology.com/tlc-vs-qlc-ssds-what-are-the-differences). Диски могут быть установлены в компьютер или сервер с достаточным количеством слотов. Подобные специализированные устройства идеальны для работы узла с высоким временем безотказной работы. Вполне возможно запустить его на ноутбуке, но за портативность придется заплатить дополнительно.
+
+Все данные должны помещаться в один том, поэтому диски необходимо объединить, например с помощью [RAID0](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_0) или LVM. Также стоит рассмотреть возможность использования [ZFS](https://en.wikipedia.org/wiki/ZFS), поскольку он поддерживает функцию "Copy-on-write", которая обеспечивает корректную запись данных на диск без каких-либо ошибок низкого уровня.
+
+Для большей стабильности и безопасности в предотвращении случайного повреждения базы данных, особенно в профессиональной среде, рассмотрите возможность использования [памяти ECC](https://en.wikipedia.org/wiki/ECC_memory), если ваша система ее поддерживает. Объем оперативной памяти (RAM) рекомендуется выбирать таким же, как и для полного узла, однако больший объем оперативной памяти может помочь ускорить синхронизацию.
+
+При первичной синхронизации клиенты будут выполнять все транзакции, начиная с исходной, в архивном режиме. Скорость выполнения в основном зависит от ограничений центрального процессора (CPU), так что более быстрый процессор может ускорить время первоначальной синхронизации. Среднестатистическому компьютеру на первоначальную синхронизацию может потребоваться до месяца.
+
+## Дополнительные материалы {#further-reading}
+
+- [Полный узел Ethereum в сравнении с архивным узлом](https://www.quicknode.com/guides/infrastructure/ethereum-full-node-vs-archive-node) - _QuickNode, сентябрь 2022 г._
+- [Создание собственного архивного узла Ethereum](https://tjayrush.medium.com/building-your-own-ethereum-archive-node-72c014affc09) - _Thomas Jay Rush, август 2021 г._
+- [Как настроить Erigon, RPC-сервер Erigon и TrueBlocks (сбор данных и API) в качестве служб](https://magnushansson.xyz/blog_posts/crypto_defi/2022-01-10-Erigon-Trueblocks) _– Magnus Hansson, обновлено в сентябре 2022 г._
+
+## Смежные темы {#related-topics}
+
+- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
+- [Запуск узла](/developers/docs/nodes-and-clients/run-a-node/)
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/bootnodes/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/bootnodes/index.md
new file mode 100644
index 00000000000..332e35cfdfe
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/bootnodes/index.md
@@ -0,0 +1,31 @@
+---
+title: "Введение в загрузочные узлы Ethereum"
+description: "Основные сведения, необходимые для понимания загрузочных узлов"
+lang: ru
+---
+
+Когда новый узел присоединяется к сети Ethereum, он должен соединиться с узлами, которые уже находятся в сети, чтобы затем открыть новые аналоги. Эти точки входа в сеть Ethereum называются загрузочными узлами. Клиенты обычно имеют список загрузочных узлов, закодированных в них. Эти загрузочные узлы, как правило, управляются командой разработчиков Ethereum Foundation или самими клиентскими командами. Обратите внимание, что загрузочные узлы - это не то же самое, что статические узлы. Статические узлы вызываются снова и снова, в то время как загрузочные узлы вызываются только в том случае, если не хватает участников для подключения, и узел должен загружать некоторые новые соединения.
+
+## Подключиться к загрузочному узлу {#connect-to-a-bootnode}
+
+У большинства клиентов есть встроенный список загрузочных узлов, но вы также можете запустить собственный загрузочный узел или использовать узел, не входящий в жестко закодированный список клиента. В этом случае вы можете указать их при запуске клиента следующим образом (например, гость, пожалуйста, проверьте документацию клиента):
+
+```
+geth --bootnodes "enode://@:<порт>"
+```
+
+## Запуск загрузочного узла {#run-a-bootnode}
+
+Загрузочные узлы — это полные узлы, которые не находятся за NAT ([трансляция сетевых адресов](https://www.geeksforgeeks.org/network-address-translation-nat/)). Каждый полный узел может выступать в качестве загрузочного узла, если он общедоступен.
+
+При запуске узел должен зарегистрировать ваш [enode](/developers/docs/networking-layer/network-addresses/#enode) — публичный идентификатор, который другие могут использовать для подключения к вашему узлу.
+
+Электронный узел обычно регенерируется при каждом перезапуске, поэтому убедитесь, что просмотрели документацию клиента о том, как генерировать постоянный электронный узел для вашего загрузочного узла.
+
+Для того чтобы быть хорошим загрузочным узлом это хорошая идея увеличить максимальное число участников, которые могут подключиться к нему. Запуск загрузочного узла со многими коллегами значительно увеличит требование к пропускной способности.
+
+## Доступные загрузочные узлы {#available-bootnodes}
+
+Список встроенных загрузочных узлов в go-ethereum можно найти [здесь](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go#L23). Эти загрузочные узлы обслуживаются Ethereum Foundation и Go-Ethereum командой.
+
+Есть другие списки загрузочных узлов, поддерживаемых добровольцами. Пожалуйста, убедитесь, что всегда включать хотя бы один официальный загрузочный узел, в противном случае вы можете быть атакованы затмением.
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/client-diversity/index.md
new file mode 100644
index 00000000000..6bf8381a64a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/client-diversity/index.md
@@ -0,0 +1,132 @@
+---
+title: "Разнообразие клиентов"
+description: "Высокий уровень объяснения важности разнообразия клиентов Ethereum."
+lang: ru
+sidebarDepth: 2
+---
+
+Поведение узла Ethereum контролируется клиентским программным обеспечением, запускаемым им. Существует несколько производственных уровней клиентов Ethereum, каждый из которых разрабатывается и поддерживается на разных языках отдельными командами. Клиенты построены по единой спецификации, которая обеспечивает беспрепятственное взаимодействие клиентов друг с другом, одинаковые функциональные возможности и эквивалентный пользовательский опыт. Однако на данный момент распределение клиентов по узлам недостаточно для того, чтобы полностью реализовать этот фортификационный потенциал этой сети. В идеале, пользователи очень равно разделяют между собой разные клиенты, что бы получить так много разнообразия клиентов насколько это возможно в сети.
+
+## Предварительные условия {#prerequisites}
+
+Если вы еще не понимаете, что такое узлы и клиенты, ознакомьтесь с разделом [«Узлы и клиенты»](/developers/docs/nodes-and-clients/). Определения [уровня исполнения](/glossary/#execution-layer) и [уровня консенсуса](/glossary/#consensus-layer) находятся в глоссарии.
+
+## Почему существует несколько клиентов? {#why-multiple-clients}
+
+Существует множество независимо разработанных и поддерживаемых клиентов, поскольку разнообразие клиентов делает сеть более устойчивой к атакам и ошибкам. Множество клиентов - это уникальная сила Ethereum - другие блокчейны полагаются на безошибочность одного клиента. Однако недостаточно просто иметь в наличии несколько клиентов — они должны быть приняты сообществом, а общее количество активных узлов должно быть распределено между ними относительно равномерно.
+
+## Почему разнообразие клиентов важно? {#client-diversity-importance}
+
+Наличие множества независимо разработанных и поддерживаемых клиентов жизненно важно для здорового развития децентрализованных сетей. Давайте рассмотрим причины, почему.
+
+### Ошибки {#bugs}
+
+Сбой в работе одного клиента представляет меньшую опасность для сети, если он затрагивает лишь меньшинство узлов Ethereum. При примерно равномерном распределении узлов между многими клиентами вероятность того, что большинство клиентов будут подвергнуты общей проблеме, мала, и в результате сеть становится более надежной.
+
+### Устойчивость к атакам {#resilience}
+
+Многообразие клиентов также обеспечивает устойчивость против атак. Например, атака, которая [обманывает определенный клиент](https://twitter.com/vdWijden/status/1437712249926393858), заставляя его перейти на определенное ответвление цепи, вряд ли будет успешной, потому что другие клиенты, скорее всего, не будут уязвимы таким же образом, и каноническая цепь останется неповрежденной. Низкая разнообразность клиентов увеличивает риск, связанный со взломом доминирующего клиента. Разнообразие клиентов уже доказало, что оно является важной защитой от злоумышленных атак на сеть, например, во время обновления Shanghai в 2016 году Dos-атака был возможна, т.к. злоумышленники смогли обмануть доминирующий клиент (Geth) на выполнение медленной дисковой операции на ввод/вывод данных десятки тысяч раз за блок. Поскольку альтернативные клиенты также работали, но были без этой уязвимости, Ethereum смог противостоять атаке и продолжать работать, пока уязвимость в Geth не была исправлена.
+
+### Окончательность Proof-of-Stake {#finality}
+
+Ошибка в клиенте консенсуса с более 33% узлов Ethereum может помешать уровню консенсуса финализировать, то есть пользователи не могут доверять, что транзакции не будут отменены или изменены в какой-то момент. Это было бы очень проблематично для многих приложений, построенных на Ethereum, особенно приложений DeFi.
+
+ Хуже того, критическая ошибка в клиенте с большинством в две трети голосов может привести к тому, что цепь неправильно разделится и финализируется, в результате чего большое количество валидаторов застрянет на недействительной цепи. Если они хотят вернуться в правильную цепь, эти валидаторы сталкиваются с наказанием урезанием или медленным и дорогостоящим добровольным выводом и реактивацией. Масштаб наказания урезанием зависит от количества виновных узлов и с максимальным сокращением (32 ETH) при количестве двух третьих.
+
+Хотя это маловероятные сценарии, экосистема Ethereum может смягчить риск их возникновения путем одинакового распределения активных узлов по разным клиентам. В идеале, ни один клиент консенсуса никогда не достигнет 33% доли от всех узлов.
+
+### Совместная ответственность {#responsibility}
+
+Наличие мажоритарных клиентов также влечет за собой человеческие издержки. Это возлагает большое напряжение и ответственность на небольшую команду разработчиков. Чем меньше разнообразие клиентов, тем большая ответственность лежит на разработчиках, поддерживающих мажоритарный клиент. Распределение этой ответственности на несколько команд хорошо как для здоровья узлов сети Ethereum, так и для людей этой сети.
+
+## Текущее разнообразие клиентов {#current-client-diversity}
+
+### Клиенты исполнения {#execution-clients-breakdown}
+
+
+
+### Клиенты консенсуса {#consensus-clients-breakdown}
+
+
+
+Эта диаграмма может быть устаревшей — перейдите на [ethernodes.org](https://ethernodes.org) и [clientdiversity.org](https://clientdiversity.org) для получения актуальной информации.
+
+Две круговые диаграммы выше показывают срезы текущего разнообразия клиентов для уровней исполнения и консенсуса (на момент написания в октябре 2025 года). Разнообразие клиентов с годами улучшилось, а на уровне исполнения наблюдается снижение доминирования [Geth](https://geth.ethereum.org/). [Nethermind](https://www.nethermind.io/nethermind-client) занимает второе место, [Besu](https://besu.hyperledger.org/) — третье, а [Erigon](https://github.com/ledgerwatch/erigon) — четвертое. На остальные клиенты приходится менее 3 % сети. Доля самого распространенного клиента уровня консенсуса, [Lighthouse](https://lighthouse.sigmaprime.io/), ненамного превышает долю второго по популярности клиента. На [Prysm](https://prysmaticlabs.com/#projects) и [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) приходится ~31 % и ~14 % соответственно, а другие клиенты используются редко.
+
+Данные по уровню исполнения были получены с [supermajority.info](https://supermajority.info/) 26 октября 2025 года. Данные для клиентов консенсуса были получены от [Майкла Спроула](https://github.com/sigp/blockprint). Получить данные о клиентах консенсуса сложнее, поскольку клиенты уровня консенсуса не всегда имеют однозначные «следы», которые можно использовать для их идентификации. Данные были сгенерированы с помощью алгоритма классификации, который иногда путает некоторых миноритарных клиентов (подробнее см. [здесь](https://twitter.com/sproulM_/status/1440512518242197516)). На диаграмме выше эти неоднозначные классификации обозначаются двойной меткой (например, Nimbus/Teku). Тем не менее, очевидно, что большая часть сети использует Prysm. Несмотря на то, что значения на диаграмме являются лишь снимками в определенные моменты времени, они дают хорошее общее представление о текущем состоянии разнообразия клиентов.
+
+Актуальные данные о разнообразии клиентов для уровня консенсуса теперь доступны на [clientdiversity.org](https://clientdiversity.org/).
+
+## Уровень исполнения {#execution-layer}
+
+До сих пор обсуждение разнообразия клиентов в основном касалось уровня консенсуса. Однако на клиент исполнения [Geth](https://geth.ethereum.org) в настоящее время приходится около 85 % всех узлов. Этот процент проблематичен по тем же причинам, что и для клиентов консенсуса. Например, баг в Geth, влияющий на обработку транзакций или построение полезных нагрузок выполнения, может привести к тому, что клиенты консенсуса одобрят проблемные или ошибочные транзакции. Таким образом, Ethereum будет безопаснее при более равномерном распределении клиентов исполнения, в идеале — когда ни один клиент не представляет больше 33% сети.
+
+## Использование миноритарного клиента {#use-minority-client}
+
+Решение проблемы разнообразия клиентов требует не только того, чтобы отдельные пользователи выбирали миноритарные клиенты, но и того, чтобы пулы валидаторов и такие организации, как крупные децентрализованные приложения и биржи, также переключались на другие клиенты. Однако все пользователи могут внести свой вклад в устранение текущего дисбаланса и уравновешивание использования всего доступного программного обеспечения Ethereum. После обновления «Слияние» все операторы узлов должны будут запустить клиент исполнения и клиент консенсуса. Выбор комбинаций клиентов, предложенных ниже, поможет улучшить разнообразие клиентов.
+
+### Клиенты-исполнители {#execution-clients}
+
+- [Besu](https://www.hyperledger.org/use/besu)
+- [Nethermind](https://downloads.nethermind.io/)
+- [Erigon](https://github.com/ledgerwatch/erigon)
+- [Go-Ethereum](https://geth.ethereum.org/)
+- [Reth](https://reth.rs/)
+
+### Клиенты консенсуса {#consensus-clients}
+
+- [Nimbus](https://nimbus.team/)
+- [Lighthouse](https://github.com/sigp/lighthouse)
+- [Teku](https://consensys.io/teku)
+- [Lodestar](https://github.com/ChainSafe/lodestar)
+- [Prysm](https://prysm.offchainlabs.com/docs/)
+- [Grandine](https://docs.grandine.io/)
+
+Опытные пользователи могут помочь ускорить этот процесс, написав больше учебных руководств и документации для миноритарных клиентов и поощряя за переход с доминирующих клиентов своих коллег, управляющих узлами. Руководства по переключению на миноритарный клиент консенсуса доступны на [clientdiversity.org](https://clientdiversity.org/).
+
+## Панели мониторинга разнообразия клиентов {#client-diversity-dashboards}
+
+Ряд панелей дают в реальном времени статистику о разных клиентах уровня выполнения и консенсуса.
+
+**Уровень консенсуса:**
+
+- [Rated.network](https://www.rated.network/)
+- [clientdiversity.org](https://clientdiversity.org/)
+
+**Уровень исполнения:**
+
+- [supermajority.info](https://supermajority.info//)
+- [Ethernodes](https://ethernodes.org/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Разнообразие клиентов на уровне консенсуса Ethereum](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA)
+- [Слияние Ethereum: используйте мажоритарный клиент на свой страх и риск!](https://dankradfeist.de/ethereum/2022/03/24/run-the-majority-client-at-your-own-peril.html) — _Данкрад Фист, 24 марта 2022 г._
+- [Важность разнообразия клиентов](https://our.status.im/the-importance-of-client-diversity/)
+- [Список сервисов узлов Ethereum](https://ethereumnodes.com/)
+- [«Пять почему» проблемы разнообразия клиентов](https://notes.ethereum.org/@afhGjrKfTKmksTOtqhB9RQ/BJGj7uh08)
+- [Разнообразие в Ethereum и как его достичь (YouTube)](https://www.youtube.com/watch?v=1hZgCaiqwfU)
+- [clientdiversity.org](https://clientdiversity.org/)
+
+## Смежные темы {#related-topics}
+
+- [Запуск узла Ethereum](/run-a-node/)
+- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/index.md
index 31b45bfb199..a3e65900197 100644
--- a/public/content/translations/ru/developers/docs/nodes-and-clients/index.md
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/index.md
@@ -1,313 +1,319 @@
---
-title: Узлы и клиенты
-description: Немного об узлах Ethereum и клиентском программном обеспечении, а также о том, как настроить узел и почему вы должны это сделать.
+title: "Узлы и клиенты"
+description: "Немного об узлах Ethereum и клиентском программном обеспечении, а также о том, как настроить узел и почему вы должны это сделать."
lang: ru
sidebarDepth: 2
---
-Ethereum — это распределенная сеть компьютеров с программным обеспечением (известным как узлы, или ноды), которое может проверять блоки и данные транзакций. Для «запуска» узла на вашем компьтере вам необходимо приложение, известное как клиент.
+Ethereum — это распределенная сеть компьютеров с программным обеспечением (известным как узлы, или ноды), которое может проверять блоки и данные транзакций. Программное обеспечение должно быть запущено на вашем компьютере, чтобы превратить его в узел Ethereum. Для создания узла требуются две отдельные части программного обеспечения (известные как "клиенты").
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Вы должны понимать концепцию одноранговой сети и [основы EVM](/developers/docs/evm/), прежде чем углубляться и запускать собственный экземпляр клиента Ethereum. Начните с [введения в Ethereum](/developers/docs/intro-to-ethereum/).
+Вам следует разобраться в концепции одноранговых сетей и [основах EVM](/developers/docs/evm/), прежде чем углубляться в тему и запускать собственный экземпляр клиента Ethereum. Ознакомьтесь с нашим [введением в Ethereum](/developers/docs/intro-to-ethereum/).
-Если ты новичок в теме узлов, мы рекомендуем сначала ознакомиться с нашим удобным для пользователя введением по [ запуску узла Ethereum](/run-a-node).
+Если вы новичок в теме узлов, мы рекомендуем сначала ознакомиться с нашим простым и понятным руководством по [запуску узла Ethereum](/run-a-node).
## Что такое узлы и клиенты? {#what-are-nodes-and-clients}
-«Узел» относится к запускаемой части клиентского программного обеспечения. Клиент — это реализация Ethereum, которая проверяет все транзакции в каждом блоке, обеспечивая безопасность сети и точность данных.
+«Узел» - это любой экземпляр клиентского программного обеспечения Ethereum, который соединен с другими компьютерами, на которых также установлено программное обеспечение Ethereum, образуя сеть. Клиент - это реализация Ethereum, которая проверяет данные на соответствие правилам протокола и обеспечивает безопасность сети. Узел работает посредством двух клиентов: клиент консенсуса и клиент исполнения.
-Вы можете увидеть сеть Ethereum в реальном времени, посмотрев на эту [карту узлов](https://etherscan.io/nodetracker).
+- Клиент исполнения (также известный как Execution Engine, EL-клиент, или ранее Eth1-клиент) улавливает новые транзакции, транслируемые в сети, выполняет их в EVM, а также хранит последнее состояние и базу данных всех текущих данных Ethereum.
+- Клиент консенсуса (также известный как Beacon Node, клиент CL, или ранее клиент Eth2) реализует алгоритм консенсуса proof-of-stake, который позволяет сети достигать согласия на основе проверенных клиентом исполнения данных. Существует также третья часть программного обеспечения, известная как «валидатор», которая может быть добавлена к клиенту консенсуса, позволяя узлу участвовать в обеспечении безопасности сети.
-[Клиенты Ethereum](/developers/docs/nodes-and-clients/#execution-clients) существуют на множестве языков программирования, таких как Go, Rust, JavaScript, Typescript, Python, C# .NET, Nim и Java. Что общего у этих реализаций, так это то, что все они следуют формальной спецификации (изначально [Желтая книга Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf)). Эта спецификация определяет, как функционирует сеть Ethereum и блокчейн.
+Эти клиенты работают совместно для отслеживания текущего состояния блокчейна Ethereum и обеспечения взаимодействия пользователей с сетью Ethereum. Модульная архитектура, при которой множество программных компонентов работают совместно, называется [инкапсулированной сложностью](https://vitalik.eth.limo/general/2022/02/28/complexity.html). Этот подход упростил беспрепятственное выполнение [Слияния](/roadmap/merge), делает клиентское программное обеспечение более простым в обслуживании и разработке и позволяет повторно использовать отдельные клиенты, например, в [экосистеме леера 2](/layer-2/).
- Упрощенная схема возможностей клиента Ethereum.
+
+Упрощенная схема совмещенного клиента исполнения и консенсуса.
+
+### Разнообразие клиентов {#client-diversity}
+
+И [клиенты-исполнители](/developers/docs/nodes-and-clients/#execution-clients), и [клиенты консенсуса](/developers/docs/nodes-and-clients/#consensus-clients) существуют в версиях на разных языках программирования, разработанных разными командами.
+
+Множественные реализации клиентов могут укрепить сеть, снижая её зависимость от единой кодовой базы. Идеальная цель - достичь разнообразия, при котором ни один клиент не доминирует в сети, тем самым устраняя потенциальную единую точку отказа.
+Разнообразие языков программирования также привлекает более широкое сообщество разработчиков и позволяет им создавать интеграции на предпочтительном для них языке.
+
+Узнайте больше о [разнообразии клиентов](/developers/docs/nodes-and-clients/client-diversity/).
+
+Общим для этих клиентских реализаций является то, что все они следуют единой спецификации. Спецификации определяют, как функционирует сеть Ethereum и блокчейн. Все технические детали и спецификации доступны в следующих материалах:
+
+- Изначально [Желтая книга Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf)
+- [Спецификации исполнения](https://github.com/ethereum/execution-specs/)
+- [Спецификации консенсуса](https://github.com/ethereum/consensus-specs)
+- [EIP](https://eips.ethereum.org/), реализованные в различных [обновлениях сети](/ethereum-forks/)
+
+### Отслеживание узлов в сети {#network-overview}
+
+Множество трекеров предлагают просмотр узлов сети Ethereum в реальном времени. Заметим, что из-за децентрализованной природы сетей, эти краулеры могут предоставить только ограниченную картину сети и иногда отображают разные данные.
+
+- [Карта узлов](https://etherscan.io/nodetracker) от Etherscan
+- [Ethernodes](https://ethernodes.org/) от Bitfly
+- [Nodewatch](https://www.nodewatch.io/) от Chainsafe, сканирует узлы консенсуса
+- [Monitoreth](https://monitoreth.io/) от MigaLabs, инструмент для мониторинга распределенных сетей
+- [Еженедельные отчеты о состоянии сети](https://probelab.io) от ProbeLab, использует [Nebula crawler](https://github.com/dennis-tra/nebula) и другие инструменты
## Типы узлов {#node-types}
-Если вы хотите [запустить собственный узел](/developers/docs/nodes-and-clients/run-a-node/), вы должны понимать, что существуют разные типы узлов, которые по-разному обрабатывают данные. Фактически клиенты могут запускать 3 разных типа узлов — легкий, полный и архивный. Существуют также варианты различных стратегий синхронизации, которые позволяют сократить время синхронизации. Синхронизация означает скорость, с которой он может получить самую свежую информацию о состоянии Ethereum.
+Если вы хотите [запустить собственный узел](/developers/docs/nodes-and-clients/run-a-node/), вы должны понимать, что существуют разные типы узлов, которые по-разному потребляют данные. В действительности, через клиенты можно выступить в роли узла трёх видов: облегчённые, полные и архивные. Также есть разные варианты, позволяющие добиться синхронизации быстрее. Синхронизация означает скорость, с которой он может получить самую свежую информацию о состоянии Ethereum.
### Полный узел {#full-node}
-- Хранит полные данные блокчейна.
+Полные узлы делают по-блоковую валидацию блокчейна. Сюда входит и загрузка и верификация тела блока, и данные состояния каждого блока. Существуют различные классы полных узлов — некоторые начинают с генезис-блока и проверяют каждый блок во всей истории блокчейна. Другие начинают свою проверку с более недавнего блока, который они считают действительным (например, «моментальная синхронизация» Geth). Независимо от того, с чего начинается проверка, полные узлы хранят только локальную копию относительно недавних данных (обычно последние 128 блоков), позволяя удалять более старые данные для экономии места на диске. Однако старые данные могут быть восстановлены при необходимости.
+
+- Хранит полные данные блокчейна (хотя они периодически сокращаются, поэтому полный узел не хранит все данные о состоянии, начиная с создания)
- Участвует в проверке блоков, проверяет все блоки и состояния.
-- Все состояния могут быть получены из полного узла.
+- Любые состояния могут быть возобновлены из локального хранилища или отпечатков «snapshots» полного узла.
- Обслуживает сеть и предоставляет данные по запросу.
-### Легкий узел {#light-node}
-
-- Сохраняет цепочку заголовков и запрашивает все остальное.
-- Может проверять достоверность данных относительно корней состояний в заголовках блоков.
-- Полезно для устройств с малой емкостью, таких как встроенные устройства или мобильные телефоны, которые не могут позволить себе хранить гигабайты данных блокчейна.
-
### Архивный узел {#archive-node}
-- Хранит все, что хранится в полном узле, и создает архив исторических состояний. Требуется, если вы хотите запросить что-то вроде баланса аккаунта в блоке № 4 000 000 или просто и надежно [протестировать свой собственный набор транзакций без их майнинга с помощью OpenEthereum](https://openethereum.github.io/JSONRPC-trace-module#trace_callmany).
-- Эти данные представляют собой несколько терабайтов, что делает узлы архива менее привлекательными для обычных пользователей, но может быть полезно для таких сервисов, как обозреватели блоков, поставщики кошельков и аналитики цепочек.
+Архивные узлы — это полные узлы, которые верифицируют каждый блок начиная с генезиса, и никогда не удаляют скачанные данные.
-Синхронизация клиентов в любом режиме, кроме архива, приведет к удалению данных блокчейна. Это означает, что не существует архива всех исторических состояний, но полный узел способен построить их по требованию.
-
-## Зачем мне запускать узел Ethereum? {#why-should-i-run-an-ethereum-node}
+- Хранит все, что хранится в полном узле, и создает архив исторических состояний. Это необходимо, если вы хотите запросить данные, например, баланс аккаунта на блоке #4,000,000, или просто надёжно протестировать собственный набор транзакций без их валидации с помощью трассировки.
+- Эти данные исчисляются в терабайтах, что делает обслуживание архивных узлов менее привлекательным для рядовых пользователей. Но они будут очень полезны проводникам по блокам, сервисам-кошелькам и блокчейн аналитикам.
-Запуск узла позволяет вам конфиденциально и ни на кого не полагаясь использовать Ethereum, поддерживая экосистему.
+Синхронизация клиентов в любом режиме, кроме архива, приведет к удалению данных блокчейна. Это означает, что не существует архива всех исторических состояний, но полный узел способен построить их по требованию.
-### Польза для вас {#benefits-to-you}
+Узнайте больше об [архивных узлах](/developers/docs/nodes-and-clients/archive-nodes).
-Запуск собственного узла позволяет вам использовать Ethereum в действительно конфиденциальной, самодостаточной и не требующей доверяться посторонним манере. Вам не нужно доверять сети, потому что вы можете сами проверить данные своим клиентом. «Не доверяйте, проверяйте» — популярная мантра блокчейна.
+### Легкий узел {#light-node}
-- Ваш узел самостоятельно проверяет все транзакции и блоки на соответствие правилам согласования. Это означает, что вам не нужно полагаться на какие-либо другие узлы в сети или полностью им доверять.
-- Вам не придется передавать свои адреса и балансы на случайные узлы. Все можно проверить с помощью собственного клиента.
-- Ваше децентрализованное приложение может быть более безопасным и конфиденциальным, если вы используете свой собственный узел. [MetaMask](https://metamask.io), [MyEtherWallet](https://myetherwallet.com) и некоторые другие кошельки могут быть легко указаны в вашем собственном локальном узле.
-- Вы можете запрограммировать собственные конечные точки RPC.
-- Вы можете подключиться к своему узлу с помощью **межпроцессного взаимодействия (IPC)** или переписать узел, чтобы загрузить свою программу в виде плагина. Это обеспечивает низкую задержку, необходимую для максимально быстрой замены ваших транзакций (т. е. опережающего выполнения).
+Вместо скачивания каждого блока, облегчённые узлы скачивают только заголовки блоков. Эти заголовки содержат суммированную информацию о содержимом блоков. За любой другой информацией облегчённый узел должен обращаться к полному узлу. Легкий узел может затем самостоятельно проверить данные, полученные из исходного состояния в заголовках блока. Легкие узлы позволяют пользователям участвовать в сети Ethereum без мощного оборудования или высокой пропускной способности, требуемых для запуска полных узлов. В конце концов, легкие узлы могут работать на мобильных телефонах или встроенных устройствах. Легкие узлы не участвуют в консенсусе (т. е. они не могут быть валидаторами), но они могут получать доступ к блокчейну Ethereum с той же функциональностью и гарантиями безопасности, что и полный узел.
-
+Облегчённые клиенты — это зона активной разработки для Ethereum, и мы надеемся вскоре увидеть новые облегчённые клиенты для консенсусного и исполнительного слоёв.
+Также существуют потенциальные маршруты для предоставления данных легкого клиента через [gossip-сеть](https://www.ethportal.net/). Это выгодно, потому что сеть сплетен могла бы поддержать сеть легких узлов, не нуждаясь в полных узлах для обслуживания запросов.
-### Преимущества сети {#network-benefits}
+Ethereum пока не поддерживает большое количество легких узлов, но поддержка легкого узла - это область, которая, как ожидается, будет быстро развиваться в ближайшем будущем. В частности, такие клиенты, как [Nimbus](https://nimbus.team/), [Helios](https://github.com/a16z/helios) и [LodeStar](https://lodestar.chainsafe.io/), в настоящее время активно занимаются легкими узлами.
-Разнообразный набор узлов важен для работоспособности, безопасности и отказоустойчивости Ethereum.
-
-- Они предоставляют доступ к данным блокчейна для легких клиентов, которые от него зависят. При высоких пиках использования должно быть достаточно полных узлов, чтобы облегчить синхронизацию узлов. Легкие узлы не хранят всю цепочку блоков, вместо этого они проверяют данные через [корни состояний в заголовках блоков](/developers/docs/blocks/#block-anatomy). При необходимости они могут запросить у блоков дополнительную информацию.
-- Полные узлы обеспечивают соблюдение правил согласования с доказательством работы, поэтому их нельзя обманом заставить принимать блоки, которые им не соответствуют. Это обеспечивает дополнительную безопасность в сети: если бы все узлы были легкими узлами, не выполняющими полную проверку, майнеры могли бы атаковать сеть и, например, создавать блоки с более высоким вознаграждением.
+## Зачем мне запускать узел Ethereum? {#why-should-i-run-an-ethereum-node}
-Если вы запустите полный узел, от этого выиграет вся сеть Ethereum.
+Обслуживание узла позволяет вам прямо, надёжно и приватно использовать сеть Ethereum, одновременно поддерживая её крепкость и децентрализованность.
-## Запуск собственного узла {#running-your-own-node}
+### Преимущества для вас {#benefits-to-you}
-Заинтересованы в запуске собственного клиента Ethereum?
+Запуск собственного узла позволяет вам использовать Ethereum в конфиденциальной, самодостаточной и не требующей доверяться посторонним манере. Вам не нужно доверять сети, потому что вы можете сами проверить данные своим клиентом. «Не доверяйте, проверяйте» — популярная мантра блокчейна.
-Для ознакомления с введением, удобным для начинающих, навестите нашу страницу [запуска узла](/run-a-node), чтобы узнать больше.
+- Ваш узел самостоятельно проверяет все транзакции и блоки на соответствие правилам согласования. Это означает, что вам не нужно полагаться на какие-либо другие узлы в сети или полностью им доверять.
+- Вы можете использовать кошелек Ethereum с собственной нодой. Использовать децентрализованные приложения более безопасно и конфиденциально, поскольку вам не придется передавать свои адреса и баланс посредникам. Все можно проверить с помощью собственного клиента. [MetaMask](https://metamask.io), [Frame](https://frame.sh/) и [многие другие кошельки](/wallets/find-wallet/) предлагают импорт RPC, что позволяет им использовать ваш узел.
+- Вы можете запускать и самостоятельно размещать другие сервисы, которые зависят от данных из Ethereum. Например, это может быть валидатор Beacon Chain, программное обеспечение, такое как леер 2, инфраструктура, обозреватели блоков, платежные процессоры и т. д.
+- Вы можете предоставлять свои собственные конечные точки [RPC](/developers/docs/apis/json-rpc/). Вы могли бы даже предложить эти конечные точки публично сообществу, чтобы помочь им избежать крупных централизованных провайдеров.
+- Вы можете подключиться к своему узлу с помощью **межпроцессного взаимодействия (IPC)** или переписать узел, чтобы загрузить свою программу в виде плагина. Это обеспечивает низкую задержку, что очень помогает, например, при обработке большого количества данных с использованием библиотек web3 или когда вам нужно как можно быстрее заменить свои транзакции (т. е. опережение).
+- Вы можете напрямую вносить ETH в стейкинг, чтобы защитить сеть и получать вознаграждения. Чтобы начать, ознакомьтесь с [индивидуальным стейкингом](/staking/solo/).
-Если вы более технически подкованный пользователь, узнайте, как [развернуть свой собственный узел](/developers/docs/nodes-and-clients/run-a-node/) с помощью командной строки!
+
-### Проекты {#projects}
+### Преимущества для сети {#network-benefits}
-[**Выберите клиент и следуйте его инструкциям**](#clients)
+Разнообразный набор узлов важен для работоспособности, безопасности и отказоустойчивости Ethereum.
-**ethnode** — **_запуск узла Ethereum (Geth или OpenEthereum) для локальной разработки._**
+- Полные узлы обеспечивают соблюдение правил консенсуса, поэтому их нельзя обманом заставить принимать блоки, которые им не соответствуют. Это обеспечивает дополнительную безопасность в сети, потому что если бы все узлы были легкими узлами, которые не выполняют полную проверку, валидаторы могли бы атаковать сеть.
+- В случае атаки, которая преодолевает криптоэкономическую защиту [доказательства владения](/developers/docs/consensus-mechanisms/pos/#what-is-pos), может быть выполнено социальное восстановление полными узлами, которые выберут следовать честной цепи.
+- Чем больше узлов в сети, тем более разнообразна и надежна сеть — это и есть конечная цель децентрализации, которая обеспечивает устойчивую к цензуре и надежную систему.
+- Полные узлы предоставляют доступ к данным блокчейна для легких клиентов, которые от него зависят. Легкие узлы не хранят всю цепочку блоков, вместо этого они проверяют данные через [корни состояний в заголовках блоков](/developers/docs/blocks/#block-anatomy). При необходимости они могут запросить у полных узлов дополнительную информацию.
-- [GitHub](https://github.com/vrde/ethnode)
+Если вы запускаете полный узел, вся сеть Ethereum выигрывает от этого, даже если вы не запускаете валидатор.
-**DAppNode** — **_графический интерфейс в операционной системе для запуска узлов Web3, включая Ethereum и Beacon Chain, на выделенной машине._**
+## Запуск собственного узла {#running-your-own-node}
-- [dappnode.io](https://dappnode.io)
+Заинтересованы в запуске собственного клиента Ethereum?
-### Ресурсы {#resources}
+Для получения понятного новичкам введения посетите нашу страницу [Запуск узла](/run-a-node), чтобы узнать больше.
-- [Запуск полных узлов Ethereum: полное руководство](https://medium.com/coinmonks/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) — _7 ноября 2019 г., Джастин Леру_
-- [Памятка по настройке узла](https://dev.to/5chdn/ethereum-node-configuration-modes-cheat-sheet-25l8) — _5 января 2019 г., Афри Шёден_
-- [Как установить и запустить узел Geth](https://www.quiknode.io/guides/infrastructure/how-to-install-and-run-a-geth-node) — _4 октября 2020 г., Сахил Сен_
-- [Как установить и запустить узел OpenEthereum (ранее Parity)](https://www.quiknode.io/guides/infrastructure/how-to-run-a-openethereum-ex-parity-client-node) — _22 сентября 2020 г., Сахил Сен_
+Если вы более технически подкованный пользователь, погрузитесь в детали и варианты того, как [запустить свой собственный узел](/developers/docs/nodes-and-clients/run-a-node/).
## Альтернативы {#alternatives}
-Запуск собственного узла может быть трудным, и вам не всегда нужно запускать собственный экземпляр. В этом случае вы можете использовать стороннего поставщика API, например [Infura](https://infura.io), [Alchemy](https://alchemyapi.io) или [QuikNode](https://www.quiknode.io). В качестве альтернативы есть [ArchiveNode](https://archivenode.io/) — это финансируемый сообществом узел Archive, предоставляющий архивные данные блокчейна Ethereum независимым разработчикам, которые в противном случае не могли бы себе этого позволить. Для получения общего представления об использовании этих услуг ознакомьтесь с разделом [узлы как услуга](/developers/docs/nodes-and-clients/nodes-as-a-service/).
+Настройка собственного узла может стоить вам времени и ресурсов, но вам не всегда нужно запускать собственный экземпляр. API Для обзора использования этих сервисов ознакомьтесь со статьей [узлы как услуга](/developers/docs/nodes-and-clients/nodes-as-a-service/).
-Если в вашем сообществе кто-то запускает узел Ethereum с общедоступным API, вы можете направить свои легкие кошельки (например, MetaMask) на узел сообщества [через Custom RPC](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node) и обезопасить себя больше, чем при работе с какой-то случайной третьей стороной.
+Если в вашем сообществе кто-то запускает узел Ethereum с общедоступным API, вы можете направить свои кошельки на узел сообщества через Custom RPC и обезопасить себя больше, чем при работе с какой-то случайной третьей стороной.
С другой стороны, если вы запустите клиент, вы можете поделиться им со своими друзьями, которым он может понадобиться.
-## Клиенты-исполнители (ранее «клиенты Eth1») {#execution-clients}
+## Клиенты-исполнители {#execution-clients}
-Сообщество Ethereum поддерживает несколько клиентов-исполнителей с открытым исходным кодом (ранее известных как «клиенты Eth1« или просто «клиенты Ethereum»), разработанных разными командами с использованием разных языков программирования. Это делает сеть более сильной и разнообразной. Идеальная цель — добиться разнообразия без доминирования клиентов, чтобы уменьшить количество точек отказа.
+Сообщество Ethereum поддерживает несколько клиентов-исполнителей с открытым исходным кодом (ранее известных как «клиенты Eth1« или просто «клиенты Ethereum»), разработанных разными командами с использованием разных языков программирования. Это делает сеть сильнее и более [разнообразной](/developers/docs/nodes-and-clients/client-diversity/). Идеальная цель — добиться разнообразия без доминирования клиентов, чтобы уменьшить количество точек отказа.
-В этой таблице представлены различные клиенты. Все они проходят [клиентское тестирование](https://github.com/ethereum/tests) и активно поддерживаются, чтобы обновляться совместно с обновлениями сети.
+В этой таблице представлены различные клиенты. Все они проходят [тесты клиентов](https://github.com/ethereum/tests) и активно поддерживаются, чтобы оставаться в курсе обновлений сети.
-| Клиент | Язык | Операционные системы | Сети | Стратегии синхронизации | Обрезка мусора |
-| ----------------------------------------------------------------------- | -------- | --------------------- | ----------------------------------------------- | ----------------------- | -------------- |
-| [Geth](https://geth.ethereum.org/) | Перейти | Linux, Windows, macOS | Основная сеть, Görli, Rinkeby, Ropsten | Снимок, полная | Архив, обрезка |
-| [Nethermind](http://nethermind.io/) | C#, .NET | Linux, Windows, macOS | Основная сеть, Görli, Ropsten, Rinkeby и другие | Быстрая, луч, архив | Архив, обрезка |
-| [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux, Windows, macOS | Основная сеть, Rinkeby, Ropsten, Görli и другие | Fast, Full | Архив, обрезка |
-| [Erigon](https://github.com/ledgerwatch/erigon) | Перейти | Linux, Windows, macOS | Основная сеть, Görli, Rinkeby, Ropsten | Полная | Архив, обрезка |
-| [OpenEthereum (устарело)](https://github.com/openethereum/openethereum) | Rust | Linux, Windows, macOS | Основная сеть, Kovan, Ropsten и другие | Warp, Full | Архив, обрезка |
-
-**Обратите внимение, что OpenEthereum [устарел](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd) и больше не поддерживается.** Используйте его с осторожностью и по возможности перейдите на другую реализацию клиента.
+| Клиент | Язык | Операционные системы | Сети | Стратегии синхронизации | Обрезка мусора |
+| -------------------------------------------------------------------------------------------------- | ------------------------ | --------------------- | ------------------------- | ---------------------------------------------------------------------------------- | -------------- |
+| [Geth](https://geth.ethereum.org/) | Go | Linux, Windows, macOS | Mainnet, Sepolia, Holesky | [Snap](#snap-sync), [Full](#full-sync) | Архив, обрезка |
+| [Nethermind](https://www.nethermind.io/) | C#, .NET | Linux, Windows, macOS | Mainnet, Sepolia, Holesky | [Snap](#snap-sync) (без обслуживания), Fast, [Full](#full-sync) | Архив, обрезка |
+| [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux, Windows, macOS | Mainnet, Sepolia, Holesky | [Snap](#snap-sync), [Fast](#fast-sync), [Full](#full-sync) | Архив, обрезка |
+| [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux, Windows, macOS | Mainnet, Sepolia, Holesky | [Full](#full-sync) | Архив, обрезка |
+| [Reth](https://reth.rs/) | Rust | Linux, Windows, macOS | Mainnet, Sepolia, Holesky | [Full](#full-sync) | Архив, обрезка |
+| [EthereumJS](https://github.com/ethereumjs/ethereumjs-monorepo) _(бета-версия)_ | TypeScript | Linux, Windows, macOS | Sepolia, Holesky | [Full](#full-sync) | Урезанный |
Подробнее о поддерживаемых сетях читайте в статье о [сетях Ethereum](/developers/docs/networks/).
-### Преимущества разных реализаций {#advantages-of-different-implementations}
-
У каждого клиента есть уникальные варианты использования и преимущества, поэтому вы должны выбрать один, исходя из своих предпочтений. Разнообразие позволяет сфокусировать реализации на различных функциях и пользовательских аудиториях. Вы можете выбрать клиента на основе функций, поддержки, языка программирования или лицензий.
-#### Go Ethereum {#geth}
+### Besu {#besu}
-Go Ethereum (сокращенно Geth) — одна из оригинальных реализаций протокола Ethereum. В настоящее время это самый распространенный клиент с самой большой пользовательской базой и множеством инструментов для пользователей и разработчиков. Он написан на Go с полностью открытым исходным кодом и под лицензией GNU LGPL v3.
+Hyperledger Besu — это клиент Ethereum корпоративного уровня для общедоступных и разрешенных сетей. Он работает со всеми функциями основной Ethereum, от трассировки до GraphQL, имеет обширный мониторинг и поддерживается ConsenSys, как в открытых каналах сообщества, так и в коммерческих соглашениях об уровне обслуживания для предприятий. Он написан на Java и имеет лицензию Apache 2.0.
-#### OpenEthereum {#openethereum}
+Обширная [документация](https://besu.hyperledger.org/en/stable/) Besu проведет вас через все детали его функций и настроек.
-OpenEthereum — это быстрый, многофункциональный и продвинутый клиент Ethereum на основе интерфейса командной строки. Он создан для обеспечения необходимой инфраструктуры для быстрых и надежных услуг, требующих быстрой синхронизации и максимального времени безотказной работы. Цель OpenEthereum — стать самым быстрым, легким и безопасным клиентом Ethereum. Он предоставляет чистую модульную кодовую базу для:
+### Erigon {#erigon}
-- простой перенастройки;
-- легкой интеграции в услуги или продукты;
-- минимального потребления памяти и хранилища.
+Erigon (в прошлом — Turbo-Geth) представляет собой ответвление Go Ethereum, ориентированное на скорость и эффективность использования дискового пространства. Erigon — это полностью переработанная архитектура реализации Ethereum, написанная на языке Go, но с планируемыми реализациями на других языках. Цель Erigon — обеспечение быстрой, более модульной и более оптимизированной реализации Ethereum. Он может выполнить полную синхронизацию архивного узла, используя менее 2ТВ дискового пространства менее чем за 3 дня.
-OpenEthereum разработан с использованием передового языка программирования Rust и распространяется под лицензией GPLv3.
+### Go Ethereum {#geth}
-**Обратите внимение, что OpenEthereum [устарел](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd) и больше не поддерживается.** Используйте его с осторожностью и по возможности перейдите на другую реализацию клиента.
+Go Ethereum (сокращенно Geth) — одна из оригинальных реализаций протокола Ethereum. В настоящее время это самый распространенный клиент с самой большой пользовательской базой и множеством инструментов для пользователей и разработчиков. Он написан на Go с полностью открытым исходным кодом и под лицензией GNU LGPL v3.
-#### Nethermind {#nethermind}
+Узнайте больше о Geth в его [документации](https://geth.ethereum.org/docs/).
-Nethermind — это реализация Ethereum, созданная с помощью технического стека C# .NET, работающая на всех основных платформах, включая ARM. Он предлагает отличную производительность с:
+### Nethermind {#nethermind}
+
+Nethermind — это реализация Ethereum под лицензией LGPL-3.0, созданная с помощью технического стека C# .NET, работающая на всех основных платформах, включая ARM. Он предлагает отличную производительность с:
- оптимизированной виртуальной машиной;
- доступом к состоянию;
-- сетью и ценными функциями: панели управления Prometheus/Grafana, поддержка ведения корпоративного журнала seq, трассировка JSON RPC и аналитические плагины.
+- сетью и богатым набором функций, таких как панели управления Prometheus/Grafana, поддержка корпоративного логирования seq, трассировка JSON-RPC и аналитические плагины.
-У Nethermind также есть [подробная документация](https://docs.nethermind.io), мощная поддержка разработчиков, онлайн-сообщество и круглосуточная поддержка, доступная для премиум-пользователей.
+Nethermind также имеет [подробную документацию](https://docs.nethermind.io), сильную поддержку разработчиков, онлайн-сообщество и круглосуточную поддержку для премиум-пользователей.
-#### Besu {#besu}
+### Reth {#reth}
-Hyperledger Besu — это клиент Ethereum корпоративного уровня для общедоступных и разрешенных сетей. Он работает со всеми функциями основной Ethereum, от трассировки до GraphQL, имеет обширный мониторинг и поддерживается ConsenSys, как в открытых каналах сообщества, так и в коммерческих соглашениях об уровне обслуживания для предприятий. Он написан на Java и имеет лицензию Apache 2.0.
+Reth (сокращение от Rust Ethereum) — это реализация полного узла Ethereum, ориентированная на удобство использования, высокую модульность, скорость и эффективность. Reth был первоначально создан и развит компанией Paradigm и лицензирован по лицензиям Apache и MIT.
-#### Erigon {#erigon}
+Reth готов к производственному использованию и подходит для применения в критически важных средах, таких как стейкинг или сервисы с высоким временем безотказной работы. Хорошо работает в сценариях, где требуется высокая производительность с большим запасом, например, RPC, MEV, индексация, симуляции и P2P-активность.
-Erigon (в прошлом — Turbo-Geth) представляет собой ответвление Go Ethereum, ориентированное на скорость и эффективность использования дискового пространства. Erigon — это полностью переработанная архитектура реализации Ethereum, написанная на Go, но с планируемыми реализациями на других языках. Цель Erigon — обеспечение быстрой, более модульной и более оптимизированной реализации Ethereum. Он может выполнить полную синхронизацию архивного узла, используя менее 2ТВ дискового пространства менее чем за 3 дня
+Узнайте больше, ознакомившись с [Reth Book](https://reth.rs/) или [репозиторием Reth на GitHub](https://github.com/paradigmxyz/reth?tab=readme-ov-file#reth).
-### Режимы синхронизации {#sync-modes}
+### В разработке {#execution-in-development}
-Чтобы отслеживать и проверять текущие данные в сети, клиент Ethereum должен синхронизироваться с последним ее состоянием. Это делается путем загрузки данных от пиров, криптографической проверки их целостности и создания локальной базы данных блокчейна.
+Эти клиенты все еще находятся на ранних стадиях разработки и пока не рекомендуются для использования в производственной среде.
-Режимы синхронизации с различными решениями представляют разные подходы к этому процессу. Клиенты также различаются по реализации алгоритмов синхронизации. Всегда обращайтесь к официальной документации выбранного клиента для уточнения особенностей реализации.
+#### EthereumJS {#ethereumjs}
-#### Обзор подходов {#overview-of-strategies}
+Клиент исполнения EthereumJS (EthereumJS) написан на TypeScript и состоит из ряда пакетов, включая основные примитивы Ethereum, представленные классами Block, Transaction и Merkle-Patricia Trie, а также основные компоненты клиента, включая реализацию виртуальной машины Ethereum (EVM), класс блокчейна и сетевой стек DevP2P.
-Общий обзор подходов к синхронизации, используемых в клиентах с поддержкой основной сети:
+Узнайте о нем больше, прочитав его [документацию](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master)
-##### Полная синхронизация
+## Клиенты консенсуса {#consensus-clients}
-Полная синхронизация загружает все блоки (включая заголовки, транзакции и квитанции) и генерирует состояние блокчейна постепенно, выполняя каждый блок из начала.
+Существует несколько клиентов консенсуса (ранее известных как клиенты «Eth2»), поддерживающих [обновления консенсуса](/roadmap/beacon-chain/). Они отвечают за всю логику, связанную с консенсусом, включая алгоритм выбора форка, обработку аттестаций и управление вознаграждениями и штрафами [доказательства владения](/developers/docs/consensus-mechanisms/pos).
-- Минимизирует необходимость доверия и обеспечивает максимальную безопасность, проверяя каждую транзакцию.
-- При увеличении количества транзакций обработка всех транзакций может занять от нескольких дней до нескольких недель.
+| Клиент | Язык | Операционные системы | Сети |
+| ------------------------------------------------------------- | ---------- | --------------------- | -------------------------------------------------------- |
+| [Lighthouse](https://lighthouse.sigmaprime.io/) | Rust | Linux, Windows, macOS | Beacon Chain, Holesky, Pyrmont, Sepolia и другие |
+| [Lodestar](https://lodestar.chainsafe.io/) | TypeScript | Linux, Windows, macOS | Beacon Chain, Holesky, Sepolia и другие |
+| [Nimbus](https://nimbus.team/) | Nim | Linux, Windows, macOS | Beacon Chain, Holesky, Sepolia и другие |
+| [Prysm](https://prysm.offchainlabs.com/docs/) | Go | Linux, Windows, macOS | Beacon Chain, Gnosis, Holesky, Pyrmont, Sepolia и другие |
+| [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) | Java | Linux, Windows, macOS | Beacon Chain, Gnosis, Holesky, Sepolia и другие |
+| [Grandine](https://docs.grandine.io/) | Rust | Linux, Windows, macOS | Beacon Chain, Holesky, Sepolia и другие |
-##### Быстрая синхронизация
+### Lighthouse {#lighthouse}
-Быстрая синхронизация загружает все блоки (включая заголовки, транзакции и квитанции), проверяет все заголовки, загружает состояние и сверяет его с заголовками.
+Lighthouse — это реализация клиента консенсуса, написанная на Rust под лицензией Apache-2.0. Он поддерживается Sigma Prime и является стабильным и готовым к работе с момента генезиса Beacon Chain. На него полагаются различные предприятия, стейкинг-пулы и частные лица. Он стремится быть безопасным, производительным и совместимым в широком диапазоне сред, от настольных ПК до сложных автоматизированных развертываний.
-- Полагается на безопасность механизма консенсуса.
-- Синхронизация займет всего несколько часов.
+Документацию можно найти в [Lighthouse Book](https://lighthouse-book.sigmaprime.io/)
-##### Легкая синхронизация
+### Lodestar {#lodestar}
-В легком режиме клиент загружает все заголовки блоков и данные блоков, а некоторые из них проверяются случайным образом. Синхронизируется только конец цепи из доверенной контрольной точки.
+Lodestar — это готовая к работе реализация клиента консенсуса, написанная на Typescript под лицензией LGPL-3.0. Он поддерживается ChainSafe Systems и является новейшим из клиентов консенсуса для соло-стейкеров, разработчиков и исследователей. Lodestar состоит из узла-маяка и клиента-валидатора, основанных на реализациях протоколов Ethereum на JavaScript. Lodestar стремится улучшить удобство использования Ethereum с помощью легких клиентов, расширить доступность для более широкой группы разработчиков и внести дальнейший вклад в разнообразие экосистемы.
-- Получает только последнее состояние, полагаясь на доверие к разработчикам и механизму консенсуса.
-- Клиент будет готов к использованию с текущим состоянием сети через несколько минут.
+Больше информации можно найти на [сайте Lodestar](https://lodestar.chainsafe.io/)
-[Подробнее о легких клиентах](https://www.parity.io/blog/what-is-a-light-client/)
+### Nimbus {#nimbus}
-##### Синхронизация снимка
+Nimbus — это реализация клиента консенсуса, написанная на Nim под лицензией Apache-2.0. Это готовый к работе клиент, используемый соло-стейкерами и стейкинг-пулами. Nimbus разработан для эффективного использования ресурсов, что позволяет легко запускать его как на устройствах с ограниченными ресурсами, так и на корпоративной инфраструктуре, не жертвуя стабильностью или производительностью вознаграждений. Меньшее потребление ресурсов означает, что клиент имеет больший запас прочности, когда сеть находится под нагрузкой.
-Реализовано Geth. Использование динамических снимков, обслуживаемых пирами, позволяет получить все данные о счетах и хранилищах без загрузки промежуточных узлов дерева, а затем восстановить дерево Меркла локально.
+Узнайте больше в [документации Nimbus](https://nimbus.guide/)
-- Самая быстрая стратегия синхронизации, разработанная компанией Geth, в настоящее время используется по умолчанию
-- Экономия дискового пространства и пропускной способности сети без ущерба для безопасности.
+### Prysm {#prysm}
-[Подробнее о снимке](https://github.com/ethereum/devp2p/blob/master/caps/snap.md)
+Prysm — это полнофункциональный клиент консенсуса с открытым исходным кодом, написанный на Go под лицензией GPL-3.0. Он имеет опциональный пользовательский веб-интерфейс и уделяет первостепенное внимание удобству использования, документации и настраиваемости как для домашних стейкеров, так и для институциональных пользователей.
-##### Варп-синхронизация
+Посетите [документацию Prysm](https://prysm.offchainlabs.com/docs/), чтобы узнать больше.
-Реализовано OpenEthereum. Узлы регулярно генерируют критичный для консенсуса снимок состояния, и любой пир может получить эти снимки по сети, обеспечивая быструю синхронизацию из этой точки.
+### Teku {#teku}
-- Самый быстрый и стандартный режим синхронизации OpenEthereum полагается на статические снимки, обслуживаемые пирами.
-- Стратегия похожа на синхронизацию снимков, но без определенных преимуществ в плане безопасности.
+Teku — один из оригинальных клиентов генезиса Beacon Chain. Наряду с обычными целями (безопасность, надежность, стабильность, удобство использования, производительность), Teku специально стремится полностью соответствовать всем различным стандартам клиентов консенсуса.
-[Подробнее о варпе](https://openethereum.github.io/Beginner-Introduction#warping---no-warp)
+Teku предлагает очень гибкие настройки разработки. Узел-маяк и клиент-валидатор могут быть запущены вместе как один процесс, что чрезвычайно удобно для соло-стейкеров, или узлы могут быть запущены отдельно для сложных операций стейкинга. Кроме того, Teku полностью совместим с [Web3Signer](https://github.com/ConsenSys/web3signer/) для обеспечения безопасности ключей подписи и защиты от слешинга.
-##### Синхронизация луча
+Teku написан на Java и имеет лицензию Apache 2.0. Он разработан командой Protocols в ConsenSys, которая также отвечает за Besu и Web3Signer. Узнайте больше в [документации Teku](https://docs.teku.consensys.net/en/latest/).
-Реализовано Nethermind и Trinity. Работает как быстрая синхронизация, но также загружает данные, необходимые для выполнения последних блоков, что позволяет запрашивать цепочку в течение первых нескольких минут после запуска.
+### Grandine {#grandine}
-- Сначала синхронизирует состояние и позволяет запросить RPC за несколько минут.
-- Этот тип все еще находится в разработке и не полностью надежен, фоновая синхронизация замедляется, а ответы RPC могут не срабатывать.
+Grandine — это реализация клиента консенсуса, написанная на Rust под лицензией GPL-3.0. Он поддерживается командой Grandine Core Team и является быстрым, высокопроизводительным и легковесным. Он подходит для широкого круга стейкеров, от соло-стейкеров, работающих на устройствах с низкими ресурсами, таких как Raspberry Pi, до крупных институциональных стейкеров, управляющих десятками тысяч валидаторов.
-[Подробнее о луче](https://medium.com/@jason.carver/intro-to-beam-sync-a0fd168be14a)
+Документацию можно найти в [Grandine Book](https://docs.grandine.io/)
-#### Настройка в клиенте {#client-setup}
+## Режимы синхронизации {#sync-modes}
-Клиенты предлагают широкие возможности конфигурации в соответствии с вашими потребностями. Выберите тот, который подходит вам лучше всего, исходя из уровня безопасности, доступных данных и стоимости. Помимо алгоритма синхронизации, вы также можете настроить «обрезку» различных типов старых данных. Обрезка позволяет удалить устаревшие данные, примером может быть удаление узлов дерева состояний, которые недоступны из новых блоков.
+Чтобы отслеживать и проверять текущие данные в сети, клиент Ethereum должен синхронизироваться с последним ее состоянием. Это делается путем загрузки данных от пиров, криптографической проверки их целостности и создания локальной базы данных блокчейна.
-Обратите внимание на документацию клиента или страницу справки, чтобы узнать, какой режим синхронизации используется по умолчанию. Вы можете определить предпочтительный тип синхронизации при настройке следующим образом.
+Режимы синхронизации с различными решениями представляют разные подходы к этому процессу. Клиенты также различаются по реализации алгоритмов синхронизации. Всегда обращайтесь к официальной документации выбранного клиента для уточнения особенностей реализации.
-**Настройка легкой синхронизации в [GETH](https://geth.ethereum.org/) или [ERIGON](https://github.com/ledgerwatch/erigon)**
+### Режимы синхронизации уровня исполнения {#execution-layer-sync-modes}
-`geth --syncmode "light"`
+Уровень исполнения может работать в разных режимах для различных сценариев использования: от повторного выполнения мирового состояния блокчейна до синхронизации только с верхушкой цепи из доверенной контрольной точки.
-**Настройка полной синхронизации с архивом в [Besu](https://besu.hyperledger.org/)**
+#### Полная синхронизация {#full-sync}
-`besu --sync-mode=FULL`
+Полная синхронизация загружает все блоки (включая заголовки и тела блоков) и постепенно воссоздает состояние блокчейна, выполняя каждый блок с самого начала (генезис-блока).
-Как и любую другую конфигурацию, ее можно определить с помощью флага запуска или в файле конфигурации. Другой пример — [Nethermind](https://docs.nethermind.io/), который предлагает вам выбрать конфигурацию во время первой инициализации и создает файл конфигурации.
+- Минимизирует необходимость доверия и обеспечивает максимальную безопасность, проверяя каждую транзакцию.
+- При увеличении количества транзакций обработка всех транзакций может занять от нескольких дней до нескольких недель.
+
+[Архивные узлы](#archive-node) выполняют полную синхронизацию для создания (и сохранения) полной истории изменений состояния, произведенных каждой транзакцией в каждом блоке.
-## Консенсус-клиенты (ранее — «клиенты Eth2») {#consensus-clients}
+#### Быстрая синхронизация {#fast-sync}
-Существует несколько консенсус-клиентов (ранее известных как «клиенты Eth2»), поддерживающих [обновления консенсуса](/roadmap/beacon-chain/). Они управляют цепочкой Beacon Chain и предоставят механизм консенсуса с доказательством владения клиентам-исполнителям после [слияния](/roadmap/merge/).
+Как и полная синхронизация, быстрая синхронизация загружает все блоки (включая заголовки, транзакции и квитанции). Однако вместо повторной обработки исторических транзакций быстрая синхронизация полагается на квитанции, пока не достигнет недавней верхушки цепи, после чего переключается на импорт и обработку блоков, чтобы стать полным узлом.
-| Клиент | Язык | Операционные системы | Сети |
-| ----------------------------------------------------------- | ---------- | --------------------- | ------------------------------------- |
-| [Teku](https://pegasys.tech/teku) | Java | Linux, Windows, macOS | Beacon Chain, Goerli |
-| [Nimbus](https://nimbus.team/) | Nim | Linux, Windows, macOS | Beacon Chain, Goerli |
-| [Lighthouse](https://lighthouse-book.sigmaprime.io/) | Rust | Linux, Windows, macOS | Beacon Chain, Goerli, Pyrmont |
-| [Lodestar](https://lodestar.chainsafe.io/) | TypeScript | Linux, Windows, macOS | Beacon Chain, Goerli |
-| [Prysm](https://prysm.offchainlabs.com/docs/) | Go | Linux, Windows, macOS | Beacon Chain, Gnosis, Goerli, Pyrmont |
+- Стратегия быстрой синхронизации.
+- Снижает нагрузку на обработку в пользу использования пропускной способности.
-## Аппаратное обеспечение {#hardware}
+#### Моментальная синхронизация {#snap-sync}
-Требования к оборудованию различаются в зависимости от клиента, но обычно не так высоки, поскольку узел просто должен оставаться синхронизированным. Не путайте это с майнингом, который требует гораздо большей вычислительной мощности. Однако время синхронизации и производительность улучшаются с более мощным оборудованием. В зависимости от ваших потребностей и желаний Ethereum можно запускать на вашем компьютере, домашнем сервере, одноплатных компьютерах или в виртуальных частных серверах в облаке.
+Моментальная синхронизация также проверяет цепочку блок за блоком. Однако вместо того, чтобы начинать с генезис-блока, моментальная синхронизация начинается с более свежей «доверенной» контрольной точки, которая, как известно, является частью истинного блокчейна. Узел сохраняет периодические контрольные точки, удаляя данные старше определенного возраста. Эти снимки используются для воссоздания данных о состоянии по мере необходимости, а не для их постоянного хранения.
-Самый простой способ запустить собственный узел — использовать самонастраиваемые блоки, такие как [DAppNode](https://dappnode.io/). Он предоставляет оборудование для запуска клиентов и приложений, которые зависят от них, с простым пользовательским интерфейсом.
+- Самая быстрая стратегия синхронизации, в настоящее время используется по умолчанию в основной сети Ethereum.
+- Экономия дискового пространства и пропускной способности сети без ущерба для безопасности.
-### Требования {#requirements}
+[Подробнее о моментальной синхронизации](https://github.com/ethereum/devp2p/blob/master/caps/snap.md).
-Перед установкой любого клиента убедитесь, что на вашем компьютере достаточно ресурсов для его запуска. Минимальные и рекомендуемые требования можно найти ниже, однако ключевой частью является дисковое пространство. Синхронизация блокчейна Ethereum требует очень больших затрат на ввод-вывод. Лучше всего иметь твердотельный накопитель (SSD). Чтобы запустить клиент Ethereum на жестком диске, вам понадобится как минимум 8 ГБ ОЗУ для использования в качестве кэша.
+#### Легкая синхронизация {#light-sync}
-#### Минимальные требования {#recommended-specifications}
+В легком режиме клиент загружает все заголовки блоков и данные блоков, а некоторые из них проверяются случайным образом. Синхронизируется только конец цепи из доверенной контрольной точки.
-- ЦП с минимум 2 ядрами
-- Минимум 4 ГБ ОЗУ с SSD, 8 ГБ, если у вас жесткий диск
-- Пропускная способность 8 Мбит/с
+- Получает только последнее состояние, полагаясь на доверие к разработчикам и механизму консенсуса.
+- Клиент будет готов к использованию с текущим состоянием сети через несколько минут.
-#### Рекомендуемые характеристики {#recommended-specifications}
+**Примечание:** легкая синхронизация еще не работает с Ethereum на proof-of-stake — новые версии легкой синхронизации должны появиться в ближайшее время!
-- Быстрый процессор с минимум 4 ядрами
-- Минимум 16 ГБ ОЗУ
-- Быстрый SSD с не менее 500 ГБ свободного места
-- Пропускная способность от 25 Мбит/с
+[Подробнее о легких клиентах](/developers/docs/nodes-and-clients/light-clients/)
-Выбранный вами режим синхронизации повлияет на требования к дисковому пространству, но мы оценили объем, который вам потребуется для каждого клиента.
+### Режимы синхронизации уровня консенсуса {#consensus-layer-sync-modes}
-| Клиент | Размер диска (быстрая синхронизация) | Размер диска (полный архив) |
-| ------------ | ------------------------------------ | --------------------------- |
-| Geth | 400ГБ+ | 6TБ+ |
-| OpenEthereum | От 280 ГБ | От 6 TБ |
-| Nethermind | От 200 ГБ | От 5 ТБ |
-| Besu | От 750 ГБ | От 5 ТБ |
-| Erigon | Н/Д | От 1 ТБ |
+#### Оптимистическая синхронизация {#optimistic-sync}
-- Примечание: Erigon не выполняет быструю синхронизацию, но возможна полная обработка (~500 ГБ)
+Оптимистическая синхронизация — это стратегия синхронизации после Слияния, разработанная как опциональная и обратно совместимая, позволяющая узлам исполнения синхронизироваться с помощью установленных методов. Механизм исполнения может _оптимистично_ импортировать блоки-маяки без их полной проверки, найти последнюю верхушку и затем начать синхронизацию цепи с помощью вышеупомянутых методов. Затем, после того как клиент исполнения догонит сеть, он проинформирует клиента консенсуса о валидности транзакций в Beacon Chain.
-Эти диаграммы показывают, что требования к хранилищу постоянно меняются. Для получения самых последних данных по Geth и OpenEthereum смотрите информацию о [полной синхронизации данных](https://etherscan.io/chartsync/chaindefault) и [синхронизации архива](https://etherscan.io/chartsync/chainarchive).
+[Подробнее об оптимистической синхронизации](https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md)
-### Ethereum на одноплатном компьютере {#ethereum-on-a-single-board-computer}
+#### Синхронизация по контрольным точкам {#checkpoint-sync}
-Самый удобный и дешевый способ запустить узел Ethereum — использовать одноплатный компьютер с архитектурой ARM, такой как Raspberry Pi. [Ethereum на ARM](https://twitter.com/EthereumOnARM) предоставляет образы клиентов Geth, OpenEthereum, Nethermind и Besu. Вот простое руководство [как создать и настроить клиент ARM](/developers/tutorials/run-node-raspberry-pi/).
+Синхронизация по контрольным точкам, также известная как синхронизация со слабой субъективностью, создает превосходный пользовательский опыт для синхронизации узла Beacon. Она основана на допущениях о [слабой субъективности](/developers/docs/consensus-mechanisms/pos/weak-subjectivity/), что позволяет синхронизировать Beacon Chain с недавней контрольной точки слабой субъективности вместо генезиса. Синхронизация по контрольным точкам делает начальное время синхронизации значительно быстрее с аналогичными допущениями о доверии, как и при синхронизации с [генезиса](/glossary/#genesis-block).
-Такие небольшие, доступные и эффективные устройства идеально подходят для работы узла дома.
+На практике это означает, что ваш узел подключается к удаленному сервису для загрузки последних финализированных состояний и продолжает проверять данные с этой точки. Третья сторона, предоставляющая данные, является доверенной и должна быть выбрана тщательно.
-## Дополнительные ресурсы {#further-reading}
+Подробнее о [синхронизации по контрольным точкам](https://notes.ethereum.org/@djrtwo/ws-sync-in-practice)
-В Интернете есть много информации о клиентах Ethereum. Вот несколько ресурсов, которые могут оказаться полезными.
+## Дополнительные материалы {#further-reading}
-- [Ethereum 101, часть 2: понимание узлов](https://kauri.io/ethereum-101-part-2-understanding-nodes/48d5098292fd4f11b251d1b1814f0bba/a) — _Уил Барнс, 13 февраля 2019 г._
-- [Запуск полных узлов Ethereum: руководство для сомневающихся](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) — _Джастин Леру, 7 ноября 2019 г._
-- [Анализ требований к оборудованию, чтобы стать полностью проверенным узлом Ethereum](https://medium.com/coinmonks/analyzing-the-hardware-requirements-to-be-an-ethereum-full-validated-node-dc064f167902) — _Альберт Палау, 24 сентября 2018 г._
-- [Запуск узла Hyperledger Besu в основной сети Ethereum: преимущества, требования и настройка](https://pegasys.tech/running-a-hyperledger-besu-node-on-the-ethereum-mainnet-benefits-requirements-and-setup/) — _Фелипе Фараджи, 7 мая 2020 г._
+- [Ethereum 101 – Часть 2 – Понимание узлов](https://kauri.io/ethereum-101-part-2-understanding-nodes/48d5098292fd4f11b251d1b1814f0bba/a) _– Уил Барнс, 13 февраля 2019 г._
+- [Запуск полных узлов Ethereum: руководство для слабо мотивированных](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _– Джастин Леру, 7 ноября 2019 г._
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Блоки](/developers/docs/blocks/)
- [Сети](/developers/docs/networks/)
## Связанные руководства {#related-tutorials}
-- [Превратите свой Raspberry Pi 4 в узел валидатора, просто прошив карту MicroSD: руководство по установке](/developers/tutorials/run-node-raspberry-pi/) _— прошейте свой Raspberry Pi 4, подключите кабель Ethernet, подключите SSD-диск и включите устройство, чтобы превратить Raspberry Pi 4 в полноценный узел Ethereum, работающий на уровне исполнения (Mainnet) и/или на уровне консенсуса (Beacon Chain / validator)._
+- [Превратите свой Raspberry Pi 4 в узел валидатора, просто прошив карту MicroSD — Руководство по установке](/developers/tutorials/run-node-raspberry-pi/) _– Прошейте ваш Raspberry Pi 4, подключите кабель Ethernet, подсоедините SSD-диск и включите устройство, чтобы превратить Raspberry Pi 4 в полноценный узел Ethereum, работающий на уровне исполнения (Mainnet) и/или на уровне консенсуса (Beacon Chain/валидатор)._
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/light-clients/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/light-clients/index.md
new file mode 100644
index 00000000000..4686debd6fe
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/light-clients/index.md
@@ -0,0 +1,61 @@
+---
+title: "Легкие клиенты"
+description: "Введение в легковесные клиенты Ethereum."
+lang: ru
+---
+
+Запуск полного узла это самый надёжный, приватный, децентрализованный и устойчивый к цензуре способ взаимодействия с Ethereum. С полной нодой вы храните свою собственную копию блокчейна, к которой можно обращаться мгновенно для получения прямого доступа к одноранговой сети Ethereum. Однако, запуск полной ноды требует значительное количество памяти, место на жёстком диске и мощный процессор. Это значит, что не каждый может обслуживать свой собственный узел. Есть несколько решений, изложенных в дорожной карте Эфириума, включая клиенты без отслеживания всего состояния, но ещё потребуется несколько лет, прежде чем они будут реализованы. На ближайшее время нужно найти компромисс, чтобы пожертвовать некоторыми преимуществами использования полного узла ради значительного повышения производительности, что позволит узлам работать с очень низкими требованиями к оборудованию. Узлы, которые находят этот компромисс, называются легковесными узлами.
+
+## Что такое легкий клиент {#what-is-a-light-client}
+
+Лёгкий узел — это узел, использующий софт легковесного клиента. Вместо хранения локальных копий данных блокчейна и независимой верификации всех изменений, они запрашивают необходимые данные у отдельных провайдеров. Провайдер может быть в прямой связи с полным узлом, или через централизованный RPC сервер. Затем дата верифицируется лёгким узлом, позволяя ему оставаться синхронизированным с последним блоком в цепочке. Легковесный узел обрабатывает только заголовки блоков, скачивая полное содержимое блоков лишь на некоторое время. Узлы могут быть разными по своей «лёгкости», в зависимости от того, какие комбинации лёгкого и полновесного клиента они используют. Например, самая лёгкая конфигурация — это запуск лёгкого исполнительного клиента и лёгкого консенсусного клиента. Также вероятно, что многие узлы будут обслуживать лёгкие консенсусные клиенты в связке с полными исполнительными клиентами, и наоборот.
+
+## Как работают легковесные клиенты? {#how-do-light-clients-work}
+
+Когда Ethereum начал использовать механизм консенсуса на основе доказательства владения, была представлена новая инфраструктура специально для поддержки легковесных клиентов. Принцип работы заключается в случайном выборе подгруппы из 512 валидаторов каждые 1,1 дня, которые будут действовать как **комитет синхронизации**. Синхронизирующий комитет подписывает заголовки последних блоков. Каждый заголовок блока содержит агрегированную подпись валидаторов из комитета синхронизации и «битовое поле», которое показывает, какие валидаторы подписали, а какие нет. Каждый заголовок также включает список валидаторов, которые, как ожидается, примут участие в подписании следующего блока. Это означает, что легковесный клиент может быстро увидеть, что комитет синхронизации одобрил полученные ими данные, а также проверить подлинность комитета синхронизации, сравнив текущий комитет с тем, который ему было сказано ожидать в предыдущем блоке. Таким образом, легковесный клиент может постоянно обновлять свою информацию о последнем блоке Ethereum, фактически не загружая сам блок, а только заголовок, содержащий итоговую информацию.
+
+На уровне исполнения не существует единой спецификации для легковесного клиента исполнения. Область применения легковесного клиента исполнения может варьироваться от «облегченного режима» полного клиента исполнения, который обладает всеми функциями EVM и сети, как полный узел, но проверяет только заголовки блоков, не загружая связанные с ними данные, или же это может быть более упрощенный клиент, который в значительной степени полагается на пересылку запросов поставщику RPC для взаимодействия с Ethereum.
+
+## Почему важны легковесные клиенты? {#why-are-light-clients-important}
+
+Легковесные клиенты важны, поскольку они позволяют пользователям проверять входящие данные, а не слепо доверять тому, что их поставщик данных корректен и честен, используя при этом лишь малую часть вычислительных ресурсов по сравнению с полным узлом. Получаемые легковесными клиентами данные можно проверить по заголовкам блоков, которые, как известно этим клиентам, подписаны как минимум 2/3 из случайного набора 512 валидаторов Ethereum. Это очень убедительное доказательство того, что данные верны.
+
+Легковесный клиент использует лишь небольшое количество вычислительной мощности, памяти и хранилища, поэтому его можно запускать на мобильном телефоне, встроить в приложение или использовать как часть браузера. Легковесные клиенты — это способ сделать доступ к Ethereum с минимальным уровнем доверия таким же простым, как и при доверии стороннему провайдеру.
+
+Давайте рассмотрим простой пример. Представьте, что вы хотите проверить баланс своего счета. Для этого вам необходимо сделать запрос узлу Ethereum. Этот узел проверит свою локальную копию состояния Ethereum, чтобы найти ваш баланс и сказать его вам. Если у вас нет прямого доступа к узлу, то существуют централизованные операторы, которые предоставляют эти данные как услугу. Вы можете отправить им запрос, они проверят свой узел и отправят вам результат. Проблема в том, что вам приходится доверять поставщику и полагаться на то, что он предоставляет вам правильную информацию. Вы никогда не сможете быть уверены в правильности информации, пока не проверите ее самостоятельно.
+
+Легковесный клиент решает эту проблему. Вы по-прежнему запрашиваете данные у какого-то внешнего поставщика, но когда вы получаете данные обратно, они сопровождаются доказательством, которое ваш легковесный узел может проверить на соответствие информации, полученной из заголовка блока. Это означает, что корректность ваших данных проверяет Ethereum, а не какой-то доверенный оператор.
+
+## Какие новшества дают легкие клиенты? Какие инновации делают возможными легкие клиенты? {#what-innovations-do-light-clients-enable}
+
+Основным преимуществом легковесных клиентов является то, что они позволяют большему количеству людей получать доступ к Ethereum независимо, с незначительными требованиями к оборудованию и минимальной зависимостью от третьих лиц. Это хорошо для пользователей, поскольку они могут проверять свои собственные данные, и это хорошо для сети, поскольку увеличивает количество и разнообразие узлов, проверяющих цепочку.
+
+Возможность запускать узлы Ethereum на устройствах с очень малым объемом памяти и вычислительной мощности — одна из основных инноваций, которую дают легковесные клиенты. Если сегодня узлы Ethereum требуют больших вычислительных ресурсов, то легковесные клиенты могли бы быть встроены в браузеры, работать на мобильных телефонах и, возможно, даже на небольших устройствах, таких как умные часы. Это означает, что кошельки Ethereum со встроенными клиентами могли бы работать и на мобильных телефонах. Это означает, что мобильные кошельки могут быть гораздо более децентрализованными, поскольку им не придется доверять свои данные централизованным поставщикам данных.
+
+Расширением этой концепции является поддержка устройств **Интернета вещей (IoT)**. Легкий клиент можно использовать для быстрого подтверждения владения балансом токенов или NFT со всеми гарантиями безопасности, предоставляемыми комитетами синхронизации, что инициирует определенное действие в сети IoT. Представьте себе [сервис по прокату велосипедов](https://youtu.be/ZHNrAXf3RDE?t=929), который использует приложение со встроенным легким клиентом, чтобы быстро проверить, владеете ли вы NFT этого сервиса, и если да, то разблокировать велосипед, на котором вы сможете уехать!
+
+Ролл-апы Ethereum также выиграют от использования легких клиентов. Одной из серьезных проблем ролл-апов были взломы мостов, которые позволяют переводить средства из основной сети Ethereum в ролл-ап. Одна из уязвимостей — это оракулы, которые ролл-апы используют для обнаружения того, что пользователь внес депозит в мост. Если оракул передает неверные данные, он может обмануть ролл-ап, заставив его думать, что в мост был внесен депозит, и некорректно высвободить средства. Легкий клиент, встроенный в ролл-ап, может использоваться для защиты от скомпрометированных оракулов, поскольку депозит в мост может сопровождаться доказательством, которое ролл-ап сможет проверить перед высвобождением токенов. Эту же концепцию можно применить и к другим межсетевым мостам.
+
+Легковесные клиенты также могут использоваться для того, чтобы улучшить кошельки Ethereum. Вместо того чтобы доверять данным, предоставляемым провайдером RPC, ваш кошелек может напрямую проверять представленные вам данные с помощью встроенного легкого клиента. Это добавило бы безопасности вашему кошельку. Если ваш RPC-провайдер был нечестен и предоставил вам неверные данные, встроенный легковесный клиент мог бы сообщить вам об этом!
+
+## Каково текущее состояние разработки легких клиентов? {#current-state-of-development}
+
+В разработке находится несколько легких клиентов, включая легкие клиенты уровня исполнения, консенсуса и комбинированные легкие клиенты исполнения/консенсуса. Ниже приведены реализации легких клиентов, о которых нам известно на момент написания этой страницы:
+
+- [Lodestar](https://github.com/ChainSafe/lodestar/tree/unstable/packages/light-client): легкий клиент консенсуса на TypeScript
+- [Helios](https://github.com/a16z/helios): комбинированный легкий клиент уровня исполнения и консенсуса на Rust
+- [Geth](https://github.com/ethereum/go-ethereum/tree/master/beacon/light): легкий режим для клиента исполнения (в разработке) на Go
+- [Nimbus](https://nimbus.guide/el-light-client.html): легкий клиент консенсуса на Nim
+
+Насколько нам известно, ни один из них еще не считается готовым к использованию в производственной среде.
+
+Также ведется большая работа по улучшению способов доступа легких клиентов к данным Ethereum. В настоящее время легкие клиенты полагаются на RPC-запросы к полным узлам, используя модель «клиент-сервер», но в будущем данные можно будет запрашивать более децентрализованным способом с помощью выделенной сети, такой как [Portal Network](https://www.ethportal.net/), которая сможет обслуживать легкие клиенты, используя одноранговый протокол gossip.
+
+Другие элементы [дорожной карты](/roadmap/), такие как [деревья Веркла](/roadmap/verkle-trees/) и [бессостоятельность](/roadmap/statelessness/), в конечном итоге обеспечат гарантии безопасности легких клиентов наравне с полными клиентами.
+
+## Дополнительные материалы {#further-reading}
+
+- [Жолт Фелфолди о легких клиентах Geth](https://www.youtube.com/watch?v=EPZeFXau-RE)
+- [Этан Кисслинг о сетевом взаимодействии легких клиентов](https://www.youtube.com/watch?v=85MeiMA4dD8)
+- [Этан Кисслинг о легких клиентах после Слияния](https://www.youtube.com/watch?v=ZHNrAXf3RDE)
+- [Пайпер Мерриам: извилистый путь к функциональным легким клиентам](https://snakecharmers.ethereum.org/the-winding-road-to-functional-light-clients/)
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/node-architecture/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/node-architecture/index.md
new file mode 100644
index 00000000000..ba02338173b
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/node-architecture/index.md
@@ -0,0 +1,59 @@
+---
+title: "Архитектура узла"
+description: "Введение в устройство узлов Ethereum."
+lang: ru
+---
+
+Узел Ethereum состоит из двух клиентов: [клиента исполнения](/developers/docs/nodes-and-clients/#execution-clients) и [клиента консенсуса](/developers/docs/nodes-and-clients/#consensus-clients). Чтобы узел мог предложить новый блок, он также должен запустить [клиент валидатора](#validators).
+
+Когда Ethereum использовал [доказательство работы](/developers/docs/consensus-mechanisms/pow/), для запуска полного узла Ethereum было достаточно клиента исполнения. Однако с момента внедрения [доказательства владения](/developers/docs/consensus-mechanisms/pow/) клиент исполнения должен использоваться вместе с другой программой, называемой [клиентом консенсуса](/developers/docs/nodes-and-clients/#consensus-clients).
+
+На диаграмме ниже показаны отношения между двумя клиентами Ethereum. Два клиента подключены к своим собственным одноранговым сетям (P2P) Отдельные P2P-сети необходимы, поскольку клиенты исполнения распространяют транзакции по своей P2P-сети, что позволяет им управлять своим локальными транзакциями, в то время как клиенты консенсуса обмениваются блоками по своей P2P-сети, что обеспечивает консенсус и рост цепочки.
+
+
+
+_Существует несколько вариантов клиента исполнения, включая Erigon, Nethermind и Besu_.
+
+Чтобы эта двухклиентская структура работала, клиенты консенсуса должны передавать пакеты транзакций клиенту исполнения. Клиент исполнения выполняет транзакции локально, чтобы убедиться, что транзакции не нарушают никаких правил Ethereum и что предлагаемое обновление состояния Ethereum является верным. Когда узел выбран в качестве производителя блока, его экземпляр клиента консенсуса запрашивает пакеты транзакций у клиента исполнения, чтобы включить их в новый блок и выполнить для обновления глобального состояния. Клиент консенсуса управляет клиентом исполнения через локальное RPC-соединение с помощью [Engine API](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md).
+
+## Что делает клиент исполнения? {#execution-client}
+
+Клиент исполнения отвечает за проверку, обработку и распространение транзакций, а также за управление состоянием и поддержку виртуальной машины Ethereum ([EVM](/developers/docs/evm/)). Он **не** несет ответственности за создание блоков, их распространение или обработку логики консенсуса. Это входит в полномочия клиента консенсуса.
+
+Клиент исполнения создает полезные нагрузки исполнения — список транзакций, обновленное дерево состояния и другие данные, связанные с исполнением. Клиенты консенсуса включают полезную нагрузку исполнения в каждый блок. Клиент исполнения также отвечает за повторное исполнение транзакций в новых блоках, чтобы гарантировать их действительность. Выполнение транзакций осуществляется на встроенном компьютере клиента исполнения, известном как [виртуальная машина Ethereum (EVM)](/developers/docs/evm).
+
+Клиент исполнения также предлагает пользовательский интерфейс для Ethereum через [методы RPC](/developers/docs/apis/json-rpc), которые позволяют пользователям запрашивать блокчейн Ethereum, отправлять транзакции и развертывать умные контракты. Вызовы RPC обычно обрабатываются библиотекой, такой как [Web3js](https://docs.web3js.org/), [Web3py](https://web3py.readthedocs.io/en/v5/), или пользовательским интерфейсом, например, браузерным кошельком.
+
+Подводя итог, можно сказать, что клиент исполнения это:
+
+- пользовательский доступ к Ethereum
+- дом для виртуальной машины Ethereum, состояния Ethereum и для транзакций.
+
+## Что делает клиент консенсуса? {#consensus-client}
+
+Клиент консенсуса отвечает за всю логику, позволяющую узлу синхронизироваться с сетью Ethereum. Это включает в себя получение блоков от узлов и запуск алгоритма выбора ответвления, чтобы гарантировать, что узел всегда следует цепочке с наибольшим накоплением аттестаций (взвешенных по эффективным балансам валидатора). Подобно клиенту исполнения, клиенты консенсуса имеют собственную одноранговую сеть, через которую они обмениваются блоками и аттестациями.
+
+Клиент консенсуса не участвует в аттестации или предложении блоков — это делает валидатор, необязательное дополнение к клиенту консенсуса. Клиент консенсуса без валидатора поддерживает связь только с концом цепи, позволяя узлу оставаться синхронизированным. Это позволяет пользователю взаимодействовать с Ethereum, используя свой клиент исполнения, будучи уверенным, что он находится в правильной цепочке.
+
+## Валидаторы {#validators}
+
+Стейкинг и запуск программного обеспечения валидатора дают узлу право быть выбранным для предложения нового блока. Операторы узлов могут добавить валидатора к своим клиентам консенсуса, внеся 32 ETH в депозитный контракт. Клиент валидатора идет в комплекте с клиентом консенсуса и может быть добавлен к узлу в любое время. Валидатор обрабатывает аттестации и предложения блоков. Это также позволяет узлу получать вознаграждения или терять ETH из-за штрафов или урезаний.
+
+[Подробнее о стейкинге](/staking/).
+
+## Сравнение компонентов узла {#node-comparison}
+
+| Клиент исполнения | Клиент консенсуса | Валидатор |
+| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
+| Распространяет транзакции через свою P2P-сеть | Распространяет блоки и аттестации через свою P2P-сеть | Предлагает блоки |
+| Выполняет/повторно выполняет транзакции | Выполняет алгоритм выбора ветвления | Накапливает вознаграждения/штрафы |
+| Проверяет поступающие изменения состояния | Отслеживает начало цепи | Делает аттестации |
+| Управляет деревьями состояния и «квитанций» | Управляет состоянием Beacon (содержит информацию консенсуса и исполнения) | Требует 32 ETH для стейкинга |
+| Создает полезную нагрузку исполнения | Отслеживает накопленную случайность в RANDAO (алгоритм, который обеспечивает проверяемую случайность для выбора валидатора и других операций консенсуса) | Может получить урезание |
+| Предоставляет API JSON-RPC для взаимодействия с Ethereum | Следить за действительностью и финализацией | |
+
+## Дополнительные материалы {#further-reading}
+
+- [Доказательство владения](/developers/docs/consensus-mechanisms/pos)
+- [Предложение блока](/developers/docs/consensus-mechanisms/pos/block-proposal)
+- [Вознаграждения и штрафы валидатора](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties)
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/nodes-as-a-service/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/nodes-as-a-service/index.md
index ed28218587e..96ab3385d1d 100644
--- a/public/content/translations/ru/developers/docs/nodes-and-clients/nodes-as-a-service/index.md
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/nodes-as-a-service/index.md
@@ -1,6 +1,6 @@
---
-title: Узлы как услуга
-description: Обзор услуг узлов на начальном уровне, плюсов и минусов, а также популярных провайдеров.
+title: "Узлы как услуга"
+description: "Обзор услуг узлов на начальном уровне, плюсов и минусов, а также популярных провайдеров."
lang: ru
sidebarDepth: 2
---
@@ -33,7 +33,7 @@ sidebarDepth: 2
Работающие собственные узлы могут быть очень дорогими из за хранения, пропускной способности и ценного инженерного времени. Такие вещи, как увеличение количества узлов при масштабировании, обновлении узлов до последней версии и обеспечении согласованности состояния, могут отвлечь от строительства нужного вам Web3-продукта и лишить возможности использовать на это ресурсы.
-## Каковы преимущества использования службы узлов? {#cons-of-using-a-node-service}
+## Каковы недостатки использования службы узлов? {#cons-of-using-a-node-service}
Используя службу узлов, вы централизируете инфраструктуру вашего продукта. По этой причине проекты, в которых децентрализация имеет первостепенное значение, могут предпочитать узлы с собственным размещением, а не аутсорсинг у третьей стороны.
diff --git a/public/content/translations/ru/developers/docs/nodes-and-clients/run-a-node/index.md b/public/content/translations/ru/developers/docs/nodes-and-clients/run-a-node/index.md
index 9fc34942066..9b172aed60c 100644
--- a/public/content/translations/ru/developers/docs/nodes-and-clients/run-a-node/index.md
+++ b/public/content/translations/ru/developers/docs/nodes-and-clients/run-a-node/index.md
@@ -1,86 +1,205 @@
---
-title: Развертывание собственного узла Ethereum
-description: Общее введение в запуск собственного экземпляра клиента Ethereum.
+title: "Развертывание собственного узла Ethereum"
+description: "Общее введение в запуск собственного экземпляра клиента Ethereum."
lang: ru
sidebarDepth: 2
---
Запуск собственного узла дает вам различные преимущества, открывает новые возможности и помогает поддерживать экосистему. Эта страница поможет вам развернуть собственный узел и принять участие в проверке транзакций Ethereum.
-## Прежде чем начать {#prerequisites}
+Обратите внимание, что после [Слияния](/roadmap/merge) для запуска узла Ethereum требуются два клиента: клиент **уровня исполнения (EL)** и клиент **уровня консенсуса (CL)**. На этой странице вы узнаете, как установить, настроить и подключить эти два клиента для запуска узла Ethereum.
-Вы должны понимать, что такое узел Ethereum и почему вам может понадобиться запустить клиент. Это описано в статье [Узлы и клиенты](/developers/docs/nodes-and-clients/).
+## Предварительные условия {#prerequisites}
-Если тема запуска собственного узла для вас новая или вы ищете менее «технический» способ, посмотрите наш более понятное для новичков [введение в запуск узлов Ethereum](/run-a-node).
+Вы должны понимать, что такое узел Ethereum и почему вам может понадобиться запустить клиент. Это описано в разделе [«Узлы и клиенты»](/developers/docs/nodes-and-clients/).
+
+Если вы новичок в теме запуска узла или ищете менее технический путь, мы рекомендуем сначала ознакомиться с нашим удобным введением в [запуск узла Ethereum](/run-a-node).
## Выбор подхода {#choosing-approach}
-Первый шаг в разворачивании вашего узла — выбор подхода. Вы должны выбрать клиент (программное обеспечение), среду и параметры, с которыми хотите начать. Просмотрите все доступные [клиенты основной сети](/developers/docs/nodes-and-clients/#advantages-of-different-implementations).
+Первый шаг в разворачивании вашего узла — выбор подхода. На основе требований и различных возможностей необходимо выбрать реализацию клиента (как клиента исполнения, так и клиента консенсуса), среду (аппаратную или системную) и параметры для настроек клиента.
+
+Эта страница поможет вам в принятии этих решений и поможет найти наиболее подходящий способ запуска вашего экземпляра Ethereum.
+
+Чтобы выбрать из реализаций клиентов, ознакомьтесь со всеми доступными для основной сети [клиентами исполнения](/developers/docs/nodes-and-clients/#execution-clients), [клиентами консенсуса](/developers/docs/nodes-and-clients/#consensus-clients) и узнайте о [разнообразии клиентов](/developers/docs/nodes-and-clients/client-diversity).
+
+Решите, запускать ли программное обеспечение на собственном [оборудовании или в облаке](#local-vs-cloud), учитывая [требования](#requirements) клиентов.
-### Настройки клиента {#client-settings}
+После подготовки среды установите выбранные клиенты либо с помощью [удобного для начинающих интерфейса](#automatized-setup), либо [вручную](#manual-setup) с помощью терминала с расширенными параметрами.
-Реализации клиента включают различные режимы синхронизации и многие другие параметры. [Режимы синхронизации](/developers/docs/nodes-and-clients/#sync-modes) представляют собой различные методы загрузки и проверки данных блокчейна. Перед запуском узла следует решить, какую сеть и режим синхронизации использовать. Наиболее важно учитывать дисковое пространство и время синхронизации, которые потребуются клиенту.
+Когда узел запущен и синхронизируется, вы готовы [использовать его](#using-the-node), но не забывайте о его [обслуживании](#operating-the-node).
-Все функции и опции можно найти в документации клиента. Различные конфигурации клиента можно установить, запустив клиент с соответствующими флагами. В целях тестирования вы можете запустить клиент в одной из тестовых сетей. [Обзор поддерживаемых сетей](/developers/docs/nodes-and-clients/#execution-clients).
+
### Среда и оборудование {#environment-and-hardware}
#### Локально или в облаке {#local-vs-cloud}
-Клиенты Ethereum могут работать на компьютерах потребительского класса и не требуют специального оборудования (например, в отличие от майнинга). Таким образом, в зависимости от ваших нужд вам доступны различные способы развертывания. Для упрощения давайте рассмотрим запуск узла как на локальной физической машине, так и на облачном сервере.
+Клиенты Ethereum могут работать на компьютерах потребительского класса и не требуют специального оборудования (например, в отличие от майнинга). Таким образом, в зависимости от ваших нужд вам доступны различные способы развертывания узла.
+Для упрощения давайте рассмотрим запуск узла как на локальной физической машине, так и на облачном сервере.
- Облако
- - Провайдеры предлагают большое время безотказной работы сервера и статические общедоступные IP-адреса
+ - Провайдеры предлагают большое время бесперебойной работы сервера и статические публичные IP-адреса
- Получение выделенного или виртуального сервера может быть более удобным, чем создание собственного
- Необходимость доверяться третьей стороне — поставщику серверов
- - Из-за большого размера хранилища для полного узла цена арендованного сервера может быть высока
+ - Из-за большого размера хранилища для полного узла цена аренды сервера может быть высока
- Собственное оборудование
- Более независимый подход, требующий меньшего доверия посторонним
- Однократное вложение
- Возможность покупки преднастроенной машины
- - Необходимость подготовить и обслуживать оборудование, а также устранять возможные проблемы
+ - Необходимость подготовить и обслуживать оборудование, а также устранять возможные проблемы с оборудованием и сетью
+
+Оба варианта имеют различные преимущества, описанные выше. Если вы ищете облачное решение, помимо многих традиционных поставщиков облачных вычислений есть сервисы, ориентированные на развертывание узлов. Ознакомьтесь с [«Узлами как услугой»](/developers/docs/nodes-and-clients/nodes-as-a-service/) для получения дополнительных сведений о размещенных узлах.
+
+#### Оборудование {#hardware}
+
+Однако устойчивая к цензуре децентрализованная сеть не должна полагаться на облачных провайдеров. Вместо этого запуск узла на собственном локальном оборудовании полезнее для экосистемы. [Оценки](https://www.ethernodes.org/networkType/cl/Hosting) показывают, что большая часть узлов работает в облаке, что может стать единой точкой отказа.
+
+Клиенты Ethereum могут работать на вашем компьютере, ноутбуке, сервере или даже на одноплатном компьютере. Хотя запуск клиентов на вашем персональном компьютере вполне возможен, наличие выделенной машины только для вашего узла может значительно повысить его производительность и безопасность, минимизируя при этом воздействие на работоспособность вашего основного компьютера.
-Оба варианта имеют различные преимущества, описанные выше. Если вы ищете облачное решение, помимо многих традиционных поставщиков облачных вычислений есть сервисы, ориентированные на развертывание узлов. Например:
+Использовать собственное оборудование может быть довольно просто. Есть как простые варианты, так и продвинутые настройки для более технически подкованных людей. Так давайте рассмотрим требования и способы запуска клиентов Ethereum на вашей машине.
-- [Узлы](https://www.quiknode.io/)
-- [Blockdaemon](https://blockdaemon.com)
-- [LunaNode](https://www.lunanode.com/)
-- [Alchemy](https://www.alchemy.com/)
+#### Требования {#requirements}
-#### Аппаратное обеспечение {#hardware}
+Требования к оборудованию различаются в зависимости от клиента, но обычно не так высоки, поскольку узел просто должен оставаться синхронизированным. Не путайте это с майнингом, который требует гораздо большей вычислительной мощности. Однако время синхронизации и производительность улучшаются с более мощным оборудованием.
+
+Перед установкой любого клиента убедитесь, что на вашем компьютере достаточно ресурсов для его запуска. Вы найдете минимальные и рекомендуемые требования ниже.
+
+Основным узким местом для вашего оборудования является дисковое пространство. Синхронизация блокчейна Ethereum очень интенсивна по операциям ввода-вывода и требует много места. Лучше всего иметь **твердотельный накопитель (SSD)** с сотнями ГБ свободного места даже после синхронизации.
+
+Размер базы данных и скорость начальной синхронизации зависят от выбранного клиента, его конфигурации и [стратегии синхронизации](/developers/docs/nodes-and-clients/#sync-modes).
+
+Также убедитесь, что ваше интернет-соединение не ограничено [лимитом пропускной способности](https://wikipedia.org/wiki/Data_cap). Рекомендуется использовать безлимитное соединение, так как первоначальная синхронизация и обмен данными с сетью могут превысить ваш лимит.
+
+##### Операционная система
+
+Все клиенты поддерживают основные операционные системы — Linux, MacOS, Windows. Это означает, что вы можете запускать узлы на обычных настольных компьютерах или серверах с операционной системой (ОС), которая подходит вам лучше всего. Убедитесь, что ваша ОС обновлена, чтобы избежать потенциальных проблем и уязвимостей.
-Однако устойчивая к цензуре децентрализованная сеть не должна полагаться на облачных провайдеров. Для экосистемы будет полезнее, если вы запустите свой узел на собственном оборудовании. Самыми простыми вариантами являются преднастроенные машины, такие как:
+##### Минимальные требования
+
+- ЦП с минимум 2 ядрами
+- 8 ГБ ОЗУ
+- 2TB SSD
+- Пропускная способность от 10 Мбит/с
+
+##### Рекомендуемые характеристики
+
+- Быстрый процессор минимум с 4 ядрами
+- Минимум 16 ГБ ОЗУ
+- Быстрый SSD минимум с 2TB памяти
+- Пропускная способность от 25 Мбит/с
+
+Выбранный вами режим синхронизации повлияет на требования к дисковому пространству, но мы оценили объем, который вам потребуется для каждого клиента.
+
+| Клиент | Размер диска (быстрая синхронизация) | Размер диска (полный архив) |
+| ---------- | ------------------------------------------------------- | ---------------------------------------------- |
+| Besu | Минимум 800GB | Минимум 12TB |
+| Erigon | Н/Д | Минимум 2.5TB |
+| Geth | 500GB+ | Минимум 12TB |
+| Nethermind | 500GB+ | Минимум 12TB |
+| Reth | Н/Д | Минимум 2.2TB |
+
+- Примечание: Erigon и Reth не предлагают snap-синхронизацию, но возможно полное сокращение (full pruning) (~2 ТБ для Erigon, ~1.2 ТБ для Reth).
+
+Для клиентов консенсуса требования к пространству также зависят от реализации клиента и включенных функций (например, слэшер валидатора), но в целом рассчитывайте еще на 200 ГБ, необходимых для данных Beacon Chain. С большим количеством валидаторов нагрузка на пропускную способность также возрастает. Вы можете найти [подробную информацию о требованиях к клиентам консенсуса в этом анализе](https://mirror.xyz/0x934e6B4D7eee305F8C9C42b46D6EEA09CcFd5EDc/b69LBy8p5UhcGJqUAmT22dpvdkU-Pulg2inrhoS9Mbc).
+
+#### Решения «подключи и работай» {#plug-and-play}
+
+Самый простой вариант запуска узла на собственном оборудовании — использование готовых устройств (plug-and-play). Предварительно настроенные машины от поставщиков предлагают самый простой опыт: заказать, подключить, запустить. Все предварительно настроено и запускается автоматически с интуитивно понятным руководством и панелью инструментов для мониторинга и управления программным обеспечением.
- [DappNode](https://dappnode.io/)
- [Avado](https://ava.do/)
-Проверьте минимальные и рекомендуемые [требования к дисковому пространству для каждого клиента и режима синхронизации](/developers/docs/nodes-and-clients/#requirements). Обычно для этого достаточно довольно скромной вычислительной мощности. Проблема обычно заключается в скорости диска. Во время начальной синхронизации клиенты Ethereum выполняют множество операций чтения и записи. Поэтому настоятельно рекомендуется использовать SSD. Клиент может даже не иметь [возможности синхронизировать текущее состояние на HDD диске](https://github.com/ethereum/go-ethereum/issues/16796#issuecomment-391649278), застревая в нескольких блоках позади основной сети. Большинство клиентов можно запустить на [одноплатном компьютере с ARM](/developers/docs/nodes-and-clients/#ethereum-on-a-single-board-computer/).
+#### Ethereum на одноплатном компьютере {#ethereum-on-a-single-board-computer}
-Это позволит вам [запустить клиент с SD-карты](/developers/tutorials/run-node-raspberry-pi/). В зависимости от выбранного вами программного и аппаратного обеспечения время первоначальной синхронизации и требования к объему хранилища могут различаться. Обязательно [проверьте время синхронизации и требования к хранилищу](/developers/docs/nodes-and-clients/#recommended-specifications). Также убедитесь, что у вашего интернет-соединения нет [ограничения пропускной способности](https://wikipedia.org/wiki/Data_cap). Рекомендуется использовать безлимитное соединение, так как первоначальная синхронизация и обмен данными с сетью могут превысить ваш лимит.
+Самый удобный и дешевый способ запустить узел Ethereum — использовать одноплатный компьютер с архитектурой ARM, такой как Raspberry Pi. [Ethereum on ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) предоставляет простые в запуске образы нескольких клиентов исполнения и консенсуса для Raspberry Pi и других плат ARM.
-#### Операционная система {#operating-system}
+Такие небольшие, доступные и эффективные устройства идеально подходят для запуска узла в домашних условиях, но не забывайте об их ограниченной производительности.
-Все клиенты поддерживают основные операционные системы — Linux, MacOS, Windows. Это означает, что вы можете запускать узлы на обычных настольных компьютерах или серверах с операционной системой (ОС), которая подходит вам лучше всего. Убедитесь, что ваша ОС обновлена, чтобы избежать потенциальных проблем и уязвимостей.
+## Запуск узла {#spinning-up-node}
+
+Фактическая настройка клиента может быть выполнена либо с помощью автоматизированных средств запуска, либо вручную, настраивая клиентское программное обеспечение напрямую.
+
+Менее продвинутым пользователям рекомендуется использовать программу-установщик — программное обеспечение, которое проведет вас через установку и автоматизирует процесс настройки клиента. Однако если у вас есть некоторый опыт работы с терминалом, следование шагам по ручной настройке не вызовет для вас больших затруднений.
+
+### Настройка с помощью мастера {#automatized-setup}
+
+Множество удобных для пользователя проектов направлены на улучшение опыта настройки клиента. Эти программы-установщики обеспечивают автоматическую установку и настройку клиента, а некоторые даже предлагают графический интерфейс для пошаговой настройки и мониторинга клиентов.
-## Раскрутка узла {#spinning-up-node}
+Ниже приведены несколько проектов, которые помогут вам установить и управлять клиентами всего в несколько кликов:
-### Получение клиентского программного обеспечения {#getting-the-client}
+- [DappNode](https://docs.dappnode.io/docs/user/getting-started/choose-your-path) — DappNode — это не только готовое устройство от поставщика. Программное обеспечение, то есть сам установщик узла и центр управления с множеством функций, можно использовать на любом оборудовании.
+- [EthPillar](https://www.coincashew.com/coins/overview-eth/ethpillar) — самый быстрый и простой способ настроить полный узел. Инструмент для настройки в одну строку и TUI для управления узлом. Бесплатно. Открытый исходный код. Общественные блага для Ethereum от соло-стейкеров. Поддержка ARM64 и AMD64.
+- [eth-docker](https://eth-docker.net/) — автоматизированная настройка с использованием Docker, ориентированная на простой и безопасный стейкинг. Требует базовых знаний терминала и Docker, рекомендуется для более продвинутых пользователей.
+- [Stereum](https://stereum-dev.github.io/ethereum-node-web-docs) — программа-установщик для установки клиентов на удаленный сервер через SSH-соединение с графическим руководством по настройке, центром управления и многими другими функциями.
+- [NiceNode](https://www.nicenode.xyz/) — программа-установщик с простым пользовательским интерфейсом для запуска узла на вашем компьютере. Просто выберите клиенты и запустите их в несколько кликов. Все еще в разработке.
+- [Sedge](https://docs.sedge.nethermind.io/docs/intro) — инструмент настройки узла, который автоматически генерирует конфигурацию Docker с помощью мастера командной строки (CLI). Написан на Go компанией Nethermind.
-Сначала скачайте [клиентское программное обеспечение](/developers/docs/nodes-and-clients/#execution-clients)
+### Ручная настройка клиентов {#manual-setup}
-Вы можете просто скачать исполняемое приложение или установочный пакет, который подходит вашей операционной системе и архитектуре. Всегда проверяйте подписи и контрольные суммы скачанных пакетов. Некоторые клиенты также предлагают репозитории для упрощения установки и обновления. Если хотите, можете сами собрать из исходников. Все клиенты имеют открытый исходный код, поэтому вы можете собрать их из исходного кода с помощью соответствующего компилятора.
+Другой вариант — загрузить, проверить и настроить клиентское программное обеспечение вручную. Даже если некоторые клиенты предлагают графический интерфейс, ручная настройка все равно требует базовых навыков работы с терминалом, но предлагает гораздо большую гибкость.
-Исполняемые файлы для стабильных реализаций клиентов основной сети можно загрузить со страниц их выпусков:
+Как объяснялось ранее, для настройки собственного узла Ethereum потребуется запустить пару клиентов: клиента консенсуса и клиента исполнения. Некоторые клиенты могут включать в себя легкий клиент другого типа и синхронизироваться без необходимости в другом программном обеспечении. Однако для полной, не требующей доверия верификации, требуются обе реализации.
+#### Получение клиентского ПО {#getting-the-client}
+
+Сначала вам необходимо получить предпочитаемое программное обеспечение [клиента исполнения](/developers/docs/nodes-and-clients/#execution-clients) и [клиента консенсуса](/developers/docs/nodes-and-clients/#consensus-clients).
+
+Вы можете просто скачать исполняемое приложение или установочный пакет, который подходит вашей операционной системе и архитектуре. Всегда проверяйте подписи и контрольные суммы скачанных пакетов. Некоторые клиенты также предлагают Docker образы для упрощения установки и обновления. Все клиенты имеют открытый исходный код, поэтому вы также можете собрать их из исходного кода. Это более сложный метод, но в некоторых случаях он может потребоваться.
+
+Инструкции по установке каждого клиента приведены в документации, ссылки на которую содержатся в списках клиентов выше.
+
+Ниже приведены страницы релизов клиентов, где вы можете найти их готовые бинарные файлы или инструкции по установке:
+
+##### Клиенты исполнения
+
+- [Besu](https://github.com/hyperledger/besu/releases)
+- [Erigon](https://github.com/ledgerwatch/erigon/releases)
- [Geth](https://geth.ethereum.org/downloads/)
-- [OpenEthereum](https://github.com/openethereum/openethereum/releases)
- [Nethermind](https://downloads.nethermind.io/)
-- [Besu](https://besu.hyperledger.org/en/stable/)
-- [Erigon](https://github.com/ledgerwatch/erigon)
+- [Reth](https://reth.rs/installation/installation.html)
+
+Также стоит отметить, что разнообразие клиентов является [проблемой на уровне исполнения](/developers/docs/nodes-and-clients/client-diversity/#execution-layer). Читателям рекомендуется рассмотреть возможность запуска клиента исполнения из меньшинства.
+
+##### Клиенты консенсуса
+
+- [Lighthouse](https://github.com/sigp/lighthouse/releases/latest)
+- [Lodestar](https://chainsafe.github.io/lodestar/run/getting-started/installation#build-from-source/) (не предоставляет готовый бинарный файл, только образ Docker или сборку из исходного кода)
+- [Nimbus](https://github.com/status-im/nimbus-eth2/releases/latest)
+- [Prysm](https://github.com/prysmaticlabs/prysm/releases/latest)
+- [Teku](https://github.com/ConsenSys/teku/releases)
+
+[Разнообразие клиентов](/developers/docs/nodes-and-clients/client-diversity/) имеет решающее значение для узлов консенсуса, на которых работают валидаторы. Если большинство валидаторов используют одну и ту же реализацию клиента, безопасность сети находится под угрозой. Поэтому рекомендуется рассмотреть возможность выбора клиента из меньшинства.
+
+[Ознакомьтесь с последними данными об использовании сетевых клиентов](https://clientdiversity.org/) и узнайте больше о [разнообразии клиентов](/developers/docs/nodes-and-clients/client-diversity).
+
+##### Верификация ПО
+
+При загрузке программного обеспечения из Интернета рекомендуется проверять его целостность. Это необязательно, но, особенно если речь идет о таком важном элементе инфраструктуры, как клиент Ethereum, важно знать о потенциальных векторах атак и избегать их. Если вы загрузили готовый бинарный файл, вам нужно доверять ему и рисковать тем, что злоумышленник может подменить исполняемый файл на вредоносный.
+
+Разработчики подписывают выпускаемые бинарные файлы своими PGP-ключами, чтобы вы могли криптографически проверить, что вы запускаете именно то программное обеспечение, которое они создали. Вам просто нужно получить публичные ключи, используемые разработчиками, которые можно найти на страницах релизов клиентов или в документации. После загрузки релиза клиента и его подписи вы можете использовать реализацию PGP, например [GnuPG](https://gnupg.org/download/index.html), чтобы легко их проверить. Ознакомьтесь с руководством по проверке программного обеспечения с открытым исходным кодом с помощью `gpg` на [Linux](https://www.tecmint.com/verify-pgp-signature-downloaded-software/) или [Windows/MacOS](https://freedom.press/training/verifying-open-source-software/).
-**Обратите внимение, что OpenEthereum [устарел](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd) и больше не поддерживается.** Используйте его с осторожностью и по возможности перейдите на другую реализацию клиента.
+Другой формой проверки является проверка того, что Хэш (уникальный криптографический отпечаток) загруженного вами программного обеспечения совпадает с тем, который предоставлен разработчиками. Это даже проще, чем использовать PGP, и некоторые клиенты предлагают только этот вариант. Просто запустите хэш-функцию для загруженного программного обеспечения и сравните результат с тем, что указан на странице релиза. Например:
-### Запуск клиента {#starting-the-client}
+```sh
+sha256sum teku-22.6.1.tar.gz
+
+9b2f8c1f8d4dab0404ce70ea314ff4b3c77e9d27aff9d1e4c1933a5439767dde
+```
+
+#### Настройка клиента {#client-setup}
+
+После установки, загрузки или компиляции клиентского программного обеспечения, вы готовы к его запуску. Это лишь означает, что его нужно запускать с правильной конфигурацией. Клиенты предлагают широкие возможности конфигурации, которые могут включать различные функции.
+
+Начнем с опций, которые могут существенно повлиять на производительность клиента и использование данных. [Режимы синхронизации](/developers/docs/nodes-and-clients/#sync-modes) представляют собой различные методы загрузки и проверки данных блокчейна. Перед запуском узла следует решить, какую сеть и режим синхронизации использовать. Наиболее важно учитывать дисковое пространство и время синхронизации, которые потребуются клиенту. Обратите внимание на документацию клиента или страницу справки, чтобы узнать, какой режим синхронизации используется по умолчанию. Выберите тот, который подходит вам лучше всего, исходя из уровня безопасности, доступных данных и стоимости. Помимо алгоритма синхронизации, вы также можете настроить «обрезку» различных типов старых данных. Сокращение (pruning) позволяет удалять устаревшие данные, то есть удалять узлы дерева состояний, которые недоступны из последних блоков.
+
+Другие базовые параметры конфигурации — это, например, выбор сети (основная сеть или тестовые сети), включение конечной точки HTTP для RPC или WebSockets и т. д. Вы можете найти все функции и параметры в документации клиента. Различные конфигурации клиента можно установить, запустив клиент с соответствующими флагами непосредственно в интерфейсе командной строки (CLI) или в файле конфигурации. Каждый клиент немного отличается; пожалуйста, всегда обращайтесь к его официальной документации или странице справки для получения подробной информации о параметрах конфигурации.
+
+В целях тестирования вы можете запустить клиент в одной из тестовых сетей. [См. обзор поддерживаемых сетей](/developers/docs/nodes-and-clients/#execution-clients).
+
+Примеры запуска клиентов исполнения с базовой конфигурацией можно найти в следующем разделе.
+
+#### Запуск клиента исполнения {#starting-the-execution-client}
Перед запуском клиентского программного обеспечения Ethereum убедитесь что ваша среда готова. Например, убедитесь в следующем:
@@ -90,76 +209,275 @@ sidebarDepth: 2
- В системе установлены правильное время и дата.
- Ваш маршрутизатор и брандмауэр принимают подключения к прослушиваемым портам. По умолчанию клиенты Ethereum используют порт слушателя (TCP) и порт обнаружения (UDP), оба по умолчанию 30303.
-Сначала запустите свой клиент в тестовой сети, чтобы убедиться, что все работает правильно. Необходимо указать все настройки клиента, которые не установлены по умолчанию. Вы можете использовать конфигурационный файл, чтобы определить свой набор настроек. Конкретные настройки можно найти в документации вашего клиента Исполнение клиента запустит его базовые функции и выбранные конечные точки, а затем начнется поиск узлов одноранговой сети. Когда узел найдет одноранговые соединения, клиент начнет синхронизацию. Актуальные данные блокчейна будут доступны, как только клиент закончит синхронизацию до текущего состояния.
+Сначала запустите свой клиент в тестовой сети, чтобы убедиться, что все работает правильно.
+
+Необходимо указать все настройки клиента, которые не установлены по умолчанию. Вы можете использовать конфигурационный файл, чтобы определить свой набор настроек. Набор функций и синтаксис конфигурации каждого клиента различаются. Для получения более подробной информации обратитесь к документации вашего клиента.
+
+Клиенты исполнения и клиенты консенсуса обмениваются данными через аутентифицированную конечную точку, указанную в [Engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine). Чтобы подключиться к клиенту консенсуса, клиент исполнения должен сгенерировать [`jwtsecret`](https://jwt.io/) по известному пути. По соображениям безопасности и стабильности клиенты должны работать на одной машине, и оба клиента должны знать этот путь, так как он используется для аутентификации локального RPC-соединения между ними. Клиент исполнения также должен определить порт прослушивания для аутентифицированных API.
+
+Этот токен генерируется автоматически клиентским программным обеспечением, но в некоторых случаях вам может потребоваться сделать это самостоятельно. Вы можете сгенерировать его с помощью [OpenSSL](https://www.openssl.org/):
+
+```sh
+openssl rand -hex 32 > jwtsecret
+```
+
+#### Запуск клиента исполнения {#running-an-execution-client}
+
+Этот раздел поможет вам запустить клиенты исполнения. Он служит лишь примером базовой конфигурации, которая запустит клиент со следующими настройками:
-### Использование клиента {#using-the-client}
+- Указывает сеть для подключения, в наших примерах это основная сеть
+ - Вместо этого вы можете выбрать [одну из тестовых сетей](/developers/docs/networks/) для предварительного тестирования вашей установки
+- Определяет каталог данных, где будут храниться все данные, включая блокчейн
+ - Обязательно замените путь на реальный, например, указывающий на ваш внешний диск
+- Включает интерфейсы для взаимодействия с клиентом
+ - Включая JSON-RPC и Engine API для связи с клиентом консенсуса
+- Определяет путь к `jwtsecret` для аутентифицированного API
+ - Обязательно замените пример пути на реальный, доступный клиентам, например, `/tmp/jwtsecret`
-Клиенты предоставляют конечные точки RPC API, которые можно использовать для управления клиентом и взаимодействием с сетью Ethereum различными способами:
+Пожалуйста, имейте в виду, что это лишь базовый пример, все остальные настройки будут установлены по умолчанию. Обратите внимание на документацию каждого клиента, чтобы узнать о значениях по умолчанию, настройках и функциях. Для получения дополнительных функций, например для запуска валидаторов, мониторинга и т. д., обратитесь к документации конкретного клиента.
-- Вызывать API вручную через наиболее подходящий протокол (например, через `curl`)
-- Подсоединять предоставленную консоль (например, `geth attach`)
-- Использовать в приложении
+> Обратите внимание, что обратные косые черты `` в примерах используются только для форматирования; флаги конфигурации можно определить в одной строке.
-У разных клиентов различаются реализации конечных точек RPC. Но существует стандарт JSON-RPC, которые можно использовать с любым клиентом. Обзор приведен в [документации JSON-RPC](https://eth.wiki/json-rpc/API). Приложения, которым требуется информация из сети Ethereum, могут использовать этот RPC. Например, популярный кошелек MetaMask позволяет вам [запустить локальный узел и присоединиться к нему](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node).
+##### Запуск Besu
+
+Этот пример запускает Besu в основной сети, сохраняет данные блокчейна в формате по умолчанию в `/data/ethereum`, включает JSON-RPC и Engine RPC для подключения клиента консенсуса. Engine API аутентифицируется с помощью токена `jwtsecret`, и разрешены только вызовы с `localhost`.
+
+```sh
+besu --network=mainnet \
+ --data-path=/data/ethereum \
+ --rpc-http-enabled=true \
+ --engine-rpc-enabled=true \
+ --engine-host-allowlist="*" \
+ --engine-jwt-enabled=true \
+ --engine-jwt-secret=/path/to/jwtsecret
+```
+
+Besu также поставляется с опцией запуска, которая задаст ряд вопросов и сгенерирует файл конфигурации. Запустите интерактивный установщик с помощью:
+
+```sh
+besu --Xlauncher
+```
+
+[Документация Besu](https://besu.hyperledger.org/public-networks/get-started/start-node/) содержит дополнительные параметры и детали конфигурации.
+
+##### Запуск Erigon
+
+Этот пример запускает Erigon в основной сети, сохраняет данные блокчейна в `/data/ethereum`, включает JSON-RPC, определяет, какие пространства имен разрешены, и включает аутентификацию для подключения клиента консенсуса, которая определяется путем к `jwtsecret`.
+
+```sh
+erigon --chain mainnet \
+ --datadir /data/ethereum \
+ --http --http.api=engine,eth,web3,net \
+ --authrpc.jwtsecret=/path/to/jwtsecret
+```
+
+По умолчанию Erigon выполняет полную синхронизацию с жестким диском объемом 8 ГБ, что приведет к более чем 2 ТБ архивных данных. Убедитесь, что `datadir` указывает на диск с достаточным количеством свободного места, или рассмотрите флаг `--prune`, который может обрезать различные типы данных. Чтобы узнать больше, воспользуйтесь командой `--help` в Erigon.
+
+##### Запуск Geth
+
+Этот пример запускает Geth в основной сети, сохраняет данные блокчейна в `/data/ethereum`, включает JSON-RPC и определяет, какие пространства имен разрешены. Он также включает аутентификацию для подключения клиента консенсуса, что требует указания пути к `jwtsecret`, а также опции, определяющей, какие соединения разрешены; в нашем примере — только с `localhost`.
+
+```sh
+geth --mainnet \
+ --datadir "/data/ethereum" \
+ --http --authrpc.addr localhost \
+ --authrpc.vhosts="localhost" \
+ --authrpc.port 8551
+ --authrpc.jwtsecret=/path/to/jwtsecret
+```
+
+Ознакомьтесь с [документацией по всем параметрам конфигурации](https://geth.ethereum.org/docs/fundamentals/command-line-options) и узнайте больше о [запуске Geth с клиентом консенсуса](https://geth.ethereum.org/docs/getting-started/consensus-clients).
+
+##### Запуск Nethermind
+
+Nethermind предлагает различные [варианты установки](https://docs.nethermind.io/get-started/installing-nethermind). Пакет поставляется с различными бинарными файлами, включая установщик с пошаговой настройкой, который поможет вам создать конфигурацию в интерактивном режиме. В качестве альтернативы вы можете найти Runner, который является самим исполняемым файлом, и вы можете просто запустить его с флагами конфигурации. JSON-RPC включен по умолчанию.
+
+```sh
+Nethermind.Runner --config mainnet \
+ --datadir /data/ethereum \
+ --JsonRpc.JwtSecretFile=/path/to/jwtsecret
+```
+
+Документация Nethermind предлагает [полное руководство](https://docs.nethermind.io/get-started/running-node/) по запуску Nethermind с клиентом консенсуса.
+
+Клиент исполнения инициирует свои основные функции, выбранные конечные точки и начнет поиск пиров. Когда узел найдет одноранговые соединения, клиент начнет синхронизацию. Клиент исполнения будет ожидать соединения от клиента консенсуса. Актуальные данные блокчейна будут доступны, как только клиент закончит синхронизацию до текущего состояния.
+
+##### Запуск Reth
+
+Этот пример запускает Reth в основной сети, используя расположение данных по умолчанию. Включает аутентификацию JSON-RPC и Engine RPC для подключения клиента консенсуса, которая определяется путем к `jwtsecret`, при этом разрешены только вызовы с `localhost`.
+
+```sh
+reth node \
+ --authrpc.jwtsecret /path/to/jwtsecret \
+ --authrpc.addr 127.0.0.1 \
+ --authrpc.port 8551
+```
+
+См. [Настройка Reth](https://reth.rs/run/config.html?highlight=data%20directory#configuring-reth), чтобы узнать больше о каталогах данных по умолчанию. [Документация Reth](https://reth.rs/run/mainnet.html) содержит дополнительные опции и детали конфигурации.
+
+#### Запуск клиента консенсуса {#starting-the-consensus-client}
+
+Клиент консенсуса должен быть запущен с правильной конфигурацией порта для установления локального RPC-соединения с клиентом исполнения. Клиенты консенсуса должны быть запущены с открытым портом клиента исполнения в качестве аргумента конфигурации.
+
+Клиенту консенсуса также нужен путь к `jwt-secret` клиента исполнения для аутентификации RPC-соединения между ними. Аналогично приведенным выше примерам исполнения, каждый клиент консенсуса имеет флаг конфигурации, который принимает путь к файлу jwt-токена в качестве аргумента. Он должен совпадать с путем к `jwtsecret`, предоставленным клиенту исполнения.
+
+Если вы планируете запустить валидатор, убедитесь, что добавили флаг конфигурации, указывающий адрес Ethereum получателя комиссии. Именно здесь накапливаются вознаграждения в ETH для вашего валидатора. Каждый клиент консенсуса имеет опцию, например `--suggested-fee-recipient=0xabcd1`, которая принимает адрес Ethereum в качестве аргумента.
+
+При запуске узла Beacon в тестовой сети вы можете значительно сэкономить время синхронизации, используя общедоступную конечную точку для [синхронизации по контрольным точкам](https://notes.ethereum.org/@launchpad/checkpoint-sync).
+
+#### Запуск клиента консенсуса {#running-a-consensus-client}
+
+##### Запуск Lighthouse
+
+Перед запуском Lighthouse узнайте больше о том, как его установить и настроить, в [Lighthouse Book](https://lighthouse-book.sigmaprime.io/installation.html).
+
+```sh
+lighthouse beacon_node \
+ --network mainnet \
+ --datadir /data/ethereum \
+ --http \
+ --execution-endpoint http://127.0.0.1:8551 \
+ --execution-jwt /path/to/jwtsecret
+```
+
+##### Запуск Lodestar
+
+Установите программное обеспечение Lodestar, скомпилировав его или загрузив образ Docker. Узнайте больше в [документации](https://chainsafe.github.io/lodestar/) и в более подробном [руководстве по установке](https://hackmd.io/@philknows/rk5cDvKmK).
+
+```sh
+lodestar beacon \
+ --dataDir="/data/ethereum" \
+ --network=mainnet \
+ --eth1.enabled=true \
+ --execution.urls="http://127.0.0.1:8551" \
+ --jwt-secret="/path/to/jwtsecret"
+```
+
+##### Запуск Nimbus
+
+Nimbus поставляется как с клиентами консенсуса, так и с клиентами исполнения. Его можно запускать на различных устройствах, даже с очень скромной вычислительной мощностью.
+После [установки зависимостей и самого Nimbus](https://nimbus.guide/quick-start.html) вы можете запустить его клиент консенсуса:
+
+```sh
+nimbus_beacon_node \
+ --network=mainnet \
+ --web3-url=http://127.0.0.1:8551 \
+ --rest \
+ --jwt-secret="/path/to/jwtsecret"
+```
+
+##### Запуск Prysm
+
+Prysm поставляется со скриптом, который обеспечивает простую автоматическую установку. Подробности можно найти в [документации Prysm](https://prysm.offchainlabs.com/docs/install-prysm/install-with-script/).
+
+```sh
+./prysm.sh beacon-chain \
+ --mainnet \
+ --datadir /data/ethereum \
+ --execution-endpoint=http://localhost:8551 \
+ --jwt-secret=/path/to/jwtsecret
+```
+
+##### Запуск Teku
+
+```sh
+teku --network mainnet \
+ --data-path "/data/ethereum" \
+ --ee-endpoint http://localhost:8551 \
+ --ee-jwt-secret-file "/path/to/jwtsecret"
+```
+
+Когда клиент консенсуса подключается к клиенту исполнения для чтения депозитного контракта и идентификации валидаторов, он также подключается к другим одноранговым узлам Beacon и начинает синхронизировать слоты консенсуса с самого начала. Как только узел Beacon достигнет текущей эпохи, Beacon API станет доступным для ваших валидаторов. Узнайте больше об [API узла Beacon](https://eth2docs.vercel.app/).
+
+### Добавление валидаторов {#adding-validators}
+
+Клиент консенсуса служит в качестве узла Beacon для подключения валидаторов. Каждый клиент консенсуса имеет собственное программное обеспечение для валидатора, подробно описанное в соответствующей документации.
+
+Запуск собственного валидатора позволяет осуществлять [соло-стейкинг](/staking/solo/), самый эффективный и не требующий доверия метод поддержки сети Ethereum. Однако для этого требуется депозит в размере 32 ETH. Чтобы запустить валидатор на собственном узле с меньшей суммой, вас может заинтересовать децентрализованный пул с операторами узлов без разрешений, такой как [Rocket Pool](https://rocketpool.net/node-operators).
+
+Самый простой способ начать стейкинг и генерацию ключей валидатора — использовать [панель запуска стейкинга в тестовой сети Hoodi](https://hoodi.launchpad.ethereum.org/), которая позволяет протестировать вашу установку, [запустив узлы на Hoodi](https://notes.ethereum.org/@launchpad/hoodi). Когда вы будете готовы к работе в основной сети, вы можете повторить эти шаги, используя [панель запуска стейкинга в основной сети](https://launchpad.ethereum.org/).
+
+Посмотрите [страницу о стейкинге](/staking) для обзора вариантов стейкинга.
+
+### Использование узла {#using-the-node}
+
+Клиенты исполнения предлагают [конечные точки API RPC](/developers/docs/apis/json-rpc/), которые вы можете использовать для отправки транзакций, взаимодействия с умными контрактами или их развертывания в сети Ethereum различными способами:
+
+- Вызывать их вручную с помощью подходящего протокола (например, используя `curl`)
+- Присоединяя предоставленную консоль (например, `geth attach`)
+- Реализуя их в приложениях с помощью библиотек web3, например [web3.py](https://web3py.readthedocs.io/en/stable/overview.html#overview), [ethers](https://github.com/ethers-io/ethers.js/)
+
+У разных клиентов различаются реализации конечных точек RPC. Но существует стандарт JSON-RPC, которые можно использовать с любым клиентом. Для обзора [прочтите документацию по JSON-RPC](/developers/docs/apis/json-rpc/). Приложения, которым требуется информация из сети Ethereum, могут использовать этот RPC. Например, популярный кошелек MetaMask позволяет вам [подключиться к вашей собственной конечной точке RPC](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node), что дает значительные преимущества в плане конфиденциальности и безопасности.
+
+Все клиенты консенсуса предоставляют [Beacon API](https://ethereum.github.io/beacon-APIs), который можно использовать для проверки статуса клиента консенсуса или загрузки блоков и данных консенсуса путем отправки запросов с помощью таких инструментов, как [Curl](https://curl.se). Более подробную информацию об этом можно найти в документации каждого клиента консенсуса.
#### Доступ к RPC {#reaching-rpc}
-Порт JSON-RPC по умолчанию — `8545`, но порты локальных конечных точек можно изменять в конфигурационном файле. По умолчанию интерфейс RPC доступен только с локального хоста компьютера. Чтобы сделать его доступным удаленно, можно сделать его открытым, сменив адрес на `0.0.0.0`. Это сделает ваш узел доступным для локальных и публичных IP-адресов. В большинстве случаев вам также нужно настроить переадресацию портов на маршрутизаторе.
+Порт по умолчанию для JSON-RPC клиента исполнения — `8545`, но вы можете изменить порты локальных конечных точек в конфигурации. По умолчанию интерфейс RPC доступен только с локального хоста компьютера. Чтобы сделать его доступным удаленно, вы можете открыть его для общего доступа, изменив адрес на `0.0.0.0`. Это сделает его доступным через локальную сеть и публичные IP-адреса. В большинстве случаев вам также нужно настроить переадресацию портов на маршрутизаторе.
-Совершать подобные манипуляции нужно с осторожностью, так как это позволит любому в Интернете управлять вашим узлом. Злонамеренные пользователи, имея доступ к вашему узлу, могут навредить системе или украсть ваши активы, если вы используете свой клиент как кошелек.
+Подходите к открытию портов в Интернет с осторожностью, так как это позволит любому в Интернете управлять вашим узлом. Злонамеренные пользователи, имея доступ к вашему узлу, могут навредить системе или украсть ваши активы, если вы используете свой клиент как кошелек.
-Эту проблему можно решить, предотвратив изменение потенциально опасных методов RPC. Например, в `geth` можно задать методы, которые можно будет использовать для модификации, через опцию командной строки: `--http.api web3,eth,txpool`.
+Эту проблему можно решить, предотвратив изменение потенциально опасных методов RPC. Например, с помощью Geth вы можете объявить изменяемые методы с помощью флага: `--http.api web3,eth,txpool`.
-Вы также можете размещать доступ к RPC интерфейсу, указывая службу веб-сервера, например Nginx, на локальный адрес и порт вашего клиента.
+Доступ к интерфейсу RPC можно расширить за счет разработки пограничных API или приложений веб-сервера, таких как Nginx, и их подключения к локальному адресу и порту вашего клиента. Использование промежуточного уровня также может дать разработчикам возможность настроить сертификат для безопасных `https`-соединений с интерфейсом RPC.
-Наиболее конфиденциальный и одновременно простой способ настроить публично доступную конечную точку — развернуть ее как сервис onion [Tor](https://www.torproject.org/). Это позволит вам получать доступ к RPC за пределами вашей локальной сети без статического публичного IP-адреса или открытых портов. Для этого:
+Настройка веб-сервера, прокси-сервера или внешнего Rest API — не единственный способ предоставить доступ к конечной точке RPC вашего узла. Еще один способ настройки общедоступной конечной точки с сохранением конфиденциальности — разместить узел на вашем собственном onion-сервисе [Tor](https://www.torproject.org/). Это позволит вам получать доступ к RPC за пределами вашей локальной сети без статического публичного IP-адреса или открытых портов. Однако использование этой конфигурации может позволить доступ к конечной точке RPC только через сеть Tor, которая поддерживается не всеми приложениями и может привести к проблемам с подключением.
-- Установите `tor`
-- Отредактируйте конфигурационный файл `torrc`, чтобы настроить скрытую службу с адресом и портом вашего RPC клиента
-- Перезапустите службу `tor`
+Для этого вам нужно создать свой собственный [onion-сервис](https://community.torproject.org/onion-services/). Ознакомьтесь с [документацией](https://community.torproject.org/onion-services/setup/) по настройке onion-сервиса, чтобы разместить свой собственный. Вы можете направить его на веб-сервер с прокси на порт RPC или просто напрямую на RPC.
-После перезапуска Tor вы получите имя хоста и ключи скрытой службы в желаемой директории. С этого момента ваш RPC будет доступен в сети Tor по своему имени хоста `.onion`.
+Наконец, один из самых популярных способов предоставления доступа к внутренним сетям — через VPN-соединение. В зависимости от вашего варианта использования и количества пользователей, которым нужен доступ к вашему узлу, безопасное VPN-соединение может быть вариантом. [OpenVPN](https://openvpn.net/) — это полнофункциональный SSL VPN, который реализует безопасное расширение сети уровня 2 или 3 OSI с использованием стандартного протокола SSL/TLS, поддерживает гибкие методы аутентификации клиентов на основе сертификатов, смарт-карт и/или учетных данных имени пользователя/пароля, а также позволяет использовать политики контроля доступа для конкретных пользователей или групп с помощью правил брандмауэра, применяемых к виртуальному интерфейсу VPN.
-### Управлением узлом {#operating-the-node}
+### Эксплуатация узла {#operating-the-node}
Вы должны регулярно проверять свой узел, чтобы убедиться, что он работает правильно. Время от времени может быть необходимо проводить техническое обслуживание.
-#### Поддержание работы узла в сети {#keeping-node-online}
+#### Поддержание узла в рабочем состоянии {#keeping-node-online}
-Ваш узел необязательно должен быть постоянно подключен к сети, но желательно держать его в сети как можно дольше, чтобы поддерживать его синхронизацию с сетью. Вы можете отключить его для перезапуска, но имейте в виду:
+Ваш узел не обязательно должен быть постоянно в сети, но вы должны поддерживать его в сети как можно дольше, чтобы он оставался синхронизированным с сетью. Вы можете выключить его для перезапуска, но имейте в виду, что:
-- Завершение работы может занять несколько минут, если последнее состояние все еще записывается на диск.
-- Принудительное отключение может повредить базу данных.
-- Ваш клиент не будет синхронизироваться с сетью, и при перезапуске потребуется повторная синхронизация.
+- Выключение может занять несколько минут, если последнее состояние все еще записывается на диск.
+- Принудительное выключение может повредить базу данных, что потребует повторной синхронизации всего узла.
+- Ваш клиент не будет синхронизироваться с сетью, и при перезапуске потребуется повторная синхронизация. Хотя узел может начать синхронизацию с того места, где он был в последний раз выключен, процесс может занять время в зависимости от того, как долго он был в автономном режиме.
-_Это не относится к узлам-валидаторам слоя консенсуса._ Выключение вашего узла повлияет на все службы, которые от него зависят. Если вы запускаете узел для _стейкинга_, вы должны минимизировать время простоя, насколько это возможно.
+_Это не относится к узлам-валидаторам уровня консенсуса._ Отключение вашего узла повлияет на все зависимые от него службы. Если вы запускаете узел для целей _стейкинга_, вы должны стараться минимизировать время простоя, насколько это возможно.
-#### Создание клиентской службы {#creating-client-service}
+#### Создание клиентских служб {#creating-client-services}
-Рассмотрим возможность создания службы для автоматической активации клиента при запуске. Например, на серверах Linux хорошим решением будет создание службы, которая выполняет клиент с определенной конфигурацией от имени пользователя с ограниченными правами и перезапускается автоматически.
+Рассмотрите возможность создания службы для автоматического запуска ваших клиентов при запуске. Например, на серверах Linux хорошей практикой будет создание службы, например с `systemd`, которая выполняет клиент с правильной конфигурацией от имени пользователя с ограниченными правами и автоматически перезапускается.
-#### Обновление клиента {#updating-client}
+#### Обновление клиентов {#updating-clients}
-Вам необходимо постоянно обновлять клиентское программное обеспечение последними исправлениями безопасности, функциями и [EIP](/eips/). Перед [хард-форками](/ethereum-forks/) обязательно нужно убедиться, что вы используете правильную версию клиента.
+Вам необходимо поддерживать ваше клиентское программное обеспечение в актуальном состоянии с последними исправлениями безопасности, функциями и [EIP](/eips/). Особенно перед [хард-форками](/ethereum-forks/) убедитесь, что вы используете правильные версии клиента.
+
+> Перед важными обновлениями сети Фонд Ethereum (EF) публикует пост в своем [блоге](https://blog.ethereum.org). Вы можете [подписаться на эти объявления](https://blog.ethereum.org/category/protocol#subscribe), чтобы получать уведомления на почту, когда ваш узел нуждается в обновлении.
+
+Обновление клиентов очень просто. У каждого клиента есть конкретные инструкции в своей документации, но процесс обычно заключается в том, чтобы просто загрузить последнюю версию и перезапустить клиент с новым исполняемым файлом. Клиент должен продолжить работу с того места, на котором он остановился, но с примененными обновлениями.
Каждая реализация клиента имеет человекочитаемую строку версии, используемой в протоколе одноранговой связи, но она также доступна из командной строки. Эта строка версии позволяет пользователям убедиться, что они используют правильную версию, и использовать обозреватели блоков и другие аналитические инструменты, задействованные в количественной оценке распространения определенных клиентов в сети. Более подробную информацию о строках версии можно получить в документации к конкретному клиенту.
#### Запуск дополнительных служб {#running-additional-services}
-Запуск собственного узла дает возможность вашим службам использовать прямой доступ к клиентскому RPC сети Ethereum. Такие службы построены поверх Ethereum, примером чего могут быть [решения слоя 2](/developers/docs/scaling/#layer-2-scaling), [консенсус-клиенты](/developers/docs/nodes-and-clients/#consensus-clients) и другие части инфраструктуры Ethereum.
+Запуск собственного узла дает возможность вашим службам использовать прямой доступ к клиентскому RPC сети Ethereum. Это сервисы, построенные на основе Ethereum, такие как [решения уровня 2](/developers/docs/scaling/#layer-2-scaling), бэкенд для кошельков, обозреватели блоков, инструменты для разработчиков и другая инфраструктура Ethereum.
+
+#### Мониторинг узла {#monitoring-the-node}
-#### Наблюдение за узлом {#monitoring-the-node}
+Чтобы правильно организовать наблюдение за узлом, представьте сбор метрик. Клиенты предоставляют конечные точки с метриками, и вы можете получить сравнительные данные о вашем узле. Используйте такие инструменты, как [InfluxDB](https://www.influxdata.com/get-influxdb/) или [Prometheus](https://prometheus.io/), для создания баз данных, которые вы можете превратить в визуализации и диаграммы в таких программах, как [Grafana](https://grafana.com/). Вы можете использовать это программное обеспечение и другие панели Graphana в различных конфигурациях, чтобы визуализировать свой узел и всю сеть в целом. Например, ознакомьтесь с [руководством по мониторингу Geth](/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/).
-«Чтобы правильно организовать наблюдение за узлом, представьте сбор метрик. Клиенты предоставляют конечные точки с метриками, и вы можете получить сравнительные данные о вашем узле. Используйте инструменты, подобные [InfluxDB](https://www.influxdata.com/get-influxdb/) или [Prometheus](https://prometheus.io/), для создания баз данных, которые вы можете превратить в визуализации и графики через такие инструменты, как [Grafana](https://grafana.com/). Вы можете использовать это программное обеспечение и другие панели Graphana в различных конфигурациях, чтобы визуализировать свой узел и всю сеть в целом. При отслеживании всегда обращайте внимание на производительность вашей системы. Во время первоначальной синхронизации узла клиентская программа может оказывать очень большую нагрузку на процессор и оперативную память. В дополнение к Graphana вы можете использовать инструменты, которая предлагает ваша операционная система, подобные `htop` или `uptime`.
+При отслеживании всегда обращайте внимание на производительность вашей системы. Во время первоначальной синхронизации узла клиентская программа может оказывать очень большую нагрузку на процессор и оперативную память. В дополнение к Grafana вы можете использовать инструменты, которые предлагает ваша ОС, например `htop` или `uptime`.
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [Анализ требований к оборудованию, чтобы стать полностью проверенным узлом Ethereum](https://medium.com/coinmonks/analyzing-the-hardware-requirements-to-be-an-ethereum-full-validated-node-dc064f167902) — _Альберт Палау, 24 сентября 2018 г._
-- [Запуск полных узлов Ethereum: руководство для сомневающихся](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) — _Джастин Леру, 7 ноября 2019 г._
-- [Запуск узла Hyperledger Besu в основной сети Ethereum: преимущества, требования и настройка](https://pegasys.tech/running-a-hyperledger-besu-node-on-the-ethereum-mainnet-benefits-requirements-and-setup/) — _Фелипе Фараджи, 7 мая 2020 г._
-- [Развертывание клиента Nethermind Ethereum со стеком мониторинга](https://medium.com/nethermind-eth/deploying-nethermind-ethereum-client-with-monitoring-stack-55ce1622edbd) _— Nethermind.eth, 8 июля 2020 г._
+- [Руководства по стейкингу Ethereum](https://github.com/SomerEsat/ethereum-staking-guides) – _Сомер Эсат, часто обновляется_
+- [Руководство | Как настроить валидатор для стейкинга Ethereum в основной сети](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet) _– CoinCashew, часто обновляется_
+- [Руководства ETHStaker по запуску валидаторов в тестовых сетях](https://github.com/remyroy/ethstaker#guides) – _ETHStaker, регулярно обновляется_
+- [Пример приложения для запуска узлов блокчейна AWS для узлов Ethereum](https://aws-samples.github.io/aws-blockchain-node-runners/docs/Blueprints/Ethereum) — _AWS, часто обновляется_
+- [Часто задаваемые вопросы о слиянии для операторов узлов](https://notes.ethereum.org/@launchpad/node-faq-merge) — _июль 2022 г._
+- [Анализ требований к оборудованию для полного проверенного узла Ethereum](https://medium.com/coinmonks/analyzing-the-hardware-requirements-to-be-an-ethereum-full-validated-node-dc064f167902) _– Albert Palau, 24 сентября 2018 г._
+- [Запуск полных узлов Ethereum: руководство для слабо мотивированных](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _– Джастин Леру, 7 ноября 2019 г._
+- [Развертывание узла Hyperledger Besu в основной сети Ethereum: преимущества, требования и настройка](https://pegasys.tech/running-a-hyperledger-besu-node-on-the-ethereum-mainnet-benefits-requirements-and-setup/) _– Фелипе Фарагги, 7 мая 2020 г._
+- [Развертывание клиента Nethermind Ethereum со стеком мониторинга](https://medium.com/nethermind-eth/deploying-nethermind-ethereum-client-with-monitoring-stack-55ce1622edbd) _– Nethermind.eth, 8 июля 2020 г._
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Узлы и клиенты](/developers/docs/nodes-and-clients/)
- [Блоки](/developers/docs/blocks/)
diff --git a/public/content/translations/ru/developers/docs/oracles/index.md b/public/content/translations/ru/developers/docs/oracles/index.md
new file mode 100644
index 00000000000..02883330060
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/oracles/index.md
@@ -0,0 +1,433 @@
+---
+title: "Оракулы"
+description: "Оракулы предоставляют смарт-контрактам Ethereum доступ к реальным данным, открывая новые возможности использования и повышая ценность для пользователей."
+lang: ru
+---
+
+Оракулы - это приложения, которые создают потоки данных, делающие внешние источники данных доступными для смарт-контрактов блокчейна. Это необходимо, поскольку смарт-контракты на базе Ethereum, по умолчанию, не могут получить доступ к информации, хранящейся за пределами сети блокчейна.
+
+Возможность выполнения смарт-контрактами операций с использованием данных вне сети повышает полезность и ценность децентрализованных приложений. Например, рынки прогноза на базе блокчейна полагаются на оракулов для предоставления информации о результатах, которую они используют для проверки прогнозов пользователей. Предположим, Алиса делает ставку 20 ETH на того, кого выберут следующим президентом США. Президент. В этом случае децентрализованному приложению рынка предсказаний понадобится оракул для подтверждения результатов выборов и анализа, имеет ли Алиса право на выплату.
+
+## Предварительные условия {#prerequisites}
+
+Эта страница предполагает, что читатель знаком с основами Ethereum, включая [узлы](/developers/docs/nodes-and-clients/), [механизмы консенсуса](/developers/docs/consensus-mechanisms/) и [EVM](/developers/docs/evm/). Вы также должны хорошо разбираться в [смарт-контрактах](/developers/docs/smart-contracts/) и [анатомии смарт-контрактов](/developers/docs/smart-contracts/anatomy/), особенно в [событиях](/glossary/#events).
+
+## Что такое блокчейн-оракул? {#what-is-a-blockchain-oracle}
+
+Оракулы — это приложения, которые получают, проверяют и передают внешнюю информацию (т. е. информацию, хранящуюся оффчейн) умным контрактам, работающим на блокчейне. Помимо «извлечения» данных из блокчейна и их трансляции в Ethereum, оракулы также могут «передавать» информацию из блокчейна во внешние системы, например, разблокировать умный замок, как только пользователь отправляет комиссию через транзакцию Ethereum.
+
+Без оракула смарт-контракт будет ограничиваться исключительно данными в цепочке.
+
+Оракулы различаются в зависимости от источника данных (один или несколько источников), моделей доверия (централизованные или децентрализованные) и архитектуры системы (немедленное чтение, публикация-подписка и запрос-ответ). Оракулы также различаются в зависимости от того, извлекают ли они внешние данные для использования в контрактах на цепочке (входные оракулы), отправляют ли информацию из блокчейна в приложения на цепочке (выходные оракулы) или выполняют вычислительные задачи на цепочке (вычислительные оракулы).
+
+## Зачем смарт-контрактам нужны оракулы? {#why-do-smart-contracts-need-oracles}
+
+Многие разработчики рассматривают смарт-контракты как код, работающий по определенным адресам в блокчейне. Однако более [общее представление об умных контрактах](/smart-contracts/) заключается в том, что это самоисполняющиеся программы, способные обеспечивать соблюдение соглашений между сторонами при выполнении определенных условий, — отсюда и термин «умные контракты».
+
+Использовать смарт-контракты для обеспечения соблюдения соглашений между людьми непросто, учитывая предопределенность Ethereum. [Детерминированная система](https://en.wikipedia.org/wiki/Deterministic_algorithm) — это система, которая всегда выдает одинаковые результаты при заданном начальном состоянии и определенных входных данных, что означает отсутствие случайности или вариативности в процессе вычисления выходных данных на основе входных.
+
+Для достижения детерминированного выполнения блокчейны ограничивают узлы достижением консенсуса по простым двоичным (истина/ложь) вопросам, используя _только_ данные, хранящиеся в самом блокчейне. Примеры таких вопросов:
+
+- «Подписал ли владелец счета (идентифицированный по открытому ключу) эту транзакцию с помощью парного закрытого ключа?»
+- "Достаточно ли средств на этом счёте для оплаты комиссии за операцию?"
+- «Действительна ли эта транзакция в контексте данного смарт-контракта?» и т. д.
+
+Если бы блокчейны получали информацию из внешних источников (т. е. из реального мира), детерминизма было бы невозможно достичь, что не позволило бы узлам договориться о достоверности изменений в состоянии блокчейна. Возьмем в пример смарт-контракт, который выполняет транзакцию на основе текущего обменного курса ETH-USD, полученного из традиционного ценового API. Эта цифра, скорее всего, будет часто меняться (не говоря уже о том, что API может устареть или быть взломан), а это означает, что узлы, выполняющие один и тот же код контракта, будут с разным результатам.
+
+Для общественного блокчейна, такого как Ethereum, с тысячами узлов по всему миру, обрабатывающих транзакции, предопределенность имеет решающее значение. В отсутствие центрального органа, выступающего в качестве источника истины, узлам необходимы механизмы для достижения одного и того же состояния после применения одних и тех же транзакций. Случай, когда узел A выполняет код смарт-контракта и получает в результате «3», а узел B получает «7» после выполнения той же транзакции, приведет к нарушению консенсуса и сведет на нет ценность Ethereum как децентрализованной вычислительной платформы.
+
+Этот сценарий также подчеркивает проблему проектирования блокчейнов для извлечения информации из внешних источников. Оракулы решают эту проблему, извлекая информацию из источников вне сети и сохраняя ее в блокчейне для использования смарт-контрактами. Поскольку информация, хранящаяся в цепочке, не может быть изменена и является общедоступной, узлы Ethereum могут безопасно использовать импортированные офчейн-данные Oracle для вычисления изменений состояния, не нарушая консенсус.
+
+Для этого оракул обычно состоит из смарт-контракта, работающего в блокчейне, и некоторых оффчейн-компонентов. Ончейн-контракт получает запросы на данные от других смарт-контрактов, которые он передает оффчейн-компоненту (называемому узлом оракула). Данный узел оракула может запрашивать источники данных (например, используя интерфейсы прикладного программирования (API)) и отправлять транзакции для сохранения запрошенных данных в хранилище смарт-контракта.
+
+Блокчейн-оракул устраняет информационный разрыв между блокчейном и внешней средой, создавая «гибридные смарт-контракты». Гибридный смарт-контракт - это контракт, функционирующий на основе комбинации кода ончейн-контракта и офчейн-инфраструктуры. Децентрализованные рынки прогнозов являются прекрасным примером гибридных смарт-контрактов. Другими примерами могут служить смарт-контракты по страхованию урожая. Выплата производится, когда набор оракулов подтверждает, что определенные погодные явления повлияли на урожай.
+
+## В чем проблема оракула? {#the-oracle-problem}
+
+Оракулы решают важную проблему, но также создают некоторые сложности, например:
+
+- Как мы можем проверить, что введенная информация была извлечена из правильного источника и не была подделана?
+
+- Какое гарантирование того, что эти данные всегда доступны и регулярно обновляются?
+
+Так называемая «проблема оракула» демонстрирует проблемы, возникающие при использовании оракулов блокчейна для отправки входных данных в смарт-контракты. Для корректного выполнения смарт-контракта данные оракула должны быть верными. Необходимость «доверять» операторам оракула в предоставлении точной информации подрывает «не требующую доверия» сущность смарт-контрактов.
+
+Разные оракулы предлагают разные решения их проблем, которые мы рассмотрим позже. Оракулы обычно оцениваются по тому, насколько хорошо они справляются со следующими задачами:
+
+1. **Корректность**: оракул не должен приводить к тому, что умные контракты будут инициировать изменения состояния на основе недействительных оффчейн-данных. Оракул должен гарантировать _подлинность_ и _целостность_ данных. Подлинность означает, что данные были получены из правильного источника, а целостность означает, что данные остались нетронутыми (т. е. не были изменены) до отправки в ончейн.
+
+2. **Доступность**: оракул не должен задерживать или мешать умным контрактам выполнять действия и инициировать изменения состояния. Это означает, что данные от оракула должны быть _доступны по запросу_ без перебоев.
+
+3. **Совместимость стимулов**: оракул должен стимулировать поставщиков оффчейн-данных предоставлять правильную информацию умным контрактам. Совместимость стимулов включает в себя _атрибутируемость_ и _подотчетность_. Атрибутируемость позволяет связать часть внешней информации с ее поставщиком, в то время как подотчетность привязывает поставщиков данных к информации, которую они предоставляют, чтобы их можно было вознаграждать или наказывать в зависимости от качества предоставленной информации.
+
+## Как работает сервис блокчейн-оракулов? {#how-does-a-blockchain-oracle-service-work}
+
+### Пользователи {#users}
+
+Пользователи — это сущности (т. е. умные контракты), которым для выполнения определенных действий требуется информация, внешняя по отношению к блокчейну. Базовый рабочий процесс службы оракула начинается с отправки пользователем запроса данных контракту оракула. Запросы данных обычно отвечают на некоторые или все из следующих вопросов:
+
+1. К каким источникам могут обращаться оффчейн-узлы за запрошенной информацией?
+
+2. Как репортеры обрабатывают информацию из источников данных и извлекают полезные данные?
+
+3. Сколько узлов оракула может участвовать в получении данных?
+
+4. Как следует управлять расхождениями в отчетах оракулов?
+
+5. Какой метод следует использовать для фильтрации представленных данных и агрегирования отчетов в единое значение?
+
+### Контракт оракула {#oracle-contract}
+
+Контракт оракула — это ончейн-компонент службы оракула. Он прослушивает запросы данных от других контрактов, ретранслирует запросы данных узлам оракула и передает возвращенные данные клиентским контрактам. Этот контракт также может выполнять некоторые вычисления над возвращенными точками данных для получения совокупного значения для отправки запрашивающему контракту.
+
+Контракт оракула предоставляет некоторые функции, которые клиентские контракты вызывают при выполнении запроса данных. При получении нового запроса умный контракт сгенерирует [событие журнала](/developers/docs/smart-contracts/anatomy/#events-and-logs) с подробностями запроса данных. Это уведомляет оффчейн-узлы, подписанные на журнал (обычно с помощью команды JSON-RPC `eth_subscribe`), которые приступают к извлечению данных, определенных в событии журнала.
+
+Ниже приведен [пример контракта оракула](https://medium.com/@pedrodc/implementing-a-blockchain-oracle-on-ethereum-cedc7e26b49e), написанный Педро Костой. Это простой сервис оракула, который может запрашивать оффчейн-API по запросу других умных контрактов и сохранять запрошенную информацию в блокчейне:
+
+```solidity
+pragma solidity >=0.4.21 <0.6.0;
+
+contract Oracle {
+ Request[] requests; //список запросов, сделанных контракту
+ uint currentId = 0; //увеличивающийся идентификатор запроса
+ uint minQuorum = 2; //минимальное количество ответов, которые необходимо получить до объявления окончательного результата
+ uint totalOracleCount = 3; // Жестко заданное количество оракулов
+
+ // определяет общий запрос к API
+ struct Request {
+ uint id; //id запроса
+ string urlToQuery; //URL-адрес API
+ string attributeToFetch; //атрибут json (ключ), который нужно получить в ответе
+ string agreedValue; //значение от ключа
+ mapping(uint => string) answers; //ответы, предоставленные оракулами
+ mapping(address => uint) quorum; //оракулы, которые будут запрашивать ответ (1 = оракул не голосовал, 2 = оракул проголосовал)
+ }
+
+ //событие, которое запускает оракула за пределами блокчейна
+ event NewRequest (
+ uint id,
+ string urlToQuery,
+ string attributeToFetch
+ );
+
+ //срабатывает при достижении консенсуса по окончательному результату
+ event UpdatedRequest (
+ uint id,
+ string urlToQuery,
+ string attributeToFetch,
+ string agreedValue
+ );
+
+ function createRequest (
+ string memory _urlToQuery,
+ string memory _attributeToFetch
+ )
+ public
+ {
+ uint length = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));
+ Request storage r = requests[length-1];
+
+ // Жестко заданные адреса оракулов
+ r.quorum[address(0x6c2339b46F41a06f09CA0051ddAD54D1e582bA77)] = 1;
+ r.quorum[address(0xb5346CF224c02186606e5f89EACC21eC25398077)] = 1;
+ r.quorum[address(0xa2997F1CA363D11a0a35bB1Ac0Ff7849bc13e914)] = 1;
+
+ // запустить событие, которое будет обнаружено оракулом за пределами блокчейна
+ emit NewRequest (
+ currentId,
+ _urlToQuery,
+ _attributeToFetch
+ );
+
+ // увеличить id запроса
+ currentId++;
+ }
+
+ //вызывается оракулом для записи своего ответа
+ function updateRequest (
+ uint _id,
+ string memory _valueRetrieved
+ ) public {
+
+ Request storage currRequest = requests[_id];
+
+ //проверить, находится ли оракул в списке доверенных оракулов
+ //и если оракул еще не голосовал
+ if(currRequest.quorum[address(msg.sender)] == 1){
+
+ //отметка о том, что этот адрес проголосовал
+ currRequest.quorum[msg.sender] = 2;
+
+ //перебирать "массив" ответов, пока позиция не освободится, и сохранить полученное значение
+ uint tmpI = 0;
+ bool found = false;
+ while(!found) {
+ //найти первый пустой слот
+ if(bytes(currRequest.answers[tmpI]).length == 0){
+ found = true;
+ currRequest.answers[tmpI] = _valueRetrieved;
+ }
+ tmpI++;
+ }
+
+ uint currentQuorum = 0;
+
+ //перебрать список оракулов и проверить, достаточно ли оракулов (минимальный кворум)
+ //проголосовали за тот же ответ, что и текущий
+ for(uint i = 0; i < totalOracleCount; i++){
+ bytes memory a = bytes(currRequest.answers[i]);
+ bytes memory b = bytes(_valueRetrieved);
+
+ if(keccak256(a) == keccak256(b)){
+ currentQuorum++;
+ if(currentQuorum >= minQuorum){
+ currRequest.agreedValue = _valueRetrieved;
+ emit UpdatedRequest (
+ currRequest.id,
+ currRequest.urlToQuery,
+ currRequest.attributeToFetch,
+ currRequest.agreedValue
+ );
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+### Узлы оракулов {#oracle-nodes}
+
+Узел оракула — это оффчейн-компонент сервиса оракулов. Он извлекает информацию из внешних источников, таких как API, размещенные на сторонних серверах, и помещает ее в ончейн для использования умными контрактами. Узлы оракулов прослушивают события от ончейн-контракта оракула и приступают к выполнению задачи, описанной в журнале.
+
+Распространенной задачей для узлов оракула является отправка запроса [HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp) в службу API, анализ ответа для извлечения соответствующих данных, форматирование в читаемый для блокчейна вид и отправка в ончейн путем включения в транзакцию к контракту оракула. От узла оракула также может потребоваться подтвердить достоверность и целостность предоставленной информации с помощью «доказательств подлинности», которые мы рассмотрим позже.
+
+Вычислительные оракулы также полагаются на оффчейн-узлы для выполнения вычислительных задач, которые было бы непрактично выполнять в ончейне, учитывая стоимость газа и ограничения на размер блока. Например, узлу оракула может быть поручено сгенерировать проверяемое случайное число (например, для игр на основе блокчейна).
+
+## Шаблоны проектирования оракулов {#oracle-design-patterns}
+
+Оракулы бывают разных типов, включая _немедленное чтение_, _публикация-подписка_ и _запрос-ответ_, причем последние два являются наиболее популярными среди умных контрактов Ethereum. Здесь мы кратко опишем модели «публикация-подписка» и «запрос-ответ».
+
+### Оракулы по модели «публикация-подписка» {#publish-subscribe-oracles}
+
+Этот тип оракула предоставляет «поток данных», который другие контракты могут регулярно считывать для получения информации. В этом случае ожидается, что данные будут часто меняться, поэтому клиентские контракты должны отслеживать обновления данных в хранилище оракула. Примером может служить оракул, который предоставляет пользователям последнюю информацию о цене ETH-USD.
+
+### Оракулы по модели «запрос-ответ» {#request-response-oracles}
+
+Схема «запрос-ответ» позволяет клиентскому контракту запрашивать произвольные данные, отличные от тех, которые предоставляет оракул по модели «публикация-подписка». Оракулы по модели «запрос-ответ» идеальны, когда набор данных слишком велик для хранения в хранилище умного контракта и/или пользователям в любой момент времени потребуется лишь небольшая часть данных.
+
+Хотя оракулы «запрос-ответ» сложнее, чем модели «публикация-подписка», по сути они представляют собой то, что мы описали в предыдущем разделе. У оракула будет ончейн-компонент, который получает запрос данных и передает его на обработку оффчейн-узлу.
+
+Пользователи, инициирующие запросы данных, должны покрывать расходы на получение информации из оффчейн-источника. Клиентский контракт также должен предоставить средства для покрытия расходов на газ, понесенных контрактом оракула при возврате ответа через функцию обратного вызова, указанную в запросе.
+
+## Централизованные и децентрализованные оракулы {#types-of-oracles}
+
+### Централизованные оракулы {#centralized-oracles}
+
+Централизованный оракул контролируется одной организацией, ответственной за агрегирование оффчейн-информации и обновление данных контракта оракула в соответствии с запросом. Централизованные оракулы эффективны, поскольку они полагаются на единый источник истины. Они могут лучше работать в тех случаях, когда проприетарные наборы данных публикуются непосредственно владельцем с общепринятой подписью. Однако у них есть и недостатки:
+
+#### Низкие гарантии корректности {#low-correctness-guarantees}
+
+С централизованными оракулами нет способа подтвердить, верна ли предоставленная информация. Даже «авторитетные» поставщики могут стать мошенниками или быть взломаны. Если оракул будет скомпрометирован, умные контракты будут выполняться на основе неверных данных.
+
+#### Низкая доступность {#poor-availability}
+
+Централизованные оракулы не гарантируют постоянную доступность оффчейн-данных для других умных контрактов. Если поставщик решит отключить услугу или хакер захватит оффчейн-компонент оракула, ваш умный контракт подвергнется риску атаки типа «отказ в обслуживании» (DoS).
+
+#### Плохая совместимость стимулов {#poor-incentive-compatibility}
+
+Централизованные оракулы часто имеют плохо продуманные или несуществующие стимулы для поставщика данных отправлять точную/неизмененную информацию. Оплата оракулу за корректность не гарантирует честности. Эта проблема усугубляется по мере увеличения объема ценностей, контролируемых умными контрактами.
+
+### Децентрализованные оракулы {#decentralized-oracles}
+
+Децентрализованные оракулы предназначены для преодоления ограничений централизованных оракулов за счет устранения единых точек отказа. Децентрализованный сервис оракулов состоит из нескольких участников одноранговой сети, которые формируют консенсус по оффчейн-данным перед отправкой их в умный контракт.
+
+Децентрализованный оракул должен (в идеале) быть бездоверительным, не требующим разрешений и свободным от администрирования со стороны центральной стороны; в действительности децентрализация среди оракулов находится в определенном спектре. Существуют полудецентрализованные сети оракулов, в которых может участвовать любой, но с «владельцем», который утверждает и удаляет узлы на основе их прошлых показателей. Также существуют полностью децентрализованные сети оракулов: обычно они работают как автономные блокчейны и имеют определенные механизмы консенсуса для координации узлов и наказания за ненадлежащее поведение.
+
+Использование децентрализованных оракулов дает следующие преимущества:
+
+### Высокие гарантии корректности {#high-correctness-guarantees}
+
+Децентрализованные оракулы пытаются достичь корректности данных, используя различные подходы. Это включает использование доказательств, подтверждающих подлинность и целостность возвращенной информации, и требование, чтобы несколько субъектов коллективно соглашались с достоверностью оффчейн-данных.
+
+#### Доказательства подлинности {#authenticity-proofs}
+
+Доказательства подлинности — это криптографические механизмы, которые обеспечивают независимую проверку информации, полученной из внешних источников. Эти доказательства могут подтвердить источник информации и обнаружить возможные изменения данных после их извлечения.
+
+Примеры доказательств подлинности:
+
+**Доказательства безопасности транспортного уровня (TLS)**: узлы оракула часто извлекают данные из внешних источников, используя безопасное HTTP-соединение на основе протокола безопасности транспортного уровня (TLS). Некоторые децентрализованные оракулы используют доказательства подлинности для проверки сеансов TLS (т. е. для подтверждения обмена информацией между узлом и конкретным сервером) и подтверждения того, что содержимое сеанса не было изменено.
+
+**Аттестации доверенной среды выполнения (TEE)**: [доверенная среда выполнения](https://en.wikipedia.org/wiki/Trusted_execution_environment) (TEE) — это изолированная («песочница») вычислительная среда, отделенная от операционных процессов своей хост-системы. TEE гарантируют, что любой код приложения или данные, хранящиеся/используемые в вычислительной среде, сохраняют целостность, конфиденциальность и неизменность. Пользователи также могут сгенерировать аттестацию, чтобы доказать, что экземпляр приложения работает в доверенной среде выполнения.
+
+Некоторые классы децентрализованных оракулов требуют, чтобы операторы узлов оракулов предоставляли аттестации TEE. Это подтверждает пользователю, что оператор узла запускает экземпляр клиента оракула в доверенной среде выполнения. TEE предотвращают изменение или чтение кода и данных приложения внешними процессами, следовательно, эти аттестации доказывают, что узел оракула сохранил информацию в целости и конфиденциальности.
+
+#### Проверка информации на основе консенсуса {#consensus-based-validation-of-information}
+
+Централизованные оракулы полагаются на единый источник истины при предоставлении данных умным контрактам, что создает возможность публикации неточной информации. Децентрализованные оракулы решают эту проблему, полагаясь на несколько узлов оракулов для запроса оффчейн-информации. Сравнивая данные из нескольких источников, децентрализованные оракулы снижают риск передачи неверной информации в ончейн-контракты.
+
+Однако децентрализованные оракулы должны иметь дело с расхождениями в информации, полученной из нескольких оффчейн-источников. Чтобы свести к минимуму различия в информации и гарантировать, что данные, передаваемые контракту оракула, отражают коллективное мнение узлов оракула, децентрализованные оракулы используют следующие механизмы:
+
+##### Голосование/стейкинг за точность данных
+
+Некоторые децентрализованные сети оракулов требуют от участников голосования или стейкинга за точность ответов на запросы данных (например, «Кто победил на выборах в США в 2020 году?»). используя нативный токен сети. Затем протокол агрегации объединяет голоса и стейки и принимает ответ, поддержанный большинством, как действительный.
+
+Узлы, чьи ответы отклоняются от ответа большинства, наказываются путем распределения их токенов среди других, кто предоставляет более правильные значения. Принуждение узлов предоставлять залог перед предоставлением данных стимулирует честные ответы, поскольку предполагается, что они являются рациональными экономическими субъектами, стремящимися к максимизации прибыли.
+
+Стейкинг/голосование также защищает децентрализованные оракулы от [атак Сивиллы](/glossary/#sybil-attack), когда злоумышленники создают несколько удостоверений для манипулирования системой консенсуса. Однако стейкинг не может предотвратить «безбилетный проезд» (узлы оракула копируют информацию у других) и «ленивую проверку» (узлы оракула следуют за большинством, не проверяя информацию самостоятельно).
+
+##### Механизмы точки Шеллинга
+
+[Точка Шеллинга](https://en.wikipedia.org/wiki/Focal_point_\(game_theory\)) — это концепция теории игр, которая предполагает, что несколько субъектов всегда будут приходить к общему решению проблемы в отсутствие какой-либо коммуникации. Механизмы точки Шеллинга часто используются в децентрализованных сетях оракулов, чтобы позволить узлам достичь консенсуса по ответам на запросы данных.
+
+Ранней идеей для этого был [SchellingCoin](https://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/), предложенный канал данных, где участники предоставляют ответы на «скалярные» вопросы (вопросы, ответы на которые описываются величиной, например, «какова цена ETH?»), вместе с депозитом. Пользователи, предоставившие значения между 25-м и 75-м [процентилями](https://en.wikipedia.org/wiki/Percentile), вознаграждаются, в то время как те, чьи значения сильно отклоняются от медианного значения, наказываются.
+
+Хотя SchellingCoin сегодня не существует, ряд децентрализованных оракулов, в частности [оракулы протокола Maker](https://docs.makerdao.com/smart-contract-modules/oracle-module), используют механизм точки Шеллинга для повышения точности данных оракула. Каждый оракул Maker состоит из оффчейн P2P-сети узлов («ретрансляторов» и «фидов»), которые предоставляют рыночные цены на залоговые активы, и ончейн-контракта «Medianizer», который вычисляет медиану всех предоставленных значений. По истечении указанного периода задержки это медианное значение становится новой справочной ценой для соответствующего актива.
+
+Другие примеры оракулов, использующих механизмы точки Шеллинга, включают [Chainlink Offchain Reporting](https://docs.chain.link/architecture-overview/off-chain-reporting) и [Witnet](https://witnet.io/). В обеих системах ответы от узлов оракула в одноранговой сети агрегируются в одно совокупное значение, например, среднее или медианное. Узлы вознаграждаются или наказываются в зависимости от того, насколько их ответы соответствуют или отклоняются от совокупного значения.
+
+Механизмы точки Шеллинга привлекательны, поскольку они минимизируют ончейн-след (необходимо отправить только одну транзакцию), гарантируя при этом децентрализацию. Последнее возможно, потому что узлы должны подписать список представленных ответов, прежде чем он будет передан в алгоритм, который производит среднее/медианное значение.
+
+### Доступность {#availability}
+
+Децентрализованные сервисы оракулов обеспечивают высокую доступность оффчейн-данных для умных контрактов. Это достигается за счет децентрализации как источника оффчейн-информации, так и узлов, ответственных за передачу информации в ончейн.
+
+Это обеспечивает отказоустойчивость, поскольку контракт оракула может полагаться на несколько узлов (которые также полагаются на несколько источников данных) для выполнения запросов от других контрактов. Децентрализация на уровне источника _и_ оператора узла имеет решающее значение — сеть узлов-оракулов, обслуживающая информацию, полученную из одного и того же источника, столкнется с той же проблемой, что и централизованный оракул.
+
+Также возможно, что оракулы, основанные на стейкинге, будут наказывать операторов узлов, которые не могут быстро реагировать на запросы данных. Это значительно стимулирует узлы оракулов инвестировать в отказоустойчивую инфраструктуру и своевременно предоставлять данные.
+
+### Хорошая совместимость стимулов {#good-incentive-compatibility}
+
+Децентрализованные оракулы реализуют различные схемы стимулирования для предотвращения [византийского](https://en.wikipedia.org/wiki/Byzantine_fault) поведения среди узлов-оракулов. В частности, они достигают _атрибутируемости_ и _подотчетности_:
+
+1. От децентрализованных узлов оракулов часто требуется подписывать данные, которые они предоставляют в ответ на запросы данных. Эта информация помогает оценить историческую производительность узлов оракулов, чтобы пользователи могли отфильтровывать ненадежные узлы оракулов при выполнении запросов данных. Примером является [алгоритмическая система репутации](https://docs.witnet.io/intro/about/architecture#algorithmic-reputation-system) Witnet.
+
+2. Децентрализованные оракулы, как объяснялось ранее, могут требовать от узлов размещения стейка в подтверждение своей уверенности в истинности предоставляемых ими данных. Если претензия подтвердится, этот стейк может быть возвращен вместе с вознаграждением за честную службу. Но он также может быть урезан в случае, если информация неверна, что обеспечивает определенную меру подотчетности.
+
+## Применение оракулов в умных контрактах {#applications-of-oracles-in-smart-contracts}
+
+Ниже приведены распространенные варианты использования оракулов в Ethereum:
+
+### Получение финансовых данных {#retrieving-financial-data}
+
+Приложения [децентрализованных финансов](/defi/) (DeFi) позволяют осуществлять одноранговое кредитование, заимствование и торговлю активами. Для этого часто требуется получение различной финансовой информации, включая данные об обменных курсах (для расчета фиатной стоимости криптовалют или сравнения цен на токены) и данные о рынках капитала (для расчета стоимости токенизированных активов, таких как золото или доллар США).
+
+Например, протокол кредитования DeFi должен запрашивать текущие рыночные цены на активы (например, ETH), депонированные в качестве обеспечения. Это позволяет контракту определять стоимость залоговых активов и определять, какую сумму можно занять в системе.
+
+Популярные «ценовые оракулы» (как их часто называют) в DeFi включают в себя ценовые каналы Chainlink, [Open Price Feed](https://compound.finance/docs/prices) от Compound Protocol, [Time-Weighted Average Prices (TWAPs)](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) от Uniswap и [Maker Oracles](https://docs.makerdao.com/smart-contract-modules/oracle-module).
+
+Разработчики должны понимать оговорки, связанные с этими ценовыми оракулами, прежде чем интегрировать их в свой проект. Эта [статья](https://blog.openzeppelin.com/secure-smart-contract-guidelines-the-dangers-of-price-oracles/) содержит подробный анализ того, что следует учитывать при планировании использования любого из упомянутых ценовых оракулов.
+
+Вот пример того, как получить последнюю цену ETH в вашем смарт-контракте, используя канал цен Chainlink:
+
+```solidity
+pragma solidity ^0.6.7;
+
+import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
+
+contract PriceConsumerV3 {
+
+ AggregatorV3Interface internal priceFeed;
+
+ /**
+ * Network: Kovan
+ * Aggregator: ETH/USD
+ * Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
+ */
+ constructor() public {
+ priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
+ }
+
+ /**
+ * Returns the latest price
+ */
+ function getLatestPrice() public view returns (int) {
+ (
+ uint80 roundID,
+ int price,
+ uint startedAt,
+ uint timeStamp,
+ uint80 answeredInRound
+ ) = priceFeed.latestRoundData();
+ return price;
+ }
+}
+```
+
+### Генерация проверяемой случайности {#generating-verifiable-randomness}
+
+Некоторые блокчейн-приложения, такие как игры на основе блокчейна или лотерейные схемы, требуют высокого уровня непредсказуемости и случайности для эффективной работы. Однако детерминированное исполнение блокчейнов исключает случайность.
+
+Первоначальный подход заключался в использовании псевдослучайных криптографических функций, таких как `blockhash`, но они могли быть [подвержены манипуляциям со стороны майнеров](https://ethereum.stackexchange.com/questions/3140/risk-of-using-blockhash-other-miners-preventing-attack#:~:text=So%20while%20the%20miners%20can,to%20one%20of%20the%20players.) решающих алгоритм доказательства выполнения работы. Кроме того, [переход Ethereum на доказательство доли владения](/roadmap/merge/) означает, что разработчики больше не могут полагаться на `blockhash` для ончейн-случайности. Вместо этого альтернативный источник случайности предоставляет [механизм RANDAO](https://eth2book.info/altair/part2/building_blocks/randomness) Beacon Chain.
+
+Можно сгенерировать случайное значение вне сети и отправить его в ончейн, но это налагает на пользователей высокие требования к доверию. Они должны верить, что значение было действительно сгенерировано с помощью непредсказуемых механизмов и не было изменено при передаче.
+
+Оракулы, предназначенные для оффчейн-вычислений, решают эту проблему путем безопасной генерации случайных результатов оффчейн, которые они передают ончейн вместе с криптографическими доказательствами, подтверждающими непредсказуемость процесса. Примером является [Chainlink VRF](https://docs.chain.link/docs/chainlink-vrf/) (проверяемая случайная функция), который представляет собой доказуемо честный и защищенный от взлома генератор случайных чисел (RNG), полезный для создания надежных умных контрактов для приложений, которые полагаются на непредсказуемые результаты.
+
+### Получение результатов событий {#getting-outcomes-for-events}
+
+С помощью оракулов легко создавать умные контракты, которые реагируют на события реального мира. Сервисы оракулов делают это возможным, позволяя контрактам подключаться к внешним API через оффчейн-компоненты и потреблять информацию из этих источников данных. Например, упомянутое ранее децентрализованное приложение для прогнозирования может запросить у оракула результаты выборов из доверенного оффчейн-источника (например, Associated Press).
+
+Использование оракулов для получения данных, основанных на результатах реального мира, позволяет использовать другие новые варианты использования; например, для эффективной работы децентрализованного страхового продукта необходима точная информация о погоде, стихийных бедствиях и т. д.
+
+### Автоматизация умных контрактов {#automating-smart-contracts}
+
+Умные контракты не запускаются автоматически; вместо этого внешний счет (EOA) или другой аккаунт контракта должен вызывать нужные функции для выполнения кода контракта. В большинстве случаев основная часть функций контракта является общедоступной и может быть вызвана EOA и другими контрактами.
+
+Но есть и _частные функции_ в контракте, которые недоступны для других;, но которые имеют решающее значение для общей функциональности децентрализованного приложения. Примеры включают функцию `mintERC721Token()`, которая периодически выпускает новые NFT для пользователей, функцию для присуждения выплат на рынке прогнозов или функцию для разблокировки заблокированных в стейкинге токенов на DEX.
+
+Разработчикам потребуется вызывать такие функции через определенные промежутки времени, чтобы обеспечить бесперебойную работу приложения. Однако это может привести к тому, что разработчики будут терять больше времени на рутинные задачи, поэтому автоматизация выполнения умных контрактов является привлекательной.
+
+Некоторые децентрализованные сети оракулов предлагают услуги автоматизации, которые позволяют оффчейн-узлам оракулов запускать функции умных контрактов в соответствии с параметрами, определенными пользователем. Обычно для этого требуется «зарегистрировать» целевой контракт в службе оракула, предоставить средства для оплаты оператору оракула и указать условия или время для запуска контракта.
+
+Сеть [Keeper Network](https://chain.link/keepers) от Chainlink предоставляет умным контрактам опции для аутсорсинга регулярных задач по обслуживанию с минимизацией доверия и децентрализованным способом. Прочитайте официальную [документацию Keeper](https://docs.chain.link/docs/chainlink-keepers/introduction/) для получения информации о том, как сделать ваш контракт совместимым с Keeper и использовать сервис Upkeep.
+
+## Как использовать блокчейн-оракулы {#use-blockchain-oracles}
+
+Существует несколько приложений-оракулов, которые вы можете интегрировать в свое децентрализованное приложение Ethereum:
+
+**[Chainlink](https://chain.link/)** — _децентрализованные сети оракулов Chainlink предоставляют защищенные от несанкционированного доступа входные, выходные данные и вычисления для поддержки передовых умных контрактов на любом блокчейне._
+
+**[RedStone Oracles](https://redstone.finance/)** — _RedStone — это децентрализованный модульный оракул, который предоставляет оптимизированные по газу потоки данных. Он специализируется на предоставлении ценовых потоков для новых активов, таких как токены ликвидного стейкинга (LST), токены ликвидного рестейкинга (LRT) и деривативы стейкинга Биткоина._
+
+**[Chronicle](https://chroniclelabs.org/)** — _Chronicle преодолевает текущие ограничения передачи данных в ончейне, разрабатывая действительно масштабируемые, экономичные, децентрализованные и проверяемые оракулы._
+
+**[Witnet](https://witnet.io/)** — _Witnet — это децентрализованный, не требующий разрешений и устойчивый к цензуре оракул, помогающий умным контрактам реагировать на реальные события с сильными криптоэкономическими гарантиями._
+
+**[UMA Oracle](https://uma.xyz)** — _оптимистичный оракул UMA позволяет умным контрактам быстро получать любые данные для различных приложений, включая страхование, финансовые деривативы и рынки прогнозов._
+
+**[Tellor](https://tellor.io/)** — _Tellor — это прозрачный и не требующий разрешений протокол оракула, который позволяет вашему умному контракту легко получать любые данные, когда это необходимо._
+
+**[Band Protocol](https://bandprotocol.com/)** — _Band Protocol — это межсетевая платформа оракулов данных, которая агрегирует и подключает реальные данные и API к умным контрактам._
+
+**[Pyth Network](https://pyth.network/)** — _сеть Pyth — это финансовая сеть оракулов от первого лица, предназначенная для публикации непрерывных данных из реального мира в ончейне в защищенной от несанкционированного доступа, децентрализованной и самодостаточной среде._
+
+**[API3 DAO](https://www.api3.org/)** — _API3 DAO предоставляет решения оракулов от первого лица, которые обеспечивают большую прозрачность источника, безопасность и масштабируемость в децентрализованном решении для умных контрактов_
+
+**[Supra](https://supra.com/)** — вертикально интегрированный инструментарий кроссчейн-решений, которые связывают все блокчейны, публичные (L1 и L2) или частные (корпоративные), предоставляя децентрализованные ценовые потоки оракулов, которые могут использоваться для ончейн- и оффчейн-приложений.
+
+**[Gas Network](https://gas.network/)** — распределенная платформа оракулов, предоставляющая данные о ценах на газ в реальном времени для различных блокчейнов. Перенося данные от ведущих поставщиков данных о ценах на газ в ончейн, Gas Network помогает повысить совместимость. Gas Network поддерживает данные для более чем 35 сетей, включая основную сеть Ethereum и многие ведущие L2.
+
+## Дополнительные материалы {#further-reading}
+
+**Статьи**
+
+- [Что такое блокчейн-оракул?](https://chain.link/education/blockchain-oracles) — _Chainlink_
+- [Что такое блокчейн-оракул?](https://medium.com/better-programming/what-is-a-blockchain-oracle-f5ccab8dbd72) — _Патрик Коллинз_
+- [Децентрализованные оракулы: всеобъемлющий обзор](https://medium.com/fabric-ventures/decentralised-oracles-a-comprehensive-overview-d3168b9a8841) — _Жюльен Тевенар_
+- [Реализация блокчейн-оракула на Ethereum](https://medium.com/@pedrodc/implementing-a-blockchain-oracle-on-ethereum-cedc7e26b49e) — _Педро Коста_
+- [Почему умные контракты не могут совершать вызовы API?](https://ethereum.stackexchange.com/questions/301/why-cant-contracts-make-api-calls) — _StackExchange_
+- [Итак, вы хотите использовать ценовой оракул](https://samczsun.com/so-you-want-to-use-a-price-oracle/) — _samczsun_
+
+**Видео**
+
+- [Оракулы и расширение полезности блокчейна](https://youtu.be/BVUZpWa8vpw) — _Real Vision Finance_
+
+**Учебники**
+
+- [Как получить текущую цену Ethereum в Solidity](https://blog.chain.link/fetch-current-crypto-price-data-solidity/) — _Chainlink_
+- [Использование данных оракула](https://docs.chroniclelabs.org/Developers/tutorials/Remix) — _Chronicle_
+
+**Примеры проектов**
+
+- [Полный стартовый проект Chainlink для Ethereum на Solidity](https://github.com/hackbg/chainlink-fullstack) — _HackBG_
diff --git a/public/content/translations/ru/developers/docs/programming-languages/dart/index.md b/public/content/translations/ru/developers/docs/programming-languages/dart/index.md
new file mode 100644
index 00000000000..ec2ff046b80
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/dart/index.md
@@ -0,0 +1,32 @@
+---
+title: "Ethereum для разработчиков на Dart"
+description: "Узнайте, как разрабатывать для Ethereum, используя язык Dart"
+lang: ru
+incomplete: true
+---
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+## Руководства {#tutorials}
+
+- [Flutter и блокчейн — децентрализованное приложение Hello World](https://www.geeksforgeeks.org/flutter-and-blockchain-hello-world-dapp/) проведет вас по всем шагам для начала работы:
+ 1. Написание смарт-контракта на [Solidity](https://soliditylang.org/)
+ 2. Написание пользовательского интерфейса в Dart
+- [Создание мобильного децентрализованного приложения с помощью Flutter](https://medium.com/dash-community/building-a-mobile-dapp-with-flutter-be945c80315a) намного короче и может подойти лучше,
+ если вы уже знакомы с основами
+- Если вы предпочитаете учиться, просматривая видео, вы можете посмотреть [Создание своего первого блокчейн-приложения на Flutter](https://www.youtube.com/watch?v=3Eeh3pJ6PeA), которое длится около часа
+- Если вы нетерпеливы, вы можете предпочесть [Создание децентрализованного блокчейн-приложения с Flutter и Dart на Ethereum](https://www.youtube.com/watch?v=jaMFEOCq_1s), которое длится всего около двадцати минут
+- [Интеграция MetaMask в приложение Flutter с помощью Web3Modal от WalletConnect](https://www.youtube.com/watch?v=v_M2buHCpc4) — это короткое видео проведет вас по шагам интеграции MetaMask в ваши приложения Flutter с помощью библиотеки [Web3Modal](https://pub.dev/packages/web3modal_flutter) от WalletConnect
+- [Курс для разработчиков мобильных блокчейн-приложений на Solidity и Flutter](https://youtube.com/playlist?list=PL4V4Unlk5luhQ26ERO6hWEbcUwHDSSmVH) — плейлист полного курса для full-stack разработчика мобильных блокчейн-приложений
+
+## Работа с клиентами Ethereum {#working-with-ethereum-clients}
+
+Вы можете использовать Ethereum для создания децентрализованных приложений (или "dapps"), использующих преимущества технологий криптовалюты и блокчейна.
+Существует по крайней мере две поддерживаемые в настоящее время библиотеки для Dart, которые используют
+[JSON-RPC API](/developers/docs/apis/json-rpc/) для Ethereum.
+
+1. [Web3dart от pwa.ir](https://pub.dev/packages/web3dart)
+2. [Ethereum 5.0.0 от darticulate.com](https://pub.dev/packages/ethereum)
+
+Существуют также дополнительные библиотеки, которые позволяют вам оперировать конкретными адресами Ethereum, или которые позволяют вам получать цены на различные криптовалюты.
+[Полный список можно посмотреть здесь](https://pub.dev/dart/packages?q=ethereum).
diff --git a/public/content/translations/ru/developers/docs/programming-languages/delphi/index.md b/public/content/translations/ru/developers/docs/programming-languages/delphi/index.md
new file mode 100644
index 00000000000..4f54120de45
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/delphi/index.md
@@ -0,0 +1,56 @@
+---
+title: "Ethereum для разработчиков на Delphi"
+description: "Узнайте, как разрабатывать для Ethereum с помощью языка программирования Delphi"
+lang: ru
+incomplete: true
+---
+
+
+
+Узнайте, как разрабатывать для Ethereum с помощью языка программирования Delphi
+
+
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они могут работать с цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+Создавайте децентрализованные приложения на базе Ethereum и взаимодействуйте со смарт-контрактами, используя язык программирования Delphi!
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-the-solidity-language}
+
+**Сделайте первые шаги к интеграции Delphi с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Справочные материалы и ссылки для начинающих {#beginner-references-and-links}
+
+**Знакомство с библиотекой Delphereum**
+
+- [Что такое Delphereum?](https://github.com/svanas/delphereum/blob/master/README.md)
+- [Подключение Delphi к локальному (in-memory) блокчейну](https://medium.com/@svanas/connecting-delphi-to-a-local-in-memory-blockchain-9a1512d6c5b0)
+- [Подключение Delphi к основной сети Ethereum](https://medium.com/@svanas/connecting-delphi-to-the-ethereum-main-net-5faf1feffd83)
+- [Подключение Delphi к смарт-контрактам](https://medium.com/@svanas/connecting-delphi-to-smart-contracts-3146b12803a1)
+
+**Хотите пока пропустить настройку и сразу перейти к примерам?**
+
+- [Смарт-контракт и Delphi за 3 минуты — часть 1](https://medium.com/@svanas/a-3-minute-smart-contract-and-delphi-61d998571d)
+- [Смарт-контракт и Delphi за 3 минуты — часть 2](https://medium.com/@svanas/a-3-minute-smart-contract-and-delphi-part-2-446925faa47b)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Создание подписи сообщения, подписанного Ethereum, в Delphi](https://medium.com/@svanas/generating-an-ethereum-signed-message-signature-in-delphi-75661ce5031b)
+- [Перевод эфира с помощью Delphi](https://medium.com/@svanas/transferring-ether-with-delphi-b5f24b1a98a4)
+- [Перевод токенов ERC-20 с помощью Delphi](https://medium.com/@svanas/transferring-erc-20-tokens-with-delphi-bb44c05b295d)
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Delphi и Служба имен Ethereum (ENS)](https://medium.com/@svanas/delphi-and-ethereum-name-service-ens-4443cd278af7)
+- [QuikNode, Ethereum и Delphi](https://medium.com/@svanas/quiknode-ethereum-and-delphi-f7bfc9671c23)
+- [Delphi и темный лес Ethereum](https://svanas.medium.com/delphi-and-the-ethereum-dark-forest-5b430da3ad93)
+- [Обмен одного токена на другой в Delphi](https://svanas.medium.com/swap-one-token-for-another-in-delphi-bcb999c47f7)
+
+Ищешь больше статей? Посетите [ethereum.org/developers](/developers/).
diff --git a/public/content/translations/ru/developers/docs/programming-languages/dot-net/index.md b/public/content/translations/ru/developers/docs/programming-languages/dot-net/index.md
new file mode 100644
index 00000000000..d169213baca
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/dot-net/index.md
@@ -0,0 +1,86 @@
+---
+title: "Ethereum для разработчиков на .NET"
+description: "Узнайте, как разработать Ethereum с помощью проектов и инструментария .NET"
+lang: ru
+incomplete: true
+---
+
+Узнайте, как вести разработку для Ethereum с помощью проектов и инструментария на основе .NET
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они могут работать с цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+Создавайте децентрализованные приложения на основе Ethereum и взаимодействуйте со смарт-контрактами, используя инструменты и языки из технологического стека Microsoft - Поддержка C #, # Visual Basic .NET, F #, таких инструментов, как VSCode и Visual Studio, в .NET Framework / .NET Core / .NET Standard. Разверните блокчейн Ethereum в Azure с помощью блокчейна Microsoft Azure за считанные минуты. Привнесите любовь к .NET в Ethereum!
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-the-solidity-language}
+
+**Сделайте свои первые шаги к интеграции .NET с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Справочные материалы и ссылки для начинающих {#beginner-references-and-links}
+
+**Представляем библиотеку Nethereum и VS Code Solidity**
+
+- [Nethereum, начало работы](https://docs.nethereum.com/en/latest/getting-started/)
+- [Установка Solidity для VS Code](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity)
+- [Рабочий процесс .NET-разработчика по созданию и вызову умных контрактов Ethereum](https://medium.com/coinmonks/a-net-developers-workflow-for-creating-and-calling-ethereum-smart-contracts-44714f191db2)
+- [Интеграция умных контрактов с Nethereum](https://kauri.io/#collections/Getting%20Started/smart-contracts-integration-with-nethereum/#smart-contracts-integration-with-nethereumm)
+- [Взаимодействие умных контрактов на блокчейне Ethereum и .NET с помощью Nethereum](https://medium.com/my-blockchain-development-daily-journey/interfacing-net-and-ethereum-blockchain-smart-contracts-with-nethereum-2fa3729ac933), также на [китайском языке](https://medium.com/my-blockchain-development-daily-journey/%E4%BD%BF%E7%94%A8nethereum%E9%80%A3%E6%8E%A5-net%E5%92%8C%E4%BB%A5%E5%A4%AA%E7%B6%B2%E5%8D%80%E5%A1%8A%E9%8F%88%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84-4a96d35ad1e1)
+- [Nethereum — библиотека интеграции .NET с открытым исходным кодом для блокчейна](https://kauri.io/#collections/a%20hackathon%20survival%20guide/nethereum-an-open-source-.net-integration-library/)
+- [Запись транзакций Ethereum в базу данных SQL с помощью Nethereum](https://medium.com/coinmonks/writing-ethereum-transactions-to-sql-database-using-nethereum-fd94e0e4fa36)
+- [Узнайте, как легко развертывать умные контракты Ethereum с помощью C# и Visual Studio](https://koukia.ca/deploy-ethereum-smart-contracts-using-c-and-visualstudio-5be188ae928c)
+
+**Хотите пока пропустить настройку и сразу перейти к примерам?**
+
+- [Playground](http://playground.nethereum.com/) — взаимодействуйте с Ethereum и узнайте, как использовать Nethereum через браузер.
+ - Запросить баланс аккаунта [C#](http://playground.nethereum.com/csharp/id/1001) [VB.NET](http://playground.nethereum.com/vb/id/2001)
+ - Запросить баланс умного контракта ERC20 [C#](http://playground.nethereum.com/csharp/id/1005) [VB.NET](http://playground.nethereum.com/vb/id/2004)
+ - Перевод эфира на аккаунт [C#](http://playground.nethereum.com/csharp/id/1003) [VB.NET](http://playground.nethereum.com/vb/id/2003)
+ - ... И многое другое!
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Рабочая книга/список примеров Nethereum](http://docs.nethereum.com/en/latest/Nethereum.Workbooks/docs/)
+- [Разверните свои собственные тестовые цепочки для разработки](https://github.com/Nethereum/Testchains)
+- [Плагин генерации кода VSCode для Solidity](https://docs.nethereum.com/en/latest/nethereum-codegen-vscodesolidity/)
+- [Unity и Ethereum: зачем и как](https://www.raywenderlich.com/5509-unity-and-ethereum-why-and-how)
+- [Создание ASP.NET Core Web API для децентрализованных приложений Ethereum](https://tech-mint.com/blockchain/create-asp-net-core-web-api-for-ethereum-dapps/)
+- [Использование Nethereum Web3 для внедрения системы отслеживания цепочек поставок](http://blog.pomiager.com/post/using-nethereum-web3-to-implement-a-supply-chain-traking-system4)
+- [Обработка блоков в Nethereum](https://nethereum.readthedocs.io/en/latest/nethereum-block-processing-detail/), с [примером для C# Playground](http://playground.nethereum.com/csharp/id/1025)
+- [Потоковая передача через Websocket в Nethereum](https://nethereum.readthedocs.io/en/latest/nethereum-subscriptions-streaming/)
+- [Kaleido и Nethereum](https://kaleido.io/kaleido-and-nethereum/)
+- [Quorum и Nethereum](https://github.com/Nethereum/Nethereum/blob/master/src/Nethereum.Quorum/README.md)
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Azure Key Vault и Nethereum](https://github.com/Azure-Samples/bc-community-samples/tree/master/akv-nethereum)
+- [Nethereum.DappHybrid](https://github.com/Nethereum/Nethereum.DappHybrid)
+- [Эталонная архитектура бэкенда Ujo Nethereum](https://docs.nethereum.com/en/latest/nethereum-ujo-backend-sample/)
+
+## Проекты, инструменты и другие интересные материалы на .NET {#dot-net-projects-tools-and-other-fun-stuff}
+
+- [Nethereum Playground](http://playground.nethereum.com/) — _компилируйте, создавайте и запускайте фрагменты кода Nethereum в браузере_
+- [Nethereum Codegen Blazor](https://github.com/Nethereum/Nethereum.CodeGen.Blazor) — _генератор кода Nethereum с пользовательским интерфейсом в Blazor_
+- [Nethereum Blazor](https://github.com/Nethereum/NethereumBlazor) — _облегченный обозреватель блокчейна и простой кошелек .NET Wasm SPA_
+- [Wonka Business Rules Engine](https://docs.nethereum.com/en/latest/wonka/) — _система правил для бизнеса (как для платформы .NET, так и для платформы Ethereum), которая по своей сути управляется метаданными_
+- [Nethermind](https://github.com/NethermindEth/nethermind) — _клиент Ethereum на .NET Core для Linux, Windows и MacOS_
+- [eth-utils](https://github.com/ethereum/eth-utils/) – _вспомогательные функции для работы с кодовыми базами, связанными с Ethereum_
+- [TestChains](https://github.com/Nethereum/TestChains) — _предварительно настроенные цепочки разработки .NET для быстрого ответа (PoA)_
+
+Ищешь больше статей? Посетите [ethereum.org/developers](/developers/).
+
+## Участники сообщества .NET {#dot-net-community-contributors}
+
+Участники проекта Nethereum в основном общаются в [Gitter](https://gitter.im/Nethereum/Nethereum), где каждый может задавать вопросы и отвечать на них, получать помощь или просто общаться. Не стесняйтесь создавать PR или открывать issue в [репозитории Nethereum на GitHub](https://github.com/Nethereum) или просто просмотрите множество наших дополнительных проектов и примеров. Вы также можете найти нас в [Discord](https://discord.gg/jQPrR58FxX)!
+
+Если вы новичок в Nethermind и вам нужна помощь, чтобы начать работу, присоединяйтесь к нашему [Discord](http://discord.gg/PaCMRFdvWT). Наши разработчики готовы ответить на ваши вопросы. Не стесняйтесь создавать PR или открывать issue в [репозитории Nethermind на GitHub](https://github.com/NethermindEth/nethermind).
+
+## Другие сводные списки {#other-aggregated-lists}
+
+[Официальный сайт Nethereum](https://nethereum.com/)
+[Официальный сайт Nethermind](https://nethermind.io/)
diff --git a/public/content/translations/ru/developers/docs/programming-languages/elixir/index.md b/public/content/translations/ru/developers/docs/programming-languages/elixir/index.md
new file mode 100644
index 00000000000..ba67b25e7c7
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/elixir/index.md
@@ -0,0 +1,55 @@
+---
+title: "Ethereum для разработчиков на Elixir"
+description: "Узнайте, как разрабатывать для Ethereum, используя проекты и инструментарий на основе Elixir."
+lang: ru
+incomplete: false
+---
+
+Узнайте, как разрабатывать для Ethereum, используя проекты и инструментарий на основе Elixir.
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения могут быть недоверенными, что означает, что после их развертывания в Ethereum они всегда будут работать так, как запрограммировано. Они могут управлять цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Сделайте первые шаги к интеграции Elixir с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Статьи для начинающих {#beginner-articles}
+
+- [Наконец-то разбираемся в аккаунтах Ethereum](https://dev.to/q9/finally-understanding-ethereum-accounts-1kpe)
+- [Ethers — первоклассная библиотека Web3 для Ethereum на Elixir](https://medium.com/@alisinabh/announcing-ethers-a-first-class-ethereum-web3-library-for-elixir-1d64e9409122)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Как подписывать необработанные транзакции контрактов Ethereum с помощью Elixir](https://kohlerjp.medium.com/how-to-sign-raw-ethereum-contract-transactions-with-elixir-f8822bcc813b)
+- [Смарт-контракты Ethereum и Elixir](https://medium.com/agile-alpha/ethereum-smart-contracts-and-elixir-c7c4b239ddb4)
+
+## Проекты и инструменты Elixir {#elixir-projects-and-tools}
+
+### Активные {#active}
+
+- [block_keys](https://github.com/ExWeb3/block_keys) — _реализация BIP32 и BIP44 на Elixir (иерархия нескольких аккаунтов для детерминированных кошельков)_
+- [ethereumex](https://github.com/mana-ethereum/ethereumex) — _клиент JSON-RPC на Elixir для блокчейна Ethereum_
+- [ethers](https://github.com/ExWeb3/elixir_ethers) — _комплексная библиотека Web3 для взаимодействия со смарт-контрактами в Ethereum с помощью Elixir_
+- [ethers_kms](https://github.com/ExWeb3/elixir_ethers_kms) — _библиотека подписи KMS для Ethers (подписывайте транзакции с помощью AWS KMS)_
+- [ex_abi](https://github.com/poanetwork/ex_abi) — _реализация парсера/декодера/кодировщика ABI для Ethereum на Elixir_
+- [ex_keccak](https://github.com/ExWeb3/ex_keccak) — _библиотека Elixir для вычисления хешей Keccak SHA3-256 с использованием NIF, созданного на основе крейта Rust tiny-keccak_
+- [ex_rlp](https://github.com/mana-ethereum/ex_rlp) — _реализация на Elixir кодировки RLP (Recursive Length Prefix) в Ethereum_
+
+### Архивные / Больше не поддерживаются {#archived--no-longer-maintained}
+
+- [eth](https://hex.pm/packages/eth) — _Утилиты Ethereum для Elixir_
+- [exw3](https://github.com/hswick/exw3) — _Высокоуровневый клиент RPC для Ethereum на Elixir_
+- [mana](https://github.com/mana-ethereum/mana) — _реализация полной ноды Ethereum, написанная на Elixir_
+
+Ищешь больше статей? Посетите [главную страницу для разработчиков](/developers/).
+
+## Участники сообщества Elixir {#elixir-community-contributors}
+
+[Канал #ethereum в Slack для Elixir](https://elixir-lang.slack.com/archives/C5RPZ3RJL) является местом для быстрорастущего сообщества и представляет собой выделенный ресурс для обсуждения любых вышеупомянутых проектов и связанных с ними тем.
diff --git a/public/content/translations/ru/developers/docs/programming-languages/golang/index.md b/public/content/translations/ru/developers/docs/programming-languages/golang/index.md
new file mode 100644
index 00000000000..e634614cd96
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/golang/index.md
@@ -0,0 +1,84 @@
+---
+title: "Ethereum для разработчиков на Go"
+description: "Узнайте, как разрабатывать для Ethereum с помощью Go проектов и инструментов"
+lang: ru
+incomplete: true
+---
+
+Узнайте, как разрабатывать для Ethereum, используя проекты и инструменты на основе Go
+
+Используйте Ethereum для создания децентрализованных приложений ("dapps"). Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они децентрализованы, что означает, что они работают в одноранговой сети и не имеют единой точки отказа. Их не контролирует ни одно юридическое или физическое лицо, и их практически невозможно подвергнуть цензуре. Они могут управлять цифровыми активами, чтобы создавать новые виды приложений.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Сделайте свои первые шаги интеграции Go с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+- [Руководство по контрактам](https://github.com/ethereum/go-ethereum/wiki/Contract-Tutorial)
+
+## Статьи и книги для начинающих {#beginner-articles-and-books}
+
+- [Начало работы с Geth](https://medium.com/@tzhenghao/getting-started-with-geth-c1a30b8d6458)
+- [Использование Golang для подключения к Ethereum](https://www.youtube.com/watch?v=-7uChuO_VzM)
+- [Развертывание смарт-контрактов Ethereum с помощью Golang](https://www.youtube.com/watch?v=pytGqQmDslE)
+- [Пошаговое руководство по тестированию и развертыванию смарт-контрактов Ethereum на Go](https://hackernoon.com/a-step-by-step-guide-to-testing-and-deploying-ethereum-smart-contracts-in-go-9fc34b178d78)
+- [Электронная книга: Разработка для Ethereum на Go](https://goethereumbook.org/) - _Разработка приложений Ethereum с помощью Go_
+
+## Статьи и документация для среднего уровня {#intermediate-articles-and-docs}
+
+- [Документация Go Ethereum](https://geth.ethereum.org/docs/) - _Документация по официальной реализации Ethereum на Golang_
+- [Руководство программиста по Erigon](https://github.com/ledgerwatch/erigon/blob/devel/docs/programmers_guide/guide.md) - _Иллюстрированное руководство, включающее дерево состояний, множественные доказательства и обработку транзакций_
+- [Erigon и Stateless Ethereum](https://youtu.be/3-Mn7OckSus?t=394) - _Конференция сообщества Ethereum 2020 г. (EthCC 3)_
+- [Erigon: оптимизация клиентов Ethereum](https://www.youtube.com/watch?v=CSpc1vZQW2Q) - _Devcon 4, 2018 г._
+- [Документация Go Ethereum GoDoc](https://godoc.org/github.com/ethereum/go-ethereum)
+- [Создание децентрализованного приложения на Go с помощью Geth](https://kauri.io/#collections/A%20Hackathon%20Survival%20Guide/creating-a-dapp-in-go-with-geth/)
+- [Работа с частной сетью Ethereum на Golang и Geth](https://myhsts.org/tutorial-learn-how-to-work-with-ethereum-private-network-with-golang-with-geth.php)
+- [Модульное тестирование контрактов Solidity в Ethereum с помощью Go](https://medium.com/coinmonks/unit-testing-solidity-contracts-on-ethereum-with-go-3cc924091281)
+- [Краткий справочник по использованию Geth в качестве библиотеки](https://medium.com/coinmonks/web3-go-part-1-31c68c68e20e)
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Симулированный бэкенд GETH](https://kauri.io/#collections/An%20ethereum%20test%20toolkit%20in%20Go/the-geth-simulated-backend/#_top)
+- [Приложения «блокчейн как услуга» с использованием Ethereum и Quorum](https://blockchain.dcwebmakers.com/blockchain-as-a-service-apps-using-ethereum-and-quorum.html)
+- [Распределенное хранилище IPFS и Swarm в блокчейн-приложениях Ethereum](https://blockchain.dcwebmakers.com/work-with-distributed-storage-ipfs-and-swarm-in-ethereum.html)
+- [Мобильные клиенты: библиотеки и внутрипроцессные узлы Ethereum (Inproc)](https://github.com/ethereum/go-ethereum/wiki/Mobile-Clients:-Libraries-and-Inproc-Ethereum-Nodes)
+- [Нативные децентрализованные приложения: привязки Go к контрактам Ethereum](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts)
+
+## Проекты и инструменты Go {#go-projects-and-tools}
+
+- [Geth / Go Ethereum](https://github.com/ethereum/go-ethereum) - _Официальная реализация протокола Ethereum на Go_
+- [Анализ кода Go Ethereum](https://github.com/ZtesoftCS/go-ethereum-code-analysis) - _Обзор и анализ исходного кода Go Ethereum_
+- [Erigon](https://github.com/ledgerwatch/erigon) - _Более быстрая производная от Go Ethereum с упором на архивные узлы_
+- [Golem](https://github.com/golemfactory/golem) - _Golem создает глобальный рынок вычислительных мощностей_
+- [Quorum](https://github.com/jpmorganchase/quorum) - _Реализация Ethereum с контролем доступа, обеспечивающая конфиденциальность данных_
+- [Prysm](https://github.com/prysmaticlabs/prysm) - _Реализация Ethereum 'Serenity' 2.0 на Go_
+- [Eth Tweet](https://github.com/yep/eth-tweet) - _Децентрализованный Twitter: сервис микроблогов, работающий на блокчейне Ethereum_
+- [Plasma MVP Golang](https://github.com/kyokan/plasma) — _Реализация на Golang и расширение спецификации минимально жизнеспособной Plasma (Minimum Viable Plasma)_
+- [Open Ethereum Mining Pool](https://github.com/sammy007/open-ethereum-pool) - _Пул для майнинга Ethereum с открытым исходным кодом_
+- [Ethereum HD-кошелек](https://github.com/miguelmota/go-ethereum-hdwallet) - _Производные HD-кошелька Ethereum на Go_
+- [Multi Geth](https://github.com/multi-geth/multi-geth) - _Поддержка многих разновидностей сетей Ethereum_
+- [Легкий клиент Geth](https://github.com/zsfelfoldi/go-ethereum/wiki/Geth-Light-Client) - _Реализация Geth для «легкого» подпротокола Ethereum_
+- [Ethereum Golang SDK](https://github.com/everFinance/goether) - _Простая реализация кошелька Ethereum и утилит на Golang_
+- [Covalent Golang SDK](https://github.com/covalenthq/covalent-api-sdk-go) - _Эффективный доступ к данным блокчейна через Go SDK для более чем 200 блокчейнов_
+
+Ищешь больше статей? Посетите [ethereum.org/developers](/developers/)
+
+## Участники сообщества Go {#go-community-contributors}
+
+- [Geth в Discord](https://discordapp.com/invite/nthXNEv)
+- [Geth в Gitter](https://gitter.im/ethereum/go-ethereum)
+- [Gophers в Slack](https://invite.slack.golangbridge.org/) - [канал #ethereum](https://gophers.slack.com/messages/C9HP1S9V2)
+- [StackExchange — Ethereum](https://ethereum.stackexchange.com/)
+- [Multi Geth в Gitter](https://gitter.im/ethoxy/multi-geth)
+- [Ethereum в Gitter](https://gitter.im/ethereum/home)
+- [Легкий клиент Geth в Gitter](https://gitter.im/ethereum/light-client)
+
+## Другие сводные списки {#other-aggregated-lists}
+
+- [Отличные ресурсы по Ethereum](https://github.com/btomashvili/awesome-ethereum)
+- [Consensys: полный список инструментов для разработчиков Ethereum](https://media.consensys.net/an-definitive-list-of-ethereum-developer-tools-2159ce865974) | [Источник на GitHub](https://github.com/ConsenSys/ethereum-developer-tools-list)
diff --git a/public/content/translations/ru/developers/docs/programming-languages/index.md b/public/content/translations/ru/developers/docs/programming-languages/index.md
new file mode 100644
index 00000000000..e218834621a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/index.md
@@ -0,0 +1,32 @@
+---
+title: "Языки программирования"
+description: "Ресурс Ethereum"
+lang: ru
+---
+
+Распространенное заблуждение заключается в том, что для разработки на Ethereum необходимо писать [смарт-контракты](/developers/docs/smart-contracts/). Это неправда.
+Одна из прекрасных особенностей сети Ethereum и ее сообщества заключается в том, что вы можете [участвовать](/community/), используя практически любой язык программирования.
+
+Ethereum и его сообщество поддерживают открытый исходный код. Вы можете найти проекты сообщества - клиентские реализации, API, фреймворки разработки, инструменты тестирования - на самых разных языках.
+
+## Выберите свой язык {#data}
+
+Выберите предпочтительный для Вас язык программирования, чтобы найти проекты, ресурсы и виртуальные сообщества:
+
+- [Ethereum для разработчиков на Dart](/developers/docs/programming-languages/dart/)
+- [Ethereum для разработчиков на Delphi](/developers/docs/programming-languages/delphi/)
+- [Ethereum для разработчиков на .NET](/developers/docs/programming-languages/dot-net/)
+- [Ethereum для разработчиков на Elixir](/developers/docs/programming-languages/elixir/)
+- [Ethereum для разработчиков на Go](/developers/docs/programming-languages/golang/)
+- [Ethereum для разработчиков на Java](/developers/docs/programming-languages/java/)
+- [Ethereum для разработчиков на JavaScript](/developers/docs/programming-languages/javascript/)
+- [Ethereum для разработчиков на Python](/developers/docs/programming-languages/python/)
+- [Ethereum для разработчиков на Ruby](/developers/docs/programming-languages/ruby/)
+- [Ethereum для разработчиков на Rust](/developers/docs/programming-languages/rust/)
+
+### Что делать, если мой язык не поддерживается {#other-lang}
+
+Если вы хотите добавить ссылку на ресурсы или указать виртуальное сообщество для дополнительного языка программирования, вы можете запросить новую страницу, [создав issue](https://github.com/ethereum/ethereum-org-website/issues/new/choose).
+
+Если вы просто хотите написать код для взаимодействия с блокчейном, используя неподдерживаемый в настоящее время язык,
+вы можете использовать [интерфейс JSON-RPC](/developers/docs/apis/json-rpc/) для подключения к сети Ethereum. Любой язык программирования, который может использовать TCP/IP, может использовать этот интерфейс.
diff --git a/public/content/translations/ru/developers/docs/programming-languages/java/index.md b/public/content/translations/ru/developers/docs/programming-languages/java/index.md
new file mode 100644
index 00000000000..131558d2542
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/java/index.md
@@ -0,0 +1,64 @@
+---
+title: "Ethereum для разработчиков на Java"
+description: "Узнайте, как разрабатывать для Ethereum с использованием проектов и инструментов на основе Java"
+lang: ru
+incomplete: true
+---
+
+Узнайте, как разрабатывать для Ethereum с использованием проектов и инструментов на основе Java
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они могут работать с цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Сделайте свои первые шаги к интеграции Java с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers.](/developers/)
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Работа с клиентами Ethereum {#working-with-ethereum-clients}
+
+Узнайте, как использовать [Web3J](https://github.com/web3j/web3j) и Hyperledger Besu — два ведущих Java-клиента для Ethereum
+
+- [Подключение к клиенту Ethereum с помощью Java, Eclipse и Web3J](https://kauri.io/article/b9eb647c47a546bc95693acc0be72546/connecting-to-an-ethereum-client-with-java-eclipse-and-web3j)
+- [Управление аккаунтом Ethereum с помощью Java и Web3j](https://kauri.io/article/925d923e12c543da9a0a3e617be963b4/manage-an-ethereum-account-with-java-and-web3j)
+- [Создание Java-оболочки из вашего умного контракта](https://kauri.io/article/84475132317d4d6a84a2c42eb9348e4b/generate-a-java-wrapper-from-your-smart-contract)
+- [Взаимодействие с умным контрактом Ethereum](https://kauri.io/article/14dc434d11ef4ee18bf7d57f079e246e/interacting-with-an-ethereum-smart-contract-in-java)
+- [Прослушивание событий умного контракта Ethereum](https://kauri.io/article/760f495423db42f988d17b8c145b0874/listening-for-ethereum-smart-contract-events-in-java)
+- [Использование Besu (Pantheon), Java-клиента Ethereum, в Linux](https://kauri.io/article/276dd27f1458443295eea58403fd6965/using-pantheon-the-java-ethereum-client-with-linux)
+- [Запуск узла Hyperledger Besu (Pantheon) в интеграционных тестах Java](https://kauri.io/article/7dc3ecc391e54f7b8cbf4e5fa0caf780/running-a-pantheon-node-in-java-integration-tests)
+- [Памятка по Web3j](https://kauri.io/web3j-cheat-sheet-\(java-ethereum\)/5dfa1ea941ac3d0001ce1d90/c)
+
+Узнайте, как использовать [ethers-kt](https://github.com/Kr1ptal/ethers-kt), асинхронную, высокопроизводительную библиотеку Kotlin для взаимодействия с блокчейнами на основе EVM. Ориентация на платформы JVM и Android.
+
+- [Перевод токенов ERC20](https://github.com/Kr1ptal/ethers-kt/blob/master/examples/src/main/kotlin/io/ethers/examples/abi/TransferERC20.kt)
+- [Обмен на UniswapV2 с прослушиванием событий](https://github.com/Kr1ptal/ethers-kt/blob/master/examples/src/main/kotlin/io/ethers/examples/tokenswapwitheventlistening/TokenSwapWithEventListening.kt)
+- [Трекер баланса ETH / ERC20](https://github.com/Kr1ptal/ethers-kt/blob/master/examples/src/main/kotlin/io/ethers/examples/balancetracker/BalanceTracker.kt)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Управление хранилищем в Java-приложении с помощью IPFS](https://kauri.io/article/3e8494f4f56f48c4bb77f1f925c6d926/managing-storage-in-a-java-application-with-ipfs)
+- [Управление токенами ERC20 в Java с помощью Web3j](https://kauri.io/article/d13e911bbf624108b1d5718175a5e0a0/manage-erc20-tokens-in-java-with-web3j)
+- [Менеджеры транзакций Web3j](https://kauri.io/article/4cb780bb4d0846438d11885a25b6d7e7/web3j-transaction-managers)
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Использование Eventeum для создания кэша данных смарт-контракта на Java](https://kauri.io/article/fe81ee9612eb4e5a9ab72790ef24283d/using-eventeum-to-build-a-java-smart-contract-data-cache)
+
+## Проекты и инструменты на Java {#java-projects-and-tools}
+
+- [Web3J (библиотека для взаимодействия с клиентами Ethereum)](https://github.com/web3j/web3j)
+- [ethers-kt (асинхронная, высокопроизводительная библиотека Kotlin/Java/Android для блокчейнов на основе EVM.)](https://github.com/Kr1ptal/ethers-kt)
+- [Eventeum (прослушиватель событий)](https://github.com/ConsenSys/eventeum)
+- [Mahuta (инструменты разработчика для IPFS)](https://github.com/ConsenSys/mahuta)
+
+Ищешь больше статей? Посетите [ethereum.org/developers.](/developers/)
+
+## Участники сообщества Java {#java-community-contributors}
+
+- [IO Builders](https://io.builders)
+- [Kauri](https://kauri.io)
diff --git a/public/content/translations/ru/developers/docs/programming-languages/javascript/index.md b/public/content/translations/ru/developers/docs/programming-languages/javascript/index.md
new file mode 100644
index 00000000000..d56b51da0a6
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/javascript/index.md
@@ -0,0 +1,72 @@
+---
+title: "Ethereum для разработчиков на JavaScript"
+description: "Узнайте как зарабатывать c помощью Ethereum используя проекты и инструменты на JavaScript."
+lang: ru
+---
+
+JavaScript - самый популярный язык в системе Ethereum. Фактически существует [команда](https://github.com/ethereumjs), которая занимается переносом как можно большего количества возможностей Ethereum в JavaScript.
+
+Есть возможность писать на JavaScript (или чем-то похожем) на [всех уровнях стека](/developers/docs/ethereum-stack/).
+
+## Взаимодействие с Ethereum {#interact-with-ethereum}
+
+### Библиотеки API для JavaScript {#javascript-api-libraries}
+
+Если вы хотите писать на JavaScript, чтобы запрашивать данные из блокчейна, отправлять транзакции и выполнять другие действия, то наиболее удобным способом для этого будет использование [библиотеки API для JavaScript](/developers/docs/apis/javascript/). Эти API позволяют разработчикам легко взаимодействовать с [узлами в сети Ethereum](/developers/docs/nodes-and-clients/).
+
+Вы можете использовать эти библиотеки для взаимодействия со смарт-контрактами на Ethereum, чтобы можно было создать децентрализованное приложение, где вы сможете использовать JavaScript для взаимодействия с уже существующими контрактами.
+
+**Ознакомьтесь**
+
+- [Web3.js](https://web3js.readthedocs.io)
+- [Ethers.js](https://ethers.org) — _включает реализацию кошелька Ethereum и утилиты на JavaScript и TypeScript._
+- [viem](https://viem.sh) — _интерфейс TypeScript для Ethereum, предоставляющий низкоуровневые примитивы без сохранения состояния для взаимодействия с Ethereum._
+- [Drift](https://ryangoree.github.io/drift/) — _метабиблиотека TypeScript со встроенным кэшированием, хуками и тестовыми моками для упрощения разработки на Ethereum с использованием различных библиотек Web3._
+
+### Умные контракты {#smart-contracts}
+
+Если вы JavaScript-разработчик и хотите написать собственный смарт-контракт, вам стоит ознакомиться с [Solidity](https://solidity.readthedocs.io). Это очень популярный язык смарт-контрактов, и он синтаксически похож на JavaScript, что может упростить его изучение.
+
+Подробнее о [смарт-контрактах](/developers/docs/smart-contracts/).
+
+## Понимание протокола {#understand-the-protocol}
+
+### Виртуальная машина Ethereum {#the-ethereum-virtual-machine}
+
+Существует реализация [виртуальной машины Ethereum](/developers/docs/evm/) на JavaScript. Она поддерживает последние форк-правила. Правила Fork означают изменения, появившиеся в EVM в результате запланированных улучшений.
+
+Он разделен на различные пакеты JavaScript, которые вы можете прочесть, чтобы лучше понять:
+
+- Аккаунты
+- Блоки
+- Сам блокчейн
+- Транзакции
+- И другое...
+
+Это поможет вам понять такие вещи как: "Какова структура данных в аккаунте?".
+
+Если вы пожелаете прочитать код, JavaScript сможет стать отличным вариантом для чтения наших документов.
+
+**Ознакомьтесь с EVM**
+[`@ethereumjs/evm`](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/evm)
+
+### Узлы и клиенты {#nodes-and-clients}
+
+Клиент Ethereumjs находится в активной разработке и позволяет вам погрузиться в понимание того, как работают Ethereum клиенты на языке, который вам понятен; JavaScript!
+
+**Ознакомьтесь с клиентом**
+[`@ethereumjs/client`](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/client)
+
+## Другие проекты {#other-projects}
+
+В мире Ethereum JavaScript происходит множество других вещей, в том числе:
+
+- библиотеки утилит кошелька.
+- инструменты для генерации, импорта и экспорта ключей Ethereum.
+- реализация `merkle-patricia-tree` — структуры данных, описанной в Желтой книге Ethereum.
+
+Изучите то, что вас больше всего интересует, в [репозитории EthereumJS](https://github.com/ethereumjs).
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/programming-languages/python/index.md b/public/content/translations/ru/developers/docs/programming-languages/python/index.md
new file mode 100644
index 00000000000..fc604e1c22d
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/python/index.md
@@ -0,0 +1,99 @@
+---
+title: "Ethereum для разработчиков на Python"
+description: "Узнайте, как разрабатывать для Ethereum с использованием проектов и инструментов на основе Python"
+lang: ru
+incomplete: true
+---
+
+Узнайте, как разрабатывать для Ethereum, используя проекты и инструментарий на основе Python
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они могут работать с цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Начни программировать на Python вместе с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+- [Отчет о состоянии Python в блокчейне за 2023 год](https://tradingstrategy.ai/blog/the-state-of-python-in-blockchain-in-2023)
+
+## Статьи для начинающих {#beginner-articles}
+
+- [Обзор web3.py](https://web3py.readthedocs.io/en/latest/overview.html)
+- [Обзор экосистемы Python для Ethereum](https://snakecharmers.ethereum.org/python-ecosystem/)
+- [Руководство по Ethereum для разработчиков (на Python)](https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/)
+- [Достойный приза: руководство по хакатону Ethereum на Python](https://snakecharmers.ethereum.org/prize-worthy/)
+- [Введение в умные контракты с Vyper](https://kauri.io/#collections/Getting%20Started/an-introduction-to-smart-contracts-with-vyper/)
+- [Как разработать контракт Ethereum с помощью Python Flask?](https://medium.com/coinmonks/how-to-develop-ethereum-contract-using-python-flask-9758fe65976e)
+- [Введение в Web3.py · Ethereum для разработчиков на Python](https://www.dappuniversity.com/articles/web3-py-intro)
+- [Как вызвать функцию умного контракта с помощью Python и web3.py](https://stackoverflow.com/questions/57580702/how-to-call-a-smart-contract-function-using-python-and-web3-py)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Друзья web3.py: введение в Ape](https://snakecharmers.ethereum.org/intro-to-ape/)
+- [Разработка децентрализованных приложений для программистов на Python](https://levelup.gitconnected.com/dapps-development-for-python-developers-f52b32b54f28)
+- [Создание интерфейса Ethereum на Python: часть 1](https://hackernoon.com/creating-a-python-ethereum-interface-part-1-4d2e47ea0f4d)
+- [Умные контракты Ethereum на Python: всеобъемлющее (почти) руководство](https://hackernoon.com/ethereum-smart-contracts-in-python-a-comprehensive-ish-guide-771b03990988)
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Шаблоны web3.py: подписки на события в реальном времени](https://snakecharmers.ethereum.org/subscriptions/)
+- [Шаблоны web3.py: WebSocketProvider](https://snakecharmers.ethereum.org/websocketprovider/)
+- [Компиляция, развертывание и вызов умного контракта Ethereum с помощью Python](https://yohanes.gultom.id/2018/11/28/compiling-deploying-and-calling-ethereum-smartcontract-using-python/)
+- [Анализ умных контрактов Solidity с помощью Slither](https://kauri.io/#collections/DevOps/analyze-solidity-smart-contracts-with-slither/#analyze-solidity-smart-contracts-with-slither)
+- [Руководство по финтеху на блокчейне: кредитование и заимствование с помощью Python](https://blog.chain.link/blockchain-fintech-defi-tutorial-lending-borrowing-python/)
+
+## Архивные статьи
+
+- [Разверните свой собственный токен ERC20 с помощью Python и Brownie](https://betterprogramming.pub/python-blockchain-token-deployment-tutorial-create-an-erc20-77a5fd2e1a58)
+- [Использование Brownie и Python для развертывания умных контрактов](https://dev.to/patrickalphac/using-brownie-for-to-deploy-smart-contracts-1kkp)
+- [Создание NFT на OpenSea с помощью Brownie](https://www.freecodecamp.org/news/how-to-make-an-nft-and-render-on-opensea-marketplace/)
+
+## Проекты и инструменты на Python {#python-projects-and-tools}
+
+### Активные: {#active}
+
+- [Web3.py](https://github.com/ethereum/web3.py) – _библиотека Python для взаимодействия с Ethereum_
+- [Vyper](https://github.com/ethereum/vyper/) – _язык умных контрактов в стиле Python для EVM_
+- [Ape](https://github.com/ApeWorX/ape) – _инструмент для разработки умных контрактов для разработчиков на Python, специалистов по данным и специалистов по безопасности_
+- [py-evm](https://github.com/ethereum/py-evm) – _реализация виртуальной машины Ethereum_
+- [eth-tester](https://github.com/ethereum/eth-tester) – _инструменты для тестирования приложений на базе Ethereum_
+- [eth-utils](https://github.com/ethereum/eth-utils/) – _вспомогательные функции для работы с кодовыми базами, связанными с Ethereum_
+- [py-solc-x](https://pypi.org/project/py-solc-x/) – _оболочка на Python для компилятора Solidity solc с поддержкой версии 0.5.x_
+- [pymaker](https://github.com/makerdao/pymaker) – _Python API для контрактов Maker_
+- [siwe](https://github.com/signinwithethereum/siwe-py) – _Sign in with Ethereum (siwe) для Python_
+- [Web3 DeFi для интеграции с Ethereum](https://github.com/tradingstrategy-ai/web3-ethereum-defi) – _пакет Python с готовыми интеграциями для ERC-20, Uniswap и других популярных проектов_
+- [Wake](https://getwake.io) – _универсальный фреймворк на Python для тестирования контрактов, фаззинга, развертывания, сканирования уязвимостей и навигации по коду (языковой сервер – [Tools for Solidity](https://marketplace.visualstudio.com/items?itemName=AckeeBlockchain.tools-for-solidity))_
+
+### Архивные / Больше не поддерживаются: {#archived--no-longer-maintained}
+
+- [Trinity](https://github.com/ethereum/trinity) – _клиент Ethereum на Python_
+- [Mamba](https://github.com/arjunaskykok/mamba) – _фреймворк для написания, компиляции и развертывания умных контрактов, написанных на языке Vyper_
+- [Brownie](https://github.com/eth-brownie/brownie) – _фреймворк на Python для развертывания, тестирования и взаимодействия с умными контрактами Ethereum_
+- [pydevp2p](https://github.com/ethereum/pydevp2p) – _реализация стека P2P Ethereum_
+- [py-wasm](https://github.com/ethereum/py-wasm) – _реализация интерпретатора WebAssembly на Python_
+
+Ищешь больше статей? Посетите [ethereum.org/developers](/developers/).
+
+## Проекты, использующие инструментарий Python {#projects-using-python-tooling}
+
+Следующие проекты на основе Ethereum используют инструменты, упомянутые на этой странице. Соответствующие репозитории с открытым исходным кодом служат хорошим справочным материалом для примера кода и лучших практик.
+
+- [Yearn Finance](https://yearn.finance/) и [репозиторий контрактов хранилищ Yearn](https://github.com/yearn/yearn-vaults)
+- [Curve](https://www.curve.finance/) и [репозиторий умных контрактов Curve](https://github.com/curvefi/curve-contract)
+- [BadgerDAO](https://badger.com/) и [умные контракты, использующие инструментарий Brownie](https://github.com/Badger-Finance/badger-system)
+- [Sushi](https://sushi.com/) использует [Python для управления и развертывания своих контрактов вестинга](https://github.com/sushiswap/sushi-vesting-protocols)
+- [Alpha Finance](https://alphafinance.io/), известная благодаря Alpha Homora, использует [Brownie для тестирования и развертывания умных контрактов](https://github.com/AlphaFinanceLab/alpha-staking-contract)
+
+## Обсуждение в сообществе Python {#python-community-contributors}
+
+- [Discord-сервер сообщества Ethereum и Python](https://discord.gg/9zk7snTfWe) для обсуждения Web3.py и других фреймворков на Python
+- [Discord-сервер Vyper](https://discord.gg/SdvKC79cJk) для обсуждения программирования умных контрактов на Vyper
+
+## Другие сводные списки {#other-aggregated-lists}
+
+На вики-странице Vyper есть [невероятный список ресурсов для Vyper](https://github.com/vyperlang/vyper/wiki/Vyper-tools-and-resources)
\ No newline at end of file
diff --git a/public/content/translations/ru/developers/docs/programming-languages/ruby/index.md b/public/content/translations/ru/developers/docs/programming-languages/ruby/index.md
new file mode 100644
index 00000000000..ee1f24be64d
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/ruby/index.md
@@ -0,0 +1,60 @@
+---
+title: "Ethereum для разработчиков на Ruby"
+description: "Узнайте, как разрабатывать для Ethereum, используя проекты и инструменты на основе Ruby."
+lang: ru
+incomplete: false
+---
+
+Узнайте, как разрабатывать для Ethereum, используя проекты и инструменты на основе Ruby.
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения могут быть недоверенными, что означает, что после их развертывания в Ethereum они всегда будут работать так, как запрограммировано. Они могут управлять цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Сделайте свои первые шаги по интеграции Ruby в Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Статьи для начинающих {#beginner-articles}
+
+- [Наконец-то разбираемся в аккаунтах Ethereum](https://dev.to/q9/finally-understanding-ethereum-accounts-1kpe)
+- [Наконец-то аутентификация пользователей Rails с помощью MetaMask](https://dev.to/q9/finally-authenticating-rails-users-with-metamask-3fj)
+- [Как подключиться к сети Ethereum с помощью Ruby](https://www.quicknode.com/guides/web3-sdks/how-to-connect-to-the-ethereum-network-using-ruby)
+- [Как сгенерировать новый адрес Ethereum в Ruby](https://www.quicknode.com/guides/web3-sdks/how-to-generate-a-new-ethereum-address-in-ruby)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+- [Приложение на блокчейне с помощью Ruby](https://www.nopio.com/blog/blockchain-app-ruby/)
+- [Использование Ruby, подключенного к Ethereum, для выполнения смарт-контракта](https://titanwolf.org/Network/Articles/Article?AID=87285822-9b25-49d5-ba2a-7ad95fff7ef9)
+
+## Проекты и инструменты Ruby {#ruby-projects-and-tools}
+
+### Активные {#active}
+
+- [eth.rb](https://github.com/q9f/eth.rb) - _Библиотека Ruby и RPC-клиент для работы с аккаунтами, сообщениями и транзакциями Ethereum_
+- [keccak.rb](https://github.com/q9f/keccak.rb) - _Хеш Keccak (SHA3), используемый в Ethereum_
+- [siwe-ruby](https://github.com/signinwithethereum/siwe-ruby) - _Реализация на Ruby функции «Вход с помощью Ethereum»_
+- [siwe-rails](https://github.com/signinwithethereum/siwe-rails) - _Gem для Rails, который добавляет локальные маршруты входа через SIWE_
+- [siwe-rails-examples](https://github.com/signinwithethereum/siwe-rails-examples) - _Пример SIWE с использованием Ruby on Rails и пользовательского контроллера_
+- [omniauth-siwe](https://github.com/signinwithethereum/omniauth-siwe) - _Стратегия OmniAuth для входа с помощью Ethereum (SIWE)_
+- [omniauth-nft](https://github.com/valthon/omniauth-nft) - _Стратегия OmniAuth для аутентификации через владение NFT_
+- [ethereum-on-rails](https://github.com/q9f/ethereum-on-rails) - _Шаблон Ethereum on Rails, позволяющий подключить MetaMask к Ruby on Rails_
+
+### Архивные / Больше не поддерживаются {#archived--no-longer-maintained}
+
+- [web3-eth](https://github.com/spikewilliams/vtada-ethereum) - _Вызов методов RPC узла Ethereum с помощью Ruby_
+- [ethereum_tree](https://github.com/longhoangwkm/ethereum_tree) - _Библиотека Ruby для генерации адресов ETH из иерархически детерминированного кошелька в соответствии со стандартом BIP32_
+- [etherlite](https://github.com/budacom/etherlite) - _Интеграция Ethereum для Ruby on Rails_
+- [ethereum.rb](https://github.com/EthWorks/ethereum.rb) - _Клиент Ethereum на Ruby, использующий интерфейс JSON-RPC для отправки транзакций, создания контрактов и взаимодействия с ними, а также полезный набор инструментов для работы с узлом Ethereum_
+- [omniauth-ethereum.rb](https://github.com/q9f/omniauth-ethereum.rb) - _Реализует стратегию провайдера Ethereum для OmniAuth_
+
+Ищешь больше статей? Посетите [главную страницу для разработчиков](/developers/).
+
+## Участники сообщества Ruby {#ruby-community-contributors}
+
+[Telegram-группа Ethereum Ruby](https://t.me/ruby_eth) — это быстрорастущее сообщество и специальный ресурс для обсуждения любого из вышеупомянутых проектов и связанных с ними тем.
diff --git a/public/content/translations/ru/developers/docs/programming-languages/rust/index.md b/public/content/translations/ru/developers/docs/programming-languages/rust/index.md
new file mode 100644
index 00000000000..6bde54a902c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/programming-languages/rust/index.md
@@ -0,0 +1,65 @@
+---
+title: "Ethereum для разработчиков на Rust"
+description: "Узнайте, как разрабатывать для Ethereum, используя проекты и инструменты на основе ржавчины"
+lang: ru
+incomplete: true
+---
+
+Узнайте, как разрабатывать для Ethereum с помощью проектов и инструментов на основе Rust
+
+Используйте Ethereum для создания децентрализованных приложений (или «dapp»), использующих преимущества криптовалют и технологии блокчейн. Эти децентрализованные приложения надежны, а это значит, что после развертывания в Ethereum они всегда будут работать в соответствии с программой. Они могут работать с цифровыми активами для создания новых видов финансовых приложений. Они могут быть децентрализованными, что означает, что ни одно юридическое лицо или лицо не контролирует их, и их практически невозможно подвергнуть цензуре.
+
+## Начало работы с умными контрактами и языком Solidity {#getting-started-with-smart-contracts-and-solidity}
+
+**Сделайте свои первые шаги интеграции Rust с Ethereum**
+
+Нужен простой пример для начала? Посетите [ethereum.org/learn](/learn/) или [ethereum.org/developers](/developers/).
+
+- [Объяснение блокчейна](https://kauri.io/article/d55684513211466da7f8cc03987607d5/blockchain-explained)
+- [Понимание умных контрактов](https://kauri.io/article/e4f66c6079e74a4a9b532148d3158188/ethereum-101-part-5-the-smart-contract)
+- [Напишите свой первый умный контракт](https://kauri.io/article/124b7db1d0cf4f47b414f8b13c9d66e2/remix-ide-your-first-smart-contract)
+- [Узнайте, как компилировать и развертывать код на Solidity](https://kauri.io/article/973c5f54c4434bb1b0160cff8c695369/understanding-smart-contract-compilation-and-deployment)
+
+## Статьи для начинающих {#beginner-articles}
+
+- [Клиент Rust Ethereum](https://openethereum.github.io/) \* **Обратите внимание, что OpenEthereum [был признан устаревшим](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd) и больше не поддерживается.** Используйте его с осторожностью и по возможности переключитесь на другую реализацию клиента.
+- [Отправка транзакции в Ethereum с помощью Rust](https://kauri.io/#collections/A%20Hackathon%20Survival%20Guide/sending-ethereum-transactions-with-rust/)
+- [Пошаговое руководство по написанию контрактов на Rust Wasm для Kovan](https://github.com/paritytech/pwasm-tutorial)
+
+## Статьи для среднего уровня {#intermediate-articles}
+
+## Продвинутые модели использования {#advanced-use-patterns}
+
+- [Библиотека pwasm_ethereum externs для взаимодействия с сетями, подобными Ethereum](https://github.com/openethereum/pwasm-ethereum)
+
+- [Создание децентрализованного чата с использованием JavaScript и Rust](https://medium.com/perlin-network/build-a-decentralized-chat-using-javascript-rust-webassembly-c775f8484b52)
+
+- [Создание децентрализованного приложения-планировщика на Vue.js и Rust](https://medium.com/@jjmace01/build-a-decentralized-todo-app-using-vue-js-rust-webassembly-5381a1895beb)
+
+- [Создание блокчейна на Rust](https://blog.logrocket.com/how-to-build-a-blockchain-in-rust/)
+
+## Проекты и инструменты на Rust {#rust-projects-and-tools}
+
+- [pwasm-ethereum](https://github.com/paritytech/pwasm-ethereum) - _Коллекция externs для взаимодействия с сетями, подобными Ethereum_
+- [Lighthouse](https://github.com/sigp/lighthouse) - _Быстрый клиент уровня консенсуса Ethereum_
+- [Ethereum WebAssembly](https://ewasm.readthedocs.io/en/mkdocs/) - _Предлагаемая реструктуризация уровня исполнения смарт-контрактов Ethereum с использованием детерминированного подмножества WebAssembly_
+- [oasis_std](https://docs.rs/oasis-std/latest/oasis_std/index.html) - _Справочник по API OASIS_
+- [Solaris](https://github.com/paritytech/sol-rs) - _Инструмент для модульного тестирования смарт-контрактов Solidity, использующий нативный EVM клиента Parity._
+- [SputnikVM](https://github.com/rust-blockchain/evm) - _Реализация виртуальной машины Ethereum на Rust_
+- [Wavelet](https://wavelet.perlin.net/docs/smart-contracts) - _Смарт-контракт Wavelet на Rust_
+- [Foundry](https://github.com/foundry-rs/foundry) - _Набор инструментов для разработки приложений Ethereum_
+- [Alloy](https://alloy.rs) - _Высокопроизводительные, хорошо протестированные и документированные библиотеки для взаимодействия с Ethereum и другими блокчейнами на основе EVM._
+- [Ethers_rs](https://github.com/gakonst/ethers-rs) - _Библиотека Ethereum и реализация кошелька_
+- [SewUp](https://github.com/second-state/SewUp) - _Библиотека, которая поможет вам создавать смарт-контракты Ethereum WebAssembly на Rust так же просто, как при разработке обычного бэкенда_
+- [Substreams](https://github.com/streamingfast/substreams) - _Технология параллельного индексирования данных блокчейна_
+- [Reth](https://github.com/paradigmxyz/reth) Reth (сокращение от Rust Ethereum) — это новая реализация полного узла Ethereum
+- [Awesome Ethereum Rust](https://github.com/Vid201/awesome-ethereum-rust) - _Тщательно подобранная коллекция проектов в экосистеме Ethereum, написанных на Rust_
+
+Ищешь больше статей? Посетите [ethereum.org/developers.](/developers/)
+
+## Участники сообщества Rust {#rust-community-contributors}
+
+- [Ethereum WebAssembly](https://gitter.im/ewasm/Lobby)
+- [Oasis Gitter](https://gitter.im/Oasis-official/Lobby)
+- [Parity Gitter](https://gitter.im/paritytech/parity)
+- [Enigma](https://discord.gg/SJK32GY)
diff --git a/public/content/translations/ru/developers/docs/scaling/index.md b/public/content/translations/ru/developers/docs/scaling/index.md
new file mode 100644
index 00000000000..7eddd4b3589
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/index.md
@@ -0,0 +1,113 @@
+---
+title: "Масштабирование"
+description: "Введение в различные варианты масштабирования, которые в настоящее время разрабатывает сообщество Ethereum."
+lang: ru
+sidebarDepth: 3
+---
+
+## Обзор масштабирования {#scaling-overview}
+
+По мере роста числа людей, использующих Ethereum, блокчейн достиг определенных ограничений по мощности. Это привело к увеличению стоимости использования сети, создавая потребность в «решениях для масштабирования» В настоящее время исследуются, тестируются и внедряются несколько решений, в которых используются разные подходы для достижения схожих целей.
+
+Основная цель масштабируемости — повысить скорость транзакций (ускорить финализацию) и пропускную способность (увеличить количество транзакций в секунду) без ущерба для децентрализации и безопасности. В блокчейне Ethereum уровня 1 высокий спрос приводит к замедлению транзакций и непомерным [ценам на газ](/developers/docs/gas/). Увеличение пропускной способности сети с точки зрения скорости и пропускной способности имеет фундаментальное значение для значимого и массового внедрения Ethereum.
+
+Хотя скорость и пропускная способность важны, важно, чтобы решения для масштабирования, позволяющие достичь этих целей, оставались децентрализованными и безопасными. Сохранение низкого барьера для входа для операторов узлов имеет решающее значение для предотвращения перехода к централизованным и небезопасным вычислительным мощностям.
+
+Концептуально мы сначала классифицируем масштабирование на ончейн-масштабирование и оффчейн-масштабирование.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны хорошо понимать все основные темы. Реализация решений масштабирования продвигается вперед, поскольку технология менее проверена в боевых условиях, а ее исследования и разработки продолжаются.
+
+## Ончейн-масштабирование {#onchain-scaling}
+
+Ончейн-масштабирование требует внесения изменений в протокол Ethereum (уровень 1 [основной сети](/glossary/#mainnet)). Долгое время масштабирование Ethereum предполагалось реализовать с помощью шардинга. В результате этого блокчейн был бы разделён на частички (шарды), которые бы верифицировались набором валидаторов. Однако, масштабирование с помощью роллапов (обёрток) 2-го уровня было выбрано приоритетным методом. Этот вариант также усилился реализацией более дешевого метода прикрепления даты в блоки Ethereum, специально разработанного чтобы сделать роллапы (обёртки) дешевыми для пользователей.
+
+### Шардинг {#sharding}
+
+Шардинг — это процесс расщепления базы данных. Подряды валидаторов ответственны за индивидуальные шарды, и не нуждаются в отслеживании всего состояния сети Ethereum. Шардинг долгое время был частью [дорожной карты](/roadmap/) Ethereum, и его планировалось запустить до перехода на proof-of-stake в рамках «Слияния» (The Merge). Однако быстрое развитие [ролл-апов уровня 2](#layer-2-scaling) и изобретение [Danksharding](/roadmap/danksharding) (добавление больших двоичных объектов с данными ролл-апов в блоки Ethereum, которые могут очень эффективно проверяться валидаторами) привело к тому, что сообщество Ethereum предпочло масштабирование, ориентированное на ролл-апы, вместо масштабирования с помощью шардинга. Это также позволило оставить простую логику консенсуса Ethereum.
+
+## Оффчейн-масштабирование {#offchain-scaling}
+
+Оффчейн-решения реализуются отдельно от основной сети (Mainnet) уровня 1 — они не требуют изменений в существующем протоколе Ethereum. Некоторые решения, известные как решения «уровня 2», получают свою безопасность непосредственно от консенсуса Ethereum уровня 1. К ним относятся [оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups/), [ролл-апы с нулевым разглашением](/developers/docs/scaling/zk-rollups/) или [каналы состояния](/developers/docs/scaling/state-channels/). Другие решения подразумевают создание новых цепей в различных формах, безопасность которых обеспечивается отдельно от основной сети (Mainnet), например [сайдчейны](#sidechains), [валидиумы](#validium) или [плазменные цепи](#plasma). Эти решения взаимодействуют с основной сетью (Mainnet), но для достижения различных целей по-разному обеспечивают свою безопасность.
+
+### Масштабирование уровня 2 {#layer-2-scaling}
+
+Эта категория оффчейн-решений получает свою безопасность от основной сети Ethereum (Mainnet).
+
+Уровень 2 - это собирательный термин для решений, разработанных для помощи в масштабировании Вашего приложения, используя обработку транзакций вне основной сети Ethereum (уровень 1), пользуясь преимуществом высокой децентрализации модели надежности Основной сети. Скорость транзакций снижается, когда сеть занята, что ухудшает пользовательский опыт для некоторых типов dapps. По мере того, как сеть становится более загруженной, цены на газ растут, поскольку отправители транзакций стремятся перебить цену друг друга. Это может сделать использование Ethereum очень дорогим.
+
+Большинство решений уровня 2 сосредоточено вокруг сервера или кластера серверов, каждый из которых может называться узлом, валидатором, оператором, секвенсором, производителем блоков или аналогичным термином. В зависимости от реализации, эти узлы уровня 2 могут запускаться отдельными лицами, предприятиями или организациями, которые их используют, или сторонним оператором, или большой группой лиц (аналогично Mainnet). Вообще говоря, транзакции отправляются на эти узлы уровня 2, а не напрямую на уровень 1 (Mainnet). В некоторых решениях экземпляр уровня 2 объединяет транзакции в группы перед их закреплением на уровне 1, после чего они защищаются уровнем 1 и не могут быть изменены. Детали того, как это делается, значительно различаются между различными технологиями и реализациями уровня 2.
+
+Конкретный экземпляр уровня 2 может быть открытым и совместно использоваться многими приложениями или может быть развернут одним проектом и предназначен для поддержки только своего приложения.
+
+#### Зачем нужен слой 2? {#why-is-layer-2-needed}
+
+- Увеличение количества транзакций в секунду значительно улучшает пользовательский опыт и снижает перегрузку сети в Mainnet Ethereum.
+- Транзакции объединяются в одну транзакцию в основной сети Ethereum (Mainnet), что снижает плату за газ для пользователей и делает Ethereum более инклюзивным и доступным для людей во всем мире.
+- Любые обновления масштабируемости не должны происходить за счет децентрализации или безопасности - уровень 2 строится поверх Ethereum.
+- Существуют специализированные сети уровня 2, которые обеспечивают собственный набор преимуществ при работе с активами в больших масштабах.
+
+[Подробнее об уровне 2](/layer-2/).
+
+#### Ролл-апы {#rollups}
+
+Свертывания выполняют транзакцию за пределами уровня 1, а затем данные отправляются на уровень 1, где достигается консенсус. Поскольку данные транзакции включены в блоки уровня 1, это позволяет защищать свертки с помощью собственной системы безопасности Ethereum.
+
+Есть два типа накопительных пакетов с разными моделями безопасности:
+
+- **Оптимистические ролл-апы**: по умолчанию предполагают, что транзакции действительны, и выполняют вычисления через [**доказательство мошенничества**](/glossary/#fraud-proof) только в случае оспаривания. [Подробнее об оптимистических ролл-апах](/developers/docs/scaling/optimistic-rollups/).
+- **Ролл-апы с нулевым разглашением**: выполняют вычисления оффчейн и предоставляют в сеть [**доказательство достоверности**](/glossary/#validity-proof). [Подробнее о ролл-апах с нулевым разглашением](/developers/docs/scaling/zk-rollups/).
+
+#### Каналы состояния {#channels}
+
+State channels utilize multisig contracts to enable participants to transact quickly and freely offchain, then settle finality with Mainnet. Это сводит к минимуму перегрузку сети, сборы и задержки. В настоящее время двумя типами каналов являются каналы состояния и каналы оплаты.
+
+Подробнее о [каналах состояния](/developers/docs/scaling/state-channels/).
+
+### Сайдчейны {#sidechains}
+
+Сайдчейн — это независимый, совместимый с EVM блокчейн, который работает параллельно с основной сетью (Mainnet). Они совместимы с Ethereum через двусторонние мосты и работают по собственным правилам консенсуса и с собственными параметрами блоков.
+
+Подробнее о [сайдчейнах](/developers/docs/scaling/sidechains/).
+
+### Плазма {#plasma}
+
+Плазменная цепь — это отдельный блокчейн, который привязан к основной цепи Ethereum и использует доказательства мошенничества (как [оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups/)) для разрешения споров.
+
+Подробнее о [плазме](/developers/docs/scaling/plasma/).
+
+### Валидиум {#validium}
+
+Цепь Валидиум использует доказательства валидности, такие как ролл-апы с нулевым разглашением, но данные не хранятся на основном уровне 1 сети Ethereum. Это может привести к 10 тысячам транзакций в секунду на цепочку Валидиум и несколько цепочек может быть запущено параллельно.
+
+Подробнее о [валидиуме](/developers/docs/scaling/validium/).
+
+## Зачем нужно столько масштабных решений? {#why-do-we-need-these}
+
+- Различные решения могут помочь снизить общую перегрузку на любом участке сети, а также предотвратить появление единых точек отказа.
+- Целое больше, чем сумма его частей. Различные решения могут существовать и работать в гармонии, что дает экспоненциальный эффект на скорость и пропускную способность транзакций в будущем.
+- Не все решения требуют прямого использования алгоритма консенсуса Ethereum, а альтернативы могут предложить преимущества, которые иначе было бы трудно получить.
+
+## Больше увлекаетесь визуализацией? {#visual-learner}
+
+
+
+_Обратите внимание: в видео термин «Layer 2» используется для обозначения всех решений масштабирования вне основной цепи, тогда как мы различаем «Layer 2» как решение вне основной цепи, которое получает свою безопасность через консенсус основной сети Layer 1 Mainnet._
+
+
+
+## Дополнительные материалы {#further-reading}
+
+- [Дорожная карта Ethereum, ориентированная на ролл-апы](https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698) _Виталик Бутерин_
+- [Актуальная аналитика по решениям масштабирования уровня 2 для Ethereum](https://www.l2beat.com/)
+- [Оценка решений масштабирования уровня 2 для Ethereum: система сравнения](https://medium.com/matter-labs/evaluating-ethereum-l2-scaling-solutions-a-comparison-framework-b6b2f410f955)
+- [Неполное руководство по ролл-апам](https://vitalik.eth.limo/general/2021/01/05/rollup.html)
+- [ZK-ролл-апы на базе Ethereum: покорители мира](https://hackmd.io/@canti/rkUT0BD8K)
+- [Оптимистические ролл-апы или ZK-ролл-апы](https://limechain.tech/blog/optimistic-rollups-vs-zk-rollups/)
+- [Почему ролл-апы и шардинг данных — единственное устойчивое решение для высокой масштабируемости](https://polynya.medium.com/why-rollups-data-shards-are-the-only-sustainable-solution-for-high-scalability-c9aabd6fbb48)
+- [Какие решения уровня 3 имеют смысл?](https://vitalik.eth.limo/general/2022/09/17/layer_3.html)
+- [Доступность данных, или: как ролл-апы научились не волноваться и полюбили Ethereum](https://web.archive.org/web/20250515194659/https://web.archive.org/web/20241108192208/https/research.2077.xyz/data-availability-or-how-rollups-learned-to-stop-worrying-and-love-ethereum)
+- [Практическое руководство по ролл-апам Ethereum](https://web.archive.org/web/20241108192208/https://research.2077.xyz/the-practical-guide-to-ethereum-rollups)
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/scaling/optimistic-rollups/index.md b/public/content/translations/ru/developers/docs/scaling/optimistic-rollups/index.md
new file mode 100644
index 00000000000..756cbb60e4a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/optimistic-rollups/index.md
@@ -0,0 +1,265 @@
+---
+title: "Оптимистичный ролл-ап"
+description: "Введение в оптимистичные роллапы — решение для масштабирования, используемое сообществом Ethereum."
+lang: ru
+---
+
+Оптимистичные свертки — это протоколы уровня 2 (L2), предназначенные для расширения пропускной способности базового уровня Ethereum. Они сокращают объем вычислений в основной цепочке Ethereum за счет обработки транзакций вне цепочки, что обеспечивает значительное повышение скорости обработки. В отличие от других решений для масштабирования, таких как [сайдчейны](/developers/docs/scaling/sidechains/), оптимистические ролл-апы обеспечивают безопасность за счет основной сети, публикуя результаты транзакций в сети (on-chain), или [цепей Plasma](/developers/docs/scaling/plasma/), которые также проверяют транзакции в Ethereum с помощью доказательств мошенничества, но хранят данные транзакций в другом месте.
+
+Поскольку вычисления — это медленная и затратная часть использования Ethereum, оптимистичные накопления могут обеспечить улучшение масштабируемости в 10–100 раз. Оптимистические ролл-апы также записывают транзакции в Ethereum как `calldata` или в виде [блобов](/roadmap/danksharding/), что снижает расходы пользователей на газ.
+
+## Предварительные условия {#prerequisites}
+
+Вам следует прочитать и понять наши страницы о [масштабировании Ethereum](/developers/docs/scaling/) и [уровне 2](/layer-2/).
+
+## Что такое оптимистичный свертывающий прогноз? {#what-is-an-optimistic-rollup}
+
+Оптимистичный подход к масштабированию Ethereum подразумевает перемещение вычислений и хранения состояний за пределы блокчейна. Оптимистические ролл-апы выполняют транзакции вне Ethereum, но публикуют данные транзакций в основной сети в виде `calldata` или в [блобах](/roadmap/danksharding/).
+
+Оптимистичные операторы объединяют несколько офчейн-транзакций в большие пакеты перед отправкой в Ethereum. Такой подход позволяет распределить фиксированные издержки по нескольким транзакциям в каждом пакете, снижая комиссию для конечных пользователей. Оптимистичные свертки также используют методы сжатия для уменьшения объема данных, размещаемых на Ethereum.
+
+Оптимистичные свертки считаются «оптимистичными», поскольку они предполагают, что транзакции вне сети являются действительными, и не публикуют доказательства действительности для пакетов транзакций, размещенных в сети. Это отличает оптимистические ролл-апы от [ролл-апов с 0-знанием](/developers/docs/scaling/zk-rollups), которые публикуют криптографические [доказательства действительности](/glossary/#validity-proof) для транзакций вне сети.
+
+Вместо этого оптимистические ролл-апы используют схему доказательства мошенничества для выявления случаев, когда транзакции рассчитываются неверно. После того как пакет ролл-апа отправлен в Ethereum, есть временное окно (называемое периодом оспаривания), в течение которого любой может оспорить результаты транзакции ролл-апа, вычислив [доказательство мошенничества](/glossary/#fraud-proof).
+
+Если доказательство мошенничества будет успешным, протокол ролл-апа повторно выполнит транзакцию (транзакции) и соответствующим образом обновит состояние ролл-апа. Другим следствием успешного доказательства мошенничества является то, что Секвенсор, ответственный за включение неверно выполненной транзакции в блок, получает штраф.
+
+Если пакет ролл-апа остается неоспоренным (т. е. все транзакции выполнены правильно) по истечении периода оспаривания, он считается действительным и принимается в Ethereum. Другие могут продолжать строить на неподтвержденном блоке ролл-апа, но с оговоркой: результаты транзакций будут отменены, если они основаны на неверно выполненной транзакции, опубликованной ранее.
+
+## Как оптимистические ролл-апы взаимодействуют с Ethereum? {#optimistic-rollups-and-Ethereum}
+
+Оптимистические ролл-апы — это [решения для масштабирования вне сети](/developers/docs/scaling/#offchain-scaling), созданные для работы поверх Ethereum. Каждый оптимистический ролл-ап управляется набором смарт-контрактов, развернутых в сети Ethereum. Оптимистические ролл-апы обрабатывают транзакции вне основной цепи Ethereum, но публикуют транзакции вне сети (пакетами) в контракте ролл-апа в сети. Как и блокчейн Ethereum, эта запись транзакций является неизменной и образует "цепь оптимистического ролл-апа".
+
+Архитектура оптимистического ролл-апа включает следующие части:
+
+**Контракты в сети**: работа оптимистического ролл-апа контролируется смарт-контрактами, работающими в Ethereum. Это включает контракты, которые хранят блоки ролл-апа, отслеживают обновления состояния в ролл-апе и отслеживают депозиты пользователей. В этом смысле Ethereum служит базовым уровнем, или "уровнем 1", для оптимистических ролл-апов.
+
+**Виртуальная машина вне сети (VM)**: хотя контракты, управляющие протоколом оптимистического ролл-апа, работают в Ethereum, протокол ролл-апа выполняет вычисления и хранение состояний на другой виртуальной машине, отдельной от [виртуальной машины Ethereum](/developers/docs/evm/). VM вне сети — это место, где находятся приложения и выполняются изменения состояния; она служит верхним уровнем, или "уровнем 2", для оптимистического ролл-апа.
+
+Поскольку оптимистические ролл-апы предназначены для запуска программ, написанных или скомпилированных для EVM, VM вне сети включает в себя многие проектные спецификации EVM. Кроме того, доказательства мошенничества, вычисленные в сети, позволяют сети Ethereum обеспечивать действительность изменений состояния, вычисленных в VM вне сети.
+
+Оптимистические ролл-апы описываются как 'гибридные решения для масштабирования', потому что, хотя они существуют как отдельные протоколы, их свойства безопасности унаследованы от Ethereum. Помимо прочего, Ethereum гарантирует правильность вычислений ролл-апа вне сети и доступность данных, лежащих в основе этих вычислений. Это делает оптимистические ролл-апы более безопасными, чем чисто протоколы масштабирования вне сети (например, [сайдчейны](/developers/docs/scaling/sidechains/)), которые не полагаются на Ethereum для обеспечения безопасности.
+
+Оптимистические ролл-апы полагаются на основной протокол Ethereum в следующих аспектах:
+
+### Доступность данных {#data-availability}
+
+Как уже упоминалось, оптимистические ролл-апы публикуют данные транзакций в Ethereum в виде `calldata` или [блобов](/roadmap/danksharding/). Поскольку выполнение цепи ролл-апа основано на отправленных транзакциях, любой может использовать эту информацию, закрепленную на базовом уровне Ethereum, для выполнения состояния ролл-апа и проверки правильности переходов состояний.
+
+[Доступность данных](/developers/docs/data-availability/) имеет решающее значение, поскольку без доступа к данным о состоянии оспаривающие стороны не могут создавать доказательства мошенничества для оспаривания недействительных операций ролл-апа. Благодаря тому, что Ethereum обеспечивает доступность данных, снижается риск того, что операторы ролл-апа смогут безнаказанно совершать злонамеренные действия (например, отправлять недействительные блоки).
+
+### Устойчивость к цензуре {#censorship-resistance}
+
+Оптимистические ролл-апы также полагаются на Ethereum для обеспечения устойчивости к цензуре. В оптимистическом ролл-апе централизованная сущность (оператор) отвечает за обработку транзакций и отправку блоков ролл-апа в Ethereum. Это имеет некоторые последствия:
+
+- Операторы ролл-апа могут подвергать пользователей цензуре, полностью отключаясь от сети или отказываясь создавать блоки, включающие в себя определенные транзакции.
+
+- Операторы ролл-апа могут помешать пользователям выводить средства, внесенные в контракт ролл-апа, удерживая данные о состоянии, необходимые для доказательств владения Меркла. Удержание данных о состоянии также может скрыть состояние ролл-апа от пользователей и помешать им взаимодействовать с ролл-апом.
+
+Оптимистические ролл-апы решают эту проблему, заставляя операторов публиковать данные, связанные с обновлениями состояния, в Ethereum. Публикация данных ролл-апа в сети имеет следующие преимущества:
+
+- Если оператор оптимистического ролл-апа отключается от сети или прекращает создавать пакеты транзакций, другой узел может использовать доступные данные для воспроизведения последнего состояния ролл-апа и продолжения производства блоков.
+
+- Пользователи могут использовать данные транзакций для создания доказательств Меркла, подтверждающих владение средствами, и выводить свои активы из ролл-апа.
+
+- Пользователи также могут отправлять свои транзакции на L1 вместо Секвенсора, и в этом случае Секвенсор должен включить транзакцию в течение определенного времени, чтобы продолжать создавать действительные блоки.
+
+### Расчет {#settlement}
+
+Еще одна роль, которую Ethereum играет в контексте оптимистических ролл-апов, — это роль расчетного уровня. Расчетный уровень закрепляет всю экосистему блокчейна, обеспечивает безопасность и объективную окончательность в случае возникновения спора на другой цепи (в данном случае, на оптимистических ролл-апах), требующего арбитража.
+
+Основная сеть Ethereum предоставляет центр для оптимистических ролл-апов для проверки доказательств мошенничества и разрешения споров. Более того, транзакции, проведенные в ролл-апе, становятся окончательными только _после_ того, как блок ролл-апа будет принят в Ethereum. Как только транзакция ролл-апа зафиксирована на базовом уровне Ethereum, ее нельзя отменить (за исключением крайне маловероятного случая реорганизации цепи).
+
+## Как работают оптимистические ролл-апы? {#how-optimistic-rollups-work}
+
+### Выполнение и агрегация транзакций {#transaction-execution-and-aggregation}
+
+Пользователи отправляют транзакции "операторам" — узлам, ответственным за обработку транзакций в оптимистическом ролл-апе. Также известный как "валидатор" или "агрегатор", оператор агрегирует транзакции, сжимает базовые данные и публикует блок в Ethereum.
+
+Хотя любой может стать валидатором, валидаторы оптимистического ролл-апа должны предоставить залог перед созданием блоков, подобно [системе proof-of-stake](/developers/docs/consensus-mechanisms/pos/). Этот залог может быть уменьшен (slashed), если валидатор публикует недействительный блок или строит на старом, но недействительном блоке (даже если его собственный блок действителен). Таким образом, оптимистические ролл-апы используют криптоэкономические стимулы для обеспечения честной работы валидаторов.
+
+Ожидается, что другие валидаторы в цепи оптимистического ролл-апа будут выполнять отправленные транзакции, используя свою копию состояния ролл-апа. Если конечное состояние валидатора отличается от предложенного состояния оператора, они могут начать оспаривание и вычислить доказательство мошенничества.
+
+Некоторые оптимистические ролл-апы могут отказаться от безразрешительной системы валидаторов и использовать одного "Секвенсора" для выполнения цепи. Подобно валидатору, Секвенсор обрабатывает транзакции, создает блоки ролл-апа и отправляет транзакции ролл-апа в цепь L1 (Ethereum).
+
+Секвенсор отличается от обычного оператора ролл-апа, поскольку он имеет больший контроль над порядком транзакций. Кроме того, Секвенсор имеет приоритетный доступ к цепи ролл-апа и является единственным субъектом, уполномоченным отправлять транзакции в контракт в сети. Транзакции от узлов, не являющихся Секвенсорами, или от обычных пользователей просто ставятся в очередь в отдельный почтовый ящик, пока Секвенсор не включит их в новый пакет.
+
+#### Отправка блоков ролл-апа в Ethereum {#submitting-blocks-to-ethereum}
+
+Как уже упоминалось, оператор оптимистического ролл-апа объединяет транзакции вне сети в пакет и отправляет его в Ethereum для нотариального заверения. Этот процесс включает сжатие данных, связанных с транзакциями, и их публикацию в Ethereum в виде `calldata` или в виде блобов.
+
+`calldata` — это немодифицируемая, непостоянная область в смарт-контракте, которая в основном ведет себя как [память](/developers/docs/smart-contracts/anatomy/#memory). Хотя `calldata` сохраняется в сети как часть [журналов истории](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html?highlight=memory#logs) блокчейна, она не хранится как часть состояния Ethereum. Поскольку `calldata` не затрагивает ни одну часть состояния Ethereum, она дешевле, чем состояние, для хранения данных в сети.
+
+Ключевое слово `calldata` также используется в Solidity для передачи аргументов в функцию смарт-контракта во время выполнения. `calldata` идентифицирует вызываемую функцию во время транзакции и содержит входные данные для функции в виде произвольной последовательности байтов.
+
+В контексте оптимистических ролл-апов `calldata` используется для отправки сжатых данных транзакций в контракт в сети. Оператор ролл-апа добавляет новый пакет, вызывая требуемую функцию в контракте ролл-апа и передавая сжатые данные в качестве аргументов функции. Использование `calldata` снижает комиссию для пользователей, поскольку большинство затрат, которые несут ролл-апы, связаны с хранением данных в сети.
+
+Вот [пример](https://eth.blockscout.com/tx/0x9102bfce17c58b5fc1c974c24b6bb7a924fb5fbd7c4cd2f675911c27422a5591) отправки пакета ролл-апа, чтобы показать, как работает эта концепция. Секвенсор вызвал метод `appendSequencerBatch()` и передал сжатые данные транзакции в качестве входных данных с помощью `calldata`.
+
+Некоторые ролл-апы теперь используют блобы для отправки пакетов транзакций в Ethereum.
+
+Блобы немодифицируемы и непостоянны (как и `calldata`), но удаляются из истории примерно через 18 дней. Для получения дополнительной информации о блобах см. [Danksharding](/roadmap/danksharding).
+
+### Обязательства по состоянию {#state-commitments}
+
+В любой момент времени состояние оптимистического ролл-апа (аккаунты, балансы, код контракта и т. д.) организовано в виде [дерева Меркла](/whitepaper/#merkle-trees), называемого «деревом состояний». Корень этого дерева Меркла (корень состояния), который ссылается на последнее состояние ролл-апа, хэшируется и хранится в контракте ролл-апа. Каждый переход состояния в цепи создает новое состояние ролл-апа, которое оператор фиксирует, вычисляя новый корень состояния.
+
+Оператор должен отправлять как старые, так и новые корни состояний при публикации пакетов. Если старый корень состояния совпадает с существующим корнем состояния в контракте в сети, последний отбрасывается и заменяется новым корнем состояния.
+
+Оператор ролл-апа также должен зафиксировать корень Меркла для самого пакета транзакций. Это позволяет любому доказать включение транзакции в пакет (на L1), представив [доказательство Меркла](/developers/tutorials/merkle-proofs-for-offline-data-integrity/).
+
+Фиксации состояний, особенно корни состояний, необходимы для доказательства правильности изменений состояний в оптимистическом ролл-апе. Контракт ролл-апа принимает новые корни состояний от операторов сразу после их публикации, но может позже удалить недействительные корни состояний, чтобы восстановить ролл-ап до его правильного состояния.
+
+### Доказательство мошенничества {#fraud-proving}
+
+Как уже объяснялось, оптимистические ролл-апы позволяют любому публиковать блоки без предоставления доказательств действительности. Однако для обеспечения безопасности цепи оптимистические ролл-апы определяют временное окно, в течение которого любой может оспорить переход состояния. Поэтому блоки ролл-апа называются «утверждениями», так как любой может оспорить их действительность.
+
+Если кто-то оспаривает утверждение, протокол ролл-апа инициирует вычисление доказательства мошенничества. Каждый тип доказательства мошенничества является интерактивным — кто-то должен опубликовать утверждение, прежде чем другой сможет его оспорить. Разница заключается в том, сколько раундов взаимодействия требуется для вычисления доказательства мошенничества.
+
+Однораундовые интерактивные схемы доказательства воспроизводят оспариваемые транзакции на L1 для выявления недействительных утверждений. Протокол ролл-апа эмулирует повторное выполнение оспариваемой транзакции на L1 (Ethereum) с использованием контракта-верификатора, при этом вычисленный корень состояния определяет, кто выигрывает оспаривание. Если утверждение оспаривающей стороны о правильном состоянии ролл-апа верно, оператор наказывается уменьшением (slashing) своего залога.
+
+Однако повторное выполнение транзакций на L1 для выявления мошенничества требует публикации фиксаций состояний для отдельных транзакций и увеличивает объем данных, которые ролл-апы должны публиковать в сети. Повторное воспроизведение транзакций также влечет за собой значительные затраты на газ. По этим причинам оптимистические ролл-апы переходят на многораундовое интерактивное доказательство, которое достигает той же цели (т. е. выявление недействительных операций ролл-апа) с большей эффективностью.
+
+#### Многораундовое интерактивное доказательство {#multi-round-interactive-proving}
+
+Многораундовое интерактивное доказательство включает в себя протокол взаимодействия между утверждающей и оспаривающей сторонами под контролем контракта-верификатора L1, который в конечном итоге определяет лгущую сторону. После того как узел L2 оспаривает утверждение, утверждающая сторона должна разделить оспариваемое утверждение на две равные половины. Каждое отдельное утверждение в этом случае будет содержать столько же шагов вычислений, сколько и другое.
+
+Затем оспаривающая сторона выберет, какое утверждение она хочет оспорить. Процесс деления (называемый «протоколом деления пополам») продолжается до тех пор, пока обе стороны не будут оспаривать утверждение об _одном_ шаге выполнения. На этом этапе контракт L1 разрешит спор, оценив инструкцию (и ее результат), чтобы поймать мошенническую сторону.
+
+Утверждающая сторона должна предоставить «одношаговое доказательство», подтверждающее действительность оспариваемого одношагового вычисления. Если утверждающая сторона не предоставляет одношаговое доказательство, или верификатор L1 считает доказательство недействительным, она проигрывает оспаривание.
+
+Некоторые замечания об этом типе доказательства мошенничества:
+
+1. Многораундовое интерактивное доказательство мошенничества считается эффективным, поскольку оно минимизирует работу, которую должна выполнять цепь L1 при арбитраже споров. Вместо повторного воспроизведения всей транзакции, цепи L1 нужно только повторно выполнить один шаг в выполнении ролл-апа.
+
+2. Протоколы деления пополам уменьшают объем данных, публикуемых в сети (нет необходимости публиковать фиксации состояний для каждой транзакции). Кроме того, транзакции оптимистического ролл-апа не ограничены лимитом газа Ethereum. И наоборот, оптимистические ролл-апы, повторно выполняющие транзакции, должны убедиться, что транзакция L2 имеет более низкий лимит газа для эмуляции ее выполнения в рамках одной транзакции Ethereum.
+
+3. Часть залога злонамеренного утверждающего присуждается оспаривающей стороне, а другая часть сжигается. Сжигание предотвращает сговор между валидаторами; если два валидатора вступят в сговор для инициирования фиктивных оспариваний, они все равно лишатся значительной части всей своей ставки.
+
+4. Многораундовое интерактивное доказательство требует, чтобы обе стороны (утверждающая и оспаривающая) делали ходы в течение указанного временного окна. Невыполнение действий до истечения срока приводит к тому, что не выполнившая обязательства сторона проигрывает оспаривание.
+
+#### Почему доказательства мошенничества важны для оптимистических ролл-апов {#fraud-proof-benefits}
+
+Доказательства мошенничества важны, поскольку они способствуют _бездоверительной окончательности_ в оптимистических ролл-апах. Бездоверительная окончательность — это качество оптимистических ролл-апов, которое гарантирует, что транзакция, если она действительна, в конечном итоге будет подтверждена.
+
+Злонамеренные узлы могут пытаться отсрочить подтверждение действительного блока ролл-апа, начиная ложные оспаривания. Однако доказательства мошенничества в конечном итоге докажут действительность блока ролл-апа и приведут к его подтверждению.
+
+Это также связано с другим свойством безопасности оптимистических ролл-апов: действительность цепи зависит от существования _одного_ честного узла. Честный узел может правильно продвигать цепь, либо публикуя действительные утверждения, либо оспаривая недействительные. В любом случае, злонамеренные узлы, вступающие в споры с честным узлом, потеряют свои ставки в процессе доказательства мошенничества.
+
+### Совместимость L1/L2 {#l1-l2-interoperability}
+
+Оптимистические ролл-апы разработаны для взаимодействия с основной сетью Ethereum и позволяют пользователям передавать сообщения и произвольные данные между L1 и L2. Они также совместимы с EVM, поэтому вы можете переносить существующие [децентрализованные приложения](/developers/docs/dapps/) на оптимистические ролл-апы или создавать новые децентрализованные приложения с помощью инструментов разработки Ethereum.
+
+#### 1. Перемещение активов {#asset-movement}
+
+##### Вход в ролл-ап
+
+Чтобы использовать оптимистический ролл-ап, пользователи вносят ETH, токены ERC-20 и другие принимаемые активы в контракт [Моста](/developers/docs/bridges/) ролл-апа на L1. Контракт Моста передаст транзакцию на L2, где будет выпущена эквивалентная сумма активов и отправлена на выбранный пользователем адрес в оптимистическом ролл-апе.
+
+Транзакции, сгенерированные пользователем (например, депозит с L1 на L2), обычно ставятся в очередь до тех пор, пока Секвенсор не отправит их повторно в контракт ролл-апа. Однако, чтобы сохранить устойчивость к цензуре, оптимистические ролл-апы позволяют пользователям отправлять транзакцию непосредственно в контракт ролл-апа в сети, если она была задержана сверх максимально допустимого времени.
+
+Некоторые оптимистические ролл-апы используют более простой подход для предотвращения цензуры пользователей Секвенсорами. Здесь блок определяется всеми транзакциями, отправленными в контракт L1 с момента предыдущего блока (например, депозиты), в дополнение к транзакциям, обработанным в цепи ролл-апа. Если Секвенсор игнорирует транзакцию L1, он опубликует (доказуемо) неверный корень состояния; следовательно, Секвенсоры не могут задерживать сообщения, сгенерированные пользователем, после их публикации на L1.
+
+##### Выход из ролл-апа
+
+Вывод средств из оптимистического ролл-апа в Ethereum сложнее из-за схемы доказательства мошенничества. Если пользователь инициирует транзакцию с L2 на L1 для вывода средств, зарезервированных на L1, он должен дождаться истечения периода оспаривания, который длится примерно семь дней. Тем не менее, сам процесс вывода средств довольно прост.
+
+После инициирования запроса на вывод средств в ролл-апе L2, транзакция включается в следующий пакет, а активы пользователя в ролл-апе сжигаются. Как только пакет будет опубликован в Ethereum, пользователь сможет вычислить доказательство Меркла, подтверждающее включение его транзакции на выход в блок. Затем остается только дождаться окончания периода задержки, чтобы завершить транзакцию на L1 и вывести средства в основную сеть.
+
+Чтобы не ждать неделю перед выводом средств в Ethereum, пользователи оптимистических ролл-апов могут воспользоваться услугами **поставщика ликвидности** (LP). Поставщик ликвидности принимает на себя владение ожидающим выводом средств с L2 и выплачивает пользователю на L1 (в обмен на комиссию).
+
+Поставщики ликвидности могут проверить действительность запроса пользователя на вывод средств (самостоятельно выполнив цепь) перед выпуском средств. Таким образом, у них есть гарантии, что транзакция в конечном итоге будет подтверждена (т. е. бездоверительная окончательность).
+
+#### 2. Совместимость с EVM {#evm-compatibility}
+
+Для разработчиков преимущество оптимистических ролл-апов заключается в их совместимости — или, что еще лучше, эквивалентности — с [виртуальной машиной Ethereum (EVM)](/developers/docs/evm/). EVM-совместимые ролл-апы соответствуют спецификациям [Желтой книги Ethereum](https://ethereum.github.io/yellowpaper/paper.pdf) и поддерживают EVM на уровне байт-кода.
+
+EVM-совместимость в оптимистических ролл-апах имеет следующие преимущества:
+
+i. Разработчики могут переносить существующие смарт-контракты из Ethereum в цепи оптимистических ролл-апов без необходимости существенного изменения кодовых баз. Это может сэкономить время командам разработчиков при развертывании смарт-контрактов Ethereum на L2.
+
+ii. Разработчики и проектные команды, использующие оптимистические ролл-апы, могут воспользоваться инфраструктурой Ethereum. Это включает языки программирования, библиотеки кода, инструменты тестирования, клиентское программное обеспечение, инфраструктуру развертывания и так далее.
+
+Использование существующих инструментов важно, потому что эти инструменты были тщательно проверены, отлажены и улучшены на протяжении многих лет. Это также избавляет разработчиков Ethereum от необходимости изучать, как создавать приложения с совершенно новым стеком разработки.
+
+#### 3. Вызовы контрактов между цепями {#cross-chain-contract-calls}
+
+Пользователи (внешние аккаунты) взаимодействуют с контрактами L2, отправляя транзакцию в контракт ролл-апа или поручая это Секвенсору или валидатору. Оптимистические ролл-апы также позволяют аккаунтам контрактов в Ethereum взаимодействовать с контрактами L2, используя контракты Мостов для ретрансляции сообщений и передачи данных между L1 и L2. Это означает, что вы можете запрограммировать контракт L1 в основной сети Ethereum для вызова функций, принадлежащих контрактам в оптимистическом ролл-апе L2.
+
+Вызовы контрактов между цепями происходят асинхронно, то есть вызов сначала инициируется, а затем выполняется позже. Это отличается от вызовов между двумя контрактами в Ethereum, где вызов дает результаты немедленно.
+
+Примером вызова контракта между цепями является описанный ранее депозит токенов. Контракт на L1 блокирует токены пользователя и отправляет сообщение парному контракту на L2 для выпуска эквивалентного количества токенов в ролл-апе.
+
+Поскольку вызовы сообщений между цепями приводят к выполнению контракта, отправитель обычно должен покрывать [затраты на газ](/developers/docs/gas/) для вычислений. Рекомендуется устанавливать высокий лимит газа, чтобы предотвратить сбой транзакции в целевой цепи. Сценарий моста для токенов — хороший пример; если сторона L1 транзакции (депонирование токенов) работает, а сторона L2 (выпуск новых токенов) не удается из-за низкого газа, депозит становится невозвратным.
+
+Наконец, следует отметить, что вызовы сообщений с L2 на L1 между контрактами должны учитывать задержки (вызовы с L1 на L2 обычно выполняются через несколько минут). Это связано с тем, что сообщения, отправленные в основную сеть из оптимистического ролл-апа, не могут быть выполнены до истечения окна оспаривания.
+
+## Как работают комиссии в оптимистических ролл-апах? {#how-do-optimistic-rollup-fees-work}
+
+Оптимистические ролл-апы используют схему комиссий за газ, подобную Ethereum, чтобы обозначить, сколько пользователи платят за транзакцию. Комиссии, взимаемые в оптимистических ролл-апах, зависят от следующих компонентов:
+
+1. **Запись состояния**: оптимистические ролл-апы публикуют данные транзакций и заголовки блоков (состоящие из хэша заголовка предыдущего блока, корня состояния, корня пакета) в Ethereum в виде `блоба`, или "двоичного большого объекта". [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) представил экономически эффективное решение для включения данных в сеть. `blob` — это новое поле транзакции, которое позволяет ролл-апам публиковать сжатые данные о переходе состояния в Ethereum L1. В отличие от `calldata`, которая остается в сети постоянно, блобы недолговечны и могут быть удалены из клиентов после [4096 эпох](https://github.com/ethereum/consensus-specs/blob/81f3ea8322aff6b9fb15132d050f8f98b16bdba4/configs/mainnet.yaml#L147) (примерно 18 дней). Используя блобы для публикации пакетов сжатых транзакций, оптимистические ролл-апы могут значительно снизить стоимость записи транзакций в L1.
+
+2. **Использованный газ для блобов**: транзакции, переносящие блобы, используют динамический механизм комиссий, аналогичный тому, что был введен [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). Комиссия за газ для транзакций типа 3 учитывает базовую комиссию для блобов, которая определяется сетью на основе спроса на пространство для блобов и использования пространства для блобов отправляемой транзакцией.
+
+3. **Комиссии оператора L2**: это сумма, выплачиваемая узлам ролл-апа в качестве компенсации за вычислительные затраты, понесенные при обработке транзакций, подобно комиссиям за газ в Ethereum. Узлы ролл-апа взимают более низкие комиссии за транзакции, поскольку L2 имеют более высокие мощности обработки и не сталкиваются с перегрузками сети, которые заставляют валидаторов в Ethereum отдавать приоритет транзакциям с более высокими комиссиями.
+
+Оптимистические ролл-апы применяют несколько механизмов для снижения комиссий для пользователей, включая пакетирование транзакций и сжатие `calldata` для снижения затрат на публикацию данных. Вы можете проверить [трекер комиссий L2](https://l2fees.info/) для получения обзора в реальном времени о том, сколько стоит использование оптимистических ролл-апов на базе Ethereum.
+
+## Как оптимистические ролл-апы масштабируют Ethereum? {#scaling-ethereum-with-optimistic-rollups}
+
+Как уже объяснялось, оптимистические ролл-апы публикуют сжатые данные транзакций в Ethereum, чтобы гарантировать доступность данных. Возможность сжимать данные, публикуемые в сети, имеет решающее значение для масштабирования пропускной способности Ethereum с помощью оптимистических ролл-апов.
+
+Основная цепь Ethereum устанавливает ограничения на объем данных, которые могут содержать блоки, выраженные в единицах газа ([средний размер блока](/developers/docs/blocks/#block-size) составляет 15 миллионов газа). Хотя это ограничивает, сколько газа может использовать каждая транзакция, это также означает, что мы можем увеличить количество обрабатываемых транзакций в блоке за счет уменьшения данных, связанных с транзакциями, что напрямую улучшает масштабируемость.
+
+Оптимистические ролл-апы используют несколько техник для достижения сжатия данных транзакций и повышения скорости TPS. Например, в этой [статье](https://vitalik.eth.limo/general/2021/01/05/rollup.html) сравниваются данные, которые генерирует базовая пользовательская транзакция (отправка эфира) в основной сети, с объемом данных, который та же транзакция генерирует в ролл-апе:
+
+| Параметр | Ethereum (L1) | Ролл-ап (L2) |
+| ----------- | ---------------------------------------------------- | ------------------------------------ |
+| Нонс | ~3 | 0 |
+| Цена газа | ~8 | 0-0.5 |
+| Газ | 3 | 0-0.5 |
+| Получатель | 21 | 4 |
+| Значение | 9 | ~3 |
+| Подпись | ~68 (2 + 33 + 33) | ~0.5 |
+| Отправитель | 0 (восстановлено из подписи) | 4 |
+| **Всего** | **~112 байт** | **~12 байтов** |
+
+Проведение некоторых грубых расчетов на основе этих цифр может помочь показать улучшения масштабируемости, предоставляемые оптимистическим ролл-апом:
+
+1. Целевой размер каждого блока составляет 15 миллионов газа, и проверка одного байта данных стоит 16 газа. Разделив средний размер блока на 16 газа (15 000 000 / 16), мы видим, что средний блок может вместить **937 500 байт данных**.
+2. Если базовая транзакция ролл-апа использует 12 байт, то средний блок Ethereum может обработать **78 125 транзакций ролл-апа** (937 500 / 12) или **39 пакетов ролл-апа** (если каждый пакет содержит в среднем 2000 транзакций).
+3. Если новый блок создается в Ethereum каждые 15 секунд, то скорость обработки ролл-апа составит примерно **5208 транзакций в секунду**. Это делается путем деления количества базовых транзакций ролл-апа, которое может вместить блок Ethereum (**78 125**), на среднее время блока (**15 секунд**).
+
+Это довольно оптимистичная оценка, учитывая, что транзакции оптимистического ролл-апа не могут полностью занимать весь блок в Ethereum. Однако это может дать приблизительное представление о том, насколько оптимистические ролл-апы могут повысить масштабируемость для пользователей Ethereum (текущие реализации предлагают до 2000 TPS).
+
+Ожидается, что введение [шардинга данных](/roadmap/danksharding/) в Ethereum улучшит масштабируемость в оптимистических ролл-апах. Поскольку транзакции ролл-апа должны делить пространство блока с другими транзакциями, не относящимися к ролл-апу, их пропускная способность ограничена пропускной способностью данных в основной цепи Ethereum. Danksharding увеличит пространство, доступное для цепей L2 для публикации данных в блоке, используя более дешевое, временное хранилище "блобов" вместо дорогого, постоянного `CALLDATA`.
+
+### Плюсы и минусы оптимистических ролл-апов {#optimistic-rollups-pros-and-cons}
+
+| Преимущества | Недостатки |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Предлагает значительные улучшения в масштабируемости без ущерба для безопасности или бездоверительности. | Задержки в окончательности транзакций из-за потенциальных оспариваний мошенничества. |
+| Данные транзакций хранятся на цепи уровня 1, что улучшает прозрачность, безопасность, устойчивость к цензуре и децентрализацию. | Централизованные операторы ролл-апов (Секвенсоры) могут влиять на порядок транзакций. |
+| Доказательство мошенничества гарантирует бездоверительную окончательность и позволяет честным меньшинствам обеспечивать безопасность цепи. | Если нет честных узлов, злонамеренный оператор может украсть средства, публикуя недействительные блоки и фиксации состояний. |
+| Вычисление доказательств мошенничества открыто для обычных узлов L2, в отличие от доказательств действительности (используемых в ZK-ролл-апах), которые требуют специального оборудования. | Модель безопасности основана на том, что по крайней мере один честный узел выполняет транзакции ролл-апа и отправляет доказательства мошенничества для оспаривания недействительных переходов состояний. |
+| Ролл-апы выигрывают от «бездоверительной живучести» (любой может заставить цепь продвигаться, выполняя транзакции и публикуя утверждения). | Пользователи должны ждать истечения недельного периода оспаривания, прежде чем выводить средства обратно в Ethereum. |
+| Оптимистические ролл-апы полагаются на хорошо продуманные криптоэкономические стимулы для повышения безопасности цепи. | Ролл-апы должны публиковать все данные транзакций в сети, что может увеличить затраты. |
+| Совместимость с EVM и Solidity позволяет разработчикам переносить нативные смарт-контракты Ethereum в ролл-апы или использовать существующие инструменты для создания новых децентрализованных приложений. | |
+
+### Визуальное объяснение оптимистических ролл-апов {#optimistic-video}
+
+Больше увлекаетесь визуализацией? Посмотрите, как Finematics объясняет оптимистические ролл-апы:
+
+
+
+## Дополнительные материалы об оптимистических ролл-апах
+
+- [Как работают оптимистические ролл-апы (полное руководство)](https://www.alchemy.com/overviews/optimistic-rollups)
+- [Что такое ролл-ап в блокчейне? Техническое введение](https://www.ethereum-ecosystem.com/blog/what-is-a-blockchain-rollup-a-technical-introduction)
+- [Основное руководство по Arbitrum](https://www.bankless.com/the-essential-guide-to-arbitrum)
+- [Практическое руководство по ролл-апам Ethereum](https://web.archive.org/web/20241108192208/https://research.2077.xyz/the-practical-guide-to-ethereum-rollups)
+- [Состояние доказательств мошенничества в Ethereum L2](https://web.archive.org/web/20241124154627/https://research.2077.xyz/the-state-of-fraud-proofs-in-ethereum-l2s)
+- [Как на самом деле работает ролл-ап Optimism?](https://www.paradigm.xyz/2021/01/how-does-optimism-s-rollup-really-work)
+- [Глубокое погружение в OVM](https://medium.com/ethereum-optimism/ovm-deep-dive-a300d1085f52)
+- [Что такое Optimistic Virtual Machine?](https://www.alchemy.com/overviews/optimistic-virtual-machine)
diff --git a/public/content/translations/ru/developers/docs/scaling/plasma/index.md b/public/content/translations/ru/developers/docs/scaling/plasma/index.md
new file mode 100644
index 00000000000..3d1773b187f
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/plasma/index.md
@@ -0,0 +1,176 @@
+---
+title: "Плазменные цепи"
+description: "Введение в плазменные цепи как решение для масштабирования, которое в настоящее время используется сообществом Ethereum."
+lang: ru
+incomplete: true
+sidebarDepth: 3
+---
+
+Плазма-цепь — это отдельный блокчейн, привязанный к основной сети Ethereum, но выполняющий транзакции вне сети (офф-чейн) с помощью собственного механизма проверки блока. Плазма-цепи иногда называют «дочерними» цепями, по сути, они являются уменьшенными копиями основной сети Ethereum. Плазма-цепи используют [доказательства мошенничества](/glossary/#fraud-proof) (как и [оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups/)) для разрешения споров.
+
+Деревья Меркла позволяют создавать бесконечный стек этих цепей, которые могут работать для разгрузки пропускной способности родительских цепей (включая основную сеть Ethereum). Однако, хотя эти цепи и получают определенную безопасность от Ethereum (через доказательства мошенничества), на их безопасность и эффективность влияет ряд конструктивных ограничений.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны хорошо разбираться во всех основополагающих темах и иметь общее представление о [масштабировании Ethereum](/developers/docs/scaling/).
+
+## Что такое Plasma?
+
+Плазма — это фреймворк для улучшения масштабируемости в публичных блокчейнах, таких как Ethereum. Как описано в оригинальном [вайтпейпере Plasma](http://plasma.io/plasma.pdf), плазма-цепи строятся поверх другого блокчейна (называемого «корневой цепью»). Каждая «дочерняя цепь» является расширением корневой цепи и обычно управляется смарт-контрактом, развернутым в родительской цепи.
+
+Контракт Plasma, помимо прочего, функционирует как [мост](/developers/docs/bridges/), позволяя пользователям перемещать активы между основной сетью Ethereum и плазма-цепью. Хотя это делает их похожими на [сайдчейны](/developers/docs/scaling/sidechains/), плазма-цепи выигрывают — по крайней мере, в некоторой степени — от безопасности основной сети Ethereum. Это отличает их от сайдчейнов, которые несут полную ответственность за свою безопасность.
+
+## Как работает Plasma?
+
+Основные компоненты фреймворка Plasma:
+
+### Офф-чейн вычисления {#offchain-computation}
+
+Текущая скорость обработки транзакций Ethereum ограничена ~15–20 транзакциями в секунду, что снижает краткосрочную возможность масштабирования для обслуживания большего числа пользователей. Эта проблема существует в основном потому, что [механизм консенсуса](/developers/docs/consensus-mechanisms/) Ethereum требует, чтобы множество одноранговых узлов проверяли каждое обновление состояния блокчейна.
+
+Хотя механизм консенсуса Ethereum необходим для обеспечения безопасности, он может подходить не для каждого варианта использования. Например, Алисе может не потребоваться, чтобы ее ежедневные платежи Бобу за чашку кофе проверялись всей сетью Ethereum, поскольку между обеими сторонами существует определенное доверие.
+
+Plasma предполагает, что основной сети Ethereum не нужно проверять все транзакции. Вместо этого мы можем обрабатывать транзакции вне основной сети, освобождая узлы от необходимости проверять каждую транзакцию.
+
+Офф-чейн вычисления необходимы, поскольку плазма-цепи можно оптимизировать по скорости и стоимости. Например, плазма-цепь может — и чаще всего так и делает — использовать одного «оператора» для управления упорядочиванием и выполнением транзакций. Поскольку транзакции проверяет только одна организация, время обработки в плазма-цепи быстрее, чем в основной сети Ethereum.
+
+### Обязательства по состоянию {#state-commitments}
+
+Хотя Plasma выполняет транзакции офф-чейн, расчеты по ним производятся на основном уровне исполнения Ethereum — в противном случае плазма-цепи не смогут воспользоваться гарантиями безопасности Ethereum. Но завершение офф-чейн транзакций без знания состояния плазма-цепи нарушило бы модель безопасности и привело бы к распространению недействительных транзакций. Вот почему оператор, организация, ответственная за создание блоков в плазма-цепи, обязан периодически публиковать «обязательства по состоянию» в Ethereum.
+
+[Схема обязательств](https://en.wikipedia.org/wiki/Commitment_scheme) — это криптографический метод, позволяющий взять на себя обязательство в отношении значения или утверждения, не раскрывая его другой стороне. Обязательства являются «обязывающими» в том смысле, что вы не можете изменить значение или утверждение после того, как вы его приняли. Обязательства по состоянию в Plasma принимают форму «корней Меркла» (полученных из [дерева Меркла](/whitepaper/#merkle-trees)), которые оператор периодически отправляет в контракт Plasma в цепи Ethereum.
+
+Корни Меркла — это криптографические примитивы, которые позволяют сжимать большие объемы информации. Корень Меркла (в данном случае также называемый «корнем блока») может представлять все транзакции в блоке. Корни Меркла также упрощают проверку того, что небольшой фрагмент данных является частью более крупного набора данных. Например, пользователь может предоставить [доказательство Меркла](/developers/tutorials/merkle-proofs-for-offline-data-integrity/#main-content), чтобы доказать включение транзакции в определенный блок.
+
+Корни Меркла важны для предоставления информации о состоянии офф-чейн сети Ethereum. Вы можете думать о корнях Меркла как о «точках сохранения»: оператор говорит: «Это состояние плазма-цепи в момент времени x, и вот корень Меркла в качестве доказательства». Оператор принимает на себя обязательство по _текущему состоянию_ плазма-цепи с помощью корня Меркла, поэтому это называется «обязательством по состоянию».
+
+### Входы и выходы {#entries-and-exits}
+
+Чтобы пользователи Ethereum могли воспользоваться преимуществами Plasma, должен существовать механизм перемещения средств между основной сетью и плазма-цепями. Однако мы не можем произвольно отправлять эфир на адрес в плазма-цепи — эти цепи несовместимы, поэтому транзакция либо не удастся, либо приведет к потере средств.
+
+Plasma использует основной контракт, работающий на Ethereum, для обработки входов и выходов пользователей. Этот основной контракт также отвечает за отслеживание обязательств по состоянию (описанных ранее) и наказание за нечестное поведение с помощью доказательств мошенничества (подробнее об этом позже).
+
+#### Вход в плазма-цепь {#entering-the-plasma-chain}
+
+Чтобы войти в плазма-цепь, Алиса (пользователь) должна внести ETH или любой токен ERC-20 в контракт Plasma. Оператор Plasma, который следит за депозитами в контракте, воссоздает сумму, равную первоначальному депозиту Алисы, и отправляет ее на ее адрес в плазма-цепи. Алиса должна подтвердить получение средств в дочерней цепи, а затем может использовать эти средства для транзакций.
+
+#### Выход из плазма-цепи {#exiting-the-plasma-chain}
+
+Выход из плазма-цепи сложнее, чем вход, по нескольким причинам. Самая большая из них заключается в том, что, хотя Ethereum имеет информацию о состоянии плазма-цепи, он не может проверить, является ли эта информация правдивой. Злонамеренный пользователь может сделать неверное утверждение («У меня 1000 ETH») и остаться безнаказанным, предоставив поддельные доказательства в поддержку этого утверждения.
+
+Для предотвращения злонамеренных выводов средств вводится «период оспаривания». В течение периода оспаривания (обычно неделя) любой может оспорить запрос на вывод средств, используя доказательство мошенничества. Если оспаривание будет успешным, запрос на вывод средств будет отклонен.
+
+Однако обычно пользователи честны и делают правильные заявления о принадлежащих им средствах. В этом сценарии Алиса инициирует запрос на вывод средств в корневой цепи (Ethereum), отправив транзакцию в контракт Plasma.
+
+Она также должна предоставить доказательство Меркла, подтверждающее, что транзакция, создавшая ее средства в плазма-цепи, была включена в блок. Это необходимо для итераций Plasma, таких как [Plasma MVP](https://www.learnplasma.org/en/learn/mvp.html), которые используют модель [непотраченных выходов транзакций (UTXO)](https://en.wikipedia.org/wiki/Unspent_transaction_output).
+
+Другие, такие как [Plasma Cash](https://www.learnplasma.org/en/learn/cash.html), представляют средства в виде [невзаимозаменяемых токенов](/developers/docs/standards/tokens/erc-721/), а не UTXO. Вывод средств в этом случае требует доказательства владения токенами в плазма-цепи. Это делается путем отправки двух последних транзакций с участием токена и предоставления доказательства Меркла, подтверждающего включение этих транзакций в блок.
+
+Пользователь также должен добавить залог к запросу на вывод средств в качестве гарантии честного поведения. Если оспаривающий докажет недействительность запроса Алисы на вывод средств, ее залог будет урезан, и часть его перейдет к оспаривающему в качестве вознаграждения.
+
+Если период оспаривания истекает, и никто не предоставляет доказательства мошенничества, запрос Алисы на вывод средств считается действительным, что позволяет ей забрать депозиты из контракта Plasma в Ethereum.
+
+### Арбитраж споров {#dispute-arbitration}
+
+Как и любой блокчейн, плазма-цепи нуждаются в механизме для обеспечения целостности транзакций на случай злонамеренных действий участников (например, двойного расходования средств). Для этого плазма-цепи используют доказательства мошенничества для разрешения споров о действительности переходов состояний и наказания за плохое поведение. Доказательства мошенничества используются как механизм, с помощью которого дочерняя плазма-цепь подает жалобу в свою родительскую цепь или в корневую цепь.
+
+Доказательство мошенничества — это просто заявление о том, что определенный переход состояния является недействительным. Примером может служить ситуация, когда пользователь (Алиса) пытается дважды потратить одни и те же средства. Возможно, она потратила UTXO в транзакции с Бобом и хочет потратить тот же UTXO (который теперь принадлежит Бобу) в другой транзакции.
+
+Чтобы предотвратить вывод средств, Боб создаст доказательство мошенничества, предоставив доказательство того, что Алиса потратила указанный UTXO в предыдущей транзакции, и доказательство Меркла о включении транзакции в блок. Тот же процесс работает в Plasma Cash — Бобу нужно будет предоставить доказательство того, что Алиса ранее перевела токены, которые она пытается вывести.
+
+Если оспаривание Боба будет успешным, запрос Алисы на вывод средств будет отменен. Однако этот подход зависит от способности Боба отслеживать запросы на вывод средств в цепи. Если Боб не в сети, то Алиса может обработать злонамеренный вывод средств по истечении периода оспаривания.
+
+## Проблема массового выхода в Plasma {#the-mass-exit-problem-in-plasma}
+
+Проблема массового выхода возникает, когда большое количество пользователей пытаются одновременно вывести средства из плазма-цепи. Причина существования этой проблемы связана с одной из самых больших проблем Plasma: **недоступностью данных**.
+
+Доступность данных — это возможность проверить, что информация для предложенного блока действительно была опубликована в сети блокчейна. Блок считается «недоступным», если производитель публикует сам блок, но скрывает данные, использованные для его создания.
+
+Блоки должны быть доступны, чтобы узлы могли загрузить блок и проверить действительность транзакций. Блокчейны обеспечивают доступность данных, заставляя производителей блоков публиковать все данные транзакций он-чейн.
+
+Доступность данных также помогает защитить протоколы офф-чейн масштабирования, которые строятся на базовом слое Ethereum. Заставляя операторов этих цепей публиковать данные транзакций в Ethereum, любой может оспорить недействительные блоки, создав доказательства мошенничества, ссылающиеся на правильное состояние цепи.
+
+Плазма-цепи в основном хранят данные транзакций у оператора и **не публикуют никаких данных в основной сети** (кроме периодических обязательств по состоянию). Это означает, что пользователи должны полагаться на оператора в предоставлении данных блока, если им нужно создать доказательства мошенничества для оспаривания недействительных транзакций. Если эта система работает, то пользователи всегда могут использовать доказательства мошенничества для защиты средств.
+
+Проблема начинается, когда злонамеренно действует оператор, а не просто какой-либо пользователь. Поскольку оператор единолично контролирует блокчейн, у него больше стимулов для продвижения недействительных переходов состояния в более крупном масштабе, например, для кражи средств, принадлежащих пользователям в плазма-цепи.
+
+В этом случае использование классической системы доказательств мошенничества не работает. Оператор может легко совершить недействительную транзакцию, переведя средства Алисы и Боба на свой кошелек, и скрыть данные, необходимые для создания доказательства мошенничества. Это возможно потому, что оператор не обязан предоставлять данные пользователям или основной сети.
+
+Поэтому самым оптимистичным решением является попытка «массового выхода» пользователей из плазма-цепи. Массовый выход замедляет план злонамеренного оператора по краже средств и обеспечивает некоторую меру защиты для пользователей. Запросы на вывод средств упорядочиваются в зависимости от времени создания каждого UTXO (или токена), что не позволяет злонамеренным операторам опережать честных пользователей.
+
+Тем не менее, нам все еще нужен способ проверки действительности запросов на вывод средств во время массового выхода, чтобы предотвратить оппортунистических личностей от наживы на хаосе, обрабатывая недействительные выходы. Решение простое: требовать от пользователей публиковать последнее **действительное состояние цепи**, чтобы вывести свои деньги.
+
+Но у этого подхода все еще есть проблемы. Например, если всем пользователям в плазма-цепи необходимо выйти (что возможно в случае злонамеренного оператора), то все действительное состояние плазма-цепи должно быть сразу же выгружено на базовый слой Ethereum. Учитывая произвольный размер плазма-цепей (высокая пропускная способность = больше данных) и ограничения на скорость обработки Ethereum, это не идеальное решение.
+
+Хотя выходные игры звучат хорошо в теории, реальные массовые выходы, скорее всего, вызовут перегрузку всей сети самого Ethereum. Помимо ущерба функциональности Ethereum, плохо скоординированный массовый выход означает, что пользователи могут не успеть вывести средства до того, как оператор опустошит все аккаунты в плазма-цепи.
+
+## Плюсы и минусы Plasma {#pros-and-cons-of-plasma}
+
+| Преимущества | Недостатки |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Предлагает высокую пропускную способность и низкую стоимость за транзакцию. | Не поддерживает общие вычисления (не может запускать смарт-контракты). С помощью логики предикатов поддерживаются только базовые передачи токенов, свопы и несколько других типов транзакций. |
+| Подходит для транзакций между произвольными пользователями (без накладных расходов на пару пользователей, если оба установлены в плазменной цепи) | Необходимо периодически следить за сетью (требование живучести) или делегировать эту ответственность кому-то другому для обеспечения безопасности ваших средств. |
+| Плазма-цепи можно адаптировать к конкретным вариантам использования, не связанным с основной цепью. Любой, включая компании, может настраивать смарт-контракты Plasma для предоставления масштабируемой инфраструктуры, работающей в различных контекстах. | Полагается на одного или нескольких операторов для хранения данных и их обслуживания по запросу. |
+| Снижает нагрузку на основную сеть Ethereum, перемещая вычисления и хранение офф-чейн. | Вывод средств задерживается на несколько дней из-за проблем. Для взаимозаменяемых активов это может быть смягчено поставщиками ликвидности, но это связано с соответствующими капитальными затратами. |
+| | Если слишком много пользователей попытаются выйти одновременно, основная сеть Ethereum может быть перегружена. |
+
+## Plasma в сравнении с протоколами масштабирования уровня 2 {#plasma-vs-layer-2}
+
+Хотя Plasma когда-то считалась полезным решением для масштабирования Ethereum, от нее отказались в пользу [протоколов масштабирования уровня 2 (L2)](/layer-2/). Решения для масштабирования L2 решают несколько проблем Plasma:
+
+### Эффективность {#efficiency}
+
+[Ролл-апы с нулевым разглашением](/developers/docs/scaling/zk-rollups) генерируют криптографические доказательства действительности каждой партии транзакций, обработанных офф-чейн. Это не позволяет пользователям (и операторам) продвигать недействительные переходы состояний, устраняя необходимость в периодах оспаривания и выходных играх. Это также означает, что пользователям не нужно периодически следить за цепью, чтобы обезопасить свои средства.
+
+### Поддержка смарт-контрактов {#support-for-smart-contracts}
+
+Еще одна проблема с фреймворком Plasma заключалась в [невозможности поддерживать выполнение смарт-контрактов Ethereum](https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598/4). В результате большинство реализаций Plasma были в основном созданы для простых платежей или обмена токенами ERC-20.
+
+И наоборот, оптимистические ролл-апы совместимы с [виртуальной машиной Ethereum](/developers/docs/evm/) и могут запускать нативные [смарт-контракты](/developers/docs/smart-contracts/) Ethereum, что делает их полезным и _безопасным_ решением для масштабирования [децентрализованных приложений](/developers/docs/dapps/). Аналогичным образом, ведутся работы по [созданию реализации EVM с нулевым разглашением (zkEVM)](https://ethresear.ch/t/a-zk-evm-specification/11549), которая позволит ZK-ролл-апам обрабатывать произвольную логику и выполнять смарт-контракты.
+
+### Недоступность данных {#data-unavailability}
+
+Как объяснялось ранее, Plasma страдает от проблемы доступности данных. Если злонамеренный оператор продвинет недействительный переход в плазма-цепи, пользователи не смогут его оспорить, поскольку оператор может скрыть данные, необходимые для создания доказательства мошенничества. Ролл-апы решают эту проблему, заставляя операторов публиковать данные транзакций в Ethereum, что позволяет любому проверять состояние цепи и при необходимости создавать доказательства мошенничества.
+
+### Проблема массового выхода {#mass-exit-problem}
+
+ZK-ролл-апы и оптимистические ролл-апы решают проблему массового выхода Plasma различными способами. Например, ZK-ролл-ап полагается на криптографические механизмы, которые гарантируют, что операторы не смогут украсть средства пользователей ни при каких обстоятельствах.
+
+Аналогичным образом, оптимистические ролл-апы устанавливают период задержки на вывод средств, в течение которого любой может инициировать оспаривание и предотвратить злонамеренные запросы на вывод. Хотя это похоже на Plasma, разница в том, что верификаторы имеют доступ к данным, необходимым для создания доказательств мошенничества. Таким образом, пользователям ролл-апов не нужно участвовать в бешеной миграции «кто первый выйдет» в основную сеть Ethereum.
+
+## Чем Plasma отличается от сайдчейнов и шардинга? {#plasma-sidechains-sharding}
+
+Plasma, сайдчейны и шардинг довольно похожи, потому что все они так или иначе подключаются к основной сети Ethereum. Однако уровень и прочность этих соединений различаются, что влияет на свойства безопасности каждого решения для масштабирования.
+
+### Plasma в сравнении с сайдчейнами {#plasma-vs-sidechains}
+
+[Сайдчейн](/developers/docs/scaling/sidechains/) — это независимо работающий блокчейн, подключенный к основной сети Ethereum через двусторонний мост. [Мосты](/bridges/) позволяют пользователям обмениваться токенами между двумя блокчейнами для совершения транзакций в сайдчейне, снижая перегрузку в основной сети Ethereum и улучшая масштабируемость.
+Сайдчейны используют отдельный механизм консенсуса и обычно намного меньше основной сети Ethereum. В результате перенос активов в эти цепи сопряжен с повышенным риском; учитывая отсутствие гарантий безопасности, унаследованных от основной сети Ethereum в модели сайдчейна, пользователи рискуют потерять средства в случае атаки на сайдчейн.
+
+И наоборот, плазма-цепи получают свою безопасность от основной сети. Это делает их заметно более безопасными, чем сайдчейны. И сайдчейны, и плазма-цепи могут иметь разные протоколы консенсуса, но разница в том, что плазма-цепи публикуют корни Меркла для каждого блока в основной сети Ethereum. Корни блоков — это небольшие фрагменты информации, которые мы можем использовать для проверки информации о транзакциях, происходящих в плазма-цепи. Если происходит атака на плазма-цепь, пользователи могут безопасно вывести свои средства обратно в основную сеть, используя соответствующие доказательства.
+
+### Plasma в сравнении с шардингом {#plasma-vs-sharding}
+
+И плазма-цепи, и шард-цепи периодически публикуют криптографические доказательства в основной сети Ethereum. Однако оба имеют разные свойства безопасности.
+
+Шард-цепи передают «заголовки сверки» в основную сеть, содержащие подробную информацию о каждом шарде данных. Узлы в основной сети проверяют и обеспечивают действительность шардов данных, снижая вероятность недействительных переходов шардов и защищая сеть от злонамеренных действий.
+
+Plasma отличается тем, что основная сеть получает лишь минимальную информацию о состоянии дочерних цепей. Это означает, что основная сеть не может эффективно проверять транзакции, проводимые в дочерних цепях, что делает их менее безопасными.
+
+**Примечание**: шардинг блокчейна Ethereum больше не входит в дорожную карту. Он был заменен масштабированием с помощью ролл-апов и [Danksharding](/roadmap/danksharding).
+
+### Используйте Plasma {#use-plasma}
+
+Несколько проектов предоставляют реализации Plasma, которые вы можете интегрировать в свои децентрализованные приложения:
+
+- [Polygon](https://polygon.technology/) (ранее Matic Network)
+
+## Дополнительные материалы {#further-reading}
+
+- [Изучите Plasma](https://www.learnplasma.org/en/)
+- [Краткое напоминание о том, что означает «общая безопасность» и почему это так важно](https://old.reddit.com/r/ethereum/comments/sgd3zt/a_quick_reminder_of_what_shared_security_means/)
+- [Сайдчейны в сравнении с Plasma и шардингом](https://vitalik.eth.limo/general/2019/06/12/plasma_vs_sharding.html)
+- [Понимание Plasma, Часть 1: Основы](https://www.theblockcrypto.com/amp/post/10793/understanding-plasma-part-1-the-basics)
+- [Жизнь и смерть Plasma](https://medium.com/dragonfly-research/the-life-and-death-of-plasma-b72c6a59c5ad#)
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/scaling/sidechains/index.md b/public/content/translations/ru/developers/docs/scaling/sidechains/index.md
new file mode 100644
index 00000000000..dd93a7811ec
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/sidechains/index.md
@@ -0,0 +1,73 @@
+---
+title: "Сайдчейны"
+description: "Введение в сайдчейны как решение для масштабирования, которое в настоящее время используется сообществом Ethereum."
+lang: ru
+sidebarDepth: 3
+---
+
+Сайдчейн — это отдельный блокчейн, который работает независимо от Ethereum и соединен с основной сетью Ethereum двусторонним мостом. Сайдчейны могут иметь отдельные параметры блока и [алгоритмы консенсуса](/developers/docs/consensus-mechanisms/), которые часто предназначены для эффективной обработки транзакций. Однако использование сайдчейна сопряжено с компромиссами, поскольку он не наследует свойства безопасности Ethereum. В отличие от [решений для масштабирования 2-го уровня](/layer-2/), сайдчейны не публикуют изменения состояния и данные о транзакциях обратно в основную сеть Ethereum.
+
+Сайдчейны также жертвуют определенной степенью децентрализации или безопасности для достижения высокой пропускной способности ([трилемма масштабируемости](https://vitalik.eth.limo/general/2021/05/23/scaling.html)). Тем не менее, Ethereum стремится к масштабированию без ущерба для децентрализации и безопасности.
+
+## Как работают сайдчейны? {#how-do-sidechains-work}
+
+Сайдчейны — это независимые блокчейны с разной историей, планами развития и проектными решениями. Хотя сайдчейн может иметь некоторые внешние сходства с Ethereum, у него есть несколько отличительных особенностей.
+
+### Алгоритмы консенсуса {#consensus-algorithms}
+
+Одним из качеств, которые делают сайдчейны уникальными (т. е. отличными от Ethereum), является используемый алгоритм консенсуса. Сайдчейны не полагаются на Ethereum для достижения консенсуса и могут выбирать альтернативные протоколы консенсуса, которые соответствуют их потребностям. Некоторые примеры алгоритмов консенсуса, используемых в сайдчейнах:
+
+- [Доказательство полномочий](/developers/docs/consensus-mechanisms/poa/)
+- [Делегированное доказательство доли владения](https://en.bitcoin.it/wiki/Delegated_proof_of_stake)
+- [Византийская отказоустойчивость](https://decrypt.co/resources/byzantine-fault-tolerance-what-is-it-explained).
+
+Подобно Ethereum, сайдчейны имеют проверяющие узлы, которые верифицируют и обрабатывают транзакции, создают блоки и хранят состояние блокчейна. Валидаторы также несут ответственность за поддержание консенсуса в сети и ее защиту от злонамеренных атак.
+
+#### Параметры блока {#block-parameters}
+
+Ethereum устанавливает ограничения на [время блока](/developers/docs/blocks/#block-time) (т. е. время, необходимое для создания новых блоков) и [размер блока](/developers/docs/blocks/#block-size) (т. е. объем данных, содержащихся в блоке, выраженный в газе). И наоборот, сайдчейны часто применяют другие параметры, такие как более быстрое время блока и более высокие лимиты газа, для достижения высокой пропускной способности, быстрых транзакций и низких комиссий.
+
+Хотя у этого есть некоторые преимущества, это имеет критические последствия для децентрализации и безопасности сети. Параметры блока, такие как быстрое время блока и большие размеры блоков, увеличивают сложность запуска полного узла, оставляя несколько "суперузлов" ответственными за безопасность цепи. В таком сценарии возрастает вероятность сговора валидаторов или злонамеренного захвата цепи.
+
+Чтобы блокчейны могли масштабироваться без ущерба для децентрализации, запуск узла должен быть доступен для всех, а не только для тех, кто обладает специализированным оборудованием. Вот почему предпринимаются усилия для того, чтобы каждый мог [запустить полный узел](/developers/docs/nodes-and-clients/#why-should-i-run-an-ethereum-node) в сети Ethereum.
+
+### Совместимость с EVM {#evm-compatibility}
+
+Некоторые сайдчейны совместимы с EVM и могут выполнять контракты, разработанные для [виртуальной машины Ethereum (EVM)](/developers/docs/evm/). Совместимые с EVM сайдчейны поддерживают смарт-контракты, [написанные на Solidity](/developers/docs/smart-contracts/languages/), а также другие языки смарт-контрактов EVM, что означает, что смарт-контракты, написанные для основной сети Ethereum, также будут работать на совместимых с EVM сайдчейнах.
+
+Это означает, что если вы хотите использовать свое [децентрализованное приложение](/developers/docs/dapps/) в сайдчейне, вам просто нужно развернуть свой [смарт-контракт](/developers/docs/smart-contracts/) в этом сайдчейне. Он выглядит, ощущается и действует так же, как основная сеть: вы пишете контракты на Solidity и взаимодействуете с цепью через RPC сайдчейна.
+
+Поскольку сайдчейны совместимы с EVM, они считаются полезным [решением для масштабирования](/developers/docs/scaling/) для нативных децентрализованных приложений Ethereum. С вашим децентрализованным приложением в сайдчейне пользователи могут пользоваться более низкими комиссиями за газ и более быстрыми транзакциями, особенно если основная сеть перегружена.
+
+Однако, как объяснялось ранее, использование сайдчейна сопряжено со значительными компромиссами. Каждый сайдчейн отвечает за свою безопасность и не наследует свойства безопасности Ethereum. Это увеличивает вероятность злонамеренных действий, которые могут повлиять на ваших пользователей или подвергнуть риску их средства.
+
+### Перемещение активов {#asset-movement}
+
+Чтобы отдельный блокчейн стал сайдчейном для основной сети Ethereum, ему необходима возможность обеспечивать перевод активов из основной сети Ethereum и в нее. Эта совместимость с Ethereum достигается с помощью блокчейн-моста. [Мосты](/bridges/) используют смарт-контракты, развернутые в основной сети Ethereum и в сайдчейне, для контроля перевода средств между ними.
+
+Хотя мосты помогают пользователям перемещать средства между Ethereum и сайдчейном, активы физически не перемещаются между двумя цепями. Вместо этого для перевода ценности между цепями используются механизмы, которые обычно включают создание и сжигание активов. Подробнее о том, [как работают мосты](/developers/docs/bridges/#how-do-bridges-work).
+
+## Плюсы и минусы сайдчейнов {#pros-and-cons-of-sidechains}
+
+| Преимущества | Недостатки |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Технология, лежащая в основе сайдчейнов, хорошо зарекомендовала себя и выигрывает от обширных исследований и усовершенствований в дизайне. | Сайдчейны жертвуют определенной степенью децентрализации и отсутствия доверия ради масштабируемости. |
+| Сайдчейны поддерживают общие вычисления и предлагают совместимость с EVM (они могут запускать нативные децентрализованные приложения Ethereum). | Сайдчейн использует отдельный механизм консенсуса и не получает преимуществ от гарантий безопасности Ethereum. |
+| Сайдчейны используют различные модели консенсуса для эффективной обработки транзакций и снижения комиссий за транзакции для пользователей. | Сайдчейны требуют более высоких допущений по доверию (например, кворум злонамеренных валидаторов сайдчейна может совершить мошенничество). |
+| Совместимые с EVM сайдчейны позволяют децентрализованным приложениям расширять свою экосистему. | |
+
+### Использование сайдчейнов {#use-sidechains}
+
+Несколько проектов предоставляют реализации сайдчейнов, которые вы можете интегрировать в свои децентрализованные приложения:
+
+- [Polygon PoS](https://polygon.technology/solutions/polygon-pos)
+- [Skale](https://skale.network/)
+- [Gnosis Chain (ранее xDai)](https://www.gnosischain.com/)
+- [Loom Network](https://loomx.io/)
+- [Metis Andromeda](https://www.metis.io/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Масштабирование децентрализованных приложений Ethereum с помощью сайдчейнов](https://medium.com/loom-network/dappchains-scaling-ethereum-dapps-through-sidechains-f99e51fff447) _8 февраля 2018 г. - Георгиос Константинопулос_
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/scaling/state-channels/index.md b/public/content/translations/ru/developers/docs/scaling/state-channels/index.md
new file mode 100644
index 00000000000..e7c00060025
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/state-channels/index.md
@@ -0,0 +1,261 @@
+---
+title: "Каналы состояния"
+description: "Введение в каналы состояния и платежные каналы в качестве решения для масштабирования, которое в настоящее время используется сообществом Ethereum."
+lang: ru
+sidebarDepth: 3
+---
+
+Каналы состояний позволяют участникам безопасно совершать транзакции вне сети, сводя взаимодействие с основной сетью Ethereum к минимуму. Участники канала могут проводить произвольное количество оффчейн-транзакций, отправляя только две ончейн-транзакции для открытия и закрытия канала. Это обеспечивает чрезвычайно высокую пропускную способность транзакций и приводит к снижению затрат для пользователей.
+
+## Предварительные условия {#prerequisites}
+
+Вам следует прочитать и понять наши страницы о [масштабировании Ethereum](/developers/docs/scaling/) и [уровне 2](/layer-2/).
+
+## Что такое каналы? {#what-are-channels}
+
+Публичные блокчейны, такие как Ethereum, сталкиваются с проблемами масштабируемости из-за своей распределенной архитектуры: ончейн-транзакции должны выполняться всеми узлами. Узлы должны иметь возможность обрабатывать объем транзакций в блоке, используя скромное оборудование, что накладывает ограничение на пропускную способность транзакций для сохранения децентрализации сети. Каналы блокчейна решают эту проблему, позволяя пользователям взаимодействовать оффчейн, при этом полагаясь на безопасность основной цепи для окончательного расчета.
+
+Каналы — это простые одноранговые протоколы, которые позволяют двум сторонам совершать множество транзакций между собой, а затем публиковать в блокчейне только окончательные результаты. Канал использует криптографию, чтобы доказать, что генерируемые им сводные данные действительно являются результатом действительного набора промежуточных транзакций. [Смарт-контракт с мультиподписью (multisig)](/developers/docs/smart-contracts/#multisig) гарантирует, что транзакции подписаны надлежащими сторонами.
+
+С помощью каналов изменения состояния выполняются и проверяются заинтересованными сторонами, что минимизирует вычисления на уровне исполнения Ethereum. Это уменьшает перегрузку в сети Ethereum, а также увеличивает скорость обработки транзакций для пользователей.
+
+Каждый канал управляется [смарт-контрактом с мультиподписью](/developers/docs/smart-contracts/#multisig), работающим в сети Ethereum. Чтобы открыть канал, участники развертывают его контракт ончейн и вносят в него средства. Обе стороны совместно подписывают обновление состояния для инициализации состояния канала, после чего они могут быстро и свободно совершать транзакции оффчейн.
+
+Чтобы закрыть канал, участники отправляют последнее согласованное состояние канала ончейн. После этого смарт-контракт распределяет заблокированные средства в соответствии с балансом каждого участника в конечном состоянии канала.
+
+Одноранговые каналы особенно полезны в ситуациях, когда заранее определенные участники хотят совершать транзакции с высокой частотой без видимых накладных расходов. Каналы блокчейна делятся на две категории: **платежные каналы** и **каналы состояний**.
+
+## Платежные каналы {#payment-channels}
+
+Платежный канал лучше всего можно описать как "двусторонний реестр", который совместно ведут два пользователя. Начальный баланс реестра — это сумма депозитов, заблокированных в ончейн-контракте на этапе открытия канала. Переводы в платежном канале могут выполняться мгновенно и без участия самого блокчейна, за исключением первоначального одноразового ончейн-создания и последующего закрытия канала.
+
+Обновления баланса реестра (т. е. состояния платежного канала) требуют одобрения всех сторон канала. Обновление канала, подписанное всеми его участниками, считается окончательным, так же как транзакция в сети Ethereum.
+
+Платежные каналы были одним из первых решений для масштабирования, разработанных для минимизации дорогостоящей ончейн-активности при простых взаимодействиях пользователей (например, переводах ETH, атомарных свопах, микроплатежах). Участники канала могут совершать неограниченное количество мгновенных транзакций без комиссии между собой, пока общая сумма их переводов не превышает депонированные токены.
+
+## Каналы состояний {#state-channels}
+
+Помимо поддержки оффчейн-платежей, платежные каналы оказались неэффективными для обработки общей логики перехода состояний. Каналы состояний были созданы для решения этой проблемы и использования каналов для масштабирования вычислений общего назначения.
+
+Каналы состояний по-прежнему имеют много общего с платежными каналами. Например, пользователи взаимодействуют путем обмена криптографически подписанными сообщениями (транзакциями), которые также должны быть подписаны другими участниками канала. Если предлагаемое обновление состояния не подписано всеми участниками, оно считается недействительным.
+
+Однако, помимо хранения балансов пользователей, канал также отслеживает текущее состояние хранилища контракта (т. е. значения переменных контракта).
+
+Это позволяет выполнять смарт-контракт оффчейн между двумя пользователями. В этом сценарии обновления внутреннего состояния смарт-контракта требуют одобрения только от участников, создавших канал.
+
+Хотя это решает описанную ранее проблему масштабируемости, это имеет последствия для безопасности. В сети Ethereum достоверность переходов состояния обеспечивается протоколом консенсуса сети. Это делает невозможным предложение неверного обновления состояния смарт-контракта или изменение его выполнения.
+
+Каналы состояний не имеют таких же гарантий безопасности. В некоторой степени канал состояния является миниатюрной версией основной сети. При ограниченном наборе участников, обеспечивающих соблюдение правил, возрастает вероятность вредоносного поведения (например, предложения недействительных обновлений состояния). Каналы состояний получают свою безопасность от системы арбитража споров, основанной на [доказательствах мошенничества](/glossary/#fraud-proof).
+
+## Как работают каналы состояний {#how-state-channels-work}
+
+По сути, активность в канале состояний — это сеанс взаимодействий с участием пользователей и системы блокчейна. Пользователи в основном общаются друг с другом оффчейн и взаимодействуют с базовым блокчейном только для открытия, закрытия канала или урегулирования потенциальных споров между участниками.
+
+В следующем разделе описывается основной рабочий процесс канала состояний:
+
+### Открытие канала {#opening-the-channel}
+
+Открытие канала требует от участников внесения средств в смарт-контракт в основной сети. Депозит также функционирует как виртуальная вкладка, поэтому участвующие субъекты могут свободно совершать транзакции без необходимости немедленного расчета платежей. Только когда канал финализируется ончейн, стороны рассчитываются друг с другом и выводят то, что осталось от их вклада.
+
+Этот депозит также служит залогом, гарантирующим честное поведение каждого участника. Если вкладчики будут признаны виновными в злонамеренных действиях на этапе разрешения спора, контракт сократит их депозит.
+
+Участники канала должны подписать начальное состояние, с которым они все согласны. Это служит генезисом канала состояний, после чего пользователи могут начать проводить транзакции.
+
+### Использование канала {#using-the-channel}
+
+После инициализации состояния канала участники взаимодействуют, подписывая транзакции и отправляя их друг другу на утверждение. Участники инициируют обновления состояния с помощью этих транзакций и подписывают обновления состояния от других. Каждая транзакция содержит:
+
+- Поле **nonce**, которое служит уникальным идентификатором транзакций и предотвращает повторные атаки. Оно также определяет порядок, в котором происходили обновления состояния (что важно для разрешения споров).
+
+- Старое состояние канала
+
+- Новое состояние канала
+
+- Транзакция, которая вызывает переход состояния (например, Алиса отправляет 5 ETH Бобу).
+
+Обновления состояния в канале не транслируются ончейн, как это обычно бывает, когда пользователи взаимодействуют в основной сети, что соответствует цели каналов состояний по минимизации ончейн-следа. Пока участники соглашаются с обновлениями состояния, они так же окончательны, как и транзакция Ethereum. Участникам нужно полагаться на консенсус основной сети только в случае возникновения спора.
+
+### Закрытие канала {#closing-the-channel}
+
+Закрытие канала состояний требует отправки окончательного, согласованного состояния канала в ончейн-смарт-контракт. Детали, указанные в обновлении состояния, включают количество ходов каждого участника и список одобренных транзакций.
+
+После проверки того, что обновление состояния является действительным (т. е. оно подписано всеми сторонами), смарт-контракт финализирует канал и распределяет заблокированные средства в соответствии с результатом канала. Платежи, совершенные оффчейн, применяются к состоянию Ethereum, и каждый участник получает свою оставшуюся часть заблокированных средств.
+
+Описанный выше сценарий представляет то, что происходит в «счастливом» случае. Иногда пользователи могут не прийти к соглашению и не завершить канал («печальный» случай). Любое из следующих утверждений может быть верным для данной ситуации:
+
+- Участники выходят из сети и не могут предложить переходы состояния.
+
+- Участники отказываются совместно подписывать действительные обновления состояния.
+
+- Участники пытаются завершить канал, предлагая старое обновление состояния для ончейн-контракта.
+
+- Участники предлагают недействительные переходы состояний для подписания другими.
+
+Всякий раз, когда между участниками канала нарушается консенсус, последним вариантом является опора на консенсус основной сети для принудительного установления окончательного, действительного состояния канала. В этом случае закрытие канала состояний требует разрешения споров ончейн.
+
+### Разрешение споров {#settling-disputes}
+
+Обычно стороны в канале заранее договариваются о закрытии канала и совместно подписывают последнее изменение состояния, которое они отправляют в смарт-контракт. После того как обновление будет одобрено ончейн, выполнение оффчейн-смарт-контракта завершается, и участники выходят из канала со своими деньгами.
+
+Однако одна из сторон может подать ончейн-запрос на прекращение выполнения смарт-контракта и завершение канала, не дожидаясь одобрения контрагента. Если возникает любая из описанных ранее ситуаций нарушения консенсуса, любая из сторон может запустить ончейн-контракт для закрытия канала и распределения средств. Это обеспечивает **недоверительность**, гарантируя, что честные стороны могут вывести свои депозиты в любой момент, независимо от действий другой стороны.
+
+Чтобы обработать выход из канала, пользователь должен отправить последнее действительное обновление состояния приложения в ончейн-контракт. Если это подтверждается (т. е. имеет подпись всех сторон), то средства перераспределяются в их пользу.
+
+Однако при выполнении запросов на выход от одного пользователя существует задержка. Если запрос на завершение канала был одобрен единогласно, то ончейн-транзакция выхода выполняется немедленно.
+
+Задержка вступает в игру при выходе одного пользователя из-за возможности мошеннических действий. Например, участник канала может попытаться завершить канал в Ethereum, отправив старое обновление состояния ончейн.
+
+В качестве контрмеры каналы состояний позволяют честным пользователям оспаривать недействительные обновления состояния, отправляя последнее действительное состояние канала ончейн. Каналы состояний спроектированы таким образом, что более новые, согласованные обновления состояния имеют приоритет над более старыми обновлениями.
+
+Как только один из участников запускает ончейн-систему разрешения споров, другая сторона должна ответить в течение определенного времени (называемого окном оспаривания). Это позволяет пользователям оспаривать транзакцию выхода, особенно если другая сторона применяет устаревшее обновление.
+
+В любом случае, у пользователей канала всегда есть сильные гарантии окончательности: если переход состояния, которым они владеют, был подписан всеми участниками и является самым последним обновлением, то он имеет такую же окончательность, как и обычная ончейн-транзакция. Им все еще приходится оспаривать другую сторону ончейн, но единственным возможным исходом является финализация последнего действительного состояния, которым они владеют.
+
+### Как каналы состояний взаимодействуют с Ethereum? {#how-do-state-channels-interact-with-ethereum}
+
+Хотя они существуют как оффчейн-протоколы, у каналов состояний есть ончейн-компонент: смарт-контракт, развернутый в Ethereum при открытии канала. Этот контракт контролирует активы, внесенные в канал, проверяет обновления состояния и разрешает споры между участниками.
+
+Каналы состояний не публикуют данные о транзакциях или обязательства по состоянию в основной сети, в отличие от решений для масштабирования [уровня 2](/layer-2/). Однако они более тесно связаны с основной сетью, чем, скажем, [сайдчейны](/developers/docs/scaling/sidechains/), что делает их несколько безопаснее.
+
+Каналы состояний полагаются на основной протокол Ethereum в следующих аспектах:
+
+#### 1. Живучесть {#liveness}
+
+Ончейн-контракт, развертываемый при открытии канала, отвечает за функциональность канала. Если контракт работает в Ethereum, то канал всегда доступен для использования. И наоборот, сайдчейн всегда может выйти из строя, даже если основная сеть работает, что подвергает риску средства пользователей.
+
+#### 2. Безопасность {#security}
+
+В некоторой степени каналы состояний полагаются на Ethereum для обеспечения безопасности и защиты пользователей от злонамеренных участников. Как обсуждается в последующих разделах, каналы используют механизм доказательства мошенничества, который позволяет пользователям оспаривать попытки завершить канал с недействительным или устаревшим обновлением.
+
+В этом случае честная сторона предоставляет последнее действительное состояние канала в качестве доказательства мошенничества в ончейн-контракт для проверки. Доказательства мошенничества позволяют взаимно недоверяющим сторонам проводить оффчейн-транзакции, не рискуя при этом своими средствами.
+
+#### 3. Финальность {#finality}
+
+Обновления состояния, коллективно подписанные пользователями канала, считаются равносильными ончейн-транзакциям. Тем не менее, вся деятельность внутри канала достигает истинной окончательности только тогда, когда канал закрывается в Ethereum.
+
+В оптимистичном случае обе стороны могут сотрудничать, подписать окончательное обновление состояния и отправить его ончейн для закрытия канала, после чего средства распределяются в соответствии с окончательным состоянием канала. В пессимистичном случае, когда кто-то пытается обмануть, публикуя неверное обновление состояния ончейн, его транзакция не будет завершена до истечения окна оспаривания.
+
+## Виртуальные каналы состояний {#virtual-state-channels}
+
+Наивной реализацией канала состояний было бы развертывание нового контракта, когда два пользователя хотят выполнить приложение оффчейн. Это не только нецелесообразно, но и сводит на нет экономическую эффективность каналов состояний (затраты на ончейн-транзакции могут быстро возрасти).
+
+Для решения этой проблемы были созданы «виртуальные каналы». В отличие от обычных каналов, которые требуют ончейн-транзакций для открытия и закрытия, виртуальный канал можно открыть, выполнить и завершить без взаимодействия с основной цепью. С помощью этого метода даже возможно разрешать споры оффчейн.
+
+Эта система опирается на существование так называемых «реестровых каналов», которые были профинансированы ончейн. Виртуальные каналы между двумя сторонами могут быть построены на основе существующего реестрового канала, при этом владелец(ы) реестрового канала выступают в качестве посредника.
+
+Пользователи в каждом виртуальном канале взаимодействуют через новый экземпляр контракта, при этом реестровый канал может поддерживать несколько экземпляров контрактов. Состояние реестрового канала также содержит более одного состояния хранилища контракта, что позволяет параллельно выполнять приложения оффчейн между разными пользователями.
+
+Как и в обычных каналах, пользователи обмениваются обновлениями состояния для продвижения конечного автомата. Если не возникает спор, к посреднику нужно обращаться только при открытии или закрытии канала.
+
+### Виртуальные платежные каналы {#virtual-payment-channels}
+
+Виртуальные платежные каналы работают по той же идее, что и виртуальные каналы состояний: участники, подключенные к одной сети, могут передавать сообщения без необходимости открывать новый канал ончейн. В виртуальных платежных каналах переводы средств маршрутизируются через одного или нескольких посредников с гарантиями того, что только предполагаемый получатель может получить переведенные средства.
+
+## Применения каналов состояний {#applications-of-state-channels}
+
+### Платежи {#payments}
+
+Ранние каналы блокчейна были простыми протоколами, которые позволяли двум участникам проводить быстрые, недорогие переводы оффчейн, не платя высоких комиссий за транзакции в основной сети. Сегодня платежные каналы по-прежнему полезны для приложений, предназначенных для обмена и внесения эфира и токенов.
+
+Платежи на основе каналов имеют следующие преимущества:
+
+1. **Пропускная способность**: количество оффчейн-транзакций в канале не связано с пропускной способностью Ethereum, на которую влияют различные факторы, особенно размер и время блока. Выполняя транзакции оффчейн, каналы блокчейна могут достигать более высокой пропускной способности.
+
+2. **Конфиденциальность**: поскольку каналы существуют оффчейн, детали взаимодействия между участниками не записываются в публичный блокчейн Ethereum. Пользователям канала нужно взаимодействовать ончейн только при финансировании и закрытии каналов или при разрешении споров. Таким образом, каналы полезны для людей, которые желают большей конфиденциальности транзакций.
+
+3. **Задержка**: оффчейн-транзакции, проводимые между участниками канала, могут быть урегулированы мгновенно, если обе стороны сотрудничают, что сокращает задержки. В отличие от этого, отправка транзакции в основной сети требует ожидания, пока узлы обработают транзакцию, создадут новый блок с транзакцией и достигнут консенсуса. Пользователям также может потребоваться дождаться большего количества подтверждений блока, прежде чем считать транзакцию завершенной.
+
+4. **Стоимость**: каналы состояний особенно полезны в ситуациях, когда набор участников будет обмениваться множеством обновлений состояния в течение длительного периода. Единственные понесенные затраты — это открытие и закрытие смарт-контракта канала состояний; каждое изменение состояния между открытием и закрытием канала будет дешевле предыдущего, поскольку стоимость расчета распределяется соответствующим образом.
+
+Внедрение каналов состояний в решениях уровня 2, таких как [ролл-апы](/developers/docs/scaling/#rollups), может сделать их еще более привлекательными для платежей. Хотя каналы предлагают дешевые платежи, затраты на настройку ончейн-контракта в основной сети на этапе открытия могут быть высокими, особенно когда плата за газ резко возрастает. Ролл-апы на основе Ethereum предлагают [более низкие комиссии за транзакции](https://l2fees.info/) и могут снизить накладные расходы для участников канала за счет снижения платы за установку.
+
+### Микротранзакции {#microtransactions}
+
+Микротранзакции — это платежи на небольшую сумму (например, меньше доли доллара), которые предприятия не могут обрабатывать без убытков. Эти организации должны платить поставщикам платежных услуг, что они не могут делать, если маржа по платежам клиентов слишком низка для получения прибыли.
+
+Платежные каналы решают эту проблему, снижая накладные расходы, связанные с микротранзакциями. Например, поставщик интернет-услуг (ISP) может открыть платежный канал с клиентом, что позволит ему осуществлять небольшие платежи каждый раз, когда он пользуется услугой.
+
+Помимо затрат на открытие и закрытие канала, участники не несут дополнительных расходов на микротранзакции (нет платы за газ). Это взаимовыгодная ситуация, поскольку клиенты получают больше гибкости в том, сколько они платят за услуги, а предприятия не теряют прибыльные микротранзакции.
+
+### Децентрализованные приложения {#decentralized-applications}
+
+Как и платежные каналы, каналы состояний могут производить условные платежи в соответствии с конечными состояниями конечного автомата. Каналы состояний также могут поддерживать произвольную логику перехода состояний, что делает их полезными для выполнения общих приложений оффчейн.
+
+Каналы состояний часто ограничиваются простыми пошаговыми приложениями, так как это упрощает управление средствами, внесенными в ончейн-контракт. Кроме того, при ограниченном количестве сторон, обновляющих состояние оффчейн-приложения с определенными интервалами, наказание нечестного поведения становится относительно простым.
+
+Эффективность приложения канала состояний также зависит от его конструкции. Например, разработчик может развернуть контракт канала приложения ончейн один раз и позволить другим игрокам повторно использовать приложение, не обращаясь к ончейну. В этом случае исходный канал приложения служит в качестве реестрового канала, поддерживающего несколько виртуальных каналов, каждый из которых запускает новый экземпляр смарт-контракта приложения оффчейн.
+
+Потенциальным вариантом использования приложений с каналами состояний являются простые игры для двух игроков, в которых средства распределяются в зависимости от исхода игры. Преимущество здесь в том, что игрокам не нужно доверять друг другу (недоверительность), а ончейн-контракт, а не игроки, контролирует распределение средств и урегулирование споров (децентрализация).
+
+Другие возможные варианты использования приложений с каналами состояний включают владение именами ENS, реестры NFT и многое другое.
+
+### Атомарные переводы {#atomic-transfers}
+
+Ранние платежные каналы были ограничены переводами между двумя сторонами, что ограничивало их удобство использования. Однако появление виртуальных каналов позволило людям направлять переводы через посредников (т. е. несколько p2p-каналов) без необходимости открывать новый канал ончейн.
+
+Часто описываемые как "многопроходные переводы", маршрутизируемые платежи являются атомарными (т. е. либо все части транзакции выполняются успешно, либо она полностью отменяется). Атомарные переводы используют [Hashed Timelock Contracts (HTLC)](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts), чтобы гарантировать, что платеж будет выполнен только при соблюдении определенных условий, тем самым снижая риск контрагента.
+
+## Недостатки использования каналов состояний {#drawbacks-of-state-channels}
+
+### Предположения о живучести {#liveness-assumptions}
+
+Для обеспечения эффективности каналы состояний устанавливают временные ограничения на возможность участников канала реагировать на споры. Это правило предполагает, что участники всегда будут в сети, чтобы отслеживать активность канала и при необходимости оспаривать вызовы.
+
+В действительности пользователи могут отключаться от сети по независящим от них причинам (например, плохое интернет-соединение, механическая поломка и т. д.). Если честный пользователь отключается от сети, злоумышленник может воспользоваться ситуацией, представив старые промежуточные состояния в арбитражный контракт и украв вложенные средства.
+
+Некоторые каналы используют "сторожевые башни" — сущности, ответственные за отслеживание ончейн-событий споров от имени других и принятие необходимых мер, таких как оповещение заинтересованных сторон. Однако это может увеличить расходы на использование канала состояний.
+
+### Недоступность данных {#data-unavailability}
+
+Как объяснялось ранее, оспаривание недействительного спора требует представления последнего действительного состояния канала состояний. Это еще одно правило, основанное на предположении, что пользователи имеют доступ к последнему состоянию канала.
+
+Хотя ожидание того, что пользователи канала будут хранить копии состояния оффчейн-приложения, является разумным, эти данные могут быть утеряны из-за ошибки или механического сбоя. Если у пользователя нет резервной копии данных, он может только надеяться, что другая сторона не завершит недействительный запрос на выход, используя имеющиеся у нее старые переходы состояний.
+
+Пользователям Ethereum не приходится сталкиваться с этой проблемой, поскольку сеть обеспечивает соблюдение правил доступности данных. Данные транзакций хранятся и распространяются всеми узлами и доступны для загрузки пользователями по мере необходимости.
+
+### Проблемы с ликвидностью {#liquidity-issues}
+
+Для создания канала блокчейна участникам необходимо заблокировать средства в ончейн-смарт-контракте на время существования канала. Это снижает ликвидность пользователей канала, а также ограничивает каналы теми, кто может позволить себе держать средства заблокированными в основной сети.
+
+Однако реестровые каналы, управляемые оффчейн-поставщиком услуг (OSP), могут уменьшить проблемы с ликвидностью для пользователей. Два участника, подключенные к реестровому каналу, могут создать виртуальный канал, который они могут открыть и завершить полностью оффчейн в любое время.
+
+Оффчейн-поставщики услуг также могут открывать каналы с несколькими участниками, что делает их полезными для маршрутизации платежей. Конечно, пользователи должны платить OSP за их услуги, что для некоторых может быть нежелательно.
+
+### Атаки вредительства (Griefing attacks) {#griefing-attacks}
+
+Атаки вредительства (Griefing attacks) являются общей чертой систем, основанных на доказательствах мошенничества. Атака вредительства не приносит прямой выгоды атакующему, но причиняет вред (т. е. ущерб) жертве, отсюда и название.
+
+Доказательство мошенничества подвержено атакам вредительства, потому что честная сторона должна отвечать на каждый спор, даже недействительный, иначе она рискует потерять свои средства. Злоумышленник может решить многократно публиковать устаревшие переходы состояний ончейн, заставляя честную сторону отвечать действительным состоянием. Стоимость этих ончейн-транзакций может быстро возрасти, в результате чего честные стороны понесут убытки.
+
+### Предопределенные наборы участников {#predefined-participant-sets}
+
+По своей конструкции количество участников, составляющих канал состояний, остается неизменным в течение всего срока его существования. Это связано с тем, что обновление набора участников усложнит работу канала, особенно при его финансировании или урегулировании споров. Добавление или удаление участников также потребует дополнительной ончейн-активности, что увеличивает накладные расходы для пользователей.
+
+Хотя это упрощает рассуждения о каналах состояний, это ограничивает полезность их конструкций для разработчиков приложений. Это отчасти объясняет, почему от каналов состояний отказались в пользу других решений для масштабирования, таких как ролл-апы.
+
+### Параллельная обработка транзакций {#parallel-transaction-processing}
+
+Участники канала состояний отправляют обновления состояния по очереди, поэтому они лучше всего подходят для "пошаговых приложений" (например, шахматной партии на двоих). Это устраняет необходимость одновременной обработки обновлений состояния и сокращает работу, которую должен выполнять ончейн-контракт для наказания тех, кто публикует устаревшие обновления. Однако побочным эффектом этой конструкции является то, что транзакции зависят друг от друга, что увеличивает задержку и ухудшает общее впечатление пользователя.
+
+Некоторые каналы состояний решают эту проблему, используя "полнодуплексную" конструкцию, которая разделяет оффчейн-состояние на два однонаправленных "симплексных" состояния, что позволяет одновременно обновлять состояния. Такие конструкции улучшают пропускную способность оффчейн и уменьшают задержки транзакций.
+
+## Использование каналов состояний {#use-state-channels}
+
+Несколько проектов предоставляют реализации каналов состояния, которые вы можете интегрировать в свои децентрализованные приложения:
+
+- [Connext](https://connext.network/)
+- [Kchannels](https://www.kchannels.io/)
+- [Perun](https://perun.network/)
+- [Raiden](https://raiden.network/)
+- [Statechannels.org](https://statechannels.org/)
+
+## Дополнительные материалы {#further-reading}
+
+**Каналы состояния**
+
+- [Разбираемся в решениях масштабирования уровня 2 в Ethereum: каналы состояний, Plasma и Truebit](https://medium.com/l4-media/making-sense-of-ethereums-layer-2-scaling-solutions-state-channels-plasma-and-truebit-22cb40dcc2f4)_ — Джош Старк, 12 февраля 2018 г._
+- [Каналы состояний — объяснение](https://www.jeffcoleman.ca/state-channels/)_ — 6 ноября 2015 г., Джефф Коулман_
+- [Основы каналов состояний](https://education.district0x.io/general-topics/understanding-ethereum/basics-state-channels/) _District0x_
+- [Каналы состояний блокчейна: современное состояние](https://ieeexplore.ieee.org/document/9627997)
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/scaling/validium/index.md b/public/content/translations/ru/developers/docs/scaling/validium/index.md
new file mode 100644
index 00000000000..e78c2d25dce
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/validium/index.md
@@ -0,0 +1,166 @@
+---
+title: "Валидиум"
+description: "Введение в Validium как решение для масштабирования, которое в настоящее время используется сообществом Ethereum."
+lang: ru
+sidebarDepth: 3
+---
+
+Валидиум — это [решение для масштабирования](/developers/docs/scaling/), которое обеспечивает целостность транзакций с помощью доказательств действительности, таких как [ZK-роллапы](/developers/docs/scaling/zk-rollups/), но не хранит данные о транзакциях в основной сети Ethereum. Несмотря на то, что доступность данных вне сети (оффчейн) сопряжена с компромиссами, она может привести к значительному улучшению масштабируемости (валидиумы могут обрабатывать [~9000 транзакций в секунду или более](https://blog.matter-labs.io/zkrollup-vs-validium-starkex-5614e38bc263)).
+
+## Предварительные условия {#prerequisites}
+
+Вам следует прочитать и понять нашу страницу о [масштабировании Ethereum](/developers/docs/scaling/) и [уровне 2](/layer-2).
+
+## Что такое валидиум? {#what-is-validium}
+
+Валидиумы — это решения для масштабирования, которые используют доступность данных и вычисления вне сети и предназначены для повышения пропускной способности за счет обработки транзакций за пределами основной сети Ethereum. Подобно роллапам с нулевым разглашением (ZK-роллапы), валидиумы публикуют [доказательства с нулевым разглашением](/glossary/#zk-proof) для проверки транзакций вне сети на Ethereum. Это предотвращает недействительные переходы состояния и повышает гарантии безопасности цепочки валидиума.
+
+Эти "доказательства действительности" могут быть в форме ZK-SNARK (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) или ZK-STARK (Zero-Knowledge Scalable Transparent ARgument of Knowledge). Подробнее о [доказательствах с нулевым разглашением](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/).
+
+Средства, принадлежащие пользователям валидиума, контролируются смарт-контрактом на Ethereum. Валидиумы предлагают практически мгновенный вывод средств, как и ZK-роллапы; как только доказательство действительности запроса на вывод будет проверено в основной сети, пользователи смогут вывести средства, предоставив [доказательства Меркла](/developers/tutorials/merkle-proofs-for-offline-data-integrity/). Доказательство Меркла подтверждает включение транзакции пользователя на вывод средств в проверенный пакет транзакций, позволяя ончейн-контракту обработать вывод.
+
+Однако средства пользователей валидиума могут быть заморожены, а вывод средств ограничен. Это может произойти, если менеджеры по обеспечению доступности данных в цепочке валидиума скрывают от пользователей данные о состоянии вне сети. Без доступа к данным о транзакциях пользователи не могут рассчитать доказательство Меркла, необходимое для подтверждения владения средствами и выполнения вывода средств.
+
+Это основное различие между валидиумами и ZK-роллапами — их положение в спектре доступности данных. Оба решения по-разному подходят к хранению данных, что сказывается на безопасности и отсутствии необходимости в доверии.
+
+## Как валидиумы взаимодействуют с Ethereum? {#how-do-validiums-interact-with-ethereum}
+
+Валидиумы — это протоколы масштабирования, построенные на основе существующей цепи Ethereum. Хотя транзакции выполняются вне сети, цепочка валидиума управляется набором смарт-контрактов, развернутых в основной сети, включая:
+
+1. **Контракт-верификатор**: контракт-верификатор проверяет действительность доказательств, представленных оператором валидиума при внесении обновлений состояния. Сюда входят доказательства действительности, подтверждающие правильность транзакций вне сети, и доказательства доступности данных, проверяющие существование данных о транзакциях вне сети.
+
+2. **Основной контракт**: основной контракт хранит обязательства по состоянию (корни Меркла), представленные производителями блоков, и обновляет состояние валидиума после проверки доказательства действительности в сети. Этот контракт также обрабатывает депозиты и выводы средств из цепи валидиума.
+
+Валидиумы также зависят от основной сети Ethereum в следующих аспектах:
+
+### Расчет {#settlement}
+
+Транзакции, выполненные в валидиуме, не могут быть полностью подтверждены, пока родительская цепочка не проверит их действительность. Все операции, проводимые в валидиуме, в конечном итоге должны быть рассчитаны в основной сети. Блокчейн Ethereum также предоставляет "гарантии расчета" для пользователей валидиума, что означает, что транзакции вне сети не могут быть отменены или изменены после их фиксации в сети.
+
+### Безопасность {#security}
+
+Ethereum, действуя как уровень расчетов, также гарантирует действительность переходов состояния в валидиуме. Транзакции вне сети, выполненные в цепи валидиума, проверяются с помощью смарт-контракта на базовом уровне Ethereum.
+
+Если ончейн-контракт верификатора сочтет доказательство недействительным, транзакции будут отклонены. Это означает, что операторы должны удовлетворять условиям действительности, установленным протоколом Ethereum, перед обновлением состояния валидиума.
+
+## Как работает валидиум? {#how-does-validium-work}
+
+### Транзакции {#transactions}
+
+Пользователи отправляют транзакции оператору — узлу, ответственному за выполнение транзакций в цепи валидиума. Некоторые валидиумы могут использовать единственного оператора для выполнения цепочки или полагаться на механизм [доказательства доли владения (PoS)](/developers/docs/consensus-mechanisms/pos/) для ротации операторов.
+
+Оператор объединяет транзакции в пакет и отправляет его в схему доказательства для проведения доказательства. Схема доказательства принимает пакет транзакций (и другие соответствующие данные) в качестве входных данных и выдает доказательство действительности, подтверждающее, что операции были выполнены правильно.
+
+### Обязательства по состоянию {#state-commitments}
+
+Состояние валидиума хэшируется в виде дерева Меркла, корень которого хранится в основном контракте на Ethereum. Корень Меркла, также известный как корень состояния, действует как криптографическое обязательство по отношению к текущему состоянию аккаунтов и балансов в валидиуме.
+
+Чтобы выполнить обновление состояния, оператор должен вычислить новый корень состояния (после выполнения транзакций) и отправить его в ончейн-контракт. Если доказательство действительности проходит проверку, предлагаемое состояние принимается, и валидиум переключается на новый корень состояния.
+
+### Депозиты и выводы средств {#deposits-and-withdrawals}
+
+Пользователи переводят средства из Ethereum в валидиум, внося ETH (или любой ERC-совместимый токен) в ончейн-контракт. Контракт передает событие депозита в валидиум вне сети, где на адрес пользователя зачисляется сумма, равная его депозиту. Оператор также включает эту транзакцию пополнения в новый пакет.
+
+Чтобы вернуть средства в основную сеть, пользователь валидиума инициирует транзакцию вывода и отправляет ее оператору, который проверяет запрос на вывод и включает его в пакет. Активы пользователя в цепи валидиума также уничтожаются, прежде чем они смогут покинуть систему. После проверки доказательства действительности, связанного с пакетом, пользователь может вызвать основной контракт для вывода остатка своего первоначального депозита.
+
+В качестве механизма защиты от цензуры протокол валидиума позволяет пользователям выводить средства непосредственно из контракта валидиума, не обращаясь к оператору. В этом случае пользователям необходимо предоставить доказательство Меркла контракту-верификатору, показывающее включение аккаунта в корень состояния. Если доказательство принято, пользователь может вызвать функцию вывода средств основного контракта, чтобы вывести свои средства из валидиума.
+
+### Отправка пакетов {#batch-submission}
+
+После выполнения пакета транзакций оператор представляет связанное с ним доказательство действительности в контракт-верификатор и предлагает новый корень состояния основному контракту. Если доказательство действительное, основной контракт обновляет состояние валидиума и завершает результаты транзакций в пакете.
+
+В отличие от ZK-роллапа, производители блоков в валидиуме не обязаны публиковать данные транзакций для пакетов транзакций (только заголовки блоков). Это делает валидиум исключительно оффчейн-протоколом масштабирования, в отличие от "гибридных" протоколов масштабирования (т. е. [уровень 2](/layer-2/)), которые публикуют данные о состоянии в основной цепи Ethereum, используя данные BLOB-объектов, `calldata` или их комбинацию.
+
+### Доступность данных {#data-availability}
+
+Как уже упоминалось, валидиумы используют модель доступности данных вне сети, где операторы хранят все данные транзакций за пределами основной сети Ethereum. Небольшой объем данных в сети валидиума улучшает масштабируемость (пропускная способность не ограничена мощностью обработки данных Ethereum) и снижает комиссии для пользователей (стоимость публикации данных в сети ниже).
+
+Однако доступность данных вне сети создает проблему: данные, необходимые для создания или проверки доказательств Меркла, могут быть недоступны. Это означает, что пользователи могут быть не в состоянии вывести средства из ончейн-контракта, если операторы будут действовать злонамеренно.
+
+Различные решения на базе валидиума пытаются решить эту проблему путем децентрализации хранения данных о состоянии. Это предполагает принуждение производителей блоков к отправке базовых данных "менеджерам по доступности данных", ответственным за хранение данных вне сети и предоставление их пользователям по запросу.
+
+Менеджеры по доступности данных в валидиуме подтверждают доступность данных для транзакций вне сети, подписывая каждый пакет валидиума. Эти подписи представляют собой форму "доказательства доступности", которую ончейн-контракт верификатора проверяет перед утверждением обновлений состояния.
+
+Валидиумы различаются в своем подходе к управлению доступностью данных. Некоторые полагаются на доверенные стороны для хранения данных о состоянии, в то время как другие используют для этой задачи случайно назначенных валидаторов.
+
+#### Комитет по доступности данных (DAC) {#data-availability-committee}
+
+Чтобы гарантировать доступность данных вне сети, некоторые решения на базе валидиума назначают группу доверенных лиц, совместно именуемую комитетом по доступности данных (DAC), для хранения копий состояния и предоставления доказательства доступности данных. DAC легче реализовать, и они требуют меньшей координации, поскольку количество членов невелико.
+
+Однако пользователи должны доверять DAC в том, что он предоставит данные, когда это необходимо (например, для генерации доказательств Меркла). Существует возможность того, что члены комитетов по доступности данных [будут скомпрометированы злоумышленником](https://notes.ethereum.org/DD7GyItYQ02d0ax_X-UbWg?view), который затем сможет скрыть данные вне сети.
+
+[Подробнее о комитетах по доступности данных в валидиумах](https://medium.com/starkware/data-availability-e5564c416424).
+
+#### Обеспеченная залогом доступность данных {#bonded-data-availability}
+
+Другие валидиумы требуют, чтобы участники, ответственные за хранение данных вне сети, разместили в стейкинге (т. е. заблокировали) токены в смарт-контракте, прежде чем приступить к выполнению своих ролей. Эта ставка служит "залогом" для гарантии честного поведения среди менеджеров по доступности данных и снижает предположения о доверии. Если эти участники не смогут доказать доступность данных, их залог будет уменьшен (слешинг).
+
+В схеме обеспеченной залогом доступности данных любой может быть назначен для хранения данных вне сети, как только он предоставит требуемую ставку. Это расширяет пул подходящих менеджеров по доступности данных, снижая централизацию, которая характерна для комитетов по доступности данных (DAC). Что еще более важно, этот подход опирается на криптоэкономические стимулы для предотвращения злонамеренной деятельности, что значительно безопаснее, чем назначение доверенных сторон для защиты данных вне сети в валидиуме.
+
+[Подробнее об обеспеченной залогом доступности данных в валидиумах](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf).
+
+## Volitions и валидиум {#volitions-and-validium}
+
+Валидиумы предлагают много преимуществ, но сопряжены с компромиссами (в первую очередь, с доступностью данных). Но, как и многие решения для масштабирования, валидиумы подходят для конкретных вариантов использования — именно поэтому были созданы volitions.
+
+Volitions сочетают в себе ZK-роллап и цепь валидиума и позволяют пользователям переключаться между двумя решениями для масштабирования. С помощью volitions пользователи могут использовать доступность данных вне сети валидиума для определенных транзакций, сохраняя при этом свободу переключения на решение с доступностью данных в сети (ZK-роллап) при необходимости. По сути, это дает пользователям свободу выбора компромиссов в зависимости от их уникальных обстоятельств.
+
+Децентрализованная биржа (DEX) может предпочесть использование масштабируемой и частной инфраструктуры валидиума для сделок с высокой стоимостью. Она также может использовать ZK-роллап для пользователей, которым нужны более высокие гарантии безопасности и отсутствие необходимости в доверии, присущие ZK-роллапу.
+
+## Валидиумы и совместимость с EVM {#validiums-and-evm-compatibility}
+
+Как и ZK-роллапы, валидиумы в основном подходят для простых приложений, таких как обмен токенов и платежи. Поддержка общих вычислений и выполнения смарт-контрактов в валидиумах сложна в реализации, учитывая значительные накладные расходы на доказательство инструкций [EVM](/developers/docs/evm/) в схеме доказательства с нулевым разглашением.
+
+Некоторые проекты валидиумов пытаются обойти эту проблему, компилируя EVM-совместимые языки (например, Solidity, Vyper) для создания пользовательского байт-кода, оптимизированного для эффективного доказательства. Недостатком этого подхода является то, что новые, дружественные к доказательствам с нулевым разглашением, виртуальные машины могут не поддерживать важные опкоды EVM, и разработчикам приходится писать непосредственно на языке высокого уровня для оптимальной работы. Это создает еще больше проблем: заставляет разработчиков создавать децентрализованные приложения с совершенно новым стеком разработки и нарушает совместимость с существующей инфраструктурой Ethereum.
+
+Однако некоторые команды пытаются оптимизировать существующие опкоды EVM для схем ZK-доказательств. Это приведет к разработке виртуальной машины Ethereum с нулевым разглашением (zkEVM) — EVM-совместимой ВМ, которая производит доказательства для проверки правильности выполнения программы. С помощью zkEVM цепи валидиума могут выполнять смарт-контракты вне сети и представлять доказательства действительности для проверки вычислений вне сети (без необходимости их повторного выполнения) на Ethereum.
+
+[Подробнее о zkEVM](https://www.alchemy.com/overviews/zkevm).
+
+## Как валидиумы масштабируют Ethereum? {#scaling-ethereum-with-validiums}
+
+### 1. Хранение данных вне сети {#offchain-data-storage}
+
+Проекты масштабирования уровня 2, такие как оптимистические роллапы и ZK-роллапы, обменивают бесконечную масштабируемость чисто оффчейн-протоколов масштабирования (например, [Plasma](/developers/docs/scaling/plasma/)) на безопасность, публикуя некоторые данные о транзакциях на L1. Но это означает, что свойства масштабируемости роллапов ограничены пропускной способностью данных в основной сети Ethereum (по этой причине [шардинг данных](/roadmap/danksharding/) предлагает улучшить емкость хранения данных Ethereum).
+
+Валидиумы достигают масштабируемости, храня все данные транзакций вне сети и публикуя только обязательства по состоянию (и доказательства действительности) при передаче обновлений состояния в основную цепь Ethereum. Существование доказательств действительности, однако, дает валидиумам более высокие гарантии безопасности, чем другим чисто оффчейн-решениям для масштабирования, включая Plasma и [сайдчейны](/developers/docs/scaling/sidechains/). Уменьшая объем данных, которые Ethereum должен обработать перед проверкой транзакций вне сети, конструкции валидиума значительно увеличивают пропускную способность в основной сети.
+
+### 2. Рекурсивные доказательства {#recursive-proofs}
+
+Рекурсивное доказательство — это доказательство действительности, которое проверяет действительность других доказательств. Эти "доказательства доказательств" генерируются путем рекурсивного объединения нескольких доказательств до тех пор, пока не будет создано одно окончательное доказательство, проверяющее все предыдущие доказательства. Рекурсивные доказательства масштабируют скорость обработки блокчейна за счет увеличения количества транзакций, которые могут быть проверены одним доказательством действительности.
+
+Как правило, каждое доказательство действительности, которое оператор валидиума представляет в Ethereum для проверки, подтверждает целостность одного блока. В то время как одно рекурсивное доказательство может быть использовано для подтверждения действительности нескольких блоков валидиума одновременно — это возможно, поскольку схема доказательства может рекурсивно объединять несколько доказательств блоков в одно окончательное доказательство. Если ончейн-контракт верификатора принимает рекурсивное доказательство, все базовые блоки немедленно финализируются.
+
+## Плюсы и минусы валидиума {#pros-and-cons-of-validium}
+
+| Преимущества | Недостатки |
+| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Доказательства действительности обеспечивают целостность транзакций вне сети и не позволяют операторам финализировать недействительные обновления состояния. | Создание доказательств действительности требует специального оборудования, что создает риск централизации. |
+| Повышает эффективность капитала для пользователей (нет задержек при выводе средств обратно в Ethereum) | Ограниченная поддержка общих вычислений и смарт-контрактов; для разработки требуются специализированные языки. |
+| Неуязвимы для определенных экономических атак, с которыми сталкиваются защищенные от мошенничества системы в важных приложениях. | Высокая вычислительная мощность, необходимая для генерации ZK-доказательств; нерентабельно для приложений с низкой пропускной способностью. |
+| Снижает плату за газ для пользователей за счет отказа от публикации calldata в основной сети Ethereum. | Более медленное субъективное время финализации (10-30 минут на создание ZK-доказательства), но более быстрое до полной финализации, поскольку нет задержки на время спора. |
+| Подходит для конкретных вариантов использования, таких как торговля или блокчейн-игры, где важны конфиденциальность транзакций и масштабируемость. | Пользователям может быть запрещено выводить средства, поскольку для создания доказательств Меркла о праве собственности требуется, чтобы данные вне сети были доступны в любое время. |
+| Доступность данных вне сети обеспечивает более высокий уровень пропускной способности и повышает масштабируемость. | Модель безопасности основана на предположениях о доверии и криптоэкономических стимулах, в отличие от ZK-роллапов, которые полностью полагаются на криптографические механизмы безопасности. |
+
+### Используйте Validium/Volitions {#use-validium-and-volitions}
+
+Несколько проектов предоставляют реализации Validium и volitions, которые вы можете интегрировать в свои децентрализованные приложения:
+
+**StarkWare StarkEx** — _StarkEx — это решение для масштабирования Ethereum уровня 2 (L2), основанное на доказательствах действительности. Он может работать в режимах доступности данных ZK-Rollup или Validium._
+
+- [Документация](https://docs.starkware.co/starkex-v4/starkex-deep-dive/data-availability-modes#validium)
+- [Веб-сайт](https://starkware.co/starkex/)
+
+**Matter Labs zkPorter** — _zkPorter — это протокол масштабирования уровня 2, решающий проблему доступности данных с помощью гибридного подхода, который сочетает в себе идеи zkRollup и шардинга. Он может поддерживать произвольное количество шардов, каждый со своей собственной политикой доступности данных._
+
+- [Блог](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf)
+- [Документация](https://docs.zksync.io/zksync-protocol/rollup/data-availability)
+- [Веб-сайт](https://zksync.io/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Валидиум и матрица 2х2 для уровня 2 — выпуск № 99](https://www.buildblockchain.tech/newsletter/issues/no-99-validium-and-the-layer-2-two-by-two)
+- [ZK-роллапы в сравнении с Validium](https://blog.matter-labs.io/zkrollup-vs-validium-starkex-5614e38bc263)
+- [Volition и возникающий спектр доступности данных](https://medium.com/starkware/volition-and-the-emerging-data-availability-spectrum-87e8bfa09bb)
+- [Роллапы, валидиумы и volitions: узнайте о самых популярных решениях для масштабирования Ethereum](https://www.defipulse.com/blog/rollups-validiums-and-volitions-learn-about-the-hottest-ethereum-scaling-solutions)
+- [Практическое руководство по ролл-апам Ethereum](https://web.archive.org/web/20241108192208/https://research.2077.xyz/the-practical-guide-to-ethereum-rollups)
diff --git a/public/content/translations/ru/developers/docs/scaling/zk-rollups/index.md b/public/content/translations/ru/developers/docs/scaling/zk-rollups/index.md
new file mode 100644
index 00000000000..13cd3717b47
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/scaling/zk-rollups/index.md
@@ -0,0 +1,257 @@
+---
+title: "Роллапы с нулевым разглашением"
+description: "Введение в zero-knowledge rollups — решение для масштабирования, используемое сообществом Ethereum."
+lang: ru
+---
+
+Ролл-апы с нулевым разглашением (ZK-rollups) — это решения для [масштабирования](/developers/docs/scaling/) второго уровня, которые увеличивают пропускную способность основной сети Ethereum за счет переноса вычислений и хранения состояния вне сети. ZK-Rollups могут обрабатывать тысячи транзакций в пакете, а затем публиковать только минимальные сводные данные в основной сети. Эти сводные данные определяют изменения, которые необходимо внести в состояние Ethereum, и некоторые криптографические доказательства правильности этих изменений.
+
+## Предварительные условия {#prerequisites}
+
+Вам следует прочитать и понять нашу страницу о [масштабировании Ethereum](/developers/docs/scaling/) и [уровне 2](/layer-2).
+
+## Что такое zero-knowledge rollups? {#what-are-zk-rollups}
+
+**Ролл-апы с нулевым разглашением (ZK-rollups)** объединяют (или «сворачивают») транзакции в пакеты, которые выполняются вне сети. Вычисления вне сети уменьшают объем данных, которые необходимо публиковать в блокчейне. Операторы ZK-ролл-апов отправляют сводку изменений, необходимых для представления всех транзакций в пакете, вместо того чтобы отправлять каждую транзакцию по отдельности. Они также создают [доказательства валидности](/glossary/#validity-proof), чтобы доказать правильность своих изменений.
+
+Состояние ZK-ролл-апа поддерживается смарт-контрактом, развернутым в сети Ethereum. Для обновления этого состояния узлы ZK-ролл-апа должны предоставить доказательство валидности для проверки. Как уже упоминалось, доказательство валидности является криптографической гарантией того, что предложенное ролл-апом изменение состояния действительно является результатом выполнения данного пакета транзакций. Это означает, что ZK-ролл-апам нужно предоставлять только доказательства валидности для финализации транзакций в Ethereum, вместо того чтобы публиковать все данные транзакций в сети, как это делают [оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups/).
+
+При переводе средств из ZK-ролл-апа в Ethereum нет задержек, поскольку транзакции выхода выполняются сразу после того, как контракт ZK-ролл-апа проверяет доказательство валидности. И наоборот, вывод средств из оптимистических ролл-апов происходит с задержкой, чтобы у любого была возможность оспорить транзакцию выхода с помощью [доказательства мошенничества](/glossary/#fraud-proof).
+
+ZK-ролл-апы записывают транзакции в Ethereum как `calldata`. `calldata` — это место, где хранятся данные, включенные во внешние вызовы функций смарт-контракта. Информация в `calldata` публикуется в блокчейне, что позволяет любому самостоятельно восстановить состояние ролл-апа. ZK-ролл-апы используют методы сжатия для уменьшения данных транзакций — например, аккаунты представляются индексом, а не адресом, что экономит 28 байт данных. Публикация данных в сети — это значительная статья расходов для ролл-апов, поэтому сжатие данных может снизить комиссии для пользователей.
+
+## Как ZK-ролл-апы взаимодействуют с Ethereum? {#zk-rollups-and-ethereum}
+
+Сеть ZK-ролл-апа — это протокол вне сети, который работает поверх блокчейна Ethereum и управляется смарт-контрактами Ethereum в основной сети. ZK-ролл-апы выполняют транзакции за пределами основной сети, но периодически фиксируют пакеты транзакций вне сети в контракте ролл-апа в основной сети. Эта запись транзакций неизменна, как и блокчейн Ethereum, и формирует сеть ZK-ролл-апа.
+
+Основная архитектура ZK-ролл-апа состоит из следующих компонентов:
+
+1. **Контракты в сети**. Как уже упоминалось, протокол ZK-ролл-апа контролируется смарт-контрактами, работающими в Ethereum. К ним относится основной контракт, который хранит блоки ролл-апа, отслеживает депозиты и наблюдает за обновлениями состояния. Другой контракт в сети (контракт-верификатор) проверяет доказательства с нулевым разглашением, представленные производителями блоков. Таким образом, Ethereum служит базовым уровнем или «уровнем 1» для ZK-ролл-апа.
+
+2. **Виртуальная машина вне сети (VM)**. Хотя протокол ZK-ролл-апа существует в Ethereum, выполнение транзакций и хранение состояния происходят на отдельной виртуальной машине, независимой от [EVM](/developers/docs/evm/). Эта VM вне сети является средой выполнения транзакций в ZK-ролл-апе и служит вторичным уровнем или «уровнем 2» для протокола ZK-ролл-апа. Доказательства валидности, проверяемые в основной сети Ethereum, гарантируют правильность переходов состояний в VM вне сети.
+
+ZK-ролл-апы — это «гибридные решения для масштабирования» — протоколы вне сети, которые работают независимо, но получают безопасность от Ethereum. В частности, сеть Ethereum обеспечивает валидность обновлений состояния в ZK-ролл-апе и гарантирует доступность данных, лежащих в основе каждого обновления состояния ролл-апа. В результате ZK-ролл-апы значительно безопаснее, чем чисто офф-чейн решения для масштабирования, такие как [сайдчейны](/developers/docs/scaling/sidechains/), которые сами отвечают за свои свойства безопасности, или [валидиумы](/developers/docs/scaling/validium/), которые также проверяют транзакции на Ethereum с помощью доказательств валидности, но хранят данные транзакций в другом месте.
+
+ZK-ролл-апы полагаются на основной протокол Ethereum в следующих аспектах:
+
+### Доступность данных {#data-availability}
+
+ZK-ролл-апы публикуют данные о состоянии для каждой транзакции, обработанной вне сети, в Ethereum. С помощью этих данных частные лица или компании могут воспроизвести состояние ролл-апа и самостоятельно валидировать его сеть. Ethereum делает эти данные доступными для всех участников сети в виде `calldata`.
+
+ZK-ролл-апам не нужно публиковать много данных о транзакциях в сети, потому что доказательства валидности уже подтверждают подлинность переходов состояния. Тем не менее хранение данных в сети по-прежнему важно, поскольку это позволяет без разрешений и независимо проверять состояние сети Уровня 2, что, в свою очередь, позволяет любому отправлять пакеты транзакций, предотвращая цензуру или замораживание сети злонамеренными операторами.
+
+Взаимодействие в сети необходимо пользователям для работы с ролл-апом. Без доступа к данным о состоянии пользователи не могут запрашивать баланс своего аккаунта или инициировать транзакции (например, вывод средств), которые зависят от информации о состоянии.
+
+### Финальность транзакций {#transaction-finality}
+
+Ethereum выступает в качестве уровня расчетов для ZK-ролл-апов: транзакции Уровня 2 финализируются только в том случае, если контракт Уровня 1 принимает доказательство валидности. Это устраняет риск того, что злонамеренные операторы повредят сеть (например, украдут средства ролл-апа), поскольку каждая транзакция должна быть одобрена в основной сети. Кроме того, Ethereum гарантирует, что операции пользователя не могут быть отменены после их финализации на Уровне 1.
+
+### Устойчивость к цензуре {#censorship-resistance}
+
+Большинство ZK-ролл-апов используют «суперузел» (оператора) для выполнения транзакций, создания пакетов и отправки блоков на Уровень 1. Хотя это обеспечивает эффективность, это увеличивает риск цензуры: злонамеренные операторы ZK-ролл-апов могут подвергать цензуре пользователей, отказываясь включать их транзакции в пакеты.
+
+В качестве меры безопасности ZK-ролл-апы позволяют пользователям отправлять транзакции непосредственно в контракт ролл-апа в основной сети, если они считают, что оператор их цензурирует. Это позволяет пользователям принудительно выйти из ZK-ролл-апа в Ethereum, не полагаясь на разрешение оператора.
+
+## Как работают ZK-ролл-апы? {#how-do-zk-rollups-work}
+
+### Транзакции {#transactions}
+
+Пользователи в ZK-ролл-апе подписывают транзакции и отправляют их операторам Уровня 2 для обработки и включения в следующий пакет. В некоторых случаях оператор является централизованной сущностью, называемой секвенсором, который выполняет транзакции, объединяет их в пакеты и отправляет на Уровень 1. Секвенсор в этой системе — единственная сущность, которой разрешено создавать блоки Уровня 2 и добавлять транзакции ролл-апа в контракт ZK-ролл-апа.
+
+Другие ZK-ролл-апы могут ротировать роль оператора, используя набор валидаторов [доказательства владения](/developers/docs/consensus-mechanisms/pos/). Потенциальные операторы вносят средства в контракт ролл-апа, при этом размер каждой доли влияет на шансы стейкера быть выбранным для создания следующего пакета ролл-апа. Доля оператора может быть подвергнута слэшингу, если он действует злонамеренно, что стимулирует их публиковать валидные блоки.
+
+#### Как ZK-ролл-апы публикуют данные транзакций в Ethereum {#how-zk-rollups-publish-transaction-data-on-ethereum}
+
+Как объяснялось ранее, данные транзакций публикуются в Ethereum как `calldata`. `calldata` — это область данных в смарт-контракте, используемая для передачи аргументов в функцию, которая ведет себя аналогично [памяти](/developers/docs/smart-contracts/anatomy/#memory). `calldata` не хранится как часть состояния Ethereum, но она сохраняется в сети как часть [журналов истории](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html?highlight=memory#logs) сети Ethereum. `calldata` не влияет на состояние Ethereum, что делает ее дешевым способом хранения данных в сети.
+
+Ключевое слово `calldata` часто идентифицирует метод смарт-контракта, вызываемый транзакцией, и содержит входные данные для метода в виде произвольной последовательности байтов. ZK-ролл-апы используют `calldata` для публикации сжатых данных транзакций в сети; оператор ролл-апа просто добавляет новый пакет, вызывая необходимую функцию в контракте ролл-апа и передавая сжатые данные в качестве аргументов функции. Это помогает снизить затраты для пользователей, так как большая часть комиссий ролл-апа идет на хранение данных транзакций в сети.
+
+### Обязательства по состоянию {#state-commitments}
+
+Состояние ZK-ролл-апа, которое включает аккаунты и балансы Уровня 2, представлено в виде [дерева Меркла](/whitepaper/#merkle-trees). Криптографический хэш корня дерева Меркла (корень Меркла) хранится в контракте в сети, что позволяет протоколу ролл-апа отслеживать изменения в состоянии ZK-ролл-апа.
+
+Ролл-ап переходит в новое состояние после выполнения нового набора транзакций. Оператор, инициировавший переход состояния, обязан вычислить новый корень состояния и отправить его в контракт в сети. Если доказательство валидности, связанное с пакетом, аутентифицировано контрактом-верификатором, новый корень Меркла становится каноническим корнем состояния ZK-ролл-апа.
+
+Помимо вычисления корней состояния, оператор ZK-ролл-апа также создает корень пакета — корень дерева Меркла, включающего все транзакции в пакете. Когда отправляется новый пакет, контракт ролл-апа сохраняет корень пакета, что позволяет пользователям доказать, что транзакция (например, запрос на вывод средств) была включена в пакет. Пользователям необходимо будет предоставить детали транзакции, корень пакета и [доказательство Меркла](/developers/tutorials/merkle-proofs-for-offline-data-integrity/), показывающее путь включения.
+
+### Доказательства валидности {#validity-proofs}
+
+Новый корень состояния, который оператор ZK-ролл-апа отправляет в контракт Уровня 1, является результатом обновлений состояния ролл-апа. Допустим, Алиса отправляет 10 токенов Бобу, оператор просто уменьшает баланс Алисы на 10 и увеличивает баланс Боба на 10. Затем оператор хэширует обновленные данные аккаунта, перестраивает дерево Меркла ролл-апа и отправляет новый корень Меркла в контракт в сети.
+
+Но контракт ролл-апа не примет автоматически предложенное обязательство по состоянию, пока оператор не докажет, что новый корень Меркла является результатом правильных обновлений состояния ролл-апа. Оператор ZK-ролл-апа делает это, создавая доказательство валидности — краткое криптографическое обязательство, подтверждающее правильность пакетных транзакций.
+
+Доказательства валидности позволяют сторонам доказывать правильность утверждения, не раскрывая само утверждение, — отсюда и их второе название «доказательства с нулевым разглашением». ZK-ролл-апы используют доказательства валидности для подтверждения правильности переходов состояния вне сети без необходимости повторного выполнения транзакций в Ethereum. Эти доказательства могут быть в форме [ZK-SNARK](https://arxiv.org/abs/2202.06877) (краткий неинтерактивный аргумент знания с нулевым разглашением) или [ZK-STARK](https://eprint.iacr.org/2018/046) (масштабируемый прозрачный аргумент знания с нулевым разглашением).
+
+И SNARK, и STARK помогают подтвердить целостность вычислений вне сети в ZK-ролл-апах, хотя каждый тип доказательства имеет свои отличительные особенности.
+
+**ZK-SNARKs**
+
+Для работы протокола ZK-SNARK необходимо создать общую эталонную строку (CRS): CRS предоставляет публичные параметры для доказывания и проверки доказательств валидности. Безопасность системы доказывания зависит от настройки CRS; если информация, используемая для создания публичных параметров, попадет в руки злоумышленников, они смогут генерировать ложные доказательства валидности.
+
+Некоторые ZK-ролл-апы пытаются решить эту проблему, используя [церемонию многосторонних вычислений (MPC)](https://zkproof.org/2021/06/30/setup-ceremonies/amp/) с участием доверенных лиц для генерации публичных параметров для схемы ZK-SNARK. Каждая сторона вносит некоторую случайность (называемую «токсичными отходами») для создания CRS, которую они должны немедленно уничтожить.
+
+Доверенные настройки используются, потому что они повышают безопасность настройки CRS. Пока хотя бы один честный участник уничтожает свои входные данные, безопасность системы ZK-SNARK гарантирована. Тем не менее, этот подход требует доверия к участникам в том, что они удалят свою выборку случайности и не подорвут гарантии безопасности системы.
+
+Несмотря на допущения о доверии, ZK-SNARKs популярны благодаря своим малым размерам доказательств и проверке за постоянное время. Поскольку проверка доказательств на Уровне 1 составляет большую часть затрат на эксплуатацию ZK-ролл-апа, Уровни 2 используют ZK-SNARKs для генерации доказательств, которые можно быстро и дешево проверить в основной сети.
+
+**ZK-STARKs**
+
+Как и ZK-SNARK, ZK-STARK доказывают валидность вычислений вне сети, не раскрывая входных данных. Однако ZK-STARK считаются усовершенствованием ZK-SNARK из-за их масштабируемости и прозрачности.
+
+ZK-STARK являются «прозрачными», поскольку они могут работать без доверенной настройки общей эталонной строки (CRS). Вместо этого ZK-STARK полагаются на публично проверяемую случайность для настройки параметров генерации и проверки доказательств.
+
+ZK-STARK также обеспечивают большую масштабируемость, поскольку время, необходимое для доказывания и проверки доказательств валидности, увеличивается _квазилинейно_ по отношению к сложности базового вычисления. В случае ZK-SNARK время доказывания и проверки масштабируется _линейно_ по отношению к размеру базового вычисления. Это означает, что ZK-STARK требуют меньше времени, чем ZK-SNARK, для доказывания и проверки при работе с большими наборами данных, что делает их полезными для приложений с большим объемом операций.
+
+ZK-STARK также устойчивы к атакам квантовых компьютеров, в то время как криптография на эллиптических кривых (ECC), используемая в ZK-SNARK, как широко считается, уязвима для атак квантовых компьютеров. Недостатком ZK-STARK является то, что они создают доказательства большего размера, проверка которых в Ethereum обходится дороже.
+
+#### Как работают доказательства валидности в ZK-ролл-апах? {#validity-proofs-in-zk-rollups}
+
+##### Генерация доказательства
+
+Прежде чем принять транзакции, оператор выполнит обычные проверки. Это включает в себя подтверждение того, что:
+
+- Аккаунты отправителя и получателя являются частью дерева состояний.
+- У отправителя достаточно средств для обработки транзакции.
+- Транзакция корректна и соответствует публичному ключу отправителя в ролл-апе.
+- Нонс отправителя корректен и т. д.
+
+Как только узел ZK-ролл-апа набирает достаточное количество транзакций, он объединяет их в пакет и компилирует входные данные для схемы доказывания, чтобы скомпилировать их в краткое ZK-доказательство. Это включает:
+
+- Корень дерева Меркла, включающий все транзакции в пакете.
+- Доказательства Меркла для транзакций, чтобы доказать их включение в пакет.
+- Доказательства Меркла для каждой пары отправитель-получатель в транзакциях, чтобы доказать, что эти аккаунты являются частью дерева состояний ролл-апа.
+- Набор промежуточных корней состояния, полученных путем обновления корня состояния после применения обновлений состояния для каждой транзакции (т. е. уменьшение балансов аккаунтов отправителей и увеличение балансов аккаунтов получателей).
+
+Схема доказывания вычисляет доказательство валидности, «проходя» по каждой транзакции и выполняя те же проверки, которые оператор завершил перед обработкой транзакции. Во-первых, она проверяет, является ли аккаунт отправителя частью существующего корня состояния, используя предоставленное доказательство Меркла. Затем она уменьшает баланс отправителя, увеличивает его нонс, хэширует обновленные данные аккаунта и объединяет их с доказательством Меркла для генерации нового корня Меркла.
+
+Этот корень Меркла отражает единственное изменение в состоянии ZK-ролл-апа: изменение баланса и нонса отправителя. Это возможно, потому что доказательство Меркла, используемое для подтверждения существования аккаунта, используется для получения нового корня состояния.
+
+Схема доказывания выполняет тот же процесс для аккаунта получателя. Она проверяет, существует ли аккаунт получателя под промежуточным корнем состояния (используя доказательство Меркла), увеличивает его баланс, повторно хэширует данные аккаунта и объединяет их с доказательством Меркла для генерации нового корня состояния.
+
+Процесс повторяется для каждой транзакции; каждый «цикл» создает новый корень состояния из обновления аккаунта отправителя и последующий новый корень из обновления аккаунта получателя. Как объяснялось, каждое обновление корня состояния представляет собой изменение одной части дерева состояний ролл-апа.
+
+Схема ZK-доказывания итерирует по всему пакету транзакций, проверяя последовательность обновлений, которые приводят к конечному корню состояния после выполнения последней транзакции. Последний вычисленный корень Меркла становится новейшим каноническим корнем состояния ZK-ролл-апа.
+
+##### Проверка доказательства
+
+После того как схема доказывания проверит правильность обновлений состояния, оператор Уровня 2 отправляет вычисленное доказательство валидности в контракт-верификатор на Уровне 1. Схема верификации контракта проверяет валидность доказательства, а также проверяет публичные входные данные, которые являются частью доказательства:
+
+- **Корень предыдущего состояния**: старый корень состояния ZK-ролл-апа (т. е. до выполнения пакетных транзакций), отражающий последнее известное валидное состояние сети Уровня 2.
+
+- **Корень последующего состояния**: новый корень состояния ZK-ролл-апа (т. е. после выполнения пакетных транзакций), отражающий новейшее состояние сети Уровня 2. Корень последующего состояния — это конечный корень, полученный после применения обновлений состояния в схеме доказывания.
+
+- **Корень пакета**: корень Меркла пакета, полученный путем _мерклизации_ транзакций в пакете и хэширования корня дерева.
+
+- **Входные данные транзакций**: данные, связанные с транзакциями, выполненными в рамках отправленного пакета.
+
+Если доказательство удовлетворяет схеме (т. е. является валидным), это означает, что существует последовательность валидных транзакций, которые переводят ролл-ап из предыдущего состояния (криптографически отмеченного корнем предыдущего состояния) в новое состояние (криптографически отмеченное корнем последующего состояния). Если корень предыдущего состояния совпадает с корнем, хранящимся в контракте ролл-апа, и доказательство валидно, контракт ролл-апа берет корень последующего состояния из доказательства и обновляет свое дерево состояний, чтобы отразить измененное состояние ролл-апа.
+
+### Входы и выходы {#entries-and-exits}
+
+Пользователи входят в ZK-ролл-ап, внося токены в контракт ролл-апа, развернутый в сети Уровня 1. Эта транзакция ставится в очередь, так как только операторы могут отправлять транзакции в контракт ролл-апа.
+
+Если очередь ожидающих депозитов начинает заполняться, оператор ZK-ролл-апа возьмет транзакции депозитов и отправит их в контракт ролл-апа. Как только средства пользователя оказываются в ролл-апе, они могут начать совершать транзакции, отправляя их оператору на обработку. Пользователи могут проверять балансы в ролл-апе, хэшируя данные своего аккаунта, отправляя хэш в контракт ролл-апа и предоставляя доказательство Меркла для проверки относительно текущего корня состояния.
+
+Вывод средств из ZK-ролл-апа на Уровень 1 прост. Пользователь инициирует транзакцию выхода, отправляя свои активы в ролл-апе на указанный аккаунт для сжигания. Если оператор включит транзакцию в следующий пакет, пользователь может отправить запрос на вывод средств в контракт в сети. Этот запрос на вывод средств будет включать следующее:
+
+- Доказательство Меркла, подтверждающее включение транзакции пользователя на аккаунт сжигания в пакет транзакций
+
+- Данные транзакции
+
+- Корень пакета
+
+- Адрес Уровня 1 для получения депонированных средств
+
+Контракт ролл-апа хэширует данные транзакции, проверяет существование корня пакета и использует доказательство Меркла, чтобы проверить, является ли хэш транзакции частью корня пакета. После этого контракт выполняет транзакцию выхода и отправляет средства на выбранный пользователем адрес на Уровне 1.
+
+## ZK-ролл-апы и совместимость с EVM {#zk-rollups-and-evm-compatibility}
+
+В отличие от оптимистических ролл-апов, ZK-ролл-апы не являются легко совместимыми с [виртуальной машиной Ethereum (EVM)](/developers/docs/evm/). Доказывание вычислений EVM общего назначения в схемах сложнее и более ресурсоемко, чем доказывание простых вычислений (например, перевод токенов, описанный ранее).
+
+Однако [достижения в технологии с нулевым разглашением](https://hackmd.io/@yezhang/S1_KMMbGt#Why-possible-now) вызывают возобновленный интерес к обертыванию вычислений EVM в доказательства с нулевым разглашением. Эти усилия направлены на создание реализации EVM с нулевым разглашением (zkEVM), которая может эффективно проверять правильность выполнения программы. zkEVM воссоздает существующие опкоды EVM для доказывания/проверки в схемах, что позволяет выполнять смарт-контракты.
+
+Как и EVM, zkEVM переходит между состояниями после выполнения вычислений над некоторыми входными данными. Разница в том, что zkEVM также создает доказательства с нулевым разглашением для проверки правильности каждого шага выполнения программы. Доказательства валидности могут проверять правильность операций, затрагивающих состояние ВМ (память, стек, хранилище), и само вычисление (т. е. вызвала ли операция правильные опкоды и выполнила ли их корректно?).
+
+Ожидается, что внедрение ZK-ролл-апов, совместимых с EVM, поможет разработчикам использовать масштабируемость и гарантии безопасности доказательств с нулевым разглашением. Что еще более важно, совместимость с нативной инфраструктурой Ethereum означает, что разработчики могут создавать дружественные к ZK децентрализованные приложения, используя знакомые (и проверенные в боях) инструменты и языки.
+
+## Как работают комиссии ZK-ролл-апов? {#how-do-zk-rollup-fees-work}
+
+Сколько пользователи платят за транзакции в ZK-ролл-апах, зависит от комиссии за газ, так же как и в основной сети Ethereum. Однако комиссии за газ на Уровне 2 работают по-другому и зависят от следующих затрат:
+
+1. **Запись состояния**: существует фиксированная стоимость записи в состояние Ethereum (т. е. отправки транзакции в блокчейн Ethereum). ZK-ролл-апы снижают эту стоимость, объединяя транзакции в пакеты и распределяя фиксированные затраты между несколькими пользователями.
+
+2. **Публикация данных**: ZK-ролл-апы публикуют данные о состоянии для каждой транзакции в Ethereum в виде `calldata`. Стоимость `calldata` в настоящее время регулируется [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), который устанавливает стоимость в 16 единиц газа за ненулевые байты и 4 единицы газа за нулевые байты `calldata` соответственно. Стоимость, уплачиваемая за каждую транзакцию, зависит от того, сколько `calldata` для нее необходимо опубликовать в сети.
+
+3. **Комиссии оператора Уровня 2**: это сумма, выплачиваемая оператору ролл-апа в качестве компенсации за вычислительные затраты, понесенные при обработке транзакций, подобно [«приоритетным комиссиям (чаевым)» за транзакции](/developers/docs/gas/#how-are-gas-fees-calculated) в основной сети Ethereum.
+
+4. **Генерация и проверка доказательств**: операторы ZK-ролл-апов должны создавать доказательства валидности для пакетов транзакций, что является ресурсоемким процессом. Проверка доказательств с нулевым разглашением в основной сети также требует газа (~ 500 000 единиц газа).
+
+Помимо объединения транзакций в пакеты, ZK-ролл-апы снижают комиссии для пользователей за счет сжатия данных транзакций. Вы можете [увидеть обзор в реальном времени](https://l2fees.info/), сколько стоит использование ZK-ролл-апов Ethereum.
+
+## Как ZK-ролл-апы масштабируют Ethereum? {#scaling-ethereum-with-zk-rollups}
+
+### Сжатие данных транзакций {#transaction-data-compression}
+
+ZK-ролл-апы увеличивают пропускную способность базового уровня Ethereum, вынося вычисления за пределы сети, но настоящий прирост в масштабировании достигается за счет сжатия данных транзакций. [Размер блока](/developers/docs/blocks/#block-size) Ethereum ограничивает объем данных, который может содержать каждый блок, и, следовательно, количество транзакций, обрабатываемых в каждом блоке. Сжимая данные, связанные с транзакциями, ZK-ролл-апы значительно увеличивают количество транзакций, обрабатываемых в каждом блоке.
+
+ZK-ролл-апы могут сжимать данные транзакций лучше, чем оптимистические ролл-апы, поскольку им не нужно публиковать все данные, необходимые для валидации каждой транзакции. Им нужно публиковать только минимальные данные, необходимые для восстановления последнего состояния аккаунтов и балансов в ролл-апе.
+
+### Рекурсивные доказательства {#recursive-proofs}
+
+Преимущество доказательств с нулевым разглашением заключается в том, что доказательства могут проверять другие доказательства. Например, один ZK-SNARK может проверять другие ZK-SNARK. Такие «доказательства доказательств» называются рекурсивными доказательствами и значительно увеличивают пропускную способность ZK-ролл-апов.
+
+В настоящее время доказательства валидности генерируются для каждого блока и отправляются в контракт Уровня 1 для проверки. Однако проверка доказательств для одного блока ограничивает пропускную способность, которую могут достичь ZK-ролл-апы, поскольку только один блок может быть финализирован, когда оператор отправляет доказательство.
+
+Рекурсивные доказательства, однако, позволяют финализировать несколько блоков с одним доказательством валидности. Это происходит потому, что схема доказывания рекурсивно агрегирует доказательства нескольких блоков до тех пор, пока не будет создано одно окончательное доказательство. Оператор Уровня 2 отправляет это рекурсивное доказательство, и если контракт его принимает, все соответствующие блоки будут финализированы мгновенно. С рекурсивными доказательствами количество транзакций ZK-ролл-апов, которые могут быть финализированы в Ethereum за определенные интервалы, увеличивается.
+
+### Плюсы и минусы ZK-ролл-апов {#zk-rollups-pros-and-cons}
+
+| Преимущества | Недостатки |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Доказательства валидности обеспечивают правильность транзакций вне сети и предотвращают выполнение операторами невалидных переходов состояния. | Затраты, связанные с вычислением и проверкой доказательств валидности, значительны и могут увеличить комиссии для пользователей ролл-апа. |
+| Обеспечивает более быструю финализацию транзакций, поскольку обновления состояния одобряются после проверки доказательств валидности на Уровне 1. | Создание ZK-ролл-апов, совместимых с EVM, затруднено из-за сложности технологии с нулевым разглашением. |
+| Полагается на бездоверительные криптографические механизмы для обеспечения безопасности, а не на честность стимулируемых участников, как в случае с [оптимистическими ролл-апами](/developers/docs/scaling/optimistic-rollups/#optimistic-pros-and-cons). | Создание доказательств валидности требует специализированного оборудования, что может способствовать централизованному контролю над сетью со стороны нескольких сторон. |
+| Хранит данные, необходимые для восстановления состояния вне сети, на Уровне 1, что гарантирует безопасность, устойчивость к цензуре и децентрализацию. | Централизованные операторы (секвенсоры) могут влиять на порядок транзакций. |
+| Пользователи выигрывают от большей эффективности капитала и могут выводить средства с Уровня 2 без задержек. | Требования к оборудованию могут сократить число участников, способных заставить сеть развиваться, что увеличивает риск заморозки состояния ролл-апа и цензуры пользователей злонамеренными операторами. |
+| Не зависит от предположений о живучести, и пользователям не нужно валидировать сеть для защиты своих средств. | Некоторые системы доказывания (например, ZK-SNARK) требуют доверенной настройки, которая, в случае неправильного обращения, может потенциально скомпрометировать модель безопасности ZK-ролл-апа. |
+| Лучшее сжатие данных может помочь снизить затраты на публикацию `calldata` в Ethereum и минимизировать комиссии ролл-апа для пользователей. | |
+
+### Визуальное объяснение ZK-ролл-апов {#zk-video}
+
+Посмотрите объяснение ZK-ролл-апов от Finematics:
+
+
+
+## Кто работает над zkEVM? {#zkevm-projects}
+
+Проекты, работающие над zkEVM, включают:
+
+- **[zkEVM](https://github.com/privacy-scaling-explorations/zkevm-specs)** — _zkEVM — это проект, финансируемый Ethereum Foundation, для разработки ZK-ролл-апа, совместимого с EVM, и механизма для генерации доказательств валидности для блоков Ethereum._
+
+- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)** — _это децентрализованный ZK-ролл-ап в основной сети Ethereum, работающий над виртуальной машиной Ethereum с нулевым разглашением (zkEVM), которая прозрачно выполняет транзакции Ethereum, включая смарт-контракты с валидацией через доказательства с нулевым разглашением._
+
+- **[Scroll](https://scroll.io/blog/zkEVM)** — _Scroll — это технологическая компания, работающая над созданием нативного решения Уровня 2 zkEVM для Ethereum._
+
+- **[Taiko](https://taiko.xyz)** — _Taiko — это децентрализованный, эквивалентный Ethereum ZK-ролл-ап ([Тип 1 ZK-EVM](https://vitalik.eth.limo/general/2022/08/04/zkevm.html))._
+
+- **[ZKsync](https://docs.zksync.io/)** — _ZKsync Era — это ZK-ролл-ап, совместимый с EVM, созданный Matter Labs и работающий на собственном zkEVM._
+
+- **[Starknet](https://starkware.co/starknet/)** — _StarkNet — это решение для масштабирования второго уровня, совместимое с EVM, созданное StarkWare._
+
+- **[Morph](https://www.morphl2.io/)** — _Morph — это гибридное решение для масштабирования ролл-апов, которое использует zk-доказательства для решения проблемы с состоянием на Уровне 2._
+
+- **[Linea](https://linea.build)** — _Linea — это эквивалентный Ethereum zkEVM Уровня 2, созданный Consensys и полностью согласованный с экосистемой Ethereum._
+
+## Дополнительные материалы для чтения о ZK-ролл-апах {#further-reading-on-zk-rollups}
+
+- [Что такое ролл-апы с нулевым разглашением?](https://coinmarketcap.com/alexandria/glossary/zero-knowledge-rollups)
+- [Что такое ролл-апы с нулевым разглашением?](https://alchemy.com/blog/zero-knowledge-rollups)
+- [Практическое руководство по ролл-апам Ethereum](https://web.archive.org/web/20241108192208/https://research.2077.xyz/the-practical-guide-to-ethereum-rollups)
+- [STARKs против SNARKs](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/)
+- [Что такое zkEVM?](https://www.alchemy.com/overviews/zkevm)
+- [Типы ZK-EVM: эквивалентные Ethereum, эквивалентные EVM, Тип 1, Тип 4 и другие загадочные модные словечки](https://taiko.mirror.xyz/j6KgY8zbGTlTnHRFGW6ZLVPuT0IV0_KmgowgStpA0K4)
+- [Введение в zkEVM](https://hackmd.io/@yezhang/S1_KMMbGt)
+- [Что такое ZK-EVM Уровня 2?](https://linea.mirror.xyz/qD18IaQ4BROn_Y40EBMTUTdJHYghUtdECscSWyMvm8M)
+- [Потрясающие ресурсы по zkEVM](https://github.com/LuozhuZhang/awesome-zkevm)
+- [ZK-SNARKS под капотом](https://vitalik.eth.limo/general/2017/02/01/zk_snarks.html)
+- [Как возможны SNARKs?](https://vitalik.eth.limo/general/2021/01/26/snarks.html)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/anatomy/index.md b/public/content/translations/ru/developers/docs/smart-contracts/anatomy/index.md
new file mode 100644
index 00000000000..a72f4d07126
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/anatomy/index.md
@@ -0,0 +1,657 @@
+---
+title: "Подробнее о смарт-контрактах"
+description: "Подробный обзор анатомии смарт-контракта – функции, данные и переменные."
+lang: ru
+---
+
+Смарт-контракт - это программа, которая запускается на определенном адресе на Ethereum. Они состоят из данных и функций, которые могут выполняться при получении транзакции. Вот обзор того, что представляет из себя смарт-контракт.
+
+## Предварительные условия {#prerequisites}
+
+Сначала убедитесь, что вы прочитали о [смарт-контрактах](/developers/docs/smart-contracts/). Эта статья предполагает, что вы уже знакомы с языками программирования, такими как JavaScript или Python.
+
+## Данные {#data}
+
+Любые данные контракта должны быть присвоены местоположению: либо `storage`, либо `memory`. Модифицировать хранилище в смарт контракте - дорогостоящая операция, поэтому вам необходимо подумать заранее, где ваши данные должны храниться.
+
+### Хранилища {#storage}
+
+Постоянные данные называются хранилищем и представлены переменными состояния. Эти значения постоянно хранятся в блокчейне. Вам необходимо объявить тип, чтобы контракт мог отслеживать, сколько пространства в блокчейне ему потребуется при компиляции.
+
+```solidity
+// Пример Solidity
+contract SimpleStorage {
+ uint storedData; // Переменная состояния
+ // ...
+}
+```
+
+```python
+Пример на Vyper
+```
+
+Если вы уже программировали объектно-ориентированные языки, то вы, скорее всего, будете знакомы с большинством типов. Однако, `address` может быть для вас в новинку, если вы новичок в разработке на Ethereum.
+
+Тип `address` может содержать адрес Ethereum, который равен 20 байтам или 160 битам. Он возвращается в шестнадцатеричной нотации с лидирующим значением 0x.
+
+Другие типы включают:
+
+- логический
+- целое число
+- числа с фиксированной точкой
+- байтовые массивы фиксированного размера
+- массивы байтов динамического размера
+- рациональные и целочисленные литералы
+- строковые литералы
+- шестнадцатеричные литералы
+- перечисления
+
+Для более подробного объяснения, ознакомьтесь с документацией:
+
+- [Смотрите типы Vyper](https://docs.vyperlang.org/en/v0.1.0-beta.6/types.html#value-types)
+- [Смотрите типы Solidity](https://docs.soliditylang.org/en/latest/types.html#value-types)
+
+### Память {#memory}
+
+Значения, которые хранятся только на время выполнения контрактной функции, называются переменными памяти. Поскольку они не хранятся постоянно в блокчейне, их использование намного дешевле.
+
+Узнайте больше о том, как EVM хранит данные (хранилище, память и стек) в [документации Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#storage-memory-and-the-stack).
+
+### Переменные среды {#environment-variables}
+
+В дополнение к переменным, которые вы определяете по вашему контракту, есть некоторые специальные глобальные переменные. Они в основном используются для предоставления информации о блокчейне или текущей транзакции.
+
+Примеры:
+
+| **Свойство** | **Переменная состояния** | **Описание** |
+| ----------------- | ------------------------ | -------------------------------------------------------- |
+| `block.timestamp` | uint256 | Текущая метка времени начала блоков |
+| `msg.sender` | адрес | Отправитель сообщения (текущий вызов) |
+
+## Функции {#functions}
+
+В наиболее упрощенных терминах функции могут получать информацию или устанавливать информацию в ответ на входящие транзакции.
+
+Существует два типа вызовов функций:
+
+- `internal` – не создают вызов EVM
+ - К внутренним функциям и переменным состояния можно получить доступ только изнутри (т. е. из текущего контракта или контрактов, производных от него)
+- `external` – создают вызов EVM
+ - Внешние функции являются частью контрактного интерфейса, что означает, что они могут быть вызваны из других контрактов и через сделки. Внешняя функция `f` не может быть вызвана внутренне (т. е. `f()` не работает, но `this.f()` работает).
+
+Они также могут быть `public` или `private`
+
+- Функции `public` можно вызывать внутренне из контракта или внешне с помощью сообщений
+- Функции `private` видны только для контракта, в котором они определены, и не видны в производных контрактах
+
+Функции и переменные состояний могут быть общедоступными или частными
+
+Вот функция обновления переменной состояния по контракту:
+
+```solidity
+// Пример солидарности
+function update_name(string value) public {
+ dapp_name = value;
+}
+```
+
+- Параметр `value` типа `string` передается в функцию: `update_name`
+- Она объявлена как `public`, что означает, что любой может получить к ней доступ
+- Она не объявлена как `view`, поэтому может изменять состояние контракта
+
+### Функции просмотра {#view-functions}
+
+Эти функции обещают не изменять состояние данных контракта. Типичными примерами являются функции "получения" - вы можете использовать их, например, для получения баланса пользователя.
+
+```solidity
+// Пример твердости
+функция balanceOf (address _owner) в публичном представлении возвращает (uint256 _balance) {
+ вернуть ownerPizzaCount [_owner];
+}
+```
+
+```python
+dappName: public(string)
+
+@view
+@public
+def readName() -> string:
+ return dappName
+```
+
+Что считается измененным состоянием:
+
+1. Запись переменных состояний.
+2. [Генерирование событий](https://docs.soliditylang.org/en/v0.7.0/contracts.html#events).
+3. [Создание других контрактов](https://docs.soliditylang.org/en/v0.7.0/control-structures.html#creating-contracts).
+4. Использование `selfdestruct`.
+5. Отправка эфира через вызовы.
+6. Вызов любой функции, не отмеченной как `view` или `pure`.
+7. Использование низкоуровневых вызовов.
+8. Используя встроенную сборку, которая содержит некоторые опкоды.
+
+### Функции конструктора {#constructor-functions}
+
+Функции `constructor` выполняются только один раз при первом развертывании контракта. Подобно `constructor` во многих объектно-ориентированных языках программирования, эти функции часто инициализируют переменные состояния их заданными значениями.
+
+```solidity
+// Пример на Solidity
+// Инициализирует данные контракта, устанавливая `owner`
+// в качестве адреса создателя контракта.
+constructor() public {
+ // Все смарт-контракты полагаются на внешние транзакции для запуска своих функций.
+ // `msg` — это глобальная переменная, которая содержит актуальные данные о данной транзакции,
+ // такие как адрес отправителя и значение ETH, включенное в транзакцию.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
+ owner = msg.sender;
+}
+```
+
+```python
+# Vyper example
+
+@external
+def __init__(_beneficiary: address, _bidding_time: uint256):
+ self.beneficiary = _beneficiary
+ self.auctionStart = block.timestamp
+ self.auctionEnd = self.auctionStart + _bidding_time
+```
+
+### Встроенные функции {#built-in-functions}
+
+В дополнение к переменным и функциям, которые вы определяете в своем контракте, есть несколько специальных встроенных функций. Самый очевидный пример:
+
+- `address.send()` – Solidity
+- `send(address)` – Vyper
+
+Это позволяет контрактам отправлять ETH на другие учетные записи.
+
+## Написание функций {#writing-functions}
+
+Ваша функция требует:
+
+- переменная параметра и тип (если он принимает параметры)
+- декларация внутреннего / внешнего
+- декларация о чистом / просмотре / к оплате
+- возвращает тип (если возвращает значение)
+
+```solidity
+pragma solidity >=0.4.0 <=0.6.0;
+
+contract ExampleDapp {
+ string dapp_name; // переменная состояния
+
+ // Вызывается при развертывании контракта и инициализирует значение
+ constructor() public {
+ dapp_name = "My Example dapp";
+ }
+
+ // Функция получения
+ function read_name() public view returns(string) {
+ return dapp_name;
+ }
+
+ // Функция установки
+ function update_name(string value) public {
+ dapp_name = value;
+ }
+}
+```
+
+Полный контракт может выглядеть примерно так. Здесь функция `constructor` задает начальное значение для переменной `dapp_name`.
+
+## События и журналы {#events-and-logs}
+
+События позволяют вашему смарт-контракту взаимодействовать с вашим внешним интерфейсом или другими подписанными приложениями. После того, как транзакция проверена и добавлена в блок, смарт-контракты могут генерировать события и регистрировать информацию, которую внешний интерфейс затем может обрабатывать и использовать.
+
+## Примеры с комментариями {#annotated-examples}
+
+Это несколько примеров, написанных на Solidity. Если вы хотите поэкспериментировать с кодом, вы можете взаимодействовать с ним в [Remix](http://remix.ethereum.org).
+
+### Hello world {#hello-world}
+
+```solidity
+// Указывает версию Solidity, используя семантическое версионирование.
+// Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+pragma solidity ^0.5.10;
+
+// Определяет контракт с именем `HelloWorld`.
+// Контракт — это набор функций и данных (его состояние).
+// После развертывания контракт находится по определенному адресу в блокчейне Ethereum.
+// Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+contract HelloWorld {
+
+ // Объявляет переменную состояния `message` типа `string`.
+ // Переменные состояния — это переменные, значения которых постоянно хранятся в хранилище контракта.
+ // Ключевое слово `public` делает переменные доступными извне контракта
+ // и создает функцию, которую могут вызывать другие контракты или клиенты для доступа к значению.
+ string public message;
+
+ // Подобно многим объектно-ориентированным языкам, конструктор — это
+ // специальная функция, которая выполняется только при создании контракта.
+ // Конструкторы используются для инициализации данных контракта.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ constructor(string memory initMessage) public {
+ // Принимает строковый аргумент `initMessage` и устанавливает его значение
+ // в переменную хранилища контракта `message`).
+ message = initMessage;
+ }
+
+ // Публичная функция, которая принимает строковый аргумент
+ // и обновляет переменную хранилища `message`.
+ function update(string memory newMessage) public {
+ message = newMessage;
+ }
+}
+```
+
+### Токен {#token}
+
+```solidity
+pragma solidity ^0.5.10;
+
+contract Token {
+ // `address` можно сравнить с адресом электронной почты — он используется для идентификации аккаунта в Ethereum.
+ // Адреса могут представлять смарт-контракт или внешние (пользовательские) аккаунты.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/types.html#address
+ address public owner;
+
+ // `mapping` — это, по сути, структура данных хеш-таблицы.
+ // Этот `mapping` присваивает беззнаковое целое число (баланс токенов) адресу (владельцу токенов).
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types
+ mapping (address => uint) public balances;
+
+ // События позволяют регистрировать активность в блокчейне.
+ // Клиенты Ethereum могут прослушивать события, чтобы реагировать на изменения состояния контракта.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events
+ event Transfer(address from, address to, uint amount);
+
+ // Инициализирует данные контракта, устанавливая `owner`
+ // в качестве адреса создателя контракта.
+ constructor() public {
+ // Все смарт-контракты полагаются на внешние транзакции для запуска своих функций.
+ // `msg` — это глобальная переменная, которая содержит актуальные данные о данной транзакции,
+ // такие как адрес отправителя и значение ETH, включенное в транзакцию.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
+ owner = msg.sender;
+ }
+
+ // Создает определенное количество новых токенов и отправляет их на адрес.
+ function mint(address receiver, uint amount) public {
+ // `require` — это управляющая структура, используемая для обеспечения выполнения определенных условий.
+ // Если выражение `require` оценивается как `false`, вызывается исключение,
+ // которое отменяет все изменения, внесенные в состояние во время текущего вызова.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
+
+ // Только владелец контракта может вызывать эту функцию
+ require(msg.sender == owner, "You are not the owner.");
+
+ // Применяет максимальное количество токенов
+ require(amount < 1e60, "Maximum issuance exceeded");
+
+ // Увеличивает баланс `receiver` на `amount`
+ balances[receiver] += amount;
+ }
+
+ // Отправляет определенное количество существующих токенов от любого вызывающего на адрес.
+ function transfer(address receiver, uint amount) public {
+ // У отправителя должно быть достаточно токенов для отправки
+ require(amount <= balances[msg.sender], "Insufficient balance.");
+
+ // Корректирует балансы токенов двух адресов
+ balances[msg.sender] -= amount;
+ balances[receiver] += amount;
+
+ // Генерирует событие, определенное ранее
+ emit Transfer(msg.sender, receiver, amount);
+ }
+}
+```
+
+### Уникальный цифровой актив {#unique-digital-asset}
+
+```solidity
+pragma solidity ^0.5.10;
+
+// Импортирует символы из других файлов в текущий контракт.
+// В данном случае — серия вспомогательных контрактов из OpenZeppelin.
+// Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files
+
+import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
+import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
+import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";
+import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";
+
+// Ключевое слово `is` используется для наследования функций и ключевых слов из внешних контрактов.
+// В этом случае `CryptoPizza` наследует от контрактов `IERC721` и `ERC165`.
+// Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance
+contract CryptoPizza is IERC721, ERC165 {
+ // Использует библиотеку SafeMath из OpenZeppelin для безопасного выполнения арифметических операций.
+ // Узнать больше: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath
+ using SafeMath for uint256;
+
+ // Константные переменные состояния в Solidity похожи на другие языки,
+ // но вы должны присваивать их из выражения, которое является константой во время компиляции.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables
+ uint256 constant dnaDigits = 10;
+ uint256 constant dnaModulus = 10 ** dnaDigits;
+ bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
+
+ // Типы Struct позволяют определять собственный тип
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs
+ struct Pizza {
+ string name;
+ uint256 dna;
+ }
+
+ // Создает пустой массив структур Pizza
+ Pizza[] public pizzas;
+
+ // Сопоставление идентификатора пиццы с адресом ее владельца
+ mapping(uint256 => address) public pizzaToOwner;
+
+ // Сопоставление адреса владельца с количеством принадлежащих ему токенов
+ mapping(address => uint256) public ownerPizzaCount;
+
+ // Сопоставление идентификатора токена с одобренным адресом
+ mapping(uint256 => address) pizzaApprovals;
+
+ // Вы можете вкладывать сопоставления, этот пример сопоставляет владельца с одобрениями оператора
+ mapping(address => mapping(address => bool)) private operatorApprovals;
+
+ // Внутренняя функция для создания случайной пиццы из строки (имени) и ДНК
+ function _createPizza(string memory _name, uint256 _dna)
+ // Ключевое слово `internal` означает, что эта функция видна только
+ // в этом контракте и в контрактах, которые его наследуют
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters
+ internal
+ // `isUnique` — это модификатор функции, который проверяет, существует ли пицца
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers
+ isUnique(_name, _dna)
+ {
+ // Добавляет пиццу в массив пицц и получает идентификатор
+ uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);
+
+ // Проверяет, что владелец пиццы совпадает с текущим пользователем
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
+
+ // обратите внимание, что address(0) — это нулевой адрес,
+ // указывающий, что pizza[id] еще не назначена конкретному пользователю.
+
+ assert(pizzaToOwner[id] == address(0));
+
+ // Сопоставляет пиццу с владельцем
+ pizzaToOwner[id] = msg.sender;
+ ownerPizzaCount[msg.sender] = SafeMath.add(
+ ownerPizzaCount[msg.sender],
+ 1
+ );
+ }
+
+ // Создает случайную пиццу из строки (имени)
+ function createRandomPizza(string memory _name) public {
+ uint256 randDna = generateRandomDna(_name, msg.sender);
+ _createPizza(_name, randDna);
+ }
+
+ // Генерирует случайную ДНК из строки (имени) и адреса владельца (создателя)
+ function generateRandomDna(string memory _str, address _owner)
+ public
+ // Функции, помеченные как `pure`, обещают не читать и не изменять состояние
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions
+ pure
+ returns (uint256)
+ {
+ // Генерирует случайный uint из строки (имени) + адреса (владельца)
+ uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +
+ uint256(_owner);
+ rand = rand % dnaModulus;
+ return rand;
+ }
+
+ // Возвращает массив пицц, найденных по владельцу
+ function getPizzasByOwner(address _owner)
+ public
+ // Функции, помеченные как `view`, обещают не изменять состояние
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions
+ view
+ returns (uint256[] memory)
+ {
+ // Использует местоположение в хранилище `memory` для хранения значений только на время
+ // жизненного цикла этого вызова функции.
+ // Узнать больше: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack
+ uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);
+ uint256 counter = 0;
+ for (uint256 i = 0; i < pizzas.length; i++) {
+ if (pizzaToOwner[i] == _owner) {
+ result[counter] = i;
+ counter++;
+ }
+ }
+ return result;
+ }
+
+ // Передает пиццу и право собственности на другой адрес
+ function transferFrom(address _from, address _to, uint256 _pizzaId) public {
+ require(_from != address(0) && _to != address(0), "Invalid address.");
+ require(_exists(_pizzaId), "Pizza does not exist.");
+ require(_from != _to, "Cannot transfer to the same address.");
+ require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
+
+ ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);
+ ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);
+ pizzaToOwner[_pizzaId] = _to;
+
+ // Генерирует событие, определенное в импортированном контракте IERC721
+ emit Transfer(_from, _to, _pizzaId);
+ _clearApproval(_to, _pizzaId);
+ }
+
+ /**
+ * Безопасно передает право собственности на данный идентификатор токена другому адресу
+ * Если целевой адрес является контрактом, он должен реализовывать `onERC721Received`,
+ * который вызывается при безопасной передаче и возвращает магическое значение
+ * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
+ * в противном случае передача отменяется.
+ */
+ function safeTransferFrom(address from, address to, uint256 pizzaId)
+ public
+ {
+ // solium-disable-next-line arg-overflow
+ this.safeTransferFrom(from, to, pizzaId, "");
+ }
+
+ /**
+ * Безопасно передает право собственности на данный идентификатор токена другому адресу
+ * Если целевой адрес является контрактом, он должен реализовывать `onERC721Received`,
+ * который вызывается при безопасной передаче и возвращает магическое значение
+ * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
+ * в противном случае передача отменяется.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 pizzaId,
+ bytes memory _data
+ ) public {
+ this.transferFrom(from, to, pizzaId);
+ require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");
+ }
+
+ /**
+ * Внутренняя функция для вызова `onERC721Received` на целевом адресе
+ * Вызов не выполняется, если целевой адрес не является контрактом
+ */
+ function _checkOnERC721Received(
+ address from,
+ address to,
+ uint256 pizzaId,
+ bytes memory _data
+ ) internal returns (bool) {
+ if (!isContract(to)) {
+ return true;
+ }
+
+ bytes4 retval = IERC721Receiver(to).onERC721Received(
+ msg.sender,
+ from,
+ pizzaId,
+ _data
+ );
+ return (retval == _ERC721_RECEIVED);
+ }
+
+ // Сжигает пиццу — полностью уничтожает токен
+ // Модификатор функции `external` означает, что эта функция
+ // является частью интерфейса контракта, и другие контракты могут ее вызывать
+ function burn(uint256 _pizzaId) external {
+ require(msg.sender != address(0), "Invalid address.");
+ require(_exists(_pizzaId), "Pizza does not exist.");
+ require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
+
+ ownerPizzaCount[msg.sender] = SafeMath.sub(
+ ownerPizzaCount[msg.sender],
+ 1
+ );
+ pizzaToOwner[_pizzaId] = address(0);
+ }
+
+ // Возвращает количество пицц по адресу
+ function balanceOf(address _owner) public view returns (uint256 _balance) {
+ return ownerPizzaCount[_owner];
+ }
+
+ // Возвращает владельца пиццы по идентификатору
+ function ownerOf(uint256 _pizzaId) public view returns (address _owner) {
+ address owner = pizzaToOwner[_pizzaId];
+ require(owner != address(0), "Invalid Pizza ID.");
+ return owner;
+ }
+
+ // Одобряет другой адрес для передачи права собственности на пиццу
+ function approve(address _to, uint256 _pizzaId) public {
+ require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");
+ pizzaApprovals[_pizzaId] = _to;
+ emit Approval(msg.sender, _to, _pizzaId);
+ }
+
+ // Возвращает одобренный адрес для конкретной пиццы
+ function getApproved(uint256 _pizzaId)
+ public
+ view
+ returns (address operator)
+ {
+ require(_exists(_pizzaId), "Pizza does not exist.");
+ return pizzaApprovals[_pizzaId];
+ }
+
+ /**
+ * Приватная функция для отмены текущего одобрения для данного идентификатора токена
+ * Отменяется, если данный адрес действительно не является владельцем токена
+ */
+ function _clearApproval(address owner, uint256 _pizzaId) private {
+ require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");
+ require(_exists(_pizzaId), "Pizza does not exist.");
+ if (pizzaApprovals[_pizzaId] != address(0)) {
+ pizzaApprovals[_pizzaId] = address(0);
+ }
+ }
+
+ /*
+ * Устанавливает или отменяет одобрение для данного оператора
+ * Оператору разрешено передавать все токены отправителя от его имени
+ */
+ function setApprovalForAll(address to, bool approved) public {
+ require(to != msg.sender, "Cannot approve own address");
+ operatorApprovals[msg.sender][to] = approved;
+ emit ApprovalForAll(msg.sender, to, approved);
+ }
+
+ // Сообщает, одобрен ли оператор данным владельцем
+ function isApprovedForAll(address owner, address operator)
+ public
+ view
+ returns (bool)
+ {
+ return operatorApprovals[owner][operator];
+ }
+
+ // Принимает право собственности на пиццу — только для одобренных пользователей
+ function takeOwnership(uint256 _pizzaId) public {
+ require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
+ address owner = this.ownerOf(_pizzaId);
+ this.transferFrom(owner, msg.sender, _pizzaId);
+ }
+
+ // Проверяет, существует ли пицца
+ function _exists(uint256 pizzaId) internal view returns (bool) {
+ address owner = pizzaToOwner[pizzaId];
+ return owner != address(0);
+ }
+
+ // Проверяет, является ли адрес владельцем или ему разрешена передача пиццы
+ function _isApprovedOrOwner(address spender, uint256 pizzaId)
+ internal
+ view
+ returns (bool)
+ {
+ address owner = pizzaToOwner[pizzaId];
+ // Отключить проверку solium из-за
+ // https://github.com/duaraghav8/Solium/issues/175
+ // solium-disable-next-line operator-whitespace
+ return (spender == owner ||
+ this.getApproved(pizzaId) == spender ||
+ this.isApprovedForAll(owner, spender));
+ }
+
+ // Проверить, является ли пицца уникальной и еще не существует
+ modifier isUnique(string memory _name, uint256 _dna) {
+ bool result = true;
+ for (uint256 i = 0; i < pizzas.length; i++) {
+ if (
+ keccak256(abi.encodePacked(pizzas[i].name)) ==
+ keccak256(abi.encodePacked(_name)) &&
+ pizzas[i].dna == _dna
+ ) {
+ result = false;
+ }
+ }
+ require(result, "Pizza with such name already exists.");
+ _;
+ }
+
+ // Возвращает, является ли целевой адрес контрактом
+ function isContract(address account) internal view returns (bool) {
+ uint256 size;
+ // В настоящее время нет лучшего способа проверить, есть ли контракт по адресу,
+ // чем проверить размер кода по этому адресу.
+ // См. https://ethereum.stackexchange.com/a/14016/36603
+ // для получения более подробной информации о том, как это работает.
+ // TODO Проверить это снова перед выпуском Serenity, потому что тогда все адреса будут
+ // контрактами.
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ size := extcodesize(account)
+ }
+ return size > 0;
+ }
+}
+```
+
+## Дополнительные материалы {#further-reading}
+
+Ознакомьтесь с документацией Solidity и Vyper для более полного обзора смарт-контрактов:
+
+- [Solidity](https://docs.soliditylang.org/)
+- [Vyper](https://docs.vyperlang.org/en/stable/)
+
+## Смежные темы {#related-topics}
+
+- [Умные контракты](/developers/docs/smart-contracts/)
+- [Виртуальная машина Ethereum](/developers/docs/evm/)
+
+## Связанные руководства {#related-tutorials}
+
+- [Сокращение контрактов для борьбы с ограничением размера контракта](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _– несколько практических советов по уменьшению размера вашего смарт-контракта._
+- [Регистрация данных из смарт-контрактов с помощью событий](/developers/tutorials/logging-events-smart-contracts/) _– введение в события смарт-контрактов и способы их использования для регистрации данных._
+- [Взаимодействие с другими контрактами из Solidity](/developers/tutorials/interact-with-other-contracts-from-solidity/) _– как развернуть смарт-контракт из существующего контракта и взаимодействовать с ним._
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/compiling/index.md b/public/content/translations/ru/developers/docs/smart-contracts/compiling/index.md
new file mode 100644
index 00000000000..a79cb2e8cfb
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/compiling/index.md
@@ -0,0 +1,282 @@
+---
+title: "Составление смарт-контрактов"
+description: "Объяснение того, почему вам нужно компилировать смарт-контракты и что на самом деле делает компиляция."
+lang: ru
+incomplete: true
+---
+
+Вам необходимо скомпилировать свой контракт, чтобы ваше веб-приложение и виртуальная машина Ethereum (EVM) могли его понять.
+
+## Предварительные условия {#prerequisites}
+
+Возможно, вам будет полезно прочитать наше введение в [умные контракты](/developers/docs/smart-contracts/) и [виртуальную машину Ethereum](/developers/docs/evm/), прежде чем читать о компиляции.
+
+## EVM {#the-evm}
+
+Чтобы [EVM](/developers/docs/evm/) могла выполнять ваш контракт, он должен быть в виде **байт-кода**. Компиляция превращает это:
+
+```solidity
+pragma solidity 0.4.24;
+
+contract Greeter {
+
+ function greet() public view returns (string memory) {
+ return "Hello";
+ }
+
+}
+```
+
+**в это**
+
+```
+PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xCFAE3217 EQ PUSH2 0x46 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5B PUSH2 0xD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x9B JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x80 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xC8 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x48656C6C6F000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 SLT 0xec 0xe 0xf5 0xf8 SLT 0xc7 0x2d STATICCALL ADDRESS SHR 0xdb COINBASE 0xb1 BALANCE 0xe8 0xf8 DUP14 0xda 0xad DUP13 LOG1 0x4c 0xb4 0x26 0xc2 DELEGATECALL PUSH7 0x8994D3E002900
+```
+
+Они называются **опкодами**. Опкоды EVM — это низкоуровневые инструкции, которые может выполнять виртуальная машина Ethereum (EVM). Каждый опкод представляет собой определенную операцию, например арифметические операции, логические операции, манипулирование данными, управление потоком и т. д.
+
+[Подробнее об опкодах](/developers/docs/evm/opcodes/)
+
+## Веб-приложения {#web-applications}
+
+Компилятор также создаст **двоичный интерфейс приложения (ABI)**, который необходим вашему приложению для понимания контракта и вызова его функций.
+
+ABI - это файл JSON, который описывает развернутый контракт и его функции смарт-контракту. Это помогает преодолеть разрыв между web2 и web3
+
+[Клиентская библиотека JavaScript](/developers/docs/apis/javascript/) будет считывать **ABI**, чтобы вы могли вызывать свой умный контракт в интерфейсе вашего веб-приложения.
+
+Ниже приведен ABI для контракта токена ERC-20. ERC-20 - это токен, которым вы можете торговать на Ethereum.
+
+```json
+[
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_spender",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "name": "balance",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "name": "_value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "_owner",
+ "type": "address"
+ },
+ {
+ "name": "_spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "payable": true,
+ "stateMutability": "payable",
+ "type": "fallback"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ }
+]
+```
+
+## Дополнительные материалы {#further-reading}
+
+- [Спецификация ABI](https://solidity.readthedocs.io/en/v0.7.0/abi-spec.html) _— Solidity_
+
+## Смежные темы {#related-topics}
+
+- [Клиентские библиотеки JavaScript](/developers/docs/apis/javascript/)
+- [виртуальная машина Ethereum](/developers/docs/evm/)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/composability/index.md b/public/content/translations/ru/developers/docs/smart-contracts/composability/index.md
new file mode 100644
index 00000000000..5de939f564d
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/composability/index.md
@@ -0,0 +1,76 @@
+---
+title: "Возможность компоновки смарт-контрактов"
+description: "Узнайте, как умные контракты можно объединять, как кубики Lego, для создания сложных децентрализованных приложений путем повторного использования существующих компонентов."
+lang: ru
+incomplete: true
+---
+
+## Краткое введение {#a-brief-introduction}
+
+Смарт-контракты общедоступны в Ethereum и могут рассматриваться как открытые API. Вам не нужно писать собственный смарт-контракт, чтобы стать разработчиком децентрализованных приложений, вам просто нужно знать, как с ними взаимодействовать. Например, вы можете использовать существующие умные контракты [Uniswap](https://uniswap.exchange/swap), децентрализованной биржи, для обработки всей логики обмена токенов в вашем приложении — вам не нужно начинать с нуля. Ознакомьтесь с некоторыми из их контрактов [v2](https://github.com/Uniswap/uniswap-v2-core/tree/master/contracts) и [v3](https://github.com/Uniswap/uniswap-v3-core/tree/main/contracts).
+
+## Что такое композиционность? {#what-is-composability}
+
+Композиционность - это объединение отдельных компонентов для создания новых систем или выходов. В разработке программного обеспечения композиционность означает, что разработчики могут многократно использовать существующие компоненты программного обеспечения для создания новых приложений. Хороший способ понять композиционность - это думать о составных элементах, как о блоках Lego. Каждый Lego может быть объединен с другим, позволяя Вам строить сложные структуры путем сочетаний различные Lego.
+
+В Ethereum каждый смарт-контракт представляет собой что-то вроде Lego - Вы можете использовать смарт-контракты из других проектов в качестве строительных блоков для Вашего проекта. Это означает, что Вам не нужно тратить время на изобретение "колеса" или строительство с нуля.
+
+## Как работает композиционность? {#how-does-composability-work}
+
+Смарт-контракты Ethereum похожи на публичные приложения, так любой может взаимодействовать с контрактом или внедрить его в децентрализованные приложения для добавления функциональности. Композиционность смарт-контрактов, как правило, работает на основе трех принципов: модульность, автономность и открытость:
+
+\*\*1. **Модульность**: это способность отдельных компонентов выполнять определенную задачу. В Ethereum каждый смарт-контракт имеет определенный вариант использования (как показано в примере Uniswap).
+
+\*\*2. **Автономность**: составные компоненты должны быть способны работать независимо. Каждый смарт-контракт в Ethereum является самоисполняемым и может функционировать, не полагаясь на другие части системы.
+
+\*\*3. **Обнаруживаемость**: разработчики не могут вызывать внешние контракты или интегрировать программные библиотеки в приложения, если первые не являются общедоступными. По дизайну, смарт-контракты являются открытыми источниками; любой может вызвать смарт-контракт или ответвление базового кода.
+
+## Преимущества композиционности {#benefits-of-composability}
+
+### Сокращенный цикл разработки {#shorter-development-cycle}
+
+Композиционность сокращает объем работы, которую разработчикам приходится выполнять при создании [децентрализованных приложений](/apps/#what-are-dapps). [Как говорит Навал Равикант:](https://twitter.com/naval/status/1444366754650656770) \
+
+Если существует смарт-контракт, который решает одну проблему, другие разработчики могут повторно использовать его, чтобы им не приходилось решать одну и ту же проблему. Таким образом, разработчики могут брать существующие библиотеки программного обеспечения и добавлять дополнительную функциональность для создания новых децентрализованных приложений.
+
+### Больше инноваций {#greater-innovation}
+
+Компонуемость поощряет инновации и эксперименты, поскольку разработчики могут свободно повторно использовать, изменять, дублировать или интегрировать код с открытым исходным кодом для достижения желаемых результатов. В результате команды разработчиков тратят меньше времени на базовую функциональность и могут уделять больше времени экспериментам с новыми функциями.
+
+### Улучшенный пользовательский опыт {#better-user-experience}
+
+Функциональная совместимость компонентов экосистемы Ethereum улучшает пользовательский опыт. Пользователи могут получить доступ к большей функциональности, когда децентрализованные приложения интегрируют внешние смарт-контракты, чем во фрагментированной экосистеме, где приложения не могут взаимодействовать друг с другом.
+
+Мы воспользуемся примером из арбитражной торговли, чтобы проиллюстрировать преимущества функциональной совместимости:
+
+Если токен торгуется на `бирже А` дороже, чем на `бирже B`, вы можете воспользоваться разницей в цене, чтобы получить прибыль. Однако вы можете сделать это, только если у вас достаточно капитала для финансирования транзакции (т. е. для покупки токена на `бирже B` и его продажи на `бирже A`).
+
+В ситуации, когда у вас недостаточно средств для совершения сделки, идеальным вариантом может стать срочный заем. [Срочные займы](/defi/#flash-loans) — это очень технически сложная вещь, но основная идея заключается в том, что вы можете заимствовать активы (без обеспечения) и вернуть их в рамках _одной_ транзакции.
+
+Возвращаясь к нашему первоначальному примеру, арбитражный трейдер может взять большой срочный заем, купить токены на `бирже B`, продать их на `бирже A`, вернуть капитал + проценты и оставить себе прибыль в рамках одной транзакции. Эта сложная логика требует объединения вызовов к нескольким контрактам, что было бы невозможно, если бы у смарт-контрактов отсутствовала функциональная совместимость.
+
+## Примеры компонуемости в Ethereum {#composability-in-ethereum}
+
+### Обмен токенов {#token-swaps}
+
+Если вы создаете децентрализованное приложение, в котором транзакции должны оплачиваться в ETH, вы можете разрешить пользователям платить другими токенами ERC-20, интегрировав логику обмена токенов. Код автоматически конвертирует токен пользователя в ETH до того, как контракт выполнит вызванную функцию.
+
+### Управление {#governance}
+
+Создание индивидуальных систем управления для [DAO](/dao/) может быть дорогостоящим и трудоемким. Вместо этого вы можете использовать инструментарий управления с открытым исходным кодом, такой как [Aragon Client](https://client.aragon.org/), чтобы запустить свою DAO и быстро создать систему управления.
+
+### Управление идентификацией {#identity-management}
+
+Вместо создания собственной системы аутентификации или использования централизованных провайдеров, вы можете интегрировать инструменты децентрализованной идентификации (DID) для управления аутентификацией пользователей. Примером может служить [SpruceID](https://www.spruceid.com/), инструментарий с открытым исходным кодом, который предлагает функцию "Войти через Ethereum", позволяющую пользователям подтверждать свою личность с помощью кошелька Ethereum.
+
+## Связанные руководства {#related-tutorials}
+
+- [Быстрый старт разработки фронтенда для вашего децентрализованного приложения с помощью create-eth-app](/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/) _— Обзор использования create-eth-app для создания приложений с популярными готовыми смарт-контрактами._
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+- [Компонуемость — это инновация](https://a16zcrypto.com/posts/article/how-composability-unlocks-crypto-and-everything-else/)
+- [Почему компонуемость важна для Web3](https://hackernoon.com/why-composability-matters-for-web3)
+- [Что такое компонуемость?](https://blog.aragon.org/what-is-composability/#:~:text=Aragon,connect%20to%20every%20other%20piece.)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/deploying/index.md b/public/content/translations/ru/developers/docs/smart-contracts/deploying/index.md
new file mode 100644
index 00000000000..c19c5bef2c5
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/deploying/index.md
@@ -0,0 +1,81 @@
+---
+title: "Развертывание смарт-контрактов"
+description: "Узнайте, как развертывать умные контракты в сетях Ethereum, включая предварительные требования, инструменты и этапы развертывания."
+lang: ru
+---
+
+Вам необходимо развернуть свой смарт-контракт, чтобы он был доступен пользователям сети Ethereum.
+
+Чтобы развернуть смарт-контракт, вы просто отправляете транзакцию Ethereum, содержащую скомпилированный код смарт-контракта, не указывая получателя.
+
+## Предварительные условия {#prerequisites}
+
+Прежде чем развертывать смарт-контракты, вам следует ознакомиться с [сетями Ethereum](/developers/docs/networks/), [транзакциями](/developers/docs/transactions/) и [анатомией смарт-контрактов](/developers/docs/smart-contracts/anatomy/).
+
+Развертывание контракта также стоит эфира (ETH), поскольку он хранится в блокчейне, поэтому вам следует ознакомиться с [газом и комиссиями](/developers/docs/gas/) в Ethereum.
+
+Наконец, перед развертыванием вам нужно будет скомпилировать ваш контракт, поэтому убедитесь, что вы прочли о [компиляции смарт-контрактов](/developers/docs/smart-contracts/compiling/).
+
+## Как развернуть смарт-контракт {#how-to-deploy-a-smart-contract}
+
+### Что вам понадобится {#what-youll-need}
+
+- Байт-код вашего контракта — он генерируется путем [компиляции](/developers/docs/smart-contracts/compiling/)
+- ETH для газа — вы устанавливаете свой лимит газа, как и для обычных транзакций, поэтому имейте в виду, что для развертывания контракта требуется гораздо больше газа, чем для простого перевода ETH
+- сценарий развертывания или плагин
+- доступ к [узлу Ethereum](/developers/docs/nodes-and-clients/) через запуск собственного узла, подключение к общедоступному или использование ключа API [сервиса узлов](/developers/docs/nodes-and-clients/nodes-as-a-service/)
+
+### Этапы развертывания смарт-контракта {#steps-to-deploy}
+
+Конкретные этапы будут зависеть от используемой среды разработки. Например, вы можете ознакомиться с [документацией Hardhat по развертыванию контрактов](https://hardhat.org/docs/tutorial/deploying) или [документацией Foundry по развертыванию и верификации смарт-контракта](https://book.getfoundry.sh/forge/deploying). После развертывания ваш контракт будет иметь адрес Ethereum, как и другие [аккаунты](/developers/docs/accounts/), и его можно будет верифицировать с помощью [инструментов верификации исходного кода](/developers/docs/smart-contracts/verifying/#source-code-verification-tools).
+
+## Связанные инструменты {#related-tools}
+
+**Remix — _Remix IDE позволяет разрабатывать, развертывать и администрировать смарт-контракты для блокчейнов, подобных Ethereum_**
+
+- [Remix](https://remix.ethereum.org)
+
+**Tenderly — _платформа для разработки Web3, предоставляющая средства отладки, наблюдаемости и инфраструктурные компоненты для разработки, тестирования, мониторинга и эксплуатации смарт-контрактов_**
+
+- [tenderly.co](https://tenderly.co/)
+- [Документация](https://docs.tenderly.co/)
+- [GitHub](https://github.com/Tenderly)
+- [Discord](https://discord.gg/eCWjuvt)
+
+**Hardhat — _среда разработки для компиляции, развертывания, тестирования и отладки вашего программного обеспечения Ethereum_**
+
+- [hardhat.org](https://hardhat.org/getting-started/)
+- [Документация по развертыванию ваших контрактов](https://hardhat.org/docs/tutorial/deploying)
+- [GitHub](https://github.com/nomiclabs/hardhat)
+- [Discord](https://discord.com/invite/TETZs2KK4k)
+
+**thirdweb — _простое развертывание любого контракта в любой EVM-совместимой сети с помощью одной команды_**
+
+- [Документация](https://portal.thirdweb.com/deploy/)
+
+**Crossmint — _платформа для разработки Web3 корпоративного уровня для развертывания смарт-контрактов, приема платежей по кредитным картам и кроссчейн-платежей, а также использования API для создания, распространения, продажи, хранения и редактирования NFT._**
+
+- [crossmint.com](https://www.crossmint.com)
+- [Документация](https://docs.crossmint.com)
+- [Discord](https://discord.com/invite/crossmint)
+- [Блог](https://blog.crossmint.com)
+
+## Связанные руководства {#related-tutorials}
+
+- [Развертывание вашего первого смарт-контракта](/developers/tutorials/deploying-your-first-smart-contract/) _– введение в развертывание вашего первого смарт-контракта в тестовой сети Ethereum._
+- [Hello World | руководство по смарт-контрактам](/developers/tutorials/hello-world-smart-contract/) _– простое руководство по созданию и развертыванию базового смарт-контракта на Ethereum._
+- [Взаимодействие с другими контрактами из Solidity](/developers/tutorials/interact-with-other-contracts-from-solidity/) _– как развернуть смарт-контракт из существующего контракта и взаимодействовать с ним._
+- [Как уменьшить размер контракта](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _– как уменьшить размер контракта, чтобы он не превышал лимит, и сэкономить на газе_
+
+## Дополнительные материалы {#further-reading}
+
+- [https://docs.openzeppelin.com/learn/deploying-and-interacting](https://docs.openzeppelin.com/learn/deploying-and-interacting) — _OpenZeppelin_
+- [Развертывание ваших контрактов с помощью Hardhat](https://hardhat.org/docs/tutorial/deploying) — _Nomic Labs_
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Фреймворки для разработки](/developers/docs/frameworks/)
+- [Запуск узла Ethereum](/developers/docs/nodes-and-clients/run-a-node/)
+- [Узлы как услуга](/developers/docs/nodes-and-clients/nodes-as-a-service)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/formal-verification/index.md b/public/content/translations/ru/developers/docs/smart-contracts/formal-verification/index.md
new file mode 100644
index 00000000000..3fcc8f8184a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/formal-verification/index.md
@@ -0,0 +1,284 @@
+---
+title: "Верификация смарт-контрактов"
+description: "Обзор формальной верификации для смарт-контрактов Ethereum"
+lang: ru
+---
+
+[Смарт-контракты](/developers/docs/smart-contracts/) делают возможным создание децентрализованных, не требующих доверия и надежных приложений, которые представляют новые варианты использования и открывают ценность для пользователей. Поскольку смарт-контракты управляют большими объемами ценностей, безопасность является критически важным аспектом для разработчиков.
+
+Формальная верификация — это один из рекомендуемых методов для улучшения [безопасности смарт-контрактов](/developers/docs/smart-contracts/security/). Формальная верификация, которая использует [формальные методы](https://www.brookings.edu/techstream/formal-methods-as-a-path-toward-better-cybersecurity/) для спецификации, проектирования и верификации программ, годами использовалась для обеспечения корректности критически важных аппаратных и программных систем.
+
+При реализации в смарт-контрактах формальная верификация может доказать, что бизнес-логика контракта соответствует предопределенной спецификации. По сравнению с другими методами оценки корректности кода контракта, такими как тестирование, формальная верификация дает более сильные гарантии того, что смарт-контракт является функционально корректным.
+
+## Что такое формальная верификация? {#what-is-formal-verification}
+
+Формальная верификация относится к процессу оценки корректности системы в соответствии с формальной спецификацией. Проще говоря, формальная верификация позволяет нам проверить, удовлетворяет ли поведение системы некоторым требованиям (т. е. делает ли она то, что мы хотим).
+
+Ожидаемое поведение системы (в данном случае смарт-контракта) описывается с помощью формального моделирования, в то время как языки спецификаций позволяют создавать формальные свойства. Затем методы формальной верификации могут проверить, что реализация контракта соответствует его спецификации, и получить математическое доказательство корректности первого. Когда контракт удовлетворяет своей спецификации, он описывается как «функционально корректный», «корректный по замыслу» или «корректный по построению».
+
+### Что такое формальная модель? {#what-is-a-formal-model}
+
+В информатике [формальная модель](https://en.wikipedia.org/wiki/Model_of_computation) — это математическое описание вычислительного процесса. Программы абстрагируются в математические функции (уравнения), при этом модель описывает, как вычисляются выходные данные функций для заданных входных данных.
+
+Формальные модели обеспечивают уровень абстракции, на котором можно оценивать анализ поведения программы. Существование формальных моделей позволяет создать _формальную спецификацию_, которая описывает желаемые свойства рассматриваемой модели.
+
+Для моделирования смарт-контрактов для формальной верификации используются различные методы. Например, некоторые модели используются для рассуждений о высокоуровневом поведении смарт-контракта. Эти методы моделирования применяют к смарт-контрактам подход «черного ящика», рассматривая их как системы, которые принимают входные данные и выполняют вычисления на основе этих входных данных.
+
+Высокоуровневые модели фокусируются на взаимосвязи между смарт-контрактами и внешними агентами, такими как внешние аккаунты (EOA), аккаунты контрактов и среда блокчейна. Такие модели полезны для определения свойств, которые указывают, как должен вести себя контракт в ответ на определенные взаимодействия с пользователем.
+
+И наоборот, другие формальные модели фокусируются на низкоуровневом поведении смарт-контракта. Хотя высокоуровневые модели могут помочь в рассуждениях о функциональности контракта, они могут не улавливать детали внутренней работы реализации. Низкоуровневые модели применяют к анализу программ подход «белого ящика» и полагаются на низкоуровневые представления приложений смарт-контрактов, такие как трассировки программ и [графы потока управления](https://en.wikipedia.org/wiki/Control-flow_graph), для рассуждений о свойствах, относящихся к выполнению контракта.
+
+Низкоуровневые модели считаются идеальными, поскольку они представляют фактическое выполнение смарт-контракта в среде выполнения Ethereum (т. е. [EVM](/developers/docs/evm/)). Методы низкоуровневого моделирования особенно полезны в установлении критических свойств безопасности в смарт-контрактах и обнаружении потенциальных уязвимостей.
+
+### Что такое формальная спецификация? {#what-is-a-formal-specification}
+
+Спецификация — это просто техническое требование, которому должна удовлетворять определенная система. В программировании спецификации представляют общие идеи о выполнении программы (т. е. что должна делать программа).
+
+В контексте смарт-контрактов формальные спецификации относятся к _свойствам_ — формальным описаниям требований, которым должен удовлетворять контракт. Такие свойства описываются как «инварианты» и представляют собой логические утверждения о выполнении контракта, которые должны оставаться верными при любых возможных обстоятельствах, без каких-либо исключений.
+
+Таким образом, мы можем думать о формальной спецификации как о наборе утверждений, написанных на формальном языке, которые описывают предполагаемое выполнение смарт-контракта. Спецификации охватывают свойства контракта и определяют, как он должен вести себя в различных обстоятельствах. Цель формальной верификации состоит в том, чтобы определить, обладает ли смарт-контракт этими свойствами (инвариантами) и что эти свойства не нарушаются во время выполнения.
+
+Формальные спецификации имеют решающее значение в разработке безопасных реализаций смарт-контрактов. Контракты, в которых не реализованы инварианты или чьи свойства нарушаются во время выполнения, подвержены уязвимостям, которые могут нанести вред функциональности или привести к злонамеренным эксплойтам.
+
+## Типы формальных спецификаций для смарт-контрактов {#formal-specifications-for-smart-contracts}
+
+Формальные спецификации позволяют проводить математические рассуждения о корректности выполнения программы. Как и в случае с формальными моделями, формальные спецификации могут фиксировать либо высокоуровневые свойства, либо низкоуровневое поведение реализации контракта.
+
+Формальные спецификации выводятся с использованием элементов [логики программ](https://en.wikipedia.org/wiki/Logic_programming), что позволяет проводить формальные рассуждения о свойствах программы. Логика программ имеет формальные правила, которые выражают (на математическом языке) ожидаемое поведение программы. При создании формальных спецификаций используются различные логики программ, включая [логику достижимости](https://en.wikipedia.org/wiki/Reachability_problem), [временную логику](https://en.wikipedia.org/wiki/Temporal_logic) и [логику Хоара](https://en.wikipedia.org/wiki/Hoare_logic).
+
+Формальные спецификации для смарт-контрактов можно в целом классифицировать как **высокоуровневые** или **низкоуровневые** спецификации. Независимо от того, к какой категории относится спецификация, она должна адекватно и недвусмысленно описывать свойство анализируемой системы.
+
+### Высокоуровневые спецификации {#high-level-specifications}
+
+Как следует из названия, высокоуровневая спецификация (также называемая «модельно-ориентированной спецификацией») описывает высокоуровневое поведение программы. Высокоуровневые спецификации моделируют смарт-контракт как [конечный автомат](https://en.wikipedia.org/wiki/Finite-state_machine) (FSM), который может переходить между состояниями, выполняя операции, при этом временная логика используется для определения формальных свойств модели FSM.
+
+[Временные логики](https://en.wikipedia.org/wiki/Temporal_logic) — это «правила для рассуждений о предложениях, квалифицированных с точки зрения времени (например, «Я _всегда_ голоден» или «Я _в конце концов_ проголодаюсь»)». Применительно к формальной верификации временные логики используются для формулирования утверждений о правильном поведении систем, смоделированных как конечные автоматы. В частности, временная логика описывает будущие состояния, в которых может находиться смарт-контракт, и как он переходит между состояниями.
+
+Высокоуровневые спецификации обычно охватывают два критических временных свойства для смарт-контрактов: **безопасность** и **живучесть**. Свойства безопасности представляют идею «никогда не случится ничего плохого» и обычно выражают инвариантность. Свойство безопасности может определять общие требования к программному обеспечению, например, отсутствие [взаимоблокировок](https://www.techtarget.com/whatis/definition/deadlock), или выражать специфичные для домена свойства для контрактов (например, инварианты контроля доступа к функциям, допустимые значения переменных состояния или условия для передачи токенов).
+
+Возьмем, к примеру, это требование безопасности, которое охватывает условия использования `transfer()` или `transferFrom()` в контрактах токенов ERC-20: _«Баланс отправителя никогда не бывает ниже запрошенной суммы токенов для отправки»_. Это описание инварианта контракта на естественном языке может быть переведено в формальную (математическую) спецификацию, которую затем можно строго проверить на валидность.
+
+Свойства живучести утверждают, что «в конце концов произойдет что-то хорошее», и касаются способности контракта переходить через различные состояния. Примером свойства живучести является «ликвидность», которая относится к способности контракта переводить свои балансы пользователям по запросу. Если это свойство нарушено, пользователи не смогут вывести активы, хранящиеся в контракте, как это случилось во время [инцидента с кошельком Parity](https://www.cnbc.com/2017/11/08/accidental-bug-may-have-frozen-280-worth-of-ether-on-parity-wallet.html).
+
+### Низкоуровневые спецификации {#low-level-specifications}
+
+Высокоуровневые спецификации берут за отправную точку конечно-автоматную модель контракта и определяют желаемые свойства этой модели. В отличие от них, низкоуровневые спецификации (также называемые «свойство-ориентированными спецификациями») часто моделируют программы (смарт-контракты) как системы, состоящие из набора математических функций, и описывают правильное поведение таких систем.
+
+Проще говоря, низкоуровневые спецификации анализируют _трассировки программ_ и пытаются определить свойства смарт-контракта на основе этих трассировок. Трассировки относятся к последовательностям выполнения функций, которые изменяют состояние смарт-контракта; следовательно, низкоуровневые спецификации помогают определить требования для внутреннего выполнения контракта.
+
+Низкоуровневые формальные спецификации могут быть представлены в виде свойств в стиле Хоара или инвариантов на путях выполнения.
+
+### Свойства в стиле Хоара {#hoare-style-properties}
+
+[Логика Хоара](https://en.wikipedia.org/wiki/Hoare_logic) предоставляет набор формальных правил для рассуждений о корректности программ, включая смарт-контракты. Свойство в стиле Хоара представляется тройкой Хоара `{P}c{Q}`, где `c` — это программа, а `P` и `Q` — предикаты состояния `c` (т. е. программы), формально описываемые как _предусловия_ и _постусловия_ соответственно.
+
+Предусловие — это предикат, описывающий условия, необходимые для корректного выполнения функции; пользователи, вызывающие контракт, должны удовлетворять этому требованию. Постусловие — это предикат, описывающий условие, которое устанавливает функция при корректном выполнении; пользователи могут ожидать, что это условие будет истинным после вызова функции. _Инвариант_ в логике Хоара — это предикат, который сохраняется при выполнении функции (т. е. не изменяется).
+
+Спецификации в стиле Хоара могут гарантировать либо _частичную корректность_, либо _полную корректность_. Реализация функции контракта является «частично корректной», если предусловие выполняется до выполнения функции, и если выполнение завершается, то постусловие также истинно. Доказательство полной корректности получается, если предусловие истинно до выполнения функции, выполнение гарантированно завершится, и когда это произойдет, постусловие будет истинным.
+
+Получить доказательство полной корректности сложно, так как некоторые выполнения могут задерживаться перед завершением или не завершаться вовсе. Тем не менее, вопрос о том, завершится ли выполнение, возможно, является спорным, поскольку механизм газа в Ethereum предотвращает бесконечные циклы программы (выполнение либо успешно завершается, либо заканчивается из-за ошибки «нехватки газа»).
+
+Спецификации смарт-контрактов, созданные с использованием логики Хоара, будут иметь предусловия, постусловия и инварианты, определенные для выполнения функций и циклов в контракте. Предусловия часто включают возможность ошибочных входных данных для функции, а постусловия описывают ожидаемую реакцию на такие входные данные (например, выбрасывание определенного исключения). Таким образом, свойства в стиле Хоара эффективны для обеспечения корректности реализаций контрактов.
+
+Многие платформы формальной верификации используют спецификации в стиле Хоара для доказательства семантической корректности функций. Также возможно добавлять свойства в стиле Хоара (как утверждения) непосредственно в код контракта, используя операторы `require` и `assert` в Solidity.
+
+Операторы `require` выражают предусловие или инвариант и часто используются для проверки входных данных пользователя, в то время как `assert` фиксирует постусловие, необходимое для безопасности. Например, надлежащий контроль доступа к функциям (пример свойства безопасности) может быть достигнут с помощью `require` в качестве проверки предусловия для идентификации вызывающего аккаунта. Аналогичным образом, инвариант для допустимых значений переменных состояния в контракте (например, общее количество токенов в обращении) можно защитить от нарушения, используя `assert` для подтверждения состояния контракта после выполнения функции.
+
+### Свойства на уровне трассировки {#trace-level-properties}
+
+Спецификации на основе трассировки описывают операции, которые переводят контракт между различными состояниями, и отношения между этими операциями. Как объяснялось ранее, трассировки — это последовательности операций, которые определенным образом изменяют состояние контракта.
+
+Этот подход основан на модели смарт-контрактов как систем с переходом состояний с некоторыми предопределенными состояниями (описанными переменными состояния) вместе с набором предопределенных переходов (описанных функциями контракта). Кроме того, [граф потока управления](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/) (CFG), который является графическим представлением потока выполнения программы, часто используется для описания операционной семантики контракта. Здесь каждая трассировка представляется как путь на графе потока управления.
+
+В первую очередь спецификации на уровне трассировки используются для рассуждений о шаблонах внутреннего выполнения в смарт-контрактах. Создавая спецификации на уровне трассировки, мы утверждаем допустимые пути выполнения (т. е. переходы состояний) для смарт-контракта. Используя такие методы, как символическое выполнение, мы можем формально проверить, что выполнение никогда не следует по пути, не определенному в формальной модели.
+
+Давайте используем пример контракта [DAO](/dao/), у которого есть несколько общедоступных функций, чтобы описать свойства на уровне трассировки. Здесь мы предполагаем, что контракт ДАО позволяет пользователям выполнять следующие операции:
+
+- Вносить средства
+
+- Голосовать по предложению после внесения средств
+
+- Требовать возврат средств, если они не голосуют по предложению
+
+Примеры свойств на уровне трассировки могут быть такими: _«пользователи, которые не вносят средства, не могут голосовать по предложению»_ или _«пользователи, которые не голосуют по предложению, всегда должны иметь возможность требовать возврат средств»_. Оба свойства утверждают предпочтительные последовательности выполнения (голосование не может происходить _до_ внесения средств, а требование возврата средств не может происходить _после_ голосования по предложению).
+
+## Методы формальной верификации смарт-контрактов {#formal-verification-techniques}
+
+### Проверка моделей {#model-checking}
+
+Проверка моделей — это метод формальной верификации, в котором алгоритм проверяет формальную модель смарт-контракта на соответствие ее спецификации. При проверке моделей смарт-контракты часто представляются как системы с переходом состояний, в то время как свойства допустимых состояний контракта определяются с использованием временной логики.
+
+Проверка моделей требует создания абстрактного математического представления системы (т. е. контракта) и выражения свойств этой системы с использованием формул, основанных на [пропозициональной логике](https://www.baeldung.com/cs/propositional-logic). Это упрощает задачу алгоритма проверки моделей, а именно, доказать, что математическая модель удовлетворяет заданной логической формуле.
+
+Проверка моделей в формальной верификации в основном используется для оценки временных свойств, которые описывают поведение контракта с течением времени. Временные свойства для смарт-контрактов включают _безопасность_ и _живучесть_, которые мы объяснили ранее.
+
+Например, свойство безопасности, связанное с контролем доступа (например, _Только владелец контракта может вызывать `selfdestruct`_), может быть записано в формальной логике. После этого алгоритм проверки моделей может проверить, удовлетворяет ли контракт этой формальной спецификации.
+
+Проверка моделей использует исследование пространства состояний, которое включает построение всех возможных состояний смарт-контракта и попытку найти достижимые состояния, приводящие к нарушениям свойств. Однако это может привести к бесконечному числу состояний (известному как «проблема взрыва состояний»), поэтому средства проверки моделей полагаются на методы абстракции, чтобы сделать возможным эффективный анализ смарт-контрактов.
+
+### Доказательство теорем {#theorem-proving}
+
+Доказательство теорем — это метод математического рассуждения о корректности программ, включая смарт-контракты. Он включает в себя преобразование модели системы контракта и ее спецификаций в математические формулы (логические утверждения).
+
+Целью доказательства теорем является проверка логической эквивалентности между этими утверждениями. «Логическая эквивалентность» (также называемая «логической биимпликацией») — это тип отношения между двумя утверждениями, при котором первое утверждение истинно _тогда и только тогда, когда_ истинно второе утверждение.
+
+Требуемое отношение (логическая эквивалентность) между утверждениями о модели контракта и ее свойстве формулируется как доказуемое утверждение (называемое теоремой). Используя формальную систему вывода, автоматический доказыватель теорем может проверить валидность теоремы. Другими словами, доказыватель теорем может окончательно доказать, что модель смарт-контракта точно соответствует его спецификациям.
+
+В то время как проверка моделей моделирует контракты как системы переходов с конечными состояниями, доказательство теорем может обрабатывать анализ систем с бесконечными состояниями. Однако это означает, что автоматический доказыватель теорем не всегда может знать, является ли логическая проблема «разрешимой» или нет.
+
+В результате часто требуется помощь человека, чтобы направить доказыватель теорем в получении доказательств корректности. Использование человеческих усилий в доказательстве теорем делает его более дорогим в использовании, чем проверка моделей, которая полностью автоматизирована.
+
+### Символическое выполнение {#symbolic-execution}
+
+Символическое выполнение — это метод анализа смарт-контракта путем выполнения функций с использованием _символических значений_ (например, `x > 5`) вместо _конкретных значений_ (например, `x == 5`). Как метод формальной верификации, символическое выполнение используется для формального рассуждения о свойствах на уровне трассировки в коде контракта.
+
+Символическое выполнение представляет трассировку выполнения в виде математической формулы над символическими входными значениями, иначе называемой _предикатом пути_. [Решатель SMT](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories) используется для проверки, является ли предикат пути «выполнимым» (т. е. существует ли значение, которое может удовлетворить формулу). Если уязвимый путь выполним, решатель SMT сгенерирует конкретное значение, которое направит выполнение по этому пути.
+
+Предположим, функция смарт-контракта принимает на вход значение `uint` (`x`) и отменяет транзакцию, если `x` больше `5`, а также меньше `10`. Поиск значения для `x`, которое вызовет ошибку, с помощью обычной процедуры тестирования потребует прогона десятков тестовых случаев (или более) без гарантии фактического обнаружения входных данных, вызывающих ошибку.
+
+Напротив, инструмент символического выполнения выполнит функцию с символическим значением: `X > 5 ∧ X < 10` (т. е. `x` больше 5 И `x` меньше 10). Связанный предикат пути `x = X > 5 ∧ X < 10` затем будет передан для решения решателю SMT. Если определенное значение удовлетворяет формуле `x = X > 5 ∧ X < 10`, решатель SMT вычислит его — например, решатель может выдать `7` в качестве значения для `x`.
+
+Поскольку символическое выполнение зависит от входных данных программы, а набор входных данных для исследования всех достижимых состояний потенциально бесконечен, это все еще форма тестирования. Однако, как показано в примере, символическое выполнение более эффективно, чем обычное тестирование, для поиска входных данных, которые вызывают нарушения свойств.
+
+Более того, символическое выполнение дает меньше ложных срабатываний, чем другие методы, основанные на свойствах (например, фаззинг), которые случайным образом генерируют входные данные для функции. Если во время символического выполнения срабатывает состояние ошибки, то можно сгенерировать конкретное значение, которое вызывает ошибку, и воспроизвести проблему.
+
+Символическое выполнение также может предоставить некоторую степень математического доказательства корректности. Рассмотрим следующий пример функции контракта с защитой от переполнения:
+
+```
+function safe_add(uint x, uint y) returns(uint z){
+
+ z = x + y;
+ require(z>=x);
+ require(z>=y);
+
+ return z;
+}
+```
+
+Трассировка выполнения, приводящая к целочисленному переполнению, должна удовлетворять формуле: `z = x + y AND (z >= x) AND (z >= y) AND (z < x OR z < y)`. Такая формула вряд ли будет решена, следовательно, это служит математическим доказательством того, что функция `safe_add` никогда не переполняется.
+
+### Зачем использовать формальную верификацию для смарт-контрактов? {#benefits-of-formal-verification}
+
+#### Необходимость надежности {#need-for-reliability}
+
+Формальная верификация используется для оценки корректности критически важных для безопасности систем, сбой которых может иметь разрушительные последствия, такие как смерть, травмы или финансовый крах. Смарт-контракты — это высокоценные приложения, контролирующие огромные суммы, и простые ошибки в проектировании могут привести к [невосполнимым потерям для пользователей](https://www.freecodecamp.org/news/a-hacker-stole-31m-of-ether-how-it-happened-and-what-it-means-for-ethereum-9e5dc29e33ce/amp/). Однако формальная верификация контракта перед развертыванием может повысить гарантии того, что он будет работать так, как ожидается, после запуска в блокчейне.
+
+Надежность — очень желаемое качество для любого смарт-контракта, особенно потому, что код, развернутый в виртуальной машине Ethereum (EVM), как правило, неизменяем. Поскольку обновления после запуска не всегда доступны, необходимость гарантировать надежность контрактов делает формальную верификацию необходимой. Формальная верификация способна обнаруживать сложные проблемы, такие как целочисленные недополнения и переполнения, повторный вход и плохая оптимизация газа, которые могут ускользнуть от аудиторов и тестировщиков.
+
+#### Доказательство функциональной корректности {#prove-functional-correctness}
+
+Тестирование программ — самый распространенный метод доказательства того, что смарт-контракт удовлетворяет некоторым требованиям. Это включает в себя выполнение контракта с образцом данных, которые он должен обрабатывать, и анализ его поведения. Если контракт возвращает ожидаемые результаты для образца данных, то разработчики получают объективное доказательство его корректности.
+
+Однако этот подход не может доказать корректное выполнение для входных значений, которые не являются частью образца. Таким образом, тестирование контракта может помочь обнаружить ошибки (т. е. если некоторые пути кода не возвращают желаемые результаты во время выполнения), но **оно не может окончательно доказать отсутствие ошибок**.
+
+Напротив, формальная верификация может формально доказать, что смарт-контракт удовлетворяет требованиям для бесконечного диапазона выполнений, _вообще не запуская_ контракт. Это требует создания формальной спецификации, которая точно описывает правильное поведение контракта, и разработки формальной (математической) модели системы контракта. Затем мы можем следовать формальной процедуре доказательства, чтобы проверить согласованность между моделью контракта и его спецификацией.
+
+При формальной верификации вопрос о том, удовлетворяет ли бизнес-логика контракта требованиям, является математическим утверждением, которое можно доказать или опровергнуть. Формально доказывая утверждение, мы можем проверить бесконечное количество тестовых случаев за конечное число шагов. Таким образом, формальная верификация имеет лучшие перспективы для доказательства того, что контракт функционально корректен по отношению к спецификации.
+
+#### Идеальные цели верификации {#ideal-verification-targets}
+
+Цель верификации описывает систему, которую необходимо формально верифицировать. Формальная верификация лучше всего используется во «встроенных системах» (небольших, простых частях программного обеспечения, которые являются частью более крупной системы). Они также идеальны для специализированных доменов с небольшим количеством правил, так как это облегчает модификацию инструментов для проверки свойств, специфичных для домена.
+
+Смарт-контракты — по крайней мере, в некоторой степени — удовлетворяют обоим требованиям. Например, небольшой размер контрактов Ethereum делает их подходящими для формальной верификации. Аналогичным образом, EVM следует простым правилам, что облегчает спецификацию и верификацию семантических свойств для программ, работающих в EVM.
+
+### Ускорение цикла разработки {#faster-development-cycle}
+
+Методы формальной верификации, такие как проверка моделей и символическое выполнение, как правило, более эффективны, чем обычный анализ кода смарт-контрактов (выполняемый во время тестирования или аудита). Это связано с тем, что формальная верификация использует символические значения для проверки утверждений («что, если пользователь попытается вывести _n_ эфира?»). в отличие от тестирования, которое использует конкретные значения («что, если пользователь попытается вывести 5 эфира?»).
+
+Символические входные переменные могут охватывать несколько классов конкретных значений, поэтому подходы формальной верификации обещают большее покрытие кода за более короткий промежуток времени. При эффективном использовании формальная верификация может ускорить цикл разработки для разработчиков.
+
+Формальная верификация также улучшает процесс создания децентрализованных приложений (dapps), уменьшая количество дорогостоящих ошибок проектирования. Обновление контрактов (где это возможно) для исправления уязвимостей требует значительной переработки кодовых баз и больших усилий на разработку. Формальная верификация может обнаружить многие ошибки в реализациях контрактов, которые могут ускользнуть от тестировщиков и аудиторов, и предоставляет широкие возможности для их исправления до развертывания контракта.
+
+## Недостатки формальной верификации {#drawbacks-of-formal-verification}
+
+### Стоимость ручного труда {#cost-of-manual-labor}
+
+Формальная верификация, особенно полуавтоматическая верификация, при которой человек направляет доказыватель для получения доказательств корректности, требует значительного ручного труда. Более того, создание формальной спецификации — это сложная деятельность, требующая высокого уровня квалификации.
+
+Эти факторы (усилия и квалификация) делают формальную верификацию более требовательной и дорогой по сравнению с обычными методами оценки корректности контрактов, такими как тестирование и аудит. Тем не менее, оплата стоимости полного аудита верификации является практичной, учитывая стоимость ошибок в реализациях смарт-контрактов.
+
+### Ложноотрицательные результаты {#false-negatives}
+
+Формальная верификация может только проверить, соответствует ли выполнение смарт-контракта формальной спецификации. Поэтому важно убедиться, что спецификация правильно описывает ожидаемое поведение смарт-контракта.
+
+Если спецификации написаны плохо, нарушения свойств, которые указывают на уязвимые выполнения, не могут быть обнаружены в ходе аудита формальной верификации. В этом случае разработчик может ошибочно предположить, что контракт не содержит ошибок.
+
+### Проблемы производительности {#performance-issues}
+
+Формальная верификация сталкивается с рядом проблем производительности. Например, проблемы взрыва состояний и путей, встречающиеся при проверке моделей и символическом выполнении соответственно, могут влиять на процедуры верификации. Кроме того, инструменты формальной верификации часто используют решатели SMT и другие решатели ограничений на своем базовом уровне, и эти решатели полагаются на вычислительно интенсивные процедуры.
+
+Кроме того, верификаторы программ не всегда могут определить, может ли свойство (описанное как логическая формула) быть выполнено или нет («[проблема разрешимости](https://en.wikipedia.org/wiki/Decision_problem)»), потому что программа может никогда не завершиться. Таким образом, может быть невозможно доказать некоторые свойства для контракта, даже если он хорошо специфицирован.
+
+## Инструменты формальной верификации для смарт-контрактов Ethereum {#formal-verification-tools}
+
+### Языки спецификаций для создания формальных спецификаций {#specification-languages}
+
+**Act**: __Act позволяет специфицировать обновления хранилища, предусловия/постусловия и инварианты контракта. Его набор инструментов также имеет бэкенды для доказательств, способные доказывать многие свойства с помощью Coq, решателей SMT или hevm.__
+
+- [GitHub](https://github.com/ethereum/act)
+- [Документация](https://github.com/argotorg/act)
+
+**Scribble** - __Scribble преобразует аннотации кода на языке спецификаций Scribble в конкретные утверждения, которые проверяют спецификацию.__
+
+- [Документация](https://docs.scribble.codes/)
+
+**Dafny** - __Dafny — это готовый к верификации язык программирования, который использует высокоуровневые аннотации для рассуждений о корректности кода и ее доказательства.__
+
+- [GitHub](https://github.com/dafny-lang/dafny)
+
+### Программные верификаторы для проверки корректности {#program-verifiers}
+
+**Certora Prover** - _Certora Prover — это автоматический инструмент формальной верификации для проверки корректности кода в смарт-контрактах. Спецификации пишутся на CVL (Certora Verification Language), а нарушения свойств обнаруживаются с помощью комбинации статического анализа и решения ограничений._
+
+- [Веб-сайт](https://www.certora.com/)
+- [Документация](https://docs.certora.com/en/latest/index.html)
+
+**Solidity SMTChecker** - __SMTChecker в Solidity — это встроенный инструмент проверки моделей, основанный на SMT (Satisfiability Modulo Theories) и решении Horn. Он подтверждает, соответствует ли исходный код контракта спецификациям во время компиляции, и статически проверяет нарушения свойств безопасности.__
+
+- [GitHub](https://github.com/ethereum/solidity)
+
+**solc-verify** - __solc-verify — это расширенная версия компилятора Solidity, которая может выполнять автоматическую формальную верификацию кода Solidity с использованием аннотаций и модульной верификации программ.__
+
+- [GitHub](https://github.com/SRI-CSL/solidity)
+
+**KEVM** - __KEVM — это формальная семантика виртуальной машины Ethereum (EVM), написанная на фреймворке K. KEVM является исполняемой и может доказывать определенные утверждения, связанные со свойствами, используя логику достижимости.__
+
+- [GitHub](https://github.com/runtimeverification/evm-semantics)
+- [Документация](https://jellopaper.org/)
+
+### Логические фреймворки для доказательства теорем {#theorem-provers}
+
+**Isabelle** - _Isabelle/HOL — это помощник для доказательств, который позволяет выражать математические формулы на формальном языке и предоставляет инструменты для доказательства этих формул. Основное применение — это формализация математических доказательств и, в частности, формальная верификация, которая включает в себя доказательство корректности компьютерного оборудования или программного обеспечения, а также доказательство свойств компьютерных языков и протоколов._
+
+- [GitHub](https://github.com/isabelle-prover)
+- [Документация](https://isabelle.in.tum.de/documentation.html)
+
+**Rocq** - _Rocq — это интерактивный доказыватель теорем, который позволяет определять программы с использованием теорем и интерактивно генерировать машино-проверяемые доказательства корректности._
+
+- [GitHub](https://github.com/rocq-prover/rocq)
+- [Документация](https://rocq-prover.org/docs)
+
+### Инструменты на основе символического выполнения для обнаружения уязвимых паттернов в смарт-контрактах {#symbolic-execution-tools}
+
+**Manticore** - __Инструмент для анализа байткода EVM на основе символического выполнения_._
+
+- [GitHub](https://github.com/trailofbits/manticore)
+- [Документация](https://github.com/trailofbits/manticore/wiki)
+
+**hevm** - __hevm — это движок символического выполнения и средство проверки эквивалентности для байткода EVM.__
+
+- [GitHub](https://github.com/dapphub/dapptools/tree/master/src/hevm)
+
+**Mythril** - _Инструмент символического выполнения для обнаружения уязвимостей в смарт-контрактах Ethereum_
+
+- [GitHub](https://github.com/ConsenSys/mythril-classic)
+- [Документация](https://mythril-classic.readthedocs.io/en/develop/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Как работает формальная верификация смарт-контрактов](https://runtimeverification.com/blog/how-formal-verification-of-smart-contracts-works/)
+- [Как формальная верификация может обеспечить безупречность смарт-контрактов](https://media.consensys.net/how-formal-verification-can-ensure-flawless-smart-contracts-cbda8ad99bd1)
+- [Обзор проектов формальной верификации в экосистеме Ethereum](https://github.com/leonardoalt/ethereum_formal_verification_overview)
+- [Полная формальная верификация депозитного смарт-контракта Ethereum 2.0](https://runtimeverification.com/blog/end-to-end-formal-verification-of-ethereum-2-0-deposit-smart-contract/)
+- [Формальная верификация самого популярного в мире смарт-контракта](https://www.zellic.io/blog/formal-verification-weth)
+- [SMTChecker и формальная верификация](https://docs.soliditylang.org/en/v0.8.15/smtchecker.html)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/index.md b/public/content/translations/ru/developers/docs/smart-contracts/index.md
new file mode 100644
index 00000000000..c46112d1a1e
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/index.md
@@ -0,0 +1,112 @@
+---
+title: "Введение в умные контракты"
+description: "Обзор смарт-контрактов с акцентом на их уникальные характеристики и ограничения."
+lang: ru
+---
+
+## Что такое смарт-контракт? {#what-is-a-smart-contract}
+
+«Смарт-контракт» — это просто программа, работающая на блокчейне Ethereum. Это набор кода (его функции) и данных (его состояние), который находится по определенному адресу в цепочке блоков Ethereum.
+
+Смарт-контракты — это тип [аккаунта Ethereum](/developers/docs/accounts/). Это значит, что они имеют баланс и могут быть целью транзакций. Однако они не контролируются пользователем, вместо этого они развертываются в сети и работают в соответствии с программой. Учетные записи пользователей могут затем взаимодействовать со смарт-контрактом, отправляя транзакции, которые выполняют функцию, определенную в смарт-контракте. Смарт-контракты могут определять правила, как обычный контракт, и автоматически обеспечивать их соблюдение с помощью кода. Смарт-контракты нельзя просто так удалить, а взаимодействие с ними необратимо.
+
+## Предварительные условия {#prerequisites}
+
+Если вы только начинаете или ищете менее техническое введение, мы рекомендуем наше [введение в смарт-контракты](/smart-contracts/).
+
+Прежде чем погрузиться в мир смарт-контрактов, убедитесь, что вы ознакомились с [аккаунтами](/developers/docs/accounts/), [транзакциями](/developers/docs/transactions/) и [виртуальной машиной Ethereum](/developers/docs/evm/).
+
+## Цифровой торговый автомат {#a-digital-vending-machine}
+
+Возможно, лучшей метафорой для смарт-контракта является торговый автомат, как его описал [Ник Сабо](https://unenumerated.blogspot.com/). При правильном вводе гарантирован определенный результат.
+
+Чтобы купить закуску в торговом автомате:
+
+```
+money + snack selection = snack dispensed
+```
+
+Эта логика запрограммирована в торговый автомат.
+
+В смарт-контракт, как в торговый автомат, заложена логика. Вот простой пример того, как этот торговый автомат мог бы выглядеть, если его запустить с помощью Solidity:
+
+```solidity
+pragma solidity 0.8.7;
+
+contract VendingMachine {
+
+ // Объявление переменных состояния контракта
+ address public owner;
+ mapping (address => uint) public cupcakeBalances;
+
+ // Когда контракт 'VendingMachine' развернут:
+ // 1. установить адрес развертывания как владельца контракта
+ // 2. установить баланс кексов развернутого смарт-контракта на 100
+ constructor() {
+ owner = msg.sender;
+ cupcakeBalances[address(this)] = 100;
+ }
+
+ // Разрешить владельцу увеличивать баланс кексов смарт-контракта
+ function refill(uint amount) public {
+ require(msg.sender == owner, "Только владелец может пополнять.");
+ cupcakeBalances[address(this)] += amount;
+ }
+
+ // Разрешить любому покупать кексы
+ function purchase(uint amount) public payable {
+ require(msg.value >= amount * 1 ether, "Вы должны заплатить не менее 1 ETH за кекс");
+ require(cupcakeBalances[address(this)] >= amount, "Недостаточно кексов на складе для совершения этой покупки");
+ cupcakeBalances[address(this)] -= amount;
+ cupcakeBalances[msg.sender] += amount;
+ }
+}
+```
+
+Подобно тому, как торговый автомат устраняет необходимость в продавце, смарт-контракты могут заменить посредников во многих отраслях.
+
+## Без разрешений {#permissionless}
+
+Кто угодно может написать смарт-контракт и развернуть его в сети. Вам просто нужно научиться программировать на [языке смарт-контрактов](/developers/docs/smart-contracts/languages/) и иметь достаточно ETH для развертывания вашего контракта. Развертывание смарт-контракта технически является транзакцией, поэтому вам нужно платить за [газ](/developers/docs/gas/) так же, как вы платите за газ для простого перевода ETH. Однако стоимость газа для развертывания контракта намного выше.
+
+В Ethereum есть удобные для разработчиков языки для написания смарт-контрактов:
+
+- Solidity
+- Vyper
+
+[Подробнее о языках](/developers/docs/smart-contracts/languages/)
+
+Однако перед развертыванием они должны быть скомпилированы, чтобы виртуальная машина Ethereum могла интерпретировать и хранить контракт. [Подробнее о компиляции](/developers/docs/smart-contracts/compiling/)
+
+## Компонуемость {#composability}
+
+Смарт-контракты общедоступны в Ethereum и могут рассматриваться как открытые API. Это означает, что вы можете вызывать другие смарт-контракты в своем собственном смарт-контракте, чтобы значительно расширить его возможности. Контракты могут даже использовать другие контракты.
+
+Узнайте больше о [компонуемости смарт-контрактов](/developers/docs/smart-contracts/composability/).
+
+## Ограничения {#limitations}
+
+Смарт-контракты сами по себе не могут получать информацию о событиях из "реального мира", так как они не могут извлекать данные из оффчейн-источников. Это означает, что они не могут реагировать на события в реальном мире. Так задумано по проекту. Зависимость от внешней информации может поставить под угрозу консенсус, который важен для безопасности и децентрализации.
+
+Однако для блокчейн-приложений важно иметь возможность использовать оффчейн-данные. Решением являются [оракулы](/developers/docs/oracles/) — инструменты, которые принимают оффчейн-данные и делают их доступными для смарт-контрактов.
+
+Еще одним ограничением смарт-контрактов является максимальный размер контракта. Смарт-контракт может быть размером не более 24 Кб, иначе у него закончится газ. Эту проблему можно обойти, используя [The Diamond Pattern](https://eips.ethereum.org/EIPS/eip-2535).
+
+## Контракты с мультиподписью {#multisig}
+
+Мультиподписные контракты (контракты с несколькими подписями) - это учетные записи смарт-контрактов, которые для выполнения транзакции требуют несколько действительных подписей. Это очень полезно, чтобы избежать единичных точек отказа для контрактов, содержащих существенное количество Эфира или других токенов. Мультиподписи также разделяют ответственность за выполнение контракта и управление ключами между многими сторонами и предотвращают потерю одного закрытого ключа, ведущую к необратимой потере денежных средств. По этим причинам мультиподписные контракты могут быть использованы для простого управления DAO. Мультиподписи требуют N подписей из M возможных приемлемых подписей (где N ≤ M и M > 1) для выполнения. Часто используются `N = 3, M = 5` и `N = 4, M = 7`. Мультиподпись 4/7 требует четыре из семи возможных действительных подписей. Это значит, что денежные средства всё ещё можно восстановить, даже если три подписи потеряны. В этом случае это также означает, что большинство держателей ключей должны согласиться и подписать контракт, чтобы он выполнился.
+
+## Ресурсы по смарт-контрактам {#smart-contract-resources}
+
+**OpenZeppelin Contracts —** **_Библиотека для безопасной разработки смарт-контрактов._**
+
+- [openzeppelin.com/contracts/](https://openzeppelin.com/contracts/)
+- [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts)
+- [Форум сообщества](https://forum.openzeppelin.com/c/general/16)
+
+## Дополнительные материалы {#further-reading}
+
+- [Coinbase: Что такое смарт-контракт?](https://www.coinbase.com/learn/crypto-basics/what-is-a-smart-contract)
+- [Chainlink: Что такое смарт-контракт?](https://chain.link/education/smart-contracts)
+- [Видео: Смарт-контракты простыми словами](https://youtu.be/ZE2HxTmxfrI)
+- [Cyfrin Updraft: Платформа для обучения и аудита в Web3](https://updraft.cyfrin.io)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/languages/index.md b/public/content/translations/ru/developers/docs/smart-contracts/languages/index.md
new file mode 100644
index 00000000000..8f4aee5c134
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/languages/index.md
@@ -0,0 +1,342 @@
+---
+title: "Языки программирования смарт-контрактов"
+description: "Обзор и сравнение двух основных языков программирования смарт контрактов – Solidity и Vyper."
+lang: ru
+---
+
+Отличительная черта Ethereum в том, что смарт-контракты могут быть написаны при помощи относительно удобных для разработчиков языков. Если у вас есть опыт работы с Python или любым [языком с фигурными скобками](https://wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages), вы можете найти язык со знакомым синтаксисом.
+
+Два наиболее часто используемых и поддерживаемых языка это:
+
+- Solidity
+- Vyper
+
+Remix IDE предоставляет комплексную среду разработки для создания и тестирования контрактов как на Solidity, так и на Vyper. [Попробуйте браузерную Remix IDE](https://remix.ethereum.org), чтобы начать программировать.
+
+Более опытные разработчики также могут использовать Yul, промежуточный язык для [виртуальной машины Ethereum](/developers/docs/evm/), или Yul+, расширение для Yul.
+
+Если вам любопытно и вы хотите помочь протестировать новые языки, которые все еще находятся в стадии активной разработки, вы можете поэкспериментировать с Fe, новым языком смарт-контрактов, который в настоящее время все еще находится в состоянии становления.
+
+## Предварительные условия {#prerequisites}
+
+Предыдущие знания языков программирования, особенно JavaScript или Python, могут помочь вам уловить разницу между языками смарт контрактов. Мы также рекомендуем вам ознакомится со смарт контрактами, как явлением, прежде чем углубляться в сравнение языков. [Введение в смарт-контракты](/developers/docs/smart-contracts/).
+
+## Solidity {#solidity}
+
+- Объектно-ориентированный высокоуровневый язык для реализации смарт-контрактов.
+- Язык "фигурных скобок", на который большое влияние оказал C++.
+- Статический (тип переменной известен во время компиляции).
+- Поддерживает:
+ - Наследование (вы можете расширять другие контракты).
+ - Библиотеки (вы можете создавать повторно используемый код, который можно вызывать из разных контрактов как статические функции в статических классах в других языках программирования).
+ - Сложные типы, определяемые пользователем.
+
+### Важные ссылки {#important-links}
+
+- [Документация](https://docs.soliditylang.org/en/latest/)
+- [Портал языка Solidity](https://soliditylang.org/)
+- [Solidity by Example](https://docs.soliditylang.org/en/latest/solidity-by-example.html)
+- [GitHub](https://github.com/ethereum/solidity/)
+- [Чат Solidity в Gitter](https://gitter.im/ethereum/solidity) с мостом в [чат Solidity в Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im)
+- [Шпаргалка](https://reference.auditless.com/cheatsheet)
+- [Блог Solidity](https://blog.soliditylang.org/)
+- [Solidity в Twitter](https://twitter.com/solidity_lang)
+
+### Пример контракта {#example-contract}
+
+```solidity
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity >= 0.7.0;
+
+contract Coin {
+ // Ключевое слово "public" делает переменные
+ // доступными из других контрактов
+ address public minter;
+ mapping (address => uint) public balances;
+
+ // События позволяют клиентам реагировать на определенные
+ // объявляемые вами изменения в контракте
+ event Sent(address from, address to, uint amount);
+
+ // Код конструктора выполняется только при
+ // создании контракта
+ constructor() {
+ minter = msg.sender;
+ }
+
+ // Отправляет определенное количество вновь созданных монет на адрес
+ // Может вызываться только создателем контракта
+ function mint(address receiver, uint amount) public {
+ require(msg.sender == minter);
+ require(amount < 1e60);
+ balances[receiver] += amount;
+ }
+
+ // Отправляет определенное количество существующих монет
+ // от любого вызывающего на адрес
+ function send(address receiver, uint amount) public {
+ require(amount <= balances[msg.sender], "Недостаточный баланс.");
+ balances[msg.sender] -= amount;
+ balances[receiver] += amount;
+ emit Sent(msg.sender, receiver, amount);
+ }
+}
+```
+
+Этот пример призван дать понимание о том, что из себя представляет синтаксис контракта на Solidity. Более подробное описание функций и переменных смотрите [в документации](https://docs.soliditylang.org/en/latest/contracts.html).
+
+## Vyper {#vyper}
+
+- Язык программирования, похожий на Python
+- Сильная типизация
+- Маленький и понятный код компилятора
+- Эффективная генерация байткода
+- Специально содержит меньше функционала, чем Solidity, с целью создания более безопасных контрактов, которые легче проверять. Vyper не поддерживает:
+ - Модификаторы
+ - Наследование
+ - Ассамблерное встраивание
+ - Перегрузку функций
+ - Перегрузку операторов
+ - Рекурсию
+ - Бесконечные циклы
+ - Бинарные фиксированные точки
+
+Для получения дополнительной информации [прочтите обоснование Vyper](https://vyper.readthedocs.io/en/latest/index.html).
+
+### Важные ссылки {#important-links-1}
+
+- [Документация](https://vyper.readthedocs.io)
+- [Vyper by Example](https://vyper.readthedocs.io/en/latest/vyper-by-example.html)
+- [More Vyper by Example](https://vyper-by-example.org/)
+- [GitHub](https://github.com/vyperlang/vyper)
+- [Чат сообщества Vyper в Discord](https://discord.gg/SdvKC79cJk)
+- [Шпаргалка](https://reference.auditless.com/cheatsheet)
+- [Платформы и инструменты для разработки смарт-контрактов для Vyper](/developers/docs/programming-languages/python/)
+- [VyperPunk: научитесь защищать и взламывать смарт-контракты на Vyper](https://github.com/SupremacyTeam/VyperPunk)
+- [Vyper Hub для разработки](https://github.com/zcor/vyper-dev)
+- [Vyper: лучшие примеры смарт-контрактов](https://github.com/pynchmeister/vyper-greatest-hits/tree/main/contracts)
+- [Awesome Vyper: избранные ресурсы](https://github.com/spadebuilders/awesome-vyper)
+
+### Пример {#example}
+
+```python
+# Открытый аукцион
+
+# Параметры аукциона
+
+# Бенефициар получает деньги от участника, предложившего самую высокую цену
+
+beneficiary: public(address)
+auctionStart: public(uint256)
+auctionEnd: public(uint256)
+
+# Текущее состояние аукциона
+
+highestBidder: public(address)
+highestBid: public(uint256)
+
+# Устанавливается в true в конце, запрещает любые изменения
+
+ended: public(bool)
+
+# Отслеживайте возвращенные ставки, чтобы мы могли следовать шаблону вывода средств
+
+pendingReturns: public(HashMap[address, uint256])
+
+# Создайте простой аукцион с `_bidding_time`
+
+# секундами времени для торгов от имени
+
+# адреса бенефициара `_beneficiary`.
+
+@external
+def __init__(_beneficiary: address, _bidding_time: uint256):
+ self.beneficiary = _beneficiary
+ self.auctionStart = block.timestamp
+ self.auctionEnd = self.auctionStart + _bidding_time
+
+# Сделайте ставку на аукционе на сумму, отправленную
+
+# вместе с этой транзакцией.
+
+# Сумма будет возвращена, только если
+
+# аукцион не выигран.
+
+@external
+@payable
+def bid():
+ # Проверьте, закончился ли период торгов.
+ assert block.timestamp < self.auctionEnd
+ # Проверьте, достаточно ли высока ставка
+ assert msg.value > self.highestBid
+ # Отследите возврат средств для предыдущего участника, предложившего самую высокую цену
+ self.pendingReturns[self.highestBidder] += self.highestBid
+ # Отследите новую высокую ставку
+ self.highestBidder = msg.sender
+ self.highestBid = msg.value
+
+# Выведите ранее возвращенную ставку. Шаблон вывода средств
+
+# используется здесь, чтобы избежать проблемы с безопасностью. Если бы возмещения были напрямую
+
+# отправлены как часть bid(), вредоносный контракт для торгов мог бы заблокировать
+
+# эти возвраты и, таким образом, заблокировать поступление новых более высоких ставок.
+
+@external
+def withdraw():
+ pending_amount: uint256 = self.pendingReturns[msg.sender]
+ self.pendingReturns[msg.sender] = 0
+ send(msg.sender, pending_amount)
+
+# Завершите аукцион и отправьте самую высокую ставку
+
+# бенефициару.
+
+@external
+def endAuction():
+ # Рекомендуется структурировать функции, которые взаимодействуют
+ # с другими контрактами (т. е. вызывают функции или отправляют эфир)
+ # в три этапа:
+ # 1. проверка условий
+ # 2. выполнение действий (потенциально изменяющих условия)
+ # 3. взаимодействие с другими контрактами
+ # Если эти этапы перепутаны, другой контракт может вызвать
+ # обратно текущий контракт и изменить состояние или вызвать
+ # многократное выполнение эффектов (выплата эфира).
+ # Если функции, вызываемые внутри, включают взаимодействие с внешними
+ # контрактами, их также следует рассматривать как взаимодействие с
+ # внешними контрактами.
+
+ # 1. Условия
+ # Проверьте, достигнуто ли время окончания аукциона
+ assert block.timestamp >= self.auctionEnd
+ # Проверьте, не была ли эта функция уже вызвана
+ assert not self.ended
+
+ # 2. Эффекты
+ self.ended = True
+
+ # 3. Взаимодействие
+ send(self.beneficiary, self.highestBid)
+```
+
+Этот пример должен дать вам представление о синтаксисе контракта Vyper. Более подробное описание функций и переменных смотрите [в документации](https://vyper.readthedocs.io/en/latest/vyper-by-example.html#simple-open-auction).
+
+## Yul и Yul+ {#yul}
+
+Если вы новичок в Ethereum и еще не программировали на языках смарт-контрактов, мы рекомендуем начать с Solidity или Vyper. Обращайтесь к Yul или Yul+ только после того, как ознакомитесь с передовыми методами обеспечения безопасности смарт-контрактов и особенностями работы с EVM.
+
+**Yul**
+
+- Промежуточный язык для Ethereum.
+- Поддерживает [EVM](/developers/docs/evm) и [Ewasm](https://github.com/ewasm), WebAssembly в стиле Ethereum, и разработан как пригодный общий знаменатель для обеих платформ.
+- Хорошо подходит для этапов высокоуровневой оптимизации, которые могут в равной степени принести пользу как платформе EVM, так и Ewasm.
+
+**Yul+**
+
+- Низкоуровневое, высокоэффективное расширение для Yul.
+- Первоначально был разработан для контракта [оптимистического ролл-апа](/developers/docs/scaling/optimistic-rollups/).
+- Yul+ можно рассматривать как экспериментальное предложение по обновлению Yul, добавляющее в него новые функции.
+
+### Важные ссылки {#important-links-2}
+
+- [Документация Yul](https://docs.soliditylang.org/en/latest/yul.html)
+- [Документация Yul+](https://github.com/fuellabs/yulp)
+- [Вводная статья о Yul+](https://medium.com/@fuellabs/introducing-yul-a-new-low-level-language-for-ethereum-aa64ce89512f)
+
+### Пример контракта {#example-contract-2}
+
+На этом простом примере реализуем функцию power. Его можно скомпилировать с помощью `solc --strict-assembly --bin input.yul`. Пример должен быть сохранен в файле input.yul.
+
+```
+{
+ function power(base, exponent) -> result
+ {
+ switch exponent
+ case 0 { result := 1 }
+ case 1 { result := base }
+ default
+ {
+ result := power(mul(base, base), div(exponent, 2))
+ if mod(exponent, 2) { result := mul(base, result) }
+ }
+ }
+ let res := power(calldataload(0), calldataload(32))
+ mstore(0, res)
+ return(0, 32)
+}
+```
+
+Если у вас уже есть большой опыт работы со смарт-контрактами, полную реализацию ERC20 на Yul можно найти [здесь](https://solidity.readthedocs.io/en/latest/yul.html#complete-erc20-example).
+
+## Fe {#fe}
+
+- Статически типизированный язык для виртуальной машины Ethereum (EVM).
+- Вдохновлен Python и Rust.
+- Стремится быть простым в освоении — даже для разработчиков, которые плохо знакомы с экосистемой Ethereum.
+- Разработка Fe все еще находится на ранней стадии, альфа-версия языка была выпущена в январе 2021 года.
+
+### Важные ссылки {#important-links-3}
+
+- [GitHub](https://github.com/ethereum/fe)
+- [Анонс Fe](https://snakecharmers.ethereum.org/fe-a-new-language-for-the-ethereum-ecosystem/)
+- [Дорожная карта Fe на 2021 год](https://notes.ethereum.org/LVhaTF30SJOpkbG1iVw1jg)
+- [Чат Fe в Discord](https://discord.com/invite/ywpkAXFjZH)
+- [Fe в Twitter](https://twitter.com/official_fe)
+
+### Пример контракта {#example-contract-3}
+
+Ниже приведен простой контракт, реализованный в Fe.
+
+```
+type BookMsg = bytes[100]
+
+contract GuestBook:
+ pub guest_book: map
+
+ event Signed:
+ book_msg: BookMsg
+
+ pub def sign(book_msg: BookMsg):
+ self.guest_book[msg.sender] = book_msg
+
+ emit Signed(book_msg=book_msg)
+
+ pub def get_msg(addr: address) -> BookMsg:
+ return self.guest_book[addr].to_mem()
+
+```
+
+## Как выбрать {#how-to-choose}
+
+Как и с другими языками программирования, это в большинстве своем выбор правильного инструмента для конкретной работы, так же, как и в личных предпочтениях.
+
+Вот несколько фактов для раздумий, если вы ещё не пробовали ни один из языков:
+
+### Какие преимущества у Solidity? {#solidity-advantages}
+
+- Если вы новичок, есть множество материалов и инструментов обучения. Подробнее об этом можно узнать в разделе [Учитесь, создавая код](/developers/learning-tools/).
+- Доступны удобные инструменты для разработчиков.
+- У Solidity большое сообщество разработчиков, что означает быстрый поиск ответов на ваши вопросы.
+
+### Какие преимущества у Vyper? {#vyper-advatages}
+
+- Отличный способ начать для Python разработчиков, которые хотят писать смарт контракты.
+- У Vyper меньшее количество функционала, что делает его превосходным инструментом для быстрой проверки идей.
+- Цель Vyper быть легким для аудитов и максимально читабельным для людей.
+
+### Какие преимущества у Yul и Yul+? {#yul-advantages}
+
+- Простой и функциональный низкоуровневый язык.
+- Позволяет максимально приблизиться к функциям EVM, что может помочь оптимизировать затраты газа в ваших контрактах.
+
+## Сравнение языков {#language-comparisons}
+
+Для сравнения базового синтаксиса, жизненного цикла контракта, интерфейсов, операторов, структур данных, функций, потока управления и многого другого ознакомьтесь с этой [шпаргалкой от Auditless](https://reference.auditless.com/cheatsheet/)
+
+## Дополнительные материалы {#further-reading}
+
+- [Библиотека контрактов Solidity от OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/)
+- [Solidity by Example](https://solidity-by-example.org)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/libraries/index.md b/public/content/translations/ru/developers/docs/smart-contracts/libraries/index.md
new file mode 100644
index 00000000000..e31db114833
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/libraries/index.md
@@ -0,0 +1,117 @@
+---
+title: "Библиотеки смарт-контрактов"
+description: "Откройте для себя многократно используемые библиотеки смарт-контрактов и строительные блоки для ускорения ваших проектов по разработке Ethereum."
+lang: ru
+---
+
+Вам не нужно писать каждый смарт-контракт в своем проекте с нуля. Доступно множество библиотек смарт-контрактов с открытым исходным кодом, которые предоставляют многократно используемые строительные блоки для вашего проекта, которые могут избавить вас от необходимости изобретать колесо.
+
+## Предварительные условия {#prerequisites}
+
+Прежде чем переходить к библиотекам смарт-контрактов, неплохо было бы хорошо понять структуру смарт-контракта. Перейдите к [анатомии умного контракта](/developers/docs/smart-contracts/anatomy/), если вы еще этого не сделали.
+
+## Что находится в библиотеке {#whats-in-a-library}
+
+Обычно в библиотеках смарт-контрактов можно найти два типа строительных блоков: многоразовые варианты поведения, которые вы можете добавить в свои контракты, и реализации различных стандартов.
+
+### Поведения {#behaviors}
+
+При написании смарт-контрактов вы, скорее всего, будете снова и снова писать похожие шаблоны, например, назначать адрес _администратора_ для выполнения защищенных операций в контракте или добавлять кнопку экстренной _паузы_ в случае непредвиденной проблемы.
+
+Библиотеки смарт-контрактов обычно предоставляют повторно используемые реализации такого поведения в виде [библиотек](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#libraries) или через [наследование](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#inheritance) в Solidity.
+
+В качестве примера ниже приведена упрощенная версия [контракта `Ownable`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/access/Ownable.sol) из [библиотеки контрактов OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), которая назначает адрес в качестве владельца контракта и предоставляет модификатор для ограничения доступа к методу только этому владельцу.
+
+```solidity
+contract Ownable {
+ address public owner;
+
+ constructor() internal {
+ owner = msg.sender;
+ }
+
+ modifier onlyOwner() {
+ require(owner == msg.sender, "Ownable: caller is not the owner");
+ _;
+ }
+}
+```
+
+Чтобы использовать такой строительный блок в своем контракте, вам нужно сначала импортировать его, а затем расширить его в своих собственных контрактах. Это позволит вам использовать модификатор, предоставляемый базовым контрактом `Ownable`, для защиты ваших собственных функций.
+
+```solidity
+import ".../Ownable.sol"; // Path to the imported library
+
+contract MyContract is Ownable {
+ // The following function can only be called by the owner
+ function secured() onlyOwner public {
+ msg.sender.transfer(1 ether);
+ }
+}
+```
+
+Другим популярным примером является [SafeMath](https://docs.openzeppelin.com/contracts/3.x/utilities#math) или [DsMath](https://dappsys.readthedocs.io/en/latest/ds_math.html). Это библиотеки (в отличие от базовых контрактов), которые предоставляют арифметические функции с проверками переполнения, которые не предусмотрены языком. Рекомендуется использовать любую из этих библиотек вместо собственных арифметических операций для защиты вашего контракта от переполнений, которые могут иметь катастрофические последствия!
+
+### Стандарты {#standards}
+
+Для обеспечения [компонуемости и функциональной совместимости](/developers/docs/smart-contracts/composability/) сообщество Ethereum определило несколько стандартов в виде **ERC**. Вы можете прочитать о них подробнее в разделе [стандартов](/developers/docs/standards/).
+
+При включении ERC в свои контракты рекомендуется искать стандартные реализации, а не пытаться развернуть свои собственные. Многие библиотеки смарт-контрактов включают реализации наиболее популярных ERC. Например, повсеместно распространенный [стандарт взаимозаменяемых токенов ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) можно найти в [HQ20](https://github.com/HQ20/contracts/blob/master/contracts/token/README.md), [DappSys](https://github.com/dapphub/ds-token/) и [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc20). Кроме того, некоторые ERC также предоставляют канонические реализации как часть самого ERC.
+
+Стоит отметить, что некоторые ERC не являются автономными, а являются дополнениями к другим ERC. Например, [ERC2612](https://eips.ethereum.org/EIPS/eip-2612) добавляет расширение к ERC20 для повышения удобства его использования.
+
+## Как добавить библиотеку {#how-to}
+
+Всегда обращайтесь к документации библиотеки, которую вы включаете, для получения конкретных инструкций о том, как включить ее в свой проект. Несколько библиотек контрактов Solidity упакованы с использованием `npm`, так что вы можете просто установить их командой `npm install`. Большинство инструментов для [компиляции](/developers/docs/smart-contracts/compiling/) контрактов будут искать в вашем каталоге `node_modules` библиотеки смарт-контрактов, поэтому вы можете сделать следующее:
+
+```solidity
+// This will load the @openzeppelin/contracts library from your node_modules
+import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
+
+contract MyNFT is ERC721 {
+ constructor() ERC721("MyNFT", "MNFT") public { }
+}
+```
+
+Независимо от используемого вами метода, при подключении библиотеки всегда следите за версией [языка](/developers/docs/smart-contracts/languages/). Например, вы не можете использовать библиотеку для Solidity 0.6, если вы пишете свои контракты на Solidity 0.5.
+
+## Когда использовать {#when-to-use}
+
+Использование библиотеки смарт-контрактов для вашего проекта имеет несколько преимуществ. Прежде всего, это экономит ваше время, предоставляя вам готовые к использованию строительные блоки, которые вы можете включить в свою систему, вместо того, чтобы кодировать их самостоятельно.
+
+Безопасность также является большим плюсом. Библиотеки смарт-контрактов с открытым исходным кодом также часто подвергаются тщательной проверке. Поскольку от них зависят многие проекты, у сообщества есть сильный стимул держать их под постоянным контролем. Гораздо чаще ошибки обнаруживаются в коде приложения, чем в многократно используемых библиотеках контрактов. Некоторые библиотеки также проходят [внешний аудит](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/audits) для дополнительной безопасности.
+
+Однако использование библиотек смарт-контрактов сопряжено с риском включения кода, с которым вы не знакомы, в свой проект. Заманчиво импортировать контракт и включить его непосредственно в ваш проект, но без хорошего понимания того, что делает этот контракт, вы можете случайно создать проблему в своей системе из-за неожиданного поведения. Всегда обязательно читайте документацию по импортируемому коду, а затем просматривайте сам код, прежде чем делать его частью своего проекта!
+
+Наконец, при принятии решения о включении библиотеки следует учитывать ее общее использование. Широко распространенный метод имеет то преимущество, что у него более широкое сообщество и больше глаз, которые следят за его проблемами. Безопасность должна быть вашим основным приоритетом при создании смарт-контрактов!
+
+## Связанные инструменты {#related-tools}
+
+**OpenZeppelin Contracts -** **_Самая популярная библиотека для безопасной разработки смарт-контрактов._**
+
+- [Документация](https://docs.openzeppelin.com/contracts/)
+- [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts)
+- [Форум сообщества](https://forum.openzeppelin.com/c/general/16)
+
+**DappSys -** **_Безопасные, простые, гибкие строительные блоки для смарт-контрактов._**
+
+- [Документация](https://dappsys.readthedocs.io/)
+- [GitHub](https://github.com/dapphub/dappsys)
+
+**HQ20 -** **_Проект Solidity с контрактами, библиотеками и примерами, которые помогут вам создавать полнофункциональные распределенные приложения для реального мира._**
+
+- [GitHub](https://github.com/HQ20/contracts)
+
+**thirdweb Solidity SDK -** **_Предоставляет инструменты, необходимые для эффективной разработки пользовательских смарт-контрактов_**
+
+- [Документация](https://portal.thirdweb.com/contracts/build/overview)
+- [GitHub](https://github.com/thirdweb-dev/contracts)
+
+## Связанные руководства {#related-tutorials}
+
+- [Рекомендации по безопасности для разработчиков Ethereum](/developers/docs/smart-contracts/security/) _– руководство по вопросам безопасности при создании смарт-контрактов, включая использование библиотек._
+- [Принципы работы смарт-контракта токена ERC-20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _– руководство по стандарту ERC20, предоставляемое несколькими библиотеками._
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/naming/index.md b/public/content/translations/ru/developers/docs/smart-contracts/naming/index.md
new file mode 100644
index 00000000000..9fa885a5021
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/naming/index.md
@@ -0,0 +1,101 @@
+---
+title: "Присвоение имен умным контрактам"
+description: "Лучшие практики по присвоению имен умным контрактам Ethereum с помощью ENS"
+lang: ru
+---
+
+Умные контракты являются краеугольным камнем децентрализованной инфраструктуры Ethereum, обеспечивая работу автономных приложений и протоколов. Но даже по мере развития возможностей контрактов пользователи и разработчики по-прежнему полагаются на необработанные шестнадцатеричные адреса для идентификации и ссылки на эти контракты.
+
+Присвоение имен умным контрактам с помощью [Службы имен Ethereum (ENS)](https://ens.domains/) улучшает пользовательский опыт за счет устранения шестнадцатеричных адресов контрактов и снижает риск атак, таких как отравление адресов и спуфинг-атаки. В этом руководстве объясняется, почему важно давать имена умным контрактам, как это можно реализовать, а также какие инструменты, такие как [Enscribe](https://www.enscribe.xyz), доступны для упрощения процесса и помощи разработчикам в освоении этой практики.
+
+## Зачем давать имена умным контрактам? {#why-name-contracts}
+
+### Человекочитаемые идентификаторы {#human-readable-identifiers}
+
+Вместо взаимодействия с непрозрачными адресами контрактов, такими как `0x8f8e...f9e3`, разработчики и пользователи могут использовать человекочитаемые имена, например `v2.myapp.eth`. Это упрощает взаимодействие с умными контрактами.
+
+Это стало возможным благодаря [Службе имен Ethereum](https://ens.domains/), которая предоставляет децентрализованную службу имен для адресов Ethereum. Это аналогично тому, как система доменных имен (DNS) позволяет пользователям Интернета получать доступ к сетевым адресам, используя такое имя, как ethereum.org, а не IP-адрес, например `104.18.176.152`.
+
+### Повышенная безопасность и доверие {#improved-security-and-trust}
+
+Именованные контракты помогают сократить количество случайных транзакций на неправильный адрес. Они также помогают пользователям идентифицировать контракты, привязанные к определенным приложениям или брендам. Это добавляет уровень репутационного доверия, особенно когда имена привязаны к известным родительским доменам, таким как `uniswap.eth`.
+
+Из-за 42-символьной длины адреса Ethereum пользователям очень трудно выявить небольшие изменения в адресах, в которых было изменено несколько символов. Например, такой адрес, как `0x58068646C148E313CB414E85d2Fe89dDc3426870`, обычно сокращается до `0x580...870` в пользовательских приложениях, таких как кошельки. Пользователь вряд ли заметит вредоносный адрес, в котором изменена пара символов.
+
+Этот тип техники используется в атаках с подменой и отравлением адресов, когда пользователей заставляют поверить, что они взаимодействуют с правильным адресом или отправляют средства на него, тогда как на самом деле адрес просто напоминает правильный, но не является им.
+
+Имена ENS для кошельков и контрактов защищают от таких атак. Подобно атакам с подменой DNS, атаки с подменой ENS также могут иметь место, однако пользователь с большей вероятностью заметит опечатку в имени ENS, чем небольшое изменение в шестнадцатеричном адресе.
+
+### Улучшенный UX для кошельков и обозревателей {#better-ux}
+
+Когда умный контракт настроен с именем ENS, такие приложения, как кошельки и обозреватели блокчейна, могут отображать имена ENS для умных контрактов вместо шестнадцатеричных адресов. Это обеспечивает значительное улучшение пользовательского опыта (UX) для пользователей.
+
+Например, при взаимодействии с таким приложением, как Uniswap, пользователи обычно видят, что приложение, с которым они взаимодействуют, размещено на веб-сайте `uniswap.org`, но им будет представлен шестнадцатеричный адрес контракта, если Uniswap не присвоил своим умным контрактам имена с помощью ENS. Если контракту присвоено имя, вместо этого они могут увидеть `v4.contracts.uniswap.eth`, что гораздо полезнее.
+
+## Присвоение имени при развертывании и после развертывания {#when-to-name}
+
+Есть два момента, когда умным контрактам можно присвоить имя:
+
+- **Во время развертывания**: присвоение имени ENS контракту по мере его развертывания.
+- **После развертывания**: сопоставление существующего адреса контракта с новым именем ENS.
+
+Оба подхода основаны на наличии у владельца или менеджера доступа к домену ENS, чтобы они могли создавать и устанавливать записи ENS.
+
+## Как работает присвоение имен ENS для контрактов {#how-ens-naming-works}
+
+Имена ENS хранятся в сети и разрешаются в адреса Ethereum через преобразователи ENS. Чтобы присвоить имя умному контракту:
+
+1. Зарегистрируйте или управляйте родительским доменом ENS (например, `myapp.eth`)
+2. Создайте субдомен (например, `v1.myapp.eth`)
+3. Установите запись `address` субдомена на адрес контракта
+4. Установите обратную запись контракта в ENS, чтобы имя можно было найти по его адресу
+
+Имена ENS иерархичны и поддерживают неограниченное количество суб-имен. Установка этих записей обычно включает взаимодействие с реестром ENS и публичными контрактами-преобразователями.
+
+## Инструменты для присвоения имен контрактам {#tools}
+
+Существует два подхода к присвоению имен умным контрактам. Либо с помощью [приложения ENS](https://app.ens.domains) с некоторыми ручными шагами, либо с помощью [Enscribe](https://www.enscribe.xyz). Они описаны ниже.
+
+### Ручная настройка ENS {#manual-ens-setup}
+
+С помощью [приложения ENS](https://app.ens.domains/) разработчики могут вручную создавать суб-имена и устанавливать записи прямых адресов. Однако они не могут установить основное имя для умного контракта, установив обратную запись для имени через приложение ENS. Необходимо выполнить ручные шаги, которые описаны в [документации ENS](https://docs.ens.domains/web/naming-contracts/).
+
+### Enscribe {#enscribe}
+
+[Enscribe](https://www.enscribe.xyz) упрощает присвоение имен умным контрактам с помощью ENS и повышает доверие пользователей к умным контрактам. Он предоставляет:
+
+- **Атомарное развертывание и присвоение имени**: присвоение имени ENS при развертывании нового контракта
+- **Присвоение имен после развертывания**: прикрепление имен к уже развернутым контрактам
+- **Поддержка нескольких сетей**: работает в сетях Ethereum и L2, где поддерживается ENS
+- **Данные верификации контракта**: включают данные верификации контракта, полученные из нескольких источников, для повышения доверия пользователей
+
+Enscribe поддерживает имена ENS, предоставленные пользователями, или собственные домены, если у пользователя нет имени ENS.
+
+Вы можете получить доступ к [приложению Enscribe](https://app.enscribe.xyz), чтобы начать присваивать имена и просматривать умные контракты.
+
+## Лучшие практики {#best-practices}
+
+- **Используйте четкие, версионированные имена**, такие как `v1.myapp.eth`, чтобы сделать обновления контрактов прозрачными
+- **Устанавливайте обратные записи**, чтобы связать контракты с именами ENS для видимости в таких приложениях, как кошельки и обозреватели блокчейна.
+- **Внимательно следите за сроками действия**, если хотите предотвратить случайную смену владельца
+- **Проверяйте источник контракта**, чтобы пользователи могли доверять, что именованный контракт ведет себя так, как ожидалось
+
+## Риски {#risks}
+
+Присвоение имен умным контрактам дает значительные преимущества пользователям Ethereum, однако владельцы доменов ENS должны быть бдительны в отношении их управления. Заметные риски включают:
+
+- **Истечение срока действия**: так же, как и имена DNS, регистрация имен ENS имеет конечный срок действия. Поэтому жизненно важно, чтобы владельцы отслеживали сроки действия своих доменов и продлевали их заблаговременно до истечения срока. Как приложение ENS, так и Enscribe предоставляют визуальные индикаторы для владельцев доменов при приближении срока истечения.
+- **Смена владельца**: записи ENS представлены в виде NFT в Ethereum, где владелец определенного домена `.eth` владеет соответствующим NFT. Следовательно, если другой аккаунт завладеет этим NFT, новый владелец сможет изменять любые записи ENS по своему усмотрению.
+
+Для снижения таких рисков аккаунт владельца доменов второго уровня (2LD) `.eth` должен быть защищен с помощью кошелька с мультиподписью, а для управления именами контрактов должны создаваться субдомены. Таким образом, в случае любых случайных или злонамеренных изменений в праве собственности на уровне субдомена, они могут быть отменены владельцем 2LD.
+
+## Будущее присвоения имен контрактам {#future}
+
+Присвоение имен контрактам становится лучшей практикой для разработки децентрализованных приложений, подобно тому, как доменные имена заменили IP-адреса в Интернете. По мере того, как все больше инфраструктурных элементов, таких как кошельки, обозреватели и панели мониторинга, интегрируют разрешение ENS для контрактов, именованные контракты повысят безопасность и уменьшат количество ошибок во всей экосистеме.
+
+Делая умные контракты более легкими для распознавания и понимания, присвоение имен помогает сократить разрыв между пользователями и приложениями на Ethereum, улучшая как безопасность, так и UX для пользователей.
+
+## Дополнительные материалы {#further-reading}
+
+- [Присвоение имен умным контрактам с помощью ENS](https://docs.ens.domains/web/naming-contracts/)
+- [Присвоение имен умным контрактам с помощью Enscribe](https://www.enscribe.xyz/docs).
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/security/index.md b/public/content/translations/ru/developers/docs/smart-contracts/security/index.md
new file mode 100644
index 00000000000..0ad475b4d1d
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/security/index.md
@@ -0,0 +1,576 @@
+---
+title: "Безопасность умных контрактов"
+description: "Обзор руководящих принципов по созданию безопасных смарт-контрактов с помощью технологии Ethereum"
+lang: ru
+---
+
+Умные контракты чрезвычайно гибки и способны контролировать большие объемы ценностей и данных, выполняя при этом неизменяемую логику на основе кода, развернутого в блокчейне. Это привело к созданию активной экосистемы децентрализованных приложений, не требующих доверия, которые предоставляют множество преимуществ по сравнению с устаревшими системами. Они также предоставляют возможности для атакующих, которые хотят получить прибыль, используя уязвимости в умных контрактах.
+
+Публичные блокчейны, такие как Ethereum, еще больше усложняют задачу обеспечения безопасности умных контрактов. Развернутый код контракта _обычно_ не может быть изменен для исправления недостатков безопасности, в то время как активы, украденные из умных контрактов, чрезвычайно трудно отследить и в основном невозможно восстановить из-за их неизменности.
+
+Хотя цифры разнятся, по оценкам, общая сумма украденных или потерянных ценностей из-за дефектов безопасности в умных контрактах легко превышает 1 миллиард долларов. Сюда входят громкие инциденты, такие как [взлом DAO](https://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/) (украдено 3,6 млн ETH, что по сегодняшним ценам составляет более 1 млрд долларов), [взлом кошелька с мультиподписью Parity](https://www.coindesk.com/markets/2017/07/19/30-million-ether-reported-stolen-due-to-parity-wallet-breach) (хакеры похитили 30 млн долларов) и [проблема с замороженным кошельком Parity](https://www.theguardian.com/technology/2017/nov/08/cryptocurrency-300m-dollars-stolen-bug-ether) (более 300 млн долларов в ETH заблокированы навсегда).
+
+Вышеупомянутые проблемы обязывают разработчиков прикладывать усилия для создания безопасных, надежных и отказоустойчивых умных контрактов. Безопасность умных контрактов — это серьезное дело, и каждому разработчику будет полезно его изучить. В этом руководстве будут рассмотрены аспекты безопасности для разработчиков Ethereum и изучены ресурсы для повышения безопасности умных контрактов.
+
+## Предварительные условия {#prerequisites}
+
+Прежде чем приступать к изучению вопросов безопасности, убедитесь, что вы знакомы с [основами разработки умных контрактов](/developers/docs/smart-contracts/).
+
+## Руководство по созданию безопасных умных контрактов Ethereum {#smart-contract-security-guidelines}
+
+### 1. Разработка надлежащих средств контроля доступа {#design-proper-access-controls}
+
+В умных контрактах функции, помеченные как `public` или `external`, могут вызываться любыми внешними аккаунтами (EOA) или аккаунтами контрактов. Указание публичной видимости для функций необходимо, если вы хотите, чтобы другие могли взаимодействовать с вашим контрактом. Однако функции, помеченные как `private`, могут вызываться только функциями внутри умного контракта, а не внешними аккаунтами. Предоставление каждому участнику сети доступа к функциям контракта может вызвать проблемы, особенно если это означает, что кто угодно может выполнять конфиденциальные операции (например, чеканку новых токенов).
+
+Чтобы предотвратить несанкционированное использование функций умного контракта, необходимо внедрить безопасные средства контроля доступа. Механизмы контроля доступа ограничивают возможность использования определенных функций в умном контракте только для утвержденных субъектов, таких как аккаунты, ответственные за управление контрактом. Патерн **Ownable** и **управление на основе ролей** — это два полезных патерна для реализации контроля доступа в умных контрактах:
+
+#### Патерн Ownable {#ownable-pattern}
+
+В патерне Ownable во время создания контракта один адрес назначается его «владельцем». Защищенным функциям присваивается модификатор `OnlyOwner`, который гарантирует, что контракт аутентифицирует личность вызывающего адреса перед выполнением функции. Вызовы защищенных функций с адресов, отличных от адреса владельца контракта, всегда отменяются, что предотвращает нежелательный доступ.
+
+#### Управление доступом на основе ролей {#role-based-access-control}
+
+Регистрация одного адреса в качестве `Owner` (владельца) в умном контракте создает риск централизации и представляет собой единую точку отказа. Если ключи аккаунта владельца будут скомпрометированы, атакующие смогут атаковать принадлежащий ему контракт. Вот почему использование патерна управления доступом на основе ролей с несколькими административными аккаунтами может быть лучшим вариантом.
+
+При управлении доступом на основе ролей доступ к конфиденциальным функциям распределяется между набором доверенных участников. Например, один аккаунт может отвечать за чеканку токенов, а другой — за выполнение обновлений или приостановку контракта. Такая децентрализация контроля доступа устраняет единые точки отказа и снижает требования к доверию для пользователей.
+
+##### Использование кошельков с мультиподписью
+
+Другой подход к реализации безопасного контроля доступа — использование [аккаунта с мультиподписью](/developers/docs/smart-contracts/#multisig) для управления контрактом. В отличие от обычного EOA, аккаунты с мультиподписью принадлежат нескольким субъектам и требуют для выполнения транзакций подписи от минимального числа аккаунтов, например, 3 из 5.
+
+Использование мультиподписи для контроля доступа добавляет дополнительный уровень безопасности, поскольку действия с целевым контрактом требуют согласия нескольких сторон. Это особенно полезно, если необходимо использовать патерн Ownable, поскольку это затрудняет для атакующего или недобросовестного инсайдера манипулирование конфиденциальными функциями контракта в злонамеренных целях.
+
+### 2. Используйте операторы require(), assert() и revert() для защиты операций контракта {#use-require-assert-revert}
+
+Как уже упоминалось, любой может вызывать публичные функции в вашем умном контракте после его развертывания в блокчейне. Поскольку вы не можете заранее знать, как внешние аккаунты будут взаимодействовать с контрактом, перед развертыванием идеально реализовать внутренние меры защиты от проблемных операций. Вы можете обеспечить правильное поведение в умных контрактах, используя операторы `require()`, `assert()` и `revert()` для вызова исключений и отмены изменений состояния, если выполнение не удовлетворяет определенным требованиям.
+
+**`require()`**: `require` определяется в начале функций и гарантирует, что предварительно определенные условия выполнены до того, как будет выполнена вызываемая функция. Оператор `require` может использоваться для проверки вводимых пользователем данных, проверки переменных состояния или аутентификации личности вызывающего аккаунта перед продолжением выполнения функции.
+
+**`assert()`**: `assert()` используется для обнаружения внутренних ошибок и проверки нарушений «инвариантов» в вашем коде. Инвариант — это логическое утверждение о состоянии контракта, которое должно оставаться истинным для всех выполнений функций. Инвариантным примером является максимальное общее предложение или баланс токенового контракта. Использование `assert()` гарантирует, что ваш контракт никогда не перейдет в уязвимое состояние, а если это произойдет, все изменения переменных состояния будут отменены.
+
+**`revert()`**: `revert()` может использоваться в операторе if-else, который вызывает исключение, если требуемое условие не выполняется. В приведенном ниже примере контракта для защиты выполнения функций используется `revert()`:
+
+```
+pragma solidity ^0.8.4;
+
+contract VendingMachine {
+ address owner;
+ error Unauthorized();
+ function buy(uint amount) public payable {
+ if (amount > msg.value / 2 ether)
+ revert("Предоставлено недостаточно Ether.");
+ // Выполнение покупки.
+ }
+ function withdraw() public {
+ if (msg.sender != owner)
+ revert Unauthorized();
+
+ payable(msg.sender).transfer(address(this).balance);
+ }
+}
+```
+
+### 3. Тестируйте умные контракты и проверяйте правильность кода {#test-smart-contracts-and-verify-code-correctness}
+
+Неизменность кода, работающего в [виртуальной машине Ethereum](/developers/docs/evm/), означает, что умные контракты требуют более высокого уровня оценки качества на этапе разработки. Тщательное тестирование вашего контракта и отслеживание любых непредвиденных результатов значительно повысит безопасность и защитит ваших пользователей в долгосрочной перспективе.
+
+Обычный метод — это написание небольших модульных тестов с использованием фиктивных данных, которые контракт, как ожидается, будет получать от пользователей. [Модульное тестирование](/developers/docs/smart-contracts/testing/#unit-testing) хорошо подходит для тестирования функциональности определенных функций и обеспечения того, чтобы умный контракт работал так, как ожидается.
+
+К сожалению, модульное тестирование минимально эффективно для повышения безопасности умных контрактов при его изолированном использовании. Модульный тест может доказать, что функция выполняется правильно для фиктивных данных, но модульные тесты эффективны лишь настолько, насколько эффективны написанные тесты. Это затрудняет обнаружение пропущенных пограничных случаев и уязвимостей, которые могут нарушить безопасность вашего умного контракта.
+
+Лучший подход — это сочетание модульного тестирования с тестированием на основе свойств, выполняемым с использованием [статического и динамического анализа](/developers/docs/smart-contracts/testing/#static-dynamic-analysis). Статический анализ опирается на низкоуровневые представления, такие как [графы потоков управления](https://en.wikipedia.org/wiki/Control-flow_graph) и [абстрактные синтаксические деревья](https://deepsource.io/glossary/ast/), для анализа достижимых состояний программы и путей выполнения. В то же время методы динамического анализа, такие как [фаззинг умных контрактов](https://www.cyfrin.io/blog/smart-contract-fuzzing-and-invariants-testing-foundry), выполняют код контракта со случайными входными значениями для обнаружения операций, нарушающих свойства безопасности.
+
+[Формальная верификация](/developers/docs/smart-contracts/formal-verification) — это еще один метод проверки свойств безопасности в умных контрактах. В отличие от обычного тестирования, формальная верификация может убедительно доказать отсутствие ошибок в умном контракте. Это достигается путем создания формальной спецификации, которая отражает желаемые свойства безопасности, и доказательства того, что формальная модель контрактов соответствует этой спецификации.
+
+### 4. Запросите независимую проверку вашего кода {#get-independent-code-reviews}
+
+После того как Вы протестировали ваш контракт, хорошей идеей будет попросить других проверить исходный код на наличие проблем с безопасностью. Тестирование не сможет выявить все возможные недостатки смарт-контракта, но независимый аудит повышает вероятность того, что уязвимости будут обнаружены.
+
+#### Аудиты {#audits}
+
+Заказ аудита умного контракта — это один из способов проведения независимой проверки кода. Аудиторы играют важную роль в обеспечении безопасности умных контрактов и отсутствия в них дефектов качества и ошибок проектирования.
+
+Тем не менее, не следует относиться к аудитам как к панацее. Аудиты умных контрактов не выявляют все ошибки и в основном предназначены для проведения дополнительного раунда проверок, который может помочь обнаружить проблемы, пропущенные разработчиками на начальных этапах разработки и тестирования. Вы также должны следовать лучшим практикам работы с аудиторами, таким как правильное документирование кода и добавление встроенных комментариев, чтобы извлечь максимальную пользу из аудита умного контракта.
+
+- [Советы и хитрости по аудиту умных контрактов](https://twitter.com/tinchoabbate/status/1400170232904400897) — _@tinchoabbate_
+- [Получите максимум от вашего аудита](https://inference.ag/blog/2023-08-14-tips/) — _Inference_
+
+#### Вознаграждения за обнаружение ошибок {#bug-bounties}
+
+Вознаграждения за обнаружение уязвимостей — ещё один способ проведения независимого аудита. Премией за обнаружение уязвимостей награждаются люди (обычно этические хакеры, или «белые шляпы»), которые находят уязвимости в приложениях.
+
+При верном использовании, такие вознаграждения мотивируют членов хакерского сообщества проверить ваш код на уязвимости. Реальным примером является «ошибка бесконечных денег», которая позволила бы атакующему создать неограниченное количество эфира на [Optimism](https://www.optimism.io/), протоколе [Леер 2](/layer-2/), работающем на Ethereum. К счастью, «белый» хакер [обнаружил уязвимость](https://www.saurik.com/optimism.html) и уведомил команду, [заработав при этом крупное вознаграждение](https://cryptoslate.com/critical-bug-in-ethereum-l2-optimism-2m-bounty-paid/).
+
+Хорошая стратегия — установить размер выплат по программе bug bounty пропорционально сумме средств, за которую вы отвечаете. Этот подход, названный «[масштабируемая программа вознаграждения за обнаружение ошибок](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7)», предоставляет финансовые стимулы для ответственного раскрытия уязвимостей вместо их эксплуатации.
+
+### 5. Следуйте лучшим практикам при разработке умных контрактов {#follow-smart-contract-development-best-practices}
+
+Наличие аудитов и программ вознаграждения за обнаружение ошибок не освобождает вас от ответственности писать высококачественный код. Хорошая безопасность умных контрактов начинается с соблюдения надлежащих процессов проектирования и разработки:
+
+- Храните весь код в системе контроля версий, такой как git
+
+- Вносите все изменения в код через запросы на слияние
+
+- Убедитесь, что запросы на слияние имеют хотя бы одного независимого рецензента — если вы работаете над проектом в одиночку, рассмотрите возможность найти других разработчиков и обмениваться с ними проверками кода
+
+- Используйте [среду разработки](/developers/docs/frameworks/) для тестирования, компиляции и развертывания умных контрактов
+
+- Прогоняйте свой код через базовые инструменты анализа кода, такие как [Cyfrin Aderyn](https://github.com/Cyfrin/aderyn), Mythril и Slither. В идеале это следует делать перед слиянием каждого запроса на слияние и сравнивать различия в результатах
+
+- Убедитесь, что ваш код компилируется без ошибок и компилятор Solidity не выдает предупреждений
+
+- Правильно документируйте свой код (используя [NatSpec](https://solidity.readthedocs.io/en/develop/natspec-format.html)) и описывайте детали архитектуры контракта на понятном языке. Это облегчит аудит и проверку вашего кода другими людьми.
+
+### 6. Внедряйте надежные планы аварийного восстановления {#implement-disaster-recovery-plans}
+
+Разработка безопасных средств контроля доступа, реализация модификаторов функций и другие предложения могут улучшить безопасность умных контрактов, но они не могут исключить возможность злонамеренных эксплойтов. Создание безопасных умных контрактов требует «подготовки к сбоям» и наличия запасного плана для эффективного реагирования на атаки. Надлежащий план аварийного восстановления будет включать некоторые или все из следующих компонентов:
+
+#### Обновления контрактов {#contract-upgrades}
+
+Хотя умные контракты Ethereum по умолчанию неизменяемы, можно достичь некоторой степени изменяемости, используя патерны обновления. Обновление контрактов необходимо в тех случаях, когда критическая уязвимость делает ваш старый контракт непригодным для использования, и развертывание новой логики является наиболее целесообразным вариантом.
+
+Механизмы обновления контрактов работают по-разному, но «патерн прокси» является одним из наиболее популярных подходов к обновлению умных контрактов. [Патерны прокси](https://www.cyfrin.io/blog/upgradeable-proxy-smart-contract-pattern) разделяют состояние и логику приложения между _двумя_ контрактами. Первый контракт (называемый «прокси-контракт») хранит переменные состояния (например, балансы пользователей), в то время как второй контракт (называемый «логический контракт») содержит код для выполнения функций контракта.
+
+Аккаунты взаимодействуют с прокси-контрактом, который перенаправляет все вызовы функций логическому контракту с помощью низкоуровневого вызова [`delegatecall()`](https://docs.soliditylang.org/en/v0.8.16/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries). В отличие от обычного вызова сообщения, `delegatecall()` гарантирует, что код, работающий по адресу логического контракта, выполняется в контексте вызывающего контракта. Это означает, что логический контракт всегда будет записывать данные в хранилище прокси-контракта (а не в свое собственное хранилище), а исходные значения `msg.sender` и `msg.value` сохраняются.
+
+Делегирование вызовов логическому контракту требует хранения его адреса в хранилище прокси-контракта. Следовательно, обновление логики контракта — это всего лишь вопрос развертывания другого логического контракта и сохранения нового адреса в прокси-контракте. Поскольку последующие вызовы прокси-контракта автоматически направляются на новый логический контракт, вы «обновите» контракт, фактически не изменяя код.
+
+[Подробнее об обновлении контрактов](/developers/docs/smart-contracts/upgrading/).
+
+#### Аварийные остановки {#emergency-stops}
+
+Как уже упоминалось, обширный аудит и тестирование не могут выявить все ошибки в умном контракте. Если после развертывания в вашем коде появляется уязвимость, исправить ее невозможно, поскольку вы не можете изменить код, работающий по адресу контракта. Кроме того, внедрение механизмов обновления (например, патернов прокси) может занять время (они часто требуют одобрения от разных сторон), что только дает атакующим больше времени для нанесения большего ущерба.
+
+Кардинальным решением является реализация функции «аварийной остановки», которая блокирует вызовы уязвимых функций в контракте. Аварийные остановки обычно включают следующие компоненты:
+
+1. Глобальная логическая переменная, указывающая, находится ли умный контракт в остановленном состоянии или нет. Эта переменная устанавливается в значение `false` при настройке контракта, но изменится на `true` после остановки контракта.
+
+2. Функции, которые ссылаются на логическую переменную при своем выполнении. Такие функции доступны, когда умный контракт не остановлен, и становятся недоступными при срабатывании функции аварийной остановки.
+
+3. Сущность, имеющая доступ к функции аварийной остановки, которая устанавливает логическую переменную в значение `true`. Для предотвращения злонамеренных действий вызовы этой функции могут быть ограничены доверенным адресом (например, владельцем контракта).
+
+После того, как контракт активирует аварийную остановку, определенные функции станут недоступными для вызова. Это достигается путем обертывания избранных функций в модификатор, который ссылается на глобальную переменную. Ниже приведен [пример](https://github.com/fravoll/solidity-patterns/blob/master/EmergencyStop/EmergencyStop.sol), описывающий реализацию этого патерна в контрактах:
+
+```solidity
+// Этот код не прошел профессиональный аудит и не дает никаких гарантий безопасности или корректности. Используйте на свой страх и риск.
+
+contract EmergencyStop {
+
+ bool isStopped = false;
+
+ modifier stoppedInEmergency {
+ require(!isStopped);
+ _;
+ }
+
+ modifier onlyWhenStopped {
+ require(isStopped);
+ _;
+ }
+
+ modifier onlyAuthorized {
+ // Здесь проверьте авторизацию msg.sender
+ _;
+ }
+
+ function stopContract() public onlyAuthorized {
+ isStopped = true;
+ }
+
+ function resumeContract() public onlyAuthorized {
+ isStopped = false;
+ }
+
+ function deposit() public payable stoppedInEmergency {
+ // Здесь происходит логика депозита
+ }
+
+ function emergencyWithdraw() public onlyWhenStopped {
+ // Здесь происходит экстренный вывод средств
+ }
+}
+```
+
+Этот пример показывает основные особенности аварийных остановок:
+
+- `isStopped` — это логическая переменная, которая в начале имеет значение `false`, а когда контракт переходит в аварийный режим, — `true`.
+
+- Модификаторы функций `onlyWhenStopped` и `stoppedInEmergency` проверяют переменную `isStopped`. `stoppedInEmergency` используется для управления функциями, которые должны быть недоступны, когда контракт уязвим (например, `deposit()`). Вызовы этих функций будут просто отменены.
+
+`onlyWhenStopped` используется для функций, которые должны быть доступны для вызова во время чрезвычайной ситуации (например, `emergencyWithdraw()`). Такие функции могут помочь разрешить ситуацию, поэтому они исключены из списка «ограниченных функций».
+
+Использование функциональности аварийной остановки обеспечивает эффективное временное решение для борьбы с серьезными уязвимостями в вашем умном контракте. Однако это увеличивает потребность пользователей доверять разработчикам, чтобы те не активировали ее в корыстных целях. Для этого возможными решениями являются децентрализация контроля над аварийной остановкой либо путем подчинения ее механизму ончейн-голосования, временной блокировке, либо одобрению с помощью кошелька с мультиподписью.
+
+#### Мониторинг событий {#event-monitoring}
+
+[События](https://docs.soliditylang.org/en/v0.8.15/contracts.html#events) позволяют отслеживать вызовы функций умного контракта и контролировать изменения переменных состояния. Идеально запрограммировать ваш умный контракт так, чтобы он генерировал событие всякий раз, когда какая-либо сторона предпринимает критически важное для безопасности действие (например, вывод средств).
+
+Регистрация событий и их мониторинг вне сети (оффчейн) дают представление об операциях контракта и способствуют более быстрому обнаружению злонамеренных действий. Это означает, что ваша команда может быстрее реагировать на взломы и принимать меры для смягчения последствий для пользователей, такие как приостановка функций или выполнение обновления.
+
+Вы также можете выбрать готовый инструмент мониторинга, который автоматически пересылает оповещения всякий раз, когда кто-то взаимодействует с вашими контрактами. Эти инструменты позволят вам создавать настраиваемые оповещения на основе различных триггеров, таких как объем транзакций, частота вызовов функций или конкретные задействованные функции. Например, вы можете запрограммировать оповещение, которое приходит, когда сумма, выведенная в одной транзакции, превышает определенный порог.
+
+### 7. Проектирование безопасных систем управления {#design-secure-governance-systems}
+
+Вы можете захотеть децентрализовать свое приложение, передав контроль над основными умными контрактами членам сообщества. В этом случае система умных контрактов будет включать модуль управления — механизм, который позволяет членам сообщества одобрять административные действия через ончейн-систему управления. Например, предложение обновить прокси-контракт до новой реализации может быть вынесено на голосование держателей токенов.
+
+Децентрализованное управление может быть полезным, особенно потому, что оно согласовывает интересы разработчиков и конечных пользователей. Тем не менее, механизмы управления умными контрактами могут создавать новые риски при неправильной реализации. Возможный сценарий — если атакующий приобретает огромную голосующую силу (измеряемую в количестве имеющихся токенов), взяв [срочный заем](/defi/#flash-loans), и проталкивает вредоносное предложение.
+
+Один из способов предотвращения проблем, связанных с ончейн-управлением, — [использование временной блокировки](https://blog.openzeppelin.com/protect-your-users-with-smart-contract-timelocks/). Временная блокировка не позволяет умному контракту выполнять определенные действия до истечения определенного времени. Другие стратегии включают присвоение «веса голоса» каждому токену в зависимости от того, как долго он был заблокирован, или измерение голосующей силы адреса в исторический период (например, 2-3 блока в прошлом) вместо текущего блока. Оба метода снижают вероятность быстрого накопления голосующей силы для влияния на результаты ончейн-голосований.
+
+Подробнее о [проектировании безопасных систем управления](https://blog.openzeppelin.com/smart-contract-security-guidelines-4-strategies-for-safer-governance-systems/), [различных механизмах голосования в DAO](https://hackernoon.com/governance-is-the-holy-grail-for-daos) и [распространенных векторах атак на DAO с использованием DeFi](https://dacian.me/dao-governance-defi-attacks) по приведенным ссылкам.
+
+### 8. Сведите сложность кода к минимуму {#reduce-code-complexity}
+
+Традиционные разработчики программного обеспечения знакомы с принципом KISS («делай проще, дурак»), который советует избегать ненужной сложности в проектировании программного обеспечения. Это следует из давнего убеждения, что «сложные системы дают сбой сложными способами» и более подвержены дорогостоящим ошибкам.
+
+Простота особенно важна при написании умных контрактов, учитывая, что они потенциально контролируют большие объемы ценностей. Совет по достижению простоты при написании умных контрактов — по возможности повторно использовать существующие библиотеки, такие как [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts/5.x/). Поскольку эти библиотеки были тщательно проверены и протестированы разработчиками, их использование снижает вероятность появления ошибок при написании новой функциональности с нуля.
+
+Еще один распространенный совет — писать небольшие функции и сохранять модульность контрактов, разделяя бизнес-логику между несколькими контрактами. Написание более простого кода не только уменьшает поверхность атаки в умном контракте, но и облегчает рассуждения о корректности всей системы и раннее обнаружение возможных ошибок проектирования.
+
+### 9. Защита от распространенных уязвимостей умных контрактов {#mitigate-common-smart-contract-vulnerabilities}
+
+#### Повторный вход {#reentrancy}
+
+EVM не допускает параллелизма, то есть два контракта, участвующие в вызове сообщения, не могут выполняться одновременно. Внешний вызов приостанавливает выполнение вызывающего контракта и его память до тех пор, пока вызов не вернется, после чего выполнение продолжается в обычном режиме. Этот процесс можно формально описать как передачу [потока управления](https://www.computerhope.com/jargon/c/contflow.htm) другому контракту.
+
+Хотя в основном это безвредно, передача потока управления ненадежным контрактам может вызвать проблемы, такие как повторный вход. Атака повторного входа происходит, когда вредоносный контракт вызывает уязвимый контракт до того, как завершится первоначальный вызов функции. Этот тип атаки лучше всего объяснить на примере.
+
+Рассмотрим простой умный контракт («Victim»), который позволяет любому вносить и выводить эфир:
+
+```solidity
+// Этот контракт уязвим. Не используйте в продакшене
+
+contract Victim {
+ mapping (address => uint256) public balances;
+
+ function deposit() external payable {
+ balances[msg.sender] += msg.value;
+ }
+
+ function withdraw() external {
+ uint256 amount = balances[msg.sender];
+ (bool success, ) = msg.sender.call.value(amount)("");
+ require(success);
+ balances[msg.sender] = 0;
+ }
+}
+```
+
+Этот контракт предоставляет функцию `withdraw()`, позволяющую пользователям выводить ETH, ранее внесенные в контракт. При обработке вывода средств контракт выполняет следующие операции:
+
+1. Проверяет баланс ETH пользователя
+2. Отправляет средства на вызывающий адрес
+3. Сбрасывает их баланс до 0, предотвращая дальнейшие выводы средств пользователем
+
+Функция `withdraw()` в контракте `Victim` следует патерну «проверки-взаимодействия-эффекты». Она _проверяет_, выполнены ли условия, необходимые для выполнения (т. е. у пользователя положительный баланс ETH), и выполняет _взаимодействие_, отправляя ETH на адрес вызывающего, прежде чем применить _эффекты_ транзакции (т. е. уменьшить баланс пользователя).
+
+Если `withdraw()` вызывается из внешнего аккаунта (EOA), функция выполняется, как и ожидалось: `msg.sender.call.value()` отправляет ETH вызывающему. Однако, если `msg.sender` является аккаунтом умного контракта и вызывает `withdraw()`, отправка средств с помощью `msg.sender.call.value()` также вызовет запуск кода, хранящегося по этому адресу.
+
+Представьте, что по адресу контракта развернут следующий код:
+
+```solidity
+ contract Attacker {
+ function beginAttack() external payable {
+ Victim(victim_address).deposit.value(1 ether)();
+ Victim(victim_address).withdraw();
+ }
+
+ function() external payable {
+ if (gasleft() > 40000) {
+ Victim(victim_address).withdraw();
+ }
+ }
+}
+```
+
+Этот контракт предназначен для выполнения трех действий:
+
+1. Принять депозит с другого аккаунта (вероятно, EOA атакующего)
+2. Внести 1 ETH в контракт Victim
+3. Вывести 1 ETH, хранящийся в умном контракте
+
+Здесь нет ничего плохого, за исключением того, что у `Attacker` есть еще одна функция, которая снова вызывает `withdraw()` в `Victim`, если оставшегося газа от входящего `msg.sender.call.value` больше 40 000. Это дает `Attacker` возможность повторно войти в `Victim` и вывести больше средств _до_ завершения первого вызова `withdraw`. Цикл выглядит следующим образом:
+
+```solidity
+- EOA атакующего вызывает `Attacker.beginAttack()` с 1 ETH
+- `Attacker.beginAttack()` вносит 1 ETH в `Victim`
+- `Attacker` вызывает `withdraw()` в `Victim`
+- `Victim` проверяет баланс `Attacker` (1 ETH)
+- `Victim` отправляет 1 ETH в `Attacker` (что вызывает функцию по умолчанию)
+- `Attacker` снова вызывает `Victim.withdraw()` (обратите внимание, что `Victim` не уменьшил баланс `Attacker` после первого вывода средств)
+- `Victim` проверяет баланс `Attacker` (который все еще составляет 1 ETH, потому что он не применил эффекты первого вызова)
+- `Victim` отправляет 1 ETH в `Attacker` (что вызывает функцию по умолчанию и позволяет `Attacker` повторно войти в функцию `withdraw`)
+- Процесс повторяется до тех пор, пока у `Attacker` не закончится газ, после чего `msg.sender.call.value` возвращается, не вызывая дополнительных выводов средств
+- `Victim` наконец применяет результаты первой транзакции (и последующих) к своему состоянию, поэтому баланс `Attacker` устанавливается в 0
+```
+
+Суть в том, что, поскольку баланс вызывающего не устанавливается в 0 до завершения выполнения функции, последующие вызовы будут успешными и позволят вызывающему вывести свой баланс несколько раз. Такой тип атаки может быть использован для опустошения умного контракта, как это произошло во время [взлома DAO в 2016 году](https://www.coindesk.com/learn/understanding-the-dao-attack). Атаки повторного входа до сих пор остаются критической проблемой для умных контрактов, как показывают [публичные списки эксплойтов повторного входа](https://github.com/pcaversaccio/reentrancy-attacks).
+
+##### Как предотвратить атаки повторного входа
+
+Один из подходов к борьбе с повторным входом — следование [патерну «проверки-эффекты-взаимодействия»](https://docs.soliditylang.org/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern). Этот патерн упорядочивает выполнение функций таким образом, что код, выполняющий необходимые проверки перед продолжением выполнения, идет первым, за ним следует код, который манипулирует состоянием контракта, а код, взаимодействующий с другими контрактами или EOA, идет последним.
+
+Патерн «проверки-эффект-взаимодействие» используется в исправленной версии контракта `Victim`, показанной ниже:
+
+```solidity
+contract NoLongerAVictim {
+ function withdraw() external {
+ uint256 amount = balances[msg.sender];
+ balances[msg.sender] = 0;
+ (bool success, ) = msg.sender.call.value(amount)("");
+ require(success);
+ }
+}
+```
+
+Этот контракт выполняет _проверку_ баланса пользователя, применяет _эффекты_ функции `withdraw()` (сбрасывая баланс пользователя до 0) и переходит к _взаимодействию_ (отправке ETH на адрес пользователя). Это гарантирует, что контракт обновит свое хранилище до внешнего вызова, устраняя условие повторного входа, которое сделало возможной первую атаку. Контракт `Attacker` все еще мог бы вызвать `NoLongerAVictim`, но поскольку `balances[msg.sender]` был установлен в 0, дополнительные выводы средств вызовут ошибку.
+
+Другой вариант — использовать блокировку взаимного исключения (обычно описываемую как «мьютекс»), которая блокирует часть состояния контракта до завершения вызова функции. Это реализуется с помощью логической переменной, которая устанавливается в `true` перед выполнением функции и возвращается в `false` после завершения вызова. Как видно из примера ниже, использование мьютекса защищает функцию от рекурсивных вызовов во время обработки исходного вызова, эффективно останавливая повторный вход.
+
+```solidity
+pragma solidity ^0.7.0;
+
+contract MutexPattern {
+ bool locked = false;
+ mapping(address => uint256) public balances;
+
+ modifier noReentrancy() {
+ require(!locked, "Заблокировано от повторного входа.");
+ locked = true;
+ _;
+ locked = false;
+ }
+ // Эта функция защищена мьютексом, поэтому повторные вызовы из `msg.sender.call` не могут снова вызвать `withdraw`.
+ // Оператор `return` возвращает `true`, но все равно выполняет оператор `locked = false` в модификаторе
+ function withdraw(uint _amount) public payable noReentrancy returns(bool) {
+ require(balances[msg.sender] >= _amount, "Нет баланса для вывода.");
+
+ balances[msg.sender] -= _amount;
+ (bool success, ) = msg.sender.call{value: _amount}("");
+ require(success);
+
+ return true;
+ }
+}
+```
+
+Вы также можете использовать систему [pull payments](https://docs.openzeppelin.com/contracts/5.x/api/security#PullPayment), которая требует от пользователей вывода средств из умных контрактов, вместо системы «push payments», которая отправляет средства на аккаунты. Это исключает возможность непреднамеренного запуска кода по неизвестным адресам (а также может предотвратить некоторые атаки типа «отказ в обслуживании»).
+
+#### Целочисленные недополнения и переполнения {#integer-underflows-and-overflows}
+
+Целочисленное переполнение происходит, когда результат арифметической операции выходит за пределы допустимого диапазона значений, что приводит к его «перебросу» на наименьшее представимое значение. Например, `uint8` может хранить значения только до 2^8-1=255. Арифметические операции, которые приводят к значениям выше `255`, переполнятся и сбросят `uint` до `0`, подобно тому, как одометр на автомобиле сбрасывается до 0, как только он достигает максимального пробега (999999).
+
+Целочисленные недополнения происходят по схожим причинам: результат арифметической операции оказывается ниже допустимого диапазона. Допустим, вы попытались уменьшить `0` в `uint8`, результат просто перескочит на максимальное представимое значение (`255`).
+
+Как целочисленные переполнения, так и недополнения могут привести к неожиданным изменениям переменных состояния контракта и привести к незапланированному выполнению. Ниже приведен пример, показывающий, как атакующий может использовать арифметическое переполнение в умном контракте для выполнения недействительной операции:
+
+```
+pragma solidity ^0.7.6;
+
+// Этот контракт предназначен для использования в качестве хранилища с временной блокировкой.
+// Пользователь может вносить средства в этот контракт, но не может выводить их в течение как минимум недели.
+// Пользователь также может продлить время ожидания сверх 1-недельного периода.
+
+/*
+1. Разверните TimeLock
+2. Разверните Attack с адресом TimeLock
+3. Вызовите Attack.attack, отправив 1 эфир. Вы сразу сможете
+ вывести свой эфир.
+
+Что произошло?
+Атака вызвала переполнение TimeLock.lockTime, что позволило вывести средства
+до истечения 1-недельного периода ожидания.
+*/
+
+contract TimeLock {
+ mapping(address => uint) public balances;
+ mapping(address => uint) public lockTime;
+
+ function deposit() external payable {
+ balances[msg.sender] += msg.value;
+ lockTime[msg.sender] = block.timestamp + 1 weeks;
+ }
+
+ function increaseLockTime(uint _secondsToIncrease) public {
+ lockTime[msg.sender] += _secondsToIncrease;
+ }
+
+ function withdraw() public {
+ require(balances[msg.sender] > 0, "Недостаточно средств");
+ require(block.timestamp > lockTime[msg.sender], "Время блокировки не истекло");
+
+ uint amount = balances[msg.sender];
+ balances[msg.sender] = 0;
+
+ (bool sent, ) = msg.sender.call{value: amount}("");
+ require(sent, "Не удалось отправить Ether");
+ }
+}
+
+contract Attack {
+ TimeLock timeLock;
+
+ constructor(TimeLock _timeLock) {
+ timeLock = TimeLock(_timeLock);
+ }
+
+ fallback() external payable {}
+
+ function attack() public payable {
+ timeLock.deposit{value: msg.value}();
+ /*
+ если t = текущее время блокировки, то нам нужно найти x, такое что
+ x + t = 2**256 = 0
+ тогда x = -t
+ 2**256 = type(uint).max + 1
+ тогда x = type(uint).max + 1 - t
+ */
+ timeLock.increaseLockTime(
+ type(uint).max + 1 - timeLock.lockTime(address(this))
+ );
+ timeLock.withdraw();
+ }
+}
+```
+
+##### Как предотвратить целочисленные недополнения и переполнения
+
+Начиная с версии 0.8.0, компилятор Solidity отклоняет код, который приводит к целочисленным недополнениям и переполнениям. Однако контракты, скомпилированные с более низкой версией компилятора, должны либо выполнять проверки в функциях, включающих арифметические операции, либо использовать библиотеку (например, [SafeMath](https://docs.openzeppelin.com/contracts/2.x/api/math)), которая проверяет на недополнение/переполнение.
+
+#### Манипуляция оракулом {#oracle-manipulation}
+
+[Оракулы](/developers/docs/oracles/) получают информацию из оффчейн-источников и отправляют ее ончейн для использования умными контрактами. С помощью оракулов вы можете создавать умные контракты, которые взаимодействуют с оффчейн-системами, такими как рынки капитала, что значительно расширяет их применение.
+
+Но если оракул поврежден и отправляет неверную информацию ончейн, умные контракты будут выполняться на основе ошибочных данных, что может вызвать проблемы. В этом заключается основа «проблемы оракула», которая касается задачи обеспечения того, чтобы информация от блокчейн-оракула была точной, актуальной и своевременной.
+
+Связанная с этим проблема безопасности — использование ончейн-оракула, такого как децентрализованная биржа, для получения спотовой цены актива. Платформы кредитования в индустрии [децентрализованных финансов (DeFi)](/defi/) часто делают это для определения стоимости залога пользователя, чтобы определить, сколько он может занять.
+
+Цены на DEX часто точны, в основном благодаря арбитражерам, восстанавливающим паритет на рынках. Однако они подвержены манипуляциям, особенно если ончейн-оракул рассчитывает цены активов на основе исторических торговых патернов (как это обычно бывает).
+
+Например, атакующий может искусственно завысить спотовую цену актива, взяв срочный заем прямо перед взаимодействием с вашим кредитным контрактом. Запрос цены актива у DEX вернет значение выше нормального (из-за того, что крупный «ордер на покупку» атакующего исказил спрос на актив), что позволит ему занять больше, чем следовало бы. Такие «атаки со срочными займами» использовались для эксплуатации зависимости от ценовых оракулов среди приложений DeFi, что стоило протоколам миллионов потерянных средств.
+
+##### Как предотвратить манипуляции оракулом
+
+Минимальное требование для [избежания манипуляций с оракулом](https://www.cyfrin.io/blog/price-oracle-manipultion-attacks-with-examples) — использование децентрализованной сети оракулов, которая запрашивает информацию из нескольких источников, чтобы избежать единых точек отказа. В большинстве случаев децентрализованные оракулы имеют встроенные криптоэкономические стимулы для поощрения узлов оракула сообщать верную информацию, что делает их более безопасными, чем централизованные оракулы.
+
+Если вы планируете запрашивать цену актива у ончейн-оракула, рассмотрите возможность использования того, который реализует механизм средневзвешенной по времени цены (TWAP). [Оракул TWAP](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) запрашивает цену актива в два разных момента времени (которые вы можете изменять) и рассчитывает спотовую цену на основе полученного среднего значения. Выбор более длительных периодов времени защищает ваш протокол от манипулирования ценами, поскольку крупные ордера, выполненные недавно, не могут повлиять на цены активов.
+
+## Ресурсы по безопасности умных контрактов для разработчиков {#smart-contract-security-resources-for-developers}
+
+### Инструменты для анализа умных контрактов и проверки правильности кода {#code-analysis-tools}
+
+- **[Инструменты и библиотеки для тестирования](/developers/docs/smart-contracts/testing/#testing-tools-and-libraries)** — _Коллекция стандартных отраслевых инструментов и библиотек для выполнения модульных тестов, статического и динамического анализа умных контрактов._
+
+- **[Инструменты формальной верификации](/developers/docs/smart-contracts/formal-verification/#formal-verification-tools)** — _Инструменты для проверки функциональной корректности в умных контрактах и проверки инвариантов._
+
+- **[Сервисы аудита умных контрактов](/developers/docs/smart-contracts/testing/#smart-contract-auditing-services)** — _Список организаций, предоставляющих услуги по аудиту умных контрактов для проектов разработки на Ethereum._
+
+- **[Платформы вознаграждений за обнаружение ошибок](/developers/docs/smart-contracts/testing/#bug-bounty-platforms)** — _Платформы для координации программ вознаграждений за обнаружение ошибок и поощрения ответственного раскрытия критических уязвимостей в умных контрактах._
+
+- **[Fork Checker](https://forkchecker.hashex.org/)** — _бесплатный онлайн-инструмент для проверки всей доступной информации о форкнутом контракте._
+
+- **[ABI Encoder](https://abi.hashex.org/)** — _бесплатный онлайн-сервис для кодирования функций вашего контракта Solidity и аргументов конструктора._
+
+- **[Aderyn](https://github.com/Cyfrin/aderyn)** — статический анализатор Solidity, обходящий абстрактные синтаксические деревья (AST) для выявления предполагаемых уязвимостей и вывода проблем в удобном для восприятия формате Markdown.
+
+### Инструменты для мониторинга умных контрактов {#smart-contract-monitoring-tools}
+
+- **[Tenderly Real-Time Alerting](https://tenderly.co/monitoring)** — _инструмент для получения уведомлений в реальном времени о необычных или неожиданных событиях в ваших умных контрактах или кошельках._
+
+### Инструменты для безопасного администрирования умных контрактов {#smart-contract-administration-tools}
+
+- **[Safe](https://safe.global/)** — _кошелек на основе умного контракта, работающий на Ethereum, который требует одобрения транзакции минимальным количеством людей (M из N)._
+
+- **[OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts/5.x/)** — _библиотеки контрактов для реализации административных функций, включая владение контрактом, обновления, контроль доступа, управление, возможность приостановки и многое другое._
+
+### Сервисы аудита умных контрактов {#smart-contract-auditing-services}
+
+- **[ConsenSys Diligence](https://diligence.consensys.io/)** — _сервис аудита умных контрактов, помогающий проектам по всей экосистеме блокчейна убедиться, что их протоколы готовы к запуску и созданы для защиты пользователей._
+
+- **[CertiK](https://www.certik.com/)** — _фирма по безопасности блокчейна, пионер в использовании передовых технологий формальной верификации на умных контрактах и блокчейн-сетях._
+
+- **[Trail of Bits](https://www.trailofbits.com/)** — _компания по кибербезопасности, которая сочетает исследования в области безопасности с мышлением атакующего, чтобы снизить риски и укрепить код._
+
+- **[PeckShield](https://peckshield.com/)** — _компания по безопасности блокчейна, предлагающая продукты и услуги для обеспечения безопасности, конфиденциальности и удобства использования всей экосистемы блокчейна._
+
+- **[QuantStamp](https://quantstamp.com/)** — _сервис аудита, способствующий массовому внедрению технологии блокчейн через услуги по оценке безопасности и рисков._
+
+- **[OpenZeppelin](https://www.openzeppelin.com/security-audits)** — _компания по безопасности умных контрактов, предоставляющая аудиты безопасности для распределенных систем._
+
+- **[Runtime Verification](https://runtimeverification.com/)** — _компания по безопасности, специализирующаяся на формальном моделировании и верификации умных контрактов._
+
+- **[Hacken](https://hacken.io)** — _аудитор кибербезопасности Web3, применяющий 360-градусный подход к безопасности блокчейна._
+
+- **[Nethermind](https://www.nethermind.io/smart-contract-audits)** — _услуги аудита Solidity и Cairo, обеспечивающие целостность умных контрактов и безопасность пользователей в Ethereum и Starknet._
+
+- **[HashEx](https://hashex.org/)** — _HashEx специализируется на аудите блокчейна и умных контрактов для обеспечения безопасности криптовалют, предоставляя такие услуги, как разработка умных контрактов, тестирование на проникновение, консалтинг в области блокчейна._
+
+- **[Code4rena](https://code4rena.com/)** — _конкурентная платформа для аудита, которая стимулирует экспертов по безопасности умных контрактов находить уязвимости и помогать делать web3 более безопасным._
+
+- **[CodeHawks](https://codehawks.com/)** — _конкурентная аудиторская платформа, проводящая соревнования по аудиту умных контрактов для исследователей безопасности._
+
+- **[Cyfrin](https://cyfrin.io)** — _мощный центр безопасности Web3, инкубирующий криптобезопасность через продукты и услуги по аудиту умных контрактов._
+
+- **[ImmuneBytes](https://immunebytes.com/smart-contract-audit/)** — _фирма по безопасности Web3, предлагающая аудиты безопасности для блокчейн-систем с помощью команды опытных аудиторов и лучших в своем классе инструментов._
+
+- **[Oxorio](https://oxor.io/)** — _аудиты умных контрактов и услуги по безопасности блокчейна с опытом в EVM, Solidity, ZK, кросс-чейн технологиях для криптофирм и проектов DeFi._
+
+- **[Inference](https://inference.ag/)** — _аудиторская компания по безопасности, специализирующаяся на аудите умных контрактов для блокчейнов на базе EVM. Благодаря своим опытным аудиторам они выявляют потенциальные проблемы и предлагают действенные решения для их устранения до развертывания._
+
+### Платформы вознаграждений за обнаружение ошибок {#bug-bounty-platforms}
+
+- **[Immunefi](https://immunefi.com/)** — _платформа вознаграждений за обнаружение ошибок для умных контрактов и проектов DeFi, где исследователи безопасности просматривают код, раскрывают уязвимости, получают вознаграждение и делают криптовалюту безопаснее._
+
+- **[HackerOne](https://www.hackerone.com/)** — _платформа для координации уязвимостей и вознаграждений за обнаружение ошибок, которая связывает компании с пентестерами и исследователями кибербезопасности._
+
+- **[HackenProof](https://hackenproof.com/)** — _экспертная платформа вознаграждений за ошибки для криптопроектов (DeFi, умные контракты, кошельки, CEX и другие), где специалисты по безопасности обеспечивают сортировочные услуги и исследователям платят за соответствующие, проверенные сообщения об ошибках._
+
+- **[Sherlock](https://www.sherlock.xyz/)** — _гарант безопасности умных контрактов в Web3, с выплатами для аудиторов, управляемыми через умные контракты, чтобы обеспечить справедливую оплату за обнаружение соответствующих ошибок._
+
+- **[CodeHawks](https://www.codehawks.com/)** — _конкурентная платформа вознаграждений за обнаружение ошибок, где аудиторы принимают участие в конкурсах и челленджах по безопасности, а (скоро) и в своих собственных частных аудитах._
+
+### Публикации известных уязвимостей и эксплойтов умных контрактов {#common-smart-contract-vulnerabilities-and-exploits}
+
+- **[ConsenSys: известные атаки на умные контракты](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/)** — _понятное для новичков объяснение наиболее значительных уязвимостей контрактов с примерами кода для большинства случаев._
+
+- **[SWC Registry](https://swcregistry.io/)** — _отобранный список элементов Common Weakness Enumeration (CWE), применимых к умным контрактам Ethereum._
+
+- **[Rekt](https://rekt.news/)** — _регулярно обновляемое издание о громких крипто-взломах и эксплойтах, а также подробные отчеты о вскрытии._
+
+### Задания для изучения безопасности умных контрактов {#challenges-for-learning-smart-contract-security}
+
+- **[Awesome BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs)** — _отобранный список военных игр, задач и соревнований [Capture The Flag](https://www.webopedia.com/definitions/ctf-event/amp/) в области безопасности блокчейна, а также разборы решений._
+
+- **[Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)** — _военная игра для изучения наступательной безопасности умных контрактов DeFi и развития навыков в поиске ошибок и аудите безопасности._
+
+- **[Ethernaut](https://ethernaut.openzeppelin.com/)** — _военная игра на основе Web3/Solidity, где каждый уровень — это умный контракт, который нужно «взломать»._
+
+- **[HackenProof x HackTheBox](https://app.hackthebox.com/tracks/HackenProof-Track)** — _задание по взлому умных контрактов в стиле фэнтезийного приключения. Успешное выполнение задания также дает доступ к частной программе вознаграждений за обнаружение ошибок._
+
+### Лучшие практики по обеспечению безопасности умных контрактов {#smart-contract-security-best-practices}
+
+- **[ConsenSys: лучшие практики безопасности умных контрактов Ethereum](https://consensys.github.io/smart-contract-best-practices/)** — _полный список рекомендаций по обеспечению безопасности умных контрактов Ethereum._
+
+- **[Nascent: простой набор инструментов для обеспечения безопасности](https://github.com/nascentxyz/simple-security-toolkit)** — _коллекция практических руководств и контрольных списков по безопасности для разработки умных контрактов._
+
+- **[Solidity Patterns](https://fravoll.github.io/solidity-patterns/)** — _полезная подборка безопасных патернов и лучших практик для языка программирования умных контрактов Solidity._
+
+- **[Документация Solidity: соображения безопасности](https://docs.soliditylang.org/en/v0.8.16/security-considerations.html)** — _руководство по написанию безопасных умных контрактов на Solidity._
+
+- **[Стандарт верификации безопасности умных контрактов](https://github.com/securing/SCSVS)** — _четырнадцатипунктовый контрольный список, созданный для стандартизации безопасности умных контрактов для разработчиков, архитекторов, ревьюеров безопасности и поставщиков._
+
+- **[Изучение безопасности и аудита умных контрактов](https://updraft.cyfrin.io/courses/security)** — _полный курс по безопасности и аудиту умных контрактов, созданный для разработчиков умных контрактов, которые хотят повысить уровень своих знаний в области безопасности и стать исследователями безопасности._
+
+### Учебные пособия по безопасности умных контрактов {#tutorials-on-smart-contract-security}
+
+- [Как писать безопасные умные контракты](/developers/tutorials/secure-development-workflow/)
+
+- [Как использовать Slither для поиска ошибок в умных контрактах](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/)
+
+- [Как использовать Manticore для поиска ошибок в умных контрактах](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/)
+
+- [Руководство по безопасности умных контрактов](/developers/tutorials/smart-contract-security-guidelines/)
+
+- [Как безопасно интегрировать ваш контракт токенов с произвольными токенами](/developers/tutorials/token-integration-checklist/)
+
+- [Cyfrin Updraft — полный курс по безопасности и аудиту умных контрактов](https://updraft.cyfrin.io/courses/security)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/testing/index.md b/public/content/translations/ru/developers/docs/smart-contracts/testing/index.md
new file mode 100644
index 00000000000..e43a1adb045
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/testing/index.md
@@ -0,0 +1,310 @@
+---
+title: "Тестирование смарт-контрактов"
+description: "Обзор техник и соображений по тестированию смарт-контрактов Ethereum."
+lang: ru
+---
+
+Публичные блокчейны, такие как Ethereum, являются неизменными, что затрудняет изменение кода смарт-контракта после его развертывания. Существуют [шаблоны обновления контрактов](/developers/docs/smart-contracts/upgrading/) для выполнения «виртуальных обновлений», но их сложно реализовать, и они требуют социального консенсуса. Более того, обновление может исправить ошибку только _после_ ее обнаружения — если злоумышленник обнаружит уязвимость первым, ваш смарт-контракт подвергается риску эксплойта.
+
+По этим причинам тестирование смарт-контрактов перед [развертыванием](/developers/docs/smart-contracts/deploying/) в основной сети (Mainnet) является минимальным требованием для обеспечения [безопасности](/developers/docs/smart-contracts/security/). Существует множество методов для тестирования контрактов и оценки правильности кода; выбор зависит от ваших потребностей. Тем не менее, набор тестов, состоящий из различных инструментов и подходов, идеально подходит для выявления как незначительных, так и серьезных недостатков безопасности в коде контракта.
+
+## Предварительные условия {#prerequisites}
+
+На этой странице объясняется, как тестировать смарт-контракты перед развертыванием в сети Ethereum. Предполагается, что вы знакомы со [смарт-контрактами](/developers/docs/smart-contracts/).
+
+## Что такое тестирование смарт-контрактов? {#what-is-smart-contract-testing}
+
+Тестирование смарт-контрактов — это процесс проверки того, что код смарт-контракта работает так, как ожидалось. Тестирование полезно для проверки того, удовлетворяет ли конкретный смарт-контракт требованиям надежности, удобства использования и безопасности.
+
+Хотя подходы различаются, большинство методов тестирования требуют выполнения смарт-контракта с небольшим объемом данных, которые он должен обрабатывать. Если контракт дает правильные результаты для выборочных данных, считается, что он функционирует должным образом. Большинство инструментов для тестирования предоставляют ресурсы для написания и выполнения [тестовых случаев](https://en.m.wikipedia.org/wiki/Test_case) для проверки соответствия выполнения контракта ожидаемым результатам.
+
+### Почему важно тестировать смарт-контракты? {#importance-of-testing-smart-contracts}
+
+Поскольку смарт-контракты часто управляют дорогостоящими финансовыми активами, незначительные ошибки программирования могут привести и часто приводят к [огромным потерям для пользователей](https://rekt.news/leaderboard/). Однако тщательное тестирование может помочь вам выявить дефекты и проблемы в коде смарт-контракта на ранней стадии и исправить их до запуска в основной сети (Mainnet).
+
+Хотя возможно обновить контракт при обнаружении ошибки, обновления сложны и могут [привести к ошибкам](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/) при неправильном обращении. Обновление контракта еще больше отрицает принцип неизменности и обременяет пользователей дополнительными предположениями о доверии. И наоборот, комплексный план тестирования вашего контракта снижает риски безопасности смарт-контрактов и уменьшает необходимость в сложных логических обновлениях после развертывания.
+
+## Методы тестирования смарт-контрактов {#methods-for-testing-smart-contracts}
+
+Методы тестирования смарт-контрактов Ethereum делятся на две большие категории: **автоматизированное тестирование** и **ручное тестирование**. Автоматизированное и ручное тестирование предлагают уникальные преимущества и компромиссы, но вы можете объединить их для создания надежного плана анализа ваших контрактов.
+
+### Автоматизированное тестирование {#automated-testing}
+
+Автоматизированное тестирование использует инструменты, которые автоматически проверяют код смарт-контракта на наличие ошибок при исполнении. Преимущество автоматизированного тестирования заключается в использовании [скриптов](https://www.techtarget.com/whatis/definition/script?amp=1) для управления оценкой функциональности контракта. Скриптовые тесты можно запланировать для многократного запуска с минимальным вмешательством человека, что делает автоматизированное тестирование более эффективным, чем ручные подходы к тестированию.
+
+Автоматизированное тестирование особенно полезно, когда тесты повторяются и занимают много времени, их трудно выполнять вручную, они подвержены человеческим ошибкам или включают оценку критически важных функций контракта. Но инструменты автоматизированного тестирования могут иметь и недостатки: они могут пропустить некоторые ошибки и выдать много [ложноположительных результатов](https://www.contrastsecurity.com/glossary/false-positive). Следовательно, идеальным является сочетание автоматизированного и ручного тестирования для смарт-контрактов.
+
+### Ручное тестирование {#manual-testing}
+
+Ручное тестирование выполняется с помощью человека и включает в себя последовательное выполнение каждого тестового случая в вашем наборе тестов при анализе правильности смарт-контракта. Это отличается от автоматизированного тестирования, где вы можете одновременно запускать несколько изолированных тестов на контракте и получать отчет, показывающий все неудачные и пройденные тесты.
+
+Ручное тестирование может проводиться одним человеком в соответствии с письменным планом тестирования, который охватывает различные сценарии тестирования. Вы также можете попросить нескольких лиц или групп взаимодействовать со смарт-контрактом в течение определенного периода в рамках ручного тестирования. Тестировщики будут сравнивать фактическое поведение контракта с ожидаемым, отмечая любое различие как ошибку.
+
+Эффективное ручное тестирование требует значительных ресурсов (навыков, времени, денег и усилий), и из-за человеческой ошибки возможно пропустить некоторые ошибки при выполнении тестов. Но ручное тестирование также может быть полезным — например, человек-тестировщик (например, аудитор) может использовать интуицию для обнаружения крайних случаев, которые пропустит инструмент автоматизированного тестирования.
+
+## Автоматизированное тестирование для смарт-контрактов {#automated-testing-for-smart-contracts}
+
+### Модульное тестирование {#unit-testing-for-smart-contracts}
+
+Модульное тестирование оценивает функции контракта по отдельности и проверяет правильность работы каждого компонента. Хорошие модульные тесты должны быть простыми, быстрыми в выполнении и давать четкое представление о том, что пошло не так, если тесты не пройдены.
+
+Модульные тесты полезны для проверки того, что функции возвращают ожидаемые значения и что хранилище контракта правильно обновляется после выполнения функции. Кроме того, запуск модульных тестов после внесения изменений в кодовую базу контракта гарантирует, что добавление новой логики не приведет к появлению ошибок. Ниже приведены некоторые рекомендации по проведению эффективных модульных тестов:
+
+#### Рекомендации по модульному тестированию смарт-контрактов {#unit-testing-guidelines}
+
+##### 1. Поймите бизнес-логику и рабочий процесс ваших контрактов
+
+Прежде чем писать модульные тесты, полезно знать, какие функции предлагает смарт-контракт и как пользователи будут получать к ним доступ и использовать их. Это особенно полезно для запуска [тестов по «счастливому пути»](https://en.m.wikipedia.org/wiki/Happy_path), которые определяют, возвращают ли функции в контракте правильный результат для допустимых пользовательских вводов. Мы объясним эту концепцию на примере (сокращенном) [контракта аукциона](https://docs.soliditylang.org/en/v0.8.17/solidity-by-example.html?highlight=Auction%20contract#simple-open-auction)
+
+```solidity
+constructor(
+ uint biddingTime,
+ address payable beneficiaryAddress
+ ) {
+ beneficiary = beneficiaryAddress;
+ auctionEndTime = block.timestamp + biddingTime;
+ }
+
+function bid() external payable {
+
+ if (block.timestamp > auctionEndTime)
+ revert AuctionAlreadyEnded();
+
+ if (msg.value <= highestBid)
+ revert BidNotHighEnough(highestBid);
+
+ if (highestBid != 0) {
+ pendingReturns[highestBidder] += highestBid;
+ }
+ highestBidder = msg.sender;
+ highestBid = msg.value;
+ emit HighestBidIncreased(msg.sender, msg.value);
+ }
+
+ function withdraw() external returns (bool) {
+ uint amount = pendingReturns[msg.sender];
+ if (amount > 0) {
+ pendingReturns[msg.sender] = 0;
+
+ if (!payable(msg.sender).send(amount)) {
+ pendingReturns[msg.sender] = amount;
+ return false;
+ }
+ }
+ return true;
+ }
+
+function auctionEnd() external {
+ if (block.timestamp < auctionEndTime)
+ revert AuctionNotYetEnded();
+ if (ended)
+ revert AuctionEndAlreadyCalled();
+
+ ended = true;
+ emit AuctionEnded(highestBidder, highestBid);
+
+ beneficiary.transfer(highestBid);
+ }
+}
+```
+
+Это простой контракт аукциона, предназначенный для приема ставок в течение периода торгов. Если `highestBid` увеличивается, предыдущий участник, сделавший самую высокую ставку, получает свои деньги; как только период торгов заканчивается, `beneficiary` вызывает контракт, чтобы получить свои деньги.
+
+Модульные тесты для такого контракта охватывали бы различные функции, которые пользователь мог бы вызывать при взаимодействии с контрактом. Примером может служить модульный тест, который проверяет, может ли пользователь сделать ставку во время аукциона (т. е. вызовы `bid()` завершаются успешно), или тест, который проверяет, может ли пользователь сделать ставку выше текущей `highestBid`.
+
+Понимание рабочего процесса контракта также помогает в написании модульных тестов, которые проверяют, соответствует ли выполнение требованиям. Например, контракт аукциона указывает, что пользователи не могут делать ставки после окончания аукциона (т. е. когда `auctionEndTime` меньше `block.timestamp`). Таким образом, разработчик может запустить модульный тест, который проверяет, завершаются ли вызовы функции `bid()` успешно или неудачно после окончания аукциона (т. е. когда `auctionEndTime` > `block.timestamp`).
+
+##### 2. Оцените все предположения, связанные с выполнением контракта
+
+Важно документировать все предположения о выполнении контракта и писать модульные тесты для проверки достоверности этих предположений. Помимо защиты от непредвиденного выполнения, тестирование утверждений заставляет вас задуматься об операциях, которые могут нарушить модель безопасности смарт-контракта. Полезный совет: выходить за рамки «тестов для счастливого пользователя» и писать негативные тесты, которые проверяют, не сбоит ли функция при неверных входных данных.
+
+Многие фреймворки для модульного тестирования позволяют создавать утверждения — простые операторы, которые определяют, что контракт может и не может делать, — и запускать тесты, чтобы увидеть, соблюдаются ли эти утверждения при выполнении. Разработчик, работающий над описанным ранее контрактом аукциона, мог бы сделать следующие утверждения о его поведении перед запуском негативных тестов:
+
+- Пользователи не могут делать ставки, когда аукцион закончился или еще не начался.
+
+- Контракт аукциона отменяет транзакцию, если ставка ниже допустимого порога.
+
+- Пользователи, не выигравшие торги, получают свои средства обратно
+
+**Примечание**: еще один способ проверить предположения — написать тесты, которые вызывают [модификаторы функций](https://docs.soliditylang.org/en/v0.8.16/contracts.html#function-modifiers) в контракте, особенно операторы `require`, `assert` и `if…else`.
+
+##### 3. Измерение покрытия кода
+
+[Покрытие кода](https://en.m.wikipedia.org/wiki/Code_coverage) — это метрика тестирования, которая отслеживает количество ветвей, строк и операторов в вашем коде, выполненных во время тестов. Тесты должны иметь хорошее покрытие кода, чтобы минимизировать риск непроверенных уязвимостей. Без достаточного покрытия вы можете ошибочно предположить, что ваш контракт безопасен, потому что все тесты пройдены, в то время как уязвимости все еще существуют в непроверенных путях кода. Однако регистрация высокого покрытия кода дает уверенность в том, что все операторы/функции в смарт-контракте были достаточно протестированы на правильность.
+
+##### 4. Используйте хорошо разработанные фреймворки для тестирования
+
+Качество инструментов, используемых для запуска модульных тестов для ваших смарт-контрактов, имеет решающее значение. Идеальный фреймворк для тестирования — это тот, который регулярно поддерживается, предоставляет полезные функции (например, возможности ведения журнала и отчетности) и должен быть широко использован и проверен другими разработчиками.
+
+Фреймворки для модульного тестирования смарт-контрактов Solidity существуют на разных языках (в основном JavaScript, Python и Rust). См. некоторые из приведенных ниже руководств для получения информации о том, как начать запускать модульные тесты с различными фреймворками для тестирования:
+
+- **[Запуск модульных тестов с помощью Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)**
+- **[Запуск модульных тестов с помощью Foundry](https://book.getfoundry.sh/forge/writing-tests)**
+- **[Запуск модульных тестов с помощью Waffle](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests)**
+- **[Запуск модульных тестов с помощью Remix](https://remix-ide.readthedocs.io/en/latest/unittesting.html#write-tests)**
+- **[Запуск модульных тестов с помощью Ape](https://docs.apeworx.io/ape/stable/userguides/testing.html)**
+- **[Запуск модульных тестов с помощью Hardhat](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)**
+- **[Запуск модульных тестов с Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/overview/)**
+
+### Интеграционное тестирование {#integration-testing-for-smart-contracts}
+
+В то время как модульное тестирование отлаживает функции контракта изолированно, интеграционные тесты оценивают компоненты смарт-контракта в целом. Интеграционное тестирование может выявить проблемы, возникающие из-за межконтрактных вызовов или взаимодействия между различными функциями в одном и том же смарт-контракте. Например, интеграционные тесты могут помочь проверить, правильно ли работают такие вещи, как [наследование](https://docs.soliditylang.org/en/v0.8.12/contracts.html#inheritance) и внедрение зависимостей.
+
+Интеграционное тестирование полезно, если ваш контракт имеет модульную архитектуру или взаимодействует с другими ончейн-контрактами во время выполнения. Один из способов проведения интеграционных тестов — это [сделать форк блокчейна](/glossary/#fork) на определенной высоте (используя такой инструмент, как [Forge](https://book.getfoundry.sh/forge/fork-testing) или [Hardhat](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks)) и смоделировать взаимодействие между вашим контрактом и развернутыми контрактами.
+
+Форкнутый блокчейн будет вести себя аналогично основной сети (Mainnet) и будет иметь аккаунты со связанными состояниями и балансами. Но он действует только как локальная среда разработки в песочнице, то есть вам не понадобятся реальные ETH для транзакций, и ваши изменения не повлияют на реальный протокол Ethereum.
+
+### Тестирование на основе свойств {#property-based-testing-for-smart-contracts}
+
+Тестирование на основе свойств — это процесс проверки того, что смарт-контракт удовлетворяет некоторому определенному свойству. Свойства утверждают факты о поведении контракта, которые, как ожидается, останутся верными в различных сценариях. Примером свойства смарт-контракта может быть: «Арифметические операции в контракте никогда не вызывают переполнения или антипереполнения».
+
+Статический и динамический анализ — два распространенных метода для проведения тестирования на основе свойств, и оба могут проверить, что код программы (в данном случае смарт-контракта) удовлетворяет некоторому предопределенному свойству. Некоторые инструменты для тестирования на основе свойств поставляются с предопределенными правилами об ожидаемых свойствах контракта и проверяют код по этим правилам, в то время как другие позволяют создавать пользовательские свойства для смарт-контракта.
+
+#### Статический анализ {#static-analysis}
+
+Статический анализатор принимает на вход исходный код смарт-контракта и выводит результаты, объявляющие, удовлетворяет ли контракт свойству или нет. В отличие от динамического анализа, статический анализ не предполагает выполнения контракта для его анализа на правильность. Вместо этого статический анализ рассуждает обо всех возможных путях, которые смарт-контракт может пройти во время выполнения (т. е. путем изучения структуры исходного кода, чтобы определить, что это будет означать для работы контракта во время выполнения).
+
+[Линтинг](https://www.perforce.com/blog/qac/what-is-linting) и [статическое тестирование](https://www.techtarget.com/whatis/definition/static-analysis-static-code-analysis) являются распространенными методами статического анализа контрактов. Оба метода требуют анализа низкоуровневых представлений выполнения контракта, таких как [абстрактные синтаксические деревья](https://en.m.wikipedia.org/wiki/Abstract_syntax_tree) и [графы потока управления](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/amp/), выводимые компилятором.
+
+В большинстве случаев статический анализ полезен для обнаружения проблем безопасности, таких как использование небезопасных конструкций, синтаксических ошибок или нарушений стандартов кодирования в коде контракта. Однако известно, что статические анализаторы, как правило, ненадёжны при обнаружении более глубоких уязвимостей и могут давать чрезмерное количество ложных срабатываний.
+
+#### Динамический анализ {#dynamic-analysis}
+
+Динамический анализ генерирует символические входные данные (например, при [символическом выполнении](https://en.m.wikipedia.org/wiki/Symbolic_execution)) или конкретные входные данные (например, при [фаззинге](https://owasp.org/www-community/Fuzzing)) для функций смарт-контракта, чтобы увидеть, нарушает ли какой-либо след(ы) выполнения определенные свойства. Эта форма тестирования на основе свойств отличается от модульных тестов тем, что тестовые случаи охватывают несколько сценариев, а программа обрабатывает генерацию тестовых случаев.
+
+[Фаззинг](https://www.halborn.com/blog/post/what-is-fuzz-testing-fuzzing) — это пример метода динамического анализа для проверки произвольных свойств в смарт-контрактах. Фаззер вызывает функции в целевом контракте со случайными или искаженными вариациями определенного входного значения. Если смарт-контракт переходит в состояние ошибки (например, когда утверждение не выполняется), проблема отмечается, а в отчете приводятся входные данные, которые направляют выполнение к уязвимому пути.
+
+Фаззинг полезен для оценки механизма проверки входных данных смарт-контракта, поскольку неправильная обработка непредвиденных входных данных может привести к непреднамеренному выполнению и вызвать опасные последствия. Эта форма тестирования на основе свойств может быть идеальной по многим причинам:
+
+1. **Написать тестовые случаи для охвата множества сценариев сложно.** Тест на основе свойств требует только того, чтобы вы определили поведение и диапазон данных для его тестирования — программа автоматически генерирует тестовые случаи на основе определенного свойства.
+
+2. **Ваш набор тестов может недостаточно охватывать все возможные пути в программе.** Даже при 100% покрытии можно упустить крайние случаи.
+
+3. Модульные тесты доказывают, что контракт выполняется правильно для выборочных данных, но остается неизвестным, правильно ли он выполняется для входных данных за пределами выборки. Тесты на основе свойств выполняют целевой контракт с множеством вариаций заданного входного значения для поиска следов выполнения, которые вызывают сбои утверждений. Таким образом, тест на основе свойств предоставляет больше гарантий того, что контракт выполняется правильно для широкого класса входных данных.
+
+### Рекомендации по проведению тестирования смарт-контрактов на основе свойств {#running-property-based-tests}
+
+Проведение тестирования на основе свойств обычно начинается с определения свойства (например, отсутствия [целочисленных переполнений](https://github.com/ConsenSys/mythril/wiki/Integer-Overflow)) или набора свойств, которые вы хотите проверить в смарт-контракте. Вам также может потребоваться определить диапазон значений, в пределах которого программа может генерировать данные для входных данных транзакции при написании тестов на основе свойств.
+
+После правильной настройки инструмент для тестирования на основе свойств будет выполнять функции вашего смарт-контракта со случайно сгенерированными входными данными. Если есть какие-либо нарушения утверждений, вы должны получить отчет с конкретными входными данными, которые нарушают оцениваемое свойство. См. некоторые из приведенных ниже руководств, чтобы начать работу с тестированием на основе свойств с помощью различных инструментов:
+
+- **[Статический анализ смарт-контрактов с помощью Slither](https://github.com/crytic/slither)**
+- **[Статический анализ смарт-контрактов с помощью Wake](https://ackeeblockchain.com/wake/docs/latest/static-analysis/using-detectors/)**
+- **[Тестирование на основе свойств с помощью Brownie](https://eth-brownie.readthedocs.io/en/stable/tests-hypothesis-property.html)**
+- **[Фаззинг контрактов с помощью Foundry](https://book.getfoundry.sh/forge/fuzz-testing)**
+- **[Фаззинг контрактов с помощью Echidna](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial)**
+- **[Фаззинг контрактов с Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/fuzzing/)**
+- **[Символическое выполнение смарт-контрактов с помощью Manticore](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore#manticore-tutorial)**
+- **[Символическое выполнение смарт-контрактов с помощью Mythril](https://mythril-classic.readthedocs.io/en/master/tutorial.html)**
+
+## Ручное тестирование смарт-контрактов {#manual-testing-for-smart-contracts}
+
+Ручное тестирование смарт-контрактов часто проводится на более поздних этапах цикла разработки после выполнения автоматизированных тестов. Эта форма тестирования оценивает смарт-контракт как единый полностью интегрированный продукт, чтобы увидеть, работает ли он в соответствии с техническими требованиями.
+
+### Тестирование контрактов на локальном блокчейне {#testing-on-local-blockchain}
+
+Хотя автоматизированное тестирование, проводимое в локальной среде разработки, может предоставить полезную информацию для отладки, вам захочется узнать, как ваш смарт-контракт ведет себя в производственной среде. Однако развертывание в основной сети Ethereum влечет за собой плату за газ, не говоря уже о том, что вы или ваши пользователи можете потерять реальные деньги, если в вашем смарт-контракте все еще есть ошибки.
+
+Тестирование вашего контракта на локальном блокчейне (также известном как [сеть разработки](/developers/docs/development-networks/)) является рекомендуемой альтернативой тестированию в основной сети (Mainnet). Локальный блокчейн — это копия блокчейна Ethereum, работающая локально на вашем компьютере, которая имитирует поведение уровня исполнения Ethereum. Таким образом, вы можете программировать транзакции для взаимодействия с контрактом, не неся значительных накладных расходов.
+
+Запуск контрактов на локальном блокчейне может быть полезен как форма ручного интеграционного тестирования. [Смарт-контракты обладают высокой степенью компонуемости](/developers/docs/smart-contracts/composability/), что позволяет вам интегрироваться с существующими протоколами, но вам все равно нужно будет убедиться, что такие сложные ончейн-взаимодействия дают правильные результаты.
+
+[Подробнее о сетях для разработки.](/developers/docs/development-networks/)
+
+### Тестирование контрактов в тестовых сетях {#testing-contracts-on-testnets}
+
+Тестовая сеть работает точно так же, как основная сеть Ethereum, за исключением того, что в ней используется эфир (ETH), не имеющий реальной ценности. Развертывание вашего контракта в [тестовой сети](/developers/docs/networks/#ethereum-testnets) означает, что любой может взаимодействовать с ним (например, через интерфейс децентрализованного приложения), не рискуя средствами.
+
+Эта форма ручного тестирования полезна для оценки сквозного потока вашего приложения с точки зрения пользователя. Здесь бета-тестеры также могут проводить пробные запуски и сообщать о любых проблемах с бизнес-логикой контракта и общей функциональностью.
+
+Развертывание в тестовой сети после тестирования на локальном блокчейне является идеальным, поскольку первая ближе к поведению виртуальной машины Ethereum. Поэтому для многих нативных проектов Ethereum является обычным делом развертывать децентрализованные приложения в тестовых сетях для оценки работы смарт-контрактов в реальных условиях.
+
+[Подробнее о тестовых сетях Ethereum.](/developers/docs/development-networks/#public-beacon-testchains)
+
+## Тестирование и формальная верификация {#testing-vs-formal-verification}
+
+Хотя тестирование помогает подтвердить, что контракт возвращает ожидаемые результаты для некоторых входных данных, оно не может окончательно доказать то же самое для входных данных, не использовавшихся во время тестов. Таким образом, тестирование смарт-контракта не может гарантировать «функциональную правильность» (т. е. не может показать, что программа ведет себя так, как требуется для _всех_ наборов входных значений).
+
+Формальная верификация — это подход к оценке правильности программного обеспечения путем проверки соответствия формальной модели программы формальной спецификации. Формальная модель — это абстрактное математическое представление программы, а формальная спецификация определяет свойства программы (т. е. логические утверждения о выполнении программы).
+
+Поскольку свойства написаны в математических терминах, становится возможным проверить, что формальная (математическая) модель системы удовлетворяет спецификации, используя логические правила вывода. Таким образом, считается, что инструменты формальной верификации производят «математическое доказательство» правильности системы.
+
+В отличие от тестирования, формальная верификация может быть использована для проверки того, что выполнение смарт-контракта удовлетворяет формальной спецификации для _всех_ выполнений (т. е. не имеет ошибок), без необходимости выполнять его с выборочными данными. Это не только сокращает время, затрачиваемое на запуск десятков модульных тестов, но и более эффективно для выявления скрытых уязвимостей. Тем не менее, методы формальной верификации лежат в спектре в зависимости от сложности их реализации и полезности.
+
+[Подробнее о формальной верификации для смарт-контрактов.](/developers/docs/smart-contracts/formal-verification)
+
+## Тестирование, аудиты и программы поощрения за поиск ошибок {#testing-vs-audits-bug-bounties}
+
+Как уже упоминалось, тщательное тестирование редко может гарантировать отсутствие ошибок в контракте; подходы формальной верификации могут дать более надежные гарантии правильности, но в настоящее время их сложно использовать, и они сопряжены со значительными затратами.
+
+Тем не менее, вы можете еще больше увеличить вероятность выявления уязвимостей контракта, получив независимую проверку кода. [Аудиты смарт-контрактов](https://www.immunebytes.com/blog/what-is-a-smart-contract-audit/) и [программы поощрения за поиск ошибок](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7) — это два способа заставить других проанализировать ваши контракты.
+
+Аудиты проводятся аудиторами, имеющими опыт в поиске недостатков безопасности и плохих практик разработки в смарт-контрактах. Аудит обычно включает тестирование (и, возможно, формальную верификацию), а также ручную проверку всей кодовой базы.
+
+И наоборот, программа поощрения за поиск ошибок обычно включает в себя предложение финансового вознаграждения человеку (обычно называемому [«белым» хакером](https.en.wikipedia.org/wiki/White_hat_\(computer_security\))), который обнаруживает уязвимость в смарт-контракте и сообщает о ней разработчикам. Программы поощрения за поиск ошибок похожи на аудиты, поскольку они предполагают просьбу о помощи в поиске дефектов в смарт-контрактах.
+
+Основное отличие заключается в том, что программы поощрения за поиск ошибок открыты для более широкого сообщества разработчиков/хакеров и привлекают широкий круг этичных хакеров и независимых специалистов по безопасности с уникальными навыками и опытом. Это может быть преимуществом перед аудитами смарт-контрактов, которые в основном полагаются на команды, которые могут обладать ограниченным или узким опытом.
+
+## Инструменты и библиотеки для тестирования {#testing-tools-and-libraries}
+
+### Инструменты модульного тестирования {#unit-testing-tools}
+
+- **[solidity-coverage](https://github.com/sc-forks/solidity-coverage)** — _инструмент для определения покрытия кода для смарт-контрактов, написанных на Solidity._
+
+- **[Waffle](https://ethereum-waffle.readthedocs.io/en/latest/)** — _фреймворк для продвинутой разработки и тестирования смарт-контрактов (на базе ethers.js)_.
+
+- **[Remix Tests](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests)** — _инструмент для тестирования смарт-контрактов Solidity. Работает под плагином Remix IDE «Solidity Unit Testing», который используется для написания и запуска тестовых случаев для контракта._
+
+- **[OpenZeppelin Test Helpers](https://github.com/OpenZeppelin/openzeppelin-test-helpers)** — _библиотека утверждений для тестирования смарт-контрактов Ethereum. Убедитесь, что ваши контракты работают должным образом!_
+
+- **[Фреймворк модульного тестирования Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** — _Brownie использует Pytest, многофункциональный тестовый фреймворк, который позволяет писать небольшие тесты с минимальным кодом, хорошо масштабируется для больших проектов и обладает высокой расширяемостью._
+
+- **[Foundry Tests](https://github.com/foundry-rs/foundry/tree/master/crates/forge)** — _Foundry предлагает Forge, быстрый и гибкий фреймворк для тестирования Ethereum, способный выполнять простые модульные тесты, проверки оптимизации газа и фаззинг контрактов._
+
+- **[Hardhat Tests](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** — _фреймворк для тестирования смарт-контрактов на основе ethers.js, Mocha и Chai._
+
+- **[ApeWorx](https://docs.apeworx.io/ape/stable/userguides/testing.html)** — _фреймворк для разработки и тестирования на Python для смарт-контрактов, предназначенных для виртуальной машины Ethereum._
+
+- **[Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/overview/)** — _фреймворк на Python для модульного тестирования и фаззинга с мощными возможностями отладки и поддержкой кросс-чейн тестирования, использующий pytest и Anvil для лучшего пользовательского опыта и производительности._
+
+### Инструменты тестирования на основе свойств {#property-based-testing-tools}
+
+#### Инструменты статического анализа {#static-analysis-tools}
+
+- **[Slither](https://github.com/crytic/slither)** — _фреймворк для статического анализа Solidity на Python для поиска уязвимостей, улучшения понимания кода и написания пользовательских анализов для смарт-контрактов._
+
+- **[Ethlint](https://ethlint.readthedocs.io/en/latest/)** — _линтер для обеспечения соблюдения стиля и лучших практик безопасности для языка программирования смарт-контрактов Solidity._
+
+- **[Cyfrin Aderyn](https://cyfrin.io/tools/aderyn)** — _статический анализатор на Rust, специально разработанный для безопасности и разработки смарт-контрактов Web3._
+
+- **[Wake](https://ackeeblockchain.com/wake/docs/latest/static-analysis/using-detectors/)** — _фреймворк для статического анализа на Python с детекторами уязвимостей и качества кода, принтерами для извлечения полезной информации из кода и поддержкой написания пользовательских подмодулей._
+
+- **[Slippy](https://github.com/fvictorio/slippy)** — _простой и мощный линтер для Solidity._
+
+#### Инструменты динамического анализа {#dynamic-analysis-tools}
+
+- **[Echidna](https://github.com/crytic/echidna/)** — _быстрый фаззер контрактов для обнаружения уязвимостей в смарт-контрактах с помощью тестирования на основе свойств._
+
+- **[Diligence Fuzzing](https://consensys.net/diligence/fuzzing/)** — _автоматизированный инструмент фаззинга, полезный для обнаружения нарушений свойств в коде смарт-контракта._
+
+- **[Manticore](https://manticore.readthedocs.io/en/latest/index.html)** — _фреймворк динамического символического выполнения для анализа байт-кода EVM._
+
+- **[Mythril](https://github.com/ConsenSys/mythril-classic)** — _инструмент оценки байт-кода EVM для обнаружения уязвимостей контрактов с использованием анализа заражения, конколического анализа и проверки потока управления._
+
+- **[Diligence Scribble](https://consensys.net/diligence/scribble/)** — _Scribble — это язык спецификаций и инструмент верификации во время выполнения, который позволяет аннотировать смарт-контракты свойствами, позволяющими автоматически тестировать контракты с помощью таких инструментов, как Diligence Fuzzing или MythX._
+
+## Связанные руководства {#related-tutorials}
+
+- [Обзор и сравнение различных продуктов для тестирования](/developers/tutorials/guide-to-smart-contract-security-tools/) \_
+- [Как использовать Echidna для тестирования смарт-контрактов](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/)
+- [Как использовать Manticore для поиска ошибок в умных контрактах](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/)
+- [Как использовать Slither для поиска ошибок в умных контрактах](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/)
+- [Как создавать заглушки для контрактов Solidity для тестирования](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/)
+- [Как запускать модульные тесты в Solidity с помощью Foundry](https://www.rareskills.io/post/foundry-testing-solidity)
+
+## Дополнительные материалы {#further-reading}
+
+- [Подробное руководство по тестированию смарт-контрактов Ethereum](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297)
+- [Как тестировать смарт-контракты Ethereum](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d)
+- [Руководство MolochDAO по модульному тестированию для разработчиков](https://github.com/MolochVentures/moloch/tree/4e786db8a4aa3158287e0935dcbc7b1e43416e38/test#moloch-testing-guide)
+- [Как тестировать смарт-контракты как рок-звезда](https://forum.openzeppelin.com/t/test-smart-contracts-like-a-rockstar/1001)
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/upgrading/index.md b/public/content/translations/ru/developers/docs/smart-contracts/upgrading/index.md
new file mode 100644
index 00000000000..cb348952717
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/upgrading/index.md
@@ -0,0 +1,165 @@
+---
+title: "Обновление смарт-контрактов"
+description: "Обзор шаблонов обновления для смарт-контрактов Ethereum"
+lang: ru
+---
+
+Смарт-контракты в Ethereum — это самоисполняемые программы, которые работают в виртуальной машине Ethereum (EVM). Эти программы по своей сути неизменяемы, что предотвращает любые обновления бизнес-логики после развертывания контракта.
+
+Хотя неизменяемость необходима для отсутствия доверия, децентрализации и безопасности смарт-контрактов, в некоторых случаях она может быть недостатком. Например, неизменяемый код может сделать невозможным для разработчиков исправление уязвимых контрактов.
+
+Однако расширенные исследования по улучшению смарт-контрактов привели к появлению нескольких шаблонов обновления. Эти шаблоны обновления позволяют разработчикам обновлять смарт-контракты (сохраняя при этом неизменяемость), размещая бизнес-логику в разных контрактах.
+
+## Предварительные условия {#prerequisites}
+
+Вы должны хорошо разбираться в [смарт-контрактах](/developers/docs/smart-contracts/), [анатомии смарт-контрактов](/developers/docs/smart-contracts/anatomy/) и [виртуальной машине Ethereum (EVM)](/developers/docs/evm/). Это руководство также предполагает, что читатели знакомы с программированием смарт-контрактов.
+
+## Что такое обновление смарт-контракта? {#what-is-a-smart-contract-upgrade}
+
+Обновление смарт-контракта включает в себя изменение бизнес-логики смарт-контракта при сохранении состояния контракта. Важно уточнить, что обновляемость и изменяемость — это не одно и то же, особенно в контексте смарт-контрактов.
+
+Вы по-прежнему не можете изменить программу, развернутую по адресу в сети Ethereum. Но вы можете изменить код, который выполняется, когда пользователи взаимодействуют со смарт-контрактом.
+
+Это можно сделать следующими способами:
+
+1. Создание нескольких версий смарт-контракта и перенос состояния (т. е. данных) из старого контракта в новый экземпляр контракта.
+
+2. Создание отдельных контрактов для хранения бизнес-логики и состояния.
+
+3. Использование прокси-шаблонов для делегирования вызовов функций от неизменяемого прокси-контракта к изменяемому контракту логики.
+
+4. Создание неизменяемого основного контракта, который взаимодействует с гибкими сателлитными контрактами и полагается на них для выполнения определенных функций.
+
+5. Использование алмазного шаблона (diamond pattern) для делегирования вызовов функций от прокси-контракта к контрактам логики.
+
+### Механизм обновления №1: миграция контракта {#contract-migration}
+
+Миграция контракта основана на управлении версиями — идее создания и управления уникальными состояниями одного и того же программного обеспечения. Миграция контракта включает в себя развертывание нового экземпляра существующего смарт-контракта и перенос хранилища и балансов в новый контракт.
+
+Вновь развернутый контракт будет иметь пустое хранилище, что позволит вам восстановить данные из старого контракта и записать их в новую реализацию. После этого вам нужно будет обновить все контракты, которые взаимодействовали со старым контрактом, чтобы отразить новый адрес.
+
+Последний шаг в миграции контракта — убедить пользователей перейти на использование нового контракта. Новая версия контракта сохранит балансы и адреса пользователей, что обеспечивает неизменность. Если это контракт на основе токенов, вам также нужно будет связаться с биржами, чтобы они отказались от старого контракта и использовали новый.
+
+Миграция контрактов — это относительно простая и безопасная мера для обновления смарт-контрактов без нарушения взаимодействия с пользователем. Однако ручной перенос пользовательского хранилища и балансов в новый контракт требует много времени и может повлечь за собой высокие затраты на газ.
+
+[Подробнее о миграции контрактов.](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/)
+
+### Механизм обновления №2: разделение данных {#data-separation}
+
+Другой метод обновления смарт-контрактов — разделение бизнес-логики и хранения данных на отдельные контракты. Это означает, что пользователи взаимодействуют с контрактом логики, а данные хранятся в контракте хранилища.
+
+Контракт логики содержит код, выполняемый, когда пользователи взаимодействуют с приложением. Он также содержит адрес контракта хранилища и взаимодействует с ним для получения и установки данных.
+
+Между тем, контракт хранилища содержит состояние, связанное со смарт-контрактом, такое как балансы и адреса пользователей. Обратите внимание, что контракт хранилища принадлежит контракту логики и настраивается с адресом последнего при развертывании. Это предотвращает вызов контракта хранилища или обновление его данных неавторизованными контрактами.
+
+По умолчанию контракт хранилища является неизменяемым, но вы можете заменить контракт логики, на который он указывает, новой реализацией. Это изменит код, который выполняется в EVM, при этом сохраняя хранилище и балансы нетронутыми.
+
+Использование этого метода обновления требует обновления адреса контракта логики в контракте хранилища. Вы также должны настроить новый контракт логики с адресом контракта хранилища по причинам, объясненным ранее.
+
+Шаблон разделения данных, возможно, проще реализовать по сравнению с миграцией контрактов. Однако вам придется управлять несколькими контрактами и реализовывать сложные схемы авторизации для защиты смарт-контрактов от вредоносных обновлений.
+
+### Механизм обновления №3: прокси-шаблоны {#proxy-patterns}
+
+Прокси-шаблон также использует разделение данных для хранения бизнес-логики и данных в отдельных контрактах. Однако в прокси-шаблоне контракт хранилища (называемый прокси) вызывает контракт логики во время выполнения кода. Это обратный метод разделения данных, где контракт логики вызывает контракт хранилища.
+
+Вот что происходит в прокси-шаблоне:
+
+1. Пользователи взаимодействуют с прокси-контрактом, который хранит данные, но не содержит бизнес-логику.
+
+2. Прокси-контракт хранит адрес контракта логики и делегирует все вызовы функций контракту логики (который содержит бизнес-логику) с помощью функции `delegatecall`.
+
+3. После того как вызов перенаправляется в контракт логики, возвращенные из него данные извлекаются и возвращаются пользователю.
+
+Использование прокси-шаблонов требует понимания функции **delegatecall**. По сути, `delegatecall` — это опкод, который позволяет одному контракту вызывать другой, при этом фактическое выполнение кода происходит в контексте вызывающего контракта. Следствием использования `delegatecall` в прокси-шаблонах является то, что прокси-контракт читает и записывает данные в свое хранилище и выполняет логику, хранящуюся в контракте логики, как если бы вызывал внутреннюю функцию.
+
+Из [документации Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries):
+
+> _Существует специальный вариант вызова сообщения, называемый **delegatecall**, который идентичен вызову сообщения, за исключением того, что код по целевому адресу выполняется в контексте (т. е. по адресу) вызывающего контракта, а `msg.sender` и `msg.value` не меняют своих значений._ _Это означает, что контракт может динамически загружать код с другого адреса во время выполнения._ _Хранилище, текущий адрес и баланс по-прежнему относятся к вызывающему контракту, только код берется с вызываемого адреса._
+
+Прокси-контракт знает, что нужно вызывать `delegatecall` всякий раз, когда пользователь вызывает функцию, потому что в него встроена функция `fallback`. В программировании на Solidity [резервная функция (fallback function)](https://docs.soliditylang.org/en/latest/contracts.html#fallback-function) выполняется, когда вызов функции не соответствует ни одной из функций, указанных в контракте.
+
+Чтобы прокси-шаблон работал, необходимо написать собственную резервную функцию (fallback function), которая определяет, как прокси-контракт должен обрабатывать вызовы функций, которые он не поддерживает. В этом случае резервная функция (fallback function) прокси-контракта запрограммирована на запуск delegatecall и перенаправление запроса пользователя к текущей реализации контракта логики.
+
+Прокси-контракт по умолчанию является неизменяемым, но можно создавать новые контракты логики с обновленной бизнес-логикой. Выполнение обновления сводится к изменению адреса контракта логики, на который ссылается прокси-контракт.
+
+Указав прокси-контракту на новый контракт логики, вы изменяете код, который выполняется, когда пользователи вызывают функцию прокси-контракта. Это позволяет нам обновлять логику контракта, не прося пользователей взаимодействовать с новым контрактом.
+
+Прокси-шаблоны — популярный метод обновления смарт-контрактов, поскольку они устраняют трудности, связанные с миграцией контрактов. Однако прокси-шаблоны сложнее в использовании и могут привести к критическим ошибкам, таким как [столкновения селекторов функций](https://medium.com/nomic-foundation-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357), при неправильном использовании.
+
+[Подробнее о прокси-шаблонах](https://blog.openzeppelin.com/proxy-patterns/).
+
+### Механизм обновления №4: шаблон «Стратегия» {#strategy-pattern}
+
+Этот метод основан на [шаблоне «Стратегия»](https://en.wikipedia.org/wiki/Strategy_pattern), который поощряет создание программ, взаимодействующих с другими программами для реализации определенных функций. Применение шаблона «Стратегия» к разработке на Ethereum будет означать создание смарт-контракта, который вызывает функции из других контрактов.
+
+Основной контракт в этом случае содержит основную бизнес-логику, но взаимодействует с другими смарт-контрактами («сателлитными контрактами») для выполнения определенных функций. Этот основной контракт также хранит адрес каждого сателлитного контракта и может переключаться между различными реализациями сателлитного контракта.
+
+Вы можете создать новый сателлитный контракт и настроить основной контракт с новым адресом. Это позволяет вам изменять _стратегии_ (т. е. реализовывать новую логику) для смарт-контракта.
+
+Хотя шаблон «Стратегия» похож на ранее обсуждавшийся прокси-шаблон, он отличается тем, что основной контракт, с которым взаимодействуют пользователи, содержит бизнес-логику. Использование этого шаблона дает вам возможность вносить ограниченные изменения в смарт-контракт, не затрагивая основную инфраструктуру.
+
+Основным недостатком является то, что этот шаблон в основном полезен для внедрения незначительных обновлений. Кроме того, если основной контракт скомпрометирован (например, в результате взлома), вы не сможете использовать этот метод обновления.
+
+### Механизм обновления №5: алмазный шаблон (diamond pattern) {#diamond-pattern}
+
+Алмазный шаблон (diamond pattern) можно считать усовершенствованием прокси-шаблона. Алмазные шаблоны (diamond patterns) отличаются от прокси-шаблонов тем, что алмазный прокси-контракт может делегировать вызовы функций более чем одному контракту логики.
+
+Контракты логики в алмазном шаблоне (diamond pattern) известны как _фасеты_ (facets). Чтобы заставить работать алмазный шаблон (diamond pattern), вам нужно создать сопоставление в прокси-контракте, которое связывает [селекторы функций](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector) с адресами различных фасетов.
+
+Когда пользователь совершает вызов функции, прокси-контракт проверяет сопоставление, чтобы найти фасет, ответственный за выполнение этой функции. Затем он вызывает `delegatecall` (используя резервную функцию (fallback function)) и перенаправляет вызов в соответствующий контракт логики.
+
+Шаблон обновления «Алмаз» (diamond) имеет некоторые преимущества перед традиционными шаблонами обновления прокси:
+
+1. Он позволяет обновлять небольшую часть контракта, не изменяя весь код. Использование прокси-шаблона для обновлений требует создания совершенно нового контракта логики, даже для незначительных обновлений.
+
+2. Все смарт-контракты (включая контракты логики, используемые в прокси-шаблонах) имеют ограничение по размеру в 24 КБ, что может быть ограничением, особенно для сложных контрактов, требующих большего количества функций. Алмазный шаблон (diamond pattern) позволяет легко решить эту проблему, разделив функции между несколькими контрактами логики.
+
+3. Прокси-шаблоны используют универсальный подход к контролю доступа. Субъект, имеющий доступ к функциям обновления, может изменить _весь_ контракт. Но алмазный шаблон (diamond pattern) позволяет использовать модульный подход к разрешениям, при котором вы можете ограничить права субъектов на обновление определенных функций в смарт-контракте.
+
+[Подробнее об алмазном шаблоне (diamond pattern)](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard?s=w).
+
+## Плюсы и минусы обновления смарт-контрактов {#pros-and-cons-of-upgrading-smart-contracts}
+
+| Преимущества | Недостатки |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Обновление смарт-контракта может облегчить исправление уязвимостей, обнаруженных на этапе после развертывания. | Обновление смарт-контрактов сводит на нет идею неизменяемости кода, что имеет последствия для децентрализации и безопасности. |
+| Разработчики могут использовать обновления логики для добавления новых функций в децентрализованные приложения. | Пользователи должны доверять разработчикам в том, что они не будут произвольно изменять смарт-контракты. |
+| Обновления смарт-контрактов могут повысить безопасность для конечных пользователей, поскольку ошибки можно быстро исправлять. | Программирование функциональности обновления в смарт-контракты добавляет еще один уровень сложности и увеличивает вероятность критических недостатков. |
+| Обновления контрактов дают разработчикам больше возможностей для экспериментов с различными функциями и улучшения децентрализованных приложений с течением времени. | Возможность обновления смарт-контрактов может побудить разработчиков быстрее запускать проекты, не проводя должной проверки на этапе разработки. |
+| | Небезопасный контроль доступа или централизация в смарт-контрактах могут облегчить злоумышленникам выполнение несанкционированных обновлений. |
+
+## Вопросы, которые следует учитывать при обновлении смарт-контрактов {#considerations-for-upgrading-smart-contracts}
+
+1. Используйте безопасные механизмы контроля доступа/авторизации для предотвращения несанкционированных обновлений смарт-контрактов, особенно при использовании прокси-шаблонов, шаблонов стратегий или разделения данных. Примером является ограничение доступа к функции обновления, чтобы ее мог вызывать только владелец контракта.
+
+2. Обновление смарт-контрактов — это сложная деятельность, требующая высокого уровня осмотрительности для предотвращения появления уязвимостей.
+
+3. Уменьшите необходимость в доверии за счет децентрализации процесса внедрения обновлений. Возможные стратегии включают использование [контракта кошелька с мультиподписью](/developers/docs/smart-contracts/#multisig) для контроля обновлений или требование к [членам DAO](/dao/) голосовать за утверждение обновления.
+
+4. Помните о затратах, связанных с обновлением контрактов. Например, копирование состояния (например, балансов пользователей) из старого контракта в новый во время миграции контракта может потребовать более одной транзакции, что означает более высокую плату за газ.
+
+5. Рассмотрите возможность внедрения **временных замков (timelocks)** для защиты пользователей. Временной замок (timelock) — это задержка, применяемая к изменениям в системе. Временные замки (timelocks) можно комбинировать с системой управления с мультиподписью для контроля обновлений: если предлагаемое действие достигает необходимого порога одобрения, оно не выполняется до истечения заранее определенного периода задержки.
+
+Временные замки (timelocks) дают пользователям время выйти из системы, если они не согласны с предлагаемым изменением (например, обновлением логики или новыми схемами комиссий). Без временных замков (timelocks) пользователям приходится доверять разработчикам в том, что они не будут вносить произвольные изменения в смарт-контракт без предварительного уведомления. Недостаток здесь в том, что временные замки (timelocks) ограничивают возможность быстрого исправления уязвимостей.
+
+## Ресурсы {#resources}
+
+**OpenZeppelin Upgrades Plugins — _набор инструментов для развертывания и защиты обновляемых смарт-контрактов._**
+
+- [GitHub](https://github.com/OpenZeppelin/openzeppelin-upgrades)
+- [Документация](https://docs.openzeppelin.com/upgrades)
+
+## Руководства {#tutorials}
+
+- [Обновление ваших смарт-контрактов | Учебное пособие на YouTube](https://www.youtube.com/watch?v=bdXJmWajZRY) от Патрика Коллинза
+- [Учебное пособие по миграции смарт-контрактов Ethereum](https://medium.com/coinmonks/ethereum-smart-contract-migration-13f6f12539bd) от Остина Гриффита
+- [Использование прокси-шаблона UUPS для обновления смарт-контрактов](https://blog.logrocket.com/author/praneshas/) от Пранеша А.С.
+- [Учебное пособие по Web3: написание обновляемого смарт-контракта (прокси) с использованием OpenZeppelin](https://dev.to/yakult/tutorial-write-upgradeable-smart-contract-proxy-contract-with-openzeppelin-1916) от fangjun.eth
+
+## Дополнительные материалы {#further-reading}
+
+- [Состояние обновлений смарт-контрактов](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/) от Сантьяго Палладино
+- [Несколько способов обновить смарт-контракт Solidity](https://cryptomarketpool.com/multiple-ways-to-upgrade-a-solidity-smart-contract/) — блог Crypto Market Pool
+- [Обучение: обновление смарт-контрактов](https://docs.openzeppelin.com/learn/upgrading-smart-contracts) — документация OpenZeppelin
+- [Прокси-шаблоны для возможности обновления контрактов Solidity: Transparent и UUPS прокси](https://mirror.xyz/0xB38709B8198d147cc9Ff9C133838a044d78B064B/M7oTptQkBGXxox-tk9VJjL66E1V8BUF0GF79MMK4YG0) от Навина Саху
+- [Как работают обновления Diamond](https://dev.to/mudgen/how-diamond-upgrades-work-417j) от Ника Маджа
diff --git a/public/content/translations/ru/developers/docs/smart-contracts/verifying/index.md b/public/content/translations/ru/developers/docs/smart-contracts/verifying/index.md
new file mode 100644
index 00000000000..dae808adfd2
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/smart-contracts/verifying/index.md
@@ -0,0 +1,113 @@
+---
+title: "Проверка смарт-контрактов"
+description: "Обзор верификации исходного кода для смарт-контрактов Ethereum"
+lang: ru
+---
+
+[Смарт-контракты](/developers/docs/smart-contracts/) спроектированы как «бездоверительные», что означает, что пользователям не нужно доверять третьим лицам (например, разработчикам и компаниям) перед взаимодействием с контрактом. В качестве обязательного условия для бездоверительности пользователи и другие разработчики должны иметь возможность верифицировать исходный код смарт-контракта. Верификация исходного кода гарантирует пользователям и разработчикам, что опубликованный код контракта является тем же кодом, который выполняется по адресу контракта в блокчейне Ethereum.
+
+Важно различать «верификацию исходного кода» и «[формальную верификацию](/developers/docs/smart-contracts/formal-verification/)». Верификация исходного кода, которая будет подробно объяснена ниже, относится к проверке того, что данный исходный код смарт-контракта на языке высокого уровня (например, Solidity) компилируется в тот же байт-код, который должен выполняться по адресу контракта. Однако формальная верификация описывает проверку правильности смарт-контракта, то есть того, что контракт ведет себя так, как ожидалось. Хотя это зависит от контекста, верификация контракта обычно относится к верификации исходного кода.
+
+## Что такое верификация исходного кода? {#what-is-source-code-verification}
+
+Перед развертыванием смарт-контракта в [виртуальной машине Ethereum (EVM)](/developers/docs/evm/) разработчики [компилируют](/developers/docs/smart-contracts/compiling/) исходный код контракта — инструкции, [написанные на Solidity](/developers/docs/smart-contracts/languages/) или другом высокоуровневом языке программирования, — в байт-код. Поскольку EVM не может интерпретировать высокоуровневые инструкции, компиляция исходного кода в байт-код (т. е. низкоуровневые машинные инструкции) необходима для выполнения логики контракта в EVM.
+
+Верификация исходного кода — это сравнение исходного кода смарт-контракта и скомпилированного байт-кода, использованного при создании контракта, для обнаружения любых различий. Верификация смарт-контрактов важна, потому что рекламируемый код контракта может отличаться от того, что работает в блокчейне.
+
+Верификация смарт-контракта позволяет исследовать, что делает контракт, с помощью языка более высокого уровня, на котором он написан, без необходимости читать машинный код. Функции, значения и обычно имена переменных и комментарии остаются такими же, как в исходном коде, который компилируется и развертывается. Это значительно облегчает чтение кода. Верификация исходного кода также предусматривает документирование кода, чтобы конечные пользователи знали, для чего предназначен смарт-контракт.
+
+### Что такое полная верификация? {#full-verification}
+
+Есть некоторые части исходного кода, которые не влияют на скомпилированный байт-код, например комментарии или имена переменных. Это означает, что два исходных кода с разными именами переменных и разными комментариями могут верифицировать один и тот же контракт. Таким образом, злоумышленник может добавить вводящие в заблуждение комментарии или дать неверные имена переменных в исходном коде, и контракт будет верифицирован с исходным кодом, отличным от оригинального.
+
+Этого можно избежать, добавив к байт-коду дополнительные данные, которые будут служить _криптографической гарантией_ точности исходного кода и _отпечатком_ информации о компиляции. Необходимая информация находится в [метаданных контракта Solidity](https://docs.soliditylang.org/en/v0.8.15/metadata.html), и хэш этого файла добавляется к байт-коду контракта. Вы можете увидеть это в действии на [площадке для работы с метаданными](https://playground.sourcify.dev)
+
+Файл метаданных содержит информацию о компиляции контракта, включая исходные файлы и их хэши. Это означает, что если изменятся какие-либо параметры компиляции или даже один байт в одном из исходных файлов, файл метаданных изменится. Следовательно, хэш файла метаданных, который добавляется к байт-коду, также изменяется. Это означает, что если байт-код контракта + добавленный хэш метаданных совпадают с заданным исходным кодом и настройками компиляции, мы можем быть уверены, что это точно тот же исходный код, который использовался при первоначальной компиляции, и в нем не отличается ни один байт.
+
+Этот тип верификации, использующий хэш метаданных, называется **«[полной верификацией](https://docs.sourcify.dev/docs/full-vs-partial-match/)»** (также «идеальной верификацией»). Если хэши метаданных не совпадают или не учитываются при верификации, это будет «частичное совпадение», что в настоящее время является более распространенным способом верификации контрактов. Без полной верификации возможно [внедрение вредоносного кода](https://samczsun.com/hiding-in-plain-sight/), который не будет отражен в верифицированном исходном коде. Большинство разработчиков не знают о полной верификации и не сохраняют файл метаданных своей компиляции, поэтому частичная верификация до сих пор является методом верификации контрактов де-факто.
+
+## Почему важна верификация исходного кода? {#importance-of-source-code-verification}
+
+### Бездоверительность {#trustlessness}
+
+Бездоверительность — это, пожалуй, самая главная предпосылка для смарт-контрактов и [децентрализованных приложений (dapps)](/developers/docs/dapps/). Смарт-контракты являются «неизменяемыми» и не могут быть изменены; контракт будет выполнять только ту бизнес-логику, которая определена в коде на момент развертывания. Это означает, что разработчики и предприятия не могут вмешиваться в код контракта после его развертывания в Ethereum.
+
+Чтобы смарт-контракт был бездоверительным, его код должен быть доступен для независимой верификации. Хотя скомпилированный байт-код для каждого смарт-контракта общедоступен в блокчейне, низкоуровневый язык трудно понять как разработчикам, так и пользователям.
+
+Проекты снижают необходимость в доверии, публикуя исходный код своих контрактов. Но это приводит к другой проблеме: трудно проверить, что опубликованный исходный код соответствует байт-коду контракта. В этом случае ценность бездоверительности теряется, потому что пользователям приходится доверять разработчикам в том, что они не изменят бизнес-логику контракта (т. е. изменив байт-код) перед его развертыванием в блокчейне.
+
+Инструменты верификации исходного кода предоставляют гарантии того, что файлы исходного кода смарт-контракта соответствуют ассемблерному коду. Результатом является бездоверительная экосистема, в которой пользователи не доверяют слепо третьим сторонам, а верифицируют код перед внесением средств в контракт.
+
+### Безопасность пользователя {#user-safety}
+
+В смарт-контрактах на кону обычно стоят большие деньги. Это требует более высоких гарантий безопасности и верификации логики смарт-контракта перед его использованием. Проблема в том, что недобросовестные разработчики могут обмануть пользователей, вставив в смарт-контракт вредоносный код. Без верификации вредоносные смарт-контракты могут иметь [бэкдоры](https://www.trustnodes.com/2018/11/10/concerns-rise-over-backdoored-smart-contracts), спорные механизмы контроля доступа, эксплуатируемые уязвимости и другие вещи, которые ставят под угрозу безопасность пользователей и остаются незамеченными.
+
+Публикация файлов исходного кода смарт-контракта облегчает заинтересованным сторонам, таким как аудиторы, оценку контракта на предмет потенциальных векторов атаки. Когда несколько сторон независимо друг от друга верифицируют смарт-контракт, пользователи получают более надежные гарантии его безопасности.
+
+## Как верифицировать исходный код для смарт-контрактов Ethereum {#source-code-verification-for-ethereum-smart-contracts}
+
+[Развертывание смарт-контракта в Ethereum](/developers/docs/smart-contracts/deploying/) требует отправки транзакции с полезной нагрузкой данных (скомпилированным байт-кодом) на специальный адрес. Полезная нагрузка данных генерируется путем компиляции исходного кода, а также [аргументы конструктора](https://docs.soliditylang.org/en/v0.8.14/contracts.html#constructor) экземпляра контракта, добавляемые к полезной нагрузке данных в транзакции. Компиляция детерминирована, то есть она всегда дает один и тот же результат (т. е. байт-код контракта), если используются одни и те же исходные файлы и параметры компиляции (например, версия компилятора, оптимизатор).
+
+
+
+Верификация смарт-контракта в основном включает в себя следующие шаги:
+
+1. Передача исходных файлов и параметров компиляции в компилятор.
+
+2. Компилятор выводит байт-код контракта
+
+3. Получение байт-кода развернутого контракта по заданному адресу
+
+4. Сравнение развернутого байт-кода с перекомпилированным байт-кодом. Если коды совпадают, контракт верифицируется с заданным исходным кодом и настройками компиляции.
+
+5. Кроме того, если хэши метаданных в конце байт-кода совпадают, это будет полное совпадение.
+
+Обратите внимание, что это упрощенное описание верификации, и существует множество исключений, которые с ним не сработают, например, наличие [неизменяемых переменных](https://docs.sourcify.dev/docs/immutables/).
+
+## Инструменты верификации исходного кода {#source-code-verification-tools}
+
+Традиционный процесс верификации контрактов может быть сложным. Вот почему у нас есть инструменты для верификации исходного кода смарт-контрактов, развернутых в Ethereum. Эти инструменты автоматизируют большую часть верификации исходного кода, а также курируют верифицированные контракты для удобства пользователей.
+
+### Etherscan {#etherscan}
+
+Хотя Etherscan в основном известен как [обозреватель блокчейна Ethereum](/developers/docs/data-and-analytics/block-explorers/), он также предлагает [сервис верификации исходного кода](https://etherscan.io/verifyContract) для разработчиков и пользователей смарт-контрактов.
+
+Etherscan позволяет перекомпилировать байт-код контракта из исходной полезной нагрузки данных (исходный код, адрес библиотеки, настройки компилятора, адрес контракта и т. д.) Если перекомпилированный байт-код связан с байт-кодом (и параметрами конструктора) ончейн-контракта, то [контракт считается верифицированным](https://info.etherscan.com/types-of-contract-verification/).
+
+После верификации исходный код вашего контракта получает метку «Verified» и публикуется на Etherscan, чтобы другие могли его проверить. Он также добавляется в раздел [Verified Contracts](https://etherscan.io/contractsVerified/) — репозиторий смарт-контрактов с верифицированным исходным кодом.
+
+Etherscan — самый используемый инструмент для верификации контрактов. Однако верификация контрактов на Etherscan имеет недостаток: она не сравнивает **хэш метаданных** ончейн-байт-кода и перекомпилированного байт-кода. Поэтому совпадения в Etherscan являются частичными.
+
+[Подробнее о верификации контрактов на Etherscan](https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327).
+
+### Blockscout {#blockscout}
+
+[Blockscout](https://blockscout.com/) — это обозреватель блокчейна с открытым исходным кодом, который также предоставляет [сервис верификации контрактов](https://eth.blockscout.com/contract-verification) для разработчиков и пользователей смарт-контрактов. Как альтернатива с открытым исходным кодом, Blockscout предлагает прозрачность в том, как выполняется верификация, и позволяет сообществу вносить свой вклад в улучшение процесса верификации.
+
+Подобно другим сервисам верификации, Blockscout позволяет вам верифицировать исходный код вашего контракта, перекомпилировав байт-код и сравнив его с развернутым контрактом. После верификации ваш контракт получает статус верификации, а исходный код становится общедоступным для аудита и взаимодействия. Верифицированные контракты также перечислены в [репозитории верифицированных контрактов](https://eth.blockscout.com/verified-contracts) Blockscout для удобного просмотра и поиска.
+
+### Sourcify {#sourcify}
+
+[Sourcify](https://sourcify.dev/#/verifier) — еще один инструмент для верификации контрактов с открытым исходным кодом, который является децентрализованным. Это не обозреватель блоков, он верифицирует контракты только в [различных сетях на базе EVM](https://docs.sourcify.dev/docs/chains). Он действует как публичная инфраструктура, на основе которой другие инструменты могут создавать свои решения, и нацелен на обеспечение более удобного для человека взаимодействия с контрактами с использованием комментариев [ABI](/developers/docs/smart-contracts/compiling/#web-applications) и [NatSpec](https://docs.soliditylang.org/en/v0.8.15/natspec-format.html), содержащихся в файле метаданных.
+
+В отличие от Etherscan, Sourcify поддерживает полные совпадения с хэшем метаданных. Верифицированные контракты обслуживаются в его [публичном репозитории](https://docs.sourcify.dev/docs/repository/) по HTTP и [IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/#what-is-ipfs), которое является децентрализованным [хранилищем с адресацией по содержимому](https://docs.storacha.network/concepts/content-addressing/). Это позволяет получать файл метаданных контракта через IPFS, поскольку добавленный хэш метаданных является хэшем IPFS.
+
+Кроме того, можно также получить файлы исходного кода через IPFS, так как хэши IPFS этих файлов также находятся в метаданных. Контракт можно верифицировать, предоставив файл метаданных и исходные файлы через его API или [пользовательский интерфейс](https://sourcify.dev/#/verifier), или с помощью плагинов. Инструмент мониторинга Sourcify также отслеживает создание контрактов в новых блоках и пытается верифицировать контракты, если их метаданные и исходные файлы опубликованы на IPFS.
+
+[Подробнее о верификации контрактов на Sourcify](https://soliditylang.org/blog/2020/06/25/sourcify-faq/).
+
+### Tenderly {#tenderly}
+
+[Платформа Tenderly](https://tenderly.co/) позволяет разработчикам Web3 создавать, тестировать, отслеживать и эксплуатировать смарт-контракты. Сочетая инструменты отладки с наблюдаемостью и стандартными элементами для создания инфраструктуры, Tenderly помогает разработчикам ускорить разработку смарт-контрактов. Чтобы полностью использовать функции Tenderly, разработчикам необходимо [выполнить верификацию исходного кода](https://docs.tenderly.co/monitoring/contract-verification) с помощью нескольких методов.
+
+Верифицировать контракт можно в частном или публичном порядке. Если верификация частная, смарт-контракт виден только вам (и другим членам вашего проекта). Публичная верификация контракта делает его видимым для всех, кто использует платформу Tenderly.
+
+Вы можете верифицировать свои контракты с помощью [панели управления](https://docs.tenderly.co/contract-verification), [плагина Tenderly для Hardhat](https://docs.tenderly.co/contract-verification/hardhat) или [интерфейса командной строки](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-cli).
+
+При верификации контрактов через панель управления вам необходимо импортировать исходный файл или файл метаданных, сгенерированный компилятором Solidity, адрес/сеть и настройки компилятора.
+
+Использование плагина Tenderly для Hardhat позволяет лучше контролировать процесс верификации с меньшими усилиями, давая вам возможность выбирать между автоматической (без кода) и ручной (на основе кода) верификацией.
+
+## Дополнительные материалы {#further-reading}
+
+- [Верификация исходного кода контракта](https://programtheblockchain.com/posts/2018/01/16/verifying-contract-source-code/)
diff --git a/public/content/translations/ru/developers/docs/standards/index.md b/public/content/translations/ru/developers/docs/standards/index.md
new file mode 100644
index 00000000000..4d8beecbc61
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/index.md
@@ -0,0 +1,59 @@
+---
+title: "Стандарты разработки Ethereum"
+description: "Узнайте о стандартах Ethereum, включая EIP, стандартах токенов, таких как ERC-20 и ERC-721, и соглашениях по разработке."
+lang: ru
+incomplete: true
+---
+
+## Обзор стандартов {#standards-overview}
+
+Сообщество Ethereum приняло множество стандартов, которые помогают поддерживать совместимость проектов (таких как [клиенты Ethereum](/developers/docs/nodes-and-clients/) и кошельки) в разных реализациях, а также обеспечивать, чтобы смарт-контракты и децентрализованные приложения оставались компонуемыми.
+
+Обычно стандарты представляются в виде [Предложений по улучшению Ethereum](/eips/) (EIP), которые обсуждаются членами сообщества в рамках [стандартного процесса](https://eips.ethereum.org/EIPS/eip-1).
+
+- [Введение в EIP](/eips/)
+- [Список EIP](https://eips.ethereum.org/)
+- [Репозиторий EIP на GitHub](https://github.com/ethereum/EIPs)
+- [Доска обсуждений EIP](https://ethereum-magicians.org/c/eips)
+- [Введение в управление Ethereum](/governance/)
+- [Обзор управления Ethereum](https://web.archive.org/web/20201107234050/https://blog.bmannconsulting.com/ethereum-governance/) _31 марта 2019 г. - Борис Манн_
+- [Управление разработкой протокола Ethereum и координация обновления сети](https://hudsonjameson.com/posts/2020-03-23-ethereum-protocol-development-governance-and-network-upgrade-coordination/) _23 марта 2020 г. - Хадсон Джеймсон_
+- [Плейлист со всеми встречами основных разработчиков Ethereum](https://www.youtube.com/@EthereumProtocol) _(плейлист на YouTube)_
+
+## Типы стандартов {#types-of-standards}
+
+Существует 3 типа EIP:
+
+- Трек стандартов: описывает любое изменение, которое влияет на большинство или все реализации Ethereum
+- [Мета-трек](https://eips.ethereum.org/meta): описывает процесс, связанный с Ethereum, или предлагает внести изменения в процесс
+- [Информационный трек](https://eips.ethereum.org/informational): описывает проблему проектирования Ethereum или предоставляет общие рекомендации или информацию сообществу Ethereum
+
+Кроме того, стандартный путь подразделяется на 4 категории:
+
+- [Ядро](https://eips.ethereum.org/core): улучшения, требующие форка для достижения консенсуса
+- [Сеть](https://eips.ethereum.org/networking): улучшения, связанные с devp2p и «облегченным» подпротоколом Ethereum, а также предлагаемые улучшения спецификаций сетевых протоколов Whisper и Swarm.
+- [Интерфейс](https://eips.ethereum.org/interface): улучшения в сфере спецификаций и стандартов API/RPC клиента, а также определенных стандартов на уровне языка, таких как имена методов и ABI контрактов.
+- [ERC](https://eips.ethereum.org/erc): стандарты и соглашения на уровне приложений
+
+Более подробную информацию об этих различных типах и категориях можно найти в [EIP-1](https://eips.ethereum.org/EIPS/eip-1#eip-types)
+
+### Стандарты токенов {#token-standards}
+
+- [ERC-20](/developers/docs/standards/tokens/erc-20/) — стандартный интерфейс для взаимозаменяемых токенов, таких как токены для голосования, токены для стейкинга или виртуальные валюты.
+ - [ERC-223](/developers/docs/standards/tokens/erc-223/) — стандарт взаимозаменяемых токенов, который делает поведение токенов идентичным поведению эфира (ether) и поддерживает обработку передачи токенов на стороне получателей.
+ - [ERC-1363](/developers/docs/standards/tokens/erc-1363/) — расширение интерфейса для токенов ERC-20, которое поддерживает выполнение обратного вызова в контрактах получателя в одной транзакции.
+- [ERC-721](/developers/docs/standards/tokens/erc-721/) — стандартный интерфейс для невзаимозаменяемых токенов, например, свидетельство о праве собственности на произведение искусства или песню.
+ - [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) — стандартизированное событие, которое генерируется при создании/передаче одного или нескольких невзаимозаменяемых токенов с использованием последовательных идентификаторов токенов.
+ - [ERC-4400](https://eips.ethereum.org/EIPS/eip-4400) — расширение интерфейса для роли потребителя EIP-721.
+ - [ERC-4907](https://eips.ethereum.org/EIPS/eip-4907) — добавляет к токенам ERC-721 ограниченную по времени роль с ограниченными разрешениями.
+- [ERC-777](/developers/docs/standards/tokens/erc-777/) — **(НЕ РЕКОМЕНДУЕТСЯ)** стандарт токенов, улучшающий ERC-20.
+- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) — стандарт токенов, который может содержать как взаимозаменяемые, так и невзаимозаменяемые активы.
+- [ERC-4626](/developers/docs/standards/tokens/erc-4626/) — стандарт токенизированного хранилища, предназначенный для оптимизации и унификации технических параметров доходных хранилищ.
+
+Узнайте больше о [стандартах токенов](/developers/docs/standards/tokens/).
+
+## Дополнительные материалы {#further-reading}
+
+- [Предложения по улучшению Ethereum (EIP)](/eips/)
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-1155/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-1155/index.md
new file mode 100644
index 00000000000..d219eaf397c
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-1155/index.md
@@ -0,0 +1,146 @@
+---
+title: "Стандарт мульти-токенов ERC-1155"
+description: "Узнайте о ERC-1155 — стандарте нескольких токенов, который объединяет взаимозаменяемые и невзаимозаменяемые токены в одном контракте."
+lang: ru
+---
+
+## Введение {#introduction}
+
+Стандартный интерфейс для контрактов, которые управляют несколькими типами токенов. Один развернутый контракт может включать любую комбинацию взаимозаменяемых токенов, невзаимозаменяемых токенов или других конфигураций (например, полувзаимозаменяемых токенов).
+
+**Что значит стандарт мульти-токена?**
+
+Идея проста и предназначена для создания интерфейса смарт-контракта, который может представлять и контролировать любое количество токенов взаимозаменяемых и невзаимозаменяемых типов. Таким образом, токен ERC-1155 может выполнять те же функции, что и токены [ERC-20](/developers/docs/standards/tokens/erc-20/) и [ERC-721](/developers/docs/standards/tokens/erc-721/), и даже обе одновременно. Это повышает функциональность стандартов ERC-20 и ERC-721, что делает их более эффективными и исправляет очевидные ошибки реализации.
+
+Токен ERC-1155 полностью описан в [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155).
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем сначала прочитать о [стандартах токенов](/developers/docs/standards/tokens/), [ERC-20](/developers/docs/standards/tokens/erc-20/) и [ERC-721](/developers/docs/standards/tokens/erc-721/).
+
+## Функции и возможности ERC-1155: {#body}
+
+- [Пакетная передача](#batch_transfers): Передача нескольких активов в одном вызове.
+- [Пакетный баланс](#batch_balance): Получение балансов нескольких активов за один вызов.
+- [Пакетное одобрение](#batch_approval): Одобрение всех токенов для одного адреса.
+- [Хуки](#receive_hook): Хук получения токенов.
+- [Поддержка NFT](#nft_support): Если объем эмиссии равен 1, токен считается NFT.
+- [Правила безопасной передачи](#safe_transfer_rule): Набор правил для безопасной передачи.
+
+### Пакетные передачи {#batch-transfers}
+
+Перевод партией работает почти так же, как и обычные ERC-20 переводы. Давайте рассмотрим обычную функцию `transferFrom` стандарта ERC-20:
+
+```solidity
+// ERC-20
+function transferFrom(address from, address to, uint256 value) external returns (bool);
+
+// ERC-1155
+function safeBatchTransferFrom(
+ address _from,
+ address _to,
+ uint256[] calldata _ids,
+ uint256[] calldata _values,
+ bytes calldata _data
+) external;
+```
+
+Единственное различие в ERC-1155 заключается в том, что мы передаем значения в виде массива и также передаем массив идентификаторов. Например, если `ids=[3, 6, 13]` и `values=[100, 200, 5]`, то в результате будут выполнены следующие передачи:
+
+1. Передача 100 токенов с ID 3 от `_from` к `_to`.
+2. Передача 200 токенов с ID 6 от `_from` к `_to`.
+3. Передача 5 токенов с ID 13 от `_from` к `_to`.
+
+В ERC-1155 есть только `transferFrom`, но нет `transfer`. Чтобы использовать ее как обычную функцию `transfer`, просто укажите в качестве адреса отправителя адрес, вызывающий функцию.
+
+### Пакетный баланс {#batch-balance}
+
+Соответствующий вызов `balanceOf` в ERC-20 также имеет парную функцию с поддержкой пакетной обработки. В качестве напоминания версия ERC-20:
+
+```solidity
+// ERC-20
+function balanceOf(address owner) external view returns (uint256);
+
+// ERC-1155
+function balanceOfBatch(
+ address[] calldata _owners,
+ uint256[] calldata _ids
+) external view returns (uint256[] memory);
+```
+
+Даже проще, чем запрос баланса, мы можем получить несколько балансов за один запрос. Мы передаем массив владельцев, а затем массив идентификаторов токенов.
+
+Например, если `_ids=[3, 6, 13]` и `_owners=[0xbeef..., 0x1337..., 0x1111...]`, возвращаемое значение будет:
+
+```solidity
+[
+ balanceOf(0xbeef...),
+ balanceOf(0x1337...),
+ balanceOf(0x1111...)
+]
+```
+
+### Пакетное одобрение {#batch-approval}
+
+```solidity
+// ERC-1155
+function setApprovalForAll(
+ address _operator,
+ bool _approved
+) external;
+
+function isApprovedForAll(
+ address _owner,
+ address _operator
+) external view returns (bool);
+```
+
+Утверждения немного отличаются от ERC-20. Вместо одобрения определенных сумм вы устанавливаете оператора как одобренного или неодобренного с помощью `setApprovalForAll`.
+
+Проверить текущий статус можно с помощью `isApprovedForAll`. Как вы видите, это операция "все или ничего". Вы не можете выбрать количество токенов для утверждения или даже класс токенов.
+
+Это сделано намеренно для простоты. Вы можете одобрить все только для одного адреса.
+
+### Хук получения {#receive-hook}
+
+```solidity
+function onERC1155BatchReceived(
+ address _operator,
+ address _from,
+ uint256[] calldata _ids,
+ uint256[] calldata _values,
+ bytes calldata _data
+) external returns(bytes4);
+```
+
+Благодаря поддержке [EIP-165](https://eips.ethereum.org/EIPS/eip-165), ERC-1155 поддерживает хуки получения только для умных контрактов. Функция-хук должна возвращать предопределенное «магическое» значение типа bytes4, которое задается как:
+
+```solidity
+bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
+```
+
+Когда принимающий контракт возвращает это значение, считается, что контракт принимает передачу и знает, как обрабатывать токены ERC-1155. Отлично, токены больше не будут застревать в контракте!
+
+### Поддержка NFT {#nft-support}
+
+Если объем предложения равен единице, то токен по сути является невзаимозаменяемым (NFT). Как и в стандарте ERC-721, вы можете задать URL метаданных. URL-адрес может считываться и изменяться клиентами, см. [здесь](https://eips.ethereum.org/EIPS/eip-1155#metadata).
+
+### Правило безопасной передачи {#safe-transfer-rule}
+
+Мы уже коснулись нескольких правил безопасного перевода в предыдущих объяснениях. Но давайте взглянем на самые важные из правил:
+
+1. Вызывающий должен иметь разрешение на расходование токенов с адреса `_from` или вызывающий должен быть равен `_from`.
+2. Вызов передачи должен быть отменен, если:
+ 1. адрес `_to` равен 0.
+ 2. длина `_ids` не совпадает с длиной `_values`.
+ 3. любой из балансов держателя(-ей) токена(-ов) из `_ids` меньше соответствующего количества из `_values`, отправляемого получателю.
+ 4. происходит любая другая ошибка.
+
+_Примечание_: все пакетные функции, включая хук, также существуют в версиях без пакетной обработки. Это сделано для эффективности расходования газа, поскольку передача одного актива, скорее всего, останется наиболее распространенным способом. Мы опустили их для простоты объяснения, включая правила безопасной передачи. Названия идентичны, просто уберите слово «Batch».
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-1155: стандарт нескольких токенов](https://eips.ethereum.org/EIPS/eip-1155)
+- [ERC-1155: документация OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/erc1155)
+- [ERC-1155: репозиторий на GitHub](https://github.com/enjin/erc-1155)
+- [Alchemy NFT API](https://www.alchemy.com/docs/reference/nft-api-quickstart)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-1363/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-1363/index.md
new file mode 100644
index 00000000000..f42853a0926
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-1363/index.md
@@ -0,0 +1,213 @@
+---
+title: "Стандарт оплачиваемых токенов ERC-1363"
+description: "ERC-1363 — это интерфейс расширения для токенов ERC-20, который поддерживает выполнение пользовательской логики в контракте получателя после переводов или в контракте расходования после одобрений в рамках одной транзакции."
+lang: ru
+---
+
+## Введение {#introduction}
+
+### Что такое ERC-1363? {#what-is-erc1363}
+
+ERC-1363 — это интерфейс расширения для токенов ERC-20, который поддерживает выполнение пользовательской логики в контракте получателя после переводов или в контракте расходования после одобрений в рамках одной транзакции.
+
+### Отличия от ERC-20 {#erc20-differences}
+
+Стандартные операции ERC-20, такие как `transfer`, `transferFrom` и `approve`, не позволяют выполнять код в контракте получателя или расходования без отдельной транзакции.
+Это усложняет разработку пользовательского интерфейса и препятствует внедрению, поскольку пользователи должны дождаться выполнения первой транзакции, а затем отправить вторую.
+Им также приходится дважды платить за ГАЗ.
+
+ERC-1363 позволяет взаимозаменяемым токенам проще выполнять действия и работать без использования каких-либо внесетевых слушателей.
+Он позволяет выполнить обратный вызов в контракте получателя или расходования после перевода или одобрения в рамках одной транзакции.
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочитать о:
+
+- [Стандарты токенов](/developers/docs/standards/tokens/)
+- [ERC-20](/developers/docs/standards/tokens/erc-20/)
+
+## Тело {#body}
+
+ERC-1363 представляет стандартный API для взаимодействия токенов ERC-20 с умными контрактами после выполнения `transfer`, `transferFrom` или `approve`.
+
+Этот стандарт предоставляет базовую функциональность для перевода токенов, а также позволяет одобрять токены, чтобы их могла потратить другая внутрисетевая третья сторона, а затем выполнить обратный вызов в контракте получателя или расходования.
+
+Существует множество предлагаемых вариантов использования умных контрактов, которые могут принимать обратные вызовы ERC-20.
+
+Примеры:
+
+- **Краудсейлы**: отправленные токены вызывают мгновенное распределение вознаграждения.
+- **Сервисы**: оплата активирует доступ к услуге за один шаг.
+- **Счета**: токены автоматически оплачивают счета.
+- **Подписки**: одобрение годовой ставки активирует подписку в рамках платежа за первый месяц.
+
+По этим причинам он изначально назывался **"оплачиваемым токеном"**.
+
+Поведение обратного вызова еще больше расширяет его полезность, обеспечивая беспрепятственные взаимодействия, такие как:
+
+- **Стейкинг**: переведенные токены вызывают автоматическую блокировку в контракте стейкинга.
+- **Голосование**: полученные токены регистрируют голоса в системе управления.
+- **Обмен**: одобрение токенов активирует логику обмена за один шаг.
+
+Токены ERC-1363 могут использоваться для определенных утилит во всех случаях, когда требуется выполнить обратный вызов после получения перевода или одобрения.
+ERC-1363 также полезен для предотвращения потери или блокировки токенов в умных контрактах путем проверки способности получателя обрабатывать токены.
+
+В отличие от других предложений по расширению ERC-20, ERC-1363 не переопределяет методы ERC-20 `transfer` и `transferFrom` и определяет идентификаторы интерфейсов, которые должны быть реализованы, сохраняя обратную совместимость с ERC-20.
+
+Из [EIP-1363](https://eips.ethereum.org/EIPS/eip-1363):
+
+### Методы {#methods}
+
+Умные контракты, реализующие стандарт ERC-1363, **ДОЛЖНЫ** реализовывать все функции интерфейса `ERC1363`, а также интерфейсов `ERC20` и `ERC165`.
+
+```solidity
+pragma solidity ^0.8.0;
+
+/**
+ * @title ERC1363
+ * @dev Интерфейс расширения для токенов ERC-20, который поддерживает выполнение кода в контракте получателя
+ * после `transfer` или `transferFrom` или кода в контракте расходования после `approve` в рамках одной транзакции.
+ */
+interface ERC1363 is ERC20, ERC165 {
+ /*
+ * ПРИМЕЧАНИЕ: идентификатор ERC-165 для этого интерфейса — 0xb0202a11.
+ * 0xb0202a11 ===
+ * bytes4(keccak256('transferAndCall(address,uint256)')) ^
+ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
+ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
+ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
+ * bytes4(keccak256('approveAndCall(address,uint256)')) ^
+ * bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
+ */
+
+ /**
+ * @dev Перемещает токены в количестве `value` со счета вызывающего на `to`
+ * и затем вызывает `ERC1363Receiver::onTransferReceived` на `to`.
+ * @param to Адрес, на который переводятся токены.
+ * @param value Количество токенов для перевода.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function transferAndCall(address to, uint256 value) external returns (bool);
+
+ /**
+ * @dev Перемещает токены в количестве `value` со счета вызывающего на `to`
+ * и затем вызывает `ERC1363Receiver::onTransferReceived` на `to`.
+ * @param to Адрес, на который переводятся токены.
+ * @param value Количество токенов для перевода.
+ * @param data Дополнительные данные без указанного формата, отправляемые при вызове `to`.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
+
+ /**
+ * @dev Перемещает токены в количестве `value` из `from` в `to`, используя механизм разрешений,
+ * и затем вызывает `ERC1363Receiver::onTransferReceived` в `to`.
+ * @param from Адрес, с которого отправляются токены.
+ * @param to Адрес, на который переводятся токены.
+ * @param value Количество токенов для перевода.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
+
+ /**
+ * @dev Перемещает токены в количестве `value` из `from` в `to`, используя механизм разрешений,
+ * и затем вызывает `ERC1363Receiver::onTransferReceived` в `to`.
+ * @param from Адрес, с которого отправляются токены.
+ * @param to Адрес, на который переводятся токены.
+ * @param value Количество токенов для перевода.
+ * @param data Дополнительные данные без указанного формата, отправляемые при вызове `to`.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
+
+ /**
+ * @dev Устанавливает количество токенов `value` в качестве разрешения для `spender` на токены вызывающего,
+ * а затем вызывает `ERC1363Spender::onApprovalReceived` на `spender`.
+ * @param spender Адрес, который будет тратить средства.
+ * @param value Количество токенов, которое будет потрачено.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function approveAndCall(address spender, uint256 value) external returns (bool);
+
+ /**
+ * @dev Устанавливает количество токенов `value` в качестве разрешения для `spender` на токены вызывающего,
+ * а затем вызывает `ERC1363Spender::onApprovalReceived` на `spender`.
+ * @param spender Адрес, который будет тратить средства.
+ * @param value Количество токенов, которое будет потрачено.
+ * @param data Дополнительные данные без указанного формата, отправляемые при вызове `spender`.
+ * @return Логическое значение, указывающее, что операция прошла успешно, если не возникло исключение.
+ */
+ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
+}
+
+interface ERC20 {
+ event Transfer(address indexed from, address indexed to, uint256 value);
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+ function transfer(address to, uint256 value) external returns (bool);
+ function transferFrom(address from, address to, uint256 value) external returns (bool);
+ function approve(address spender, uint256 value) external returns (bool);
+ function totalSupply() external view returns (uint256);
+ function balanceOf(address account) external view returns (uint256);
+ function allowance(address owner, address spender) external view returns (uint256);
+}
+
+interface ERC165 {
+ function supportsInterface(bytes4 interfaceId) external view returns (bool);
+}
+```
+
+Умный контракт, который хочет принимать токены ERC-1363 через `transferAndCall` или `transferFromAndCall`, **ДОЛЖЕН** реализовывать интерфейс `ERC1363Receiver`:
+
+```solidity
+/**
+ * @title ERC1363Receiver
+ * @dev Интерфейс для любого контракта, который хочет поддерживать `transferAndCall` или `transferFromAndCall` от контрактов токенов ERC-1363.
+ */
+interface ERC1363Receiver {
+ /**
+ * @dev Эта функция вызывается всякий раз, когда токены ERC-1363 переводятся в этот контракт с помощью `ERC1363::transferAndCall` или `ERC1363::transferFromAndCall`
+ * оператором `operator` от `from`.
+ *
+ * ПРИМЕЧАНИЕ: чтобы принять перевод, эта функция должна вернуть
+ * `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`
+ * (т. е. 0x88a7ca5c или свой собственный селектор функции).
+ *
+ * @param operator Адрес, который вызвал функцию `transferAndCall` или `transferFromAndCall`.
+ * @param from Адрес, с которого были переведены токены.
+ * @param value Количество переведенных токенов.
+ * @param data Дополнительные данные без указанного формата.
+ * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))`, если перевод разрешен, если не возникло исключение.
+ */
+ function onTransferReceived(address operator, address from, uint256 value, bytes calldata data) external returns (bytes4);
+}
+```
+
+Умный контракт, который хочет принимать токены ERC-1363 через `approveAndCall`, **ДОЛЖЕН** реализовывать интерфейс `ERC1363Spender`:
+
+```solidity
+/**
+ * @title ERC1363Spender
+ * @dev Интерфейс для любого контракта, который хочет поддерживать `approveAndCall` от контрактов токенов ERC-1363.
+ */
+interface ERC1363Spender {
+ /**
+ * @dev Эта функция вызывается всякий раз, когда `owner` токенов ERC-1363 одобряет этот контракт через `ERC1363::approveAndCall`
+ * для траты своих токенов.
+ *
+ * ПРИМЕЧАНИЕ: чтобы принять одобрение, эта функция должна вернуть
+ * `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`
+ * (т. е. 0x7b04a2d0 или свой собственный селектор функции).
+ *
+ * @param owner Адрес, который вызвал функцию `approveAndCall` и ранее владел токенами.
+ * @param value Количество токенов, которое будет потрачено.
+ * @param data Дополнительные данные без указанного формата.
+ * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))`, если одобрение разрешено, если не возникло исключение.
+ */
+ function onApprovalReceived(address owner, uint256 value, bytes calldata data) external returns (bytes4);
+}
+```
+
+## Дополнительные материалы {#further-reading}
+
+- [ERC-1363: Стандарт оплачиваемых токенов](https://eips.ethereum.org/EIPS/eip-1363)
+- [ERC-1363: репозиторий GitHub](https://github.com/vittominacori/erc1363-payable-token)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-20/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-20/index.md
new file mode 100644
index 00000000000..1b75c7ee41a
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-20/index.md
@@ -0,0 +1,186 @@
+---
+title: "Стандарт токенов ERC-20"
+description: "Узнайте об ERC-20, стандарте для взаимозаменяемых токенов на Ethereum, который обеспечивает совместимость приложений для токенов."
+lang: ru
+---
+
+## Введение {#introduction}
+
+**Что такое токен?**
+
+Токены в Ethereum могут представлять практически все, что угодно:
+
+- баллы репутации на онлайн-платформе
+- навыки персонажа в игре
+- финансовые активы, такие как доля в компании
+- фиатная валюта, как доллар США
+- унция золота
+- и многое другое...
+
+Такая важная функция Ethereum должна обрабатываться надежным стандартом, верно? Именно эту роль выполняет ERC-20. Этот стандарт позволяет разработчикам создавать приложения для токенов, которые совместимы с другими продуктами и услугами. Стандарт ERC-20 также используется для предоставления дополнительной функциональности [эфиру](/glossary/#ether).
+
+**Что такое ERC-20?**
+
+ERC-20 вводит стандарт для взаимозаменяемых токенов, другими словами, они обладают свойством, которое делает каждый токен точно таким же (по типу и ценности), как и другой токен. Например, токен ERC-20 действует точно так же, как ETH, означая, что 1 токен всегда равен и всегда будет равен всем остальным токенам.
+
+## Предварительные условия {#prerequisites}
+
+- [Аккаунты](/developers/docs/accounts)
+- [Смарт-контракты](/developers/docs/smart-contracts/)
+- [Стандарты токенов](/developers/docs/standards/tokens/)
+
+## Тело {#body}
+
+ERC-20 (Ethereum Request for Comments 20), предложенный Фабианом Фогельстеллером в ноябре 2015 года, является стандартом токенов, который реализует API для токенов в смарт-контрактах.
+
+Примеры функциональности, которую предоставляет ERC-20:
+
+- перевод токенов с одного аккаунта на другой
+- узнать текущий баланс токенов на счету
+- узнать количество доступных токенов в сети
+- подтвердить, может ли сумма токена со счета быть потрачена аккаунтом третьей стороны
+
+Если Смарт-контракт реализует следующие методы и события, его можно назвать контрактом ERC-20 токенов, и после развертывания он будет отвечать за отслеживание созданных токенов в Ethereum.
+
+Из [EIP-20](https://eips.ethereum.org/EIPS/eip-20):
+
+### Методы {#methods}
+
+```solidity
+function name() public view returns (string)
+function symbol() public view returns (string)
+function decimals() public view returns (uint8)
+function totalSupply() public view returns (uint256)
+function balanceOf(address _owner) public view returns (uint256 balance)
+function transfer(address _to, uint256 _value) public returns (bool success)
+function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
+function approve(address _spender, uint256 _value) public returns (bool success)
+function allowance(address _owner, address _spender) public view returns (uint256 remaining)
+```
+
+### События {#events}
+
+```solidity
+event Transfer(address indexed _from, address indexed _to, uint256 _value)
+event Approval(address indexed _owner, address indexed _spender, uint256 _value)
+```
+
+### Примеры {#web3py-example}
+
+Давайте разберемся почему Стандарт настолько важен, чтобы упростить для нас проверку любого контракта токена ERC-20 в Ethereum.
+Нам просто нужен двоичный интерфейс приложения контракта (ABI) для создания интерфейса для любого токена ERC-20. Как вы можете увидеть ниже, мы будем использовать упрощенный ABI, чтобы сделать пример простым.
+
+#### Пример Web3.py {#web3py-example}
+
+Во-первых, убедитесь, что вы установили библиотеку Python [Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation):
+
+```
+pip install web3
+```
+
+```python
+from web3 import Web3
+
+
+w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))
+
+dai_token_addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # DAI
+weth_token_addr = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" # Обернутый эфир (WETH)
+
+acc_address = "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11" # Uniswap V2: DAI 2
+
+# Это упрощенный двоичный интерфейс приложения (ABI) контракта токена ERC-20.
+# Он будет предоставлять только методы: balanceOf(address), decimals(), symbol() и totalSupply()
+simplified_abi = [
+ {
+ 'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}],
+ 'name': 'balanceOf',
+ 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'decimals',
+ 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'symbol',
+ 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'totalSupply',
+ 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ }
+]
+
+dai_contract = w3.eth.contract(address=w3.to_checksum_address(dai_token_addr), abi=simplified_abi)
+symbol = dai_contract.functions.symbol().call()
+decimals = dai_contract.functions.decimals().call()
+totalSupply = dai_contract.functions.totalSupply().call() / 10**decimals
+addr_balance = dai_contract.functions.balanceOf(acc_address).call() / 10**decimals
+
+# DAI
+print("===== %s =====" % symbol)
+print("Общее предложение:", totalSupply)
+print("Баланс адреса:", addr_balance)
+
+weth_contract = w3.eth.contract(address=w3.to_checksum_address(weth_token_addr), abi=simplified_abi)
+symbol = weth_contract.functions.symbol().call()
+decimals = weth_contract.functions.decimals().call()
+totalSupply = weth_contract.functions.totalSupply().call() / 10**decimals
+addr_balance = weth_contract.functions.balanceOf(acc_address).call() / 10**decimals
+
+# WETH
+print("===== %s =====" % symbol)
+print("Общее предложение:", totalSupply)
+print("Баланс адреса:", addr_balance)
+```
+
+## Известные проблемы {#erc20-issues}
+
+### Проблема с получением токенов ERC-20 {#reception-issue}
+
+**По состоянию на 20.06.2024 из-за этой проблемы было потеряно токенов ERC-20 на сумму не менее 83 656 418 долларов США. Обратите внимание, что чистая реализация ERC-20 подвержена этой проблеме, если вы не примените набор дополнительных ограничений поверх стандарта, перечисленных ниже.**
+
+Когда токены ERC-20 отправляются на умный контракт, который не предназначен для обработки токенов ERC-20, эти токены могут быть безвозвратно утеряны. Это происходит потому, что у принимающего контракта нет функциональности для распознавания входящих токенов или реагирования на них, и в стандарте ERC-20 нет механизма для уведомления принимающего контракта о входящих токенах. Эта проблема проявляется в основном следующими способами:
+
+1. Механизм перевода токенов
+
+- Токены ERC-20 переводятся с помощью функций transfer или transferFrom
+ - Когда пользователь отправляет токены на адрес контракта с помощью этих функций, токены переводятся независимо от того, предназначен ли принимающий контракт для их обработки
+
+2. Отсутствие уведомления
+ - Принимающий контракт не получает уведомления или обратного вызова о том, что на него были отправлены токены
+ - Если в принимающем контракте отсутствует механизм для обработки токенов (например, резервная функция или специальная функция для управления приемом токенов), токены фактически застревают на адресе контракта
+3. Отсутствие встроенной обработки
+ - Стандарт ERC-20 не включает обязательную функцию для реализации принимающими контрактами, что приводит к ситуации, когда многие контракты не могут должным образом управлять входящими токенами
+
+**Возможные решения**
+
+Хотя полностью предотвратить эту проблему с ERC-20 невозможно, существуют методы, которые позволяют значительно снизить вероятность потери токенов для конечного пользователя:
+
+- Наиболее распространенная проблема возникает, когда пользователь отправляет токены на адрес самого контракта токена (например, USDT, депонированный на адрес контракта токена USDT). Рекомендуется ограничить функцию `transfer(..)` , чтобы отменять такие попытки перевода. Рассмотрите возможность добавления проверки `require(_to != address(this));` в реализацию функции `transfer(..)`.
+- Функция `transfer(..)` в целом не предназначена для внесения токенов на контракты. `approve(..) и шаблон `transferFrom(..)`используется для внесения токенов ERC-20 на контракты. Можно ограничить функцию перевода, чтобы запретить с ее помощью вносить токены на любые контракты, однако это может нарушить совместимость с контрактами, которые предполагают, что токены могут быть депонированы на контракты с помощью функции`trasnfer(..)` (например, пулы ликвидности Uniswap).
+- Всегда предполагайте, что токены ERC-20 могут оказаться в вашем контракте, даже если ваш контракт не должен их получать. Не существует способа предотвратить или отклонить случайные пополнения на стороне получателя. Рекомендуется реализовать функцию, которая позволит извлекать случайно депонированные токены ERC-20.
+- Рассмотрите возможность использования альтернативных стандартов токенов.
+
+В результате этой проблемы появились некоторые альтернативные стандарты, такие как [ERC-223](/developers/docs/standards/tokens/erc-223) или [ERC-1363](/developers/docs/standards/tokens/erc-1363).
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-20: Стандарт токенов ERC-20](https://eips.ethereum.org/EIPS/eip-20)
+- [OpenZeppelin - Токены](https://docs.openzeppelin.com/contracts/3.x/tokens#ERC20)
+- [OpenZeppelin - Реализация ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)
+- [Alchemy - Руководство по токенам ERC20 на Solidity](https://www.alchemy.com/overviews/erc20-solidity)
+
+## Другие стандарты взаимозаменяемых токенов {#fungible-token-standards}
+
+- [ERC-223](/developers/docs/standards/tokens/erc-223)
+- [ERC-1363](/developers/docs/standards/tokens/erc-1363)
+- [ERC-777](/developers/docs/standards/tokens/erc-777)
+- [ERC-4626 - Токенизированные хранилища](/developers/docs/standards/tokens/erc-4626)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-223/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-223/index.md
new file mode 100644
index 00000000000..6423c20441f
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-223/index.md
@@ -0,0 +1,198 @@
+---
+title: "Стандарт токенов ERC-223"
+description: "Обзор стандарта взаимозаменяемых токенов ERC-223, принципы его работы и сравнение с ERC-20."
+lang: ru
+---
+
+## Введение {#introduction}
+
+### Что такое ERC-223? {#what-is-erc223}
+
+ERC-223 — это стандарт для взаимозаменяемых токенов, похожий на стандарт ERC-20. Ключевое отличие заключается в том, что ERC-223 определяет не только API токена, но и логику перевода токенов от отправителя к получателю. Он вводит модель коммуникации, которая позволяет обрабатывать переводы токенов на стороне получателя.
+
+### Отличия от ERC-20 {#erc20-differences}
+
+ERC-223 устраняет некоторые ограничения ERC-20 и вводит новый метод взаимодействия между контрактом токена и контрактом, который получает токены. Есть несколько вещей, которые возможны с ERC-223, но не с ERC-20:
+
+- Обработка перевода токенов на стороне получателя: получатели могут обнаружить, что токен ERC-223 зачисляется.
+- Отклонение неправильно отправленных токенов: если пользователь отправляет токены ERC-223 на контракт, который не предназначен для их получения, контракт может отклонить транзакцию, предотвращая потерю токенов.
+- Метаданные в переводах: токены ERC-223 могут включать метаданные, что позволяет прикреплять произвольную информацию к транзакциям с токенами.
+
+## Предварительные условия {#prerequisites}
+
+- [Аккаунты](/developers/docs/accounts)
+- [Смарт-контракты](/developers/docs/smart-contracts/)
+- [Стандарты токенов](/developers/docs/standards/tokens/)
+- [ERC-20](/developers/docs/standards/tokens/erc-20/)
+
+## Тело {#body}
+
+ERC-223 — это стандарт токенов, который реализует API для токенов в смарт-контрактах. Он также объявляет API для контрактов, которые должны получать токены ERC-223. Контракты, которые не поддерживают API получателя ERC-223, не могут получать токены ERC-223, что предотвращает ошибку пользователя.
+
+Если смарт-контракт реализует следующие методы и события, его можно назвать контрактом токена, совместимым с ERC-223. После развертывания он
+будет отвечать за отслеживание созданных токенов в Ethereum.
+
+Контракт не обязан иметь только эти функции, и разработчик может добавить в него любую другую функцию из разных стандартов токенов. Например, функции `approve` и `transferFrom` не являются частью стандарта ERC-223, но они могут быть реализованы при необходимости.
+
+Из [EIP-223](https://eips.ethereum.org/EIPS/eip-223):
+
+### Методы {#methods}
+
+Токен ERC-223 должен включать следующие методы:
+
+```solidity
+function name() public view returns (string)
+function symbol() public view returns (string)
+function decimals() public view returns (uint8)
+function totalSupply() public view returns (uint256)
+function balanceOf(address _owner) public view returns (uint256 balance)
+function transfer(address _to, uint256 _value) public returns (bool success)
+function transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success)
+```
+
+Контракт, который должен получать токены ERC-223, должен иметь в себе следующий метод:
+
+```solidity
+function tokenReceived(address _from, uint _value, bytes calldata _data)
+```
+
+Если токены ERC-223 отправляются на контракт, который не реализует функцию `tokenReceived(..)`, то перевод должен завершиться неудачей, а токены не должны быть списаны с баланса отправителя.
+
+### События {#events}
+
+```solidity
+event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)
+```
+
+### Примеры: {#examples}
+
+API токена ERC-223 похож на API токена ERC-20, поэтому с точки зрения разработки пользовательского интерфейса разницы нет. Единственное исключение здесь заключается в том, что токены ERC-223 могут не иметь функций `approve` + `transferFrom`, поскольку они являются необязательными для этого стандарта.
+
+#### Примеры на Solidity {#solidity-example}
+
+Следующий пример иллюстрирует, как работает базовый контракт токена ERC-223:
+
+```solidity
+pragma solidity ^0.8.19;
+abstract contract IERC223Recipient {
+ function tokenReceived(address _from, uint _value, bytes memory _data) public virtual;
+}
+contract VeryBasicERC223Token {
+ event Transfer(address indexed from, address indexed to, uint value, bytes data);
+ string private _name;
+ string private _symbol;
+ uint8 private _decimals;
+ uint256 private _totalSupply;
+ mapping(address => uint256) private balances;
+ function name() public view returns (string memory) { return _name; }
+ function symbol() public view returns (string memory) {return _symbol; }
+ function decimals() public view returns (uint8) { return _decimals; }
+ function totalSupply() public view returns (uint256) { return _totalSupply; }
+ function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; }
+ function isContract(address account) internal view returns (bool) {
+ uint256 size;
+ assembly { size := extcodesize(account) }
+ return size > 0;
+ }
+ function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success){
+ balances[msg.sender] = balances[msg.sender] - _value;
+ balances[_to] = balances[_to] + _value;
+ if(isContract(_to)) {
+ IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data);
+ }
+ emit Transfer(msg.sender, _to, _value, _data);
+ return true;
+ }
+ function transfer(address _to, uint _value) public returns (bool success){
+ bytes memory _empty = hex"00000000";
+ balances[msg.sender] = balances[msg.sender] - _value;
+ balances[_to] = balances[_to] + _value;
+ if(isContract(_to)) {
+ IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty);
+ }
+ emit Transfer(msg.sender, _to, _value, _empty);
+ return true;
+ }
+}
+```
+
+Теперь мы хотим, чтобы другой контракт принимал депозиты `tokenA`, предполагая, что tokenA — это токен ERC-223. Контракт должен принимать только tokenA и отклонять любые другие токены. Когда контракт получает tokenA, он должен вызвать событие `Deposit()` и увеличить значение внутренней переменной `deposits`.
+
+Вот код:
+
+```solidity
+contract RecipientContract is IERC223Recipient {
+ event Deposit(address whoSentTheTokens);
+ uint256 deposits = 0;
+ address tokenA; // Единственный токен, который мы хотим принимать.
+ function tokenReceived(address _from, uint _value, bytes memory _data) public override
+ {
+ // Важно понимать, что в этой функции
+ // msg.sender — это адрес получаемого токена,
+ // msg.value всегда равен 0, так как в большинстве случаев контракт токена не владеет и не отправляет эфир,
+ // _from — это отправитель перевода токена,
+ // _value — это количество зачисленных токенов.
+ require(msg.sender == tokenA);
+ deposits += _value;
+ emit Deposit(_from);
+ }
+}
+```
+
+## Часто задаваемые вопросы {#faq}
+
+### Что произойдет, если мы отправим на контракт какой-нибудь tokenB? {#sending-tokens}
+
+Транзакция не пройдёт, а передача токенов — не произойдет. Токены вернутся на адрес отправителя.
+
+### Как мы можем сделать депозит на этот контракт? {#contract-deposits}
+
+Вызовите функцию `transfer(address,uint256)` или `transfer(address,uint256,bytes)` токена ERC-223, указав адрес `RecipientContract`.
+
+### Что будет, если отправить токен ERC-20 на этот контракт? {#erc-20-transfers}
+
+Если токен ERC-20 будет отправлен на `RecipientContract`, токены будут переведены, но перевод не будет распознан (событие `Deposit()` не будет вызвано, а значение депозитов не изменится). Нежелательные депозиты ERC-20 не могут быть отфильтрованы или предотвращены.
+
+### Что, если мы хотим выполнить какую-то функцию после депозита токена? {#function-execution}
+
+Есть несколько способов. В этом примере мы будем следовать методу, который делает переводы ERC-223 идентичными переводам эфира:
+
+```solidity
+contract RecipientContract is IERC223Recipient {
+ event Foo();
+ event Bar(uint256 someNumber);
+ address tokenA; // Единственный токен, который мы хотим принимать.
+ function tokenReceived(address _from, uint _value, bytes memory _data) public override
+ {
+ require(msg.sender == tokenA);
+ address(this).call(_data); // Обработка входящей транзакции и выполнение последующего вызова функции.
+ }
+ function foo() public
+ {
+ emit Foo();
+ }
+ function bar(uint256 _someNumber) public
+ {
+ emit Bar(_someNumber);
+ }
+}
+```
+
+Когда `RecipientContract` получит токен ERC-223, контракт выполнит функцию, закодированную как параметр `_data` транзакции токена, идентично тому, как транзакции эфира кодируют вызовы функций как транзакцию `data`. Для получения дополнительной информации прочтите [о поле данных](/developers/docs/transactions/#the-data-field).
+
+В приведенном выше примере токен ERC-223 должен быть переведен на адрес `RecipientContract` с помощью функции `transfer(address,uin256,bytes calldata _data)`. Если параметр данных будет `0xc2985578` (сигнатура функции `foo()`), то функция foo() будет вызвана после получения депозита токена, и будет запущено событие Foo().
+
+Параметры также могут быть закодированы в `data` перевода токена, например, мы можем вызвать функцию bar() со значением 12345 для `_someNumber`. В этом случае `data` должен быть `0x0423a13200000000000000000000000000000000000000000000000000000000000004d2`, где `0x0423a132` — это сигнатура функции `bar(uint256)`, а `00000000000000000000000000000000000000000000000000000000000004d2` — это 12345 в виде uint256.
+
+## Ограничения {#limitations}
+
+Несмотря на то, что стандарт ERC-223 решает ряд проблем стандарта ERC-20, он не без ограничений:
+
+- Внедрение и совместимость: ERC-223 еще не получил широкого распространения, что может ограничивать его совместимость с существующими инструментами и платформами.
+- Обратная совместимость: ERC-223 не имеет обратной совместимости с ERC-20, что означает, что существующие контракты и инструменты ERC-20 — без модификаций — не будут работать с токенами ERC-223.
+- Стоимость газа: дополнительные проверки и функции при переводе ERC-223 могут привести к более высоким затратам на газ по сравнению с транзакциями ERC-20.
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-223: Стандарт токенов ERC-223](https://eips.ethereum.org/EIPS/eip-223)
+- [Первоначальное предложение по ERC-223](https://github.com/ethereum/eips/issues/223)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-4626/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-4626/index.md
new file mode 100644
index 00000000000..096996fae9f
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-4626/index.md
@@ -0,0 +1,227 @@
+---
+title: "Стандарт токенизированных хранилищ ERC-4626"
+description: "Стандарт для доходных хранилищ."
+lang: ru
+---
+
+## Введение {#introduction}
+
+ERC-4626 - стандарт, разработанный для оптимизации и объединения технических параметров доходных хранилищ. Он предоставляет стандартный API для токенизированных доходных хранилищ, которые представляют собой доли одного базового токена ERC-20. ERC-4626 также описывает необязательное расширение для токенизированных хранилищ, использующих ERC-20, предлагая базовую функциональность для внесения депозита, вывода токенов и считывания балансов.
+
+**Роль ERC-4626 в доходных хранилищах**
+
+Рынки кредитования, агрегаторы и внутренне процентные токены помогают пользователям находить лучшую доходность на свои криптотокены путем выполнения различных стратегий. Эти стратегии выполняются с небольшими вариациями, что может приводить к ошибкам или тратить впустую ресурсы на разработку.
+
+ERC-4626 в доходных хранилищах снизит трудозатраты на интеграцию и откроет доступ к доходности в различных приложениях с небольшими специальными усилиями со стороны разработчиков путем создания более последовательных и надежных шаблонов реализации.
+
+Токен ERC-4626 полностью описан в [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626).
+
+**Асинхронное расширение хранилища (ERC-7540)**
+
+ERC-4626 оптимизирован для атомарных депозитов и погашений до определенного лимита. Если лимит достигнут, новые депозиты или погашения не могут быть отправлены. Это ограничение плохо работает для любой системы умных контрактов с асинхронными действиями или задержками в качестве необходимого условия для взаимодействия с Хранилищем (например, протоколы реальных активов, протоколы кредитования с недостаточным обеспечением, межсетевые протоколы кредитования, токены ликвидного стейкинга или модули страховой безопасности).
+
+ERC-7540 расширяет полезность Хранилищ ERC-4626 для асинхронных сценариев использования. Существующий интерфейс Хранилища (`deposit`/`withdraw`/`mint`/`redeem`) полностью используется для получения асинхронных Запросов.
+
+Расширение ERC-7540 полностью описано в [ERC-7540](https://eips.ethereum.org/EIPS/eip-7540).
+
+**Расширение хранилища с несколькими активами (ERC-7575)**
+
+Один из недостающих вариантов использования, который не поддерживается ERC-4626, — это Хранилища, которые имеют несколько активов или точек входа, такие как токены поставщика ликвидности (LP). Они, как правило, громоздки или несовместимы из-за требования к самому ERC-4626 быть токеном ERC-20.
+
+ERC-7575 добавляет поддержку Хранилищ с несколькими активами путем вынесения реализации токена ERC-20 за пределы реализации ERC-4626.
+
+Расширение ERC-7575 полностью описано в [ERC-7575](https://eips.ethereum.org/EIPS/eip-7575).
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочитать о [стандартах токенов](/developers/docs/standards/tokens/) и [ERC-20](/developers/docs/standards/tokens/erc-20/).
+
+## Функции и возможности ERC-4626: {#body}
+
+### Методы {#methods}
+
+#### актив {#asset}
+
+```solidity
+function asset() public view returns (address assetTokenAddress)
+```
+
+Эта функция возвращает адрес базового токена, используемого хранилищем для учета, внесения депозитов и вывода средств.
+
+#### всегоАктивов {#totalassets}
+
+```solidity
+function totalAssets() public view returns (uint256)
+```
+
+Эта функция возвращает общее количество базовых активов, хранящихся в хранилище.
+
+#### конвертироватьВДОли {#convertoshares}
+
+```solidity
+function convertToShares(uint256 assets) public view returns (uint256 shares)
+```
+
+Эта функция возвращает количество долей (`shares`), которое будет обменено хранилищем на предоставленное количество активов (`assets`).
+
+#### конвертироватьВАктивы {#convertoassets}
+
+```solidity
+function convertToAssets(uint256 shares) public view returns (uint256 assets)
+```
+
+Эта функция возвращает количество активов (`assets`), которое будет обменено хранилищем на предоставленное количество долей (`shares`).
+
+#### максДепозит {#maxdeposit}
+
+```solidity
+function maxDeposit(address receiver) public view returns (uint256 maxAssets)
+```
+
+Эта функция возвращает максимальное количество базовых активов, которое можно внести одним вызовом [`deposit`](#deposit), при этом доли выпускаются для получателя (`receiver`).
+
+#### предпросмотрДепозита {#previewdeposit}
+
+```solidity
+function previewDeposit(uint256 assets) public view returns (uint256 shares)
+```
+
+Эта функция позволяет пользователям симулировать результат своего депозита на текущем блоке.
+
+#### депозит {#deposit}
+
+```solidity
+function deposit(uint256 assets, address receiver) public returns (uint256 shares)
+```
+
+Эта функция вносит активы (`assets`) базовых токенов в хранилище и передает право собственности на доли (`shares`) получателю (`receiver`).
+
+#### максМинт {#maxmint}
+
+```solidity
+function maxMint(address receiver) public view returns (uint256 maxShares)
+```
+
+Эта функция возвращает максимальное количество долей, которое можно выпустить одним вызовом [`mint`](#mint), при этом доли выпускаются для получателя (`receiver`).
+
+#### предпросмотрМинта {#previewmint}
+
+```solidity
+function previewMint(uint256 shares) public view returns (uint256 assets)
+```
+
+Эта функция позволяет пользователям симулировать результат своего выпуска (минта) на текущем блоке.
+
+#### минт {#mint}
+
+```solidity
+function mint(uint256 shares, address receiver) public returns (uint256 assets)
+```
+
+Эта функция выпускает (минтит) ровно `shares` (долей) хранилища для получателя (`receiver`) путем внесения `assets` (активов) базовых токенов.
+
+#### максВывод {#maxwithdraw}
+
+```solidity
+function maxWithdraw(address owner) public view returns (uint256 maxAssets)
+```
+
+Эта функция возвращает максимальное количество базовых активов, которое можно вывести с баланса владельца (`owner`) одним вызовом [`withdraw`](#withdraw).
+
+#### предпросмотрВывода {#previewwithdraw}
+
+```solidity
+function previewWithdraw(uint256 assets) public view returns (uint256 shares)
+```
+
+Эта функция позволяет пользователям симулировать результат своего вывода на текущем блоке.
+
+#### вывод {#withdraw}
+
+```solidity
+function withdraw(uint256 assets, address receiver, address owner) public returns (uint256 shares)
+```
+
+Эта функция сжигает доли (`shares`) владельца (`owner`) и отправляет ровно `assets` (активов) токена из хранилища получателю (`receiver`).
+
+#### максПогашение {#maxredeem}
+
+```solidity
+function maxRedeem(address owner) public view returns (uint256 maxShares)
+```
+
+Эта функция возвращает максимальное количество долей, которое можно погасить с баланса владельца (`owner`) через вызов [`redeem`](#redeem).
+
+#### предпросмотрПогашения {#previewredeem}
+
+```solidity
+function previewRedeem(uint256 shares) public view returns (uint256 assets)
+```
+
+Эта функция позволяет пользователям симулировать результат своего погашения на текущем блоке.
+
+#### погашение {#redeem}
+
+```solidity
+function redeem(uint256 shares, address receiver, address owner) public returns (uint256 assets)
+```
+
+Эта функция погашает определенное количество долей (`shares`) владельца (`owner`) и отправляет активы (`assets`) базового токена из хранилища получателю (`receiver`).
+
+#### общееПредложение {#totalsupply}
+
+```solidity
+function totalSupply() public view returns (uint256)
+```
+
+Возвращает общее количество непогашенных долей хранилища в обращении.
+
+#### баланс {#balanceof}
+
+```solidity
+function balanceOf(address owner) public view returns (uint256)
+```
+
+Возвращает общее количество долей хранилища, которыми в настоящее время владеет `owner`.
+
+### Карта интерфейса {#mapOfTheInterface}
+
+
+
+### События {#events}
+
+#### Событие Deposit
+
+**ДОЛЖНО** генерироваться, когда токены вносятся в хранилище с помощью методов [`mint`](#mint) и [`deposit`](#deposit).
+
+```solidity
+event Deposit(
+ address indexed sender,
+ address indexed owner,
+ uint256 assets,
+ uint256 shares
+)
+```
+
+Где `sender` — это пользователь, который обменял `assets` на `shares` и перевел эти `shares` владельцу (`owner`).
+
+#### Событие Withdraw
+
+**ДОЛЖНО** генерироваться, когда доли выводятся из хранилища вкладчиком с помощью методов [`redeem`](#redeem) или [`withdraw`](#withdraw).
+
+```solidity
+event Withdraw(
+ address indexed sender,
+ address indexed receiver,
+ address indexed owner,
+ uint256 assets,
+ uint256 shares
+)
+```
+
+Где `sender` — это пользователь, который инициировал вывод и обменял `shares` (доли), принадлежащие `owner` (владельцу), на `assets` (активы). `receiver` — это пользователь, который получил выведенные `assets` (активы).
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-4626: Стандарт токенизированного хранилища](https://eips.ethereum.org/EIPS/eip-4626)
+- [ERC-4626: репозиторий на GitHub](https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-721/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-721/index.md
new file mode 100644
index 00000000000..bcb9110fb85
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-721/index.md
@@ -0,0 +1,255 @@
+---
+title: "Стандарт невзаимозаменяемых токенов ERC-721"
+description: "Узнайте о ERC-721, стандарте для невзаимозаменяемых токенов (NFT), которые представляют собой уникальные цифровые активы в сети Ethereum."
+lang: ru
+---
+
+## Введение {#introduction}
+
+**Что такое невзаимозаменяемый токен?**
+
+Невзаимозаменяемые токены (NFT) используются для уникальной идентификации чего-то или кого-то. Этот тип токена идеально подходит для использования на платформах, предлагающих коллекционные предметы, ключи доступа, лотерейные билеты, пронумерованные места на концерты, спортивные матчи и т.д. Этот особый тип токена имеет удивительные возможности, поэтому он заслуживает надлежащего стандарта, ERC-721 призван решить эту проблему!
+
+**Что такое ERC-721?**
+
+ERC-721 вводит стандарт для NFT, другими словами, этот тип токена уникален и может иметь значение, отличное от другого токена из того же смарт-контракта, возможно, из-за его возраста, редкости или даже из-за чего-то другого, например его внешнего вида.
+Подожди, визуально?
+
+Да! У всех NFT есть переменная `uint256` под названием `tokenId`, поэтому для любого контракта ERC-721 пара
+`contract address, uint256 tokenId` должна быть глобально уникальной. При этом у децентрализованного приложения может быть "конвертер", который
+использует `tokenId` в качестве входных данных и выводит изображение чего-то классного, например: зомби, оружия, навыков или удивительных котят!
+
+## Предварительные условия {#prerequisites}
+
+- [Аккаунты](/developers/docs/accounts/)
+- [Смарт-контракты](/developers/docs/smart-contracts/)
+- [Стандарты токенов](/developers/docs/standards/tokens/)
+
+## Тело {#body}
+
+ERC-721 (Ethereum Request for Comments 721), предложенный Уильямом Энтрикеном, Дитером Ширли, Якобом Эвансом и Настасьей Сакс в январе 2018 года, является стандартом невзаимозаменяемых токенов, который реализует API для токенов в смарт-контрактах.
+
+Он предоставляет такие функции, как: перенос токенов из одной учетной записи в другую, получение текущего баланса токенов учетной записи, узнать кто владелец определенного токена, а также узнать общее количество токенов, доступных в сети.
+Помимо этого, он также имеет некоторые другие функции, такие как подтверждение того, что количество токенов из учетной записи может быть перемещено сторонней учетной записью.
+
+Если в смарт-контракте реализованы следующие методы и события, его можно назвать контрактом невзаимозаменяемых токенов ERC-721, и после развертывания он будет нести ответственность за отслеживание созданных токенов в Ethereum.
+
+Из [EIP-721](https://eips.ethereum.org/EIPS/eip-721):
+
+### Методы {#methods}
+
+```solidity
+ function balanceOf(address _owner) external view returns (uint256);
+ function ownerOf(uint256 _tokenId) external view returns (address);
+ function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
+ function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
+ function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
+ function approve(address _approved, uint256 _tokenId) external payable;
+ function setApprovalForAll(address _operator, bool _approved) external;
+ function getApproved(uint256 _tokenId) external view returns (address);
+ function isApprovedForAll(address _owner, address _operator) external view returns (bool);
+```
+
+### События {#events}
+
+```solidity
+ event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
+ event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
+ event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
+```
+
+### Примеры {#web3py-example}
+
+Давайте посмотрим, насколько важен стандарт, чтобы упростить нам проверку любого контракта токена ERC-721 на Ethereum.
+Нам просто нужен двоичный интерфейс приложения контракта (ABI) для создания интерфейса к любому токену ERC-721. Как вы можете увидеть ниже, мы будем использовать упрощенный ABI, чтобы сделать пример простым.
+
+#### Пример Web3.py {#web3py-example}
+
+Во-первых, убедитесь, что вы установили библиотеку Python [Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation):
+
+```
+pip install web3
+```
+
+```python
+from web3 import Web3
+from web3._utils.events import get_event_data
+
+
+w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))
+
+ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # Контракт CryptoKitties
+
+acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # Аукцион по продаже CryptoKitties
+
+# Это упрощенный двоичный интерфейс приложения (ABI) для контракта ERC-721 NFT.
+# Он будет раскрывать только методы: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply()
+simplified_abi = [
+ {
+ 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}],
+ 'name': 'balanceOf',
+ 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
+ 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'name',
+ 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [{'internalType': 'uint256', 'name': 'tokenId', 'type': 'uint256'}],
+ 'name': 'ownerOf',
+ 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}],
+ 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'symbol',
+ 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [],
+ 'name': 'totalSupply',
+ 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
+ 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+]
+
+ck_extra_abi = [
+ {
+ 'inputs': [],
+ 'name': 'pregnantKitties',
+ 'outputs': [{'name': '', 'type': 'uint256'}],
+ 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
+ },
+ {
+ 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],
+ 'name': 'isPregnant',
+ 'outputs': [{'name': '', 'type': 'bool'}],
+ 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
+ }
+]
+
+ck_contract = w3.eth.contract(address=w3.to_checksum_address(ck_token_addr), abi=simplified_abi+ck_extra_abi)
+name = ck_contract.functions.name().call()
+symbol = ck_contract.functions.symbol().call()
+kitties_auctions = ck_contract.functions.balanceOf(acc_address).call()
+print(f"{name} [{symbol}] NFT на аукционах: {kitties_auctions}")
+
+pregnant_kitties = ck_contract.functions.pregnantKitties().call()
+print(f"{name} [{symbol}] беременных NFT: {pregnant_kitties}")
+
+# Используем ABI события Transfer для получения информации о переданных Kitties.
+tx_event_abi = {
+ 'anonymous': False,
+ 'inputs': [
+ {'indexed': False, 'name': 'from', 'type': 'address'},
+ {'indexed': False, 'name': 'to', 'type': 'address'},
+ {'indexed': False, 'name': 'tokenId', 'type': 'uint256'}],
+ 'name': 'Transfer',
+ 'type': 'event'
+}
+
+# Нам нужна подпись события для фильтрации журналов
+event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex()
+
+logs = w3.eth.get_logs({
+ "fromBlock": w3.eth.block_number - 120,
+ "address": w3.to_checksum_address(ck_token_addr),
+ "topics": [event_signature]
+})
+
+# Примечания:
+# - Увеличьте количество блоков с 120, если событие Transfer не будет возвращено.
+# - Если вы не нашли событие Transfer, вы можете попытаться получить tokenId по адресу:
+# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events
+# Нажмите, чтобы развернуть журналы события и скопировать его аргумент "tokenId"
+recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]
+
+if recent_tx:
+ kitty_id = recent_tx[0]['tokenId'] # Вставьте сюда tokenId по ссылке выше
+ is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()
+ print(f"{name} [{symbol}] NFT {kitty_id} беременен: {is_pregnant}")
+```
+
+В контракте CryptoKitties есть несколько интересных событий, помимо стандартных.
+
+Давайте проверим два из них: `Pregnant` и `Birth`.
+
+```python
+# Используем ABI событий Pregnant и Birth для получения информации о новых Kitties.
+ck_extra_events_abi = [
+ {
+ 'anonymous': False,
+ 'inputs': [
+ {'indexed': False, 'name': 'owner', 'type': 'address'},
+ {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
+ {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
+ {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}],
+ 'name': 'Pregnant',
+ 'type': 'event'
+ },
+ {
+ 'anonymous': False,
+ 'inputs': [
+ {'indexed': False, 'name': 'owner', 'type': 'address'},
+ {'indexed': False, 'name': 'kittyId', 'type': 'uint256'},
+ {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
+ {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
+ {'indexed': False, 'name': 'genes', 'type': 'uint256'}],
+ 'name': 'Birth',
+ 'type': 'event'
+ }]
+
+# Нам нужна подпись события для фильтрации журналов
+ck_event_signatures = [
+ w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(),
+ w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),
+]
+
+# Вот событие Pregnant:
+# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog
+pregnant_logs = w3.eth.get_logs({
+ "fromBlock": w3.eth.block_number - 120,
+ "address": w3.to_checksum_address(ck_token_addr),
+ "topics": [ck_event_signatures[0]]
+})
+
+recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]
+
+# Вот событие Birth:
+# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a
+birth_logs = w3.eth.get_logs({
+ "fromBlock": w3.eth.block_number - 120,
+ "address": w3.to_checksum_address(ck_token_addr),
+ "topics": [ck_event_signatures[1]]
+})
+
+recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs]
+```
+
+## Популярные NFT {#popular-nfts}
+
+- [Etherscan NFT Tracker](https://etherscan.io/nft-top-contracts) перечисляет лучшие NFT на Ethereum по объему переводов.
+- [CryptoKitties](https://www.cryptokitties.co/) — это игра, основанная на разведении и коллекционировании очаровательных
+ существ, которых мы называем CryptoKitties.
+- [Sorare](https://sorare.com/) — это глобальный фэнтези-футбол, в котором вы можете коллекционировать предметы ограниченного выпуска,
+ управлять своими командами и соревноваться за призы.
+- [Служба имён Ethereum (ENS)](https://ens.domains/) предлагает безопасный и децентрализованный способ адресации ресурсов как
+ в блокчейне, так и за его пределами, используя простые, удобочитаемые имена.
+- [POAP](https://poap.xyz) предоставляет бесплатные NFT людям, которые посещают мероприятия или выполняют определенные действия. POAP-ы бесплатные для создания и распространения.
+- [Unstoppable Domains](https://unstoppabledomains.com/) — это компания из Сан-Франциско, которая создает домены на
+ блокчейнах. Домены на блокчейне заменяют адреса криптовалют на удобочитаемые имена и могут использоваться для создания
+ устойчивых к цензуре веб-сайтов.
+- [Gods Unchained Cards](https://godsunchained.com/) — это ККИ (коллекционная карточная игра) в блокчейне Ethereum, которая использует NFT для обеспечения реального права собственности
+ на внутриигровые активы.
+- [Bored Ape Yacht Club](https://boredapeyachtclub.com) — это коллекция из 10 000 уникальных NFT, которые, помимо того, что являются доказуемо редкими произведениями искусства, действуют как членский токен клуба, предоставляя участникам льготы и преимущества, которые со временем увеличиваются в результате усилий сообщества.
+
+## Дополнительные материалы {#further-reading}
+
+- [EIP-721: стандарт невзаимозаменяемых токенов ERC-721](https://eips.ethereum.org/EIPS/eip-721)
+- [OpenZeppelin — документация по ERC-721](https://docs.openzeppelin.com/contracts/3.x/erc721)
+- [OpenZeppelin — реализация ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol)
+- [Alchemy NFT API](https://www.alchemy.com/docs/reference/nft-api-quickstart)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/erc-777/index.md b/public/content/translations/ru/developers/docs/standards/tokens/erc-777/index.md
new file mode 100644
index 00000000000..c1ea29c6213
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/erc-777/index.md
@@ -0,0 +1,45 @@
+---
+title: "Стандарт токенов ERC-777"
+description: "Узнайте об ERC-777, улучшенном стандарте взаимозаменяемых токенов с перехватчиками, хотя по соображениям безопасности рекомендуется ERC-20."
+lang: ru
+---
+
+## Предупреждение {#warning}
+
+**ERC-777 трудно реализовать должным образом из-за его [подверженности различным формам атак](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2620). Вместо этого рекомендуется использовать [ERC-20](/developers/docs/standards/tokens/erc-20/).** Эта страница оставлена в качестве исторического архива.
+
+## Введение? Введение {#introduction}
+
+ERC-777 — это стандарт взаимозаменяемых токенов, улучшающий существующий стандарт [ERC-20](/developers/docs/standards/tokens/erc-20/).
+
+## Предварительные условия {#prerequisites}
+
+Чтобы лучше понять эту страницу, мы рекомендуем вам сначала прочитать об [ERC-20](/developers/docs/standards/tokens/erc-20/).
+
+## Какие именно улучшения над ERC-20 предлагает ERC-777? {#-erc-777-vs-erc-20}
+
+ERC-777 обеспечивает следующие усовершенствования по сравнению с ERC-20.
+
+### Перехватчики {#hooks}
+
+Перехватчики — это функция, описанная в коде умного контракта. Перехватчики вызываются при отправке или получении токенов через контракт. Это позволяет умному контракту реагировать на входящие или исходящие токены.
+
+Перехватчики регистрируются и обнаруживаются с помощью стандарта [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820).
+
+#### Чем хороши перехватчики? {#why-are-hooks-great}
+
+1. Перехватчики позволяют отправлять токены в контракт и уведомлять контракт в рамках одной транзакции, в отличие от [ERC-20](https://eips.ethereum.org/EIPS/eip-20), который для этого требует двойного вызова (`approve`/`transferFrom`).
+2. Контракты, в которых не зарегистрированы перехватчики, несовместимы с ERC-777. Отправляющий контракт прервет транзакцию, если в принимающем контракте не зарегистрирован перехватчик. Это предотвращает случайные переводы на умные контракты, несовместимые с ERC-777.
+3. Перехватчики могут отклонять транзакции.
+
+### Десятичные знаки {#decimals}
+
+Этот стандарт также решает проблему путаницы вокруг `decimals`, вызванную в ERC-20. Эта ясность улучшает опыт разработчика.
+
+### Обратная совместимость с ERC-20 {#backwards-compatibility-with-erc-20}
+
+С контрактами ERC-777 можно взаимодействовать так, будто бы они — контракты ERC-20.
+
+## Дополнительные материалы {#further-reading}
+
+[EIP-777: Стандарт токенов](https://eips.ethereum.org/EIPS/eip-777)
diff --git a/public/content/translations/ru/developers/docs/standards/tokens/index.md b/public/content/translations/ru/developers/docs/standards/tokens/index.md
new file mode 100644
index 00000000000..0871ce8b81b
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/standards/tokens/index.md
@@ -0,0 +1,41 @@
+---
+title: "Стандарты токенов"
+description: "Изучите стандарты токенов Ethereum, включая ERC-20, ERC-721 и ERC-1155, для взаимозаменяемых и невзаимозаменяемых токенов."
+lang: ru
+incomplete: true
+---
+
+## Введение {#introduction}
+
+Многие стандарты разработки Ethereum сосредоточены на интерфейсах токенов. Эти стандарты помогают обеспечить компонуемость смарт-контрактов, поэтому, когда новый проект выпускает токен, он остается совместимым с существующими децентрализованными биржами и приложениями.
+
+Стандарты токенов определяют, как токены ведут себя и взаимодействуют в экосистеме Ethereum. Они облегчают разработчикам создание продуктов, избавляя от необходимости изобретать велосипед, и обеспечивают беспрепятственную работу токенов с кошельками, биржами и платформами DeFi. Будь то в играх, управлении или других вариантах использования, эти стандарты обеспечивают согласованность и делают Ethereum более взаимосвязанным.
+
+## Предварительные условия {#prerequisites}
+
+- [Стандарты разработки Ethereum](/developers/docs/standards/)
+- [Умные контракты](/developers/docs/smart-contracts/)
+
+## Стандарты токенов {#token-standards}
+
+Вот некоторые из самых популярных стандартов токенов в Ethereum:
+
+- [ERC-20](/developers/docs/standards/tokens/erc-20/) — стандартный интерфейс для взаимозаменяемых токенов, таких как токены для голосования, токены для стейкинга или виртуальные валюты.
+
+### Стандарты NFT {#nft-standards}
+
+- [ERC-721](/developers/docs/standards/tokens/erc-721/) — стандартный интерфейс для невзаимозаменяемых токенов, например, свидетельство о праве собственности на произведение искусства или песню.
+- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) — стандарт ERC-1155 позволяет совершать более эффективные сделки и объединять транзакции, тем самым экономя средства. Этот стандарт токенов позволяет создавать как утилитарные токены (такие, как $BNB или $BAT), так и NFT, например - CryptoPunks.
+
+Полный список предложений [ERC](https://eips.ethereum.org/erc).
+
+## Дополнительные материалы {#further-reading}
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Связанные руководства {#related-tutorials}
+
+- [Контрольный список интеграции токенов](/developers/tutorials/token-integration-checklist/) _— контрольный список вопросов, которые следует учитывать при взаимодействии с токенами._
+- [Как устроен смарт-контракт токена ERC-20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _— введение в развертывание вашего первого смарт-контракта в тестовой сети Ethereum._
+- [Переводы и одобрение токенов ERC-20 из смарт-контракта Solidity](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _— как использовать смарт-контракт для взаимодействия с токеном на языке Solidity._
+- [Реализация рынка ERC-721 [практическое руководство]](/developers/tutorials/how-to-implement-an-erc721-market/) _— как выставлять токенизированные предметы на продажу на децентрализованной доске объявлений._
diff --git a/public/content/translations/ru/developers/docs/storage/index.md b/public/content/translations/ru/developers/docs/storage/index.md
new file mode 100644
index 00000000000..43708a344c4
--- /dev/null
+++ b/public/content/translations/ru/developers/docs/storage/index.md
@@ -0,0 +1,216 @@
+---
+title: "Децентрализованное хранилище"
+description: "Обзор того, что такое децентрализованное хранилище, и доступные инструменты для его интеграции в децентрализованное приложение."
+lang: ru
+---
+
+В отличие от централизованного сервера, управляемого одной компанией или организацией, децентрализованные системы хранения состоят из одноранговой сети пользователей-операторов, которые владеют частью общих данных, создавая отказоустойчивую систему совместного использования файловых хранилищ. Это может быть приложение на основе блокчейна или любая одноранговая сеть.
+
+Сам Ethereum можно использовать как децентрализованную систему хранения, это касается хранения кода во всех смарт-контрактах. Однако, когда дело доходит до больших объемов данных - Ethereum для этого не предназначен. Блокчейн постоянно растет, но на момент написания этой статьи размер блокчейна Ethereum составляет около 500 ГБ – 1 ТБ ([в зависимости от клиента](https://etherscan.io/chartsync/chaindefault)), и каждый узел в сети должен иметь возможность хранить все эти данные. Если бы цепочка расширилась до больших объемов данных (скажем, 5 ТБ), было бы невозможно, чтобы все узлы продолжали работать. Кроме того, стоимость развертывания такого большого объема данных в основную сеть будет непомерно высокой из-за комиссий за [газ](/developers/docs/gas).
+
+Из-за этих ограничений нам нужна другая цепочка или методология для децентрализованного хранения больших объемов данных.
+
+При рассмотрении вариантов децентрализованного хранилища (dStorage) пользователь должен помнить о нескольких вещах.
+
+- Механизм устойчивости/структура стимулов
+- Обеспечение сохранности данных
+- Децентрализация
+- Консенсус
+
+## Механизм сохранения / структура стимулов {#persistence-mechanism}
+
+### На основе блокчейна {#blockchain-based}
+
+Чтобы часть данных сохранялась навсегда, нам нужно использовать механизм устойчивости. Например, в Ethereum механизм устойчивости заключается в том, что при запуске узла необходимо учитывать всю цепочку. Новые данные прикрепляются к концу цепочки, и она продолжает расти, требуя, чтобы каждый узел копировал все новые включенные данные.
+
+Это называется сохранением **на основе блокчейна**.
+
+Проблема с сохранением на основе блокчейна в том, что блокчейн может стать слишком большим, чтобы его можно было поддерживать и хранить все данные (например, по оценкам [многих источников](https://healthit.com.au/how-big-is-the-internet-and-how-do-we-measure-it/), для Интернета требуется более 40 зеттабайт дискового пространства).
+
+Кроме того, блокчейн должен иметь механизм поощрения. Для постоянства на основе блокчейна существует платеж валидатору. Когда данные добавляются в цепочку, валидаторам платят за добавление данных.
+
+Платформы с устойчивостью на основе блокчейна:
+
+- Ethereum
+- [Arweave](https://www.arweave.org/)
+
+### На основе контракта {#contract-based}
+
+**Сохранение на основе контракта** исходит из того, что данные не могут быть скопированы каждым узлом и храниться вечно, а вместо этого их сохранность должна поддерживаться контрактными соглашениями. Эти соглашения установлены между множеством узлов, пообещавших хранить фрагмент данных некоторое время. Они должны быть оплачены или обновлены каждый раз, когда они исполняются для того, чтобы записать новое состояние.
+
+В большинстве случаев вместо хранения всех данных ончейн сохраняется хэш местоположения данных в блокчейне. Таким образом нет надобности держать все данные в блокчейне.
+
+Платформы с устойчивостью на основе контракта:
+
+- [Filecoin](https://docs.filecoin.io/basics/what-is-filecoin)
+- [Skynet](https://sia.tech/)
+- [Storj](https://storj.io/)
+- [Züs](https://zus.network/)
+- [Crust Network](https://crust.network)
+- [Swarm](https://www.ethswarm.org/)
+- [4EVERLAND](https://www.4everland.org/)
+
+### Дополнительные соображения {#additional-consideration}
+
+IPFS — это распределенная система для хранения и доступа к файлам, веб-сайтам, приложениям и данным. Она не имеет встроенной системы поощрения, но вместо этого может использоваться с любым из вышеперечисленных объектов на контрактной основе для долгосрочного хранения. Другой способ сохранения данных на IPFS это работа со службой привязки, которая привязывает ваши данные для вас. Вы можете запустить свой собственный узел IPFS и внести свой вклад в сеть, чтобы сохранить свои и/или чужие данные бесплатно!
+
+- [IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/)
+- [Pinata](https://www.pinata.cloud/) _(сервис закрепления IPFS)_
+- [web3.storage](https://web3.storage/) _(сервис закрепления IPFS/Filecoin)_
+- [Infura](https://infura.io/product/ipfs) _(сервис закрепления IPFS)_
+- [IPFS Scan](https://ipfs-scan.io) _(обозреватель закреплений IPFS)_
+- [4EVERLAND](https://www.4everland.org/) _(сервис закрепления IPFS)_
+- [Filebase](https://filebase.com) _(сервис закрепления IPFS)_
+- [Spheron Network](https://spheron.network/) _(сервис закрепления IPFS/Filecoin)_
+
+SWARM — это децентрализованная технология хранения и распространения данных с системой поощрения за хранение и оракулом цен на аренду хранилища.
+
+## Хранение данных {#data-retention}
+
+Чтобы сохранить данные, системы должны иметь какой-то механизм, обеспечивающий это сохранение.
+
+### Механизм оспаривания {#challenge-mechanism}
+
+Один из самых популярных способов убедиться что данные сохранены - задать узлам криптографическую задачу, призванную подтвердить что узлы все еще хранят данные. Один из простых вариантов - посмотреть на proof-of-access в Arweave. Они проверяют узлы, чтобы убедиться имеют ли последние доступ одновременно к самому свежему блоку - и случайному блоку из прошлого. Если узел не может ответить корректно - он штрафуется.
+
+Виды децентрализованных хранилищ с механизмом обеспечения:
+
+- Züs
+- Skynet
+- Arweave
+- Filecoin
+- Crust Network
+- 4EVERLAND
+
+### Децентрализованность {#decentrality}
+
+Не существует хороших инструментов для измерения уровня децентрализации платформ, предоставляющих доказательства того, что они не централизованы, но в целом вам следует использовать инструменты, которые не имеют какой-либо формы KYC.
+
+Децентрализованные инструменты без KYC:
+
+- Skynet
+- Arweave
+- Filecoin
+- IPFS
+- Ethereum
+- Crust Network
+- 4EVERLAND
+
+### Консенсус {#consensus}
+
+Большинство из этих инструментов имеют собственную версию [механизма консенсуса](/developers/docs/consensus-mechanisms/), но, как правило, они основаны либо на [**доказательстве работы (PoW)**](/developers/docs/consensus-mechanisms/pow/), либо на [**доказательстве владения (PoS)**](/developers/docs/consensus-mechanisms/pos/).
+
+На основе доказательства работы:
+
+- Skynet
+- Arweave
+
+На основе доказательства владения:
+
+- Ethereum
+- Filecoin
+- Züs
+- Crust Network
+
+## Связанные инструменты {#related-tools}
+
+**IPFS — _InterPlanetary File System — это децентрализованное хранилище и система ссылок на файлы для Ethereum._**
+
+- [Ipfs.io](https://ipfs.io/)
+- [Документация](https://docs.ipfs.io/)
+- [GitHub](https://github.com/ipfs/ipfs)
+
+**Storj DCS — _безопасное, приватное и совместимое с S3 децентрализованное облачное хранилище объектов для разработчиков._**
+
+- [Storj.io](https://storj.io/)
+- [Документация](https://docs.storj.io/)
+- [GitHub](https://github.com/storj/storj)
+
+**Sia — _использует криптографию для создания бездоверительного рынка облачных хранилищ, позволяя покупателям и продавцам совершать транзакции напрямую._**
+
+- [Skynet.net](https://sia.tech/)
+- [Документация](https://docs.sia.tech/)
+- [GitHub](https://github.com/SiaFoundation/)
+
+**Filecoin — _Filecoin был создан той же командой, что стоит за IPFS. Это система поощрения, построенная поверх идеалов IPFS._**
+
+- [Filecoin.io](https://filecoin.io/)
+- [Документация](https://docs.filecoin.io/)
+- [GitHub](https://github.com/filecoin-project/)
+
+**Arweave — _Arweave — это платформа децентрализованного хранилища (dStorage) для хранения данных._**
+
+- [Arweave.org](https://www.arweave.org/)
+- [Документация](https://docs.arweave.org/info/)
+- [Arweave](https://github.com/ArweaveTeam/arweave/)
+
+**Züs — _Züs — это платформа децентрализованного хранилища (dStorage) на основе доказательства владения (proof-of-stake) с шардингом и блобберами._**
+
+- [zus.network](https://zus.network/)
+- [Документация](https://docs.zus.network/zus-docs/)
+- [GitHub](https://github.com/0chain/)
+
+**Crust Network — _Crust — это платформа децентрализованного хранилища (dStorage), работающая поверх IPFS._**
+
+- [Crust.network](https://crust.network)
+- [Документация](https://wiki.crust.network)
+- [GitHub](https://github.com/crustio)
+
+**Swarm — _платформа распределенного хранения и служба распространения контента для стека Ethereum Web3._**
+
+- [EthSwarm.org](https://www.ethswarm.org/)
+- [Документация](https://docs.ethswarm.org/)
+- [GitHub](https://github.com/ethersphere/)
+
+**OrbitDB — _децентрализованная одноранговая база данных поверх IPFS._**
+
+- [OrbitDB.org](https://orbitdb.org/)
+- [Документация](https://github.com/orbitdb/field-manual/)
+- [GitHub](https://github.com/orbitdb/orbit-db/)
+
+**Aleph.im — _децентрализованный облачный проект (база данных, файловое хранилище, вычисления и DID). Уникальное сочетание оффчейн и ончейн одноранговых технологий. Уникальное сочетание оффчейн и ончейн одноранговых технологий._**
+
+- [Aleph.im](https://aleph.cloud/)
+- [Документация](https://docs.aleph.cloud/)
+- [GitHub](https://github.com/aleph-im/)
+
+**Ceramic — _управляемое пользователем хранилище баз данных IPFS для приложений с большим объемом данных и высокой вовлеченностью._**
+
+- [Ceramic.network](https://ceramic.network/)
+- [Документация](https://developers.ceramic.network/)
+- [GitHub](https://github.com/ceramicnetwork/js-ceramic/)
+
+**Filebase — _совместимое с S3 децентрализованное хранилище и геоизбыточный сервис закрепления IPFS. Все файлы, загруженные в IPFS через Filebase, автоматически закрепляются в инфраструктуре Filebase с 3-кратной репликацией по всему миру._**
+
+- [Filebase.com](https://filebase.com/)
+- [Документация](https://docs.filebase.com/)
+- [GitHub](https://github.com/filebase)
+
+**4EVERLAND — _платформа облачных вычислений Web 3.0, которая объединяет основные возможности хранения, вычислений и сетевого взаимодействия, совместима с S3 и обеспечивает синхронное хранение данных в децентрализованных сетях хранения, таких как IPFS и Arweave._**
+
+- [4everland.org](https://www.4everland.org/)
+- [Документация](https://docs.4everland.org/)
+- [GitHub](https://github.com/4everland)
+
+**Kaleido — _платформа «блокчейн как услуга» с узлами IPFS, создаваемыми одним нажатием кнопки_**
+
+- [Kaleido](https://kaleido.io/)
+- [Документация](https://docs.kaleido.io/kaleido-services/ipfs/)
+- [GitHub](https://github.com/kaleido-io)
+
+**Spheron Network — _Spheron — это платформа как услуга (PaaS), предназначенная для децентрализованных приложений, которые хотят запустить свои приложения в децентрализованной инфраструктуре с наилучшей производительностью. Она предоставляет готовые к использованию вычислительные мощности, децентрализованное хранилище, CDN и веб-хостинг._**
+
+- [spheron.network](https://spheron.network/)
+- [Документация](https://docs.spheron.network/)
+- [GitHub](https://github.com/spheronFdn)
+
+## Дополнительные материалы {#further-reading}
+
+- [Что такое децентрализованное хранилище?](https://coinmarketcap.com/academy/article/what-is-decentralized-storage-a-deep-dive-by-filecoin) — _CoinMarketCap_
+- [Развенчиваем пять распространенных мифов о децентрализованном хранилище](https://www.storj.io/blog/busting-five-common-myths-about-decentralized-storage) — _Storj_
+
+_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
+
+## Смежные темы {#related-topics}
+
+- [Фреймворки для разработки](/developers/docs/frameworks/)
diff --git a/public/content/translations/ru/developers/docs/transactions/index.md b/public/content/translations/ru/developers/docs/transactions/index.md
index 21303ded0b6..021e638fed3 100644
--- a/public/content/translations/ru/developers/docs/transactions/index.md
+++ b/public/content/translations/ru/developers/docs/transactions/index.md
@@ -1,20 +1,21 @@
---
-title: Транзакции
-description: 'Обзор транзакций Ethereum: как они работают, их структура данных и как их отправлять через приложение.'
+title: "Транзакции"
+description: "Обзор транзакций Ethereum: как они работают, их структура данных и как их отправлять через приложение."
lang: ru
---
Транзакции — это криптографически подписанные инструкции от аккаунтов. Аккаунт инициирует транзакцию для обновления состояния сети Ethereum. Самая простая транзакция — перевод ETH с одного аккаунта на другой.
-## Прежде чем начать {#prerequisites}
+## Предварительные условия {#prerequisites}
-Чтобы помочь вам лучше понять эту страницу, мы рекомендуем сначала прочитать разделы [Аккаунты](/developers/docs/accounts/) и наше [Введение в Ethereum](/developers/docs/intro-to-ethereum/).
+Чтобы помочь вам лучше понять эту страницу, мы рекомендуем сначала прочитать [Аккаунты](/developers/docs/accounts/) и наше [введение в Ethereum](/developers/docs/intro-to-ethereum/).
## Что такое транзакция? {#whats-a-transaction}
Транзакция Ethereum относится к действию, инициированному внешним аккаунтом, то есть аккаунтом, управляемым человеком, а не контрактом. Например, если Боб отправляет Алисе 1 ETH, аккаунт Боба должен быть дебетован, а счет Алисы — кредитован. Это действие по изменению состояния происходит внутри транзакции.
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Диаграмма адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
Транзакции, которые изменяют состояние EVM, должны транслироваться по всей сети. Любой узел может транслировать запрос на выполнение транзакции на EVM; после этого валидатор выполнит транзакцию и распространит результирующее измененное состояние на остальную часть сети.
@@ -22,17 +23,17 @@ lang: ru
Отправленная транзакция включает следующую информацию:
-- `from` - адрес отправителя, который будет подписывать транзакцию. Это будет внешний аккаунт, поскольку аккаунты контрактов не могут отправлять транзакции.
-- `to` — адрес получателя (если аккаунт внешний, транзакция передаст информацию о стоимости. Если это аккаунт контракта, транзакция выполнит код контракта).
+- `from` — адрес отправителя, который будет подписывать транзакцию. Это будет внешний аккаунт, поскольку аккаунты контрактов не могут отправлять транзакции
+- `to` — адрес получателя (если это внешний аккаунт, транзакция передаст стоимость. Если это аккаунт контракта, транзакция выполнит код контракта).
- `signature` — идентификатор отправителя. Он генерируется, когда приватный ключ отправителя подписывает транзакцию и подтверждает, что отправитель авторизовал эту транзакцию.
-- `nonce` - последовательно возрастающий счетчик, указывающий номер транзакции аккаунта.
-- `value` — количество ETH для передачи от отправителя получателю (номинировано в WEI, где 1ETH равен 1e+18wei).
+- `nonce` — последовательно увеличивающийся счетчик, который указывает номер транзакции для аккаунта
+- `value` — сумма ETH для перевода от отправителя получателю (указывается в WEI, где 1 ETH равен 1e+18 wei)
- `input data` — необязательное поле для включения произвольных данных.
-- `gasLimit` — максимальное количество единиц газа, которое может быть использовано транзакцией. [EVM](/developers/docs/evm/opcodes) определяет количество газа, необходимого для каждого этапа вычислений.
-- `maxPriorityFeePerGas` — максимальная цена потребленного газа, которая будет включена в качестве чаевых для валидатора.
-- `maxFeePerGas` — максимальная комиссия за единицу газа, которая будет выплачена за транзакцию (включая `baseFeePerGas` и `maxPriorityFeePerGas`).
+- `gasLimit` — максимальное количество единиц газа, которое может быть потреблено транзакцией. [EVM](/developers/docs/evm/opcodes) определяет количество единиц газа, необходимое для каждого вычислительного шага
+- `maxPriorityFeePerGas` — максимальная цена потребленного газа, которая будет включена в качестве чаевых для валидатора
+- `maxFeePerGas` — максимальная комиссия за единицу газа, которую готовы заплатить за транзакцию (включая `baseFeePerGas` и `maxPriorityFeePerGas`)
-Газ — это ссылка на вычисления, необходимые для обработки транзакции валидатором. Пользователи должны платить за это вычисление. `GasLimit` и `maxPriorityFeePerGas` определяют максимальную комиссию за транзакцию, выплачиваемую валидатору. [Подробнее о газе](/developers/docs/gas/).
+Газ — это ссылка на вычисления, необходимые для обработки транзакции валидатором. Пользователи должны платить за это вычисление. `gasLimit` и `maxPriorityFeePerGas` определяют максимальную комиссию за транзакцию, выплачиваемую валидатору. [Подробнее о газе](/developers/docs/gas/).
Объект транзакции будет выглядеть примерно так:
@@ -99,22 +100,26 @@ lang: ru
}
```
-- `raw` — это подписанная транзакция в закодированной форме [рекурсивной длины префикса (RLP)](/developers/docs/data-structures-and-encoding/rlp).
-- `tx` — это подписанная транзакция в форме JSON.
+- `raw` — это подписанная транзакция в закодированном виде с [префиксом рекурсивной длины (RLP)](/developers/docs/data-structures-and-encoding/rlp)
+- `tx` — это подписанная транзакция в формате JSON
С помощью хэша подписи можно криптографически доказать, что транзакция пришла от отправителя и была отправлена в сеть.
### Поле данных {#the-data-field}
-В подавляющем большинстве операций доступ к контракту осуществляется с внешнего аккаунта. Большинство контрактов написаны на Solidity и интерпретируют свое поле данных в соответствии с [бинарным интерфейсом приложения (ABI)](/glossary/#abi).
+В подавляющем большинстве операций доступ к контракту осуществляется с внешнего аккаунта.
+Большинство контрактов написаны на Solidity и интерпретируют свое поле данных в соответствии с [двоичным интерфейсом приложения (ABI)](/glossary/#abi).
-Первые четыре байта указывают, какую функцию следует вызвать, используя хэш имени функции и ее аргументов. Иногда можно определить функцию по селектору, используя [эту базу данных](https://www.4byte.directory/signatures/).
+Первые четыре байта указывают, какую функцию следует вызвать, используя хэш имени функции и ее аргументов.
+Иногда можно определить функцию по селектору, используя [эту базу данных](https://www.4byte.directory/signatures/).
Остальная часть calldata — это аргументы, [закодированные в соответствии со спецификациями ABI](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding).
-Например, рассмотрим [эту транзакцию](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1). Чтобы увидеть calldata, используйте **Нажмите, чтобы увидеть больше**.
+Например, давайте посмотрим на [эту транзакцию](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1).
+Используйте **Click to see More**, чтобы просмотреть данные calldata.
-Селектор функции — `0xa9059cbb`. Существует несколько [известных функций с такой сигнатурой](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb). В этом случае [исходный код контракта](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) был загружен в Etherscan, поэтому мы функцию: `transfer(address, uint256)`.
+Селектор функции — `0xa9059cbb`. Существует несколько [известных функций с этой подписью](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb).
+В данном случае [исходный код контракта](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) был загружен в Etherscan, поэтому мы знаем, что функцией является `transfer(address,uint256)`.
Остальные данные таковы:
@@ -123,7 +128,9 @@ lang: ru
000000000000000000000000000000000000000000000000000000003b0559f4
```
-Согласно спецификациям ABI целочисленные значения (такие как адреса, которые являются 20-байтовыми целыми числами) отображаются в ABI как 32-байтовые слова, заполненные нулями спереди. Итак, мы знаем адрес `to`: [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279). Значение `value` равно 0x3b0559f4 = 990206452.
+Согласно спецификациям ABI целочисленные значения (такие как адреса, которые являются 20-байтовыми целыми числами) отображаются в ABI как 32-байтовые слова, заполненные нулями спереди.
+Таким образом, мы знаем, что адрес `to` — [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279).
+Значение `value` равно 0x3b0559f4 = 990206452.
## Типы транзакций {#types-of-transactions}
@@ -135,9 +142,9 @@ lang: ru
### О газе {#on-gas}
-Как уже упоминалось, выполнение транзакций требует затрат [газа](/developers/docs/gas/). Для простых транзакций перевода требуется 21 000 единиц газа.
+Как уже упоминалось, для выполнения транзакций требуется [газ](/developers/docs/gas/). Для простых транзакций перевода требуется 21 000 единиц газа.
-Таким образом, чтобы Боб отправил Алисе 1 ETH с `baseFeePerGas` 190 gwei и `maxPriorityFeePerGas` 10 gwei, Бобу необходимо будет заплатить следующую комиссию:
+Итак, чтобы Боб отправил Алисе 1 ETH при `baseFeePerGas` в 190 gwei и `maxPriorityFeePerGas` в 10 gwei, Бобу нужно будет заплатить следующую комиссию:
```
(190 + 10) * 21 000 = 4 200 000 gwei
@@ -145,76 +152,81 @@ lang: ru
0,0042 ETH
```
-Со счета Боба будет списано **1,0042 ETH** (1 ETH для Алисы + 0,0042 ETH как комиссия за газ)
+Со счета Боба будет списано **-1,0042 ETH** (1 ETH для Алисы + 0,0042 ETH в виде комиссии за газ).
На счет Алисы будет зачислено **+1,0 ETH**
-Сжигаемая базовая комиссия составит **-0,00399 ЕТН**
+Базовая комиссия будет сожжена **-0,00399 ETH**
-Валидатор получит **+0,000210 ETH**
+Валидатор получает чаевые **+0,000210 ETH**
-
- _Источник адаптированной диаграммы: [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
+
+_Диаграмма адаптирована из [Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_
Любой газ, не использованный в транзакции, возвращается в аккаунт пользователя.
-### Взаимодействия смарт-контрактов {#smart-contract-interactions}
+### Взаимодействие со смарт-контрактами {#smart-contract-interactions}
Газ необходим для любой транзакции, которая связана со смарт-контрактом.
-Смарт-контракты также могут содержать функции, известные как [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) или [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions), которые не изменяют состояние контракта. Поэтому для вызова этих функций из внешней учетной записи (EOA) не требуется газ. Базовый вызов RPC для этого сценария — [`eth_call`](/developers/docs/apis/json-rpc#eth_call)
+Смарт-контракты также могут содержать функции, известные как функции [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) или [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions), которые не изменяют состояние контракта. Поэтому для вызова этих функций из внешней учетной записи (EOA) не требуется газ. Основной вызов RPC для этого сценария — [`eth_call`](/developers/docs/apis/json-rpc#eth_call).
-В отличие от доступа с помощью `eth_call`, эти функции `view` или `pure` также обычно вызываются внутри (т. е. из самого контракта или из другого контракта), что требует затрат газа.
+В отличие от доступа через `eth_call`, эти функции `view` или `pure` также часто вызываются внутренне (т. е. из самого контракта или из другого контракта), что требует затрат газа.
## Жизненный цикл транзакции {#transaction-lifecycle}
После отправки транзакции происходит следующее:
-1. Хэш транзакции генерируется криптографически: `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017`
+1. Хэш транзакции генерируется криптографически:
+ `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017`
2. Затем транзакция транслируется в сеть и добавляется в пул транзакций, состоящий из всех других ожидающих транзакций сети.
3. Валидатор должен взять вашу транзакцию и включить ее в блок, чтобы подтвердить транзакцию и признать ее «успешной».
-4. По прошествии времени блок, содержащий вашу транзакцию, будет обновлен до уровня «утвержденный», а затем «завершенный» Эти обновления дают гораздо больше уверенности, что ваша сделка была успешной, а изменить ее невозможно. Как только блок «завершен», он может быть изменен только при атаке на сетевом уровне, которая стоила бы миллиарды долларов.
+4. По прошествии времени блок, содержащий вашу транзакцию, будет обновлен до уровня «утвержденный», а затем «завершенный» Эти обновления делают гораздо
+ более вероятным, что ваша транзакция была успешной и никогда не будет изменена. Как только блок будет «финализирован», его можно будет изменить
+ только путем атаки на уровне сети, которая будет стоить многие миллиарды долларов.
-## Визуализация {#a-visual-demo}
+## Наглядная демонстрация {#a-visual-demo}
Посмотрите, как Остин рассказывает о транзакциях, газе и майнинге.
-## Типизированная оболочка транзакций {#typed-transaction-envelope}
+## Типизированный конверт транзакции {#typed-transaction-envelope}
-Ethereum изначально имел один формат транзакций. Каждая транзакция содержала значение nonce, цену на газ, лимит газа, адрес, значение, данные, v, r и s. Эти поля [кодируются с помощью RLP](/developers/docs/data-structures-and-encoding/rlp/), чтобы выглядеть примерно так:
+Ethereum изначально имел один формат транзакций. Каждая транзакция содержала значение nonce, цену на газ, лимит газа, адрес, значение, данные, v, r и s. Эти поля [кодируются с помощью RLP](/developers/docs/data-structures-and-encoding/rlp/), и выглядят примерно так:
`RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])`
-Ethereum эволюционировал до поддержки нескольких типов транзакций, чтобы реализовать новые функции, такие как списки доступа и [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), без влияния на старые форматы транзакций.
+Ethereum эволюционировал и теперь поддерживает несколько типов транзакций, что позволяет реализовывать новые функции, такие как списки доступа и [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), не затрагивая устаревшие форматы транзакций.
-[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) — это то, что позволяет такие действия. Транзакции интепретируются следующим образом:
+Именно [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) обеспечивает такое поведение. Транзакции интепретируются следующим образом:
`TransactionType || TransactionPayload`
Где поля определяются так:
-- `TransactionType`: число между 0 и 0x7f, в общей сложности 128 возможных типов транзакций.
-- `TransactionPayload` — произвольный байтовый массив, определяемый типом транзакции.
+- `TransactionType` — число от 0 до 0x7f, что в сумме дает 128 возможных типов транзакций.
+- `TransactionPayload` — произвольный массив байтов, определяемый типом транзакции.
-В зависимости от значения `TransactionType` транзакция может быть классифицирована как
+В зависимости от значения `TransactionType` транзакцию можно классифицировать как:
-1. **Транзакции типа 0 (устаревшие).** Исходный формат транзакций, используемый с момента запуска Ethereum. Они не включают функций от [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), таких как динамические расчеты затрат газа или списки доступа для смарт-контрактов. Устаревшие транзакции не имеют конкретного префикса, указывающего их тип в сериализованной форме, и начинаются с байта `0xf8` при использовании кодировки [RLP](/developers/docs/data-structures-and-encoding/rlp). Значение TransactionType для этих транзакций — `0x0`.
+1. **Транзакции типа 0 (устаревшие):** исходный формат транзакций, используемый с момента запуска Ethereum. Они не включают такие функции из [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), как динамический расчет комиссии за газ или списки доступа для смарт-контрактов. Устаревшие транзакции не имеют определенного префикса, указывающего их тип в сериализованной форме, и начинаются с байта `0xf8` при использовании кодировки [префикса рекурсивной длины (RLP)](/developers/docs/data-structures-and-encoding/rlp). Значение `TransactionType` для этих транзакций равно `0x0`.
-2. **Транзакции типа 1.** Эти транзакции, которые появились в [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) в результате [обновления Berlin](/ethereum-forks/#berlin), включают параметр `accessList`. В этом списке указываются адреса и ключи хранения, к которым транзакция должна получить доступ, что потенциально помогает снизить затраты на [газ](/developers/docs/gas/) в сложных транзакциях, связанных со смарт-контрактами. Изменения рынка комиссий EIP-1559 не включены в транзакции типа 1. Транзакции типа 1 также включают параметр `yParity`, который может быть либо `0x0`, либо `0x1`, что указывает на четность y-значения подписи secp256k1. Они идентифицируются по байту в начале — `0x01`, а их значение TransactionType — `0x1`.
+2. **Транзакции типа 1:** Эти транзакции, представленные в [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) в рамках [обновления Berlin](/ethereum-forks/#berlin) для Ethereum, включают параметр `accessList`. Этот список определяет адреса и ключи хранилища, к которым, как ожидается, будет обращаться транзакция, что помогает потенциально снизить затраты на [газ](/developers/docs/gas/) для сложных транзакций с участием смарт-контрактов. Изменения рынка комиссий EIP-1559 не включены в транзакции типа 1. Транзакции типа 1 также включают параметр `yParity`, который может быть либо `0x0`, либо `0x1` и указывает на четность y-значения подписи secp256k1. Они идентифицируются по начальному байту `0x01`, а их значение `TransactionType` равно `0x1`.
-3. **Транзакции типа 2**, обычно называемые транзакциями EIP-1559, являются транзакциями, которые появились в [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) в результате [обновления London](/ethereum-forks/#london). Они стали стандартным типом транзакций в сети Ethereum. Эти транзакции создают новый механизм рынка комиссий, который повышает предсказуемость, разделяя комиссию за транзакции на базовую и приоритетную. Они начинаются с байта `0x02` и включают такие поля, как `maxPriorityFeePerGas` и `maxFeePerGas`. Транзакции типа 2 теперь являются стандартными из-за их гибкости и эффективности, особенно предпочтительны в периоды высокой загруженности сети из-за их способности помочь пользователям управлять комиссиями за транзакции более предсказуемо. Значение TransactionType для этих транзакций — `0x2`.
+3. **Транзакции типа 2**, широко известные как транзакции EIP-1559, это транзакции, введенные в [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) в рамках [обновления London](/ethereum-forks/#london) для Ethereum. Они стали стандартным типом транзакций в сети Ethereum. Эти транзакции создают новый механизм рынка комиссий, который повышает предсказуемость, разделяя комиссию за транзакции на базовую и приоритетную. Они начинаются с байта `0x02` и включают такие поля, как `maxPriorityFeePerGas` и `maxFeePerGas`. Транзакции типа 2 теперь являются стандартными из-за их гибкости и эффективности, особенно предпочтительны в периоды высокой загруженности сети из-за их способности помочь пользователям управлять комиссиями за транзакции более предсказуемо. Значение `TransactionType` для этих транзакций равно `0x2`.
+4. **Транзакции типа 3 (Blob)** были введены в [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) в рамках [обновления Dencun](/ethereum-forks/#dencun) в Ethereum. Эти транзакции предназначены для более эффективной обработки данных типа blob (Binary Large Objects), что особенно выгодно для ролл-апов уровня 2, поскольку они предоставляют способ публикации данных в сети Ethereum по более низкой цене. Транзакции типа blob включают дополнительные поля, такие как `blobVersionedHashes`, `maxFeePerBlobGas` и `blobGasPrice`. Они начинаются с байта `0x03`, а их значение `TransactionType` равно `0x3`. Транзакции типа blob представляют собой значительное улучшение доступности данных и возможностей масштабирования Ethereum.
+5. **Транзакции типа 4** были введены в [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) в рамках [обновления Pectra](/roadmap/pectra/) в Ethereum. Эти транзакции разработаны с учетом прямой совместимости с абстракцией аккаунтов. Они позволяют EOA временно вести себя как аккаунты смарт-контрактов, не нарушая их исходной функциональности. Они включают параметр `authorization_list`, который указывает смарт-контракт, которому EOA делегирует свои полномочия. После транзакции поле кода EOA будет содержать адрес делегированного смарт-контракта.
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
-- [EIP-2718: типизированная оболочка транзакции](https://eips.ethereum.org/EIPS/eip-2718)
+- [EIP-2718: Типизированный конверт транзакции](https://eips.ethereum.org/EIPS/eip-2718)
_Знаете ресурс сообщества, который вам пригодился? Измените эту страницу и добавьте его!_
-## Похожие темы {#related-topics}
+## Смежные темы {#related-topics}
- [Аккаунты](/developers/docs/accounts/)
- [Виртуальная машина Ethereum (EVM)](/developers/docs/evm/)
diff --git a/public/content/translations/ru/developers/docs/web2-vs-web3/index.md b/public/content/translations/ru/developers/docs/web2-vs-web3/index.md
index dc7f9dd5261..be14067979e 100644
--- a/public/content/translations/ru/developers/docs/web2-vs-web3/index.md
+++ b/public/content/translations/ru/developers/docs/web2-vs-web3/index.md
@@ -1,12 +1,12 @@
---
-title: Сравнение Web2 и Web3
-description:
+title: "Сравнение Web2 и Web3"
+description: "Сравните централизованные сервисы Web2 с децентрализованными приложениями Web3, построенными на блокчейн технологии Ethereum."
lang: ru
---
Web2 — это версия Интернета, известная сегодня большинству из нас. Интернет, в котором доминируют компании, предоставляющие услуги в обмен на ваши личные данные. Web3 в контексте Ethereum относится к децентрализованным приложениям, работающим на технологии блокчейна. Это приложения, которые позволяют каждому из нас пользоваться ими, не монетизируя при этом наши личные данные.
-Ищете более удобный для начинающих ресурс? Взгляните на наше [введение в web3](/web3/).
+Ищете более удобный для начинающих ресурс? Ознакомьтесь с нашим [введением в Web3](/web3/).
## Преимущества Web3 {#web3-benefits}
@@ -17,12 +17,12 @@ Web2 — это версия Интернета, известная сегодн
- Платежи производятся через собственный токен, эфир (ETH).
- Ethereum является полным по Тьюрингу. Это означает, что вы можете программировать практически что угодно.
-## Практическое сравнение {#practical-comparisons}
+## Практические сравнения {#practical-comparisons}
-| Web2 | Web3 |
-| ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
-| Twitter может цензурировать любой аккаунт или твит | Твиты Web3 не смогут быть подвергнуты цензуре, так как контроль в такой сети децентрализован |
-| Платежный сервис может принять решение не разрешать оплату определенных видов работ | Платежные приложения Web3 не требуют личных данных и не могут препятствовать проведению платежей |
+| Web2 | Web3 |
+| ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Twitter может цензурировать любой аккаунт или твит | Твиты Web3 не смогут быть подвергнуты цензуре, так как контроль в такой сети децентрализован |
+| Платежный сервис может принять решение не разрешать оплату определенных видов работ | Платежные приложения Web3 не требуют личных данных и не могут препятствовать проведению платежей |
| Серверы для приложений, связанных с гиг-экономикой, могут выйти из строя и повлиять на доход работников | Серверы Web3 не могут выходить из строя: в качестве бэкэнда они используют Ethereum — децентрализованную сеть из тысяч компьютеров |
Это не значит, что все сервисы должны быть превращены в децентрализованные приложения. Эти примеры иллюстрируют основные различия между сервисами web2 и web3.
@@ -40,23 +40,23 @@ Web2 — это версия Интернета, известная сегодн
В таблице, представленной ниже, перечислены некоторые общие преимущества и недостатки централизованных и децентрализованных цифровых сетей.
-| Централизованные системы | Децентрализованные системы |
-| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Низкий диаметр сети (то есть когда все участники подключены к одному крупному источнику); информация распространяется быстро, так как распространение осуществляется центральным органом, располагающим большим количеством вычислительных ресурсов. | Наиболее удаленные друг от друга участники сети потенциально могут находиться на огромном расстоянии. Информации, транслируемой с одной стороны сети, может потребоваться много времени, чтобы достичь другой стороны. |
-| Обычно более высокая производительность (более высокая пропускная способность, затрата меньшего объема общих вычислительных ресурсов) и простота реализации. | Обычно более низкая производительность (меньшая пропускная способность, затрачивается больше общих вычислительных ресурсов) и повышенная сложность в реализации. |
-| В случае противоречивых данных разрешение понятно и легко: окончательный источник истины — это центральный орган. | Если одноранговые узлы приходят к противоречивым заключениям о состоянии данных, по которым участники должны синхронизироваться, то для разрешения таких споров необходим протокол (часто сложный). |
-| Единая точка отказа: злоумышленники могут вывести из строя сеть, выбрав целью центральный орган. | Нет единой точки отказа: сеть может продолжать функционировать, даже если большая часть участников подвергнется атаке или отключению от сети. |
-| Координация между участниками сети намного проще и осуществляется центральным органом управления. Центральный орган может заставить участников сети применять обновления системы или протоколов с минимальными трениями. | Координация часто затруднена, поскольку ни один участник системы не имеет последнего слова при принятии решений на уровне сети, обновлении протокола и т. д. В худшем случае сеть приблизится к расколу из-за разногласий по поводу изменений протокола. |
-| Центральный орган может подвергать данные цензуре, потенциально отрезая части сети от взаимодействия с остальной ее частью. | Подвергать что-либо цензуре становится намного сложнее, поскольку информация может распространяться по сети разными способами. |
-| Участие в сети контролируется центральным органом. | Кто угодно может участвовать в сети, так как там нет никаких «надзирателей». В идеале цена участия очень низкая. |
+| Централизованные системы | Децентрализованные системы |
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Низкий диаметр сети (то есть когда все участники подключены к одному крупному источнику); информация распространяется быстро, так как распространение осуществляется центральным органом, располагающим большим количеством вычислительных ресурсов. | Наиболее удаленные друг от друга участники сети потенциально могут находиться на огромном расстоянии. Информации, транслируемой с одной стороны сети, может потребоваться много времени, чтобы достичь другой стороны. |
+| Обычно более высокая производительность (более высокая пропускная способность, затрата меньшего объема общих вычислительных ресурсов) и простота реализации. | Обычно более низкая производительность (меньшая пропускная способность, затрачивается больше общих вычислительных ресурсов) и повышенная сложность в реализации. |
+| В случае противоречивых данных разрешение понятно и легко: окончательный источник истины — это центральный орган. | Если одноранговые узлы приходят к противоречивым заключениям о состоянии данных, по которым участники должны синхронизироваться, то для разрешения таких споров необходим протокол (часто сложный). |
+| Единая точка отказа: злоумышленники могут вывести из строя сеть, выбрав целью центральный орган. | Нет единой точки отказа: сеть может продолжать функционировать, даже если большая часть участников подвергнется атаке или отключению от сети. |
+| Координация между участниками сети намного проще и осуществляется центральным органом управления. Центральный орган может заставить участников сети применять обновления системы или протоколов с минимальными трениями. | Координация часто затруднена, поскольку ни один участник системы не имеет последнего слова при принятии решений на уровне сети, обновлении протокола и т. д. В худшем случае сеть приблизится к расколу из-за разногласий по поводу изменений протокола. |
+| Центральный орган может подвергать данные цензуре, потенциально отрезая части сети от взаимодействия с остальной ее частью. | Подвергать что-либо цензуре становится намного сложнее, поскольку информация может распространяться по сети разными способами. |
+| Участие в сети контролируется центральным органом. | Кто угодно может участвовать в сети, так как там нет никаких «надзирателей». В идеале цена участия очень низкая. |
Обратите внимание, что это общие шаблоны, которые могут не выполняться в каждой из сетей. Более того, в действительности степень централизации или децентрализации сети выражается промежуточным значением; ни одна сеть не является полностью централизованной или полностью децентрализованной.
-## Дополнительные ресурсы {#further-reading}
+## Дополнительные материалы {#further-reading}
- [Что такое Web3?](/web3/) — _ethereum.org_
-- [Архитектура приложения Web 3.0](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) — _Прити Касиредди_
-- [Значение децентрализации](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) — _6 февраля 2017 г., Виталик Бутерин_
-- [Почему важна децентрализация](https://medium.com/s/story/why-decentralization-matters-5e3f79f7638e) — _18 февраля 2018 г., Крис Диксон_
-- [Что такое Web 3.0 и почему это важно](https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b) — _31 декабря 2019 г., Макс Мерш и Ричард Мюрхед_
-- [Зачем нам Web 3.0](https://medium.com/@gavofyork/why-we-need-web-3-0-5da4f2bf95ab) — _12 сентября 2018 г., Гэвин Вуд_
+- [Архитектура Web 3.0-приложения](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) — _Preethi Kasireddy_
+- [Значение децентрализации](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) _6 февраля 2017 г. — Виталик Бутерин_
+- [Почему децентрализация имеет значение](https://onezero.medium.com/why-decentralization-matters-5e3f79f7638e) _18 февраля 2018 г. — Крис Диксон_
+- [Что такое Web 3.0 и почему это важно](https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b) _31 декабря 2019 г. — Макс Мерш и Ричард Мьюирхед_
+- [Зачем нам нужен Web 3.0](https://gavofyork.medium.com/why-we-need-web-3-0-5da4f2bf95ab) _12 сентября 2018 г. — Гэвин Вуд_
diff --git a/public/content/translations/ru/developers/docs/wrapped-eth/index.md b/public/content/translations/ru/developers/docs/wrapped-eth/index.md
index a1a9bec063f..c23bb3a7c2f 100644
--- a/public/content/translations/ru/developers/docs/wrapped-eth/index.md
+++ b/public/content/translations/ru/developers/docs/wrapped-eth/index.md
@@ -1,6 +1,6 @@
---
-title: Что такое обернутый эфир (WETH)
-description: Введение в обернутый эфир (WETH) — ERC20-совместимую оболочку для эфира (ETH).
+title: "Что такое обернутый эфир (WETH)"
+description: "Введение в обернутый эфир (WETH) — ERC20-совместимую оболочку для эфира (ETH)."
lang: ru
---
@@ -35,19 +35,16 @@ Ether (ETH) — основная валюта Ethereum. Он используе
Вы платите комиссию за газ для обертывания или развертывания ETH с использованием контракта WETH.
-
WETH обычно считается безопасным, поскольку он основан на простом и проверенном смарт-контракте. Контракт WETH также официально проверен, что является высшим стандартом безопасности для смарт-контрактов на Ethereum.
-
Помимо [канонической реализации WETH](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), описанной на этой странице, существуют и другие варианты. Это могут быть специальные токены, созданные разработчиками приложений, или версии, выпущенные в других блокчейнах, которые могут вести себя по-разному или иметь другие параметры безопасности. **Всегда дважды проверяйте информацию о токене, чтобы знать, с какой реализацией WETH вы взаимодействуете.**
-
@@ -55,7 +52,6 @@ WETH обычно считается безопасным, поскольку о
- [Основная сеть Ethereum](https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
- [Arbitrum](https://arbiscan.io/token/0x82af49447d8a07e3bd95bd0d56f35241523fbab1)
- [Optimism](https://optimistic.etherscan.io/token/0x4200000000000000000000000000000000000006)
-
## Дополнительные материалы {#further-reading}
diff --git a/public/content/translations/ru/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/ru/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md
new file mode 100644
index 00000000000..aff2c8a8786
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md
@@ -0,0 +1,300 @@
+---
+title: "Введение в Ethereum для разработчиков на Python, часть 1"
+description: "Введение в разработку для Ethereum, особенно полезное для тех, кто знаком с языком программирования Python"
+author: Marc Garreau
+lang: ru
+tags: [ "Python", "web3.py" ]
+skill: beginner
+published: 2020-09-08
+source: Snake charmers
+sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/
+---
+
+Итак, вы слышали об Ethereum и готовы нырнуть в кроличью нору? В этой статье мы быстро рассмотрим некоторые основы блокчейна, а затем вы сможете поработать с симулированным узлом Ethereum: читать данные блоков, проверять балансы счетов и отправлять транзакции. Попутно мы выделим различия между традиционными способами создания приложений и этой новой децентрализованной парадигмой.
+
+## Рекомендуемые предварительные требования {#soft-prerequisites}
+
+Эта статья призвана быть доступной для широкого круга разработчиков. В статье будут использоваться [инструменты Python](/developers/docs/programming-languages/python/), но они являются лишь средством для демонстрации идей. Ничего страшного, если вы не являетесь Python-разработчиком. Однако я сделаю несколько предположений о том, что вы уже знаете, чтобы мы могли быстрее перейти к особенностям Ethereum.
+
+Предположения:
+
+- Вы умеете работать в терминале,
+- Вы написали несколько строк кода на Python,
+- На вашем компьютере установлен Python версии 3.6 или выше (настоятельно рекомендуется использовать [виртуальную среду](https://realpython.com/effective-python-environment/#virtual-environments)), и
+- вы использовали `pip`, установщик пакетов Python.
+ Опять же, если что-то из этого неверно или вы не планируете воспроизводить код из этой статьи, вы, скорее всего, все равно сможете без проблем следить за изложением.
+
+## Коротко о блокчейнах {#blockchains-briefly}
+
+Существует много способов описать Ethereum, но в его основе лежит блокчейн. Блокчейны состоят из серии блоков, так что давайте с этого и начнем. Проще говоря, каждый блок в блокчейне Ethereum — это просто набор метаданных и список транзакций. В формате JSON это выглядит примерно так:
+
+```json
+{
+ "number": 1234567,
+ "hash": "0xabc123...",
+ "parentHash": "0xdef456...",
+ ...,
+ "transactions": [...]
+}
+```
+
+Каждый [блок](/developers/docs/blocks/) содержит ссылку на предшествующий ему блок; `parentHash` — это просто хэш предыдущего блока.
+
+Примечание. Ethereum регулярно использует хэш-функции для получения значений фиксированного размера («хэшей»). Хэши играют важную роль в Ethereum, но пока вы можете спокойно считать их уникальными идентификаторами.
+
+
+
+_По сути, блокчейн — это связный список; каждый блок содержит ссылку на предыдущий._
+
+Эта структура данных не нова, но новаторскими являются правила (т. е. одноранговые протоколы), которые управляют сетью. Центрального органа управления нет; участники сети должны сотрудничать для ее поддержания и конкурировать за право решать, какие транзакции включать в следующий блок. Итак, когда вы хотите отправить деньги другу, вам нужно будет объявить об этой транзакции в сети, а затем дождаться ее включения в один из следующих блоков.
+
+Единственный способ для блокчейна проверить, что деньги действительно были отправлены от одного пользователя другому, — это использовать собственную валюту (т. е. созданную и управляемую) этого блокчейна. В Ethereum эта валюта называется ether (эфир), а блокчейн Ethereum содержит единственную официальную запись о балансах счетов.
+
+## Новая парадигма {#a-new-paradigm}
+
+Этот новый децентрализованный технологический стек породил новые инструменты для разработчиков. Такие инструменты существуют для многих языков программирования, но мы будем рассматривать их через призму Python. Повторюсь: даже если Python не является языком вашего выбора, вам не составит особого труда следить за изложением.
+
+Python-разработчики, которые хотят взаимодействовать с Ethereum, скорее всего, воспользуются [Web3.py](https://web3py.readthedocs.io/). Web3.py — это библиотека, которая значительно упрощает подключение к узлу Ethereum, а также отправку и получение данных от него.
+
+Примечание. «Узел Ethereum» и «клиент Ethereum» используются как взаимозаменяемые понятия. В любом случае речь идет о программном обеспечении, которое запускает участник сети Ethereum. Это программное обеспечение может читать данные блоков, получать обновления при добавлении в цепь новых блоков, объявлять о новых транзакциях и многое другое. Технически клиент — это программное обеспечение, а узел — это компьютер, на котором это программное обеспечение запущено.
+
+[Клиенты Ethereum](/developers/docs/nodes-and-clients/) могут быть настроены для доступа по [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP или через веб-сокеты, поэтому Web3.py должен будет отражать эту конфигурацию. Web3.py называет эти варианты подключения **провайдерами**. Вам нужно будет выбрать одного из трех провайдеров, чтобы связать экземпляр Web3.py с вашим узлом.
+
+
+
+_Настройте узел Ethereum и Web3.py для обмена данными по одному и тому же протоколу, например, IPC на этой диаграмме._
+
+После правильной настройки Web3.py вы можете начать взаимодействовать с блокчейном. Вот пара примеров использования Web3.py в качестве предварительного ознакомления с тем, что нас ждет впереди:
+
+```python
+# чтение данных блока:
+w3.eth.get_block('latest')
+
+# отправка транзакции:
+w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...})
+```
+
+## Установка {#installation}
+
+В этом пошаговом руководстве мы будем работать только в интерпретаторе Python. Мы не будем создавать никаких каталогов, файлов, классов или функций.
+
+Примечание. В приведенных ниже примерах команды, начинающиеся с `$`, предназначены для запуска в терминале. (Не вводите символ `$`, он просто обозначает начало строки.)
+
+Сначала установите [IPython](https://ipython.org/), чтобы получить удобную среду для изучения. Помимо прочих функций, IPython предлагает автодополнение по клавише Tab, что значительно упрощает изучение возможностей Web3.py.
+
+```bash
+pip install ipython
+```
+
+Web3.py опубликован под названием `web3`. Установить его можно так:
+
+```bash
+pip install web3
+```
+
+И еще кое-что: позже мы будем симулировать блокчейн, для чего потребуется еще пара зависимостей. Их можно установить с помощью следующей команды:
+
+```bash
+pip install 'web3[tester]'
+```
+
+Все готово к работе!
+
+Примечание. Пакет `web3[tester]` работает вплоть до версии Python 3.10.xx
+
+## Запускаем песочницу {#spin-up-a-sandbox}
+
+Откройте новую среду Python, запустив `ipython` в своем терминале. Это похоже на запуск `python`, но с большим количеством дополнительных возможностей.
+
+```bash
+ipython
+```
+
+Будет выведена информация о версиях Python и IPython, после чего вы увидите приглашение для ввода:
+
+```python
+In [1]:
+```
+
+Теперь вы смотрите в интерактивную оболочку Python. По сути, это песочница для экспериментов. Если вы дошли до этого места, то пора импортировать Web3.py:
+
+```python
+In [1]: from web3 import Web3
+```
+
+## Знакомство с модулем Web3 {#introducing-the-web3-module}
+
+Помимо того, что модуль [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) является шлюзом в Ethereum, он предлагает несколько удобных функций. Давайте рассмотрим некоторые из них.
+
+В приложении Ethereum часто возникает необходимость конвертировать номиналы валют. Модуль Web3 предоставляет для этого пару вспомогательных методов: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) и [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei).
+
+
+Примечание. Компьютеры печально известны плохой обработкой десятичной арифметики. Чтобы обойти это, разработчики часто хранят суммы в долларах в центах. Например, товар с ценой $5,99 может храниться в базе данных как 599.
+
+Аналогичный подход используется при обработке транзакций в ether. Однако вместо двух десятичных знаков у ether их 18! Самая маленькая единица ether называется wei, и именно это значение указывается при отправке транзакций.
+
+1 ether = 1000000000000000000 wei
+
+1 wei = 0.000000000000000001 ether
+
+
+
+Попробуйте конвертировать некоторые значения в wei и обратно. Обратите внимание, что [многие из номиналов](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations) между ether и wei имеют свои названия. Один из наиболее известных среди них — **gwei**, так как в нем часто указывают комиссию за транзакции.
+
+```python
+In [2]: Web3.to_wei(1, 'ether')
+Out[2]: 1000000000000000000
+
+In [3]: Web3.from_wei(500000000, 'gwei')
+Out[3]: Decimal('0.5')
+```
+
+Другие служебные методы модуля Web3 включают преобразователи форматов данных (например, [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), вспомогательные функции для адресов (например, [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) и хэш-функции (например, [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)). Многие из них будут рассмотрены далее в этой серии статей. Чтобы просмотреть все доступные методы и свойства, воспользуйтесь автодополнением IPython, набрав `Web3`. и дважды нажав клавишу Tab после точки.
+
+## Общение с блокчейном {#talk-to-the-chain}
+
+Вспомогательные методы — это прекрасно, но давайте перейдем к блокчейну. Следующим шагом является настройка Web3.py для взаимодействия с узлом Ethereum. Здесь у нас есть возможность использовать провайдеры IPC, HTTP или Websocket.
+
+Мы не будем идти по этому пути, но пример полного рабочего процесса с использованием HTTP-провайдера может выглядеть примерно так:
+
+- Скачайте узел Ethereum, например, [Geth](https://geth.ethereum.org/).
+- Запустите Geth в одном окне терминала и дождитесь синхронизации с сетью. Порт HTTP по умолчанию — `8545`, но его можно настроить.
+- Сообщите Web3.py, чтобы он подключался к узлу через HTTP, по адресу `localhost:8545`.
+ `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))`
+- Используйте экземпляр `w3` для взаимодействия с узлом.
+
+Хотя это один из «реальных» способов, процесс синхронизации занимает часы и не является необходимым, если вам просто нужна среда разработки. Для этой цели Web3.py предоставляет четвертый провайдер — **EthereumTesterProvider**. Этот тестовый провайдер подключается к симулированному узлу Ethereum с более мягкими правами доступа и поддельной валютой для экспериментов.
+
+
+
+_EthereumTesterProvider подключается к симулированному узлу и удобен для быстрой организации сред разработки._
+
+Этот симулированный узел называется [eth-tester](https://github.com/ethereum/eth-tester), и мы установили его в рамках команды `pip install web3[tester]`. Настроить Web3.py для использования этого тестового провайдера очень просто:
+
+```python
+In [4]: w3 = Web3(Web3.EthereumTesterProvider())
+```
+
+Теперь вы готовы к серфингу по блокчейну! Вообще-то так не говорят. Я только что это выдумал. Давайте совершим краткий тур.
+
+## Краткий тур {#the-quick-tour}
+
+Первым делом — проверка работоспособности:
+
+```python
+In [5]: w3.is_connected()
+Out[5]: True
+```
+
+Поскольку мы используем тестовый провайдер, эта проверка не очень информативна, но если она не удалась, скорее всего, вы что-то не так набрали при создании экземпляра переменной `w3`. Перепроверьте, что вы включили внутренние скобки, т. е. `Web3.EthereumTesterProvider()`.
+
+## Остановка № 1: [аккаунты](/developers/docs/accounts/) {#tour-stop-1-accounts}
+
+Для удобства тестовый провайдер создал несколько аккаунтов и предварительно пополнил их тестовым эфиром.
+
+Сначала давайте посмотрим список этих аккаунтов:
+
+```python
+In [6]: w3.eth.accounts
+Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
+ '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',
+ '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...]
+```
+
+Если вы выполните эту команду, вы должны увидеть список из десяти строк, начинающихся с `0x`. Каждая из них является **публичным адресом** и в некотором роде аналогична номеру расчетного счета. Вы можете предоставить этот адрес тому, кто хочет отправить вам эфир.
+
+Как уже упоминалось, тестовый провайдер предварительно пополнил каждый из этих аккаунтов некоторым количеством тестового эфира. Давайте узнаем, сколько средств на первом аккаунте:
+
+```python
+In [7]: w3.eth.get_balance(w3.eth.accounts[0])
+Out[7]: 1000000000000000000000000
+```
+
+Как много нулей! Прежде чем вы побежите в поддельный банк, вспомните урок о номиналах валюты. Суммы в ether выражаются в наименьшем номинале — wei. Конвертируйте это в ether:
+
+```python
+In [8]: w3.from_wei(1000000000000000000000000, 'ether')
+Out[8]: Decimal('1000000')
+```
+
+Один миллион тестовых ether — тоже неплохо.
+
+## Остановка № 2: данные блока {#tour-stop-2-block-data}
+
+Давайте посмотрим на состояние этого симулированного блокчейна:
+
+```python
+In [9]: w3.eth.get_block('latest')
+Out[9]: AttributeDict({
+ 'number': 0,
+ 'hash': HexBytes('0x9469878...'),
+ 'parentHash': HexBytes('0x0000000...'),
+ ...
+ 'transactions': []
+})
+```
+
+О блоке возвращается много информации, но здесь следует отметить лишь несколько моментов:
+
+- Номер блока — ноль, независимо от того, как давно вы настроили тестовый провайдер. В отличие от реальной сети Ethereum, которая добавляет новый блок каждые 12 секунд, эта симуляция будет ждать, пока вы не дадите ей какую-нибудь работу.
+- `transactions` — это пустой список по той же причине: мы еще ничего не делали. Этот первый блок — **пустой блок**, он нужен просто для того, чтобы запустить цепочку.
+- Обратите внимание, что `parentHash` — это просто набор пустых байтов. Это означает, что это первый блок в цепочке, также известный как **генезис-блок**.
+
+## Остановка № 3: [транзакции](/developers/docs/transactions/) {#tour-stop-3-transactions}
+
+Мы застряли на нулевом блоке, пока не появится ожидающая транзакция, так что давайте создадим ее. Отправьте несколько тестовых ether с одного аккаунта на другой:
+
+```python
+In [10]: tx_hash = w3.eth.send_transaction({
+ 'from': w3.eth.accounts[0],
+ 'to': w3.eth.accounts[1],
+ 'value': w3.to_wei(3, 'ether'),
+ 'gas': 21000
+})
+```
+
+Обычно в этот момент вам пришлось бы ждать несколько секунд, пока ваша транзакция не будет включена в новый блок. Полный процесс выглядит примерно так:
+
+1. Отправьте транзакцию и сохраните ее хэш. Пока блок, содержащий транзакцию, не будет создан и распространен, транзакция находится в состоянии «ожидания».
+ `tx_hash = w3.eth.send_transaction({ … })`
+2. Дождитесь включения транзакции в блок:
+ `w3.eth.wait_for_transaction_receipt(tx_hash)`
+3. Продолжите логику приложения. Чтобы просмотреть успешную транзакцию:
+ `w3.eth.get_transaction(tx_hash)`
+
+Наша симулированная среда мгновенно добавит транзакцию в новый блок, так что мы можем сразу же просмотреть транзакцию:
+
+```python
+In [11]: w3.eth.get_transaction(tx_hash)
+Out[11]: AttributeDict({
+ 'hash': HexBytes('0x15e9fb95dc39...'),
+ 'blockNumber': 1,
+ 'transactionIndex': 0,
+ 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
+ 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',
+ 'value': 3000000000000000000,
+ ...
+})
+```
+
+Здесь вы увидите некоторые знакомые детали: поля `from`, `to` и `value` должны соответствовать входным данным нашего вызова `send_transaction`. Еще один обнадеживающий момент заключается в том, что эта транзакция была включена как первая транзакция (`'transactionIndex': 0`) в блок номер 1.
+
+Мы также можем легко проверить успешность этой транзакции, проверив балансы двух задействованных аккаунтов. Три ether должны были переместиться с одного на другой.
+
+```python
+In [12]: w3.eth.get_balance(w3.eth.accounts[0])
+Out[12]: 999996999979000000000000
+
+In [13]: w3.eth.get_balance(w3.eth.accounts[1])
+Out[13]: 1000003000000000000000000
+```
+
+Последний выглядит хорошо! Баланс изменился с 1 000 000 до 1 000 003 ether. Но что случилось с первым аккаунтом? Похоже, он потерял немного больше трех ether. Увы, в жизни ничто не дается бесплатно, и использование публичной сети Ethereum требует, чтобы вы компенсировали другим участникам их поддерживающую роль. С аккаунта, отправившего транзакцию, была списана небольшая комиссия за транзакцию. Эта комиссия представляет собой объем сожженного газа (21 000 единиц газа за перевод ETH), умноженный на базовую комиссию, которая варьируется в зависимости от активности сети, плюс чаевые, которые получает валидатор, включивший транзакцию в блок.
+
+Подробнее о [газе](/developers/docs/gas/#post-london)
+
+Примечание. В публичной сети комиссии за транзакции являются переменными и зависят от спроса в сети и от того, насколько быстро вы хотите, чтобы транзакция была обработана. Если вас интересует, как рассчитываются комиссии, см. мой предыдущий пост о том, как транзакции включаются в блок.
+
+## И выдохнем {#and-breathe}
+
+Мы уже довольно долго этим занимаемся, так что это хорошее место, чтобы сделать перерыв. Кроличья нора продолжается, и мы продолжим ее исследование во второй части этой серии статей. Некоторые из будущих тем: подключение к реальному узлу, смарт-контракты и токены. Остались вопросы? Дайте мне знать! Ваши отзывы повлияют на то, куда мы будем двигаться дальше. Запросы принимаются через [Twitter](https://twitter.com/wolovim).
diff --git a/public/content/translations/ru/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/ru/developers/tutorials/all-you-can-cache/index.md
new file mode 100644
index 00000000000..5a57f9c72e3
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/all-you-can-cache/index.md
@@ -0,0 +1,867 @@
+---
+title: "Что можно кешировать"
+description: "Узнайте, как создать и использовать кеширующий контракт для более дешевых транзакций ролл-апа"
+author: Ori Pomerantz
+tags: [ "уровень 2", "кеширование", "хранилище" ]
+skill: intermediate
+published: 2022-09-15
+lang: ru
+---
+
+При использовании ролл-апов стоимость байта в транзакции намного выше, чем стоимость слота в хранилище. Поэтому имеет смысл кешировать ончейн как можно больше информации.
+
+В этой статье вы узнаете, как создавать и использовать кеширующий контракт таким образом, чтобы любое значение параметра, которое, скорее всего, будет использоваться несколько раз, кешировалось и было доступно для использования (после первого раза) с гораздо меньшим количеством байтов, и как писать оффчейн-код, использующий этот кеш.
+
+Если вы хотите пропустить статью и просто посмотреть исходный код, [он находится здесь](https://github.com/qbzzt/20220915-all-you-can-cache). Стек разработки — [Foundry](https://getfoundry.sh/introduction/installation/).
+
+## Общий дизайн {#overall-design}
+
+Для простоты предположим, что все параметры транзакции имеют тип `uint256` и длину 32 байта. Когда мы получаем транзакцию, мы разбираем каждый параметр следующим образом:
+
+1. Если первый байт равен `0xFF`, взять следующие 32 байта как значение параметра и записать его в кеш.
+
+2. Если первый байт равен `0xFE`, взять следующие 32 байта как значение параметра, но _не_ записывать его в кеш.
+
+3. Для любого другого значения взять старшие четыре бита как количество дополнительных байтов, а младшие четыре бита — как старшие значащие биты ключа кеша. Вот несколько примеров:
+
+ | Байты в calldata | Ключ кеша |
+ | :--------------- | --------: |
+ | 0x0F | 0x0F |
+ | 0x10,0x10 | 0x10 |
+ | 0x12,0xAC | 0x02AC |
+ | 0x2D,0xEA, 0xD6 | 0x0DEAD6 |
+
+## Манипулирование кешем {#cache-manipulation}
+
+Кеш реализован в [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol). Давайте рассмотрим его построчно.
+
+```solidity
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.13;
+
+
+contract Cache {
+
+ bytes1 public constant INTO_CACHE = 0xFF;
+ bytes1 public constant DONT_CACHE = 0xFE;
+```
+
+Эти константы используются для интерпретации особых случаев, когда мы предоставляем всю информацию и решаем, записывать ее в кеш или нет. Запись в кеш требует двух операций [`SSTORE`](https://www.evm.codes/#55) в ранее неиспользованные слоты хранилища стоимостью 22100 ед. газа каждая, поэтому мы делаем ее необязательной.
+
+```solidity
+
+ mapping(uint => uint) public val2key;
+```
+
+[Сопоставление (mapping)](https://www.geeksforgeeks.org/solidity/solidity-mappings/) между значениями и их ключами. Эта информация необходима для кодирования значений перед отправкой транзакции.
+
+```solidity
+ // Ячейка n содержит значение для ключа n+1, потому что нам нужно сохранить
+ // ноль как значение «не в кеше».
+ uint[] public key2val;
+```
+
+Мы можем использовать массив для сопоставления ключей со значениями, потому что мы сами назначаем ключи, и для простоты делаем это последовательно.
+
+```solidity
+ function cacheRead(uint _key) public view returns (uint) {
+ require(_key <= key2val.length, "Чтение неинициализированной записи кеша");
+ return key2val[_key-1];
+ } // cacheRead
+```
+
+Чтение значения из кеша.
+
+```solidity
+ // Записать значение в кеш, если его там еще нет
+ // Public только для того, чтобы тест работал
+ function cacheWrite(uint _value) public returns (uint) {
+ // Если значение уже есть в кеше, вернуть текущий ключ
+ if (val2key[_value] != 0) {
+ return val2key[_value];
+ }
+```
+
+Нет смысла помещать одно и то же значение в кеш более одного раза. Если значение уже есть, просто верните существующий ключ.
+
+```solidity
+ // Поскольку 0xFE — это особый случай, самый большой ключ, который может
+ // содержать кеш, — это 0x0D, за которым следуют 15 значений 0xFF. Если длина кеша уже
+ // настолько велика, произойдет сбой.
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
+ "переполнение кеша");
+```
+
+Я не думаю, что мы когда-нибудь получим кеш такого большого размера (примерно 1,8\*1037 записей, для хранения которых потребуется около 1027 ТБ). Однако я достаточно стар, чтобы помнить [«640 КБ всегда будет достаточно»](https://quoteinvestigator.com/2011/09/08/640k-enough/). Эта проверка очень «дешевая» (не требует больших затрат).
+
+```solidity
+ // Записать значение, используя следующий ключ
+ val2key[_value] = key2val.length+1;
+```
+
+Добавление обратного поиска (от значения к ключу).
+
+```solidity
+ key2val.push(_value);
+```
+
+Добавление прямого поиска (от ключа к значению). Поскольку мы присваиваем значения последовательно, мы можем просто добавить его после последнего значения массива.
+
+```solidity
+ return key2val.length;
+ } // cacheWrite
+```
+
+Возвращается новая длина `key2val`, которая является ячейкой, где хранится новое значение.
+
+```solidity
+ function _calldataVal(uint startByte, uint length)
+ private pure returns (uint)
+```
+
+Эта функция считывает из calldata значение произвольной длины (до 32 байт, размер слова).
+
+```solidity
+ {
+ uint _retVal;
+
+ require(length < 0x21,
+ "_calldataVal length limit is 32 bytes");
+ require(length + startByte <= msg.data.length,
+ "_calldataVal trying to read beyond calldatasize");
+```
+
+Эта функция является внутренней, поэтому, если остальная часть кода написана правильно, эти тесты не требуются. Однако они не требуют больших затрат, так что их можно оставить.
+
+```solidity
+ assembly {
+ _retVal := calldataload(startByte)
+ }
+```
+
+Этот код написан на [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html). Он считывает 32-байтовое значение из calldata. Это работает, даже если calldata заканчивается до `startByte+32`, потому что неинициализированное пространство в EVM считается нулевым.
+
+```solidity
+ _retVal = _retVal >> (256-length*8);
+```
+
+Нам не обязательно нужно 32-байтовое значение. Это избавляет от лишних байтов.
+
+```solidity
+ return _retVal;
+ } // _calldataVal
+
+
+ // Считать один параметр из calldata, начиная с _fromByte
+ function _readParam(uint _fromByte) internal
+ returns (uint _nextByte, uint _parameterValue)
+ {
+```
+
+Считывание одного параметра из calldata. Обратите внимание, что нам нужно вернуть не только прочитанное значение, но и местоположение следующего байта, потому что параметры могут иметь длину от 1 до 33 байт.
+
+```solidity
+ // Первый байт говорит нам, как интерпретировать остальные
+ uint8 _firstByte;
+
+ _firstByte = uint8(_calldataVal(_fromByte, 1));
+```
+
+Solidity пытается уменьшить количество ошибок, запрещая потенциально опасные [неявные преобразования типов](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions). Понижение, например с 256 бит до 8 бит, должно быть явным.
+
+```solidity
+
+ // Прочитать значение, но не записывать его в кеш
+ if (_firstByte == uint8(DONT_CACHE))
+ return(_fromByte+33, _calldataVal(_fromByte+1, 32));
+
+ // Прочитать значение и записать его в кеш
+ if (_firstByte == uint8(INTO_CACHE)) {
+ uint _param = _calldataVal(_fromByte+1, 32);
+ cacheWrite(_param);
+ return(_fromByte+33, _param);
+ }
+
+ // Если мы дошли до этого места, это означает, что нам нужно читать из кеша
+
+ // Количество дополнительных байтов для чтения
+ uint8 _extraBytes = _firstByte / 16;
+```
+
+Возьмите младший [ниббл](https://en.wikipedia.org/wiki/Nibble) и объедините его с другими байтами, чтобы прочитать значение из кеша.
+
+```solidity
+ uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) +
+ _calldataVal(_fromByte+1, _extraBytes);
+
+ return (_fromByte+_extraBytes+1, cacheRead(_key));
+
+ } // _readParam
+
+
+ // Прочитать n параметров (функции знают, сколько параметров они ожидают)
+ function _readParams(uint _paramNum) internal returns (uint[] memory) {
+```
+
+Мы могли бы получить количество имеющихся у нас параметров из самой calldata, но функции, которые нас вызывают, знают, сколько параметров они ожидают. Проще позволить им сообщить нам.
+
+```solidity
+ // Параметры, которые мы читаем
+ uint[] memory params = new uint[](_paramNum);
+
+ // Параметры начинаются с 4-го байта, до этого идет сигнатура функции
+ uint _atByte = 4;
+
+ for(uint i=0; i<_paramNum; i++) {
+ (_atByte, params[i]) = _readParam(_atByte);
+ }
+```
+
+Считывайте параметры, пока не получите необходимое их количество. Если мы выйдем за конец calldata, `_readParams` отменит вызов.
+
+```solidity
+
+ return(params);
+ } // readParams
+
+ // Для тестирования _readParams, протестируйте чтение четырех параметров
+ function fourParam() public
+ returns (uint256,uint256,uint256,uint256)
+ {
+ uint[] memory params;
+ params = _readParams(4);
+ return (params[0], params[1], params[2], params[3]);
+ } // fourParam
+```
+
+Одним из больших преимуществ Foundry является то, что он позволяет писать тесты на Solidity ([см. Тестирование кеша ниже](#testing-the-cache)). Это значительно упрощает модульные тесты. Это функция, которая считывает четыре параметра и возвращает их, чтобы тест мог проверить их правильность.
+
+```solidity
+ // Получить значение, вернуть байты, которые будут его кодировать (используя кеш, если это возможно)
+ function encodeVal(uint _val) public view returns(bytes memory) {
+```
+
+`encodeVal` — это функция, которую вызывает оффчейн-код, чтобы помочь создать calldata, использующую кеш. Она получает одно значение и возвращает байты, которые его кодируют. Эта функция является `view`, поэтому она не требует транзакции и при внешнем вызове не требует затрат газа.
+
+```solidity
+ uint _key = val2key[_val];
+
+ // Значения еще нет в кеше, добавляем его
+ if (_key == 0)
+ return bytes.concat(INTO_CACHE, bytes32(_val));
+```
+
+В [EVM](/developers/docs/evm/) все неинициализированное хранилище считается нулевым. Поэтому, если мы ищем ключ для значения, которого там нет, мы получаем ноль. В этом случае байты, которые его кодируют, — это `INTO_CACHE` (чтобы в следующий раз оно было кешировано), за которым следует фактическое значение.
+
+```solidity
+ // Если ключ <0x10, вернуть его как один байт
+ if (_key < 0x10)
+ return bytes.concat(bytes1(uint8(_key)));
+```
+
+С одиночными байтами проще всего. Мы просто используем [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat), чтобы превратить тип `bytes` в массив байтов, который может быть любой длины. Несмотря на название, она отлично работает и при наличии только одного аргумента.
+
+```solidity
+ // Двухбайтовое значение, закодированное как 0x1vvv
+ if (_key < 0x1000)
+ return bytes.concat(bytes2(uint16(_key) | 0x1000));
+```
+
+Когда у нас есть ключ меньше 163, мы можем выразить его в двух байтах. Сначала мы преобразуем `_key`, которое является 256-битным значением, в 16-битное значение и используем логическое «ИЛИ», чтобы добавить количество дополнительных байтов к первому байту. Затем мы просто преобразуем его в значение `bytes2`, которое может быть конвертировано в `bytes`.
+
+```solidity
+ // Вероятно, есть более изящный способ сделать следующие строки в виде цикла,
+ // но это функция view, поэтому я оптимизирую ее с точки зрения времени программиста и
+ // простоты.
+
+ if (_key < 16*256**2)
+ return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2)));
+ if (_key < 16*256**3)
+ return bytes.concat(bytes4(uint32(_key) | (0x3 * 16 * 256**3)));
+ .
+ .
+ .
+ if (_key < 16*256**14)
+ return bytes.concat(bytes15(uint120(_key) | (0xE * 16 * 256**14)));
+ if (_key < 16*256**15)
+ return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15)));
+```
+
+Другие значения (3 байта, 4 байта и т. д.) обрабатываются таким же образом, только с полями разного размера.
+
+```solidity
+ // Если мы дошли до этого места, что-то не так.
+ revert("Ошибка в encodeVal, этого не должно было случиться");
+```
+
+Если мы дошли до этого места, это означает, что мы получили ключ, который не меньше 16\*25615. Но `cacheWrite` ограничивает ключи, поэтому мы не можем даже дойти до 14\*25616 (первый байт которого будет 0xFE, так что это будет выглядеть как `DONT_CACHE`). Но добавить тест на случай, если будущий программист допустит ошибку, не составит большого труда.
+
+```solidity
+ } // encodeVal
+
+} // Cache
+```
+
+### Тестирование кеша {#testing-the-cache}
+
+Одно из преимуществ Foundry заключается в том, что [оно позволяет писать тесты на Solidity](https://getfoundry.sh/forge/tests/overview/), что упрощает написание модульных тестов. Тесты для класса `Cache` находятся [здесь](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Поскольку код для тестов повторяется, что характерно для тестов, в этой статье объясняются только интересные части.
+
+```solidity
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.13;
+
+import "forge-std/Test.sol";
+
+
+// Необходимо запустить `forge test -vv` для console.
+import "forge-std/console.sol";
+```
+
+Это просто шаблонный код, необходимый для использования тестового пакета и `console.log`.
+
+```solidity
+import "src/Cache.sol";
+```
+
+Нам нужно знать контракт, который мы тестируем.
+
+```solidity
+contract CacheTest is Test {
+ Cache cache;
+
+ function setUp() public {
+ cache = new Cache();
+ }
+```
+
+Функция `setUp` вызывается перед каждым тестом. В этом случае мы просто создаем новый кеш, чтобы наши тесты не влияли друг на друга.
+
+```solidity
+ function testCaching() public {
+```
+
+Тесты — это функции, имена которых начинаются с `test`. Эта функция проверяет базовую функциональность кеша, записывая значения и считывая их снова.
+
+```solidity
+ for(uint i=1; i<5000; i++) {
+ cache.cacheWrite(i*i);
+ }
+
+ for(uint i=1; i<5000; i++) {
+ assertEq(cache.cacheRead(i), i*i);
+```
+
+Вот как вы проводите фактическое тестирование, используя [функции `assert...`](https://getfoundry.sh/reference/forge-std/std-assertions/). В этом случае мы проверяем, что значение, которое мы записали, является тем, которое мы прочитали. Мы можем отбросить результат `cache.cacheWrite`, потому что знаем, что ключи кеша назначаются линейно.
+
+```solidity
+ }
+ } // testCaching
+
+
+ // Кешировать одно и то же значение несколько раз, убедиться, что ключ остается
+ // прежним
+ function testRepeatCaching() public {
+ for(uint i=1; i<100; i++) {
+ uint _key1 = cache.cacheWrite(i);
+ uint _key2 = cache.cacheWrite(i);
+ assertEq(_key1, _key2);
+ }
+```
+
+Сначала мы записываем каждое значение в кеш дважды и убеждаемся, что ключи одинаковы (то есть вторая запись на самом деле не произошла).
+
+```solidity
+ for(uint i=1; i<100; i+=3) {
+ uint _key = cache.cacheWrite(i);
+ assertEq(_key, i);
+ }
+ } // testRepeatCaching
+```
+
+Теоретически может существовать ошибка, которая не влияет на последовательные записи в кеш. Так что здесь мы делаем несколько записей, которые не являются последовательными, и видим, что значения все еще не перезаписываются.
+
+```solidity
+ // Считывание uint из буфера памяти (чтобы убедиться, что мы получаем обратно параметры,
+ // которые отправили)
+ function toUint256(bytes memory _bytes, uint256 _start) internal pure
+ returns (uint256)
+```
+
+Считывание 256-битного слова из буфера `bytes memory`. Эта служебная функция позволяет нам убедиться, что мы получаем правильные результаты при выполнении вызова функции, использующей кеш.
+
+```solidity
+ {
+ require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
+ uint256 tempUint;
+
+ assembly {
+ tempUint := mload(add(add(_bytes, 0x20), _start))
+ }
+```
+
+Yul не поддерживает структуры данных сложнее `uint256`, поэтому, когда вы обращаетесь к более сложной структуре данных, такой как буфер памяти `_bytes`, вы получаете адрес этой структуры. Solidity хранит значения `bytes memory` в виде 32-байтового слова, которое содержит длину, за которой следуют фактические байты, так что для того чтобы получить байт номер `_start`, нам нужно вычислить `_bytes+32+_start`.
+
+```solidity
+
+ return tempUint;
+ } // toUint256
+
+ // Сигнатура функции для fourParams() взята с
+ // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d
+ bytes4 constant FOUR_PARAMS = 0x3edc1e6d;
+
+ // Просто несколько постоянных значений, чтобы убедиться, что мы получаем правильные значения
+ uint256 constant VAL_A = 0xDEAD60A7;
+ uint256 constant VAL_B = 0xBEEF;
+ uint256 constant VAL_C = 0x600D;
+ uint256 constant VAL_D = 0x600D60A7;
+```
+
+Некоторые константы, которые нам нужны для тестирования.
+
+```solidity
+ function testReadParam() public {
+```
+
+Вызов `fourParams()`, функции, которая использует `readParams`, чтобы проверить, можем ли мы правильно читать параметры.
+
+```solidity
+ address _cacheAddr = address(cache);
+ bool _success;
+ bytes memory _callInput;
+ bytes memory _callOutput;
+```
+
+Мы не можем использовать обычный механизм ABI для вызова функции, использующей кеш, поэтому нам нужно использовать низкоуровневый механизм [`.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses). Этот механизм принимает на вход `bytes memory` и возвращает его (а также логическое значение) в качестве выходных данных.
+
+```solidity
+ // Первый вызов, кеш пуст
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+```
+
+Полезно, чтобы один и тот же контракт поддерживал как кешированные функции (для вызовов непосредственно из транзакций), так и некешированные функции (для вызовов из других смарт-контрактов). Для этого нам нужно продолжать полагаться на механизм Solidity для вызова правильной функции, вместо того чтобы помещать все в [функцию `fallback`](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function). Это значительно упрощает компонуемость. Одного байта в большинстве случаев было бы достаточно для идентификации функции, поэтому мы тратим впустую три байта (16\*3=48 ед. газа). Однако на момент написания этой статьи эти 48 ед. газа стоят 0,07 цента, что является разумной ценой за более простой и менее подверженный ошибкам код.
+
+```solidity
+ // Первое значение, добавить его в кеш
+ cache.INTO_CACHE(),
+ bytes32(VAL_A),
+```
+
+Первое значение: флаг, указывающий, что это полное значение, которое необходимо записать в кеш, за которым следуют 32 байта значения. Остальные три значения похожи, за исключением того, что `VAL_B` не записывается в кеш, а `VAL_C` является и третьим, и четвертым параметром.
+
+```solidity
+ .
+ .
+ .
+ );
+ (_success, _callOutput) = _cacheAddr.call(_callInput);
+```
+
+Здесь мы фактически вызываем контракт `Cache`.
+
+```solidity
+ assertEq(_success, true);
+```
+
+Мы ожидаем, что звонок будет успешным.
+
+```solidity
+ assertEq(cache.cacheRead(1), VAL_A);
+ assertEq(cache.cacheRead(2), VAL_C);
+```
+
+Мы начинаем с пустого кеша, а затем добавляем `VAL_A`, а затем `VAL_C`. Мы ожидаем, что у первого будет ключ 1, а у второго — 2.
+
+```
+ assertEq(toUint256(_callOutput,0), VAL_A);
+ assertEq(toUint256(_callOutput,32), VAL_B);
+ assertEq(toUint256(_callOutput,64), VAL_C);
+ assertEq(toUint256(_callOutput,96), VAL_C);
+```
+
+На выходе мы получаем четыре параметра. Здесь мы проверяем его правильность.
+
+```solidity
+ // Второй вызов, мы можем использовать кеш
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+
+ // Первое значение в кеше
+ bytes1(0x01),
+```
+
+Ключи кеша размером менее 16 — это всего один байт.
+
+```solidity
+ // Второе значение, не добавляйте его в кеш
+ cache.DONT_CACHE(),
+ bytes32(VAL_B),
+
+ // Третье и четвертое значения, одинаковые значения
+ bytes1(0x02),
+ bytes1(0x02)
+ );
+ .
+ .
+ .
+ } // testReadParam
+```
+
+Тесты после вызова идентичны тестам после первого вызова.
+
+```solidity
+ function testEncodeVal() public {
+```
+
+Эта функция похожа на `testReadParam`, за исключением того, что вместо явной записи параметров мы используем `encodeVal()`.
+
+```solidity
+ .
+ .
+ .
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+ cache.encodeVal(VAL_A),
+ cache.encodeVal(VAL_B),
+ cache.encodeVal(VAL_C),
+ cache.encodeVal(VAL_D)
+ );
+ .
+ .
+ .
+ assertEq(_callInput.length, 4+1*4);
+ } // testEncodeVal
+```
+
+Единственный дополнительный тест в `testEncodeVal()` — это проверка правильности длины `_callInput`. Для первого вызова это 4+33*4. Для второго, где каждое значение уже находится в кеше, это 4+1*4.
+
+```solidity
+ // Тестирование encodeVal, когда ключ состоит более чем из одного байта
+ // Максимум три байта, потому что заполнение кеша до четырех байт занимает
+ // слишком много времени.
+ function testEncodeValBig() public {
+ // Поместить несколько значений в кеш.
+ // Для простоты используйте ключ n для значения n.
+ for(uint i=1; i<0x1FFF; i++) {
+ cache.cacheWrite(i);
+ }
+```
+
+Приведенная выше функция `testEncodeVal` записывает в кеш только четыре значения, поэтому [часть функции, которая работает с многобайтовыми значениями](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171), не проверяется. Но этот код сложен и подвержен ошибкам.
+
+Первая часть этой функции представляет собой цикл, который записывает все значения от 1 до 0x1FFF в кеш по порядку, так что мы сможем закодировать эти значения и узнать, куда они пойдут.
+
+```solidity
+ .
+ .
+ .
+
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+ cache.encodeVal(0x000F), // Один байт 0x0F
+ cache.encodeVal(0x0010), // Два байта 0x1010
+ cache.encodeVal(0x0100), // Два байта 0x1100
+ cache.encodeVal(0x1000) // Три байта 0x201000
+ );
+```
+
+Проверьте значения в один, два и три байта. Мы не будем тестировать дальше, потому что для записи достаточного количества записей стека потребуется слишком много времени (не менее 0x10000000, примерно четверть миллиарда).
+
+```solidity
+ .
+ .
+ .
+ .
+ } // testEncodeValBig
+
+
+ // Тестируем, что при слишком маленьком буфере мы получаем отмену
+ function testShortCalldata() public {
+```
+
+Проверьте, что происходит в нештатном случае, когда параметров недостаточно.
+
+```solidity
+ .
+ .
+ .
+ (_success, _callOutput) = _cacheAddr.call(_callInput);
+ assertEq(_success, false);
+ } // testShortCalldata
+```
+
+Так как он отменяется, мы должны получить результат `false`.
+
+```
+ // Вызов с ключами кеша, которых нет
+ function testNoCacheKey() public {
+ .
+ .
+ .
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+
+ // Первое значение, добавить его в кеш
+ cache.INTO_CACHE(),
+ bytes32(VAL_A),
+
+ // Второе значение
+ bytes1(0x0F),
+ bytes2(0x1234),
+ bytes11(0xA10102030405060708090A)
+ );
+```
+
+Эта функция получает четыре совершенно законных параметра, за исключением того, что кеш пуст, поэтому в нем нет значений для чтения.
+
+```solidity
+ .
+ .
+ .
+ // Тестируем, что при слишком большом буфере все работает
+ function testLongCalldata() public {
+ address _cacheAddr = address(cache);
+ bool _success;
+ bytes memory _callInput;
+ bytes memory _callOutput;
+
+ // Первый вызов, кеш пуст
+ _callInput = bytes.concat(
+ FOUR_PARAMS,
+
+ // Первое значение, добавить его в кеш
+ cache.INTO_CACHE(), bytes32(VAL_A),
+
+ // Второе значение, добавить его в кеш
+ cache.INTO_CACHE(), bytes32(VAL_B),
+
+ // Третье значение, добавить его в кеш
+ cache.INTO_CACHE(), bytes32(VAL_C),
+
+ // Четвертое значение, добавить его в кеш
+ cache.INTO_CACHE(), bytes32(VAL_D),
+
+ // И еще одно значение для «удачи»
+ bytes4(0x31112233)
+ );
+```
+
+Эта функция отправляет пять значений. Мы знаем, что пятое значение игнорируется, потому что оно не является допустимой записью кеша, что привело бы к отмене, если бы оно не было включено.
+
+```solidity
+ (_success, _callOutput) = _cacheAddr.call(_callInput);
+ assertEq(_success, true);
+ .
+ .
+ .
+ } // testLongCalldata
+
+} // CacheTest
+
+```
+
+## Пример приложения {#a-sample-app}
+
+Писать тесты на Solidity — это, конечно, хорошо, но в конечном счете, чтобы быть полезным, децентрализованное приложение должно уметь обрабатывать запросы извне сети. В этой статье показано, как использовать кеширование в децентрализованном приложении с помощью `WORM`, что означает «Write Once, Read Many» (запись один раз, чтение много раз). Если ключ еще не записан, вы можете записать в него значение. Если ключ уже записан, вы получите отмену.
+
+### Контракт {#the-contract}
+
+[Вот этот контракт](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Он в основном повторяет то, что мы уже сделали с `Cache` и `CacheTest`, так что мы рассмотрим только интересные части.
+
+```solidity
+import "./Cache.sol";
+
+contract WORM is Cache {
+```
+
+Самый простой способ использовать `Cache` — это унаследовать его в нашем собственном контракте.
+
+```solidity
+ function writeEntryCached() external {
+ uint[] memory params = _readParams(2);
+ writeEntry(params[0], params[1]);
+ } // writeEntryCached
+```
+
+Эта функция похожа на `fourParam` в `CacheTest` выше. Поскольку мы не следуем спецификациям ABI, лучше не объявлять никаких параметров в функции.
+
+```solidity
+ // Упростить вызов
+ // Сигнатура функции для writeEntryCached() взята с
+ // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3
+ bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3;
+```
+
+Внешний код, который вызывает `writeEntryCached`, должен будет вручную создавать calldata, а не использовать `worm.writeEntryCached`, потому что мы не следуем спецификациям ABI. Наличие этого постоянного значения просто облегчает его написание.
+
+Обратите внимание, что хотя мы определяем `WRITE_ENTRY_CACHED` как переменную состояния, для ее считывания извне необходимо использовать функцию-геттер для нее, `worm.WRITE_ENTRY_CACHED()`.
+
+```solidity
+ function readEntry(uint key) public view
+ returns (uint _value, address _writtenBy, uint _writtenAtBlock)
+```
+
+Функция чтения — это `view`, поэтому она не требует транзакции и не расходует газ. В результате использование кеша для параметра не дает никаких преимуществ. С функциями view лучше использовать стандартный, более простой механизм.
+
+### Тестовый код {#the-testing-code}
+
+[Это тестовый код для контракта](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Опять же, давайте рассмотрим только то, что интересно.
+
+```solidity
+ function testWReadWrite() public {
+ worm.writeEntry(0xDEAD, 0x60A7);
+
+ vm.expectRevert(bytes("entry already written"));
+ worm.writeEntry(0xDEAD, 0xBEEF);
+```
+
+[Так (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) мы указываем в тесте Foundry, что следующий вызов должен завершиться неудачей, и сообщаемую причину сбоя. Это применимо, когда мы используем синтаксис `.()`, а не создаем calldata и вызываем контракт с помощью низкоуровневого интерфейса (`.call()` и т. д.).
+
+```solidity
+ function testReadWriteCached() public {
+ uint cacheGoat = worm.cacheWrite(0x60A7);
+```
+
+Здесь мы используем тот факт, что `cacheWrite` возвращает ключ кеша. Это не то, что мы ожидаем использовать в продакшене, потому что `cacheWrite` изменяет состояние и, следовательно, может вызываться только во время транзакции. Транзакции не возвращают значения, если у них есть результаты, эти результаты должны генерироваться как события. Таким образом, возвращаемое значение `cacheWrite` доступно только из ончейн-кода, а ончейн-код не нуждается в кешировании параметров.
+
+```solidity
+ (_success,) = address(worm).call(_callInput);
+```
+
+Вот как мы сообщаем Solidity, что, хотя `.call()` имеет два возвращаемых значения, нас интересует только первое.
+
+```solidity
+ (_success,) = address(worm).call(_callInput);
+ assertEq(_success, false);
+```
+
+Поскольку мы используем низкоуровневую функцию `.call()`, мы не можем использовать `vm.expectRevert()` и должны смотреть на логическое значение успеха, которое мы получаем от вызова.
+
+```solidity
+ event EntryWritten(uint indexed key, uint indexed value);
+
+ .
+ .
+ .
+
+ _callInput = bytes.concat(
+ worm.WRITE_ENTRY_CACHED(), worm.encodeVal(a), worm.encodeVal(b));
+ vm.expectEmit(true, true, false, false);
+ emit EntryWritten(a, b);
+ (_success,) = address(worm).call(_callInput);
+```
+
+Это способ, которым мы проверяем, что код [правильно генерирует событие](https://getfoundry.sh/reference/cheatcodes/expect-emit/) в Foundry.
+
+### Клиент {#the-client}
+
+Единственное, что вы не получаете с тестами Solidity, — это код JavaScript, который можно вырезать и вставить в свое собственное приложение. Чтобы написать этот код, я развернул WORM в [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli), новой тестовой сети [Optimism](https://www.optimism.io/). Он находится по адресу [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a).
+
+[Вы можете увидеть код JavaScript для клиента здесь](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Чтобы использовать его:
+
+1. Клонируйте git-репозиторий:
+
+ ```sh
+ git clone https://github.com/qbzzt/20220915-all-you-can-cache.git
+ ```
+
+2. Установите необходимые пакеты:
+
+ ```sh
+ cd javascript
+ yarn
+ ```
+
+3. Скопируйте файл конфигурации:
+
+ ```sh
+ cp .env.example .env
+ ```
+
+4. Отредактируйте `.env` для своей конфигурации:
+
+ | Параметр | Значение |
+ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+ | MNEMONIC | Мнемоническая фраза для аккаунта, у которого достаточно ETH для оплаты транзакции. [Вы можете получить бесплатный ETH для сети Optimism Goerli здесь](https://optimismfaucet.xyz/). |
+ | OPTIMISM_GOERLI_URL | URL для Optimism Goerli. Общедоступная конечная точка `https://goerli.optimism.io` имеет ограничение по скорости, но этого достаточно для того, что нам здесь нужно. |
+
+5. Запустите `index.js`.
+
+ ```sh
+ node index.js
+ ```
+
+ Это примерное приложение сначала записывает запись в WORM, отображая calldata и ссылку на транзакцию в Etherscan. Затем оно считывает эту запись и отображает используемый ключ и значения в записи (значение, номер блока и автор).
+
+Большая часть клиента — это обычный JavaScript для децентрализованных приложений. Так что, опять же, мы рассмотрим только интересные части.
+
+```javascript
+.
+.
+.
+const main = async () => {
+ const func = await worm.WRITE_ENTRY_CACHED()
+
+ // Каждый раз нужен новый ключ
+ const key = await worm.encodeVal(Number(new Date()))
+```
+
+В данный слот можно записать только один раз, поэтому мы используем временную метку, чтобы убедиться, что мы не будем повторно использовать слоты.
+
+```javascript
+const val = await worm.encodeVal("0x600D")
+
+// Записать запись
+const calldata = func + key.slice(2) + val.slice(2)
+```
+
+Ethers ожидает, что данные вызова будут шестнадцатеричной строкой, `0x`, за которым следует четное количество шестнадцатеричных цифр. Поскольку `key` и `val` начинаются с `0x`, нам нужно удалить эти заголовки.
+
+```javascript
+const tx = await worm.populateTransaction.writeEntryCached()
+tx.data = calldata
+
+sentTx = await wallet.sendTransaction(tx)
+```
+
+Как и в случае с тестовым кодом Solidity, мы не можем вызвать кешированную функцию обычным способом. Вместо этого нам нужно использовать механизм более низкого уровня.
+
+```javascript
+ .
+ .
+ .
+ // Прочитать только что сделанную запись
+ const realKey = '0x' + key.slice(4) // удалить флаг FF
+ const entryRead = await worm.readEntry(realKey)
+ .
+ .
+ .
+```
+
+Для чтения записей можно использовать обычный механизм. Для функций `view` нет необходимости использовать кеширование параметров.
+
+## Заключение {#conclusion}
+
+Код в этой статье является доказательством концепции, цель которой — сделать идею легкой для понимания. Для готовой к производству системы вы можете захотеть реализовать некоторые дополнительные функции:
+
+- Обработка значений, которые не являются `uint256`. Например, строки.
+- Вместо глобального кеша, возможно, стоит использовать сопоставление между пользователями и кешами. Разные пользователи используют разные значения.
+- Значения, используемые для адресов, отличаются от тех, что используются для других целей. Возможно, имеет смысл иметь отдельный кеш только для адресов.
+- В настоящее время ключи кеша работают по алгоритму «первым пришел — наименьший ключ». Первые шестнадцать значений могут быть отправлены в виде одного байта. Следующие 4080 значений могут быть отправлены в виде двух байтов. Следующий примерно миллион значений — это три байта и т. д. Производственная система должна вести счетчики использования записей кеша и реорганизовывать их так, чтобы шестнадцать _наиболее распространенных_ значений занимали один байт, следующие 4080 наиболее распространенных значений — два байта и т. д.
+
+ Однако это потенциально опасная операция. Представьте себе следующую последовательность событий:
+
+ 1. Ноам Наив вызывает `encodeVal` для кодирования адреса, на который он хочет отправить токены. Этот адрес является одним из первых, используемых в приложении, поэтому закодированное значение — 0x06. Это функция `view`, а не транзакция, поэтому это происходит между Ноамом и узлом, который он использует, и никто другой об этом не знает.
+
+ 2. Оуэн Оунер запускает операцию по реорганизации кеша. Очень немногие люди действительно используют этот адрес, поэтому теперь он закодирован как 0x201122. Другому значению, 1018, присваивается 0x06.
+
+ 3. Ноам Наив отправляет свои токены на 0x06. Они отправляются на адрес `0x0000000000000000000000000de0b6b3a7640000`, и, поскольку никто не знает приватный ключ для этого адреса, они просто застревают там. Ноам _недоволен_.
+
+ Есть способы решить эту проблему и связанную с ней проблему транзакций, которые находятся в мемпуле во время реорганизации кеша, но вы должны знать об этом.
+
+Я продемонстрировал кеширование здесь с помощью Optimism, потому что я сотрудник Optimism, и это ролл-ап, который я знаю лучше всего. Но это должно работать с любым ролл-апом, который взимает минимальную плату за внутреннюю обработку, так что по сравнению с этим запись данных транзакции в L1 является основной статьей расходов.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
diff --git a/public/content/translations/ru/developers/tutorials/app-plasma/index.md b/public/content/translations/ru/developers/tutorials/app-plasma/index.md
new file mode 100644
index 00000000000..c3b4babfa59
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/app-plasma/index.md
@@ -0,0 +1,1261 @@
+---
+title: "Напишите специфичное для приложения plasma, которое сохраняет конфиденциальность"
+description: "В этом руководстве мы создадим полусекретный банк для депозитов. Банк — это централизованный компонент; он знает баланс каждого пользователя. Однако эта информация не хранится ончейн. Вместо этого банк публикует хэш состояния. Каждый раз, когда происходит транзакция, банк публикует новый хэш вместе с доказательством с нулевым разглашением того, что у него есть подписанная транзакция, которая изменяет состояние хэша на новое. Прочитав это руководство, вы поймете не только, как использовать доказательства с нулевым разглашением, но и зачем их использовать и как делать это безопасно."
+author: Ori Pomerantz
+tags:
+ [
+ "с нулевым разглашением",
+ "сервер",
+ "офчейн",
+ "конфиденциальность"
+ ]
+skill: advanced
+lang: ru
+published: 2025-10-15
+---
+
+## Введение {#introduction}
+
+В отличие от [роллапов](/developers/docs/scaling/zk-rollups/), [плазмы](/developers/docs/scaling/plasma) используют основную сеть Ethereum для целостности, но не для доступности. В этой статье мы напишем приложение, которое ведет себя как плазма, где Ethereum гарантирует целостность (отсутствие несанкционированных изменений), но не доступность (централизованный компонент может выйти из строя и отключить всю систему).
+
+Приложение, которое мы здесь пишем, — это банк, сохраняющий конфиденциальность. Разные адреса имеют аккаунты с балансами, и они могут отправлять деньги (ETH) на другие аккаунты. Банк публикует хэши состояния (аккаунты и их балансы) и транзакции, но хранит фактические балансы оффчейн, где они могут оставаться приватными.
+
+## Проектирование {#design}
+
+Это не готовая к эксплуатации система, а учебный инструмент. Поэтому она написана с несколькими упрощающими допущениями.
+
+- Фиксированный пул аккаунтов. Существует определенное количество аккаунтов, и каждый аккаунт принадлежит предопределенному адресу. Это значительно упрощает систему, поскольку в доказательствах с нулевым разглашением сложно обрабатывать структуры данных переменного размера. Для системы, готовой к производству, мы можем использовать [корень Меркла](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) в качестве хэша состояния и предоставлять доказательства Меркла для требуемых балансов.
+
+- Хранение в памяти. В производственной системе нам необходимо записывать все балансы аккаунтов на диск, чтобы сохранить их в случае перезапуска. Здесь же допустимо, если информация просто будет утеряна.
+
+- Только переводы. Производственная система потребовала бы способа вносить активы в банк и выводить их. Но здесь цель — просто проиллюстрировать концепцию, поэтому этот банк ограничен переводами.
+
+### Доказательства с нулевым разглашением {#zero-knowledge-proofs}
+
+На фундаментальном уровне доказательство с нулевым разглашением показывает, что доказывающий знает некоторые данные, _Dataprivate_, такие, что существует связь _Relationship_ между некоторыми публичными данными, _Datapublic_, и _Dataprivate_. Верификатор знает _Relationship_ и _Datapublic_.
+
+Чтобы сохранить конфиденциальность, нам необходимо, чтобы состояния и транзакции были приватными. Но для обеспечения целостности нам необходимо, чтобы [криптографический хэш](https://en.wikipedia.org/wiki/Cryptographic_hash_function) состояний был публичным. Чтобы доказать людям, которые отправляют транзакции, что эти транзакции действительно произошли, нам также нужно публиковать хэши транзакций.
+
+В большинстве случаев _Dataprivate_ — это входные данные для программы доказательства с нулевым разглашением, а _Datapublic_ — выходные.
+
+Эти поля в _Dataprivate_:
+
+- _Staten_, старое состояние
+- _Staten+1_, новое состояние
+- _Транзакция_, транзакция, которая изменяет старое состояние на новое. Эта транзакция должна включать следующие поля:
+ - _Адрес назначения_, который получает перевод
+ - _Сумма_ перевода
+ - _Nonce_ для гарантии того, что каждая транзакция может быть обработана только один раз.
+ Адрес источника не обязательно должен быть в транзакции, поскольку его можно восстановить из подписи.
+- _Подпись_, подпись, которая авторизована для выполнения транзакции. В нашем случае единственный адрес, авторизованный для выполнения транзакции, — это адрес источника. Поскольку наша система с нулевым разглашением работает именно так, нам также нужен публичный ключ аккаунта в дополнение к подписи Ethereum.
+
+Это поля в _Datapublic_:
+
+- _Hash(Staten)_ — хэш старого состояния
+- _Hash(Staten+1)_ — хэш нового состояния
+- _Hash(Transaction)_ — хэш транзакции, которая изменяет состояние со _Staten_ на _Staten+1_.
+
+Связь проверяет несколько условий:
+
+- Публичные хэши действительно являются правильными хэшами для приватных полей.
+- Транзакция при применении к старому состоянию приводит к новому состоянию.
+- Подпись исходит от адреса источника транзакции.
+
+Благодаря свойствам криптографических хэш-функций, доказательство этих условий достаточно для обеспечения целостности.
+
+### Структуры данных {#data-structures}
+
+Основная структура данных — это состояние, хранимое сервером. Для каждого аккаунта сервер отслеживает баланс аккаунта и [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce), используемый для предотвращения [атак повторного воспроизведения](https://en.wikipedia.org/wiki/Replay_attack).
+
+### Компоненты {#components}
+
+Эта система требует двух компонентов:
+
+- _Сервер_, который получает транзакции, обрабатывает их и публикует хэши в блокчейн вместе с доказательствами с нулевым разглашением.
+- _Смарт-контракт_, который хранит хэши и проверяет доказательства с нулевым разглашением, чтобы убедиться в легитимности переходов состояний.
+
+### Потоки данных и управления {#flows}
+
+Это способы, которыми различные компоненты взаимодействуют для перевода с одного аккаунта на другой.
+
+1. Веб-браузер отправляет подписанную транзакцию, запрашивая перевод со счета подписывающего на другой счет.
+
+2. Сервер проверяет, что транзакция действительна:
+
+ - У подписывающего есть счет в банке с достаточным балансом.
+ - У получателя есть счет в банке.
+
+3. Сервер вычисляет новое состояние, вычитая переведенную сумму из баланса подписывающего и добавляя ее к балансу получателя.
+
+4. Сервер вычисляет доказательство с нулевым разглашением того, что изменение состояния является действительным.
+
+5. Сервер отправляет в Ethereum транзакцию, которая включает:
+
+ - Хэш нового состояния
+ - Хэш транзакции (чтобы отправитель транзакции мог знать, что она обработана)
+ - Доказательство с нулевым разглашением, которое доказывает, что переход к новому состоянию действителен
+
+6. Смарт-контракт проверяет доказательство с нулевым разглашением.
+
+7. Если доказательство с нулевым разглашением проходит проверку, смарт-контракт выполняет следующие действия:
+ - Обновляет текущий хэш состояния на новый хэш состояния
+ - Генерирует запись в журнале с новым хэшем состояния и хэшем транзакции
+
+### Инструменты {#tools}
+
+Для клиентского кода мы будем использовать [Vite](https://vite.dev/), [React](https://react.dev/), [Viem](https://viem.sh/) и [Wagmi](https://wagmi.sh/). Это стандартные отраслевые инструменты; если вы с ними не знакомы, можете воспользоваться [этим руководством](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/).
+
+Большая часть сервера написана на JavaScript с использованием [Node](https://nodejs.org/en). Часть с нулевым разглашением написана на [Noir](https://noir-lang.org/). Нам нужна версия `1.0.0-beta.10`, поэтому после того, как вы [установите Noir согласно инструкции](https://noir-lang.org/docs/getting_started/quick_start), выполните:
+
+```
+noirup -v 1.0.0-beta.10
+```
+
+Блокчейн, который мы используем, — это `anvil`, локальный тестовый блокчейн, который является частью [Foundry](https://getfoundry.sh/introduction/installation).
+
+## Реализация {#implementation}
+
+Поскольку это сложная система, мы будем реализовывать ее поэтапно.
+
+### Этап 1 — Ручное нулевое разглашение {#stage-1}
+
+На первом этапе мы подпишем транзакцию в браузере, а затем вручную предоставим информацию для доказательства с нулевым разглашением. Код с нулевым разглашением ожидает получить эту информацию в `server/noir/Prover.toml` (документация [здесь](https://noir-lang.org/docs/getting_started/project_breakdown#provertoml-1)).
+
+Чтобы увидеть это в действии:
+
+1. Убедитесь, что у вас установлены [Node](https://nodejs.org/en/download) и [Noir](https://noir-lang.org/install). Желательно установить их в UNIX-системе, такой как macOS, Linux или [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
+
+2. Загрузите код этапа 1 и запустите веб-сервер для обслуживания клиентского кода.
+
+ ```sh
+ git clone https://github.com/qbzzt/250911-zk-bank.git -b 01-manual-zk
+ cd 250911-zk-bank
+ cd client
+ npm install
+ npm run dev
+ ```
+
+ Причина, по которой здесь нужен веб-сервер, заключается в том, что для предотвращения некоторых видов мошенничества многие кошельки (например, MetaMask) не принимают файлы, обслуживаемые непосредственно с диска.
+
+3. Откройте браузер с кошельком.
+
+4. В кошельке введите новую кодовую фразу. Обратите внимание, что это удалит вашу существующую кодовую фразу, поэтому _убедитесь, что у вас есть резервная копия_.
+
+ Кодовая фраза — `test test test test test test test test test test test junk`, стандартная тестовая кодовая фраза для anvil.
+
+5. Перейдите к [клиентскому коду](http://localhost:5173/).
+
+6. Подключитесь к кошельку и выберите аккаунт назначения и сумму.
+
+7. Нажмите **Sign** (Подписать) и подпишите транзакцию.
+
+8. Под заголовком **Prover.toml** вы найдете текст. Замените `server/noir/Prover.toml` этим текстом.
+
+9. Выполните доказательство с нулевым разглашением.
+
+ ```sh
+ cd ../server/noir
+ nargo execute
+ ```
+
+ Вывод должен быть похож на
+
+ ```
+ ori@CryptoDocGuy:~/noir/250911-zk-bank/server/noir$ nargo execute
+
+ [zkBank] Circuit witness successfully solved
+ [zkBank] Witness saved to target/zkBank.gz
+ [zkBank] Circuit output: (0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b, 0x0cfc0a67cb7308e4e9b254026b54204e34f6c8b041be207e64c5db77d95dd82d, 0x450cf9da6e180d6159290554ae3d8787, 0x6d8bc5a15b9037e52fb59b6b98722a85)
+ ```
+
+10. Сравните последние два значения с хэшем, который вы видите в веб-браузере, чтобы проверить, правильно ли хэшировано сообщение.
+
+#### `server/noir/Prover.toml` {#server-noir-prover-toml}
+
+[Этот файл](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) показывает формат информации, ожидаемый Noir.
+
+```toml
+message="send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 500 finney (milliEth) 0 "
+```
+
+Сообщение представлено в текстовом формате, что облегчает его понимание пользователем (что необходимо при подписи) и разбор кодом Noir. Сумма указана в finney, чтобы, с одной стороны, обеспечить возможность дробных переводов, а с другой — быть легко читаемой. Последнее число — это [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce).
+
+Строка имеет длину 100 символов. Доказательства с нулевым разглашением плохо работают с данными переменного размера, поэтому часто необходимо дополнять данные.
+
+```toml
+pubKeyX=["0x83",...,"0x75"]
+pubKeyY=["0x35",...,"0xa5"]
+signature=["0xb1",...,"0x0d"]
+```
+
+Эти три параметра являются массивами байтов фиксированного размера.
+
+```toml
+[[accounts]]
+address="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
+balance=100_000
+nonce=0
+
+[[accounts]]
+address="0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
+balance=100_000
+nonce=0
+```
+
+Это способ задания массива структур. Для каждой записи мы указываем адрес, баланс (в milliETH, т. е. [finney](https://cryptovalleyjournal.com/glossary/finney/)) и следующее значение nonce.
+
+#### `client/src/Transfer.tsx` {#client-src-transfer-tsx}
+
+[Этот файл](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/client/src/Transfer.tsx) реализует обработку на стороне клиента и генерирует файл `server/noir/Prover.toml` (тот, который включает параметры с нулевым разглашением).
+
+Вот объяснение наиболее интересных частей.
+
+```tsx
+export default attrs => {
+```
+
+Эта функция создает компонент `Transfer` React, который могут импортировать другие файлы.
+
+```tsx
+ const accounts = [
+ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
+ "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
+ "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
+ "0x90F79bf6EB2c4f870365E785982E1f101E93b906",
+ "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
+ ]
+```
+
+Это адреса аккаунтов, адреса, созданные `test ...` кодовой фразой `test junk`. Если вы хотите использовать свои собственные адреса, просто измените это определение.
+
+```tsx
+ const account = useAccount()
+ const wallet = createWalletClient({
+ transport: custom(window.ethereum!)
+ })
+```
+
+Эти [хуки Wagmi](https://wagmi.sh/react/api/hooks) позволяют нам получить доступ к библиотеке [viem](https://viem.sh/) и кошельку.
+
+```tsx
+ const message = `send ${toAccount} ${ethAmount*1000} finney (milliEth) ${nonce}`.padEnd(100, " ")
+```
+
+Это сообщение, дополненное пробелами. Каждый раз, когда изменяется одна из переменных [`useState`](https://react.dev/reference/react/useState), компонент перерисовывается, а `message` обновляется.
+
+```tsx
+ const sign = async () => {
+```
+
+Эта функция вызывается, когда пользователь нажимает кнопку **Sign** (Подписать). Сообщение обновляется автоматически, но подпись требует подтверждения пользователя в кошельке, и мы не хотим запрашивать его без необходимости.
+
+```tsx
+ const signature = await wallet.signMessage({
+ account: fromAccount,
+ message,
+ })
+```
+
+Попросить кошелек [подписать сообщение](https://viem.sh/docs/accounts/local/signMessage).
+
+```tsx
+ const hash = hashMessage(message)
+```
+
+Получить хэш сообщения. Полезно предоставить его пользователю для отладки (кода Noir).
+
+```tsx
+ const pubKey = await recoverPublicKey({
+ hash,
+ signature
+ })
+```
+
+[Получить публичный ключ](https://viem.sh/docs/utilities/recoverPublicKey). Это необходимо для функции [Noir `ecrecover`](https://github.com/colinnielsen/ecrecover-noir).
+
+```tsx
+ setSignature(signature)
+ setHash(hash)
+ setPubKey(pubKey)
+```
+
+Установить переменные состояния. Это действие перерисовывает компонент (после завершения функции `sign`) и показывает пользователю обновленные значения.
+
+```tsx
+ let proverToml = `
+```
+
+Текст для `Prover.toml`.
+
+```tsx
+message="${message}"
+
+pubKeyX=${hexToArray(pubKey.slice(4,4+2*32))}
+pubKeyY=${hexToArray(pubKey.slice(4+2*32))}
+```
+
+Viem предоставляет нам публичный ключ в виде 65-байтовой шестнадцатеричной строки. Первый байт — `0x04`, маркер версии. За ним следуют 32 байта для `x` публичного ключа, а затем 32 байта для `y` публичного ключа.
+
+Однако Noir ожидает получить эту информацию в виде двух массивов байтов, один для `x` и один для `y`. Проще разобрать это здесь, на клиенте, а не в рамках доказательства с нулевым разглашением.
+
+Обратите внимание, что это хорошая практика в области доказательств с нулевым разглашением в целом. Код внутри доказательства с нулевым разглашением является дорогостоящим, поэтому любая обработка, которая может быть выполнена вне доказательства с нулевым разглашением, _должна_ быть выполнена вне доказательства с нулевым разглашением.
+
+```tsx
+signature=${hexToArray(signature.slice(2,-2))}
+```
+
+Подпись также предоставляется в виде 65-байтовой шестнадцатеричной строки. Однако последний байт необходим только для восстановления публичного ключа. Поскольку публичный ключ уже будет предоставлен коду Noir, он нам не нужен для проверки подписи, и код Noir его не требует.
+
+```tsx
+${accounts.map(accountInProverToml).reduce((a,b) => a+b, "")}
+`
+```
+
+Предоставьте аккаунты.
+
+```tsx
+ setProverToml(proverToml)
+ }
+
+ return (
+ <>
+ Перевод
+```
+
+Это формат HTML (точнее, [JSX](https://react.dev/learn/writing-markup-with-jsx)) компонента.
+
+#### `server/noir/src/main.nr` {#server-noir-src-main-nr}
+
+[Этот файл](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/src/main.nr) является фактическим кодом с нулевым разглашением.
+
+```
+use std::hash::pedersen_hash;
+```
+
+[Хэш Педерсена](https://rya-sge.github.io/access-denied/2024/05/07/pedersen-hash-function/) предоставляется стандартной библиотекой [Noir](https://noir-lang.org/docs/noir/standard_library/cryptographic_primitives/hashes#pedersen_hash). Доказательства с нулевым разглашением обычно используют эту хэш-функцию. Ее гораздо проще вычислять внутри [арифметических схем](https://rareskills.io/post/arithmetic-circuit) по сравнению со стандартными хэш-функциями.
+
+```
+use keccak256::keccak256;
+use dep::ecrecover;
+```
+
+Эти две функции являются внешними библиотеками, определенными в [`Nargo.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Nargo.toml). Они представляют собой именно то, для чего они названы: функция, которая вычисляет [хэш keccak256](https://emn178.github.io/online-tools/keccak_256.html), и функция, которая проверяет подписи Ethereum и восстанавливает адрес Ethereum подписывающего.
+
+```
+global ACCOUNT_NUMBER : u32 = 5;
+```
+
+Noir вдохновлен [Rust](https://www.rust-lang.org/). Переменные по умолчанию являются константами. Так мы определяем глобальные константы конфигурации. В частности, `ACCOUNT_NUMBER` — это количество аккаунтов, которые мы храним.
+
+Типы данных с именем `u` — это беззнаковые числа с указанным количеством битов. Единственными поддерживаемыми типами являются `u8`, `u16`, `u32`, `u64` и `u128`.
+
+```
+global FLAT_ACCOUNT_FIELDS : u32 = 2;
+```
+
+Эта переменная используется для хэша Педерсена аккаунтов, как объяснено ниже.
+
+```
+global MESSAGE_LENGTH : u32 = 100;
+```
+
+Как объяснялось выше, длина сообщения фиксирована. Она указана здесь.
+
+```
+global ASCII_MESSAGE_LENGTH : [u8; 3] = [0x31, 0x30, 0x30];
+global HASH_BUFFER_SIZE : u32 = 26+3+MESSAGE_LENGTH;
+```
+
+[Подписи EIP-191](https://eips.ethereum.org/EIPS/eip-191) требуют буфер с 26-байтовым префиксом, за которым следует длина сообщения в ASCII и, наконец, само сообщение.
+
+```
+struct Account {
+ balance: u128,
+ address: Field,
+ nonce: u32,
+}
+```
+
+Информация, которую мы храним об аккаунте. [`Field`](https://noir-lang.org/docs/noir/concepts/data_types/fields) — это число, обычно до 253 бит, которое можно использовать непосредственно в [арифметической схеме](https://rareskills.io/post/arithmetic-circuit), реализующей доказательство с нулевым разглашением. Здесь мы используем `Field` для хранения 160-битного адреса Ethereum.
+
+```
+struct TransferTxn {
+ from: Field,
+ to: Field,
+ amount: u128,
+ nonce: u32
+}
+```
+
+Информация, которую мы храним для транзакции перевода.
+
+```
+fn flatten_account(account: Account) -> [Field; FLAT_ACCOUNT_FIELDS] {
+```
+
+Определение функции. Параметром является информация об `аккаунте`. Результатом является массив переменных `Field`, длина которого равна `FLAT_ACCOUNT_FIELDS`.
+
+```
+ let flat = [
+ account.address,
+ ((account.balance << 32) + account.nonce.into()).into(),
+ ];
+```
+
+Первое значение в массиве — это адрес аккаунта. Второе включает в себя как баланс, так и nonce. Вызовы `.into()` изменяют число на тот тип данных, которым оно должно быть. `account.nonce` — это значение `u32`, но чтобы добавить его к `account.balance << 32`, значению `u128`, оно должно быть `u128`. Это первый `.into()`. Второй преобразует результат `u128` в `Field`, чтобы он поместился в массив.
+
+```
+ flat
+}
+```
+
+В Noir функции могут возвращать значение только в конце (нет раннего возврата). Чтобы указать возвращаемое значение, вы вычисляете его непосредственно перед закрывающей скобкой функции.
+
+```
+fn flatten_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] {
+```
+
+Эта функция преобразует массив аккаунтов в массив `Field`, который можно использовать в качестве входных данных для хэша Петерсена.
+
+```
+ let mut flat: [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] = [0; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER];
+```
+
+Так вы указываете изменяемую переменную, то есть _не_ константу. Переменные в Noir всегда должны иметь значение, поэтому мы инициализируем эту переменную всеми нулями.
+
+```
+ for i in 0..ACCOUNT_NUMBER {
+```
+
+Это цикл `for`. Обратите внимание, что границы являются константами. В Noir границы циклов должны быть известны во время компиляции. Причина в том, что арифметические схемы не поддерживают управление потоком. При обработке цикла `for` компилятор просто помещает код внутри него несколько раз, по одному на каждую итерацию.
+
+```
+ let fields = flatten_account(accounts[i]);
+ for j in 0..FLAT_ACCOUNT_FIELDS {
+ flat[i*FLAT_ACCOUNT_FIELDS + j] = fields[j];
+ }
+ }
+
+ flat
+}
+
+fn hash_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> Field {
+ pedersen_hash(flatten_accounts(accounts))
+}
+```
+
+Наконец, мы дошли до функции, которая хэширует массив аккаунтов.
+
+```
+fn find_account(accounts: [Account; ACCOUNT_NUMBER], address: Field) -> u32 {
+ let mut account : u32 = ACCOUNT_NUMBER;
+
+ for i in 0..ACCOUNT_NUMBER {
+ if accounts[i].address == address {
+ account = i;
+ }
+ }
+```
+
+Эта функция находит аккаунт с определенным адресом. Эта функция была бы ужасно неэффективной в стандартном коде, потому что она перебирает все аккаунты, даже после того, как нашла адрес.
+
+Однако в доказательствах с нулевым разглашением нет управления потоком. Если нам когда-либо понадобится проверить условие, мы должны проверять его каждый раз.
+
+Аналогичная вещь происходит с операторами `if`. Оператор `if` в приведенном выше цикле преобразуется в эти математические утверждения.
+
+_conditionresult = accounts[i].address == address_ // единица, если они равны, ноль в противном случае
+
+_accountnew = conditionresult*i + (1-conditionresult)*accountold_
+
+```rust
+ assert (account < ACCOUNT_NUMBER, f"{address} does not have an account");
+
+ account
+}
+```
+
+Функция [`assert`](https://noir-lang.org/docs/dev/noir/concepts/assert) вызывает сбой доказательства с нулевым разглашением, если утверждение ложно. В данном случае, если мы не можем найти аккаунт с соответствующим адресом. Чтобы сообщить адрес, мы используем [форматированную строку](https://noir-lang.org/docs/noir/concepts/data_types/strings#format-strings).
+
+```rust
+fn apply_transfer_txn(accounts: [Account; ACCOUNT_NUMBER], txn: TransferTxn) -> [Account; ACCOUNT_NUMBER] {
+```
+
+Эта функция применяет транзакцию перевода и возвращает новый массив аккаунтов.
+
+```rust
+ let from = find_account(accounts, txn.from);
+ let to = find_account(accounts, txn.to);
+
+ let (txnFrom, txnAmount, txnNonce, accountNonce) =
+ (txn.from, txn.amount, txn.nonce, accounts[from].nonce);
+```
+
+Мы не можем получить доступ к элементам структуры внутри форматированной строки в Noir, поэтому мы создаем пригодную для использования копию.
+
+```rust
+ assert (accounts[from].balance >= txn.amount,
+ f"{txnFrom} does not have {txnAmount} finney");
+
+ assert (accounts[from].nonce == txn.nonce,
+ f"Transaction has nonce {txnNonce}, but the account is expected to use {accountNonce}");
+```
+
+Это два условия, которые могут сделать транзакцию недействительной.
+
+```rust
+ let mut newAccounts = accounts;
+
+ newAccounts[from].balance -= txn.amount;
+ newAccounts[from].nonce += 1;
+ newAccounts[to].balance += txn.amount;
+
+ newAccounts
+}
+```
+
+Создайте новый массив аккаунтов, а затем верните его.
+
+```rust
+fn readAddress(messageBytes: [u8; MESSAGE_LENGTH]) -> Field
+```
+
+Эта функция считывает адрес из сообщения.
+
+```rust
+{
+ let mut result : Field = 0;
+
+ for i in 7..47 {
+```
+
+Адрес всегда имеет длину 20 байт (т. е. 40 шестнадцатеричных цифр) и начинается с символа №7.
+
+```rust
+ result *= 0x10;
+ if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9
+ result += (messageBytes[i]-48).into();
+ }
+ if messageBytes[i] >= 65 & messageBytes[i] <= 70 { // A-F
+ result += (messageBytes[i]-65+10).into()
+ }
+ if messageBytes[i] >= 97 & messageBytes[i] <= 102 { // a-f
+ result += (messageBytes[i]-97+10).into()
+ }
+ }
+
+ result
+}
+
+fn readAmountAndNonce(messageBytes: [u8; MESSAGE_LENGTH]) -> (u128, u32)
+```
+
+Считайте сумму и nonce из сообщения.
+
+```rust
+{
+ let mut amount : u128 = 0;
+ let mut nonce: u32 = 0;
+ let mut stillReadingAmount: bool = true;
+ let mut lookingForNonce: bool = false;
+ let mut stillReadingNonce: bool = false;
+```
+
+В сообщении первое число после адреса — это сумма в finney (т. е. тысячная доля ETH) для перевода. Второе число — это nonce. Любой текст между ними игнорируется.
+
+```rust
+ for i in 48..MESSAGE_LENGTH {
+ if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9
+ let digit = (messageBytes[i]-48);
+
+ if stillReadingAmount {
+ amount = amount*10 + digit.into();
+ }
+
+ if lookingForNonce { // We just found it
+ stillReadingNonce = true;
+ lookingForNonce = false;
+ }
+
+ if stillReadingNonce {
+ nonce = nonce*10 + digit.into();
+ }
+ } else {
+ if stillReadingAmount {
+ stillReadingAmount = false;
+ lookingForNonce = true;
+ }
+ if stillReadingNonce {
+ stillReadingNonce = false;
+ }
+ }
+ }
+
+ (amount, nonce)
+}
+```
+
+Возврат [кортежа](https://noir-lang.org/docs/noir/concepts/data_types/tuples) — это способ в Noir вернуть несколько значений из функции.
+
+```rust
+fn readTransferTxn(message: str) -> TransferTxn
+{
+ let mut txn: TransferTxn = TransferTxn { from: 0, to: 0, amount:0, nonce:0 };
+ let messageBytes = message.as_bytes();
+
+ txn.to = readAddress(messageBytes);
+ let (amount, nonce) = readAmountAndNonce(messageBytes);
+ txn.amount = amount;
+ txn.nonce = nonce;
+
+ txn
+}
+```
+
+Эта функция преобразует сообщение в байты, а затем преобразует суммы в `TransferTxn`.
+
+```rust
+// The equivalent to Viem's hashMessage
+// https://viem.sh/docs/utilities/hashMessage#hashmessage
+fn hashMessage(message: str) -> [u8;32] {
+```
+
+Мы смогли использовать хэш Педерсена для аккаунтов, потому что они хэшируются только внутри доказательства с нулевым разглашением. Однако в этом коде нам нужно проверить подпись сообщения, которая генерируется браузером. Для этого нам нужно следовать формату подписи Ethereum в [EIP-191](https://eips.ethereum.org/EIPS/eip-191). Это означает, что нам нужно создать объединенный буфер со стандартным префиксом, длиной сообщения в ASCII и самим сообщением, и использовать стандартный для Ethereum keccak256 для его хэширования.
+
+```rust
+ // ASCII prefix
+ let prefix_bytes = [
+ 0x19, // \x19
+ 0x45, // 'E'
+ 0x74, // 't'
+ 0x68, // 'h'
+ 0x65, // 'e'
+ 0x72, // 'r'
+ 0x65, // 'e'
+ 0x75, // 'u'
+ 0x6D, // 'm'
+ 0x20, // ' '
+ 0x53, // 'S'
+ 0x69, // 'i'
+ 0x67, // 'g'
+ 0x6E, // 'n'
+ 0x65, // 'e'
+ 0x64, // 'd'
+ 0x20, // ' '
+ 0x4D, // 'M'
+ 0x65, // 'e'
+ 0x73, // 's'
+ 0x73, // 's'
+ 0x61, // 'a'
+ 0x67, // 'g'
+ 0x65, // 'e'
+ 0x3A, // ':'
+ 0x0A // '\n'
+ ];
+```
+
+Чтобы избежать случаев, когда приложение просит пользователя подписать сообщение, которое может быть использовано как транзакция или для какой-либо другой цели, EIP-191 указывает, что все подписанные сообщения начинаются с символа 0x19 (недействительный символ ASCII), за которым следует `Ethereum Signed Message:` и новая строка.
+
+```rust
+ let mut buffer: [u8; HASH_BUFFER_SIZE] = [0u8; HASH_BUFFER_SIZE];
+ for i in 0..26 {
+ buffer[i] = prefix_bytes[i];
+ }
+
+ let messageBytes : [u8; MESSAGE_LENGTH] = message.as_bytes();
+
+ if MESSAGE_LENGTH <= 9 {
+ for i in 0..1 {
+ buffer[i+26] = ASCII_MESSAGE_LENGTH[i];
+ }
+
+ for i in 0..MESSAGE_LENGTH {
+ buffer[i+26+1] = messageBytes[i];
+ }
+ }
+
+ if MESSAGE_LENGTH >= 10 & MESSAGE_LENGTH <= 99 {
+ for i in 0..2 {
+ buffer[i+26] = ASCII_MESSAGE_LENGTH[i];
+ }
+
+ for i in 0..MESSAGE_LENGTH {
+ buffer[i+26+2] = messageBytes[i];
+ }
+ }
+
+ if MESSAGE_LENGTH >= 100 {
+ for i in 0..3 {
+ buffer[i+26] = ASCII_MESSAGE_LENGTH[i];
+ }
+
+ for i in 0..MESSAGE_LENGTH {
+ buffer[i+26+3] = messageBytes[i];
+ }
+ }
+
+ assert(MESSAGE_LENGTH < 1000, "Messages whose length is over three digits are not supported");
+```
+
+Обрабатывать длины сообщений до 999 и выдавать ошибку, если она больше. Я добавил этот код, хотя длина сообщения является константой, потому что это упрощает ее изменение. В производственной системе вы, вероятно, просто предположите, что `MESSAGE_LENGTH` не изменится ради лучшей производительности.
+
+```rust
+ keccak256::keccak256(buffer, HASH_BUFFER_SIZE)
+}
+```
+
+Используйте стандартную функцию Ethereum `keccak256`.
+
+```rust
+fn signatureToAddressAndHash(
+ message: str,
+ pubKeyX: [u8; 32],
+ pubKeyY: [u8; 32],
+ signature: [u8; 64]
+ ) -> (Field, Field, Field) // address, first 16 bytes of hash, last 16 bytes of hash
+{
+```
+
+Эта функция проверяет подпись, что требует хэша сообщения. Затем она предоставляет нам адрес, который ее подписал, и хэш сообщения. Хэш сообщения предоставляется в виде двух значений `Field`, потому что их проще использовать в остальной части программы, чем массив байтов.
+
+Нам нужно использовать два значения `Field`, потому что вычисления с полями выполняются [по модулю](https://en.wikipedia.org/wiki/Modulo) большого числа, но это число обычно меньше 256 бит (иначе было бы трудно выполнять эти вычисления в EVM).
+
+```rust
+ let hash = hashMessage(message);
+
+ let mut (hash1, hash2) = (0,0);
+
+ for i in 0..16 {
+ hash1 = hash1*256 + hash[31-i].into();
+ hash2 = hash2*256 + hash[15-i].into();
+ }
+```
+
+Укажите `hash1` и `hash2` как изменяемые переменные и запишите в них хэш побайтово.
+
+```rust
+ (
+ ecrecover::ecrecover(pubKeyX, pubKeyY, signature, hash),
+```
+
+Это похоже на [`ecrecover` в Solidity](https://docs.soliditylang.org/en/v0.8.30/cheatsheet.html#mathematical-and-cryptographic-functions), с двумя важными отличиями:
+
+- Если подпись недействительна, вызов не проходит `assert`, и программа прерывается.
+- Хотя публичный ключ можно восстановить из подписи и хэша, это обработка, которую можно выполнить извне, и, следовательно, не стоит делать внутри доказательства с нулевым разглашением. Если кто-то попытается обмануть нас здесь, проверка подписи не удастся.
+
+```rust
+ hash1,
+ hash2
+ )
+}
+
+fn main(
+ accounts: [Account; ACCOUNT_NUMBER],
+ message: str,
+ pubKeyX: [u8; 32],
+ pubKeyY: [u8; 32],
+ signature: [u8; 64],
+ ) -> pub (
+ Field, // Hash of old accounts array
+ Field, // Hash of new accounts array
+ Field, // First 16 bytes of message hash
+ Field, // Last 16 bytes of message hash
+ )
+```
+
+Наконец, мы добрались до функции `main`. Нам нужно доказать, что у нас есть транзакция, которая действительным образом изменяет хэш аккаунтов со старого значения на новое. Нам также нужно доказать, что у нее есть этот конкретный хэш транзакции, чтобы человек, который ее отправил, знал, что его транзакция была обработана.
+
+```rust
+{
+ let mut txn = readTransferTxn(message);
+```
+
+Нам нужно, чтобы `txn` был изменяемым, потому что мы не читаем адрес «от кого» из сообщения, мы читаем его из подписи.
+
+```rust
+ let (fromAddress, txnHash1, txnHash2) = signatureToAddressAndHash(
+ message,
+ pubKeyX,
+ pubKeyY,
+ signature);
+
+ txn.from = fromAddress;
+
+ let newAccounts = apply_transfer_txn(accounts, txn);
+
+ (
+ hash_accounts(accounts),
+ hash_accounts(newAccounts),
+ txnHash1,
+ txnHash2
+ )
+}
+```
+
+### Этап 2 — Добавление сервера {#stage-2}
+
+На втором этапе мы добавляем сервер, который получает и реализует транзакции перевода из браузера.
+
+Чтобы увидеть это в действии:
+
+1. Остановите Vite, если он запущен.
+
+2. Загрузите ветку, которая включает сервер, и убедитесь, что у вас есть все необходимые модули.
+
+ ```sh
+ git checkout 02-add-server
+ cd client
+ npm install
+ cd ../server
+ npm install
+ ```
+
+ Нет необходимости компилировать код Noir, он такой же, как код, который вы использовали для этапа 1.
+
+3. Запустите сервер.
+
+ ```sh
+ npm run start
+ ```
+
+4. В отдельном окне командной строки запустите Vite для обслуживания кода браузера.
+
+ ```sh
+ cd client
+ npm run dev
+ ```
+
+5. Перейдите к клиентскому коду по адресу [http://localhost:5173](http://localhost:5173).
+
+6. Прежде чем вы сможете выполнить транзакцию, вам нужно знать nonce, а также сумму, которую вы можете отправить. Чтобы получить эту информацию, нажмите **Update account data** (Обновить данные аккаунта) и подпишите сообщение.
+
+ Здесь у нас дилемма. С одной стороны, мы не хотим подписывать сообщение, которое может быть использовано повторно ([атака повторного воспроизведения](https://en.wikipedia.org/wiki/Replay_attack)), и именно поэтому нам в первую очередь нужен nonce. Однако у нас еще нет nonce. Решение состоит в том, чтобы выбрать nonce, который можно использовать только один раз и который у нас уже есть с обеих сторон, например, текущее время.
+
+ Проблема с этим решением в том, что время может быть не идеально синхронизировано. Поэтому вместо этого мы подписываем значение, которое меняется каждую минуту. Это означает, что наше окно уязвимости для атак повторного воспроизведения составляет не более одной минуты. Учитывая, что в производственной среде подписанный запрос будет защищен TLS, и что другая сторона туннеля — сервер — уже может раскрыть баланс и nonce (он должен их знать для работы), это приемлемый риск.
+
+7. Как только браузер получает обратно баланс и nonce, он показывает форму перевода. Выберите адрес назначения и сумму и нажмите **Transfer** (Перевести). Подпишите этот запрос.
+
+8. Чтобы увидеть перевод, либо **обновите данные аккаунта**, либо посмотрите в окне, где вы запускаете сервер. Сервер регистрирует состояние каждый раз, когда оно меняется.
+
+ ```
+ ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start
+
+ > server@1.0.0 start
+ > node --experimental-json-modules index.mjs
+
+ Listening on port 3000
+ Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 36000 finney (milliEth) 0 processed
+ New state:
+ 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 64000 (1)
+ 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 100000 (0)
+ 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0)
+ 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 136000 (0)
+ 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0)
+ Txn send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 7200 finney (milliEth) 1 processed
+ New state:
+ 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 56800 (2)
+ 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 107200 (0)
+ 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0)
+ 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 136000 (0)
+ 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0)
+ Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 3000 finney (milliEth) 2 processed
+ New state:
+ 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 53800 (3)
+ 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 107200 (0)
+ 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0)
+ 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 139000 (0)
+ 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0)
+ ```
+
+#### `server/index.mjs` {#server-index-mjs-1}
+
+[Этот файл](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/index.mjs) содержит серверный процесс и взаимодействует с кодом Noir в [`main.nr`](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/noir/src/main.nr). Вот объяснение интересных частей.
+
+```js
+import { Noir } from '@noir-lang/noir_js'
+```
+
+Библиотека [noir.js](https://www.npmjs.com/package/@noir-lang/noir_js) взаимодействует между кодом JavaScript и кодом Noir.
+
+```js
+const circuit = JSON.parse(await fs.readFile("./noir/target/zkBank.json"))
+const noir = new Noir(circuit)
+```
+
+Загрузите арифметическую схему — скомпилированную программу Noir, которую мы создали на предыдущем этапе, — и подготовьтесь к ее выполнению.
+
+```js
+// Мы предоставляем информацию об аккаунте только в ответ на подписанный запрос
+const accountInformation = async signature => {
+ const fromAddress = await recoverAddress({
+ hash: hashMessage("Get account data " + Math.floor((new Date().getTime())/60000)),
+ signature
+ })
+```
+
+Для предоставления информации об аккаунте нам нужна только подпись. Причина в том, что мы уже знаем, каким будет сообщение, и, следовательно, хэш сообщения.
+
+```js
+const processMessage = async (message, signature) => {
+```
+
+Обработайте сообщение и выполните закодированную в нем транзакцию.
+
+```js
+ // Получить публичный ключ
+ const pubKey = await recoverPublicKey({
+ hash,
+ signature
+ })
+```
+
+Теперь, когда мы запускаем JavaScript на сервере, мы можем получить публичный ключ там, а не на клиенте.
+
+```js
+ let noirResult
+ try {
+ noirResult = await noir.execute({
+ message,
+ signature: signature.slice(2,-2).match(/.{2}/g).map(x => `0x${x}`),
+ pubKeyX,
+ pubKeyY,
+ accounts: Accounts
+ })
+```
+
+`noir.execute` запускает программу Noir. Параметры эквивалентны тем, что предоставлены в [`Prover.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml). Обратите внимание, что длинные значения предоставляются как массив шестнадцатеричных строк (`["0x60", "0xA7"]`), а не как одно шестнадцатеричное значение (`0x60A7`), как это делает Viem.
+
+```js
+ } catch (err) {
+ console.log(`Noir error: ${err}`)
+ throw Error("Invalid transaction, not processed")
+ }
+```
+
+Если возникла ошибка, перехватите ее, а затем передайте упрощенную версию клиенту.
+
+```js
+ Accounts[fromAccountNumber].nonce++
+ Accounts[fromAccountNumber].balance -= amount
+ Accounts[toAccountNumber].balance += amount
+```
+
+Примените транзакцию. Мы уже сделали это в коде Noir, но здесь проще сделать это снова, чем извлекать результат оттуда.
+
+```js
+let Accounts = [
+ {
+ address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
+ balance: 5000,
+ nonce: 0,
+ },
+```
+
+Начальная структура `Accounts`.
+
+### Этап 3 — Смарт-контракты Ethereum {#stage-3}
+
+1. Остановите процессы сервера и клиента.
+
+2. Загрузите ветку со смарт-контрактами и убедитесь, что у вас есть все необходимые модули.
+
+ ```sh
+ git checkout 03-smart-contracts
+ cd client
+ npm install
+ cd ../server
+ npm install
+ ```
+
+3. Запустите `anvil` в отдельном окне командной строки.
+
+4. Сгенерируйте ключ верификации и верификатор Solidity, затем скопируйте код верификатора в проект Solidity.
+
+ ```sh
+ cd noir
+ bb write_vk -b ./target/zkBank.json -o ./target --oracle_hash keccak
+ bb write_solidity_verifier -k ./target/vk -o ./target/Verifier.sol
+ cp target/Verifier.sol ../../smart-contracts/src
+ ```
+
+5. Перейдите к смарт-контрактам и установите переменные среды для использования блокчейна `anvil`.
+
+ ```sh
+ cd ../../smart-contracts
+ export ETH_RPC_URL=http://localhost:8545
+ ETH_PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
+ ```
+
+6. Разверните `Verifier.sol` и сохраните адрес в переменной среды.
+
+ ```sh
+ VERIFIER_ADDRESS=`forge create src/Verifier.sol:HonkVerifier --private-key $ETH_PRIVATE_KEY --optimize --broadcast | awk '/Deployed to:/ {print $3}'`
+ echo $VERIFIER_ADDRESS
+ ```
+
+7. Разверните контракт `ZkBank`.
+
+ ```sh
+ ZKBANK_ADDRESS=`forge create ZkBank --private-key $ETH_PRIVATE_KEY --broadcast --constructor-args $VERIFIER_ADDRESS 0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b | awk '/Deployed to:/ {print $3}'`
+ echo $ZKBANK_ADDRESS
+ ```
+
+ Значение `0x199..67b` — это хэш Педерсена начального состояния `Accounts`. Если вы измените это начальное состояние в `server/index.mjs`, вы можете запустить транзакцию, чтобы увидеть начальный хэш, сообщаемый доказательством с нулевым разглашением.
+
+8. Запустите сервер.
+
+ ```sh
+ cd ../server
+ npm run start
+ ```
+
+9. Запустите клиент в другом окне командной строки.
+
+ ```sh
+ cd client
+ npm run dev
+ ```
+
+10. Выполните несколько транзакций.
+
+11. Чтобы убедиться, что состояние изменилось в блокчейне, перезапустите процесс сервера. Убедитесь, что `ZkBank` больше не принимает транзакции, потому что исходное значение хэша в транзакциях отличается от значения хэша, хранящегося в блокчейне.
+
+ Это ожидаемый тип ошибки.
+
+ ```
+ ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start
+
+ > server@1.0.0 start
+ > node --experimental-json-modules index.mjs
+
+ Listening on port 3000
+ Verification error: ContractFunctionExecutionError: The contract function "processTransaction" reverted with the following reason:
+ Wrong old state hash
+
+ Contract Call:
+ address: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
+ function: processTransaction(bytes _proof, bytes32[] _publicInputs)
+ args: (0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf00000000000000000000000000000000000000000000000b75c020998797da7800000000000000000000000000000000000000000000000
+ ```
+
+#### `server/index.mjs` {#server-index-mjs-2}
+
+Изменения в этом файле в основном касаются создания фактического доказательства и его отправки в блокчейн.
+
+```js
+import { exec } from 'child_process'
+import util from 'util'
+
+const execPromise = util.promisify(exec)
+```
+
+Нам нужно использовать [пакет Barretenberg](https://github.com/AztecProtocol/aztec-packages/tree/next/barretenberg) для создания фактического доказательства для отправки в блокчейн. Мы можем использовать этот пакет либо через интерфейс командной строки (`bb`), либо с помощью [библиотеки JavaScript, `bb.js`](https://www.npmjs.com/package/@aztec/bb.js). Библиотека JavaScript работает намного медленнее, чем нативный код, поэтому мы используем [`exec`](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback) для использования командной строки.
+
+Обратите внимание, что если вы решите использовать `bb.js`, вам нужно будет использовать версию, совместимую с версией Noir, которую вы используете. На момент написания статьи текущая версия Noir (1.0.0-beta.11) использует `bb.js` версии 0.87.
+
+```js
+const zkBankAddress = process.env.ZKBANK_ADDRESS || "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
+```
+
+Адрес здесь — это тот, который вы получаете, начиная с чистого `anvil` и следуя приведенным выше инструкциям.
+
+```js
+const walletClient = createWalletClient({
+ chain: anvil,
+ transport: http(),
+ account: privateKeyToAccount("0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6")
+})
+```
+
+Этот приватный ключ — один из стандартных предварительно пополненных аккаунтов в `anvil`.
+
+```js
+const generateProof = async (witness, fileID) => {
+```
+
+Сгенерируйте доказательство с помощью исполняемого файла `bb`.
+
+```js
+ const fname = `witness-${fileID}.gz`
+ await fs.writeFile(fname, witness)
+```
+
+Запишите свидетельство в файл.
+
+```js
+ await execPromise(`bb prove -b ./noir/target/zkBank.json -w ${fname} -o ${fileID} --oracle_hash keccak --output_format fields`)
+```
+
+Фактически создайте доказательство. Этот шаг также создает файл с публичными переменными, но нам он не нужен. Мы уже получили эти переменные из `noir.execute`.
+
+```js
+ const proof = "0x" + JSON.parse(await fs.readFile(`./${fileID}/proof_fields.json`)).reduce((a,b) => a+b, "").replace(/0x/g, "")
+```
+
+Доказательство представляет собой JSON-массив значений `Field`, каждое из которых представлено шестнадцатеричным значением. Однако нам нужно отправить его в транзакции как одно значение `bytes`, которое Viem представляет большой шестнадцатеричной строкой. Здесь мы изменяем формат, объединяя все значения, удаляя все `0x` и затем добавляя один в конце.
+
+```js
+ await execPromise(`rm -r ${fname} ${fileID}`)
+
+ return proof
+}
+```
+
+Очистка и возврат доказательства.
+
+```js
+const processMessage = async (message, signature) => {
+ .
+ .
+ .
+
+ const publicFields = noirResult.returnValue.map(x=>'0x' + x.slice(2).padStart(64, "0"))
+```
+
+Публичные поля должны быть массивом 32-байтовых значений. Однако, поскольку нам нужно было разделить хэш транзакции на два значения `Field`, он отображается как 16-байтовое значение. Здесь мы добавляем нули, чтобы Viem понял, что это на самом деле 32 байта.
+
+```js
+ const proof = await generateProof(noirResult.witness, `${fromAddress}-${nonce}`)
+```
+
+Каждый адрес использует каждый nonce только один раз, поэтому мы можем использовать комбинацию `fromAddress` и `nonce` в качестве уникального идентификатора для файла свидетельства и выходного каталога.
+
+```js
+ try {
+ await zkBank.write.processTransaction([
+ proof, publicFields])
+ } catch (err) {
+ console.log(`Verification error: ${err}`)
+ throw Error("Can't verify the transaction onchain")
+ }
+ .
+ .
+ .
+}
+```
+
+Отправьте транзакцию в блокчейн.
+
+#### `smart-contracts/src/ZkBank.sol` {#smart-contracts-src-zkbank-sol}
+
+Это ончейн-код, который получает транзакцию.
+
+```solidity
+// SPDX-License-Identifier: MIT
+
+pragma solidity >=0.8.21;
+
+import {HonkVerifier} from "./Verifier.sol";
+
+contract ZkBank {
+ HonkVerifier immutable myVerifier;
+ bytes32 currentStateHash;
+
+ constructor(address _verifierAddress, bytes32 _initialStateHash) {
+ currentStateHash = _initialStateHash;
+ myVerifier = HonkVerifier(_verifierAddress);
+ }
+```
+
+Ончейн-код должен отслеживать две переменные: верификатор (отдельный контракт, созданный `nargo`) и текущий хэш состояния.
+
+```solidity
+ event TransactionProcessed(
+ bytes32 indexed transactionHash,
+ bytes32 oldStateHash,
+ bytes32 newStateHash
+ );
+```
+
+Каждый раз, когда состояние изменяется, мы генерируем событие `TransactionProcessed`.
+
+```solidity
+ function processTransaction(
+ bytes calldata _proof,
+ bytes32[] calldata _publicFields
+ ) public {
+```
+
+Эта функция обрабатывает транзакции. Она получает доказательство (как `bytes`) и публичные входные данные (как массив `bytes32`) в формате, требуемом верификатором (для минимизации обработки в блокчейне и, следовательно, затрат на газ).
+
+```solidity
+ require(_publicInputs[0] == currentStateHash,
+ "Wrong old state hash");
+```
+
+Доказательство с нулевым разглашением должно доказывать, что транзакция изменяет наш текущий хэш на новый.
+
+```solidity
+ myVerifier.verify(_proof, _publicFields);
+```
+
+Вызовите контракт верификатора для проверки доказательства с нулевым разглашением. Этот шаг отменяет транзакцию, если доказательство с нулевым разглашением неверно.
+
+```solidity
+ currentStateHash = _publicFields[1];
+
+ emit TransactionProcessed(
+ _publicFields[2]<<128 | _publicFields[3],
+ _publicFields[0],
+ _publicFields[1]
+ );
+ }
+}
+```
+
+Если все в порядке, обновите хэш состояния до нового значения и сгенерируйте событие `TransactionProcessed`.
+
+## Злоупотребления со стороны централизованного компонента {#abuses}
+
+Информационная безопасность состоит из трех атрибутов:
+
+- _Конфиденциальность_ — пользователи не могут читать информацию, на чтение которой они не авторизованы.
+- _Целостность_ — информация не может быть изменена, кроме как авторизованными пользователями авторизованным способом.
+- _Доступность_ — авторизованные пользователи могут использовать систему.
+
+В этой системе целостность обеспечивается с помощью доказательств с нулевым разглашением. Доступность гораздо сложнее гарантировать, а конфиденциальность невозможна, потому что банк должен знать баланс каждого аккаунта и все транзакции. Невозможно помешать сущности, обладающей информацией, делиться этой информацией.
+
+Возможно, удастся создать действительно конфиденциальный банк с использованием [скрытых адресов](https://vitalik.eth.limo/general/2023/01/20/stealth.html), но это выходит за рамки данной статьи.
+
+### Ложная информация {#false-info}
+
+Один из способов, которым сервер может нарушить целостность, — это предоставление ложной информации при [запросе данных](https://github.com/qbzzt/250911-zk-bank/blob/03-smart-contracts/server/index.mjs#L278-L291).
+
+Чтобы решить эту проблему, мы можем написать вторую программу Noir, которая получает аккаунты в качестве приватного ввода и адрес, для которого запрашивается информация, в качестве публичного ввода. Выводом являются баланс и nonce этого адреса, а также хэш аккаунтов.
+
+Конечно, это доказательство не может быть проверено в блокчейне, потому что мы не хотим публиковать nonce и балансы в блокчейне. Однако оно может быть проверено клиентским кодом, работающим в браузере.
+
+### Принудительные транзакции {#forced-txns}
+
+Обычный механизм для обеспечения доступности и предотвращения цензуры на L2 — это [принудительные транзакции](https://docs.optimism.io/stack/transactions/forced-transaction). Но принудительные транзакции не сочетаются с доказательствами с нулевым разглашением. Сервер — единственная сущность, которая может проверять транзакции.
+
+Мы можем изменить `smart-contracts/src/ZkBank.sol`, чтобы он принимал принудительные транзакции и не позволял серверу изменять состояние до их обработки. Однако это открывает нас для простой атаки типа «отказ в обслуживании». Что если принудительная транзакция недействительна и поэтому ее невозможно обработать?
+
+Решение — иметь доказательство с нулевым разглашением того, что принудительная транзакция недействительна. Это дает серверу три варианта:
+
+- Обработать принудительную транзакцию, предоставив доказательство с нулевым разглашением того, что она была обработана, и новый хэш состояния.
+- Отклонить принудительную транзакцию и предоставить контракту доказательство с нулевым разглашением того, что транзакция недействительна (неизвестный адрес, неверный nonce или недостаточный баланс).
+- Игнорировать принудительную транзакцию. Невозможно заставить сервер действительно обработать транзакцию, но это означает, что вся система недоступна.
+
+#### Облигации доступности {#avail-bonds}
+
+В реальной реализации, вероятно, будет какой-то мотив прибыли для поддержания работы сервера. Мы можем усилить этот стимул, заставив сервер разместить облигацию доступности, которую любой может сжечь, если принудительная транзакция не будет обработана в течение определенного периода.
+
+### Неправильный код Noir {#bad-noir-code}
+
+Обычно, чтобы заставить людей доверять смарт-контракту, мы загружаем исходный код в [обозреватель блоков](https://eth.blockscout.com/address/0x7D16d2c4e96BCFC8f815E15b771aC847EcbDB48b?tab=contract). Однако в случае доказательств с нулевым разглашением этого недостаточно.
+
+`Verifier.sol` содержит ключ верификации, который является функцией программы Noir. Однако этот ключ не говорит нам, какой была программа Noir. Чтобы действительно иметь доверенное решение, вам нужно загрузить программу Noir (и версию, которая ее создала). В противном случае доказательства с нулевым разглашением могут отражать другую программу, с бэкдором.
+
+Пока обозреватели блоков не начнут позволять нам загружать и проверять программы Noir, вам следует делать это самостоятельно (предпочтительно в [IPFS](/developers/tutorials/ipfs-decentralized-ui/)). Тогда опытные пользователи смогут загрузить исходный код, скомпилировать его самостоятельно, создать `Verifier.sol` и убедиться, что он идентичен тому, что находится в блокчейне.
+
+## Заключение {#conclusion}
+
+Приложения типа Plasma требуют централизованного компонента для хранения информации. Это открывает потенциальные уязвимости, но взамен позволяет нам сохранять конфиденциальность способами, недоступными в самом блокчейне. С помощью доказательств с нулевым разглашением мы можем обеспечить целостность и, возможно, сделать экономически выгодным для того, кто управляет централизованным компонентом, поддерживать доступность.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
+## Благодарности {#acknowledgements}
+
+- Джош Крайтс прочитал черновик этой статьи и помог мне с запутанным вопросом по Noir.
+
+Ответственность за любые оставшиеся ошибки лежит на мне.
diff --git a/public/content/translations/ru/developers/tutorials/calling-a-smart-contract-from-javascript/index.md b/public/content/translations/ru/developers/tutorials/calling-a-smart-contract-from-javascript/index.md
new file mode 100644
index 00000000000..be71da99702
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/calling-a-smart-contract-from-javascript/index.md
@@ -0,0 +1,131 @@
+---
+title: "Вызов смарт-контракта из JavaScript"
+description: "Как вызвать функцию смарт-контракта из JavaScript на примере токена Dai"
+author: jdourlens
+tags: [ "транзакции", "интерфейс", "JavaScript", "web3.js" ]
+skill: beginner
+lang: ru
+published: 2020-04-19
+source: EthereumDev
+sourceUrl: https://ethereumdev.io/calling-a-smart-contract-from-javascript/
+address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+---
+
+В этом руководстве мы рассмотрим, как вызвать функцию [смарт-контракта](/developers/docs/smart-contracts/) из JavaScript. Сначала мы прочитаем состояние смарт-контракта (например, баланс держателя ERC20), а затем изменим состояние блокчейна, выполнив перевод токенов. Вы уже должны быть знакомы с [настройкой JS-среды для взаимодействия с блокчейном](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/).
+
+В этом примере мы будем работать с токеном DAI, для целей тестирования мы сделаем форк блокчейна с помощью ganache-cli и разблокируем адрес, на котором уже есть много DAI:
+
+```bash
+ganache-cli -f https://mainnet.infura.io/v3/[ВАШ КЛЮЧ INFURA] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81
+```
+
+Для взаимодействия со смарт-контрактом нам понадобятся его адрес и ABI:
+
+```js
+const ERC20TransferABI = [
+ {
+ constant: false,
+ inputs: [
+ {
+ name: "_to",
+ type: "address",
+ },
+ {
+ name: "_value",
+ type: "uint256",
+ },
+ ],
+ name: "transfer",
+ outputs: [
+ {
+ name: "",
+ type: "bool",
+ },
+ ],
+ payable: false,
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ constant: true,
+ inputs: [
+ {
+ name: "_owner",
+ type: "address",
+ },
+ ],
+ name: "balanceOf",
+ outputs: [
+ {
+ name: "balance",
+ type: "uint256",
+ },
+ ],
+ payable: false,
+ stateMutability: "view",
+ type: "function",
+ },
+]
+
+const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f"
+```
+
+Для этого проекта мы урезали полный ABI ERC20, оставив только функции `balanceOf` и `transfer`, но вы можете найти [полный ABI ERC20 здесь](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/).
+
+Затем нам нужно создать экземпляр нашего смарт-контракта:
+
+```js
+const web3 = new Web3("http://localhost:8545")
+
+const daiToken = new web3.eth.Contract(ERC20TransferABI, DAI_ADDRESS)
+```
+
+Мы также настроим два адреса:
+
+- тот, который получит перевод, и
+- тот, который мы уже разблокировали и с которого будем отправлять:
+
+```js
+const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81"
+const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+```
+
+В следующей части мы вызовем функцию `balanceOf`, чтобы получить текущее количество токенов, которыми владеют оба адреса.
+
+## Вызов: чтение значения из смарт-контракта {#call-reading-value-from-a-smart-contract}
+
+В первом примере будет вызван «константный» метод, и его метод смарт-контракта будет выполнен в EVM без отправки какой-либо транзакции. Для этого мы прочитаем баланс ERC20 адреса. [Прочтите нашу статью о токенах ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/).
+
+Вы можете получить доступ к методам созданного экземпляра смарт-контракта, для которого вы предоставили ABI, следующим образом: `yourContract.methods.methodname`. Используя функцию `call`, вы получите результат выполнения функции.
+
+```js
+daiToken.methods.balanceOf(senderAddress).call(function (err, res) {
+ if (err) {
+ console.log("Произошла ошибка", err)
+ return
+ }
+ console.log("Баланс: ", res)
+})
+```
+
+Помните, что DAI ERC20 имеет 18 знаков после запятой, что означает, что вам нужно убрать 18 нулей, чтобы получить правильную сумму. Значения uint256 возвращаются в виде строк, так как JavaScript не обрабатывает большие числовые значения. Если вы не уверены, [как работать с большими числами в JS, ознакомьтесь с нашим руководством по bignumber.js](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/).
+
+## Отправка: отправка транзакции в функцию смарт-контракта {#send-sending-a-transaction-to-a-smart-contract-function}
+
+Во втором примере мы вызовем функцию transfer смарт-контракта DAI, чтобы отправить 10 DAI на наш второй адрес. Функция transfer принимает два параметра: адрес получателя и сумму токенов для перевода:
+
+```js
+daiToken.methods
+ .transfer(receiverAddress, "100000000000000000000")
+ .send({ from: senderAddress }, function (err, res) {
+ if (err) {
+ console.log("Произошла ошибка", err)
+ return
+ }
+ console.log("Хэш транзакции: " + res)
+ })
+```
+
+Функция call возвращает хэш транзакции, которая будет включена в блокчейн. В Ethereum хэши транзакций предсказуемы — так мы можем получить хэш транзакции до ее выполнения ([узнайте, как рассчитываются хэши, здесь](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction)).
+
+Поскольку функция только отправляет транзакцию в блокчейн, мы не можем увидеть результат, пока не узнаем, когда она будет добыта и включена в блокчейн. В следующем руководстве мы узнаем, [как дождаться выполнения транзакции в блокчейне, зная ее хэш](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/).
diff --git a/public/content/translations/ru/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/ru/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md
new file mode 100644
index 00000000000..a7f7b5cca0c
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md
@@ -0,0 +1,585 @@
+---
+title: "Создание пользовательского интерфейса для вашего контракта"
+description: "Используя современные компоненты, такие как TypeScript, React, Vite и Wagmi, мы рассмотрим современный, но минимальный пользовательский интерфейс и научимся подключать кошелек к пользовательскому интерфейсу, вызывать смарт-контракт для чтения информации, отправлять транзакцию в смарт-контракт и отслеживать события со смарт-контракта для выявления изменений."
+author: Ori Pomerantz
+tags: [ "TypeScript", "react", "vite", "wagmi", "интерфейс" ]
+skill: beginner
+published: 2023-11-01
+lang: ru
+sidebarDepth: 3
+---
+
+Вы нашли функцию, которая нам нужна в экосистеме Ethereum. Вы написали смарт-контракты для ее реализации и, возможно, даже какой-то связанный с этим код, который выполняется вне сети. Это здорово! К сожалению, без пользовательского интерфейса у вас не будет пользователей, а в последний раз, когда вы писали веб-сайт, люди пользовались модемами с коммутируемым доступом, а JavaScript был в новинку.
+
+Эта статья для вас. Я предполагаю, что вы знаете программирование и, возможно, немного JavaScript и HTML, но ваши навыки работы с пользовательским интерфейсом устарели. Вместе мы рассмотрим простое современное приложение, чтобы вы увидели, как это делается в наши дни.
+
+## Почему это важно {#why-important}
+
+Теоретически вы могли бы просто позволить людям использовать [Etherscan](https://holesky.etherscan.io/address/0x432d810484add7454ddb3b5311f0ac2e95cecea8#writeContract) или [Blockscout](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=write_contract) для взаимодействия с вашими контрактами. Это будет отлично для опытных пользователей Ethereum. Но мы пытаемся обслужить [еще миллиард человек](https://blog.ethereum.org/2021/05/07/ethereum-for-the-next-billion). Этого не произойдет без отличного пользовательского опыта, а дружественный пользовательский интерфейс — большая его часть.
+
+## Приложение Greeter {#greeter-app}
+
+Существует много теории о том, как работает современный пользовательский интерфейс, и [много хороших сайтов](https://react.dev/learn/thinking-in-react), [которые это объясняют](https://wagmi.sh/core/getting-started). Вместо того чтобы повторять прекрасную работу, проделанную на этих сайтах, я предположу, что вы предпочитаете учиться на практике и начнете с приложения, с которым можно поиграть. Вам все еще нужна теория, чтобы все сделать, и мы до нее доберемся — мы просто будем разбирать исходный файл за исходным файлом и обсуждать все по мере их появления.
+
+### Установка {#installation}
+
+1. При необходимости добавьте [блокчейн Holesky](https://chainlist.org/?search=holesky&testnets=true) в свой кошелек и [получите тестовые ETH](https://www.holeskyfaucet.io/).
+
+2. Клонируйте репозиторий github.
+
+ ```sh
+ git clone https://github.com/qbzzt/20230801-modern-ui.git
+ ```
+
+3. Установить нужные пакеты.
+
+ ```sh
+ cd 20230801-modern-ui
+ pnpm install
+ ```
+
+4. Запустите приложение.
+
+ ```sh
+ pnpm dev
+ ```
+
+5. Перейдите по URL-адресу, указанному в приложении. В большинстве случаев это [http://localhost:5173/](http://localhost:5173/).
+
+6. Вы можете увидеть исходный код контракта, немного измененную версию Greeter от Hardhat, [в обозревателе блокчейна](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contract).
+
+### Обзор файлов {#file-walk-through}
+
+#### `index.html` {#index-html}
+
+Этот файл является стандартным шаблоном HTML, за исключением этой строки, которая импортирует файл скрипта.
+
+```html
+
+```
+
+#### `src/main.tsx` {#main-tsx}
+
+Расширение файла говорит нам, что этот файл является [компонентом React](https://www.w3schools.com/react/react_components.asp), написанным на [TypeScript](https://www.typescriptlang.org/), расширении JavaScript, которое поддерживает [проверку типов](https://en.wikipedia.org/wiki/Type_system#Type_checking). TypeScript компилируется в JavaScript, поэтому мы можем использовать его для выполнения на стороне клиента.
+
+```tsx
+import '@rainbow-me/rainbowkit/styles.css'
+import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
+import * as React from 'react'
+import * as ReactDOM from 'react-dom/client'
+import { WagmiConfig } from 'wagmi'
+import { chains, config } from './wagmi'
+```
+
+Импортируйте необходимый код библиотеки.
+
+```tsx
+import { App } from './App'
+```
+
+Импортируйте компонент React, который реализует приложение (см. ниже).
+
+```tsx
+ReactDOM.createRoot(document.getElementById('root')!).render(
+```
+
+Создайте корневой компонент React. Параметр `render` — это [JSX](https://www.w3schools.com/react/react_jsx.asp), язык-расширение, который использует как HTML, так и JavaScript/TypeScript. Восклицательный знак здесь говорит компоненту TypeScript: "вы не знаете, что `document.getElementById('root')` будет допустимым параметром для `ReactDOM.createRoot`, но не волнуйтесь - я разработчик и я говорю вам, что он будет".
+
+```tsx
+
+```
+
+Приложение находится внутри [компонента `React.StrictMode`](https://react.dev/reference/react/StrictMode). Этот компонент указывает библиотеке React вставлять дополнительные проверки для отладки, что полезно во время разработки.
+
+```tsx
+
+```
+
+Приложение также находится внутри [компонента `WagmiConfig`](https://wagmi.sh/react/api/WagmiProvider). [Библиотека wagmi (we are going to make it)](https://wagmi.sh/) соединяет определения пользовательского интерфейса React с [библиотекой viem](https://viem.sh/) для написания децентрализованного приложения Ethereum.
+
+```tsx
+
+```
+
+И, наконец, [компонент `RainbowKitProvider`](https://www.rainbowkit.com/). Этот компонент обрабатывает вход в систему и связь между кошельком и приложением.
+
+```tsx
+
+```
+
+Теперь у нас может быть компонент для приложения, который фактически реализует пользовательский интерфейс. Символ `/>` в конце компонента говорит React, что этот компонент не содержит никаких определений внутри себя, согласно стандарту XML.
+
+```tsx
+
+
+ ,
+)
+```
+
+Конечно, мы должны закрыть другие компоненты.
+
+#### `src/App.tsx` {#app-tsx}
+
+```tsx
+import { ConnectButton } from '@rainbow-me/rainbowkit'
+import { useAccount } from 'wagmi'
+import { Greeter } from './components/Greeter'
+
+export function App() {
+```
+
+Это стандартный способ создания компонента React — определить функцию, которая вызывается каждый раз, когда ее нужно отрисовать. Эта функция обычно содержит в начале некоторый код TypeScript или JavaScript, за которым следует оператор `return`, возвращающий код JSX.
+
+```tsx
+ const { isConnected } = useAccount()
+```
+
+Здесь мы используем [`useAccount`](https://wagmi.sh/react/api/hooks/useAccount), чтобы проверить, подключены ли мы к блокчейну через кошелек или нет.
+
+По соглашению, в React функции, называемые `use...`, являются [хуками](https://www.w3schools.com/react/react_hooks.asp), которые возвращают какие-либо данные. Когда вы используете такие хуки, ваш компонент не только получает данные, но и при изменении этих данных компонент повторно отрисовывается с обновленной информацией.
+
+```tsx
+ return (
+ <>
+```
+
+JSX компонента React _должен_ возвращать один компонент. Когда у нас несколько компонентов, и нет ничего, что оборачивает их "естественным образом", мы используем пустой компонент (`<> ...` \>`) чтобы сделать из них один компонент.
+
+```tsx
+ Greeter
+
+```
+
+Мы получаем [компонент `ConnectButton`](https://www.rainbowkit.com/docs/connect-button) из RainbowKit. Когда мы не подключены, он предоставляет нам кнопку `Connect Wallet`, которая открывает модальное окно, объясняющее, что такое кошельки, и позволяющее выбрать, какой из них использовать. Когда мы подключены, он отображает используемый нами блокчейн, адрес нашего аккаунта и баланс ETH. Мы можем использовать эти дисплеи для переключения сети или для отключения.
+
+```tsx
+ {isConnected && (
+```
+
+Когда нам нужно вставить фактический JavaScript (или TypeScript, который будет скомпилирован в JavaScript) в JSX, мы используем скобки (`{}`).
+
+Синтаксис `a && b` является сокращением для [`a ?` b : a`](https://www.w3schools.com/react/react_es6_ternary.asp). То есть, если `a`истинно, оно вычисляется как`b`, а в противном случае — как `a`(которое может быть`false`, `0` и т.д.). Это простой способ сообщить React, что компонент должен отображаться только при выполнении определенного условия.
+
+В этом случае мы хотим показывать пользователю `Greeter` только если пользователь подключен к блокчейну.
+
+```tsx
+
+ )}
+ >
+ )
+}
+```
+
+#### `src/components/Greeter.tsx` {#greeter-tsx}
+
+Этот файл содержит большую часть функциональности пользовательского интерфейса. Он включает определения, которые обычно находятся в нескольких файлах, но поскольку это учебное пособие, программа оптимизирована для простоты понимания с первого раза, а не для производительности или простоты обслуживания.
+
+```tsx
+import { useState, ChangeEventHandler } from 'react'
+import { useNetwork,
+ useReadContract,
+ usePrepareContractWrite,
+ useContractWrite,
+ useContractEvent
+ } from 'wagmi'
+```
+
+Мы используем эти функции библиотеки. Опять же, они объясняются ниже, там, где они используются.
+
+```tsx
+import { AddressType } from 'abitype'
+```
+
+[Библиотека `abitype`](https://abitype.dev/) предоставляет нам определения TypeScript для различных типов данных Ethereum, таких как [`AddressType`](https://abitype.dev/config#addresstype).
+
+```tsx
+let greeterABI = [
+ .
+ .
+ .
+] as const // greeterABI
+```
+
+ABI для контракта `Greeter`.
+Если вы разрабатываете контракты и пользовательский интерфейс одновременно, вы обычно помещаете их в один репозиторий и используете ABI, сгенерированный компилятором Solidity, как файл в вашем приложении. Однако здесь это не обязательно, потому что контракт уже разработан и меняться не будет.
+
+```tsx
+type AddressPerBlockchainType = {
+ [key: number]: AddressType
+}
+```
+
+TypeScript строго типизирован. Мы используем это определение, чтобы указать адрес, по которому контракт `Greeter` развернут в разных сетях. Ключ — это число (chainId), а значение — `AddressType` (адрес).
+
+```tsx
+const contractAddrs: AddressPerBlockchainType = {
+ // Holesky
+ 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8',
+
+ // Sepolia
+ 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0'
+}
+```
+
+Адрес контракта в двух поддерживаемых сетях: [Holesky](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contact_code) и [Sepolia](https://eth-sepolia.blockscout.com/address/0x7143d5c190F048C8d19fe325b748b081903E3BF0?tab=contact_code).
+
+Примечание: на самом деле есть третье определение, для Redstone Holesky, оно будет объяснено ниже.
+
+```tsx
+type ShowObjectAttrsType = {
+ name: string,
+ object: any
+}
+```
+
+Этот тип используется в качестве параметра для компонента `ShowObject` (объяснение будет позже). Он включает имя объекта и его значение, которые отображаются в целях отладки.
+
+```tsx
+type ShowGreetingAttrsType = {
+ greeting: string | undefined
+}
+```
+
+В любой момент времени мы можем либо знать, что такое приветствие (потому что мы прочитали его из блокчейна), либо не знать (потому что мы его еще не получили). Поэтому полезно иметь тип, который может быть либо строкой, либо ничем.
+
+##### Компонент `Greeter` {#greeter-component}
+
+```tsx
+const Greeter = () => {
+```
+
+Наконец, мы переходим к определению компонента.
+
+```tsx
+ const { chain } = useNetwork()
+```
+
+Информация о сети, которую мы используем, предоставленная [wagmi](https://wagmi.sh/react/hooks/useNetwork).
+Поскольку это хук (`use...`), каждый раз, когда эта информация меняется, компонент перерисовывается.
+
+```tsx
+ const greeterAddr = chain && contractAddrs[chain.id]
+```
+
+Адрес контракта Greeter, который зависит от сети (и который равен `undefined`, если у нас нет информации о сети или мы находимся в сети без этого контракта).
+
+```tsx
+ const readResults = useReadContract({
+ address: greeterAddr,
+ abi: greeterABI,
+ functionName: "greet" , // Нет аргументов
+ watch: true
+ })
+```
+
+[Хук `useReadContract`](https://wagmi.sh/react/api/hooks/useReadContract) читает информацию из контракта. Вы можете точно увидеть, какую информацию он возвращает, раскрыв `readResults` в пользовательском интерфейсе. В этом случае мы хотим, чтобы он продолжал отслеживать, чтобы мы были проинформированы, когда приветствие изменится.
+
+**Примечание:** Мы могли бы прослушивать [события `setGreeting`](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=logs), чтобы знать, когда меняется приветствие, и обновлять его таким образом. Однако, хотя это может быть более эффективно, это применимо не во всех случаях. Когда пользователь переключается на другую сеть, приветствие также меняется, но это изменение не сопровождается событием. Мы могли бы иметь одну часть кода, прослушивающую события, и другую для определения изменений сети, но это было бы сложнее, чем просто установить [параметр `watch`](https://wagmi.sh/react/api/hooks/useReadContract#watch-optional).
+
+```tsx
+ const [ newGreeting, setNewGreeting ] = useState("")
+```
+
+[Хук `useState` из React](https://www.w3schools.com/react/react_usestate.asp) позволяет нам указать переменную состояния, значение которой сохраняется от одной отрисовки компонента к другой. Начальное значение — это параметр, в данном случае пустая строка.
+
+Хук `useState` возвращает список с двумя значениями:
+
+1. Текущее значение переменной состояния.
+2. Функция для изменения переменной состояния при необходимости. Поскольку это хук, каждый раз при его вызове компонент отрисовывается заново.
+
+В этом случае мы используем переменную состояния для нового приветствия, которое хочет установить пользователь.
+
+```tsx
+ const greetingChange : ChangeEventHandler = (evt) =>
+ setNewGreeting(evt.target.value)
+```
+
+Это обработчик события изменения поля ввода нового приветствия. Тип [`ChangeEventHandler`](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/) указывает, что это обработчик изменения значения элемента ввода HTML. Часть `` используется, потому что это [обобщенный тип](https://www.w3schools.com/typescript/typescript_basic_generics.php).
+
+```tsx
+ const preparedTx = usePrepareContractWrite({
+ address: greeterAddr,
+ abi: greeterABI,
+ functionName: 'setGreeting',
+ args: [ newGreeting ]
+ })
+ const workingTx = useContractWrite(preparedTx.config)
+```
+
+Это процесс отправки транзакции в блокчейн с точки зрения клиента:
+
+1. Отправьте транзакцию узлу в блокчейне с помощью [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas).
+2. Дождитесь ответа от узла.
+3. Когда ответ получен, попросите пользователя подписать транзакцию через кошелек. Этот шаг _должен_ произойти после получения ответа от узла, потому что пользователю показывается стоимость газа транзакции перед ее подписанием.
+4. Дождитесь одобрения пользователя.
+5. Отправьте транзакцию еще раз, на этот раз используя [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction).
+
+Шаг 2, скорее всего, займет ощутимое количество времени, в течение которого пользователи будут задаваться вопросом, действительно ли их команда была получена пользовательским интерфейсом и почему им еще не предлагают подписать транзакцию. Это приводит к плохому пользовательскому опыту (UX).
+
+Решение — использовать [хуки подготовки](https://wagmi.sh/react/prepare-hooks). Каждый раз, когда меняется параметр, немедленно отправляйте узлу запрос `eth_estimateGas`. Затем, когда пользователь действительно хочет отправить транзакцию (в данном случае, нажав **Обновить приветствие**), стоимость газа известна, и пользователь может сразу увидеть страницу кошелька.
+
+```tsx
+ return (
+```
+
+Теперь мы наконец можем создать фактический HTML для возврата.
+
+```tsx
+ <>
+ Greeter
+ {
+ !readResults.isError && !readResults.isLoading &&
+
+ }
+
+```
+
+Создайте компонент `ShowGreeting` (описан ниже), но только если приветствие было успешно прочитано из блокчейна.
+
+```tsx
+
+```
+
+Это поле для ввода текста, где пользователь может установить новое приветствие. Каждый раз, когда пользователь нажимает клавишу, мы вызываем `greetingChange`, который вызывает `setNewGreeting`. Поскольку `setNewGreeting` происходит из хука `useState`, это заставляет компонент `Greeter` отрисовываться снова. Это означает, что:
+
+- Нам нужно указать `value`, чтобы сохранить значение нового приветствия, иначе оно вернется к значению по умолчанию — пустой строке.
+- `usePrepareContractWrite` вызывается каждый раз, когда `newGreeting` меняется, что означает, что в подготовленной транзакции всегда будет самое последнее `newGreeting`.
+
+```tsx
+
+```
+
+Если `workingTx.write` отсутствует, значит, мы все еще ждем информацию, необходимую для отправки обновления приветствия, поэтому кнопка отключена. Если значение `workingTx.write` есть, то это функция, которую нужно вызвать для отправки транзакции.
+
+```tsx
+
+
+
+
+ >
+ )
+}
+```
+
+Наконец, чтобы помочь вам увидеть, что мы делаем, покажем три объекта, которые мы используем:
+
+- `readResults`
+- `preparedTx`
+- `workingTx`
+
+##### Компонент `ShowGreeting` {#showgreeting-component}
+
+Этот компонент показывает
+
+```tsx
+const ShowGreeting = (attrs : ShowGreetingAttrsType) => {
+```
+
+Функция компонента получает параметр со всеми атрибутами компонента.
+
+```tsx
+ return {attrs.greeting}
+}
+```
+
+##### Компонент `ShowObject` {#showobject-component}
+
+В информационных целях мы используем компонент `ShowObject` для отображения важных объектов (`readResults` для чтения приветствия и `preparedTx` и `workingTx` для создаваемых нами транзакций).
+
+```tsx
+const ShowObject = (attrs: ShowObjectAttrsType ) => {
+ const keys = Object.keys(attrs.object)
+ const funs = keys.filter(k => typeof attrs.object[k] == "function")
+ return <>
+
+```
+
+Мы не хотим загромождать пользовательский интерфейс всей информацией, поэтому, чтобы можно было просматривать или скрывать ее, мы используем тег [`details`](https://www.w3schools.com/tags/tag_details.asp).
+
+```tsx
+ {attrs.name}
+
+ {JSON.stringify(attrs.object, null, 2)}
+```
+
+Большинство полей отображаются с помощью [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp).
+
+```tsx
+
+ { funs.length > 0 &&
+ <>
+ Функции:
+
+```
+
+Исключение составляют функции, которые не являются частью [стандарта JSON](https://www.json.org/json-en.html), поэтому их нужно отображать отдельно.
+
+```tsx
+ {funs.map((f, i) =>
+```
+
+Внутри JSX код внутри `{` фигурных скобок `}` интерпретируется как JavaScript. Затем код внутри `(` круглых скобок `)` снова интерпретируется как JSX.
+
+```tsx
+ (- {f}
)
+ )}
+```
+
+React требует, чтобы теги в [дереве DOM](https://www.w3schools.com/js/js_htmldom.asp) имели уникальные идентификаторы. Это означает, что дочерние элементы одного и того же тега (в данном случае [неупорядоченного списка](https://www.w3schools.com/tags/tag_ul.asp)) должны иметь разные атрибуты `key`.
+
+```tsx
+
+ >
+ }
+
+ >
+}
+```
+
+Закройте различные HTML-теги.
+
+##### Финальный `export` {#the-final-export}
+
+```tsx
+export { Greeter }
+```
+
+Компонент `Greeter` — это тот, который нам нужно экспортировать для приложения.
+
+#### `src/wagmi.ts` {#wagmi-ts}
+
+Наконец, различные определения, связанные с WAGMI, находятся в `src/wagmi.ts`. Я не буду здесь все объяснять, потому что большая часть — это шаблонный код, который вам вряд ли понадобится менять.
+
+Код здесь не совсем такой же, как [на github](https://github.com/qbzzt/20230801-modern-ui/blob/main/src/wagmi.ts), потому что позже в статье мы добавляем еще одну сеть ([Redstone Holesky](https://redstone.xyz/docs/network-info)).
+
+```ts
+import { getDefaultWallets } from '@rainbow-me/rainbowkit'
+import { configureChains, createConfig } from 'wagmi'
+import { holesky, sepolia } from 'wagmi/chains'
+```
+
+Импортируйте блокчейны, которые поддерживает приложение. Вы можете увидеть список поддерживаемых сетей [на GitHub viem](https://github.com/wagmi-dev/viem/tree/main/src/chains/definitions).
+
+```ts
+import { publicProvider } from 'wagmi/providers/public'
+
+const walletConnectProjectId = 'c96e690bb92b6311e8e9b2a6a22df575'
+```
+
+Чтобы использовать [WalletConnect](https://walletconnect.com/), вам нужен идентификатор проекта для вашего приложения. Вы можете получить его на [cloud.walletconnect.com](https://cloud.walletconnect.com/sign-in).
+
+```ts
+const { chains, publicClient, webSocketPublicClient } = configureChains(
+ [ holesky, sepolia ],
+ [
+ publicProvider(),
+ ],
+)
+
+const { connectors } = getDefaultWallets({
+ appName: 'My wagmi + RainbowKit App',
+ chains,
+ projectId: walletConnectProjectId,
+})
+
+export const config = createConfig({
+ autoConnect: true,
+ connectors,
+ publicClient,
+ webSocketPublicClient,
+})
+
+export { chains }
+```
+
+### Добавление другого блокчейна {#add-blockchain}
+
+В наши дни существует множество [решений для масштабирования L2](/layer-2/), и вы, возможно, захотите поддержать некоторые, которые viem еще не поддерживает. Для этого вы изменяете `src/wagmi.ts`. Эти инструкции объясняют, как добавить [Redstone Holesky](https://redstone.xyz/docs/network-info).
+
+1. Импортируйте тип `defineChain` из viem.
+
+ ```ts
+ import { defineChain } from 'viem'
+ ```
+
+2. Добавьте определение сети.
+
+ ```ts
+ const redstoneHolesky = defineChain({
+ id: 17_001,
+ name: 'Redstone Holesky',
+ network: 'redstone-holesky',
+ nativeCurrency: {
+ decimals: 18,
+ name: 'Ether',
+ symbol: 'ETH',
+ },
+ rpcUrls: {
+ default: {
+ http: ['https://rpc.holesky.redstone.xyz'],
+ webSocket: ['wss://rpc.holesky.redstone.xyz/ws'],
+ },
+ public: {
+ http: ['https://rpc.holesky.redstone.xyz'],
+ webSocket: ['wss://rpc.holesky.redstone.xyz/ws'],
+ },
+ },
+ blockExplorers: {
+ default: { name: 'Explorer', url: 'https://explorer.holesky.redstone.xyz' },
+ },
+ })
+ ```
+
+3. Добавьте новую сеть в вызов `configureChains`.
+
+ ```ts
+ const { chains, publicClient, webSocketPublicClient } = configureChains(
+ [ holesky, sepolia, redstoneHolesky ],
+ [ publicProvider(), ],
+ )
+ ```
+
+4. Убедитесь, что приложение знает адрес ваших контрактов в новой сети. В этом случае мы изменяем `src/components/Greeter.tsx`:
+
+ ```ts
+ const contractAddrs : AddressPerBlockchainType = {
+ // Holesky
+ 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8',
+
+ // Redstone Holesky
+ 17001: '0x4919517f82a1B89a32392E1BF72ec827ba9986D3',
+
+ // Sepolia
+ 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0'
+ }
+ ```
+
+## Заключение {#conclusion}
+
+Конечно, вас не особо волнует предоставление пользовательского интерфейса для `Greeter`. Вы хотите создать пользовательский интерфейс для своих собственных контрактов. Чтобы создать собственное приложение, выполните следующие шаги:
+
+1. Укажите, что нужно создать приложение wagmi.
+
+ ```sh copy
+ pnpm create wagmi
+ ```
+
+2. Назовите приложение.
+
+3. Выберите фреймворк **React**.
+
+4. Выберите вариант **Vite**.
+
+5. Вы можете [добавить Rainbow kit](https://www.rainbowkit.com/docs/installation#manual-setup).
+
+Теперь идите и сделайте свои контракты пригодными для использования во всем мире.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
diff --git a/public/content/translations/ru/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/ru/developers/tutorials/deploying-your-first-smart-contract/index.md
new file mode 100644
index 00000000000..82f5974f736
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/deploying-your-first-smart-contract/index.md
@@ -0,0 +1,101 @@
+---
+title: "Развертывание вашего первого смарт-контракта"
+description: "Введение в развертывание вашего первого смарт-контракта в тестовой сети Ethereum"
+author: "jdourlens"
+tags:
+ [
+ "Умные контракты",
+ "Remix",
+ "Solidity",
+ "развертывание"
+ ]
+skill: beginner
+lang: ru
+published: 2020-04-03
+source: EthereumDev
+sourceUrl: https://ethereumdev.io/deploying-your-first-smart-contract/
+address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+---
+
+Полагаю, вы так же, как и мы, с нетерпением ждете возможности [развернуть](/developers/docs/smart-contracts/deploying/) и повзаимодействовать со своим первым [смарт-контрактом](/developers/docs/smart-contracts/) в блокчейне Ethereum.
+
+Не волнуйтесь, так как это наш первый смарт-контракт, мы развернем его в [локальной тестовой сети](/developers/docs/networks/), поэтому его развертывание и эксперименты с ним будут для вас совершенно бесплатными.
+
+## Написание нашего контракта {#writing-our-contract}
+
+Первым делом [посетите Remix](https://remix.ethereum.org/) и создайте новый файл. В левой верхней части интерфейса Remix добавьте новый файл и введите желаемое имя файла.
+
+
+
+В новый файл мы вставим следующий код.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity >=0.5.17;
+
+contract Counter {
+
+ // Открытая переменная типа unsigned int для хранения количества подсчетов
+ uint256 public count = 0;
+
+ // Функция, которая увеличивает наш счетчик
+ function increment() public {
+ count += 1;
+ }
+
+ // Необязательный геттер для получения значения счетчика
+ function getCount() public view returns (uint256) {
+ return count;
+ }
+
+}
+```
+
+Если вы знакомы с программированием, вы легко догадаетесь, что делает эта программа. Вот построчное объяснение:
+
+- Строка 4: мы определяем контракт с именем `Counter`.
+- Строка 7: наш контракт хранит одно беззнаковое целое число с именем `count`, начальное значение которого равно 0.
+- Строка 10: первая функция изменит состояние контракта и увеличит (`increment()`) значение нашей переменной `count`.
+- Строка 15: вторая функция — это просто геттер, позволяющий считывать значение переменной `count` извне смарт-контракта. Обратите внимание, что, поскольку мы определили нашу переменную `count` как public, в этом нет необходимости, но это показано в качестве примера.
+
+Это все, что касается нашего первого простого смарт-контракта. Как вы, возможно, знаете, он похож на класс из языков ООП (объектно-ориентированного программирования), таких как Java или C++. Теперь пришло время поэкспериментировать с нашим контрактом.
+
+## Развертывание нашего контракта {#deploying-our-contract}
+
+Поскольку мы написали наш самый первый смарт-контракт, теперь мы развернем его в блокчейне, чтобы поэкспериментировать с ним.
+
+[Развертывание смарт-контракта в блокчейне](/developers/docs/smart-contracts/deploying/) — это, по сути, просто отправка транзакции, содержащей код скомпилированного смарт-контракта, без указания получателей.
+
+Сначала мы [скомпилируем контракт](/developers/docs/smart-contracts/compiling/), нажав на значок компиляции в левой части:
+
+
+
+Затем нажмите кнопку компиляции:
+
+
+
+Вы можете выбрать опцию «Auto compile», чтобы контракт всегда компилировался при сохранении содержимого в текстовом редакторе.
+
+Затем перейдите на экран «deploy and run transactions»:
+
+
+
+Когда вы окажетесь на экране «deploy and run transactions», дважды проверьте, что отображается имя вашего контракта, и нажмите «Deploy». Как видно в верхней части страницы, текущая среда — «JavaScript VM». Это означает, что мы будем развертывать наш смарт-контракт и взаимодействовать с ним в локальном тестовом блокчейне, чтобы иметь возможность проводить тестирование быстрее и без каких-либо комиссий.
+
+
+
+После нажатия кнопки «Deploy» вы увидите свой контракт в нижней части экрана. Нажмите на стрелку слева, чтобы развернуть его и увидеть содержимое нашего контракта. Это наша переменная `counter`, наша функция `increment()` и геттер `getCounter()`.
+
+Если вы нажмете на кнопку `count` или `getCount`, она получит и отобразит содержимое переменной `count` контракта. Поскольку мы еще не вызывали функцию `increment`, она должна отобразить 0.
+
+
+
+Теперь давайте вызовем функцию `increment`, нажав на соответствующую кнопку. В нижней части окна вы увидите журналы выполненных транзакций. Вы увидите, что журналы отличаются, когда вы нажимаете кнопку для получения данных, а не кнопку `increment`. Это потому, что чтение данных из блокчейна не требует каких-либо транзакций (записи) или комиссий. Потому что только изменение состояния блокчейна требует выполнения транзакции:
+
+
+
+После нажатия кнопки `increment`, которая создаст транзакцию для вызова нашей функции `increment()`, если мы снова нажмем на кнопки `count` или `getCount`, мы прочтем новое обновленное состояние нашего смарт-контракта, в котором переменная `count` будет больше 0.
+
+
+
+В следующем руководстве мы рассмотрим, [как добавлять события в смарт-контракты](/developers/tutorials/logging-events-smart-contracts/). Ведение журнала событий — это удобный способ отладить ваш смарт-контракт и понять, что происходит при вызове функции.
diff --git a/public/content/translations/ru/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md b/public/content/translations/ru/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md
new file mode 100644
index 00000000000..9955e911e61
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md
@@ -0,0 +1,372 @@
+---
+title: "Как разработать и протестировать децентрализованное приложение в локальной многоклиентской тестовой сети"
+description: "В этом руководстве вы сначала узнаете, как создать и настроить локальную многоклиентскую тестовую сеть Ethereum, а затем использовать эту тестовую сеть для развертывания и тестирования децентрализованного приложения."
+author: "Tedi Mitiku"
+tags:
+ [
+ "клиенты",
+ "узлы",
+ "Умные контракты",
+ "композиционность",
+ "уровень консенсуса",
+ "Уровень исполнения",
+ "тестирование"
+ ]
+skill: intermediate
+lang: ru
+published: 2023-04-11
+---
+
+## Введение {#introduction}
+
+Это руководство проведет вас через процесс создания настраиваемой локальной тестовой сети Ethereum, развертывания в ней смарт-контракта и использования тестовой сети для запуска тестов для вашего децентрализованного приложения. Это руководство предназначено для разработчиков децентрализованных приложений, которые хотят разрабатывать и тестировать свои децентрализованные приложения локально с различными конфигурациями сети перед развертыванием в работающую тестовую сеть или основную сеть.
+
+В этом руководстве вы:
+
+- Создадите локальную тестовую сеть Ethereum с помощью [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package), используя [Kurtosis](https://www.kurtosis.com/),
+- Подключите среду разработки децентрализованных приложений Hardhat к локальной тестовой сети, чтобы скомпилировать, развернуть и протестировать децентрализованное приложение, и
+- Настроите локальную тестовую сеть, включая такие параметры, как количество узлов и конкретные пары клиентов EL/CL, чтобы обеспечить рабочие процессы разработки и тестирования для различных конфигураций сети.
+
+### Что такое Kurtosis? {#what-is-kurtosis}
+
+[Kurtosis](https://www.kurtosis.com/) — это компонуемая система сборки, предназначенная для настройки многоконтейнерных тестовых сред. Он специально позволяет разработчикам создавать воспроизводимые среды, требующие динамической логики настройки, например, тестовые сети блокчейна.
+
+В этом руководстве пакет Kurtosis eth-network-package запускает локальную тестовую сеть Ethereum с поддержкой клиента уровня исполнения (EL) [`geth`](https://geth.ethereum.org/), а также клиентов уровня консенсуса (CL) [`teku`](https://consensys.io/teku), [`lighthouse`](https://lighthouse.sigmaprime.io/) и [`lodestar`](https://lodestar.chainsafe.io/). Этот пакет служит настраиваемой и компонуемой альтернативой сетям во фреймворках, таких как Hardhat Network, Ganache и Anvil. Kurtosis предлагает разработчикам больший контроль и гибкость над используемыми ими тестовыми сетями, что является основной причиной, по которой [Ethereum Foundation использовал Kurtosis для тестирования Слияния](https://www.kurtosis.com/blog/testing-the-ethereum-merge) и продолжает использовать его для тестирования обновлений сети.
+
+## Настройка Kurtosis {#setting-up-kurtosis}
+
+Прежде чем продолжить, убедитесь, что у вас есть:
+
+- [Установленный и запущенный движок Docker](https://docs.kurtosis.com/install/#i-install--start-docker) на вашем локальном компьютере
+- [Установленный Kurtosis CLI](https://docs.kurtosis.com/install#ii-install-the-cli) (или обновленный до последней версии, если CLI у вас уже установлен)
+- Установленные [Node.js](https://nodejs.org/en), [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable) и [npx](https://www.npmjs.com/package/npx) (для вашей среды децентрализованных приложений)
+
+## Создание локальной тестовой сети Ethereum {#instantiate-testnet}
+
+Чтобы запустить локальную тестовую сеть Ethereum, выполните:
+
+```python
+kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package
+```
+
+Примечание: эта команда дает вашей сети имя «local-eth-testnet» с помощью флага `--enclave`.
+
+Kurtosis выведет на экран шаги, которые он выполняет «под капотом» в процессе интерпретации, проверки и последующего выполнения инструкций. В конце вы должны увидеть вывод, похожий на следующий:
+
+```python
+INFO[2023-04-04T18:09:44-04:00] ======================================================
+INFO[2023-04-04T18:09:44-04:00] || Created enclave: local-eth-testnet ||
+INFO[2023-04-04T18:09:44-04:00] ======================================================
+Name: local-eth-testnet
+UUID: 39372d756ae8
+Status: RUNNING
+Creation Time: Tue, 04 Apr 2023 18:09:03 EDT
+
+========================================= Files Artifacts =========================================
+UUID Name
+d4085a064230 cl-genesis-data
+1c62cb792e4c el-genesis-data
+bd60489b73a7 genesis-generation-config-cl
+b2e593fe5228 genesis-generation-config-el
+d552a54acf78 geth-prefunded-keys
+5f7e661eb838 prysm-password
+054e7338bb59 validator-keystore-0
+
+========================================== User Services ==========================================
+UUID Name Ports Status
+e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> RUNNING
+ metrics: 5054/tcp ->
+ tcp-discovery: 9000/tcp -> 127.0.0.1:54263
+ udp-discovery: 9000/udp -> 127.0.0.1:60470
+a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING
+ metrics: 5064/tcp ->
+d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING
+ rpc: 8545/tcp -> 127.0.0.1:54251
+ tcp-discovery: 30303/tcp -> 127.0.0.1:54254
+ udp-discovery: 30303/udp -> 127.0.0.1:53834
+ ws: 8546/tcp -> 127.0.0.1:54252
+514a829c0a84 prelaunch-data-generator-1680646157905431468 STOPPED
+62bd62d0aa7a prelaunch-data-generator-1680646157915424301 STOPPED
+05e9619e0e90 prelaunch-data-generator-1680646157922872635 STOPPED
+
+```
+
+Поздравляем! Вы использовали Kurtosis для создания локальной тестовой сети Ethereum с клиентом CL (`lighthouse`) и клиентом EL (`geth`) через Docker.
+
+### Обзор {#review-instantiate-testnet}
+
+В этом разделе вы выполнили команду, которая указала Kurtosis использовать [`eth-network-package`, размещенный удаленно на GitHub](https://github.com/kurtosis-tech/eth-network-package), для запуска локальной тестовой сети Ethereum в Kurtosis [Enclave](https://docs.kurtosis.com/advanced-concepts/enclaves/). Внутри вашего анклава вы найдете как «файловые артефакты», так и «пользовательские службы».
+
+[Файловые артефакты](https://docs.kurtosis.com/advanced-concepts/files-artifacts/) в вашем анклаве включают все данные, сгенерированные и используемые для начальной загрузки клиентов EL и CL. Данные были созданы с помощью службы `prelaunch-data-generator`, созданной на основе этого [образа Docker](https://github.com/ethpandaops/ethereum-genesis-generator).
+
+Пользовательские службы отображают все контейнеризированные службы, работающие в вашем анклаве. Вы заметите, что был создан один узел, включающий как клиент EL, так и клиент CL.
+
+## Подключите среду разработки децентрализованного приложения к локальной тестовой сети Ethereum {#connect-your-dapp}
+
+### Настройка среды разработки децентрализованного приложения {#set-up-dapp-env}
+
+Теперь, когда у вас есть запущенная локальная тестовая сеть, вы можете подключить свою среду разработки децентрализованного приложения для использования локальной тестовой сети. Фреймворк Hardhat будет использоваться в этом руководстве для развертывания децентрализованного приложения для игры в блэкджек в вашей локальной тестовой сети.
+
+Чтобы настроить среду разработки децентрализованного приложения, клонируйте репозиторий, содержащий наше примерное децентрализованное приложение, и установите его зависимости, выполнив команду:
+
+```python
+git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn
+```
+
+Папка [smart-contract-example](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example), используемая здесь, содержит типичную настройку для разработчика децентрализованного приложения, использующего фреймворк [Hardhat](https://hardhat.org/):
+
+- [`contracts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/contracts) содержит несколько простых смарт-контрактов для децентрализованного приложения Blackjack
+- [`scripts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/scripts) содержит скрипт для развертывания контракта токена в вашей локальной сети Ethereum
+- [`test/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/test) содержит простой тест на .js для вашего контракта токена, чтобы подтвердить, что для каждого игрока в нашем децентрализованном приложении Blackjack отчеканено 1000 фишек
+- [`hardhat.config.ts`](https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/smart-contract-example/hardhat.config.ts) настраивает вашу установку Hardhat
+
+### Настройка Hardhat для использования локальной тестовой сети {#configure-hardhat}
+
+После настройки среды разработки децентрализованного приложения вы подключите Hardhat для использования локальной тестовой сети Ethereum, созданной с помощью Kurtosis. Для этого замените `<$YOUR_PORT>` в структуре `localnet` в файле конфигурации `hardhat.config.ts` на порт из вывода RPC URI любой службы `el-client-`. В этом примере порт будет `64248`. Ваш порт будет другим.
+
+Пример в `hardhat.config.ts`:
+
+```js
+localnet: {
+url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: ЗАМЕНИТЕ $YOUR_PORT НА ПОРТ URI УЗЛА, ВЫДАННЫЙ ПАКЕТОМ СЕТИ ETH KURTOSIS
+
+// Это приватные ключи, связанные с предварительно пополненными тестовыми аккаунтами, созданными пакетом eth-network-package
+//
+accounts: [
+ "ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2",
+ "48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567",
+ "7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31",
+ "b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35",
+ "df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f",
+ "7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6",
+ ],
+},
+```
+
+После сохранения файла ваша среда разработки децентрализованных приложений Hardhat будет подключена к вашей локальной тестовой сети Ethereum! Вы можете убедиться, что ваша тестовая сеть работает, выполнив команду:
+
+```python
+npx hardhat balances --network localnet
+```
+
+Вывод должен выглядеть примерно так:
+
+```python
+0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000
+0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000
+0xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000
+0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000
+0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000
+0x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000
+```
+
+Это подтверждает, что Hardhat использует вашу локальную тестовую сеть и обнаруживает предварительно пополненные аккаунты, созданные `eth-network-package`.
+
+### Развертывание и тестирование вашего децентрализованного приложения локально {#deploy-and-test-dapp}
+
+Когда среда разработки децентрализованного приложения полностью подключена к локальной тестовой сети Ethereum, вы можете запускать рабочие процессы разработки и тестирования для вашего децентрализованного приложения, используя локальную тестовую сеть.
+
+Чтобы скомпилировать и развернуть смарт-контракт `ChipToken.sol` для локального прототипирования и разработки, выполните:
+
+```python
+npx hardhat compile
+npx hardhat run scripts/deploy.ts --network localnet
+```
+
+Вывод должен выглядеть примерно так:
+
+```python
+ChipToken развернут по адресу: 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d
+```
+
+Теперь попробуйте запустить тест `simple.js` для вашего локального децентрализованного приложения, чтобы подтвердить, что для каждого игрока в нашем децентрализованном приложении Blackjack отчеканено 1000 фишек:
+
+Вывод должен выглядеть примерно так:
+
+```python
+npx hardhat test --network localnet
+```
+
+Вывод должен выглядеть примерно так:
+
+```python
+ChipToken
+ чеканка
+ ✔ должно быть отчеканено 1000 фишек для ИГРОКА ОДИН
+
+ 1 пройден (654 мс)
+```
+
+### Обзор {#review-dapp-workflows}
+
+К этому моменту вы настроили среду разработки децентрализованного приложения, подключили ее к локальной сети Ethereum, созданной Kurtosis, и скомпилировали, развернули и запустили простой тест для вашего децентрализованного приложения.
+
+Теперь давайте рассмотрим, как можно настроить базовую сеть для тестирования наших децентрализованных приложений в различных конфигурациях сети.
+
+## Настройка локальной тестовой сети Ethereum {#configure-testnet}
+
+### Изменение конфигураций клиентов и количества узлов {#configure-client-config-and-num-nodes}
+
+Ваша локальная тестовая сеть Ethereum может быть настроена для использования различных пар клиентов EL и CL, а также различного количества узлов, в зависимости от сценария и конкретной конфигурации сети, которую вы хотите разработать или протестировать. Это означает, что после настройки вы можете запустить настраиваемую локальную тестовую сеть и использовать ее для выполнения тех же рабочих процессов (развертывание, тесты и т. д.) в различных конфигурациях сети, чтобы убедиться, что все работает так, как ожидалось. Чтобы узнать больше о других параметрах, которые вы можете изменить, перейдите по этой ссылке.
+
+Попробуйте! Вы можете передавать различные параметры конфигурации в `eth-network-package` через JSON-файл. Этот JSON-файл с параметрами сети предоставляет конкретные конфигурации, которые Kurtosis будет использовать для настройки локальной сети Ethereum.
+
+Возьмите файл конфигурации по умолчанию и отредактируйте его, чтобы запустить три узла с разными парами EL/CL:
+
+- Узел 1 с `geth`/`lighthouse`
+- Узел 2 с `geth`/`lodestar`
+- Узел 3 с `geth`/`teku`
+
+Эта конфигурация создает гетерогенную сеть реализаций узлов Ethereum для тестирования вашего децентрализованного приложения. Ваш файл конфигурации теперь должен выглядеть так:
+
+```yaml
+{
+ "participants":
+ [
+ {
+ "el_client_type": "geth",
+ "el_client_image": "",
+ "el_client_log_level": "",
+ "cl_client_type": "lighthouse",
+ "cl_client_image": "",
+ "cl_client_log_level": "",
+ "beacon_extra_params": [],
+ "el_extra_params": [],
+ "validator_extra_params": [],
+ "builder_network_params": null,
+ },
+ {
+ "el_client_type": "geth",
+ "el_client_image": "",
+ "el_client_log_level": "",
+ "cl_client_type": "lodestar",
+ "cl_client_image": "",
+ "cl_client_log_level": "",
+ "beacon_extra_params": [],
+ "el_extra_params": [],
+ "validator_extra_params": [],
+ "builder_network_params": null,
+ },
+ {
+ "el_client_type": "geth",
+ "el_client_image": "",
+ "el_client_log_level": "",
+ "cl_client_type": "teku",
+ "cl_client_image": "",
+ "cl_client_log_level": "",
+ "beacon_extra_params": [],
+ "el_extra_params": [],
+ "validator_extra_params": [],
+ "builder_network_params": null,
+ },
+ ],
+ "network_params":
+ {
+ "preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete",
+ "num_validator_keys_per_node": 64,
+ "network_id": "3151908",
+ "deposit_contract_address": "0x4242424242424242424242424242424242424242",
+ "seconds_per_slot": 12,
+ "genesis_delay": 120,
+ "capella_fork_epoch": 5,
+ },
+}
+```
+
+Каждая структура `participants` сопоставляется с узлом в сети, поэтому 3 структуры `participants` сообщат Kurtosis о запуске 3 узлов в вашей сети. Каждая структура `participants` позволит вам указать пару EL и CL, используемую для этого конкретного узла.
+
+Структура `network_params` настраивает параметры сети, которые используются для создания файлов генезиса для каждого узла, а также другие настройки, такие как количество секунд на слот в сети.
+
+Сохраните отредактированный файл параметров в любом каталоге (в примере ниже он сохранен на рабочем столе), а затем используйте его для запуска пакета Kurtosis, выполнив:
+
+```python
+kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)"
+```
+
+Примечание: команда `kurtosis clean -a` используется здесь, чтобы указать Kurtosis уничтожить старую тестовую сеть и ее содержимое перед запуском новой.
+
+Опять же, Kurtosis будет некоторое время работать и выводить на печать отдельные шаги, которые выполняются. В конечном итоге вывод должен выглядеть примерно так:
+
+```python
+Starlark code successfully run. No output was returned.
+INFO[2023-04-07T11:43:16-04:00] ==========================================================
+INFO[2023-04-07T11:43:16-04:00] || Created enclave: local-eth-testnet ||
+INFO[2023-04-07T11:43:16-04:00] ==========================================================
+Name: local-eth-testnet
+UUID: bef8c192008e
+Status: RUNNING
+Creation Time: Fri, 07 Apr 2023 11:41:58 EDT
+
+========================================= Files Artifacts =========================================
+UUID Name
+cc495a8e364a cl-genesis-data
+7033fcdb5471 el-genesis-data
+a3aef43fc738 genesis-generation-config-cl
+8e968005fc9d genesis-generation-config-el
+3182cca9d3cd geth-prefunded-keys
+8421166e234f prysm-password
+d9e6e8d44d99 validator-keystore-0
+23f5ba517394 validator-keystore-1
+4d28dea40b5c validator-keystore-2
+
+========================================== User Services ==========================================
+UUID Name Ports Status
+485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING
+ metrics: 5054/tcp -> http://127.0.0.1:65011
+ tcp-discovery: 9000/tcp -> 127.0.0.1:65012
+ udp-discovery: 9000/udp -> 127.0.0.1:54455
+73739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING
+ metrics: 5064/tcp -> http://127.0.0.1:65017
+1b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING
+ metrics: 8008/tcp -> 127.0.0.1:65023
+ tcp-discovery: 9000/tcp -> 127.0.0.1:65024
+ udp-discovery: 9000/udp -> 127.0.0.1:56031
+ validator-metrics: 5064/tcp -> 127.0.0.1:65022
+949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING
+ metrics: 8008/tcp -> 127.0.0.1:65030
+ tcp-discovery: 9000/tcp -> 127.0.0.1:65031
+ udp-discovery: 9000/udp -> 127.0.0.1:60784
+ validator-metrics: 5064/tcp -> 127.0.0.1:65029
+c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING
+ metrics: 8008/tcp -> 127.0.0.1:65035
+ tcp-discovery: 9000/tcp -> 127.0.0.1:65036
+ udp-discovery: 9000/udp -> 127.0.0.1:63581
+e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING
+ rpc: 8545/tcp -> 127.0.0.1:64988
+ tcp-discovery: 30303/tcp -> 127.0.0.1:64987
+ udp-discovery: 30303/udp -> 127.0.0.1:55706
+ ws: 8546/tcp -> 127.0.0.1:64989
+e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING
+ rpc: 8545/tcp -> 127.0.0.1:64995
+ tcp-discovery: 30303/tcp -> 127.0.0.1:64994
+ udp-discovery: 30303/udp -> 127.0.0.1:58096
+ ws: 8546/tcp -> 127.0.0.1:64996
+ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING
+ rpc: 8545/tcp -> 127.0.0.1:65001
+ tcp-discovery: 30303/tcp -> 127.0.0.1:65000
+ udp-discovery: 30303/udp -> 127.0.0.1:57269
+ ws: 8546/tcp -> 127.0.0.1:65002
+12d04a9dbb69 prelaunch-data-generator-1680882122181135513 STOPPED
+5b45f9c0504b prelaunch-data-generator-1680882122192182847 STOPPED
+3d4aaa75e218 prelaunch-data-generator-1680882122201668972 STOPPED
+```
+
+Поздравляем! Вы успешно настроили свою локальную тестовую сеть, чтобы в ней было 3 узла вместо 1. Чтобы запустить те же рабочие процессы, что и раньше, для вашего децентрализованного приложения (развертывание и тестирование), выполните те же операции, что и раньше, заменив `<$YOUR_PORT>` в структуре `localnet` в вашем файле конфигурации `hardhat.config.ts` на порт из вывода RPC URI любой службы `el-client-` в вашей новой 3-узловой локальной тестовой сети.
+
+## Заключение {#conclusion}
+
+Вот и все! Подводя итоги этого краткого руководства, вы:
+
+- Создали локальную тестовую сеть Ethereum через Docker с помощью Kurtosis
+- Подключили свою локальную среду разработки децентрализованных приложений к локальной сети Ethereum
+- Развернули децентрализованное приложение и запустили для него простой тест в локальной сети Ethereum
+- Настроили базовую сеть Ethereum на 3 узла
+
+Мы будем рады услышать от вас о том, что у вас получилось, что можно улучшить, или ответить на любые ваши вопросы. Не стесняйтесь обращаться к нам через [GitHub](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) или [пишите нам по электронной почте](mailto:feedback@kurtosistech.com)!
+
+### Другие примеры и руководства {#other-examples-guides}
+
+Мы рекомендуем вам ознакомиться с нашим [кратким руководством](https://docs.kurtosis.com/quickstart) и другими примерами в нашем [репозитории awesome-kurtosis](https://github.com/kurtosis-tech/awesome-kurtosis), где вы найдете несколько отличных примеров, включая пакеты для:
+
+- Запуск той же локальной тестовой сети Ethereum, но с подключением дополнительных служб, таких как спамер транзакций (для имитации транзакций), монитор форков и подключенные экземпляры Grafana и Prometheus
+- Проведение [теста подсети](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/ethereum-network-partition-test) в той же локальной сети Ethereum
diff --git a/public/content/translations/ru/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/ru/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md
new file mode 100644
index 00000000000..bf040300210
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md
@@ -0,0 +1,144 @@
+---
+title: "Уменьшение размера контрактов для борьбы с ограничением их размера"
+description: "Что можно сделать, чтобы ваши смарт-контракты не становились слишком большими?"
+author: Markus Waas
+lang: ru
+tags: [ "Solidity", "Умные контракты", "хранилище" ]
+skill: intermediate
+published: 2020-06-26
+source: soliditydeveloper.com
+sourceUrl: https://soliditydeveloper.com/max-contract-size
+---
+
+## Почему существует ограничение? {#why-is-there-a-limit}
+
+22 ноября 2016 г. в хардфорке [Spurious Dragon](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) было введено [EIP-170](https://eips.ethereum.org/EIPS/eip-170), которое добавило ограничение на размер смарт-контракта в 24,576 кб. Для вас как для разработчика на Solidity это означает, что по мере добавления все большей функциональности в ваш контракт в какой-то момент вы достигнете предела и при развертывании увидите ошибку:
+
+`Предупреждение: Размер кода контракта превышает 24576 байт (ограничение, введенное в Spurious Dragon).` Этот контракт может оказаться невозможно развернуть в основной сети. `Рассмотрите возможность включения оптимизатора (с низким значением \"runs\"!), отключения строк отката или использования библиотек.`
+
+Это ограничение было введено для предотвращения атак типа «отказ в обслуживании» (DoS-атак). Любой вызов контракта относительно дешев с точки зрения затрат газа. Однако влияние вызова контракта на узлы Ethereum непропорционально возрастает в зависимости от размера кода вызываемого контракта (чтение кода с диска, предварительная обработка кода, добавление данных в доказательство Меркла). Всякий раз, когда возникает ситуация, в которой атакующему требуется мало ресурсов, чтобы заставить других проделать большую работу, появляется возможность для DoS-атак.
+
+Изначально это было не такой большой проблемой, потому что одним из естественных ограничений размера контракта является лимит газа блока. Очевидно, что контракт должен быть развернут в рамках транзакции, которая содержит весь байткод контракта. Если вы включите в блок только эту одну транзакцию, вы можете использовать весь газ, но он не бесконечен. После [обновления London](/ethereum-forks/#london) лимит газа блока может варьироваться от 15 до 30 млн единиц в зависимости от загруженности сети.
+
+Далее мы рассмотрим некоторые методы, упорядоченные по их потенциальному влиянию. Думайте об этом как о похудении. Лучшая стратегия для достижения целевого веса (в нашем случае 24 кб) — это сначала сосредоточиться на методах с наибольшим влиянием. В большинстве случаев для достижения цели достаточно просто изменить свой рацион, но иногда требуется нечто большее. Затем вы можете добавить некоторые упражнения (среднее влияние) или даже пищевые добавки (небольшое влияние).
+
+## Значительное влияние {#big-impact}
+
+### Разделяйте свои контракты {#separate-your-contracts}
+
+Это всегда должно быть вашим первым шагом. Как можно разделить контракт на несколько меньших? Как правило, это заставляет вас разработать хорошую архитектуру для ваших контрактов. С точки зрения читаемости кода всегда предпочтительнее использовать контракты меньшего размера. Чтобы разделить контракты, задайте себе следующие вопросы:
+
+- Какие функции логически связаны? Каждый набор функций лучше всего разместить в отдельном контракте.
+- Какие функции не требуют чтения состояния контракта или требуют лишь определенного подмножества состояния?
+- Можно ли разделить хранилище и функциональность?
+
+### Библиотеки {#libraries}
+
+Один из простых способов отделить код функциональности от хранилища — использовать [библиотеку](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries). Не объявляйте функции библиотеки как internal, так как они будут [добавлены в контракт](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) напрямую во время компиляции. Но если вы используете функции public, то они фактически будут находиться в отдельном контракте библиотеки. Рассмотрите возможность использования [using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for), чтобы сделать использование библиотек более удобным.
+
+### Прокси-контракты {#proxies}
+
+Более продвинутой стратегией является система прокси-контрактов. Библиотеки используют `DELEGATECALL` «под капотом», что просто выполняет функцию другого контракта с состоянием вызывающего контракта. Прочтите [эту статью в блоге](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2), чтобы узнать больше о системах прокси-контрактов. Они предоставляют вам больше функциональности, например, они обеспечивают возможность обновления, но они также добавляют много сложности. Я бы не стал добавлять их только для уменьшения размера контракта, если по какой-либо причине это не является вашим единственным вариантом.
+
+## Среднее влияние {#medium-impact}
+
+### Удаление функций {#remove-functions}
+
+Это должно быть очевидно. Функции довольно сильно увеличивают размер контракта.
+
+- **External**: Часто мы добавляем много функций `view` для удобства. Это совершенно нормально, пока вы не достигнете предела размера. Тогда вам, возможно, стоит подумать об удалении всех функций, кроме абсолютно необходимых.
+- **Internal**: Вы также можете удалить функции `internal`/`private` и просто встроить код, если функция вызывается только один раз.
+
+### Избегайте дополнительных переменных {#avoid-additional-variables}
+
+```solidity
+function get(uint id) returns (address,address) {
+ MyStruct memory myStruct = myStructs[id];
+ return (myStruct.addr1, myStruct.addr2);
+}
+```
+
+```solidity
+function get(uint id) returns (address,address) {
+ return (myStructs[id].addr1, myStructs[id].addr2);
+}
+```
+
+Такое простое изменение дает разницу в **0,28 кб**. Скорее всего, вы сможете найти много подобных ситуаций в ваших контрактах, и в сумме они могут дать значительную экономию.
+
+### Сократите сообщения об ошибках {#shorten-error-message}
+
+Длинные сообщения отката и, в частности, множество различных сообщений отката могут раздувать контракт. Вместо этого используйте короткие коды ошибок и декодируйте их в своем клиенте. Длинное сообщение может стать намного короче:
+
+```solidity
+require(msg.sender == owner, \"Только владелец этого контракта может вызывать эту функцию\");
+```
+
+```solidity
+require(msg.sender == owner, \"OW1\");
+```
+
+### Используйте пользовательские ошибки вместо сообщений об ошибках
+
+Пользовательские ошибки были введены в [Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/). Это отличный способ уменьшить размер ваших контрактов, потому что они кодируются в ABI как селекторы (так же, как и функции).
+
+```solidity
+error Unauthorized();
+
+if (msg.sender != owner) {
+ revert Unauthorized();
+}
+```
+
+### Рассмотрите возможность использования низкого значения runs в оптимизаторе {#consider-a-low-run-value-in-the-optimizer}
+
+Вы также можете изменить настройки оптимизатора. Значение по умолчанию, равное 200, означает, что он пытается оптимизировать байткод так, как если бы функция вызывалась 200 раз. Если вы измените его на 1, вы, по сути, даете команду оптимизатору оптимизировать код для случая, когда каждая функция выполняется только один раз. Оптимизированная для однократного выполнения функция означает, что она оптимизирована для самого развертывания. Имейте в виду, что **это увеличивает [стоимость газа](/developers/docs/gas/) за выполнение функций**, поэтому, возможно, вы не захотите этого делать.
+
+## Небольшое влияние {#small-impact}
+
+### Избегайте передачи структур в функции {#avoid-passing-structs-to-functions}
+
+Если вы используете [ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2), может помочь отказ от передачи структур в функции. Вместо того чтобы передавать параметр в виде структуры, передавайте необходимые параметры напрямую. В этом примере мы сэкономили еще **0,1 кб**.
+
+```solidity
+function get(uint id) returns (address,address) {
+ return _get(myStruct);
+}
+
+function _get(MyStruct memory myStruct) private view returns(address,address) {
+ return (myStruct.addr1, myStruct.addr2);
+}
+```
+
+```solidity
+function get(uint id) returns(address,address) {
+ return _get(myStructs[id].addr1, myStructs[id].addr2);
+}
+
+function _get(address addr1, address addr2) private view returns(address,address) {
+ return (addr1, addr2);
+}
+```
+
+### Объявляйте правильную область видимости для функций и переменных {#declare-correct-visibility-for-functions-and-variables}
+
+- Функции или переменные, которые вызываются только извне? Объявляйте их как `external`, а не `public`.
+- Функции или переменные, вызываемые только из самого контракта? Объявляйте их как `private` или `internal` вместо `public`.
+
+### Удаление модификаторов {#remove-modifiers}
+
+Модификаторы, особенно при интенсивном использовании, могут оказывать значительное влияние на размер контракта. Рассмотрите возможность их удаления и использования вместо них функций.
+
+```solidity
+modifier checkStuff() {}
+
+function doSomething() checkStuff {}
+```
+
+```solidity
+function checkStuff() private {}
+
+function doSomething() { checkStuff(); }
+```
+
+Эти советы должны помочь вам значительно уменьшить размер контракта. Еще раз, не могу не подчеркнуть: всегда стремитесь к разделению контрактов, если это возможно, для достижения наибольшего эффекта.
diff --git a/public/content/translations/ru/developers/tutorials/eip-1271-smart-contract-signatures/index.md b/public/content/translations/ru/developers/tutorials/eip-1271-smart-contract-signatures/index.md
new file mode 100644
index 00000000000..89e880e30d8
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/eip-1271-smart-contract-signatures/index.md
@@ -0,0 +1,129 @@
+---
+title: "EIP-1271: Подписание и проверка подписей умных контрактов"
+description: "Обзор создания и проверки подписей умных контрактов с использованием EIP-1271. Мы также рассмотрим реализацию EIP-1271, используемую в Safe (ранее Gnosis Safe), чтобы предоставить конкретный пример для разработчиков умных контрактов, на который они могут опереться."
+author: Nathan H. Leung
+lang: ru
+tags:
+ [
+ "eip-1271",
+ "смарт-контракты",
+ "проверка",
+ "подписание"
+ ]
+skill: intermediate
+published: 2023-01-12
+---
+
+Стандарт [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) позволяет умным контрактам проверять подписи.
+
+В этом руководстве мы даем обзор цифровых подписей, предыстории EIP-1271 и конкретной реализации EIP-1271, используемой [Safe](https://safe.global/) (ранее Gnosis Safe). В совокупности это может послужить отправной точкой для реализации EIP-1271 в ваших собственных контрактах.
+
+## Что такое подпись?
+
+В данном контексте подпись (точнее, «цифровая подпись») — это сообщение плюс некое доказательство того, что сообщение пришло от определенного человека/отправителя/адреса.
+
+Например, цифровая подпись может выглядеть так:
+
+1. Сообщение: «Я хочу войти на этот сайт с помощью своего кошелька Ethereum».
+2. Подписавший: Мой адрес `0x000…`
+3. Доказательство: Вот доказательство того, что я, `0x000…`, действительно создал все это сообщение (обычно это нечто криптографическое).
+
+Важно отметить, что цифровая подпись включает в себя и «сообщение», и «подпись».
+
+Почему? Например, если бы вы дали мне на подпись контракт, а я бы отрезал страницу с подписью и вернул вам только свои подписи без остальной части контракта, контракт не был бы действительным.
+
+Точно так же цифровая подпись ничего не значит без связанного с ней сообщения!
+
+## Почему существует EIP-1271?
+
+Чтобы создать цифровую подпись для использования в блокчейнах на базе Ethereum, вам обычно нужен секретный приватный ключ, который никто больше не знает. Это то, что делает вашу подпись вашей (никто другой не может создать такую же подпись, не зная секретного ключа).
+
+Ваш аккаунт Ethereum (т. е. ваш аккаунт во внешнем владении / EOA) имеет связанный с ним приватный ключ, и это тот приватный ключ, который обычно используется, когда веб-сайт или децентрализованное приложение запрашивает у вас подпись (например, для «Входа с помощью Ethereum»).
+
+Приложение может [проверить подпись](https://www.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum), которую вы создали, с помощью сторонней библиотеки, такой как ethers.js, [не зная вашего приватного ключа](https://en.wikipedia.org/wiki/Public-key_cryptography) и быть уверенным, что именно _вы_ создали подпись.
+
+> На самом деле, поскольку цифровые подписи EOA используют криптографию с открытым ключом, их можно генерировать и проверять **офчейн**! Именно так работает безгазовое голосование в DAO — вместо того, чтобы отправлять голоса ончейн, цифровые подписи могут создаваться и проверяться офчейн с помощью криптографических библиотек.
+
+В то время как аккаунты EOA имеют приватный ключ, аккаунты умных контрактов не имеют никакого приватного или секретного ключа (поэтому «Вход с помощью Ethereum» и т. п. не может нативно работать с аккаунтами умных контрактов).
+
+Проблема, которую призван решить EIP-1271: как мы можем определить, что подпись умного контракта действительна, если у умного контракта нет «секрета», который он может включить в подпись?
+
+## Как работает EIP-1271?
+
+Умные контракты не имеют приватных ключей, которые можно использовать для подписи сообщений. Так как же мы можем определить, является ли подпись подлинной?
+
+Что ж, одна из идей заключается в том, что мы можем просто _спросить_ у умного контракта, является ли подпись подлинной!
+
+EIP-1271 стандартизирует идею «запроса» у умного контракта о действительности данной подписи.
+
+Контракт, реализующий EIP-1271, должен иметь функцию `isValidSignature`, которая принимает сообщение и подпись. Затем контракт может запустить некоторую логику проверки (спецификация не предписывает здесь ничего конкретного) и вернуть значение, указывающее, действительна ли подпись.
+
+Если `isValidSignature` возвращает действительный результат, это практически означает, что контракт говорит: «да, я одобряю эту подпись + сообщение!»
+
+### Интерфейс
+
+Вот точный интерфейс в спецификации EIP-1271 (мы поговорим о параметре `_hash` ниже, но пока думайте о нем как о проверяемом сообщении):
+
+```jsx
+pragma solidity ^0.5.0;
+
+contract ERC1271 {
+
+ // bytes4(keccak256("isValidSignature(bytes32,bytes)")
+ bytes4 constant internal MAGICVALUE = 0x1626ba7e;
+
+ /**
+ * @dev Должна возвращать, является ли предоставленная подпись действительной для предоставленного хэша
+ * @param _hash Хэш данных для подписи
+ * @param _signature Массив байтов подписи, связанный с _hash
+ *
+ * ДОЛЖНА возвращать магическое значение bytes4 0x1626ba7e при успешном выполнении функции.
+ * НЕ ДОЛЖНА изменять состояние (с использованием STATICCALL для solc < 0.5, модификатора view для solc > 0.5)
+ * ДОЛЖНА разрешать внешние вызовы
+ */
+ function isValidSignature(
+ bytes32 _hash,
+ bytes memory _signature)
+ public
+ view
+ returns (bytes4 magicValue);
+}
+```
+
+## Пример реализации EIP-1271: Safe
+
+Контракты могут реализовывать `isValidSignature` многими способами — спецификация не говорит много о точной реализации.
+
+Одним из примечательных контрактов, реализующих EIP-1271, является Safe (ранее Gnosis Safe).
+
+В коде Safe функция `isValidSignature` [реализована](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) так, что подписи можно создавать и проверять [двумя способами](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support):
+
+1. Ончейн-сообщения
+ 1. Создание: владелец Safe создает новую транзакцию Safe, чтобы «подписать» сообщение, передавая сообщение в качестве данных в транзакцию. Как только достаточное количество владельцев подпишет транзакцию для достижения порога мультиподписи, транзакция транслируется и выполняется. В транзакции есть функция Safe (`signMessage(bytes calldata _data)`), которая добавляет сообщение в список «одобренных» сообщений.
+ 2. Проверка: вызовите `isValidSignature` в контракте Safe и передайте сообщение для проверки в качестве параметра сообщения, а [пустое значение для параметра подписи](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (т. е. `0x`). Safe увидит, что параметр подписи пуст, и вместо криптографической проверки подписи он просто проверит, находится ли сообщение в списке «одобренных» сообщений.
+2. Офчейн-сообщения:
+ 1. Создание: владелец Safe создает сообщение офчейн, затем получает подписи от других владельцев Safe по отдельности, пока не будет достаточно подписей для преодоления порога одобрения мультиподписи.
+ 2. Проверка: вызовите `isValidSignature`. В параметр сообщения передайте сообщение, которое нужно проверить. В параметр подписи передайте все индивидуальные подписи владельцев Safe, объединенные вместе, одна за другой. Safe проверит, что подписей достаточно для достижения порога **и** что каждая подпись действительна. Если это так, он вернет значение, указывающее на успешную проверку подписи.
+
+## Что именно представляет собой параметр `_hash`? Почему бы не передать все сообщение целиком?
+
+Вы могли заметить, что функция `isValidSignature` в [интерфейсе EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) принимает не само сообщение, а параметр `_hash`. Это означает, что вместо передачи полного сообщения произвольной длины в `isValidSignature` мы передаем 32-байтовый хэш сообщения (обычно keccak256).
+
+Каждый байт calldata — т. е. данных параметров функции, передаваемых в функцию умного контракта — [стоит 16 единиц газа (4 единицы газа, если это нулевой байт)](https://eips.ethereum.org/EIPS/eip-2028), так что это может сэкономить много газа, если сообщение длинное.
+
+### Предыдущие спецификации EIP-1271
+
+Существуют спецификации EIP-1271, в которых функция `isValidSignature` имеет первый параметр типа `bytes` (произвольной длины, вместо фиксированной длины `bytes32`) и имя параметра `message`. Это [более старая версия](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) стандарта EIP-1271.
+
+## Как следует реализовывать EIP-1271 в моих собственных контрактах?
+
+Здесь спецификация очень открыта. Реализация Safe содержит несколько хороших идей:
+
+- Вы можете считать подписи EOA от «владельца» контракта действительными.
+- Вы можете хранить список одобренных сообщений и считать действительными только их.
+
+В конце концов, это зависит от вас как от разработчика контракта!
+
+## Заключение
+
+[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) — это универсальный стандарт, который позволяет умным контрактам проверять подписи. Он открывает возможность для умных контрактов действовать больше как EOA — например, предоставляя способ для «Входа с помощью Ethereum» работать с умными контрактами — и может быть реализован многими способами (Safe имеет нетривиальную, интересную реализацию для рассмотрения).
diff --git a/public/content/translations/ru/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/ru/developers/tutorials/erc-721-vyper-annotated-code/index.md
new file mode 100644
index 00000000000..e802e08ed39
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/erc-721-vyper-annotated-code/index.md
@@ -0,0 +1,713 @@
+---
+title: "Пошаговый разбор контракта Vyper ERC-721"
+description: "Контракт ERC-721 от Ryuya Nakamura и принцип его работы"
+author: Ori Pomerantz
+lang: ru
+tags: [ "Vyper", "erc-721", "Python" ]
+skill: beginner
+published: 2021-04-01
+---
+
+## Введение {#introduction}
+
+Стандарт [ERC-721](/developers/docs/standards/tokens/erc-721/) используется для владения невзаимозаменяемыми токенами (NFT).
+Токены [ERC-20](/developers/docs/standards/tokens/erc-20/) ведут себя как товар, так как между отдельными токенами нет разницы.
+В отличие от них, токены ERC-721 предназначены для активов, которые похожи, но не идентичны, например, различные мультяшные
+коты или права собственности на различные объекты недвижимости.
+
+В этой статье мы проанализируем [контракт ERC-721 от Ryuya Nakamura](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy).
+Этот контракт написан на [Vyper](https://vyper.readthedocs.io/en/latest/index.html), языке контрактов, похожем на Python, который разработан таким образом, чтобы
+затруднить написание небезопасного кода по сравнению с Solidity.
+
+## Контракт {#contract}
+
+```python
+# @dev Реализация стандарта невзаимозаменяемых токенов ERC-721.
+# @author Ryuya Nakamura (@nrryuya)
+# Изменено из: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy
+```
+
+Комментарии в Vyper, как и в Python, начинаются с символа решетки (`#`) и продолжаются до конца строки. Комментарии, которые включают
+`@`, используются [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) для создания удобочитаемой
+документации.
+
+```python
+from vyper.interfaces import ERC721
+
+implements: ERC721
+```
+
+Интерфейс ERC-721 встроен в язык Vyper.
+[Определение кода можно посмотреть здесь](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py).
+Определение интерфейса написано на Python, а не на Vyper, потому что интерфейсы используются не только в
+блокчейне, но и при отправке транзакции в блокчейн с внешнего клиента, который может быть написан на
+Python.
+
+Первая строка импортирует интерфейс, а вторая указывает, что мы реализуем его здесь.
+
+### Интерфейс ERC721Receiver {#receiver-interface}
+
+```python
+# Интерфейс для контракта, вызываемого safeTransferFrom()
+interface ERC721Receiver:
+ def onERC721Received(
+```
+
+ERC-721 поддерживает два типа перевода:
+
+- `transferFrom`, который позволяет отправителю указать любой адрес назначения и возлагает ответственность
+ за перевод на отправителя. Это означает, что вы можете перевести средства на недействительный адрес, и в этом случае
+ NFT будет безвозвратно утерян.
+- `safeTransferFrom`, который проверяет, является ли адрес назначения контрактом. Если это так, контракт ERC-721
+ спрашивает у принимающего контракта, хочет ли он получить NFT.
+
+Чтобы отвечать на запросы `safeTransferFrom`, принимающий контракт должен реализовывать `ERC721Receiver`.
+
+```python
+ _operator: address,
+ _from: address,
+```
+
+Адрес `_from` — это текущий владелец токена. Адрес `_operator` — это адрес, который
+запросил перевод (эти два адреса могут не совпадать из-за разрешений).
+
+```python
+ _tokenId: uint256,
+```
+
+Идентификаторы токенов ERC-721 имеют размер 256 бит. Обычно они создаются путем хэширования описания того, что
+представляет собой токен.
+
+```python
+ _data: Bytes[1024]
+```
+
+Запрос может содержать до 1024 байт пользовательских данных.
+
+```python
+ ) -> bytes32: view
+```
+
+Чтобы предотвратить случаи, когда контракт случайно принимает перевод, возвращаемое значение является не логическим,
+а 256-битным значением с определенным содержанием.
+
+Эта функция является `view`, что означает, что она может читать состояние блокчейна, но не изменять его.
+
+### События {#events}
+
+[События](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e)
+создаются для информирования пользователей и серверов за пределами блокчейна о событиях. Обратите внимание, что содержимое событий
+недоступно контрактам в блокчейне.
+
+```python
+# @dev Создается, когда право собственности на любой NFT изменяется любым механизмом. Это событие создается при создании NFT (`from` == 0) и их уничтожении (`to` == 0). Исключение: во время создания контракта любое
+# количество NFT может быть создано и назначено без создания события Transfer. Во время любого
+# перевода одобренный адрес для этого NFT (если он есть) сбрасывается.
+# @param _from Отправитель NFT (если адрес нулевой, это указывает на создание токена).
+# @param _to Получатель NFT (если адрес нулевой, это указывает на уничтожение токена).
+# @param _tokenId Переданный NFT.
+event Transfer:
+ sender: indexed(address)
+ receiver: indexed(address)
+ tokenId: indexed(uint256)
+```
+
+Это похоже на событие Transfer в ERC-20, за исключением того, что мы сообщаем `tokenId` вместо суммы.
+Никто не владеет нулевым адресом, поэтому по соглашению мы используем его для сообщения о создании и уничтожении токенов.
+
+```python
+# @dev Создается, когда одобренный адрес для NFT изменяется или подтверждается. Нулевой
+# адрес указывает на отсутствие одобренного адреса. Когда создается событие Transfer, это также
+# указывает, что одобренный адрес для этого NFT (если таковой имеется) сбрасывается.
+# @param _owner Владелец NFT.
+# @param _approved Адрес, который мы одобряем.
+# @param _tokenId NFT, который мы одобряем.
+event Approval:
+ owner: indexed(address)
+ approved: indexed(address)
+ tokenId: indexed(uint256)
+```
+
+Одобрение в ERC-721 похоже на разрешение в ERC-20. Определенному адресу разрешается переводить определенный
+токен. Это дает контрактам механизм для реагирования, когда они принимают токен. Контракты не могут
+прослушивать события, поэтому, если вы просто переведете им токен, они не \"узнают\" об этом. Таким образом, владелец
+сначала отправляет одобрение, а затем отправляет запрос контракту: \"Я одобрил для вас перевод токена
+X, пожалуйста, сделайте ...\".
+
+Это проектное решение, призванное сделать стандарт ERC-721 похожим на стандарт ERC-20. Поскольку
+токены ERC-721 не являются взаимозаменяемыми, контракт также может определить, что он получил определенный токен,
+проверив право собственности на токен.
+
+```python
+# @dev Это событие создается, когда оператор включается или отключается для владельца. Оператор может управлять
+# всеми NFT владельца.
+# @param _owner Владелец NFT.
+# @param _operator Адрес, которому мы устанавливаем права оператора.
+# @param _approved Статус прав оператора (true, если права оператора предоставлены, и false, если
+# они отозваны).
+event ApprovalForAll:
+ owner: indexed(address)
+ operator: indexed(address)
+ approved: bool
+```
+
+Иногда бывает полезно иметь _оператора_, который может управлять всеми токенами аккаунта определенного типа (теми, которые управляются
+определенным контрактом), подобно доверенности. Например, я могу захотеть предоставить такие полномочия контракту, который проверяет, не
+связывался ли я с ним в течение шести месяцев, и если да, то распределяет мои активы между моими наследниками (если один из них попросит об этом, контракты
+не могут ничего делать без вызова транзакцией). В ERC-20 мы можем просто дать высокое разрешение на контракт наследования,
+но это не работает для ERC-721, потому что токены не являются взаимозаменяемыми. Это эквивалент.
+
+Значение `approved` говорит нам о том, является ли событие одобрением или отзывом одобрения.
+
+### Переменные состояния {#state-vars}
+
+Эти переменные содержат текущее состояние токенов: какие из них доступны и кто ими владеет. Большинство из них
+это объекты `HashMap`, [однонаправленные сопоставления, которые существуют между двумя типами](https://vyper.readthedocs.io/en/latest/types.html#mappings).
+
+```python
+# @dev Сопоставление идентификатора NFT с адресом его владельца.
+idToOwner: HashMap[uint256, address]
+
+# @dev Сопоставление идентификатора NFT с одобренным адресом.
+idToApprovals: HashMap[uint256, address]
+```
+
+Идентификаторы пользователей и контрактов в Ethereum представлены 160-битными адресами. Эти две переменные сопоставляют
+идентификаторы токенов с их владельцами и теми, кто одобрен для их перевода (максимум по одному для каждого). В Ethereum
+неинициализированные данные всегда равны нулю, поэтому, если нет владельца или одобренного отправителя, значение для этого токена
+равно нулю.
+
+```python
+# @dev Сопоставление адреса владельца с количеством его токенов.
+ownerToNFTokenCount: HashMap[address, uint256]
+```
+
+Эта переменная содержит количество токенов для каждого владельца. Сопоставления от владельцев к токенам не существует, поэтому
+единственный способ идентифицировать токены, которыми владеет конкретный владелец, — это просмотреть историю событий блокчейна
+и найти соответствующие события `Transfer`. Мы можем использовать эту переменную, чтобы знать, когда у нас есть все NFT и не
+нужно заглядывать еще дальше во времени.
+
+Обратите внимание, что этот алгоритм работает только для пользовательских интерфейсов и внешних серверов. Код, работающий в блокчейне,
+сам по себе не может читать прошлые события.
+
+```python
+# @dev Сопоставление адреса владельца с сопоставлением адресов операторов.
+ownerToOperators: HashMap[address, HashMap[address, bool]]
+```
+
+У аккаунта может быть несколько операторов. Простого `HashMap` недостаточно, чтобы
+отслеживать их, потому что каждый ключ ведет к одному значению. Вместо этого вы можете использовать
+`HashMap[address, bool]` в качестве значения. По умолчанию значение для каждого адреса — `False`, что означает, что он
+не является оператором. Вы можете установить значения на `True` по мере необходимости.
+
+```python
+# @dev Адрес минтера, который может создавать токен
+minter: address
+```
+
+Новые токены должны как-то создаваться. В этом контракте есть единственная сущность, которой разрешено это делать, —
+`минтер`. Этого, например, скорее всего, будет достаточно для игры. Для других целей может потребоваться
+создать более сложную бизнес-логику.
+
+```python
+# @dev Сопоставление идентификатора интерфейса с логическим значением о том, поддерживается он или нет
+supportedInterfaces: HashMap[bytes32, bool]
+
+# @dev Идентификатор интерфейса ERC165 для ERC165
+ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7
+
+# @dev Идентификатор интерфейса ERC165 для ERC721
+ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd
+```
+
+[ERC-165](https://eips.ethereum.org/EIPS/eip-165) определяет механизм, с помощью которого контракт может раскрывать, как приложения
+могут с ним взаимодействовать, каким стандартам ERC он соответствует. В данном случае контракт соответствует стандартам ERC-165 и ERC-721.
+
+### Функции {#functions}
+
+Это функции, которые фактически реализуют ERC-721.
+
+#### Конструктор {#constructor}
+
+```python
+@external
+def __init__():
+```
+
+В Vyper, как и в Python, функция-конструктор называется `__init__`.
+
+```python
+ """
+ @dev Конструктор контракта.
+ """
+```
+
+В Python и Vyper вы также можете создать комментарий, указав многострочную строку (которая начинается и заканчивается
+`"""`) и никак ее не используя. Эти комментарии также могут включать
+[NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html).
+
+```python
+ self.supportedInterfaces[ERC165_INTERFACE_ID] = True
+ self.supportedInterfaces[ERC721_INTERFACE_ID] = True
+ self.minter = msg.sender
+```
+
+Для доступа к переменным состояния используйте `self.<имя переменной>` (опять же, как и в Python).
+
+#### Функции просмотра {#views}
+
+Это функции, которые не изменяют состояние блокчейна и поэтому могут выполняться
+бесплатно, если вызываются извне. Если функции просмотра вызываются контрактом, они все равно должны выполняться на
+каждом узле и, следовательно, стоят газа.
+
+```python
+@view
+@external
+```
+
+Эти ключевые слова перед определением функции, которые начинаются со знака «собачка» (`@`), называются _декораторами_. Они
+указывают обстоятельства, при которых может быть вызвана функция.
+
+- `@view` указывает, что эта функция является функцией просмотра.
+- `@external` указывает, что данная функция может быть вызвана транзакциями и другими контрактами.
+
+```python
+def supportsInterface(_interfaceID: bytes32) -> bool:
+```
+
+В отличие от Python, Vyper — это [язык со статической типизацией](https://wikipedia.org/wiki/Type_system#Static_type_checking).
+Нельзя объявить переменную или параметр функции, не указав [тип данных](https://vyper.readthedocs.io/en/latest/types.html). В данном случае входной параметр — `bytes32`, 256-битное значение
+(256 бит — это нативный размер слова [виртуальной машины Ethereum](/developers/docs/evm/)). Выходные данные — это логическое
+значение. По соглашению имена параметров функции начинаются с символа подчеркивания (`_`).
+
+```python
+ """
+ @dev Идентификация интерфейса указана в ERC-165.
+ @param _interfaceID Идентификатор интерфейса
+ """
+ return self.supportedInterfaces[_interfaceID]
+```
+
+Возвращает значение из HashMap `self.supportedInterfaces`, которое устанавливается в конструкторе (`__init__`).
+
+```python
+### ФУНКЦИИ ПРОСМОТРА ###
+
+```
+
+Это функции просмотра, которые делают информацию о токенах доступной для пользователей и других контрактов.
+
+```python
+@view
+@external
+def balanceOf(_owner: address) -> uint256:
+ """
+ @dev Возвращает количество NFT, принадлежащих `_owner`.
+ Вызывает исключение, если `_owner` является нулевым адресом. NFT, назначенные нулевому адресу, считаются недействительными.
+ @param _owner Адрес, для которого запрашивается баланс.
+ """
+ assert _owner != ZERO_ADDRESS
+```
+
+Эта строка [проверяет](https://vyper.readthedocs.io/en/latest/statements.html#assert), что `_owner` не
+равен нулю. Если это так, возникает ошибка и операция отменяется.
+
+```python
+ return self.ownerToNFTokenCount[_owner]
+
+@view
+@external
+def ownerOf(_tokenId: uint256) -> address:
+ """
+ @dev Возвращает адрес владельца NFT.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ @param _tokenId Идентификатор для NFT.
+ """
+ owner: address = self.idToOwner[_tokenId]
+ # Вызывает исключение, если `_tokenId` не является действительным NFT
+ assert owner != ZERO_ADDRESS
+ return owner
+```
+
+В виртуальной машине Ethereum (EVM) любое хранилище, в котором не хранится значение, равно нулю.
+Если по адресу `_tokenId` нет токена, то значение `self.idToOwner[_tokenId]` равно нулю. В этом
+случае функция отменяется.
+
+```python
+@view
+@external
+def getApproved(_tokenId: uint256) -> address:
+ """
+ @dev Получает одобренный адрес для одного NFT.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ @param _tokenId Идентификатор NFT для запроса его одобрения.
+ """
+ # Вызывает исключение, если `_tokenId` не является действительным NFT
+ assert self.idToOwner[_tokenId] != ZERO_ADDRESS
+ return self.idToApprovals[_tokenId]
+```
+
+Обратите внимание, что `getApproved` _может_ вернуть ноль. Если токен действителен, он возвращает `self.idToApprovals[_tokenId]`.
+Если нет утверждающего, это значение равно нулю.
+
+```python
+@view
+@external
+def isApprovedForAll(_owner: address, _operator: address) -> bool:
+ """
+ @dev Проверяет, является ли `_operator` одобренным оператором для `_owner`.
+ @param _owner Адрес, которому принадлежат NFT.
+ @param _operator Адрес, который действует от имени владельца.
+ """
+ return (self.ownerToOperators[_owner])[_operator]
+```
+
+Эта функция проверяет, разрешено ли `_operator` управлять всеми токенами `_owner` в этом контракте.
+Поскольку операторов может быть несколько, это двухуровневый HashMap.
+
+#### Вспомогательные функции перевода {#transfer-helpers}
+
+Эти функции реализуют операции, которые являются частью перевода или управления токенами.
+
+```python
+
+### ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ПЕРЕВОДА ###
+
+@view
+@internal
+```
+
+Этот декоратор `@internal` означает, что функция доступна только из других функций в том
+же контракте. По соглашению, имена этих функций также начинаются с символа подчеркивания (`_`).
+
+```python
+def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool:
+ """
+ @dev Возвращает, может ли данный тратящий перевести данный идентификатор токена
+ @param spender адрес тратящего для запроса
+ @param tokenId uint256 ID токена для перевода
+ @return bool, является ли msg.sender одобренным для данного ID токена,
+ является ли оператором владельца, или является владельцем токена
+ """
+ owner: address = self.idToOwner[_tokenId]
+ spenderIsOwner: bool = owner == _spender
+ spenderIsApproved: bool = _spender == self.idToApprovals[_tokenId]
+ spenderIsApprovedForAll: bool = (self.ownerToOperators[owner])[_spender]
+ return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll
+```
+
+Существует три способа, которыми адрес может быть разрешен для перевода токена:
+
+1. Адрес является владельцем токена
+2. Адрес одобрен для расходования этого токена
+3. Адрес является оператором для владельца токена
+
+Вышеупомянутая функция может быть функцией просмотра, поскольку она не изменяет состояние. Чтобы снизить эксплуатационные расходы, любая
+функция, которая _может_ быть функцией просмотра, _должна_ ею быть.
+
+```python
+@internal
+def _addTokenTo(_to: address, _tokenId: uint256):
+ """
+ @dev Добавляет NFT на данный адрес
+ Вызывает исключение, если `_tokenId` принадлежит кому-то.
+ """
+ # Вызывает исключение, если `_tokenId` принадлежит кому-то
+ assert self.idToOwner[_tokenId] == ZERO_ADDRESS
+ # Изменение владельца
+ self.idToOwner[_tokenId] = _to
+ # Изменение отслеживания количества
+ self.ownerToNFTokenCount[_to] += 1
+
+
+@internal
+def _removeTokenFrom(_from: address, _tokenId: uint256):
+ """
+ @dev Удаляет NFT с данного адреса
+ Вызывает исключение, если `_from` не является текущим владельцем.
+ """
+ # Вызывает исключение, если `_from` не является текущим владельцем
+ assert self.idToOwner[_tokenId] == _from
+ # Изменение владельца
+ self.idToOwner[_tokenId] = ZERO_ADDRESS
+ # Изменение отслеживания количества
+ self.ownerToNFTokenCount[_from] -= 1
+```
+
+Когда возникает проблема с переводом, мы отменяем вызов.
+
+```python
+@internal
+def _clearApproval(_owner: address, _tokenId: uint256):
+ """
+ @dev Очищает одобрение для данного адреса
+ Вызывает исключение, если `_owner` не является текущим владельцем.
+ """
+ # Вызывает исключение, если `_owner` не является текущим владельцем
+ assert self.idToOwner[_tokenId] == _owner
+ if self.idToApprovals[_tokenId] != ZERO_ADDRESS:
+ # Сброс одобрений
+ self.idToApprovals[_tokenId] = ZERO_ADDRESS
+```
+
+Изменяйте значение только при необходимости. Переменные состояния находятся в хранилище. Запись в хранилище —
+одна из самых дорогих операций, которые выполняет EVM (виртуальная машина Ethereum) (с точки зрения
+[газа](/developers/docs/gas/)). Поэтому хорошей идеей является ее минимизация, даже запись
+существующего значения имеет высокую стоимость.
+
+```python
+@internal
+def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address):
+ """
+ @dev Выполнение перевода NFT.
+ Вызывает исключение, если `msg.sender` не является текущим владельцем, авторизованным оператором или одобренным
+ адресом для этого NFT. (ПРИМЕЧАНИЕ: `msg.sender` не разрешен в приватной функции, поэтому передайте `_sender`.)
+ Вызывает исключение, если `_to` является нулевым адресом.
+ Вызывает исключение, если `_from` не является текущим владельцем.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ """
+```
+
+У нас есть эта внутренняя функция, потому что существует два способа перевода токенов (обычный и безопасный), но
+мы хотим, чтобы это делалось только в одном месте кода, чтобы облегчить аудит.
+
+```python
+ # Проверка требований
+ assert self._isApprovedOrOwner(_sender, _tokenId)
+ # Вызывает исключение, если `_to` является нулевым адресом
+ assert _to != ZERO_ADDRESS
+ # Очистка одобрения. Вызывает исключение, если `_from` не является текущим владельцем
+ self._clearApproval(_from, _tokenId)
+ # Удаление NFT. Вызывает исключение, если `_tokenId` не является действительным NFT
+ self._removeTokenFrom(_from, _tokenId)
+ # Добавление NFT
+ self._addTokenTo(_to, _tokenId)
+ # Логирование перевода
+ log Transfer(_from, _to, _tokenId)
+```
+
+Чтобы сгенерировать событие в Vyper, используется оператор `log` ([подробнее см. здесь](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)).
+
+#### Функции перевода {#transfer-funs}
+
+```python
+
+### ФУНКЦИИ ПЕРЕВОДА ###
+
+@external
+def transferFrom(_from: address, _to: address, _tokenId: uint256):
+ """
+ @dev Вызывает исключение, если `msg.sender` не является текущим владельцем, авторизованным оператором или одобренным
+ адресом для этого NFT.
+ Вызывает исключение, если `_from` не является текущим владельцем.
+ Вызывает исключение, если `_to` является нулевым адресом.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ @notice Вызывающий несет ответственность за подтверждение того, что `_to` способен получать NFT, иначе
+ они могут быть навсегда потеряны.
+ @param _from Текущий владелец NFT.
+ @param _to Новый владелец.
+ @param _tokenId NFT для перевода.
+ """
+ self._transferFrom(_from, _to, _tokenId, msg.sender)
+```
+
+Эта функция позволяет выполнять перевод на произвольный адрес. Если адрес не является адресом пользователя или контракта, который
+знает, как переводить токены, любой переведенный вами токен застрянет на этом адресе и станет бесполезным.
+
+```python
+@external
+def safeTransferFrom(
+ _from: address,
+ _to: address,
+ _tokenId: uint256,
+ _data: Bytes[1024]=b""
+ ):
+ """
+ @dev Передает право собственности на NFT с одного адреса на другой.
+ Вызывает исключение, если `msg.sender` не является текущим владельцем, авторизованным оператором или
+ одобренным адресом для этого NFT.
+ Вызывает исключение, если `_from` не является текущим владельцем.
+ Вызывает исключение, если `_to` — нулевой адрес.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ Если `_to` — это смарт-контракт, он вызывает `onERC721Received` для `_to` и вызывает исключение, если
+ возвращаемое значение не равно `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
+ ПРИМЕЧАНИЕ: bytes4 представлен как bytes32 с дополнением
+ @param _from Текущий владелец NFT.
+ @param _to Новый владелец.
+ @param _tokenId NFT для перевода.
+ @param _data Дополнительные данные без определенного формата, отправляемые при вызове `_to`.
+ """
+ self._transferFrom(_from, _to, _tokenId, msg.sender)
+```
+
+Можно сначала выполнить перевод, потому что если возникнет проблема, мы все равно отменим операцию,
+так что все, что было сделано в вызове, будет отменено.
+
+```python
+ if _to.is_contract: # проверяем, является ли `_to` адресом контракта
+```
+
+Сначала проверьте, является ли адрес контрактом (есть ли у него код). Если нет, предположим, что это адрес пользователя,
+и пользователь сможет использовать токен или перевести его. Но не позволяйте этому усыпить вашу
+бдительность. Вы можете потерять токены, даже с `safeTransferFrom`, если переведете
+их на адрес, для которого никто не знает приватный ключ.
+
+```python
+ returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data)
+```
+
+Вызовите целевой контракт, чтобы узнать, может ли он получать токены ERC-721.
+
+```python
+ # Вызывает исключение, если получатель перевода — это контракт, который не реализует 'onERC721Received'
+ assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32)
+```
+
+Если получатель — это контракт, но он не принимает токены ERC-721 (или решил не принимать этот
+конкретный перевод), отмените операцию.
+
+```python
+@external
+def approve(_approved: address, _tokenId: uint256):
+ """
+ @dev Устанавливает или подтверждает одобренный адрес для NFT. Нулевой адрес указывает на отсутствие одобренного адреса.
+ Вызывает исключение, если `msg.sender` не является текущим владельцем NFT или авторизованным оператором текущего владельца.
+ Вызывает исключение, если `_tokenId` не является действительным NFT. (ПРИМЕЧАНИЕ: этого нет в EIP)
+ Вызывает исключение, если `_approved` является текущим владельцем. (ПРИМЕЧАНИЕ: этого нет в EIP)
+ @param _approved Адрес, который должен быть одобрен для данного идентификатора NFT.
+ @param _tokenId Идентификатор токена, который должен быть одобрен.
+ """
+ owner: address = self.idToOwner[_tokenId]
+ # Вызывает исключение, если `_tokenId` не является действительным NFT
+ assert owner != ZERO_ADDRESS
+ # Вызывает исключение, если `_approved` является текущим владельцем
+ assert _approved != owner
+```
+
+По соглашению, если вы не хотите иметь утверждающего, вы назначаете нулевой адрес, а не себя.
+
+```python
+ # Проверка требований
+ senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender
+ senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender]
+ assert (senderIsOwner or senderIsApprovedForAll)
+```
+
+Чтобы установить одобрение, вы можете быть либо владельцем, либо оператором, уполномоченным владельцем.
+
+```python
+ # Установка одобрения
+ self.idToApprovals[_tokenId] = _approved
+ log Approval(owner, _approved, _tokenId)
+
+
+@external
+def setApprovalForAll(_operator: address, _approved: bool):
+ """
+ @dev Включает или отключает одобрение для третьей стороны ("оператора") для управления всеми
+ активами `msg.sender`. Также генерирует событие ApprovalForAll.
+ Вызывает исключение, если `_operator` является `msg.sender`. (ПРИМЕЧАНИЕ: этого нет в EIP)
+ @notice Это работает, даже если отправитель не владеет никакими токенами в данный момент.
+ @param _operator Адрес для добавления в набор авторизованных операторов.
+ @param _approved True, если оператор одобрен, false — для отзыва одобрения.
+ """
+ # Вызывает исключение, если `_operator` является `msg.sender`
+ assert _operator != msg.sender
+ self.ownerToOperators[msg.sender][_operator] = _approved
+ log ApprovalForAll(msg.sender, _operator, _approved)
+```
+
+#### Создание новых токенов и уничтожение существующих {#mint-burn}
+
+Аккаунт, создавший контракт, является `минтером` — суперпользователем, уполномоченным создавать
+новые NFT. Однако даже ему не разрешается сжигать существующие токены. Это может сделать только владелец или уполномоченное им лицо.
+
+```python
+### ФУНКЦИИ СОЗДАНИЯ И СЖИГАНИЯ ###
+
+@external
+def mint(_to: address, _tokenId: uint256) -> bool:
+```
+
+Эта функция всегда возвращает `True`, потому что в случае сбоя операция отменяется.
+
+```python
+ """
+ @dev Функция для создания токенов
+ Вызывает исключение, если `msg.sender` не является минтером.
+ Вызывает исключение, если `_to` является нулевым адресом.
+ Вызывает исключение, если `_tokenId` уже принадлежит кому-то.
+ @param _to Адрес, который получит созданные токены.
+ @param _tokenId Идентификатор токена для создания.
+ @return Логическое значение, которое указывает, была ли операция успешной.
+ """
+ # Вызывает исключение, если `msg.sender` не является минтером
+ assert msg.sender == self.minter
+```
+
+Только минтер (аккаунт, создавший контракт ERC-721) может создавать новые токены. Это может
+стать проблемой в будущем, если мы захотим изменить идентификатор минтера. В
+рабочем контракте, вероятно, понадобится функция, позволяющая минтеру передавать
+привилегии минтера кому-то другому.
+
+```python
+ # Вызывает исключение, если `_to` является нулевым адресом
+ assert _to != ZERO_ADDRESS
+ # Добавление NFT. Вызывает исключение, если `_tokenId` уже принадлежит кому-то
+ self._addTokenTo(_to, _tokenId)
+ log Transfer(ZERO_ADDRESS, _to, _tokenId)
+ return True
+```
+
+По соглашению, создание новых токенов считается переводом с нулевого адреса.
+
+```python
+
+@external
+def burn(_tokenId: uint256):
+ """
+ @dev Сжигает определенный токен ERC721.
+ Вызывает исключение, если `msg.sender` не является текущим владельцем, авторизованным оператором или одобренным
+ адресом для этого NFT.
+ Вызывает исключение, если `_tokenId` не является действительным NFT.
+ @param _tokenId uint256 id токена ERC721 для сжигания.
+ """
+ # Проверка требований
+ assert self._isApprovedOrOwner(msg.sender, _tokenId)
+ owner: address = self.idToOwner[_tokenId]
+ # Вызывает исключение, если `_tokenId` не является действительным NFT
+ assert owner != ZERO_ADDRESS
+ self._clearApproval(owner, _tokenId)
+ self._removeTokenFrom(owner, _tokenId)
+ log Transfer(owner, ZERO_ADDRESS, _tokenId)
+```
+
+Любой, кому разрешено переводить токен, может его сжечь. Хотя сжигание кажется эквивалентным
+переводу на нулевой адрес, нулевой адрес на самом деле не получает токен. Это позволяет нам
+освободить все хранилище, которое использовалось для токена, что может снизить стоимость газа транзакции.
+
+## Использование этого контракта {#using-contract}
+
+В отличие от Solidity, в Vyper нет наследования. Это сознательное проектное решение, чтобы сделать
+код более ясным и, следовательно, более простым в обеспечении безопасности. Поэтому для создания собственного контракта Vyper ERC-721 вы берете этот
+контракт и изменяете его
+для реализации желаемой бизнес-логики.
+
+## Заключение {#conclusion}
+
+Для обзора, вот некоторые из наиболее важных идей в этом контракте:
+
+- Для получения токенов ERC-721 с помощью безопасного перевода контракты должны реализовывать интерфейс `ERC721Receiver`.
+- Даже если вы используете безопасный перевод, токены все равно могут застрять, если вы отправите их на адрес, чей приватный ключ
+ неизвестен.
+- При возникновении проблемы с операцией рекомендуется `отменить` вызов, а не просто возвращать
+ значение сбоя.
+- Токены ERC-721 существуют, когда у них есть владелец.
+- Есть три способа получить разрешение на передачу NFT. Вы можете быть владельцем, иметь одобрение для конкретного токена
+ или быть оператором для всех токенов владельца.
+- Прошлые события видны только за пределами блокчейна. Код, работающий внутри блокчейна, не может их просматривать.
+
+А теперь идите и реализуйте безопасные контракты Vyper.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
diff --git a/public/content/translations/ru/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/ru/developers/tutorials/erc20-annotated-code/index.md
new file mode 100644
index 00000000000..ce93324c877
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/erc20-annotated-code/index.md
@@ -0,0 +1,932 @@
+---
+title: "Пошаговый разбор контракта ERC-20"
+description: "Что содержит контракт ERC-20 от OpenZeppelin и для чего это нужно?"
+author: Ori Pomerantz
+lang: ru
+tags: [ "Solidity", "erc-20" ]
+skill: beginner
+published: 2021-03-09
+---
+
+## Введение {#introduction}
+
+Чаще всего Ethereum используется для создания собственного токена, который можно использовать как валюту. Эти токены обычно следуют стандарту,
+[ERC-20](/developers/docs/standards/tokens/erc-20/). Этот стандарт позволяет создавать такие инструменты, как пулы ликвидности и кошельки, которые работают со всеми токенами
+ERC-20. В этой статье мы проанализируем
+[реализацию ERC20 на Solidity от OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol), а также
+[определение интерфейса](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol).
+
+Это аннотированный исходный код. Если вы хотите реализовать ERC-20,
+[прочтите это руководство](https://docs.openzeppelin.com/contracts/2.x/erc20-supply).
+
+## Интерфейс {#the-interface}
+
+Цель такого стандарта, как ERC-20, — обеспечить совместимость множества реализаций токенов в различных приложениях, таких как кошельки и децентрализованные биржи. Для этого мы создаем
+[интерфейс](https://www.geeksforgeeks.org/solidity/solidity-basics-of-interface/). Любой код, которому требуется использовать контракт токена,
+может использовать те же определения в интерфейсе и быть совместимым со всеми контрактами токенов, которые его используют, будь то кошелек, такой как
+MetaMask, децентрализованное приложение, такое как etherscan.io, или другой контракт, например пул ликвидности.
+
+
+
+Если вы опытный программист, вы, вероятно, помните, что видели подобные конструкции в [Java](https://www.w3schools.com/java/java_interface.asp)
+или даже в [заголовочных файлах C](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html).
+
+Это определение [интерфейса ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)
+от OpenZeppelin. Это перевод [человекочитаемого стандарта](https://eips.ethereum.org/EIPS/eip-20) в код Solidity. Конечно, сам
+интерфейс не определяет, _как_ что-либо делать. Это объясняется в исходном коде контракта ниже.
+
+
+
+```solidity
+// SPDX-License-Identifier: MIT
+```
+
+Файлы Solidity должны содержать идентификатор лицензии. [Вы можете посмотреть список лицензий здесь](https://spdx.org/licenses/). Если вам нужна другая
+лицензия, просто укажите это в комментариях.
+
+
+
+```solidity
+pragma solidity >=0.6.0 <0.8.0;
+```
+
+Язык Solidity все еще быстро развивается, и новые версии могут быть несовместимы со старым кодом
+([см. здесь](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Поэтому рекомендуется указывать не только минимальную
+версию языка, но и максимальную — последнюю, с которой вы тестировали код.
+
+
+
+```solidity
+/**
+ * @dev Интерфейс стандарта ERC20, как определено в EIP.
+ */
+```
+
+`@dev` в комментарии является частью [формата NatSpec](https://docs.soliditylang.org/en/develop/natspec-format.html), используемого для создания
+документации из исходного кода.
+
+
+
+```solidity
+interface IERC20 {
+```
+
+По соглашению, имена интерфейсов начинаются с `I`.
+
+
+
+```solidity
+ /**
+ * @dev Возвращает количество существующих токенов.
+ */
+ function totalSupply() external view returns (uint256);
+```
+
+Эта функция является `external`, что означает, [что она может быть вызвана только извне контракта](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2).
+Она возвращает общее количество токенов в контракте. Это значение возвращается с использованием самого распространенного типа в Ethereum, 256-битного беззнакового целого числа (256 бит — это
+собственный размер слова EVM). Эта функция также является `view`, что означает, что она не изменяет состояние, поэтому ее можно выполнить на одном узле, вместо того чтобы ее
+выполнял каждый узел в блокчейне. Такая функция не создает транзакцию и не требует [Газа](/developers/docs/gas/).
+
+**Примечание.** Теоретически может показаться, что создатель контракта может сжульничать, возвращая общее предложение меньше реального, чтобы каждый токен казался
+более ценным, чем он есть на самом деле. Однако этот страх игнорирует истинную природу блокчейна. Все, что происходит в блокчейне, может быть проверено
+каждым узлом. Для этого машинный код и хранилище каждого контракта доступны на каждом узле. Хотя вы не обязаны публиковать код
+Solidity для вашего контракта, никто не воспримет вас всерьез, если вы не опубликуете исходный код и версию Solidity, с которой он был скомпилирован, чтобы его можно было
+проверить на соответствие предоставленному вами машинному коду.
+Например, см. [этот контракт](https://eth.blockscout.com/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD?tab=contract).
+
+
+
+```solidity
+ /**
+ * @dev Возвращает количество токенов, принадлежащих `account`.
+ */
+ function balanceOf(address account) external view returns (uint256);
+```
+
+Как следует из названия, `balanceOf` возвращает баланс аккаунта. Аккаунты Ethereum идентифицируются в Solidity с помощью типа `address`, который содержит 160 бит.
+Она также `external` и `view`.
+
+
+
+```solidity
+ /**
+ * @dev Перемещает `amount` токенов со счета вызывающего на `recipient`.
+ *
+ * Возвращает логическое значение, указывающее, успешно ли выполнена операция.
+ *
+ * Инициирует событие {Transfer}.
+ */
+ function transfer(address recipient, uint256 amount) external returns (bool);
+```
+
+Функция `transfer` переводит токены с вызывающего адреса на другой адрес. Это связано с изменением состояния, поэтому она не является `view`.
+Когда пользователь вызывает эту функцию, создается транзакция и расходуется Газ. Она также инициирует событие `Transfer`, чтобы проинформировать всех в
+блокчейне об этом событии.
+
+Функция имеет два типа вывода для двух разных типов вызывающих:
+
+- Пользователи, которые вызывают функцию напрямую из пользовательского интерфейса. Обычно пользователь отправляет транзакцию
+ и не ждет ответа, что может занять неопределенное количество времени. Пользователь может увидеть, что произошло,
+ поискав квитанцию о транзакции (которая идентифицируется по Хэшу транзакции) или поискав событие
+ `Transfer`.
+- Другие контракты, которые вызывают функцию как часть общей транзакции. Эти контракты получают результат немедленно,
+ потому что они выполняются в той же транзакции, поэтому они могут использовать возвращаемое функцией значение.
+
+Тот же тип вывода создается и другими функциями, которые изменяют состояние контракта.
+
+
+
+Разрешения позволяют аккаунту тратить некоторые токены, принадлежащие другому владельцу.
+Это полезно, например, для контрактов, которые действуют как продавцы. Контракты не могут
+отслеживать события, поэтому, если покупатель переведет токены на контракт продавца
+напрямую, этот контракт не узнает, что ему заплатили. Вместо этого покупатель разрешает
+контракту продавца потратить определенную сумму, и продавец переводит эту сумму.
+Это делается с помощью функции, которую вызывает контракт продавца, поэтому контракт продавца
+может узнать, была ли операция успешной.
+
+```solidity
+ /**
+ * @dev Возвращает оставшееся количество токенов, которые `spender` сможет
+ * потратить от имени `owner` через {transferFrom}. По умолчанию
+ * это ноль.
+ *
+ * Это значение изменяется при вызове {approve} или {transferFrom}.
+ */
+ function allowance(address owner, address spender) external view returns (uint256);
+```
+
+Функция `allowance` позволяет любому запросить, какое разрешение один
+адрес (`owner`) дает другому адресу (`spender`) на трату.
+
+
+
+```solidity
+ /**
+ * @dev Устанавливает `amount` в качестве разрешенной суммы для `spender` сверх токенов вызывающей стороны.
+ *
+ * Возвращает логическое значение, указывающее, успешно ли выполнена операция.
+ *
+ * ВАЖНО: имейте в виду, что изменение разрешения с помощью этого метода несет в себе риск,
+ * что кто-то может использовать и старое, и новое разрешение из-за неудачного
+ * порядка транзакций. Одним из возможных решений для смягчения этого состояния гонки
+ * является сначала уменьшение разрешения для тратящего до 0, а затем установка
+ * желаемого значения:
+ * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
+ *
+ * Инициирует событие {Approval}.
+ */
+ function approve(address spender, uint256 amount) external returns (bool);
+```
+
+Функция `approve` создает разрешение. Обязательно прочтите сообщение о том,
+как это можно использовать не по назначению. В Ethereum вы контролируете порядок своих собственных транзакций,
+но не можете контролировать порядок, в котором будут выполняться транзакции
+других людей, если только вы не отправите свою собственную транзакцию после
+того, как увидите, что транзакция другой стороны произошла.
+
+
+
+```solidity
+ /**
+ * @dev Перемещает токены в размере `amount` от `sender` к `recipient` с использованием
+ * механизма разрешений. Затем `amount` вычитается из разрешения
+ * вызывающей стороны.
+ *
+ * Возвращает логическое значение, указывающее, успешно ли выполнена операция.
+ *
+ * Инициирует событие {Transfer}.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
+```
+
+Наконец, `transferFrom` используется тратящим для фактического использования разрешения.
+
+
+
+```solidity
+
+ /**
+ * @dev Создается при перемещении `value` токенов с одного аккаунта (`from`) на
+ * другой (`to`).
+ *
+ * Обратите внимание, что `value` может быть равно нулю.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 value);
+
+ /**
+ * @dev Создается, когда лимит для `spender` от `owner` устанавливается
+ * вызовом {approve}. `value` — это новый лимит.
+ */
+ event Approval(address indexed owner, address indexed spender, uint256 value);
+}
+```
+
+Эти события инициируются при изменении состояния контракта ERC-20.
+
+## Сам контракт {#the-actual-contract}
+
+Это фактический контракт, реализующий стандарт ERC-20,
+[взятый отсюда](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol).
+Он не предназначен для использования «как есть», но вы можете
+[наследоваться](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) от него, чтобы расширить его до чего-то пригодного для использования.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity >=0.6.0 <0.8.0;
+```
+
+
+
+### Инструкции импорта {#import-statements}
+
+Помимо определений интерфейса выше, определение контракта импортирует два других файла:
+
+```solidity
+
+import "../../GSN/Context.sol";
+import "./IERC20.sol";
+import "../../math/SafeMath.sol";
+```
+
+- `GSN/Context.sol` — это определения, необходимые для использования [OpenGSN](https://www.opengsn.org/), системы, которая позволяет пользователям без
+ ether использовать блокчейн. Обратите внимание, что это старая версия, если вы хотите интегрироваться с OpenGSN,
+ [используйте это руководство](https://docs.opengsn.org/javascript-client/tutorial.html).
+- [Библиотека SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/), которая предотвращает
+ арифметические переполнения/недополнения для версий Solidity **<0.8.0**. В Solidity ≥0.8.0 арифметические операции автоматически
+ отменяются при переполнении/недополнении, что делает SafeMath ненужной. Этот контракт использует SafeMath для обратной совместимости со
+ старыми версиями компилятора.
+
+
+
+Этот комментарий объясняет назначение контракта.
+
+```solidity
+/**
+ * @dev Реализация интерфейса {IERC20}.
+ *
+ * Эта реализация не зависит от способа создания токенов. Это означает,
+ * что механизм предоставления должен быть добавлен в производный контракт с использованием {_mint}.
+ * Общий механизм см. в {ERC20PresetMinterPauser}.
+ *
+ * СОВЕТ: для подробного описания см. наше руководство
+ * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[Как
+ * реализовать механизмы предоставления].
+ *
+ * Мы следовали общим рекомендациям OpenZeppelin: функции отменяются вместо
+ * возврата `false` при сбое. Такое поведение, тем не менее, является общепринятым
+ * и не противоречит ожиданиям приложений ERC20.
+ *
+ * Кроме того, при вызовах {transferFrom} инициируется событие {Approval}.
+ * Это позволяет приложениям восстанавливать разрешение для всех аккаунтов, просто
+ * прослушивая указанные события. Другие реализации EIP могут не инициировать
+ * эти события, поскольку это не требуется спецификацией.
+ *
+ * Наконец, были добавлены нестандартные функции {decreaseAllowance} и {increaseAllowance}
+ * для смягчения известных проблем, связанных с установкой
+ * разрешений. См. {IERC20-approve}.
+ */
+
+```
+
+### Определение контракта {#contract-definition}
+
+```solidity
+contract ERC20 is Context, IERC20 {
+```
+
+Эта строка определяет наследование, в данном случае от `IERC20` выше и `Context` для OpenGSN.
+
+
+
+```solidity
+
+ using SafeMath for uint256;
+
+```
+
+Эта строка присоединяет библиотеку `SafeMath` к типу `uint256`. Вы можете найти эту библиотеку
+[здесь](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol).
+
+### Определения переменных {#variable-definitions}
+
+Эти определения определяют переменные состояния контракта. Эти переменные объявлены `private`, но
+это означает только то, что другие контракты в блокчейне не могут их читать. _В блокчейне нет
+секретов_, программное обеспечение на каждом узле имеет состояние каждого контракта
+в каждом блоке. По соглашению переменные состояния именуются `_<что-то>`.
+
+Первые две переменные — это [сопоставления (mappings)](https://www.tutorialspoint.com/solidity/solidity_mappings.htm),
+что означает, что они ведут себя примерно так же, как [ассоциативные массивы](https://wikipedia.org/wiki/Associative_array),
+за исключением того, что ключи являются числовыми значениями. Хранилище выделяется только для записей, которые имеют значения, отличные
+от значения по умолчанию (ноль).
+
+```solidity
+ mapping (address => uint256) private _balances;
+```
+
+Первое сопоставление, `_balances`, — это адреса и их соответствующие балансы этого токена. Чтобы получить доступ к
+балансу, используйте этот синтаксис: `_balances[]`.
+
+
+
+```solidity
+ mapping (address => mapping (address => uint256)) private _allowances;
+```
+
+Эта переменная, `_allowances`, хранит разрешения, объясненные ранее. Первый индекс — это владелец
+токенов, а второй — контракт с разрешением. Чтобы получить доступ к сумме, которую адрес A может
+потратить со счета адреса B, используйте `_allowances[B][A]`.
+
+
+
+```solidity
+ uint256 private _totalSupply;
+```
+
+Как следует из названия, эта переменная отслеживает общее предложение токенов.
+
+
+
+```solidity
+ string private _name;
+ string private _symbol;
+ uint8 private _decimals;
+```
+
+Эти три переменные используются для улучшения читаемости. Первые две говорят сами за себя, а вот `_decimals`
+— нет.
+
+С одной стороны, в Ethereum нет переменных с плавающей запятой или дробных переменных. С другой стороны,
+людям нравится иметь возможность делить токены. Одна из причин, по которой люди остановились на золоте в качестве валюты, заключалась в том, что
+было трудно разменивать деньги, когда кто-то хотел купить утку за часть коровы.
+
+Решение состоит в том, чтобы отслеживать целые числа, но считать не реальный токен, а дробный токен, который
+почти ничего не стоит. В случае с ether дробный токен называется wei, и 10^18 wei равны одному
+ETH. На момент написания 10 000 000 000 000 wei примерно равны одному центу США или евро.
+
+Приложениям необходимо знать, как отображать баланс токена. Если у пользователя 3 141 000 000 000 000 000 wei, это
+3,14 ETH? 31,41 ETH? 3141 ETH? В случае с ether определено 10^18 wei на ETH, но для вашего
+токена вы можете выбрать другое значение. Если деление токена не имеет смысла, вы можете использовать
+значение `_decimals`, равное нулю. Если вы хотите использовать тот же стандарт, что и для ETH, используйте значение **18**.
+
+### Конструктор {#the-constructor}
+
+```solidity
+ /**
+ * @dev Устанавливает значения для {name} и {symbol}, инициализирует {decimals} со
+ * значением по умолчанию 18.
+ *
+ * Чтобы выбрать другое значение для {decimals}, используйте {_setupDecimals}.
+ *
+ * Все три этих значения неизменяемы: их можно установить только один раз во время
+ * создания.
+ */
+ constructor (string memory name_, string memory symbol_) public {
+ // В Solidity ≥0.7.0 'public' является неявным и может быть опущен.
+
+ _name = name_;
+ _symbol = symbol_;
+ _decimals = 18;
+ }
+```
+
+Конструктор вызывается при первом создании контракта. По соглашению параметры функции именуются `<что-то>_`.
+
+### Функции пользовательского интерфейса {#user-interface-functions}
+
+```solidity
+ /**
+ * @dev Возвращает имя токена.
+ */
+ function name() public view returns (string memory) {
+ return _name;
+ }
+
+ /**
+ * @dev Возвращает символ токена, обычно более короткую версию
+ * имени.
+ */
+ function symbol() public view returns (string memory) {
+ return _symbol;
+ }
+
+ /**
+ * @dev Возвращает количество десятичных знаков, используемых для получения его представления для пользователя.
+ * Например, если `decimals` равно `2`, баланс `505` токенов должен
+ * отображаться пользователю как `5,05` (`505 / 10 ** 2`).
+ *
+ * Токены обычно выбирают значение 18, имитируя отношение между
+ * ether и wei. Это значение, которое использует {ERC20}, если не вызывается {_setupDecimals}.
+ *
+ * ПРИМЕЧАНИЕ: Эта информация используется только для _отображения_: она ни в коем
+ * случае не влияет на арифметику контракта, включая
+ * {IERC20-balanceOf} и {IERC20-transfer}.
+ */
+ function decimals() public view returns (uint8) {
+ return _decimals;
+ }
+```
+
+Эти функции, `name`, `symbol` и `decimals`, помогают пользовательским интерфейсам узнать о вашем контракте, чтобы они могли правильно его отображать.
+
+Возвращаемый тип — `string memory`, что означает возврат строки, которая хранится в памяти. Переменные, такие как
+строки, могут храниться в трех местах:
+
+| | Время жизни | Доступ к контракту | Стоимость Газа |
+| --------- | ------------- | ------------------ | ---------------------------------------------------------------------------------------- |
+| Память | Вызов функции | Чтение/запись | Десятки или сотни (больше для более высоких местоположений) |
+| Calldata | Вызов функции | Только для чтения | Не может использоваться как тип возвращаемого значения, только как тип параметра функции |
+| Хранилище | До изменения | Чтение/запись | Высокая (800 для чтения, 20 тыс. для записи) |
+
+В данном случае `memory` — лучший выбор.
+
+### Чтение информации о токене {#read-token-information}
+
+Это функции, которые предоставляют информацию о токене: общее предложение или баланс
+аккаунта.
+
+```solidity
+ /**
+ * @dev См. {IERC20-totalSupply}.
+ */
+ function totalSupply() public view override returns (uint256) {
+ return _totalSupply;
+ }
+```
+
+Функция `totalSupply` возвращает общее предложение токенов.
+
+
+
+```solidity
+ /**
+ * @dev См. {IERC20-balanceOf}.
+ */
+ function balanceOf(address account) public view override returns (uint256) {
+ return _balances[account];
+ }
+```
+
+Чтение баланса аккаунта. Обратите внимание, что любой может получить баланс аккаунта
+любого другого. Нет смысла пытаться скрыть эту информацию, потому что она и так доступна на каждом
+узле. _В блокчейне нет секретов._
+
+### Перевод токенов {#transfer-tokens}
+
+```solidity
+ /**
+ * @dev См. {IERC20-transfer}.
+ *
+ * Требования:
+ *
+ * - `recipient` не может быть нулевым адресом.
+ * - у вызывающего должен быть баланс не менее `amount`.
+ */
+ function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
+```
+
+Функция `transfer` вызывается для перевода токенов со счета отправителя на другой. Обратите
+внимание, что хотя она и возвращает логическое значение, это значение всегда **true**. Если перевод
+не удается, контракт отменяет вызов.
+
+
+
+```solidity
+ _transfer(_msgSender(), recipient, amount);
+ return true;
+ }
+```
+
+Функция `_transfer` выполняет фактическую работу. Это приватная функция, которая может быть вызвана только
+другими функциями контракта. По соглашению приватные функции именуются `_<что-то>`, так же как и переменные
+состояния.
+
+Обычно в Solidity мы используем `msg.sender` для отправителя сообщения. Однако это нарушает работу
+[OpenGSN](http://opengsn.org/). Если мы хотим разрешить транзакции без ether с нашим токеном, нам
+нужно использовать `_msgSender()`. Она возвращает `msg.sender` для обычных транзакций, но для транзакций без ether
+возвращает исходного подписанта, а не контракт, который переслал сообщение.
+
+### Функции разрешений {#allowance-functions}
+
+Это функции, которые реализуют функциональность разрешений: `allowance`, `approve`, `transferFrom`
+и `_approve`. Кроме того, реализация OpenZeppelin выходит за рамки базового стандарта и включает некоторые функции, которые улучшают
+безопасность: `increaseAllowance` и `decreaseAllowance`.
+
+#### Функция allowance {#allowance}
+
+```solidity
+ /**
+ * @dev См. {IERC20-allowance}.
+ */
+ function allowance(address owner, address spender) public view virtual override returns (uint256) {
+ return _allowances[owner][spender];
+ }
+```
+
+Функция `allowance` позволяет всем проверять любое разрешение.
+
+#### Функция approve {#approve}
+
+```solidity
+ /**
+ * @dev См. {IERC20-approve}.
+ *
+ * Требования:
+ *
+ * - `spender` не может быть нулевым адресом.
+ */
+ function approve(address spender, uint256 amount) public virtual override returns (bool) {
+```
+
+Эта функция вызывается для создания разрешения. Она похожа на функцию `transfer` выше:
+
+- Функция просто вызывает внутреннюю функцию (в данном случае `_approve`), которая выполняет реальную работу.
+- Функция либо возвращает `true` (в случае успеха), либо отменяет операцию (в противном случае).
+
+
+
+```solidity
+ _approve(_msgSender(), spender, amount);
+ return true;
+ }
+```
+
+Мы используем внутренние функции, чтобы минимизировать количество мест, где происходят изменения состояния. _Любая_ функция, изменяющая
+состояние, является потенциальным риском безопасности, который необходимо проверить на безопасность. Таким образом, у нас меньше шансов ошибиться.
+
+#### Функция transferFrom {#transferFrom}
+
+Это функция, которую тратящий вызывает для использования разрешения. Это требует двух операций: перевода потраченной суммы
+и уменьшения разрешения на эту сумму.
+
+```solidity
+ /**
+ * @dev См. {IERC20-transferFrom}.
+ *
+ * Инициирует событие {Approval}, указывающее на обновленное разрешение. Это не
+ * требуется EIP. См. примечание в начале {ERC20}.
+ *
+ * Требования:
+ *
+ * - `sender` и `recipient` не могут быть нулевыми адресами.
+ * - у `sender` должен быть баланс не менее `amount`.
+ * - у вызывающего должно быть разрешение на токены ``sender`` не менее
+ * `amount`.
+ */
+ function transferFrom(address sender, address recipient, uint256 amount) public virtual
+ override returns (bool) {
+ _transfer(sender, recipient, amount);
+```
+
+
+
+Вызов функции `a.sub(b, "message")` выполняет две вещи. Во-первых, он вычисляет `a-b`, что является новым разрешением.
+Во-вторых, он проверяет, что этот результат не является отрицательным. Если он отрицательный, вызов отменяется с предоставленным сообщением. Обратите внимание, что когда вызов отменяется, любая обработка, выполненная ранее во время этого вызова, игнорируется, поэтому нам не нужно
+отменять `_transfer`.
+
+```solidity
+ _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount,
+ "ERC20: сумма перевода превышает разрешение"));
+ return true;
+ }
+```
+
+#### Дополнения безопасности OpenZeppelin {#openzeppelin-safety-additions}
+
+Опасно устанавливать ненулевое разрешение на другое ненулевое значение,
+потому что вы контролируете только порядок своих собственных транзакций, а не чьих-либо еще. Представьте, что у вас
+есть два пользователя: Алиса, которая наивна, и Билл, который нечестен. Алиса хочет получить какую-то услугу от
+Билла, которая, по ее мнению, стоит пять токенов, поэтому она дает Биллу разрешение на пять токенов.
+
+Затем что-то меняется, и цена Билла повышается до десяти токенов. Алиса, которая все еще хочет получить услугу,
+отправляет транзакцию, которая устанавливает разрешение Билла на десять. В тот момент, когда Билл видит эту новую транзакцию
+в пуле транзакций, он отправляет транзакцию, которая тратит пять токенов Алисы и имеет гораздо
+более высокую цену на Газ, чтобы она была добыта быстрее. Таким образом, Билл может сначала потратить пять токенов, а затем,
+когда новое разрешение Алисы будет добыто, потратить еще десять, что в общей сложности составит пятнадцать токенов — больше, чем
+Алиса намеревалась разрешить. Этот метод называется
+[опережением (фронтраннинг)](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running)
+
+| Транзакция Алисы | Nonce Алисы | Транзакция Билла | Nonce Билла | Разрешение для Билла | Общий доход Билла от Алисы |
+| ------------------------------------ | ----------- | ------------------------------------------------ | ----------- | -------------------- | -------------------------- |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
+| approve(Bill, 10) | 11 | | | 10 | 5 |
+| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 |
+
+Чтобы избежать этой проблемы, эти две функции (`increaseAllowance` и `decreaseAllowance`) позволяют вам
+изменять разрешение на определенную сумму. Так что, если Билл уже потратил пять токенов, он сможет
+потратить еще пять. В зависимости от времени это может работать двумя способами, оба из
+которых заканчиваются тем, что Билл получает только десять токенов:
+
+A:
+
+| Транзакция Алисы | Nonce Алисы | Транзакция Билла | Nonce Билла | Разрешение для Билла | Общий доход Билла от Алисы |
+| --------------------------------------------- | ----------: | ----------------------------------------------- | ----------: | -------------------: | -------------------------- |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 |
+| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 |
+| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 |
+
+B:
+
+| Транзакция Алисы | Nonce Алисы | Транзакция Билла | Nonce Билла | Разрешение для Билла | Общий доход Билла от Алисы |
+| --------------------------------------------- | ----------: | ------------------------------------------------ | ----------: | -------------------: | -------------------------: |
+| approve(Bill, 5) | 10 | | | 5 | 0 |
+| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 |
+| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 |
+
+```solidity
+ /**
+ * @dev Атомарно увеличивает разрешение, предоставленное `spender` вызывающей стороной.
+ *
+ * Это альтернатива {approve}, которая может использоваться для смягчения
+ * проблем, описанных в {IERC20-approve}.
+ *
+ * Инициирует событие {Approval}, указывающее на обновленное разрешение.
+ *
+ * Требования:
+ *
+ * - `spender` не может быть нулевым адресом.
+ */
+ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
+ _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
+ return true;
+ }
+```
+
+Функция `a.add(b)` — это безопасное сложение. В маловероятном случае, если `a`+`b`>=`2^256`, оно не переносится
+, как обычное сложение.
+
+```solidity
+
+ /**
+ * @dev Атомарно уменьшает разрешение, предоставленное `spender` вызывающей стороной.
+ *
+ * Это альтернатива {approve}, которая может использоваться для смягчения
+ * проблем, описанных в {IERC20-approve}.
+ *
+ * Инициирует событие {Approval}, указывающее на обновленное разрешение.
+ *
+ * Требования:
+ *
+ * - `spender` не может быть нулевым адресом.
+ * - `spender` должен иметь разрешение для вызывающей стороны не менее
+ * `subtractedValue`.
+ */
+ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
+ _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue,
+ "ERC20: уменьшенное разрешение ниже нуля"));
+ return true;
+ }
+```
+
+### Функции, изменяющие информацию о токене {#functions-that-modify-token-information}
+
+Это четыре функции, которые выполняют фактическую работу: `_transfer`, `_mint`, `_burn` и `_approve`.
+
+#### Функция _transfer {#_transfer}
+
+```solidity
+ /**
+ * @dev Перемещает токены в размере `amount` от `sender` к `recipient`.
+ *
+ * Эта внутренняя функция эквивалентна {transfer} и может использоваться для
+ * реализации, например, автоматических комиссий за токены, механизмов слэшинга и т. д.
+ *
+ * Инициирует событие {Transfer}.
+ *
+ * Требования:
+ *
+ * - `sender` не может быть нулевым адресом.
+ * - `recipient` не может быть нулевым адресом.
+ * - у `sender` должен быть баланс не менее `amount`.
+ */
+ function _transfer(address sender, address recipient, uint256 amount) internal virtual {
+```
+
+Эта функция, `_transfer`, переводит токены с одного аккаунта на другой. Она вызывается как
+`transfer` (для переводов с собственного счета отправителя), так и `transferFrom` (для использования разрешений
+для перевода со счета другого лица).
+
+
+
+```solidity
+ require(sender != address(0), "ERC20: перевод с нулевого адреса");
+ require(recipient != address(0), "ERC20: перевод на нулевой адрес");
+```
+
+Никто на самом деле не владеет нулевым адресом в Ethereum (то есть никто не знает приватный ключ, соответствующий публичный ключ которого
+преобразуется в нулевой адрес). Когда люди используют этот адрес, это обычно ошибка программного обеспечения, поэтому мы
+прерываем операцию, если нулевой адрес используется как отправитель или получатель.
+
+
+
+```solidity
+ _beforeTokenTransfer(sender, recipient, amount);
+
+```
+
+Есть два способа использовать этот контракт:
+
+1. Использовать его как шаблон для своего собственного кода
+2. [Наследоваться от него](https://www.bitdegree.org/learn/solidity-inheritance) и переопределять только те функции, которые вам нужно изменить
+
+Второй метод намного лучше, потому что код OpenZeppelin ERC-20 уже был проверен и признан безопасным. Когда вы используете наследование,
+ясно, какие функции вы изменяете, и чтобы доверять вашему контракту, людям нужно проверить только эти конкретные функции.
+
+Часто бывает полезно выполнять функцию каждый раз, когда токены переходят из рук в руки. Однако `_transfer` — очень важная функция, и ее можно
+написать небезопасно (см. ниже), поэтому лучше ее не переопределять. Решение — `_beforeTokenTransfer`,
+[функция-перехватчик (hook)](https://wikipedia.org/wiki/Hooking). Вы можете переопределить эту функцию, и она будет вызываться при каждом переводе.
+
+
+
+```solidity
+ _balances[sender] = _balances[sender].sub(amount, "ERC20: сумма перевода превышает баланс");
+ _balances[recipient] = _balances[recipient].add(amount);
+```
+
+Это строки, которые фактически выполняют перевод. Обратите внимание, что между ними **ничего** нет, и что мы вычитаем
+переведенную сумму у отправителя перед тем, как добавить ее получателю. Это важно, потому что если бы посредине был
+вызов другого контракта, его можно было бы использовать для обмана этого контракта. Таким образом, перевод
+является атомарным, ничего не может произойти в его середине.
+
+
+
+```solidity
+ emit Transfer(sender, recipient, amount);
+ }
+```
+
+Наконец, инициируйте событие `Transfer`. События недоступны для Умных контрактов, но код, работающий вне блокчейна,
+может прослушивать события и реагировать на них. Например, кошелек может отслеживать, когда владелец получает больше токенов.
+
+#### Функции _mint и _burn {#_mint-and-_burn}
+
+Эти две функции (`_mint` и `_burn`) изменяют общее предложение токенов.
+Они являются внутренними, и в этом контракте нет функции, которая их вызывает,
+поэтому они полезны только в том случае, если вы наследуете от контракта и добавляете свою собственную
+логику для решения, при каких условиях создавать новые токены или сжигать существующие.
+
+**ПРИМЕЧАНИЕ:** У каждого токена ERC-20 своя бизнес-логика, которая диктует управление токенами.
+Например, контракт с фиксированным предложением может вызывать `_mint` только
+в конструкторе и никогда не вызывать `_burn`. Контракт, который продает токены,
+будет вызывать `_mint` при получении оплаты и, предположительно, вызывать `_burn` в какой-то момент,
+чтобы избежать безудержной инфляции.
+
+```solidity
+ /** @dev Создает `amount` токенов и назначает их `account`, увеличивая
+ * общее предложение.
+ *
+ * Инициирует событие {Transfer} с `from`, установленным на нулевой адрес.
+ *
+ * Требования:
+ *
+ * - `to` не может быть нулевым адресом.
+ */
+ function _mint(address account, uint256 amount) internal virtual {
+ require(account != address(0), "ERC20: создание токенов на нулевой адрес");
+ _beforeTokenTransfer(address(0), account, amount);
+ _totalSupply = _totalSupply.add(amount);
+ _balances[account] = _balances[account].add(amount);
+ emit Transfer(address(0), account, amount);
+ }
+```
+
+Не забудьте обновить `_totalSupply` при изменении общего количества токенов.
+
+
+
+```solidity
+ /**
+ * @dev Уничтожает `amount` токенов с `account`, уменьшая
+ * общее предложение.
+ *
+ * Инициирует событие {Transfer} с `to`, установленным на нулевой адрес.
+ *
+ * Требования:
+ *
+ * - `account` не может быть нулевым адресом.
+ * - `account` должен иметь не менее `amount` токенов.
+ */
+ function _burn(address account, uint256 amount) internal virtual {
+ require(account != address(0), "ERC20: сжигание с нулевого адреса");
+
+ _beforeTokenTransfer(account, address(0), amount);
+
+ _balances[account] = _balances[account].sub(amount, "ERC20: сумма сжигания превышает баланс");
+ _totalSupply = _totalSupply.sub(amount);
+ emit Transfer(account, address(0), amount);
+ }
+```
+
+Функция `_burn` почти идентична `_mint`, за исключением того, что она работает в обратном направлении.
+
+#### Функция _approve {#_approve}
+
+Это функция, которая фактически определяет разрешения. Обратите внимание, что она позволяет владельцу указать
+разрешение, превышающее текущий баланс владельца. Это нормально, потому что баланс
+проверяется во время перевода, когда он может отличаться от баланса при
+создании разрешения.
+
+```solidity
+ /**
+ * @dev Устанавливает `amount` в качестве разрешения `spender` над токенами `owner`.
+ *
+ * Эта внутренняя функция эквивалентна `approve` и может использоваться для
+ * установки, например, автоматических разрешений для определенных подсистем и т. д.
+ *
+ * Инициирует событие {Approval}.
+ *
+ * Требования:
+ *
+ * - `owner` не может быть нулевым адресом.
+ * - `spender` не может быть нулевым адресом.
+ */
+ function _approve(address owner, address spender, uint256 amount) internal virtual {
+ require(owner != address(0), "ERC20: разрешение с нулевого адреса");
+ require(spender != address(0), "ERC20: разрешение на нулевой адрес");
+
+ _allowances[owner][spender] = amount;
+```
+
+
+
+Инициируйте событие `Approval`. В зависимости от того, как написано приложение, контракт тратящего может быть уведомлен о
+разрешении либо владельцем, либо сервером, который прослушивает эти события.
+
+```solidity
+ emit Approval(owner, spender, amount);
+ }
+
+```
+
+### Изменение переменной decimals {#modify-the-decimals-variable}
+
+```solidity
+
+
+ /**
+ * @dev Устанавливает {decimals} на значение, отличное от значения по умолчанию 18.
+ *
+ * ВНИМАНИЕ: Эту функцию следует вызывать только из конструктора. Большинство
+ * приложений, взаимодействующих с контрактами токенов, не ожидают,
+ * что {decimals} когда-либо изменится, и могут работать неправильно, если это произойдет.
+ */
+ function _setupDecimals(uint8 decimals_) internal {
+ _decimals = decimals_;
+ }
+```
+
+Эта функция изменяет переменную `_decimals`, которая используется для того, чтобы сообщить пользовательским интерфейсам, как интерпретировать сумму.
+Вы должны вызывать ее из конструктора. Было бы нечестно вызывать ее в любой последующий момент, и приложения
+не предназначены для обработки этого.
+
+### Перехватчики {#hooks}
+
+```solidity
+
+ /**
+ * @dev Перехватчик, который вызывается перед любым переводом токенов. Это включает
+ * создание и сжигание.
+ *
+ * Условия вызова:
+ *
+ * - когда `from` и `to` оба не равны нулю, `amount` токенов ``from``
+ * будет переведено `to`.
+ * - когда `from` равно нулю, `amount` токенов будет создано для `to`.
+ * - когда `to` равно нулю, `amount` токенов ``from`` будет сожжено.
+ * - `from` и `to` никогда не равны нулю одновременно.
+ *
+ * Чтобы узнать больше о перехватчиках, перейдите к xref:ROOT:extending-contracts.adoc#using-hooks[Использование перехватчиков].
+ */
+ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
+}
+```
+
+Это функция-перехватчик, которая вызывается во время переводов. Здесь она пуста, но если вам нужно,
+чтобы она что-то делала, вы просто переопределяете ее.
+
+## Заключение {#conclusion}
+
+Для обзора, вот некоторые из самых важных идей в этом контракте (по моему мнению, ваше может отличаться):
+
+- _В блокчейне не существует секретов_. Любая информация, к которой может получить доступ Умный контракт,
+ доступна всему миру.
+- Вы можете контролировать порядок своих собственных транзакций, но не то, когда происходят транзакции
+ других людей. Именно по этой причине изменение разрешения может быть опасным, потому что оно позволяет
+ тратящему потратить сумму обоих разрешений.
+- Значения типа `uint256` циклически переносятся. Другими словами, _0-1=2^256-1_. Если это нежелательное
+ поведение, вы должны проверять его (или использовать библиотеку SafeMath, которая делает это за вас). Обратите внимание, что это изменилось в
+ [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html).
+- Выполняйте все изменения состояния определенного типа в определенном месте, потому что это облегчает аудит.
+ Именно по этой причине у нас есть, например, `_approve`, который вызывается `approve`, `transferFrom`,
+ `increaseAllowance` и `decreaseAllowance`
+- Изменения состояния должны быть атомарными, без каких-либо других действий в их середине (как вы можете видеть
+ в `_transfer`). Это связано с тем, что во время изменения состояния у вас несогласованное состояние. Например,
+ между моментом вычета из баланса отправителя и моментом добавления к балансу
+ получателя существует меньше токенов, чем должно быть. Этим потенциально можно злоупотребить, если
+ между ними есть операции, особенно вызовы другого контракта.
+
+Теперь, когда вы увидели, как написан контракт OpenZeppelin ERC-20, и особенно как он
+сделан более безопасным, идите и пишите свои собственные безопасные контракты и приложения.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/ru/developers/tutorials/erc20-with-safety-rails/index.md
new file mode 100644
index 00000000000..318602e9753
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/erc20-with-safety-rails/index.md
@@ -0,0 +1,217 @@
+---
+title: "ERC-20 с мерами предосторожности"
+description: "Как помочь людям избежать глупых ошибок"
+author: Ori Pomerantz
+lang: ru
+tags: [ "erc-20" ]
+skill: beginner
+published: 2022-08-15
+---
+
+## Введение {#introduction}
+
+Одно из замечательных качеств Ethereum — это отсутствие центрального органа, который мог бы изменять или отменять ваши транзакции. Одна из больших проблем Ethereum заключается в том, что нет центрального органа, уполномоченного исправлять ошибки пользователей или отменять незаконные транзакции. В этой статье вы узнаете о некоторых распространенных ошибках, которые пользователи совершают с токенами [ERC-20](/developers/docs/standards/tokens/erc-20/), а также о том, как создавать контракты ERC-20, которые помогают пользователям избежать этих ошибок или которые предоставляют центральному органу некоторые полномочия (например, для замораживания аккаунтов).
+
+Обратите внимание, что, хотя мы будем использовать [контракт токена ERC-20 от OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20), в этой статье он не объясняется в мельчайших подробностях. Эту информацию можно найти [здесь](/developers/tutorials/erc20-annotated-code).
+
+Если вы хотите увидеть полный исходный код:
+
+1. Откройте [Remix IDE](https://remix.ethereum.org/).
+2. Нажмите на значок клонирования github ().
+3. Клонируйте репозиторий github `https://github.com/qbzzt/20220815-erc20-safety-rails`.
+4. Откройте **contracts > erc20-safety-rails.sol**.
+
+## Создание контракта ERC-20 {#creating-an-erc-20-contract}
+
+Прежде чем мы сможем добавить функциональность мер предосторожности, нам понадобится контракт ERC-20. В этой статье мы воспользуемся [Мастером контрактов OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/wizard). Откройте его в другом браузере и следуйте этим инструкциям:
+
+1. Выберите **ERC20**.
+
+2. Введите следующие настройки:
+
+ | Параметр | Значение |
+ | ---------------------- | ---------------- |
+ | Имя | SafetyRailsToken |
+ | Символ | SAFE |
+ | Premint | 1000 |
+ | Функции | Нет |
+ | Контроль доступа | Ownable |
+ | Возможность обновления | Нет |
+
+3. Прокрутите вверх и нажмите **Открыть в Remix** (для Remix) или **Загрузить**, чтобы использовать другую среду. Я буду исходить из того, что вы используете Remix. Если вы используете что-то другое, просто внесите соответствующие изменения.
+
+4. Теперь у нас есть полнофункциональный контракт ERC-20. Вы можете развернуть `.deps` > `npm`, чтобы увидеть импортированный код.
+
+5. Скомпилируйте, разверните и поработайте с контрактом, чтобы убедиться, что он функционирует как контракт ERC-20. Если вам нужно научиться пользоваться Remix, [воспользуйтесь этим руководством](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth).
+
+## Распространенные ошибки {#common-mistakes}
+
+### Ошибки {#the-mistakes}
+
+Иногда пользователи отправляют токены на неверный адрес. Хотя мы не можем читать их мысли, чтобы знать, что они хотели сделать, есть два типа ошибок, которые случаются часто и легко обнаруживаются:
+
+1. Отправка токенов на собственный адрес контракта. Например, [токену OP от Optimism](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) удалось накопить [более 120 000](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000042) токенов OP менее чем за два месяца. Это представляет собой значительное состояние, которое, по-видимому, люди просто потеряли.
+
+2. Отправка токенов на пустой адрес, который не соответствует [внешнему аккаунту](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) или [умному контракту](/developers/docs/smart-contracts). Хотя у меня нет статистики о том, как часто это происходит, [один инцидент мог стоить 20 000 000 токенов](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595).
+
+### Предотвращение переводов {#preventing-transfers}
+
+Контракт ERC-20 от OpenZeppelin включает [перехватчик (hook) `_beforeTokenTransfer`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368), который вызывается перед передачей токена. По умолчанию этот перехватчик ничего не делает, но мы можем «повесить» на него собственную функциональность, например, проверки, которые отменяют транзакцию в случае возникновения проблемы.
+
+Чтобы использовать перехватчик, добавьте эту функцию после конструктора:
+
+```solidity
+ function _beforeTokenTransfer(address from, address to, uint256 amount)
+ internal virtual
+ override(ERC20)
+ {
+ super._beforeTokenTransfer(from, to, amount);
+ }
+```
+
+Некоторые части этой функции могут быть новыми, если вы не очень хорошо знакомы с Solidity:
+
+```solidity
+ internal virtual
+```
+
+Ключевое слово `virtual` означает, что так же, как мы унаследовали функциональность от `ERC20` и переопределили эту функцию, другие контракты могут наследоваться от нас и переопределять эту функцию.
+
+```solidity
+ override(ERC20)
+```
+
+Мы должны явно указать, что мы [переопределяем](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) определение `_beforeTokenTransfer` для токена ERC20. В целом, с точки зрения безопасности, явные определения намного лучше, чем неявные — вы не можете забыть, что что-то сделали, если это прямо перед вами. Это также причина, по которой нам нужно указать, чей `_beforeTokenTransfer` суперкласса мы переопределяем.
+
+```solidity
+ super._beforeTokenTransfer(from, to, amount);
+```
+
+Эта строка вызывает функцию `_beforeTokenTransfer` контракта или контрактов, от которых мы унаследовали и в которых она есть. В данном случае это только `ERC20`, у `Ownable` этого перехватчика нет. Несмотря на то, что в настоящее время `ERC20._beforeTokenTransfer` ничего не делает, мы вызываем его на случай, если в будущем будет добавлена функциональность (и мы затем решим переразвернуть контракт, потому что контракты не меняются после развертывания).
+
+### Программирование требований {#coding-the-requirements}
+
+Мы хотим добавить в функцию следующие требования:
+
+- Адрес `to` не может быть равен `address(this)`, то есть адресу самого контракта ERC-20.
+- Адрес `to` не может быть пустым, он должен быть либо:
+ - Внешний аккаунт (EOA). Мы не можем напрямую проверить, является ли адрес EOA, но мы можем проверить баланс ETH по этому адресу. EOA почти всегда имеют баланс, даже если они больше не используются — трудно очистить их до последнего wei.
+ - Умный контракт. Проверить, является ли адрес умным контрактом, немного сложнее. Существует код операции (opcode), который проверяет длину внешнего кода, он называется [`EXTCODESIZE`](https://www.evm.codes/#3b), но он недоступен напрямую в Solidity. Для этого мы должны использовать [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html), который является ассемблером EVM. Есть и другие значения, которые мы могли бы использовать из Solidity ([`.code` и `.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)), но они стоят дороже.
+
+Давайте рассмотрим новый код построчно:
+
+```solidity
+ require(to != address(this), "Нельзя отправлять токены на адрес контракта");
+```
+
+Это первое требование, проверка того, что `to` и `this(address)` — это не одно и то же.
+
+```solidity
+ bool isToContract;
+ assembly {
+ isToContract := gt(extcodesize(to), 0)
+ }
+```
+
+Вот как мы проверяем, является ли адрес контрактом. Мы не можем получать выходные данные напрямую из Yul, поэтому вместо этого мы определяем переменную для хранения результата (в данном случае `isToContract`). Yul работает так, что каждый код операции (opcode) считается функцией. Итак, сначала мы вызываем [`EXTCODESIZE`](https://www.evm.codes/#3b), чтобы получить размер контракта, а затем используем [`GT`](https://www.evm.codes/#11), чтобы проверить, что он не равен нулю (мы имеем дело с беззнаковыми целыми числами, поэтому, конечно, он не может быть отрицательным). Затем мы записываем результат в `isToContract`.
+
+```solidity
+ require(to.balance != 0 || isToContract, "Нельзя отправлять токены на пустой адрес");
+```
+
+И, наконец, у нас есть фактическая проверка на пустые адреса.
+
+## Административный доступ {#admin-access}
+
+Иногда полезно иметь администратора, который может исправлять ошибки. Чтобы уменьшить вероятность злоупотреблений, этот администратор может быть [мультиподписным кошельком (multisig)](https://blog.logrocket.com/security-choices-multi-signature-wallets/), чтобы для выполнения действия требовалось согласие нескольких человек. В этой статье мы рассмотрим две административные функции:
+
+1. Замораживание и размораживание аккаунтов. Это может быть полезно, например, когда аккаунт может быть скомпрометирован.
+2. Очистка активов.
+
+ Иногда мошенники отправляют поддельные токены на контракт настоящего токена, чтобы завоевать доверие. Например, [смотрите здесь](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe?tab=holders). Настоящий контракт ERC-20 — это [0x4200....0042](https://optimism.blockscout.com/token/0x4200000000000000000000000000000000000042). Мошеннический контракт, который выдает себя за него, — это [0x234....bbe](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe).
+
+ Также возможно, что люди по ошибке отправят настоящие токены ERC-20 на наш контракт, и это еще одна причина, по которой стоит иметь способ их оттуда вывести.
+
+OpenZeppelin предоставляет два механизма для обеспечения административного доступа:
+
+- Контракты [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) имеют одного владельца. Функции, имеющие [модификатор](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `onlyOwner`, могут вызываться только этим владельцем. Владельцы могут передать право собственности кому-то другому или полностью от него отказаться. Права всех остальных аккаунтов обычно идентичны.
+- Контракты [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) имеют [управление доступом на основе ролей (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control).
+
+Для простоты в этой статье мы используем `Ownable`.
+
+### Замораживание и размораживание счетов {#freezing-and-thawing-contracts}
+
+Для замораживания и размораживания счетов требуется несколько изменений:
+
+- [Сопоставление (mapping)](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) адресов с [логическими значениями (booleans)](https://en.wikipedia.org/wiki/Boolean_data_type) для отслеживания замороженных адресов. Все значения изначально равны нулю, что для логических значений интерпретируется как false. Это то, что нам нужно, потому что по умолчанию аккаунты не заморожены.
+
+ ```solidity
+ mapping(address => bool) public frozenAccounts;
+ ```
+
+- [События (events)](https://www.tutorialspoint.com/solidity/solidity_events.htm), информирующие всех заинтересованных лиц о замораживании или размораживании аккаунта. Технически говоря, события не требуются для этих действий, но они помогают коду вне блокчейна (offchain) прослушивать эти события и знать, что происходит. Считается хорошим тоном, когда умный контракт генерирует их, когда происходит что-то, что может быть важно для кого-то еще.
+
+ События индексируются, поэтому можно будет найти все случаи замораживания или размораживания аккаунта.
+
+ ```solidity
+ // Когда аккаунты замораживаются или размораживаются
+ event AccountFrozen(address indexed _addr);
+ event AccountThawed(address indexed _addr);
+ ```
+
+- Функции для замораживания и размораживания аккаунтов. Эти две функции почти идентичны, поэтому мы рассмотрим только функцию заморозки.
+
+ ```solidity
+ function freezeAccount(address addr)
+ public
+ onlyOwner
+ ```
+
+ Функции, помеченные как [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm), могут вызываться из других умных контрактов или напрямую через транзакцию.
+
+ ```solidity
+ {
+ require(!frozenAccounts[addr], "Аккаунт уже заморожен");
+ frozenAccounts[addr] = true;
+ emit AccountFrozen(addr);
+ } // freezeAccount
+ ```
+
+ Если аккаунт уже заморожен, отменить транзакцию. В противном случае заморозьте его и сгенерируйте (`emit`) событие.
+
+- Измените `_beforeTokenTransfer`, чтобы предотвратить перемещение денег с замороженного аккаунта. Обратите внимание, что деньги все еще можно переводить на замороженный аккаунт.
+
+ ```solidity
+ require(!frozenAccounts[from], "Аккаунт заморожен");
+ ```
+
+### Очистка активов {#asset-cleanup}
+
+Чтобы высвободить токены ERC-20, хранящиеся в этом контракте, нам нужно вызвать функцию в контракте токена, которому они принадлежат, — либо [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer), либо [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve). В данном случае нет смысла тратить газ на разрешения (allowances), мы можем просто перевести их напрямую.
+
+```solidity
+ function cleanupERC20(
+ address erc20,
+ address dest
+ )
+ public
+ onlyOwner
+ {
+ IERC20 token = IERC20(erc20);
+```
+
+Это синтаксис для создания объекта для контракта, когда мы получаем адрес. Мы можем это сделать, потому что у нас есть определение для токенов ERC20 как часть исходного кода (см. строку 4), и этот файл включает [определение для IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), интерфейс для контракта ERC-20 от OpenZeppelin.
+
+```solidity
+ uint balance = token.balanceOf(address(this));
+ token.transfer(dest, balance);
+ }
+```
+
+Это функция очистки, поэтому, предположительно, мы не хотим оставлять никаких токенов. Вместо того чтобы получать баланс от пользователя вручную, мы можем автоматизировать этот процесс.
+
+## Заключение {#conclusion}
+
+Это не идеальное решение — идеального решения для проблемы «пользователь совершил ошибку» не существует. Однако использование подобных проверок может по крайней мере предотвратить некоторые ошибки. Возможность замораживать аккаунты, хотя и является опасной, может быть использована для ограничения ущерба от некоторых взломов, лишая хакера украденных средств.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/ethereum-for-web2-auth/index.md b/public/content/translations/ru/developers/tutorials/ethereum-for-web2-auth/index.md
new file mode 100644
index 00000000000..09a452f55ca
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/ethereum-for-web2-auth/index.md
@@ -0,0 +1,886 @@
+---
+title: "Использование Ethereum для аутентификации web2"
+description: "После прочтения этого руководства разработчик сможет интегрировать вход в систему Ethereum (web3) с входом в систему SAML — стандартом, используемым в web2 для обеспечения единого входа и других сопутствующих услуг. Это позволяет аутентифицировать доступ к ресурсам web2 с помощью подписей Ethereum, при этом атрибуты пользователя берутся из аттестаций."
+author: Ori Pomerantz
+tags: [ "web2", "аутентификация", "eas" ]
+skill: beginner
+lang: ru
+published: 2025-04-30
+---
+
+## Введение
+
+[SAML](https://www.onelogin.com/learn/saml) — это стандарт, используемый в web2, который позволяет [поставщику удостоверений (IdP)](https://en.wikipedia.org/wiki/Identity_provider#SAML_identity_provider) предоставлять информацию о пользователе [поставщикам услуг (SP)](https://en.wikipedia.org/wiki/Service_provider_\(SAML\)).
+
+В этом руководстве вы узнаете, как интегрировать подписи Ethereum с SAML, чтобы позволить пользователям использовать свои кошельки Ethereum для аутентификации в сервисах web2, которые пока не поддерживают Ethereum нативно.
+
+Обратите внимание, что это руководство предназначено для двух разных аудиторий:
+
+- Пользователи Ethereum, которые разбираются в Ethereum и хотят изучить SAML
+- Пользователи Web2, которые разбираются в SAML и аутентификации web2 и хотят изучить Ethereum
+
+В результате в нем будет много вводного материала, который вы уже знаете. Не стесняйтесь пропускать его.
+
+### SAML для пользователей Ethereum
+
+SAML — это централизованный протокол. Поставщик услуг (SP) принимает утверждения (например, "это мой пользователь John, у него должны быть разрешения на выполнение A, B и C") от поставщика удостоверений (IdP), только если у него есть предварительно установленные доверительные отношения либо с ним, либо с [центром сертификации](https://www.ssl.com/article/what-is-a-certificate-authority-ca/), который подписал сертификат этого IdP.
+
+Например, SP может быть туристическим агентством, предоставляющим туристические услуги компаниям, а IdP — внутренним веб-сайтом компании. Когда сотрудникам необходимо забронировать деловую поездку, туристическое агентство отправляет их на аутентификацию в компанию, прежде чем позволить им фактически забронировать поездку.
+
+
+
+Таким образом три сущности — браузер, SP и IdP — договариваются о доступе. SP не нужно заранее ничего знать о пользователе, использующем браузер, ему достаточно доверять IdP.
+
+### Ethereum для пользователей SAML
+
+Ethereum — это децентрализованная система.
+
+
+
+У пользователей есть приватный ключ (обычно хранящийся в расширении браузера). Из приватного ключа можно получить публичный ключ, а из него — 20-байтовый адрес. Когда пользователям необходимо войти в систему, им предлагается подписать сообщение с помощью nonce (одноразового значения). Сервер может проверить, что подпись была создана этим адресом.
+
+
+
+Подпись подтверждает только адрес Ethereum. Чтобы получить другие атрибуты пользователя, обычно используются [аттестации](https://attest.org/). Аттестация обычно содержит следующие поля:
+
+- **Аттестующий**, адрес, который сделал аттестацию
+- **Получатель**, адрес, к которому применяется аттестация
+- **Данные**, аттестуемые данные, такие как имя, разрешения и т. д.
+- **Схема**, идентификатор схемы, используемой для интерпретации данных.
+
+Из-за децентрализованной природы Ethereum любой пользователь может делать аттестации. Личность аттестующего важна для определения того, какие аттестации мы считаем надежными.
+
+## Настройка
+
+Первый шаг — обеспечить взаимодействие между SAML SP и SAML IdP.
+
+1. Загрузите программное обеспечение. Пример программного обеспечения для этой статьи находится [на GitHub](https://github.com/qbzzt/250420-saml-ethereum). Разные этапы хранятся в разных ветках, для этого этапа вам нужна ветка `saml-only`
+
+ ```sh
+ git clone https://github.com/qbzzt/250420-saml-ethereum -b saml-only
+ cd 250420-saml-ethereum
+ pnpm install
+ ```
+
+2. Создайте ключи с самоподписанными сертификатами. Это означает, что ключ является собственным центром сертификации и должен быть импортирован вручную поставщику услуг. Дополнительную информацию см. в [документации OpenSSL](https://docs.openssl.org/master/man1/openssl-req/).
+
+ ```sh
+ mkdir keys
+ cd keys
+ openssl req -new -x509 -days 365 -nodes -sha256 -out saml-sp.crt -keyout saml-sp.pem -subj /CN=sp/
+ openssl req -new -x509 -days 365 -nodes -sha256 -out saml-idp.crt -keyout saml-idp.pem -subj /CN=idp/
+ cd ..
+ ```
+
+3. Запустите серверы (и SP, и IdP)
+
+ ```sh
+ pnpm start
+ ```
+
+4. Перейдите по URL-адресу SP [http://localhost:3000/](http://localhost:3000/) и нажмите кнопку для перенаправления на IdP (порт 3001).
+
+5. Укажите свой адрес электронной почты в IdP и нажмите **Login to the service provider**. Убедитесь, что вы были перенаправлены обратно к поставщику услуг (порт 3000) и что он распознает вас по вашему адресу электронной почты.
+
+### Подробное объяснение
+
+Вот что происходит, шаг за шагом:
+
+
+
+#### src/config.mts
+
+Этот файл содержит конфигурацию как для поставщика удостоверений, так и для поставщика услуг. Обычно это две разные сущности, но здесь для простоты мы можем использовать общий код.
+
+```typescript
+const fs = await import("fs")
+
+const protocol="http"
+```
+
+Пока мы просто тестируем, поэтому можно использовать HTTP.
+
+```typescript
+export const spCert = fs.readFileSync("keys/saml-sp.crt").toString()
+export const idpCert = fs.readFileSync("keys/saml-idp.crt").toString()
+```
+
+Прочтите публичные ключи, которые обычно доступны обоим компонентам (и либо доверяются напрямую, либо подписаны доверенным центром сертификации).
+
+```typescript
+export const spPort = 3000
+export const spHostname = "localhost"
+export const spDir = "sp"
+
+export const idpPort = 3001
+export const idpHostname = "localhost"
+export const idpDir = "idp"
+
+export const spUrl = `${protocol}://${spHostname}:${spPort}/${spDir}`
+export const idpUrl = `${protocol}://${idpHostname}:${idpPort}/${idpDir}`
+```
+
+URL-адреса для обоих компонентов.
+
+```typescript
+export const spPublicData = {
+```
+
+Публичные данные для поставщика услуг.
+
+```typescript
+ entityID: `${spUrl}/metadata`,
+```
+
+По соглашению, в SAML `entityID` — это URL-адрес, по которому доступны метаданные сущности. Эти метаданные соответствуют здешним публичным данным, за исключением того, что они представлены в формате XML.
+
+```typescript
+ wantAssertionsSigned: true,
+ authnRequestsSigned: false,
+ signingCert: spCert,
+ allowCreate: true,
+ assertionConsumerService: [{
+ Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
+ Location: `${spUrl}/assertion`,
+ }]
+ }
+```
+
+Самым важным определением для наших целей является `assertionConsumerServer`. Это означает, что для утверждения чего-либо (например, "пользователь, который отправляет вам эту информацию, — somebody@example.com") поставщику услуг нам нужно использовать [HTTP POST](https://www.w3schools.com/tags/ref_httpmethods.asp) на URL-адрес `http://localhost:3000/sp/assertion`.
+
+```typescript
+export const idpPublicData = {
+ entityID: `${idpUrl}/metadata`,
+ signingCert: idpCert,
+ wantAuthnRequestsSigned: false,
+ singleSignOnService: [{
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
+ Location: `${idpUrl}/login`
+ }],
+ singleLogoutService: [{
+ Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
+ Location: `${idpUrl}/logout`
+ }],
+ }
+```
+
+Публичные данные для поставщика удостоверений похожи. В нем указано, что для входа пользователя в систему необходимо отправить POST-запрос на `http://localhost:3001/idp/login`, а для выхода — на `http://localhost:3001/idp/logout`.
+
+#### src/sp.mts
+
+Это код, который реализует поставщика услуг.
+
+```typescript
+import * as config from "./config.mts"
+const fs = await import("fs")
+const saml = await import("samlify")
+```
+
+Мы используем библиотеку [`samlify`](https://www.npmjs.com/package/samlify) для реализации SAML.
+
+```typescript
+import * as validator from "@authenio/samlify-node-xmllint"
+saml.setSchemaValidator(validator)
+```
+
+Библиотека `samlify` ожидает наличия пакета для проверки того, что XML-документ корректен, подписан ожидаемым публичным ключом и т. д. Для этой цели мы используем [`@authenio/samlify-node-xmllint`](https://www.npmjs.com/package/@authenio/samlify-node-xmllint).
+
+```typescript
+const express = (await import("express")).default
+const spRouter = express.Router()
+const app = express()
+```
+
+[`Router`](https://expressjs.com/en/5x/api.html#router) из [`express`](https://expressjs.com/) — это "мини-веб-сайт", который можно встроить в другой веб-сайт. В данном случае мы используем его для группировки всех определений поставщика услуг.
+
+```typescript
+const spPrivateKey = fs.readFileSync("keys/saml-sp.pem").toString()
+
+const sp = saml.ServiceProvider({
+ privateKey: spPrivateKey,
+ ...config.spPublicData
+})
+```
+
+Собственное представление поставщика услуг о себе — это все публичные данные и приватный ключ, который он использует для подписи информации.
+
+```typescript
+const idp = saml.IdentityProvider(config.idpPublicData);
+```
+
+Публичные данные содержат все, что поставщик услуг должен знать о поставщике удостоверений.
+
+```typescript
+spRouter.get(`/metadata`,
+ (req, res) => res.header("Content-Type", "text/xml").send(sp.getMetadata())
+)
+```
+
+Чтобы обеспечить совместимость с другими компонентами SAML, поставщики услуг и удостоверений должны предоставлять свои публичные данные (называемые метаданными) в формате XML по адресу `/metadata`.
+
+```typescript
+spRouter.post(`/assertion`,
+```
+
+Это страница, к которой обращается браузер для самоидентификации. Утверждение включает идентификатор пользователя (здесь мы используем адрес электронной почты) и может содержать дополнительные атрибуты. Это обработчик для шага 7 на диаграмме последовательности выше.
+
+```typescript
+ async (req, res) => {
+ // console.log(`SAML response:\n${Buffer.from(req.body.SAMLResponse, 'base64').toString('utf-8')}`)
+```
+
+Вы можете использовать закомментированную команду, чтобы увидеть данные XML, предоставленные в утверждении. Они [закодированы в base64](https://en.wikipedia.org/wiki/Base64).
+
+```typescript
+ try {
+ const loginResponse = await sp.parseLoginResponse(idp, 'post', req);"
+```
+
+Проанализируйте запрос на вход от сервера удостоверений.
+
+```typescript
+ res.send(`
+
+
+ Hello ${loginResponse.extract.nameID}
+
+
+ `)
+ res.send();
+```
+
+Отправьте HTML-ответ, чтобы показать пользователю, что мы получили запрос на вход.
+
+```typescript
+ } catch (err) {
+ console.error('Error processing SAML response:', err);
+ res.status(400).send('SAML authentication failed');
+ }
+ }
+)
+```
+
+Сообщите пользователю в случае сбоя.
+
+```typescript
+spRouter.get('/login',
+```
+
+Создайте запрос на вход, когда браузер пытается получить эту страницу. Это обработчик для шага 1 на диаграмме последовательности выше.
+
+```typescript
+ async (req, res) => {
+ const loginRequest = await sp.createLoginRequest(idp, "post")
+```
+
+Получите информацию для отправки запроса на вход.
+
+```typescript
+ res.send(`
+
+
+
+```
+
+Эта страница автоматически отправляет форму (см. ниже). Таким образом, пользователю не нужно ничего делать для перенаправления. Это шаг 2 на диаграмме последовательности выше.
+
+```typescript
+
+
+
+ `)
+ }
+)
+
+app.use(express.urlencoded({extended: true}))
+```
+
+[Это промежуточное ПО](https://expressjs.com/en/5x/api.html#express.urlencoded) читает тело [HTTP-запроса](https://www.tutorialspoint.com/http/http_requests.htm). По умолчанию express игнорирует его, потому что большинство запросов этого не требуют. Нам это нужно, потому что POST использует тело запроса.
+
+```typescript
+app.use(`/${config.spDir}`, spRouter)
+```
+
+Подключите маршрутизатор в каталоге поставщика услуг (`/sp`).
+
+```typescript
+app.get("/", (req, res) => {
+ res.send(`
+
+
+
+
+
+ `)
+})
+```
+
+Если браузер пытается получить корневой каталог, предоставьте ему ссылку на страницу входа.
+
+```typescript
+app.listen(config.spPort, () => {
+ console.log(`service provider is running on http://${config.spHostname}:${config.spPort}`)
+})
+```
+
+Прослушивайте `spPort` с помощью этого приложения express.
+
+#### src/idp.mts
+
+Это поставщик удостоверений. Он очень похож на поставщика услуг, приведенные ниже объяснения относятся к тем частям, которые отличаются.
+
+```typescript
+const xmlParser = new (await import("fast-xml-parser")).XMLParser(
+ {
+ ignoreAttributes: false, // Сохранять атрибуты
+ attributeNamePrefix: "@_", // Префикс для атрибутов
+ }
+)
+```
+
+Нам нужно прочитать и понять XML-запрос, который мы получаем от поставщика услуг.
+
+```typescript
+const getLoginPage = requestId => `
+```
+
+Эта функция создает страницу с автоматически отправляемой формой, которая возвращается на шаге 4 диаграммы последовательности выше.
+
+```typescript
+
+
+ Страница входа
+
+
+ Страница входа
+
+
+
+
+const idpRouter = express.Router()
+
+idpRouter.post("/loginSubmitted", async (req, res) => {
+ const loginResponse = await idp.createLoginResponse(
+```
+
+Это обработчик для шага 5 на диаграмме последовательности выше. [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125) создает ответ на запрос входа.
+
+```typescript
+ sp,
+ {
+ authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport',
+ audience: sp.entityID,
+```
+
+Аудитория — это поставщик услуг.
+
+```typescript
+ extract: {
+ request: {
+ id: req.body.requestId
+ }
+ },
+```
+
+Информация, извлеченная из запроса. Единственный параметр, который нас интересует в запросе, — это requestId, который позволяет поставщику услуг сопоставлять запросы и ответы на них.
+
+```typescript
+ signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // Обеспечить подпись
+```
+
+Нам нужен `signingKey` для получения данных для подписи ответа. Поставщик услуг не доверяет неподписанным запросам.
+
+```typescript
+ },
+ "post",
+ {
+ email: req.body.email
+```
+
+Это поле с информацией о пользователе, которую мы отправляем обратно поставщику услуг.
+
+```typescript
+ }
+ );
+
+ res.send(`
+
+
+
+
+
+
+
+ `)
+})
+```
+
+Опять же, используйте автоматически отправляемую форму. Это шаг 6 на диаграмме последовательности выше.
+
+```typescript
+
+// Конечная точка IdP для запросов на вход
+idpRouter.post(`/login`,
+```
+
+Это конечная точка, которая получает запрос на вход от поставщика услуг. Это обработчик для шага 3 на диаграмме последовательности выше.
+
+```typescript
+ async (req, res) => {
+ try {
+ // Обходной путь, потому что мне не удалось заставить parseLoginRequest работать.
+ // const loginRequest = await idp.parseLoginRequest(sp, 'post', req)
+ const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8'))
+ res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"]))
+```
+
+Мы должны иметь возможность использовать [`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144) для чтения ID запроса на аутентификацию. Однако мне не удалось заставить его работать, и не стоило тратить на это много времени, поэтому я просто использую [XML-парсер общего назначения](https://www.npmjs.com/package/fast-xml-parser). Информация, которая нам нужна, — это атрибут `ID` внутри тега ``, который находится на верхнем уровне XML.
+
+## Использование подписей Ethereum
+
+Теперь, когда мы можем отправлять идентификатор пользователя поставщику услуг, следующий шаг — получить идентификатор пользователя надежным способом. Viem позволяет нам просто запросить у кошелька адрес пользователя, но это означает запрос информации у браузера. Мы не контролируем браузер, поэтому не можем автоматически доверять ответу, который мы от него получаем.
+
+Вместо этого IdP отправит браузеру строку для подписи. Если кошелек в браузере подписывает эту строку, это означает, что это действительно тот самый адрес (то есть он знает приватный ключ, соответствующий этому адресу).
+
+Чтобы увидеть это в действии, остановите существующие IdP и SP и выполните следующие команды:
+
+```sh
+git checkout eth-signatures
+pnpm install
+pnpm start
+```
+
+Затем перейдите [к SP](http://localhost:3000) и следуйте инструкциям.
+
+Обратите внимание, что на данном этапе мы не знаем, как получить адрес электронной почты из адреса Ethereum, поэтому вместо этого мы сообщаем SP `<адрес Ethereum>@bad.email.address`.
+
+### Подробное объяснение
+
+Изменения касаются шагов 4-5 на предыдущей диаграмме.
+
+
+
+Единственный файл, который мы изменили, — `idp.mts`. Вот измененные части.
+
+```typescript
+import { v4 as uuidv4 } from 'uuid'
+import { verifyMessage } from 'viem'
+```
+
+Нам нужны эти две дополнительные библиотеки. Мы используем [`uuid`](https://www.npmjs.com/package/uuid) для создания значения [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce). Само значение не имеет значения, важен лишь тот факт, что оно используется только один раз.
+
+Библиотека [`viem`](https://viem.sh/) позволяет нам использовать определения Ethereum. Здесь она нужна нам для проверки действительности подписи.
+
+```typescript
+const loginPrompt = "Чтобы получить доступ к поставщику услуг, подпишите этот nonce: "
+```
+
+Кошелек запрашивает у пользователя разрешение на подписание сообщения. Сообщение, которое является просто nonce, может сбить с толку пользователей, поэтому мы включаем это приглашение.
+
+```typescript
+// Храните здесь requestID
+let nonces = {}
+```
+
+Нам нужна информация о запросе, чтобы иметь возможность ответить на него. Мы могли бы отправить ее с запросом (шаг 4) и получить обратно (шаг 5). Однако мы не можем доверять информации, которую получаем от браузера, находящегося под контролем потенциально враждебного пользователя. Поэтому лучше хранить ее здесь, используя nonce в качестве ключа.
+
+Обратите внимание, что для простоты мы делаем это здесь в виде переменной. Однако у этого есть несколько недостатков:
+
+- Мы уязвимы для атаки типа «отказ в обслуживании». Злонамеренный пользователь может попытаться войти в систему несколько раз, заполнив нашу память.
+- Если процесс IdP необходимо перезапустить, мы потеряем существующие значения.
+- Мы не можем распределять нагрузку между несколькими процессами, потому что у каждого будет своя переменная.
+
+В производственной системе мы бы использовали базу данных и реализовали какой-либо механизм истечения срока действия.
+
+```typescript
+const getSignaturePage = requestId => {
+ const nonce = uuidv4()
+ nonces[nonce] = requestId
+```
+
+Создайте nonce и сохраните `requestId` для будущего использования.
+
+```typescript
+ return `
+
+
+
+
+
+ Пожалуйста, подпишите
+
+
+
+
+
+`
+}
+```
+
+Остальное — просто стандартный HTML.
+
+```typescript
+idpRouter.get("/signature/:nonce/:account/:signature", async (req, res) => {
+```
+
+Это обработчик для шага 5 на диаграмме последовательности.
+
+```typescript
+ const requestId = nonces[req.params.nonce]
+ if (requestId === undefined) {
+ res.send("Bad nonce")
+ return ;
+ }
+
+ nonces[req.params.nonce] = undefined
+```
+
+Получите ID запроса и удалите nonce из `nonces`, чтобы убедиться, что его нельзя использовать повторно.
+
+```typescript
+ try {
+```
+
+Поскольку существует так много способов, которыми подпись может быть недействительной, мы оборачиваем это в `try ...` блок `catch`, чтобы перехватить любые возникающие ошибки.
+
+```typescript
+ const validSignature = await verifyMessage({
+ address: req.params.account,
+ message: `${loginPrompt}${req.params.nonce}`,
+ signature: req.params.signature
+ })
+```
+
+Используйте [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage#verifymessage) для реализации шага 5.5 на диаграмме последовательности.
+
+```typescript
+ if (!validSignature)
+ throw("Bad signature")
+ } catch (err) {
+ res.send("Error:" + err)
+ return ;
+ }
+```
+
+Остальная часть обработчика эквивалентна тому, что мы делали в обработчике `/loginSubmitted` ранее, за исключением одного небольшого изменения.
+
+```typescript
+ const loginResponse = await idp.createLoginResponse(
+ .
+ .
+ .
+ {
+ email: req.params.account + "@bad.email.address"
+ }
+ );
+```
+
+У нас нет фактического адреса электронной почты (мы получим его в следующем разделе), поэтому пока мы возвращаем адрес Ethereum и четко помечаем его как не являющийся адресом электронной почты.
+
+```typescript
+// Конечная точка IdP для запросов на вход
+idpRouter.post(`/login`,
+ async (req, res) => {
+ try {
+ // Обходной путь, потому что мне не удалось заставить parseLoginRequest работать.
+ // const loginRequest = await idp.parseLoginRequest(sp, 'post', req)
+ const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8'))
+ res.send(getSignaturePage(samlRequest["samlp:AuthnRequest"]["@_ID"]))
+ } catch (err) {
+ console.error('Error processing SAML response:', err);
+ res.status(400).send('SAML authentication failed');
+ }
+ }
+)
+```
+
+Вместо `getLoginPage` теперь используйте `getSignaturePage` в обработчике шага 3.
+
+## Получение адреса электронной почты
+
+Следующий шаг — получение адреса электронной почты, идентификатора, запрошенного поставщиком услуг. Для этого мы используем [Ethereum Attestation Service (EAS)](https://attest.org/).
+
+Самый простой способ получить аттестации — использовать [GraphQL API](https://docs.attest.org/docs/developer-tools/api). Мы используем этот запрос:
+
+```
+query GetAttestationsByRecipient {
+ attestations(
+ where: {
+ recipient: { equals: "${getAddress(ethAddr)}" }
+ schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" }
+ }
+ take: 1
+ ) {
+ data
+ id
+ attester
+ }
+}
+```
+
+Этот [`schemaId`](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) включает только адрес электронной почты. Этот запрос запрашивает аттестации этой схемы. Субъект аттестации называется `recipient`. Это всегда адрес Ethereum.
+
+Внимание: способ получения аттестаций здесь имеет две проблемы с безопасностью.
+
+- Мы обращаемся к конечной точке API, `https://optimism.easscan.org/graphql`, которая является централизованным компонентом. Мы можем получить атрибут `id`, а затем выполнить поиск он-чейн, чтобы проверить, что аттестация реальна, но конечная точка API все еще может подвергать цензуре аттестации, не сообщая нам о них.
+
+ Эту проблему можно решить: мы могли бы запустить собственную конечную точку GraphQL и получать аттестации из логов цепи, но это излишне для наших целей.
+
+- Мы не смотрим на личность аттестующего. Любой может предоставить нам ложную информацию. В реальной реализации у нас был бы набор доверенных аттестующих, и мы бы рассматривали только их аттестации.
+
+Чтобы увидеть это в действии, остановите существующие IdP и SP и выполните следующие команды:
+
+```sh
+git checkout email-address
+pnpm install
+pnpm start
+```
+
+Затем укажите свой адрес электронной почты. У вас есть два способа сделать это:
+
+- Импортируйте кошелек, используя приватный ключ, и используйте тестовый приватный ключ `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`.
+
+- Добавьте аттестацию для своего собственного адреса электронной почты:
+
+ 1. Перейдите к [схеме в обозревателе аттестаций](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977).
+
+ 2. Нажмите **Attest with Schema**.
+
+ 3. Введите свой адрес Ethereum в качестве получателя, свой адрес электронной почты в качестве адреса электронной почты и выберите **Onchain**. Затем нажмите **Make Attestation**.
+
+ 4. Одобрите транзакцию в своем кошельке. Вам понадобится немного ETH в [блокчейне Optimism](https://app.optimism.io/bridge/deposit), чтобы заплатить за газ.
+
+В любом случае, после этого перейдите по адресу [http://localhost:3000](http://localhost:3000) и следуйте инструкциям. Если вы импортировали тестовый приватный ключ, вы получите электронное письмо `test_addr_0@example.com`. Если вы использовали свой собственный адрес, это должно быть то, что вы аттестовали.
+
+### Подробное объяснение
+
+
+
+Новые шаги — это взаимодействие GraphQL, шаги 5.6 и 5.7.
+
+И снова, вот измененные части `idp.mts`.
+
+```typescript
+import { GraphQLClient } from 'graphql-request'
+import { SchemaEncoder } from '@ethereum-attestation-service/eas-sdk'
+```
+
+Импортируйте необходимые нам библиотеки.
+
+```typescript
+const graphqlEndpointUrl = "https://optimism.easscan.org/graphql"
+```
+
+Для каждого блокчейна существует [отдельная конечная точка](https://docs.attest.org/docs/developer-tools/api).
+
+```typescript
+const graphqlClient = new GraphQLClient(graphqlEndpointUrl, { fetch })
+```
+
+Создайте новый клиент `GraphQLClient`, который мы можем использовать для запросов к конечной точке.
+
+```typescript
+const graphqlSchema = 'string emailAddress'
+const graphqlEncoder = new SchemaEncoder(graphqlSchema)
+```
+
+GraphQL дает нам только непрозрачный объект данных с байтами. Чтобы понять его, нам нужна схема.
+
+```typescript
+const ethereumAddressToEmail = async ethAddr => {
+```
+
+Функция для получения адреса электронной почты из адреса Ethereum.
+
+```typescript
+ const query = `
+ query GetAttestationsByRecipient {
+```
+
+Это GraphQL-запрос.
+
+```typescript
+ attestations(
+```
+
+Мы ищем аттестации.
+
+```typescript
+ where: {
+ recipient: { equals: "${getAddress(ethAddr)}" }
+ schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" }
+ }
+```
+
+Аттестации, которые нам нужны, — это те, что находятся в нашей схеме, где получателем является `getAddress(ethAddr)`. Функция [`getAddress`](https://viem.sh/docs/utilities/getAddress#getaddress) гарантирует, что наш адрес имеет правильную [контрольную сумму](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md). Это необходимо, поскольку GraphQL чувствителен к регистру. "0xBAD060A7", "0xBad060A7" и "0xbad060a7" — это разные значения.
+
+```typescript
+ take: 1
+```
+
+Независимо от того, сколько аттестаций мы найдем, нам нужна только первая.
+
+```typescript
+ ) {
+ data
+ id
+ attester
+ }
+ }`
+```
+
+Поля, которые мы хотим получить.
+
+- `attester`: адрес, который отправил аттестацию. Обычно это используется для принятия решения о том, доверять ли аттестации.
+- `id`: идентификатор аттестации. Вы можете использовать это значение, чтобы [прочитать аттестацию он-чейн](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000021?tab=read_proxy&source_address=0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088#0xa3112a64) и проверить, верна ли информация из запроса GraphQL.
+- `data`: данные схемы (в данном случае адрес электронной почты).
+
+```typescript
+ const queryResult = await graphqlClient.request(query)
+
+ if (queryResult.attestations.length == 0)
+ return "no_address@available.is"
+```
+
+Если аттестации нет, верните очевидно неверное значение, которое, однако, будет выглядеть действительным для поставщика услуг.
+
+```typescript
+ const attestationDataFields = graphqlEncoder.decodeData(queryResult.attestations[0].data)
+ return attestationDataFields[0].value.value
+}
+```
+
+Если значение есть, используйте `decodeData` для его декодирования. Нам не нужны предоставляемые метаданные, только само значение.
+
+```typescript
+ const loginResponse = await idp.createLoginResponse(
+ sp,
+ {
+ .
+ .
+ .
+ },
+ "post",
+ {
+ email: await ethereumAddressToEmail(req.params.account)
+ }
+ );
+```
+
+Используйте новую функцию для получения адреса электронной почты.
+
+## Что насчет децентрализации?
+
+В этой конфигурации пользователи не могут выдавать себя за кого-то другого, пока мы полагаемся на надежных аттестующих для сопоставления адресов Ethereum с адресами электронной почты. Однако наш поставщик удостоверений по-прежнему является централизованным компонентом. Любой, у кого есть приватный ключ поставщика удостоверений, может отправить ложную информацию поставщику услуг.
+
+Возможно, есть решение с использованием [многосторонних вычислений (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation). Я надеюсь написать об этом в будущем руководстве.
+
+## Заключение
+
+Внедрение стандарта входа в систему, такого как подписи Ethereum, сталкивается с проблемой «курицы и яйца». Поставщики услуг хотят привлечь как можно более широкий рынок. Пользователи хотят иметь возможность получать доступ к услугам, не беспокоясь о поддержке своего стандарта входа.
+Создание адаптеров, таких как Ethereum IdP, может помочь нам преодолеть это препятствие.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/ru/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md
new file mode 100644
index 00000000000..ceaf99ff00a
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md
@@ -0,0 +1,156 @@
+---
+title: "Начало разработки Ethereum"
+description: "Это руководство для начинающих по разработке на Ethereum. Мы проведем вас от развертывания конечной точки API и выполнения запроса в командной строке до написания вашего первого скрипта web3! Опыт разработки на блокчейне не требуется!"
+author: "Elan Halpern"
+tags:
+ [
+ "JavaScript",
+ "ethers.js",
+ "узлы",
+ "запросы",
+ "Alchemy"
+ ]
+skill: beginner
+lang: ru
+published: 2020-10-30
+source: Medium
+sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-development-using-alchemy-c3d6a45c567f
+---
+
+
+
+Это руководство для начинающих по разработке на Ethereum. В этом руководстве мы будем использовать [Alchemy](https://alchemyapi.io/), ведущую платформу для разработчиков блокчейна, которая обслуживает миллионы пользователей из 70 % лучших блокчейн-приложений, включая Maker, 0x, MyEtherWallet, Dharma и Kyber. Alchemy предоставит нам доступ к конечной точке API в сети Ethereum, чтобы мы могли читать и записывать транзакции.
+
+Мы проведем вас от регистрации в Alchemy до написания вашего первого скрипта web3! Опыт разработки на блокчейне не требуется!
+
+## 1. Зарегистрируйте бесплатный аккаунт Alchemy {#sign-up-for-a-free-alchemy-account}
+
+Создать аккаунт в Alchemy легко, [зарегистрируйтесь бесплатно здесь](https://auth.alchemy.com/).
+
+## 2. Создайте приложение Alchemy {#create-an-alchemy-app}
+
+Чтобы взаимодействовать с сетью Ethereum и использовать продукты Alchemy, вам понадобится ключ API для аутентификации ваших запросов.
+
+Вы можете [создать ключи API на панели управления](https://dashboard.alchemy.com/). Чтобы создать новый ключ, перейдите в раздел «Create App» (Создать приложение), как показано ниже:
+
+Отдельная благодарность [_ShapeShift_](https://shapeshift.com/) _за то, что позволили нам показать их панель управления!_
+
+
+
+Заполните данные в разделе «Create App» (Создать приложение), чтобы получить новый ключ. Здесь вы также можете увидеть приложения, которые вы создали ранее, и те, которые создала ваша команда. Получите существующие ключи, нажав «View Key» (Просмотреть ключ) для любого приложения.
+
+
+
+Вы также можете получить существующие ключи API, наведя курсор на «Apps» (Приложения) и выбрав одно из них. Здесь вы можете выбрать «View Key» (Просмотреть ключ), а также «Edit App» (Редактировать приложение), чтобы внести определенные домены в белый список, просмотреть несколько инструментов для разработчиков и аналитику.
+
+
+
+## 3. Сделайте запрос из командной строки {#make-a-request-from-the-command-line}
+
+Взаимодействуйте с блокчейном Ethereum через Alchemy, используя JSON-RPC и curl.
+
+Для запросов вручную мы рекомендуем взаимодействовать с `JSON-RPC` через `POST`-запросы. Просто передайте заголовок `Content-Type: application/json` и ваш запрос в качестве тела `POST`-запроса со следующими полями:
+
+- `jsonrpc`: версия JSON-RPC — в настоящее время поддерживается только `2.0`.
+- `method`: метод ETH API. [См. справочник по API.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc)
+- `params`: список параметров для передачи в метод.
+- `id`: идентификатор вашего запроса. Он будет возвращен в ответе, чтобы вы могли отслеживать, к какому запросу относится ответ.
+
+Вот пример, который можно запустить из командной строки, чтобы получить текущую цену на газ:
+
+```bash
+curl https://eth-mainnet.alchemyapi.io/v2/demo \
+-X POST \
+-H "Content-Type: application/json" \
+-d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}'
+```
+
+_**ПРИМЕЧАНИЕ.** Замените [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) на свой собственный ключ API `https://eth-mainnet.alchemyapi.io/v2/**your-api-key`._
+
+**Результаты:**
+
+```json
+{ "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 }
+```
+
+## 4. Настройте свой клиент Web3 {#set-up-your-web3-client}
+
+**Если у вас уже есть клиент,** измените URL-адрес текущего провайдера узла на URL-адрес Alchemy с вашим ключом API: `“https://eth-mainnet.alchemyapi.io/v2/your-api-key"`
+
+**_ПРИМЕЧАНИЕ:_** Приведенные ниже скрипты необходимо запускать в **контексте node** или **сохранять в файл**, а не запускать из командной строки. Если у вас еще не установлены Node или npm, ознакомьтесь с этим кратким [руководством по настройке для Mac](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs).
+
+Существует множество [библиотек Web3](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries), которые можно интегрировать с Alchemy, однако мы рекомендуем использовать [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), прямую замену web3.js, созданную и настроенную для бесперебойной работы с Alchemy. Это дает множество преимуществ, таких как автоматические повторные попытки и надежная поддержка WebSocket.
+
+Чтобы установить AlchemyWeb3.js, **перейдите в каталог вашего проекта** и выполните:
+
+**С помощью Yarn:**
+
+```
+yarn add @alch/alchemy-web3
+```
+
+**С помощью NPM:**
+
+```
+npm install @alch/alchemy-web3
+```
+
+Чтобы взаимодействовать с инфраструктурой узлов Alchemy, запустите в NodeJS или добавьте это в файл JavaScript:
+
+```js
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(
+ "https://eth-mainnet.alchemyapi.io/v2/your-api-key"
+)
+```
+
+## 5. Напишите свой первый скрипт Web3! {#write-your-first-web3-script}
+
+Теперь, чтобы немного попрактиковаться в программировании на web3, мы напишем простой скрипт, который выводит номер последнего блока из основной сети Ethereum.
+
+**1. Если вы еще этого не сделали, создайте в своем терминале новый каталог проекта и перейдите в него с помощью cd:**
+
+```
+mkdir web3-example
+cd web3-example
+```
+
+**2. Установите зависимость Alchemy web3 (или любую другую web3) в свой проект, если вы еще этого не сделали:**
+
+```
+npm install @alch/alchemy-web3
+```
+
+**3. Создайте файл с именем `index.js` и добавьте в него следующее содержимое:**
+
+> В конечном итоге вы должны заменить `demo` своим ключом HTTP API от Alchemy.
+
+```js
+async function main() {
+ const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+ const web3 = createAlchemyWeb3("https://eth-mainnet.alchemyapi.io/v2/demo")
+ const blockNumber = await web3.eth.getBlockNumber()
+ console.log("Последний номер блока: " + blockNumber)
+}
+main()
+```
+
+Не знакомы с асинхронностью? Ознакомьтесь с этой [статьей на Medium](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c).
+
+**4.** Запустите его в терминале с помощью node\*\*
+
+```
+node index.js
+```
+
+**5.** Теперь вы должны увидеть вывод последнего номера блока в вашей консоли!\*\*
+
+```
+Последний номер блока: 11043912
+```
+
+**Ура! Поздравляем! Вы только что написали свой первый скрипт web3 с помощью Alchemy 🎉**
+
+Не знаете, что делать дальше? Попробуйте развернуть свой первый смарт-контракт и попрактиковаться в программировании на Solidity с помощью нашего [руководства по созданию смарт-контракта Hello World](https://www.alchemy.com/docs/hello-world-smart-contract) или проверьте свои знания о панели управления с помощью [демо-приложения Dashboard](https://docs.alchemyapi.io/tutorials/demo-app)!
+
+_[Зарегистрируйтесь в Alchemy бесплатно](https://auth.alchemy.com/), ознакомьтесь с нашей [документацией](https://www.alchemy.com/docs/), а чтобы быть в курсе последних новостей, подписывайтесь на нас в [Twitter](https://twitter.com/AlchemyPlatform)_.
diff --git a/public/content/translations/ru/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/ru/developers/tutorials/guide-to-smart-contract-security-tools/index.md
new file mode 100644
index 00000000000..cdb6f6e52ce
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/guide-to-smart-contract-security-tools/index.md
@@ -0,0 +1,102 @@
+---
+title: "Руководство по инструментам безопасности смарт-контрактов"
+description: "Обзор трех различных методов тестирования и анализа программ"
+author: "Trailofbits"
+lang: ru
+tags: [ "Solidity", "Умные контракты", "безопасность" ]
+skill: intermediate
+published: 2020-09-07
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis
+---
+
+Мы будем использовать три различных метода тестирования и анализа программ:
+
+- **Статический анализ с помощью [Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/).** Все пути программы аппроксимируются и анализируются одновременно через различные представления программы (например, граф потока управления).
+- **Фазинг с помощью [Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/).** Код выполняется с псевдослучайной генерацией транзакций. Фазер попытается найти последовательность транзакций для нарушения заданного свойства.
+- **Символическое выполнение с помощью [Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/).** Метод формальной верификации, который преобразует каждый путь выполнения в математическую формулу, для которой можно проверить ограничения.
+
+Каждый метод имеет свои преимущества и недостатки и будет полезен в [конкретных случаях](#determining-security-properties):
+
+| Метод | Инструмент | Использование | Скорость | Пропущенные ошибки | Ложные срабатывания |
+| ------------------------ | ---------- | --------------------------- | -------- | ------------------ | ------------------- |
+| Статический анализ | Slither | CLI и скрипты | секунд | Средний уровень | Низкий уровень |
+| Фазинг | Echidna | Свойства Solidity | минут | Низкий уровень | Отсутствуют |
+| Символическое выполнение | Manticore | Свойства Solidity и скрипты | часа | Отсутствуют\* | Отсутствуют |
+
+\* если все пути исследованы без тайм-аута
+
+**Slither** анализирует контракты за считаные секунды, однако статический анализ может приводить к ложным срабатываниям и будет менее пригоден для сложных проверок (например, арифметических). Запускайте Slither через API для простого доступа к встроенным детекторам или через API для пользовательских проверок.
+
+Выполнение **Echidna** занимает несколько минут, и она выдает только истинно-положительные результаты. Echidna проверяет предоставленные пользователем свойства безопасности, написанные на Solidity. Она может пропускать ошибки, поскольку основана на случайном исследовании.
+
+**Manticore** выполняет самый "тяжеловесный" анализ. Как и Echidna, Manticore проверяет предоставленные пользователем свойства. Ее выполнение занимает больше времени, но она может доказать достоверность свойства и не сообщает о ложных срабатываниях.
+
+## Предлагаемый рабочий процесс {#suggested-workflow}
+
+Начните со встроенных детекторов Slither, чтобы убедиться, что простые ошибки отсутствуют сейчас и не появятся позже. Используйте Slither для проверки свойств, связанных с наследованием, зависимостями переменных и структурными проблемами. По мере роста кодовой базы используйте Echidna для тестирования более сложных свойств конечного автомата. Вернитесь к Slither для разработки пользовательских проверок для защиты, недоступной в Solidity, например, для защиты от переопределения функции. Наконец, используйте Manticore для целенаправленной проверки критически важных свойств безопасности, например, арифметических операций.
+
+- Используйте CLI Slither для выявления распространенных проблем
+- Используйте Echidna для тестирования высокоуровневых свойств безопасности вашего контракта
+- Используйте Slither для написания пользовательских статических проверок
+- Используйте Manticore, когда вам потребуется углубленная проверка критически важных свойств безопасности
+
+**Примечание о модульных тестах**. Модульные тесты необходимы для создания высококачественного программного обеспечения. Однако эти методы не очень подходят для поиска уязвимостей в системе безопасности. Обычно они используются для тестирования позитивного поведения кода (т. е. код работает так, как ожидалось в обычном контексте), в то время как уязвимости в системе безопасности, как правило, находятся в крайних случаях, которые разработчики не учли. В нашем исследовании десятков аудитов безопасности смарт-контрактов [покрытие модульными тестами не повлияло на количество или серьезность уязвимостей](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/), которые мы обнаружили в коде наших клиентов.
+
+## Определение свойств безопасности {#determining-security-properties}
+
+Чтобы эффективно тестировать и проверять ваш код, вы должны определить области, требующие внимания. Поскольку ваши ресурсы, затрачиваемые на безопасность, ограничены, важно определить слабые или наиболее ценные части вашей кодовой базы, чтобы оптимизировать ваши усилия. Моделирование угроз может помочь. Рассмотрите следующие материалы:
+
+- [Быстрая оценка рисков (Rapid Risk Assessments)](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (наш предпочтительный подход при нехватке времени)
+- [Руководство по моделированию угроз для систем, ориентированных на данные (Guide to Data-Centric System Threat Modeling)](https://csrc.nist.gov/pubs/sp/800/154/ipd) (также известно как NIST 800-154)
+- [Моделирование угроз по Шостаку (Shostack threat modeling)](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998)
+- [STRIDE](https://wikipedia.org/wiki/STRIDE_\(security\)) / [DREAD](https://wikipedia.org/wiki/DREAD_\(risk_assessment_model\))
+- [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.)
+- [Использование утверждений (Use of Assertions)](https://blog.regehr.org/archives/1091)
+
+### Компоненты {#components}
+
+Знание того, что вы хотите проверить, также поможет вам выбрать правильный инструмент.
+
+Общие области, которые часто актуальны для смарт-контрактов, включают в себя:
+
+- **Конечный автомат.** Большинство контрактов можно представить в виде конечного автомата. Рассмотрите возможность проверки того, что (1) недопустимое состояние не может быть достигнуто, (2) если состояние является допустимым, оно может быть достигнуто и (3) никакое состояние не блокирует контракт.
+
+ - Echidna и Manticore — предпочтительные инструменты для тестирования спецификаций конечного автомата.
+
+- **Средства контроля доступа.** Если в вашей системе есть привилегированные пользователи (например, владелец, контроллеры и т. д.) вы должны убедиться, что (1) каждый пользователь может выполнять только разрешенные действия и (2) ни один пользователь не может заблокировать действия более привилегированного пользователя.
+
+ - Slither, Echidna и Manticore могут проверять правильность контроля доступа. Например, Slither может проверить, что только у функций из белого списка отсутствует модификатор onlyOwner. Echidna и Manticore полезны для более сложного контроля доступа, например, когда разрешение предоставляется только в том случае, если контракт достигает определенного состояния.
+
+- **Арифметические операции.** Проверка правильности арифметических операций имеет решающее значение. Использование `SafeMath` повсеместно — это хороший шаг для предотвращения переполнения/потери значимости, однако вам все равно нужно учитывать другие арифметические недостатки, включая проблемы с округлением и недостатки, которые блокируют контракт.
+
+ - Manticore — лучший выбор в этом случае. Echidna можно использовать, если арифметика выходит за рамки возможностей решателя SMT.
+
+- **Корректность наследования.** Контракты Solidity в значительной степени полагаются на множественное наследование. Можно легко допустить такие ошибки, как отсутствие вызова `super` в затеняющей функции и неправильно интерпретированный порядок линеаризации c3.
+
+ - Slither — это инструмент для обеспечения обнаружения этих проблем.
+
+- **Внешние взаимодействия.** Контракты взаимодействуют друг с другом, и некоторым внешним контрактам не следует доверять. Например, если ваш контракт полагается на внешние оракулы, останется ли он безопасным, если половина доступных оракулов будет скомпрометирована?
+
+ - Manticore и Echidna — лучший выбор для тестирования внешних взаимодействий с вашими контрактами. У Manticore есть встроенный механизм для создания заглушек для внешних контрактов.
+
+- **Соответствие стандартам.** Стандарты Ethereum (например, ERC20) имеют историю недостатков в своей конструкции. Помните об ограничениях стандарта, на котором вы строите.
+ - Slither, Echidna и Manticore помогут вам обнаружить отклонения от заданного стандарта.
+
+### Шпаргалка по выбору инструментов {#tool-selection-cheatsheet}
+
+| Компонент | Инструменты | Примеры программ |
+| ------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Конечный автомат | Echidna, Manticore | |
+| Контроль доступа | Slither, Echidna, Manticore | [Упражнение 2 для Slither](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md), [Упражнение 2 для Echidna](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) |
+| Арифметические операции | Manticore, Echidna | [Упражнение 1 для Echidna](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md), [Упражнения 1–3 для Manticore](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) |
+| Корректность наследования | Slither | [Упражнение 1 для Slither](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) |
+| Внешние взаимодействия | Manticore, Echidna | |
+| Соответствие стандартам | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) |
+
+В зависимости от ваших целей необходимо будет проверить и другие области, но эти общие области внимания являются хорошей отправной точкой для любой системы смарт-контрактов.
+
+Наши публичные аудиты содержат примеры проверенных или протестированных свойств. Рекомендуем прочитать разделы `Automated Testing and Verification` (Автоматическое тестирование и проверка) следующих отчетов, чтобы ознакомиться с реальными свойствами безопасности:
+
+- [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf)
+- [Balancer](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf)
diff --git a/public/content/translations/ru/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/ru/developers/tutorials/hello-world-smart-contract-fullstack/index.md
new file mode 100644
index 00000000000..11460fb1922
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/hello-world-smart-contract-fullstack/index.md
@@ -0,0 +1,1544 @@
+---
+title: "Смарт-контракт Hello World для начинающих — полный стек"
+description: "Вводное руководство по написанию и развертыванию простого смарт-контракта на Ethereum."
+author: "nstrike2"
+tags:
+ [
+ "Solidity",
+ "hardhat",
+ "alchemy",
+ "Умные контракты",
+ "развертывание",
+ "обозреватель блоков",
+ "интерфейс",
+ "транзакции"
+ ]
+skill: beginner
+lang: ru
+published: 2021-10-25
+---
+
+Это руководство для вас, если вы новичок в разработке блокчейна и не знаете, с чего начать или как развертывать смарт-контракты и взаимодействовать с ними. Мы рассмотрим создание и развертывание простого смарт-контракта в тестовой сети Goerli с использованием [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org) и [Alchemy](https://alchemy.com/eth).
+
+Для выполнения этого руководства вам понадобится аккаунт Alchemy. [Зарегистрируйте бесплатный аккаунт](https://www.alchemy.com/).
+
+Если у вас возникнут вопросы, обращайтесь в [Discord Alchemy](https://discord.gg/gWuC7zB)!
+
+## Часть 1. Создание и развертывание вашего смарт-контракта с помощью Hardhat {#part-1}
+
+### Подключение к сети Ethereum {#connect-to-the-ethereum-network}
+
+Существует много способов отправлять запросы в сеть Ethereum. Для простоты мы будем использовать бесплатный аккаунт на Alchemy, платформе для разработчиков блокчейна и API, которая позволяет нам взаимодействовать с блокчейном Ethereum без необходимости запускать собственный узел. Alchemy также имеет инструменты для разработчиков для мониторинга и аналитики; мы воспользуемся ими в этом руководстве, чтобы понять, что происходит «под капотом» при развертывании нашего смарт-контракта.
+
+### Создайте свое приложение и ключ API {#create-your-app-and-api-key}
+
+После создания аккаунта Alchemy вы можете сгенерировать ключ API, создав приложение. Это позволит вам делать запросы к тестовой сети Goerli. Если вы не знакомы с тестовыми сетями, вы можете [прочитать руководство Alchemy по выбору сети](https://www.alchemy.com/docs/choosing-a-web3-network).
+
+На панели инструментов Alchemy найдите выпадающее меню **Приложения** на панели навигации и нажмите **Создать приложение**.
+
+
+
+Дайте вашему приложению имя «_Hello World_» и напишите краткое описание. Выберите **Staging** в качестве среды и **Goerli** в качестве сети.
+
+
+
+_Примечание: обязательно выберите **Goerli**, иначе это руководство не будет работать._
+
+Нажмите **Создать приложение**. Ваше приложение появится в таблице ниже.
+
+### Создайте аккаунт Ethereum {#create-an-ethereum-account}
+
+Вам нужен аккаунт Ethereum для отправки и получения транзакций. Мы будем использовать MetaMask, виртуальный кошелек в браузере, который позволяет пользователям управлять адресом своего аккаунта Ethereum.
+
+Вы можете бесплатно скачать и создать аккаунт MetaMask [здесь](https://metamask.io/download). При создании аккаунта или если у вас уже есть аккаунт, убедитесь, что вы переключились на «тестовую сеть Goerli» в правом верхнем углу (чтобы мы не имели дело с реальными деньгами).
+
+### Шаг 4. Добавьте эфир из крана (Faucet) {#step-4-add-ether-from-a-faucet}
+
+Чтобы развернуть свой смарт-контракт в тестовой сети, вам понадобится немного тестовых ETH. Чтобы получить ETH в сети Goerli, перейдите в кран Goerli и введите адрес своего аккаунта Goerli. Обратите внимание, что краны Goerli в последнее время могут быть немного ненадежными — смотрите [страницу тестовых сетей](/developers/docs/networks/#goerli) для списка вариантов, которые можно попробовать:
+
+_Примечание: из-за перегрузки сети это может занять некоторое время._
+``
+
+### Шаг 5: Проверьте свой баланс {#step-5-check-your-balance}
+
+Чтобы перепроверить, что ETH находится в вашем кошельке, давайте сделаем запрос [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) с помощью [инструмента-компоновщика Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Результат будет содержать сумму ETH в нашем кошельке. Чтобы узнать больше, посмотрите [короткое руководство от Alchemy о том, как использовать инструмент-компоновщик](https://youtu.be/r6sjRxBZJuU).
+
+Введите адрес своего аккаунта MetaMask и нажмите **Отправить запрос**. Вы увидите ответ, похожий на фрагмент кода ниже.
+
+```json
+{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }
+```
+
+> _Примечание: этот результат указан в wei, а не в ETH._ _Wei используется как наименьшая единица эфира._
+
+Фух! Наши ненастоящие деньги уже все там.
+
+### Шаг 6: Инициализация нашего проекта {#step-6-initialize-our-project}
+
+Во-первых, нам нужно создать папку для нашего проекта. Перейдите в командную строку и введите следующее.
+
+```
+mkdir hello-world
+cd hello-world
+```
+
+Теперь, когда мы находимся в папке нашего проекта, мы будем использовать `npm init` для его инициализации.
+
+> Если у вас еще не установлен npm, следуйте [этим инструкциям по установке Node.js и npm](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm).
+
+Для целей этого руководства не имеет значения, как вы ответите на вопросы инициализации. Вот как мы это сделали для примера:
+
+```
+имя пакета: (hello-world)
+версия: (1.0.0)
+описание: смарт-контракт hello world
+точка входа: (index.js)
+команда для тестирования:
+репозиторий git:
+ключевые слова:
+автор:
+лицензия: (ISC)
+
+Будет записано в /Users/.../.../.../hello-world/package.json:
+
+{
+ "name": "hello-world",
+ "version": "1.0.0",
+ "description": "смарт-контракт hello world",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
+```
+
+Подтвердите `package.json`, и мы готовы!
+
+### Шаг 7: Загрузка Hardhat {#step-7-download-hardhat}
+
+Hardhat - это среда для сборки, развертывания, тестирования и отладки программного обеспечения Ethereum. Он помогает разработчикам создавать смарт-контракты и децентрализованные приложения локально перед их развертыванием в основной сети.
+
+Внутри нашего проекта `hello-world` запустите:
+
+```
+npm install --save-dev hardhat
+```
+
+Более подробную информацию об [инструкциях по установке](https://hardhat.org/getting-started/#overview) можно найти на этой странице.
+
+### Шаг 8: Создание проекта Hardhat {#step-8-create-hardhat-project}
+
+В папке нашего проекта `hello-world` выполните:
+
+```
+npx hardhat
+```
+
+Вы увидите приветственное сообщение и интерфейс с вариантами того, что делать дальше. Выберите "create an empty hardhat.config.js":
+
+```
+888 888 888 888 888
+888 888 888 888 888
+888 888 888 888 888
+8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
+888 888 "88b 888P" d88" 888 888 "88b "88b 888
+888 888 .d888888 888 888 888 888 888 .d888888 888
+888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
+888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
+
+👷 Добро пожаловать в Hardhat v2.0.11 👷
+
+Что вы хотите сделать? …
+Создать пример проекта
+❯ Создать пустой hardhat.config.js
+Выйти
+```
+
+Это создаст файл `hardhat.config.js` в проекте. Мы будем использовать его позже в этом руководстве, чтобы указать настройки для нашего проекта.
+
+### Шаг 9: Добавление папок проекта {#step-9-add-project-folders}
+
+Чтобы поддерживать порядок в проекте, давайте создадим две новые папки. В командной строке перейдите в корневой каталог вашего проекта `hello-world` и введите:
+
+```
+mkdir contracts
+mkdir scripts
+```
+
+- `contracts/` — здесь мы будем хранить файл с кодом нашего смарт-контракта «hello world».
+- `scripts/` — здесь мы будем хранить скрипты для развертывания нашего контракта и взаимодействия с ним.
+
+### Шаг 10: Написание нашего контракта {#step-10-write-our-contract}
+
+Вы можете спросить себя, когда мы собираемся писать код? Время пришло!
+
+Откройте проект hello-world в своем любимом редакторе. Смарт-контракты чаще всего пишутся на Solidity, который мы и будем использовать для написания нашего смарт-контракта.
+
+1. Перейдите в папку `contracts` и создайте новый файл с именем `HelloWorld.sol`
+2. Ниже приведен пример смарт-контракта Hello World, который мы будем использовать в этом руководстве. Скопируйте содержимое ниже в файл `HelloWorld.sol`.
+
+_Примечание: обязательно прочитайте комментарии, чтобы понять, что делает этот контракт._
+
+```
+// Указывает версию Solidity, используя семантическое версионирование.
+// Узнайте больше: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+pragma solidity >=0.7.3;
+
+// Определяет контракт с именем `HelloWorld`.
+// Контракт — это набор функций и данных (его состояние). После развертывания контракт находится по определенному адресу в блокчейне Ethereum. Узнайте больше: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+contract HelloWorld {
+
+ // Генерируется при вызове функции update
+ //События смарт-контракта — это способ сообщить из вашего контракта во фронтенд вашего приложения о том, что что-то произошло в блокчейне. Фронтенд может «прослушивать» определенные события и предпринимать действия, когда они происходят.
+ event UpdatedMessages(string oldStr, string newStr);
+
+ // Объявляет переменную состояния `message` типа `string`.
+ // Переменные состояния — это переменные, значения которых постоянно хранятся в хранилище контракта. Ключевое слово `public` делает переменные доступными извне контракта и создает функцию, которую другие контракты или клиенты могут вызывать для доступа к значению.
+ string public message;
+
+ // Подобно многим объектно-ориентированным языкам на основе классов, конструктор — это специальная функция, которая выполняется только при создании контракта.
+ // Конструкторы используются для инициализации данных контракта. Узнайте больше:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ constructor(string memory initMessage) {
+
+ // Принимает строковый аргумент `initMessage` и устанавливает значение в переменную хранилища контракта `message`).
+ message = initMessage;
+ }
+
+ // Публичная функция, которая принимает строковый аргумент и обновляет переменную хранилища `message`.
+ function update(string memory newMessage) public {
+ string memory oldMsg = message;
+ message = newMessage;
+ emit UpdatedMessages(oldMsg, newMessage);
+ }
+}
+```
+
+Это базовый смарт-контракт, который хранит сообщение при создании. Его можно обновить, вызвав функцию `update`.
+
+### Шаг 11. Подключите MetaMask и Alchemy к вашему проекту {#step-11-connect-metamask-alchemy-to-your-project}
+
+Мы создали кошелек MetaMask, учетную запись Alchemy и написали наш смарт-контракт, теперь пришло время их соединить.
+
+Каждая транзакция, отправляемая из вашего кошелька, требует подписи с использованием вашего уникального приватного ключа. Чтобы предоставить нашей программе это разрешение, мы можем безопасно хранить наш приватный ключ в файле среды. Мы также будем хранить здесь ключ API для Alchemy.
+
+> Чтобы узнать больше об отправке транзакций, ознакомьтесь с [этим руководством](https://www.alchemy.com/docs/hello-world-smart-contract#step-11-connect-metamask--alchemy-to-your-project) по отправке транзакций с помощью web3.
+
+Во-первых, установите dotenv, находясь в директории проекта:
+
+```
+npm install dotenv --save
+```
+
+Затем создайте файл `.env` в корневом каталоге проекта. Добавьте в него свой приватный ключ MetaMask и URL-адрес HTTP API Alchemy.
+
+Ваш файл среды должен называться `.env`, иначе он не будет распознан как файл среды.
+
+Не называйте его `process.env`, `.env-custom` или как-либо еще.
+
+- Следуйте [этим инструкциям](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key), чтобы экспортировать свой приватный ключ.
+- Ниже показано, как получить URL-адрес HTTP API Alchemy
+
+
+
+Ваш `.env` должен выглядеть следующим образом:
+
+```
+API_URL = "https://eth-goerli.alchemyapi.io/v2/ваш-api-ключ"
+PRIVATE_KEY = "ваш-приватный-ключ-metamask"
+```
+
+Чтобы подключить их к нашему коду, мы будем ссылаться на эти переменные в нашем файле `hardhat.config.js` в шаге 13.
+
+### Шаг 12: Установите Ethers.js {#step-12-install-ethersjs}
+
+Ethers.js — это библиотека, которая упрощает взаимодействие и отправку запросов в Ethereum, оборачивая [стандартные методы JSON-RPC](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) в более удобные для пользователя методы.
+
+Hardhat позволяет нам интегрировать [плагины](https://hardhat.org/plugins/) для дополнительных инструментов и расширенной функциональности. Мы воспользуемся [плагином Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) для развертывания контракта.
+
+В директории проекта запустите:
+
+```bash
+npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
+```
+
+### Шаг 13: Обновление hardhat.config.js {#step-13-update-hardhat-configjs}
+
+Мы добавили несколько зависимостей и плагинов, и теперь нам нужно обновить `hardhat.config.js`, чтобы наш проект знал обо всех них.
+
+Обновите ваш `hardhat.config.js`, чтобы он выглядел следующим образом:
+
+```javascript
+/**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+
+require("dotenv").config()
+require("@nomiclabs/hardhat-ethers")
+
+const { API_URL, PRIVATE_KEY } = process.env
+
+module.exports = {
+ solidity: "0.7.3",
+ defaultNetwork: "goerli",
+ networks: {
+ hardhat: {},
+ goerli: {
+ url: API_URL,
+ accounts: [`0x${PRIVATE_KEY}`],
+ },
+ },
+}
+```
+
+### Шаг 14: Компиляция нашего контракта {#step-14-compile-our-contract}
+
+Пора заставить это работать, давайте скомпилируем наш контракт. Задача `compile` — одна из встроенных задач hardhat.
+
+Запустите в командной строке:
+
+```bash
+npx hardhat compile
+```
+
+Вы можете получить предупреждение `SPDX license identifier not provided in source file`, но не стоит об этом беспокоиться — надеемся, все остальное выглядит хорошо! Если нет, вы всегда можете написать в [Discord-канал Alchemy](https://discord.gg/u72VCg3).
+
+### Шаг 15: Написание нашего скрипта развертывания {#step-15-write-our-deploy-script}
+
+Контракт написан, файл конфигурации корректен, пора писать скрипт развертывания.
+
+Перейдите в папку `scripts/`, создайте новый файл `deploy.js` и добавьте в него следующее содержимое:
+
+```javascript
+async function main() {
+ const HelloWorld = await ethers.getContractFactory("HelloWorld")
+
+ // Начинаем развертывание, возвращая promise, который разрешается в объект контракта
+ const hello_world = await HelloWorld.deploy("Hello World!")
+ console.log("Контракт развернут по адресу:", hello_world.address)
+}
+
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error)
+ process.exit(1)
+ })
+```
+
+Hardhat отлично объясняет, что делает каждая из этих строк кода, в своем [руководстве по контрактам](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), мы использовали их объяснения здесь.
+
+```javascript
+const HelloWorld = await ethers.getContractFactory("HelloWorld")
+```
+
+`ContractFactory` в ethers.js — это абстракция, используемая для развертывания новых смарт-контрактов, поэтому `HelloWorld` здесь — это [фабрика](https://en.wikipedia.org/wiki/Factory_\(object-oriented_programming\)) для экземпляров нашего контракта hello world. При использовании плагина `hardhat-ethers` экземпляры `ContractFactory` и `Contract` по умолчанию подключаются к первому подписанту (владельцу).
+
+```javascript
+const hello_world = await HelloWorld.deploy()
+```
+
+Вызов `deploy()` на `ContractFactory` запустит развертывание и вернет `Promise`, который разрешается в объект `Contract`. Это объект, который имеет метод для каждой из функций нашего смарт контракта.
+
+### Шаг 16: Разверните наш контракт {#step-16-deploy-our-contract}
+
+Мы наконец-то готовы развернуть наш смарт контракт! Перейдите в командную строку и запустите:
+
+```bash
+npx hardhat run scripts/deploy.js --network goerli
+```
+
+Вы должны увидеть что-то наподобие:
+
+```bash
+Контракт развернут по адресу: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
+```
+
+**Пожалуйста, сохраните этот адрес**. Мы будем использовать его позже в этом руководстве.
+
+Если мы перейдем на [Etherscan для Goerli](https://goerli.etherscan.io) и поищем адрес нашего контракта, мы должны увидеть, что он был успешно развернут. Транзакция будет выглядеть примерно так:
+
+
+
+Адрес `From` должен совпадать с адресом вашего аккаунта MetaMask, а в адресе `To` будет указано **Создание контракта**. Если мы щелкнем по транзакции, то увидим адрес нашего контракта в поле `To`.
+
+
+
+Поздравляем! Вы только что развернули смарт-контракт в тестовой сети Ethereum.
+
+Чтобы понять, что происходит «под капотом», давайте перейдем на вкладку Explorer на нашей [панели инструментов Alchemy](https://dashboard.alchemy.com/explorer). Если у вас несколько приложений Alchemy, убедитесь, что вы отфильтровали их по приложению и выбрали **Hello World**.
+
+
+
+Здесь вы увидите несколько методов JSON-RPC, которые Hardhat/Ethers сделали для нас «под капотом», когда мы вызвали функцию `.deploy()`. Два важных метода здесь — это [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), который является запросом на запись нашего контракта в сеть Goerli, и [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), который является запросом на чтение информации о нашей транзакции по заданному хэшу. Чтобы узнать больше об отправке транзакций, ознакомьтесь с [нашим руководством по отправке транзакций с помощью Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/).
+
+## Часть 2. Взаимодействие с вашим смарт-контрактом {#part-2-interact-with-your-smart-contract}
+
+Теперь, когда мы успешно развернули смарт-контракт в сети Goerli, давайте научимся с ним взаимодействовать.
+
+### Создайте файл interact.js {#create-a-interactjs-file}
+
+Это файл, в котором мы напишем наш скрипт взаимодействия. Мы будем использовать библиотеку Ethers.js, которую вы ранее установили в Части 1.
+
+В папке `scripts/` создайте новый файл с именем `interact.js` и добавьте следующий код:
+
+```javascript
+// interact.js
+
+const API_KEY = process.env.API_KEY
+const PRIVATE_KEY = process.env.PRIVATE_KEY
+const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
+```
+
+### Обновите ваш файл .env {#update-your-env-file}
+
+Мы будем использовать новые переменные среды, поэтому нам нужно определить их в файле `.env`, который [мы создали ранее](#step-11-connect-metamask-&-alchemy-to-your-project).
+
+Нам нужно будет добавить определение для нашего `API_KEY` Alchemy и `CONTRACT_ADDRESS`, по которому был развернут ваш смарт-контракт.
+
+Ваш файл `.env` должен выглядеть примерно так:
+
+```bash
+# .env
+
+API_URL = "https://eth-goerli.alchemyapi.io/v2/<ваш-api-ключ>"
+API_KEY = "<ваш-api-ключ>"
+PRIVATE_KEY = "<ваш-приватный-ключ-metamask>"
+CONTRACT_ADDRESS = "0x<адрес_вашего_контракта>"
+```
+
+### Получите ABI вашего контракта {#grab-your-contract-ABI}
+
+Наш [ABI (двоичный интерфейс приложения)](/glossary/#abi) контракта — это интерфейс для взаимодействия с нашим смарт-контрактом. Hardhat автоматически генерирует ABI и сохраняет его в `HelloWorld.json`. Чтобы использовать ABI, нам нужно будет разобрать его содержимое, добавив следующие строки кода в наш файл `interact.js`:
+
+```javascript
+// interact.js
+const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
+```
+
+Если вы хотите увидеть ABI, вы можете вывести его в консоль:
+
+```javascript
+console.log(JSON.stringify(contract.abi))
+```
+
+Чтобы увидеть ваш ABI, выведенный в консоль, перейдите в терминал и выполните:
+
+```bash
+npx hardhat run scripts/interact.js
+```
+
+### Создайте экземпляр вашего контракта {#create-an-instance-of-your-contract}
+
+Для взаимодействия с нашим контрактом нам нужно создать экземпляр контракта в нашем коде. Чтобы сделать это с помощью Ethers.js, нам нужно будет работать с тремя концепциями:
+
+1. Provider (провайдер) — поставщик узлов, который дает вам доступ на чтение и запись в блокчейн.
+2. Signer (подписант) — представляет аккаунт Ethereum, который может подписывать транзакции.
+3. Contract (контракт) — объект Ethers.js, представляющий конкретный контракт, развернутый в сети.
+
+Мы будем использовать ABI контракта из предыдущего шага, чтобы создать наш экземпляр контракта:
+
+```javascript
+// interact.js
+
+// Провайдер
+const alchemyProvider = new ethers.providers.AlchemyProvider(
+ (network = "goerli"),
+ API_KEY
+)
+
+// Подписант
+const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
+
+// Контракт
+const helloWorldContract = new ethers.Contract(
+ CONTRACT_ADDRESS,
+ contract.abi,
+ signer
+)
+```
+
+Узнайте больше о провайдерах, подписантах и контрактах в [документации ethers.js](https://docs.ethers.io/v5/).
+
+### Прочитайте начальное сообщение {#read-the-init-message}
+
+Помните, как мы развертывали наш контракт с `initMessage = "Hello world!"`? Теперь мы собираемся прочитать это сообщение, хранящееся в нашем смарт-контракте, и вывести его в консоль.
+
+В JavaScript асинхронные функции используются при взаимодействии с сетями. Чтобы узнать больше об асинхронных функциях, [прочитайте эту статью на Medium](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff).
+
+Используйте приведенный ниже код, чтобы вызвать функцию `message` в нашем смарт-контракте и прочитать начальное сообщение:
+
+```javascript
+// interact.js
+
+// ...
+
+async function main() {
+ const message = await helloWorldContract.message()
+ console.log("Сообщение: " + message)
+}
+main()
+```
+
+После запуска файла с помощью `npx hardhat run scripts/interact.js` в терминале мы должны увидеть следующий ответ:
+
+```
+Сообщение: Hello world!
+```
+
+Поздравляем! Вы только что успешно прочитали данные смарт-контракта из блокчейна Ethereum, так держать!
+
+### Обновите сообщение {#update-the-message}
+
+Вместо того, чтобы просто читать сообщение, мы также можем обновить сообщение, сохраненное в нашем смарт-контракте, с помощью функции `update`! Круто, не так ли?
+
+Чтобы обновить сообщение, мы можем напрямую вызвать функцию `update` на нашем созданном объекте Contract:
+
+```javascript
+// interact.js
+
+// ...
+
+async function main() {
+ const message = await helloWorldContract.message()
+ console.log("Сообщение: " + message)
+
+ console.log("Обновление сообщения...")
+ const tx = await helloWorldContract.update("Это новое сообщение.")
+ await tx.wait()
+}
+main()
+```
+
+Обратите внимание, что в строке 11 мы вызываем `.wait()` для возвращенного объекта транзакции. Это гарантирует, что наш скрипт дождется майнинга транзакции в блокчейне перед выходом из функции. Если вызов `.wait()` не включен, скрипт может не увидеть обновленное значение `message` в контракте.
+
+### Прочитайте новое сообщение {#read-the-new-message}
+
+Вы должны быть в состоянии повторить [предыдущий шаг](#read-the-init-message), чтобы прочитать обновленное значение `message`. Потратьте немного времени и посмотрите, сможете ли вы внести необходимые изменения, чтобы вывести это новое значение!
+
+Если вам нужна подсказка, вот как должен выглядеть ваш файл `interact.js` на данном этапе:
+
+```javascript
+// interact.js
+
+const API_KEY = process.env.API_KEY
+const PRIVATE_KEY = process.env.PRIVATE_KEY
+const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
+
+const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
+
+// провайдер - Alchemy
+const alchemyProvider = new ethers.providers.AlchemyProvider(
+ (network = "goerli"),
+ API_KEY
+)
+
+// подписант - вы
+const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
+
+// экземпляр контракта
+const helloWorldContract = new ethers.Contract(
+ CONTRACT_ADDRESS,
+ contract.abi,
+ signer
+)
+
+async function main() {
+ const message = await helloWorldContract.message()
+ console.log("Сообщение: " + message)
+
+ console.log("Обновление сообщения...")
+ const tx = await helloWorldContract.update("это новое сообщение")
+ await tx.wait()
+
+ const newMessage = await helloWorldContract.message()
+ console.log("Новое сообщение: " + newMessage)
+}
+
+main()
+```
+
+Теперь просто запустите скрипт, и вы сможете увидеть старое сообщение, статус обновления и новое сообщение, выведенные в ваш терминал!
+
+`npx hardhat run scripts/interact.js --network goerli`
+
+```
+Сообщение: Hello World!
+Обновление сообщения...
+Новое сообщение: This is the new message.
+```
+
+Во время выполнения этого скрипта вы можете заметить, что шаг `Обновление сообщения...` занимает некоторое время перед загрузкой нового сообщения. Это связано с процессом майнинга; если вам интересно отслеживать транзакции во время их майнинга, посетите [мемпул Alchemy](https://dashboard.alchemyapi.io/mempool), чтобы увидеть статус транзакции. Если транзакция была отброшена, также полезно проверить [Etherscan для Goerli](https://goerli.etherscan.io) и найти хэш вашей транзакции.
+
+## Часть 3: Публикация вашего смарт-контракта на Etherscan {#part-3-publish-your-smart-contract-to-etherscan}
+
+Вы проделали всю тяжелую работу по воплощению вашего смарт-контракта в жизнь; теперь пришло время поделиться им со всем миром!
+
+Проверив свой смарт-контракт на Etherscan, любой сможет просмотреть ваш исходный код и взаимодействовать с вашим смарт-контрактом. Давайте начнем!
+
+### Шаг 1: Создайте ключ API в своей учетной записи Etherscan {#step-1-generate-an-api-key-on-your-etherscan-account}
+
+Ключ API Etherscan необходим для подтверждения того, что вы являетесь владельцем смарт-контракта, который пытаетесь опубликовать.
+
+Если у вас еще нет аккаунта Etherscan, [зарегистрируйте аккаунт](https://etherscan.io/register).
+
+После входа в систему найдите свое имя пользователя на панели навигации, наведите на него курсор и выберите кнопку **Мой профиль**.
+
+На странице вашего профиля вы должны увидеть боковую панель навигации. На боковой панели навигации выберите **API Keys**. Затем нажмите кнопку «Add», чтобы создать новый ключ API, назовите свое приложение **hello-world** и нажмите кнопку **Create New API Key**.
+
+Ваш новый ключ API должен появиться в таблице ключей API. Скопируйте ключ API в буфер обмена.
+
+Далее нам нужно добавить ключ API Etherscan в наш файл `.env`.
+
+После его добавления ваш файл `.env` должен выглядеть так:
+
+```javascript
+API_URL = "https://eth-goerli.alchemyapi.io/v2/ваш-api-ключ"
+PUBLIC_KEY = "ваш-публичный-адрес-аккаунта"
+PRIVATE_KEY = "ваш-приватный-адрес-аккаунта"
+CONTRACT_ADDRESS = "адрес-вашего-контракта"
+ETHERSCAN_API_KEY = "ваш-ключ-etherscan"
+```
+
+### Смарт-контракты, развернутые с помощью Hardhat {#hardhat-deployed-smart-contracts}
+
+#### Установите hardhat-etherscan {#install-hardhat-etherscan}
+
+Публикация вашего контракта на Etherscan с помощью Hardhat очень проста. Сначала вам нужно будет установить плагин `hardhat-etherscan`. `hardhat-etherscan` автоматически проверит исходный код смарт-контракта и ABI на Etherscan. Чтобы добавить его, в каталоге `hello-world` выполните:
+
+```text
+npm install --save-dev @nomiclabs/hardhat-etherscan
+```
+
+После установки включите следующее выражение вверху вашего `hardhat.config.js` и добавьте параметры конфигурации Etherscan:
+
+```javascript
+// hardhat.config.js
+
+require("dotenv").config()
+require("@nomiclabs/hardhat-ethers")
+require("@nomiclabs/hardhat-etherscan")
+
+const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env
+
+module.exports = {
+ solidity: "0.7.3",
+ defaultNetwork: "goerli",
+ networks: {
+ hardhat: {},
+ goerli: {
+ url: API_URL,
+ accounts: [`0x${PRIVATE_KEY}`],
+ },
+ },
+ etherscan: {
+ // Ваш ключ API для Etherscan
+ // Получите его на https://etherscan.io/
+ apiKey: ETHERSCAN_API_KEY,
+ },
+}
+```
+
+#### Подтвердите свой смарт-контракт на Etherscan {#verify-your-smart-contract-on-etherscan}
+
+Убедитесь, что все файлы сохранены и все переменные `.env` настроены правильно.
+
+Запустите задачу `verify`, передав адрес контракта и сеть, в которой он развернут:
+
+```text
+npx hardhat verify --network goerli АДРЕС_РАЗВЕРНУТОГО_КОНТРАКТА 'Hello World!'
+```
+
+Убедитесь, что `DEPLOYED_CONTRACT_ADDRESS` — это адрес вашего развернутого смарт-контракта в тестовой сети Goerli. Кроме того, последний аргумент (`'Hello World!'`) должен быть той же строковой величиной, которая использовалась [на этапе развертывания в части 1](#write-our-deploy-script).
+
+Если все пройдет хорошо, вы увидите следующее сообщение в своем терминале:
+
+```text
+Исходный код для контракта успешно отправлен
+contracts/HelloWorld.sol:HelloWorld по адресу 0xdeployed-contract-address
+для проверки на Etherscan. Ожидание результата проверки...
+
+
+Контракт HelloWorld успешно проверен на Etherscan.
+https://goerli.etherscan.io/address/<адрес-контракта>#contracts
+```
+
+Поздравляем! Код вашего смарт-контракта находится на Etherscan!
+
+### Проверьте свой смарт-контракт на Etherscan! {#check-out-your-smart-contract-on-etherscan}
+
+Когда вы перейдете по ссылке, указанной в вашем терминале, вы сможете увидеть код вашего смарт-контракта и ABI, опубликованные на Etherscan!
+
+**Урааа — ты сделал это, чемпион! Теперь любой может вызывать или записывать данные в ваш смарт-контракт! Нам не терпится увидеть, что вы создадите дальше!**
+
+## Часть 4 — Интеграция вашего смарт-контракта с фронтендом {#part-4-integrating-your-smart-contract-with-the-frontend}
+
+К концу этого руководства вы узнаете, как:
+
+- Подключить кошелек MetaMask к вашему децентрализованному приложению
+- Считывать данные с вашего смарт-контракта с помощью API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3)
+- Подписывать транзакции Ethereum с помощью MetaMask
+
+Для этого децентрализованного приложения мы будем использовать [React](https://react.dev/) в качестве нашего фронтенд-фреймворка; однако важно отметить, что мы не будем тратить много времени на разбор его основ, поскольку в основном мы сосредоточимся на внедрении функциональности Web3 в наш проект.
+
+В качестве предварительного условия вы должны иметь начальный уровень понимания React. В противном случае мы рекомендуем пройти официальное [руководство по введению в React](https://react.dev/learn).
+
+### Клонируйте стартовые файлы {#clone-the-starter-files}
+
+Сначала перейдите в [репозиторий GitHub hello-world-part-four](https://github.com/alchemyplatform/hello-world-part-four-tutorial), чтобы получить стартовые файлы для этого проекта, и клонируйте этот репозиторий на свой локальный компьютер.
+
+Откройте клонированный репозиторий локально. Обратите внимание, что он содержит две папки: `starter-files` и `completed`.
+
+- `starter-files` - **мы будем работать в этом каталоге**, мы подключим пользовательский интерфейс к вашему кошельку Ethereum и смарт-контракту, который мы опубликовали на Etherscan в [Части 3](#part-3).
+- `completed` содержит полностью завершенное руководство и должен использоваться только в качестве справочника, если вы застряли.
+
+Далее откройте свою копию `starter-files` в вашем любимом редакторе кода, а затем перейдите в папку `src`.
+
+Весь код, который мы напишем, будет находиться в папке `src`. Мы будем редактировать компонент `HelloWorld.js` и файлы JavaScript `util/interact.js`, чтобы придать нашему проекту функциональность Web3.
+
+### Ознакомьтесь со стартовыми файлами {#check-out-the-starter-files}
+
+Прежде чем мы начнем писать код, давайте рассмотрим, что нам предоставлено в стартовых файлах.
+
+#### Запустите ваш React-проект {#get-your-react-project-running}
+
+Начнем с запуска проекта React в нашем браузере. Прелесть React в том, что как только наш проект запускается в нашем браузере, любые сохраняемые нами изменения будут обновляться в реальном времени в нашем браузере.
+
+Чтобы запустить проект, перейдите в корневой каталог папки `starter-files` и запустите `npm install` в своем терминале, чтобы установить зависимости проекта:
+
+```bash
+cd starter-files
+npm install
+```
+
+После завершения установки выполните `npm start` в терминале:
+
+```bash
+npm start
+```
+
+Это должно открыть [http://localhost:3000/](http://localhost:3000/) в вашем браузере, где вы увидите интерфейс нашего проекта. Он должен состоять из одного поля (места для обновления сообщения, хранящегося в вашем смарт-контракте), кнопки «Подключить кошелек» и кнопки «Обновить».
+
+Если вы попробуете нажать на любую из кнопок, вы заметите, что они не работают — это потому, что нам все еще нужно запрограммировать их функциональность.
+
+#### Компонент `HelloWorld.js` {#the-helloworld-js-component}
+
+Давайте вернемся в папку `src` в нашем редакторе и откроем файл `HelloWorld.js`. Очень важно, чтобы мы понимали все в этом файле, поскольку это основной компонент React, над которым мы будем работать.
+
+В верхней части этого файла вы заметите, что у нас есть несколько операторов импорта, которые необходимы для запуска нашего проекта, включая библиотеку React, хуки useEffect и useState, некоторые элементы из `./util/interact.js` (мы опишем их более подробно в ближайшее время!) и логотип Alchemy.
+
+```javascript
+// HelloWorld.js
+
+import React from "react"
+import { useEffect, useState } from "react"
+import {
+ helloWorldContract,
+ connectWallet,
+ updateMessage,
+ loadCurrentMessage,
+ getCurrentWalletConnected,
+} from "./util/interact.js"
+
+import alchemylogo from "./alchemylogo.svg"
+```
+
+Далее у нас есть переменные состояния, которые мы будем обновлять после определенных событий.
+
+```javascript
+// HelloWorld.js
+
+//Переменные состояния
+const [walletAddress, setWallet] = useState("")
+const [status, setStatus] = useState("")
+const [message, setMessage] = useState("Нет подключения к сети.")
+const [newMessage, setNewMessage] = useState("")
+```
+
+Вот что представляет собой каждая из переменных:
+
+- `walletAddress` — строка, в которой хранится адрес кошелька пользователя
+- `status` — строка, в которой хранится полезное сообщение, которое помогает пользователю взаимодействовать с децентрализованным приложением
+- `message` — строка, в которой хранится текущее сообщение в смарт-контракте
+- `newMessage` — строка, в которой хранится новое сообщение, которое будет записано в смарт-контракт
+
+После переменных состояния вы увидите пять нереализованных функций: `useEffect`, `addSmartContractListener`, `addWalletListener`, `connectWalletPressed` и `onUpdatePressed`. Ниже мы объясним, что они делают:
+
+```javascript
+// HelloWorld.js
+
+//вызывается только один раз
+useEffect(async () => {
+ //TODO: реализовать
+}, [])
+
+function addSmartContractListener() {
+ //TODO: реализовать
+}
+
+function addWalletListener() {
+ //TODO: реализовать
+}
+
+const connectWalletPressed = async () => {
+ //TODO: реализовать
+}
+
+const onUpdatePressed = async () => {
+ //TODO: реализовать
+}
+```
+
+- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html) — это хук React, который вызывается после рендеринга вашего компонента. Поскольку в него передается пустой массив `[]` в качестве свойства (см. строку 4), он будет вызываться только при _первом_ рендеринге компонента. Здесь мы загрузим текущее сообщение, хранящееся в нашем смарт-контракте, вызовем наши прослушиватели смарт-контракта и кошелька и обновим наш пользовательский интерфейс, чтобы отразить, подключен ли уже кошелек.
+- `addSmartContractListener` — эта функция настраивает прослушиватель, который будет отслеживать событие `UpdatedMessages` нашего контракта HelloWorld и обновлять наш пользовательский интерфейс при изменении сообщения в нашем смарт-контракте.
+- `addWalletListener` — эта функция настраивает прослушиватель, который обнаруживает изменения в состоянии кошелька MetaMask пользователя, например, когда пользователь отключает свой кошелек или переключает адреса.
+- `connectWalletPressed` — эта функция будет вызываться для подключения кошелька MetaMask пользователя к нашему децентрализованному приложению.
+- `onUpdatePressed` — эта функция будет вызываться, когда пользователь захочет обновить сообщение, хранящееся в смарт-контракте.
+
+Ближе к концу этого файла находится пользовательский интерфейс нашего компонента.
+
+```javascript
+// HelloWorld.js
+
+//UI нашего компонента
+return (
+
+
+
+
+ Текущее сообщение:
+ {message}
+
+ Новое сообщение:
+
+
+ setNewMessage(e.target.value)}
+ value={newMessage}
+ />
+ {status}
+
+
+
+
+
+)
+```
+
+Если вы внимательно изучите этот код, вы заметите, где мы используем наши различные переменные состояния в нашем пользовательском интерфейсе:
+
+- В строках 6–12, если кошелек пользователя подключен (т. е. `walletAddress.length > 0`), мы отображаем усеченную версию `walletAddress` пользователя на кнопке с идентификатором «walletButton»; в противном случае она просто гласит «Подключить кошелек».
+- В строке 17 мы отображаем текущее сообщение, хранящееся в смарт-контракте, которое зафиксировано в строке `message`.
+- В строках 23–26 мы используем [контролируемый компонент](https://legacy.reactjs.org/docs/forms.html#controlled-components) для обновления нашей переменной состояния `newMessage` при изменении ввода в текстовом поле.
+
+В дополнение к нашим переменным состояния вы также увидите, что функции `connectWalletPressed` и `onUpdatePressed` вызываются при нажатии кнопок с идентификаторами `publishButton` и `walletButton` соответственно.
+
+Наконец, давайте рассмотрим, куда добавляется этот компонент `HelloWorld.js`.
+
+Если вы перейдете к файлу `App.js`, который является основным компонентом в React, выступающим в качестве контейнера для всех других компонентов, вы увидите, что наш компонент `HelloWorld.js` внедряется в строке 7.
+
+И последнее, но не менее важное: давайте рассмотрим еще один предоставленный вам файл — `interact.js`.
+
+#### Файл `interact.js` {#the-interact-js-file}
+
+Поскольку мы хотим следовать парадигме [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), нам понадобится отдельный файл, который содержит все наши функции для управления логикой, данными и правилами нашего децентрализованного приложения, а затем мы сможем экспортировать эти функции в наш интерфейс (наш компонент `HelloWorld.js`).
+
+👆🏽Именно в этом и заключается цель нашего файла `interact.js`!
+
+Перейдите в папку `util` в вашем каталоге `src`, и вы заметите, что мы включили файл с именем `interact.js`, который будет содержать все наши функции и переменные для взаимодействия со смарт-контрактами и кошельками.
+
+```javascript
+// interact.js
+
+//export const helloWorldContract;
+
+export const loadCurrentMessage = async () => {}
+
+export const connectWallet = async () => {}
+
+const getCurrentWalletConnected = async () => {}
+
+export const updateMessage = async (message) => {}
+```
+
+Вы заметите, что вверху файла мы закомментировали объект `helloWorldContract`. Позже в этом руководстве мы раскомментируем этот объект и создадим экземпляр нашего смарт-контракта в этой переменной, который затем экспортируем в наш компонент `HelloWorld.js`.
+
+Четыре нереализованные функции после нашего объекта `helloWorldContract` делают следующее:
+
+- `loadCurrentMessage` — эта функция обрабатывает логику загрузки текущего сообщения, хранящегося в смарт-контракте. Она сделает вызов для _чтения_ в смарт-контракт Hello World с помощью [API Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3).
+- `connectWallet` — эта функция подключит MetaMask пользователя к нашему децентрализованному приложению.
+- `getCurrentWalletConnected` — эта функция проверит, подключен ли уже аккаунт Ethereum к нашему децентрализованному приложению при загрузке страницы, и соответствующим образом обновит наш пользовательский интерфейс.
+- `updateMessage` — эта функция обновит сообщение, хранящееся в смарт-контракте. Она сделает вызов для _записи_ в смарт-контракт Hello World, поэтому кошелек MetaMask пользователя должен будет подписать транзакцию Ethereum для обновления сообщения.
+
+Теперь, когда мы понимаем, с чем работаем, давайте разберемся, как читать из нашего смарт-контракта!
+
+### Шаг 3: Чтение из вашего смарт-контракта {#step-3-read-from-your-smart-contract}
+
+Чтобы читать из вашего смарт-контракта, вам нужно будет успешно настроить:
+
+- API-соединение с блокчейном Ethereum
+- Загруженный экземпляр вашего смарт-контракта
+- Функция для вызова функции вашего смарт-контракта
+- Прослушиватель для отслеживания обновлений, когда данные, которые вы читаете из смарт-контракта, изменяются
+
+Это может показаться большим количеством шагов, но не волнуйтесь! Мы проведем вас через каждый из них шаг за шагом! :\)
+
+#### Установите API-соединение с блокчейном Ethereum {#establish-an-api-connection-to-the-ethereum-chain}
+
+Итак, помните, как во второй части этого руководства мы использовали наш ключ [Alchemy Web3 для чтения из нашего смарт-контракта](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? Вам также понадобится ключ Alchemy Web3 в вашем децентрализованном приложении для чтения из блокчейна.
+
+Если у вас его еще нет, сначала установите [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3), перейдя в корневой каталог ваших `starter-files` и выполнив в терминале следующую команду:
+
+```text
+npm install @alch/alchemy-web3
+```
+
+[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) — это оболочка для [Web3.js](https://docs.web3js.org/), предоставляющая расширенные методы API и другие важные преимущества, облегчающие жизнь веб-разработчика. Он разработан с требованием минимальной настройки, поэтому вы можете сразу начать использовать его в своем приложении!
+
+Затем установите пакет [dotenv](https://www.npmjs.com/package/dotenv) в каталог вашего проекта, чтобы у нас было безопасное место для хранения нашего ключа API после того, как мы его получим.
+
+```text
+npm install dotenv --save
+```
+
+Для нашего децентрализованного приложения **мы будем использовать наш ключ API для Websockets**, а не наш ключ API для HTTP, так как это позволит нам настроить прослушиватель, который обнаруживает, когда меняется сообщение, хранящееся в смарт-контракте.
+
+Как только у вас будет ключ API, создайте файл `.env` в вашем корневом каталоге и добавьте в него свой URL-адрес для Websockets Alchemy. После этого ваш файл `.env` должен выглядеть следующим образом:
+
+```javascript
+REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/<ключ>
+```
+
+Теперь мы готовы настроить нашу конечную точку Alchemy Web3 в нашем децентрализованном приложении! Давайте вернемся к нашему `interact.js`, который находится в нашей папке `util`, и добавим следующий код в начало файла:
+
+```javascript
+// interact.js
+
+require("dotenv").config()
+const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(alchemyKey)
+
+//export const helloWorldContract;
+```
+
+Выше мы сначала импортировали ключ Alchemy из нашего файла `.env`, а затем передали наш `alchemyKey` в `createAlchemyWeb3`, чтобы установить нашу конечную точку Alchemy Web3.
+
+С этой готовой конечной точкой пришло время загрузить наш смарт-контракт!
+
+#### Загрузка вашего смарт-контракта Hello World {#loading-your-hello-world-smart-contract}
+
+Чтобы загрузить ваш смарт-контракт Hello World, вам понадобится его адрес контракта и ABI, оба из которых можно найти на Etherscan, если вы завершили [Часть 3 этого руководства.](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan)
+
+#### Как получить ABI вашего контракта с Etherscan {#how-to-get-your-contract-abi-from-etherscan}
+
+Если вы пропустили часть 3 этого руководства, вы можете использовать контракт HelloWorld с адресом [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). Его ABI можно найти [здесь](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code).
+
+ABI контракта необходим для указания, какую функцию будет вызывать контракт, а также для обеспечения того, чтобы функция возвращала данные в ожидаемом формате. После того, как мы скопировали ABI нашего контракта, давайте сохраним его в виде файла JSON с именем `contract-abi.json` в вашем каталоге `src`.
+
+Ваш файл contract-abi.json должен храниться в вашей папке src.
+
+Вооружившись адресом нашего контракта, ABI и конечной точкой Alchemy Web3, мы можем использовать [метод contract](https://docs.web3js.org/api/web3-eth-contract/class/Contract), чтобы загрузить экземпляр нашего смарт-контракта. Импортируйте ABI вашего контракта в файл `interact.js` и добавьте адрес вашего контракта.
+
+```javascript
+// interact.js
+
+const contractABI = require("../contract-abi.json")
+const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"
+```
+
+Теперь мы наконец-то можем раскомментировать нашу переменную `helloWorldContract` и загрузить смарт-контракт с помощью нашей конечной точки AlchemyWeb3:
+
+```javascript
+// interact.js
+export const helloWorldContract = new web3.eth.Contract(
+ contractABI,
+ contractAddress
+)
+```
+
+Подводя итог, первые 12 строк вашего `interact.js` теперь должны выглядеть так:
+
+```javascript
+// interact.js
+
+require("dotenv").config()
+const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(alchemyKey)
+
+const contractABI = require("../contract-abi.json")
+const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"
+
+export const helloWorldContract = new web3.eth.Contract(
+ contractABI,
+ contractAddress
+)
+```
+
+Теперь, когда мы загрузили наш контракт, мы можем реализовать нашу функцию `loadCurrentMessage`!
+
+#### Реализация `loadCurrentMessage` в вашем файле `interact.js` {#implementing-loadCurrentMessage-in-your-interact-js-file}
+
+Эта функция очень проста. Мы сделаем простой асинхронный вызов web3 для чтения из нашего контракта. Наша функция вернет сообщение, хранящееся в смарт-контракте:
+
+Обновите `loadCurrentMessage` в вашем файле `interact.js` до следующего:
+
+```javascript
+// interact.js
+
+export const loadCurrentMessage = async () => {
+ const message = await helloWorldContract.methods.message().call()
+ return message
+}
+```
+
+Поскольку мы хотим отображать этот смарт-контракт в нашем пользовательском интерфейсе, давайте обновим функцию `useEffect` в нашем компоненте `HelloWorld.js` до следующего:
+
+```javascript
+// HelloWorld.js
+
+//вызывается только один раз
+useEffect(async () => {
+ const message = await loadCurrentMessage()
+ setMessage(message)
+}, [])
+```
+
+Обратите внимание, мы хотим, чтобы наша `loadCurrentMessage` вызывалась только один раз во время первого рендеринга компонента. Вскоре мы реализуем `addSmartContractListener` для автоматического обновления пользовательского интерфейса после изменения сообщения в смарт-контракте.
+
+Прежде чем мы углубимся в наш прослушиватель, давайте посмотрим, что у нас есть на данный момент! Сохраните ваши файлы `HelloWorld.js` и `interact.js`, а затем перейдите по адресу [http://localhost:3000/](http://localhost:3000/)
+
+Вы заметите, что текущее сообщение больше не гласит «Нет подключения к сети». Вместо этого оно отражает сообщение, хранящееся в смарт-контракте. Отлично!
+
+#### Ваш пользовательский интерфейс теперь должен отражать сообщение, хранящееся в смарт-контракте {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract}
+
+Теперь о прослушивателе...
+
+#### Реализуйте `addSmartContractListener` {#implement-addsmartcontractlistener}
+
+Если вы вернетесь к файлу `HelloWorld.sol`, который мы написали в [Части 1 этой серии руководств](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract), вы вспомните, что есть событие смарт-контракта под названием `UpdatedMessages`, которое генерируется после вызова функции `update` нашего смарт-контракта (см. строки 9 и 27):
+
+```javascript
+// HelloWorld.sol
+
+// Указывает версию Solidity, используя семантическое версионирование.
+// Узнайте больше: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+pragma solidity ^0.7.3;
+
+// Определяет контракт с именем `HelloWorld`.
+// Контракт — это набор функций и данных (его состояние). После развертывания контракт находится по определенному адресу в блокчейне Ethereum. Узнайте больше: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+contract HelloWorld {
+
+ // Генерируется при вызове функции update
+ //События смарт-контракта — это способ сообщить из вашего контракта во фронтенд вашего приложения о том, что что-то произошло в блокчейне. Фронтенд может «прослушивать» определенные события и предпринимать действия, когда они происходят.
+ event UpdatedMessages(string oldStr, string newStr);
+
+ // Объявляет переменную состояния `message` типа `string`.
+ // Переменные состояния — это переменные, значения которых постоянно хранятся в хранилище контракта. Ключевое слово `public` делает переменные доступными извне контракта и создает функцию, которую другие контракты или клиенты могут вызывать для доступа к значению.
+ string public message;
+
+ // Подобно многим объектно-ориентированным языкам на основе классов, конструктор — это специальная функция, которая выполняется только при создании контракта.
+ // Конструкторы используются для инициализации данных контракта. Узнайте больше:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ constructor(string memory initMessage) {
+
+ // Принимает строковый аргумент `initMessage` и устанавливает значение в переменную хранилища контракта `message`).
+ message = initMessage;
+ }
+
+ // Публичная функция, которая принимает строковый аргумент и обновляет переменную хранилища `message`.
+ function update(string memory newMessage) public {
+ string memory oldMsg = message;
+ message = newMessage;
+ emit UpdatedMessages(oldMsg, newMessage);
+ }
+}
+```
+
+События смарт-контракта — это способ, которым ваш контракт сообщает вашему фронтенд-приложению о том, что что-то произошло (т. е. произошло _событие_) в блокчейне, которое может «прослушивать» определенные события и предпринимать действия, когда они происходят.
+
+Функция `addSmartContractListener` будет специально прослушивать событие `UpdatedMessages` нашего смарт-контракта Hello World и обновлять наш пользовательский интерфейс для отображения нового сообщения.
+
+Измените `addSmartContractListener` на следующее:
+
+```javascript
+// HelloWorld.js
+
+function addSmartContractListener() {
+ helloWorldContract.events.UpdatedMessages({}, (error, data) => {
+ if (error) {
+ setStatus("😥 " + error.message)
+ } else {
+ setMessage(data.returnValues[1])
+ setNewMessage("")
+ setStatus("🎉 Ваше сообщение было обновлено!")
+ }
+ })
+}
+```
+
+Давайте разберем, что происходит, когда прослушиватель обнаруживает событие:
+
+- Если при генерации события произойдет ошибка, она будет отражена в пользовательском интерфейсе через нашу переменную состояния `status`.
+- В противном случае мы будем использовать возвращенный объект `data`. `data.returnValues` — это массив, индексированный с нуля, где первый элемент массива хранит предыдущее сообщение, а второй — обновленное. В целом, при успешном событии мы установим нашу строку `message` на обновленное сообщение, очистим строку `newMessage` и обновим нашу переменную состояния `status`, чтобы отразить, что новое сообщение было опубликовано в нашем смарт-контракте.
+
+Наконец, давайте вызовем наш прослушиватель в нашей функции `useEffect`, чтобы он был инициализирован при первом рендеринге компонента `HelloWorld.js`. В целом, ваша функция `useEffect` должна выглядеть так:
+
+```javascript
+// HelloWorld.js
+
+useEffect(async () => {
+ const message = await loadCurrentMessage()
+ setMessage(message)
+ addSmartContractListener()
+}, [])
+```
+
+Теперь, когда мы можем читать из нашего смарт-контракта, было бы здорово разобраться, как в него записывать! Однако, чтобы записывать в наше децентрализованное приложение, у нас сначала должен быть подключенный к нему кошелек Ethereum.
+
+Итак, далее мы займемся настройкой нашего кошелька Ethereum (MetaMask), а затем подключим его к нашему децентрализованному приложению!
+
+### Шаг 4: Настройте свой кошелек Ethereum {#step-4-set-up-your-ethereum-wallet}
+
+Чтобы что-либо записать в блокчейн Ethereum, пользователи должны подписывать транзакции с помощью приватных ключей своего виртуального кошелька. В этом руководстве мы будем использовать [MetaMask](https://metamask.io/), виртуальный кошелек в браузере, используемый для управления адресом вашего аккаунта Ethereum, так как он делает подписание транзакций очень простым для конечного пользователя.
+
+Если вы хотите больше узнать о том, как работают транзакции в Ethereum, ознакомьтесь с [этой страницей](/developers/docs/transactions/) от Ethereum Foundation.
+
+#### Загрузите MetaMask {#download-metamask}
+
+Вы можете бесплатно скачать и создать аккаунт MetaMask [здесь](https://metamask.io/download). При создании аккаунта или если у вас уже есть аккаунт, убедитесь, что вы переключились на «тестовую сеть Goerli» в правом верхнем углу (чтобы мы не имели дело с реальными деньгами).
+
+#### Добавьте эфир из крана {#add-ether-from-a-faucet}
+
+Чтобы подписать транзакцию в блокчейне Ethereum, нам понадобится немного тестового Eth. Чтобы получить Eth, вы можете перейти на [FaucETH](https://fauceth.komputing.org) и ввести адрес своего аккаунта Goerli, нажать «Запросить средства», затем выбрать «Ethereum Testnet Goerli» в выпадающем списке и, наконец, снова нажать кнопку «Запросить средства». Вскоре после этого вы должны увидеть Eth в своей учетной записи MetaMask!
+
+#### Проверьте свой баланс {#check-your-balance}
+
+Чтобы дважды проверить наш баланс, давайте сделаем запрос [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance), используя [инструмент для составления запросов от Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Так сумма Eth вернется в наш кошелек. После ввода адреса вашего аккаунта MetaMask и нажатия «Send Request» вы должны увидеть примерно такой ответ:
+
+```text
+{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
+```
+
+**ПРИМЕЧАНИЕ:** этот результат указан в wei, а не в ETH. Wei это наименьшая единица измерения эфира. Преобразование wei в eth: 1 eth = 10¹⁸ wei. Итак, если мы преобразуем 0xde0b6b3a7640000 в десятичное число, мы получим 1\*10¹⁸, что равно 1 eth.
+
+Фух! Наши ненастоящие деньги уже все там! 🤑
+
+### Шаг 5: Подключите MetaMask к вашему пользовательскому интерфейсу {#step-5-connect-metamask-to-your-UI}
+
+Теперь, когда наш кошелек MetaMask настроен, давайте подключим к нему наше децентрализованное приложение!
+
+#### Функция `connectWallet` {#the-connectWallet-function}
+
+В нашем файле `interact.js` мы реализуем функцию `connectWallet`, которую затем сможем вызвать в нашем компоненте `HelloWorld.js`.
+
+Давайте изменим `connectWallet` на следующее:
+
+```javascript
+// interact.js
+
+export const connectWallet = async () => {
+ if (window.ethereum) {
+ try {
+ const addressArray = await window.ethereum.request({
+ method: "eth_requestAccounts",
+ })
+ const obj = {
+ status: "👆🏽 Напишите сообщение в текстовом поле выше.",
+ address: addressArray[0],
+ }
+ return obj
+ } catch (err) {
+ return {
+ address: "",
+ status: "😥 " + err.message,
+ }
+ }
+ } else {
+ return {
+ address: "",
+ status: (
+
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в свой
+ браузер.
+
+
+
+ ),
+ }
+ }
+}
+```
+
+Так что же именно делает этот гигантский блок кода?
+
+Ну, во-первых, он проверяет, включен ли `window.ethereum` в вашем браузере.
+
+`window.ethereum` — это глобальный API, внедряемый MetaMask и другими поставщиками кошельков, который позволяет веб-сайтам запрашивать аккаунты пользователей Ethereum. В случае одобрения он может считывать данные из блокчейнов, к которым подключен пользователь, и предлагать пользователю подписывать сообщения и транзакции. Для получения дополнительной информации см. [документацию MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)!
+
+Если `window.ethereum` _отсутствует_, это означает, что MetaMask не установлен. В результате возвращается объект JSON, где возвращаемый `address` представляет собой пустую строку, а объект `status` JSX сообщает, что пользователь должен установить MetaMask.
+
+Если же `window.ethereum` _присутствует_, то здесь начинается самое интересное.
+
+Используя цикл try/catch, мы попытаемся подключиться к MetaMask, вызвав [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Вызов этой функции откроет MetaMask в браузере, и пользователю будет предложено подключить свой кошелек к вашему децентрализованному приложению.
+
+- Если пользователь решит подключиться, `method: "eth_requestAccounts"` вернет массив, содержащий все адреса аккаунтов пользователя, подключенных к децентрализованному приложению. В целом, наша функция `connectWallet` вернет объект JSON, который содержит _первый_ `address` в этом массиве (см. строку 9) и сообщение `status`, предлагающее пользователю написать сообщение в смарт-контракт.
+- Если пользователь отклоняет подключение, то объект JSON будет содержать пустую строку для возвращаемого `address` и сообщение `status`, которое отражает, что пользователь отклонил подключение.
+
+Теперь, когда мы написали эту функцию `connectWallet`, следующим шагом является ее вызов в нашем компоненте `HelloWorld.js`.
+
+#### Добавьте функцию `connectWallet` в ваш компонент пользовательского интерфейса `HelloWorld.js` {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component}
+
+Перейдите к функции `connectWalletPressed` в `HelloWorld.js` и обновите ее до следующего:
+
+```javascript
+// HelloWorld.js
+
+const connectWalletPressed = async () => {
+ const walletResponse = await connectWallet()
+ setStatus(walletResponse.status)
+ setWallet(walletResponse.address)
+}
+```
+
+Обратите внимание, как большая часть нашей функциональности абстрагирована от нашего компонента `HelloWorld.js` из файла `interact.js`? Это значит, что мы соответствуем парадигме M-V-С!
+
+В `connectWalletPressed` мы просто делаем вызов `await` к нашей импортированной функции `connectWallet` и, используя ее ответ, обновляем наши переменные `status` и `walletAddress` через их хуки состояния.
+
+Теперь давайте сохраним оба файла (`HelloWorld.js` и `interact.js`) и протестируем наш пользовательский интерфейс.
+
+Откройте браузер на странице [http://localhost:3000/](http://localhost:3000/) и нажмите кнопку «Подключить кошелек» в правом верхнем углу страницы.
+
+Если у вас установлен MetaMask, вам будет предложено подключить кошелек к вашему децентрализованному приложению. Примите приглашение на подключение.
+
+Вы должны увидеть, что кнопка кошелька теперь показывает, что ваш адрес подключен! Даааааа 🔥
+
+Далее попробуйте обновить страницу... это странно. Кнопка нашего кошелька предлагает нам подключить MetaMask, хотя он уже подключен...
+
+Однако, не бойтесь! Мы легко можем решить эту проблему (поняли каламбур с адресом?). реализовав `getCurrentWalletConnected`, которая проверит, подключен ли уже адрес к нашему децентрализованному приложению, и соответствующим образом обновит наш пользовательский интерфейс!
+
+#### Функция `getCurrentWalletConnected` {#the-getcurrentwalletconnected-function}
+
+Обновите вашу функцию `getCurrentWalletConnected` в файле `interact.js` до следующего:
+
+```javascript
+// interact.js
+
+export const getCurrentWalletConnected = async () => {
+ if (window.ethereum) {
+ try {
+ const addressArray = await window.ethereum.request({
+ method: "eth_accounts",
+ })
+ if (addressArray.length > 0) {
+ return {
+ address: addressArray[0],
+ status: "👆🏽 Напишите сообщение в текстовом поле выше.",
+ }
+ } else {
+ return {
+ address: "",
+ status: "🦊 Подключитесь к MetaMask, используя кнопку в правом верхнем углу.",
+ }
+ }
+ } catch (err) {
+ return {
+ address: "",
+ status: "😥 " + err.message,
+ }
+ }
+ } else {
+ return {
+ address: "",
+ status: (
+
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в свой
+ браузер.
+
+
+
+ ),
+ }
+ }
+}
+```
+
+Этот код _очень_ похож на функцию `connectWallet`, которую мы только что написали в предыдущем шаге.
+
+Основное отличие состоит в том, что вместо вызова метода `eth_requestAccounts`, который открывает MetaMask для подключения пользователя к кошельку, мы вызываем метод `eth_accounts`, который просто возвращает массив с адресами MetaMask, которые в данный момент подключены к нашему децентрализованному приложению.
+
+Чтобы увидеть эту функцию в действии, давайте вызовем ее в нашей функции `useEffect` нашего компонента `HelloWorld.js`:
+
+```javascript
+// HelloWorld.js
+
+useEffect(async () => {
+ const message = await loadCurrentMessage()
+ setMessage(message)
+ addSmartContractListener()
+
+ const { address, status } = await getCurrentWalletConnected()
+ setWallet(address)
+ setStatus(status)
+}, [])
+```
+
+Обратите внимание: мы используем ответ на наш вызов `getCurrentWalletConnected` для обновления наших переменных состояния `walletAddress` и `status`.
+
+Теперь, когда вы добавили этот код, давайте попробуем обновить окно нашего браузера.
+
+Отличнооооо! На кнопке должно быть указано, что вы подключены, и показан предварительный просмотр адреса вашего подключенного кошелька — даже после обновления!
+
+#### Реализуйте `addWalletListener` {#implement-addwalletlistener}
+
+Последним шагом в настройке нашего кошелька в децентрализированном приложении является реализация прослушивателя кошелька, чтобы наш пользовательский интерфейс обновлялся при изменении состояния нашего кошелька, например, когда пользователь отключает или переключает учетные записи.
+
+В вашем файле `HelloWorld.js` измените вашу функцию `addWalletListener` следующим образом:
+
+```javascript
+// HelloWorld.js
+
+function addWalletListener() {
+ if (window.ethereum) {
+ window.ethereum.on("accountsChanged", (accounts) => {
+ if (accounts.length > 0) {
+ setWallet(accounts[0])
+ setStatus("👆🏽 Напишите сообщение в текстовом поле выше.")
+ } else {
+ setWallet("")
+ setStatus("🦊 Подключитесь к MetaMask, используя кнопку в правом верхнем углу.")
+ }
+ })
+ } else {
+ setStatus(
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в свой браузер.
+
+
+ )
+ }
+}
+```
+
+Спорим, вам даже не нужна наша помощь, чтобы понять, что здесь происходит, но для полноты картины давайте быстро разберем это:
+
+- Сначала наша функция проверяет, включен ли `window.ethereum` (т. е. установлен ли MetaMask).
+ - Если нет, мы просто устанавливаем для нашей переменной состояния `status` строку JSX, которая предлагает пользователю установить MetaMask.
+ - Если он включен, мы устанавливаем прослушиватель `window.ethereum.on("accountsChanged")` в строке 3, который прослушивает изменения состояния в кошельке MetaMask, включая подключение пользователем дополнительного аккаунта к децентрализованному приложению, переключение аккаунтов или отключение аккаунта. Если подключен хотя бы один аккаунт, переменная состояния `walletAddress` обновляется как первый аккаунт в массиве `accounts`, возвращаемом прослушивателем. В противном случае `walletAddress` устанавливается как пустая строка.
+
+И последнее, но не менее важное: мы должны вызвать ее в нашей функции `useEffect`:
+
+```javascript
+// HelloWorld.js
+
+useEffect(async () => {
+ const message = await loadCurrentMessage()
+ setMessage(message)
+ addSmartContractListener()
+
+ const { address, status } = await getCurrentWalletConnected()
+ setWallet(address)
+ setStatus(status)
+
+ addWalletListener()
+}, [])
+```
+
+Вот и все! Мы успешно завершили программирование всей функциональности нашего кошелька! Теперь перейдем к нашей последней задаче: обновлению сообщения, хранящегося в нашем смарт-контракте!
+
+### Шаг 6: Реализуйте функцию `updateMessage` {#step-6-implement-the-updateMessage-function}
+
+Итак, друзья, мы на финишной прямой! В `updateMessage` вашего файла `interact.js` мы сделаем следующее:
+
+1. Убедитесь, что сообщение, которое мы хотим опубликовать в нашем смарт-контакте, является действительным
+2. Подписать нашу транзакцию с помощью MetaMask
+3. Вызвать эту функцию из нашего фронтенд-компонента `HelloWorld.js`
+
+Это не займет много времени; давайте завершим это децентрализованное приложение!
+
+#### Обработка ошибок ввода {#input-error-handling}
+
+Естественно, имеет смысл иметь некоторую обработку ошибок ввода в начале функции.
+
+Мы хотим, чтобы наша функция завершалась раньше, если не установлено расширение MetaMask, не подключен кошелек (т. е. переданный `address` является пустой строкой) или `message` является пустой строкой. Давайте добавим следующую обработку ошибок в `updateMessage`:
+
+```javascript
+// interact.js
+
+export const updateMessage = async (address, message) => {
+ if (!window.ethereum || address === null) {
+ return {
+ status:
+ "💡 Подключите свой кошелек MetaMask, чтобы обновить сообщение в блокчейне.",
+ }
+ }
+
+ if (message.trim() === "") {
+ return {
+ status: "❌ Ваше сообщение не может быть пустой строкой.",
+ }
+ }
+}
+```
+
+Теперь, когда у нас есть правильная обработка ошибок ввода, пришло время подписать транзакцию через MetaMask!
+
+#### Подписание нашей транзакции {#signing-our-transaction}
+
+Если вы уже знакомы с традиционными транзакциями Ethereum в web3, код, который мы напишем дальше, будет вам очень знаком. Ниже вашего кода обработки ошибок ввода добавьте следующее в `updateMessage`:
+
+```javascript
+// interact.js
+
+//настройка параметров транзакции
+const transactionParameters = {
+ to: contractAddress, // Обязательно, кроме случаев публикации контракта.
+ from: address, // должен совпадать с активным адресом пользователя.
+ data: helloWorldContract.methods.update(message).encodeABI(),
+}
+
+//подписание транзакции
+try {
+ const txHash = await window.ethereum.request({
+ method: "eth_sendTransaction",
+ params: [transactionParameters],
+ })
+ return {
+ status: (
+
+ ✅{" "}
+
+ Посмотрите статус вашей транзакции на Etherscan!
+
+
+ ℹ️ Как только транзакция будет проверена сетью, сообщение будет
+ обновлено автоматически.
+
+ ),
+ }
+} catch (error) {
+ return {
+ status: "😥 " + error.message,
+ }
+}
+```
+
+Давайте разберемся, что происходит. Сначала мы настраиваем параметры наших транзакций, где:
+
+- `to` указывает адрес получателя (наш смарт-контракт)
+- `from` указывает подписанта транзакции, переменную `address`, которую мы передали в нашу функцию
+- `data` содержит вызов метода `update` нашего смарт-контракта Hello World, получая нашу строковую переменную `message` в качестве входных данных
+
+Затем мы делаем вызов await, `window.ethereum.request`, где мы просим MetaMask подписать транзакцию. Обратите внимание, в строках 11 и 12 мы указываем наш метод eth, `eth_sendTransaction`, и передаем наши `transactionParameters`.
+
+На этом этапе MetaMask откроется в браузере и предложит пользователю подписать или отклонить транзакцию.
+
+- Если транзакция будет успешной, функция вернет объект JSON, где строковая JSX `status` предлагает пользователю проверить Etherscan для получения дополнительной информации о своей транзакции.
+- Если транзакция не удастся, функция вернет объект JSON, где строковая `status` передает сообщение об ошибке.
+
+В целом, наша функция `updateMessage` должна выглядеть так:
+
+```javascript
+// interact.js
+
+export const updateMessage = async (address, message) => {
+ //обработка ошибок ввода
+ if (!window.ethereum || address === null) {
+ return {
+ status:
+ "💡 Подключите свой кошелек MetaMask, чтобы обновить сообщение в блокчейне.",
+ }
+ }
+
+ if (message.trim() === "") {
+ return {
+ status: "❌ Ваше сообщение не может быть пустой строкой.",
+ }
+ }
+
+ //настройка параметров транзакции
+ const transactionParameters = {
+ to: contractAddress, // Обязательно, кроме случаев публикации контракта.
+ from: address, // должен совпадать с активным адресом пользователя.
+ data: helloWorldContract.methods.update(message).encodeABI(),
+ }
+
+ //подписание транзакции
+ try {
+ const txHash = await window.ethereum.request({
+ method: "eth_sendTransaction",
+ params: [transactionParameters],
+ })
+ return {
+ status: (
+
+ ✅{" "}
+
+ Посмотрите статус вашей транзакции на Etherscan!
+
+
+ ℹ️ Как только транзакция будет проверена сетью, сообщение будет
+ обновлено автоматически.
+
+ ),
+ }
+ } catch (error) {
+ return {
+ status: "😥 " + error.message,
+ }
+ }
+}
+```
+
+И последнее, но не менее важное: нам нужно подключить нашу функцию `updateMessage` к нашему компоненту `HelloWorld.js`.
+
+#### Подключите `updateMessage` к фронтенду `HelloWorld.js` {#connect-updatemessage-to-the-helloworld-js-frontend}
+
+Наша функция `onUpdatePressed` должна сделать вызов await к импортированной функции `updateMessage` и изменить переменную состояния `status`, чтобы отразить, удалась ли наша транзакция или нет:
+
+```javascript
+// HelloWorld.js
+
+const onUpdatePressed = async () => {
+ const { status } = await updateMessage(walletAddress, newMessage)
+ setStatus(status)
+}
+```
+
+Это очень чисто и просто. И угадайте что... ВАШЕ ДЕЦЕНТРАЛИЗОВАННОЕ ПРИЛОЖЕНИЕ ГОТОВО!!!
+
+Вперед, протестируйте кнопку **Обновить**!
+
+### Создайте свое собственное децентрализованное приложение {#make-your-own-custom-dapp}
+
+Ура, вы дошли до конца руководства! Подведем итоги, вы научились:
+
+- Подключить кошелек MetaMask к вашему проекту децентрализованного приложения
+- Считывать данные с вашего смарт-контракта с помощью API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3)
+- Подписывать транзакции Ethereum с помощью MetaMask
+
+Теперь вы полностью готовы применить навыки из этого руководства для создания своего собственного проекта децентрализованного приложения! Как всегда, если у вас есть какие-либо вопросы, не стесняйтесь обращаться к нам за помощью в [Discord Alchemy](https://discord.gg/gWuC7zB). 🧙♂️
+
+Как только вы завершите это руководство, дайте нам знать, как прошел ваш опыт или если у вас есть какие-либо отзывы, отметив нас в Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform)!
diff --git a/public/content/translations/ru/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/ru/developers/tutorials/hello-world-smart-contract/index.md
new file mode 100644
index 00000000000..7088312fe7a
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/hello-world-smart-contract/index.md
@@ -0,0 +1,367 @@
+---
+title: "Смарт-контракт Hello World для начинающих"
+description: "Вводное руководство по написанию и развертыванию простого смарт-контракта на Ethereum."
+author: "elanh"
+tags:
+ [
+ "Solidity",
+ "Hardhat",
+ "Alchemy",
+ "Умные контракты",
+ "развертывание"
+ ]
+skill: beginner
+lang: ru
+published: 2021-03-31
+---
+
+Если вы новичок в разработке блокчейн-приложений и не знаете, с чего начать, или если вы просто хотите понять, как развертывать смарт-контракты и взаимодействовать с ними, это руководство для вас. Мы рассмотрим создание и развертывание простого смарт-контракта в тестовой сети Sepolia с помощью виртуального кошелька [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) и [Alchemy](https://www.alchemy.com/eth) (не волнуйтесь, если вы еще не понимаете, что все это значит, мы объясним).
+
+Во [второй части](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) этого руководства мы рассмотрим, как можно взаимодействовать с нашим смарт-контрактом после его развертывания, а в [третьей части](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) мы расскажем, как опубликовать его на Etherscan.
+
+Если у вас на любом этапе возникнут вопросы, не стесняйтесь задавать их в [Discord-канале Alchemy](https://discord.gg/gWuC7zB)!
+
+## Шаг 1. Подключение к сети Ethereum {#step-1}
+
+Существует много способов отправлять запросы в сеть Ethereum. Для простоты мы будем использовать бесплатную учетную запись на Alchemy — это платформа для блокчейн-разработчиков и API, которая позволяет нам взаимодействовать с блокчейном Ethereum без необходимости запускать собственные узлы. Платформа также имеет инструменты для мониторинга и аналитики, которыми мы воспользуемся в этом руководстве, чтобы понять, что происходит «под капотом» при развертывании нашего смарт-контракта. Если у вас еще нет учетной записи Alchemy, [вы можете бесплатно зарегистрироваться здесь](https://dashboard.alchemy.com/signup).
+
+## Шаг 2. Создайте свое приложение (и ключ API) {#step-2}
+
+Как только регистрация в Alchemy завершена, можно создать приложение и таким образом сгенерировать ключ API. Это позволит нам делать запросы к тестовой сети Sepolia. Если вы не знакомы с тестовыми сетями, ознакомьтесь с [этой страницей](/developers/docs/networks/).
+
+1. Перейдите на страницу "Create new app" в вашей панели управления Alchemy, выбрав "Select an app" на панели навигации и нажав "Create new app"
+
+
+
+2. Назовите свое приложение "Hello World", добавьте краткое описание и выберите вариант использования, например "Infra & Tooling". Далее найдите "Ethereum" и выберите сеть.
+
+
+
+3. Нажмите "Next" для продолжения, затем “Create app”, и все готово! Ваше приложение должно появиться в раскрывающемся меню панели навигации, а ключ API будет доступен для копирования.
+
+## Шаг 3. Создайте учетную запись Ethereum (адрес) {#step-3}
+
+Нам нужен аккаунт Ethereum для того, чтобы отправлять и получать транзакции. В этом руководстве мы будем использовать MetaMask, виртуальный кошелек в браузере, используемый для управления адресом вашего аккаунта Ethereum. Подробнее о [транзакциях](/developers/docs/transactions/).
+
+Вы можете скачать MetaMask и бесплатно создать учетную запись Ethereum [здесь](https://metamask.io/download). При создании учетной записи или если она у вас уже есть, обязательно переключитесь на тестовую сеть "Sepolia" в раскрывающемся меню сетей (чтобы мы не работали с реальными деньгами).
+
+Если вы не видите Sepolia в списке, зайдите в меню, затем в раздел Advanced и прокрутите вниз, чтобы включить опцию "Show test networks". В меню выбора сети перейдите на вкладку "Custom", чтобы найти список тестовых сетей, и выберите "Sepolia".
+
+
+
+## Шаг 4. Получите эфир из крана {#step-4}
+
+Чтобы развернуть наш смарт-контракт в тестовой сети, нам понадобится немного тестового Eth. Чтобы получить ETH в сети Sepolia, вы можете перейти к [сведениям о сети Sepolia](/developers/docs/networks/#sepolia), чтобы просмотреть список различных кранов. Если один не работает, попробуйте другой, так как они иногда могут иссякать. Получение тестовых ETH может занять некоторое время из-за загруженности сети. Вскоре после этого вы увидите ETH в своем кошельке MetaMask!
+
+## Шаг 5. Проверьте свой баланс {#step-5}
+
+Чтобы дважды проверить наш баланс, давайте сделаем запрос [eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance), используя [инструмент Alchemy Composer](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest). Результат будет содержать сумму ETH в нашем кошельке. После ввода адреса вашего аккаунта MetaMask и нажатия «Send Request» вы должны увидеть примерно такой ответ:
+
+```json
+{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }
+```
+
+> **ПРИМЕЧАНИЕ.** Этот результат указан в wei, а не в ETH. Wei это наименьшая единица измерения эфира. Конвертация из wei в ETH: 1 eth = 1018 wei. Итак, если мы конвертируем 0x2B5E3AF16B1880000 в десятичную систему, мы получим 5\*10¹⁸, что равно 5 ETH.
+>
+> Фух! Наши тестовые деньги на месте .
+
+## Шаг 6. Инициализируйте наш проект {#step-6}
+
+Во-первых, надо создать директорию для нашего проекта. Перейдите в вашу командную строку и наберите:
+
+```
+mkdir hello-world
+cd hello-world
+```
+
+Теперь, когда мы находимся в папке нашего проекта, мы будем использовать `npm init` для его инициализации. Если у вас еще не установлен npm, следуйте [этим инструкциям](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (нам также понадобится Node.js, так что скачайте и его!).
+
+```
+npm init
+```
+
+Неважно, как вы ответите на вопросы при установке. Вот как для примера сделали это мы:
+
+```
+имя пакета: (hello-world)
+версия: (1.0.0)
+описание: hello world smart contract
+точка входа: (index.js)
+тестовая команда:
+репозиторий git:
+ключевые слова:
+автор:
+лицензия: (ISC)
+О файле /Users/.../.../.../hello-world/package.json будет записано следующее:
+
+{
+ "name": "hello-world",
+ "version": "1.0.0",
+ "description": "hello world smart contract",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
+```
+
+Подтвердите `package.json`, и мы готовы!
+
+## Шаг 7. Загрузите [Hardhat](https://hardhat.org/getting-started/#overview) {#step-7}
+
+Hardhat - это среда для сборки, развертывания, тестирования и отладки программного обеспечения Ethereum. Он помогает разработчикам создавать смарт-контракты и децентрализованные приложения локально перед их развертыванием в основной сети.
+
+Внутри нашего проекта `hello-world` запустите:
+
+```
+npm install --save-dev hardhat
+```
+
+Более подробную информацию об [инструкциях по установке](https://hardhat.org/getting-started/#overview) можно найти на этой странице.
+
+## Шаг 8. Создайте проект Hardhat {#step-8}
+
+В директории проекта запустите:
+
+```
+npx hardhat
+```
+
+Вы увидите приветственное сообщение и интерфейс с вариантами того, что делать дальше. Выберите "create an empty hardhat.config.js":
+
+```
+888 888 888 888 888
+888 888 888 888 888
+888 888 888 888 888
+8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
+888 888 "88b 888P" d88" 888 888 "88b "88b 888
+888 888 .d888888 888 888 888 888 888 .d888888 888
+888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
+888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
+
+👷 Добро пожаловать в Hardhat v2.0.11 👷?
+
+Что вы хотите сделать? …
+Создать пример проекта
+❯ Создать пустой hardhat.config.js
+Выйти
+```
+
+Эта команда создаст для нас файл `hardhat.config.js`, в котором мы укажем все настройки для нашего проекта (в шаге 13).
+
+## Шаг 9. Добавьте папки проекта {#step-9}
+
+Для поддержания порядка в проекте мы создадим две новые папки. Перейдите в командной строке в корневую директорию проекта и наберите:
+
+```
+mkdir contracts
+mkdir scripts
+```
+
+- `contracts/` — здесь мы будем хранить файл с кодом нашего смарт-контракта «hello world».
+- `scripts/` — здесь мы будем хранить скрипты для развертывания нашего контракта и взаимодействия с ним.
+
+## Шаг 10. Напишите наш контракт {#step-10}
+
+Вы, наверное, спрашиваете себя, когда же мы наконец начнем писать код?? Что ж, вот мы и на шаге 10.
+
+Откройте проект hello-world в вашем любимом редакторе (нам нравится [VSCode](https://code.visualstudio.com/)). Смарт-контракты пишутся на языке под названием Solidity, который мы и будем использовать для написания нашего смарт-контракта HelloWorld.sol.
+
+1. Перейдите в папку «contracts» и создайте новый файл с именем HelloWorld.sol
+2. Ниже приведен пример смарт-контракта Hello World от Ethereum Foundation, который мы будем использовать в этом руководстве. Скопируйте и вставьте приведенное ниже содержимое в ваш файл HelloWorld.sol и обязательно прочтите комментарии, чтобы понять, что делает этот контракт:
+
+```solidity
+// Указывает версию Solidity с использованием семантического версионирования.
+// Подробнее: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
+pragma solidity ^0.7.0;
+
+// Определяет контракт с именем `HelloWorld`.
+// Контракт — это набор функций и данных (его состояние). После развертывания контракт размещается по определенному адресу в блокчейне Ethereum. Подробнее: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
+contract HelloWorld {
+
+ // Объявляет переменную состояния `message` типа `string`.
+ // Переменные состояния — это переменные, значения которых постоянно хранятся в хранилище контракта. Ключевое слово `public` делает переменные доступными извне контракта и создает функцию, которую другие контракты или клиенты могут вызывать для доступа к значению.
+ string public message;
+
+ // Подобно многим объектно-ориентированным языкам на основе классов, конструктор — это специальная функция, которая выполняется только при создании контракта.
+ // Конструкторы используются для инициализации данных контракта. Подробнее: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
+ constructor(string memory initMessage) {
+
+ // Принимает строковый аргумент `initMessage` и устанавливает значение в переменной хранения контракта `message`).
+ message = initMessage;
+ }
+
+ // Публичная функция, которая принимает строковый аргумент и обновляет переменную хранения `message`.
+ function update(string memory newMessage) public {
+ message = newMessage;
+ }
+}
+```
+
+Это очень простой смарт-контракт, который сохраняет сообщение при создании и может быть обновлен путем вызова функции `update`.
+
+## Шаг 11. Подключите MetaMask и Alchemy к вашему проекту {#step-11}
+
+Мы создали кошелек MetaMask, учетную запись Alchemy и написали наш смарт-контракт, теперь пришло время их соединить.
+
+Каждая транзакция, сделанная с вашего виртуального кошелька, требует подпись с использованием вашего же персонального ключа. Чтобы дать программе такую возможность, мы можем сохранить наш приватный ключ (и ключ API Alchemy) в файле окружения.
+
+> Чтобы узнать больше об отправке транзакций, ознакомьтесь с [этим руководством по отправке транзакций с использованием web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/).
+
+Во-первых, установите dotenv, находясь в директории проекта:
+
+```
+npm install dotenv --save
+```
+
+Затем создайте файл `.env` в корневом каталоге нашего проекта и добавьте в него свой закрытый ключ MetaMask и URL-адрес HTTP API Alchemy.
+
+- Следуйте [этим инструкциям](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/), чтобы экспортировать свой приватный ключ
+- Ниже показано, как получить URL-адрес HTTP API Alchemy
+
+
+
+Скопируйте URL-адрес API Alchemy
+
+Ваш `.env` должен выглядеть следующим образом:
+
+```
+API_URL = "https://eth-sepolia.g.alchemy.com/v2/ваш-ключ-api"
+PRIVATE_KEY = "ваш-приватный-ключ-metamask"
+```
+
+Чтобы подключить их к нашему коду, мы будем ссылаться на эти переменные в нашем файле `hardhat.config.js` в шаге 13.
+
+
+
+
+Не добавляйте .env в коммиты! Пожалуйста, никогда и никому не сообщайте и не показывайте содержимое файла .env, так как тем самым вы компрометируете свои секретные данные. Если вы используете систему контроля версий, добавьте .env в файл gitignore.
+
+
+
+
+## Шаг 12: Установите Ethers.js {#step-12-install-ethersjs}
+
+Ethers.js — это библиотека, которая упрощает взаимодействие и отправку запросов в Ethereum, оборачивая [стандартные методы JSON-RPC](/developers/docs/apis/json-rpc/) в более удобные для пользователя методы.
+
+Hardhat очень упрощает интеграцию [плагинов](https://hardhat.org/plugins/) для дополнительных инструментов и расширенной функциональности. Мы воспользуемся преимуществами [плагина Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) для развертывания контракта ([Ethers.js](https://github.com/ethers-io/ethers.js/) имеет несколько очень удобных методов развертывания контрактов).
+
+В директории проекта запустите:
+
+```
+npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
+```
+
+Нам также потребуется ethers в нашем `hardhat.config.js` на следующем шаге.
+
+## Шаг 13: Обновите hardhat.config.js {#step-13-update-hardhatconfigjs}
+
+Мы добавили несколько зависимостей и плагинов, и теперь нам нужно обновить `hardhat.config.js`, чтобы наш проект знал обо всех них.
+
+Обновите ваш `hardhat.config.js`, чтобы он выглядел следующим образом:
+
+```
+require('dotenv').config();
+
+require("@nomiclabs/hardhat-ethers");
+const { API_URL, PRIVATE_KEY } = process.env;
+
+/**
+* @type import('hardhat/config').HardhatUserConfig
+*/
+module.exports = {
+ solidity: "0.7.3",
+ defaultNetwork: "sepolia",
+ networks: {
+ hardhat: {},
+ sepolia: {
+ url: API_URL,
+ accounts: [`0x${PRIVATE_KEY}`]
+ }
+ },
+}
+```
+
+## Шаг 14: Скомпилируйте наш контракт {#step-14-compile-our-contracts}
+
+Пора заставить это работать, давайте скомпилируем наш контракт. Задача `compile` — одна из встроенных задач hardhat.
+
+Запустите в командной строке:
+
+```
+npx hardhat compile
+```
+
+Вы можете получить предупреждение об `SPDX license identifier not provided in source file`, но не беспокойтесь об этом — надеюсь, все остальное выглядит хорошо! Если нет, вы всегда можете написать в [Discord-канал Alchemy](https://discord.gg/u72VCg3).
+
+## Шаг 15: Напишите наш скрипт развертывания {#step-15-write-our-deploy-scripts}
+
+Контракт написан, файл конфигурации корректен, пора писать скрипт развертывания.
+
+Перейдите в папку `scripts/`, создайте новый файл `deploy.js` и добавьте в него следующее содержимое:
+
+```
+async function main() {
+ const HelloWorld = await ethers.getContractFactory("HelloWorld");
+
+ // Start deployment, returning a promise that resolves to a contract object
+ const hello_world = await HelloWorld.deploy("Привет, мир!");
+ console.log("Контракт развернут по адресу:", hello_world.address);}
+
+main()
+ .then(() => process.exit(0))
+ .catch(error => {
+ console.error(error);
+ process.exit(1);
+ });
+```
+
+Hardhat отлично объясняет, что делает каждая из этих строк кода, в своем [руководстве по контрактам](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), мы использовали их объяснения здесь.
+
+```
+const HelloWorld = await ethers.getContractFactory("HelloWorld");
+```
+
+`ContractFactory` в ethers.js — это абстракция, используемая для развертывания новых смарт-контрактов, так что `HelloWorld` здесь — это фабрика для экземпляров нашего контракта «hello world». При использовании плагина `hardhat-ethers` экземпляры `ContractFactory` и `Contract` по умолчанию подключаются к первому подписанту.
+
+```
+const hello_world = await HelloWorld.deploy();
+```
+
+Вызов `deploy()` на `ContractFactory` запустит развертывание и вернет `Promise`, который разрешается в `Contract`. Это объект, который имеет метод для каждой из функций нашего смарт контракта.
+
+## Шаг 16: Разверните наш контракт {#step-16-deploy-our-contract}
+
+Мы наконец-то готовы развернуть наш смарт контракт! Перейдите в командную строку и запустите:
+
+```
+npx hardhat run scripts/deploy.js --network sepolia
+```
+
+Вы должны увидеть что-то наподобие:
+
+```
+Контракт развернут по адресу: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
+```
+
+Если мы перейдем на [Etherscan для Sepolia](https://sepolia.etherscan.io/) и выполним поиск по адресу нашего контракта, то увидим, что он был успешно развернут. Транзакция будет выглядеть примерно так:
+
+
+
+Адрес `From` должен совпадать с адресом вашей учетной записи MetaMask, а в адресе `To` будет указано «Contract Creation», но если мы нажмем на транзакцию, мы увидим адрес нашего контракта в поле `To`:
+
+
+
+Поздравляем! Вы только что развернули смарт-контракт в блокчейне Ethereum 🎉
+
+Чтобы понять, что происходит «под капотом», давайте перейдем на вкладку Explorer в нашей [панели управления Alchemy](https://dashboard.alchemyapi.io/explorer). Если у вас несколько приложений Alchemy, убедитесь, что вы отфильтровали их по приложению и выбрали «Hello World».
+
+
+Здесь вы увидите несколько вызовов JSON-RPC, которые Hardhat/Ethers сделали для нас «под капотом», когда мы вызывали функцию `.deploy()`. Здесь следует отметить два важных вызова: [`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction), который является запросом на фактическую запись нашего контракта в сеть Sepolia, и [`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash), который является запросом на чтение информации о нашей транзакции по заданному хешу (типичный шаблон при работе с
+транзакциями). Чтобы узнать больше об отправке транзакций, ознакомьтесь с этим руководством по [отправке транзакций с помощью Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)
+
+На этом первая часть этого руководства закончена, во второй части мы будем [взаимодействовать с нашим смарт-контрактом](https://www.alchemy.com/docs/interacting-with-a-smart-contract), обновив наше первоначальное сообщение, а в третьей части мы [опубликуем наш смарт-контракт на Etherscan](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan), чтобы каждый мог узнать, как с ним взаимодействовать.
+
+**Хотите узнать больше об Alchemy? Посетите наш [веб-сайт](https://www.alchemy.com/eth). Никогда не хотите пропускать обновления? Подпишитесь на нашу рассылку [здесь](https://www.alchemy.com/newsletter)! Обязательно присоединяйтесь к нашему [Discord](https://discord.gg/u72VCg3).**.
diff --git a/public/content/translations/ru/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/ru/developers/tutorials/how-to-implement-an-erc721-market/index.md
new file mode 100644
index 00000000000..41884a12c1f
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-implement-an-erc721-market/index.md
@@ -0,0 +1,145 @@
+---
+title: "Как внедрить рынок ERC-721"
+description: "Как поставить «токенизированные» товары на продажу на децентрализованную доску объявлений"
+author: "Alberto Cuesta Cañada"
+tags: [ "смарт-контракты", "erc-721", "Solidity", "токенов" ]
+skill: intermediate
+lang: ru
+published: 2020-03-19
+source: Hackernoon
+sourceUrl: https://hackernoon.com/how-to-implement-an-erc721-market-1e1a32j9
+---
+
+В этой статье я покажу вам, как программировать Craigslist для блокчейна Ethereum.
+
+До Gumtree, Ebay and Craigslist, классифицированные доски в основном были сделаны из пробки или бумаги. В школьных коридорах были доски объявлений, газеты, уличные фонари, витрины магазинов.
+
+С появлением интернета все изменилось. Число людей, которые могли увидеть конкретную доску объявлений, увеличилось на много порядков. Благодаря этому рынки, которые они представляют, стали гораздо эффективнее и масштабировались до глобальных размеров. Ebay — это огромный бизнес, который берет свое начало от этих физических досок объявлений.
+
+С появлением блокчейна эти рынки снова изменятся, и я покажу вам, как именно.
+
+## Монетизация {#monetization}
+
+Бизнес-модель общедоступной блокчейн-доски объявлений должна будет отличаться от бизнес-модели Ebay и подобных компаний.
+
+Во-первых, есть [аспект децентрализации](/developers/docs/web2-vs-web3/). Существующие платформы должны обслуживать собственные серверы. Децентрализованная платформа поддерживается ее пользователями, поэтому стоимость эксплуатации основной платформы для ее владельца падает до нуля.
+
+Далее идет внешний интерфейс, веб-сайт или интерфейс, который предоставляет доступ к платформе. Здесь есть много вариантов. Владельцы платформы могут ограничивать доступ и заставлять всех использовать их интерфейс, взимая за это плату. Владельцы платформы также могут решить открыть доступ (Власть народу!) и позволить любому создавать интерфейсы для платформы. Или владельцы могут выбрать любой подход между этими двумя крайностями.
+
+_Бизнес-лидеры с более широким видением, чем у меня, будут знать, как это монетизировать. Все, что я вижу, — это то, что это отличается от существующего положения вещей и, вероятно, выгодно._
+
+Кроме того, есть аспект автоматизации и платежей. Некоторые вещи можно очень [эффективно токенизировать](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) и продавать на доске объявлений. Токенизированные активы легко передаются в блокчейне. В блокчейне можно легко реализовать очень сложные методы оплаты.
+
+Я просто чую здесь возможность для бизнеса. Доска объявлений без эксплуатационных расходов может быть легко реализована, со сложными путями платежей, включенными в каждую транзакцию. Уверен, кто-нибудь придумает, для чего это можно использовать.
+
+Я просто рад это создавать. Давайте посмотрим на код.
+
+## Реализация {#implementation}
+
+Некоторое время назад мы создали [репозиторий с открытым исходным кодом](https://github.com/HQ20/contracts?ref=hackernoon.com) с примерами реализаций бизнес-кейсов и другими полезными вещами, пожалуйста, ознакомьтесь.
+
+Код для этой [доски объявлений Ethereum](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) находится там, пожалуйста, используйте его и злоупотребляйте им. Просто имейте в виду, что код не прошел аудит, и вам необходимо провести собственную комплексную проверку, прежде чем вкладывать в него деньги.
+
+Основы доски объявлений несложны. Все объявления на доске будут представлять собой просто структуру с несколькими полями:
+
+```solidity
+struct Trade {
+ address poster;
+ uint256 item;
+ uint256 price;
+ bytes32 status; // Открыта, Исполнена, Отменена
+}
+```
+
+Итак, кто-то размещает объявление. Товар на продажу. Цена за товар. Статус сделки, который может быть «открыта», «исполнена» или «отменена».
+
+Все эти сделки будут храниться в сопоставлении (mapping). Потому что в Solidity все, кажется, является сопоставлением (mapping). А также потому, что это удобно.
+
+```solidity
+mapping(uint256 => Trade) public trades;
+```
+
+Использование сопоставления (mapping) просто означает, что мы должны придумать идентификатор для каждого объявления перед его размещением, и нам нужно будет знать идентификатор объявления, прежде чем мы сможем с ним работать. Есть несколько способов справиться с этим либо в смарт-контракте, либо во внешнем интерфейсе. Пожалуйста, спросите, если вам нужны какие-либо подсказки.
+
+Далее возникает вопрос о том, с какими предметами мы имеем дело, и какая валюта используется для оплаты транзакции.
+
+Что касается предметов, мы просто попросим, чтобы они реализовывали интерфейс [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com), который на самом деле является просто способом представления предметов реального мира в блокчейне, хотя он [лучше всего работает с цифровыми активами](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Мы собираемся указать наш собственный контракт ERC721 в конструкторе, что означает, что любые активы на нашей доске объявлений должны быть предварительно токенизированы.
+
+Для платежей мы собираемся сделать нечто подобное. Большинство блокчейн-проектов определяют свою собственную криптовалюту [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com). Некоторые другие предпочитают использовать популярную валюту, например DAI. На этой доске объявлений вам просто нужно при создании решить, какой будет ваша валюта. Легко.
+
+```solidity
+constructor (
+ address _currencyTokenAddress, address _itemTokenAddress
+) public {
+ currencyToken = IERC20(_currencyTokenAddress);
+ itemToken = IERC721(_itemTokenAddress);
+ tradeCounter = 0;
+}
+```
+
+Мы почти у цели. У нас есть объявления, предметы для торговли и валюта для платежей. Разместить объявление означает поместить предмет на эскроу-счет, чтобы показать, что он у вас есть и что вы не разместили его дважды, возможно, на другой доске.
+
+Приведенный ниже код делает именно это. Помещает предмет на эскроу-счет, создает объявление, выполняет некоторые административные действия.
+
+```solidity
+function openTrade(uint256 _item, uint256 _price)
+ public
+{
+ itemToken.transferFrom(msg.sender, address(this), _item);
+ trades[tradeCounter] = Trade({
+ poster: msg.sender,
+ item: _item,
+ price: _price,
+ status: "Open"
+ });
+ tradeCounter += 1;
+ emit TradeStatusChange(tradeCounter - 1, "Open");
+}
+```
+
+Принять сделку означает выбрать объявление (сделку), оплатить цену, получить товар. Код ниже извлекает сделку. Проверяет ее доступность. Оплачивает товар. Получает товар. Обновляет объявление.
+
+```solidity
+function executeTrade(uint256 _trade)
+ public
+{
+ Trade memory trade = trades[_trade];
+ require(trade.status == "Open", "Сделка не открыта.");
+ currencyToken.transferFrom(msg.sender, trade.poster, trade.price);
+ itemToken.transferFrom(address(this), msg.sender, trade.item);
+ trades[_trade].status = "Executed";
+ emit TradeStatusChange(_trade, "Executed");
+}
+```
+
+Наконец, у нас есть возможность для продавцов отказаться от сделки до того, как ее примет покупатель. В некоторых моделях объявления вместо этого будут активны в течение определенного периода времени, прежде чем истечет их срок действия. Ваш выбор, в зависимости от дизайна вашего рынка.
+
+Код очень похож на тот, что используется для исполнения сделки, только валюта не переходит из рук в руки, а товар возвращается автору объявления.
+
+```solidity
+function cancelTrade(uint256 _trade)
+ public
+{
+ Trade memory trade = trades[_trade];
+ require(
+ msg.sender == trade.poster,
+ "Сделка может быть отменена только ее автором."
+ );
+ require(trade.status == "Open", "Сделка не открыта.");
+ itemToken.transferFrom(address(this), trade.poster, trade.item);
+ trades[_trade].status = "Cancelled";
+ emit TradeStatusChange(_trade, "Cancelled");
+}
+```
+
+Вот и все. Вы дошли до конца реализации. Удивительно, насколько компактными могут быть некоторые бизнес-концепции, выраженные в коде, и это один из таких случаев. Посмотрите полный контракт [в нашем репозитории](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol).
+
+## Заключение {#conclusion}
+
+Доски объявлений — это распространенная конфигурация рынка, которая массово масштабировалась с появлением Интернета, став чрезвычайно популярной бизнес-моделью с несколькими монополистическими победителями.
+
+Доски объявлений также оказались простым инструментом для воспроизведения в среде блокчейна, с очень специфическими особенностями, которые сделают возможным вызов существующим гигантам.
+
+В этой статье я попытался соединить бизнес-реальность доски объявлений с технологической реализацией. Эти знания должны помочь вам создать видение и дорожную карту для реализации, если у вас есть необходимые навыки.
+
+Как всегда, если вы собираетесь создать что-то интересное и хотели бы получить совет, пожалуйста, [напишите мне](https://albertocuesta.es/)! Я всегда рад помочь.
diff --git a/public/content/translations/ru/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/ru/developers/tutorials/how-to-mint-an-nft/index.md
new file mode 100644
index 00000000000..43eeac731af
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-mint-an-nft/index.md
@@ -0,0 +1,329 @@
+---
+title: "Как создать NFT (часть 2 из 3 серии руководств по NFT)"
+description: "Это руководство описывает, как создать NFT в блокчейне Ethereum, используя наш смарт-контракт и Web3."
+author: "Sumi Mudgil"
+tags: [ "ERC-721", "Alchemy", "Solidity", "Умные контракты" ]
+skill: beginner
+lang: ru
+published: 2021-04-22
+---
+
+[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 69 миллионов долларов
+[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 11 миллионов долларов
+[Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 6 миллионов долларов
+
+Все они создали свои NFT, используя мощный API Alchemy. В этом руководстве мы научим вас, как сделать то же самое менее чем за 10 минут.
+
+«Создание NFT» — это акт публикации уникального экземпляра вашего токена ERC-721 в блокчейне. Используя наш смарт-контракт из [части 1 этой серии руководств по NFT](/developers/tutorials/how-to-write-and-deploy-an-nft/), давайте продемонстрируем наши навыки в Web3 и создадим NFT. В конце этого руководства вы сможете создать столько NFT, сколько душе (и кошельку) будет угодно!
+
+Приступим!
+
+## Шаг 1. Установите Web3 {#install-web3}
+
+Если вы следовали первому руководству по созданию смарт-контракта NFT, у вас уже есть опыт использования Ethers.js. Web3 похож на Ethers, так как это библиотека, используемая для упрощения создания запросов в блокчейн Ethereum. В этом руководстве мы будем использовать [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3), которая является усовершенствованной библиотекой Web3, предлагающей автоматические повторные попытки и надежную поддержку WebSocket.
+
+В домашнем каталоге вашего проекта выполните:
+
+```
+npm install @alch/alchemy-web3
+```
+
+## Шаг 2. Создайте файл `mint-nft.js` {#create-mintnftjs}
+
+В каталоге `scripts` создайте файл `mint-nft.js` и добавьте следующие строки кода:
+
+```js
+require("dotenv").config()
+const API_URL = process.env.API_URL
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(API_URL)
+```
+
+## Шаг 3. Получите ABI вашего контракта {#contract-abi}
+
+ABI (двоичный интерфейс приложения) нашего контракта — это интерфейс для взаимодействия с нашим смарт-контрактом. Подробнее об ABI контрактов можно узнать [здесь](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is). Hardhat автоматически генерирует для нас ABI и сохраняет его в файле `MyNFT.json`. Чтобы использовать его, нам нужно будет проанализировать содержимое, добавив следующие строки кода в наш файл `mint-nft.js`:
+
+```js
+const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
+```
+
+Если вы хотите увидеть ABI, вы можете вывести его в консоль:
+
+```js
+console.log(JSON.stringify(contract.abi))
+```
+
+Чтобы запустить `mint-nft.js` и увидеть свой ABI, выведенный в консоль, перейдите в терминал и выполните команду:
+
+```js
+node scripts/mint-nft.js
+```
+
+## Шаг 4. Настройте метаданные для вашего NFT с помощью IPFS {#config-meta}
+
+Если вы помните из нашего руководства в части 1, наша функция смарт-контракта `mintNFT` принимает параметр tokenURI, который должен преобразовываться в JSON-документ, описывающий метаданные NFT, — это то, что действительно оживляет NFT, позволяя ему иметь настраиваемые свойства, такие как имя, описание, изображение и другие атрибуты.
+
+> _Межпланетная файловая система (Interplanetary File System, IPFS) — это децентрализованный протокол и одноранговая сеть для хранения и обмена данными в распределенной файловой системе._
+
+Мы будем использовать Pinata, удобный API и инструментарий для IPFS, для хранения нашего NFT-актива и метаданных, чтобы гарантировать, что наш NFT действительно децентрализован. Если у вас нет аккаунта Pinata, зарегистрируйте бесплатный аккаунт [здесь](https://app.pinata.cloud) и выполните шаги для подтверждения вашей электронной почты.
+
+После создания аккаунта:
+
+- Перейдите на страницу «Файлы» и нажмите синюю кнопку «Загрузить» в левом верхнем углу страницы.
+
+- Загрузите изображение в Pinata — это будет графический актив для вашего NFT. Не стесняйтесь называть актив так, как вам хочется.
+
+- После загрузки вы увидите информацию о файле в таблице на странице «Файлы». Вы также увидите столбец CID. Вы можете скопировать CID, нажав на кнопку копирования рядом с ним. Вы можете просмотреть загруженный файл по адресу: `https://gateway.pinata.cloud/ipfs/`. Например, изображение, которое мы использовали, можно найти на IPFS [здесь](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5).
+
+Для тех, кто лучше воспринимает информацию визуально, вышеуказанные шаги кратко изложены здесь:
+
+
+
+Теперь нам нужно загрузить в Pinata еще один документ. Но прежде чем мы это сделаем, нам нужно его создать!
+
+В корневом каталоге создайте новый файл с именем `nft-metadata.json` и добавьте в него следующий JSON-код:
+
+```json
+{
+ "attributes": [
+ {
+ "trait_type": "Порода",
+ "value": "Мальтипу"
+ },
+ {
+ "trait_type": "Цвет глаз",
+ "value": "Мокко"
+ }
+ ],
+ "description": "Самый очаровательный и чувствительный щенок в мире.",
+ "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
+ "name": "Рамзес"
+}
+```
+
+Вы можете изменять данные в JSON. Вы можете удалять или добавлять атрибуты в раздел `attributes`. Самое главное, убедитесь, что поле `image` указывает на местоположение вашего изображения в IPFS — в противном случае ваш NFT будет содержать фотографию (очень милой!) собаки.
+
+Завершив редактирование файла JSON, сохраните его и загрузите в Pinata, выполнив те же действия, что и при загрузке изображения.
+
+
+
+## Шаг 5. Создайте экземпляр вашего контракта {#instance-contract}
+
+Теперь, чтобы взаимодействовать с нашим контрактом, нам нужно создать его экземпляр в нашем коде. Для этого нам понадобится адрес нашего контракта, который мы можем получить из развертывания или [Blockscout](https://eth-sepolia.blockscout.com/), найдя адрес, который вы использовали для развертывания контракта.
+
+
+
+В приведенном выше примере адрес нашего контракта — 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778.
+
+Далее мы будем использовать [метод contract](https://docs.web3js.org/api/web3-eth-contract/class/Contract) из Web3 для создания нашего контракта, используя ABI и адрес. В свой файл `mint-nft.js` добавьте следующее:
+
+```js
+const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
+
+const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
+```
+
+## Шаг 6. Обновите файл `.env` {#update-env}
+
+Теперь для создания и отправки транзакций в сеть Ethereum мы будем использовать адрес вашего публичного аккаунта Ethereum, чтобы получить nonce аккаунта (объясним ниже).
+
+Добавьте свой публичный ключ в файл `.env` — если вы выполнили часть 1 руководства, ваш файл `.env` теперь должен выглядеть так:
+
+```js
+API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key"
+PRIVATE_KEY = "your-private-account-address"
+PUBLIC_KEY = "your-public-account-address"
+```
+
+## Шаг 7. Создайте свою транзакцию {#create-txn}
+
+Сначала давайте определим функцию с именем `mintNFT(tokenData)` и создадим нашу транзакцию, выполнив следующие действия:
+
+1. Возьмите _PRIVATE_KEY_ и _PUBLIC_KEY_ из файла `.env`.
+
+2. Далее нам нужно определить nonce аккаунта. Спецификация nonce используется для отслеживания количества транзакций, отправленных с вашего адреса, что необходимо в целях безопасности и для предотвращения [атак повторного воспроизведения](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce). Чтобы получить количество транзакций, отправленных с вашего адреса, мы используем [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount).
+
+3. Наконец, мы настроим нашу транзакцию со следующей информацией:
+
+- `'from': PUBLIC_KEY` — источник нашей транзакции — наш публичный адрес.
+
+- `'to': contractAddress` — контракт, с которым мы хотим взаимодействовать и которому отправляем транзакцию.
+
+- `'nonce': nonce` — nonce аккаунта с количеством транзакций, отправленных с нашего адреса.
+
+- `'gas': estimatedGas` — расчетное количество газа, необходимое для завершения транзакции.
+
+- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — вычисление, которое мы хотим выполнить в этой транзакции, — в данном случае это создание NFT.
+
+Теперь ваш файл `mint-nft.js` должен выглядеть следующим образом:
+
+```js
+ require('dotenv').config();
+ const API_URL = process.env.API_URL;
+ const PUBLIC_KEY = process.env.PUBLIC_KEY;
+ const PRIVATE_KEY = process.env.PRIVATE_KEY;
+
+ const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
+ const web3 = createAlchemyWeb3(API_URL);
+
+ const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
+ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778";
+ const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
+
+ async function mintNFT(tokenURI) {
+ const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //получаем последний nonce
+
+ //транзакция
+ const tx = {
+ 'from': PUBLIC_KEY,
+ 'to': contractAddress,
+ 'nonce': nonce,
+ 'gas': 500000,
+ 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
+ };
+ }
+```
+
+## Шаг 8. Подпишите транзакцию {#sign-txn}
+
+Теперь, когда мы создали нашу транзакцию, нам нужно подписать ее, чтобы отправить. Здесь мы будем использовать наш приватный ключ.
+
+`web3.eth.sendSignedTransaction` предоставит нам хэш транзакции, который мы можем использовать, чтобы убедиться, что наша транзакция была обработана и не была отброшена сетью. Вы заметите, что в разделе подписи транзакции мы добавили проверку ошибок, чтобы знать, успешно ли прошла наша транзакция.
+
+```js
+require("dotenv").config()
+const API_URL = process.env.API_URL
+const PUBLIC_KEY = process.env.PUBLIC_KEY
+const PRIVATE_KEY = process.env.PRIVATE_KEY
+
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(API_URL)
+
+const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
+const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
+const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
+
+async function mintNFT(tokenURI) {
+ const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //получаем последний nonce
+
+ //транзакция
+ const tx = {
+ from: PUBLIC_KEY,
+ to: contractAddress,
+ nonce: nonce,
+ gas: 500000,
+ data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
+ }
+
+ const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
+ signPromise
+ .then((signedTx) => {
+ web3.eth.sendSignedTransaction(
+ signedTx.rawTransaction,
+ function (err, hash) {
+ if (!err) {
+ console.log(
+ "Хэш вашей транзакции: ",
+ hash,
+ "\nПроверьте Mempool в Alchemy, чтобы просмотреть статус вашей транзакции!"
+ )
+ } else {
+ console.log(
+ "Что-то пошло не так при отправке вашей транзакции:",
+ err
+ )
+ }
+ }
+ )
+ })
+ .catch((err) => {
+ console.log(" Ошибка Promise:", err)
+ })
+}
+```
+
+## Шаг 9. Вызовите `mintNFT` и запустите `node mint-nft.js` {#call-mintnft-fn}
+
+Помните файл `metadata.json`, который вы загрузили в Pinata? Получите его хэш-код из Pinata и передайте в качестве параметра функции `mintNFT` следующее: `https://gateway.pinata.cloud/ipfs/`
+
+Вот как получить хэш-код:
+
+_Как получить хэш-код метаданных вашего NFT на Pinata_
+
+> Дважды проверьте, что скопированный вами хэш-код ссылается на ваш **metadata.json**, загрузив `https://gateway.pinata.cloud/ipfs/` в отдельном окне. Страница должна выглядеть примерно так же, как на скриншоте ниже:
+
+_На вашей странице должны отображаться метаданные JSON_
+
+В итоге ваш код должен выглядеть примерно так:
+
+```js
+require("dotenv").config()
+const API_URL = process.env.API_URL
+const PUBLIC_KEY = process.env.PUBLIC_KEY
+const PRIVATE_KEY = process.env.PRIVATE_KEY
+
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(API_URL)
+
+const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
+const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"
+const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
+
+async function mintNFT(tokenURI) {
+ const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //получаем последний nonce
+
+ //транзакция
+ const tx = {
+ from: PUBLIC_KEY,
+ to: contractAddress,
+ nonce: nonce,
+ gas: 500000,
+ data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
+ }
+
+ const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
+ signPromise
+ .then((signedTx) => {
+ web3.eth.sendSignedTransaction(
+ signedTx.rawTransaction,
+ function (err, hash) {
+ if (!err) {
+ console.log(
+ "Хэш вашей транзакции: ",
+ hash,
+ "\nПроверьте Mempool в Alchemy, чтобы просмотреть статус вашей транзакции!"
+ )
+ } else {
+ console.log(
+ "Что-то пошло не так при отправке вашей транзакции:",
+ err
+ )
+ }
+ }
+ )
+ })
+ .catch((err) => {
+ console.log("Ошибка Promise:", err)
+ })
+}
+
+mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP")
+```
+
+Теперь выполните `node scripts/mint-nft.js`, чтобы создать свой NFT. Через пару секунд вы должны увидеть в своем терминале примерно такой ответ:
+
+ ```
+ Хэш вашей транзакции: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8
+
+ Проверьте Mempool в Alchemy, чтобы просмотреть статус вашей транзакции!
+ ```
+
+Затем посетите [mempool в Alchemy](https://dashboard.alchemyapi.io/mempool), чтобы увидеть статус вашей транзакции (ожидает ли она, обработана или отклонена сетью). Если ваша транзакция была отклонена, также полезно проверить [Blockscout](https://eth-sepolia.blockscout.com/) и найти хэш вашей транзакции.
+
+_Просмотр хэша транзакции вашего NFT на Etherscan_
+
+Вот и все! Вы развернули и создали NFT в блокчейне Ethereum
+
+С помощью `mint-nft.js` вы можете создать столько NFT, сколько душе (и кошельку) угодно! Только не забудьте передать новый tokenURI, описывающий метаданные NFT (иначе вы просто создадите кучу одинаковых NFT с разными идентификаторами).
+
+Предположительно, вы хотели бы иметь возможность похвастаться своим NFT в своем кошельке — так что обязательно ознакомьтесь с [Частью 3: Как просмотреть свой NFT в кошельке](/developers/tutorials/how-to-view-nft-in-metamask/)!
diff --git a/public/content/translations/ru/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/ru/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md
new file mode 100644
index 00000000000..ad4f2449deb
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md
@@ -0,0 +1,108 @@
+---
+title: "Как имитировать умные контракты Solidity для тестирования"
+description: "Почему Вы должны получить удовольствие при тестировании Ваших контрактов"
+author: Markus Waas
+lang: ru
+tags:
+ [
+ "Solidity",
+ "Умные контракты",
+ "тестирование",
+ "имитация"
+ ]
+skill: intermediate
+published: 2020-05-02
+source: soliditydeveloper.com
+sourceUrl: https://soliditydeveloper.com/mocking-contracts
+---
+
+[Мок-объекты](https://wikipedia.org/wiki/Mock_object) — это распространенный шаблон проектирования в объектно-ориентированном программировании. Произойдя от старого Французского слова 'mocquer' со значением 'высмеивать', оно эволюционировало до 'имитировать что-то реальное', что актуально, когда мы собираемся программировать. Пожалуйста, чтобы получать удовольствие от Ваших смарт-контрактов, если Вы хотите, то имитируете их всякий раз, когда можете. Это делает Вашу жизнь легче.
+
+## Юнит-тестирование контрактов с помощью мок-объектов {#unit-testing-contracts-with-mocks}
+
+По существу, мокинг контракта означает создание второй версии контракта, которая ведет себя очень похоже на оригинал, но такой, чтобы разработчик мог легче ее контролировать. Часто приходится иметь дело со сложными контрактами, в которых вы хотите [провести юнит-тестирование только небольших частей контракта](/developers/docs/smart-contracts/testing/). Проблема в том, что если для тестирования этой небольшой части требуется очень специфическое состояние контракта, которого трудно достичь?
+
+Можно каждый раз писать сложную логику настройки теста, которая приводит контракт в требуемое состояние, или же написать мок-объект. Имитировать контракт легко с помощью наследования. Просто создайте второй мок-контракт, который наследует от исходного. Теперь вы можете переопределить функции в своем мок-объекте. Давайте посмотрим это на примере.
+
+## Пример: закрытый ERC20 {#example-private-erc20}
+
+Мы используем пример контракта ERC-20, у которого есть начальный закрытый период. Владелец может управлять закрытыми пользователями, и только им будет разрешено получать токены вначале. По истечении определенного времени все смогут использовать токены. Если вам интересно, мы используем хук [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) из новых контрактов OpenZeppelin v3.
+
+```solidity
+pragma solidity ^0.6.0;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+
+contract PrivateERC20 is ERC20, Ownable {
+ mapping (address => bool) public isPrivateUser;
+ uint256 private publicAfterTime;
+
+ constructor(uint256 privateERC20timeInSec) ERC20("PrivateERC20", "PRIV") public {
+ publicAfterTime = now + privateERC20timeInSec;
+ }
+
+ function addUser(address user) external onlyOwner {
+ isPrivateUser[user] = true;
+ }
+
+ function isPublic() public view returns (bool) {
+ return now >= publicAfterTime;
+ }
+
+ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
+ super._beforeTokenTransfer(from, to, amount);
+
+ require(_validRecipient(to), "PrivateERC20: invalid recipient");
+ }
+
+ function _validRecipient(address to) private view returns (bool) {
+ if (isPublic()) {
+ return true;
+ }
+
+ return isPrivateUser[to];
+ }
+}
+```
+
+А теперь давайте мокнем его.
+
+```solidity
+pragma solidity ^0.6.0;
+import "../PrivateERC20.sol";
+
+contract PrivateERC20Mock is PrivateERC20 {
+ bool isPublicConfig;
+
+ constructor() public PrivateERC20(0) {}
+
+ function setIsPublic(bool isPublic) external {
+ isPublicConfig = isPublic;
+ }
+
+ function isPublic() public view returns (bool) {
+ return isPublicConfig;
+ }
+}
+```
+
+Вы получите одно из следующих сообщений об ошибке:
+
+- `PrivateERC20Mock.sol: Ошибка типа: У переопределяющей функции отсутствует спецификатор "override".`
+- `PrivateERC20.sol: Ошибка типа: Попытка переопределить невиртуальную функцию.` `Вы забыли добавить "virtual"?`
+
+Поскольку мы используем новую версию Solidity 0.6, мы должны добавить ключевое слово `virtual` для функций, которые можно переопределить, и `override` для переопределяющей функции. Давайте добавим их в обе функции `isPublic`.
+
+Теперь в своих юнит-тестах вы можете использовать вместо этого `PrivateERC20Mock`. Когда вы хотите протестировать поведение во время закрытого периода использования, используйте `setIsPublic(false)` и аналогично `setIsPublic(true)` для тестирования открытого периода использования. Конечно, в нашем примере мы могли бы просто использовать [вспомогательные функции времени](https://docs.openzeppelin.com/test-helpers/0.5/api#increase), чтобы соответствующим образом изменить время. Но идея имитации теперь должна быть ясна, и вы можете представить сценарии, в которых это не так просто, как простое продвижение времени.
+
+## Имитация многих контрактов {#mocking-many-contracts}
+
+Может возникнуть беспорядок, если вам придется создавать еще один контракт для каждого отдельного мок-объекта. Если вас это беспокоит, вы можете взглянуть на библиотеку [MockContract](https://github.com/gnosis/mock-contract). Она позволяет переопределять и изменять поведение контрактов «на лету». Однако она работает только для имитации вызовов другого контракта, поэтому для нашего примера она не подойдет.
+
+## Имитация может быть еще более мощной {#mocking-can-be-even-more-powerful}
+
+Возможности имитации на этом не заканчиваются.
+
+- Добавление функций: полезно не только переопределять определенную функцию, но и просто добавлять дополнительные функции. Хорошим примером для токенов является наличие дополнительной функции `mint`, позволяющей любому пользователю бесплатно получать новые токены.
+- Использование в тестовых сетях: когда вы развертываете и тестируете свои контракты в тестовых сетях вместе со своим децентрализованным приложением, рассмотрите возможность использования мок-версии. Избегайте переопределения функций, если в этом нет крайней необходимости. В конце концов, вы хотите протестировать реальную логику. Но может быть полезно добавить, например, функцию сброса, которая просто сбрасывает состояние контракта к начальному, не требуя нового развертывания. Очевидно, что вы бы не хотели иметь это в контракте в основной сети.
diff --git a/public/content/translations/ru/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/ru/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md
new file mode 100644
index 00000000000..97920e8487c
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md
@@ -0,0 +1,709 @@
+---
+title: "Как использовать Echidna для тестирования смарт-контрактов"
+description: "Как использовать Echidna для автоматического тестирования смарт-контрактов"
+author: "Trailofbits"
+lang: ru
+tags:
+ [
+ "Solidity",
+ "Умные контракты",
+ "безопасность",
+ "тестирование",
+ "фаззинг"
+ ]
+skill: advanced
+published: 2020-04-10
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna
+---
+
+## Установка {#installation}
+
+Echidna можно установить через docker или с помощью предварительно скомпилированного двоичного файла.
+
+### Echidna через docker {#echidna-through-docker}
+
+```bash
+docker pull trailofbits/eth-security-toolbox
+docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox
+```
+
+_Последняя команда запускает eth-security-toolbox в контейнере Docker, который имеет доступ к вашему текущему каталогу._ Вы можете изменять файлы со своего хоста и запускать инструменты для работы с этими файлами из контейнера Docker_
+
+Внутри docker выполните:
+
+```bash
+solc-select 0.5.11
+cd /home/training
+```
+
+### Двоичный файл {#binary}
+
+[https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0)
+
+## Введение в фаззинг на основе свойств {#introduction-to-property-based-fuzzing}
+
+Echidna — это фаззер на основе свойств, как мы описывали в наших предыдущих статьях в блоге ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)).
+
+### Фаззинг {#fuzzing}
+
+[Фаззинг](https://wikipedia.org/wiki/Fuzzing) — это хорошо известная техника в сообществе безопасности. Она заключается в генерировании более или менее случайных входных данных для поиска ошибок в программе. Фаззеры для традиционного программного обеспечения (такие как [AFL](http://lcamtuf.coredump.cx/afl/) или [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) известны как эффективные инструменты для поиска ошибок.
+
+Помимо чисто случайной генерации входных данных, существует множество методов и стратегий для создания качественных входных данных, в том числе:
+
+- Получение обратной связи от каждого выполнения и использование ее для направления генерации. Например, если вновь сгенерированные входные данные приводят к обнаружению нового пути, имеет смысл сгенерировать новые входные данные, близкие к ним.
+- Генерация входных данных с соблюдением структурных ограничений. Например, если ваши входные данные содержат заголовок с контрольной суммой, имеет смысл позволить фаззеру генерировать входные данные, проверяющие контрольную сумму.
+- Использование известных входных данных для генерации новых: если у вас есть доступ к большому набору действительных входных данных, ваш фаззер может генерировать новые входные данные из них, а не начинать генерацию с нуля. Обычно их называют _затравками_.
+
+### Фаззинг на основе свойств {#property-based-fuzzing}
+
+Echidna принадлежит к особому семейству фаззеров: фаззинг на основе свойств, в значительной степени вдохновленный [QuickCheck](https://wikipedia.org/wiki/QuickCheck). В отличие от классического фаззера, который пытается найти сбои, Echidna пытается нарушить определенные пользователем инварианты.
+
+В смарт-контрактах инварианты — это функции Solidity, которые могут представлять любое неверное или недопустимое состояние, в которое может перейти контракт, в том числе:
+
+- Неправильный контроль доступа: злоумышленник стал владельцем контракта.
+- Неправильный конечный автомат: токены могут быть переданы, пока контракт приостановлен.
+- Неправильная арифметика: пользователь может вызвать целочисленное опустошение (underflow) своего баланса и получить неограниченное количество бесплатных токенов.
+
+### Тестирование свойства с помощью Echidna {#testing-a-property-with-echidna}
+
+Мы рассмотрим, как тестировать смарт-контракт с помощью Echidna. Целью является следующий смарт-контракт [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol):
+
+```solidity
+contract Token{
+ mapping(address => uint) public balances;
+ function airdrop() public{
+ balances[msg.sender] = 1000;
+ }
+ function consume() public{
+ require(balances[msg.sender]>0);
+ balances[msg.sender] -= 1;
+ }
+ function backdoor() public{
+ balances[msg.sender] += 1;
+ }
+}
+```
+
+Мы сделаем предположение, что этот токен должен обладать следующими свойствами:
+
+- Любой может иметь не более 1000 токенов
+- Токен не может быть передан (это не токен ERC20)
+
+### Написание свойства {#write-a-property}
+
+Свойства Echidna — это функции Solidity. Свойство должно:
+
+- Не иметь аргументов
+- Возвращать `true` в случае успеха
+- Иметь имя, начинающееся с `echidna`
+
+Echidna будет:
+
+- Автоматически генерировать произвольные транзакции для проверки свойства.
+- Сообщать о любых транзакциях, которые заставляют свойство возвращать `false` или вызывать ошибку.
+- Отбрасывать побочные эффекты при вызове свойства (то есть если свойство изменяет переменную состояния, это изменение отменяется после теста)
+
+Следующее свойство проверяет, что у вызывающего не более 1000 токенов:
+
+```solidity
+function echidna_balance_under_1000() public view returns(bool){
+ return balances[msg.sender] <= 1000;
+}
+```
+
+Используйте наследование, чтобы отделить ваш контракт от ваших свойств:
+
+```solidity
+contract TestToken is Token{
+ function echidna_balance_under_1000() public view returns(bool){
+ return balances[msg.sender] <= 1000;
+ }
+ }
+```
+
+[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) реализует свойство и наследуется от токена.
+
+### Инициализация контракта {#initiate-a-contract}
+
+Echidna требуется [конструктор](/developers/docs/smart-contracts/anatomy/#constructor-functions) без аргументов. Если вашему контракту требуется особая инициализация, ее необходимо выполнить в конструкторе.
+
+В Echidna есть несколько особых адресов:
+
+- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72`, который вызывает конструктор.
+- `0x10000`, `0x20000` и `0x00a329C0648769a73afAC7F9381e08fb43DBEA70`, которые случайным образом вызывают другие функции.
+
+В нашем текущем примере не требуется никакой особой инициализации, поэтому наш конструктор пуст.
+
+### Запуск Echidna {#run-echidna}
+
+Echidna запускается с помощью:
+
+```bash
+echidna-test contract.sol
+```
+
+Если contract.sol содержит несколько контрактов, вы можете указать целевой контракт:
+
+```bash
+echidna-test contract.sol --contract MyContract
+```
+
+### Итог: тестирование свойства {#summary-testing-a-property}
+
+Ниже приведены итоги запуска Echidna на нашем примере:
+
+```solidity
+contract TestToken is Token{
+ constructor() public {}
+ function echidna_balance_under_1000() public view returns(bool){
+ return balances[msg.sender] <= 1000;
+ }
+ }
+```
+
+```bash
+echidna-test testtoken.sol --contract TestToken
+...
+
+echidna_balance_under_1000: failed!💥
+ Call sequence, shrinking (1205/5000):
+ airdrop()
+ backdoor()
+
+...
+```
+
+Echidna обнаружила, что свойство нарушается, если вызывается `backdoor`.
+
+## Фильтрация функций для вызова во время фаззинга {#filtering-functions-to-call-during-a-fuzzing-campaign}
+
+Мы рассмотрим, как фильтровать функции, подлежащие фаззингу.
+Целью является следующий смарт-контракт:
+
+```solidity
+contract C {
+ bool state1 = false;
+ bool state2 = false;
+ bool state3 = false;
+ bool state4 = false;
+
+ function f(uint x) public {
+ require(x == 12);
+ state1 = true;
+ }
+
+ function g(uint x) public {
+ require(state1);
+ require(x == 8);
+ state2 = true;
+ }
+
+ function h(uint x) public {
+ require(state2);
+ require(x == 42);
+ state3 = true;
+ }
+
+ function i() public {
+ require(state3);
+ state4 = true;
+ }
+
+ function reset1() public {
+ state1 = false;
+ state2 = false;
+ state3 = false;
+ return;
+ }
+
+ function reset2() public {
+ state1 = false;
+ state2 = false;
+ state3 = false;
+ return;
+ }
+
+ function echidna_state4() public returns (bool) {
+ return (!state4);
+ }
+}
+```
+
+Этот небольшой пример заставляет Echidna найти определенную последовательность транзакций, чтобы изменить переменную состояния.
+Это сложно для фаззера (рекомендуется использовать инструмент символьного выполнения, такой как [Manticore](https://github.com/trailofbits/manticore)).
+Мы можем запустить Echidna, чтобы проверить это:
+
+```bash
+echidna-test multi.sol
+...
+echidna_state4: passed! 🎉
+Seed: -3684648582249875403
+```
+
+### Фильтрация функций {#filtering-functions}
+
+Echidna испытывает трудности с поиском правильной последовательности для тестирования этого контракта, потому что две функции сброса (`reset1` и `reset2`) установят все переменные состояния в `false`.
+Однако мы можем использовать специальную функцию Echidna, чтобы либо добавить функции сброса в черный список, либо добавить в белый список только функции `f`, `g`,
+`h` и `i`.
+
+Чтобы добавить функции в черный список, мы можем использовать этот файл конфигурации:
+
+```yaml
+filterBlacklist: true
+filterFunctions: ["reset1", "reset2"]
+```
+
+Другой подход к фильтрации функций — перечислить функции из белого списка. Для этого мы можем использовать этот файл конфигурации:
+
+```yaml
+filterBlacklist: false
+filterFunctions: ["f", "g", "h", "i"]
+```
+
+- `filterBlacklist` по умолчанию имеет значение `true`.
+- Фильтрация будет выполняться только по имени (без параметров). Если у вас есть `f()` и `f(uint256)`, фильтр `"f"` будет соответствовать обеим функциям.
+
+### Запуск Echidna {#run-echidna-1}
+
+Чтобы запустить Echidna с файлом конфигурации `blacklist.yaml`:
+
+```bash
+echidna-test multi.sol --config blacklist.yaml
+...
+echidna_state4: failed!💥
+ Call sequence:
+ f(12)
+ g(8)
+ h(42)
+ i()
+```
+
+Echidna почти сразу найдет последовательность транзакций, чтобы опровергнуть это свойство.
+
+### Итог: фильтрация функций {#summary-filtering-functions}
+
+Echidna может либо добавлять функции в черный, либо в белый список для вызова во время фаззинга, используя:
+
+```yaml
+filterBlacklist: true
+filterFunctions: ["f1", "f2", "f3"]
+```
+
+```bash
+echidna-test contract.sol --config config.yaml
+...
+```
+
+Echidna начинает кампанию фаззинга, либо добавляя в черный список `f1`, `f2` и `f3`, либо вызывая только их, в зависимости от значения логической переменной `filterBlacklist`.
+
+## Как тестировать утверждения (assert) Solidity с помощью Echidna {#how-to-test-soliditys-assert-with-echidna}
+
+В этом коротком руководстве мы покажем, как использовать Echidna для тестирования проверки утверждений в контрактах. Предположим, у нас есть такой контракт:
+
+```solidity
+contract Incrementor {
+ uint private counter = 2**200;
+
+ function inc(uint val) public returns (uint){
+ uint tmp = counter;
+ counter += val;
+ // tmp <= counter
+ return (counter - tmp);
+ }
+}
+```
+
+### Написание утверждения {#write-an-assertion}
+
+Мы хотим убедиться, что `tmp` меньше или равно `counter` после возврата их разницы. Мы могли бы написать свойство
+Echidna, но нам нужно было бы где-то хранить значение `tmp`. Вместо этого мы могли бы использовать такое утверждение:
+
+```solidity
+contract Incrementor {
+ uint private counter = 2**200;
+
+ function inc(uint val) public returns (uint){
+ uint tmp = counter;
+ counter += val;
+ assert (tmp <= counter);
+ return (counter - tmp);
+ }
+}
+```
+
+### Запуск Echidna {#run-echidna-2}
+
+Чтобы включить тестирование сбоев утверждений, создайте [файл конфигурации Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`:
+
+```yaml
+checkAsserts: true
+```
+
+Когда мы запускаем этот контракт в Echidna, мы получаем ожидаемые результаты:
+
+```bash
+echidna-test assert.sol --config config.yaml
+Analyzing contract: assert.sol:Incrementor
+assertion in inc: failed!💥
+ Call sequence, shrinking (2596/5000):
+ inc(21711016731996786641919559689128982722488122124807605757398297001483711807488)
+ inc(7237005577332262213973186563042994240829374041602535252466099000494570602496)
+ inc(86844066927987146567678238756515930889952488499230423029593188005934847229952)
+
+Seed: 1806480648350826486
+```
+
+Как вы можете видеть, Echidna сообщает о сбое утверждения в функции `inc`. Можно добавить более одного утверждения на функцию, но Echidna не сможет сказать, какое именно утверждение не удалось.
+
+### Когда и как использовать утверждения {#when-and-how-use-assertions}
+
+Утверждения могут использоваться как альтернатива явным свойствам, особенно если условия для проверки напрямую связаны с правильным использованием некоторой операции `f`. Добавление утверждений после некоторого кода обеспечит, что проверка произойдет сразу после его выполнения:
+
+```solidity
+function f(..) public {
+ // какой-то сложный код
+ ...
+ assert (condition);
+ ...
+}
+
+```
+
+Напротив, использование явного свойства Echidna приведет к случайному выполнению транзакций, и нет простого способа точно определить, когда будет выполнена проверка. Тем не менее, можно использовать такой обходной путь:
+
+```solidity
+function echidna_assert_after_f() public returns (bool) {
+ f(..);
+ return(condition);
+}
+```
+
+Однако есть некоторые проблемы:
+
+- Это не сработает, если `f` объявлена как `internal` или `external`.
+- Непонятно, какие аргументы следует использовать для вызова `f`.
+- Если `f` отменяет транзакцию, свойство не будет выполнено.
+
+В целом мы рекомендуем следовать [рекомендациям Джона Регера](https://blog.regehr.org/archives/1091) о том, как использовать утверждения:
+
+- Не вызывайте никаких побочных эффектов во время проверки утверждения. Например: `assert(ChangeStateAndReturn() == 1)`
+- Не утверждайте очевидные вещи. Например `assert(var >= 0)`, где `var` объявлена как `uint`.
+
+Наконец, пожалуйста, **не используйте** `require` вместо `assert`, так как Echidna не сможет это обнаружить (но контракт все равно отменит транзакцию).
+
+### Итог: проверка утверждений {#summary-assertion-checking}
+
+Ниже приведены итоги запуска Echidna на нашем примере:
+
+```solidity
+contract Incrementor {
+ uint private counter = 2**200;
+
+ function inc(uint val) public returns (uint){
+ uint tmp = counter;
+ counter += val;
+ assert (tmp <= counter);
+ return (counter - tmp);
+ }
+}
+```
+
+```bash
+echidna-test assert.sol --config config.yaml
+Analyzing contract: assert.sol:Incrementor
+assertion in inc: failed!💥
+ Call sequence, shrinking (2596/5000):
+ inc(21711016731996786641919559689128982722488122124807605757398297001483711807488)
+ inc(7237005577332262213973186563042994240829374041602535252466099000494570602496)
+ inc(86844066927987146567678238756515930889952488499230423029593188005934847229952)
+
+Seed: 1806480648350826486
+```
+
+Echidna обнаружила, что утверждение в `inc` может не сработать, если эта функция вызывается несколько раз с большими аргументами.
+
+## Сбор и изменение корпуса Echidna {#collecting-and-modifying-an-echidna-corpus}
+
+Мы рассмотрим, как собирать и использовать корпус транзакций с помощью Echidna. Целью является следующий смарт-контракт [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol):
+
+```solidity
+contract C {
+ bool value_found = false;
+ function magic(uint magic_1, uint magic_2, uint magic_3, uint magic_4) public {
+ require(magic_1 == 42);
+ require(magic_2 == 129);
+ require(magic_3 == magic_4+333);
+ value_found = true;
+ return;
+ }
+
+ function echidna_magic_values() public returns (bool) {
+ return !value_found;
+ }
+
+}
+```
+
+Этот небольшой пример заставляет Echidna найти определенные значения для изменения переменной состояния. Это сложно для фаззера
+(рекомендуется использовать инструмент символьного выполнения, такой как [Manticore](https://github.com/trailofbits/manticore)).
+Мы можем запустить Echidna, чтобы проверить это:
+
+```bash
+echidna-test magic.sol
+...
+
+echidna_magic_values: passed! 🎉
+
+Seed: 2221503356319272685
+```
+
+Однако мы все еще можем использовать Echidna для сбора корпуса при запуске этой кампании фаззинга.
+
+### Сбор корпуса {#collecting-a-corpus}
+
+Чтобы включить сбор корпуса, создайте каталог корпуса:
+
+```bash
+mkdir corpus-magic
+```
+
+И [файл конфигурации Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`:
+
+```yaml
+coverage: true
+corpusDir: "corpus-magic"
+```
+
+Теперь мы можем запустить наш инструмент и проверить собранный корпус:
+
+```bash
+echidna-test magic.sol --config config.yaml
+```
+
+Echidna все еще не может найти правильные магические значения, но мы можем взглянуть на собранный ею корпус.
+Например, одним из этих файлов был:
+
+```json
+[
+ {
+ "_gas'": "0xffffffff",
+ "_delay": ["0x13647", "0xccf6"],
+ "_src": "00a329c0648769a73afac7f9381e08fb43dbea70",
+ "_dst": "00a329c0648769a73afac7f9381e08fb43dbea72",
+ "_value": "0x0",
+ "_call": {
+ "tag": "SolCall",
+ "contents": [
+ "magic",
+ [
+ {
+ "contents": [
+ 256,
+ "93723985220345906694500679277863898678726808528711107336895287282192244575836"
+ ],
+ "tag": "AbiUInt"
+ },
+ {
+ "contents": [256, "334"],
+ "tag": "AbiUInt"
+ },
+ {
+ "contents": [
+ 256,
+ "68093943901352437066264791224433559271778087297543421781073458233697135179558"
+ ],
+ "tag": "AbiUInt"
+ },
+ {
+ "tag": "AbiUInt",
+ "contents": [256, "332"]
+ }
+ ]
+ ]
+ },
+ "_gasprice'": "0xa904461f1"
+ }
+]
+```
+
+Очевидно, что эти входные данные не вызовут сбоя в нашем свойстве. Однако на следующем шаге мы увидим, как изменить его для этого.
+
+### Заполнение корпуса {#seeding-a-corpus}
+
+Echidna нужна помощь, чтобы справиться с функцией `magic`. Мы скопируем и изменим входные данные, чтобы использовать для них подходящие
+параметры:
+
+```bash
+cp corpus/2712688662897926208.txt corpus/new.txt
+```
+
+Мы изменим `new.txt`, чтобы вызывать `magic(42,129,333,0)`. Теперь мы можем снова запустить Echidna:
+
+```bash
+echidna-test magic.sol --config config.yaml
+...
+echidna_magic_values: failed!💥
+ Call sequence:
+ magic(42,129,333,0)
+
+
+Unique instructions: 142
+Unique codehashes: 1
+Seed: -7293830866560616537
+
+```
+
+На этот раз он сразу обнаружил, что свойство нарушено.
+
+## Поиск транзакций с высоким потреблением газа {#finding-transactions-with-high-gas-consumption}
+
+Мы рассмотрим, как найти транзакции с высоким потреблением газа с помощью Echidna. Целью является следующий смарт-контракт:
+
+```solidity
+contract C {
+ uint state;
+
+ function expensive(uint8 times) internal {
+ for(uint8 i=0; i < times; i++)
+ state = state + i;
+ }
+
+ function f(uint x, uint y, uint8 times) public {
+ if (x == 42 && y == 123)
+ expensive(times);
+ else
+ state = 0;
+ }
+
+ function echidna_test() public returns (bool) {
+ return true;
+ }
+
+}
+```
+
+Здесь `expensive` может иметь большое потребление газа.
+
+В настоящее время Echidna всегда требует свойство для тестирования: здесь `echidna_test` всегда возвращает `true`.
+Мы можем запустить Echidna, чтобы проверить это:
+
+```
+echidna-test gas.sol
+...
+echidna_test: passed! 🎉
+
+Seed: 2320549945714142710
+```
+
+### Измерение потребления газа {#measuring-gas-consumption}
+
+Чтобы включить измерение потребления газа с помощью Echidna, создайте файл конфигурации `config.yaml`:
+
+```yaml
+estimateGas: true
+```
+
+В этом примере мы также уменьшим размер последовательности транзакций, чтобы результаты было легче понять:
+
+```yaml
+seqLen: 2
+estimateGas: true
+```
+
+### Запуск Echidna {#run-echidna-3}
+
+После создания файла конфигурации мы можем запустить Echidna следующим образом:
+
+```bash
+echidna-test gas.sol --config config.yaml
+...
+echidna_test: passed! 🎉
+
+f использовала максимум 1333608 газа
+ Call sequence:
+ f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2
+
+Unique instructions: 157
+Unique codehashes: 1
+Seed: -325611019680165325
+
+```
+
+- Показанный газ является оценкой, предоставленной [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-).
+
+### Отфильтровывание вызовов, снижающих потребление газа {#filtering-out-gas-reducing-calls}
+
+Приведенное выше руководство по **фильтрации функций для вызова во время фаззинга** показывает, как
+удалить некоторые функции из вашего тестирования.
+Это может быть критически важно для получения точной оценки газа.
+Рассмотрим следующий пример:
+
+```solidity
+contract C {
+ address [] addrs;
+ function push(address a) public {
+ addrs.push(a);
+ }
+ function pop() public {
+ addrs.pop();
+ }
+ function clear() public{
+ addrs.length = 0;
+ }
+ function check() public{
+ for(uint256 i = 0; i < addrs.length; i++)
+ for(uint256 j = i+1; j < addrs.length; j++)
+ if (addrs[i] == addrs[j])
+ addrs[j] = address(0x0);
+ }
+ function echidna_test() public returns (bool) {
+ return true;
+ }
+}
+```
+
+Если Echidna может вызывать все функции, она не сможет легко найти транзакции с высокой стоимостью газа:
+
+```
+echidna-test pushpop.sol --config config.yaml
+...
+pop использовала максимум 10746 газа
+...
+check использовала максимум 23730 газа
+...
+clear использовала максимум 35916 газа
+...
+push использовала максимум 40839 газа
+```
+
+Это потому, что стоимость зависит от размера `addrs`, а случайные вызовы, как правило, оставляют массив почти пустым.
+Однако добавление `pop` и `clear` в черный список дает нам гораздо лучшие результаты:
+
+```yaml
+filterBlacklist: true
+filterFunctions: ["pop", "clear"]
+```
+
+```
+echidna-test pushpop.sol --config config.yaml
+...
+push использовала максимум 40839 газа
+...
+check использовала максимум 1484472 газа
+```
+
+### Итог: поиск транзакций с высоким потреблением газа {#summary-finding-transactions-with-high-gas-consumption}
+
+Echidna может находить транзакции с высоким потреблением газа, используя опцию конфигурации `estimateGas`:
+
+```yaml
+estimateGas: true
+```
+
+```bash
+echidna-test contract.sol --config config.yaml
+...
+```
+
+Echidna сообщит о последовательности с максимальным потреблением газа для каждой функции после завершения кампании фаззинга.
diff --git a/public/content/translations/ru/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/ru/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md
new file mode 100644
index 00000000000..0d8b38d3d01
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md
@@ -0,0 +1,524 @@
+---
+title: "Как использовать Manticore для поиска ошибок в смарт-контрактах"
+description: "Как использовать Manticore для автоматического поиска ошибок в смарт-контрактах"
+author: Trailofbits
+lang: ru
+tags:
+ [
+ "Solidity",
+ "Умные контракты",
+ "безопасность",
+ "тестирование",
+ "формальная верификация"
+ ]
+skill: advanced
+published: 2020-01-13
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore
+---
+
+Цель этого руководства — показать, как использовать Manticore для автоматического поиска ошибок в смарт-контрактах.
+
+## Установка {#installation}
+
+Для Manticore требуется Python версии 3.6 или выше. Его можно установить через pip или с помощью Docker.
+
+### Manticore через Docker {#manticore-through-docker}
+
+```bash
+docker pull trailofbits/eth-security-toolbox
+docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox
+```
+
+_Последняя команда запускает eth-security-toolbox в контейнере Docker, который имеет доступ к вашему текущему каталогу._ Вы можете изменять файлы со своего хоста и запускать инструменты для работы с этими файлами из контейнера Docker_
+
+Внутри контейнера Docker выполните:
+
+```bash
+solc-select 0.5.11
+cd /home/trufflecon/
+```
+
+### Manticore через pip {#manticore-through-pip}
+
+```bash
+pip3 install --user manticore
+```
+
+Рекомендуется использовать solc 0.5.11.
+
+### Запуск скрипта {#running-a-script}
+
+Чтобы запустить скрипт Python с помощью Python 3:
+
+```bash
+python3 script.py
+```
+
+## Введение в динамическое символическое выполнение {#introduction-to-dynamic-symbolic-execution}
+
+### Динамическое символическое выполнение в двух словах {#dynamic-symbolic-execution-in-a-nutshell}
+
+Динамическое символическое выполнение (DSE) — это метод анализа программ, который исследует пространство состояний с высокой степенью семантической осведомленности. Этот метод основан на обнаружении «путей программы», представленных в виде математических формул, называемых `предикатами путей`. Концептуально этот метод работает с предикатами путей в два этапа:
+
+1. Они создаются с помощью ограничений на входные данные программы.
+2. Они используются для генерации входных данных программы, которые вызовут выполнение соответствующих путей.
+
+Этот подход не дает ложноположительных результатов в том смысле, что все выявленные состояния программы могут быть вызваны во время конкретного выполнения. Например, если анализ находит целочисленное переполнение, оно гарантированно будет воспроизводимым.
+
+### Пример предиката пути {#path-predicate-example}
+
+Чтобы понять, как работает DSE, рассмотрим следующий пример:
+
+```solidity
+function f(uint a){
+
+ if (a == 65) {
+ // Присутствует ошибка
+ }
+
+}
+```
+
+Поскольку `f()` содержит два пути, DSE создаст два разных предиката пути:
+
+- Путь 1: `a == 65`
+- Путь 2: `Not (a == 65)`
+
+Каждый предикат пути является математической формулой, которую можно передать в так называемый [решатель SMT](https://wikipedia.org/wiki/Satisfiability_modulo_theories), который попытается решить уравнение. Для `Пути 1` решатель скажет, что путь можно исследовать при `a = 65`. Для `Пути 2` решатель может присвоить `a` любое значение, кроме 65, например, `a = 0`.
+
+### Проверка свойств {#verifying-properties}
+
+Manticore предоставляет полный контроль над выполнением каждого пути. В результате это позволяет добавлять произвольные ограничения практически ко всему. Этот контроль позволяет создавать свойства для контракта.
+
+Рассмотрим следующий пример:
+
+```solidity
+function unsafe_add(uint a, uint b) returns(uint c){
+ c = a + b; // нет защиты от переполнения
+ return c;
+}
+```
+
+Здесь в функции есть только один путь для исследования:
+
+- Путь 1: `c = a + b`
+
+Используя Manticore, вы можете проверить наличие переполнения и добавить ограничения к предикату пути:
+
+- `c = a + b AND (c < a OR c < b)`
+
+Если возможно найти такие значения `a` и `b`, для которых приведенный выше предикат пути выполним, это означает, что вы обнаружили переполнение. Например, решатель может сгенерировать входные данные `a = 10, b = MAXUINT256`.
+
+Если рассмотреть исправленную версию:
+
+```solidity
+function safe_add(uint a, uint b) returns(uint c){
+ c = a + b;
+ require(c>=a);
+ require(c>=b);
+ return c;
+}
+```
+
+Связанная формула с проверкой на переполнение будет выглядеть так:
+
+- `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)`
+
+Эту формулу невозможно решить; другими словами, это **доказательство** того, что в `safe_add` значение `c` всегда будет увеличиваться.
+
+Таким образом, DSE является мощным инструментом, который может проверять произвольные ограничения в вашем коде.
+
+## Запуск в Manticore {#running-under-manticore}
+
+Мы рассмотрим, как исследовать смарт-контракт с помощью Manticore API. Целью является следующий смарт-контракт [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol):
+
+```solidity
+pragma solidity >=0.4.24 <0.6.0;
+
+contract Simple {
+ function f(uint a) payable public{
+ if (a == 65) {
+ revert();
+ }
+ }
+}
+```
+
+### Запуск автономного исследования {#run-a-standalone-exploration}
+
+Вы можете запустить Manticore непосредственно на смарт-контракте с помощью следующей команды (`project` может быть файлом Solidity или каталогом проекта):
+
+```bash
+$ manticore project
+```
+
+Вы получите вывод тестовых случаев, подобный этому (порядок может измениться):
+
+```
+...
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 0 - STOP
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 1 - REVERT
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 2 - RETURN
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 3 - REVERT
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 4 - STOP
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 5 - REVERT
+... m.c.manticore:INFO: Сгенерирован тестовый пример № 6 - REVERT
+... m.c.manticore:INFO: Результаты в /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3
+...
+```
+
+Без дополнительной информации Manticore будет исследовать контракт с новыми символическими транзакциями до тех пор, пока не перестанет находить новые пути в контракте. Manticore не запускает новые транзакции после неудачной (например, после revert).
+
+Manticore выведет информацию в каталог `mcore_*`. Помимо прочего, в этом каталоге вы найдете:
+
+- `global.summary`: покрытие и предупреждения компилятора
+- `test_XXXXX.summary`: покрытие, последняя инструкция, балансы аккаунтов для каждого тестового примера
+- `test_XXXXX.tx`: подробный список транзакций для каждого тестового примера
+
+Здесь Manticore нашел 7 тестовых примеров, которые соответствуют следующему (порядок файлов может меняться):
+
+| | Транзакция 0 | Транзакция 1 | Транзакция 2 | Результат |
+| :-------------------------------------------------------: | :----------------: | :------------------------: | -------------------------- | :---------------------: |
+| **test_00000000.tx** | Создание контракта | f(!=65) | f(!=65) | Приостановка выполнения |
+| **test_00000001.tx** | Создание контракта | Резервная функция | | REVERT |
+| **test_00000002.tx** | Создание контракта | | | RETURN |
+| **test_00000003.tx** | Создание контракта | f(65) | | REVERT |
+| **test_00000004.tx** | Создание контракта | f(!=65) | | Приостановка выполнения |
+| **test_00000005.tx** | Создание контракта | f(!=65) | f(65) | REVERT |
+| **test_00000006.tx** | Создание контракта | f(!=65) | Резервная функция | REVERT |
+
+_Сводка исследования: f(!=65) означает, что f вызывается с любым значением, отличным от 65._
+
+Как вы можете заметить, Manticore создает уникальный тестовый пример для каждой успешной или отмененной транзакции.
+
+Используйте флаг `--quick-mode` для быстрого исследования кода (он отключает детекторы ошибок, расчет газа и т. д.).
+
+### Манипулирование смарт-контрактом через API {#manipulate-a-smart-contract-through-the-api}
+
+В этом разделе подробно описывается, как управлять смарт-контрактом через Manticore Python API. Вы можете создать новый файл с расширением `*.py` и написать необходимый код, добавив в этот файл команды API (основы которых будут описаны ниже), а затем запустить его с помощью команды `$ python3 *.py`. Также вы можете выполнять приведенные ниже команды непосредственно в консоли python, для запуска консоли используйте команду `$ python3`.
+
+### Создание аккаунтов {#creating-accounts}
+
+Первое, что вам нужно сделать, — это инициировать новый блокчейн с помощью следующих команд:
+
+```python
+from manticore.ethereum import ManticoreEVM
+
+m = ManticoreEVM()
+```
+
+Пользовательский аккаунт создается с помощью [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account):
+
+```python
+user_account = m.create_account(balance=1000)
+```
+
+Контракт Solidity можно развернуть с помощью [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract):
+
+```solidity
+source_code = '''
+pragma solidity >=0.4.24 <0.6.0;
+contract Simple {
+ function f(uint a) payable public{
+ if (a == 65) {
+ revert();
+ }
+ }
+}
+'''
+# Инициировать контракт
+contract_account = m.solidity_create_contract(source_code, owner=user_account)
+```
+
+#### Сводка {#summary}
+
+- Вы можете создавать аккаунты пользователей и контрактов с помощью [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) и [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract).
+
+### Выполнение транзакций {#executing-transactions}
+
+Manticore поддерживает два типа транзакций:
+
+- Необработанная транзакция: исследуются все функции
+- Именованная транзакция: исследуется только одна функция
+
+#### Необработанная транзакция {#raw-transaction}
+
+Необработанная транзакция выполняется с помощью [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction):
+
+```python
+m.transaction(caller=user_account,
+ address=contract_account,
+ data=data,
+ value=value)
+```
+
+Вызывающий, адрес, данные или значение транзакции могут быть конкретными или символическими:
+
+- [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) создает символическое значение.
+- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) создает символический массив байтов.
+
+Например:
+
+```python
+symbolic_value = m.make_symbolic_value()
+symbolic_data = m.make_symbolic_buffer(320)
+m.transaction(caller=user_account,
+ address=contract_address,
+ data=symbolic_data,
+ value=symbolic_value)
+```
+
+Если данные являются символическими, Manticore будет исследовать все функции контракта во время выполнения транзакции. Будет полезно ознакомиться с объяснением резервной функции в статье [Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/), чтобы понять, как работает выбор функции.
+
+#### Именованная транзакция {#named-transaction}
+
+Функции могут выполняться по их имени.
+Чтобы выполнить `f(uint var)` с символическим значением с аккаунта user_account и с 0 эфира, используйте:
+
+```python
+symbolic_var = m.make_symbolic_value()
+contract_account.f(symbolic_var, caller=user_account, value=0)
+```
+
+Если `value` транзакции не указано, по умолчанию оно равно 0.
+
+#### Итог {#summary-1}
+
+- Аргументы транзакции могут быть конкретными или символическими
+- Необработанная транзакция будет исследовать все функции
+- Функция может быть вызвана по имени
+
+### Рабочее пространство {#workspace}
+
+`m.workspace` — это каталог, используемый в качестве выходного каталога для всех сгенерированных файлов:
+
+```python
+print("Результаты находятся в {}".format(m.workspace))
+```
+
+### Завершение исследования {#terminate-the-exploration}
+
+Чтобы остановить исследование, используйте [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize). После вызова этого метода не следует отправлять никаких других транзакций, и Manticore сгенерирует тестовые примеры для каждого исследованного пути.
+
+### Итог: запуск в Manticore {#summary-running-under-manticore}
+
+Объединив все предыдущие шаги, мы получим:
+
+```python
+from manticore.ethereum import ManticoreEVM
+
+m = ManticoreEVM()
+
+with open('example.sol') as f:
+ source_code = f.read()
+
+user_account = m.create_account(balance=1000)
+contract_account = m.solidity_create_contract(source_code, owner=user_account)
+
+symbolic_var = m.make_symbolic_value()
+contract_account.f(symbolic_var)
+
+print("Результаты в {}".format(m.workspace))
+m.finalize() # остановить исследование
+```
+
+Весь приведенный выше код вы можете найти в файле [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)
+
+## Получение путей, вызывающих исключения {#getting-throwing-paths}
+
+Теперь мы сгенерируем конкретные входные данные для путей, вызывающих исключение в `f()`. Целью является следующий смарт-контракт [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol):
+
+```solidity
+pragma solidity >=0.4.24 <0.6.0;
+contract Simple {
+ function f(uint a) payable public{
+ if (a == 65) {
+ revert();
+ }
+ }
+}
+```
+
+### Использование информации о состоянии {#using-state-information}
+
+Каждый выполненный путь имеет свое состояние блокчейна. Состояние может быть либо готовым (ready), либо завершенным (killed), что означает, что оно достигло инструкции THROW или REVERT:
+
+- `[m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing)`: список готовых состояний (они не выполнили REVERT/INVALID)
+- `[m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings)`: список завершенных состояний
+- `[m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings)`: все состояния
+
+```python
+for state in m.all_states:
+ # сделать что-то с состоянием
+```
+
+Вы можете получить доступ к информации о состоянии. Например:
+
+- `state.platform.get_balance(account.address)`: баланс аккаунта
+- `state.platform.transactions`: список транзакций
+- `state.platform.transactions[-1].return_data`: данные, возвращенные последней транзакцией
+
+Данные, возвращенные последней транзакцией, представляют собой массив, который можно преобразовать в значение с помощью ABI.deserialize, например:
+
+```python
+data = state.platform.transactions[0].return_data
+data = ABI.deserialize("uint", data)
+```
+
+### Как сгенерировать тестовый пример {#how-to-generate-testcase}
+
+Используйте [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) для генерации тестового примера:
+
+```python
+m.generate_testcase(state, 'BugFound')
+```
+
+### Итог {#summary-2}
+
+- Вы можете перебирать состояния с помощью m.all_states
+- `state.platform.get_balance(account.address)` возвращает баланс аккаунта
+- `state.platform.transactions` возвращает список транзакций
+- `transaction.return_data` — это возвращаемые данные
+- `m.generate_testcase(state, name)` генерирует входные данные для состояния
+
+### Итог: получение пути, вызывающего исключение {#summary-getting-throwing-path}
+
+```python
+from manticore.ethereum import ManticoreEVM
+
+m = ManticoreEVM()
+
+with open('example.sol') as f:
+ source_code = f.read()
+
+user_account = m.create_account(balance=1000)
+contract_account = m.solidity_create_contract(source_code, owner=user_account)
+
+symbolic_var = m.make_symbolic_value()
+contract_account.f(symbolic_var)
+
+## Проверить, завершается ли выполнение с REVERT или INVALID
+
+for state in m.terminated_states:
+ last_tx = state.platform.transactions[-1]
+ if last_tx.result in ['REVERT', 'INVALID']:
+ print('Найдено исключение {}'.format(m.workspace))
+ m.generate_testcase(state, 'ThrowFound')
+```
+
+Весь приведенный выше код вы можете найти в файле [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)
+
+_Обратите внимание, что мы могли бы создать гораздо более простой скрипт, поскольку все состояния, возвращаемые terminated_state, имеют в своем результате REVERT или INVALID: этот пример был предназначен только для демонстрации того, как управлять API._
+
+## Добавление ограничений {#adding-constraints}
+
+Мы рассмотрим, как ограничивать исследование. Мы сделаем допущение, что в документации `f()` указано, что функция никогда не вызывается с `a == 65`, поэтому любая ошибка при `a == 65` не является настоящей ошибкой. Целью является следующий смарт-контракт [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol):
+
+```solidity
+pragma solidity >=0.4.24 <0.6.0;
+contract Simple {
+ function f(uint a) payable public{
+ if (a == 65) {
+ revert();
+ }
+ }
+}
+```
+
+### Операторы {#operators}
+
+Модуль [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) облегчает работу с ограничениями, среди прочего он предоставляет:
+
+- Operators.AND,
+- Operators.OR,
+- Operators.UGT (больше беззнакового),
+- Operators.UGE (больше или равно беззнакового),
+- Operators.ULT (меньше беззнакового),
+- Operators.ULE (меньше или равно беззнакового).
+
+Для импорта модуля используйте следующее:
+
+```python
+from manticore.core.smtlib import Operators
+```
+
+`Operators.CONCAT` используется для конкатенации массива со значением. Например, return_data транзакции необходимо преобразовать в значение для сравнения с другим значением:
+
+```python
+last_return = Operators.CONCAT(256, *last_return)
+```
+
+### Ограничения {#state-constraint}
+
+Вы можете использовать ограничения глобально или для определенного состояния.
+
+#### Глобальное ограничение {#state-constraint}
+
+Используйте `m.constrain(constraint)` для добавления глобального ограничения.
+Например, вы можете вызвать контракт с символического адреса и ограничить этот адрес определенными значениями:
+
+```python
+symbolic_address = m.make_symbolic_value()
+m.constraint(Operators.OR(symbolic == 0x41, symbolic_address == 0x42))
+m.transaction(caller=user_account,
+ address=contract_account,
+ data=m.make_symbolic_buffer(320),
+ value=0)
+```
+
+#### Ограничение состояния {#state-constraint}
+
+Используйте [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) для добавления ограничения к определенному состоянию.
+Его можно использовать для ограничения состояния после его исследования, чтобы проверить какое-либо свойство на нем.
+
+### Проверка ограничения {#checking-constraint}
+
+Используйте `solver.check(state.constraints)`, чтобы узнать, является ли ограничение все еще выполнимым.
+Например, следующий код наложит ограничение на symbolic_value, чтобы оно было отличным от 65, и проверит, остается ли состояние выполнимым:
+
+```python
+state.constrain(symbolic_var != 65)
+if solver.check(state.constraints):
+ # состояние выполнимо
+```
+
+### Итог: добавление ограничений {#summary-adding-constraints}
+
+Добавляя ограничение к предыдущему коду, мы получим:
+
+```python
+from manticore.ethereum import ManticoreEVM
+from manticore.core.smtlib.solver import Z3Solver
+
+solver = Z3Solver.instance()
+
+m = ManticoreEVM()
+
+with open("example.sol") as f:
+ source_code = f.read()
+
+user_account = m.create_account(balance=1000)
+contract_account = m.solidity_create_contract(source_code, owner=user_account)
+
+symbolic_var = m.make_symbolic_value()
+contract_account.f(symbolic_var)
+
+no_bug_found = True
+
+## Проверить, завершается ли выполнение с REVERT или INVALID
+
+for state in m.terminated_states:
+ last_tx = state.platform.transactions[-1]
+ if last_tx.result in ['REVERT', 'INVALID']:
+ # мы не рассматриваем путь, где a == 65
+ condition = symbolic_var != 65
+ if m.generate_testcase(state, name="BugFound", only_if=condition):
+ print(f'Найдена ошибка, результаты в {m.workspace}')
+ no_bug_found = False
+
+if no_bug_found:
+ print(f'Ошибок не найдено')
+```
+
+Весь приведенный выше код вы можете найти в файле [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py)
diff --git a/public/content/translations/ru/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/ru/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md
new file mode 100644
index 00000000000..9b07ffdca17
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md
@@ -0,0 +1,239 @@
+---
+title: "Как использовать Slither для поиска ошибок в умных контрактах"
+description: "Как использовать Slither для автоматического поиска ошибок в умных контрактах"
+author: Trailofbits
+lang: ru
+tags:
+ [
+ "Solidity",
+ "Умные контракты",
+ "безопасность",
+ "тестирование"
+ ]
+skill: advanced
+published: 2020-06-09
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither
+---
+
+## Как использовать Slither {#how-to-use-slither}
+
+Цель этого руководства — показать, как использовать Slither для автоматического поиска ошибок в умных контрактах.
+
+- [Установка](#installation)
+- [Использование командной строки](#command-line)
+- [Введение в статический анализ](#static-analysis): краткое введение в статический анализ
+- [API](#api-basics): описание API Python
+
+## Установка {#installation}
+
+Slither требует Python >= 3.6. Его можно установить через pip или с помощью Docker.
+
+Slither через pip:
+
+```bash
+pip3 install --user slither-analyzer
+```
+
+Slither через docker:
+
+```bash
+docker pull trailofbits/eth-security-toolbox
+docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox
+```
+
+_Последняя команда запускает eth-security-toolbox в контейнере Docker, который имеет доступ к вашему текущему каталогу._ Вы можете изменять файлы со своего хоста и запускать инструменты для работы с этими файлами из контейнера Docker_
+
+Внутри контейнера Docker выполните:
+
+```bash
+solc-select 0.5.11
+cd /home/trufflecon/
+```
+
+### Запуск скрипта {#running-a-script}
+
+Чтобы запустить скрипт Python с помощью Python 3:
+
+```bash
+python3 script.py
+```
+
+### Командная строка {#command-line}
+
+**Командная строка в сравнении с пользовательскими скриптами.** Slither поставляется с набором предопределенных детекторов, которые находят много распространенных ошибок. Вызов Slither из командной строки запустит все детекторы, при этом не требуются глубокие знания статического анализа:
+
+```bash
+slither project_paths
+```
+
+В дополнение к детекторам Slither имеет возможности анализа кода с помощью своих [принтеров](https://github.com/crytic/slither#printers) и [инструментов](https://github.com/crytic/slither#tools).
+
+Используйте [crytic.io](https://github.com/crytic), чтобы получить доступ к приватным детекторам и интеграции с GitHub.
+
+## Статический анализ {#static-analysis}
+
+Возможности и дизайн фреймворка статического анализа Slither были описаны в постах в блоге ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) и [научной статье](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf).
+
+Статический анализ существует в разных вариантах. Вы, скорее всего, понимаете, что компиляторы, такие как [clang](https://clang-analyzer.llvm.org/) и [gcc](https://lwn.net/Articles/806099/), зависят от этих исследовательских техник, но они также лежат в основе ([Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) и инструментов, основанных на формальных методах, таких как [Frama-C](https://frama-c.com/) и [Polyspace](https://www.mathworks.com/products/polyspace.html)).
+
+Мы не будем здесь исчерпывающе рассматривать техники статического анализа и исследования. Вместо этого мы сосредоточимся на том, что необходимо для понимания работы Slither, чтобы вы могли более эффективно использовать его для поиска ошибок и понимания кода.
+
+- [Представление кода](#code-representation)
+- [Анализ кода](#analysis)
+- [Промежуточное представление](#intermediate-representation)
+
+### Представление кода {#code-representation}
+
+В отличие от динамического анализа, который рассматривает один путь выполнения, статический анализ рассматривает все пути одновременно. Для этого он использует другое представление кода. Два наиболее распространенных — это абстрактное синтаксическое дерево (AST) и граф потока управления (CFG).
+
+### Абстрактные синтаксические деревья (AST) {#abstract-syntax-trees-ast}
+
+AST используются каждый раз, когда компилятор анализирует код. Это, вероятно, самая основная структура, на которой может выполняться статический анализ.
+
+Вкратце, AST — это структурированное дерево, где, как правило, каждый лист содержит переменную или константу, а внутренние узлы являются операндами или операциями управления потоком. Рассмотрим следующий код:
+
+```solidity
+function safeAdd(uint a, uint b) pure internal returns(uint){
+ if(a + b <= a){
+ revert();
+ }
+ return a + b;
+}
+```
+
+Соответствующее дерево AST показано ниже:
+
+
+
+Slither использует AST, экспортируемый компилятором solc.
+
+Хотя AST легко построить, он представляет собой вложенную структуру. Иногда его анализировать не так просто. Например, чтобы определить операции, используемые в выражении `a + b <= a`, вы должны сначала проанализировать `<=` а затем `+`. Распространенным подходом является использование так называемого шаблона «посетитель», который рекурсивно обходит дерево. Slither содержит универсальный «посетитель» в [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py).
+
+Следующий код использует `ExpressionVisitor` для определения, содержит ли выражение операцию сложения:
+
+```python
+from slither.visitors.expression.expression import ExpressionVisitor
+from slither.core.expressions.binary_operation import BinaryOperationType
+
+class HasAddition(ExpressionVisitor):
+
+ def result(self):
+ return self._result
+
+ def _post_binary_operation(self, expression):
+ if expression.type == BinaryOperationType.ADDITION:
+ self._result = True
+
+visitor = HasAddition(expression) # expression — это проверяемое выражение
+print(f'Выражение {expression} содержит сложение: {visitor.result()}')
+```
+
+### Граф потока управления (CFG) {#control-flow-graph-cfg}
+
+Второе по распространенности представление кода — это граф потока управления (CFG). Как следует из названия, это представление на основе графа, которое показывает все пути выполнения. Каждый узел содержит одну или несколько инструкций. Ребра в графе представляют операции управления потоком (if/then/else, цикл и т. д.). CFG для нашего предыдущего примера следующий:
+
+
+
+CFG — это представление, на основе которого построено большинство видов анализа.
+
+Существует много других представлений кода. Каждое представление имеет свои преимущества и недостатки в зависимости от анализа, который вы хотите выполнить.
+
+### Анализ {#analysis}
+
+Простейший тип анализа, который можно выполнить с помощью Slither, — это синтаксический анализ.
+
+### Синтаксический анализ {#syntax-analysis}
+
+Slither может перемещаться по различным компонентам кода и их представлениям, чтобы находить несоответствия и недостатки с помощью подхода, подобного сопоставлению с образцом.
+
+Например, следующие детекторы ищут проблемы, связанные с синтаксисом:
+
+- [Сокрытие переменной состояния](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): перебирает все переменные состояния и проверяет, не скрывает ли какая-либо из них переменную из унаследованного контракта ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62))
+
+- [Неправильный интерфейс ERC20](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): ищет неправильные сигнатуры функций ERC20 ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55))
+
+### Семантический анализ {#semantic-analysis}
+
+В отличие от синтаксического анализа, семантический анализ идет глубже и анализирует «смысл» кода. Эта категория включает несколько обширных типов анализа. Они позволяют получать более мощные и полезные результаты, но и писать их сложнее.
+
+Семантический анализ используется для обнаружения наиболее сложных уязвимостей.
+
+#### Анализ зависимостей данных {#fixed-point-computation}
+
+Говорят, что переменная `variable_a` зависит по данным от `variable_b`, если существует путь, в котором на значение `variable_a` влияет `variable_b`.
+
+В следующем коде `variable_a` зависит от `variable_b`:
+
+```solidity
+// ...
+variable_a = variable_b + 1;
+```
+
+Slither поставляется со встроенными возможностями [анализа зависимостей по данным](https://github.com/crytic/slither/wiki/data-dependency) благодаря своему промежуточному представлению (обсуждается в одном из следующих разделов).
+
+Пример использования зависимостей по данным можно найти в [детекторе опасного строгого равенства](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities). Здесь Slither будет искать сравнение на строгое равенство с опасным значением ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)) и сообщит пользователю, что следует использовать `>=` или `<=` вместо `==`, чтобы злоумышленник не смог заблокировать контракт. Помимо прочего, детектор будет считать опасным возвращаемое значение вызова `balanceOf(address)` ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)) и будет использовать механизм зависимостей по данным для отслеживания его использования.
+
+#### Вычисление с неподвижной точкой {#fixed-point-computation}
+
+Если ваш анализ перемещается по CFG и следует по ребрам, вы, скорее всего, увидите уже посещенные узлы. Например, если цикл представлен так, как показано ниже:
+
+```solidity
+for(uint i; i < range; ++){
+ variable_a += 1
+}
+```
+
+Вашему анализу нужно будет знать, когда остановиться. Здесь есть две основные стратегии: (1) выполнить итерацию для каждого узла конечное число раз, (2) вычислить так называемую _неподвижную точку_. Неподвижная точка по сути означает, что анализ этого узла больше не дает никакой значимой информации.
+
+Пример использования неподвижной точки можно найти в детекторах повторного входа: Slither исследует узлы и ищет внешние вызовы, запись в хранилище и чтение из него. Как только будет достигнута неподвижная точка ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), он останавливает исследование и анализирует результаты, чтобы определить, присутствует ли возможность повторного входа, с помощью различных шаблонов повторного входа ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)).
+
+Написание анализов с использованием эффективного вычисления неподвижной точки требует хорошего понимания того, как анализ распространяет информацию.
+
+### Промежуточное представление {#intermediate-representation}
+
+Промежуточное представление (IR) — это язык, который должен быть более удобен для статического анализа, чем исходный. Slither переводит Solidity в собственное промежуточное представление: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR).
+
+Понимание SlithIR не является обязательным, если вы хотите писать только базовые проверки. Однако это пригодится, если вы планируете писать сложные семантические анализы. Принтеры [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) и [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) помогут вам понять, как переводится код.
+
+## Основы API {#api-basics}
+
+У Slither есть API, который позволяет исследовать основные атрибуты контракта и его функций.
+
+Чтобы загрузить кодовую базу:
+
+```python
+from slither import Slither
+slither = Slither('/path/to/project')
+
+```
+
+### Исследование контрактов и функций {#exploring-contracts-and-functions}
+
+Объект `Slither` имеет:
+
+- `contracts (list(Contract))`: список контрактов
+- `contracts_derived (list(Contract))`: список контрактов, не унаследованных от другого контракта (подмножество контрактов)
+- `get_contract_from_name (str)`: возвращает контракт по его имени
+
+Объект `Contract` имеет:
+
+- `name (str)`: имя контракта
+- `functions (list(Function))`: список функций
+- `modifiers (list(Modifier))`: список модификаторов
+- `all_functions_called (list(Function/Modifier))`: список всех внутренних функций, достижимых из контракта
+- `inheritance (list(Contract))`: список унаследованных контрактов
+- `get_function_from_signature (str)`: возвращает функцию по ее сигнатуре
+- `get_modifier_from_signature (str)`: возвращает модификатор по его сигнатуре
+- `get_state_variable_from_name (str)`: возвращает переменную состояния по ее имени
+
+Объект `Function` или `Modifier` имеет:
+
+- `name (str)`: имя функции
+- `contract (contract)`: контракт, в котором объявлена функция
+- `nodes (list(Node))`: список узлов, составляющих CFG функции/модификатора
+- `entry_point (Node)`: точка входа CFG
+- `variables_read (list(Variable))`: список прочитанных переменных
+- `variables_written (list(Variable))`: список записанных переменных
+- `state_variables_read (list(StateVariable))`: список прочитанных переменных состояния (подмножество `variables_read`)
+- `state_variables_written (list(StateVariable))`: список записанных переменных состояния (подмножество `variables_written`)
diff --git a/public/content/translations/ru/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/ru/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md
new file mode 100644
index 00000000000..4325f54074c
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md
@@ -0,0 +1,81 @@
+---
+title: "Как настроить Tellor в качестве оракула"
+description: "Руководство по началу работы с интеграцией оракула Tellor в ваш протокол"
+author: "Tellor"
+lang: ru
+tags: [ "Solidity", "Умные контракты", "оракулы" ]
+skill: beginner
+published: 2021-06-29
+source: Tellor Docs
+sourceUrl: https://docs.tellor.io/tellor/
+---
+
+Вопрос: Ваш протокол почти готов, но ему нужен оракул, чтобы получить доступ к данным вне цепочки... Что делать?
+
+## (Необязательные) предварительные требования {#soft-prerequisites}
+
+Цель этого поста — сделать доступ к каналу оракула максимально простым и понятным. Тем не менее, чтобы сосредоточиться на аспекте оракула, мы предполагаем, что у вас есть следующие навыки в кодировании.
+
+Предположения:
+
+- вы умеете ориентироваться в терминале
+- у вас установлен npm
+- вы знаете, как использовать npm для управления зависимостями
+
+Tellor — это живой оракул с открытым исходным кодом, готовый к внедрению. Это руководство для начинающих должно продемонстрировать вам, насколько легко можно начать работу с Tellor, предоставив вашему проекту полностью децентрализованный и устойчивый к цензуре оракул.
+
+## Обзор {#overview}
+
+Tellor — это система-оракул, в которой стороны могут запрашивать значение точки данных оффчейн (например, BTC/USD), а репортеры соревнуются за добавление этого значения в банк данных ончейна, доступный для всех смарт-контрактов Ethereum. Входные данные в этот банк данных защищены сетью репортеров со стейком. Tellor использует криптоэкономические механизмы стимулирования, вознаграждая репортеров за честные представления данных и наказывая злоумышленников посредством выпуска токена Tellor, Tributes (TRB) и механизма разрешения споров.
+
+В этом руководстве мы рассмотрим:
+
+- Настройка начального набора инструментов, который понадобится вам для начала работы.
+- Разбор простого примера.
+- Список адресов тестовых сетей, на которых в настоящее время можно тестировать Tellor.
+
+## Использование Tellor {#usingtellor}
+
+Первое, что вам нужно сделать, это установить основные инструменты, необходимые для использования Tellor в качестве оракула. Используйте [этот пакет](https://github.com/tellor-io/usingtellor), чтобы установить пользовательские контракты Tellor:
+
+`npm install usingtellor`
+
+После установки это позволит вашим контрактам наследовать функции контракта «UsingTellor».
+
+Отлично! Теперь, когда у вас есть готовые инструменты, давайте выполним простое упражнение, в котором мы получим цену биткоина:
+
+### Пример BTC/USD {#btcusd-example}
+
+Наследуйте контракт UsingTellor, передав адрес Tellor в качестве аргумента конструктора:
+
+Приведем пример.
+
+```solidity
+import "usingtellor/contracts/UsingTellor.sol";
+
+contract PriceContract is UsingTellor {
+ uint256 public btcPrice;
+
+ //Этот контракт теперь имеет доступ ко всем функциям в UsingTellor
+
+constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {}
+
+function setBtcPrice() public {
+ bytes memory _b = abi.encode("SpotPrice",abi.encode("btc","usd"));
+ bytes32 _queryId = keccak256(_b);
+
+ uint256 _timestamp;
+ bytes _value;
+
+ (_value, _timestamp) = getDataBefore(_queryId, block.timestamp - 15 minutes);
+
+ btcPrice = abi.decode(_value,(uint256));
+ }
+}
+```
+
+Полный список адресов контрактов можно найти [здесь](https://docs.tellor.io/tellor/the-basics/contracts-reference).
+
+Для удобства использования и упрощения интеграции репозиторий UsingTellor поставляется с версией контракта [Tellor Playground](https://github.com/tellor-io/TellorPlayground). Список полезных функций см. [здесь](https://github.com/tellor-io/sampleUsingTellor#tellor-playground).
+
+Для более надежной реализации оракула Tellor ознакомьтесь с полным списком доступных функций [здесь](https://github.com/tellor-io/usingtellor/blob/master/README.md).
diff --git a/public/content/translations/ru/developers/tutorials/how-to-view-nft-in-metamask/index.md b/public/content/translations/ru/developers/tutorials/how-to-view-nft-in-metamask/index.md
new file mode 100644
index 00000000000..7be45594757
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-view-nft-in-metamask/index.md
@@ -0,0 +1,33 @@
+---
+title: "Как просмотреть свой NFT в кошельке (часть 3/3 серии руководств по NFT)"
+description: "В этом руководстве описывается, как просмотреть имеющийся NFT в MetaMask!"
+author: "Sumi Mudgil"
+tags: [ "ERC-721", "Alchemy", "Solidity" ]
+skill: beginner
+lang: ru
+published: 2021-04-22
+---
+
+Это руководство — часть 3/3 из серии руководств по NFT, в которой мы просматриваем наш недавно созданный NFT. Однако вы можете использовать это общее руководство для любого токена ERC-721 с помощью MetaMask, в том числе в Mainnet или любой тестовой сети. Если вы хотите узнать, как создать свой собственный NFT в Ethereum, ознакомьтесь с [частью 1 о том, как написать и развернуть смарт-контракт NFT](/developers/tutorials/how-to-write-and-deploy-an-nft)!
+
+Поздравляем! Вы добрались до самой короткой и простой части нашей серии руководств по NFT — как просмотреть только что созданный NFT в виртуальном кошельке. В этом примере мы будем использовать MetaMask, так как мы использовали его в предыдущих двух частях.
+
+В качестве предварительного условия у вас уже должно быть установлено мобильное приложение MetaMask, и оно должно содержать аккаунт, на который вы создали свой NFT. Вы можете бесплатно скачать приложение для [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) или [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US).
+
+## Шаг 1. Выберите сеть Sepolia {#set-network-to-sepolia}
+
+В верхней части приложения нажмите кнопку «Кошелек», после чего вам будет предложено выбрать сеть. Поскольку наш NFT был создан в сети Sepolia, вам нужно будет выбрать Sepolia в качестве вашей сети.
+
+
+
+## Шаг 2. Добавьте свой коллекционный предмет в MetaMask {#add-nft-to-metamask}
+
+Когда вы перейдете в сеть Sepolia, выберите вкладку «Collectibles» справа и добавьте адрес смарт-контракта NFT и идентификатор токена ERC-721 вашего NFT, которые вы сможете найти в Etherscan по хешу транзакции от вашего NFT, развернутого во второй части нашего руководства.
+
+
+
+Возможно, вам придется несколько раз обновить страницу, чтобы увидеть свой NFT, но он будет там !
+
+
+
+Поздравляем! Вы успешно создали NFT и теперь можете его просмотреть! Нам не терпится увидеть, как вы покорите мир NFT!
diff --git a/public/content/translations/ru/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/ru/developers/tutorials/how-to-write-and-deploy-an-nft/index.md
new file mode 100644
index 00000000000..b93b9e77f3e
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/how-to-write-and-deploy-an-nft/index.md
@@ -0,0 +1,380 @@
+---
+title: "Как написать и развернуть NFT (часть 1 из 3 серии руководств по NFT)"
+description: "Это руководство является Первой частью серии статей о NFT, в которых вы шаг за шагом узнаете, как написать и развернуть смарт-контракт невзаимозаменяемого токена (токен ERC-721) с использованием Ethereum и Inter Planetary File System (IPFS)."
+author: "Sumi Mudgil"
+tags: [ "ERC-721", "Alchemy", "Solidity", "смарт-контракты" ]
+skill: beginner
+lang: ru
+published: 2021-04-22
+---
+
+Поскольку NFT привлекают всеобщее внимание к блокчейну, сейчас у вас есть отличная возможность самим разобраться в этой шумихе, опубликовав собственный контракт NFT (токен ERC-721) в блокчейне Ethereum!
+
+Alchemy очень гордится тем, что поддерживает крупнейшие проекты в сфере NFT, включая Makersplace (недавно установивший рекорд по продаже цифровых произведений искусства на аукционе Christie's за 69 миллионов долларов), Dapper Labs (создатели NBA Top Shot и Crypto Kitties), OpenSea (крупнейший в мире NFT-маркетплейс), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable и другие.
+
+В этом руководстве мы рассмотрим создание и развертывание смарт-контракта ERC-721 в тестовой сети Sepolia с использованием [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) и [Alchemy](https://alchemy.com/signup/eth) (не волнуйтесь, если вы пока не понимаете, что все это значит — мы объясним!).
+
+Во второй части этого руководства мы рассмотрим, как использовать наш смарт-контракт, чтобы отчеканить NFT, а в третьей части объясним, как просматривать свой NFT в MetaMask.
+
+И, конечно, если у вас в любой момент возникнут вопросы, не стесняйтесь задавать их в [Discord-канале Alchemy](https://discord.gg/gWuC7zB) или посетите [документацию по NFT API от Alchemy](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api)!
+
+## Шаг 1. Подключение к сети Ethereum {#connect-to-ethereum}
+
+Существует множество способов отправлять запросы в блокчейн Ethereum, но для простоты мы будем использовать бесплатный аккаунт на [Alchemy](https://alchemy.com/signup/eth) — платформе для разработчиков блокчейнов и API, которая позволяет нам взаимодействовать с сетью Ethereum без необходимости запускать собственные узлы.
+
+В этом руководстве мы также воспользуемся инструментами для разработчиков от Alchemy для мониторинга и аналитики, чтобы понять, что происходит «под капотом» при развертывании нашего смарт-контракта. Если у вас еще нет аккаунта Alchemy, вы можете бесплатно зарегистрироваться [здесь](https://alchemy.com/signup/eth).
+
+## Шаг 2. Создайте приложение (и ключ API) {#make-api-key}
+
+Как только регистрация в Alchemy завершена, можно создать приложение и таким образом сгенерировать ключ API. Это позволит нам делать запросы к тестовой сети Sepolia. Ознакомьтесь с [этим руководством](https://docs.alchemyapi.io/guides/choosing-a-network), если вам интересно узнать больше о тестовых сетях.
+
+1. Перейдите к странице "Create App” в своем Alchemy Dashboard - наведите на "Apps" в навигационной панели и кликните "Create App”
+
+
+
+2. Назовите свое приложение (мы выбрали «My First NFT!»), дайте краткое описание, выберите «Ethereum» в поле Chain и «Sepolia» в поле network. После Слияния другие тестовые сети устарели.
+
+
+
+3. Нажмите "Create app" и все готово! Ваше приложение должно появиться в таблице ниже.
+
+## Шаг 3. Создайте аккаунт Ethereum (адрес) {#create-eth-address}
+
+Нам нужен аккаунт Ethereum для того, чтобы отправлять и получать транзакции. В этом руководстве мы будем использовать MetaMask, виртуальный кошелек в браузере, используемый для управления адресом вашего аккаунта Ethereum. Если вы хотите больше узнать о том, как работают транзакции в Ethereum, ознакомьтесь с [этой страницей](/developers/docs/transactions/) от Ethereum Foundation.
+
+Вы можете бесплатно скачать и создать аккаунт MetaMask [здесь](https://metamask.io/download). При создании аккаунта или если он у вас уже есть, обязательно переключитесь на «Sepolia Test Network» в правом верхнем углу (чтобы мы не работали с настоящими деньгами).
+
+
+
+## Шаг 4. Добавьте эфир из крана (Faucet) {#step-4-add-ether-from-a-faucet}
+
+Чтобы загрузить наш смарт контракт в тестовую сеть, нам нужно немного тестового ETH. Чтобы получить ETH, перейдите в [кран Sepolia](https://sepoliafaucet.com/) от Alchemy, войдите в систему, введите адрес своего аккаунта и нажмите «Send Me ETH». Вскоре вы должны увидеть ETH в своем аккаунте MetaMask!
+
+## Шаг 5. Проверьте свой баланс {#check-balance}
+
+Чтобы перепроверить наличие баланса, давайте сделаем запрос [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) с помощью [инструмента Composer от Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Результат будет содержать сумму ETH в нашем кошельке. После ввода адреса вашего аккаунта MetaMask и нажатия «Send Request» вы должны увидеть примерно такой ответ:
+
+ ````
+ ```{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}```
+ ````
+
+> **Примечание.** Этот результат указан в wei, а не в ETH. Wei это наименьшая единица измерения эфира. Конвертация из wei в ETH: 1 eth = 1018 wei. Таким образом, если мы конвертируем 0xde0b6b3a7640000 в десятичную систему, мы получим 1\*1018 wei, что равно 1 ETH.
+
+Фух! Наши ненастоящие деньги уже все там.
+
+## Шаг 6. Инициализируйте наш проект {#initialize-project}
+
+Во-первых, надо создать директорию для нашего проекта. Перейдите в вашу командную строку и наберите:
+
+ ```
+ mkdir my-nft
+ cd my-nft
+ ```
+
+Сейчас, когда мы внутри директории нашего проекта, мы будем использовать npm init, чтобы инициализировать проект. Если у вас еще не установлен npm, следуйте [этим инструкциям](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (нам также понадобится [Node.js](https://nodejs.org/en/download/), так что загрузите и его!).
+
+ ```
+ npm init
+ ```
+
+Неважно, как вы ответите на вопросы при установке. Для справки, вот как это сделали мы:
+
+```json
+ имя пакета: (my-nft)
+ версия: (1.0.0)
+ описание: Мой первый NFT!
+ точка входа: (index.js)
+ тестовая команда:
+ репозиторий git:
+ ключевые слова:
+ автор:
+ лицензия: (ISC)
+ Файл /Users/thesuperb1/Desktop/my-nft/package.json будет содержать:
+
+ {
+ "name": "my-nft",
+ "version": "1.0.0",
+ "description": "Мой первый NFT!",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+ }
+```
+
+Подтвердите package.json, и мы готовы к работе!
+
+## Шаг 7. Установите [Hardhat](https://hardhat.org/getting-started/#overview) {#install-hardhat}
+
+Hardhat - это среда для сборки, развертывания, тестирования и отладки программного обеспечения Ethereum. Он помогает разработчикам создавать смарт-контракты и децентрализованные приложения локально перед их развертыванием в основной сети.
+
+Внутри нашего проекта my-nft выполните:
+
+ ```
+ npm install --save-dev hardhat
+ ```
+
+Более подробную информацию об [инструкциях по установке](https://hardhat.org/getting-started/#overview) можно найти на этой странице.
+
+## Шаг 8. Создайте проект Hardhat {#create-hardhat-project}
+
+В директории проекта запустите:
+
+ ```
+ npx hardhat
+ ```
+
+Вы увидите приветственное сообщение и интерфейс с вариантами того, что делать дальше. Выберите "create an empty hardhat.config.js":
+
+ ```
+ 888 888 888 888 888
+ 888 888 888 888 888
+ 888 888 888 888 888
+ 8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
+ 888 888 "88b 888P" d88" 888 888 "88b "88b 888
+ 888 888 .d888888 888 888 888 888 888 .d888888 888
+ 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
+ 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
+ 👷 Добро пожаловать в Hardhat v2.0.11 👷
+ ? Что вы хотите сделать? …
+ Создать пример проекта
+ ❯ Создать пустой файл hardhat.config.js
+ Выйти
+ ```
+
+Это создаст для нас файл hardhat.config.js, в котором мы укажем все настройки для нашего проекта (в шаге 13).
+
+## Шаг 9. Добавьте папки проекта {#add-project-folders}
+
+Чтобы наш проект был организован, мы создадим две новые папки. Перейдите в командной строке в корневую директорию проекта и наберите:
+
+ ```
+ mkdir contracts
+ mkdir scripts
+ ```
+
+- contracts/ — здесь мы будем хранить код нашего смарт-контракта NFT
+
+- scripts/ — здесь мы будем хранить скрипты для развертывания и взаимодействия с нашим смарт-контрактом
+
+## Шаг 10. Напишите наш контракт {#write-contract}
+
+Теперь, когда наша среда настроена, перейдем к более интересным вещам: _написанию кода нашего смарт-контракта!_
+
+Откройте проект my-nft в вашем любимом редакторе (нам нравится [VSCode](https://code.visualstudio.com/)). Смарт-контракты пишутся на языке под названием Solidity, который мы и будем использовать для написания нашего смарт-контракта MyNFT.sol.
+
+1. Перейдите в папку `contracts` и создайте новый файл с именем MyNFT.sol
+
+2. Ниже приведен код нашего смарт-контракта NFT, который основан на реализации ERC-721 из библиотеки [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721). Скопируйте и вставьте приведенное ниже содержимое в ваш файл MyNFT.sol.
+
+ ```solidity
+ //Контракт основан на [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
+ // SPDX-License-Identifier: MIT
+ pragma solidity ^0.8.0;
+
+ import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
+ import "@openzeppelin/contracts/utils/Counters.sol";
+ import "@openzeppelin/contracts/access/Ownable.sol";
+ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
+
+ contract MyNFT is ERC721URIStorage, Ownable {
+ using Counters for Counters.Counter;
+ Counters.Counter private _tokenIds;
+
+ constructor() ERC721("MyNFT", "NFT") {}
+
+ function mintNFT(address recipient, string memory tokenURI)
+ public onlyOwner
+ returns (uint256)
+ {
+ _tokenIds.increment();
+
+ uint256 newItemId = _tokenIds.current();
+ _mint(recipient, newItemId);
+ _setTokenURI(newItemId, tokenURI);
+
+ return newItemId;
+ }
+ }
+ ```
+
+3. Поскольку мы наследуем классы из библиотеки контрактов OpenZeppelin, в командной строке выполните `npm install @openzeppelin/contracts^4.0.0`, чтобы установить библиотеку в нашу папку.
+
+Так что же именно _делает_ этот код? Давайте разберем его по строчкам.
+
+Вверху нашего смарт-контракта мы импортируем три класса смарт-контрактов [OpenZeppelin](https://openzeppelin.com/):
+
+- @openzeppelin/contracts/token/ERC721/ERC721.sol содержит реализацию стандарта ERC-721, которую унаследует наш смарт-контракт NFT. (Чтобы NFT был действительным, ваш смарт-контракт должен реализовывать все методы стандарта ERC-721). Чтобы узнать больше о наследуемых функциях ERC-721, ознакомьтесь с определением интерфейса [здесь](https://eips.ethereum.org/EIPS/eip-721).
+
+- @openzeppelin/contracts/utils/Counters.sol предоставляет счетчики, которые можно увеличивать или уменьшать только на единицу. Наш смарт-контракт использует счетчик для отслеживания общего количества выпущенных NFT и для установки уникального идентификатора для нашего нового NFT. (Каждому NFT, выпущенному с помощью смарт-контракта, должен быть присвоен уникальный идентификатор — здесь наш уникальный идентификатор определяется общим количеством существующих NFT. Например, первый NFT, который мы выпускаем с помощью нашего смарт-контракта, имеет ID «1», наш второй NFT имеет ID «2» и т. д.)
+
+- @openzeppelin/contracts/access/Ownable.sol настраивает [контроль доступа](https://docs.openzeppelin.com/contracts/3.x/access-control) к нашему смарт-контракту, поэтому только владелец смарт-контракта (вы) может выпускать NFT. (Обратите внимание, что включение контроля доступа — это исключительно ваше предпочтение. Если вы хотите, чтобы кто угодно мог выпустить NFT с помощью вашего смарт-контракта, удалите слово Ownable в строке 10 и onlyOwner в строке 17.)
+
+После наших операторов импорта у нас есть наш собственный смарт-контракт NFT, который на удивление короткий — он содержит только счетчик, конструктор и одну функцию! Это благодаря нашим унаследованным контрактам OpenZeppelin, которые реализуют большинство методов, необходимых для создания NFT, таких как `ownerOf`, который возвращает владельца NFT, и `transferFrom`, который передает право собственности на NFT с одного аккаунта на другой.
+
+В нашем конструкторе ERC-721 вы заметите, что мы передаем 2 строки: «MyNFT» и «NFT». Первая переменная — это имя смарт-контракта, а вторая — его символ. Вы можете назвать каждую из этих переменных как угодно!
+
+Наконец, у нас есть функция `mintNFT(address recipient, string memory tokenURI)`, которая позволяет нам выпустить NFT! Вы заметите, что эта функция принимает две переменные:
+
+- `address recipient` указывает адрес, который получит ваш свежевыпущенный NFT
+
+- `string memory tokenURI` — это строка, которая должна указывать на JSON-документ, описывающий метаданные NFT. Метаданные NFT — это то, что оживляет его, позволяя ему иметь настраиваемые свойства, такие как имя, описание, изображение и другие атрибуты. Во второй части этого руководства мы опишем, как настроить эти метаданные.
+
+`mintNFT` вызывает некоторые методы из унаследованной библиотеки ERC-721 и в конечном итоге возвращает число, представляющее идентификатор только что выпущенного NFT.
+
+## Шаг 11. Подключите MetaMask и Alchemy к вашему проекту {#connect-metamask-and-alchemy}
+
+Теперь, когда мы создали кошелек MetaMask, аккаунт Alchemy и написали наш смарт-контракт, пришло время соединить все три компонента.
+
+Каждая транзакция, сделанная с вашего виртуального кошелька, требует подпись с использованием вашего же персонального ключа. Чтобы дать программе такую возможность, мы можем сохранить наш приватный ключ (и ключ API Alchemy) в файле окружения.
+
+Чтобы узнать больше об отправке транзакций, ознакомьтесь с [этим руководством по отправке транзакций с использованием web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/).
+
+Во-первых, установите dotenv, находясь в директории проекта:
+
+ ```
+ npm install dotenv --save
+ ```
+
+Затем создайте файл `.env` в корневом каталоге нашего проекта и добавьте в него свой закрытый ключ MetaMask и URL-адрес HTTP API Alchemy.
+
+- Следуйте [этим инструкциям](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key), чтобы экспортировать свой закрытый ключ из MetaMask.
+
+- Ниже показано, как получить URL-адрес HTTP API Alchemy и скопировать его в буфер обмена.
+
+
+
+Ваш `.env` теперь должен выглядеть так:
+
+ ```
+ API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key"
+ PRIVATE_KEY="your-metamask-private-key"
+ ```
+
+Чтобы подключить их к нашему коду, мы будем ссылаться на эти переменные в нашем файле hardhat.config.js на шаге 13.
+
+
+
+## Шаг 12. Установите Ethers.js {#install-ethers}
+
+Ethers.js — это библиотека, которая упрощает взаимодействие и отправку запросов в Ethereum, оборачивая [стандартные методы JSON-RPC](/developers/docs/apis/json-rpc/) в более удобные для пользователя методы.
+
+Hardhat очень упрощает интеграцию [плагинов](https://hardhat.org/plugins/) для дополнительных инструментов и расширенной функциональности. Мы воспользуемся преимуществами [плагина Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) для развертывания контракта ([Ethers.js](https://github.com/ethers-io/ethers.js/) имеет несколько очень удобных методов развертывания контрактов).
+
+В директории проекта запустите:
+
+ ```
+ npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0
+ ```
+
+Так же в следующем шаге мы добавим ethers в hardhat.config.js.
+
+## Шаг 13. Обновите hardhat.config.js {#update-hardhat-config}
+
+Мы добавили несколько зависимостей и плагинов, а сейчас мы должны обновить hardhat.config.js, чтобы наш проект узнал об этих изменениях.
+
+Измените ваш hardhat.config.js, чтобы он выглядел примерно так:
+
+```js
+ /**
+ * @type import('hardhat/config').HardhatUserConfig
+ */
+ require('dotenv').config();
+ require("@nomiclabs/hardhat-ethers");
+ const { API_URL, PRIVATE_KEY } = process.env;
+ module.exports = {
+ solidity: "0.8.1",
+ defaultNetwork: "sepolia",
+ networks: {
+ hardhat: {},
+ sepolia: {
+ url: API_URL,
+ accounts: [`0x${PRIVATE_KEY}`]
+ }
+ },
+ }
+```
+
+## Шаг 14. Скомпилируйте наш контракт {#compile-contract}
+
+Пора заставить это работать, давайте скомпилируем наш контракт. Задача compile это одна из встроенных в Hardhat задач.
+
+Запустите в командной строке:
+
+ ```
+ npx hardhat compile
+ ```
+
+Может появиться предупреждение вроде SPDX license identifier not provided in source file, но об этом не стоит беспокоиться - надеемся все остальное выглядит хорошо! Если нет, вы всегда можете написать в [Discord-канал Alchemy](https://discord.gg/u72VCg3).
+
+## Шаг 15. Напишите наш скрипт развертывания {#write-deploy}
+
+Контракт написан, файл конфигурации корректен, пора писать скрипт развертывания.
+
+Перейдите в папку `scripts/` и создайте новый файл с именем `deploy.js`, добавив в него следующее содержимое:
+
+```js
+async function main() {
+ const MyNFT = await ethers.getContractFactory("MyNFT")
+
+ // Начинаем развертывание, возвращая промис, который разрешается в объект контракта
+ const myNFT = await MyNFT.deploy()
+ await myNFT.deployed()
+ console.log("Контракт развернут по адресу:", myNFT.address)
+}
+
+main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error)
+ process.exit(1)
+ })
+```
+
+Hardhat отлично объясняет, что делает каждая из этих строк кода, в своем [руководстве по контрактам](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), мы использовали их объяснения здесь.
+
+ ```
+ const MyNFT = await ethers.getContractFactory("MyNFT");
+ ```
+
+ContractFactory в ethers.js — это абстракция, используемая для развертывания новых смарт-контрактов, поэтому MyNFT здесь является фабрикой для экземпляров нашего контракта NFT. При использовании плагина hardhat-ethers экземпляры ContractFactory и Contract по умолчанию связаны с первым подписавшим.
+
+ ```
+ const myNFT = await MyNFT.deploy();
+ ```
+
+Вызов deploy() на ContractFactory запустит развертывание, и вернет Promise, который разрешается в Contract. Это объект, который имеет метод для каждой из функций нашего смарт контракта.
+
+## Шаг 16. Разверните наш контракт {#deploy-contract}
+
+Мы наконец-то готовы развернуть наш смарт контракт! Вернитесь в корневой каталог вашего проекта и в командной строке выполните:
+
+ ```
+ npx hardhat --network sepolia run scripts/deploy.js
+ ```
+
+Вы должны увидеть что-то наподобие:
+
+ ```
+ Контракт развернут по адресу: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650
+ ```
+
+Если мы перейдем в [обозреватель блоков Sepolia Etherscan](https://sepolia.etherscan.io/) и найдем наш контракт по адресу, то сможем убедиться, что он был успешно развернут. Если вы не видите его сразу, подождите некоторое время, так как это может занять некоторое время. Транзакция будет выглядеть примерно так:
+
+
+
+Адрес в поле «From» (От) должен совпадать с адресом вашего аккаунта MetaMask, а в поле «To» (Кому) будет указано «Contract Creation» (Создание контракта). Если мы нажмем на транзакцию, то увидим адрес нашего контракта в поле «To»:
+
+
+
+Да-а-а-а! Вы только что развернули свой смарт-контракт NFT в сети Ethereum (тестовой сети)!
+
+Чтобы понять, что происходит «под капотом», давайте перейдем на вкладку Explorer в нашей [панели управления Alchemy](https://dashboard.alchemyapi.io/explorer). Если у вас несколько приложений Alchemy, убедитесь, что вы отфильтровали их по приложению и выбрали «MyNFT».
+
+
+
+Вы увидите пачку вызовов JSON-RPC, которые произвел Hardhat/Ethers после того, как мы запустили функцию .deploy(). Здесь стоит отметить два важных вызова: [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction), который является запросом на фактическую запись нашего смарт-контракта в сеть Sepolia, и [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash), который является запросом на чтение информации о нашей транзакции по ее хешу (типичный шаблон при отправке транзакций). Чтобы узнать больше об отправке транзакций, ознакомьтесь с этим руководством по [отправке транзакций с использованием Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/).
+
+На этом первая часть этого руководства закончена. Во [второй части мы будем взаимодействовать с нашим смарт-контрактом, отчеканивая NFT](/developers/tutorials/how-to-mint-an-nft/), а в [третьей части мы покажем, как просматривать свои NFT в кошельке Ethereum](/developers/tutorials/how-to-view-nft-in-metamask/)!
diff --git a/public/content/translations/ru/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/ru/developers/tutorials/interact-with-other-contracts-from-solidity/index.md
new file mode 100644
index 00000000000..a8b288f2fdc
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/interact-with-other-contracts-from-solidity/index.md
@@ -0,0 +1,179 @@
+---
+title: "Взаимодействие с другими контрактами из Solidity"
+description: "Как развернуть умный контракт из существующего контракта и взаимодействовать с ним"
+author: "jdourlens"
+tags:
+ [
+ "Умные контракты",
+ "Solidity",
+ "Remix",
+ "развертывание",
+ "композиционность"
+ ]
+skill: advanced
+lang: ru
+published: 2020-04-05
+source: EthereumDev
+sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/
+address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+---
+
+В предыдущих руководствах мы многое узнали о том, [как развернуть свой первый умный контракт](/developers/tutorials/deploying-your-first-smart-contract/) и добавить в него некоторые функции, такие как [контроль доступа с помощью модификаторов](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) или [обработка ошибок в Solidity](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/). В этом руководстве мы узнаем, как развернуть умный контракт из существующего контракта и взаимодействовать с ним.
+
+Мы создадим контракт, который позволит любому желающему иметь свой собственный умный контракт `Counter`, создав для него фабрику. Ее название будет `CounterFactory`. Во-первых, вот код нашего первоначального умного контракта `Counter`:
+
+```solidity
+pragma solidity 0.5.17;
+
+contract Counter {
+
+ uint256 private _count;
+ address private _owner;
+ address private _factory;
+
+
+ modifier onlyOwner(address caller) {
+ require(caller == _owner, "Вы не являетесь владельцем контракта");
+ _;
+ }
+
+ modifier onlyFactory() {
+ require(msg.sender == _factory, "Вы должны использовать фабрику");
+ _;
+ }
+
+ constructor(address owner) public {
+ _owner = owner;
+ _factory = msg.sender;
+ }
+
+ function getCount() public view returns (uint256) {
+ return _count;
+ }
+
+ function increment(address caller) public onlyFactory onlyOwner(caller) {
+ _count++;
+ }
+
+}
+```
+
+Обратите внимание, что мы немного изменили код контракта, чтобы отслеживать адрес фабрики и адрес владельца контракта. Когда вы вызываете код контракта из другого контракта, `msg.sender` будет ссылаться на адрес нашей фабрики контрактов. Это **действительно важный момент для понимания**, поскольку использование одного контракта для взаимодействия с другими является обычной практикой. Поэтому в сложных случаях следует обращать внимание на то, кто является отправителем.
+
+Для этого мы также добавили модификатор `onlyFactory`, который гарантирует, что функция изменения состояния может быть вызвана только фабрикой, которая передаст исходного вызывающего в качестве параметра.
+
+Внутри нашего нового `CounterFactory`, который будет управлять всеми остальными `Counters`, мы добавим сопоставление, которое будет связывать владельца с адресом его контракта-счетчика:
+
+```solidity
+mapping(address => Counter) _counters;
+```
+
+В Ethereum сопоставления эквивалентны объектам в javascript, они позволяют сопоставить ключ типа А со значением типа Б. В данном случае мы сопоставляем адрес владельца с экземпляром его `Counter`.
+
+Создание нового экземпляра `Counter` для кого-либо будет выглядеть так:
+
+```solidity
+ function createCounter() public {
+ require (_counters[msg.sender] == Counter(0));
+ _counters[msg.sender] = new Counter(msg.sender);
+ }
+```
+
+Сначала мы проверяем, владеет ли человек уже счетчиком. Если у него нет счетчика, мы создаем новый экземпляр счетчика, передавая его адрес в конструктор `Counter`, и присваиваем вновь созданный экземпляр сопоставлению.
+
+Получение значения определенного `Counter` будет выглядеть так:
+
+```solidity
+function getCount(address account) public view returns (uint256) {
+ require (_counters[account] != Counter(0));
+ return (_counters[account].getCount());
+}
+
+function getMyCount() public view returns (uint256) {
+ return (getCount(msg.sender));
+}
+```
+
+Первая функция проверяет, существует ли контракт `Counter` для данного адреса, а затем вызывает метод `getCount` из экземпляра. Вторая функция, `getMyCount`, — это просто сокращение для прямой передачи `msg.sender` в функцию `getCount`.
+
+Функция `increment` очень похожа, но она передает исходного отправителя транзакции в контракт `Counter`:
+
+```solidity
+function increment() public {
+ require (_counters[msg.sender] != Counter(0));
+ Counter(_counters[msg.sender]).increment(msg.sender);
+ }
+```
+
+Обратите внимание, что при слишком большом количестве вызовов наш счетчик может стать жертвой переполнения. Вам следует как можно чаще использовать [библиотеку SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/), чтобы защититься от этого возможного случая.
+
+Чтобы развернуть наш контракт, вам нужно будет предоставить код как `CounterFactory`, так и `Counter`. При развертывании, например в Remix, вам нужно будет выбрать `CounterFactory`.
+
+Вот полный код:
+
+```solidity
+pragma solidity 0.5.17;
+
+contract Counter {
+
+ uint256 private _count;
+ address private _owner;
+ address private _factory;
+
+
+ modifier onlyOwner(address caller) {
+ require(caller == _owner, "Вы не являетесь владельцем контракта");
+ _;
+ }
+
+ modifier onlyFactory() {
+ require(msg.sender == _factory, "Вы должны использовать фабрику");
+ _;
+ }
+
+ constructor(address owner) public {
+ _owner = owner;
+ _factory = msg.sender;
+ }
+
+ function getCount() public view returns (uint256) {
+ return _count;
+ }
+
+ function increment(address caller) public onlyFactory onlyOwner(caller) {
+ _count++;
+ }
+
+}
+
+contract CounterFactory {
+
+ mapping(address => Counter) _counters;
+
+ function createCounter() public {
+ require (_counters[msg.sender] == Counter(0));
+ _counters[msg.sender] = new Counter(msg.sender);
+ }
+
+ function increment() public {
+ require (_counters[msg.sender] != Counter(0));
+ Counter(_counters[msg.sender]).increment(msg.sender);
+ }
+
+ function getCount(address account) public view returns (uint256) {
+ require (_counters[account] != Counter(0));
+ return (_counters[account].getCount());
+ }
+
+ function getMyCount() public view returns (uint256) {
+ return (getCount(msg.sender));
+ }
+
+}
+```
+
+После компиляции в разделе развертывания Remix вы выберете фабрику для развертывания:
+
+
+
+Затем вы можете поэкспериментировать с вашей фабрикой контрактов и проверить изменение значения. Если вы хотите вызвать умный контракт с другого адреса, вам нужно будет изменить адрес в поле выбора аккаунта в Remix.
diff --git a/public/content/translations/ru/developers/tutorials/ipfs-decentralized-ui/index.md b/public/content/translations/ru/developers/tutorials/ipfs-decentralized-ui/index.md
new file mode 100644
index 00000000000..5a68c0fb290
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/ipfs-decentralized-ui/index.md
@@ -0,0 +1,73 @@
+---
+title: "IPFS для децентрализованных пользовательских интерфейсов"
+description: "В этом руководстве рассказывается, как использовать IPFS для хранения пользовательского интерфейса децентрализованного приложения. Хотя данные и бизнес-логика приложения децентрализованы, без устойчивого к цензуре пользовательского интерфейса пользователи все равно могут потерять к нему доступ."
+author: Ori Pomerantz
+tags: [ "ipfs" ]
+skill: beginner
+lang: ru
+published: 2024-06-29
+---
+
+Вы написали невероятное новое децентрализованное приложение. Вы даже написали для него [пользовательский интерфейс](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/). Но теперь вы боитесь, что кто-то попытается подвергнуть его цензуре, отключив ваш пользовательский интерфейс, который представляет собой всего лишь один сервер в облаке. Из этого руководства вы узнаете, как избежать цензуры, разместив свой пользовательский интерфейс в **[межпланетной файловой системе (IPFS)](https://ipfs.tech/developers/)**, чтобы любой желающий мог закрепить его на сервере для будущего доступа.
+
+Вы можете использовать сторонний сервис, такой как [Fleek](https://resources.fleek.xyz/docs/), чтобы сделать всю работу. Это руководство предназначено для тех, кто хочет сделать достаточно, чтобы понять, что они делают, даже если это потребует больше работы.
+
+## Начало работы в локальной сети {#getting-started-locally}
+
+Существует несколько [сторонних провайдеров IPFS](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service), но для тестирования лучше всего начать с локального запуска IPFS.
+
+1. Установите [пользовательский интерфейс IPFS](https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions).
+
+2. Создайте каталог с вашим веб-сайтом. Если вы используете [Vite](https://vite.dev/), используйте эту команду:
+
+ ```sh
+ pnpm vite build
+ ```
+
+3. В IPFS Desktop нажмите **Импорт > Папка** и выберите каталог, созданный на предыдущем шаге.
+
+4. Выберите только что загруженную папку и нажмите **Переименовать**. Дайте ей более осмысленное имя.
+
+5. Выберите ее снова и нажмите **Поделиться ссылкой**. Скопируйте URL-адрес в буфер обмена. Ссылка будет похожа на `https://ipfs.io/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`.
+
+6. Нажмите **Статус**. Разверните вкладку **Дополнительно**, чтобы увидеть адрес шлюза. Например, в моей системе адрес `http://127.0.0.1:8080`.
+
+7. Объедините путь из шага со ссылкой с адресом шлюза, чтобы найти свой адрес. Например, для приведенного выше примера URL-адрес — `http://127.0.0.1:8080/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`. Откройте этот URL-адрес в браузере, чтобы увидеть ваш сайт.
+
+## Загрузка {#uploading}
+
+Итак, теперь вы можете использовать IPFS для локальной раздачи файлов, что не очень интересно. Следующий шаг — сделать их доступными для всего мира, когда вы не в сети.
+
+Существует ряд хорошо известных [сервисов закрепления](https://docs.ipfs.tech/concepts/persistence/#pinning-services). Выберите один из них. Какой бы сервис вы ни использовали, вам необходимо создать аккаунт и предоставить ему **идентификатор контента (CID)** в вашем IPFS desktop.
+
+Лично я считаю, что [4EVERLAND](https://docs.4everland.org/storage/4ever-pin/guides) является самым простым в использовании. Вот инструкция для него:
+
+1. Перейдите на [панель управления](https://dashboard.4everland.org/overview) и войдите в систему с помощью своего кошелька.
+
+2. В левой боковой панели нажмите **Хранилище > 4EVER Pin**.
+
+3. Нажмите **Загрузить > Выбранный CID**. Дайте вашему контенту имя и укажите CID из IPFS desktop. В настоящее время CID — это строка, которая начинается с `Qm`, за которой следуют 44 буквы и цифры, представляющие собой [закодированный в base-58](https://medium.com/bootdotdev/base64-vs-base58-encoding-c25553ff4524) хэш, например `QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`, но [это, вероятно, изменится](https://docs.ipfs.tech/concepts/content-addressing/#version-1-v1).
+
+4. Начальный статус: **В очереди**. Перезагружайте, пока он не изменится на **Закреплено**.
+
+5. Нажмите на свой CID, чтобы получить ссылку. Вы можете увидеть мое приложение [здесь](https://bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im/).
+
+6. Возможно, вам потребуется активировать свой аккаунт, чтобы он был закреплен более чем на месяц. Активация аккаунта стоит около 1 $. Если вы закрыли его, выйдите из системы и войдите снова, чтобы вам снова предложили активацию.
+
+## Использование из IPFS {#using-from-ipfs}
+
+На данный момент у вас есть ссылка на централизованный шлюз, который обслуживает ваш контент IPFS. Короче говоря, ваш пользовательский интерфейс может быть немного безопаснее, но он все еще не устойчив к цензуре. Для настоящей устойчивости к цензуре пользователям необходимо использовать IPFS [непосредственно из браузера](https://docs.ipfs.tech/install/ipfs-companion/#prerequisites).
+
+После того как вы его установили (и настольный IPFS работает), вы можете перейти на [/ipfs/``](https://any.site/ipfs/bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im) на любом сайте, и вы получите этот контент, обслуживаемый децентрализованно.
+
+## Недостатки {#drawbacks}
+
+Вы не можете надежно удалить файлы IPFS, поэтому, пока вы изменяете свой пользовательский интерфейс, вероятно, лучше либо оставить его централизованным, либо использовать [межпланетную систему имен (IPNS)](https://docs.ipfs.tech/concepts/ipns/#mutability-in-ipfs), систему, которая обеспечивает изменяемость поверх IPFS. Конечно, все, что является изменяемым, может быть подвергнуто цензуре, в случае IPNS путем давления на человека, имеющего соответствующий приватный ключ.
+
+Кроме того, некоторые пакеты имеют проблемы с IPFS, поэтому, если ваш веб-сайт очень сложен, это может быть не лучшим решением. И, конечно, все, что зависит от серверной интеграции, не может быть децентрализовано только за счет размещения клиентской части в IPFS.
+
+## Заключение {#conclusion}
+
+Точно так же, как Ethereum позволяет децентрализовать базу данных и бизнес-логику вашего децентрализованного приложения, IPFS позволяет децентрализовать пользовательский интерфейс. Это позволяет вам перекрыть еще один вектор атаки на ваше децентрализованное приложение.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md b/public/content/translations/ru/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md
new file mode 100644
index 00000000000..61e3396f8e6
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md
@@ -0,0 +1,111 @@
+---
+title: "Начните разработку интерфейса для вашего децентрализованного приложения с помощью create-eth-app"
+description: "Обзор использования create-eth-app и его возможностей"
+author: "Markus Waas"
+tags:
+ [
+ "интерфейс",
+ "JavaScript",
+ "ethers.js",
+ "the graph",
+ "defi"
+ ]
+skill: beginner
+lang: ru
+published: 2020-04-27
+source: soliditydeveloper.com
+sourceUrl: https://soliditydeveloper.com/create-eth-app
+---
+
+В прошлый раз мы рассмотрели [общую картину Solidity](https://soliditydeveloper.com/solidity-overview-2020) и уже упоминали [create-eth-app](https://github.com/PaulRBerg/create-eth-app). Теперь вы узнаете, как его использовать, какие функции интегрированы, а также дополнительные идеи по его расширению. Это приложение, созданное Полом Разваном Бергом, основателем [Sablier](http://sablier.com/), ускорит разработку вашего интерфейса и поставляется с несколькими дополнительными интеграциями на выбор.
+
+## Установка {#installation}
+
+Для установки требуется Yarn 0.25 или выше (`npm install yarn --global`). Это так же просто, как запустить:
+
+```bash
+yarn create eth-app my-eth-app
+cd my-eth-app
+yarn react-app:start
+```
+
+Под капотом используется [create-react-app](https://github.com/facebook/create-react-app). Чтобы увидеть свое приложение, откройте `http://localhost:3000/`. Когда вы будете готовы к развертыванию в производственной среде, создайте минимизированный пакет с помощью yarn build. Один из простых способов разместить его — [Netlify](https://www.netlify.com/). Вы можете создать репозиторий GitHub, добавить его в Netlify, настроить команду сборки, и все готово! Ваше приложение будет размещено и доступно для всех. И все это бесплатно.
+
+## Возможности {#features}
+
+### React и create-react-app {#react--create-react-app}
+
+Прежде всего, сердце приложения: React и все дополнительные возможности, которые предоставляет _create-react-app_. Использование только этого — отличный вариант, если вы не хотите интегрировать Ethereum. Сам [React](https://react.dev/) значительно упрощает создание интерактивных пользовательских интерфейсов. Он может быть не таким дружелюбным для новичков, как [Vue](https://vuejs.org/), но он все еще наиболее широко используется, имеет больше возможностей и, что наиболее важно, тысячи дополнительных библиотек на выбор. _create-react-app_ также очень упрощает начало работы и включает в себя:
+
+- Поддержка синтаксиса React, JSX, ES6, TypeScript, Flow.
+- Дополнительные языковые возможности помимо ES6, такие как оператор расширения объекта.
+- Автоматически добавляемые префиксы в CSS, поэтому вам не понадобятся `-webkit-` или другие префиксы.
+- Быстрое интерактивное средство для запуска модульных тестов со встроенной поддержкой отчетов о покрытии.
+- Сервер для разработки в реальном времени, который предупреждает о распространенных ошибках.
+- Скрипт сборки для объединения JS, CSS и изображений для производственной среды с хэшами и картами исходного кода.
+
+В частности, _create-eth-app_ использует новые [эффекты хуков](https://legacy.reactjs.org/docs/hooks-effect.html). Это метод для написания мощных, но очень маленьких так называемых функциональных компонентов. См. раздел об Apollo ниже, чтобы узнать, как они используются в _create-eth-app_.
+
+### Yarn Workspaces {#yarn-workspaces}
+
+[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) позволяют иметь несколько пакетов, но при этом управлять ими всеми из корневой папки и устанавливать зависимости для всех сразу с помощью `yarn install`. Это особенно полезно для небольших дополнительных пакетов, таких как управление адресами/ABI умных контрактов (информация о том, где вы развернули какие умные контракты и как с ними взаимодействовать) или интеграция с The Graph, которые являются частью `create-eth-app`.
+
+### ethers.js {#ethersjs}
+
+Хотя [Web3](https://docs.web3js.org/) все еще используется чаще всего, [ethers.js](https://docs.ethers.io/) в последний год набирает популярность в качестве альтернативы, и именно он интегрирован в _create-eth-app_. Вы можете работать с ним, заменить его на Web3 или рассмотреть возможность обновления до [ethers.js v5](https://docs.ethers.org/v5/), который почти вышел из бета-версии.
+
+### The Graph {#the-graph}
+
+[GraphQL](https://graphql.org/) — это альтернативный способ обработки данных по сравнению с [RESTful API](https://restfulapi.net/). У них есть несколько преимуществ перед RESTful API, особенно для децентрализованных данных блокчейна. Если вас интересуют причины, ознакомьтесь со статьей [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a).
+
+Обычно вы получаете данные напрямую из своего умного контракта. Хотите узнать время последней сделки? Просто вызовите `MyContract.methods.latestTradeTime().call()`, который получает данные из узла Ethereum в ваше децентрализованное приложение. Но что, если вам нужны сотни разных точек данных? Это приведет к сотням запросов данных к узлу, каждый из которых требует [RTT](https://wikipedia.org/wiki/Round-trip_delay_time), что делает ваше децентрализованное приложение медленным и неэффективным. Одним из обходных путей может быть функция в вашем контракте, которая возвращает сразу несколько данных. Однако это не всегда идеально.
+
+Кроме того, вас могут заинтересовать исторические данные. Вы хотите знать не только время последней сделки, но и время всех сделок, которые вы когда-либо совершали сами. Используйте пакет подграфа _create-eth-app_, прочтите [документацию](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) и адаптируйте его к своим собственным контрактам. Если вы ищете популярные умные контракты, для них уже может существовать подграф. Ознакомьтесь с [обозревателем подграфов](https://thegraph.com/explorer/).
+
+Как только у вас появится подграф, вы сможете написать в своем децентрализованном приложении один простой запрос, который извлекает все важные данные блокчейна, включая исторические, и для этого потребуется всего один запрос.
+
+### Apollo {#apollo}
+
+Благодаря интеграции [Apollo Boost](https://www.apollographql.com/docs/react/get-started/) вы можете легко интегрировать The Graph в свое децентрализованное приложение на React. Особенно при использовании [хуков React и Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks) получение данных сводится к написанию одного GraphQL-запроса в вашем компоненте:
+
+```js
+const { loading, error, data } = useQuery(myGraphQlQuery)
+
+React.useEffect(() => {
+ if (!loading && !error && data) {
+ console.log({ data })
+ }
+}, [loading, error, data])
+```
+
+## Шаблоны {#templates}
+
+Кроме того, вы можете выбрать один из нескольких различных шаблонов. На данный момент вы можете использовать интеграцию с Aave, Compound, UniSwap или Sablier. Все они добавляют важные адреса умных контрактов сервисов вместе с готовыми интеграциями подграфов. Просто добавьте шаблон в команду создания, например: `yarn create eth-app my-eth-app --with-template aave`.
+
+### Aave {#aave}
+
+[Aave](https://aave.com/) — это децентрализованный рынок денежного кредитования. Вкладчики предоставляют ликвидность рынку для получения пассивного дохода, в то время как заемщики могут брать займы под залог. Одной из уникальных особенностей Aave являются [срочные займы](https://aave.com/docs/developers/flash-loans), которые позволяют вам брать деньги в долг без какого-либо залога, при условии, что вы вернете заем в рамках одной транзакции. Это может быть полезно, например, для получения дополнительных денежных средств при арбитражной торговле.
+
+Торгуемые токены, которые приносят вам проценты, называются _aTokens_.
+
+Когда вы решите интегрировать Aave с _create-eth-app_, вы получите [интеграцию подграфа](https://docs.aave.com/developers/getting-started/using-graphql). Aave использует The Graph и уже предоставляет несколько готовых к использованию подграфов в сетях [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) и [Mainnet](https://thegraph.com/explorer/subgraph/aave/protocol) в [необработанном](https://thegraph.com/explorer/subgraph/aave/protocol-raw) или [отформатированном](https://thegraph.com/explorer/subgraph/aave/protocol) виде.
+
+
+
+### Compound {#compound}
+
+[Compound](https://compound.finance/) похож на Aave. Интеграция уже включает в себя новый [подграф Compound v2](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195). Токены, приносящие проценты, здесь, как ни странно, называются _cTokens_.
+
+### Uniswap {#uniswap}
+
+[Uniswap](https://uniswap.exchange/) — это децентрализованная биржа (DEX). Поставщики ликвидности могут зарабатывать комиссии, предоставляя необходимые токены или эфир для обеих сторон сделки. Она широко используется и поэтому имеет одну из самых высоких ликвидностей для очень широкого спектра токенов. Вы можете легко интегрировать ее в свое децентрализованное приложение, чтобы, например, позволить пользователям обменивать свои ETH на DAI.
+
+К сожалению, на момент написания этой статьи интеграция доступна только для Uniswap v1, а не для [только что выпущенной v2](https://uniswap.org/blog/uniswap-v2/).
+
+### Sablier {#sablier}
+
+[Sablier](https://sablier.com/) позволяет пользователям осуществлять потоковые денежные платежи. Вместо одного дня выплаты вы фактически получаете деньги постоянно без дополнительного администрирования после первоначальной настройки. Интеграция включает в себя [собственный подграф](https://thegraph.com/explorer/subgraph/sablierhq/sablier).
+
+## Что дальше? {#whats-next}
+
+Если у вас есть вопросы о _create-eth-app_, зайдите на [сервер сообщества Sablier](https://discord.gg/bsS8T47), где вы сможете связаться с авторами _create-eth-app_. В качестве следующих шагов вы можете интегрировать фреймворк пользовательского интерфейса, например [Material UI](https://mui.com/material-ui/), написать GraphQL-запросы для данных, которые вам действительно нужны, и настроить развертывание.
diff --git a/public/content/translations/ru/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md b/public/content/translations/ru/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md
new file mode 100644
index 00000000000..3e521b4c319
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md
@@ -0,0 +1,269 @@
+---
+title: "Изучите основные темы Ethereum с помощью SQL"
+description: "Это руководство помогает читателям понять основополагающие концепции Ethereum, включая транзакции, блоки и газ, путем запроса он-чейн данных с помощью языка структурированных запросов (SQL)."
+author: "Paul Apivat"
+tags: [ "SQL", "Запросы", "Транзакции" ]
+skill: beginner
+lang: ru
+published: 2021-05-11
+source: paulapivat.com
+sourceUrl: https://paulapivat.com/post/query_ethereum/
+---
+
+Многие руководства по Ethereum предназначены для разработчиков, но не хватает образовательных ресурсов для аналитиков данных или для людей, которые хотят видеть он-чейн данные без запуска клиента или узла.
+
+Это руководство помогает читателям понять основополагающие концепции Ethereum, включая транзакции, блоки и газ, путем запроса он-чейн данных с помощью языка структурированных запросов (SQL) через интерфейс, предоставляемый [Dune Analytics](https://dune.com/).
+
+Он-чейн данные могут помочь нам понять Ethereum как сеть и как экономику вычислительной мощности, а также должны служить основой для понимания проблем, с которыми сегодня сталкивается Ethereum (например, растущие цены на газ), и, что более важно, обсуждений решений по масштабированию.
+
+### Транзакции {#transactions}
+
+Путь пользователя в Ethereum начинается с инициализации управляемого пользователем аккаунта или сущности с балансом ETH. Существует два типа аккаунтов: управляемый пользователем или смарт-контракт (см. [ethereum.org](/developers/docs/accounts/)).
+
+Любой аккаунт можно просмотреть в обозревателе блоков, таком как [Etherscan](https://etherscan.io/) или [Blockscout](https://eth.blockscout.com/). Обозреватели блоков — это портал к данным Ethereum. Они отображают в реальном времени данные о блоках, транзакциях, майнерах, аккаунтах и другой он-чейн активности (см. [здесь](/developers/docs/data-and-analytics/block-explorers/)).
+
+Однако пользователь может захотеть запросить данные напрямую для сверки информации, предоставляемой внешними обозревателями блоков. [Dune Analytics](https://dune.com/) предоставляет эту возможность любому, кто имеет некоторые знания SQL.
+
+Для справки: аккаунт смарт-контракта Ethereum Foundation (EF) можно просмотреть на [Blockscout](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe).
+
+Следует отметить, что все аккаунты, включая аккаунт EF, имеют публичный адрес, который можно использовать для отправки и получения транзакций.
+
+Баланс аккаунта на Etherscan включает в себя обычные и внутренние транзакции. Внутренние транзакции, несмотря на название, не являются _настоящими_ транзакциями, которые изменяют состояние цепи. Это переводы средств, инициированные выполнением контракта ([источник](https://ethereum.stackexchange.com/questions/3417/how-to-get-contract-internal-transactions)). Поскольку внутренние транзакции не имеют подписи, они **не** включаются в блокчейн и не могут быть запрошены с помощью Dune Analytics.
+
+Поэтому это руководство будет посвящено обычным транзакциям. Это можно запросить следующим образом:
+
+```sql
+WITH temp_table AS (
+SELECT
+ hash,
+ block_number,
+ block_time,
+ "from",
+ "to",
+ value / 1e18 AS ether,
+ gas_used,
+ gas_price / 1e9 AS gas_price_gwei
+FROM ethereum."transactions"
+WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
+ORDER BY block_time DESC
+)
+SELECT
+ hash,
+ block_number,
+ block_time,
+ "from",
+ "to",
+ ether,
+ (gas_used * gas_price_gwei) / 1e9 AS txn_fee
+FROM temp_table
+```
+
+Это даст ту же информацию, что и на странице транзакций Etherscan. Для сравнения, вот два источника:
+
+#### Etherscan {#etherscan}
+
+
+
+[Страница контракта EF на Blockscout.](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe)
+
+#### Dune Analytics {#dune-analytics}
+
+
+
+Вы можете найти панель управления [здесь](https://dune.com/paulapivat/Learn-Ethereum). Нажмите на таблицу, чтобы увидеть запрос (также см. выше).
+
+### Разбор транзакций {#breaking_down_transactions}
+
+Отправленная транзакция включает в себя несколько частей информации, в том числе ([источник](/developers/docs/transactions/)):
+
+- **Получатель**: адрес получателя (запрашивается как "to")
+- **Подпись**: хотя приватный ключ отправителя подписывает транзакцию, с помощью SQL мы можем запросить публичный адрес отправителя ("from").
+- **Значение**: это количество переданных ETH (см. столбец `ether`).
+- **Данные**: это произвольные данные, которые были хэшированы (см. столбец `data`)
+- **gasLimit** — максимальное количество единиц газа, которое может быть использовано транзакцией. Единицы газа представляют собой вычислительные шаги
+- **maxPriorityFeePerGas** — максимальное количество газа, которое можно использовать в качестве награды для майнера
+- **maxFeePerGas** — максимальное количество газа, которое будет выплачено за транзакцию (включая baseFeePerGas и maxPriorityFeePerGas)
+
+Мы можем запросить эти конкретные части информации для транзакций на публичный адрес Ethereum Foundation:
+
+```sql
+SELECT
+ "to",
+ "from",
+ value / 1e18 AS ether,
+ data,
+ gas_limit,
+ gas_price / 1e9 AS gas_price_gwei,
+ gas_used,
+ ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
+FROM ethereum."transactions"
+WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
+ORDER BY block_time DESC
+```
+
+### Блоки {#blocks}
+
+Каждая транзакция изменяет состояние виртуальной машины Ethereum ([EVM](/developers/docs/evm/)) ([источник](/developers/docs/transactions/)). Транзакции транслируются в сеть для проверки и включения в блок. Каждая транзакция связана с номером блока. Чтобы увидеть данные, мы можем запросить конкретный номер блока: 12396854 (самый последний блок среди транзакций Ethereum Foundation на момент написания статьи, 11/5/21).
+
+Более того, когда мы запрашиваем следующие два блока, мы видим, что каждый блок содержит хэш предыдущего блока (т. е. родительский хэш), что иллюстрирует, как формируется блокчейн.
+
+Каждый блок содержит ссылку на родительский блок. Это показано ниже между столбцами `hash` и `parent_hash` ([источник](/developers/docs/blocks/)):
+
+
+
+Вот [запрос](https://dune.com/queries/44856/88292) в Dune Analytics:
+
+```sql
+SELECT
+ time,
+ number,
+ hash,
+ parent_hash,
+ nonce
+FROM ethereum."blocks"
+WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
+LIMIT 10
+```
+
+Мы можем изучить блок, запросив время, номер блока, сложность, хэш, родительский хэш и nonce.
+
+Единственное, что этот запрос не охватывает, это _список транзакций_, который требует отдельного запроса ниже, и _корень состояния_. Полный или архивный узел будет хранить все транзакции и переходы состояний, позволяя клиентам запрашивать состояние цепи в любой момент времени. Поскольку это требует большого дискового пространства, мы можем отделить данные цепи от данных о состоянии:
+
+- Данные цепи (список блоков, транзакций)
+- Данные о состоянии (результат перехода состояния каждой транзакции)
+
+Корень состояния относится ко второму типу и является _неявными_ данными (не хранится он-чейн), в то время как данные цепи являются явными и хранятся в самой цепи ([источник](https://ethereum.stackexchange.com/questions/359/where-is-the-state-data-stored)).
+
+В этом руководстве мы сосредоточимся на он-чейн данных, которые _можно_ запрашивать с помощью SQL через Dune Analytics.
+
+Как указано выше, каждый блок содержит список транзакций, и мы можем запросить его, отфильтровав по конкретному блоку. Попробуем самый последний блок, 12396854:
+
+```sql
+SELECT * FROM ethereum."transactions"
+WHERE block_number = 12396854
+ORDER BY block_time DESC`
+```
+
+Вот вывод SQL в Dune:
+
+
+
+Добавление этого одного блока в цепь изменяет состояние виртуальной машины Ethereum ([EVM](/developers/docs/evm/)). За раз проверяются десятки, а иногда и сотни транзакций. В этом конкретном случае было включено 222 транзакции.
+
+Чтобы увидеть, сколько из них были действительно успешными, мы добавим еще один фильтр для подсчета успешных транзакций:
+
+```sql
+WITH temp_table AS (
+ SELECT * FROM ethereum."transactions"
+ WHERE block_number = 12396854 AND success = true
+ ORDER BY block_time DESC
+)
+SELECT
+ COUNT(success) AS num_successful_txn
+FROM temp_table
+```
+
+Для блока 12396854 из 222 транзакций 204 были успешно проверены:
+
+
+
+Запросы на транзакции происходят десятки раз в секунду, но блоки фиксируются примерно раз в 15 секунд ([источник](/developers/docs/blocks/)).
+
+Чтобы убедиться, что один блок создается примерно каждые 15 секунд, мы можем взять количество секунд в дне (86 400) и разделить на 15, чтобы получить примерное среднее количество блоков в день (~ 5760).
+
+График созданных блоков Ethereum в день (с 2016 г. по настоящее время):
+
+
+
+Среднее количество блоков, создаваемых ежедневно за этот период, составляет ~5874:
+
+
+
+Запросы:
+
+```sql
+# запрос для визуализации количества блоков, создаваемых ежедневно с 2016 года
+
+SELECT
+ DATE_TRUNC('day', time) AS dt,
+ COUNT(*) AS block_count
+FROM ethereum."blocks"
+GROUP BY dt
+OFFSET 1
+
+# среднее количество блоков, создаваемых в день
+
+WITH temp_table AS (
+SELECT
+ DATE_TRUNC('day', time) AS dt,
+ COUNT(*) AS block_count
+FROM ethereum."blocks"
+GROUP BY dt
+OFFSET 1
+)
+SELECT
+ AVG(block_count) AS avg_block_count
+FROM temp_table
+```
+
+Среднее количество блоков, создаваемых в день с 2016 года, немного превышает это число и составляет 5874. С другой стороны, деление 86 400 секунд на 5874 (среднее количество блоков) дает 14,7 секунды, или примерно один блок каждые 15 секунд.
+
+### Газ {#gas}
+
+Размер блоков ограничен. Максимальный размер блока динамичен и варьируется в зависимости от спроса в сети от 12 500 000 до 25 000 000 единиц. Ограничения необходимы, чтобы предотвратить произвольно большие размеры блоков, создающие нагрузку на полные узлы с точки зрения требований к дисковому пространству и скорости ([источник](/developers/docs/blocks/)).
+
+Один из способов осмыслить лимит газа блока — это думать о нем как о **предложении** доступного пространства в блоке, в котором можно пакетировать транзакции. Лимит газа блока можно запросить и визуализировать с 2016 года по сегодняшний день:
+
+
+
+```sql
+SELECT
+ DATE_TRUNC('day', time) AS dt,
+ AVG(gas_limit) AS avg_block_gas_limit
+FROM ethereum."blocks"
+GROUP BY dt
+OFFSET 1
+```
+
+Затем есть фактический газ, используемый ежедневно для оплаты вычислений, выполняемых в цепи Ethereum (т. е. отправка транзакции, вызов смарт-контракта, минтинг NFT). Это **спрос** на доступное пространство в блоках Ethereum:
+
+
+
+```sql
+SELECT
+ DATE_TRUNC('day', time) AS dt,
+ AVG(gas_used) AS avg_block_gas_used
+FROM ethereum."blocks"
+GROUP BY dt
+OFFSET 1
+```
+
+Мы также можем сопоставить эти два графика, чтобы увидеть, как соотносятся **спрос и предложение**:
+
+
+
+Таким образом, мы можем понимать цены на газ как функцию спроса на пространство в блоках Ethereum, учитывая имеющееся предложение.
+
+Наконец, мы можем захотеть запросить средние дневные цены на газ для цепи Ethereum, однако это приведет к особенно долгому времени выполнения запроса, поэтому мы отфильтруем наш запрос до среднего количества газа, уплаченного за транзакцию Ethereum Foundation.
+
+
+
+Мы можем видеть цены на газ, уплаченные за все транзакции, сделанные на адрес Ethereum Foundation за эти годы. Вот запрос:
+
+```sql
+SELECT
+ block_time,
+ gas_price / 1e9 AS gas_price_gwei,
+ value / 1e18 AS eth_sent
+FROM ethereum."transactions"
+WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
+ORDER BY block_time DESC
+```
+
+### Сводка {#summary}
+
+С помощью этого руководства мы поняли основополагающие концепции Ethereum и то, как работает блокчейн Ethereum, запрашивая и знакомясь с он-чейн данными.
+
+Панель управления, содержащая весь код, использованный в этом руководстве, находится [здесь](https://dune.com/paulapivat/Learn-Ethereum).
+
+Чтобы узнать больше об использовании данных для изучения Web3, [найдите меня в Twitter](https://twitter.com/paulapivat).
diff --git a/public/content/translations/ru/developers/tutorials/logging-events-smart-contracts/index.md b/public/content/translations/ru/developers/tutorials/logging-events-smart-contracts/index.md
new file mode 100644
index 00000000000..60a34746ff4
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/logging-events-smart-contracts/index.md
@@ -0,0 +1,42 @@
+---
+title: "Регистрация данных из умных контрактов с помощью событий"
+description: "Введение в события умных контрактов и способы их использования для регистрации данных."
+author: "jdourlens"
+tags: [ "Умные контракты", "Remix", "Solidity", "события" ]
+skill: intermediate
+lang: ru
+published: 2020-04-03
+source: EthereumDev
+sourceUrl: https://ethereumdev.io/logging-data-with-events/
+address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+---
+
+В Solidity [события](/developers/docs/smart-contracts/anatomy/#events-and-logs) — это отправляемые сигналы, которые могут инициировать умные контракты. Децентрализованные приложения или все, что подключено к Ethereum JSON-RPC API, могут прослушивать эти события и действовать соответствующим образом. Событие также можно индексировать, чтобы в дальнейшем можно было осуществлять поиск по истории событий.
+
+## События {#events}
+
+Наиболее распространенным событием в блокчейне Ethereum на момент написания этой статьи является событие Transfer, которое генерируется токенами ERC20, когда кто-то переводит токены.
+
+```solidity
+event Transfer(address indexed from, address indexed to, uint256 value);
+```
+
+Сигнатура события объявляется внутри кода контракта и может быть вызвана с помощью ключевого слова emit. Например, событие transfer регистрирует, кто отправил перевод (_from_), кому (_to_) и сколько токенов было переведено (_value_).
+
+Если мы вернемся к нашему умному контракту Counter и решим регистрировать каждое изменение значения. Поскольку этот контракт не предназначен для развертывания, а служит основой для создания другого контракта путем его расширения, он называется абстрактным контрактом. В случае с нашим примером счетчика это будет выглядеть так:
+
+```solidity
+pragma solidity 0.5.17;\n\ncontract Counter {\n\n event ValueChanged(uint oldValue, uint256 newValue);\n\n // Приватная переменная типа unsigned int для хранения количества подсчетов\n uint256 private count = 0;\n\n // Функция, которая увеличивает наш счетчик\n function increment() public {\n count += 1;\n emit ValueChanged(count - 1, count);\n }\n\n // Геттер для получения значения счетчика\n function getCount() public view returns (uint256) {\n return count;\n }\n\n}
+```
+
+Обратите внимание:
+
+- **Строка 5**: мы объявляем наше событие и то, что оно содержит: старое и новое значение.
+
+- **Строка 13**: когда мы увеличиваем нашу переменную count, мы генерируем событие.
+
+Если мы сейчас развернем контракт и вызовем функцию increment, мы увидим, что Remix автоматически отобразит его, если вы нажмете на новую транзакцию в массиве с именем logs.
+
+
+
+Логи очень полезны для отладки ваших умных контрактов, но они также важны, если вы создаете приложения, используемые разными людьми. Они облегчают аналитику для отслеживания и понимания того, как используется ваш умный контракт. Логи, сгенерированные транзакциями, отображаются в популярных инструментах изучения блоков, и вы также можете, например, использовать их для создания офф-чейн скриптов для прослушивания определенных событий и принятия мер при их возникновении.
diff --git a/public/content/translations/ru/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/ru/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md
new file mode 100644
index 00000000000..73d23dc8e47
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md
@@ -0,0 +1,252 @@
+---
+title: "Доказательства Меркла для целостности офлайн-данных"
+description: "Обеспечение целостности ончейн-данных для данных, которые хранятся преимущественно оффчейн"
+author: Ori Pomerantz
+tags: [ "хранилище" ]
+skill: advanced
+lang: ru
+published: 2021-12-30
+---
+
+## Введение {#introduction}
+
+В идеале мы хотели бы хранить все в месте хранения Ethereum, которое распределено по тысячам компьютеров и обладает
+чрезвычайно высокой доступностью (данные не могут быть подвергнуты цензуре) и целостностью (данные не могут быть изменены
+несанкционированным образом), но хранение 32-байтового слова обычно стоит 20 000 единиц газа. На момент написания этой статьи эта стоимость
+эквивалентна 6,60 долларам США. При цене 21 цент за байт это слишком дорого для многих вариантов использования.
+
+Для решения этой проблемы экосистема Ethereum разработала множество альтернативных способов хранения данных децентрализованным
+образом. Обычно они предполагают компромисс между доступностью
+и ценой. Однако целостность обычно гарантируется.
+
+В этой статье вы узнаете, **как** обеспечить целостность данных, не храня их в блокчейне, с помощью
+[доказательств Меркла](https://computersciencewiki.org/index.php/Merkle_proof).
+
+## Как это работает? {#how-does-it-work}
+
+Теоретически мы могли бы просто хранить хэш данных в сети (он-чейн) и отправлять все данные в требующих их транзакциях. Однако это все еще слишком дорого. Байт данных в транзакции стоит около 16 единиц газа, что в настоящее время составляет около половины цента или около 5 долларов за килобайт. При цене 5000 долларов за мегабайт это все еще слишком дорого для многих вариантов использования, даже без учета дополнительных затрат на хэширование данных.
+
+Решение заключается в многократном хэшировании различных подмножеств данных, поэтому для данных, которые вам не нужно отправлять, вы можете просто отправить хэш. Это делается с помощью дерева Меркла, древовидной структуры данных, в которой каждый узел представляет собой хэш узлов, расположенных под ним:
+
+
+
+Корневой хэш — единственная часть, которую необходимо хранить в сети (он-чейн). Чтобы доказать определенное значение, вы предоставляете все хэши, которые необходимо объединить с ним для получения корневого хэша. Например, чтобы доказать `C`, вы предоставляете `D`, `H(A-B)` и `H(E-H)`.
+
+
+
+## Реализация {#implementation}
+
+[Пример кода приведен здесь](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity).
+
+### Код вне сети (офф-чейн) {#offchain-code}
+
+В этой статье мы используем JavaScript для вычислений вне сети (офф-чейн). Большинство децентрализованных приложений имеют свой компонент вне сети (офф-чейн), написанный на JavaScript.
+
+#### Создание корня Меркла {#creating-the-merkle-root}
+
+Сначала нам нужно предоставить корень Меркла в сеть.
+
+```javascript
+const ethers = require("ethers")
+```
+
+[Мы используем хэш-функцию из пакета ethers](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256).
+
+```javascript
+// Необработанные данные, целостность которых мы должны проверить. Первые два байта
+// — это идентификатор пользователя, а последние два байта — количество токенов, которыми
+// пользователь владеет в настоящее время.
+const dataArray = [
+ 0x0bad0010, 0x60a70020, 0xbeef0030, 0xdead0040, 0xca110050, 0x0e660060,
+ 0xface0070, 0xbad00080, 0x060d0091,
+]
+```
+
+Кодирование каждой записи в одно 256-битное целое число приводит к менее читаемому коду, чем, например, при использовании JSON. Однако это означает значительно меньшую обработку для извлечения данных в контракте и, следовательно, гораздо более низкие затраты на газ. [Вы можете считывать JSON в сети (он-чейн)](https://github.com/chrisdotn/jsmnSol), но это плохая идея, если этого можно избежать.
+
+```javascript
+// Массив хэш-значений в виде BigInts
+const hashArray = dataArray
+```
+
+В данном случае наши данные изначально представляют собой 256-битные значения, поэтому обработка не требуется. Если мы используем более сложную структуру данных, например строки, нам нужно сначала хэшировать данные, чтобы получить массив хэшей. Обратите внимание, что это также связано с тем, что нам неважно, знают ли пользователи информацию о других пользователях. В противном случае нам пришлось бы выполнить хэширование, чтобы пользователь 1 не знал значение для пользователя 0, пользователь 2 не знал значение для пользователя 3 и т. д.
+
+```javascript
+// Преобразование между строкой, которую ожидает хэш-функция, и
+// BigInt, который мы используем во всем остальном коде.
+const hash = (x) =>
+ BigInt(ethers.utils.keccak256("0x" + x.toString(16).padStart(64, 0)))
+```
+
+Хэш-функция ethers ожидает получить строку JavaScript с шестнадцатеричным числом, например `0x60A7`, и возвращает другую строку с той же структурой. Однако для остальной части кода проще использовать `BigInt`, поэтому мы преобразуем его в шестнадцатеричную строку и обратно.
+
+```javascript
+// Симметричный хэш пары, поэтому нам неважно, обратный ли порядок.
+const pairHash = (a, b) => hash(hash(a) ^ hash(b))
+```
+
+Эта функция симметрична (хэш от a [xor](https://en.wikipedia.org/wiki/Exclusive_or) b). Это означает, что при проверке доказательства Меркла нам не нужно беспокоиться о том, ставить ли значение из доказательства до или после вычисленного значения. Проверка доказательства Меркла выполняется в сети (он-чейн), поэтому чем меньше нам нужно там делать, тем лучше.
+
+Предупреждение:
+Криптография сложнее, чем кажется.
+В первоначальной версии этой статьи была хэш-функция `hash(a^b)`.
+Это была **плохая** идея, поскольку она означала, что если вы знаете допустимые значения `a` и `b`, вы можете использовать `b' = a^b^a'`, чтобы доказать любое желаемое значение `a'`.
+С этой функцией вам пришлось бы вычислять `b'` так, чтобы `hash(a') ^ hash(b')` равнялось известному значению (следующей ветви на пути к корню), что намного сложнее.
+
+```javascript
+// Значение, обозначающее, что определенная ветвь пуста, то есть
+// не имеет значения
+const empty = 0n
+```
+
+Когда количество значений не является целой степенью двойки, нам нужно обрабатывать пустые ветви. Эта программа делает это, используя ноль в качестве заполнителя.
+
+
+
+```javascript
+// Вычислить один уровень вверх по дереву массива хэшей, взяв хэш
+// каждой пары в последовательности
+const oneLevelUp = (inputArray) => {
+ var result = []
+ var inp = [...inputArray] // Чтобы избежать перезаписи входных данных // При необходимости добавьте пустое значение (нам нужно, чтобы все листья были // объединены в пары)
+
+ if (inp.length % 2 === 1) inp.push(empty)
+
+ for (var i = 0; i < inp.length; i += 2)
+ result.push(pairHash(inp[i], inp[i + 1]))
+
+ return result
+} // oneLevelUp
+```
+
+Эта функция «поднимается» на один уровень в дереве Меркла путем хэширования пар значений на текущем слое. Обратите внимание, что это не самая эффективная реализация. Мы могли бы избежать копирования входных данных и просто добавлять `hashEmpty` в цикле, где это необходимо, но этот код оптимизирован для удобочитаемости.
+
+```javascript
+const getMerkleRoot = (inputArray) => {
+ var result
+
+ result = [...inputArray] // Поднимаемся по дереву до тех пор, пока не останется только одно значение, которое и является // корнем. // // Если слой содержит нечетное количество записей, // код в oneLevelUp добавляет пустое значение, поэтому, если у нас, например, // 10 листьев, то на втором слое будет 5 ветвей, 3 // ветви на третьем, 2 на четвертом и корень на пятом
+
+ while (result.length > 1) result = oneLevelUp(result)
+
+ return result[0]
+}
+```
+
+Чтобы получить корень, поднимайтесь вверх, пока не останется только одно значение.
+
+#### Создание доказательства Меркла {#creating-a-merkle-proof}
+
+Доказательство Меркла — это значения, которые необходимо хэшировать вместе с доказываемым значением, чтобы получить корень Меркла. Доказываемое значение часто доступно из других данных, поэтому я предпочитаю предоставлять его отдельно, а не как часть кода.
+
+```javascript
+// Доказательство Меркла состоит из списка значений, которые нужно
+// хэшировать. Поскольку мы используем симметричную хэш-функцию, для проверки
+// доказательства нам не требуется позиция элемента, она нужна только для его создания.
+const getMerkleProof = (inputArray, n) => {
+ var result = [], currentLayer = [...inputArray], currentN = n
+
+ // Пока не достигнем вершины
+ while (currentLayer.length > 1) {
+ // Не допускаются слои нечетной длины
+ if (currentLayer.length % 2)
+ currentLayer.push(empty)
+
+ result.push(currentN % 2
+ // Если currentN нечетное, добавить в доказательство значение перед ним
+ ? currentLayer[currentN-1]
+ // Если четное, добавить значение после него
+ : currentLayer[currentN+1])
+
+```
+
+Мы хэшируем `(v[0],v[1])`, `(v[2],v[3])` и т. д. Так, для четных значений нам нужно следующее, а для нечетных — предыдущее.
+
+```javascript
+ // Переход на следующий слой вверх
+ currentN = Math.floor(currentN/2)
+ currentLayer = oneLevelUp(currentLayer)
+ } // пока currentLayer.length > 1
+
+ return result
+} // getMerkleProof
+```
+
+### Код в сети (он-чейн) {#onchain-code}
+
+Наконец, у нас есть код, который проверяет доказательство. Код в сети (он-чейн) написан на [Solidity](https://docs.soliditylang.org/en/v0.8.11/). Здесь оптимизация гораздо важнее, потому что газ относительно дорог.
+
+```solidity
+//SPDX-License-Identifier: Public Domain
+pragma solidity ^0.8.0;
+
+import "hardhat/console.sol";
+```
+
+Я написал это с помощью [среды разработки Hardhat](https://hardhat.org/), которая позволяет нам получать [вывод консоли из Solidity](https://hardhat.org/docs/cookbook/debug-logs) во время разработки.
+
+```solidity
+
+contract MerkleProof {
+ uint merkleRoot;
+
+ function getRoot() public view returns (uint) {
+ return merkleRoot;
+ }
+
+ // Крайне небезопасно, в рабочем коде доступ к
+ // этой функции ДОЛЖЕН БЫТЬ строго ограничен, вероятно, только для
+ // владельца
+ function setRoot(uint _merkleRoot) external {
+ merkleRoot = _merkleRoot;
+ } // setRoot
+```
+
+Функции установки и получения для корня Меркла. Разрешение всем обновлять корень Меркла — _крайне плохая идея_ в производственной системе. Я делаю это здесь для простоты примера кода. **Не делайте этого в системе, где целостность данных действительно важна**.
+
+```solidity
+ function hash(uint _a) internal pure returns(uint) {
+ return uint(keccak256(abi.encode(_a)));
+ }
+
+ function pairHash(uint _a, uint _b) internal pure returns(uint) {
+ return hash(hash(_a) ^ hash(_b));
+ }
+```
+
+Эта функция генерирует хэш пары. Это просто перевод кода JavaScript для `hash` и `pairHash` на Solidity.
+
+**Примечание:** это еще один случай оптимизации для удобочитаемости. Основываясь на [определении функции](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm), возможно, можно хранить данные как значение [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) и избежать преобразований.
+
+```solidity
+ // Проверка доказательства Меркла
+ function verifyProof(uint _value, uint[] calldata _proof)
+ public view returns (bool) {
+ uint temp = _value;
+ uint i;
+
+ for(i=0; i<_proof.length; i++) {
+ temp = pairHash(temp, _proof[i]);
+ }
+
+ return temp == merkleRoot;
+ }
+
+} // MarkleProof
+```
+
+В математической нотации проверка доказательства Меркла выглядит так: `H(proof_n, H(proof_n-1, H(proof_n-2, ...` H(proof_1, H(proof_0, value))...)))`. Этот код реализует это.
+
+## Доказательства Меркла и ролл-апы несовместимы {#merkle-proofs-and-rollups}
+
+Доказательства Меркла плохо работают с [ролл-апами](/developers/docs/scaling/#rollups). Причина в том, что ролл-апы записывают все данные транзакций на уровне L1, но обрабатывают их на L2. Стоимость отправки доказательства Меркла с транзакцией составляет в среднем 638 единиц газа на слой (в настоящее время байт в данных вызова стоит 16 единиц газа, если он не равен нулю, и 4, если он равен нулю). Если у нас есть 1024 слова данных, доказательство Меркла потребует десять слоев, или в общей сложности 6380 единиц газа.
+
+На примере [Optimism](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m) можно увидеть, что запись газа на L1 стоит около 100 gwei, а газ на L2 — 0,001 gwei (это обычная цена, которая может расти при перегрузках). Таким образом, за стоимость одной единицы газа L1 мы можем потратить сто тысяч единиц газа на обработку L2. Если предположить, что мы не перезаписываем хранилище, это означает, что мы можем записать около пяти слов в хранилище на L2 по цене одной единицы газа L1. Для одного доказательства Меркла мы можем записать все 1024 слова в хранилище (при условии, что они могут быть вычислены в сети (он-чейн) с самого начала, а не предоставлены в транзакции), и при этом у нас останется большая часть газа.
+
+## Заключение {#conclusion}
+
+В реальной жизни вам, возможно, никогда не придется реализовывать деревья Меркла самостоятельно. Существуют хорошо известные и проверенные библиотеки, которые можно использовать, и, вообще говоря, лучше не реализовывать криптографические примитивы самостоятельно. Но я надеюсь, что теперь вы лучше понимаете доказательства Меркла и можете решить, когда их стоит использовать.
+
+Обратите внимание, что, хотя доказательства Меркла сохраняют _целостность_, они не сохраняют _доступность_. Знание того, что никто другой не может забрать ваши активы, — слабое утешение, если хранилище данных решит запретить доступ и вы также не сможете построить дерево Меркла для доступа к ним. Поэтому деревья Меркла лучше всего использовать с каким-либо децентрализованным хранилищем, например IPFS.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md b/public/content/translations/ru/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md
new file mode 100644
index 00000000000..38bd67080ff
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md
@@ -0,0 +1,151 @@
+---
+title: "Мониторинг Geth с помощью InfluxDB и Grafana"
+description: "Настройте мониторинг для своего узла Geth с помощью InfluxDB и Grafana, чтобы отслеживать производительность и выявлять проблемы."
+author: "Mario Havel"
+tags: [ "клиенты", "узлы" ]
+skill: intermediate
+lang: ru
+published: 2021-01-13
+---
+
+Это руководство поможет вам настроить мониторинг для своего узла Geth, чтобы вы могли лучше понимать его производительность и выявлять потенциальные проблемы.
+
+## Предварительные условия {#prerequisites}
+
+- У вас уже должен быть запущен экземпляр Geth.
+- Большинство шагов и примеров предназначены для среды Linux, поэтому будут полезны базовые знания о работе с терминалом.
+- Посмотрите этот видеообзор набора метрик Geth: [Мониторинг инфраструктуры Ethereum от Петера Силадьи](https://www.youtube.com/watch?v=cOBab8IJMYI).
+
+## Стек мониторинга {#monitoring-stack}
+
+Клиент Ethereum собирает множество данных, которые можно прочитать в виде хронологической базы данных. Чтобы упростить мониторинг, вы можете передать эти данные в программное обеспечение для визуализации. Доступно несколько вариантов:
+
+- [Prometheus](https://prometheus.io/) (модель извлечения)
+- [InfluxDB](https://www.influxdata.com/get-influxdb/) (модель передачи)
+- [Telegraf](https://www.influxdata.com/get-influxdb/)
+- [Grafana](https://www.grafana.com/)
+- [Datadog](https://www.datadoghq.com/)
+- [Chronograf](https://www.influxdata.com/time-series-platform/chronograf/)
+
+Также есть [Geth Prometheus Exporter](https://github.com/hunterlong/gethexporter) — вариант, предварительно настроенный для InfluxDB и Grafana.
+
+В этом руководстве мы настроим ваш клиент Geth для передачи данных в InfluxDB, чтобы создать базу данных, и Grafana для создания графической визуализации данных. Выполнение этой операции вручную поможет вам лучше понять процесс, изменить его и развернуть в различных средах.
+
+## Настройка InfluxDB {#setting-up-influxdb}
+
+Сначала скачаем и установим InfluxDB. Различные варианты загрузки можно найти на [странице релизов Influxdata](https://portal.influxdata.com/downloads/). Выберите тот, который подходит для вашей среды.
+Вы также можете установить его из [репозитория](https://repos.influxdata.com/). Например, в дистрибутиве на базе Debian:
+
+```
+curl -tlsv1.3 --proto =https -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add
+source /etc/lsb-release
+echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
+sudo apt update
+sudo apt install influxdb -y
+sudo systemctl enable influxdb
+sudo systemctl start influxdb
+sudo apt install influxdb-client
+```
+
+После успешной установки InfluxDB убедитесь, что он работает в фоновом режиме. По умолчанию он доступен по адресу `localhost:8086`.
+Перед использованием клиента `influx` вы должны создать нового пользователя с правами администратора. Этот пользователь будет использоваться для управления высокого уровня, создания баз данных и пользователей.
+
+```
+curl -XPOST "http://localhost:8086/query" --data-urlencode "q=CREATE USER username WITH PASSWORD 'password' WITH ALL PRIVILEGES"
+```
+
+Теперь вы можете использовать клиент influx для входа в [оболочку InfluxDB](https://docs.influxdata.com/influxdb/v1.8/tools/shell/) с этим пользователем.
+
+```
+influx -username 'username' -password 'password'
+```
+
+Взаимодействуя с InfluxDB напрямую в его оболочке, вы можете создать базу данных и пользователя для метрик geth.
+
+```
+create database geth
+create user geth with password choosepassword
+```
+
+Проверьте созданные записи с помощью:
+
+```
+show databases
+show users
+```
+
+Выйдите из оболочки InfluxDB.
+
+```
+exit
+```
+
+InfluxDB запущен и настроен для хранения метрик из Geth.
+
+## Подготовка Geth {#preparing-geth}
+
+После настройки базы данных необходимо включить сбор метрик в Geth. Обратите внимание на `METRICS AND STATS OPTIONS` в `geth --help`. Там можно найти несколько опций, в данном случае мы хотим, чтобы Geth передавал данные в InfluxDB.
+Базовая настройка указывает конечную точку, по которой доступен InfluxDB, и аутентификацию для базы данных.
+
+```
+geth --metrics --metrics.influxdb --metrics.influxdb.endpoint "http://0.0.0.0:8086" --metrics.influxdb.username "geth" --metrics.influxdb.password "chosenpassword"
+```
+
+Эти флаги можно добавить к команде, запускающей клиент, или сохранить в файле конфигурации.
+
+Вы можете убедиться, что Geth успешно передает данные, например, выведя список метрик в базе данных. В оболочке InfluxDB:
+
+```
+use geth
+show measurements
+```
+
+## Настройка Grafana {#setting-up-grafana}
+
+Следующий шаг — установка Grafana, которая будет интерпретировать данные графически. Следуйте процессу установки для вашей среды в документации Grafana. Убедитесь, что вы устанавливаете версию OSS, если не хотите иного.
+Пример шагов установки для дистрибутивов Debian с использованием репозитория:
+
+```
+curl -tlsv1.3 --proto =https -sL https://packages.grafana.com/gpg.key | sudo apt-key add -
+echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
+sudo apt update
+sudo apt install grafana
+sudo systemctl enable grafana-server
+sudo systemctl start grafana-server
+```
+
+Когда Grafana будет запущена, она должна быть доступна по адресу `localhost:3000`.
+Используйте предпочитаемый браузер для доступа к этому пути, затем войдите в систему с учетными данными по умолчанию (пользователь: `admin` и пароль: `admin`). При появлении запроса измените пароль по умолчанию и сохраните.
+
+
+
+Вы будете перенаправлены на домашнюю страницу Grafana. Сначала настройте источник данных. Нажмите на значок конфигурации на левой панели и выберите "Источники данных".
+
+
+
+Источники данных еще не созданы, нажмите "Добавить источник данных", чтобы определить один.
+
+
+
+Для этой настройки выберите "InfluxDB" и продолжайте.
+
+
+
+Конфигурация источника данных довольно проста, если вы запускаете инструменты на одной и той же машине. Вам нужно указать адрес InfluxDB и данные для доступа к базе данных. Обратитесь к изображению ниже.
+
+
+
+Если все заполнено и InfluxDB доступен, нажмите "Сохранить и протестировать" и дождитесь появления подтверждения.
+
+
+
+Теперь Grafana настроена на чтение данных из InfluxDB. Теперь вам нужно создать панель мониторинга, которая будет интерпретировать и отображать данные. Свойства панелей мониторинга кодируются в JSON-файлах, которые могут быть созданы кем угодно и легко импортированы. На левой панели нажмите "Создать и импортировать".
+
+
+
+Для панели мониторинга Geth скопируйте ID [этой панели мониторинга](https://grafana.com/grafana/dashboards/13877/) и вставьте его на странице "Импорт" в Grafana. После сохранения панели мониторинга она должна выглядеть так:
+
+
+
+Вы можете изменять свои панели мониторинга. Каждую панель можно редактировать, перемещать, удалять или добавлять. Вы можете изменять свои конфигурации. Все зависит от вас! Чтобы узнать больше о том, как работают панели мониторинга, обратитесь к [документации Grafana](https://grafana.com/docs/grafana/latest/dashboards/).
+Вас также могут заинтересовать [Оповещения](https://grafana.com/docs/grafana/latest/alerting/). Это позволяет настроить уведомления на случаи, когда метрики достигают определенных значений. Поддерживаются различные каналы связи.
diff --git a/public/content/translations/ru/developers/tutorials/nft-minter/index.md b/public/content/translations/ru/developers/tutorials/nft-minter/index.md
new file mode 100644
index 00000000000..ab224484a2b
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/nft-minter/index.md
@@ -0,0 +1,876 @@
+---
+title: "Руководство по NFT Minter"
+description: "В этом руководстве вы научитесь создавать NFT-минтер и узнаете, как создать полнофункциональное децентрализованное приложение, подключив свой смарт-контракт к интерфейсу React с помощью инструментов MetaMask и Web3."
+author: "smudgil"
+tags:
+ [
+ "Solidity",
+ "NFT",
+ "alchemy",
+ "смарт-контракты",
+ "интерфейс",
+ "Pinata"
+ ]
+skill: intermediate
+lang: ru
+published: 2021-10-06
+---
+
+Одна из самых больших проблем для разработчиков, имеющих опыт работы с Web2, — это выяснить, как подключить ваш смарт-контракт к внешнему проекту и научиться взаимодействовать с ним.
+
+Создавая NFT-минтер — простой пользовательский интерфейс, в который вы сможете ввести ссылку на свой цифровой актив, название и описание — вы узнаете, как:
+
+- Подключаться к MetaMask через ваш фронтенд-проект
+- Вызывать методы смарт-контракта из вашего интерфейса
+- Подписывать транзакции с помощью MetaMask
+
+В этом руководстве мы будем использовать [React](https://react.dev/) в качестве фреймворка для фронтенда. Поскольку это руководство в первую очередь ориентировано на разработку Web3, мы не будем тратить много времени на изучение основ React. Вместо этого мы сосредоточимся на добавлении функциональности в наш проект.
+
+Изначально вы уже должны иметь начальное понимание React — знать, как работают компоненты, реквизиты, useState/useEffect и вызов базовых функций. Если вы никогда раньше не слышали ни об одном из этих терминов, рекомендуем ознакомиться с этим [руководством «Введение в React»](https://react.dev/learn/tutorial-tic-tac-toe). Для тех, кто лучше воспринимает информацию визуально, мы настоятельно рекомендуем эту превосходную серию видеороликов [«Полное руководство по современному React»](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d) от Net Ninja.
+
+И если вы еще этого не сделали, вам обязательно понадобится создать аккаунт Alchemy, чтобы пройти это руководство, а также создать что-нибудь на блокчейне. Зарегистрируйте бесплатный аккаунт [здесь](https://alchemy.com/).
+
+Без лишних слов, давайте начнем!
+
+## Создание NFT для начинающих {#making-nfts-101}
+
+Прежде чем мы начнем изучать какой-либо код, важно понять, как работает создание NFT. Он состоит из двух шагов:
+
+### Публикация смарт-контракта NFT в блокчейне Ethereum {#publish-nft}
+
+Самая большая разница между двумя стандартами смарт-контрактов NFT заключается в том, что ERC-1155 является стандартом с несколькими токенами и включает в себя пакетную функциональность, тогда как ERC-721 является стандартом на один токен и, следовательно, поддерживает передачу только одного токена за раз.
+
+### Вызов функции минтинга {#minting-function}
+
+Обычно эта функция минтинга требует, чтобы вы передали две переменные в качестве параметров: во-первых, `recipient` — адрес, на который будет получен ваш свежевыпущенный NFT, а во-вторых, `tokenURI` NFT — строку, которая преобразуется в JSON-документ, описывающий метаданные NFT.
+
+Метаданные NFT на самом деле оживляют его, позволяя ему иметь такие свойства, как имя, описание, изображение (или другой цифровой актив) и другие атрибуты. Вот [пример tokenURI](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2), который содержит метаданные NFT.
+
+В этом уроке мы сосредоточимся на части 2, вызывая существующую функцию создания смарт-контракта NFT с помощью нашего пользовательского интерфейса React.
+
+[Вот ссылка](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) на смарт-контракт NFT стандарта ERC-721, который мы будем вызывать в этом руководстве. Если вы хотите узнать, как мы его создали, настоятельно рекомендуем ознакомиться с нашим другим руководством, [«Как создать NFT»](https://www.alchemy.com/docs/how-to-create-an-nft).
+
+Отлично, теперь, когда мы понимаем, как работает создание NFT, давайте клонируем наши стартовые файлы!
+
+## Клонируйте стартовые файлы {#clone-the-starter-files}
+
+Для начала перейдите в [репозиторий nft-minter-tutorial на GitHub](https://github.com/alchemyplatform/nft-minter-tutorial), чтобы получить стартовые файлы для этого проекта. Клонируйте этот репозиторий в свою локальную среду.
+
+Открыв этот клонированный репозиторий `nft-minter-tutorial`, вы заметите, что он содержит две папки: `minter-starter-files` и `nft-minter`.
+
+- `minter-starter-files` содержит стартовые файлы (по сути, пользовательский интерфейс React) для этого проекта. В этом руководстве **мы будем работать в этой директории**, и вы научитесь оживлять этот пользовательский интерфейс, подключив его к вашему кошельку Ethereum и смарт-контракту NFT.
+- `nft-minter` содержит полностью завершенное руководство, и вы можете использовать его в качестве **справочного материала**, **если у вас возникнут трудности.**
+
+Далее откройте свою копию `minter-starter-files` в редакторе кода, а затем перейдите в папку `src`.
+
+Весь код, который мы напишем, будет находиться в папке `src`. Мы будем редактировать компонент `Minter.js` и писать дополнительные javascript-файлы, чтобы добавить в наш проект функциональность Web3.
+
+## Шаг 2. Ознакомьтесь с нашими стартовыми файлами {#step-2-check-out-our-starter-files}
+
+Прежде чем мы начнем кодировку, важно проверить, что нам уже предоставлено в стартовых файлах.
+
+### Запустите ваш React-проект {#get-your-react-project-running}
+
+Начнем с запуска проекта React в нашем браузере. Прелесть React в том, что как только наш проект запускается в нашем браузере, любые сохраняемые нами изменения будут обновляться в реальном времени в нашем браузере.
+
+Чтобы запустить проект, перейдите в корневой каталог папки `minter-starter-files` и выполните `npm install` в терминале, чтобы установить зависимости проекта:
+
+```bash
+cd minter-starter-files
+npm install
+```
+
+После завершения установки выполните `npm start` в терминале:
+
+```bash
+npm start
+```
+
+При этом в вашем браузере должен открыться http://localhost:3000/, где вы увидите интерфейс нашего проекта. Он должен состоять из трех полей: место для ввода ссылки на ваш NFT-ресурс, имя вашего NFT и описание.
+
+Если вы попытаетесь нажать кнопки «Connect Wallet» или «Mint NFT», вы заметите, что они не работают - это потому, что нам все еще нужно их запрограммировать! :\)
+
+### Компонент Minter.js {#minter-js}
+
+**ПРИМЕЧАНИЕ:** Убедитесь, что вы находитесь в папке `minter-starter-files`, а не в `nft-minter`!
+
+Вернемся в папку `src` в нашем редакторе и откроем файл `Minter.js`. Очень важно, чтобы мы понимали все в этом файле, поскольку это основной компонент React, над которым мы будем работать.
+
+В верхней части этого файла находятся переменные состояния, которые мы будем обновлять после определенных событий.
+
+```javascript
+//Переменные состояния
+const [walletAddress, setWallet] = useState("")
+const [status, setStatus] = useState("")
+const [name, setName] = useState("")
+const [description, setDescription] = useState("")
+const [url, setURL] = useState("")
+```
+
+Никогда не слышали о переменных состояния React или перехватах состояния? Ознакомьтесь с [этой](https://legacy.reactjs.org/docs/hooks-state.html) документацией.
+
+Вот что представляет собой каждая из переменных:
+
+- `walletAddress` — строка, в которой хранится адрес кошелька пользователя
+- `status` — строка, содержащая сообщение для отображения в нижней части пользовательского интерфейса
+- `name` — строка, в которой хранится имя NFT
+- `description` — строка, в которой хранится описание NFT
+- `url` — строка, которая является ссылкой на цифровой актив NFT
+
+После переменных состояния вы увидите три нереализованные функции: `useEffect`, `connectWalletPressed` и `onMintPressed`. Вы заметите, что все эти функции являются `async` (асинхронными), потому что в них мы будем делать асинхронные вызовы API! Их названия соответствуют их функциям:
+
+```javascript
+useEffect(async () => {
+ //TODO: реализовать
+}, [])
+
+const connectWalletPressed = async () => {
+ //TODO: реализовать
+}
+
+const onMintPressed = async () => {
+ //TODO: реализовать
+}
+```
+
+- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html) — это хук React, который вызывается после рендеринга вашего компонента. Поскольку в него передается пустой массив `[]` в качестве свойства (см. строку 3), он будет вызываться только при _первом_ рендеринге компонента. Здесь мы вызовем наш прослушиватель кошелька и другую функцию кошелька, чтобы обновить наш пользовательский интерфейс и указать, подключен ли он.
+- `connectWalletPressed` — эта функция будет вызываться для подключения кошелька MetaMask пользователя к нашему децентрализованному приложению.
+- `onMintPressed` — эта функция будет вызываться для минтинга NFT пользователя.
+
+Ближе к концу этого файла находится пользовательский интерфейс нашего компонента. Если вы внимательно изучите этот код, вы заметите, что мы обновляем наши переменные состояния `url`, `name` и `description`, когда изменяется ввод в соответствующих текстовых полях.
+
+Вы также увидите, что `connectWalletPressed` и `onMintPressed` вызываются при нажатии кнопок с идентификаторами `mintButton` и `walletButton` соответственно.
+
+```javascript
+//Пользовательский интерфейс нашего компонента
+return (
+
+
+
+
+ 🧙♂️ Минтер NFT от Alchemy
+
+ Просто добавьте ссылку на ваш актив, имя и описание, а затем нажмите «Минтить».
+
+
+
+ {status}
+
+)
+```
+
+Наконец, давайте рассмотрим, где добавили этот компонент Minter.
+
+Если вы перейдете в файл `App.js`, который является основным компонентом React и выступает в качестве контейнера для всех других компонентов, вы увидите, что наш компонент Minter вставлен в строке 7.
+
+**В этом руководстве мы будем редактировать только файл `Minter.js` и добавлять файлы в нашу папку `src`.**
+
+Теперь, когда нам ясно, с чем работаем, давайте настроим наш кошелек Ethereum!
+
+## Настройте ваш кошелек Ethereum {#set-up-your-ethereum-wallet}
+
+Чтобы пользователи могли взаимодействовать с вашим смарт-контрактом, им необходимо подключить свой кошелек Ethereum к вашему децентрализованному приложению.
+
+### Загрузите MetaMask {#download-metamask}
+
+В этом руководстве мы будем использовать MetaMask, виртуальный кошелек в браузере, используемый для управления адресом вашего аккаунта Ethereum. Если вы хотите больше узнать о том, как работают транзакции в Ethereum, ознакомьтесь с [этой страницей](/developers/docs/transactions/).
+
+Вы можете бесплатно скачать и создать аккаунт MetaMask [здесь](https://metamask.io/download). Если вы создаете аккаунт или если у вас уже есть аккаунт, обязательно переключитесь на «Тестовую сеть Ropsten» в правом верхнем углу \ (чтобы мы не имели дело с реальными деньгами \).
+
+### Получите ether из крана {#add-ether-from-faucet}
+
+Чтобы выпускать наши NFT (или подписывать любые транзакции в блокчейне Ethereum), нам понадобится немного фальшивых Eth. Чтобы получить ETH, вы можете перейти к [крану Ropsten](https://faucet.ropsten.be/), ввести адрес своего аккаунта Ropsten и нажать «Отправить ETH из Ropsten». Вскоре после этого вы должны увидеть Eth в своей учетной записи MetaMask!
+
+### Проверьте свой баланс {#check-your-balance}
+
+Чтобы дважды проверить наш баланс, давайте сделаем запрос [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance), используя [инструмент для составления запросов от Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Так сумма Eth вернется в наш кошелек. После ввода адреса вашего аккаунта MetaMask и нажатия «Send Request» вы должны увидеть примерно такой ответ:
+
+```text
+{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
+```
+
+**ПРИМЕЧАНИЕ:** этот результат указан в wei, а не в ETH. Wei это наименьшая единица измерения эфира. Преобразование wei в eth: 1 eth = 10¹⁸ wei. Итак, если мы преобразуем 0xde0b6b3a7640000 в десятичное число, мы получим 1\*10¹⁸, что равно 1 eth.
+
+Фух! Наши ненастоящие деньги уже все там!
+
+## Подключите MetaMask к вашему пользовательскому интерфейсу {#connect-metamask-to-your-UI}
+
+Теперь, когда наш кошелек MetaMask настроен, давайте подключим к нему наше децентрализованное приложение!
+
+Поскольку мы хотим придерживаться парадигмы [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), мы создадим отдельный файл, который будет содержать наши функции для управления логикой, данными и правилами нашего децентрализованного приложения, а затем передадим эти функции нашему фронтенду (компоненту Minter.js).
+
+### Функция `connectWallet` {#connect-wallet-function}
+
+Для этого создадим новую папку с именем `utils` в каталоге `src` и добавим в нее файл `interact.js`, который будет содержать все функции взаимодействия с кошельком и смарт-контрактом.
+
+В нашем файле `interact.js` мы напишем функцию `connectWallet`, которую затем импортируем и вызовем в нашем компоненте `Minter.js`.
+
+В ваш файл `interact.js` добавьте следующее:
+
+```javascript
+export const connectWallet = async () => {
+ if (window.ethereum) {
+ try {
+ const addressArray = await window.ethereum.request({
+ method: "eth_requestAccounts",
+ })
+ const obj = {
+ status: "👆🏽 Напишите сообщение в текстовом поле выше.",
+ address: addressArray[0],
+ }
+ return obj
+ } catch (err) {
+ return {
+ address: "",
+ status: "😥 " + err.message,
+ }
+ }
+ } else {
+ return {
+ address: "",
+ status: (
+
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в вашем
+ браузере.
+
+
+
+ ),
+ }
+ }
+}
+```
+
+Давайте разберем, что делает этот код:
+
+Сначала наша функция проверяет, включен ли `window.ethereum` в вашем браузере.
+
+`window.ethereum` — это глобальный API, внедряемый MetaMask и другими поставщиками кошельков, который позволяет веб-сайтам запрашивать аккаунты пользователей Ethereum. В случае одобрения он может считывать данные из блокчейнов, к которым подключен пользователь, и предлагать пользователю подписывать сообщения и транзакции. Для получения дополнительной информации см. [документацию MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)!
+
+Если `window.ethereum` _отсутствует_, это означает, что MetaMask не установлен. В результате возвращается объект JSON, где возвращаемый `address` представляет собой пустую строку, а объект `status` JSX сообщает, что пользователь должен установить MetaMask.
+
+**Большинство написанных нами функций будут возвращать объекты JSON, которые мы можем использовать для обновления переменных состояния и пользовательского интерфейса.**
+
+Если же `window.ethereum` _присутствует_, то здесь начинается самое интересное.
+
+Используя цикл try/catch, мы попытаемся подключиться к MetaMask, вызвав [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Вызов этой функции откроет MetaMask в браузере, и пользователю будет предложено подключить свой кошелек к вашему децентрализованному приложению.
+
+- Если пользователь решит подключиться, `method: "eth_requestAccounts"` вернет массив, содержащий все адреса аккаунтов пользователя, подключенных к децентрализованному приложению. В целом, наша функция `connectWallet` вернет объект JSON, который содержит _первый_ `address` в этом массиве (см. строку 9) и сообщение `status`, предлагающее пользователю написать сообщение в смарт-контракт.
+- Если пользователь отклоняет подключение, то объект JSON будет содержать пустую строку для возвращаемого `address` и сообщение `status`, которое отражает, что пользователь отклонил подключение.
+
+### Добавление функции connectWallet в компонент пользовательского интерфейса Minter.js {#add-connect-wallet}
+
+Теперь, когда мы написали функцию `connectWallet`, давайте подключим ее к нашему компоненту `Minter.js.`.
+
+Во-первых, нам нужно импортировать нашу функцию в наш файл `Minter.js`, добавив `import { connectWallet } from "./utils/interact.js";` вверху файла `Minter.js`. Ваши первые 11 строк `Minter.js` теперь должны выглядеть так:
+
+```javascript
+import { useEffect, useState } from "react";
+import { connectWallet } from "./utils/interact.js";
+
+const Minter = (props) => {
+
+ //Переменные состояния
+ const [walletAddress, setWallet] = useState("");
+ const [status, setStatus] = useState("");
+ const [name, setName] = useState("");
+ const [description, setDescription] = useState("");
+ const [url, setURL] = useState("");
+```
+
+Затем внутри нашей функции `connectWalletPressed` мы вызовем импортированную функцию `connectWallet`:
+
+```javascript
+const connectWalletPressed = async () => {
+ const walletResponse = await connectWallet()
+ setStatus(walletResponse.status)
+ setWallet(walletResponse.address)
+}
+```
+
+Заметили, как большая часть нашей функциональности абстрагирована от компонента `Minter.js` в файл `interact.js`? Это значит, что мы соответствуем парадигме M-V-С!
+
+В `connectWalletPressed` мы просто делаем вызов `await` к нашей импортированной функции `connectWallet` и, используя ее ответ, обновляем наши переменные `status` и `walletAddress` через их хуки состояния.
+
+Теперь давайте сохраним оба файла `Minter.js` и `interact.js` и протестируем наш пользовательский интерфейс.
+
+Откройте браузер на локальном хосте: 3000 и нажмите кнопку «Connect Wallet» в правом верхнем углу страницы.
+
+Если у вас установлен MetaMask, вам будет предложено подключить кошелек к вашему децентрализованному приложению. Примите приглашение на подключение.
+
+Вы должны увидеть, что кнопка кошелька теперь показывает, что ваш адрес подключен.
+
+Далее попробуйте обновить страницу... это странно. Кнопка нашего кошелька предлагает нам подключить MetaMask, хотя он уже подключен...
+
+Однако не стоит беспокоиться! Мы легко можем это исправить, реализовав функцию под названием `getCurrentWalletConnected`, которая проверит, подключен ли уже адрес к нашему децентрализованному приложению, и соответствующим образом обновит наш пользовательский интерфейс!
+
+### Функция getCurrentWalletConnected {#get-current-wallet}
+
+В вашем файле `interact.js` добавьте следующую функцию `getCurrentWalletConnected`:
+
+```javascript
+export const getCurrentWalletConnected = async () => {
+ if (window.ethereum) {
+ try {
+ const addressArray = await window.ethereum.request({
+ method: "eth_accounts",
+ })
+ if (addressArray.length > 0) {
+ return {
+ address: addressArray[0],
+ status: "👆🏽 Напишите сообщение в текстовом поле выше.",
+ }
+ } else {
+ return {
+ address: "",
+ status: "🦊 Подключитесь к MetaMask с помощью кнопки в правом верхнем углу.",
+ }
+ }
+ } catch (err) {
+ return {
+ address: "",
+ status: "😥 " + err.message,
+ }
+ }
+ } else {
+ return {
+ address: "",
+ status: (
+
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в вашем
+ браузере.
+
+
+
+ ),
+ }
+ }
+}
+```
+
+Этот код _очень_ похож на функцию `connectWallet`, которую мы написали ранее.
+
+Основное отличие состоит в том, что вместо вызова метода `eth_requestAccounts`, который открывает MetaMask для подключения пользователя к кошельку, мы вызываем метод `eth_accounts`, который просто возвращает массив с адресами MetaMask, которые в данный момент подключены к нашему децентрализованному приложению.
+
+Чтобы увидеть эту функцию в действии, давайте вызовем ее в функции `useEffect` нашего компонента `Minter.js`.
+
+Как и в случае с `connectWallet`, мы должны импортировать эту функцию из нашего файла `interact.js` в наш файл `Minter.js` следующим образом:
+
+```javascript
+import { useEffect, useState } from "react"
+import {
+ connectWallet,
+ getCurrentWalletConnected, //импортируйте здесь
+} from "./utils/interact.js"
+```
+
+Теперь просто вызовем ее в нашей функции `useEffect`:
+
+```javascript
+useEffect(async () => {
+ const { address, status } = await getCurrentWalletConnected()
+ setWallet(address)
+ setStatus(status)
+}, [])
+```
+
+Обратите внимание: мы используем ответ на наш вызов `getCurrentWalletConnected` для обновления наших переменных состояния `walletAddress` и `status`.
+
+После добавления этого кода попробуйте обновить окно браузера. На кнопке должно быть указано, что вы подключены, и показан предварительный просмотр адреса вашего подключенного кошелька — даже после обновления!
+
+### Реализация addWalletListener {#implement-add-wallet-listener}
+
+Последним шагом в настройке нашего кошелька в децентрализированном приложении является реализация прослушивателя кошелька, чтобы наш пользовательский интерфейс обновлялся при изменении состояния нашего кошелька, например, когда пользователь отключает или переключает учетные записи.
+
+В ваш файл `Minter.js` добавьте функцию `addWalletListener`, которая выглядит следующим образом:
+
+```javascript
+function addWalletListener() {
+ if (window.ethereum) {
+ window.ethereum.on("accountsChanged", (accounts) => {
+ if (accounts.length > 0) {
+ setWallet(accounts[0])
+ setStatus("👆🏽 Напишите сообщение в текстовом поле выше.")
+ } else {
+ setWallet("")
+ setStatus("🦊 Подключитесь к MetaMask с помощью кнопки в правом верхнем углу.")
+ }
+ })
+ } else {
+ setStatus(
+
+ {" "}
+ 🦊
+ Вы должны установить MetaMask, виртуальный кошелек Ethereum, в вашем браузере.
+
+
+ )
+ }
+}
+```
+
+Давайте быстро разберем, что здесь происходит:
+
+- Сначала наша функция проверяет, включен ли `window.ethereum` (т. е. установлен ли MetaMask).
+ - Если нет, мы просто устанавливаем для нашей переменной состояния `status` строку JSX, которая предлагает пользователю установить MetaMask.
+ - Если он включен, мы устанавливаем прослушиватель `window.ethereum.on("accountsChanged")` в строке 3, который прослушивает изменения состояния в кошельке MetaMask, включая подключение пользователем дополнительного аккаунта к децентрализованному приложению, переключение аккаунтов или отключение аккаунта. Если подключен хотя бы один аккаунт, переменная состояния `walletAddress` обновляется как первый аккаунт в массиве `accounts`, возвращаемом прослушивателем. В противном случае `walletAddress` устанавливается как пустая строка.
+
+Наконец, мы должны вызвать ее в нашей функции `useEffect`:
+
+```javascript
+useEffect(async () => {
+ const { address, status } = await getCurrentWalletConnected()
+ setWallet(address)
+ setStatus(status)
+
+ addWalletListener()
+}, [])
+```
+
+И вуаля! Мы закончили программирование всех функций нашего кошелька! Теперь, когда наш кошелек настроен, давайте разберемся, как выпустить наш NFT!
+
+## Основы метаданных NFT {#nft-metadata-101}
+
+Итак, помните метаданные NFT, о которых мы только что говорили в шаге 0 этого руководства — они оживляют NFT, позволяя ему иметь такие свойства, как цифровой актив, имя, описание и другие характеристики.
+
+Нам нужно будет настроить эти метаданные в виде объекта JSON и сохранить их, чтобы мы могли передать их в качестве параметра `tokenURI` при вызове функции `mintNFT` нашего смарт-контракта.
+
+Текст в полях «Ссылка на актив», «Имя», «Описание» будет содержать различные свойства метаданных нашего NFT. Мы отформатируем эти метаданные в виде объекта JSON, но есть несколько вариантов хранения этого объекта JSON:
+
+- Мы могли бы хранить его в блокчейне Ethereum; однако это будет очень дорого.
+- Мы могли бы хранить его на централизованном сервере, например AWS или Firebase. Но это подорвет суть нашей децентрализации.
+- Мы могли бы использовать IPFS, децентрализованный протокол и одноранговую сеть для хранения и обмена данными в распределенной файловой системе. Поскольку это децентрализованный и бесплатный протокол, он подходит нам идеально!
+
+Для хранения наших метаданных в IPFS мы будем использовать [Pinata](https://pinata.cloud/), удобный API и набор инструментов IPFS. На следующем шаге мы объясним, как именно это сделать!
+
+## Использование Pinata для закрепления ваших метаданных в IPFS {#use-pinata-to-pin-your-metadata-to-IPFS}
+
+Если у вас нет аккаунта [Pinata](https://pinata.cloud/), зарегистрируйте бесплатный аккаунт [здесь](https://app.pinata.cloud/auth/signup) и выполните действия по подтверждению электронной почты и аккаунта.
+
+### Создайте свой ключ API Pinata {#create-pinata-api-key}
+
+Перейдите на страницу [https://pinata.cloud/keys](https://pinata.cloud/keys), затем нажмите кнопку «New Key» (Новый ключ) вверху, включите виджет Admin и дайте имя своему ключу.
+
+Затем у вас появится всплывающее окно с информацией о вашем API. Обязательно поместите его в безопасное место.
+
+Теперь, когда наш ключ настроен, давайте добавим его в наш проект, чтобы начать его использовать.
+
+### Создайте файл .env {#create-a-env}
+
+Мы можем безопасно хранить ключ Pinata и секрет в файле среды. Давайте установим пакет [dotenv](https://www.npmjs.com/package/dotenv) в вашем каталоге проекта.
+
+Откройте новую вкладку в своем терминале (отдельную от той, на которой запущен локальный хост) и убедитесь, что вы находитесь в папке `minter-starter-files`, затем выполните следующую команду в своем терминале:
+
+```text
+npm install dotenv --save
+```
+
+Далее создайте файл `.env` в корневом каталоге `minter-starter-files`, введя в командной строке следующее:
+
+```javascript
+vim .env
+```
+
+При этом ваш файл `.env` откроется в vim (текстовом редакторе). Для сохранения нажмите «esc» + «:» + «q» на клавиатуре в указанном порядке.
+
+Затем в VSCode перейдите к файлу `.env` и добавьте в него ключ API Pinata и секрет API, как показано ниже:
+
+```text
+REACT_APP_PINATA_KEY = <ключ-api-pinata>
+REACT_APP_PINATA_SECRET = <секрет-api-pinata>
+```
+
+Сохраните файл, и после этого вы сможете приступить к написанию функции для загрузки метаданных JSON в IPFS!
+
+### Реализация pinJSONToIPFS {#pin-json-to-ipfs}
+
+К счастью для нас, Pinata имеет [API специально для загрузки данных JSON в IPFS](https://docs.pinata.cloud/api-reference/endpoint/ipfs/pin-json-to-ipfs#pin-json) и удобный пример на JavaScript с axios, который мы можем использовать с небольшими изменениями.
+
+Давайте создадим в вашей папке `utils` еще один файл с именем `pinata.js`, а затем импортируем секрет и ключ Pinata из файла .env следующим образом:
+
+```javascript
+require("dotenv").config()
+const key = process.env.REACT_APP_PINATA_KEY
+const secret = process.env.REACT_APP_PINATA_SECRET
+```
+
+Затем вставьте дополнительный код ниже в файл `pinata.js`. Не волнуйтесь, сейчас мы разберем, что все означает!
+
+```javascript
+require("dotenv").config()
+const key = process.env.REACT_APP_PINATA_KEY
+const secret = process.env.REACT_APP_PINATA_SECRET
+
+const axios = require("axios")
+
+export const pinJSONToIPFS = async (JSONBody) => {
+ const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS`
+ //делаем POST-запрос axios к Pinata ⬇️
+ return axios
+ .post(url, JSONBody, {
+ headers: {
+ pinata_api_key: key,
+ pinata_secret_api_key: secret,
+ },
+ })
+ .then(function (response) {
+ return {
+ success: true,
+ pinataUrl:
+ "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash,
+ }
+ })
+ .catch(function (error) {
+ console.log(error)
+ return {
+ success: false,
+ message: error.message,
+ }
+ })
+}
+```
+
+Так что же именно делает этот код?
+
+Во-первых, он импортирует [axios](https://www.npmjs.com/package/axios), HTTP-клиент на основе промисов для браузера и node.js, который мы будем использовать для отправки запроса в Pinata.
+
+Затем у нас есть асинхронная функция `pinJSONToIPFS`, которая принимает `JSONBody` в качестве входных данных, а также ключ и секрет API Pinata в своем заголовке, и все это для выполнения POST-запроса к их `pinJSONToIPFS` API.
+
+- Если этот POST-запрос оказывается успешным, наша функция возвращает объект JSON с логическим значением `success` как true и `pinataUrl`, где были закреплены наши метаданные. Мы будем использовать этот возвращенный `pinataUrl` в качестве входных данных `tokenURI` для функции минтинга нашего смарт-контракта.
+- Если этот запрос на отправку завершается неудачей, наша функция возвращает объект JSON с логическим значением `success` как false и строку `message`, которая передает нашу ошибку.
+
+Как и в случае с типами возвращаемых значений функции `connectWallet`, мы возвращаем объекты JSON, чтобы можно было использовать их параметры для обновления переменных состояния и пользовательского интерфейса.
+
+## Загрузите свой смарт-контракт {#load-your-smart-contract}
+
+Теперь, когда у нас есть способ загрузить метаданные NFT в IPFS с помощью функции `pinJSONToIPFS`, нам нужно создать способ загрузки экземпляра нашего смарт-контракта, чтобы мы могли вызвать его функцию `mintNFT`.
+
+Как мы упоминали ранее, в этом руководстве мы будем использовать [этот существующий смарт-контракт NFT](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE); однако, если вы хотите узнать, как мы его создали, или создать его самостоятельно, мы настоятельно рекомендуем вам ознакомиться с другим нашим руководством, [«Как создать NFT»](https://www.alchemy.com/docs/how-to-create-an-nft).
+
+### ABI контракта {#contract-abi}
+
+Если вы внимательно изучили наши файлы, то заметили, что в нашем каталоге `src` есть файл `contract-abi.json`. ABI необходим для указания того, какую функцию будет вызывать контракт, а также для обеспечения того, чтобы функция возвращала данные в ожидаемом формате.
+
+Нам также понадобится ключ API Alchemy и API Alchemy Web3 для подключения к блокчейну Ethereum и загрузки нашего смарт-контракта.
+
+### Создайте свой ключ API Alchemy {#create-alchemy-api}
+
+Если у вас еще нет аккаунта Alchemy, [зарегистрируйтесь бесплатно здесь.](https://alchemy.com/?a=eth-org-nft-minter)
+
+Как только регистрация в Alchemy завершена, можно создать приложение и таким образом сгенерировать ключ API. Это позволит нам делать запросы к тестовой сети Ropsten.
+
+Перейдите на страницу «Create App» (Создать приложение) в вашей панели инструментов Alchemy, наведя курсор на «Apps» (Приложения) в навигационной панели и нажав «Create App» (Создать приложение).
+
+Назовите свое приложение, которое мы выбрали, «My First NFT!», дайте краткое описание, выберите «Staging» для среды, используемой для учета вашего приложения, и выберите «Ropsten» для своей сети.
+
+Нажмите "Create app" и все готово! Ваше приложение должно появиться в таблице ниже.
+
+Отлично, теперь, когда мы создали URL-адрес API HTTP Alchemy, скопируйте его в буфер обмена...
+
+…а затем добавьте его в наш файл `.env`. В целом ваш файл .env должен выглядеть так:
+
+```text
+REACT_APP_PINATA_KEY =
+REACT_APP_PINATA_SECRET =
+REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/
+```
+
+Теперь, когда у нас есть ABI контракта и ключ API Alchemy, мы готовы загрузить наш смарт-контракт с помощью [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3).
+
+### Настройка конечной точки Alchemy Web3 и контракта {#setup-alchemy-endpoint}
+
+Во-первых, если у вас его еще нет, вам необходимо установить [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3), перейдя в домашний каталог: `nft-minter-tutorial` в терминале:
+
+```text
+cd ..
+npm install @alch/alchemy-web3
+```
+
+Теперь вернемся к нашему файлу `interact.js`. В верхней части файла добавьте следующий код, чтобы импортировать ключ Alchemy из файла .env и настроить конечную точку Alchemy Web3:
+
+```javascript
+require("dotenv").config()
+const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(alchemyKey)
+```
+
+[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) — это оболочка для [Web3.js](https://docs.web3js.org/), предоставляющая расширенные методы API и другие важные преимущества, облегчающие жизнь веб-разработчика. Он разработан с требованием минимальной настройки, поэтому вы можете сразу начать использовать его в своем приложении!
+
+Далее давайте добавим в наш файл ABI и адрес контракта.
+
+```javascript
+require("dotenv").config()
+const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
+const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
+const web3 = createAlchemyWeb3(alchemyKey)
+
+const contractABI = require("../contract-abi.json")
+const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE"
+```
+
+После того, как мы создали и то, и другое, мы готовы начать кодировать нашу функцию монетного двора!
+
+## Реализация функции mintNFT {#implement-the-mintnft-function}
+
+Внутри вашего файла `interact.js` давайте определим нашу функцию `mintNFT`, которая, как следует из названия, будет минтить наш NFT.
+
+Поскольку мы будем выполнять множество асинхронных вызовов \(Pinata для закрепления наших метаданных в IPFS, Alchemy Web3 для загрузки нашего смарт-контракта и MetaMask для подписи наших транзакций), наша функция также будет асинхронной.
+
+Тремя входными данными для нашей функции будут `url` нашего цифрового актива, `name` и `description`. Добавьте следующую сигнатуру функции под функцией `connectWallet`:
+
+```javascript
+export const mintNFT = async (url, name, description) => {}
+```
+
+### Обработка ошибок ввода {#input-error-handling}
+
+Естественно, имеет смысл провести некоторую обработку ошибок ввода в начале функции, поэтому мы выходим из этой функции, если наши входные параметры неверны. Внутри нашей функции добавим следующий код:
+
+```javascript
+export const mintNFT = async (url, name, description) => {
+ //обработка ошибок
+ if (url.trim() == "" || name.trim() == "" || description.trim() == "") {
+ return {
+ success: false,
+ status: "❗Перед минтингом убедитесь, что все поля заполнены.",
+ }
+ }
+}
+```
+
+По сути, если какой-либо из входных параметров оказывается пустой строкой, мы возвращаем объект JSON, в котором логическое значение `success` имеет значение false, а строка `status` сообщает, что все поля в нашем пользовательском интерфейсе должны быть заполнены.
+
+### Загрузка метаданных в IPFS {#upload-metadata-to-ipfs}
+
+Как только мы узнаем, что наши метаданные отформатированы правильно, следующим шагом будет обернуть их в объект JSON и загрузить в IPFS через написанный нами `pinJSONToIPFS`!
+
+Для этого нам сначала нужно импортировать функцию `pinJSONToIPFS` в наш файл `interact.js`. В самом верху `interact.js` добавим:
+
+```javascript
+import { pinJSONToIPFS } from "./pinata.js"
+```
+
+Напомним, что `pinJSONToIPFS` принимает тело JSON. Поэтому, прежде чем мы вызовем его, нам нужно отформатировать наши параметры `url`, `name` и `description` в объект JSON.
+
+Давайте обновим наш код, чтобы создать объект JSON с именем `metadata`, а затем выполним вызов `pinJSONToIPFS` с этим параметром `metadata`:
+
+```javascript
+export const mintNFT = async (url, name, description) => {
+ //обработка ошибок
+ if (url.trim() == "" || name.trim() == "" || description.trim() == "") {
+ return {
+ success: false,
+ status: "❗Перед минтингом убедитесь, что все поля заполнены.",
+ }
+ }
+
+ //создание метаданных
+ const metadata = new Object()
+ metadata.name = name
+ metadata.image = url
+ metadata.description = description
+
+ //вызов pinata
+ const pinataResponse = await pinJSONToIPFS(metadata)
+ if (!pinataResponse.success) {
+ return {
+ success: false,
+ status: "😢 Что-то пошло не так при загрузке вашего tokenURI.",
+ }
+ }
+ const tokenURI = pinataResponse.pinataUrl
+}
+```
+
+Обратите внимание: мы сохраняем ответ на наш вызов `pinJSONToIPFS(metadata)` в объекте `pinataResponse`. Затем мы анализируем этот объект на наличие ошибок.
+
+Если возникает ошибка, мы возвращаем объект JSON, где логическое значение `success` имеет значение false, а наша строка `status` сообщает, что наш вызов не удался. В противном случае мы извлекаем `pinataURL` из `pinataResponse` и сохраняем его как переменную `tokenURI`.
+
+Теперь пришло время загрузить наш смарт-контракт с помощью API Alchemy Web3, который мы инициализировали в верхней части нашего файла. Добавьте следующую строку кода в конец функции `mintNFT`, чтобы установить контракт в глобальной переменной `window.contract`:
+
+```javascript
+window.contract = await new web3.eth.Contract(contractABI, contractAddress)
+```
+
+Последнее, что нужно добавить в нашу функцию `mintNFT` — это транзакция Ethereum:
+
+```javascript
+//настройка транзакции Ethereum
+const transactionParameters = {
+ to: contractAddress, // Обязательно, кроме случаев публикации контракта.
+ from: window.ethereum.selectedAddress, // должен совпадать с активным адресом пользователя.
+ data: window.contract.methods
+ .mintNFT(window.ethereum.selectedAddress, tokenURI)
+ .encodeABI(), //вызов смарт-контракта NFT
+}
+
+//подписание транзакции через MetaMask
+try {
+ const txHash = await window.ethereum.request({
+ method: "eth_sendTransaction",
+ params: [transactionParameters],
+ })
+ return {
+ success: true,
+ status:
+ "✅ Проверьте свою транзакцию в Etherscan: https://ropsten.etherscan.io/tx/" +
+ txHash,
+ }
+} catch (error) {
+ return {
+ success: false,
+ status: "😥 Что-то пошло не так: " + error.message,
+ }
+}
+```
+
+Если вы уже знакомы с транзакциями Ethereum, вы заметите, что структура очень похожа на ту, которую вы видели раньше.
+
+- Сначала мы настраиваем параметры наших транзакций.
+ - `to` указывает адрес получателя (наш смарт-контракт)
+ - `from` указывает на подписавшего транзакцию (адрес пользователя, подключенного к MetaMask: `window.ethereum.selectedAddress`)
+ - `data` содержит вызов метода `mintNFT` нашего смарт-контракта, который получает наш `tokenURI` и адрес кошелька пользователя, `window.ethereum.selectedAddress`, в качестве входных данных
+- Затем мы делаем ожидающий вызов, `window.ethereum.request`, где просим MetaMask подписать транзакцию. Обратите внимание: в этом запросе мы указываем наш метод ETH (eth_SentTransaction) и передаем наши `transactionParameters`. На этом этапе MetaMask откроется в браузере и предложит пользователю подписать или отклонить транзакцию.
+ - Если транзакция прошла успешно, функция вернет объект JSON, в котором логическое значение `success` установлено в true, а строка `status` предлагает пользователю проверить Etherscan для получения дополнительной информации о его транзакции.
+ - Если транзакция не удалась, функция вернет объект JSON, в котором для логического значения `success` установлено значение false, а строка `status` передает сообщение об ошибке.
+
+В целом наша функция `mintNFT` должна выглядеть так:
+
+```javascript
+export const mintNFT = async (url, name, description) => {
+ //обработка ошибок
+ if (url.trim() == "" || name.trim() == "" || description.trim() == "") {
+ return {
+ success: false,
+ status: "❗Перед минтингом убедитесь, что все поля заполнены.",
+ }
+ }
+
+ //создание метаданных
+ const metadata = new Object()
+ metadata.name = name
+ metadata.image = url
+ metadata.description = description
+
+ //запрос на закрепление в pinata
+ const pinataResponse = await pinJSONToIPFS(metadata)
+ if (!pinataResponse.success) {
+ return {
+ success: false,
+ status: "😢 Что-то пошло не так при загрузке вашего tokenURI.",
+ }
+ }
+ const tokenURI = pinataResponse.pinataUrl
+
+ //загрузка смарт-контракта
+ window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract();
+
+ //настройка транзакции Ethereum
+ const transactionParameters = {
+ to: contractAddress, // Обязательно, кроме случаев публикации контракта.
+ from: window.ethereum.selectedAddress, // должен совпадать с активным адресом пользователя.
+ data: window.contract.methods
+ .mintNFT(window.ethereum.selectedAddress, tokenURI)
+ .encodeABI(), //вызов смарт-контракта NFT
+ }
+
+ //подписание транзакции через MetaMask
+ try {
+ const txHash = await window.ethereum.request({
+ method: "eth_sendTransaction",
+ params: [transactionParameters],
+ })
+ return {
+ success: true,
+ status:
+ "✅ Проверьте свою транзакцию в Etherscan: https://ropsten.etherscan.io/tx/" +
+ txHash,
+ }
+ } catch (error) {
+ return {
+ success: false,
+ status: "😥 Что-то пошло не так: " + error.message,
+ }
+ }
+}
+```
+
+Это одна гигантская функция! Теперь нам просто нужно подключить нашу функцию `mintNFT` к нашему компоненту `Minter.js`...
+
+## Подключение mintNFT к нашему фронтенду Minter.js {#connect-our-frontend}
+
+Откройте файл `Minter.js` и обновите строку `import { connectWallet, getCurrentWalletConnected } from "./utils/interact.js";` вверху так:
+
+```javascript
+import {
+ connectWallet,
+ getCurrentWalletConnected,
+ mintNFT,
+} from "./utils/interact.js"
+```
+
+Наконец, реализуйте функцию `onMintPressed`, чтобы выполнить вызов `await` к импортированной функции `mintNFT`, и обновите переменную состояния `status`, чтобы отразить, была ли наша транзакция успешной или неудачной:
+
+```javascript
+const onMintPressed = async () => {
+ const { status } = await mintNFT(url, name, description)
+ setStatus(status)
+}
+```
+
+## Развертывание вашего NFT на действующем веб-сайте {#deploy-your-NFT}
+
+Готовы опубликовать свой проект, чтобы пользователи могли с ним взаимодействовать? Ознакомьтесь с [этим руководством](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) по развертыванию вашего минтера на действующем веб-сайте.
+
+Самый последний шаг...
+
+## Покорите мир блокчейна {#take-the-blockchain-world-by-storm}
+
+Шучу, вы дошли до конца руководства!
+
+Подводя итог, создав компонент NFT, вы научились:
+
+- Подключаться к MetaMask через ваш фронтенд-проект
+- Вызывать методы смарт-контракта из вашего интерфейса
+- Подписывать транзакции с помощью MetaMask
+
+Вероятно, вы хотели бы иметь возможность демонстрировать NFT, выпущенные через ваше децентрализованное приложение, в своем кошельке — поэтому обязательно ознакомьтесь с нашим кратким руководством [«Как просмотреть свой NFT в своем кошельке»](https://www.alchemy.com/docs/how-to-view-your-nft-in-your-mobile-wallet)!
+
+И, как всегда, если у вас есть вопросы, мы готовы помочь в [Discord-канале Alchemy](https://discord.gg/gWuC7zB). Нам не терпится увидеть, как вы примените концепции из этого руководства в своих будущих проектах!
diff --git a/public/content/translations/ru/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/ru/developers/tutorials/optimism-std-bridge-annotated-code/index.md
new file mode 100644
index 00000000000..c0c1b7b2027
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/optimism-std-bridge-annotated-code/index.md
@@ -0,0 +1,1355 @@
+---
+title: "Пошаговый обзор контракта стандартного Моста Optimism"
+description: "Как работает стандартный Мост для Optimism? Почему он работает именно так?"
+author: Ori Pomerantz
+tags: [ "Solidity", "Мост", "уровень 2" ]
+skill: intermediate
+published: 2022-03-30
+lang: ru
+---
+
+[Optimism](https://www.optimism.io/) — это [оптимистический ролл-ап](/developers/docs/scaling/optimistic-rollups/).
+Оптимистические ролл-апы могут обрабатывать транзакции по гораздо более низкой цене, чем основная сеть Ethereum (также известная как уровень 1, или L1), поскольку транзакции обрабатываются только несколькими узлами, а не каждым узлом в сети.
+В то же время все данные записываются в L1, поэтому все можно доказать и реконструировать со всеми гарантиями целостности и доступности основной сети.
+
+Чтобы использовать активы L1 в Optimism (или в любом другом L2), их необходимо [перевести через Мост](/bridges/#prerequisites).
+Один из способов добиться этого — предоставить пользователям возможность заблокировать активы (наиболее распространенными являются ETH и [токены ERC-20](/developers/docs/standards/tokens/erc-20/)) на L1 и получить эквивалентные активы для использования на L2.
+В конечном итоге тот, кто их получит, может захотеть вернуть их на L1 через Мост.
+При этом активы сжигаются на L2, а затем возвращаются пользователю на L1.
+
+Именно так работает [стандартный Мост Optimism](https://docs.optimism.io/app-developers/bridging/standard-bridge).
+В этой статье мы рассмотрим исходный код этого Моста, чтобы увидеть, как он работает, и изучим его как пример хорошо написанного кода на Solidity.
+
+## Потоки управления {#control-flows}
+
+Мост имеет два основных потока:
+
+- Депозит (с L1 на L2)
+- Вывод (с L2 на L1)
+
+### Поток депозита {#deposit-flow}
+
+#### Уровень 1 {#deposit-flow-layer-1}
+
+1. При внесении ERC-20 вкладчик дает Мосту разрешение на расходование вносимой суммы
+2. Вкладчик вызывает Мост L1 (`depositERC20`, `depositERC20To`, `depositETH` или `depositETHTo`)
+3. Мост L1 получает во владение переведенный через Мост актив
+ - ETH: актив передается вкладчиком в рамках вызова
+ - ERC-20: актив переводится Мостом самому себе, используя разрешение, предоставленное вкладчиком
+4. Мост L1 использует механизм междоменных сообщений для вызова `finalizeDeposit` на Мосте L2
+
+#### Уровень 2 {#deposit-flow-layer-2}
+
+5. Мост L2 проверяет, что вызов `finalizeDeposit` является легитимным:
+ - Вызов поступил из контракта междоменных сообщений
+ - Изначально был отправлен с Моста на L1
+6. Мост L2 проверяет, является ли контракт токена ERC-20 на L2 верным:
+ - Контракт L2 сообщает, что его аналог на L1 совпадает с тем, от которого поступили токены на L1
+ - Контракт L2 сообщает, что он поддерживает правильный интерфейс ([с использованием ERC-165](https://eips.ethereum.org/EIPS/eip-165)).
+7. Если контракт L2 является верным, он вызывается для выпуска соответствующего количества токенов на соответствующий адрес. В противном случае запускается процесс вывода, чтобы пользователь мог получить токены на L1.
+
+### Поток вывода {#withdrawal-flow}
+
+#### Уровень 2 {#withdrawal-flow-layer-2}
+
+1. Инициатор вывода вызывает Мост L2 (`withdraw` или `withdrawTo`)
+2. Мост L2 сжигает соответствующее количество токенов, принадлежащих `msg.sender`
+3. Мост L2 использует механизм междоменных сообщений для вызова `finalizeETHWithdrawal` или `finalizeERC20Withdrawal` на Мосте L1
+
+#### Уровень 1 {#withdrawal-flow-layer-1}
+
+4. Мост L1 проверяет, что вызов `finalizeETHWithdrawal` или `finalizeERC20Withdrawal` является легитимным:
+ - Вызов поступил через механизм междоменных сообщений
+ - Изначально был отправлен с Моста на L2
+5. Мост L1 переводит соответствующий актив (ETH или ERC-20) на соответствующий адрес
+
+## Код уровня 1 {#layer-1-code}
+
+Это код, который выполняется на L1, в основной сети Ethereum.
+
+### IL1ERC20Bridge {#IL1ERC20Bridge}
+
+[Этот интерфейс определен здесь](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol).
+Он включает функции и определения, необходимые для перевода токенов ERC-20 через Мост.
+
+```solidity
+// SPDX-License-Identifier: MIT
+```
+
+[Большая часть кода Optimism выпущена под лицензией MIT](https://help.optimism.io/hc/en-us/articles/4411908707995-What-software-license-does-Optimism-use-).
+
+```solidity
+pragma solidity >0.5.0 <0.9.0;
+```
+
+На момент написания статьи последняя версия Solidity — 0.8.12.
+Пока не выйдет версия 0.9.0, неизвестно, будет ли этот код совместим с ней.
+
+```solidity
+/**
+ * @title IL1ERC20Bridge
+ */
+interface IL1ERC20Bridge {
+ /**********
+ * События *
+ **********/
+
+ event ERC20DepositInitiated(
+```
+
+В терминологии Моста Optimism _депозит_ означает перевод с L1 на L2, а _вывод_ — перевод с L2 на L1.
+
+```solidity
+ address indexed _l1Token,
+ address indexed _l2Token,
+```
+
+В большинстве случаев адрес ERC-20 на L1 не совпадает с адресом эквивалентного ERC-20 на L2.
+[Список адресов токенов можно посмотреть здесь](https://static.optimism.io/optimism.tokenlist.json).
+Адрес с `chainId` 1 находится на L1 (в основной сети), а адрес с `chainId` 10 — на L2 (в сети Optimism).
+Два других значения `chainId` предназначены для тестовой сети Kovan (42) и тестовой сети Optimistic Kovan (69).
+
+```solidity
+ address indexed _from,
+ address _to,
+ uint256 _amount,
+ bytes _data
+ );
+```
+
+К переводам можно добавлять примечания, и в этом случае они добавляются в сообщающие о них события.
+
+```solidity
+ event ERC20WithdrawalFinalized(
+ address indexed _l1Token,
+ address indexed _l2Token,
+ address indexed _from,
+ address _to,
+ uint256 _amount,
+ bytes _data
+ );
+```
+
+Один и тот же контракт Моста обрабатывает переводы в обоих направлениях.
+В случае Моста L1 это означает инициализацию депозитов и финализацию выводов.
+
+```solidity
+
+ /********************
+ * Публичные функции *
+ ********************/
+
+ /**
+ * @dev Получить адрес соответствующего контракта Моста L2.
+ * @return Адрес соответствующего контракта Моста L2.
+ */
+ function l2TokenBridge() external returns (address);
+```
+
+Эта функция на самом деле не нужна, так как на L2 это предварительно развернутый контракт, поэтому он всегда находится по адресу `0x4200000000000000000000000000000000000010`.
+Она здесь для симметрии с Мостом L2, потому что адрес Моста L1 узнать _не_ тривиально.
+
+```solidity
+ /**
+ * @dev внести сумму ERC20 на баланс вызывающего на L2.
+ * @param _l1Token Адрес ERC20 на L1, который мы вносим
+ * @param _l2Token Адрес соответствующего ERC20 на L2
+ * @param _amount Сумма ERC20 для внесения
+ * @param _l2Gas Лимит газа, необходимый для завершения депозита на L2.
+ * @param _data Необязательные данные для пересылки на L2. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function depositERC20(
+ address _l1Token,
+ address _l2Token,
+ uint256 _amount,
+ uint32 _l2Gas,
+ bytes calldata _data
+ ) external;
+```
+
+Параметр `_l2Gas` — это количество газа на L2, которое может потратить транзакция.
+[До определенного (высокого) лимита это бесплатно](https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions-2), поэтому, если только контракт ERC-20 не делает что-то действительно странное при выпуске, это не должно быть проблемой.
+Эта функция предназначена для распространенного сценария, когда пользователь переводит активы через Мост на тот же адрес в другом блокчейне.
+
+```solidity
+ /**
+ * @dev внести сумму ERC20 на баланс получателя на L2.
+ * @param _l1Token Адрес ERC20 на L1, который мы вносим
+ * @param _l2Token Адрес соответствующего ERC20 на L2
+ * @param _to Адрес L2, на который будет зачислен вывод средств.
+ * @param _amount Сумма ERC20 для внесения.
+ * @param _l2Gas Лимит газа, необходимый для завершения депозита на L2.
+ * @param _data Необязательные данные для пересылки на L2. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function depositERC20To(
+ address _l1Token,
+ address _l2Token,
+ address _to,
+ uint256 _amount,
+ uint32 _l2Gas,
+ bytes calldata _data
+ ) external;
+```
+
+Эта функция почти идентична `depositERC20`, но позволяет отправить ERC-20 на другой адрес.
+
+```solidity
+ /*************************
+ * Межсетевые функции *
+ *************************/
+
+ /**
+ * @dev Завершить вывод с L2 на L1 и зачислить средства на баланс получателя
+ * токена ERC20 на L1.
+ * Этот вызов не удастся, если инициированный вывод с L2 не был завершен.
+ *
+ * @param _l1Token Адрес токена L1 для finalizeWithdrawal.
+ * @param _l2Token Адрес токена L2, на котором был инициирован вывод.
+ * @param _from Адрес L2, инициирующий перевод.
+ * @param _to Адрес L1, на который будет зачислен вывод.
+ * @param _amount Сумма ERC20 для внесения.
+ * @param _data Данные, предоставленные отправителем на L2. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function finalizeERC20Withdrawal(
+ address _l1Token,
+ address _l2Token,
+ address _from,
+ address _to,
+ uint256 _amount,
+ bytes calldata _data
+ ) external;
+}
+```
+
+Вывод средств (и другие сообщения с L2 на L1) в Optimism — это двухэтапный процесс:
+
+1. Инициирующая транзакция на L2.
+2. Завершающая или запрашивающая транзакция на L1.
+ Эта транзакция должна произойти после окончания [периода оспаривания сбоев](https://community.optimism.io/docs/how-optimism-works/#fault-proofs) для транзакции L2.
+
+### IL1StandardBridge {#il1standardbridge}
+
+[Этот интерфейс определен здесь](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1StandardBridge.sol).
+Этот файл содержит определения событий и функций для ETH.
+Эти определения очень похожи на определения в `IL1ERC20Bridge`, приведенные выше для ERC-20.
+
+Интерфейс Моста разделен на два файла, поскольку некоторые токены ERC-20 требуют специальной обработки и не могут обрабатываться стандартным Мостом.
+Таким образом, пользовательский Мост, обрабатывающий такой токен, может реализовать `IL1ERC20Bridge` и не должен также переводить ETH через Мост.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity >0.5.0 <0.9.0;
+
+import "./IL1ERC20Bridge.sol";
+
+/**
+ * @title IL1StandardBridge
+ */
+interface IL1StandardBridge is IL1ERC20Bridge {
+ /**********
+ * События *
+ **********/
+ event ETHDepositInitiated(
+ address indexed _from,
+ address indexed _to,
+ uint256 _amount,
+ bytes _data
+ );
+```
+
+Это событие почти идентично версии для ERC-20 (`ERC20DepositInitiated`), за исключением отсутствия адресов токенов L1 и L2.
+То же самое относится и к другим событиям и функциям.
+
+```solidity
+ event ETHWithdrawalFinalized(
+ .
+ .
+ .
+ );
+
+ /********************
+ * Публичные функции *
+ ********************/
+
+ /**
+ * @dev Депозит суммы ETH на баланс вызывающего на L2.
+ .
+ .
+ .
+ */
+ function depositETH(uint32 _l2Gas, bytes calldata _data) external payable;
+
+ /**
+ * @dev Депозит суммы ETH на баланс получателя на L2.
+ .
+ .
+ .
+ */
+ function depositETHTo(
+ address _to,
+ uint32 _l2Gas,
+ bytes calldata _data
+ ) external payable;
+
+ /*************************
+ * Межсетевые функции *
+ *************************/
+
+ /**
+ * @dev Завершить вывод с L2 на L1 и зачислить средства на баланс получателя
+ * токена ETH на L1. Поскольку только xDomainMessenger может вызывать эту функцию, она никогда не будет вызвана
+ * до завершения вывода.
+ .
+ .
+ .
+ */
+ function finalizeETHWithdrawal(
+ address _from,
+ address _to,
+ uint256 _amount,
+ bytes calldata _data
+ ) external;
+}
+```
+
+### CrossDomainEnabled {#crossdomainenabled}
+
+[Этот контракт](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/CrossDomainEnabled.sol) наследуется обоими Мостами ([L1](#the-l1-bridge-contract) и [L2](#the-l2-bridge-contract)) для отправки сообщений на другой уровень.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity >0.5.0 <0.9.0;
+
+/* Interface Imports */
+import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol";
+```
+
+[Этот интерфейс](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/ICrossDomainMessenger.sol) сообщает контракту, как отправлять сообщения на другой уровень с помощью междоменного мессенджера.
+Этот междоменный мессенджер — это целая отдельная система, которая заслуживает отдельной статьи, и я надеюсь написать ее в будущем.
+
+```solidity
+/**
+ * @title CrossDomainEnabled
+ * @dev Вспомогательный контракт для контрактов, выполняющих междоменные коммуникации
+ *
+ * Используемый компилятор: определяется наследующим контрактом
+ */
+contract CrossDomainEnabled {
+ /*************
+ * Переменные *
+ *************/
+
+ // Контракт-мессенджер, используемый для отправки и получения сообщений из другого домена.
+ address public messenger;
+
+ /***************
+ * Конструктор *
+ ***************/
+
+ /**
+ * @param _messenger Адрес CrossDomainMessenger на текущем уровне.
+ */
+ constructor(address _messenger) {
+ messenger = _messenger;
+ }
+```
+
+Единственный параметр, который должен знать контракт, — это адрес междоменного мессенджера на этом уровне.
+Этот параметр устанавливается один раз в конструкторе и никогда не изменяется.
+
+```solidity
+
+ /**********************
+ * Модификаторы функций *
+ **********************/
+
+ /**
+ * Гарантирует, что измененную функцию может вызывать только определенная междоменная учетная запись.
+ * @param _sourceDomainAccount Единственный аккаунт в исходном домене, который аутентифицирован для вызова этой функции.
+ */
+ modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) {
+```
+
+Междоменный обмен сообщениями доступен любому контракту в блокчейне, в котором он запущен (либо в основной сети Ethereum, либо в Optimism).
+Но нам нужно, чтобы Мост на каждой стороне доверял только определенным сообщениям, если они исходят от Моста на другой стороне.
+
+```solidity
+ require(
+ msg.sender == address(getCrossDomainMessenger()),
+ "OVM_XCHAIN: messenger contract unauthenticated"
+ );
+```
+
+Доверять можно только сообщениям от соответствующего междоменного мессенджера (`messenger`, как вы увидите ниже).
+
+```solidity
+
+ require(
+ getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount,
+ "OVM_XCHAIN: wrong sender of cross-domain message"
+ );
+```
+
+Междоменный мессенджер предоставляет адрес, отправивший сообщение на другой уровень, с помощью [функции `.xDomainMessageSender()`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol#L122-L128).
+Пока он вызывается в транзакции, инициированной сообщением, он может предоставить эту информацию.
+
+Нам нужно убедиться, что полученное сообщение пришло от другого Моста.
+
+```solidity
+
+ _;
+ }
+
+ /**********************
+ * Внутренние функции *
+ **********************/
+
+ /**
+ * Получает мессенджер, обычно из хранилища. Эта функция доступна на случай, если дочернему контракту
+ * потребуется переопределение.
+ * @return Адрес контракта междоменного мессенджера, который следует использовать.
+ */
+ function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) {
+ return ICrossDomainMessenger(messenger);
+ }
+```
+
+Эта функция возвращает междоменный мессенджер.
+Мы используем функцию, а не переменную `messenger`, чтобы позволить контрактам, которые наследуются от этого, использовать алгоритм для указания, какой междоменный мессенджер использовать.
+
+```solidity
+
+ /**
+ * Отправляет сообщение на аккаунт в другом домене
+ * @param _crossDomainTarget Предполагаемый получатель в домене назначения
+ * @param _message Данные для отправки цели (обычно calldata для функции с
+ * `onlyFromCrossDomainAccount()`)
+ * @param _gasLimit gasLimit для получения сообщения в целевом домене.
+ */
+ function sendCrossDomainMessage(
+ address _crossDomainTarget,
+ uint32 _gasLimit,
+ bytes memory _message
+```
+
+Наконец, функция, которая отправляет сообщение на другой уровень.
+
+```solidity
+ ) internal {
+ // slither-disable-next-line reentrancy-events, reentrancy-benign
+```
+
+[Slither](https://github.com/crytic/slither) — это статический анализатор, который Optimism запускает для каждого контракта для поиска уязвимостей и других потенциальных проблем.
+В этом случае следующая строка вызывает две уязвимости:
+
+1. [События повторного входа](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3)
+2. [Безопасный повторный вход](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2)
+
+```solidity
+ getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit);
+ }
+}
+```
+
+В данном случае мы не беспокоимся о повторном входе, поскольку знаем, что `getCrossDomainMessenger()` возвращает надежный адрес, даже если Slither не может этого знать.
+
+### Контракт Моста L1 {#the-l1-bridge-contract}
+
+[Исходный код этого контракта находится здесь](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1StandardBridge.sol).
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.9;
+```
+
+Интерфейсы могут быть частью других контрактов, поэтому они должны поддерживать широкий диапазон версий Solidity.
+Но сам Мост — это наш контракт, и мы можем быть строги в отношении того, какую версию Solidity он использует.
+
+```solidity
+/* Interface Imports */
+import { IL1StandardBridge } from "./IL1StandardBridge.sol";
+import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol";
+```
+
+[IL1ERC20Bridge](#IL1ERC20Bridge) и [IL1StandardBridge](#IL1StandardBridge) описаны выше.
+
+```solidity
+import { IL2ERC20Bridge } from "../../L2/messaging/IL2ERC20Bridge.sol";
+```
+
+[Этот интерфейс](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) позволяет нам создавать сообщения для управления стандартным Мостом на L2.
+
+```solidity
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+```
+
+[Этот интерфейс](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) позволяет нам управлять контрактами ERC-20.
+[Вы можете прочитать больше об этом здесь](/developers/tutorials/erc20-annotated-code/#the-interface).
+
+```solidity
+/* Library Imports */
+import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol";
+```
+
+[Как объяснялось выше](#crossdomainenabled), этот контракт используется для межуровневого обмена сообщениями.
+
+```solidity
+import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol";
+```
+
+[`Lib_PredeployAddresses`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol) содержит адреса для контрактов L2, которые всегда имеют один и тот же адрес. Сюда входит стандартный Мост на L2.
+
+```solidity
+import { Address } from "@openzeppelin/contracts/utils/Address.sol";
+```
+
+[Утилиты Address от OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol). Они используются для различения адресов контрактов и адресов, принадлежащих внешним аккаунтам (EOA).
+
+Обратите внимание, что это не идеальное решение, поскольку невозможно отличить прямые вызовы от вызовов, сделанных из конструктора контракта, но, по крайней мере, это позволяет нам выявлять и предотвращать некоторые распространенные ошибки пользователей.
+
+```solidity
+import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+```
+
+[Стандарт ERC-20](https://eips.ethereum.org/EIPS/eip-20) поддерживает два способа, которыми контракт может сообщить о сбое:
+
+1. Revert (откат)
+2. Вернуть `false`
+
+Обработка обоих случаев усложнила бы наш код, поэтому вместо этого мы используем [`SafeERC20` от OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol), который гарантирует, что [все сбои приводят к откату](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L96).
+
+```solidity
+/**
+ * @title L1StandardBridge
+ * @dev Мост L1 для ETH и ERC20 — это контракт, который хранит депонированные средства L1 и стандартные
+ * токены, используемые на L2. Он синхронизирует соответствующий Мост L2, информируя его о депозитах
+ * и прослушивая его на предмет новых завершенных выводов.
+ *
+ */
+contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled {
+ using SafeERC20 for IERC20;
+```
+
+Эта строка указывает на использование оболочки `SafeERC20` каждый раз, когда мы используем интерфейс `IERC20`.
+
+```solidity
+
+ /********************************
+ * Ссылки на внешние контракты *
+ ********************************/
+
+ address public l2TokenBridge;
+```
+
+Адрес [L2StandardBridge](#the-l2-bridge-contract).
+
+```solidity
+
+ // Сопоставляет токен L1 с токеном L2 для баланса депонированного токена L1
+ mapping(address => mapping(address => uint256)) public deposits;
+```
+
+Двойное [сопоставление (mapping)](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) — это способ определения [двумерного разреженного массива](https://en.wikipedia.org/wiki/Sparse_matrix).
+Значения в этой структуре данных идентифицируются как `deposit[адрес токена L1][адрес токена L2]`.
+Значение по умолчанию равно нулю.
+В хранилище записываются только ячейки, которым присвоено другое значение.
+
+```solidity
+
+ /***************
+ * Конструктор *
+ ***************/
+
+ // Этот контракт находится за прокси, поэтому параметры конструктора не будут использоваться.
+ constructor() CrossDomainEnabled(address(0)) {}
+```
+
+Чтобы иметь возможность обновлять этот контракт без необходимости копировать все переменные в хранилище.
+Для этого мы используем [`Прокси`](https://docs.openzeppelin.com/contracts/3.x/api/proxy), контракт, который использует [`delegatecall`](https://solidity-by-example.org/delegatecall/) для перенаправления вызовов отдельному контракту, адрес которого хранится в прокси-контракте (при обновлении вы указываете прокси-контракту изменить этот адрес).
+Когда вы используете `delegatecall`, хранилище остается хранилищем _вызывающего_ контракта, поэтому значения всех переменных состояния контракта не затрагиваются.
+
+Одним из следствий этого шаблона является то, что хранилище контракта, который является _вызываемым_ для `delegatecall`, не используется, и поэтому значения конструктора, переданные ему, не имеют значения.
+Именно по этой причине мы можем предоставить бессмысленное значение конструктору `CrossDomainEnabled`.
+Это также причина того, что приведенная ниже инициализация отделена от конструктора.
+
+```solidity
+ /******************
+ * Инициализация *
+ ******************/
+
+ /**
+ * @param _l1messenger Адрес мессенджера L1, используемый для межсетевых коммуникаций.
+ * @param _l2TokenBridge Адрес стандартного Моста L2.
+ */
+ // slither-disable-next-line external-function
+```
+
+Этот [тест Slither](https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external) идентифицирует функции, которые не вызываются из кода контракта и поэтому могут быть объявлены как `external` вместо `public`.
+Стоимость газа для `external`-функций может быть ниже, поскольку им можно предоставить параметры в calldata.
+Функции, объявленные как `public`, должны быть доступны изнутри контракта.
+Контракты не могут изменять свои собственные calldata, поэтому параметры должны находиться в памяти.
+Когда такая функция вызывается извне, необходимо скопировать calldata в память, что стоит газ.
+В этом случае функция вызывается только один раз, поэтому неэффективность для нас не имеет значения.
+
+```solidity
+ function initialize(address _l1messenger, address _l2TokenBridge) public {
+ require(messenger == address(0), "Contract has already been initialized.");
+```
+
+Функцию `initialize` следует вызывать только один раз.
+Если адрес междоменного мессенджера L1 или Моста токенов L2 изменится, мы создадим новый прокси и новый Мост, который его вызывает.
+Такое вряд ли случится, за исключением случаев обновления всей системы, что является очень редким явлением.
+
+Обратите внимание, что у этой функции нет никакого механизма, который ограничивает, _кто_ может ее вызывать.
+Это означает, что теоретически злоумышленник может подождать, пока мы развернем прокси и первую версию Моста, а затем [опередить](https://solidity-by-example.org/hacks/front-running/) транзакцию, чтобы добраться до функции `initialize` раньше, чем это сделает легитимный пользователь. Но есть два способа предотвратить это:
+
+1. Если контракты развертываются не напрямую EOA, а [в транзакции, в которой их создает другой контракт](https://medium.com/upstate-interactive/creating-a-contract-with-a-smart-contract-bdb67c5c8595), весь процесс может быть атомарным и завершиться до выполнения любой другой транзакции.
+2. Если легитимный вызов `initialize` не удался, всегда можно проигнорировать вновь созданный прокси и Мост и создать новые.
+
+```solidity
+ messenger = _l1messenger;
+ l2TokenBridge = _l2TokenBridge;
+ }
+```
+
+Это два параметра, которые должен знать Мост.
+
+```solidity
+
+ /**************
+ * Внесение депозита *
+ **************/
+
+ /** @dev Модификатор, требующий, чтобы отправитель был EOA. Эту проверку можно обойти с помощью вредоносного
+ * контракта через initcode, но она помогает избежать ошибки пользователя, которой мы хотим избежать.
+ */
+ modifier onlyEOA() {
+ // Используется для прекращения депозитов от контрактов (во избежание случайной потери токенов)
+ require(!Address.isContract(msg.sender), "Account not EOA");
+ _;
+ }
+```
+
+Именно по этой причине нам понадобились утилиты `Address` от OpenZeppelin.
+
+```solidity
+ /**
+ * @dev Эту функцию можно вызвать без данных
+ * для внесения суммы ETH на баланс вызывающего на L2.
+ * Поскольку функция receive не принимает данные, консервативная
+ * сумма по умолчанию пересылается на L2.
+ */
+ receive() external payable onlyEOA {
+ _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes(""));
+ }
+```
+
+Эта функция существует для целей тестирования.
+Обратите внимание, что она не появляется в определениях интерфейса — она не предназначена для обычного использования.
+
+```solidity
+ /**
+ * @inheritdoc IL1StandardBridge
+ */
+ function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA {
+ _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data);
+ }
+
+ /**
+ * @inheritdoc IL1StandardBridge
+ */
+ function depositETHTo(
+ address _to,
+ uint32 _l2Gas,
+ bytes calldata _data
+ ) external payable {
+ _initiateETHDeposit(msg.sender, _to, _l2Gas, _data);
+ }
+```
+
+Эти две функции являются обертками `_initiateETHDeposit`, функции, которая обрабатывает фактический депозит ETH.
+
+```solidity
+ /**
+ * @dev Выполняет логику для депозитов, сохраняя ETH и информируя шлюз L2 ETH о
+ * депозите.
+ * @param _from Аккаунт для снятия депозита на L1.
+ * @param _to Аккаунт для зачисления депозита на L2.
+ * @param _l2Gas Лимит газа, необходимый для завершения депозита на L2.
+ * @param _data Необязательные данные для пересылки на L2. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function _initiateETHDeposit(
+ address _from,
+ address _to,
+ uint32 _l2Gas,
+ bytes memory _data
+ ) internal {
+ // Конструируем calldata для вызова finalizeDeposit
+ bytes memory message = abi.encodeWithSelector(
+```
+
+Междоменные сообщения работают следующим образом: контракт назначения вызывается с сообщением в качестве его calldata.
+Контракты Solidity всегда интерпретируют свои calldata в соответствии с
+[спецификациями ABI](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html).
+Функция Solidity [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#abi-encoding-and-decoding-functions) создает эти calldata.
+
+```solidity
+ IL2ERC20Bridge.finalizeDeposit.selector,
+ address(0),
+ Lib_PredeployAddresses.OVM_ETH,
+ _from,
+ _to,
+ msg.value,
+ _data
+ );
+```
+
+Здесь сообщение вызывает [функцию `finalizeDeposit`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol#L141-L148) со следующими параметрами:
+
+| Параметр | Значение | Значение |
+| ------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| \_l1Token | address(0) | Специальное значение для обозначения ETH (который не является токеном ERC-20) на L1 |
+| \_l2Token | Lib_PredeployAddresses.OVM_ETH | Контракт L2, который управляет ETH в Optimism, `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` (этот контракт предназначен только для внутреннего использования в Optimism) |
+| \_from | \_from | Адрес на L1, который отправляет ETH |
+| \_to | \_to | Адрес на L2, который получает ETH |
+| сумма | msg.value | Количество отправленных wei (которые уже отправлены на Мост) |
+| \_data | \_data | Дополнительные данные для присоединения к депозиту |
+
+```solidity
+ // Отправить calldata на L2
+ // slither-disable-next-line reentrancy-events
+ sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);
+```
+
+Отправьте сообщение через междоменный мессенджер.
+
+```solidity
+ // slither-disable-next-line reentrancy-events
+ emit ETHDepositInitiated(_from, _to, msg.value, _data);
+ }
+```
+
+Выпустить событие, чтобы уведомить любое децентрализованное приложение, которое отслеживает этот перевод.
+
+```solidity
+ /**
+ * @inheritdoc IL1ERC20Bridge
+ */
+ function depositERC20(
+ .
+ .
+ .
+ ) external virtual onlyEOA {
+ _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data);
+ }
+
+ /**
+ * @inheritdoc IL1ERC20Bridge
+ */
+ function depositERC20To(
+ .
+ .
+ .
+ ) external virtual {
+ _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data);
+ }
+```
+
+Эти две функции являются обертками `_initiateERC20Deposit`, функции, которая обрабатывает фактический депозит ERC-20.
+
+```solidity
+ /**
+ * @dev Выполняет логику для депозитов, информируя контракт депонированного токена L2
+ * о депозите и вызывая обработчик для блокировки средств на L1 (например, transferFrom).
+ *
+ * @param _l1Token Адрес ERC20 на L1, который мы вносим
+ * @param _l2Token Адрес соответствующего ERC20 на L2
+ * @param _from Аккаунт для снятия депозита на L1
+ * @param _to Аккаунт для зачисления депозита на L2
+ * @param _amount Сумма ERC20 для внесения.
+ * @param _l2Gas Лимит газа, необходимый для завершения депозита на L2.
+ * @param _data Необязательные данные для пересылки на L2. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function _initiateERC20Deposit(
+ address _l1Token,
+ address _l2Token,
+ address _from,
+ address _to,
+ uint256 _amount,
+ uint32 _l2Gas,
+ bytes calldata _data
+ ) internal {
+```
+
+Эта функция аналогична `_initiateETHDeposit` выше, но с несколькими важными отличиями.
+Первое отличие состоит в том, что эта функция получает адреса токенов и сумму для перевода в качестве параметров.
+В случае с ETH вызов Моста уже включает перевод актива на счет Моста (`msg.value`).
+
+```solidity
+ // Когда депозит инициируется на L1, Мост L1 переводит средства себе для будущих
+ // выводов. safeTransferFrom также проверяет, есть ли у контракта код, поэтому это не удастся, если
+ // _from является EOA или address(0).
+ // slither-disable-next-line reentrancy-events, reentrancy-benign
+ IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount);
+```
+
+Переводы токенов ERC-20 следуют иному процессу, чем ETH:
+
+1. Пользователь (`_from`) дает Мосту разрешение на перевод соответствующих токенов.
+2. Пользователь вызывает Мост, указывая адрес контракта токена, сумму и т. д.
+3. Мост переводит токены (самому себе) в рамках процесса депозита.
+
+Первый шаг может выполняться в отдельной транзакции от двух последних.
+Однако упреждающее выполнение (front-running) не является проблемой, поскольку две функции, которые вызывают `_initiateERC20Deposit` (`depositERC20` и `depositERC20To`), вызывают эту функцию только с `msg.sender` в качестве параметра `_from`.
+
+```solidity
+ // Конструируем calldata для _l2Token.finalizeDeposit(_to, _amount)
+ bytes memory message = abi.encodeWithSelector(
+ IL2ERC20Bridge.finalizeDeposit.selector,
+ _l1Token,
+ _l2Token,
+ _from,
+ _to,
+ _amount,
+ _data
+ );
+
+ // Отправить calldata на L2
+ // slither-disable-next-line reentrancy-events, reentrancy-benign
+ sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);
+
+ // slither-disable-next-line reentrancy-benign
+ deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount;
+```
+
+Добавьте внесенную сумму токенов в структуру данных `deposits`.
+На L2 может быть несколько адресов, соответствующих одному и тому же токену ERC-20 на L1, поэтому недостаточно использовать баланс Моста токена ERC-20 на L1 для отслеживания депозитов.
+
+```solidity
+
+ // slither-disable-next-line reentrancy-events
+ emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data);
+ }
+
+ /*************************
+ * Межсетевые функции *
+ *************************/
+
+ /**
+ * @inheritdoc IL1StandardBridge
+ */
+ function finalizeETHWithdrawal(
+ address _from,
+ address _to,
+ uint256 _amount,
+ bytes calldata _data
+```
+
+Мост L2 отправляет сообщение междоменному мессенджеру L2, который заставляет междоменный мессенджер L1 вызывать эту функцию (конечно, как только [транзакция, завершающая сообщение](https://community.optimism.io/docs/developers/bridge/messaging/#fees-for-l2-%E2%87%92-l1-transactions), будет отправлена на L1).
+
+```solidity
+ ) external onlyFromCrossDomainAccount(l2TokenBridge) {
+```
+
+Убедитесь, что это _легитимное_ сообщение, исходящее от междоменного мессенджера и отправленное с Моста токенов L2.
+Эта функция используется для вывода ETH с Моста, поэтому мы должны убедиться, что она вызывается только авторизованным вызывающим.
+
+```solidity
+ // slither-disable-next-line reentrancy-events
+ (bool success, ) = _to.call{ value: _amount }(new bytes(0));
+```
+
+Способ перевода ETH заключается в вызове получателя с суммой wei в `msg.value`.
+
+```solidity
+ require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
+
+ // slither-disable-next-line reentrancy-events
+ emit ETHWithdrawalFinalized(_from, _to, _amount, _data);
+```
+
+Выпустить событие о выводе средств.
+
+```solidity
+ }
+
+ /**
+ * @inheritdoc IL1ERC20Bridge
+ */
+ function finalizeERC20Withdrawal(
+ address _l1Token,
+ address _l2Token,
+ address _from,
+ address _to,
+ uint256 _amount,
+ bytes calldata _data
+ ) external onlyFromCrossDomainAccount(l2TokenBridge) {
+```
+
+Эта функция аналогична `finalizeETHWithdrawal` выше, с необходимыми изменениями для токенов ERC-20.
+
+```solidity
+ deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount;
+```
+
+Обновите структуру данных `deposits`.
+
+```solidity
+
+ // Когда вывод завершается на L1, Мост L1 переводит средства тому, кто их выводит
+ // slither-disable-next-line reentrancy-events
+ IERC20(_l1Token).safeTransfer(_to, _amount);
+
+ // slither-disable-next-line reentrancy-events
+ emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);
+ }
+
+
+ /*****************************
+ * Временно - миграция ETH *
+ *****************************/
+
+ /**
+ * @dev Добавляет баланс ETH на аккаунт. Это предназначено для того, чтобы
+ * ETH можно было перенести со старого шлюза на новый.
+ * ПРИМЕЧАНИЕ: Это оставлено только для одного обновления, чтобы мы могли получить перенесенный ETH со
+ * старого контракта
+ */
+ function donateETH() external payable {}
+}
+```
+
+Существовала более ранняя реализация Моста.
+Когда мы перешли от той реализации к этой, нам пришлось переместить все активы.
+Токены ERC-20 можно просто переместить.
+Однако для перевода ETH на контракт необходимо одобрение этого контракта, что нам и предоставляет `donateETH`.
+
+## Токены ERC-20 на L2 {#erc-20-tokens-on-l2}
+
+Чтобы токен ERC-20 подходил для стандартного Моста, он должен позволять стандартному Мосту и _только_ стандартному Мосту выпускать токены.
+Это необходимо, потому что Мосты должны гарантировать, что количество токенов, находящихся в обращении в сети Optimism, равно количеству токенов, заблокированных в контракте Моста L1.
+Если на L2 будет слишком много токенов, некоторые пользователи не смогут вернуть свои активы на L1 через Мост.
+Вместо доверенного Моста мы, по сути, воссоздали бы [частичное банковское резервирование](https://www.investopedia.com/terms/f/fractionalreservebanking.asp).
+Если на L1 слишком много токенов, некоторые из этих токенов навсегда останутся заблокированными в контракте Моста, потому что их невозможно освободить без сжигания токенов L2.
+
+### IL2StandardERC20 {#il2standarderc20}
+
+Каждый токен ERC-20 на L2, который использует стандартный Мост, должен предоставлять [этот интерфейс](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/IL2StandardERC20.sol), который содержит функции и события, необходимые стандартному Мосту.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.9;
+
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+```
+
+[Стандартный интерфейс ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) не включает функции `mint` и `burn`.
+Эти методы не требуются [стандартом ERC-20](https://eips.ethereum.org/EIPS/eip-20), который оставляет неуказанными механизмы создания и уничтожения токенов.
+
+```solidity
+import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+```
+
+[Интерфейс ERC-165](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol) используется для указания, какие функции предоставляет контракт.
+[Вы можете прочитать стандарт здесь](https://eips.ethereum.org/EIPS/eip-165).
+
+```solidity
+interface IL2StandardERC20 is IERC20, IERC165 {
+ function l1Token() external returns (address);
+```
+
+Эта функция предоставляет адрес токена L1, который переведен на этот контракт через Мост.
+Обратите внимание, что аналогичной функции в обратном направлении у нас нет.
+Нам нужно иметь возможность переводить через Мост любой токен L1, независимо от того, планировалась ли поддержка L2 при его реализации или нет.
+
+```solidity
+
+ function mint(address _to, uint256 _amount) external;
+
+ function burn(address _from, uint256 _amount) external;
+
+ event Mint(address indexed _account, uint256 _amount);
+ event Burn(address indexed _account, uint256 _amount);
+}
+```
+
+Функции и события для выпуска (создания) и сжигания (уничтожения) токенов.
+Мост должен быть единственной сущностью, которая может выполнять эти функции, чтобы гарантировать правильное количество токенов (равное количеству токенов, заблокированных на L1).
+
+### L2StandardERC20 {#L2StandardERC20}
+
+[Это наша реализация интерфейса `IL2StandardERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/L2StandardERC20.sol).
+Если вам не нужна какая-то специальная логика, вам следует использовать эту реализацию.
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.9;
+
+import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+```
+
+[Контракт ERC-20 от OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol).
+Optimism не верит в изобретение велосипеда, особенно когда велосипед хорошо проверен и должен быть достаточно надежным для хранения активов.
+
+```solidity
+import "./IL2StandardERC20.sol";
+
+contract L2StandardERC20 is IL2StandardERC20, ERC20 {
+ address public l1Token;
+ address public l2Bridge;
+```
+
+Это два дополнительных параметра конфигурации, которые нам требуются и которых обычно нет у ERC-20.
+
+```solidity
+
+ /**
+ * @param _l2Bridge Адрес стандартного Моста L2.
+ * @param _l1Token Адрес соответствующего токена L1.
+ * @param _name Название ERC20.
+ * @param _symbol Символ ERC20.
+ */
+ constructor(
+ address _l2Bridge,
+ address _l1Token,
+ string memory _name,
+ string memory _symbol
+ ) ERC20(_name, _symbol) {
+ l1Token = _l1Token;
+ l2Bridge = _l2Bridge;
+ }
+```
+
+Сначала вызовите конструктор контракта, от которого мы наследуем (`ERC20(_name, _symbol)`), а затем установите наши собственные переменные.
+
+```solidity
+
+ modifier onlyL2Bridge() {
+ require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn");
+ _;
+ }
+
+
+ // slither-disable-next-line external-function
+ function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
+ bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
+ bytes4 secondSupportedInterface = IL2StandardERC20.l1Token.selector ^
+ IL2StandardERC20.mint.selector ^
+ IL2StandardERC20.burn.selector;
+ return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
+ }
+```
+
+Именно так работает [ERC-165](https://eips.ethereum.org/EIPS/eip-165).
+Каждый интерфейс — это набор поддерживаемых функций, и он идентифицируется как [исключающее ИЛИ](https://en.wikipedia.org/wiki/Exclusive_or) [селекторов функций ABI](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html#function-selector) этих функций.
+
+Мост L2 использует ERC-165 в качестве проверки на вменяемость, чтобы убедиться, что контракт ERC-20, на который он отправляет активы, является `IL2StandardERC20`.
+
+**Примечание:** Ничто не мешает мошенническому контракту предоставлять ложные ответы на `supportsInterface`, поэтому это механизм проверки на вменяемость, а _не_ механизм безопасности.
+
+```solidity
+ // slither-disable-next-line external-function
+ function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {
+ _mint(_to, _amount);
+
+ emit Mint(_to, _amount);
+ }
+
+ // slither-disable-next-line external-function
+ function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {
+ _burn(_from, _amount);
+
+ emit Burn(_from, _amount);
+ }
+}
+```
+
+Только Мосту L2 разрешено выпускать и сжигать активы.
+
+`_mint` и `_burn` на самом деле определены в [контракте ERC-20 от OpenZeppelin](/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn).
+Этот контракт просто не предоставляет их внешне, потому что условия для выпуска и сжигания токенов столь же разнообразны, как и количество способов использования ERC-20.
+
+## Код Моста L2 {#l2-bridge-code}
+
+Это код, который запускает Мост на Optimism.
+[Исходный код этого контракта находится здесь](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol).
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.9;
+
+/* Interface Imports */
+import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol";
+import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol";
+import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol";
+```
+
+Интерфейс [IL2ERC20Bridge](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) очень похож на [эквивалент L1](#IL1ERC20Bridge), который мы видели выше.
+Есть два существенных различия:
+
+1. На L1 вы инициируете депозиты и завершаете вывод средств.
+ Здесь вы инициируете выводы и завершаете депозиты.
+2. На L1 необходимо различать токены ETH и ERC-20.
+ На L2 мы можем использовать одни и те же функции для обоих, поскольку внутренние балансы ETH в Optimism обрабатываются как токен ERC-20 с адресом [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://explorer.optimism.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000).
+
+```solidity
+/* Library Imports */
+import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
+import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol";
+import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol";
+
+/* Contract Imports */
+import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol";
+
+/**
+ * @title L2StandardBridge
+ * @dev Стандартный Мост L2 — это контракт, который работает совместно со стандартным Мостом L1
+ * для обеспечения переходов ETH и ERC20 между L1 и L2.
+ * Этот контракт действует как эмитент для новых токенов, когда он получает информацию о депозитах в стандартный
+ * Мост L1.
+ * Этот контракт также действует как сжигатель токенов, предназначенных для вывода, информируя
+ * Мост L1 о необходимости высвобождения средств L1.
+ */
+contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled {
+ /********************************
+ * Ссылки на внешние контракты *
+ ********************************/
+
+ address public l1TokenBridge;
+```
+
+Отслеживаем адрес Моста L1.
+Обратите внимание, что в отличие от эквивалента L1, здесь нам _необходима_ эта переменная.
+Адрес Моста L1 заранее не известен.
+
+```solidity
+
+ /***************
+ * Конструктор *
+ ***************/
+
+ /**
+ * @param _l2CrossDomainMessenger Междоменный мессенджер, используемый этим контрактом.
+ * @param _l1TokenBridge Адрес Моста L1, развернутого в основной сети.
+ */
+ constructor(address _l2CrossDomainMessenger, address _l1TokenBridge)
+ CrossDomainEnabled(_l2CrossDomainMessenger)
+ {
+ l1TokenBridge = _l1TokenBridge;
+ }
+
+ /***************
+ * Вывод средств *
+ ***************/
+
+ /**
+ * @inheritdoc IL2ERC20Bridge
+ */
+ function withdraw(
+ address _l2Token,
+ uint256 _amount,
+ uint32 _l1Gas,
+ bytes calldata _data
+ ) external virtual {
+ _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _l1Gas, _data);
+ }
+
+ /**
+ * @inheritdoc IL2ERC20Bridge
+ */
+ function withdrawTo(
+ address _l2Token,
+ address _to,
+ uint256 _amount,
+ uint32 _l1Gas,
+ bytes calldata _data
+ ) external virtual {
+ _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _l1Gas, _data);
+ }
+```
+
+Эти две функции инициируют вывод средств.
+Обратите внимание, что нет необходимости указывать адрес токена L1.
+Ожидается, что токены L2 сообщат нам адрес эквивалента на L1.
+
+```solidity
+
+ /**
+ * @dev Выполняет логику вывода средств, сжигая токен и информируя
+ * шлюз токенов L1 о выводе.
+ * @param _l2Token Адрес токена L2, на котором инициирован вывод.
+ * @param _from Аккаунт для списания выводимых средств на L2.
+ * @param _to Аккаунт для зачисления выводимых средств на L1.
+ * @param _amount Сумма токена для вывода.
+ * @param _l1Gas Не используется, но включен для потенциальной прямой совместимости.
+ * @param _data Необязательные данные для пересылки на L1. Эти данные предоставляются
+ * исключительно для удобства внешних контрактов. Кроме ограничения максимальной
+ * длины, эти контракты не дают никаких гарантий относительно их содержимого.
+ */
+ function _initiateWithdrawal(
+ address _l2Token,
+ address _from,
+ address _to,
+ uint256 _amount,
+ uint32 _l1Gas,
+ bytes calldata _data
+ ) internal {
+ // Когда инициируется вывод, мы сжигаем средства выводившего для предотвращения последующего использования на L2
+ // slither-disable-next-line reentrancy-events
+ IL2StandardERC20(_l2Token).burn(msg.sender, _amount);
+```
+
+Обратите внимание, что мы _не_ полагаемся на параметр `_from`, а на `msg.sender`, который намного сложнее подделать (насколько я знаю, невозможно).
+
+```solidity
+
+ // Конструируем calldata для l1TokenBridge.finalizeERC20Withdrawal(_to, _amount)
+ // slither-disable-next-line reentrancy-events
+ address l1Token = IL2StandardERC20(_l2Token).l1Token();
+ bytes memory message;
+
+ if (_l2Token == Lib_PredeployAddresses.OVM_ETH) {
+```
+
+На L1 необходимо различать ETH и ERC-20.
+
+```solidity
+ message = abi.encodeWithSelector(
+ IL1StandardBridge.finalizeETHWithdrawal.selector,
+ _from,
+ _to,
+ _amount,
+ _data
+ );
+ } else {
+ message = abi.encodeWithSelector(
+ IL1ERC20Bridge.finalizeERC20Withdrawal.selector,
+ l1Token,
+ _l2Token,
+ _from,
+ _to,
+ _amount,
+ _data
+ );
+ }
+
+ // Отправить сообщение на Мост L1
+ // slither-disable-next-line reentrancy-events
+ sendCrossDomainMessage(l1TokenBridge, _l1Gas, message);
+
+ // slither-disable-next-line reentrancy-events
+ emit WithdrawalInitiated(l1Token, _l2Token, msg.sender, _to, _amount, _data);
+ }
+
+ /************************************
+ * Межсетевая функция: Депозит *
+ ************************************/
+
+ /**
+ * @inheritdoc IL2ERC20Bridge
+ */
+ function finalizeDeposit(
+ address _l1Token,
+ address _l2Token,
+ address _from,
+ address _to,
+ uint256 _amount,
+ bytes calldata _data
+```
+
+Эта функция вызывается `L1StandardBridge`.
+
+```solidity
+ ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) {
+```
+
+Убедитесь, что источник сообщения легитимен.
+Это важно, потому что эта функция вызывает `_mint` и может быть использована для выдачи токенов, которые не покрыты токенами, принадлежащими Мосту на L1.
+
+```solidity
+ // Проверяем, что целевой токен соответствует требованиям, и
+ // убеждаемся, что депонированный токен на L1 соответствует представлению токена на L2
+ if (
+ // slither-disable-next-line reentrancy-events
+ ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) &&
+ _l1Token == IL2StandardERC20(_l2Token).l1Token()
+```
+
+Проверки на вменяемость:
+
+1. Поддерживается правильный интерфейс
+2. Адрес L1 контракта L2 ERC-20 соответствует источнику токенов на L1
+
+```solidity
+ ) {
+ // Когда депозит завершается, мы зачисляем на аккаунт на L2 такую же сумму
+ // токенов.
+ // slither-disable-next-line reentrancy-events
+ IL2StandardERC20(_l2Token).mint(_to, _amount);
+ // slither-disable-next-line reentrancy-events
+ emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);
+```
+
+Если проверки на вменяемость пройдены, завершите депозит:
+
+1. Выпустить токены
+2. Выпустить соответствующее событие
+
+```solidity
+ } else {
+ // Либо токен L2, на который делается депозит, не согласен с правильным адресом
+ // своего токена L1, либо не поддерживает правильный интерфейс.
+ // Это должно происходить только в случае вредоносного токена L2 или если пользователь как-то
+ // указал неправильный адрес токена L2 для депозита.
+ // В любом случае мы останавливаем процесс здесь и конструируем сообщение о выводе,
+ // чтобы пользователи в некоторых случаях могли вернуть свои средства.
+ // Невозможно полностью предотвратить вредоносные контракты токенов, но это ограничивает
+ // ошибки пользователя и смягчает некоторые формы вредоносного поведения контрактов.
+```
+
+Если пользователь допустил обнаруживаемую ошибку, используя неправильный адрес токена L2, мы хотим отменить депозит и вернуть токены на L1.
+Единственный способ сделать это с L2 — отправить сообщение, которому придется ждать периода оспаривания, но для пользователя это намного лучше, чем безвозвратная потеря токенов.
+
+```solidity
+ bytes memory message = abi.encodeWithSelector(
+ IL1ERC20Bridge.finalizeERC20Withdrawal.selector,
+ _l1Token,
+ _l2Token,
+ _to, // поменяли _to и _from местами, чтобы вернуть депозит отправителю
+ _from,
+ _amount,
+ _data
+ );
+
+ // Отправить сообщение на Мост L1
+ // slither-disable-next-line reentrancy-events
+ sendCrossDomainMessage(l1TokenBridge, 0, message);
+ // slither-disable-next-line reentrancy-events
+ emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _data);
+ }
+ }
+}
+```
+
+## Заключение {#conclusion}
+
+Стандартный Мост является наиболее гибким механизмом для перевода активов.
+Однако из-за своей универсальности он не всегда является самым простым в использовании механизмом.
+Особенно для вывода средств, большинство пользователей предпочитают использовать [сторонние Мосты](https://optimism.io/apps#bridge), которые не ждут периода оспаривания и не требуют доказательства Меркла для завершения вывода.
+
+Эти Мосты обычно работают за счет наличия активов на L1, которые они предоставляют немедленно за небольшую плату (часто меньшую, чем стоимость газа при стандартном выводе через Мост).
+Когда Мост (или люди, управляющие им) предвидит нехватку активов L1, он переводит достаточное количество активов с L2. Поскольку это очень крупные выводы, стоимость вывода амортизируется на большую сумму и составляет гораздо меньший процент.
+
+Надеемся, эта статья помогла вам лучше понять, как работает уровень 2 и как писать понятный и безопасный код на Solidity.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/reverse-engineering-a-contract/index.md b/public/content/translations/ru/developers/tutorials/reverse-engineering-a-contract/index.md
new file mode 100644
index 00000000000..fe2c2bdfe03
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/reverse-engineering-a-contract/index.md
@@ -0,0 +1,744 @@
+---
+title: "Обратный инжиниринг контракта"
+description: "Как понять контракт, если у вас нет исходного кода"
+author: Ori Pomerantz
+lang: ru
+tags: [ "evm", "опкоды" ]
+skill: advanced
+published: 2021-12-30
+---
+
+## Введение {#introduction}
+
+_В блокчейне нет секретов_, все, что происходит, последовательно, поддается проверке и общедоступно. В идеале [исходный код контрактов должен быть опубликован и верифицирован на Etherscan](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code). Однако [это не всегда так](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code). В этой статье вы узнаете, как проводить обратный инжиниринг контрактов на примере контракта без исходного кода, [`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f).
+
+Существуют обратные компиляторы, но они не всегда дают [пригодные для использования результаты](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f). В этой статье вы узнаете, как вручную провести обратный инжиниринг и понять контракт по [опкодам](https://github.com/wolflo/evm-opcodes), а также как интерпретировать результаты декомпилятора.
+
+Чтобы понять эту статью, вы уже должны знать основы EVM и хотя бы немного разбираться в ассемблере EVM. [Вы можете прочитать об этих темах здесь](https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e).
+
+## Подготовка исполняемого кода {#prepare-the-executable-code}
+
+Вы можете получить опкоды, зайдя на Etherscan для контракта, нажав на вкладку **Контракт** и затем на **Переключиться на вид опкодов**. Вы получите представление, в котором на каждой строке находится один опкод.
+
+
+
+Однако, чтобы понять переходы, вам нужно знать, где в коде расположен каждый опкод. Один из способов это сделать — открыть Google Таблицу и вставить опкоды в столбец C. [Вы можете пропустить следующие шаги, создав копию этой уже подготовленной таблицы](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing).
+
+Следующий шаг — получить правильные местоположения в коде, чтобы мы могли понимать переходы. Мы поместим размер опкода в столбец B, а местоположение (в шестнадцатеричном формате) в столбец A. Введите эту функцию в ячейку `B1`, а затем скопируйте и вставьте ее в остальные ячейки столбца B до конца кода. После этого вы можете скрыть столбец B.
+
+```
+=1+IF(REGEXMATCH(C1,"PUSH"),REGEXEXTRACT(C1,"PUSH(\d+)"),0)
+```
+
+Сначала эта функция добавляет один байт для самого опкода, а затем ищет `PUSH`. Опкоды Push особенные, потому что им требуются дополнительные байты для значения, которое помещается в стек. Если опкод является `PUSH`, мы извлекаем количество байт и добавляем его.
+
+В `A1` укажите первое смещение, ноль. Затем в `A2` введите эту функцию и снова скопируйте и вставьте ее в остальные ячейки столбца A:
+
+```
+=dec2hex(hex2dec(A1)+B1)
+```
+
+Нам нужна эта функция для получения шестнадцатеричного значения, потому что значения, помещаемые в стек перед переходами (`JUMP` и `JUMPI`), даны нам в шестнадцатеричном формате.
+
+## Точка входа (0x00) {#the-entry-point-0x00}
+
+Исполнение контрактов всегда начинается с первого байта. Это начальная часть кода:
+
+| Смещение | Опкод | Стек (после опкода) |
+| -------: | -------------------------------------------- | ---------------------------------------------- |
+| 0 | PUSH1 0x80 | 0x80 |
+| 2 | PUSH1 0x40 | 0x40, 0x80 |
+| 4 | Сохранить слово в память | Пусто |
+| 5 | PUSH1 0x04 | 0x04 |
+| 7 | Получить размер входных данных текущей среды | CALLDATASIZE 0x04 |
+| 8 | Меньше, чем сравниваемое | CALLDATASIZE\<4 |
+| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE\<4 |
+| C | Условно изменить счетчик команд | Пусто |
+
+Этот код делает две вещи:
+
+1. Записывает 0x80 как 32-байтное значение в ячейки памяти 0x40–0x5F (0x80 сохраняется в 0x5F, а 0x40–0x5E — все нули).
+2. Считывает размер данных вызова (calldata). Обычно данные вызова для контракта Ethereum соответствуют [ABI (двоичному интерфейсу приложения)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html), для которого требуется как минимум четыре байта для селектора функции. Если размер данных вызова меньше четырех, происходит переход к 0x5E.
+
+
+
+### Обработчик в 0x5E (для данных вызова не по ABI) {#the-handler-at-0x5e-for-non-abi-call-data}
+
+| Смещение | Опкод |
+| -------: | -------------------------------------------- |
+| 5E | Отметить допустимое место для прыжков |
+| 5F | Получить размер входных данных текущей среды |
+| 60 | PUSH2 0x007c |
+| 63 | Условно изменить счетчик команд |
+
+Этот фрагмент начинается с `JUMPDEST`. Программы EVM (виртуальной машины Ethereum) вызывают исключение, если вы переходите к опкоду, который не является `JUMPDEST`. Затем он смотрит на CALLDATASIZE, и если он «истинный» (то есть не нулевой), переходит к 0x7C. Мы вернемся к этому ниже.
+
+| Смещение | Опкод | Стек (после опкода) |
+| -------: | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
+| 64 | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение | [Wei](/glossary/#wei), предоставленные вызовом. В Solidity называется `msg.value` |
+| 65 | PUSH1 0x06 | 6 CALLVALUE |
+| 67 | PUSH1 0x00 | 0 6 CALLVALUE |
+| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE |
+| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE |
+| 6B | Загрузить слово из хранилища | Storage[6] CALLVALUE 0 6 CALLVALUE |
+
+Итак, когда нет данных вызова, мы считываем значение из Storage[6]. Мы еще не знаем, что это за значение, но мы можем поискать транзакции, которые контракт получил без данных вызова. Транзакции, которые просто переводят ETH без каких-либо данных вызова (и, следовательно, без метода), в Etherscan имеют метод `Transfer`. На самом деле, [самая первая транзакция, которую получил контракт](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7), — это перевод.
+
+Если мы посмотрим на эту транзакцию и нажмем **Щелкните, чтобы увидеть больше**, мы увидим, что данные вызова, называемые входными данными, действительно пусты (`0x`). Также обратите внимание, что значение равно 1,559 ETH, это будет важно позже.
+
+
+
+Затем щелкните вкладку **State** (Состояние) и разверните контракт, который мы реверс-инжинирим (0x2510...). Вы можете видеть, что `Storage[6]` изменилось во время транзакции, и если вы измените Hex на **Number**, вы увидите, что оно стало 1 559 000 000 000 000 000, значение, переведенное в wei (я добавил запятые для ясности), что соответствует следующему значению контракта.
+
+![Изменение в Storage[6]](storage6.png)
+
+Если мы посмотрим на изменения состояния, вызванные [другими транзакциями `Transfer` за тот же период](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange), мы увидим, что `Storage[6]` некоторое время отслеживало стоимость контракта. Пока назовем его `Value*`. Звездочка (`*`) напоминает нам, что мы еще _не знаем_, что делает эта переменная, но она не может использоваться просто для отслеживания стоимости контракта, потому что нет необходимости использовать хранилище, которое очень дорого, когда вы можете получить баланс вашего счета с помощью `ADDRESS BALANCE`. Первый опкод помещает в стек собственный адрес контракта. Второй считывает адрес на вершине стека и заменяет его балансом этого адреса.
+
+| Смещение | Опкод | Стек |
+| -------: | ----------------------- | ------------------------------------------- |
+| 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE |
+| 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE |
+| 70 | SWAP1 | Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 74 | Изменить счетчик команд | |
+
+Мы продолжим отслеживать этот код в месте назначения перехода.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ----------------------------------------------------------- |
+| 1A7 | Отметить допустимое место для прыжков | Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1AB | Побитовое НЕ операция | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+
+Операция `NOT` является побитовой, поэтому она инвертирует каждый бит значения вызова.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------- | ------------------------------------------------------------------------------------------------------ |
+| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1AD | Больше, чем сравниваемое | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1AE | Просто НЕ оператор | Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1AF | PUSH2 0x01df | 0x01DF Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1B2 | Условно изменить счетчик команд | |
+
+Мы переходим, если `Value*` меньше или равно 2^256-CALLVALUE-1. Это похоже на логику предотвращения переполнения. И действительно, мы видим, что после нескольких бессмысленных операций (например, запись в память, которая вот-вот будет удалена) по смещению 0x01DE контракт возвращается, если обнаруживается переполнение, что является нормальным поведением.
+
+Обратите внимание, что такое переполнение крайне маловероятно, потому что для этого потребуется, чтобы значение вызова плюс `Value*` было сопоставимо с 2^256 wei, что составляет около 10^59 ETH. [Общее количество ETH на момент написания статьи составляет менее двухсот миллионов](https://etherscan.io/stat/supply).
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ----------------------------------------- |
+| 1DF | Отметить допустимое место для прыжков | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1E0 | удалить слово из стека | Value\* CALLVALUE 0x75 0 6 CALLVALUE |
+| 1E1 | Добавление | Value\*+CALLVALUE 0x75 0 6 CALLVALUE |
+| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE |
+| 1E3 | Изменить счетчик команд | |
+
+Если мы попали сюда, получаем `Value* + CALLVALUE` и переходим к смещению 0x75.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ------------------------------- |
+| 75 | Отметить допустимое место для прыжков | Value\*+CALLVALUE 0 6 CALLVALUE |
+| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE |
+| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE |
+| 78 | Сохранить слово в хранилище | 0 CALLVALUE |
+
+Если мы попадем сюда (что требует, чтобы данные вызова были пустыми), мы добавляем к `Value*` значение вызова. Это соответствует тому, что мы видим в транзакциях `Transfer`.
+
+| Смещение | Опкод |
+| -------: | ----------------------- |
+| 79 | удалить слово из стека |
+| 7A | удалить слово из стека |
+| 7B | Приостановка выполнения |
+
+Наконец, очистите стек (что не является необходимым) и сигнализируйте об успешном завершении транзакции.
+
+Подводя итог, вот блок-схема для начального кода.
+
+
+
+## Обработчик в 0x7C {#the-handler-at-0x7c}
+
+Я намеренно не указал в заголовке, что делает этот обработчик. Цель состоит не в том, чтобы научить вас, как работает этот конкретный контракт, а в том, как проводить обратный инжиниринг контрактов. Вы узнаете, что он делает, так же, как и я, следуя коду.
+
+Мы попадаем сюда из нескольких мест:
+
+- Если есть данные вызова размером 1, 2 или 3 байта (со смещения 0x63)
+- Если сигнатура метода неизвестна (со смещений 0x42 и 0x5D)
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ------------------------------------------------------------------------ |
+| 7C | Отметить допустимое место для прыжков | |
+| 7D | PUSH1 0x00 | 0x00 |
+| 7F | PUSH2 0x009d | 0x9D 0x00 |
+| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 |
+| 84 | Загрузить слово из хранилища | Storage[3] 0x9D 0x00 |
+
+Это еще одна ячейка хранилища, которую я не смог найти ни в одной транзакции, поэтому труднее понять, что она означает. Код ниже сделает это яснее.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 |
+| 9A | Побитовое И операция | Storage[3]-as-address 0x9D 0x00 |
+
+Эти опкоды усекают значение, которое мы считываем из Storage[3], до 160 бит, длины адреса Ethereum.
+
+| Смещение | Опкод | Стек |
+| -------: | ----------------------- | ----------------------------------------------------------------------------------- |
+| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 |
+| 9C | Изменить счетчик команд | Storage[3]-as-address 0x00 |
+
+Этот переход является излишним, так как мы переходим к следующему опкоду. Этот код далеко не так эффективен с точки зрения расхода газа, как мог бы быть.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
+| 9D | Отметить допустимое место для прыжков | Storage[3]-as-address 0x00 |
+| 9E | SWAP1 | 0x00 Storage[3]-as-address |
+| 9F | удалить слово из стека | Storage[3]-as-address |
+| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address |
+| A2 | Загрузить слово из памяти | Mem[0x40] Storage[3]-as-address |
+
+В самом начале кода мы установили Mem[0x40] в 0x80. Если мы посмотрим на 0x40 позже, то увидим, что мы его не меняем, поэтому можно предположить, что это 0x80.
+
+| Смещение | Опкод | Стек |
+| -------: | -------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
+| A3 | Получить размер входных данных текущей среды | CALLDATASIZE 0x80 Storage[3]-as-address |
+| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address |
+| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address |
+| A7 | Скопировать входных данные текущей среды | 0x80 Storage[3]-as-address |
+
+Скопируйте все данные вызова в память, начиная с 0x80.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address |
+| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address |
+| AB | Получить размер входных данных текущей среды | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address |
+| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address |
+| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address |
+| AE | Получить количество доступного газа, включая соответсвующее сокращение количества доступного газа | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address |
+| AF | DELEGATE_CALL | |
+
+Теперь все стало намного яснее. Этот контракт может действовать как [прокси](https://blog.openzeppelin.com/proxy-patterns/), вызывая адрес в Storage[3] для выполнения реальной работы. `DELEGATE_CALL` вызывает отдельный контракт, но остается в том же хранилище. Это означает, что делегированный контракт, для которого мы являемся прокси, получает доступ к тому же пространству хранилища. Параметры вызова:
+
+- _Газ_: весь оставшийся газ
+- _Вызываемый адрес_: Storage[3]-as-address
+- _Данные вызова_: байты CALLDATASIZE, начинающиеся с 0x80, куда мы поместили исходные данные вызова
+- _Возвращаемые данные_: нет (0x00 - 0x00) Мы получим возвращаемые данные другими способами (см. ниже)
+
+| Смещение | Опкод | Стек |
+| -------: | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| B0 | RETURNDATASIZE | RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B5 | RETURNDATACOPY | RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+
+Здесь мы копируем все возвращаемые данные в буфер памяти, начиная с 0x80.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| B6 | DUP2 | (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B7 | DUP1 | (((успех/неудача вызова))) (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B8 | Просто НЕ оператор | (((произошла ли ошибка вызова))) (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| B9 | PUSH2 0x00c0 | 0xC0 (((произошла ли ошибка вызова))) (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| BC | Условно изменить счетчик команд | (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| BD | DUP2 | RETURNDATASIZE (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| BE | DUP5 | 0x80 RETURNDATASIZE (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| BF | RETURN | |
+
+Таким образом, после вызова мы копируем возвращаемые данные в буфер 0x80 - 0x80+RETURNDATASIZE, и если вызов успешен, мы затем выполняем `RETURN` с этим же буфером.
+
+### Ошибка DELEGATECALL {#delegatecall-failed}
+
+Если мы попадаем сюда, в 0xC0, это означает, что вызванный нами контракт был отменен. Поскольку мы являемся лишь прокси для этого контракта, мы хотим вернуть те же данные и также выполнить откат.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| C0 | Отметить допустимое место для прыжков | (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| C1 | DUP2 | RETURNDATASIZE (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| C2 | DUP5 | 0x80 RETURNDATASIZE (((успех/неудача вызова))) RETURNDATASIZE (((успех/неудача вызова))) 0x80 Storage[3]-as-address |
+| C3 | REVERT | |
+
+Итак, мы выполняем `REVERT` с тем же буфером, который использовали для `RETURN` ранее: 0x80 - 0x80+RETURNDATASIZE
+
+
+
+## Вызовы ABI {#abi-calls}
+
+Если размер данных вызова составляет четыре байта или более, это может быть действительный вызов ABI.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
+| D | PUSH1 0x00 | 0x00 |
+| F | Получить входные данные текущей среды | (((Первое слово (256 бит) данных вызова))) |
+| 10 | PUSH1 0xe0 | 0xE0 (((Первое слово (256 бит) данных вызова))) |
+| 12 | Сместиться вправо | (((первые 32 бита (4 байта) данных вызова))) |
+
+Etherscan сообщает нам, что `1C` — это неизвестный опкод, потому что [он был добавлен после того, как Etherscan написал эту функцию](https://eips.ethereum.org/EIPS/eip-145), и они ее еще не обновили. [Актуальная таблица опкодов](https://github.com/wolflo/evm-opcodes) показывает нам, что это сдвиг вправо.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| 13 | DUP1 | (((первые 32 бита (4 байта) данных вызова))) (((первые 32 бита (4 байта) данных вызова))) |
+| 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((первые 32 бита (4 байта) данных вызова))) (((первые 32 бита (4 байта) данных вызова))) |
+| 19 | Больше, чем сравниваемое | 0x3CD8045E>первые-32-бита-данных-вызова (((первые 32 бита (4 байта) данных вызова))) |
+| 1А | PUSH2 0x0043 | 0x43 0x3CD8045E>первые-32-бита-данных-вызова (((первые 32 бита (4 байта) данных вызова))) |
+| 1D | Условно изменить счетчик команд | (((первые 32 бита (4 байта) данных вызова))) |
+
+Разделение тестов на соответствие сигнатуры метода на две части таким образом экономит в среднем половину тестов. Код, который следует сразу за этим, и код в 0x43 следуют одному и тому же шаблону: `DUP1` первые 32 бита данных вызова, `PUSH4 (((сигнатура метода)))`, запуск `EQ` для проверки на равенство, а затем `JUMPI`, если сигнатура метода совпадает. Вот сигнатуры методов, их адреса и, если известно, [соответствующее определение метода](https://www.4byte.directory/):
+
+| Метод | Сигнатура метода | Смещение для перехода |
+| --------------------------------------------------------------------------------------------------------- | ---------------- | --------------------- |
+| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 |
+| ??? | 0x81e580d3 | 0x0138 |
+| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 |
+| ??? | 0x1f135823 | 0x00C4 |
+| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED |
+
+Если совпадение не найдено, код переходит к [обработчику прокси по адресу 0x7C](#the-handler-at-0x7c) в надежде, что контракт, для которого мы являемся прокси, найдет совпадение.
+
+
+
+## splitter() {#splitter}
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
+| 103 | Отметить допустимое место для прыжков | |
+| 104 | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение |
+| 105 | DUP1 | CALLVALUE CALLVALUE |
+| 106 | Просто НЕ оператор | CALLVALUE==0 CALLVALUE |
+| 107 | PUSH2 0x010f | 0x010F CALLVALUE==0 CALLVALUE |
+| 10A | Условно изменить счетчик команд | Получение внесенной суммы по инструкции/транзакция отвечающая за это выполнение |
+| 10B | PUSH1 0x00 | 0x00 CALLVALUE |
+| 10D | DUP1 | 0x00 0x00 CALLVALUE |
+| 10E | REVERT | |
+
+Первое, что делает эта функция, — проверяет, что вызов не отправил ETH. Эта функция не является [`payable`](https://solidity-by-example.org/payable/). Если кто-то отправил нам ETH, это должно быть ошибкой, и мы хотим выполнить `REVERT`, чтобы избежать ситуации, когда эти ETH станут недоступны для возврата.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 10F | Отметить допустимое место для прыжков | |
+| 110 | удалить слово из стека | |
+| 111 | PUSH1 0x03 | 0x03 |
+| 113 | Загрузить слово из хранилища | (((Storage[3], т. е. контракт, для которого мы являемся прокси))) |
+| 114 | PUSH1 0x40 | 0x40 (((Storage[3], т. е. контракт, для которого мы являемся прокси))) |
+| 116 | Загрузить слово из памяти | 0x80 (((Storage[3], т. е. контракт, для которого мы являемся прокси))) |
+| 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3], т. е. контракт, для которого мы являемся прокси))) |
+| 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3], т. е. контракт, для которого мы являемся прокси))) |
+| 12D | SWAP2 | (((Storage[3], т. е. контракт, для которого мы являемся прокси))) 0xFF...FF 0x80 |
+| 12E | Побитовое И операция | ProxyAddr 0x80 |
+| 12F | DUP2 | 0x80 ProxyAddr 0x80 |
+| 130 | Сохранить слово в память | 0x80 |
+
+И 0x80 теперь содержит адрес прокси
+
+| Смещение | Опкод | Стек |
+| -------: | ----------------------- | --------- |
+| 131 | PUSH1 0x20 | 0x20 0x80 |
+| 133 | Добавление | 0xA0 |
+| 134 | PUSH2 0x00e4 | 0xE4 0xA0 |
+| 137 | Изменить счетчик команд | 0xA0 |
+
+### Код E4 {#the-e4-code}
+
+Мы впервые видим эти строки, но они используются и в других методах (см. ниже). Итак, мы назовем значение в стеке X и просто запомним, что в `splitter()` значение этого X равно 0xA0.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ----------- |
+| E4 | Отметить допустимое место для прыжков | X |
+| E5 | PUSH1 0x40 | 0x40 X |
+| E7 | Загрузить слово из памяти | 0x80 X |
+| E8 | DUP1 | 0x80 0x80 X |
+| E9 | SWAP2 | X 0x80 0x80 |
+| EA | Вычитание | X-0x80 0x80 |
+| EB | SWAP1 | 0x80 X-0x80 |
+| EC | RETURN | |
+
+Таким образом, этот код получает указатель на память в стеке (X) и заставляет контракт выполнить `RETURN` с буфером, равным 0x80 - X.
+
+В случае `splitter()` это возвращает адрес, для которого мы являемся прокси. `RETURN` возвращает буфер в 0x80-0x9F, куда мы и записали эти данные (смещение 0x130 выше).
+
+## currentWindow() {#currentwindow}
+
+Код в смещениях 0x158-0x163 идентичен тому, что мы видели в 0x103-0x10E в `splitter()` (за исключением адреса назначения `JUMPI`), поэтому мы знаем, что `currentWindow()` также не является `payable`.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ------------------------------------------------------------------------ |
+| 164 | Отметить допустимое место для прыжков | |
+| 165 | удалить слово из стека | |
+| 166 | PUSH2 0x00da | 0xDA |
+| 169 | PUSH1 0x01 | 0x01 0xDA |
+| 16B | Загрузить слово из хранилища | Storage[1] 0xDA |
+| 16C | DUP2 | 0xDA Storage[1] 0xDA |
+| 16D | Изменить счетчик команд | Storage[1] 0xDA |
+
+### Код DA {#the-da-code}
+
+Этот код также используется совместно с другими методами. Поэтому мы назовем значение в стеке Y и просто запомним, что в `currentWindow()` значение Y равно Storage[1].
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ---------------- |
+| DA | Отметить допустимое место для прыжков | Y 0xDA |
+| DB | PUSH1 0x40 | 0x40 Y 0xDA |
+| DD | Загрузить слово из памяти | 0x80 Y 0xDA |
+| DE | SWAP1 | Y 0x80 0xDA |
+| DF | DUP2 | 0x80 Y 0x80 0xDA |
+| E0 | Сохранить слово в память | 0x80 0xDA |
+
+Запишите Y в 0x80-0x9F.
+
+| Смещение | Опкод | Стек |
+| -------: | ---------- | -------------- |
+| E1 | PUSH1 0x20 | 0x20 0x80 0xDA |
+| E3 | Добавление | 0xA0 0xDA |
+
+А остальное уже объяснено [выше](#the-e4-code). Таким образом, переходы к 0xDA записывают верхний элемент стека (Y) в 0x80-0x9F и возвращают это значение. В случае `currentWindow()` возвращается Storage[1].
+
+## merkleRoot() {#merkleroot}
+
+Код в смещениях 0xED-0xF8 идентичен тому, что мы видели в 0x103-0x10E в `splitter()` (за исключением адреса назначения `JUMPI`), поэтому мы знаем, что `merkleRoot()` также не является `payable`.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ------------------------------------------------------------------------ |
+| F9 | Отметить допустимое место для прыжков | |
+| FA | удалить слово из стека | |
+| FB | PUSH2 0x00da | 0xDA |
+| FE | PUSH1 0x00 | 0x00 0xDA |
+| 100 | Загрузить слово из хранилища | Storage[0] 0xDA |
+| 101 | DUP2 | 0xDA Storage[0] 0xDA |
+| 102 | Изменить счетчик команд | Storage[0] 0xDA |
+
+Что происходит после прыжка, [мы уже выяснили](#the-da-code). Таким образом, `merkleRoot()` возвращает Storage[0].
+
+## 0x81e580d3 {#0x81e580d3}
+
+Код в смещениях 0x138-0x143 идентичен тому, что мы видели в 0x103-0x10E в `splitter()` (за исключением адреса назначения `JUMPI`), поэтому мы знаем, что эта функция также не является `payable`.
+
+| Смещение | Опкод | Стек |
+| -------: | -------------------------------------------- | ------------------------------------------------------------------------------- |
+| 144 | Отметить допустимое место для прыжков | |
+| 145 | удалить слово из стека | |
+| 146 | PUSH2 0x00da | 0xDA |
+| 149 | PUSH2 0x0153 | 0x0153 0xDA |
+| 14C | Получить размер входных данных текущей среды | CALLDATASIZE 0x0153 0xDA |
+| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA |
+| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA |
+| 152 | Изменить счетчик команд | 0x04 CALLDATASIZE 0x0153 0xDA |
+| 18F | Отметить допустимое место для прыжков | 0x04 CALLDATASIZE 0x0153 0xDA |
+| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 196 | Вычитание | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 197 | Подписано меньше, чем сравниваемое | CALLDATASIZE-4\<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 198 | Просто НЕ оператор | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 19C | Условно изменить счетчик команд | 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+
+Похоже, эта функция принимает по меньшей мере 32 байта (одно слово) данных вызова.
+
+| Смещение | Опкод | Стек |
+| -------: | ------ | -------------------------------------------- |
+| 19D | DUP1 | 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 19F | REVERT | |
+
+Если она не получает данные вызова, транзакция отменяется без каких-либо возвращаемых данных.
+
+Давайте посмотрим, что произойдет, если функция _получит_ необходимые ей данные вызова.
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | ----------------------------------------------------------- |
+| 1A0 | Отметить допустимое место для прыжков | 0x00 0x04 CALLDATASIZE 0x0153 0xDA |
+| 1A1 | удалить слово из стека | 0x04 CALLDATASIZE 0x0153 0xDA |
+| 1A2 | Получить входные данные текущей среды | calldataload(4) CALLDATASIZE 0x0153 0xDA |
+
+`calldataload(4)` — это первое слово данных вызова _после_ сигнатуры метода
+
+| Смещение | Опкод | Стек |
+| -------: | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA |
+| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA |
+| 1A5 | удалить слово из стека | 0x0153 calldataload(4) 0xDA |
+| 1A6 | Изменить счетчик команд | calldataload(4) 0xDA |
+| 153 | Отметить допустимое место для прыжков | calldataload(4) 0xDA |
+| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA |
+| 157 | Изменить счетчик команд | calldataload(4) 0xDA |
+| 16E | Отметить допустимое место для прыжков | calldataload(4) 0xDA |
+| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA |
+| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA |
+| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA |
+| 173 | Загрузить слово из хранилища | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA |
+| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA |
+| 175 | Меньше, чем сравниваемое | calldataload(4)\)`, а другой — `isClaimed()`, так что это похоже на контракт для аирдропа. Вместо того чтобы проходить через остальные опкоды по одному, мы можем [попробовать декомпилятор](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761), который дает пригодные для использования результаты для трех функций из этого контракта. Обратный инжиниринг остальных оставляется в качестве упражнения для читателя.
+
+### scaleAmountByPercentage {#scaleamountbypercentage}
+
+Вот что декомпилятор выдает для этой функции:
+
+```python
+def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable:
+ require calldata.size - 4 >=′ 64
+ if _param1 and _param2 > -1 / _param1:
+ revert with 0, 17
+ return (_param1 * _param2 / 100 * 10^6)
+```
+
+Первое требование `require` проверяет, что данные вызова, помимо четырех байтов сигнатуры функции, содержат не менее 64 байтов, что достаточно для двух параметров. Если нет, то очевидно, что что-то не так.
+
+Оператор `if`, по-видимому, проверяет, что `_param1` не равен нулю, и что `_param1 * _param2` не является отрицательным. Вероятно, это сделано для предотвращения случаев переполнения.
+
+Наконец, функция возвращает масштабированное значение.
+
+### claim {#claim}
+
+Код, создаваемый декомпилятором, сложен, и не весь он имеет для нас значение. Я пропущу некоторые его части, чтобы сосредоточиться на строках, которые, по моему мнению, содержат полезную информацию.
+
+```python
+def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _param4) payable:
+ ...
+ require _param2 == addr(_param2)
+ ...
+ if currentWindow <= _param1:
+ revert with 0, 'cannot claim for a future window'
+```
+
+Здесь мы видим две важные вещи:
+
+- `_param2`, хотя он объявлен как `uint256`, на самом деле является адресом.
+- `_param1` — это окно, на которое подается заявка, и оно должно быть `currentWindow` или раньше.
+
+```python
+ ...
+ if stor5[_claimWindow][addr(_claimFor)]:
+ revert with 0, 'Account already claimed the given window'
+```
+
+Итак, теперь мы знаем, что Storage[5] — это массив окон и адресов, и в нем хранится информация о том, получил ли адрес вознаграждение за это окно.
+
+```python
+ ...
+ idx = 0
+ s = 0
+ while idx < _param4.length:
+ ...
+ if s + sha3(mem[(32 * _param4.length) + 328 len mem[(32 * _param4.length) + 296]]) > mem[(32 * idx) + 296]:
+ mem[mem[64] + 32] = mem[(32 * idx) + 296]
+ ...
+ s = sha3(mem[_62 + 32 len mem[_62]])
+ continue
+ ...
+ s = sha3(mem[_66 + 32 len mem[_66]])
+ continue
+ if unknown2eb4a7ab != s:
+ revert with 0, 'Invalid proof'
+```
+
+Мы знаем, что `unknown2eb4a7ab` на самом деле является функцией `merkleRoot()`, поэтому этот код, похоже, проверяет [доказательство Меркла](https://medium.com/crypto-0-nite/merkle-proofs-explained-6dd429623dc5). Это означает, что `_param4` является доказательством Меркла.
+
+```python
+ call addr(_param2) with:
+ value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei
+ gas 30000 wei
+```
+
+Именно так контракт переводит свои собственные ETH на другой адрес (контракт или внешний счет). Он вызывает его со значением, равным сумме для перевода. Так что похоже, это аирдроп ETH.
+
+```python
+ if not return_data.size:
+ if not ext_call.success:
+ require ext_code.size(stor2)
+ call stor2.deposit() with:
+ value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei
+```
+
+Две нижние строки говорят нам, что Storage[2] — это тоже контракт, который мы вызываем. Если мы [посмотрим на транзакцию конструктора](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange), мы увидим, что этот контракт — [0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), контракт на обернутый эфир, [исходный код которого был загружен на Etherscan](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code).
+
+Похоже, контракты пытаются отправить ETH на `_param2`. Если это удастся, отлично. Если нет, он пытается отправить [WETH](https://weth.tkn.eth.limo/). Если `_param2` является внешним счетом (EOA), то он всегда может получать ETH, но контракты могут отказываться от получения ETH. Однако WETH — это ERC-20, и контракты не могут отказаться от его приема.
+
+```python
+ ...
+ log 0xdbd5389f: addr(_param2), unknown81e580d3[_param1] * _param3 / 100 * 10^6, bool(ext_call.success)
+```
+
+В конце функции мы видим, что создается запись в журнале. [Посмотрите на сгенерированные записи в журнале](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events) и отфильтруйте по теме, которая начинается с `0xdbd5...`. Если мы [щелкнем по одной из транзакций, сгенерировавших такую запись](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274), мы увидим, что это действительно похоже на получение вознаграждения — аккаунт отправил сообщение контракту, который мы реверс-инжинирим, и взамен получил ETH.
+
+
+
+### 1e7df9d3 {#1e7df9d3}
+
+Эта функция очень похожа на [`claim`](#claim) выше. Он также проверяет доказательство Меркла, пытается перевести ETH первому и создает тот же тип записи в журнале.
+
+```python
+def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable:
+ ...
+ idx = 0
+ s = 0
+ while idx < _param3.length:
+ if idx >= mem[96]:
+ revert with 0, 50
+ _55 = mem[(32 * idx) + 128]
+ if s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]]) > mem[(32 * idx) + 128]:
+ ...
+ s = sha3(mem[_58 + 32 len mem[_58]])
+ continue
+ mem[mem[64] + 32] = s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]])
+ ...
+ if unknown2eb4a7ab != s:
+ revert with 0, 'Invalid proof'
+ ...
+ call addr(_param1) with:
+ value s wei
+ gas 30000 wei
+ if not return_data.size:
+ if not ext_call.success:
+ require ext_code.size(stor2)
+ call stor2.deposit() with:
+ value s wei
+ gas gas_remaining wei
+ ...
+ log 0xdbd5389f: addr(_param1), s, bool(ext_call.success)
+```
+
+Основное отличие в том, что первый параметр, окно для вывода средств, отсутствует. Вместо этого есть цикл по всем окнам, которые можно было бы затребовать.
+
+```python
+ idx = 0
+ s = 0
+ while idx < currentWindow:
+ ...
+ if stor5[mem[0]]:
+ if idx == -1:
+ revert with 0, 17
+ idx = idx + 1
+ s = s
+ continue
+ ...
+ stor5[idx][addr(_param1)] = 1
+ if idx >= unknown81e580d3.length:
+ revert with 0, 50
+ mem[0] = 4
+ if unknown81e580d3[idx] and _param2 > -1 / unknown81e580d3[idx]:
+ revert with 0, 17
+ if s > !(unknown81e580d3[idx] * _param2 / 100 * 10^6):
+ revert with 0, 17
+ if idx == -1:
+ revert with 0, 17
+ idx = idx + 1
+ s = s + (unknown81e580d3[idx] * _param2 / 100 * 10^6)
+ continue
+```
+
+Так что это похоже на вариант `claim`, который запрашивает все окна.
+
+## Заключение {#conclusion}
+
+К настоящему моменту вы должны знать, как понимать контракты, исходный код которых недоступен, используя либо опкоды, либо (когда это работает) декомпилятор. Как видно из длины этой статьи, обратный инжиниринг контракта — нетривиальная задача, но в системе, где безопасность имеет первостепенное значение, умение проверять, что контракты работают, как обещано, является важным навыком.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/ru/developers/tutorials/run-node-raspberry-pi/index.md
new file mode 100644
index 00000000000..b1bee9d94bd
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/run-node-raspberry-pi/index.md
@@ -0,0 +1,190 @@
+---
+title: "Запуск узла Ethereum на Raspeberry Pi 4"
+description: "Прошейте Raspberry Pi 4, подключите кабель Ethernet, подсоедините SSD-диск и включите устройство, чтобы превратить Raspberry Pi 4 в полноценный узел и валидатор Ethereum"
+author: "EthereumOnArm"
+tags:
+ [
+ "клиенты",
+ "Уровень исполнения",
+ "уровень консенсуса",
+ "узлы"
+ ]
+lang: ru
+skill: intermediate
+published: 2022-06-10
+source: Ethereum on ARM
+sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/
+---
+
+**Ethereum on Arm — это специальный образ Linux, который может превратить Raspberry Pi в узел Ethereum.**
+
+Чтобы использовать Ethereum on Arm для превращения Raspberry Pi в узел Ethereum, рекомендуется следующее оборудование:
+
+- Платы Raspberry 4 (модель B, 8 ГБ), Odroid M1 или Rock 5B (8/16 ГБ ОЗУ)
+- Карта MicroSD (минимум 16 ГБ, класс 10)
+- SSD-диск объемом не менее 2 ТБ с интерфейсом USB 3.0 или SSD-диск с корпусом-переходником USB-SATA.
+- Блок питания
+- Кабель Ethernet
+- Переадресация портов (для получения дополнительной информации см. раздел «Клиенты»)
+- Корпус с радиатором и вентилятором
+- USB-клавиатура, монитор и кабель HDMI (micro-HDMI) (необязательно)
+
+## Зачем запускать Ethereum на ARM? {#why-run-ethereum-on-arm}
+
+Платы ARM — это очень доступные, гибкие и небольшие компьютеры. Они хорошо подходят для запуска узлов Ethereum, потому что их можно дешево купить, настроить так, чтобы все их ресурсы были сосредоточены только на узле, что делает их эффективными, они потребляют мало энергии и физически малы, поэтому могут незаметно разместиться в любом доме. Также очень легко запустить узлы, потому что MicroSD-карту Raspberry Pi можно просто прошить готовым образом, не требуя загрузки или сборки программного обеспечения.
+
+## Как это работает? {#how-does-it-work}
+
+Карта памяти Raspberry Pi прошивается готовым образом. Этот образ содержит все необходимое для запуска узла Ethereum. С прошитой картой все, что нужно сделать пользователю, это включить Raspberry Pi. Все процессы, необходимые для запуска узла, запускаются автоматически. Это работает, потому что на карте памяти установлена операционная система (ОС) на базе Linux, поверх которой автоматически запускаются системные процессы, превращающие устройство в узел Ethereum.
+
+Ethereum нельзя запустить на популярной ОС для Raspberry Pi "Raspbian", так как Raspbian все еще использует 32-битную архитектуру, что приводит к проблемам с памятью у пользователей Ethereum, а клиенты консенсуса не поддерживают 32-битные двоичные файлы. Чтобы решить эту проблему, команда Ethereum on Arm перешла на нативную 64-битную ОС под названием "Armbian".
+
+**Образы берут на себя все необходимые шаги**: от настройки среды и форматирования SSD-диска до установки и запуска программного обеспечения Ethereum, а также запуска синхронизации блокчейна.
+
+## Примечание о клиентах исполнения и клиентах консенсуса {#note-on-execution-and-consensus-clients}
+
+Образ Ethereum on Arm включает в себя готовые клиенты исполнения и клиенты консенсуса в качестве служб. Для узла Ethereum требуется, чтобы оба клиента были синхронизированы и запущены. Вам нужно только скачать и прошить образ, а затем запустить службы. В образ предварительно загружены следующие клиенты исполнения:
+
+- Geth
+- Nethermind
+- Besu
+
+и следующие клиенты консенсуса:
+
+- Lighthouse
+- Nimbus
+- Prysm
+- Teku
+
+Вам нужно выбрать по одному клиенту каждого типа для запуска — все клиенты исполнения совместимы со всеми клиентами консенсуса. Если вы не выберете клиент явно, узел вернется к настройкам по умолчанию — Geth и Lighthouse — и запустит их автоматически при включении платы. Вы должны открыть порт 30303 на своем маршрутизаторе, чтобы Geth мог находить пиров и подключаться к ним.
+
+## Загрузка образа {#downloading-the-image}
+
+Образ Ethereum для Raspberry Pi 4 — это образ "plug and play", который автоматически устанавливает и настраивает как клиенты исполнения, так и клиенты консенсуса, настраивая их для взаимодействия друг с другом и подключения к сети Ethereum. Все, что нужно сделать пользователю, — это запустить их процессы с помощью простой команды.
+
+Загрузите образ Raspberry Pi с [Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1) и проверьте хэш SHA256:
+
+```sh
+# Из каталога, содержащего загруженный образ
+shasum -a 256 ethonarm_22.04.00.img.zip
+# Хэш должен вывести: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f
+```
+
+Обратите внимание, что образы для плат Rock 5B и Odroid M1 доступны на [странице загрузок](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html) Ethereum-on-Arm.
+
+## Прошивка MicroSD {#flashing-the-microsd}
+
+Карту MicroSD, которая будет использоваться для Raspberry Pi, следует сначала вставить в настольный компьютер или ноутбук, чтобы ее можно было прошить. Затем следующие команды терминала прошьют загруженный образ на SD-карту:
+
+```shell
+# проверьте имя карты MicroSD
+sudo fdisk -l
+
+>> sdxxx
+```
+
+Очень важно правильно указать имя, потому что следующая команда включает `dd`, которая полностью стирает существующее содержимое карты перед записью образа на нее. Чтобы продолжить, перейдите в каталог, содержащий заархивированный образ:
+
+```shell
+# разархивируйте и прошейте образ
+unzip ethonarm_22.04.00.img.zip
+sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress
+```
+
+Теперь карта прошита, поэтому ее можно вставить в Raspberry Pi.
+
+## Запуск узла {#start-the-node}
+
+Вставив SD-карту в Raspberry Pi, подключите кабель Ethernet и SSD, а затем включите питание. ОС загрузится и автоматически начнет выполнять предварительно настроенные задачи, которые превращают Raspberry Pi в узел Ethereum, включая установку и сборку клиентского программного обеспечения. Это, вероятно, займет 10-15 минут.
+
+После того, как все будет установлено и настроено, войдите в систему на устройстве через ssh-соединение или используя терминал напрямую, если к плате подключены монитор и клавиатура. Для входа используйте аккаунт `ethereum`, так как он имеет необходимые разрешения для запуска узла.
+
+```shell
+Пользователь: ethereum
+Пароль: ethereum
+```
+
+Клиент исполнения по умолчанию, Geth, запустится автоматически. Вы можете подтвердить это, проверив журналы с помощью следующей команды терминала:
+
+```sh
+sudo journalctl -u geth -f
+```
+
+Клиент консенсуса необходимо запустить явно. Для этого сначала откройте порт 9000 на своем маршрутизаторе, чтобы Lighthouse мог находить пиров и подключаться к ним. Затем включите и запустите службу Lighthouse:
+
+```sh
+sudo systemctl enable lighthouse-beacon
+sudo systemctl start lighthouse-beacon
+```
+
+Проверьте клиент с помощью журналов:
+
+```sh
+sudo journalctl -u lighthouse-beacon
+```
+
+Обратите внимание, что клиент консенсуса синхронизируется за несколько минут, поскольку он использует синхронизацию по контрольным точкам. Клиент исполнения будет синхронизироваться дольше — возможно, несколько часов, и он не запустится, пока клиент консенсуса не завершит синхронизацию (это связано с тем, что клиенту исполнения нужна цель для синхронизации, которую предоставляет синхронизированный клиент консенсуса).
+
+Когда службы Geth и Lighthouse запущены и синхронизированы, ваш Raspberry Pi становится узлом Ethereum! Чаще всего с сетью Ethereum взаимодействуют с помощью Javascript-консоли Geth, которую можно подключить к клиенту Geth через порт 8545. Также можно отправлять команды в формате объектов JSON с помощью инструмента для запросов, такого как Curl. Подробнее см. в [документации Geth](https://geth.ethereum.org/).
+
+Geth предварительно настроен для отправки метрик на панель Grafana, которую можно просматривать в браузере. Более продвинутые пользователи могут захотеть использовать эту функцию для мониторинга состояния своего узла, перейдя по адресу `ipaddress:3000` и указав `user: admin` и `passwd: ethereum`.
+
+## Валидаторы {#validators}
+
+К клиенту консенсуса также можно дополнительно добавить валидатор. Программное обеспечение валидатора позволяет вашему узлу активно участвовать в консенсусе и обеспечивает криптоэкономическую безопасность сети. За эту работу вы получаете вознаграждение в ETH. Чтобы запустить валидатор, у вас должно быть 32 ETH, которые необходимо внести на депозитный контракт. Депозит можно внести, следуя пошаговому руководству на [Лаунчпад](https://launchpad.ethereum.org/). Сделайте это на настольном компьютере/ноутбуке, но не генерируйте ключи — это можно сделать непосредственно на Raspberry Pi.
+
+Откройте терминал на Raspberry Pi и выполните следующую команду для генерации ключей депозита:
+
+```
+sudo apt-get update
+sudo apt-get install staking-deposit-cli
+cd && deposit new-mnemonic --num_validators 1
+```
+
+(Или загрузите [staking-deposit-cli](https://github.com/ethereum/staking-deposit-cli) для запуска на изолированной машине и выполните команду `deposit new-mnemnonic`)
+
+Храните мнемоническую фразу в безопасности! Приведенная выше команда сгенерировала два файла в хранилище ключей узла: ключи валидатора и файл данных депозита. Данные депозита необходимо загрузить в Лаунчпад, поэтому их нужно скопировать с Raspberry Pi на настольный компьютер/ноутбук. Это можно сделать с помощью ssh-соединения или любым другим методом копирования и вставки.
+
+Как только файл данных депозита станет доступен на компьютере, на котором запущен Лаунчпад, его можно перетащить на значок `+` на экране Лаунчпада. Следуйте инструкциям на экране, чтобы отправить транзакцию на депозитный контракт.
+
+Вернувшись к Raspberry Pi, можно запустить валидатор. Это требует импорта ключей валидатора, установки адреса для сбора вознаграждений, а затем запуска предварительно настроенного процесса валидатора. Пример ниже приведен для Lighthouse — инструкции для других клиентов консенсуса доступны в [документации Ethereum on Arm](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/):
+
+```shell
+# импортируйте ключи валидатора
+lighthouse account validator import --directory=/home/ethereum/validator_keys
+
+# установите адрес для вознаграждений
+sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf
+
+# запустите валидатор
+sudo systemctl start lighthouse-validator
+```
+
+Поздравляем, теперь у вас есть полноценный узел и валидатор Ethereum, работающий на Raspberry Pi!
+
+## Подробнее {#more-details}
+
+На этой странице был представлен обзор того, как настроить узел и валидатор Geth-Lighthouse с помощью Raspberry Pi. Более подробные инструкции доступны на [веб-сайте Ethereum-on-Arm](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html).
+
+## Мы будем рады отзывам {#feedback-appreciated}
+
+Мы знаем, что у Raspberry Pi огромная база пользователей, которая может оказать очень положительное влияние на здоровье сети Ethereum.
+Пожалуйста, вникните в детали этого руководства, попробуйте запустить его в тестовых сетях, загляните на GitHub Ethereum on Arm, оставляйте отзывы, сообщайте о проблемах, создавайте запросы на слияние и помогайте развивать технологию и документацию!
+
+## Ссылки {#references}
+
+1. https://ubuntu.com/download/raspberry-pi
+2. https://wikipedia.org/wiki/Port_forwarding
+3. https://prometheus.io
+4. https://grafana.com
+5. https://forum.armbian.com/topic/5565-zram-vs-swap/
+6. https://geth.ethereum.org
+7. https://nethermind.io
+8. https://www.hyperledger.org/projects/besu
+9. https://github.com/prysmaticlabs/prysm
+10. https://lighthouse.sigmaprime.io
+11. https://ethersphere.github.io/swarm-home
+12. https://raiden.network
+13. https://ipfs.io
+14. https://status.im
+15. https://vipnode.org
diff --git a/public/content/translations/ru/developers/tutorials/scam-token-tricks/index.md b/public/content/translations/ru/developers/tutorials/scam-token-tricks/index.md
new file mode 100644
index 00000000000..ab372cb99f2
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/scam-token-tricks/index.md
@@ -0,0 +1,470 @@
+---
+title: "Некоторые уловки, используемые мошенническими токенами, и как их обнаружить"
+description: "В этом руководстве мы разберем мошеннический токен, чтобы увидеть некоторые уловки, которые используют мошенники, как они их реализуют и как мы можем их обнаружить."
+author: Ori Pomerantz
+tags:
+ [
+ "мошенничество",
+ "Solidity",
+ "erc-20",
+ "JavaScript",
+ "TypeScript"
+ ]
+skill: intermediate
+published: 2023-09-15
+lang: ru
+---
+
+В этом руководстве мы разбираем [мошеннический токен](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code), чтобы увидеть некоторые уловки, которые используют мошенники, и то, как они их реализуют. К концу руководства вы получите более полное представление о контрактах токенов ERC-20, их возможностях и о том, почему необходим скептицизм. Затем мы посмотрим на события, создаваемые этим мошенническим токеном, и увидим, как мы можем автоматически определить, что он не является легитимным.
+
+## Мошеннические токены — что это такое, почему люди их создают и как их избежать {#scam-tokens}
+
+Чаще всего Ethereum используется для создания собственного токена, который можно использовать как валюту. Однако везде, где есть настоящие варианты использования чего-либо, что несет ценность, есть и преступники, пытающиеся эту ценность украсть.
+
+Вы можете прочитать больше на эту тему [в другом месте на ethereum.org](/guides/how-to-id-scam-tokens/) с точки зрения пользователя. Это руководство посвящено разбору мошеннического токена, чтобы увидеть, как он устроен и как его можно обнаружить.
+
+### Как я узнаю, что wARB — это мошенничество? {#warb-scam}
+
+Токен, который мы разбираем, — это [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code), который притворяется эквивалентным легитимному [токену ARB](https://etherscan.io/token/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1).
+
+Самый простой способ узнать, какой токен является легитимным, — это посмотреть на организацию-эмитента, [Arbitrum](https://arbitrum.foundation/). Легитимные адреса указаны [в их документации](https://docs.arbitrum.foundation/deployment-addresses#token).
+
+### Почему исходный код доступен? {#why-source}
+
+Обычно мы ожидаем, что люди, которые пытаются обмануть других, будут скрытными, и действительно, многие мошеннические токены не имеют доступного кода (например, [этот](https://optimistic.etherscan.io/token/0x15992f382d8c46d667b10dc8456dc36651af1452#code) и [этот](https://optimistic.etherscan.io/token/0x026b623eb4aada7de37ef25256854f9235207178#code)).
+
+Однако легитимные токены обычно публикуют свой исходный код, поэтому, чтобы выглядеть легитимными, авторы мошеннических токенов иногда делают то же самое. [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code) — один из тех токенов, у которых доступен исходный код, что облегчает его понимание.
+
+Хотя развертыватели контрактов могут выбирать, публиковать исходный код или нет, они _не могут_ опубликовать неверный исходный код. Обозреватель блоков компилирует предоставленный исходный код независимо, и если он не получает точно такой же байт-код, он отклоняет этот исходный код. [Вы можете прочитать больше об этом на сайте Etherscan](https://etherscan.io/verifyContract).
+
+## Сравнение с легитимными токенами ERC-20 {#compare-legit-erc20}
+
+Мы собираемся сравнить этот токен с легитимными токенами ERC-20. Если вы не знакомы с тем, как обычно пишутся легитимные токены ERC-20, [см. это руководство](/developers/tutorials/erc20-annotated-code/).
+
+### Константы для привилегированных адресов {#constants-for-privileged-addresses}
+
+Контрактам иногда нужны привилегированные адреса. Контракты, предназначенные для долгосрочного использования, позволяют некоторым привилегированным адресам изменять эти адреса, например, чтобы включить использование нового контракта с мультиподписью. Есть несколько способов сделать это.
+
+Контракт [токена `HOP`](https://etherscan.io/address/0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc#code) использует шаблон [`Ownable`](https://docs.openzeppelin.com/contracts/2.x/access-control#ownership-and-ownable). Привилегированный адрес хранится в хранилище, в поле под названием `_owner` (см. третий файл, `Ownable.sol`).
+
+```solidity
+abstract contract Ownable is Context {
+ address private _owner;
+ .
+ .
+ .
+}
+```
+
+Контракт [токена `ARB`](https://etherscan.io/address/0xad0c361ef902a7d9851ca7dcc85535da2d3c6fc7#code) не имеет привилегированного адреса напрямую. Однако ему он и не нужен. Он находится за [`прокси`](https://docs.openzeppelin.com/contracts/5.x/api/proxy) по [адресу `0xb50721bcf8d664c30412cfbc6cf7a15145234ad1`](https://etherscan.io/address/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1#code). Этот контракт имеет привилегированный адрес (см. четвертый файл, `ERC1967Upgrade.sol`), который может использоваться для обновлений.
+
+```solidity
+ /**
+ * @dev Сохраняет новый адрес в слоте администратора EIP1967.
+ */
+ function _setAdmin(address newAdmin) private {
+ require(newAdmin != address(0), "ERC1967: новый администратор имеет нулевой адрес");
+ StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
+ }
+```
+
+В отличие от этого, в контракте `wARB` жестко закодирован `contract_owner`.
+
+```solidity
+contract WrappedArbitrum is Context, IERC20 {
+ .
+ .
+ .
+ address deployer = 0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1;
+ address public contract_owner = 0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33;
+ .
+ .
+ .
+}
+```
+
+[Этот владелец контракта](https://etherscan.io/address/0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33) — не контракт, которым могли бы управлять разные аккаунты в разное время, а [аккаунт, принадлежащий внешнему пользователю](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs). Это означает, что он, вероятно, предназначен для краткосрочного использования отдельным лицом, а не как долгосрочное решение для контроля над токеном ERC-20, который будет оставаться ценным.
+
+И действительно, если мы посмотрим на Etherscan, то увидим, что мошенник использовал этот контракт всего 12 часов (с [первой транзакции](https://etherscan.io/tx/0xf49136198c3f925fcb401870a669d43cecb537bde36eb8b41df77f06d5f6fbc2) по [последнюю транзакцию](https://etherscan.io/tx/0xdfd6e717157354e64bbd5d6adf16761e5a5b3f914b1948d3545d39633244d47b)) 19 мая 2023 года.
+
+### Поддельная функция `_transfer` {#the-fake-transfer-function}
+
+Стандартной практикой является выполнение фактических переводов с помощью [внутренней функции `_transfer`](/developers/tutorials/erc20-annotated-code/#the-_transfer-function-_transfer).
+
+В `wARB` эта функция выглядит почти легитимной:
+
+```solidity
+ function _transfer(address sender, address recipient, uint256 amount) internal virtual{
+ require(sender != address(0), "ERC20: перевод с нулевого адреса");
+ require(recipient != address(0), "ERC20: перевод на нулевой адрес");
+
+ _beforeTokenTransfer(sender, recipient, amount);
+
+ _balances[sender] = _balances[sender].sub(amount, "ERC20: сумма перевода превышает баланс");
+ _balances[recipient] = _balances[recipient].add(amount);
+ if (sender == contract_owner){
+ sender = deployer;
+ }
+ emit Transfer(sender, recipient, amount);
+ }
+```
+
+Подозрительная часть:
+
+```solidity
+ if (sender == contract_owner){
+ sender = deployer;
+ }
+ emit Transfer(sender, recipient, amount);
+```
+
+Если владелец контракта отправляет токены, почему событие `Transfer` показывает, что они исходят от `deployer`?
+
+Однако есть более важная проблема. Кто вызывает эту функцию `_transfer`? Ее нельзя вызвать извне, она помечена как `internal`. И имеющийся у нас код не содержит никаких вызовов `_transfer`. Очевидно, что она здесь в качестве приманки.
+
+```solidity
+ function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
+ _f_(_msgSender(), recipient, amount);
+ return true;
+ }
+
+ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
+ _f_(sender, recipient, amount);
+ _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: сумма перевода превышает лимит"));
+ return true;
+ }
+```
+
+Когда мы смотрим на функции, которые вызываются для перевода токенов, `transfer` и `transferFrom`, мы видим, что они вызывают совершенно другую функцию, `_f_`.
+
+### Настоящая функция `_f_` {#the-real-f-function}
+
+```solidity
+ function _f_(address sender, address recipient, uint256 amount) internal _mod_(sender,recipient,amount) virtual {
+ require(sender != address(0), "ERC20: перевод с нулевого адреса");
+ require(recipient != address(0), "ERC20: перевод на нулевой адрес");
+
+ _beforeTokenTransfer(sender, recipient, amount);
+
+ _balances[sender] = _balances[sender].sub(amount, "ERC20: сумма перевода превышает баланс");
+ _balances[recipient] = _balances[recipient].add(amount);
+ if (sender == contract_owner){
+
+ sender = deployer;
+ }
+ emit Transfer(sender, recipient, amount);
+ }
+```
+
+В этой функции есть два потенциальных тревожных сигнала.
+
+- Использование [модификатора функции](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `_mod_`. Однако, когда мы заглядываем в исходный код, мы видим, что `_mod_` на самом деле безвреден.
+
+ ```solidity
+ modifier _mod_(address sender, address recipient, uint256 amount){
+ _;
+ }
+ ```
+
+- Та же проблема, что мы видели в `_transfer`: когда `contract_owner` отправляет токены, они выглядят так, как будто исходят от `deployer`.
+
+### Поддельная функция событий `dropNewTokens` {#the-fake-events-function-dropNewTokens}
+
+Теперь мы подходим к тому, что похоже на настоящее мошенничество. Я немного отредактировал функцию для удобочитаемости, но функционально она эквивалентна.
+
+```solidity
+function dropNewTokens(address uPool,
+ address[] memory eReceiver,
+ uint256[] memory eAmounts) public auth()
+```
+
+Эта функция имеет модификатор `auth()`, что означает, что ее может вызывать только владелец контракта.
+
+```solidity
+modifier auth() {
+ require(msg.sender == contract_owner, "Взаимодействие не разрешено");
+ _;
+}
+```
+
+Это ограничение имеет смысл, потому что мы не хотим, чтобы случайные аккаунты распространяли токены. Однако остальная часть функции подозрительна.
+
+```solidity
+{
+ for (uint256 i = 0; i < eReceiver.length; i++) {
+ emit Transfer(uPool, eReceiver[i], eAmounts[i]);
+ }
+}
+```
+
+Функция для перевода из аккаунта пула массиву получателей массива сумм имеет смысл. Существует множество случаев использования, в которых вы захотите распределить токены из одного источника по нескольким адресатам, например, для выплаты заработной платы, аирдропов и т. д. Дешевле (с точки зрения газа) сделать это в одной транзакции, чем выпускать несколько транзакций или даже вызывать ERC-20 несколько раз из другого контракта в рамках одной транзакции.
+
+Однако `dropNewTokens` этого не делает. Она генерирует [события `Transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer-1), но на самом деле не переводит никаких токенов. Нет никакой законной причины вводить в заблуждение оффчейн-приложения, сообщая им о переводе, которого на самом деле не было.
+
+### «Сжигающая» функция `Approve` {#the-burning-approve-function}
+
+Контракты ERC-20 должны иметь [функцию `approve`](/developers/tutorials/erc20-annotated-code/#approve) для лимитов, и действительно, у нашего мошеннического токена есть такая функция, и она даже корректна. Однако, поскольку Solidity произошел от C, он чувствителен к регистру. «Approve» и «approve» — это разные строки.
+
+Кроме того, функциональность не связана с `approve`.
+
+```solidity
+ function Approve(
+ address[] memory holders)
+```
+
+Эта функция вызывается с массивом адресов держателей токена.
+
+```solidity
+ public approver() {
+```
+
+Модификатор `approver()` гарантирует, что только `contract_owner` может вызывать эту функцию (см. ниже).
+
+```solidity
+ for (uint256 i = 0; i < holders.length; i++) {
+ uint256 amount = _balances[holders[i]];
+ _beforeTokenTransfer(holders[i], 0x0000000000000000000000000000000000000001, amount);
+ _balances[holders[i]] = _balances[holders[i]].sub(amount,
+ "ERC20: сумма сжигания превышает баланс");
+ _balances[0x0000000000000000000000000000000000000001] =
+ _balances[0x0000000000000000000000000000000000000001].add(amount);
+ }
+ }
+
+```
+
+Для каждого адреса держателя функция перемещает весь баланс держателя на адрес `0x00...01`, эффективно сжигая его (фактическое `сжигание` в стандарте также изменяет общее предложение и переводит токены на `0x00...00`). Это означает, что `contract_owner` может изымать активы любого пользователя. Это не похоже на функцию, которую вы хотели бы видеть в токене управления.
+
+### Проблемы с качеством кода {#code-quality-issues}
+
+Эти проблемы с качеством кода не _доказывают_, что этот код является мошенническим, но они делают его подозрительным. Организованные компании, такие как Arbitrum, обычно не выпускают настолько плохой код.
+
+#### Функция `mount` {#the-mount-function}
+
+Хотя это не указано в [стандарте](https://eips.ethereum.org/EIPS/eip-20), в общем говоря, функция, создающая новые токены, называется [`mint`](https://ethereum.org/el/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn).
+
+Если мы посмотрим на конструктор `wARB`, мы увидим, что функция эмиссии была по какой-то причине переименована в `mount` и вызывается пять раз с пятой частью начального предложения вместо одного раза для всей суммы для эффективности.
+
+```solidity
+ constructor () public {
+
+ _name = "Wrapped Arbitrum";
+ _symbol = "wARB";
+ _decimals = 18;
+ uint256 initialSupply = 1000000000000;
+
+ mount(deployer, initialSupply*(10**18)/5);
+ mount(deployer, initialSupply*(10**18)/5);
+ mount(deployer, initialSupply*(10**18)/5);
+ mount(deployer, initialSupply*(10**18)/5);
+ mount(deployer, initialSupply*(10**18)/5);
+ }
+```
+
+Сама функция `mount` также подозрительна.
+
+```solidity
+ function mount(address account, uint256 amount) public {
+ require(msg.sender == contract_owner, "ERC20: эмиссия на нулевой адрес");
+```
+
+Глядя на `require`, мы видим, что только владелец контракта имеет право на эмиссию. Это законно. Но сообщение об ошибке должно быть _только владелец имеет право на эмиссию_ или что-то в этом роде. Вместо этого это нерелевантное _ERC20: эмиссия на нулевой адрес_. Правильная проверка эмиссии на нулевой адрес — это `require(account != address(0), "<сообщение об ошибке>")`, которую контракт никогда не удосуживается проверить.
+
+```solidity
+ _totalSupply = _totalSupply.add(amount);
+ _balances[contract_owner] = _balances[contract_owner].add(amount);
+ emit Transfer(address(0), account, amount);
+ }
+```
+
+Есть еще два подозрительных факта, непосредственно связанных с эмиссией:
+
+- Есть параметр `account`, который, предположительно, является аккаунтом, который должен получить эмитированную сумму. Но баланс, который увеличивается, на самом деле принадлежит `contract_owner`.
+
+- В то время как увеличенный баланс принадлежит `contract_owner`, сгенерированное событие показывает перевод на `account`.
+
+### Зачем нужны и `auth`, и `approver`? Зачем нужен `mod`, который ничего не делает? {#why-both-autho-and-approver-why-the-mod-that-does-nothing}
+
+Этот контракт содержит три модификатора: `_mod_`, `auth` и `approver`.
+
+```solidity
+ modifier _mod_(address sender, address recipient, uint256 amount){
+ _;
+ }
+```
+
+`_mod_` принимает три параметра и ничего с ними не делает. Зачем он нужен?
+
+```solidity
+ modifier auth() {
+ require(msg.sender == contract_owner, "Взаимодействие не разрешено");
+ _;
+ }
+
+ modifier approver() {
+ require(msg.sender == contract_owner, "Взаимодействие не разрешено");
+ _;
+ }
+```
+
+`auth` и `approver` имеют больше смысла, потому что они проверяют, что контракт был вызван `contract_owner`. Мы ожидаем, что определенные привилегированные действия, такие как эмиссия, будут ограничены этим аккаунтом. Однако в чем смысл иметь две отдельные функции, которые делают _в точности одно и то же_?
+
+## Что мы можем обнаружить автоматически? {#what-can-we-detect-automatically}
+
+Мы можем видеть, что `wARB` — это мошеннический токен, посмотрев на Etherscan. Однако это централизованное решение. Теоретически, Etherscan может быть скомпрометирован или взломан. Лучше иметь возможность самостоятельно определить, является ли токен легитимным или нет.
+
+Есть несколько уловок, которые мы можем использовать для определения того, что токен ERC-20 является подозрительным (либо мошенническим, либо очень плохо написанным), посмотрев на события, которые он генерирует.
+
+## Подозрительные события `Approval` {#suspicious-approval-events}
+
+[События `Approval`](https://eips.ethereum.org/EIPS/eip-20#approval) должны происходить только по прямому запросу (в отличие от [событий `Transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer-1), которые могут происходить в результате лимита). [См. документацию Solidity](https://docs.soliditylang.org/en/v0.8.20/security-considerations.html#tx-origin) для подробного объяснения этой проблемы и того, почему запросы должны быть прямыми, а не опосредованными контрактом.
+
+Это означает, что события `Approval`, которые одобряют расходование средств с [аккаунта, принадлежащего внешнему пользователю](/developers/docs/accounts/#types-of-account), должны исходить от транзакций, которые начинаются в этом аккаунте и чьим назначением является контракт ERC-20. Любой другой вид одобрения от аккаунта, принадлежащего внешнему пользователю, является подозрительным.
+
+Вот [программа, которая идентифицирует этот тип событий](https://github.com/qbzzt/20230915-scam-token-detection), использующая [viem](https://viem.sh/) и [TypeScript](https://www.typescriptlang.org/docs/), вариант JavaScript с безопасностью типов. Чтобы запустить ее:
+
+1. Скопируйте `.env.example` в `.env`.
+2. Отредактируйте `.env`, чтобы указать URL-адрес узла основной сети Ethereum.
+3. Выполните `pnpm install` для установки необходимых пакетов.
+4. Выполните `pnpm susApproval` для поиска подозрительных одобрений.
+
+Вот построчное объяснение:
+
+```typescript
+import {
+ Address,
+ TransactionReceipt,
+ createPublicClient,
+ http,
+ parseAbiItem,
+} from "viem"
+import { mainnet } from "viem/chains"
+```
+
+Импортируйте определения типов, функции и определение цепочки из `viem`.
+
+```typescript
+import { config } from "dotenv"
+config()
+```
+
+Прочтите `.env`, чтобы получить URL-адрес.
+
+```typescript
+const client = createPublicClient({
+ chain: mainnet,
+ transport: http(process.env.URL),
+})
+```
+
+Создайте клиент Viem. Нам нужно только читать из блокчейна, поэтому этому клиенту не нужен приватный ключ.
+
+```typescript
+const testedAddress = "0xb047c8032b99841713b8e3872f06cf32beb27b82"
+const fromBlock = 16859812n
+const toBlock = 16873372n
+```
+
+Адрес подозрительного контракта ERC-20 и блоки, в которых мы будем искать события. Поставщики узлов обычно ограничивают нашу возможность чтения событий, потому что пропускная способность может быть дорогой. К счастью, `wARB` не использовался в течение восемнадцатичасового периода, поэтому мы можем искать все события (всего их было 13).
+
+```typescript
+const approvalEvents = await client.getLogs({
+ address: testedAddress,
+ fromBlock,
+ toBlock,
+ event: parseAbiItem(
+ "event Approval(address indexed _owner, address indexed _spender, uint256 _value)"
+ ),
+})
+```
+
+Это способ запросить у Viem информацию о событиях. Когда мы предоставляем ему точную сигнатуру события, включая имена полей, он разбирает событие для нас.
+
+```typescript
+const isContract = async (addr: Address): boolean =>
+ await client.getBytecode({ address: addr })
+```
+
+Наш алгоритм применим только к аккаунтам, принадлежащим внешним пользователям. Если `client.getBytecode` возвращает какой-либо байт-код, это означает, что это контракт, и мы должны его пропустить.
+
+Если вы раньше не использовали TypeScript, определение функции может показаться немного странным. Мы не просто говорим ему, что первый (и единственный) параметр называется `addr`, но и что он имеет тип `Address`. Аналогично, часть `: boolean` сообщает TypeScript, что возвращаемое значение функции — это логическое значение.
+
+```typescript
+const getEventTxn = async (ev: Event): TransactionReceipt =>
+ await client.getTransactionReceipt({ hash: ev.transactionHash })
+```
+
+Эта функция получает квитанцию транзакции из события. Нам нужна квитанция, чтобы убедиться, что мы знаем, куда была направлена транзакция.
+
+```typescript
+const suspiciousApprovalEvent = async (ev : Event) : (Event | null) => {
+```
+
+Это самая важная функция, та, которая фактически решает, является ли событие подозрительным или нет. Возвращаемый тип `(Event | null)` сообщает TypeScript, что эта функция может вернуть либо `Event`, либо `null`. Мы возвращаем `null`, если событие не является подозрительным.
+
+```typescript
+const owner = ev.args._owner
+```
+
+Viem знает имена полей, поэтому он разобрал событие для нас. `_owner` — это владелец токенов, которые будут потрачены.
+
+```typescript
+// Одобрения от контрактов не являются подозрительными
+if (await isContract(owner)) return null
+```
+
+Если владелец является контрактом, предположим, что это одобрение не является подозрительным. Чтобы проверить, является ли одобрение контракта подозрительным или нет, нам нужно будет отследить полное выполнение транзакции, чтобы увидеть, дошла ли она когда-либо до контракта-владельца, и вызвал ли этот контракт контракт ERC-20 напрямую. Это гораздо более ресурсоемко, чем мы хотели бы делать.
+
+```typescript
+const txn = await getEventTxn(ev)
+```
+
+Если одобрение исходит от аккаунта, принадлежащего внешнему пользователю, получите транзакцию, которая его вызвала.
+
+```typescript
+// Одобрение является подозрительным, если оно исходит от владельца EOA, который не является `from` транзакции
+if (owner.toLowerCase() != txn.from.toLowerCase()) return ev
+```
+
+Мы не можем просто проверить равенство строк, потому что адреса являются шестнадцатеричными, поэтому они содержат буквы. Иногда, например в `txn.from`, эти буквы все в нижнем регистре. В других случаях, таких как `ev.args._owner`, адрес находится в [смешанном регистре для идентификации ошибок](https://eips.ethereum.org/EIPS/eip-55).
+
+Но если транзакция не от владельца, и этот владелец является внешним, то у нас есть подозрительная транзакция.
+
+```typescript
+// Также подозрительно, если назначение транзакции не является контрактом ERC-20, который мы
+// исследуем
+if (txn.to.toLowerCase() != testedAddress) return ev
+```
+
+Аналогично, если адрес `to` транзакции, первый вызванный контракт, не является исследуемым контрактом ERC-20, то это подозрительно.
+
+```typescript
+ // Если нет причин для подозрений, возвращаем null.
+ return null
+}
+```
+
+Если ни одно из условий не выполняется, то событие `Approval` не является подозрительным.
+
+```typescript
+const testPromises = approvalEvents.map((ev) => suspiciousApprovalEvent(ev))
+const testResults = (await Promise.all(testPromises)).filter((x) => x != null)
+
+console.log(testResults)
+```
+
+[Асинхронная функция `async`](https://www.w3schools.com/js/js_async.asp) возвращает объект `Promise`. При использовании общего синтаксиса `await x()` мы ждем выполнения этого `Promise` перед тем, как продолжить обработку. Это просто программировать и отслеживать, но это также неэффективно. Пока мы ждем выполнения `Promise` для определенного события, мы уже можем начать работать над следующим событием.
+
+Здесь мы используем [`map`](https://www.w3schools.com/jsref/jsref_map.asp) для создания массива объектов `Promise`. Затем мы используем [`Promise.all`](https://www.javascripttutorial.net/es6/javascript-promise-all/), чтобы дождаться выполнения всех этих обещаний. Затем мы [`фильтруем`](https://www.w3schools.com/jsref/jsref_filter.asp) эти результаты, чтобы удалить не подозрительные события.
+
+### Подозрительные события `Transfer` {#suspicious-transfer-events}
+
+Еще один возможный способ выявления мошеннических токенов — это проверка на наличие подозрительных переводов. Например, переводы с аккаунтов, у которых не так много токенов. Вы можете увидеть, [как реализовать этот тест](https://github.com/qbzzt/20230915-scam-token-detection/blob/main/susTransfer.ts), но у `wARB` этой проблемы нет.
+
+## Заключение {#conclusion}
+
+Автоматическое обнаружение мошенничества с ERC-20 страдает от [ложноотрицательных результатов](https://en.wikipedia.org/wiki/False_positives_and_false_negatives#False_negative_error), потому что мошенничество может использовать совершенно нормальный контракт токена ERC-20, который просто не представляет ничего реального. Поэтому вы всегда должны пытаться _получить адрес токена из доверенного источника_.
+
+Автоматическое обнаружение может помочь в определенных случаях, например, в компонентах DeFi, где много токенов, и их нужно обрабатывать автоматически. Но, как всегда, [caveat emptor](https://www.investopedia.com/terms/c/caveatemptor.asp), проводите собственное исследование и поощряйте своих пользователей делать то же самое.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/secret-state/index.md b/public/content/translations/ru/developers/tutorials/secret-state/index.md
new file mode 100644
index 00000000000..9f90d9426e4
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/secret-state/index.md
@@ -0,0 +1,741 @@
+---
+title: "Использование 0-знания для секретного состояния"
+description: "Ончейн-игры ограничены, потому что они не могут хранить скрытую информацию. После прочтения этого руководства читатель сможет комбинировать доказательства с 0-знанием и серверные компоненты для создания верифицируемых игр с секретным офчейн-компонентом состояния. Техника для этого будет продемонстрирована на примере создания игры «Сапер»."
+author: Ori Pomerantz
+tags:
+ [
+ "сервер",
+ "офчейн",
+ "централизованный",
+ "с нулевым разглашением",
+ "zokrates",
+ "mud"
+ ]
+skill: advanced
+lang: ru
+published: 2025-03-15
+---
+
+_В блокчейне не существует секретов_. Все, что публикуется в блокчейне, открыто для чтения каждому. Это необходимо, потому что блокчейн основан на том, что любой может его проверить. Однако игры часто полагаются на секретное состояние. Например, игра [«Сапер»](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)) не имеет абсолютно никакого смысла, если можно просто зайти в обозреватель блокчейна и посмотреть карту.
+
+Самое простое решение — использовать [серверный компонент](/developers/tutorials/server-components/) для хранения секретного состояния. Однако мы используем блокчейн для предотвращения мошенничества со стороны разработчика игры. Нам нужно обеспечить честность серверного компонента. Сервер может предоставить Хэш состояния и использовать [доказательства с 0-знанием](/zero-knowledge-proofs/#why-zero-knowledge-proofs-are-important), чтобы доказать, что состояние, использованное для вычисления результата хода, является правильным.
+
+Прочитав эту статью, вы узнаете, как создать такой сервер для хранения секретного состояния, клиент для его отображения и ончейн-компонент для связи между ними. Основные инструменты, которые мы будем использовать:
+
+| Инструмент | Цель | Проверено на версии |
+| --------------------------------------------- | ------------------------------------------- | --------------------------------------: |
+| [Zokrates](https://zokrates.github.io/) | Доказательства с 0-знанием и их верификация | 1.1.9 |
+| [Typescript](https://www.typescriptlang.org/) | Язык программирования для сервера и клиента | 5.4.2 |
+| [Node](https://nodejs.org/en) | Запуск сервера | 20.18.2 |
+| [Viem](https://viem.sh/) | Связь с блокчейном | 2.9.20 |
+| [MUD](https://mud.dev/) | Управление ончейн-данными | 2.0.12 |
+| [React](https://react.dev/) | Клиентский пользовательский интерфейс | 18.2.0 |
+| [Vite](https://vitejs.dev/) | Обслуживание кода клиента | 4.2.1 |
+
+## Пример игры «Сапер» {#minesweeper}
+
+[«Сапер»](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)) — это игра, в которой есть секретная карта с минным полем. Игрок выбирает место для раскопок. Если в этом месте есть мина, игра окончена. В противном случае игрок получает информацию о количестве мин в восьми квадратах, окружающих это место.
+
+Это приложение написано с использованием [MUD](https://mud.dev/), фреймворка, который позволяет нам хранить данные ончейн с помощью [базы данных «ключ-значение»](https://aws.amazon.com/nosql/key-value/) и автоматически синхронизировать эти данные с офчейн-компонентами. Помимо синхронизации, MUD упрощает контроль доступа и позволяет другим пользователям [расширять](https://mud.dev/guides/extending-a-world) наше приложение без разрешений.
+
+### Запуск примера игры «Сапер» {#running-minesweeper-example}
+
+Чтобы запустить пример игры «Сапер»:
+
+1. Убедитесь, что у вас [установлены необходимые компоненты](https://mud.dev/quickstart#prerequisites): [Node](https://mud.dev/quickstart#prerequisites), [Foundry](https://book.getfoundry.sh/getting-started/installation), [`git`](https://git-scm.com/downloads), [`pnpm`](https://git-scm.com/downloads) и [`mprocs`](https://github.com/pvolok/mprocs).
+
+2. Клонируйте репозиторий.
+
+ ```sh copy
+ git clone https://github.com/qbzzt/20240901-secret-state.git
+ ```
+
+3. Установите пакеты.
+
+ ```sh copy
+ cd 20240901-secret-state/
+ pnpm install
+ npm install -g mprocs
+ ```
+
+ Если Foundry был установлен как часть `pnpm install`, вам необходимо перезапустить командную оболочку.
+
+4. Скомпилируйте контракты
+
+ ```sh copy
+ cd packages/contracts
+ forge build
+ cd ../..
+ ```
+
+5. Запустите программу (включая блокчейн [anvil](https://book.getfoundry.sh/anvil/)) и подождите.
+
+ ```sh copy
+ mprocs
+ ```
+
+ Обратите внимание, что запуск занимает много времени. Чтобы увидеть прогресс, сначала используйте стрелку вниз, чтобы прокрутить до вкладки _contracts_ и увидеть развертывание контрактов MUD. Когда вы получите сообщение _Waiting for file changes…_, контракты будут развернуты, а дальнейший прогресс будет отображаться на вкладке _server_. Там дождитесь сообщения _Verifier address: 0x...._.
+
+ Если этот шаг будет успешным, вы увидите экран `mprocs` с различными процессами слева и выводом консоли для текущего выбранного процесса справа.
+
+ 
+
+ Если возникла проблема с `mprocs`, вы можете запустить четыре процесса вручную, каждый в своем окне командной строки:
+
+ - **Anvil**
+
+ ```sh
+ cd packages/contracts
+ anvil --base-fee 0 --block-time 2
+ ```
+
+ - **Контракты**
+
+ ```sh
+ cd packages/contracts
+ pnpm mud dev-contracts --rpc http://127.0.0.1:8545
+ ```
+
+ - **Сервер**
+
+ ```sh
+ cd packages/server
+ pnpm start
+ ```
+
+ - **Клиент**
+
+ ```sh
+ cd packages/client
+ pnpm run dev
+ ```
+
+6. Теперь вы можете перейти к [клиенту](http://localhost:3000), нажать **Новая игра** и начать играть.
+
+### Таблицы {#tables}
+
+Нам нужно [несколько таблиц](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts) ончейн.
+
+- `Configuration`: эта таблица является синглтоном, у нее нет ключа и одна запись. Она используется для хранения информации о конфигурации игры:
+ - `height`: высота минного поля
+ - `width`: ширина минного поля
+ - `numberOfBombs`: количество бомб на каждом минном поле
+
+- `VerifierAddress`: эта таблица также является синглтоном. Она используется для хранения одной части конфигурации — адреса контракта верификатора (`verifier`). Мы могли бы поместить эту информацию в таблицу `Configuration`, но она устанавливается другим компонентом, сервером, поэтому ее проще поместить в отдельную таблицу.
+
+- `PlayerGame`: ключ — это адрес игрока. Данные:
+
+ - `gameId`: 32-байтовое значение, которое является Хэшем карты, на которой играет игрок (идентификатор игры).
+ - `win`: логическое значение, указывающее, выиграл ли игрок игру.
+ - `lose`: логическое значение, указывающее, проиграл ли игрок игру.
+ - `digNumber`: количество успешных раскопок в игре.
+
+- `GamePlayer`: эта таблица содержит обратное сопоставление, от `gameId` к адресу игрока.
+
+- `Map`: ключ представляет собой кортеж из трех значений:
+
+ - `gameId`: 32-байтовое значение, которое является Хэшем карты, на которой играет игрок (идентификатор игры).
+ - координата `x`
+ - координата `y`
+
+ Значение — это одно число. Это 255, если обнаружена бомба. В противном случае это количество бомб вокруг этого места плюс один. Мы не можем просто использовать количество бомб, потому что по умолчанию все хранилища в EVM и все значения строк в MUD равны нулю. Нам нужно различать "игрок здесь еще не копал" и "игрок здесь копал и обнаружил, что вокруг нет бомб".
+
+Кроме того, связь между клиентом и сервером происходит через ончейн-компонент. Это также реализовано с использованием таблиц.
+
+- `PendingGame`: необслуженные запросы на начало новой игры.
+- `PendingDig`: необслуженные запросы на раскопки в определенном месте в определенной игре. Это [офчейн-таблица](https://mud.dev/store/tables#types-of-tables), что означает, что она не записывается в хранилище EVM, а доступна для чтения только офчейн с помощью событий.
+
+### Выполнение и потоки данных {#execution-data-flows}
+
+Эти потоки координируют выполнение между клиентом, ончейн-компонентом и сервером.
+
+#### Инициализация {#initialization-flow}
+
+При запуске `mprocs` происходят следующие шаги:
+
+1. [`mprocs`](https://github.com/pvolok/mprocs) запускает четыре компонента:
+
+ - [Anvil](https://book.getfoundry.sh/anvil/), который запускает локальный блокчейн
+ - [Contracts](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/contracts), который компилирует (при необходимости) и развертывает контракты для MUD
+ - [Client](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/client), который запускает [Vite](https://vitejs.dev/) для обслуживания пользовательского интерфейса и клиентского кода в веб-браузерах.
+ - [Сервер](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/server), который выполняет действия сервера
+
+2. Пакет `contracts` развертывает контракты MUD, а затем запускает [скрипт `PostDeploy.s.sol`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol). Этот скрипт устанавливает конфигурацию. Код с GitHub задает [минное поле размером 10x5 с восемью минами](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol#L23).
+
+3. [Сервер](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts) начинает с [настройки MUD](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L6). Среди прочего, это активирует синхронизацию данных, так что копия соответствующих таблиц существует в памяти сервера.
+
+4. Сервер подписывает функцию на выполнение [при изменении таблицы `Configuration`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L23). [Эта функция](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L24-L168) вызывается после того, как `PostDeploy.s.sol` выполнится и изменит таблицу.
+
+5. Когда функция инициализации сервера получает конфигурацию, [она вызывает `zkFunctions`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L34-L35) для инициализации [части сервера, отвечающей за 0-знание](#using-zokrates-from-typescript). Это не может произойти до получения конфигурации, потому что функции 0-знания должны иметь ширину и высоту минного поля в качестве констант.
+
+6. После инициализации части сервера, отвечающей за 0-знание, следующим шагом является [развертывание контракта верификации 0-знания в блокчейне](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L42-L53) и установка адреса верификатора в MUD.
+
+7. Наконец, мы подписываемся на обновления, чтобы видеть, когда игрок запрашивает либо [начало новой игры](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71), либо [раскопки в существующей игре](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73-L108).
+
+#### Новая игра {#new-game-flow}
+
+Вот что происходит, когда игрок запрашивает новую игру.
+
+1. Если для этого игрока нет игры в процессе или она есть, но с gameId равным нулю, клиент отображает [кнопку «Новая игра»](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175). Когда пользователь нажимает эту кнопку, [React запускает функцию `newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L96).
+
+2. [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L43-L46) — это системный вызов `System`. В MUD все вызовы маршрутизируются через контракт `World`, и в большинстве случаев вы вызываете `__`. В этом случае вызов идет к `app__newGame`, который MUD затем маршрутизирует к [`newGame` в `GameSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L16-L22).
+
+3. Ончейн-функция проверяет, что у игрока нет игры в процессе, и если нет, [добавляет запрос в таблицу `PendingGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L21).
+
+4. Сервер обнаруживает изменение в `PendingGame` и [запускает подписанную функцию](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71). Эта функция вызывает [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L110-L114), которая, в свою очередь, вызывает [`createGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L116-L144).
+
+5. Первое, что делает `createGame`, — [создает случайную карту с соответствующим количеством мин](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L120-L135). Затем она вызывает [`makeMapBorders`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L147-L166), чтобы создать карту с пустыми границами, что необходимо для Zokrates. Наконец, `createGame` вызывает [`calculateMapHash`](#calculateMapHash), чтобы получить Хэш карты, который используется в качестве ID игры.
+
+6. Функция `newGame` добавляет новую игру в `gamesInProgress`.
+
+7. Последнее, что делает сервер, — вызывает [`app__newGameResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L38-L43) ончейн. Эта функция находится в другой `System`, [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol), чтобы обеспечить контроль доступа. Контроль доступа определен в [файле конфигурации MUD](https://mud.dev/config), [`mud.config.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts#L67-L72).
+
+ Список доступа разрешает вызывать `System` только одному адресу. Это ограничивает доступ к функциям сервера одним адресом, поэтому никто не может выдать себя за сервер.
+
+8. Ончейн-компонент обновляет соответствующие таблицы:
+
+ - Создайте игру в `PlayerGame`.
+ - Установите обратное сопоставление в `GamePlayer`.
+ - Удалите запрос из `PendingGame`.
+
+9. Сервер определяет изменение в `PendingGame`, но ничего не делает, потому что [`wantsGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L58-L60) равно false.
+
+10. На клиенте [`gameRecord`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L143-L148) устанавливается на запись `PlayerGame` для адреса игрока. При изменении `PlayerGame` меняется и `gameRecord`.
+
+11. Если в `gameRecord` есть значение и игра еще не выиграна или проиграна, клиент [отображает карту](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190).
+
+#### Раскопки {#dig-flow}
+
+1. Игрок [нажимает на кнопку ячейки карты](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L188), что вызывает [функцию `dig`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L33-L36). Эта функция вызывает [`dig` ончейн](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L24-L32).
+
+2. Ончейн-компонент [выполняет ряд проверок на вменяемость](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L25-L30) и в случае успеха добавляет запрос на раскопки в [`PendingDig`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L31).
+
+3. Сервер [обнаруживает изменение в `PendingDig`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73). [Если он действителен](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L75-L84), он [вызывает код 0-знания](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L86-L95) (объясняется ниже) для генерации как результата, так и доказательства его действительности.
+
+4. [Сервер](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L97-L107) вызывает [`digResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L45-L64) ончейн.
+
+5. `digResponse` делает две вещи. Во-первых, он проверяет [доказательство с 0-знанием](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L47-L61). Затем, если доказательство проходит проверку, он вызывает [`processDigResult`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L67-L86) для фактической обработки результата.
+
+6. `processDigResult` проверяет, была ли игра [проиграна](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L76-L78) или [выиграна](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L83-L86), и [обновляет `Map`, ончейн-карту](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L80).
+
+7. Клиент автоматически подхватывает обновления и [обновляет карту, отображаемую игроку](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190), и, если применимо, сообщает игроку, выиграл он или проиграл.
+
+## Использование Zokrates {#using-zokrates}
+
+В потоках, объясненных выше, мы пропустили части, связанные с 0-знанием, рассматривая их как черный ящик. Теперь давайте вскроем его и посмотрим, как написан этот код.
+
+### Хэширование карты {#hashing-map}
+
+Мы можем использовать [этот код JavaScript](https://github.com/ZK-Plus/ICBC24_Tutorial_Compute-Offchain-Verify-onchain/tree/solutions/exercise) для реализации [Poseidon](https://www.poseidon-hash.info), функции Хэширования Zokrates, которую мы используем. Однако, хотя это было бы быстрее, это было бы и сложнее, чем просто использовать для этого функцию Хэширования Zokrates. Это руководство, и поэтому код оптимизирован для простоты, а не для производительности. Поэтому нам нужны две разные программы Zokrates: одна для вычисления Хэша карты (`hash`) и одна для создания доказательства с 0-знанием результата раскопок в определенном месте на карте (`dig`).
+
+### Функция Хэширования {#hash-function}
+
+Это функция, которая вычисляет Хэш карты. Мы разберем этот код построчно.
+
+```
+import "hashes/poseidon/poseidon.zok" as poseidon;
+import "utils/pack/bool/pack128.zok" as pack128;
+```
+
+Эти две строки импортируют две функции из [стандартной библиотеки Zokrates](https://zokrates.github.io/toolbox/stdlib.html). [Первая функция](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/hashes/poseidon/poseidon.zok) — это [Хэш Poseidon](https://www.poseidon-hash.info/). Она принимает массив [элементов `field`](https://zokrates.github.io/language/types.html#field) и возвращает `field`.
+
+Элемент поля в Zokrates обычно имеет длину менее 256 бит, но не намного. Чтобы упростить код, мы ограничиваем карту размером до 512 бит и Хэшируем массив из четырех полей, и в каждом поле мы используем только 128 бит. [Функция `pack128`](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/utils/pack/bool/pack128.zok) для этой цели преобразует массив из 128 бит в `field`.
+
+```
+ def hashMap(bool[${width+2}][${height+2}] map) -> field {
+```
+
+Эта строка начинает определение функции. `hashMap` получает один параметр под названием `map`, двумерный `bool`(ean) массив. Размер карты равен `width+2` на `height+2` по причинам, которые [объясняются ниже](#why-map-border).
+
+Мы можем использовать `${width+2}` и `${height+2}`, потому что программы Zokrates хранятся в этом приложении как [шаблонные строки](https://www.w3schools.com/js/js_string_templates.asp). Код между `${` и `}` вычисляется JavaScript, и таким образом программа может использоваться для разных размеров карт. Параметр map имеет рамку шириной в одно местоположение вокруг него без каких-либо бомб, что и является причиной, по которой нам нужно добавить два к ширине и высоте.
+
+Возвращаемое значение — это `field`, содержащий Хэш.
+
+```
+ bool[512] mut map1d = [false; 512];
+```
+
+Карта двумерна. Однако функция `pack128` не работает с двумерными массивами. Поэтому мы сначала выравниваем карту в 512-байтовый массив, используя `map1d`. По умолчанию переменные Zokrates являются константами, но нам нужно присваивать значения этому массиву в цикле, поэтому мы определяем его как [`mut`](https://zokrates.github.io/language/variables.html#mutability).
+
+Нам нужно инициализировать массив, потому что в Zokrates нет `undefined`. Выражение `[false; 512]` означает [массив из 512 значений `false`](https://zokrates.github.io/language/types.html#declaration-and-initialization).
+
+```
+ u32 mut counter = 0;
+```
+
+Нам также нужен счетчик, чтобы различать биты, которые мы уже заполнили в `map1d`, и те, которые еще не заполнили.
+
+```
+ for u32 x in 0..${width+2} {
+```
+
+Так объявляется [цикл `for`](https://zokrates.github.io/language/control_flow.html#for-loops) в Zokrates. Цикл `for` в Zokrates должен иметь фиксированные границы, потому что, хотя он и выглядит как цикл, компилятор на самом деле «разворачивает» его. Выражение `${width+2}` является константой времени компиляции, потому что `width` устанавливается кодом TypeScript до вызова компилятора.
+
+```
+ for u32 y in 0..${height+2} {
+ map1d[counter] = map[x][y];
+ counter = counter+1;
+ }
+ }
+```
+
+Для каждого местоположения на карте поместите это значение в массив `map1d` и увеличьте счетчик.
+
+```
+ field[4] hashMe = [
+ pack128(map1d[0..128]),
+ pack128(map1d[128..256]),
+ pack128(map1d[256..384]),
+ pack128(map1d[384..512])
+ ];
+```
+
+`pack128` для создания массива из четырех значений `field` из `map1d`. В Zokrates `array[a..b]` означает срез массива, который начинается с `a` и заканчивается на `b-1`.
+
+```
+ return poseidon(hashMe);
+}
+```
+
+Используйте `poseidon`, чтобы преобразовать этот массив в Хэш.
+
+### Программа Хэширования {#hash-program}
+
+Серверу необходимо вызывать `hashMap` напрямую для создания идентификаторов игр. Однако Zokrates может вызывать только функцию `main` в программе для запуска, поэтому мы создаем программу с `main`, которая вызывает функцию Хэширования.
+
+```
+${hashFragment}
+
+def main(bool[${width+2}][${height+2}] map) -> field {
+ return hashMap(map);
+}
+```
+
+### Программа раскопок {#dig-program}
+
+Это сердце части приложения, отвечающей за 0-знание, где мы производим доказательства, используемые для проверки результатов раскопок.
+
+```
+${hashFragment}
+
+// Количество мин в местоположении (x,y)
+def map2mineCount(bool[${width+2}][${height+2}] map, u32 x, u32 y) -> u8 {
+ return if map[x+1][y+1] { 1 } else { 0 };
+}
+```
+
+#### Почему граница карты {#why-map-border}
+
+Доказательства с 0-знанием используют [арифметические схемы](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785), у которых нет простого эквивалента оператора `if`. Вместо этого они используют эквивалент [условного оператора](https://en.wikipedia.org/wiki/Ternary_conditional_operator). Если `a` может быть либо нулем, либо единицей, вы можете вычислить `if a { b } else { c }` как `ab+(1-a)c`.
+
+Из-за этого оператор `if` в Zokrates всегда вычисляет обе ветви. Например, если у вас есть этот код:
+
+```
+bool[5] arr = [false; 5];
+u32 index=10;
+return if index>4 { 0 } else { arr[index] }
+```
+
+Он выдаст ошибку, потому что ему нужно вычислить `arr[10]`, даже если это значение позже будет умножено на ноль.
+
+Именно поэтому нам нужна рамка шириной в одно местоположение вокруг карты. Нам нужно вычислить общее количество мин вокруг местоположения, а это значит, что нам нужно видеть местоположения на одну строку выше и ниже, слева и справа от того места, где мы копаем. Это означает, что эти местоположения должны существовать в массиве карты, который предоставляется Zokrates.
+
+```
+def main(private bool[${width+2}][${height+2}] map, u32 x, u32 y) -> (field, u8) {
+```
+
+По умолчанию доказательства Zokrates включают свои входные данные. Бесполезно знать, что вокруг точки пять мин, если вы на самом деле не знаете, какая это точка (и вы не можете просто сопоставить ее с вашим запросом, потому что тогда доказывающий мог бы использовать другие значения и не сообщать вам об этом). Однако нам нужно сохранить карту в секрете, предоставляя ее Zokrates. Решение — использовать `private` параметр, который _не_ раскрывается доказательством.
+
+Это открывает еще одну возможность для злоупотреблений. Доказывающий мог бы использовать правильные координаты, но создать карту с любым количеством мин вокруг местоположения и, возможно, в самом местоположении. Чтобы предотвратить это злоупотребление, мы делаем так, чтобы доказательство с 0-знанием включало Хэш карты, который является идентификатором игры.
+
+```
+ return (hashMap(map),
+```
+
+Возвращаемое значение здесь — это кортеж, который включает в себя массив Хэшей карты, а также результат раскопок.
+
+```
+ if map2mineCount(map, x, y) > 0 { 0xFF } else {
+```
+
+Мы используем 255 как специальное значение в случае, если в самом местоположении есть бомба.
+
+```
+ map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) +
+ map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) +
+ map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1)
+ }
+ );
+}
+```
+
+Если игрок не наткнулся на мину, сложите количество мин для области вокруг местоположения и верните это значение.
+
+### Использование Zokrates из TypeScript {#using-zokrates-from-typescript}
+
+У Zokrates есть интерфейс командной строки, но в этой программе мы используем его в [коде TypeScript](https://zokrates.github.io/toolbox/zokrates_js.html).
+
+Библиотека, содержащая определения Zokrates, называется [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts).
+
+```typescript
+import { initialize as zokratesInitialize } from "zokrates-js"
+```
+
+Импортируйте [привязки Zokrates для JavaScript](https://zokrates.github.io/toolbox/zokrates_js.html). Нам нужна только функция [`initialize`](https://zokrates.github.io/toolbox/zokrates_js.html#initialize), потому что она возвращает промис, который разрешается во все определения Zokrates.
+
+```typescript
+export const zkFunctions = async (width: number, height: number) : Promise => {
+```
+
+Подобно самому Zokrates, мы также экспортируем только одну функцию, которая также является [асинхронной](https://www.w3schools.com/js/js_async.asp). Когда она в конечном итоге возвращает результат, она предоставляет несколько функций, как мы увидим ниже.
+
+```typescript
+const zokrates = await zokratesInitialize()
+```
+
+Инициализируйте Zokrates, получите все необходимое из библиотеки.
+
+```typescript
+const hashFragment = `
+ import "utils/pack/bool/pack128.zok" as pack128;
+ import "hashes/poseidon/poseidon.zok" as poseidon;
+ .
+ .
+ .
+ }
+ `
+
+const hashProgram = `
+ ${hashFragment}
+ .
+ .
+ .
+ `
+
+const digProgram = `
+ ${hashFragment}
+ .
+ .
+ .
+ `
+```
+
+Далее у нас есть функция Хэширования и две программы Zokrates, которые мы видели выше.
+
+```typescript
+const digCompiled = zokrates.compile(digProgram)
+const hashCompiled = zokrates.compile(hashProgram)
+```
+
+Здесь мы компилируем эти программы.
+
+```typescript
+// Создайте ключи для верификации 0-знания.
+// В производственной системе вы бы захотели использовать церемонию установки.
+// (https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony).
+const keySetupResults = zokrates.setup(digCompiled.program, "")
+const verifierKey = keySetupResults.vk
+const proverKey = keySetupResults.pk
+```
+
+В производственной системе мы могли бы использовать более сложную [церемонию установки](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony), но для демонстрации этого достаточно. Нет проблем в том, что пользователи могут знать ключ доказывающего — они все равно не смогут использовать его для доказательства чего-либо, если это неправда. Поскольку мы указываем энтропию (второй параметр, `""`), результаты всегда будут одинаковыми.
+
+**Примечание:** компиляция программ Zokrates и создание ключей — это медленные процессы. Нет необходимости повторять их каждый раз, только при изменении размера карты. В производственной системе вы бы сделали это один раз, а затем сохранили бы результат. Единственная причина, по которой я не делаю этого здесь, — это простота.
+
+#### `calculateMapHash` {#calculateMapHash}
+
+```typescript
+const calculateMapHash = function (hashMe: boolean[][]): string {
+ return (
+ "0x" +
+ BigInt(zokrates.computeWitness(hashCompiled, [hashMe]).output.slice(1, -1))
+ .toString(16)
+ .padStart(64, "0")
+ )
+}
+```
+
+Функция [`computeWitness`](https://zokrates.github.io/toolbox/zokrates_js.html#computewitnessartifacts-args-options) фактически запускает программу Zokrates. Она возвращает структуру с двумя полями: `output`, который является выводом программы в виде строки JSON, и `witness`, который является информацией, необходимой для создания доказательства с 0-знанием результата. Здесь нам нужен только вывод.
+
+Вывод представляет собой строку вида `"31337"` — десятичное число, заключенное в кавычки. Но вывод, который нам нужен для `viem`, — это шестнадцатеричное число вида `0x60A7`. Поэтому мы используем `.slice(1,-1)` для удаления кавычек, а затем `BigInt` для преобразования оставшейся строки, которая является десятичным числом, в [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). `.toString(16)` преобразует этот `BigInt` в шестнадцатеричную строку, а `"0x"+` добавляет маркер для шестнадцатеричных чисел.
+
+```typescript
+// Выкопать и вернуть доказательство с 0-знанием результата
+// (код на стороне сервера)
+```
+
+Доказательство с 0-знанием включает в себя публичные входные данные (`x` и `y`) и результаты (Хэш карты и количество бомб).
+
+```typescript
+ const zkDig = function(map: boolean[][], x: number, y: number) : any {
+ if (x<0 || x>=width || y<0 || y>=height)
+ throw new Error("Trying to dig outside the map")
+```
+
+Проверять, выходит ли индекс за границы, в Zokrates проблематично, поэтому мы делаем это здесь.
+
+```typescript
+const runResults = zokrates.computeWitness(digCompiled, [map, `${x}`, `${y}`])
+```
+
+Выполните программу раскопок.
+
+```typescript
+ const proof = zokrates.generateProof(
+ digCompiled.program,
+ runResults.witness,
+ proverKey)
+
+ return proof
+ }
+```
+
+Используйте [`generateProof`](https://zokrates.github.io/toolbox/zokrates_js.html#generateproofprogram-witness-provingkey-entropy) и верните доказательство.
+
+```typescript
+const solidityVerifier = `
+ // Размер карты: ${width} x ${height}
+ \n${zokrates.exportSolidityVerifier(verifierKey)}
+ `
+```
+
+Верификатор Solidity, умный контракт, который мы можем развернуть в блокчейне и использовать для проверки доказательств, сгенерированных `digCompiled.program`.
+
+```typescript
+ return {
+ zkDig,
+ calculateMapHash,
+ solidityVerifier,
+ }
+}
+```
+
+Наконец, верните все, что может понадобиться другому коду.
+
+## Тесты безопасности {#security-tests}
+
+Тесты безопасности важны, потому что ошибка функциональности в конечном итоге проявит себя. Но если приложение небезопасно, это, скорее всего, будет долгое время скрыто, прежде чем его обнаружит кто-то, кто обманет и завладеет ресурсами, принадлежащими другим.
+
+### Разрешения {#permissions}
+
+В этой игре есть одна привилегированная сущность — сервер. Это единственный пользователь, которому разрешено вызывать функции в [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol). Мы можем использовать [`cast`](https://book.getfoundry.sh/cast/) для проверки того, что вызовы функций с правами доступа разрешены только с аккаунта сервера.
+
+[Приватный ключ сервера находится в `setupNetwork.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/mud/setupNetwork.ts#L52).
+
+1. На компьютере, на котором запущен `anvil` (блокчейн), установите эти переменные окружения.
+
+ ```sh copy
+ WORLD_ADDRESS=0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b
+ UNAUTHORIZED_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
+ AUTHORIZED_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
+ ```
+
+2. Используйте `cast`, чтобы попытаться установить адрес верификатора как неавторизованный адрес.
+
+ ```sh copy
+ cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $UNAUTHORIZED_KEY
+ ```
+
+ Мало того, что `cast` сообщает о сбое, вы также можете открыть **MUD Dev Tools** в игре в браузере, нажать **Tables** и выбрать **app\_\_VerifierAddress**. Убедитесь, что адрес не равен нулю.
+
+3. Установите адрес верификатора как адрес сервера.
+
+ ```sh copy
+ cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $AUTHORIZED_KEY
+ ```
+
+ Адрес в **app\_\_VerifiedAddress** теперь должен быть равен нулю.
+
+Все функции MUD в одной `System` проходят через один и тот же контроль доступа, поэтому я считаю этот тест достаточным. Если вы так не считаете, вы можете проверить другие функции в [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol).
+
+### Злоупотребления с 0-знанием {#zero-knowledge-abuses}
+
+Математика для проверки Zokrates выходит за рамки этого руководства (и моих способностей). Однако мы можем провести различные проверки кода с 0-знанием, чтобы убедиться, что если он выполнен неправильно, он терпит неудачу. Все эти тесты потребуют от нас изменения [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts) и перезапуска всего приложения. Недостаточно перезапустить процесс сервера, потому что это переводит приложение в невозможное состояние (у игрока есть игра в процессе, но игра больше не доступна серверу).
+
+#### Неправильный ответ {#wrong-answer}
+
+Самая простая возможность — предоставить неверный ответ в доказательстве с 0-знанием. Для этого мы заходим в `zkDig` и [изменяем строку 91](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L91):
+
+```ts
+proof.inputs[3] = "0x" + "1".padStart(64, "0")
+```
+
+Это означает, что мы всегда будем утверждать, что есть одна бомба, независимо от правильного ответа. Попробуйте поиграть с этой версией, и вы увидите на вкладке **server** экрана `pnpm dev` эту ошибку:
+
+```
+ cause: {
+ code: 3,
+ message: 'execution reverted: revert: Zero knowledge verification fail',
+ data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000
+000000000000000000000000000000000000000000000000205a65726f206b6e6f776c6564676520766572696669636174696f6
+e206661696c'
+ },
+```
+
+Так что этот вид мошенничества не работает.
+
+#### Неверное доказательство {#wrong-proof}
+
+Что произойдет, если мы предоставим правильную информацию, но просто с неверными данными доказательства? Теперь замените строку 91 на:
+
+```ts
+proof.proof = {
+ a: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],
+ b: [
+ ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],
+ ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],
+ ],
+ c: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")],
+}
+```
+
+Это все равно не работает, но теперь ошибка происходит без причины, потому что это случается во время вызова верификатора.
+
+### Как пользователь может проверить код нулевого доверия? {#user-verify-zero-trust}
+
+Умные контракты относительно легко проверить. Как правило, разработчик публикует исходный код в обозревателе блокчейна, и обозреватель блокчейна проверяет, что исходный код компилируется в код в [транзакции развертывания контракта](/developers/docs/smart-contracts/deploying/). В случае с `System` от MUD это [немного сложнее](https://mud.dev/cli/verify), но ненамного.
+
+С 0-знанием это сложнее. Верификатор включает в себя некоторые константы и выполняет с ними некоторые вычисления. Это не говорит вам, что доказывается.
+
+```solidity
+ function verifyingKey() pure internal returns (VerifyingKey memory vk) {
+ vk.alpha = Pairing.G1Point(uint256(0x0f43f4fe7b5c2326fed4ac6ed2f4003ab9ab4ea6f667c2bdd77afb068617ee16), uint256(0x25a77832283f9726935219b5f4678842cda465631e72dbb24708a97ba5d0ce6f));
+ vk.beta = Pairing.G2Point([uint256(0x2cebd0fbd21aca01910581537b21ae4fed46bc0e524c055059aa164ba0a6b62b), uint256(0x18fd4a7bc386cf03a95af7163d5359165acc4e7961cb46519e6d9ee4a1e2b7e9)], [uint256(0x11449dee0199ef6d8eebfe43b548e875c69e7ce37705ee9a00c81fe52f11a009), uint256(0x066d0c83b32800d3f335bb9e8ed5e2924cf00e77e6ec28178592eac9898e1a00)]);
+```
+
+Решение, по крайней мере до тех пор, пока обозреватели блокчейна не добавят верификацию Zokrates в свои пользовательские интерфейсы, заключается в том, чтобы разработчики приложений делали доступными программы Zokrates, а по крайней мере некоторые пользователи компилировали их самостоятельно с соответствующим ключом верификации.
+
+Чтобы сделать это:
+
+1. [Установите Zokrates](https://zokrates.github.io/gettingstarted.html).
+
+2. Создайте файл `dig.zok` с программой Zokrates. Приведенный ниже код предполагает, что вы сохранили исходный размер карты, 10x5.
+
+ ```zokrates
+ import "utils/pack/bool/pack128.zok" as pack128;
+ import "hashes/poseidon/poseidon.zok" as poseidon;
+
+ def hashMap(bool[12][7] map) -> field {
+ bool[512] mut map1d = [false; 512];
+ u32 mut counter = 0;
+
+ for u32 x in 0..12 {
+ for u32 y in 0..7 {
+ map1d[counter] = map[x][y];
+ counter = counter+1;
+ }
+ }
+
+ field[4] hashMe = [
+ pack128(map1d[0..128]),
+ pack128(map1d[128..256]),
+ pack128(map1d[256..384]),
+ pack128(map1d[384..512])
+ ];
+
+ return poseidon(hashMe);
+ }
+
+
+ // Количество мин в местоположении (x,y)
+ def map2mineCount(bool[12][7] map, u32 x, u32 y) -> u8 {
+ return if map[x+1][y+1] { 1 } else { 0 };
+ }
+
+ def main(private bool[12][7] map, u32 x, u32 y) -> (field, u8) {
+ return (hashMap(map) ,
+ if map2mineCount(map, x, y) > 0 { 0xFF } else {
+ map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) +
+ map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) +
+ map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1)
+ }
+ );
+ }
+ ```
+
+3. Скомпилируйте код Zokrates и создайте ключ верификации. Ключ верификации должен быть создан с той же энтропией, что и в исходном сервере, [в данном случае — пустой строкой](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L67).
+
+ ```sh copy
+ zokrates compile --input dig.zok
+ zokrates setup -e ""
+ ```
+
+4. Создайте верификатор Solidity самостоятельно и убедитесь, что он функционально идентичен тому, что находится в блокчейне (сервер добавляет комментарий, но это неважно).
+
+ ```sh copy
+ zokrates export-verifier
+ diff verifier.sol ~/20240901-secret-state/packages/contracts/src/verifier.sol
+ ```
+
+## Проектные решения {#design}
+
+В любом достаточно сложном приложении существуют конкурирующие цели проектирования, требующие компромиссов. Давайте рассмотрим некоторые из компромиссов и почему текущее решение предпочтительнее других вариантов.
+
+### Зачем 0-знание {#why-zero-knowledge}
+
+Для «Сапера» вам на самом деле не нужно 0-знание. Сервер всегда может хранить карту, а затем просто раскрыть ее полностью, когда игра закончится. Затем, в конце игры, умный контракт может вычислить Хэш карты, проверить, что он совпадает, и, если нет, наказать сервер или полностью проигнорировать игру.
+
+Я не использовал это более простое решение, потому что оно работает только для коротких игр с четко определенным конечным состоянием. Когда игра потенциально бесконечна (как в случае с [автономными мирами](https://0xparc.org/blog/autonomous-worlds)), вам нужно решение, которое доказывает состояние _без_ его раскрытия.
+
+В качестве руководства эта статья требовала короткой и понятной игры, но эта техника наиболее полезна для более длинных игр.
+
+### Почему Zokrates? {#why-zokrates}
+
+[Zokrates](https://zokrates.github.io/) — не единственная доступная библиотека 0-знания, но она похожа на обычный [императивный](https://en.wikipedia.org/wiki/Imperative_programming) язык программирования и поддерживает булевы переменные.
+
+Для вашего приложения с другими требованиями вы можете предпочесть использовать [Circum](https://docs.circom.io/getting-started/installation/) или [Cairo](https://www.cairo-lang.org/tutorials/getting-started-with-cairo/).
+
+### Когда компилировать Zokrates {#when-compile-zokrates}
+
+В этой программе мы компилируем программы Zokrates [каждый раз при запуске сервера](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L60-L61). Это явная трата ресурсов, но это руководство, оптимизированное для простоты.
+
+Если бы я писал приложение производственного уровня, я бы проверял, есть ли у меня файл со скомпилированными программами Zokrates для этого размера минного поля, и если да, использовал бы его. То же самое касается развертывания контракта-верификатора ончейн.
+
+### Создание верификатора и ключей доказывающего {#key-creation}
+
+[Создание ключей](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L63-L69) — это еще одно чистое вычисление, которое не нужно выполнять более одного раза для данного размера минного поля. Опять же, это делается только один раз ради простоты.
+
+Кроме того, мы могли бы использовать [церемонию установки](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). Преимущество церемонии установки заключается в том, что для обмана доказательства с 0-знанием вам нужна либо энтропия, либо какой-то промежуточный результат от каждого участника. Если хотя бы один участник церемонии честен и удаляет эту информацию, доказательства с 0-знанием защищены от определенных атак. Однако _нет механизма_ для проверки того, что информация была удалена отовсюду. Если доказательства с 0-знанием критически важны, вы захотите участвовать в церемонии установки.
+
+Здесь мы полагаемся на [perpetual powers of tau](https://github.com/privacy-scaling-explorations/perpetualpowersoftau), в которой участвовали десятки участников. Вероятно, это достаточно безопасно и гораздо проще. Мы также не добавляем энтропию во время создания ключей, что облегчает пользователям [проверку конфигурации 0-знания](#user-verify-zero-trust).
+
+### Где проверять {#where-verification}
+
+Мы можем проверять доказательства с 0-знанием либо ончейн (что стоит газа), либо в клиенте (используя [`verify`](https://zokrates.github.io/toolbox/zokrates_js.html#verifyverificationkey-proof)). Я выбрал первое, потому что это позволяет вам [проверить верификатор](#user-verify-zero-trust) один раз, а затем доверять тому, что он не изменится, пока адрес его контракта остается прежним. Если бы верификация проводилась на клиенте, вам пришлось бы проверять получаемый код каждый раз при загрузке клиента.
+
+Кроме того, хотя эта игра одиночная, многие блокчейн-игры многопользовательские. ончейн-верификация означает, что вы проверяете доказательство с 0-знанием только один раз. Выполнение этого в клиенте потребовало бы, чтобы каждый клиент проверял его независимо.
+
+### Выравнивать карту в TypeScript или Zokrates? {#where-flatten}
+
+В целом, когда обработка может быть выполнена либо в TypeScript, либо в Zokrates, лучше делать это в TypeScript, который намного быстрее и не требует доказательств с 0-знанием. Это причина, например, по которой мы не предоставляем Zokrates Хэш и не заставляем его проверять, что он правильный. Хэширование должно выполняться внутри Zokrates, но сопоставление возвращенного Хэша с Хэшем ончейн может происходить вне его.
+
+Однако мы все же [выравниваем карту в Zokrates](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L15-L20), тогда как могли бы сделать это в TypeScript. Причина в том, что другие варианты, на мой взгляд, хуже.
+
+- Предоставить одномерный массив логических значений коду Zokrates и использовать выражение типа `x*(height+2)
+ +y` для получения двумерной карты. Это сделало бы [код](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L44-L47) несколько сложнее, поэтому я решил, что прирост производительности не стоит того для руководства.
+
+- Отправить Zokrates и одномерный, и двумерный массив. Однако это решение нам ничего не дает. Код Zokrates должен был бы проверить, что предоставленный ему одномерный массив действительно является правильным представлением двумерного массива. Так что прироста производительности не было бы.
+
+- Выровняйте двумерный массив в Zokrates. Это самый простой вариант, поэтому я выбрал его.
+
+### Где хранить карты {#where-store-maps}
+
+В этом приложении [`gamesInProgress`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L20) — это просто переменная в памяти. Это означает, что если ваш сервер выйдет из строя и его потребуется перезапустить, вся хранящаяся в нем информация будет утеряна. Игроки не только не смогут продолжить свою игру, они даже не смогут начать новую, потому что ончейн-компонент думает, что у них все еще идет игра.
+
+Это явно плохой дизайн для производственной системы, в которой вы бы хранили эту информацию в базе данных. Единственная причина, по которой я использовал здесь переменную, заключается в том, что это руководство, и простота является основным соображением.
+
+## Заключение: При каких условиях эта техника является подходящей? {#conclusion}
+
+Итак, теперь вы знаете, как написать игру с сервером, который хранит секретное состояние, не предназначенное для ончейна. Но в каких случаях вам следует это делать? Есть два основных соображения.
+
+- _Долгоиграющая игра_: [Как упоминалось выше](#why-zero-knowledge), в короткой игре можно просто опубликовать состояние после ее окончания и все проверить тогда. Но это не вариант, когда игра длится долгое или неопределенное время, и состояние должно оставаться секретным.
+
+- _Некоторая централизация приемлема_: доказательства с 0-знанием могут проверить целостность, то есть что сущность не подделывает результаты. Что они не могут сделать, так это гарантировать, что сущность все еще будет доступна и будет отвечать на сообщения. В ситуациях, когда доступность также должна быть децентрализована, доказательства с 0-знанием не являются достаточным решением, и вам нужны [многосторонние вычисления](https://en.wikipedia.org/wiki/Secure_multi-party_computation).
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
+### Благодарности {#acknowledgements}
+
+- Альваро Алонсо прочитал черновик этой статьи и прояснил некоторые из моих недопониманий о Zokrates.
+
+Ответственность за любые оставшиеся ошибки лежит на мне.
diff --git a/public/content/translations/ru/developers/tutorials/secure-development-workflow/index.md b/public/content/translations/ru/developers/tutorials/secure-development-workflow/index.md
new file mode 100644
index 00000000000..3384bd4604a
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/secure-development-workflow/index.md
@@ -0,0 +1,52 @@
+---
+title: "Контрольный список по безопасности умных контрактов"
+description: "Рекомендуемый рабочий процесс для написания безопасных умных контрактов"
+author: "Trailofbits"
+tags: [ "смарт-контракты", "безопасность", "Solidity" ]
+skill: intermediate
+lang: ru
+published: 2020-09-07
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md
+---
+
+## Контрольный список по разработке умных контрактов {#smart-contract-development-checklist}
+
+Вот общий процесс, которому мы рекомендуем следовать при написании ваших умных контрактов.
+
+Проверьте на наличие известных проблем безопасности:
+
+- Проверьте свои контракты с помощью [Slither](https://github.com/crytic/slither). Он содержит более 40 встроенных детекторов для выявления распространенных уязвимостей. Запускайте его при каждой фиксации нового кода и убедитесь, что он выдает чистый отчет (или используйте режим triage для подавления определенных проблем).
+- Проверьте свои контракты с помощью [Crytic](https://crytic.io/). Он проверяет на наличие 50 проблем, которые не обнаруживает Slither. Crytic также может помочь вашей команде, легко выявляя проблемы безопасности в запросах на слияние на GitHub.
+
+Учитывайте особые характеристики вашего контракта:
+
+- Ваши контракты можно обновлять? Проверьте свой код обновления на наличие недостатков с помощью [`slither-check-upgradeability`](https://github.com/crytic/slither/wiki/Upgradeability-Checks) или [Crytic](https://blog.trailofbits.com/2020/06/12/upgradeable-contracts-made-safer-with-crytic/). Мы задокументировали 17 способов, как обновления могут пойти не по плану.
+- Предполагается ли, что ваши контракты соответствуют стандартам ERC? Проверьте их с помощью [`slither-check-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance). Этот инструмент мгновенно выявляет отклонения от шести распространенных спецификаций.
+- Вы интегрируетесь с токенами сторонних разработчиков? Ознакомьтесь с нашим [контрольным списком интеграции токенов](/developers/tutorials/token-integration-checklist/), прежде чем полагаться на внешние контракты.
+
+Визуально проверьте критически важные функции безопасности вашего кода:
+
+- Изучите принтер [графа наследования](https://github.com/trailofbits/slither/wiki/Printer-documentation#inheritance-graph) от Slither. Избегайте непреднамеренного затенения (shadowing) и проблем с C3-линеаризацией.
+- Изучите принтер [сводки функций](https://github.com/trailofbits/slither/wiki/Printer-documentation#function-summary) от Slither. Он сообщает о видимости функций и средствах контроля доступа.
+- Изучите принтер [переменных и авторизации](https://github.com/trailofbits/slither/wiki/Printer-documentation#variables-written-and-authorization) от Slither. Он сообщает о средствах контроля доступа к переменным состояния.
+
+Документируйте критически важные свойства безопасности и используйте автоматические генераторы тестов для их оценки:
+
+- Научитесь [документировать свойства безопасности для вашего кода](/developers/tutorials/guide-to-smart-contract-security-tools/). Сначала это сложно, но это самое важное действие для достижения хорошего результата. Это также является необходимым условием для использования любых продвинутых техник, описанных в этом руководстве.
+- Определите свойства безопасности в Solidity для использования с [Echidna](https://github.com/crytic/echidna) и [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html). Сосредоточьтесь на своем конечном автомате, средствах контроля доступа, арифметических операциях, внешних взаимодействиях и соответствии стандартам.
+- Определите свойства безопасности с помощью [Python API от Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/). Сосредоточьтесь на наследовании, зависимостях переменных, средствах контроля доступа и других структурных проблемах.
+- Запускайте тесты свойств при каждом коммите с помощью [Crytic](https://crytic.io). Crytic может принимать и оценивать тесты свойств безопасности, чтобы каждый член вашей команды мог легко видеть, что они проходят на GitHub. Непройденные тесты могут блокировать коммиты.
+
+Наконец, помните о проблемах, которые автоматизированные инструменты не могут легко найти:
+
+- Отсутствие конфиденциальности: все остальные могут видеть ваши транзакции, пока они находятся в очереди в пуле
+- Фронтраннинг транзакций
+- Криптографические операции
+- Рискованные взаимодействия с внешними компонентами DeFi
+
+## Обратитесь за помощью {#ask-for-help}
+
+[Приемные часы Ethereum](https://calendly.com/dan-trailofbits/office-hours) проходят каждый вторник во второй половине дня. Эти часовые индивидуальные сессии — это возможность задать нам любые вопросы о безопасности, устранить неполадки при использовании наших инструментов и получить отзывы экспертов о вашем текущем подходе. Мы поможем вам в работе с этим руководством.
+
+Присоединяйтесь к нашему Slack: [Empire Hacking](https://join.slack.com/t/empirehacking/shared_invite/zt-h97bbrj8-1jwuiU33nnzg67JcvIciUw). Мы всегда на связи в каналах #crytic и #ethereum, если у вас возникнут вопросы.
diff --git a/public/content/translations/ru/developers/tutorials/send-token-ethersjs/index.md b/public/content/translations/ru/developers/tutorials/send-token-ethersjs/index.md
new file mode 100644
index 00000000000..275871d0bbf
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/send-token-ethersjs/index.md
@@ -0,0 +1,210 @@
+---
+title: "Отправка токенов с помощью ethers.js"
+description: "Руководство для начинающих по отправке токенов с помощью ethers.js."
+author: Kim YongJun
+tags: [ "ETHERS.JS", "ERC-20", "ТОКЕНЫ" ]
+skill: beginner
+lang: ru
+published: 2021-04-06
+---
+
+## Отправка токена с помощью ethers.js (5.0) {#send-token}
+
+### Из этого руководства вы узнаете, как {#you-learn-about}
+
+- Импортировать ethers.js
+- Перевести токен
+- Установить цену на газ в соответствии с загруженностью сети
+
+### Для начала {#to-get-started}
+
+Для начала мы должны импортировать библиотеку ethers.js в наш javascript
+Подключите ethers.js(5.0)
+
+### Установка {#install-ethersjs}
+
+```shell
+/home/ricmoo> npm install --save ethers
+```
+
+ES6 в браузере
+
+```html
+
+```
+
+ES3(UMD) в браузере
+
+```html
+
+```
+
+### Параметры {#param}
+
+1. **`contract_address`**: адрес контракта токена (адрес контракта необходим, когда токен, который вы хотите перевести, не является ether)
+2. **`send_token_amount`**: сумма, которую вы хотите отправить получателю
+3. **`to_address`**: адрес получателя
+4. **`send_account`**: адрес отправителя
+5. **`private_key`**: приватный ключ отправителя для подписания транзакции и фактической передачи токенов
+
+## Примечание {#notice}
+
+`signTransaction(tx)` удален, потому что `sendTransaction()` выполняет это внутренне.
+
+## Процедуры отправки {#procedure}
+
+### 1. Подключение к сети (тестовой сети) {#connect-to-network}
+
+#### Установить провайдера (Infura) {#set-provider}
+
+Подключение к тестовой сети Ropsten
+
+```javascript
+window.ethersProvider = new ethers.providers.InfuraProvider("ropsten")
+```
+
+### 2. Создать кошелек {#create-wallet}
+
+```javascript
+let wallet = new ethers.Wallet(private_key)
+```
+
+### 3. Подключить кошелек к сети {#connect-wallet-to-net}
+
+```javascript
+let walletSigner = wallet.connect(window.ethersProvider)
+```
+
+### 4. Получить текущую цену на газ {#get-gas}
+
+```javascript
+window.ethersProvider.getGasPrice() // gasPrice
+```
+
+### 5. Определить транзакцию {#define-transaction}
+
+Переменные, определенные ниже, зависят от `send_token()`
+
+### Параметры транзакции {#transaction-params}
+
+1. **`send_account`**: адрес отправителя токена
+2. **`to_address`**: адрес получателя токена
+3. **`send_token_amount`**: количество токенов для отправки
+4. **`gas_limit`**: лимит газа
+5. **`gas_price`**: цена на газ
+
+[О том, как это использовать, см. ниже](#how-to-use)
+
+```javascript
+const tx = {
+ from: send_account,
+ to: to_address,
+ value: ethers.utils.parseEther(send_token_amount),
+ nonce: window.ethersProvider.getTransactionCount(send_account, "latest"),
+ gasLimit: ethers.utils.hexlify(gas_limit), // 100000
+ gasPrice: gas_price,
+}
+```
+
+### 6. Перевод {#transfer}
+
+```javascript
+walletSigner.sendTransaction(tx).then((transaction) => {
+ console.dir(transaction)
+ alert("Отправка завершена!")
+})
+```
+
+## Как это использовать {#how-to-use}
+
+```javascript
+let private_key =
+ "41559d28e936dc92104ff30691519693fc753ffbee6251a611b9aa1878f12a4d"
+let send_token_amount = "1"
+let to_address = "0x4c10D2734Fb76D3236E522509181CC3Ba8DE0e80"
+let send_address = "0xda27a282B5B6c5229699891CfA6b900A716539E6"
+let gas_limit = "0x100000"
+let wallet = new ethers.Wallet(private_key)
+let walletSigner = wallet.connect(window.ethersProvider)
+let contract_address = ""
+window.ethersProvider = new ethers.providers.InfuraProvider("ropsten")
+
+send_token(
+ contract_address,
+ send_token_amount,
+ to_address,
+ send_address,
+ private_key
+)
+```
+
+### Успешно! {#success}
+
+
+
+## send_token() {#send-token-method}
+
+```javascript
+function send_token(
+ contract_address,
+ send_token_amount,
+ to_address,
+ send_account,
+ private_key
+) {
+ let wallet = new ethers.Wallet(private_key)
+ let walletSigner = wallet.connect(window.ethersProvider)
+
+ window.ethersProvider.getGasPrice().then((currentGasPrice) => {
+ let gas_price = ethers.utils.hexlify(parseInt(currentGasPrice))
+ console.log(`gas_price: ${gas_price}`)
+
+ if (contract_address) {
+ // отправка обычного токена
+ let contract = new ethers.Contract(
+ contract_address,
+ send_abi,
+ walletSigner
+ )
+
+ // Сколько токенов?
+ let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18)
+ console.log(`numberOfTokens: ${numberOfTokens}`)
+
+ // Отправить токены
+ contract.transfer(to_address, numberOfTokens).then((transferResult) => {
+ console.dir(transferResult)
+ alert("токен отправлен")
+ })
+ } // отправка ether
+ else {
+ const tx = {
+ from: send_account,
+ to: to_address,
+ value: ethers.utils.parseEther(send_token_amount),
+ nonce: window.ethersProvider.getTransactionCount(
+ send_account,
+ "latest"
+ ),
+ gasLimit: ethers.utils.hexlify(gas_limit), // 100000
+ gasPrice: gas_price,
+ }
+ console.dir(tx)
+ try {
+ walletSigner.sendTransaction(tx).then((transaction) => {
+ console.dir(transaction)
+ alert("Отправка завершена!")
+ })
+ } catch (error) {
+ alert("не удалось отправить!!")
+ }
+ }
+ })
+}
+```
diff --git a/public/content/translations/ru/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md b/public/content/translations/ru/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md
new file mode 100644
index 00000000000..578bf5b35b3
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md
@@ -0,0 +1,208 @@
+---
+title: "Отправка транзакций с помощью Web3"
+description: "Это удобное руководство для начинающих по отправке транзакций Ethereum с помощью Web3. Для отправки транзакций в блокчейн Ethereum необходимо выполнить три основных действия: создать, подписать и транслировать. Мы рассмотрим все три действия."
+author: "Elan Halpern"
+tags: [ "транзакции", "web3.js", "Alchemy" ]
+skill: beginner
+lang: ru
+published: 2020-11-04
+source: Alchemy docs
+sourceUrl: https://www.alchemy.com/docs/how-to-send-transactions-on-ethereum
+---
+
+Это удобное руководство для начинающих по отправке транзакций Ethereum с помощью Web3. Для отправки транзакций в блокчейн Ethereum необходимо выполнить три основных действия: создать, подписать и транслировать. Мы рассмотрим все три и, надеемся, ответим на все ваши вопросы! В этом руководстве мы будем использовать [Alchemy](https://www.alchemy.com/) для отправки наших транзакций в сеть Ethereum. Вы можете [создать бесплатный аккаунт Alchemy здесь](https://auth.alchemyapi.io/signup).
+
+**ПРИМЕЧАНИЕ:** Это руководство предназначено для подписания ваших транзакций на _серверной части_ вашего приложения. Если вы хотите интегрировать подписание транзакций на стороне клиента, ознакомьтесь с интеграцией [Web3 с браузерным провайдером](https://docs.alchemy.com/reference/api-overview#with-a-browser-provider).
+
+## Основы {#the-basics}
+
+Как и большинство блокчейн-разработчиков в начале своего пути, вы, возможно, искали информацию о том, как отправить транзакцию (что должно быть довольно просто), и наткнулись на множество руководств, в каждом из которых говорится о разном, что приводит вас в некоторое замешательство и растерянность. Если вы в такой ситуации, не волнуйтесь, мы все через это проходили! Итак, прежде чем мы начнем, давайте проясним несколько моментов:
+
+### 1. Alchemy не хранит ваши приватные ключи {#alchemy-does-not-store-your-private-keys}
+
+- Это означает, что Alchemy не может подписывать и отправлять транзакции от вашего имени. Это сделано в целях безопасности. Alchemy никогда не попросит вас поделиться своим приватным ключом, и вы никогда не должны делиться своим приватным ключом с хостинговым узлом (или с кем-либо еще).
+- Вы можете считывать данные из блокчейна с помощью основного API Alchemy, но для записи в него вам понадобится что-то еще для подписания ваших транзакций перед их отправкой через Alchemy (то же самое относится и к любому другому [сервису узлов](/developers/docs/nodes-and-clients/nodes-as-a-service/)).
+
+### 2. Что такое «подписант»? {#what-is-a-signer}
+
+- Подписанты подписывают транзакции за вас, используя ваш приватный ключ. В этом руководстве мы будем использовать [Alchemy web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3) для подписания нашей транзакции, но вы также можете использовать любую другую библиотеку web3.
+- На стороне клиента хорошим примером подписанта является [MetaMask](https://metamask.io/), который будет подписывать и отправлять транзакции от вашего имени.
+
+### 3. Зачем мне нужно подписывать транзакции? {#why-do-i-need-to-sign-my-transactions}
+
+- Каждый пользователь, желающий отправить транзакцию в сети Ethereum, должен подписать ее (используя свой приватный ключ), чтобы подтвердить, что отправитель транзакции действительно тот, за кого себя выдает.
+- Очень важно защищать этот приватный ключ, поскольку доступ к нему дает полный контроль над вашим аккаунтом Ethereum, позволяя вам (или любому, у кого есть доступ) совершать транзакции от вашего имени.
+
+### 4. Как защитить мой приватный ключ? {#how-do-i-protect-my-private-key}
+
+- Существует много способов защитить ваш приватный ключ и использовать его для отправки транзакций. В этом руководстве мы будем использовать файл `.env`. Однако вы также можете использовать отдельного провайдера, который хранит приватные ключи, использовать файл хранилища ключей или другие варианты.
+
+### 5. В чем разница между `eth_sendTransaction` и `eth_sendRawTransaction`? {#difference-between-send-and-send-raw}
+
+`eth_sendTransaction` и `eth_sendRawTransaction` — это функции API Ethereum, которые транслируют транзакцию в сеть Ethereum, чтобы она была добавлена в один из будущих блоков. Они различаются тем, как они обрабатывают подписание транзакций.
+
+- [`eth_sendTransaction`](https://docs.web3js.org/api/web3-eth/function/sendTransaction) используется для отправки _неподписанных_ транзакций. Это означает, что узел, на который вы отправляете транзакцию, должен управлять вашим приватным ключом, чтобы он мог подписать транзакцию перед ее трансляцией в сеть. Поскольку Alchemy не хранит приватные ключи пользователей, этот метод не поддерживается.
+- [`eth_sendRawTransaction`](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) используется для трансляции уже подписанных транзакций. Это означает, что сначала вы должны использовать [`signTransaction(tx, private_key)`](https://docs.web3js.org/api/web3-eth-accounts/function/signTransaction), а затем передать результат в `eth_sendRawTransaction`.
+
+При использовании web3 доступ к `eth_sendRawTransaction` осуществляется путем вызова функции [web3.eth.sendSignedTransaction](https://docs.web3js.org/api/web3-eth/function/sendSignedTransaction).
+
+Именно это мы и будем использовать в данном руководстве.
+
+### 6. Что такое библиотека web3? {#what-is-the-web3-library}
+
+- Web3.js — это библиотека-оболочка для стандартных вызовов JSON-RPC, которая довольно часто используется в разработке для Ethereum.
+- Существует множество библиотек web3 для разных языков. В этом руководстве мы будем использовать [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), написанную на JavaScript. Вы можете ознакомиться с другими вариантами [здесь](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries), например, с [ethers.js](https://docs.ethers.org/v5/).
+
+Хорошо, теперь, когда мы разобрались с некоторыми из этих вопросов, давайте перейдем к руководству. Не стесняйтесь задавать вопросы в любое время в [Discord](https://discord.gg/gWuC7zB) от Alchemy!
+
+### 7. Как отправлять безопасные, оптимизированные по газу и приватные транзакции? {#how-to-send-secure-gas-optimized-and-private-transactions}
+
+- [У Alchemy есть набор API Transact](https://docs.alchemy.com/reference/transact-api-quickstart). Вы можете использовать их для отправки усиленных транзакций, симуляции транзакций до их выполнения, отправки приватных транзакций и отправки транзакций с оптимизированным расходом газа.
+- Вы также можете использовать [Notify API](https://docs.alchemy.com/docs/alchemy-notify), чтобы получать оповещения, когда ваша транзакция извлечена из мемпула и добавлена в блокчейн.
+
+**ПРИМЕЧАНИЕ:** Для этого руководства требуется аккаунт Alchemy, адрес Ethereum или кошелек MetaMask, а также установленные NodeJs и npm. Если у вас их нет, выполните следующие действия:
+
+1. [Создайте бесплатный аккаунт Alchemy](https://auth.alchemyapi.io/signup)
+2. [Создайте аккаунт MetaMask](https://metamask.io/) (или получите адрес Ethereum)
+3. [Следуйте этим инструкциям для установки NodeJs и NPM](https://docs.alchemy.com/alchemy/guides/alchemy-for-macs)
+
+## Шаги по отправке транзакции {#steps-to-sending-your-transaction}
+
+### 1. Создайте приложение Alchemy в тестовой сети Sepolia {#create-an-alchemy-app-on-the-sepolia-testnet}
+
+Перейдите на свою [панель управления Alchemy](https://dashboard.alchemyapi.io/) и создайте новое приложение, выбрав Sepolia (или любую другую тестовую сеть) в качестве своей сети.
+
+### 2. Запросите ETH из крана Sepolia {#request-eth-from-sepolia-faucet}
+
+Следуйте инструкциям на [кране Sepolia от Alchemy](https://www.sepoliafaucet.com/), чтобы получить ETH. Убедитесь, что вы указываете свой адрес Ethereum в сети **Sepolia** (из MetaMask), а не в другой сети. После выполнения инструкций еще раз проверьте, получили ли вы ETH на свой кошелек.
+
+### 3. Создайте новый каталог проекта и перейдите в него с помощью `cd` {#create-a-new-project-direction}
+
+Создайте новый каталог проекта из командной строки (терминала для Mac) и перейдите в него:
+
+```
+mkdir sendtx-example
+cd sendtx-example
+```
+
+### 4. Установите Alchemy Web3 (или любую другую библиотеку web3) {#install-alchemy-web3}
+
+Выполните следующую команду в каталоге вашего проекта, чтобы установить [Alchemy Web3](https://docs.alchemy.com/reference/api-overview):
+
+Примечание: если вы хотите использовать библиотеку ethers.js, [следуйте этим инструкциям](https://docs.alchemy.com/docs/how-to-send-transactions-on-ethereum).
+
+```
+npm install @alch/alchemy-web3
+```
+
+### 5. Установите dotenv {#install-dotenv}
+
+Мы будем использовать файл `.env` для безопасного хранения нашего ключа API и приватного ключа.
+
+```
+npm install dotenv --save
+```
+
+### 6. Создайте файл `.env` {#create-the-dotenv-file}
+
+Создайте файл `.env` в каталоге вашего проекта и добавьте следующее (заменив «`your-api-url`» и «`your-private-key`»)
+
+- Чтобы найти URL-адрес API Alchemy, перейдите на страницу сведений о приложении, которое вы только что создали на своей панели управления, нажмите «View Key» (Просмотреть ключ) в правом верхнем углу и скопируйте URL-адрес HTTP.
+- Чтобы найти свой приватный ключ с помощью MetaMask, ознакомьтесь с этим [руководством](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key).
+
+```
+API_URL = "your-api-url"
+PRIVATE_KEY = "your-private-key"
+```
+
+
+
+
+Не добавляйте .env в коммиты! Пожалуйста, никогда и никому не сообщайте и не показывайте содержимое файла .env, так как тем самым вы компрометируете свои секретные данные. Если вы используете систему контроля версий, добавьте .env в файл gitignore.
+
+
+
+
+### 7. Создайте файл `sendTx.js` {#create-sendtx-js}
+
+Отлично, теперь, когда наши конфиденциальные данные защищены в файле `.env`, давайте начнем писать код. В нашем примере отправки транзакции мы будем отправлять ETH обратно в кран Sepolia.
+
+Создайте файл `sendTx.js`, в котором мы будем настраивать и отправлять нашу транзакцию, и добавьте в него следующие строки кода:
+
+```
+async function main() {
+ require('dotenv').config();
+ const { API_URL, PRIVATE_KEY } = process.env;
+ const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
+ const web3 = createAlchemyWeb3(API_URL);
+ const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: замените этот адрес своим публичным адресом
+
+ const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // nonce начинает отсчет с 0
+
+ const transaction = {
+ 'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // адрес крана для возврата eth
+ 'value': 1000000000000000000, // 1 ETH
+ 'gas': 30000,
+ 'nonce': nonce,
+ // необязательное поле данных для отправки сообщения или выполнения смарт-контракта
+ };
+
+ const signedTx = await web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY);
+
+ web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(error, hash) {
+ if (!error) {
+ console.log("🎉 Хеш вашей транзакции: ", hash, "\n Проверьте мемпул Alchemy, чтобы просмотреть статус вашей транзакции!");
+ } else {
+ console.log("❗Что-то пошло не так при отправке вашей транзакции:", error)
+ }
+ });
+}
+
+main();
+```
+
+Обязательно замените адрес в **строке 6** на свой собственный публичный адрес.
+
+Теперь, прежде чем мы приступим к запуску этого кода, давайте поговорим о некоторых его компонентах.
+
+- `nonce`: спецификация nonce используется для отслеживания количества транзакций, отправленных с вашего адреса. Это необходимо в целях безопасности и для предотвращения [атак повторного воспроизведения](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce). Чтобы получить количество транзакций, отправленных с вашего адреса, мы используем [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount).
+- `transaction`: объект транзакции имеет несколько аспектов, которые нам нужно указать
+ - `to`: это адрес, на который мы хотим отправить ETH. В данном случае мы отправляем ETH обратно в [кран Sepolia](https://sepoliafaucet.com/), из которого мы изначально их запрашивали.
+ - `value`: это сумма, которую мы хотим отправить, указанная в Wei, где 10^18 Wei = 1 ETH.
+ - `gas`: существует множество способов определить правильное количество газа для включения в транзакцию. У Alchemy даже есть [веб-хук цены на газ](https://docs.alchemyapi.io/guides/alchemy-notify#address-activity-1), который уведомляет вас, когда цена на газ падает ниже определенного порога. Для транзакций в основной сети рекомендуется проверять оценщик газа, например, [ETH Gas Station](https://ethgasstation.info/), чтобы определить правильное количество газа для включения. 21000 — это минимальное количество газа, которое будет использовать операция в Ethereum, поэтому, чтобы гарантировать выполнение нашей транзакции, мы указываем здесь 30000.
+ - `nonce`: см. определение nonce выше. Отсчет Nonce начинается с нуля.
+ - [НЕОБЯЗАТЕЛЬНО] data: используется для отправки дополнительной информации с вашим переводом или вызова смарт-контракта, не требуется для переводов баланса, см. примечание ниже.
+- `signedTx`: для подписания нашего объекта транзакции мы будем использовать метод `signTransaction` с нашим `PRIVATE_KEY`.
+- `sendSignedTransaction`: как только у нас будет подписанная транзакция, мы можем отправить ее для включения в последующий блок с помощью `sendSignedTransaction`.
+
+**Примечание о данных**
+Существует два основных типа транзакций, которые можно отправлять в Ethereum.
+
+- Перевод баланса: отправка ETH с одного адреса на другой. Поле данных не требуется, однако, если вы хотите отправить дополнительную информацию вместе с транзакцией, вы можете включить эту информацию в формате HEX в это поле.
+ - Например, предположим, мы хотим записать хеш документа IPFS в блокчейн Ethereum, чтобы присвоить ему неизменяемую временную метку. Тогда наше поле данных должно выглядеть так: data: `web3.utils.toHex('хеш IPFS')`. И теперь любой может сделать запрос к блокчейну и увидеть, когда этот документ был добавлен.
+- Транзакция смарт-контракта: выполните какой-либо код смарт-контракта в блокчейне. В этом случае поле данных должно содержать интеллектуальную функцию, которую вы хотите выполнить, а также любые параметры.
+ - Практический пример см. в шаге 8 этого [руководства «Hello World»](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#step-8-create-the-transaction).
+
+### 8. Запустите код с помощью `node sendTx.js` {#run-the-code-using-node-sendtx-js}
+
+Вернитесь в свой терминал или командную строку и выполните:
+
+```
+node sendTx.js
+```
+
+### 9. Просмотр транзакции в мемпуле {#see-your-transaction-in-the-mempool}
+
+Откройте [страницу Mempool](https://dashboard.alchemyapi.io/mempool) на панели инструментов Alchemy и отфильтруйте по созданному вами приложению, чтобы найти свою транзакцию. Здесь мы можем наблюдать, как наша транзакция переходит из состояния ожидания в состояние «добыто» (в случае успеха) или в состояние «отклонено» (в случае неудачи). Убедитесь, что вы оставили значение «All» (Все), чтобы отслеживать «добытые», «ожидающие» и «отклоненные» транзакции. Вы также можете найти свою транзакцию, выполнив поиск транзакций, отправленных на адрес `0x31b98d14007bdee637298086988a0bbd31184523`.
+
+Чтобы просмотреть детали вашей транзакции после того, как вы ее найдете, выберите хеш транзакции, после чего вы попадете на страницу, которая выглядит следующим образом:
+
+
+
+Оттуда вы можете просмотреть свою транзакцию на Etherscan, щелкнув значок, обведенный красным!
+
+**Урааа! Вы только что отправили свою первую транзакцию Ethereum с помощью Alchemy 🎉**
+
+_Чтобы оставить отзыв и предложения по этому руководству, напишите Элану в [Discord](https://discord.gg/A39JVCM) от Alchemy!_
+
+_Оригинал статьи опубликован по адресу [https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy](https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy)_
diff --git a/public/content/translations/ru/developers/tutorials/server-components/index.md b/public/content/translations/ru/developers/tutorials/server-components/index.md
new file mode 100644
index 00000000000..e43b6f988b2
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/server-components/index.md
@@ -0,0 +1,295 @@
+---
+title: "Серверные компоненты и агенты для приложений Web3"
+description: "Прочитав это руководство, вы сможете писать серверы на TypeScript, которые прослушивают события в блокчейне и соответствующим образом реагируют на них собственными транзакциями. Это позволит вам писать централизованные приложения (поскольку сервер является точкой отказа), которые могут взаимодействовать с сущностями Web3. Эти же методы можно использовать для написания агента, который реагирует на ончейн-события без участия человека."
+
+author: Ori Pomerantz
+lang: ru
+tags: [ "агент", "сервер", "офчейн" ]
+skill: beginner
+published: 2024-07-15
+---
+
+## Введение {#introduction}
+
+В большинстве случаев децентрализованное приложение использует сервер для распространения программного обеспечения, но все фактическое взаимодействие происходит между клиентом (обычно веб-браузером) и блокчейном.
+
+
+
+Однако есть случаи, когда приложению было бы полезно иметь независимо работающий серверный компонент. Такой сервер сможет реагировать на события и запросы, поступающие из других источников, например API, создавая транзакции.
+
+
+
+Такой сервер может выполнять несколько возможных задач.
+
+- Хранитель секретного состояния. В играх часто бывает полезно, чтобы не вся известная игре информация была доступна игрокам. Однако _в блокчейне нет секретов_, и любую информацию, находящуюся в блокчейне, легко может узнать кто угодно. Поэтому, если часть состояния игры должна храниться в секрете, ее необходимо хранить в другом месте (и, возможно, проверять эффекты этого состояния с помощью [доказательств с 0-знанием](/zero-knowledge-proofs)).
+
+- Централизованный оракул. Если ставки достаточно низки, внешнего сервера, который считывает некоторую информацию в сети, а затем публикует ее в цепи, может быть достаточно для использования в качестве [оракула](/developers/docs/oracles/).
+
+- Агент. В блокчейне ничего не происходит без транзакции, которая это активирует. Сервер может действовать от имени пользователя для выполнения таких действий, как [арбитраж](/developers/docs/mev/#mev-examples-dex-arbitrage), когда предоставляется такая возможность.
+
+## Пример программы {#sample-program}
+
+Пример сервера можно посмотреть [на GitHub](https://github.com/qbzzt/20240715-server-component). Этот сервер прослушивает события, поступающие от [этого контракта](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=contract_code), модифицированной версии Greeter от Hardhat. Когда приветствие изменяется, он меняет его обратно.
+
+Чтобы запустить ее:
+
+1. Клонируйте репозиторий.
+
+ ```sh copy
+ git clone https://github.com/qbzzt/20240715-server-component.git
+ cd 20240715-server-component
+ ```
+
+2. Установить нужные пакеты. Если у вас еще нет Node, [сначала установите его](https://nodejs.org/en/download/package-manager).
+
+ ```sh copy
+ npm install
+ ```
+
+3. Отредактируйте `.env`, чтобы указать приватный ключ аккаунта, на котором есть ETH в тестовой сети Holesky. Если у вас нет ETH в сети Holesky, вы можете [воспользоваться этим краном](https://holesky-faucet.pk910.de/).
+
+ ```sh filename=".env" copy
+ PRIVATE_KEY=0x <сюда введите приватный ключ>
+ ```
+
+4. Запустите сервер.
+
+ ```sh copy
+ npm start
+ ```
+
+5. Перейдите в [обозреватель блоков](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=write_contract) и, используя адрес, отличный от того, к которому относится приватный ключ, измените приветствие. Вы увидите, что приветствие автоматически изменится обратно.
+
+### Как это работает? {#how-it-works}
+
+Самый простой способ понять, как написать серверный компонент, — это построчно разобрать пример.
+
+#### `src/app.ts` {#src-app-ts}
+
+Основная часть программы содержится в [`src/app.ts`](https://github.com/qbzzt/20240715-server-component/blob/main/src/app.ts).
+
+##### Создание необходимых объектов
+
+```typescript
+import {
+ createPublicClient,
+ createWalletClient,
+ getContract,
+ http,
+ Address,
+} from "viem"
+```
+
+Это сущности [Viem](https://viem.sh/), которые нам нужны: функции и [тип `Address`](https://viem.sh/docs/glossary/types#address). Этот сервер написан на [TypeScript](https://www.typescriptlang.org/) — расширении JavaScript, которое делает его [строго типизированным](https://en.wikipedia.org/wiki/Strong_and_weak_typing).
+
+```typescript
+import { privateKeyToAccount } from "viem/accounts"
+```
+
+[Эта функция](https://viem.sh/docs/accounts/privateKey) позволяет нам генерировать информацию о кошельке, включая адрес, соответствующий приватному ключу.
+
+```typescript
+import { holesky } from "viem/chains"
+```
+
+Чтобы использовать блокчейн в Viem, необходимо импортировать его определение. В данном случае мы хотим подключиться к тестовому блокчейну [Holesky](https://github.com/eth-clients/holesky).
+
+```typescript
+// Так мы добавляем определения из .env в process.env.
+import * as dotenv from "dotenv"
+dotenv.config()
+```
+
+Таким образом мы считываем `.env` в окружение. Это нужно нам для приватного ключа (см. далее).
+
+```typescript
+const greeterAddress : Address = "0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6"
+const greeterABI = [
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_greeting",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ .
+ .
+ .
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_greeting",
+ "type": "string"
+ }
+ ],
+ "name": "setGreeting",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+] as const
+```
+
+Для использования контракта нам нужен его адрес и [ABI](/glossary/#abi). Здесь мы предоставляем и то, и другое.
+
+В JavaScript (и, следовательно, в TypeScript) нельзя присвоить новое значение константе, но _можно_ изменить объект, который в ней хранится. Используя суффикс `as const`, мы сообщаем TypeScript, что сам список является константой и не может быть изменен.
+
+```typescript
+const publicClient = createPublicClient({
+ chain: holesky,
+ transport: http(),
+})
+```
+
+Создайте [публичный клиент](https://viem.sh/docs/clients/public.html) Viem. Публичные клиенты не имеют привязанного приватного ключа и поэтому не могут отправлять транзакции. Они могут вызывать [функции `view`](https://www.tutorialspoint.com/solidity/solidity_view_functions.htm), считывать балансы аккаунтов и т. д.
+
+```typescript
+const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
+```
+
+Переменные окружения доступны в [`process.env`](https://www.totaltypescript.com/how-to-strongly-type-process-env). Однако TypeScript строго типизирован. Переменная окружения может быть любой строкой или пустой, поэтому тип для переменной окружения — `string | undefined`. Однако ключ в Viem определяется как `0x${string}` (`0x`, за которым следует строка). Здесь мы сообщаем TypeScript, что переменная окружения `PRIVATE_KEY` будет этого типа. Если это не так, мы получим ошибку времени выполнения.
+
+Функция [`privateKeyToAccount`](https://viem.sh/docs/accounts/privateKey) затем использует этот приватный ключ для создания полного объекта аккаунта.
+
+```typescript
+const walletClient = createWalletClient({
+ account,
+ chain: holesky,
+ transport: http(),
+})
+```
+
+Далее мы используем объект аккаунта для создания [клиента кошелька](https://viem.sh/docs/clients/wallet). Этот клиент имеет приватный ключ и адрес, поэтому его можно использовать для отправки транзакций.
+
+```typescript
+const greeter = getContract({
+ address: greeterAddress,
+ abi: greeterABI,
+ client: { public: publicClient, wallet: walletClient },
+})
+```
+
+Теперь, когда у нас есть все необходимое, мы можем наконец создать [экземпляр контракта](https://viem.sh/docs/contract/getContract). Мы будем использовать этот экземпляр контракта для связи с ончейн-контрактом.
+
+##### Чтение из блокчейна
+
+```typescript
+console.log(`Current greeting:`, await greeter.read.greet())
+```
+
+Функции контракта, предназначенные только для чтения ([`view`](https://www.tutorialspoint.com/solidity/solidity_view_functions.htm) и [`pure`](https://www.tutorialspoint.com/solidity/solidity_pure_functions.htm)), доступны в `read`. В данном случае мы используем ее для доступа к функции [`greet`](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=read_contract#cfae3217), которая возвращает приветствие.
+
+JavaScript является однопоточным, поэтому, когда мы запускаем длительный процесс, нам нужно [указать, что мы делаем это асинхронно](https://eloquentjavascript.net/11_async.html#h-XvLsfAhtsE). Вызов блокчейна, даже для операции только для чтения, требует обмена данными между компьютером и узлом блокчейна. Именно по этой причине мы указываем, что код должен `await` (ожидать) результата.
+
+Если вам интересно, как это работает, вы можете [прочитать об этом здесь](https://www.w3schools.com/js/js_promise.asp), но на практике все, что вам нужно знать, это то, что вы должны `await` (ожидать) результатов, если вы начинаете операцию, которая занимает много времени, и что любая функция, которая это делает, должна быть объявлена как `async`.
+
+##### Создание транзакций
+
+```typescript
+const setGreeting = async (greeting: string): Promise => {
+```
+
+Это функция, которую вы вызываете для создания транзакции, изменяющей приветствие. Поскольку это длительная операция, функция объявлена как `async`. Из-за внутренней реализации любая `async`-функция должна возвращать объект `Promise`. В данном случае `Promise` означает, что мы не указываем, что именно будет возвращено в `Promise`.
+
+```typescript
+const txHash = await greeter.write.setGreeting([greeting])
+```
+
+Поле `write` экземпляра контракта содержит все функции, которые записывают данные в состояние блокчейна (те, которые требуют отправки транзакции), например [`setGreeting`](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=write_contract#a4136862). Параметры, если они есть, предоставляются в виде списка, а функция возвращает хэш транзакции.
+
+```typescript
+ console.log(`Working on a fix, see https://eth-holesky.blockscout.com/tx/${txHash}`)
+
+ return txHash
+}
+```
+
+Сообщите хэш транзакции (как часть URL-адреса для его просмотра в обозревателе блоков) и верните его.
+
+##### Реагирование на события
+
+```typescript
+greeter.watchEvent.SetGreeting({
+```
+
+[Функция `watchEvent`](https://viem.sh/docs/actions/public/watchEvent) позволяет указать функцию, которая будет выполняться при возникновении события. Если вас интересует только один тип события (в данном случае `SetGreeting`), вы можете использовать этот синтаксис, чтобы ограничиться этим типом события.
+
+```typescript
+ onLogs: logs => {
+```
+
+Функция `onLogs` вызывается при наличии записей в журнале. В Ethereum «log» (запись в журнале) и «event» (событие), как правило, взаимозаменяемы.
+
+```typescript
+console.log(
+ `Address ${logs[0].args.sender} changed the greeting to ${logs[0].args.greeting}`
+)
+```
+
+Событий может быть несколько, но для простоты нас интересует только первое. `logs[0].args` — это аргументы события, в данном случае `sender` и `greeting`.
+
+```typescript
+ if (logs[0].args.sender != account.address)
+ setGreeting(`${account.address} insists on it being Hello!`)
+ }
+})
+```
+
+Если отправитель — _не_ этот сервер, используйте `setGreeting`, чтобы изменить приветствие.
+
+#### `package.json` {#package-json}
+
+[Этот файл](https://github.com/qbzzt/20240715-server-component/blob/main/package.json) управляет конфигурацией [Node.js](https://nodejs.org/en). В этой статье объясняются только важные определения.
+
+```json
+{
+ "main": "dist/index.js",
+```
+
+Это определение указывает, какой файл JavaScript нужно запустить.
+
+```json
+ "scripts": {
+ "start": "tsc && node dist/app.js",
+ },
+```
+
+Скрипты — это различные действия приложения. В данном случае у нас есть только `start`, который компилирует, а затем запускает сервер. Команда `tsc` является частью пакета `typescript` и компилирует TypeScript в JavaScript. Если вы хотите запустить его вручную, он находится в `node_modules/.bin`. Вторая команда запускает сервер.
+
+```json
+ "type": "module",
+```
+
+Существует несколько типов приложений Node.js. Тип `module` позволяет нам использовать `await` в коде верхнего уровня, что важно при выполнении медленных (и, следовательно, асинхронных) операций.
+
+```json
+ "devDependencies": {
+ "@types/node": "^20.14.2",
+ "typescript": "^5.4.5"
+ },
+```
+
+Это пакеты, которые требуются только для разработки. Здесь нам нужен `typescript`, и поскольку мы используем его с Node.js, мы также получаем типы для переменных и объектов node, таких как `process`. [Обозначение `^`](https://github.com/npm/node-semver?tab=readme-ov-file#caret-ranges-123-025-004) означает эту версию или более высокую версию, не содержащую критических изменений. Подробнее о значении номеров версий см. [здесь](https://semver.org).
+
+```json
+ "dependencies": {
+ "dotenv": "^16.4.5",
+ "viem": "2.14.1"
+ }
+}
+```
+
+Это пакеты, которые требуются во время выполнения, при запуске `dist/app.js`.
+
+## Заключение {#conclusion}
+
+Созданный нами здесь централизованный сервер выполняет свою работу — действует как агент для пользователя. Любой другой, кто хочет, чтобы децентрализованное приложение продолжало функционировать, и готов потратить газ, может запустить новый экземпляр сервера со своим собственным адресом.
+
+Однако это работает только тогда, когда действия централизованного сервера можно легко проверить. Если централизованный сервер хранит какую-либо информацию о секретном состоянии или выполняет сложные вычисления, он является централизованной сущностью, которой необходимо доверять для использования приложения, а это именно то, чего пытаются избежать блокчейны. В одной из следующих статей я планирую показать, как использовать [доказательства с 0-знанием](/zero-knowledge-proofs), чтобы обойти эту проблему.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
diff --git a/public/content/translations/ru/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md b/public/content/translations/ru/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md
new file mode 100644
index 00000000000..fce1e32f487
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md
@@ -0,0 +1,92 @@
+---
+title: "Настройка web3.js для использования блокчейна Ethereum в JavaScript"
+description: "Узнайте, как настраивать и конфигурировать библиотеку web3.js для взаимодействия с блокчейном Ethereum из JavaScript-приложений."
+author: "jdourlens"
+tags: [ "web3.js", "JavaScript" ]
+skill: beginner
+lang: ru
+published: 2020-04-11
+source: EthereumDev
+sourceUrl: https://ethereumdev.io/setup-web3js-to-use-the-ethereum-blockchain-in-javascript/
+address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"
+---
+
+В этом руководстве мы рассмотрим, как начать работу с [web3.js](https://web3js.readthedocs.io/), чтобы взаимодействовать с блокчейном Ethereum. Web3.js можно использовать как во фронтенде, так и в бэкенде, чтобы считывать данные из блокчейна, совершать транзакции и даже развертывать смарт-контракты.
+
+Первый шаг — это включить web3.js в ваш проект. Чтобы использовать его на веб-странице, вы можете импортировать библиотеку напрямую, используя CDN, например JSDeliver.
+
+```html
+
+```
+
+Если вы предпочитаете установить библиотеку для использования в бэкенде или в проекте с фронтендом, использующим сборку, вы можете установить ее с помощью npm:
+
+```bash
+npm install web3 --save
+```
+
+Затем, чтобы импортировать Web3.js в скрипт Node.js или фронтенд-проект Browserify, вы можете использовать следующую строку JavaScript:
+
+```js
+const Web3 = require("web3")
+```
+
+Теперь, когда мы включили библиотеку в проект, нам нужно ее инициализировать. Ваш проект должен иметь возможность взаимодействовать с блокчейном. Большинство библиотек Ethereum взаимодействуют с [узлом](/developers/docs/nodes-and-clients/) через вызовы RPC. Чтобы инициализировать нашего провайдера Web3, мы создадим экземпляр Web3, передав в конструктор URL-адрес провайдера. Если у вас есть узел или [экземпляр ganache, запущенный на вашем компьютере](https://ethereumdev.io/testing-your-smart-contract-with-existing-protocols-ganache-fork/), это будет выглядеть так:
+
+```js
+const web3 = new Web3("http://localhost:8545")
+```
+
+Если вы хотите получить прямой доступ к размещенному узлу, вы можете найти варианты на странице [«Узлы как услуга»](/developers/docs/nodes-and-clients/nodes-as-a-service).
+
+```js
+const web3 = new Web3("https://cloudflare-eth.com")
+```
+
+Чтобы проверить, правильно ли мы настроили наш экземпляр Web3, мы попытаемся получить номер последнего блока с помощью функции `getBlockNumber`. Эта функция принимает в качестве параметра обратный вызов и возвращает номер блока в виде целого числа.
+
+```js
+var Web3 = require("web3")
+const web3 = new Web3("https://cloudflare-eth.com")
+
+web3.eth.getBlockNumber(function (error, result) {
+ console.log(result)
+})
+```
+
+Если вы выполните эту программу, она просто выведет номер последнего блока: вершину блокчейна. Вы также можете использовать вызовы функций `await/async`, чтобы избежать вложенных обратных вызовов в вашем коде:
+
+```js
+async function getBlockNumber() {
+ const latestBlockNumber = await web3.eth.getBlockNumber()
+ console.log(latestBlockNumber)
+ return latestBlockNumber
+}
+
+getBlockNumber()
+```
+
+Вы можете увидеть все функции, доступные в экземпляре Web3, в [официальной документации web3.js](https://docs.web3js.org/).
+
+Большинство библиотек Web3 асинхронны, потому что в фоновом режиме библиотека выполняет вызовы JSON-RPC к узлу, который отправляет обратно результат.
+
+
+
+Если вы работаете в браузере, некоторые кошельки напрямую внедряют экземпляр Web3, и вам следует пытаться использовать его по возможности, особенно если вы планируете взаимодействовать с адресом Ethereum пользователя для совершения транзакций.
+
+Вот фрагмент кода для обнаружения доступности кошелька MetaMask и попытки его включения. Это позволит вам в дальнейшем считывать баланс пользователя и дать ему возможность подтверждать транзакции, которые вы хотите, чтобы он совершал в блокчейне Ethereum:
+
+```js
+if (window.ethereum != null) {
+ state.web3 = new Web3(window.ethereum)
+ try {
+ // При необходимости запросить доступ к аккаунту
+ await window.ethereum.enable()
+ // Аккаунты теперь доступны
+ } catch (error) {
+ // Пользователь отказал в доступе к аккаунту...
+ }
+}
+```
+
+Существуют и широко используются альтернативы web3.js, такие как [Ethers.js](https://docs.ethers.io/). В следующем руководстве мы рассмотрим, [как легко отслеживать поступление новых блоков в блокчейне и видеть их содержимое](https://ethereumdev.io/listening-to-new-transactions-happening-on-the-blockchain/).
diff --git a/public/content/translations/ru/developers/tutorials/short-abi/index.md b/public/content/translations/ru/developers/tutorials/short-abi/index.md
new file mode 100644
index 00000000000..4a1b95464c6
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/short-abi/index.md
@@ -0,0 +1,585 @@
+---
+title: "Краткие ABI для оптимизации calldata"
+description: "Оптимизация смарт-контрактов для оптимистических ролл-апов"
+author: Ori Pomerantz
+lang: ru
+tags: [ "уровень 2" ]
+skill: intermediate
+published: 2022-04-01
+---
+
+## Введение {#introduction}
+
+В этой статье вы узнаете об [оптимистических ролл-апах](/developers/docs/scaling/optimistic-rollups), стоимости транзакций на них и о том, как эта иная структура затрат требует от нас оптимизации для других целей, чем в основной сети Ethereum.
+Вы также узнаете, как реализовать эту оптимизацию.
+
+### Полное раскрытие информации {#full-disclosure}
+
+Я штатный сотрудник [Optimism](https://www.optimism.io/), поэтому примеры в этой статье будут работать на Optimism.
+Однако описанная здесь техника должна работать так же хорошо и для других ролл-апов.
+
+### Терминология {#terminology}
+
+При обсуждении ролл-апов термин «уровень 1» (L1) используется для Mainnet, производственной сети Ethereum.
+Термин «уровень 2» (L2) используется для ролл-апа или любой другой системы, которая полагается на L1 для обеспечения безопасности, но выполняет большую часть своей обработки вне сети.
+
+## Как мы можем еще больше снизить стоимость транзакций на L2? {#how-can-we-further-reduce-the-cost-of-L2-transactions}
+
+[Оптимистические ролл-апы](/developers/docs/scaling/optimistic-rollups) должны сохранять запись каждой исторической транзакции, чтобы любой мог просмотреть их и проверить правильность текущего состояния.
+Самый дешевый способ передать данные в основную сеть Ethereum — это записать их как calldata.
+Это решение было выбрано как [Optimism](https://help.optimism.io/hc/en-us/articles/4413163242779-What-is-a-rollup-), так и [Arbitrum](https://developer.offchainlabs.com/docs/rollup_basics#intro-to-rollups).
+
+### Стоимость транзакций на L2 {#cost-of-l2-transactions}
+
+Стоимость транзакций на L2 состоит из двух компонентов:
+
+1. Обработка на L2, которая обычно чрезвычайно дешева
+2. Хранилище на L1, которое привязано к стоимости газа в Mainnet
+
+На момент написания этой статьи стоимость газа на L2 в Optimism составляет 0,001 [Gwei](/developers/docs/gas/#pre-london).
+С другой стороны, стоимость газа на L1 составляет примерно 40 Gwei.
+[Текущие цены можно посмотреть здесь](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m).
+
+Байт calldata стоит либо 4 газа (если он нулевой), либо 16 газа (если это любое другое значение).
+Одна из самых дорогостоящих операций в EVM — это запись в хранилище.
+Максимальная стоимость записи 32-байтового слова в хранилище на L2 составляет 22 100 газа. На данный момент это 22,1 Gwei.
+Таким образом, если мы сможем сэкономить хотя бы один нулевой байт calldata, мы сможем записать в хранилище около 200 байт и все равно остаться в выигрыше.
+
+### ABI {#the-abi}
+
+В подавляющем большинстве операций доступ к контракту осуществляется с внешнего аккаунта.
+Большинство контрактов написаны на Solidity и интерпретируют поле данных в соответствии с [двоичным интерфейсом приложения (ABI)](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding).
+
+Однако ABI был разработан для L1, где байт calldata стоит примерно столько же, сколько четыре арифметические операции, а не для L2, где байт calldata стоит более тысячи арифметических операций.
+Calldata разделяется следующим образом:
+
+| Раздел | Длина | Байты | Потраченные впустую байты | Потраченный впустую газ | Необходимые байты | Необходимый газ |
+| ---------------- | ----: | ----: | ------------------------: | ----------------------: | ----------------: | --------------: |
+| Селектор функции | 4 | 0-3 | 3 | 48 | 1 | 16 |
+| Нули | 12 | 4-15 | 12 | 48 | 0 | 0 |
+| Адрес назначения | 20 | 16-35 | 0 | 0 | 20 | 320 |
+| Сумма | 32 | 36-67 | 17 | 64 | 15 | 240 |
+| Итого | 68 | | | 160 | | 576 |
+
+Пояснение:
+
+- **Селектор функции**: в контракте менее 256 функций, поэтому мы можем различать их по одному байту.
+ Эти байты обычно ненулевые, и поэтому [стоят шестнадцать газа](https://eips.ethereum.org/EIPS/eip-2028).
+- **Нули**: эти байты всегда равны нулю, поскольку для хранения двадцатибайтового адреса не требуется тридцатидвухбайтовое слово.
+ Байты, которые содержат ноль, стоят четыре единицы газа ([см. Желтую книгу](https://ethereum.github.io/yellowpaper/paper.pdf), Приложение G,
+ стр. 27, значение для `G``txdatazero`).
+- **Сумма**: если предположить, что в этом контракте `decimals` равно восемнадцати (стандартное значение), а максимальное количество токенов, которое мы переводим, составит 1018, то мы получим максимальную сумму в 1036.
+ 25615 > 1036, так что пятнадцати байт достаточно.
+
+Потеря 160 единиц газа на L1 обычно незначительна. Транзакция стоит как минимум [21 000 газа](https://yakkomajuri.medium.com/blockchain-definition-of-the-week-ethereum-gas-2f976af774ed), так что лишние 0,8% не имеют значения.
+Однако на L2 все иначе. Почти вся стоимость транзакции — это ее запись на L1.
+В дополнение к calldata транзакции существует 109 байт заголовка транзакции (адрес назначения, подпись и т. д.).
+Таким образом, общая стоимость составляет `109*16+576+160=2480`, и мы тратим впустую около 6,5% от этой суммы.
+
+## Снижение затрат, когда вы не контролируете назначение {#reducing-costs-when-you-dont-control-the-destination}
+
+Если предположить, что у вас нет контроля над контрактом назначения, вы все равно можете использовать решение, подобное [этому](https://github.com/qbzzt/ethereum.org-20220330-shortABI).
+Давайте рассмотрим соответствующие файлы.
+
+### Token.sol {#token-sol}
+
+[Это контракт назначения](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/Token.sol).
+Это стандартный контракт ERC-20 с одной дополнительной функцией.
+Эта функция `faucet` позволяет любому пользователю получить немного токенов для использования.
+Это сделало бы производственный контракт ERC-20 бесполезным, но это облегчает жизнь, когда ERC-20 существует только для упрощения тестирования.
+
+```solidity
+ /**
+ * @dev Дает вызывающему 1000 токенов для использования
+ */
+ function faucet() external {
+ _mint(msg.sender, 1000);
+ } // функция faucet
+```
+
+### CalldataInterpreter.sol {#calldatainterpreter-sol}
+
+[Это контракт, который транзакции должны вызывать с более короткими calldata](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/CalldataInterpreter.sol).
+Давайте рассмотрим его построчно.
+
+```solidity
+//SPDX-License-Identifier: Unlicense
+pragma solidity ^0.8.0;
+
+
+import { OrisUselessToken } from "./Token.sol";
+```
+
+Нам нужна функция токена, чтобы знать, как ее вызывать.
+
+```solidity
+contract CalldataInterpreter {
+
+ OrisUselessToken public immutable token;
+```
+
+Адрес токена, для которого мы являемся прокси.
+
+```solidity
+
+ /**
+ * @dev Укажите адрес токена
+ * @param tokenAddr_ адрес контракта ERC-20
+ */
+ constructor(
+ address tokenAddr_
+ ) {
+ token = OrisUselessToken(tokenAddr_);
+ } // конструктор
+```
+
+Адрес токена — единственный параметр, который нам нужно указать.
+
+```solidity
+ function calldataVal(uint startByte, uint length)
+ private pure returns (uint) {
+```
+
+Считываем значение из calldata.
+
+```solidity
+ uint _retVal;
+
+ require(length < 0x21,
+ "предел длины calldataVal — 32 байта");
+
+ require(length + startByte <= msg.data.length,
+ "calldataVal пытается прочитать за пределами calldatasize");
+```
+
+Мы собираемся загрузить в память одно 32-байтовое (256-битное) слово и удалить байты, которые не являются частью нужного нам поля.
+Этот алгоритм не работает для значений длиннее 32 байт, и, конечно же, мы не можем читать за концом calldata.
+На L1 может быть необходимо пропустить эти тесты для экономии газа, но на L2 газ чрезвычайно дешев, что позволяет проводить любые проверки на вменяемость (sanity check), какие только можно придумать.
+
+```solidity
+ assembly {
+ _retVal := calldataload(startByte)
+ }
+```
+
+Мы могли бы скопировать данные из вызова в `fallback()` (см. ниже), но проще использовать [Yul](https://docs.soliditylang.org/en/v0.8.12/yul.html), язык ассемблера EVM.
+
+Здесь мы используем [опкод CALLDATALOAD](https://www.evm.codes/#35), чтобы считать байты с `startByte` до `startByte+31` в стек.
+В общем, синтаксис опкода в Yul следующий: `<имя опкода>(<первое значение стека, если есть>,<второе значение стека, если есть>...)`.
+
+```solidity
+
+ _retVal = _retVal >> (256-length*8);
+```
+
+Только самые старшие `length` байт являются частью поля, поэтому мы делаем [сдвиг вправо](https://en.wikipedia.org/wiki/Logical_shift), чтобы избавиться от других значений.
+Это дает дополнительное преимущество, перемещая значение в правую часть поля, так что это само значение, а не значение, умноженное на 256что-то.
+
+```solidity
+
+ return _retVal;
+ }
+
+
+ fallback() external {
+```
+
+Когда вызов контракта Solidity не соответствует ни одной из сигнатур функций, он вызывает [функцию `fallback()`](https://docs.soliditylang.org/en/v0.8.12/contracts.html#fallback-function) (если она есть).
+В случае с `CalldataInterpreter` любой вызов попадает сюда, потому что других `external` или `public` функций нет.
+
+```solidity
+ uint _func;
+
+ _func = calldataVal(0, 1);
+```
+
+Считываем первый байт calldata, который сообщает нам функцию.
+Есть две причины, по которым эта функция может быть недоступна:
+
+1. Функции `pure` или `view` не изменяют состояние и не требуют газа (при вызове вне сети).
+ Нет смысла пытаться снизить их стоимость в газе.
+2. Функции, которые полагаются на [`msg.sender`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#block-and-transaction-properties).
+ Значением `msg.sender` будет адрес `CalldataInterpreter`, а не вызывающего.
+
+К сожалению, [если посмотреть на спецификации ERC-20](https://eips.ethereum.org/EIPS/eip-20), остается только одна функция — `transfer`.
+У нас остается только две функции: `transfer` (потому что мы можем вызвать `transferFrom`) и `faucet` (потому что мы можем перевести токены обратно тому, кто нас вызвал).
+
+```solidity
+
+ // Вызов методов изменения состояния токена с использованием
+ // информации из calldata
+
+ // faucet
+ if (_func == 1) {
+```
+
+Вызов `faucet()`, у которого нет параметров.
+
+```solidity
+ token.faucet();
+ token.transfer(msg.sender,
+ token.balanceOf(address(this)));
+ }
+```
+
+После вызова `token.faucet()` мы получаем токены. Однако нам как прокси-контракту токены не **нужны**.
+Они нужны EOA (внешнему аккаунту) или контракту, который нас вызвал.
+Поэтому мы переводим все наши токены тому, кто нас вызвал.
+
+```solidity
+ // transfer (предполагается, что у нас есть разрешение на это)
+ if (_func == 2) {
+```
+
+Для перевода токенов требуются два параметра: адрес назначения и сумма.
+
+```solidity
+ token.transferFrom(
+ msg.sender,
+```
+
+Мы разрешаем вызывающим переводить только те токены, которыми они владеют
+
+```solidity
+ address(uint160(calldataVal(1, 20))),
+```
+
+Адрес назначения начинается с байта №1 (байт №0 — это функция).
+Как адрес, он имеет длину 20 байт.
+
+```solidity
+ calldataVal(21, 2)
+```
+
+Для этого конкретного контракта мы предполагаем, что максимальное количество токенов, которое кто-либо захочет перевести, умещается в два байта (менее 65 536).
+
+```solidity
+ );
+ }
+```
+
+В целом перевод занимает 35 байт calldata:
+
+| Раздел | Длина | Байты |
+| ---------------- | ----: | ----: |
+| Селектор функции | 1 | 0 |
+| Адрес назначения | 32 | 1-32 |
+| Сумма | 2 | 33-34 |
+
+```solidity
+ } // fallback
+
+} // контракт CalldataInterpreter
+```
+
+### test.js {#test-js}
+
+[Этот модульный тест на JavaScript](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/test/test.js) показывает, как использовать этот механизм (и как проверить, что он работает правильно).
+Я буду исходить из того, что вы понимаете [chai](https://www.chaijs.com/) и [ethers](https://docs.ethers.io/v5/) и объясню только те части, которые относятся непосредственно к контракту.
+
+```js
+const { expect } = require("chai");
+
+describe("CalldataInterpreter", function () {
+ it("Должен позволить нам использовать токены", async function () {
+ const Token = await ethers.getContractFactory("OrisUselessToken")
+ const token = await Token.deploy()
+ await token.deployed()
+ console.log("Адрес токена:", token.address)
+
+ const Cdi = await ethers.getContractFactory("CalldataInterpreter")
+ const cdi = await Cdi.deploy(token.address)
+ await cdi.deployed()
+ console.log("Адрес CalldataInterpreter:", cdi.address)
+
+ const signer = await ethers.getSigner()
+```
+
+Мы начинаем с развертывания обоих контрактов.
+
+```javascript
+ // Получаем токены для использования
+ const faucetTx = {
+```
+
+Мы не можем использовать высокоуровневые функции, которые обычно используем (например, `token.faucet()`) для создания транзакций, потому что мы не следуем ABI.
+Вместо этого мы должны создать транзакцию самостоятельно, а затем отправить ее.
+
+```javascript
+ to: cdi.address,
+ data: "0x01"
+```
+
+Для транзакции необходимо указать два параметра:
+
+1. `to` — адрес назначения.
+ Это контракт-интерпретатор calldata.
+2. `data` — отправляемые calldata.
+ В случае вызова faucet данные представляют собой один байт, `0x01`.
+
+```javascript
+
+ }
+ await (await signer.sendTransaction(faucetTx)).wait()
+```
+
+Мы вызываем [метод `sendTransaction` подписанта](https://docs.ethers.io/v5/api/signer/#Signer-sendTransaction), потому что мы уже указали назначение (`faucetTx.to`), и нам нужно, чтобы транзакция была подписана.
+
+```javascript
+// Проверяем, что faucet правильно предоставляет токены
+expect(await token.balanceOf(signer.address)).to.equal(1000)
+```
+
+Здесь мы проверяем баланс.
+Нет необходимости экономить на газе для функций `view`, поэтому мы просто запускаем их в обычном режиме.
+
+```javascript
+// Даем CDI разрешение (одобрения не могут быть проксированы)
+const approveTX = await token.approve(cdi.address, 10000)
+await approveTX.wait()
+expect(await token.allowance(signer.address, cdi.address)).to.equal(10000)
+```
+
+Даем интерпретатору calldata разрешение на выполнение переводов.
+
+```javascript
+// Переводим токены
+const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d"
+const transferTx = {
+ to: cdi.address,
+ data: "0x02" + destAddr.slice(2, 42) + "0100",
+}
+```
+
+Создайте транзакцию перевода. Первый байт — «0x02», за ним следует адрес назначения и, наконец, сумма (0x0100, что равно 256 в десятичном формате).
+
+```javascript
+ await (await signer.sendTransaction(transferTx)).wait()
+
+ // Проверяем, что у нас на 256 токенов меньше
+ expect (await token.balanceOf(signer.address)).to.equal(1000-256)
+
+ // И что наш получатель получил их
+ expect (await token.balanceOf(destAddr)).to.equal(256)
+ }) // it
+}) // describe
+```
+
+## Снижение затрат, когда вы контролируете контракт назначения {#reducing-the-cost-when-you-do-control-the-destination-contract}
+
+Если у вас есть контроль над контрактом назначения, вы можете создавать функции, которые обходят проверки `msg.sender`, поскольку они доверяют интерпретатору calldata.
+[Вы можете увидеть пример того, как это работает, здесь, в ветке `control-contract`](https://github.com/qbzzt/ethereum.org-20220330-shortABI/tree/control-contract).
+
+Если бы контракт отвечал только на внешние транзакции, мы могли бы обойтись всего одним контрактом.
+Однако это нарушило бы [компонуемость](/developers/docs/smart-contracts/composability/).
+Гораздо лучше иметь контракт, который отвечает на обычные вызовы ERC-20, и другой контракт, который отвечает на транзакции с короткими данными вызовов.
+
+### Token.sol {#token-sol-2}
+
+В этом примере мы можем изменить `Token.sol`.
+Это позволяет нам иметь ряд функций, которые может вызывать только прокси.
+Вот новые части:
+
+```solidity
+ // Единственный адрес, которому разрешено указывать адрес CalldataInterpreter
+ address owner;
+
+ // Адрес CalldataInterpreter
+ address proxy = address(0);
+```
+
+Контракт ERC-20 должен знать идентификатор авторизованного прокси.
+Однако мы не можем установить эту переменную в конструкторе, поскольку еще не знаем ее значение.
+Этот контракт создается первым, поскольку прокси-сервер ожидает адрес токена в своем конструкторе.
+
+```solidity
+ /**
+ * @dev Вызывает конструктор ERC20.
+ */
+ constructor(
+ ) ERC20("Oris useless token-2", "OUT-2") {
+ owner = msg.sender;
+ }
+```
+
+Здесь хранится адрес создателя (называемого `owner`), поскольку это единственный адрес, разрешенный для установки прокси.
+
+```solidity
+ /**
+ * @dev установить адрес для прокси (CalldataInterpreter).
+ * Может быть вызван только один раз владельцем
+ */
+ function setProxy(address _proxy) external {
+ require(msg.sender == owner, "Может быть вызван только владельцем");
+ require(proxy == address(0), "Прокси уже установлен");
+
+ proxy = _proxy;
+ } // функция setProxy
+```
+
+Прокси имеет привилегированный доступ, поскольку может обходить проверки безопасности.
+Чтобы убедиться, что мы можем доверять прокси, мы позволяем `owner` вызывать эту функцию, и только один раз.
+Как только `proxy` имеет реальное значение (не нулевое), это значение не может измениться, поэтому даже если владелец решит стать мошенником или будет раскрыта мнемоника для него, мы все равно будем в безопасности.
+
+```solidity
+ /**
+ * @dev Некоторые функции могут быть вызваны только прокси.
+ */
+ modifier onlyProxy {
+```
+
+Это [`модификатор` функции](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm), он изменяет способ работы других функций.
+
+```solidity
+ require(msg.sender == proxy);
+```
+
+Сначала убедитесь, что вам позвонил прокси и никто другой.
+Если нет, то `revert`.
+
+```solidity
+ _;
+ }
+```
+
+Если да, запустите функцию, которую мы модифицируем.
+
+```solidity
+ /* Функции, которые позволяют прокси фактически проксировать для аккаунтов */
+
+ function transferProxy(address from, address to, uint256 amount)
+ public virtual onlyProxy() returns (bool)
+ {
+ _transfer(from, to, amount);
+ return true;
+ }
+
+ function approveProxy(address from, address spender, uint256 amount)
+ public virtual onlyProxy() returns (bool)
+ {
+ _approve(from, spender, amount);
+ return true;
+ }
+
+ function transferFromProxy(
+ address spender,
+ address from,
+ address to,
+ uint256 amount
+ ) public virtual onlyProxy() returns (bool)
+ {
+ _spendAllowance(from, spender, amount);
+ _transfer(from, to, amount);
+ return true;
+ }
+```
+
+Для того чтобы сообщение пришло непосредственно от объекта, передающего токены или утверждающего разрешение, необходимы эти три операции.
+Здесь у нас есть прокси-версия этих операций, которая:
+
+1. Изменяется с помощью `onlyProxy()`, поэтому никто другой не может ими управлять.
+2. Получает адрес, который обычно выглядит как `msg.sender`, в качестве дополнительного параметра.
+
+### CalldataInterpreter.sol {#calldatainterpreter-sol-2}
+
+Интерпретатор calldata почти идентичен приведенному выше, за исключением того, что прокси-функции получают параметр `msg.sender` и нет необходимости в разрешении для `transfer`.
+
+```solidity
+ // transfer (разрешение не требуется)
+ if (_func == 2) {
+ token.transferProxy(
+ msg.sender,
+ address(uint160(calldataVal(1, 20))),
+ calldataVal(21, 2)
+ );
+ }
+
+ // approve
+ if (_func == 3) {
+ token.approveProxy(
+ msg.sender,
+ address(uint160(calldataVal(1, 20))),
+ calldataVal(21, 2)
+ );
+ }
+
+ // transferFrom
+ if (_func == 4) {
+ token.transferFromProxy(
+ msg.sender,
+ address(uint160(calldataVal( 1, 20))),
+ address(uint160(calldataVal(21, 20))),
+ calldataVal(41, 2)
+ );
+ }
+```
+
+### Test.js {#test-js-2}
+
+Между предыдущим тестовым кодом и этим есть несколько изменений.
+
+```js
+const Cdi = await ethers.getContractFactory("CalldataInterpreter")
+const cdi = await Cdi.deploy(token.address)
+await cdi.deployed()
+await token.setProxy(cdi.address)
+```
+
+Нам нужно указать контракту ERC-20, какому прокси нужно доверять
+
+```js
+console.log("Адрес CalldataInterpreter:", cdi.address)
+
+// Требуются два подписанта для проверки разрешений
+const signers = await ethers.getSigners()
+const signer = signers[0]
+const poorSigner = signers[1]
+```
+
+Для проверки `approve()` и `transferFrom()` нам понадобится второй подписант.
+Мы называем его `poorSigner`, потому что он не получает никаких наших токенов (хотя, конечно, у него должен быть ETH).
+
+```js
+// Переводим токены
+const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d"
+const transferTx = {
+ to: cdi.address,
+ data: "0x02" + destAddr.slice(2, 42) + "0100",
+}
+await (await signer.sendTransaction(transferTx)).wait()
+```
+
+Поскольку контракт ERC-20 доверяет прокси-серверу (`cdi`), нам не требуется разрешение на ретрансляцию передач.
+
+```js
+// approval и transferFrom
+const approveTx = {
+ to: cdi.address,
+ data: "0x03" + poorSigner.address.slice(2, 42) + "00FF",
+}
+await (await signer.sendTransaction(approveTx)).wait()
+
+const destAddr2 = "0xE1165C689C0c3e9642cA7606F5287e708d846206"
+
+const transferFromTx = {
+ to: cdi.address,
+ data: "0x04" + signer.address.slice(2, 42) + destAddr2.slice(2, 42) + "00FF",
+}
+await (await poorSigner.sendTransaction(transferFromTx)).wait()
+
+// Проверяем, что комбинация approve / transferFrom была выполнена правильно
+expect(await token.balanceOf(destAddr2)).to.equal(255)
+```
+
+Протестируйте две новые функции.
+Обратите внимание, что для `transferFromTx` требуются два параметра адреса: тот, кто выдал разрешение, и получатель.
+
+## Заключение {#conclusion}
+
+И [Optimism](https://medium.com/ethereum-optimism/the-road-to-sub-dollar-transactions-part-2-compression-edition-6bb2890e3e92), и [Arbitrum](https://developer.offchainlabs.com/docs/special_features) ищут способы уменьшить размер calldata, записываемых на L1, и, следовательно, стоимость транзакций.
+Однако, поскольку мы являемся поставщиками инфраструктуры, ищущими универсальные решения, наши возможности ограничены.
+Как разработчик децентрализованных приложений, вы обладаете знаниями, специфичными для приложения, что позволяет вам оптимизировать данные вызовов гораздо лучше, чем мы могли бы в обычном решении.
+Надеемся, эта статья поможет вам найти идеальное решение для ваших нужд.
+
+[Больше моих работ смотрите здесь](https://cryptodocguy.pro/).
+
diff --git a/public/content/translations/ru/developers/tutorials/smart-contract-security-guidelines/index.md b/public/content/translations/ru/developers/tutorials/smart-contract-security-guidelines/index.md
new file mode 100644
index 00000000000..1462903a817
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/smart-contract-security-guidelines/index.md
@@ -0,0 +1,91 @@
+---
+title: "Рекомендации по обеспечению безопасности смарт-контрактов"
+description: "Список рекомендаций по безопасности, которые следует учитывать при создании вашего децентрализованного приложения"
+author: "Trailofbits"
+tags: [ "Solidity", "смарт-контракты", "безопасность" ]
+skill: intermediate
+lang: ru
+published: 2020-09-06
+source: Building secure contracts
+sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/guidelines.md
+---
+
+Следуйте этим общим рекомендациям для создания более защищенных смарт-контрактов.
+
+## Руководство по дизайну {#design-guidelines}
+
+Разработку контракта следует обсуждать заранее, ещё до написания кода.
+
+### Документация и спецификации {#documentation-and-specifications}
+
+Документация может быть написана на разных уровнях и должна обновляться в процессе реализации контрактов:
+
+- **Описание системы на простом английском языке**, описывающее, что делают контракты, и любые допущения по кодовой базе.
+- **Схемы и архитектурные диаграммы**, включая взаимодействия контрактов и конечный автомат системы. [Принтеры Slither](https://github.com/crytic/slither/wiki/Printer-documentation) могут помочь в создании этих схем.
+- **Подробная документация кода**, для Solidity можно использовать [формат Natspec](https://docs.soliditylang.org/en/develop/natspec-format.html).
+
+### Ончейн- и офчейн-вычисления {#onchain-vs-offchain-computation}
+
+- **Старайтесь хранить как можно больше кода вне сети (офчейн).** Ончейн-уровень должен быть небольшим. Предварительно обрабатывайте данные с помощью кода офчейн таким образом, чтобы ончейн-проверка была простой. Вам нужен упорядоченный список? Сортируйте список офчейн, а затем просто проверяйте его порядок ончейн.
+
+### Возможность обновления {#upgradeability}
+
+Мы обсуждали различные решения для обновления в [нашей статье в блоге](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/). Примите осознанное решение о поддержке возможности обновления, прежде чем писать какой-либо код. Это решение повлияет на то, как вы структурируете свой код. В целом мы рекомендуем:
+
+- **Отдавайте предпочтение [миграции контрактов](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) перед возможностью обновления.** Системы миграции имеют многие из тех же преимуществ, что и обновляемые, но лишены их недостатков.
+- **Используйте шаблон разделения данных вместо шаблона delegatecallproxy.** Если в вашем проекте есть четкое разделение абстракций, возможность обновления с использованием разделения данных потребует лишь нескольких корректировок. Шаблон delegatecallproxy требует экспертных знаний EVM и очень подвержен ошибкам.
+- **Документируйте процедуру миграции/обновления перед развертыванием.** Если вам придется реагировать в стрессовой ситуации без каких-либо инструкций, вы совершите ошибки. Заранее опишите процедуру, которой нужно следовать. Она должна включать:
+ - Вызовы, которые инициируют новые контракты
+ - Где хранятся ключи и как получить к ним доступ
+ - Как проверить развертывание! Разработайте и протестируйте скрипт для запуска после развертывания.
+
+## Руководство по реализации {#implementation-guidelines}
+
+**Стремитесь к простоте.** Всегда используйте самое простое решение, которое соответствует вашей цели. Любой член вашей команды должен быть в состоянии понять ваше решение.
+
+### Композиция функций {#function-composition}
+
+Структура вашей кодовой базы должна облегчать просмотр вашего кода. Избегайте структуры, которая уменьшает возможность рассуждать о ее правильности.
+
+- **Разделяйте логику вашей системы** либо с помощью нескольких контрактов, либо путем группировки схожих функций (например, аутентификация, арифметика и т. д.).
+- **Пишите небольшие функции с четкой целью.** Это облегчит проверку и позволит тестировать отдельные компоненты.
+
+### Наследование {#inheritance}
+
+- **Сделайте наследование управляемым.** Наследование следует использовать для разделения логики, однако в вашем проекте следует стремиться к минимизации глубины и ширины дерева наследования.
+- **Используйте [принтер наследования Slither](https://github.com/crytic/slither/wiki/Printer-documentation#inheritance-graph) для проверки иерархии контрактов.** Принтер наследования поможет вам проверить размер иерархии.
+
+### События {#events}
+
+- **Записывайте в журнал все важные операции.** События помогут отладить контракт во время разработки и отслеживать его работу после развертывания.
+
+### Избегайте известных подводных камней {#avoid-known-pitfalls}
+
+- **Помните о наиболее распространенных проблемах безопасности.** Существует множество онлайн-ресурсов для изучения распространенных проблем, таких как [Ethernaut CTF](https://ethernaut.openzeppelin.com/), [Capture the Ether](https://capturetheether.com/) или [Not so smart contracts](https://github.com/crytic/not-so-smart-contracts/).
+- **Обращайте внимание на разделы с предупреждениями в [документации Solidity](https://docs.soliditylang.org/en/latest/).** Разделы с предупреждениями сообщат вам о неочевидном поведении языка.
+
+### Зависимости {#dependencies}
+
+- **Используйте хорошо протестированные библиотеки.** Импорт кода из хорошо протестированных библиотек снизит вероятность написания кода с ошибками. Если вы хотите написать контракт ERC20, используйте [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20).
+- **Используйте менеджер зависимостей; избегайте копирования и вставки кода.** Если вы полагаетесь на внешний источник, вы должны поддерживать его в актуальном состоянии в соответствии с оригинальным источником.
+
+### Тестирование и верификация {#testing-and-verification}
+
+- **Пишите подробные модульные тесты.** Обширный набор тестов имеет решающее значение для создания высококачественного программного обеспечения.
+- **Пишите пользовательские проверки и свойства для [Slither](https://github.com/crytic/slither), [Echidna](https://github.com/crytic/echidna) и [Manticore](https://github.com/trailofbits/manticore).** Автоматизированные инструменты помогут обеспечить безопасность вашего контракта. Ознакомьтесь с остальной частью этого руководства, чтобы узнать, как писать эффективные проверки и свойства.
+- **Используйте [crytic.io](https://crytic.io/).** Crytic интегрируется с GitHub, предоставляет доступ к частным детекторам Slither и запускает пользовательские проверки свойств от Echidna.
+
+### Solidity {#solidity}
+
+- **Отдавайте предпочтение Solidity 0.5 перед 0.4 и 0.6.** По нашему мнению, Solidity 0.5 является более безопасным и имеет лучшие встроенные практики, чем 0.4. Solidity 0.6 оказался слишком нестабильным для производственного использования и ему нужно время, чтобы «созреть».
+- **Используйте стабильный релиз для компиляции; используйте последний релиз для проверки предупреждений.** Убедитесь, что ваш код не имеет зарегистрированных проблем с последней версией компилятора. Однако у Solidity быстрый цикл релизов и есть история ошибок компилятора, поэтому мы не рекомендуем использовать последнюю версию для развертывания (см. [рекомендацию по версии solc от Slither](https://github.com/crytic/slither/wiki/Detector-Documentation#recommendation-33)).
+- **Не используйте встроенный ассемблер.** Ассемблер требует экспертных знаний EVM. Не пишите код для EVM, если вы не _освоили_ «желтую книгу».
+
+## Руководство по развертыванию {#deployment-guidelines}
+
+После разработки и развертывания контракта:
+
+- **Отслеживайте свои контракты.** Следите за журналами и будьте готовы отреагировать в случае компрометации контракта или кошелька.
+- **Добавьте свою контактную информацию в [blockchain-security-contacts](https://github.com/crytic/blockchain-security-contacts).** Этот список поможет третьим лицам связаться с вами в случае обнаружения уязвимости в системе безопасности.
+- **Обезопасьте кошельки привилегированных пользователей.** Следуйте нашим [лучшим практикам](https://blog.trailofbits.com/2018/11/27/10-rules-for-the-secure-use-of-cryptocurrency-hardware-wallets/), если вы храните ключи в аппаратных кошельках.
+- **Имейте план реагирования на инциденты.** Учитывайте, что ваши умные контракты могут быть скомпрометированы. Даже если в ваших контрактах нет ошибок, злоумышленник может завладеть ключами владельца контракта.
diff --git a/public/content/translations/ru/developers/tutorials/stealth-addr/index.md b/public/content/translations/ru/developers/tutorials/stealth-addr/index.md
new file mode 100644
index 00000000000..19164ed778b
--- /dev/null
+++ b/public/content/translations/ru/developers/tutorials/stealth-addr/index.md
@@ -0,0 +1,443 @@
+---
+title: "Использование скрытых адресов"
+description: "Скрытые адреса позволяют пользователям анонимно переводить активы. Прочитав эту статью, вы сможете: объяснить, что такое скрытые адреса и как они работают, понять, как использовать скрытые адреса для сохранения анонимности, а также написать веб-приложение, использующее скрытые адреса."
+author: Ori Pomerantz
+tags:
+ [
+ "Скрытый адрес",
+ "конфиденциальность",
+ "криптография",
+ "Rust",
+ "wasm"
+ ]
+skill: intermediate
+published: 2025-11-30
+lang: ru
+sidebarDepth: 3
+---
+
+Вы — Билл. По причинам, которые мы не будем рассматривать, вы хотите сделать пожертвование в кампанию "Алиса — королева мира" и хотите, чтобы Алиса знала о вашем пожертвовании, чтобы она вознаградила вас в случае своей победы. К сожалению, ее победа не гарантирована. Существует конкурирующая кампания "Кэрол — императрица Солнечной системы". Если Кэрол победит и узнает, что вы пожертвовали Алисе, у вас будут проблемы. Поэтому вы не можете просто перевести 200 ETH со своего аккаунта на аккаунт Алисы.
+
+Решение предлагает [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564). Этот ERC объясняет, как использовать [скрытые адреса](https://nerolation.github.io/stealth-utils) для анонимных переводов.
+
+**Предупреждение**. Криптография, лежащая в основе скрытых адресов, насколько нам известно, надежна. Однако существуют потенциальные атаки по побочным каналам. [Ниже](#go-wrong) вы увидите, что можно сделать, чтобы снизить этот риск.
+
+## Как работают скрытые адреса {#how}
+
+В этой статье мы попытаемся объяснить скрытые адреса двумя способами. Первый — [как их использовать](#how-use). Этой части достаточно, чтобы понять остальную часть статьи. Затем следует [объяснение математических основ](#how-math). Если вы интересуетесь криптографией, прочтите и эту часть.
+
+### Простая версия (как использовать скрытые адреса) {#how-use}
+
+Алиса создает два приватных ключа и публикует соответствующие публичные ключи (которые можно объединить в один метаадрес двойной длины). Билл также создает приватный ключ и публикует соответствующий публичный ключ.
+
+Используя публичный ключ одной стороны и приватный ключ другой, можно получить общий секрет, известный только Алисе и Биллу (его нельзя получить только из публичных ключей). Используя этот общий секрет, Билл получает скрытый адрес и может отправлять на него активы.
+
+Алиса также получает адрес из общего секрета, но поскольку она знает приватные ключи к опубликованным ею публичным ключам, она также может получить приватный ключ, который позволяет ей снимать средства с этого адреса.
+
+### Математика (почему скрытые адреса работают именно так) {#how-math}
+
+Стандартные скрытые адреса используют [криптографию на эллиптических кривых (ECC)](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/#elliptic-curves-building-blocks-of-a-better-trapdoor) для повышения производительности с меньшим количеством битов ключа при сохранении того же уровня безопасности. Но по большей части мы можем это игнорировать и делать вид, что используем обычную арифметику.
+
+Существует число, известное всем, — _G_. Вы можете умножать на _G_. Но из-за природы ECC практически невозможно делить на _G_. В Ethereum криптография с публичным ключом обычно работает так: вы можете использовать приватный ключ _Ppriv_ для подписи транзакций, которые затем проверяются публичным ключом _Ppub = GPpriv_.
+
+Алиса создает два приватных ключа: _Kpriv_ и _Vpriv_. _Kpriv_ будет использоваться для траты денег со скрытого адреса, а _Vpriv_ — для просмотра адресов, принадлежащих Алисе. Затем Алиса публикует публичные ключи: _Kpub = GKpriv_ и _Vpub = GVpriv_
+
+Билл создает третий приватный ключ _Rpriv_ и публикует _Rpub = GRpriv_ в центральном реестре (Билл мог бы отправить его Алисе, но мы предполагаем, что Кэрол слушает).
+
+Билл вычисляет _RprivVpub = GRprivVpriv_, который, как он ожидает, Алиса также знает (объяснено ниже). Это значение называется _S_, общий секрет. Это дает Биллу публичный ключ _Ppub = Kpub+G\*hash(S)_. Из этого публичного ключа он может вычислить адрес и отправить на него любые ресурсы. В будущем, если Алиса победит, Билл может сообщить ей _Rpriv_, чтобы доказать, что ресурсы поступили от него.
+
+Алиса вычисляет _RpubVpriv = GRprivVpriv_. Это дает ей тот же общий секрет, _S_. Поскольку она знает приватный ключ _Kpriv_, она может вычислить _Ppriv = Kpriv+hash(S)_. Этот ключ позволяет ей получить доступ к активам на адресе, который является результатом _Ppub = GPpriv = GKpriv+G*hash(S) = Kpub+G*hash(S)_.
+
+У нас есть отдельный ключ просмотра, чтобы Алиса могла передать подряд Dave's World Domination Campaign Services. Алиса готова сообщить Дэйву публичные адреса и информировать ее о поступлении новых денег, но она не хочет, чтобы он тратил деньги ее кампании.
+
+Поскольку для просмотра и траты используются разные ключи, Алиса может дать Дэйву _Vpriv_. Тогда Дэйв может вычислить _S = RpubVpriv = GRprivVpriv_ и таким образом получить публичные ключи (_Ppub = Kpub+G\*hash(S)_). Но без _Kpriv_ Дэйв не сможет получить приватный ключ.
+
+Таким образом, это значения, известные разным участникам.
+
+| Алиса | Опубликовано | Билл | Дэйв | |
+| ------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------- |
+| G | G | G | G | |
+| _Kpriv_ | – | – | – | |
+| _Vpriv_ | – | – | _Vpriv_ | |
+| _Kpub = GKpriv_ | _Kpub_ | _Kpub_ | _Kpub_ | |
+| _Vpub = GVpriv_ | _Vpub_ | _Vpub_ | _Vpub_ | |
+| – | – | _Rpriv_ | – | |
+| _Rpub_ | _Rpub_ | _Rpub = GRpriv_ | _Rpub_ | |
+| _S = RpubVpriv = GRprivVpriv_ | – | _S = RprivVpub = GRprivVpriv_ | _S = _RpubVpriv_ = GRprivVpriv_ | |
+| _Ppub = Kpub+G\*hash(S)_ | – | _Ppub = Kpub+G\*hash(S)_ | _Ppub = Kpub+G\*hash(S)_ | |
+| _Address=f(Ppub)_ | – | _Address=f(Ppub)_ | _Address=f(Ppub)_ | _Address=f(Ppub)_ |
+| _Ppriv = Kpriv+hash(S)_ | – | – | – | |
+
+## Когда скрытые адреса работают не так, как надо {#go-wrong}
+
+_В блокчейне нет секретов_. Хотя скрытые адреса могут обеспечить вам конфиденциальность, эта конфиденциальность уязвима для анализа трафика. В качестве простого примера представьте, что Билл пополняет адрес и сразу же отправляет транзакцию для публикации значения _Rpub_. Без _Vpriv_ Алисы мы не можем быть уверены, что это скрытый адрес, но стоит сделать ставку именно на это. Затем мы видим еще одну транзакцию, которая переводит все ETH с этого адреса на адрес фонда кампании Алисы. Возможно, мы не сможем этого доказать, но, скорее всего, Билл только что сделал пожертвование в кампанию Алисы. Кэрол наверняка так и подумает.
+
+Биллу легко отделить публикацию _Rpub_ от финансирования скрытого адреса (делать это в разное время, с разных адресов). Однако этого недостаточно. Кэрол ищет закономерность: Билл пополняет адрес, а затем фонд кампании Алисы снимает с него средства.
+
+Одно из решений состоит в том, чтобы кампания Алисы не снимала деньги напрямую, а использовала их для оплаты третьей стороне. Если кампания Алисы отправит 10 ETH в Dave's World Domination Campaign Services, Кэрол будет знать только то, что Билл сделал пожертвование одному из клиентов Дэйва. Если у Дэйва достаточно клиентов, Кэрол не сможет узнать, пожертвовал ли Билл Алисе, которая с ней конкурирует, или Адаму, Альберту или Эбигейл, до которых Кэрол нет дела. Алиса может включить в платеж хэшированное значение, а затем предоставить Дэйву прообраз, чтобы доказать, что это было ее пожертвование. В качестве альтернативы, как отмечалось выше, если Алиса даст Дэйву свой _Vpriv_, он уже будет знать, от кого пришел платеж.
+
+Основная проблема этого решения в том, что оно требует от Алисы заботиться о секретности, когда эта секретность выгодна Биллу. Алиса может захотеть сохранить свою репутацию, чтобы друг Билла, Боб, тоже сделал ей пожертвование. Но также возможно, что она не прочь разоблачить Билла, потому что тогда он будет бояться того, что произойдет, если Кэрол победит. Билл может в итоге оказать Алисе еще большую поддержку.
+
+### Использование нескольких скрытых слоев {#multi-layer}
+
+Вместо того чтобы полагаться на Алису в сохранении конфиденциальности Билла, Билл может сделать это сам. Он может сгенерировать несколько метаадресов для вымышленных людей, Боба и Беллы. Затем Билл отправляет ETH Бобу, а "Боб" (который на самом деле Билл) отправляет их Белле. "Белла" (тоже Билл) отправляет их Алисе.
+
+Кэрол все еще может анализировать трафик и видеть цепочку от Билла к Бобу, от Боба к Белле, от Беллы к Алисе. Однако, если "Боб" и "Белла" также используют ETH для других целей, не будет выглядеть так, будто Билл что-то перевел Алисе, даже если Алиса немедленно снимет средства со скрытого адреса на известный адрес своей кампании.
+
+## Написание приложения для скрытых адресов {#write-app}
+
+В этой статье объясняется приложение для скрытых адресов, [доступное на GitHub](https://github.com/qbzzt/251022-stealth-addresses.git).
+
+### Инструменты {#tools}
+
+Существует [библиотека скрытых адресов на typescript](https://github.com/ScopeLift/stealth-address-sdk), которую мы могли бы использовать. Однако криптографические операции могут быть ресурсоемкими для процессора. Я предпочитаю реализовывать их на компилируемом языке, таком как [Rust](https://rust-lang.org/), и использовать [WASM](https://webassembly.org/) для запуска кода в браузере.
+
+Мы будем использовать [Vite](https://vite.dev/) и [React](https://react.dev/). Это стандартные отраслевые инструменты; если вы с ними не знакомы, можете воспользоваться [этим руководством](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/). Для использования Vite нам нужен Node.
+
+### Скрытые адреса в действии {#in-action}
+
+1. Установите необходимые инструменты: [Rust](https://rust-lang.org/tools/install/) и [Node](https://nodejs.org/en/download).
+
+2. Клонируйте репозиторий GitHub.
+
+ ```sh
+ git clone https://github.com/qbzzt/251022-stealth-addresses.git
+ cd 251022-stealth-addresses
+ ```
+
+3. Установите необходимые компоненты и скомпилируйте код Rust.
+
+ ```sh
+ cd src/rust-wasm
+ rustup target add wasm32-unknown-unknown
+ cargo install wasm-pack
+ wasm-pack build --target web
+ ```
+
+4. Запустите веб-сервер.
+
+ ```sh
+ cd ../..
+ npm install
+ npm run dev
+ ```
+
+5. Перейдите в [приложение](http://localhost:5173/). Эта страница приложения имеет два фрейма: один для пользовательского интерфейса Алисы, а другой — для Билла. Два фрейма не взаимодействуют; они находятся на одной странице только для удобства.
+
+6. От имени Алисы нажмите **Generate a Stealth Meta-Address**. Будет отображен новый скрытый адрес и соответствующие ему приватные ключи. Скопируйте скрытый метаадрес в буфер обмена.
+
+7. От имени Билла вставьте новый скрытый метаадрес и нажмите **Generate an address**. Вы получите адрес для пополнения счета Алисы.
+
+8. Скопируйте адрес и публичный ключ Билла и вставьте их в область "Private key for address generated by Bill" пользовательского интерфейса Алисы. После заполнения этих полей вы увидите приватный ключ для доступа к активам по этому адресу.
+
+9. Вы можете использовать [онлайн-калькулятор](https://iancoleman.net/ethereum-private-key-to-address/), чтобы убедиться, что приватный ключ соответствует адресу.
+
+### Как работает программа {#how-the-program-works}
+
+#### Компонент WASM {#wasm}
+
+Исходный код, который компилируется в WASM, написан на [Rust](https://rust-lang.org/). Вы можете увидеть его в [`src/rust_wasm/src/lib.rs`](https://github.com/qbzzt/251022-stealth-addresses/blob/main/src/rust-wasm/src/lib.rs). Этот код в основном является интерфейсом между кодом JavaScript и [библиотекой `eth-stealth-addresses`](https://github.com/kassandraoftroy/eth-stealth-addresses).
+
+**`Cargo.toml`**
+
+[`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html) в Rust является аналогом [`package.json`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) в JavaScript. Он содержит информацию о пакете, объявления зависимостей и т. д.
+
+```toml
+[package]
+name = "rust-wasm"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+eth-stealth-addresses = "0.1.0"
+hex = "0.4.3"
+wasm-bindgen = "0.2.104"
+getrandom = { version = "0.2", features = ["js"] }
+```
+
+Пакет [`getrandom`](https://docs.rs/getrandom/latest/getrandom/) необходим для генерации случайных значений. Это невозможно сделать чисто алгоритмическими средствами; для этого требуется доступ к физическому процессу как источнику энтропии. Это определение указывает, что мы будем получать эту энтропию, запрашивая ее у браузера, в котором мы работаем.
+
+```toml
+console_error_panic_hook = "0.1.7"
+```
+
+[Эта библиотека](https://docs.rs/console_error_panic_hook/latest/console_error_panic_hook/) выдает более содержательные сообщения об ошибках, когда код WASM паникует и не может продолжать работу.
+
+```toml
+[lib]
+crate-type = ["cdylib", "rlib"]
+```
+
+Тип вывода, необходимый для создания кода WASM.
+
+**`lib.rs`**
+
+Это собственно код на Rust.
+
+```rust
+use wasm_bindgen::prelude::*;
+```
+
+Определения для создания пакета WASM из Rust. Они задокументированы [здесь](https://wasm-bindgen.github.io/wasm-bindgen/reference/attributes/index.html).
+
+```rust
+use eth_stealth_addresses::{
+ generate_stealth_meta_address,
+ generate_stealth_address,
+ compute_stealth_key
+};
+```
+
+Функции, которые нам нужны из [библиотеки `eth-stealth-addresses`](https://github.com/kassandraoftroy/eth-stealth-addresses).
+
+```rust
+use hex::{decode,encode};
+```
+
+Rust обычно использует для значений байтовые [массивы](https://doc.rust-lang.org/std/primitive.array.html) (`[u8; ]`). Но в JavaScript мы обычно используем шестнадцатеричные строки. [Библиотека `hex`](https://docs.rs/hex/latest/hex/) переводит для нас значения из одного представления в другое.
+
+```rust
+#[wasm_bindgen]
+```
+
+Сгенерируйте привязки WASM, чтобы можно было вызывать эту функцию из JavaScript.
+
+```rust
+pub fn wasm_generate_stealth_meta_address() -> String {
+```
+
+Самый простой способ вернуть объект с несколькими полями — вернуть строку JSON.
+
+```rust
+ let (address, spend_private_key, view_private_key) =
+ generate_stealth_meta_address();
+```
+
+[`generate_stealth_meta_address`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.generate_stealth_meta_address.html) возвращает три поля:
+
+- Метаадрес (_Kpub_ и _Vpub_)
+- Приватный ключ просмотра (_Vpriv_)
+- Приватный ключ для траты средств (_Kpriv_)
+
+Синтаксис [кортежа](https://doc.rust-lang.org/std/primitive.tuple.html) позволяет нам снова разделить эти значения.
+
+```rust
+ format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}",
+ encode(address),
+ encode(view_private_key),
+ encode(spend_private_key)
+ )
+}
+```
+
+Используйте макрос [`format!`](https://doc.rust-lang.org/std/fmt/index.html) для генерации строки в формате JSON. Используйте [`hex::encode`](https://docs.rs/hex/latest/hex/fn.encode.html) для преобразования массивов в шестнадцатеричные строки.
+
+```rust
+fn str_to_array(s: &str) -> Option<[u8; N]> {
+```
+
+Эта функция преобразует шестнадцатеричную строку (предоставленную JavaScript) в байтовый массив. Мы используем ее для разбора значений, предоставленных кодом JavaScript. Эта функция сложна из-за того, как Rust обрабатывает массивы и векторы.
+
+Выражение `` называется [обобщением (generic)](https://doc.rust-lang.org/book/ch10-01-syntax.html). `N` — это параметр, который управляет длиной возвращаемого массива. Функция на самом деле вызывается как `str_to_array::`, где `n` — длина массива.
+
+Возвращаемое значение — `Option<[u8; N]>`, что означает, что возвращаемый массив является [необязательным](https://doc.rust-lang.org/std/option/). Это типичный шаблон в Rust для функций, которые могут завершиться сбоем.
+
+Например, если мы вызовем `str_to_array::10("bad060a7")`, функция должна вернуть массив из десяти значений, но на вход подается только четыре байта. Функция должна завершиться сбоем, и она делает это, возвращая `None`. Возвращаемым значением для `str_to_array::4("bad060a7")` будет `Some<[0xba, 0xd0, 0x60, 0xa7]>`.
+
+```rust
+ // decode возвращает Result, _>
+ let vec = decode(s).ok()?;
+```
+
+Функция [`hex::decode`](https://docs.rs/hex/latest/hex/fn.decode.html) возвращает `Result, FromHexError>`. Тип [`Result`](https://doc.rust-lang.org/std/result/) может содержать либо успешный результат (`Ok(value)`), либо ошибку (`Err(error)`).
+
+Метод `.ok()` превращает `Result` в `Option`, значением которого является либо значение `Ok()`, если успешно, либо `None`, если нет. Наконец, [оператор вопросительного знака](https://doc.rust-lang.org/std/option/#the-question-mark-operator-) прерывает текущие функции и возвращает `None`, если `Option` пуст. В противном случае он разворачивает значение и возвращает его (в данном случае для присвоения значения `vec`).
+
+Это выглядит как странно запутанный метод обработки ошибок, но `Result` и `Option` гарантируют, что все ошибки будут обработаны тем или иным способом.
+
+```rust
+ if vec.len() != N { return None; }
+```
+
+Если количество байтов неверно, это сбой, и мы возвращаем `None`.
+
+```rust
+ // try_into поглощает vec и пытается создать [u8; N]
+ let array: [u8; N] = vec.try_into().ok()?;
+```
+
+В Rust есть два типа массивов. [Массивы](https://doc.rust-lang.org/std/primitive.array.html) имеют фиксированный размер. [Векторы](https://doc.rust-lang.org/std/vec/index.html) могут расти и сжиматься. `hex::decode` возвращает вектор, но библиотека `eth_stealth_addresses` хочет получать массивы. [`.try_into()`](https://doc.rust-lang.org/std/convert/trait.TryInto.html#required-methods) преобразует значение в другой тип, например, вектор в массив.
+
+```rust
+ Some(array)
+}
+```
+
+Rust не требует использования ключевого слова [`return`](https://doc.rust-lang.org/std/keyword.return.html) при возврате значения в конце функции.
+
+```rust
+#[wasm_bindgen]
+pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option {
+```
+
+Эта функция получает публичный метаадрес, который включает в себя как _Vpub_, так и _Kpub_. Она возвращает скрытый адрес, публичный ключ для публикации (_Rpub_) и однобайтовое значение сканирования, которое ускоряет идентификацию того, какие опубликованные адреса могут принадлежать Алисе.
+
+Значение сканирования является частью общего секрета (_S = GRprivVpriv_). Это значение доступно Алисе, и его проверка намного быстрее, чем проверка того, равно ли _f(Kpub+G\*hash(S))_ опубликованному адресу.
+
+```rust
+ let (address, r_pub, scan) =
+ generate_stealth_address(&str_to_array::<66>(stealth_address)?);
+```
+
+Мы используем [`generate_stealth_address`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.generate_stealth_address.html) из библиотеки.
+
+```rust
+ format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}",
+ encode(address),
+ encode(r_pub),
+ encode(&[scan])
+ ).into()
+}
+```
+
+Подготовьте выходную строку в формате JSON.
+
+```rust
+#[wasm_bindgen]
+pub fn wasm_compute_stealth_key(
+ address: &str,
+ bill_pub_key: &str,
+ view_private_key: &str,
+ spend_private_key: &str
+) -> Option {
+ .
+ .
+ .
+}
+```
+
+Эта функция использует [`compute_stealth_key`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.compute_stealth_key.html) из библиотеки для вычисления приватного ключа для снятия средств с адреса (_Rpriv_). Для этого вычисления требуются следующие значения:
+
+- Адрес (_Address=f(Ppub)_)
+- Публичный ключ, сгенерированный Биллом (_Rpub_)
+- Приватный ключ просмотра (_Vpriv_)
+- Приватный ключ для траты средств (_Kpriv_)
+
+```rust
+#[wasm_bindgen(start)]
+```
+
+[`#[wasm_bindgen(start)]`](https://wasm-bindgen.github.io/wasm-bindgen/reference/attributes/on-rust-exports/start.html) указывает, что функция выполняется при инициализации кода WASM.
+
+```rust
+pub fn main() {
+ console_error_panic_hook::set_once();
+}
+```
+
+Этот код указывает, что вывод паники должен быть отправлен в консоль JavaScript. Чтобы увидеть это в действии, используйте приложение и дайте Биллу неверный метаадрес (просто измените одну шестнадцатеричную цифру). Вы увидите эту ошибку в консоли JavaScript:
+
+```
+rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs:701:9:
+assertion `left == right` failed
+ left: 0
+ right: 1
+```
+
+За этим последует трассировка стека. Затем дайте Биллу действительный метаадрес, а Алисе — либо неверный адрес, либо неверный публичный ключ. Вы увидите эту ошибку:
+
+```
+rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/eth-stealth-addresses-0.1.0/src/lib.rs:78:9:
+keys do not generate stealth address
+```
+
+Снова последует трассировка стека.
+
+#### Пользовательский интерфейс {#ui}
+
+Пользовательский интерфейс написан с использованием [React](https://react.dev/) и обслуживается [Vite](https://vite.dev/). Вы можете узнать о них из [этого руководства](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/). Здесь нет необходимости в [WAGMI](https://wagmi.sh/), потому что мы не взаимодействуем напрямую с блокчейном или кошельком.
+
+Единственная неочевидная часть пользовательского интерфейса — это подключение WASM. Вот как это работает.
+
+**`vite.config.js`**
+
+Этот файл содержит [конфигурацию Vite](https://vite.dev/config/).
+
+```js
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import wasm from "vite-plugin-wasm";
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react(), wasm()],
+})
+```
+
+Нам нужны два плагина Vite: [react](https://www.npmjs.com/package/@vitejs/plugin-react) и [wasm](https://github.com/Menci/vite-plugin-wasm#readme).
+
+**`App.jsx`**
+
+Этот файл является основным компонентом приложения. Это контейнер, который включает два компонента: `Alice` и `Bill` — пользовательские интерфейсы для этих пользователей. Актуальная часть для WASM — это код инициализации.
+
+```jsx
+import init from './rust-wasm/pkg/rust_wasm.js'
+```
+
+Когда мы используем [`wasm-pack`](https://rustwasm.github.io/docs/wasm-pack/), он создает два файла, которые мы здесь используем: файл wasm с фактическим кодом (здесь `src/rust-wasm/pkg/rust_wasm_bg.wasm`) и файл JavaScript с определениями для его использования (здесь `src/rust_wasm/pkg/rust_wasm.js`). Экспорт по умолчанию этого файла JavaScript — это код, который необходимо запустить для инициации WASM.
+
+```jsx
+function App() {
+ .
+ .
+ .
+ useEffect(() => {
+ const loadWasm = async () => {
+ try {
+ await init();
+ setWasmReady(true)
+ } catch (err) {
+ console.error('Error loading wasm:', err)
+ alert("Wasm error: " + err)
+ }
+ }
+
+ loadWasm()
+ }, []
+ )
+```
+
+[Хук `useEffect`](https://react.dev/reference/react/useEffect) позволяет указать функцию, которая выполняется при изменении переменных состояния. Здесь список переменных состояния пуст (`[]`), поэтому эта функция выполняется только один раз при загрузке страницы.
+
+Функция эффекта должна возвращаться немедленно. Чтобы использовать асинхронный код, такой как `init` WASM (который должен загрузить файл `.wasm` и, следовательно, занимает время), мы определяем внутреннюю функцию [`async`](https://en.wikipedia.org/wiki/Async/await) и запускаем ее без `await`.
+
+**`Bill.jsx`**
+
+Это пользовательский интерфейс для Билла. У него есть одно действие: создание адреса на основе скрытого метаадреса, предоставленного Алисой.
+
+```jsx
+import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js'
+```
+
+В дополнение к экспорту по умолчанию, код JavaScript, сгенерированный `wasm-pack`, экспортирует функцию для каждой функции в коде WASM.
+
+```jsx
+