(parentheses + italics = commentary, questions on how these challenges are structured. obviously not intended to be in the text for the students.)
(This challenge is focused on not needing any coding skills and just discussing/knowing basic bitcoin mechanisms)
Tx number | Fee /sats | Weight | Standard? | Consensus valid? | Spends from |
---|---|---|---|---|---|
1 | 58M | 3.6M | ✔️ | ✔️ | 4 |
2 | 10K | 0.01M | ✔️ | ✔️ | |
3 | 10M | 0.11M | ❌ | ✔️ | 2 |
4 | 20M | 0.5M | ❌ | ✔️ | |
5 | 20K | 0.03M | ✔️ | ✔️ | 1 |
6 | 0.01K | 0.4M | ✔️ | ✔️ | 5 |
7 | 0.12M | 2.2M | ✔️ | ✔️ | |
8 | 0.11M | 0.4M | ✔️ | ✔️ | 7 |
9 | 0.65M | 0.4M | ✔️ | ❌ | |
10 | 0.24M | 0.4M | ✔️ | ✔️ | 9 |
Terms: Weight : defined as (witness bytes + 4 * non-witness bytes). Hint: why is this important for mining a block?
Spends from (x) : means this transaction has an input which consumes an output from the other numbered transaction.
"Standard", "Consensus valid" : investigate what is the importance of a transaction being "standard" in bitcoin vs. a transaction being "consensus valid" (search on the internet!)
You are a miner of bitcoin, and these 10 are all the transactions available to you (in your "mempool").
Question : Which transactions do you choose to include in your block, and what is your overall block reward (in September 2024)?
(This is included, again, to allow progress for those who aren't able to do any coding; it just requires searching and understanding terminology)
Here is a list of transaction types:
- Coinjoin transaction
- Taproot spending transaction
- Coinbase transaction
- Transaction using OP_RETURN to inscribe data
- Lightning channel open transaction
- Lightning penalty (justice) transaction (they are rare!)
- A transaction which has an output which you know for sure is of type "p2sh-p2wpkh".
Task: Find one example of each from the bitcoin blockchain and write down the transaction-id (txid) of each one.
(re: for sure - you have to provide evidence, in the form of another txid).
(I put a lot of hand holding here to avoid, e.g., delving into BIP340 challenge construction details and x-only keys, way too much, I just want them to see the simple extraction of a key from nonce reuse. Also since I want to give people a chance that are not "math-freaks", I wrote some guidance on doing the division of (delta s)/(delta e)).
Here are two valid Schnorr signatures on my private key, for two different messages. They are formatted the same way as on the Bitcoin blockchain:
Sig A: d902ff7196ddc842ef5b4ea5d0aa17608e9b7f5f9a964ba1281cd432a7abe2e9 87f2c5c6f19d80ef12308a3e4ba10a91492feb4f37a1a5da48724fa86cff00d5
Sig B: d902ff7196ddc842ef5b4ea5d0aa17608e9b7f5f9a964ba1281cd432a7abe2e9 a861c9cff94fe4f715bc339a5962c9e7aebf018034a9d7a42cdf5e200f5b5f93
Do you notice something strange about these two signatures?
Background: The Schnorr signature 's' is calculated as:
s = (k + e * x) mod N
Here: N is the group order of secp256k1. k is the 'nonce'. And e is the 'hash challenge'. In bitcoin it is calculated with the formula in BIP340. For this challenge we will just give you the e values for each signature:
e for sig A: c5bd0b050471ec7820edeafdc94420d0216de07905aa3eb10782ba42cf22fa7
e for sig B: 28b9b2cea01bdddbc75258cf4603f6b57e46db2fdb9e38fdc454e0925998fe53
The values above are hexadecimal representations of integers.
Question : Can you find my private key? (Hint : if you can't see how, search for "nonce reuse" on the internet for more explanation)
Question (Optional) : What nonce did I use? What did i do wrong?
Hints: you need to be able to divide in modular arithmetic. For example, if you want to find the value of 7 / 3 in modulo 11, you need to find the modular inverse of 3 in mod 11, and then multiply the result by 7, mod 11. For that, in Python 3.8+ you can do:
y = pow(3, -1, 11)
.. while for other programming environments, you may need to search for the "Extended euclidean algorithm" or just "modular inverse".
Step 1 Create a p2pkh (pay to public key hash) address ending in the character "b" (the fact that it's the end of the address is unusual, but shouldn't matter, even though this is the checksum portion; you just run the private key to address algo the same way, repeatedly)
Step 2 Create a p2sh-p2wpkh (so segwit wrapped with pay-to-script-hash) address ending in the two characters "tc"
Step 3 Explain why it's impossible to do the same for "BITCOIN" instead of "b" or tc" (Notice: impossible, not just difficult!).
(Scrap this! It's too complicated)(Optional) Step 4: how many sha2 calculations on average would you expect to run to generate a p2sh-p2wpkh address ending in the characters "btc"?
(This one requires some non-trivial setup, but is fairly easy for the students EXCEPT that they have to know how to craft and sign a transaction, given a privkey and a utxo; they could conceivably use tools to greatly simplify that, but they have to make an OP_RETURN output, so I guess not. Is that too hard?)
Here is a transaction on the signet blockchain, decoded into json for easier reading:
(provide the txid, then the json)
(Here we could make 1 transaction for each student group, perhaps 5 or more? Each transaction will have two outputs, both p2wpkh because that's the most 'vanilla' today)
In this transaction, the private key of the second output is:
SHA-256(the address of the first transaction)
Task: Find this private key then create a new transaction spending that (second output). Your new transaction should:
- pay a fee of between 1000 and 10000 sats
- have one output that is OP_RETURN and should encode your name(s)
- have one other output (so exactly 2 total) that is the change which should be returned to the first address
Then broadcast this transaction onto the signet network.
Hint: you can study OP_RETURN here (but do search for other info if you need it). This helpfully refers to examples, like this transaction: https://mempool.space/tx/6dfb16dd580698242bcfd8e433d557ed8c642272a368894de27292a8844a4e75 which has its third output as an OP_RETURN of the string "hello world".
(i originally thought about giving 5 "decoys", i.e. 'which one is unusual', but, this problem is hard enough; the critical thing is to give a guiding clue; I think the one I give here is reasonable)
Here is an address, holding a utxo (i.e. still unspent output) of type taproot:
bc1peyz0h83xfh9vqqymhhpj8jh9ze2quu4kys3u26x7c6s4djjcht9qrnd3ng
Investigate the utxo. There is something unique about it. What makes it unique amongst all the taproot utxos that exist?
Clue 1: why is it still unspent after a long time?
Clue 2: Think about the elliptic curve. (is this too easy?)
(Currently 'in limbo' since these can't be brcst; probably ditch it)
(I am going to have to prepare this non-taproot-spending signet tx in advance, but it's awkward because if anyone spends it it'll remove the ability for students to "check if valid". I guess we can just tell them to testmempoolaccept it and hope they do that?)
Clue: investigate what "malleated transaction" means in bitcoin.
Here is a hex-encoded fully-signed signet bitcoin transaction:
02....
Step 1: decode the transaction and describe its structure; describe the number and type of inputs and outputs.
Step 2: without knowing the private keys of the inputs, how can you change the transaction hex and still have the transaction be valid, i.e. you can have it confirmed in a block on signet? For full credit do this by making two different edits.
Step 3: Could you do step 2 if all the inputs are of type p2tr? Explain how you could, or why you could not.
(this first step is probably way too hard for anyone who hasn't even looked at taproot? i guess?)
Step 1: Create a taproot (p2tr) address that can be spent (or "unlocked") by providing the text "hunter2" as the preimage of the sha256 hash:
f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a3f6c7
Help: you need to make the 'script path spending' for the taproot spending be a script:
OP_HASH256 f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a3f6c7 OP_EQUAL
You can make the taproot internal key any value you like, but read BIP341 for a recommendation for cases where "key path spending" is not used. (todo: probably tell them what internal key to use, so there is one answer.)
Step 2: Explain why knowing the "password" (hunter2) is not enough to guarantee that you receive the money - even if no one else knows that secret password!.
Step 3: How do systems like the Lightning network prevent the problem described in Step 2?
(shamelessly cribbed from Greg Maxwell back in the day, but a way easier version. while it's "easy when you know how", actually arriving at that knowledge is absurdly arcane/obscure, so i put in a massive clue)
What is the private key for the public key:
0200000000000000000000003b78ce563f89a0ed9414f5aa28ad0d96d6795f9c63
Clue: what is half of a generator?
Notes for "Insecure nonce-sense":
Here is a dump of the part-random data I used to create this case:
Signatures are of course (R, s).
Maybe we should somehow emphasise more that it's about the fact that the first half of that string is the same in each case?no that's obvious enough!Note I actually used sha256(R,m) as the challenge algo, before realising it was just too messy to include that, and instead just chose to give the reader the 'e' value directly.
The value of k that is repeated is 500.