Защита от двойного расходования


🇬🇧 / 🇷🇺

Суть этого вида мошенничества состоит в том, чтобы использовать один и тот же платёжный объект два и более раза. Это довольно распространенная атака на традиционные блокчейны, из за чего транзакции в них обычно выполняются весьма небыстро, а результаты носят вероятностный характер. Последнее означает, что прошедшие транзакции даже с высоким уровнем подтверждённости, тем не менее, могут быть отменены, и на практике отмена транзакций встречается достаточно часто, а конкретно для финансовых транзакций – неприемлемо часто.

Противодействие в Universa

Сеть Universa существенно отличается от традиционного блокчейна. Для того чтобы понять, почему двойное использование/расходование в Universa не проходит, важны следущие её свойства:

  • любая транзакция либо принимается всей сетью, либо отвергается, путем голосования. Консенсус подтверждения составляет 90%, что существенно больше консенсуса для отклонения (10% + 1 голос). Также, он заметно выше, чем консенсус «50% + 1 голос», характерный для многих других блокчейнов. В результате любое голосование всегда приходит к определённому результату.

  • пока идёт голосование по изменению какого-то контракта, его текущее состояние блокируется до завершения голосования. Блокировка означает, что, если придет транзакция на изменение статуса контракта, который уже заблокирован, эта транзакция будет отвергнута нодой.

  • во время голосования каждая нода определяет свой голос (свое мнение о допустимости транзакции), но по завершению голосования каждая нода принимает решение, принятое сетью, независимо от своего голоса.

Вместе эти факторы очень эффективно отражают атаку двойного расходования. Рассмотрим на примере, как это действует.

Пример

Пусть некий мошенник Чак, в распоряжении которого контракт на 10 000 UTN (S), хочет обмануть своих друзей Боба и Алису, отправив каждому из них этот контракт в обмен на какой-то товар, услугу и т.д. Считая себя хакером, он вручную создает две ревизии контракта: A и B, в которых владельцами становятся Алиса и Боб (а точнее, их криптографические ключи) соответственно. Дальше он подписывает оба эти контракта своим ключом и пишет программу на питоне, с целью одновременно запустить регистрацию этих ревизий с разных точек сети (хотя реальный программист напишет, скорее, скрипт на баше, используя uniclient tool).

Bob, Alice, Chuck and 1000UTN

Чак совершенно правильно полагает, что обе этих ревизии совершенно валидны в настоящий момент. Тут он прав. А вот затем он делает излишне смелый вывод, что сеть примет как ту, так и другую ревизию; он полагает, что если он запустит их настолько одновременно, насколько это возможно, с разных концов сети, то сеть может по ошибке принять обе сразу, что и будет успешной «атакой двойного расходования».

Увы, жизнь сильно отличается от рассказов на форумах и кинопостановок. И Universa принципиально отличается от идеологических клонов биткойна.

«Одновременный» случай

Итак, предположим что у нас строго одновременно началась регистрация двух взаимоисключающих транзакций. И пусть все развивается по наихудшему сценарию: ноды получают либо один стейт (состояние), либо другой, пока это возможно. Все эти ноды, получившие только один стейт, сочтут что транзакция в порядке.

Vote starts

Таким образом, через некоторое время образуется какое-то количество нод, которые получили только одну из транзакций, A или B, и считают их валидными. Таких нод, в нашем самом худшем случае, будет по 50% соответственно,.. что недостаточно для положительного консенсуса в 90%:

50 by 50

А вот теперь уже каждая следующая нода, получая транзакцию А или B, будет отвергать стейт, так как его родительский стейт уже залочен другой транзакцией. Так как у нас одна половина сети (уже) решила, что верен стейт А, а вторая – что B, то, по мере распространения по сети, стейты будут получать только отрицательные голоса. Нода не может проголосовать за B, если она уже голосует за A (и наоборот) – у них общий предок, который уже заблокирован и не может использоваться в другой транзакции до разблокировки!

Спустя довольно небольшое время A и B наберут отрицательные консенсусы (10% + 1), и обе ревизии будут отвергнуты сетью (каждая нода примет и запомнит это решение, независимо от того, каким было её мнение при голосовании). То есть, атака не удалась:

10%+1 achieved

На диаграмме первые две ноды, получившие оба стейта, сформировали отрицательные голоса, которых в данном примере и хватило для отрицательного решения по обеим транзакциям.

Это был идеально-плохой случай, когда обе ревизии не сталкиваются максимально долго. В более вероятном случае, коллизии (когда нода получает обе ревизии и отвергает ту, что придет второй) начнутся гораздо раньше, и сеть отвергнет ревизии даже раньше, чем они распространятся по всей сети.

Случай с «обгоном»

В случае же, если одна транзакция сильно запаздывает, другая может успеть набрать свои 90% и будет принята сетью; вторая же в этом случае будет отвергнута сразу, так как её родительский стейт уже не активен, прошедшая транзакция сбросила его в REVOKED, и теперь вторая транзакция будет сразу набирать только отрицательные голоса и быстро окажется отвергнута.

Интересным фактом является то, что попытка запустить одновременно более 2 конфликтных транзакций только ускорит отмену, так как коллизии начнутся раньше. Предположим, что мы запустили столько конфликтных стейтов, сколько нод в сети, и каждый запустили со своей ноды. В этом случае каждая ревизия соберёт ровно один положительный голос (от ноды, с которой её запустят), а все остальные ноды транзакцию отвергнут, так как они уже «признали» другую; и в итоге необходимые 10% + 1 отрицательных голосов будут набраны очень быстро.

Подводя итог

Суммируя вышеизложенное, мы видим, что в результате атаки двойного расходования в сети Universa может быть только два исхода:

  • либо обе транзакции будут отвергнуты (более или менее одновременный случай);
  • либо одна из транзакций будет принята, а другая (или другие) отвергуты.

Оба исхода совершенно корректны: в первом никто не получит перевод (и перевод просто не случится), во втором – кто то (случайно) получит корректный перевод, а другой (другие) ничего не получат.

Приятным бонусом для законопослушных участников сети (в частности, владельцев нод) является то, что при этом сеть возьмет комиссию за обе попытки, независимо от результата – неудавшиеся попытки наживиться на попытках взлома сети бьют хакера по карману и при этом приносят сети прибыль, как и обычное её использование.