Только в образовательных целях; не является инвестиционным советом или инвестиционной рекомендацией. Инвестиции могут привести к убыткам.
Краткий ответ
EIP-712 стандартизирует описание, хеширование и запрос подписей типизированных структурированных данных в приложениях Ethereum. Запрос содержит types, primaryType, domain и message; его дайджест равен keccak256("\x19\x01" || domainSeparator || hashStruct(message)). Кодирование становится детерминированным, а совместимый кошелек может показать поля понятнее непрозрачного хеша.
Стандарт не делает сообщение правдивым, безвредным, отзывным или защищенным от повторного использования. Приложение обязано связать полномочие с правильной сетью и проверяющим контрактом, однозначно определить поля, применять nonce и сроки, проверить нужного подписанта и ограничить исполнение. Действительная подпись подтверждает одобрение точного дайджеста по конкретному правилу проверки, но не личность, осознанное намерение или безопасность сайта и контракта.
Завершение этой проверки не доказывает безопасность актива, транзакции или системы.
Как это работает
1. Определите действие и путь проверки
Установите, разрешает ли запрос вход, ордер, голосование, allowance токена, перевод, ретранслируемый вызов или другое действие. Найдите код, восстанавливающий дайджест и использующий подпись. Для внешне управляемого аккаунта обычно восстанавливают адрес из ECDSA-подписи; для контрактного аккаунта может понадобиться ERC-1271 isValidSignature(hash, signature) и проверка успешного значения 0x1626ba7e.
2. Зафиксируйте домен
Проверьте точный тип EIP712Domain и значения. Стандартные поля — name, version, chainId, verifyingContract и salt, но хешируются только включенные поля. Независимо подтвердите активную сеть, развернутый код и ожидаемый проверяющий контракт; знакомых имени, символа, метки прокси или checksum-адреса недостаточно. ERC-5267 eip712Domain() может раскрыть домен, однако поддержка необязательна, а прокси и обновления все равно требуют анализа.
3. Восстановите граф типов
Начните с primaryType, сохраните порядок членов и рекурсивно соберите ссылочные структуры. encodeType добавляет их определения, отсортированные по имени типа. EIP-712 поддерживает целые фиксированной ширины, address, bool, от bytes1 до bytes32, динамические bytes и string, массивы и структуры. Псевдонимы uint и int, типы с фиксированной точкой и циклические значения не определены.
4. Расшифруйте каждое значение и единицу
Сопоставьте значение с объявленным типом и смыслом в приложении. Проверьте полные адреса, сырые целые единицы, знак, порядок массивов, получателей, spender, активы, суммы, комиссии, лимиты, назначения, хеши calldata и читаемые строки. Динамические bytes и string представлены в encodeData хешем Keccak-256 содержимого; массивы хешируют сцепленные кодировки элементов, а вложенные структуры используют свой hashStruct.
5. Независимо пересчитайте дайджест
Вычислите typeHash = keccak256(encodeType(primaryType)), затем hashStruct(message) = keccak256(typeHash || encodeData(message)). Так же получите разделитель домена и объедините его с байтами версии ERC-191 0x19 0x01. Сравните результат интерфейса, библиотеки подписи, проверяющего контракта и независимой реализации; одинаковый вид JSON не доказывает одинаковое типизированное кодирование.
6. Проверьте replay, время и исполнение
EIP-712 сам не обеспечивает защиту от повторов. Проверяющий код должен установить ожидаемого подписанта, использовать или аннулировать правильный nonce, применить deadline либо окно действия, связать все критические параметры и сохранить задуманный результат, если relayer или опережающий участник отправит первым. Разделение домена предотвращает коллизии только между фактически закодированными доменами; пропущенные или ошибочные поля могут оставить повторное использование между контрактами или сетями.
7. Подписывайте минимум и сверяйте результат
Откажитесь при скрытых полях, необъясненных типах, безлимитных значениях, далеком сроке, неизвестном контракте, несовпадающем chain ID, слепой подписи или неполном контексте исполнения. Сохраните точный JSON и дайджест, по возможности используйте аккаунт узкого назначения и проверьте транзакцию, квитанцию, события, балансы, allowances, nonces, статус ордера и финальность. Отключение сайта не отзывает пригодную подпись или уже созданное полномочие.
Расчетные примеры
Пример 1: Построение типа и дайджеста
Для Order(address maker,address token,uint256 amount,uint256 nonce,uint256 deadline) значение typeHash — хеш Keccak-256 этой точной строки с учетом порядка полей. Хеш сообщения равен keccak256(typeHash || maker || token || amount || nonce || deadline), каждый член занимает 32 байта. Итоговый дайджест добавляет 0x1901, разделитель домена и хеш сообщения. Изменение amount с 250000000 на 250000001 меняет дайджест и делает старую подпись недействительной.
Пример 2: Единицы и срок
250 USDC токена с шестью знаками кодируются сырым значением 250000000, а не 250. При текущей метке времени 1727000000 и сроке 1727000900 окно составляет 900 seconds = 15 minutes. Десятичное отображение кошелька и локальные часы лишь помогают; проверяющий использует сырое целое и выбранное правило времени в сети.
Пример 3: Контроль повторов
Ордер содержит nonce 41 и максимум 5 ETH. После отметки nonce 41 использованным вторая отправка должна завершиться ошибкой, даже если подпись криптографически верна. Если контракт не расходует nonce и исполнение не идемпотентно, та же подпись может разрешить еще 5 ETH; один разделитель домена этого не предотвращает.
Пример 4: Действительность контрактного кошелька
Контрактный кошелек 2-из-3 одобряет дайджест при подписантах A, B и C. Подписи A и B сегодня могут заставить ERC-1271 вернуть 0x1626ba7e. Если обновление модуля заменит B на D, те же байты могут стать недействительными: проверка ERC-1271 может зависеть от текущего состояния, политики, времени и внешних вызовов; одного восстановления адреса для контрактного аккаунта недостаточно.
Риски
- Ошибочный или отсутствующий
chainId - Поддельный или неожиданный
verifyingContract - Вводящие в заблуждение
nameилиversionдомена - Изменение реализации прокси или домена после обновления
- Ошибочный
primaryTypeили похожий теневой тип - Несовпадение порядка членов, зависимостей или кодировщика
- Усеченный, подмененный или неверно подписанный адрес
- Ошибка десятичных разрядов или знакового целого
- Скрытый элемент массива, вложенная структура или payload
bytes - Безлимитная сумма, широкая область или получатель атакующего
- Отсутствующий, устаревший, общий или неверно использованный nonce
- Отсутствующий, далекий, переполненный или двусмысленный срок
- Replay между сетями, контрактами, аккаунтами или действиями
- Удержание, цензура, опережение или перенаправление relayer
- Пластичность подписи или слишком мягкое восстановление ECDSA
- Изменение подписанта, модуля, порога, состояния или кода ERC-1271
- Ошибка отображения, слепой подписи или неподдерживаемого типа
- JSON интерфейса отличается от дайджеста проверяющего
- Отзыв или отмена проигрывает гонку порядка
- Диалог подписи принимают за квитанцию, состояние или финальность
Распространенные заблуждения
Заблуждение 1: Подписи EIP-712 являются транзакциями
Это подписанные вне сети сообщения. Relayer может позже передать их контракту, а итоговая транзакция способна потратить Gas и изменить состояние, не будучи отправленной подписантом.
Заблуждение 2: Структурированное отображение означает безопасность
Типизированные поля упрощают проверку, но вредоносные схемы, значения, контракты, метки, скрытые вложения и неполное отображение кошелька все еще могут обмануть.
Заблуждение 3: Разделитель домена предотвращает любой replay
Он разделяет лишь закодированный домен. Для повторов внутри домена нужны nonce, срок, отмена, учет исполнения или идемпотентность; пропущенное поле границы не создает.
Заблуждение 4: Ожидаемый восстановленный адрес доказывает полномочие
Восстановление доказывает EOA-подпись дайджеста, но не смысл приложения. Контрактным аккаунтам нужна политика ERC-1271, а не обычное восстановление адреса.
Заблуждение 5: Закрытие страницы или отключение кошелька отменяет подпись
Скопированная подпись пригодна, пока nonce, срок, отмена, состояние или политика проверяющего не сделают ее недействительной. Проверяйте состояние в сети, а не сеанс.
Связанные темы
- Идентификатор сети
- Nonce и срок ERC-2612 Permit
- Риск подписи Permit2
- Разрешение кошелька
- Подпись кошелька
Источники
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- ERC-191: Signed Data Standard - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- ERC-1271: Standard Signature Validation Method for Contracts - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- ERC-5267: Retrieval of EIP-712 domain - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- EIP-2: Homestead Hard-fork Changes - Ethereum Improvement Proposals (дата обращения: 2026-08-19)
- Contract ABI Specification - Solidity Documentation (дата обращения: 2026-08-19)
- ERC-7730: Structured Data Clear Signing Format - Ethereum Improvement Proposals (дата обращения: 2026-08-19)