Electrum-NMC: Name Transaction Creation
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 nVersion
modified.
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.
While both 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.
Creating the 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_new
created by Electrum-NMC, sent to Namecoin Corename_firstupdate
created by Namecoin Core, spending thename_new
created by Electrum-NMCname_firstupdate
created by Electrum-NMCname_update
created by Electrum-NMC
This work was funded by Cyphrs and NLnet Foundation’s Internet Hardening Fund.