If you have been dealing with crypto currencies for a while, you will have heard about “Multi-Sig Wallets” being used to safeguard ether or tokens held by an entity — often as the result of an ICO. They are used for several reasons, the foremost of these being
- To stop one person from running off with the loot
- To reduce key person risk in case one person is incapacitated or loses their keys.
So, you’ve just raised 10,000 Ether in an ICO, you’re thinking that it sounds like a good idea. Next you start trying to figure out what one is and how to use it.
When I first heard of multi-sig wallets I was puzzled and thought of a group of people sitting around a computer or mobile device waiting for their turn to key in a password. Hey we are the blockchain generation! It’s decentralised. Your multi-sig wallet is a smart contract living on the blockchain!
Each of the wallet’s users can be in a different location in different timezones. The weird bit is that they each have to use a normal wallet to talk to the multi-sig wallet.
We will go through the basics and then see examples of following these steps using the Parity Wallet. You can use almost any wallet but the Parity wallet is BIG and FRIENDLY which suits me for this tutorial. If you are having trouble and want to see some of the basics on another wallet tell me in the comments.
At its core, a multi-signature wallet needs
- A list of people who are allowed to do things
- Rules on how many of those people have to agree before it happens
- A way to receive ETHER
- A way to submit a request
- A way to agree to a request (and submit it if you are last)
- A way to re-submit the request if it fails
There are a load of nice to have as well, but that is enough to get started.
The first two rules have to be decided right at the beginning
Say we have Tom, Dick and Harry sharing their funds and they decide that any two if them can decide to spend some Ether, we would right at the beginning deploy a smart wallet with Tom, Dick and Harry as the owners and the number TWO as the requirement (we need TWO approvals). We can carry on using this wallet as long as we are happy with these conditions.
Once the multi-sig wallet has been deployed, Ether can be sent to it just like to any other Ethereum address.
Submitting a request
Every transaction in Ethereum consists of
- who it’s intended for (an Ethereum address)
- the amount of Ether (if any) it carries (in Wei*)
- special data
*1 Ether = 1,000,000,000,000,000,000 Wei
These values are not to be confused with things like gasLimit and gasPrice which user use to submit the transaction but are not part of the actual transaction.
example : To send 10 Ether to Alice,
to: 0x31EFd75bc0b5fbafc6015Bd50590f4fDab6a3F22 *
value : 10,000,000,000,000,000,000
*ok — I lied, that’s not Alice’s address, it’s mine. Contributions gratefully accepted 😐
If you want to call a function on a contract you need to add some data e.g. to call a function finalize() on a contract at address
0xf09bEda21EFd99bc7719E284696f4f8471d0286C you would send a transaction like this:
Don’t worry about how to find the data, I will give an example later.
Your multi-sig wallet will have a function on it with a name like
function submitTransaction(address destination, uint value, bytes data)So you have enough information to call this function once you have setup your wallet to talk to the multi-sig.
Once Tom has submitted, in his generosity
submitTransaction(0x31EFd75bc0....fDab6a3F22,1000000000,)he will get a message back from his wallet with a number or hash code which is the transactionID. Tom has to communicate this transactionID to Dick or Harry to get them to confirm it.
Confirming the transaction
When either Harry or Dick receive the transactionID from Tom, they should use the transactionID to review the transaction data, then they can confirm it by calling
function confirmTransaction(uint transactionId)In our case, with the required amount of signatories being set to two, that would cause the transaction to be sent.
If we had a higher number of signatures required, the person whose confirmation caused that requirement to be met would cause it to be executed.
What if it fails?
There are numerous reasons why you could fail to send the transaction. The most obvious is that you do not have enough Ether to send. The multi-sig wallet should give you the opportunity to retry the transaction.
Is that it?
No, of course it isn’t. If you had such a wallet you would have a load of administration things and “what-if’s” that need handling which I will address in part II of the article. For now, let’s see how this all works with just these functions. I will look at it using Parity for the moment :
Deploying the wallet
I downloaded the following multi-sig wallet: https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol
Next I booted up the Kovan Testnet. Let’s see how the selected contract helps us by deploying it from Parity’s web interface*. I am assuming that you have already downloaded the file from Github. Select develop from the contracts tab.
*Parity’s web interface is at at http://127.0.0.1:8180
Next click “import” and import the contract file into Parity. The contract will be compiled automatically. Remember to save it.
Now click on the “Deploy” button.
Don’t be alarmed by the warning. Just enter a name for the wallet and select the account to launch it from.
Next you will be asked to supply the signees.
Nobody is included by default, not even the person launching the contract .
Click on the “+” sign to add signees (owners). Note that once you have entered the required number of signees and, of course, enough actual signees, the warning bar will disappear.
Note : The person deploying the contract is not automatically a signatory
Now click on “Create” and, once you have signed the transaction, your wallet will be ready for action.
You can look at the properties of the wallet — check who the owners are, how many signatures are required etc. from the properties page of the contract. You can also send Ether to the wallet. Any Ether sent will be reflected at the top of the wallet :
Proposing a transaction
Tom, Dick and Harry need to be watching the multi-sig contract. In order for this to happen, the person who generated the contract must share
- The Address of the contract
- The ABI (Application Binary Interface)
You can find both of these by inspecting the deployed contract on the machine that deployed it.
Once you are watching the contract you can click on the “execute” icon to execute the contract’s functions. Select
Enter (or select from your address book) the destination and value. If you are sending Ether, leave the data field empty (
Sign and submit the transaction. The contract will now show the result in as two events, a submission and a single confirmation:
Confirming the transaction…
Tom tells Dick that he has submitted a transaction to send 1.2 Eth to the Test Address and needs it confirmed. Dick, not trusting Tom an inch checks the contract. He sees that there is ONE pending transaction :
Anyway, Dick can also see the events so he knows it is Transaction Id
0 so he checks the transaction:
Satisfied, Dick confirms and the transaction (id=
And the transaction will be confirmed and the Ether sent.
Hang on! The transaction was confirmed but the execution failed! Why? A quick check (see above) reveals that the contract does not have enough Ether in to to pay “test Address” his 1.2 Ether. Sending more Ether to the contract should solve that…
Somebody needs to ask the wallet to try again. It can be any of the signatories.
The person holding the “test Address” account will now see their funds arrive:
And Tom, Dick and Harry will see the success in the event list of the contract:
In part TWO I will look at some of the administrative functions of the contract. Meanwhile :
You can find the ABI and address of my sample wallet (deployed on the Kovan test network) here on github gists
If you found this useful in helping you safeguard your thousands of Ether, why not send a small donation to “Alice” at