Деталь о транзакции Dusk, на которой я постоянно застревал, заключается в том, что выполнение контракта может быть отменено, не исчезая при этом сама транзакция.

Первый мой инстинкт был свести это к одному исходу.

вызов успешен = транзакция произошла.
вызов отменён = транзакция не произошла.

Moonlight работает не так чисто.

до принятия сеть проверяет, что отправитель может покрыть значение, любой депозит контракта и максимальный газ: gas_limit × gas_price.

затем она проверяет подпись и после этого убеждается, что nonce на единицу больше текущего nonce аккаунта.

ладно.

самое интересное начинается после выполнения.

в whitepaper сказано, что если выполнение смарт-контракта откатывается, соответствующая сумма возвращается. неиспользованный газ тоже возвращается.

но nonce увеличивается при принятии.

так что «контракт отменил изменение состояния» и «сеть израсходовала попытку этой транзакции» — это не одно и то же состояние.

откат может отменить эффект на стороне контракта, пока механизм упорядочивания на стороне аккаунта продолжает двигаться вперёд.

газ создаёт ещё одну границу.

пользователь должен покрыть максимальный газ до выполнения, даже если в итоге он заплатит меньше, потому что неиспользованный газ возвращается.

итого задействованы три суммы:

что вы должны уметь покрыть,
что потребляет выполнение,
что возвращается после.

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

теперь представьте приложение, которое готовит несколько транзакций Moonlight по очереди.

транзакция N вызывает контракт и откатывается.
эффект контракта исчезает.
но если N была принята, nonce отправителя уже сдвинулся.

транзакция N+1 не может рассуждать по принципу «предыдущий вызов не удался», как будто ничего не произошло.

сбой изменил что-то вне контракта.

вот в чём разница, которая мне нравится:

откат выполнения — локальный.
история транзакций — нет.

и это меняет вопрос интеграции.

когда приложение говорит пользователю «эта транзакция не удалась», что именно не удалось?

задуманный переход состояния?

или сама транзакция?

в Dusk это могут быть два разных ответа.

@Dusk_Foundation #Dusk $DUSK $GPS $TUT