The following is I believe an example of how we can use a transaction (kernel) timelock to implement a timelock on a single output.
I believe this could also be extended to more complex scenarios by using multisig
to allow conditionals like “Output can be spent by Alice after 100 blocks or by Bob immediately”.
We know how to do two things today -
- We can add an absolute, unconditional lock_height to a tx_kernel.
The transaction will not be accepted earlier than block height x. - We can “split” a private key and use the two parts across two outputs such that they can only be spent as a pair.
k = k1 + k2
(Similar to how we split private keys when generating the kernel offset in https://github.com/mimblewimble/grin/pull/681).
If we use k1
to sign tx1
(output o1
) and k2
to sign tx2
(output o2
) I think we can construct a pair of outputs [o1, o2]
such that they can be spent as a pair.
If we can split the key in such a way that no party knows the individual key parts k1
, k2
then they can only be spent as a pair with key k
.
We now have a situation where tx1
and tx2
can be accepted to the blockchain separately.
But o1
and o2
can only be spent together as a pair in a subsequent tx.
By introducing a simple unconditional lock_height on one of these transactions,
this lock_height will restrict the other output from being spent.
For example tx1
(output o1
) has a lock_height of x
. We cannot broadcast tx1
until at least block height x
.
We can broadcast tx2
immediately but the contained output o2
cannot be spent
until height x
, given the lock_height on tx1
.
Output o2
in tx2
cannot be spent until height x
, due to the timelock on tx1
.
Or stated differently - the private key to spend o2
is only available once tx1
is accepted at height x
due to [o1, o2]
only being spendable as a pair via the single private key k
.
We have turned a transaction (kernel) timelock into a timelock on a single output, via a private key, allowing us to also potentially introduce conditional logic via multisig.