# Спецификация каналов оплаты `L2`
## Оригина
https://github.com/serokell/ton-paychan/blob/master/doc/Payment-channel.md
https://github.com/zeropoolnetwork/zeropool-core/blob/master/smart-contracts/ZeroPool.full.sol
https://habr.com/ru/company/distributedlab/blog/418853/
https://uniswap.org/docs/v2
## Обзор
Предположим, что две стороны, Алиса и Боб, хотели бы сделать серию платежей друг другу, и по соображениям эффективности они решили выполнять их через платежный канал, а не по цепочке.
Они согласовывают параметры канала, такие как доли, которые они должны внести (которые будут определять, сколько каждый из них может друг другу в процессе), время ожидания бездействия и штраф за неправильное поведение. Затем контракт канала оплаты предварительно конфигурируется и развертывается в сети блокчейна (это может сделать либо Алиса, либо Боб, либо кто-то еще).
Контракт начинается в состоянии «ожидания», что означает, что он ожидает первоначальных обязательств от обеих сторон. Алиса и Боб должны отправить в контракт суммы токенов, равные их долям, плюс дополнительные депозиты, которые будут заблокированы для использования в качестве штрафа в случае неправильного поведения. Как только обе стороны вносят свои доли, токены блокируются в договоре, **и канал оплаты считается открытым.**
Теперь, если одна из сторон хочет отправить платеж другой, они готовят специальное `IOU`[^IOU] сообщение, которое содержит сумму транзакции и два значения, которые записывают, сколько каждая из них передала другой. Сообщение подписывается и передается через любую коммуникационную среду, которую Алиса и Боб предпочитают использовать. Включение общих сумм, которые они должны друг другу, в каждое сообщение необходимо, чтобы убедиться, что если в какой-то момент одна из сторон исчезнет, у другой стороны будет подписано сообщение с указанием последнего распределения средств, на которое они согласились.
Эти микротранзакции могут быть отправлены в любое время и столько раз, сколько пожелают стороны, при условии, что типы данных, используемые для отслеживания их обязательств, не переполняются, и до тех пор, пока они остаются в пределах, которые они взяли на себя во время конфигурации контракта, то есть должно быть достаточно средств, хранящихся в договоре. Обратите внимание, что канал является двунаправленным, и получение платежа уменьшает задолженность получателя, поэтому, пока взаимные долги сбалансированы и остаются в допустимых пределах, канал может оставаться открытым в течение длительного периода времени.
Сторонам рекомендуется подтверждать получение каждого микроплатежа (например, это может произойти естественным образом стороной, предоставляющей услуги, за которые они были оплачены); однако безопасность канала не зависит от этого. Также не требуется, чтобы сообщения `IOU` доставлялись в порядке или фактически доставлялись вообще. **???** Поскольку каждое сообщение `IOU` несет всю информацию о текущих долгах, необходимое и достаточное условие платежа в канале - получение последнее `IOU` до закрытия канала.
Когда Алиса и Боб не ожидают дальнейших микротранзакций, они начинают закрывать канал. Рекомендуется, чтобы они обменялись двумя заключительными сообщениями `IOU`, посылая друг другу `0`, чтобы подтвердить, что они согласны в отношении окончательных сумм, причитающихся друг другу. Когда все будет готово, Алиса отправляет в контракт запрос на выплату и прикрепляет последнюю `IOU`, которую она получила от Боба. Затем у Боба есть фиксированное время, чтобы либо подтвердить, что он согласен с предложенным распределением, либо, если это не так, предложить другое распространение.
В любом случае, поскольку предложения о распространении поддерживаются расписками, подписанными другой стороной, смарт-контракт канала платежей сможет принять решение о справедливом распределении, которое будет гарантировать, что обе стороны получат как минимум столько средств, сколько они ожидают получить , исходя из входящих платежей, которые они видели.
## Внецепной протокол
### Формат сообщения
В следующем `IOU` типе данных указан проводной формат сообщения `IOU`:
```javascript=
data Signed a = MkSigned
{ payload :: a // Произвольные данные
, signature :: Signature // Подпись для полезной нагрузки
}
-- serialisation:
-- / signature (= 512) /
-- \ bits \
-- ref1 = payload
// Данные полезной нагрузки
data IouPayload = MkIouPayload
{ channel :: Address // Адрес контракта канала оплаты
, amount :: UInt120 // Эта сумма микроплатежа
, iou :: UInt248 // Общая сумма, переданная другой стороне
, uome :: UInt248 // Общая сумма, полученная от другой стороны
}
-- serialisation:
-- / channel (= 8 + 256) / amount (<= 124) / iou (<= 253) / uome (<= 253) /
-- \ uint8 + uint256 \ varuint16 \ varuint32 \ varuint32 \
type Iou = Signed IouPayload
```
Адрес канала включен как форма защиты воспроизведения; это гарантирует, что каждый конкретный `IOU` может использоваться только в контексте одного канала. Никакой другой защиты от повторного воспроизведения не требуется, поскольку поля `iou` и `uome` не уменьшаются и, таким образом, естественно играют роль никогда не повторяющихся порядковых номеров.
[^IOU]: I Own You - Я тебе должен, долговая расписка