Token Transfers with the Simple MultiSig Wallet

Alejandro Diaz
Mar 12, 2019 · 6 min read

In this article I’m going show how to use Christain Lundkvist’s MultiSig Wallet to transfer ERC-20 tokens.

Background

Over a year ago Christian Lundkvist came up with a very elegant, simple
idea for a rock-solid multisig wallet. (See Exploring Simpler Ethereum Multisig-Contracts.) But the thing that makes this wallet incredibly secure, namely its simple, spartan, no-frills design, is the same thing that makes it somewhat difficult to use. I wrote a front-end (user interface) for this contract to make it a bit more accessible to a wide audience. This front-end is on IPFS at: https://ipfs.io/ipns/simplemultisig.io/wallet

I’ve already written a Hand-Holding Guide to the Simple MultiSig Wallet, which shows how to use a wallet that transacts in Ether. In this article I’m going to use the Simple MultiSig Wallet to transfer ERC-20 tokens. Although there are a lot of manual steps, conceptually it’s easier than you might think!

The Setup

I’m going to assume that you already know how to create and deploy a multisig wallet. If you’re not sure, then check out the previous article, Hand-Holding Guide to the Simple MultiSig Wallet. For this example I set up a two-party multisig wallet, with me and my mom as owners… It’s really a convenience wallet, (which is to say I trust her), so I set the “threshold” to 1 so that either one of us can execute transactions. Here you can see how it looks when I view the wallet:

Funding the Wallet

Sending Dai to the wallet is like sending to any other address. You can use MyCrypto, or MetaMask, or whatever you normally use for sending tokens. Here I’m going to use MetaMask to transfer 1 Dai. (You can skip this section if you already know how to transfer tokens.) I start by copying the wallet address:

Next I click on the MetaMask icon, and then click on the menu icon towards the upper left of the MetaMask dialog. MetaMask immediately shows the tokens that are owned by my address:

When I select Dai, I’m presented with the Send-Tokens dialog shown below:

I paste the wallet address in the To field, enter the number of Dai that I want to send (1 Dai), and click Next. I then confirm the transaction, which is shown below:

Creating the Token-Transfer Hex Data

Wouldn’t you know it, but shortly after I deposited the Dai my mom called up and asked me to transfer 1 Dai out of the multisig wallet to her address. Here’s where things get tricky. The first thing we need is the ERC20 interface ABI. This is essentially a formal specification of functions that are included in the ERC20 standard. You can get this from the ethereum.org wiki. Copy the entire ABI from the open bracket to the close bracket:

Alternately, for your convenience I’ve provided the ERC20 ABI in a condensed format (I removed the new-lines). You can copy the text below:

[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"value","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

After copying the ERC20 ABI, head over to https://abi.hashex.org/:

Left-click once where it says “Enter you ABI…” and then paste the ERC20 ABI that you copied, and then click Parse:

Now from the drop-down selector I select the Transfer function and fill in the function parameters. For the To address I pasted my mom’s address. For the Value parameter I entered a 1 followed by 18 zeros. The reason for the 18 zeros is that Dai uses 18 decimals, just like Ether.

I copied the resulting hex string. Then I opened up the multisig wallet, clicked on the Transaction tab, selected the ‘Token Xfer Test’ wallet, and pasted the hex string it into the Data text-box. Note that I prefixed the hex data with ‘0x’:

Getting the Token Contract Address

We’ve filled in the Data text-box — that was the hard part. The next step is to head over to etherscan.io to look up the address of the Dai token contract:

Click on the entry for Dai, and then copy the address of the contract:

Going back to the Simple MultiSig Wallet page, I paste the Dai Token Contract address into the To field:

I set the Value field to zero, because we’re not sending any Ether in this transaction. But I modified the Gas Limit from 21,000 to 210,000 to pay for the execution of the Transfer function. In fact the token transfer transaction only needs about 140,000 gas, but it doesn’t hurt to provide a little extra, since it is refunded at the completion of a successful transaction. I set the Executor address to my own address, since I’m going to execute the transaction; but I also could have set it to ‘0x0’, since that allows anyone to execute the transaction.

Finally I can sign the transaction. Since only one signature is required, I can immediately execute the transaction:

When I click ‘Execute this transaction’ I’m presnted with a MetaMask dialog to confirm:

After confirming I only need to wait a few moments for the transaction to be mined on the Blockchain:

Clicking the View-transaction link opens an etherscan.io page where you can see that (after the transaction is confirmed) indeed 1 Dai was transferred to my mom’s address:

Summary

We’ve walked through all the steps to transfer Dai into and out of the Simple MultiSig Wallet. The same technique can be used to direct the Simple MultiSig contract to execute pretty much any function from any other contract. In this way the Simple MultiSig contract is incredibly powerful.

If this was your first time digging into contract ABI’s and such it might seem a bit daunting. But let it settle in. A part of the beauty of the Simple MultiSig Wallet is that it doesn’t hide any of its function. That is part of what makes it so versatile and so secure.

Alejandro Diaz

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade