[bitcoin-dev] [BIP Proposal] Standard address format for timelocked funds

ZmnSCPxj ZmnSCPxj at protonmail.com
Sat Jul 8 01:13:01 UTC 2017


<pre>
BIP: ?
Title: Standard address format for timelocked funds
Author: ZmnSCPxj <ZmnSCPxj at protonmail.com>
Comments-Summary: ?
Comments-URI: ?
Status: ?
Type: ?
Created: 2017-07-01
License: CC0-1.0
</pre>
== Abstract ==
<code>OP_CHECKLOCKTIMEVERIFY</code> provides a method of
locking funds until a particular time arrives.
One potential use of this opcode is for a user to precommit
himself or herself to not spend funds until a particular
date, i.e. to hold the funds until a later date.
This proposal adds a format for specifying addresses that
precommit to timelocked funds, as well as specifying a
redemption code to redeem funds after the timelock has
passed.
This allows ordinary non-technical users to make use of
<code>OP_CHECKLOCKTIMEVERIFY</code> easily.
== Copyright ==
This BIP is released under CC0-1.0.
== Specification ==
This proposal provides formats for specifying an
address that locks funds until a specified date,
and a redemption code that allows the funds to be
swept on or after the specified date.
At minimum, wallet software supporting this BIP must
be capable of sweeping the redemption code on or after
the specified date.
In addition, the wallet software should support sending
funds to the timelocked address specified here.
Finally, wallet software may provide a command to create
a pair of timelocked address and redemption code.
Addresses and redemption codes are encoded using
[https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#Bech32
Bech32 encoding].
=== Timelocked Address Format ===
The human-readable part of the address is composed of:
# The four characters <code>hodl</code>.
# A date, in <code>YYYYMMDD</code> form. For example,
the date August 1, 2017 is encoded as <code>20170801</code>.
# A network code, either <code>tb</code> for testnet,
or <code>bc</code> for Bitcoin mainnet.
The data part of the address is composed of:
# A version quintet (5 bits), which must be 0 for this
BIP.
# A public key hash, 32 quintets (160 bits). As is
usual for Bitcoin, this is big-endian.
This is to be interpreted as follows:
# The given date is the first day that the funds in
the given address may be redeemed.
# The funds are owned by whoever controls the private
key corresponding to the public key hash given.
=== Redemption Code ===
The human-readable part of the redemption code is
composed of:
# The four characters <code>hedl</code>.
# A date, in <code>YYYYMMDD</code> form.
# A network code, either <code>tb</code> for testnet,
or <code>bc</code> for Bitcoin mainnet.
The data part of the address is composed of:
# A version quintet (5 bits), which must be 0 for this
BIP.
# A private key, 52 quintets (260 bits). This is the
256-bit private key, prepended with 4 <code>0</code>
bits, in big-endian order. <!-- We could consider
some kind of mini private key instead if the security
is similar anyway. -->
This is to be interpreted as follows:
# The given date is the first day that the funds in
the given address may be redeemed.
# The private key unlocks the funds.
=== Lock Time Computation ===
Given a particular lock date <code>YYYYMMDD</code>, the
actual lock time is computed as follows:
# The day before the lock date is taken. For example,
if the lock date is <code>20180101</code> or
January 1, 2018, we take the date December 31, 2017.
# We take the time 1000h (10:00 AM, or 10 in the morning)
of the date from the above step.
This lock time is then translated to a
Unix epoch time, as per POSIX.1-2001 (which removes the
buggy day February 29, 2100 in previous POSIX revisions).
The translation should use, at minimum, unsigned 32-bit
numbers to represent the Unix epoch time.
The Unix epoch time shall then be interpreted as an
<code>nLockTime</code> value, as per standard Bitcoin.
Whether it is possible to represent dates past 2038
will depend on whether standard Bitcoin can represent
<code>nLockTime</code> values to represent dates past
2038.
Since <code>nLockTime</code> is an unsigned 32-bit
value, it should be possible to represent dates until
06:28:15 UTC+0 2106-02-07.
Future versions of Bitcoin should be able to support
<code>nLockTime</code> larger than unsigned 32-bit,
in order to allow even later dates.
The reason for using an earlier lock time than the
specified date is given in the Rationale section of
this BIP.
=== Payment to a Timelocked Address ===
An ordinary P2SH payment is used to provide funds to a
timelocked address.
The script below is used as the <code>redeemScript</code>
for the P2SH payment:
<timeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_DUP OP_HASH160 <publickeyhash> OP_EQUALVERIFY OP_CHECKSIG
Once the <code>redeemScript</code> is derived, the hash is
determined, and an ordinary P2SH output with the below
<code>scriptPubKey</code> used:
OP_HASH160 <redeemScripthash> OP_EQUAL
In case of SegWit deployment, SegWit-compatible wallets
should be able to use P2SH, P2WSH, or P2SH-P2WSH, as per
the output they would normally use in that situation.
Obviously, a timelocked address has an equivalent
Bitcoin <code>3</code> (P2SH) address.
A simple service or software that translates from a
public timelocked address to a P2SH address can be
created that makes timelocking (but not redemption)
backwards compatible with wallets that do not support
this BIP.
This proposal recommends that wallets supporting payment
to P2PKH, P2SH, P2WPKH, and P2WSH Bitcoin addresses should
reuse the same interface for paying to such addresses as
paying into timelocked addresses of this proposal.
=== Redemption of a Timelocked Redemption Code ===
To sweep a timelocked redemption code after the timelock,
one must provide the given <code>redeemScript</code> as
part of the <code>scriptSig</code>, of all unspent
outputs that pay to the given <code>redeemScript</code>
hash.
When sweeping a timelocked redemption code, first the
wallet must extract the private key from the redemption
code, then derive the public key, the public key hash,
the <code>redeemScript</code>, and finally the
<code>redeemScript</code> hash.
Then, the wallet must find all unspent outputs that pay
to the <code>redeemScript</code> hash via P2SH (and, in the
case of SegWit deployment, via P2SH-P2WSH and P2WSH).
For each such output, the wallet then generates a
transaction input with the below <code>scriptSig</code>, as
per usual P2SH redemptions:
<signature> <pubkey> <redeemScript>
The wallet then outputs to an address it can control.
As the Script involved uses <code>OP_CHECKLOCKTIMEVERIFY</code>,
the <code>nSequence</code> must be 0 and the
<code>nLockTime</code> must be equal to the computed
lock time.
This implies that the transaction cannot be transmitted
(and the funds cannot be sweeped)
until after the given lock time.
The above procedure is roughly identical to sweeping an
ordinary, exported private key.
This proposal recommends that wallets supporting a sweep
function should reuse the same interface for sweeping
individual private keys (wallet import format) for sweeping
timelocked redemption codes.
== Motivation ==
A key motivation for this BIP is to allow easy use of
<code>OP_CHECKLOCKTIMEVERIFY</code> by end-users.
The below are expected use cases of this proposal:
# A user wants to purchase an amount of Bitcoin,
and subsequently wait for an amount of time before
cashing out.
The user fears that he or she may have "weak hands",
i.e. sell unfavorably on a temporary dip, and thus
commits the coins into a timelocked fund that can
only be opened after a specific date.
# A user wants to gift an amount of Bitcoins to
an infant or minor, and wants the fund to not be spent
on ill-advised purchases until the infant or minor
reaches the age of maturity.
# A user may wish to prepare some kind of monthly subsidy
or allowance to another user, and prepares a series of
timelocked addresses, redeemable at some set date on
each month, and provides the private redemption codes to
the beneficiary.
# A user may fear duress or ransom for a particular
future time horizon, and voluntarily impose a lock time
during which a majority of their funds cannot be spent.
== Rationale ==
While in principle, this proposal may be implemented as a
separate service or software, we should consider the long
time horizons that may be desired by users.
A user using a particular software to timelock a fund may
have concerns, for example, of specifying a timelock
18 years in the future for a gift or inheritance to a
newborn infant.
The software or service may no longer exist after 18 years,
unless the user himself or herself takes over maintenance
of that software or service.
By having a single standard for timelocked funds that is
shared and common among multiple implementations of Bitcoin
wallets, the user has some assurance that the redemption code
for the funds is still useable after 18 years.
Further, a publicly-accessible standard specifying how the
funds can be redeemed will allow technically-capable users
or beneficiaries to create software that can redeem the
timelocked fund.
This proposal provides a timelock at the granularity of a
day.
The expectation is that users will have long time
durations of months or years, so that the ability to
specify exact times, which would require specifying the
timezone, is unneeded.
The actual timeout used is 1000h of the day before the
human-readable date, so that timezones of UTC+14 will
definitely be able to redeem the money starting at
0000h of the human-readable date, local time (UTC+14).
Given the expectation that users will use long time
durations, the fact that timezones of UTC-12 will
actually be able to redeem the funds on 2200h UTC-12
time two days before can be considered an acceptable
error.
The human-readable date is formatted according to
[https://www.iso.org/iso-8601-date-and-time-format.html
ISO standard dates], with the dashes removed.
Dashes may prevent double-click selection, making
usability of these addresses less desirable.
<!--
We can consider something like 2021m12d11 instead,
which would be much more readable and understandable
to human users.
-->
The <code>bc</code> or <code>tb</code> is after the
date since the date is composed of digits and the bech32
separator itself is the digit <code>1</code>. One
simply needs to compare <code>hedlbc202111211...</code>
and <code>hedl20211121bc1...</code>.
A version quintet is added in case of a future
sociopolitical event that changes interpretation of
dates, or changes in scripting that would allow for more
efficient redemptions of timelocked funds (which would
change the <code>redeemScript</code> paid to), or changes
in the size and/or format of lock times, and so on.
Such changes are unlikely, so the version is a quintet in
the bech32 data part rather than a substring in the
human-readable part.
The public address format uses the <code>hodl</code> as
the start of the code, while the private key (the
redemption code) uses <code>hedl</code>.
This provides a simple mnemonic for users:
"Pay into the <code>hodl</code> code to hold your
coins until the given date.
After you've held the coins (on or after the given date)
use the <code>hedl</code> code to redeem the coins."
The obvious misspelling of "hodl" is a homage to the common
meme within the Bitcoin community.
<!-- The above misspelling may be corrected if it is considered
to be in bad taste. -->
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20170707/05ada9ef/attachment-0001.html>


More information about the bitcoin-dev mailing list