Ethereum multi-sig wallets Part II

Dave Appleton
hellogold

--

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

The main use of multi sig wallets is to protect funds. It is not so easy to set them up for calling functions. Possible but not easy. This is usually done in supporting javascript libraries. Unless you have the ability to install these you may be better advised to use a normal wallet to call functions on contracts. If you really have to do it from a multi-sig*, please read on.

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.

The problem

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

[
{
"constant": false,
"inputs": [
{
"name": "_required",
"type": "uint256"
}
],
"name": "changeRequirement",
"outputs": [],
"payable": false,
"type": "function"
}
]

We also paste the contract’s address into the required field: 0x905698Effe73365B186e75cC3DcC7EaE56BAbADa

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

{"nonce":"0x00","gasPrice":"0x0bdfd63e00","gasLimit":"0x53d9","to":"0x905698Effe73365B186e75cC3DcC7EaE56BAbADa","value":"0x00","data":"0xba51a6df0000000000000000000000000000000000000000000000000000000000000003","chainId":1}

Take the data value and save it to paste into the data field of your transaction using submitTransaction. You should end up with:

to: 0x905698Effe73365B186e75cC3DcC7EaE56BAbADa
value: 0
data: 0xba51a6df0000000000000000000000000000000000000000000000000000000000000003

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.

--

--

Dave Appleton
hellogold

HelloGold's blockchain lead and Senior Advisor at Akomba Labs; a technology anachronism who codes, teaches, mentors and consumes far too much caffeine.