₿OSS Challenge 2 complete 🎉

That was a tough one

Well it took wayyyy longer than I was expecting, but I finally finished the second ₿OSS coding challenge. The task was to code two transactions spending a UTXO from the wallet created in the first challenge. The first transaction sent funds to a multisig taproot script, the second spent these funds.

It was very hard to wrap my head around the technical details of constructing a taproot script. Especially the ‘tweaking’ concept was new to me. It depends on a property of Schnorr signatures that allow a public key and corresponding private key to be increased by the same amount (the ‘tweak’), and the tweaked private key can still create a valid signature for the tweaked public key.

This matters for taproot scripts because any number of scripts can be created to unlock funds, then hashed and combined with a public key to create the scriptpubkey, which is basically the address for transaction funds to be sent. Because of the tweak property, the receiver of those funds can reveal the script and prove it was part of the hash that created the scriptpubkey.

The challenges are great because they really force you to understand these complex and confusing concepts. Especially when dealing with transactions, the terminology can be confusing - there are outpoints, inputs, outputs, input outputs, public keys, scriptpubkeys, witnesses and witness programs. But I’m sure over time this will all become second nature.

A tedious and error-prone part of the task was to assemble the commitment hash and hex transaction itself. There are many different components to each of these, and getting one byte wrong will invalidate the transaction. Like it or not, debugging is part of the development process, and good developers become proficient at this. For this task, I and many others had to work through an ambiguous Invalid Schnorr signature error when submitting my first transaction to the mempool. I had to insert logging into bitcoin core to reveal more details. It turned out the amount in my commitment hash was wrong.

This ate up many hours, and later I set up debugging with CLion and bitcoind by compiling bitcoind with the -DCMAKE_BUILD_TYPE=Debug flag and attaching the CLion debugger to the bitcoind process. This helped me debug a Witness program hash error when submitting my second transaction. This time, my function calculating the ‘parity bit’ of the tweaked public key was returning the wrong boolean value. More descriptive transaction rejection messages could have saved a lot of time. Maybe this will be a future PR!

I’ll get as far as I can in subsequent challenges before the next program phase on Feb. 12. There is another warnet game starting in a couple days too.

Bitcoin is all about proof of work, and here’s mine: look for my github handle rsamartino in the OP_RETURN feed.

Signing off for now 🫡


Write a comment
No comments yet.