Late July produced one of the cleaner post-Toccata design threads in the channel: how to let someone borrow a UTXO once without turning that permission into a reusable hot key.
On July 30, Michael Sutton told Maxim he had found a way to provide an OTP for a borrow: a one-time allowance to borrow a UTXO, after which the next state recreates the permission model without leaving a standing secondary spend key. Maxim said the older nearby idea was covenant-lineage permissioning, which can cover one-time or longer-lived attempts. Sutton's requirement was stricter. The borrower should get only one use. [1] [2] [3]
Maxim sketched a covenant-id permission UTXO that can be spent only by recreating the owner UTXO and producing a single borrower-controlled result. Sutton called that too complicated and said it did not cleanly read as a pure one-time allowance. He said he had a simpler hash-only solution. [4] [5] [6] [7]
The hard part was replay. If the borrower reveals a preimage in the mempool, observers can see it. If the same commit remains valid, anyone can reuse it. If the borrower may choose the next commit freely, the borrower can also reuse the permission. Sutton's hint was to turn the reveal into a new commit. The scheme can support a finite number of borrows, then needs reset or reallocation, with N allowed to be large. [8] [9] [10] [11] [12]
Maxim eventually landed on the structure Sutton wanted: a hash chain. The simpler formulation was a chain of N hashes, hash(hash(...hash(seed))), starting from the top-level hash. Each successful borrow reveals another layer, and that revealed value becomes the next commit. Sutton confirmed the idea. [13] [14] [15] [16] [17] [18]
They also fixed the threat model in public. Maxim kept returning to the fact that a mempool observer can race the intended borrower. Sutton agreed that is possible and said it is not the threat model for the use case he cares about. The target flow is a wallet that wants to stay in control of its UTXOs, issue a one-time receive or borrow capability, wait for payment, and revoke if payment never arrives, without signing every receive path. In that setting, stealing the current OTP from the mempool does not create a long-lived attacker capability the way a standing secondary key would. [19] [20] [21] [22] [23] [24] [25] [26]
Sutton said the original inspiration came from an old paper and linked it after the riddle played out. The channel result is not a merged standard. It is a crisp pattern: finite hash-chain OTPs for one-shot borrow permissions, with explicit rejection of "standing borrower key" as the default answer. [27]
All sources link to public messages in the Kaspa Core R&D (public) Telegram channel.
Sources
- Kaspa Core R&D · message 15532
- Kaspa Core R&D · message 15534
- Kaspa Core R&D · message 15535
- Kaspa Core R&D · message 15538
- Kaspa Core R&D · message 15539
- Kaspa Core R&D · message 15540
- Kaspa Core R&D · message 15542
- Kaspa Core R&D · message 15548
- Kaspa Core R&D · message 15549
- Kaspa Core R&D · message 15551
- Kaspa Core R&D · message 15553
- Kaspa Core R&D · message 15554
- Kaspa Core R&D · message 15561
- Kaspa Core R&D · message 15562
- Kaspa Core R&D · message 15573
- Kaspa Core R&D · message 15574
- Kaspa Core R&D · message 15575
- Kaspa Core R&D · message 15576
- Kaspa Core R&D · message 15555
- Kaspa Core R&D · message 15556
- Kaspa Core R&D · message 15568
- Kaspa Core R&D · message 15569
- Kaspa Core R&D · message 15570
- Kaspa Core R&D · message 15571
- Kaspa Core R&D · message 15577
- Kaspa Core R&D · message 15578
- Kaspa Core R&D · message 15582



