Guide: Vote proxy setup with seth

Note: In these instructions the private key of the cold wallet is temporarily copied to the disk of your computer, and it is your responsibility to delete the private key from the disk after performing the steps described below. Do not use these instructions if you don’t agree to this.

This guide will show how to set up the cold-hot wallet link on your personal voting contract (or vote proxy) without the use of To initiate the link, we will use seth, a simple ethereum client tool in the collection. To approve the link, approve MKR transfers, and lock up MKR, we will use MyEtherWallet (MEW). The reader needs either a Ledger Nano S or a paper wallet (as the cold wallet) and access to their MetaMask hot wallet. The following instructions work for both GNU/Linux and macOS.

Let’s get started!


  1. Configure geth
  2. Configure seth
  3. Configure cold wallet
  4. Initiate link
  5. Approve link
  6. Approve MKR transfer
  7. Lock MKR
  8. Clean up
  9. Conclusion

Configure geth

Install geth:

Configure seth

Install, which includes seth:

$ curl | sh

Remember to open a new terminal!

For this tutorial, we will work with the Kovan testnet:

$ export SETH_CHAIN=kovan

Configure cold wallet

Paper wallet

Here is an example of a paper wallet:

Create a keystore file with your private key:

$ geth account import <(echo <privateKey>)

By default, geth saves your keystore file stored in:

~/Library/Ethereum/keystore/<UTC……> — <yourPublicAddress>

For seth, let’s specify the location of the newly created keystore file:

$ export ETH_KEYSTORE=~/Library/Ethereum/keystore

Check your account(s):

$ seth ls

If everything is set up correctly, you should see all addresses supplied from your keystore directory and their respective balances displayed on the console. For example:

Important cleanup step

Since you won’t be using the private key again, you’ll need to delete it from your bash history. If you’re not using a bash shell, you’ll probably know how to delete the shell’s history.

To view your bash history:

$ history

Locate the line number that contains your private key and delete it:

$ history -d <insert number>

Ledger Nano S

Seth will scan for Ledger Nano S hardware wallets by default. When you use a sending address that belongs to the hardware wallet, seth will automatically use it for signing transactions. Note that it only looks for the first four addresses derived from your seed phrase.

Your Ledger Nano S will need to be in the following state:

  • Unlocked
  • Ethereum app downloaded
  • Ethereum app -> Settings -> Contract data -> Yes
  • Ethereum app -> Settings -> Browser support -> No
  • Ethereum app opened

Alright, back to the CLI. After your Ledger is set up, let’s check its first four accounts (and any other accounts from a populated keystore directory):

$ seth ls

If everything is set up correctly, you should see four addresses with their balances displayed on the console. If the command does not display anything, ensure that you have Browser support set to No. You will use one of these addresses as a variable, so be sure to copy one.

Initiate Link

Let’s initiate the link with the following arguments:

  • Hot Wallet Address
  • Gas price: 10 Gwei
  • Gas: 75000

Make sure you have enough kovan ethereum to cover gas costs. You can get kovan ETH here.

$ KPROXYFACTORY=0x3E08741A68c2d964d172793cD0Ad14292F658cd8
$ HOTADDRESS=< address of one of your MetaMask wallets >
$ GAS=75000
$ GASPRICE=10000000000
$ YOURADDRESS=< one of your cold addresses listed after seth ls >
$ seth send $KPROXYFACTORY “initiateLink(address)” $HOTADDRESS -G $GAS -P $GASPRICE -F $YOURADDRESS

If you set up a passphrase with your paper-imported wallet, you’ll need to type it in; if using a Ledger Nano address, you’ll need to confirm the transaction on the device.

Approve Link

To approve the link, we need to call approveLink(coldAddress) with our MetaMask wallet. To mitigate the risks in moving multiple private keys at once, we will use MEW to call this smart contract function; however, if preferred, the reader could still import the private keys into seth using the same process when pulling in the paper wallet.

Now, let’s head over to

Input the kovan proxy factory contract and approveLink( ) ABI as follows:

  • Contract address: 0x3E08741A68c2d964d172793cD0Ad14292F658cd8
  • ABI / JSON Interface:
