Hash time lock contracts (HTLC)
HTLC контракты представляют собой несложную, но при этом очень эффективную конструкцию, позволяющую создавать платежи с определенным “сроком годности”. Как вы наверно уже догадались, htlc-контракт состит из 2ух частей: проверки хеша и проверки истечения определенного времени.
Начнем разбор с хеша. Для создания HTLC платежа сначала должен быть создан секрет R, а затем посчитан его хеш. В качестве секрета может выступать что угодно — цифра или слово, в любом случае это всего лишь набор байтов.
H = Hash(R)
Этот хеш H будет включен в запирающий скрипт. Таким образом испльзовать платеж сможет только тот, кто знает секрет, хешированием которого был получен H. Секрет R также называют прообразом (preimage) .
Второй частью htlc-контракта является проверка истечения времени блокировки платежа. Если секрет не был вовремя выявлен и платеж не был использован, отправитель может вернуть все средства себе.
Рассмотрим пример HTLC платежа, предназначенного определенному человеку:
# check if secret R is preimage of H
HASH160 <H> EQUAL
IF
# check if person, who revealed secret is intended payee
<Payee Public key> CHECKSIG
ELSE
# check if time-lock is ended
<locktime> CHECKLOCKTIMEVERIFY
# check that person that requested refund is original payer
<Payer Public Key> CHECKSIG
ENDIF
При предоставлении верного секрета R, являющегося прообразом хеша H мы попадаем в поток IF, где далее идет проверка: действительно ли человек, нашедший секрет R, это тот, кому предназначен платеж. Чтобы потратить этот платеж, получателю нужно предоставить довольно простой отпирающий скрипт:
<sig> <secret R>
Если же предоставленный секрет R будет неверным, мы попадаем в поток ELSE, где сначала проверяется, прошло ли отведенное количество времени, и если да, то отправительно платежа может вернуть все средства. Отпирающий скрипт для возврата средств ничем не отличается, за исключением того, что мы должны специально указать неверный секрет, чтобы попасть в ELSE поток:
<sig> <wrong secret>
Конечно же, это очень базовая имплементация HTLC-контракта, представляющая из себя обычный time-lock платеж. Вы можете добавить сколько угодно различный условий к скрипту: убрав, например, проверку публичного ключа в IF потоке, мы можем сделать платеж доступным любому, кто знает секрет или же вместо одной подписи требовать несколько, как в мультисиге и тд.
P.S: В данном примере используется опкод CHECKLOCKTIMEVERIFY, который использует абсолютное значение для задания времени блокировки, например “Этот выход не может быть потрачен до блока #546212”. Кроме этого, например в Lightning Network, помимо него также используется еще и другой, более “гибкий” вариант — CHECKSEQUENCEVERIFY, он задает время блокировки относительно, то есть возможен такой вариант: “Этот выход не может быть потрачен, пока с момента отправки транзакции в сеть не прошло 1000 блоков.” .
Источник: https://habr.com/ru/post/350790/