My second Dogecoin PR was pretty big; this is PR 1856. There’s a lot to explain, so I’ll cover it in a few posts.
As background, this is what first caught my eye before I created PR 1835. I was doing research to see if this change was reasonable.
What attracted me to this? I’ve done web development, but I haven’t done any desktop GUI development in a long time. I haven’t done much C++ or Qt in a very, very long time. The requesting ticket (#1808) had really clear guidelines, used the “Help Wanted” tag, and seemed large enough that it wasn’t likely anyone else was working on it.
In retrospect, it would have been wiser for me to respond to that issue to say that I was interested to do the work. On the other hand, a lot of “Help Wanted” tickets attract comments like that, and then never see a followup, so maybe it was fine to do the work myself.
Before getting too deeply into my initial plan, you need to understand the differences between a couple of things.
First, the wallet code represents your private keys and Dogecoin addresses. When you send or receive transactions, you use your wallet to process changes to the blockchain. If you don’t have a wallet, your Dogecoin node will only do things like relay transactions, share the blockchain with other nodes, and perhaps mine new blocks.
Second, the Qt GUI code is the nice friendly Comic Sans-and-Shiba Inu meme graphical user interface you see when you launch the Dogecoin core on your computer. You can click through a history of transactions, look at the peer nodes you’ve connected to, and so on.
Finally, the RPC interface is a system that allows you to send textual
commands to the Dogecoin core, whether through the dogecoin-cli
program from
a terminal window, or the RPC interface in the Qt GUI. If you’re a power user
comfortable with typing commands at computers, this can be really useful. It’s
not particularly friendly if you don’t like doing this, or if you don’t know
some details about how cryptocurrency works though.
That was the entire point of the ticket Patrick filed; Dogecoin would be a lot friendlier if users didn’t have to understand the RPC system to import private keys.
I read some of the code before I agreed (in my head) to commit to doing the work. The task seemed straightforward enough as Patrick had outlined it:
- understand the RPC code to import a private key
- find a way to call that code from the Qt GUI
- create the GUI to get that data from the user and send it to the backend
At least, that’s what I assumed.
For any existing software project that’s been around for a while and hasn’t collapsed under the weight of its own maintenance, you can usually assume a couple of things:
- stuff exists
- hopefully where you expect it
I expected that I’d have to deal with three logical units of code: something that represents a wallet, something that understands user input from the RPC system, and something that presents the graphical user interface via QT. The good news is that all three existed and looked mostly like I expected.
Why does this matter?
You can run the Dogecoin core with several different independent options. You can run a network node without a GUI. You can run a GUI without a wallet. You can run a network node on your laptop with a GUI but without RPC. All of these options are available, and the system has to work with all of them.
For the system to work, Dogecoin has to enforce some type of separation between these systems. It would be difficult to run a GUI on your laptop without RPC if RPC code were mingled with the GUI code, for example. It would be really dangerous to run a wallet with both the GUI and RPC enabled if both the RPC and GUI code poked directly into the wallet. You could end up corrupting your keys and losing your coins!
Even though I hadn’t done C++ or GUI programming in a while, almost everything Patrick was looking for already existed in the code elsewhere. There was already code to display the user interface elements necessary to take user input (textboxes, labels, submit buttons, etc). There was already code to validate the private key and insert it into the wallet.
I did think it would be easier to share the wallet between the RPC system and the GUI than it was though. I’ll talk more about implementing this code in the next post.