[{“constant”:false,”inputs”: [{“name”:”cold”,”type”:”address”}],”name”:”approveLink”,”outputs”:[{“name”:”voteProxy”,”type”:”address”}],”payable”:false,”stateMutability”:”nonpayable”,”type”:”function”}]

Confirm you are on the kovan network (top right of screen), and click `Access` (bottom left).

Below, you’ll be able to select the approveLink( ) method.

After selection, include your cold wallet address in the parameter field, and submit the transaction with the default txn settings and your MetaMask hot wallet.

If the transaction went through without any reverts, great! Your link is now approved. Next, let’s lock up some MKR to be used in Executive/Governance voting.

Approve MKR Transfer

Before we can lock up MKR, we need to approve our ERC20 token (MKR) to be pulled from our paper wallet and pushed to the voting contract (DSCheif). We need to use seth again because it gives us access to your cold wallet. Feel free to change the allowance to a value more appropriate for your case.

  • Allowance: 100000 MKR
  • Gas price: 5 Gwei
  • Gas: 75000

The approve(address, uint256) method requires us to provide the amount argument in hex, denominated in WEI. Fortunately, seth has a number of simple conversion commands that will allow you to easily convert the amount in ether to wei and then to uint256:

$ seth — to-uint256 $(seth — to-wei 100000 ether)

You’ll also need the address of your vote proxy. This can be found via and under the internal transactions tab of your previous transaction (the one used to approve the cold-hot link).

Let’s set up and approve the Voting Proxy contract that you made in the previous step:

$ KVOTEPROXY=< fill in your vote proxy address >
$ KMKR=0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD
$ ALLOW=$(seth — to-uint256 $(seth — to-wei 100000 ether))
$ GAS=75000
$ GASPRICE=5000000000
$ YOURADDRESS=< your cold wallet address >
$ seth send $KMKR “approve(address,uint256)” $KVOTEPROXY $ALLOW -G $GAS -P $GASPRICE -F $YOURADDRESS

Lock MKR

To call the lock( ) method, we will use seth, though the method can be called from your hot wallet. The lock method will pull MKR from your cold wallet and push it to DSCheif. In this example, we will lock 5 MKR. Note that the MKR amount has to be represented in units of WEI.

$ KVOTEPROXY=< fill in your vote proxy address >
$ MKRAMOUNT=$(seth — to-uint256 $(seth — to-wei 5 ether))
$ GAS=150000
$ GASPRICE=5000000000
$ YOURADDRESS=< your cold wallet address >

If the transaction went through without any reverts, great! Time to cleanup your environment.

Clean up

Now that you initiated your cold-hot wallet link, you won’t need access to it for executive/governance voting; all can be achieved through your hot wallet. Just for precautions, if you forgot to delete your private key from your current shell history, below is a friendly reminder.

If you used a paper wallet, you’ll need to delete the keystore file under /Library/Ethereum/Keystore and bash history that contains your private key. If you’re not using a bash shell, you’ll probably know how to delete the shell’s history.

To view your bash history:

$ history

Locate the line number that contains your private key and delete it:

$ history -d <insert number>


In this guide, you imported a cold wallet (paper/Ledger) into seth, initiated and approved a cold-hot wallet link, approved an MKR transfer, and locked MKR in DSCheif. You can now participate in Executive/Governance Voting from the dai-gov dashboard!

If you wish to work with mainnet, you would need to go through the guide again with a couple different parameters — set the chain to mainnet, change the gas price to be consistent with the present average gas/txn, and use all mainnet addresses:

$ export SETH_CHAIN=ethlive
$ GAS=<insert competitive gas price>
$ PROXYFACTORY=0xa63E145309cadaa6A903a19993868Ef7E85058BE

When ready, head over to with your MetaMask hotwallet. At the top of the screen, you should see your MKR locked up and cold wallet linked.

For instructions on how to vote, and finding your way around the rest of the dashboard, please click here.

If you have any questions, we’re always here to help either on our subreddit or

Happy voting