Страница оплаты зависла на пять секунд — я чуть дёрнулся и нажал ещё раз. Обычные платежи позволяют проверить две операции, а при приватных транзакциях, где скрыты и суммы, и участники, почему сеть вообще должна знать, что вы не потратили одни и те же деньги дважды?
Я, следуя этому вопросу, заново разобрал Phoenix от @Dusk . Она не учитывает средства как публичный баланс: вместо этого она разбивает их на зашифрованные note и записывает обязательства по note в Merkle-дерево. Во время расходования нулевое знание (zero-knowledge) доказывает, что это note действительно существует, находится под контролем пользователя и соблюдается сохранение входов и выходов — при этом не раскрываются ни точная сумма, ни соответствующее note.
По-настоящему ловит «двойную трату» nullifier: это можно понимать как уникальный признак аннулирования, который остаётся после того, как note уже использовано. Внешний мир не может по нему восстановить исходное note, но сеть может проверить, появлялся ли этот признак раньше. Если одно и то же note построено так, чтобы фигурировать в двух транзакциях, то они будут конфликтовать по одному и тому же nullifier — две операции не смогут одновременно считаться действительными.
В текущей документации Dusk также прямо сказано: когда в мемпуле при Phoenix-транзакциях возникает конфликт nullifier, заменой для старой транзакции может стать только новая транзакция с строго более высокой ценой газа. Повышение комиссии и повторная отправка, возможно, и означает замену платежа, а не создание дополнительной операции. Но как только транзакция попадает в уже принятый блок и выполняется, даже если контракт возвращает ошибку, соответствующие note и Gas всё равно будут потрачены; а окончательным итогом это считается только после того, как блок будет переведён в finalized.
Так что криптография решает проблему невозможности копирования активов, но кошелёк всё равно должен объяснить пользователю статус: ожидает обработки, заменена, выполнена с ошибкой и окончательно подтверждена. Показывать только «ошибка» недостаточно — пользователь может продолжать многократно повторять попытки.
$DUSK — это Gas и залоговый актив, но не стоит использовать его как гарантию качества пользовательского опыта продукта. Мне куда интереснее, может ли кошелёк отображать связь замен, причину расходования note и состояние окончательности. Приватность может скрывать детали, но не может скрывать факт совершения транзакции.
#dusk $DUSK