Stellar Multisig Transactions without a Multisig Account
A simple question was asked in the Stellar developers chat: “Can I make a transaction require multiple signatures without adding them as signers on my account?”. For instance, I want to send my friend Alice 100 XLM but I want Bob to explicitly approve it before it can be submitted. However I don’t want Bob to have to approve all my transactions, just that one.
The answer is “Yes”, and the secret to doing it is by combining two of Stellar’s features that some people don’t realize exists:
- You can include multiple operations per transaction. This means you can send a payment to Alice and a payment to Bob and neither payment will go through if the other one fails.
- Operations in a transaction can have a source account that’s different than the transaction source account. This is most often used for channels, but can also be used to group completely unrelated operations from different accounts into a single transaction. In order for the transaction to be valid it must satisfy the signature requirements for each source account.
With those two things in mind a solution reveals itself: we have to create a transaction with two operations, one where I’m the source account and one where Bob is the source account. This will require that I sign it and that Bob signs it in order for it to be successfully submitted.
There’s one small catch though — we don’t want Bob to have to make any changes to his account or Stellar balance in order to help us out with the signature. Thankfully Stellar has an operation called setOptions where none of the options are required, and leaving them all empty is essentially a no-op.
So let’s put it all together and see how it would look in code:
As you can see, we build a transaction like normal, except we have an extra operation in there where Bob is the source account. If Bob had not signed the transaction and we tried to submit it, that operation would fail with an op_bad_auth error and the entire transaction would fail.
We’ve done it! We’ve figured out how create a multisig transaction without using a multisig account. But what can we actually use this for in real life? One possibility is what I’ll call a “crypto receipt”. A merchant sends you their token with a memo that corresponds to an item you’ve purchased, and you sign and submit the transaction when you receive the item. Think of it as a delivery receipt, except recorded on the ledger for both parties to refer to in the event of a dispute.
Got any other ideas for how this could be used? Please share!