$$\rightleftharpoonup{xx}$$
$$\longleftharp{xx}$$,
$$\longrightharp{xx}$$,
Входные материалы для изучения
В этом исследовании в качестве входных данных для проверки использовались два смарт-контракта Solidity. Первый был контрактом в стиле Simple DAO, использовавшимся как кейс по повторному вступлению. Второй — это упрощённый реестр/переходный контракт, предназначенный для проверки ограничений на уровне контрактов против двойного расходования. Исходный код Solidity служил входом для процессов абстракции и проверки, определённых в этом протоколе. Общий процесс трансформации, используемый для таких контрактов, иллюстрирован на рисунке 1, где показано постепенное преобразование исходного кода Solidity в модели FSM, Event-B и SMV во время верификации.
Моделирование границы
Формальное моделирование сосредоточено на логике управления и потоком смарт-контрактов, включая поведение при входе и выходе функций, внутреннее выполнение и переходы состояний на уровне контракта. Видимость функций (публичная, внешняя, внутренняя и приватная) представлялась вместе с соответствующим поведением стека вызовов, относящимся к анализу повторного входа. Типы абстрактных переходов (вызов, отправка, передача) рассматривались как операции для передачи эфиров.
Инварианты на уровне контракта были определены для обеспечения уникальности транзакций и предотвращения двойного расходования в пределах границы абстракции. Для представления требований к выбору валидации и целостности блока уровень абстракции протокол-логики был определен с помощью переходов состояний на уровне протокола как Proof of Work, так и Proof of Stake.
Граница абстракции не включала элементы сетевого уровня, включая планирование доставки сообщений и задержки, вызванные любым числом переходов, разрешение форков, сетевые противники с использованием византийских стратегий, семантику виртуальной машины Ethereum и семантику газа, контролируемую узлами сети, распространение исключений, асинхронные выполнения, сложное поведение запасных вариантов и окончательность на уровне сети. Таким образом, результаты определения двойного расхода применяются только к инвариантам на уровне контрактов и не являются сетевым соглашением о окончательности.
Инструменты и конфигурация
Платформа Rodin использовалась для моделирования, доработки, генерации обязательств по доказательствам и внедрения модели Event-B (версия 3.7.0), которая позволяла доказателям PP, ML, SMT и Atelier-B автоматически и интерактивно выпускать доказательства. nuXmv версии 2.0.0 запускалась на сгенерированных моделях SMV в полном режиме CTL-исследования для проверки CTL-моделей.
Все выполнения верификации выполнялись в контролируемой вычислительной среде с использованием Ubuntu 22.04 LTS, OpenJDK 11 и Python 3.10.12. Web3 (7.6.0), NetworkX (3.4.2), Matplotlib (3.8.0), Graphviz (0.20.3), NumPy (1.26.4) и Pandas (2.2.2) использовались для реализации элементов симуляции и визуализации. Такая конструкция гарантировала возможность воспроизведения формальной верификации и симуляции при выполнении при тех же условиях выполнения.
Рабочий процесс трансформации
Этот процесс верификации состоял из четырёх этапов. Контракты твердости сначала были преобразованы в представление с использованием конечных автоматов (FSM-SC). Модель FSM-SC впоследствии была закодирована в Событии-B с чётко определёнными инвариантами и степенями уточнения. Абстракция FSM-SC была преобразована в модель SMV в nuXmv. Результаты верификации были представлены в виде статистики по списанию доказательств обязательств и проверки модели CTL, а также приводились контрпримеры в качестве кейсов.
Конструкция FSM
Каждый контракт абстрагировался как конечный автомат, определяемый как:

Где:
S = множество состояний
S₀ = начальное состояние
T = отношение перехода
V = карта видимости
G = охранительные предикаты
A = действия/обновления состояния.
Алгоритм 1: построение FSM из Solidity
Вход: исходный код Solidity
Выход: FSM-SC
1) Парсировать абстрактное синтаксисическое дерево контракта Solidity.
2) Создать начальное состояние S₀ из определения конструктора.
3) Для каждой функции солидности f создать отдельный S_f управляющего состояния и записать видимость V(f) ∈ {публичная, внешняя, внутренняя, приватная}.
4) Для каждого оператора в функции f выведите переход t, извлекая защитные предикаты из условий require/assert и действий из обновлений переменных состояния.
5) Добавить переход t к T.
6) Создавать явные типы переходов для операций передачи эфира (вызов, отправка, передача), внутренних и внешних вызовов, delegatecall, самоуничтожения, использования tx.origin, условных ветвей и конструкций циклов.
7) Возврат FSM-SC = (S, S₀, T, V, G, A).
И каждая функция солидности связана с разным управляющим состоянием FSM. Для понимания уязвимостей соответствующие уязвимости потоки исполнения, например, такие потоки с внешними вызовами, за которыми следовали обновления баланса, явно абстрагировались в упорядоченные переходы. Рисунок 2 описывает пример схемы FSM-SC для контракта в стиле SimpleDAO, показывающей, как на этапе строительства абстрагировались состояния входа, переходы внешних вызовов и последовательности обновления состояний.
Кодирование FSM в событие-B
Переход FSM был представлен как конструкции Event-B. Все переходы соответствуют событиям События-B, включая определённых охранников и действия.
Алгоритм 2: кодирование FSM в Event-B
Вход: FSM-SC
Вывод: машина Event-B и контекст
1) Определить STATE_SET и ФУНКЦИЮ в контексте контракта.
2) Объявить переменные, представляющие состояние контроля FSM и состояние на уровне контракта.
3) Представить каждое состояние управления FSM s ∈ S с помощью current_state ∈ STATE_SET.
4) Для каждого перехода (s → s′, g, a) создать событие Event-B E_t с:
5) ГДЕ current_state = s ∧ g
6) ТОГДА current_state := s′ ∥ применимо(a)
7) Кодировать ограничения видимости с помощью защитных, полученных из V(f).
8) Определить инварианты inv1–inv9 для захвата свойств безопасности и согласованности.
9) Определите INITIALIZATION, присваивая значения S₀ и по умолчанию.
Набор состояний, текущее состояние, видимость функций, стек вызовов, временная метка транзакции, статус передачи эфира, флаг вызова делегата, флаг самоуничтожения и условие верификации — это некоторые из переменных, отражаемых в модели Event-B. Инварианты (inv1-inv9) и действия инициализаций (act1-act6) совпадают с действиями формальной спецификации. Рисунок 3 также показывает, как поддерживаются ключевые события, связанные с уязвимостями, особенно переходы, связанные с повторным входом, в кодировании Event-B. На этом рисунке объясняется, как структурные паттерны модели FSM-SC, показанные на рисунке 2, отображаются в проверяемые события Event-B.
Стратегия усовершенствования
Были внедрены два уровня доработки. Высокоуровневые контрактные управляющие потоки и инварианты ядра были представлены на абстрактном уровне. Усовершенствованный уровень добавил ограничения, специфичные для контракта, включая ограничения на стек вызовов, ограничения видимости и условия предотвращения повторного входа.
Алгоритм 3: Уточнение и разряд по доказательству
Вход: Абстрактная машина и усовершенствованная машина
Результаты: Обязательства по доказательствам и статистика
1) Генерировать доказательства для абстрактной машины в Родене.
2) Выполнить автоматические проверки с активным активом и записать результаты разряда.
3) Генерировать обязательства по обеспечению устойчивости к доработке для переработанной машины.
4) Применять автоматические доказательства к обязанностям по уточнению.
5) Выполнять оставшиеся обязательства интерактивно, когда это необходимо.
6) Экспорт статистики доказательств и отчётов о состоянии.
Отчётность по доказательствам включала количество инвариантов, уровни уточнения, генерируемые обязательства по доказательствам, автоматическую скорость сброса, интерактивную скорость сброса и конечную скорость сброса.
Спецификация свойств CTL и проверка модели
Абстракция FSM-SC была преобразована в модель SMV для временной проверки с временем ветвления в nuXmv.
Алгоритм 4: Проверка FSM в SMV и CTL
Вывод: результат проверки PASS/FAIL и контрпримерные трассы (если есть)
1. Записывать управляющие состояния FSM как перечисленное состояние SMV.
2. Преобразовать переходы FSM в охраняемые next(state) назначения.
3. Поддерживать флаги для уязвимых условий, таких как внешние вызовы и обновления баланса.
4. Закодировать свойства CTL в nuXmv и выполнить проверку модели.
5. Если свойство не работает, генерируйте контрпримерные следы, представляющие последовательности переходов FSM.
Проверка CTL включала требования к приказам повторного входа, финализацию обновлений состояния после операций передачи, ограничение неограниченного рекурсивного входа в критические участки и избегание тупиков.
Проверены свойства безопасности
Контракт в стиле Simple DAO, предотвращающий повторный вход, был подтверждён безопасным упорядочением между внешними вызовами и обновлениями состояния через инварианты и ограничения CTL. Там, где это было разрешено, эти охранники проверяли ограничения доступа, чтобы несанкционированные переходы были ограничены инвариантами. Модель уменьшенного реестра проверяла инварианты уникальности сделок и согласованности реестра на уровне предотвращения внутри контракта.
Отчетные результаты
Раздел «Результаты» содержит отчёты по структурным метрикам FSM, метрикам модели Event-B и статистике для подтверждения обязательств и проверки CTL. Результаты формального доказательства и результатов проверки моделей CTL приводятся отдельно для различия доказательств гарантий корректности инвариантами и доказательств проверки времени с использованием временной проверки.