Take-Home Lab 1: Spend Your Bitcoin Before It's Gone
- Released: Wednesday, September 16, 2026
- Due: Wednesday, September 23, 2026 at 11:59 PM ET
- You can collaborate (e.g., discuss) with another student, but each student should submit their own results.
- Start early, and come to office hours if you need help.
We can implement a retractable coin using Bitcoin Script:
OP_IF <student_public_key>
OP_ELSE <nLockTime> OP_CHECKLOCKTIMEVERIFY OP_DROP <course_staff_public_key>
OP_ENDIF
OP_CHECKSIG
In this lab, you will be sent 0.0001 testnet BTC locked by the redeem script above.1 Beginning on Wednesday, September 23, 2026 at 11:59 PM EDT, course staff can retract any output that remains unspent.2 Your task is to spend your UTXO before then!
To make your life easier, I developed a Python program called
timelock.py for creating and
spending these outputs. Course staff use its create subcommand to construct
the P2SH addresses, and you can use its spend subcommand to claim your coin.
Your work is mainly to understand how to use timelock.py by reading its source
code and documentation.
After a transaction has been sent to a P2SH output tailed to your public key, we will post the sender’s public key,
funding transaction ID, and UTXO index (one for each student).
You will need this information to run timelock.py, along with information you
must obtain yourself, such as your secret key.
Sender’s public key: 03b1c5e8cd51e2a1a9e4057ea1afc5d21159ca2014f103aa0dd1cb71901b51b42e
Confirmation times are block timestamps in Eastern Time. This column refreshes from mempool.space when the page loads; if it cannot be reached, the last recorded values remain.
Recover your secret key
To use timelock.py, you need the secret key that corresponds to
the public key you submitted during the Bitcoin hands-on component.
There are multiple ways to do it; you can use the following script.
Set WALLET, ADDRESS, and PUBKEY at the top of the script to your own
values:
import json
import shlex
import subprocess
import sys
import bitcoin
from bip32 import BIP32
from bitcoin.wallet import CBitcoinSecret
WALLET = "YOUR_WALLET_NAME"
ADDRESS = "YOUR_LEGACY_ADDRESS"
PUBKEY = "YOUR_PUBLIC_KEY"
def bitcoin_cli(*arguments):
command = [
"bitcoin-cli",
"-testnet4",
f"-rpcwallet={WALLET}",
*arguments,
]
print(f"+ {shlex.join(command)}", file=sys.stderr)
return json.loads(subprocess.check_output(command, text=True))
bitcoin.SelectParams("testnet")
address_info = bitcoin_cli("getaddressinfo", ADDRESS)
hd_path = address_info["hdkeypath"]
if address_info["pubkey"].lower() != PUBKEY.lower():
raise SystemExit("The address does not match the public key")
hd_keys = bitcoin_cli(
"-named",
"gethdkeys",
"active_only=true",
"private=true",
)
for hd_key in hd_keys:
if "xprv" not in hd_key:
continue
private_key = CBitcoinSecret.from_secret_bytes(
BIP32.from_xpriv(hd_key["xprv"]).get_privkey_from_path(hd_path)
)
if private_key.pub.hex().lower() == PUBKEY.lower():
print(private_key)
break
else:
raise SystemExit("Could not find the secret key for this public key")
Tips on how to run Python scripts
To run this script, we recommend using a virtual environment. See Python’s documentation on virtual environments for more information.
On macOS or Linux, run:
python3 -m venv .venv
source .venv/bin/activate
On Windows PowerShell, run:
py -m venv .venv
.venv\Scripts\Activate.ps1
Then install the two Python packages used by the scripts:
python -m pip install bip32 python-bitcoinlib
Make sure Bitcoin Core is running and the wallet named in WALLET is loaded.
Save the embedded script as get-secret-key.py, then run it:
python get-secret-key.py
The script verifies that the recovered secret key matches the public key before printing it.
What to Submit
Submit a PDF with your NetID, name, group members (if any), and answers to the following questions. Everyone must submit their own work, even if you are in a group. If you did not get a full answer, document partial progress.
- What
scriptSigwould course staff use to retract the output? - What is the
scriptPubKeyof the assigned funding output? - What is the txid of your spending transaction?
- What is the
scriptSigof the input in your spending transaction?
You can use the LaTeX template for your PDF submission.
-
This is why we need the public key you were asked to submit on Canvas. ↩︎
-
The corresponding
nLockTimeis1790222340, the Unix timestamp for the date and time above. ↩︎