On incomplete transactions
A transaction that is not valid yet, might be called partially signed or incomplete. ElectrumSV has a temporary way to structure these but it only serves the pre-existing needs we had. This article does not attempt to propose a solution but instead aims to gather some related thoughts together.
ElectrumSV’s temporary format
The incomplete transaction format that ESV inherited from Electrum Core was a binary variation on legitimate Bitcoin transactions. When parsing a Bitcoin transaction it was possible to identify whether it was complete or incomplete and extract any signing metadata if it was the latter.
When I released ElectrumSV 1.3.0 and added the ability to support non-P2SH forms of multi-signature, I needed to extend it. I didn’t want to have to deal with an extended format based on Electrum Core’s binary variation, so created a temporary JSON-based format until there was time to work out the larger needs.
A cosigner is not expected to have any of the UTXOs being spent or the transactions they belong to. They can verify what is being spent, and where it is going. Presumably this means they already know the address that should be getting paid and can visually verify it matches. But what they can see is that coins from their wallet are spent and how much coin is gong to the recipient and how much is returning as change.
The format above only suits limited cases where the application that processes it should know the xpub in use, and if other cosigners are involved work out who has already signed or who needs to sign still. So offline signing and multi-signature.
Moving towards a better format
The current format we use is rather ad-hoc, but it might be possible to extrapolate from it.
Script templates and parameterisation
Any application participating likely needs to know the common script type, and to be able to construct and deconstruct it. It might be that they don’t need to understand it, but can instead pick out the data that parameterises the script, and can put back in new parameters. And merely know the offsets, format of the parameters, and the repercussions of what modifying them does. With that context in mind, it can be seen that the above is very multi-signature specific, “threshold” should be part of the parameterisation of the script, as would “signatures” and the “x_pubkeys” in some form.
I suspect it is possible to generate templates from scrypt contracts, so ElectrumSV has a library of scripts perhaps a subset of the complete set it knows about, that were sourced in this way.
Synchronising state
An offline cosigner cannot fetch the transactions the outputs are being spent from, so each spent “value” is provided mainly for informative purposes. It is assumed that offline signing is usually in the context where the signers are less concerned about this being correct.
I suspect that there is some crossover here between the move to a P2P model versus the current blockchain synchronisation model. In some cases the incomplete transaction should be accompanied by the transactions whose outputs are being spent, and in other cases the offline wallet might want to synchronise all the wallet state it is missing. But the challenge might be to do it in a way where it can trust that information given the reason it is doing offline signing, is to maintain a wall between the online wallet and the signing keys.
However a problem we now have in ElectrumSV with offline signing is that it you cannot always do it with hardware wallets using their latest firmware. Ledger for example have updated their signing to require full input transactions to be provided with the incomplete one the user is asking the hardware wallet to sign. This means that we already need transference of state where the offline wallet can get prior data.
Verifying the recipient by name
One of the problems with hardware wallets is that they are limited to only being able to handle addresses. More complicated scripts that cannot be abbreviated to addresses are beyond their ability to present to users. As it is, expecting users to compare addresses to be sure they are signing the transaction they think they are signing, is not user friendly in any sense. But it is better than any current alternative, and can give users a way to ensure that their coins are not stolen. And this goes for any transaction signing, not just those done with hardware wallets.
In the future you should be able to use an approach like seeing the name of the contact you are paying to, and the identity details for that contact. Exactly like you see the name of whomever you are sending an email to, and also their email address. Any derived payment address or script should be irrelevant — perhaps viewable on request, but not necessary to even see.
Verifying payment to the recipient
I’ll give two ways this could be done. Any eventual solution might be similar, resemble one of these, or even a combination of both.
On-chain identity
If a parameter that requires a key is defined in terms of an identity public key and a method of derivation, then each application participating in the construction of the completed transaction should have a way to obtain the identity packet for the given identity public key. Within this there might be a root payment key, and from that the method of derivation can be applied to get the final payment key.
The signing application then has a way to know it is paying to the identity it is told it is paying to.
Identity oracles
If all applications have a set of accepted identity oracles, then another approach is for the payment key to be given but for it’s ownership by the identity of the receiver to be shown in a signed proof from the identity oracle. I believe Tokenized are doing it in a way like this.
Prior art
There are two different versions of this that I know of, both with more limited potential for applications. I’ll list each here.
Electrum Core format
This is the format ElectrumSV inherited and decided not to try and extend when we moved to multi-signature.
Partially signed bitcoin transactions
This is a JSON format that was adopted in Bitcoin Core and is now incorporated in Electrum Core as well. There’s a presentation here from before it was more widely adopted.
The Bitcoin Core BIP standard is also linked here.
Summing up
This document does not even begin to enumerate the full scope of all the different use cases.
- Offline signing.
- Hardware wallet signing.
- Multi-signature.
- Split control over wallet state in both desktop and mobile.
- Negotiation over transaction contents for P2P payments.
It might be that it is best to concentrate on the now cases, and leave later extensions to cover the future cases.
External discussion
You can discuss this on PowPing: