Ethereum multi-sig wallets Part II
The tricky bits
We left off in part I having deployed a multi-sig wallet and successfully seen a transaction through to its conclusion with two signatures.
I did introduce one “what-if?” by making the transaction fail and showing how it could be re-attempted however there are a load of housekeeping functions in the contract as well so, for the sake of completeness, I will cover them here.
We will cover :
- Managing unsent transactions
- Calling functions on contracts
- Managing the signatories
- Other “nice to have” features
Managing unsent transactions
Ever had one of those facepalm moments when you realise that you have done something stupid? Like approved a transaction only to realise that it was sending ten times the amount of Ether as intended?
Some wallets may allow you to remove the transaction, the wallet that we are using simply permits you to revoke your signature.
function revokeConfirmation(uint transactionId)
Simply call this function with the transactionID that you have previously approved and your signature will be removed.
You cannot, of course, revoke a sent transaction, nor can you stop others from approving it.
Calling functions on contracts
This one may require a bit of wrapping your head around so let’s start by going a step beyond what we covered in Part I on sending Ether in a transaction.
If you recall, the information required to send any transaction is
to: <ethereum address>
value: <amount in wei>
data: <any additional data to send>
So far we have not used the data field because we have been sending Ether and sending Ether does not usually require any extra data.
If you are happy installing all the wallet’s support files life is easy — you will get a webpage that helps you generate the data. I am assuming you don’t so I will help you get that data using myEtherWallet.
If we want to call a contract’s function we need to tell the contract which function to call and provide any associated data. Ethereum uses what is called ABI encoding to create the data from the function name and parameters. You can read about it here. If you remember we used the ABI data to introduce the contract’s interface to our Parity wallet.
While you could encode the data by hand, you can also cheat by using myEtherWallet to encode the data for you.
Go to myEtherWallet.com and generate a wallet. You won’t actually use this wallet for much except getting the data. Copy the private key to a text file on your hard drive.
WARNING — do NOT do that with a live wallet.
Browse to https://www.myetherwallet.com/#contracts
Paste your contract’s ABI data into the box.
In our case we will call the changeRequirement function on our own contract. Since my demo was on Parity’s Kovan network we select the correct network.
function changeRequirement(uint _required)
We paste part of our wallet’s ABI Code — the ABI for changeRequirement
We also paste the contract’s address into the required field:
This address is not needed but it makes myEtherWallet happy.
Click “access”. Then select the function. You will see it knows what parameters to expect.
Enter the required information in the box(es) and click WRITE. You will be asked to provide a key to myEtherWallet. Paste the private key and unlock the wallet.
Leave this — we don’t need it. Click “Generate Transaction”
You will see that the Raw Transaction looks like this
Take the data value and save it to paste into the data field of your transaction using submitTransaction. You should end up with:
One day I will write a utility to help with this. Maybe.
Managing the signatories
Things don’t remain static for long. People drift away. Rules change. Pretty soon you are going to have to change either the number of signatories required to sign a transaction or the actual signatories themselves. Naturally any decent multi-sig wallet will have functions to handle this.
Obviously these functions need the approval of the other signatories and the selected wallet handles this by requiring you to make the wallet call the required function on itself using the method just shown. You need to use the method above to generate the data for the transactions as listed below but submit them as transactions to be sent to the wallet’s address:
Adding a new signatory
function addOwner(address owner)
Removing a signatory
function removeOwner(address owner)
Replacing a signatory
function replaceOwner(address owner, address newOwner)
Changing the number of signatories required
function changeRequirement(uint _required)
Note : both “
removing an owner” and “
changing the number of signatories required” will fail if, after the update, there are not enough signatories to satisfy the required number.
Other nice to have features
There are numerous nice to have features that help manage funds. Most of these regulate usage such as
- How many signatories are required to spend <X> Ether
- How frequently you can withdraw from the wallet
And various other functions. You will find several other multi-sig wallets but they all have similar base functions.