Bitcoin Time-Lock Tutorial
Tags: bitcoin, blockchain, pension
Published: 2023-04-18 21:25:30

There are different ways to time-lock Bitcoins. There is a very good article about options and nuances in [this article](https://medium.com/summa-technology/bitcoins-time-locks-27e0c362d7a1). I'm not going to further dig into the possibilities but suggest just one approach. Also this post is not generally about [Bitcoin scripting](https://en.bitcoin.it/wiki/Script).

This tutorial creates two transactions locking-up Bitcoins for some time and unlocking them again later.

1. Funding P2SH transaction to be mined **now**
2. Redeeming P2WPKH transaction to be mined **later**

We'll use the service of [coinb.in](https://coinb.in/). It's very important to note that as long as you execute the steps of the tutorial on that page, your funds are at risk of being stolen by whoever is in control of coinb.in. I'll mention when to disable internet connection to mitigate some of the risk.

# 1. Funding Transaction

First we need to produce a redeem script. This script will be presented to unlock the funds later. We keep it secret, but we wouldn't need to because it will be signed. The hash of this script is actually the P2SH address. The redeem script will contain the lock-time and the public key of who will sign the second transaction.

These are the steps.

1. **Create the crypto keys.** The public key will be able to redeem the funds by presenting the redeem script and the transaction signature.
  * Open <https://coinb.in/#newAddress> in a private browser window
  * Disable internet
  * Click generate
  * Copy-and-paste the details to somewhere else
  * Close the browser
  ![Public Key Cryptography](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dbej2mx6jeojlu334v5.png)
2. **Create a time-lock script and hash it.**
  * Open <https://coinb.in/#newTimeLocked>
  * Enter the previously generated public key and a lock-time.
  ![Time-lock script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z406uvdrqi0um8oaydv9.png)
3. Store the address (actually the script hash) and the redeem script for future use.
4. Pay some funds to the generated P2SH address (`3PEQuKQybPh6VGT7JujWFmTEa52C6gi5u2`). Those funds will not be redeemable before lock-time!
5. Observe how your transaction is being mined (<https://live.blockcypher.com/btc/tx/12b123103fd042a12b44f2e78e7807bb96231aa14d97c179c492ab34f7835f67/>).

Let some time pass…

# 2. Redeeming Transaction

To spend the funds after lock-time has passed, we need to create a transaction which presents the redeem script of which we previously only revealed the hash. Since our script includes a signature check, we'll need to sign the resulting transaction with the private key generated in 1.1.

Maybe now it's a good time to have a look at what the redeem script actually does. It is an assembly script for the Bitcoin stack language represented in hex. If you decode it (e.g. in the assembly tab of <https://siminchen.github.io/bitcoinIDE/build/editor.html>), you'll receive the following mnemonics:

```
2ce53e64
OP_NOP2
OP_DROP 
0397b6389e42392943aacd69538068814d9bb08ba601416a2f5219dff140962962
OP_CHECKSIG
```

This a very simple script, approximately doing the following:
* Push the timestamp to the stack
* Compare the timestamp with the designated field of the transaction and drop the result from the stack. This is the combined "`OP_HODL" opcode.
* Push the public key (generated in 1.1.) to the stack
* Check the signature of the transaction against the public key on the stack.

If this whole script checks out, the transaction is considered valid.

1. Now let's **create the P2WPK transaction** to actually redeem the funds again.
  * Visit <https://coinb.in/#newTransaction>
  * Paste the redeem script into the input field and click load. This automatically fills out the input part of the transaction by searching the script hash on the blockchain.
  * Paste a "normal" P2WPKH address into the address field and fill in an amount to move away. Make sure there are some transaction fees left.
  * Click submit to create a raw (still unsigned) transaction
  ![Generate raw transaction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e7hns2fypxds94qilly.png)
  * Copy the transaction hex
2. **Sign the transaction**
  * Open a private browser window for <https://coinb.in/#sign>
  * Disable internet
  * Paste the private key from 1.1. and the raw transaction hex from 2.1.
  * Click submit
    ![Signed transaction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epq9fxq3nn77zfafclrn.png)
  * Copy the signed transaction
  * Close the browser
3. **Broadcast the transaction** to the Bitcoin network to transfer your time-locked funds.
  * Go to <https://coinb.in/#broadcast>
  * Paste the signed transaction
  * Click submit
    ![Broadcasted transaction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kho4e3ya8ed05yl1lo3.png)
  * Observe your transaction getting mined (<https://live.blockcypher.com/btc/tx/7982d8ab6876443d20fbad5de777b85f0e4a5a37ea5c24a6d4c72e5688e06be6/?txid=7982d8ab6876443d20fbad5de777b85f0e4a5a37ea5c24a6d4c72e5688e06be6>)

That's it. You time-locked funds and retrieved them again.