Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

158 lines (109 sloc) 5.2 KB

Multisig Wallet

This is demonstration of an M of N wallet, where there are N private keys and it takes signatures from M of the N participants to release the funds. See bitcoin’s version.

Requirements

Python version 3.7 is required. See https://www.python.org/downloads/ or use a package manager for your OS to install it. On Mac OS X, consider brew.

Set up

First, create a virtualenv. There are many ways to do this. Here is one.

$ python3 -m venv env
$ ln -s env/bin/activate
$ source ./activate
$ pip install -r requirements.txt
$ pip install -e .

Run ledger-sim

In a new terminal window, start ledger-sim. The multisig wallet will connect to this instance.

$ cd walllets
$ source ./activate
$ ledger-sim

Now go back to the original terminal window.

Create the N private wallets

For our example, we will use M=2, N=4.

Do the following:

  $ signer
  wallet name> anna
  public hd key is 00000001000000000000000000b09562cb56fa84e0040cc53213af65b4d2e8e2eef1327694cc8a4c766c76a9de160607f5bd0b4111a55c63dcaa62050653b4c3e76f767bf3b93cb7c6fffbc43ff5c65b2252cf5a6ab651d2b4a38fa839
enter partially-signed transaction hex>

Note that if the wallet does not exist, it’s created and written to private.anna.json. Subsequent attempts to start using wallet name anna will reload this wallet.

The hd key is generated using OS level randomness (os.urandom), so the key generated by your machine will very probably be different.

When prompted for a partially-signed transaction, enter a blank link to exit.

Now create three more wallets with names bob, carry and doug. Or make up your own names. Or use numbers. Whatever you want. Normally this would be done by different people on different machines.

Each wallet prints the hierarchical deterministic (hd) wallet public key. You will need these values to create the multisig wallet.

Create the multisig wallet

A central facilitator collects the public hd keys from the N participants, and creates the multisig wallet. Do the following:

$ multisig_wallet
Creating M of N wallet
Enter a public hd key> 

Now enter the four hd keys you created above. Obviously they’re too long to accurately retype, so use copy and paste.

Enter a blank line after the fourth key. Then set M to 2.

Now you’ll see the main menu. Subsequent runs will notice the existence of the file multisig-wallet.json and skip the creation step. Exit using choice q and run it again to check.

Generate an address

Try this yourself.

$ multisig_wallet
Choose:
1. Generate an address
2. Spend a coin
3. Sync
q. Quit
> 1
Choose index (integer >= 0)> 0
address #0 is 51dad6c07c29233116bfe638f4c9c7d6f3fbe410c9b6815c9d0b6e2f8f97698b
Generate coins with this address? (y/n)> y
1 new block loaded
Coin count: 2
06493e152e6c264583049fc6c2176ccd361b157a7d7d70c87452a87305308d81    1000000000     0
4cde9e0d251f5667edde8e0714c99f2f9cbe257088b49f7919d37ee629fc87c6             0     0

Obviously, the address you generate will not match the above.

You may also optionally generate a sample coin locked via the generated address by simulating farming a new block. You can use it in step 2.

Spend the coin

Generate the Unfinished Spend

Choose option 2. The destination address is preselected, as this is demonstration is more about the process of generating and aggregating the signatures rather than creating smart destinations.

Copy and paste a sample coin. You can enter multiple coins as inputs, but for now, try just one coin by entering a blank line for the second coin.

You will see a huge blob of hex. This is the unfinished spend.

Sign the Unfinished Spend

This hex blob must be sent to M different signers, who will each sign it.

Open another terminal window, and without exiting the multisig wallet, relaunch the signer program.

$ cd wallets
$ source ./activate
$ signer
wallet name> anna
public hd key is 00000001000000000000000000b09562cb56fa84e0040cc53213af65b4d2e8e2eef1327694cc8a4c766c76a9de160607f5bd0b4111a55c63dcaa62050653b4c3e76f767bf3b93cb7c6fffbc43ff5c65b2252cf5a6ab651d2b4a38fa839
enter partially-signed transaction hex>

Now copy and paste the large blob representing the unfinished spend and hit return.

Eventually the signing program should also display some information about exactly what it’s signing so the user can examine it for correctness before approving that it be signed. This step is currently skipped.

The signing program will analyze the blob and generate whatever signatures is can, one per line.

Copy the Signature to Wallet

The signer would then transmit the signature to the central coordinator. In this demo, that means copy and paste the signature. You will see a message similar to

coin cf55bad003a4894b4027901edac2137870ce6405f1aaff568d4521b1638e49a0 has 1 of 2 sigs

Now repeat the procedure with another wallet like bob. Once you copy and paste this signature, you will see another large blob called the “spend”. This is a finalized transaction that will correctly validate.

You may optionally send it to ledger sim, and the coins will be spent.

You can’t perform that action at this time.