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.
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 .
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
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
doug. Or make up your own names.
Or use numbers. Whatever you want. Normally this would be done by different people on different
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
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
You may optionally send it to ledger sim, and the coins will be spent.