In a previous article, I wrote about the “reading” side of Electrum-NMC’s name script support (i.e. detecting and displaying name transactions in the wallet, and doing name lookups). Obviously, the logical next step is the “writing” side, i.e. creating name transactions.
I started out by trying to implement
name_new. Electrum’s command API is quite flexible (yet quite user-friendly), so most of the relevant functionality was fairly straightforward to implement by adding slight modifications to the existing transaction creation commands. These modifications essentially just add an extra output to the transaction that has a non-null name operation. I did, however, need to add some extra functionality to the accounting, to adjust for the fact that a
name_new transaction destroys 0.01 NMC by permanently locking it inside an output. (Usually, it’s desirable to treat that locked namecent as zero for display purposes, but when funding a transaction, treating it as zero would produce Bad Things ™.)
Electrum’s API philosophy differs from that of Bitcoin Core, in that while Bitcoin Core wallet commands tend to broadcast the result automatically, Electrum wallet commands tend to simply return a transaction, which you’re expected to broadcast with the
broadcast command. I’m following this approach for the name wallet commands. Creating the
name_new transaction completed rather easily without errors; however, when I tried to broadcast the
name_new transaction, it was rejected by my Namecoin Core node that serves as the backend for my ElectrumX instance. I inspected my Namecoin Core node’s
debug.log, and quickly found the issue: I had forgotten to set the transaction’s
nVersion field to the value that permits name operations. Namecoin requires all name operations to appear in transactions with an
nVersion field of
0x7100, which is a value that doesn’t show up in Bitcoin at all. I decided not to modify the transaction construction API’s in Electrum to allow manual setting of the
nVersion field per command (end users don’t want to think about these details), and instead decided that it was easier to simply add a couple of lines to the
Transaction class so that if you supply it with an output that has a name operation attached to it, the resulting transaction will automatically have its
With that fix, I could create
name_new transactions and broadcast them. I sent a
name_new from Electrum-NMC to my Namecoin Core wallet and also created one that stayed within Electrum-NMC. The underlying logic here was two-fold: (1) I wanted to make sure that both explicitly-specified recipient addresses and automatically-generated local addresses worked properly, and (2) if an issue happened while trying to spend the
name_new outputs with Electrum-NMC, I wanted to be able to quickly compare the results with Namecoin Core so that I would know whether the problem was with the code trying to spend the output or with the code that created the output.
name_new transactions were reaching their required 12 blocks of confirmations, I implemented
name_firstupdate support. This was a little bit more interesting, because it meant I had to explicitly add a mandatory name input (the
name_new) in addition to a mandatory name output (the
name_firstupdate). Electrum makes it very easy to add mandatory outputs, since that’s commonplace in Bitcoinland. Adding mandatory inputs, however, is not exactly straightforward. I ended up modifying a few of the coin selection algorithms to allow specifying mandatory inputs that would be applied before any other inputs are added, and while I wish it could be done with fewer changes, I’m reasonably happy with the result.
name_firstupdate transaction was relatively easy to do from Electrum-NMC without errors. Unfortunately, once again the transaction was rejected by my ElectrumX instance’s Namecoin Core node. This time the error was a lot less intelligible; the error had something to do with the signature check failing, but it wasn’t clear to me exactly what the problem was. To narrow down the issue, I tried spending the
name_new that I had sent to my Namecoin Core wallet into a
name_firstupdate, and that one worked fine. So clearly the issue was in the
name_firstupdate code in Electrum-NMC, and not anything broken in the
name_new that was already created. I ended up copying the invalid transaction into Namecoin Core’s
decoderawtransaction RPC method, and then pasting the hex-encoded script into Bitcoin IDE to simulate exactly what was happening. And it definitely was clear that something was wrong: the hash that the signature signed didn’t match the hash it was supposed to be signing.
This seemed rather weird, since I hadn’t touched any of the signature code. After some grep-fu of the Electrum codebase, I figured out what had happened. In Bitcoin transactions, the signatures cover the scriptPubKeys of the previous transaction outputs. This shouldn’t be a problem, but Electrum tries to be clever in order to avoid actually looking up the previous transactions. Electrum actually guesses the previous scriptPubKey based on the scriptSig. This actually works fine for the transaction types that one normally finds in Bitcoinland. However, in Namecoin, name operations are prefixed to the scriptPubKey, and nothing about that name prefix (even whether one exists at all) can be inferred from the scriptSig that spends the name output. As a result, the previous scriptPubKey that was being signed didn’t have a name prefix at all, which of course caused the hashes to mismatch.
Modifying the wallet code to pass through name operations to the data structures that the scriptPubKey-guessing code has access to wasn’t particularly painful, nor was modifying the scriptPubKey-guessing code to prefix the correct name script when needed. With that out of the way, a
name_firstupdate from Electrum-NMC was able to broadcast successfully.
name_update was comparatively simple. The main change needed for this one was that while
name_firstupdate specified the mandatory name input by TXID,
name_update specifies it by name identifier. Adding this functionality to the coin selection algorithms wasn’t particularly unpleasant. And thus, I was able to create and broadcast a
name_update transaction as well. Yay!
The next future step is probably to hook these commands into the GUI.
And, with that out of the way, here are some transactions I created with Electrum-NMC’s console:
name_newcreated by Electrum-NMC, sent to Namecoin Core
name_firstupdatecreated by Namecoin Core, spending the
name_newcreated by Electrum-NMC
name_firstupdatecreated by Electrum-NMC
name_updatecreated by Electrum-NMC
This work was funded by Cyphrs and NLnet Foundation’s Internet Hardening Fund.