|
@@ -1,386 +0,0 @@
|
|
|
-MMGen = Multi-Mode GENerator
|
|
|
-============================
|
|
|
-##### a Bitcoin cold storage solution for the command line
|
|
|
-
|
|
|
-Getting Started with MMGen
|
|
|
---------------------------
|
|
|
-
|
|
|
-#### 1. Generate a wallet (offline computer):
|
|
|
-
|
|
|
-On your offline computer, generate a wallet with a random seed:
|
|
|
-
|
|
|
- $ mmgen-walletgen
|
|
|
- ...
|
|
|
- Wallet saved to file '89ABCDEF-76543210[256,3].mmdat'
|
|
|
-
|
|
|
-"89ABCDEF" is the Seed ID; "76543210" is the Key ID. These are randomly
|
|
|
-generated, so your IDs will of course be different than the fictitious ones used
|
|
|
-here.
|
|
|
-
|
|
|
-The Seed ID never changes and will be used to identify all keys/addresses
|
|
|
-generated by this seed. The Key ID changes when the wallet's password or hash
|
|
|
-preset are changed.
|
|
|
-
|
|
|
-"256" is the seed length; "3" is the scrypt hash preset. These values are
|
|
|
-configurable: type `mmgen-walletgen --help` for details.
|
|
|
-
|
|
|
-#### 2. Generate addresses (offline computer):
|
|
|
-
|
|
|
-Now generate ten addresses with your just-created wallet:
|
|
|
-
|
|
|
- $ mmgen-addrgen 89ABCDEF-76543210[256,3].mmdat 1-10
|
|
|
- ...
|
|
|
- Address data saved to file '89ABCDEF[1-10].addrs'
|
|
|
-
|
|
|
- $ cat '89ABCDEF[1-10].addrs'
|
|
|
- 89ABCDEF {
|
|
|
- 1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE
|
|
|
- 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc
|
|
|
- 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N
|
|
|
- 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
|
|
|
- 5 1PeI55vtp2bX2uKDkAAR2c6ekHNYe4Hcq7
|
|
|
- 6 1FEqfEsSILwXPfMvVvVuUovzTaaST62Mnf
|
|
|
- 7 1LTTzuhMqPLwQ4IGCwwugny6ZMtUQJSJ1
|
|
|
- 8 1F9495H8EJLb54wirgZkVgI47SP7M2RQWv
|
|
|
- 9 1JbrCyt7BdxRE9GX1N7GiEct8UnIjPmpYd
|
|
|
- 10 1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
|
|
|
- }
|
|
|
-
|
|
|
-Note that the address range, "1-10", is reflected in the resulting filename.
|
|
|
-MMGen addresses are identified by their seed ID and index number, separated by a
|
|
|
-colon. In this example, "89ABCDEF:1" is the MMGen equivalent of Bitcoin address
|
|
|
-16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE, "89ABCDEF:2" the equivalent of
|
|
|
-1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc, and so forth.
|
|
|
-
|
|
|
-Let's say you've decided to transfer some BTC into the first four addresses
|
|
|
-above. Your first step, then, will be to import these addresses into the
|
|
|
-tracking wallet on your online machine so their balances will be visible.
|
|
|
-For convenient identification, you've chosen to provide the addresses with the
|
|
|
-labels "Donations", "Storage 1", "Storage 2" and "Storage 3".
|
|
|
-
|
|
|
-Make a copy of the file:
|
|
|
-
|
|
|
- $ cp '89ABCDEF[1-10].addrs' my_addrs
|
|
|
-
|
|
|
-and edit the copy using your favorite text editor to look like this:
|
|
|
-
|
|
|
- $ cat my_addrs
|
|
|
- # My first MMGen addresses
|
|
|
- 89ABCDEF {
|
|
|
- 1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations
|
|
|
- 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
|
|
- 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
|
|
- 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
|
|
- }
|
|
|
-
|
|
|
-Note the comment beginning with a '#' symbol. Comments may be placed at the
|
|
|
-ends of lines as well. Note also that rows in the list may be arranged in any
|
|
|
-order: addresses need not be consecutive.
|
|
|
-
|
|
|
-Copy this file onto a USB stick and transfer it to your online computer.
|
|
|
-
|
|
|
-#### 3. Import addresses (online computer):
|
|
|
-
|
|
|
-On your online computer, start bitcoind and import the addresses into the
|
|
|
-tracking wallet with the command:
|
|
|
-
|
|
|
- $ mmgen-addrimport my_addrs
|
|
|
-
|
|
|
-These addresses will now be tracked by bitcoind. Any BTC transferred to them
|
|
|
-will show up in your listing of unspent outputs.
|
|
|
-
|
|
|
-If you have any existing addresses with balances, you'll want to track them too.
|
|
|
-Make a plain list of these addresses, one address per line, and import the list
|
|
|
-into the tracking wallet using `mmgen-addrimport -l`.
|
|
|
-
|
|
|
- $ mmgen-addrimport -l my_existing_addrs_with_balances
|
|
|
-
|
|
|
-Since the importing process is slow, you may want to do it in stages, a few
|
|
|
-addresses at a time.
|
|
|
-
|
|
|
-Continue in this fashion until you've imported all addresses with balances into
|
|
|
-your tracking wallet.
|
|
|
-
|
|
|
-#### 4. Create a transaction (online computer):
|
|
|
-
|
|
|
-Now that your existing addresses are imported, you're ready to create a test
|
|
|
-transaction using the `mmgen-txcreate` command. Note that transactions are
|
|
|
-harmless until they're signed and broadcast to the network, so feel free to
|
|
|
-experiment with different transactions using different combinations of inputs
|
|
|
-and outputs.
|
|
|
-
|
|
|
-First of all you'll want to examine your balances:
|
|
|
-
|
|
|
- $ mmgen-txcreate -i
|
|
|
-
|
|
|
-A list of all your unspent outputs will appear, along with a menu allowing you
|
|
|
-to sort the outputs by four criteria: transaction ID, address, amount and
|
|
|
-transaction age. Your overall balance in BTC appears at the top of the screen.
|
|
|
-The list may be viewed in a pager or printed to file. If you have ten unspent
|
|
|
-outputs, your display will look something like this:
|
|
|
-
|
|
|
- UNSPENT OUTPUTS (sort order: reverse amount) Total BTC: 39.72
|
|
|
- Num TX id Vout Address Amount (BTC) Age(days)
|
|
|
- 1) 04f97185... 2 1F93Znz8PI5Pnvv8ZAJsb74EzKpmRMLFbk 10 320
|
|
|
- 2) dd900544... 1 194Fceqx86jqIWumphUmfVyFMjAAbMLcSE 9.9287435 7
|
|
|
- 3) 7ec81a8f... 0 1FhIkRabPSZhhUsA6qvukmfK4T4PZLbC4M 7.26 17
|
|
|
- 4) 64094b55... 0 16JSUJdGMbxUBEQatAR5sGE89tbSIsLHqg 3.15 140
|
|
|
- 5) fd687c65... 1 1QKAtU66aUntCBx9m6TfEIf3gQuCNWCVDY 3.15 140
|
|
|
- 6) 9a8f20e2... 1 1FMNDFz1yUywjJSprjvYY9t1yxkE8GGIwT 3.15 140
|
|
|
- 7) 03a7c51a... 3 1svxnSdKVIcMs6qWYA7qLzA29orXbzXUm 1.6382466 54
|
|
|
- 8) 9955f06c... 2 18nWPLQGUzI7X1Rcm4zmVV6Z3xhokdYx9G 1.2 27
|
|
|
- 9) 8a4ab4f5... 0 13S9HNu7PQn1aJ4qILfhqRSakXwvSTnbwJ 0.23033 3
|
|
|
- 10) 5bfe5621... 1 1FV1Lhs6Dnc9gMxjJTo6h4nTeIjJbQ1PgV 0.01 42
|
|
|
-
|
|
|
- Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [M]mgen addr
|
|
|
- View options: [g]roup, show [m]mgen addr
|
|
|
- (Type 'q' to quit sorting, 'p' to print to file, 'v' to view in pager):
|
|
|
-
|
|
|
-Now let's actually create a transaction. Let's say you've decided to gradually
|
|
|
-begin moving your 39.72 BTC balance into your shiny new MMGen wallet with seed
|
|
|
-ID 89ABCDEF.
|
|
|
-
|
|
|
-Before moving any funds into your MMGen wallet, you should back it up in several
|
|
|
-places and possibly on several media too: paper, flash memory or CD-ROM, for
|
|
|
-example. Of course the wallet should have a passphrase. Otherwise, anyone who
|
|
|
-gains physical access to one of your backups can easily steal your coins.
|
|
|
-
|
|
|
-Recall that there's no limit to the number of addresses you can generate with
|
|
|
-your seed. You've wisely determined that having many addresses with relatively
|
|
|
-small balances is a Good Idea. So you've decided to begin by breaking up the
|
|
|
-address with the largest balance, 10 BTC, into three roughly equal parts,
|
|
|
-sending it to the addresses labeled "Storage 1", "Storage 2" and "Storage 3"
|
|
|
-(89ABCDEF:2, 89ABCDEF:3 and 89ABCDEF:4).
|
|
|
-
|
|
|
-To refresh your memory, here are the three addresses in question:
|
|
|
-
|
|
|
- $ cat my.addrs
|
|
|
- # My first MMGen addresses
|
|
|
- 89ABCDEF {
|
|
|
- 1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations
|
|
|
- 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
|
|
- 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
|
|
- 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
|
|
- }
|
|
|
-
|
|
|
-The following command will send 3.3 BTC to the first two addresses and the
|
|
|
-remainder of the transaction's 10 BTC input to the third, subtracting a default
|
|
|
-transaction fee of 0.001 BTC:
|
|
|
-
|
|
|
- $ mmgen-txcreate 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,3.3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N,3.3 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
|
|
|
-
|
|
|
-The bare address with no amount is the **change address**. MMGen will compute
|
|
|
-the change amount (3.399 BTC in this case) automatically.
|
|
|
-
|
|
|
-Alternatively, and more conveniently, you can list your three addresses in MMGen
|
|
|
-format:
|
|
|
-
|
|
|
- $ mmgen-txcreate 89ABCDEF:2,3.3 89ABCDEF:3,3.3 89ABCDEF:4
|
|
|
-
|
|
|
-Now hit ENTER, choose the transaction's input from the list (10 BTC, address
|
|
|
-1F9495H8EJL..., txid 04f97185...,2), and confirm. If all goes well,
|
|
|
-`mmgen-txcreate` will exit with the message:
|
|
|
-
|
|
|
- Transaction data saved to file 'tx_1EDCBA[6.6].raw'
|
|
|
-
|
|
|
-Note that the transaction has a unique ID, and the non-change output amount, 6.6
|
|
|
-BTC, is conveniently included in the filename.
|
|
|
-
|
|
|
-#### 5. Sign the transaction (offline computer):
|
|
|
-
|
|
|
-Now copy the raw transaction you've just created to a USB stick and transfer it
|
|
|
-to your offline computer for signing. You need to find the key for your
|
|
|
-transaction's one input address, 1F9495H8EJL.... If the key in question is in a
|
|
|
-bitcoin 'wallet.dat', there's an included command (a modified version of the
|
|
|
-well-known pywallet utility) that will conveniently extract it for you:
|
|
|
-
|
|
|
- $ mmgen-pywallet -k wallet.dat
|
|
|
- ...
|
|
|
- wallet.dat secret keys saved to file wd_EDBC983A[102].keys
|
|
|
-
|
|
|
-You've in fact extracted a list of all of the wallet's 102 keys here, but that's
|
|
|
-not a problem, since the unused keys will be ignored. Now go ahead and sign the
|
|
|
-transaction using this list of keys.
|
|
|
-
|
|
|
- $ mmgen-txsign -k wd_EDBC983A[102].keys tx_1EDCBA[6.6].raw
|
|
|
- ...
|
|
|
- Signed transaction saved to file tx_1EDCBA[6.6].sig
|
|
|
-
|
|
|
-Note that mmgen-pywallet's output is just a flat list of keys. So if you have
|
|
|
-several Bitcoin wallets with balances, you can just dump all their keys and
|
|
|
-merge them into a single file which you can use to sign all future transactions
|
|
|
-with wallet.dat inputs:
|
|
|
-
|
|
|
- $ mmgen-pywallet -k wallet1.dat
|
|
|
- $ mmgen-pywallet -k wallet2.dat
|
|
|
- $ mmgen-pywallet -k wallet3.dat
|
|
|
- $ cat wd_*.keys > all_keys
|
|
|
-
|
|
|
-For your future transactions with MMGen address inputs, you'll list the MMGen
|
|
|
-seed source (wallet, mnemonic or seed file) on the command line after the
|
|
|
-transaction file, and the required keys will be generated automatically, as in
|
|
|
-this example:
|
|
|
-
|
|
|
- $ mmgen-txsign tx_9D2C3A[1.23].raw B73B58EA-125FB230[256,3].mmdat
|
|
|
-
|
|
|
-Transactions may contain a mixture of MMGen and non-MMGen inputs as well as
|
|
|
-inputs with more than one MMGen seed ID. Just provide a seed source for each
|
|
|
-seed ID on the command line.
|
|
|
-
|
|
|
-Eventually, when you've placed all your BTC under MMGen control, you'll never
|
|
|
-have deal with keys directly again, because MMGen generates all keys on the fly
|
|
|
-using the seed.
|
|
|
-
|
|
|
-#### 6. Send the transaction (online computer):
|
|
|
-
|
|
|
-Now you're ready for the final step: broadcasting the transaction to the network.
|
|
|
-Copy the `tx_*.sig` file to your online computer, start bitcoind, if it's not
|
|
|
-running, and execute the command:
|
|
|
-
|
|
|
- $ mmgen-txsend tx_1EDCBA[6.6].sig
|
|
|
-
|
|
|
-Like all mmgen commands, `mmgen-txsend` is interactive, so you'll be asked for
|
|
|
-confirmation before the transaction is actually sent.
|
|
|
-
|
|
|
-Once the transaction's confirmed by the network, your three new MMGen addresses
|
|
|
-will appear on the listing of `mmgen-txcreate -i`. Type 'm' at the menu to
|
|
|
-see them displayed in MMGen format.
|
|
|
-
|
|
|
-Congratulations! You've performed your first MMGen transaction and placed your
|
|
|
-first funds under MMGen control.
|
|
|
-
|
|
|
-### Additional Features
|
|
|
-
|
|
|
-#### Using the mnemonic and seed features:
|
|
|
-
|
|
|
-Continuing our example above, generate a mnemonic from the wallet:
|
|
|
-
|
|
|
- $ mmgen-walletchk -m '89ABCDEF-76543210[256,3].mmdat'
|
|
|
- ...
|
|
|
- Mnemonic data saved to file '89ABCDEF.mmwords'
|
|
|
-
|
|
|
- $ cat 89ABCDEF.mmwords
|
|
|
- pleasure tumble spider laughter many stumble secret bother after search
|
|
|
- float absent path strong curtain savior worst suspend bright touch away
|
|
|
- dirty measure thorn
|
|
|
-
|
|
|
-Note: a 128- or 192-bit seed will generate a shorter mnemonic of 12 or 18
|
|
|
-words. You may generate a wallet with these seed lengths using the `'-l'`
|
|
|
-option to `mmgen-walletgen`.
|
|
|
-
|
|
|
-Though some consider 128 bits of entropy to provide adequate security for the
|
|
|
-foreseeable future, you should stick to the default 256-bit seed length if
|
|
|
-you're not planning to use the mnemonic feature.
|
|
|
-
|
|
|
-NOTE: MMGen mnemonics are generated from the Electrum wordlist, but using
|
|
|
-ordinary base conversion instead of Electrum's more complicated algorithm.
|
|
|
-
|
|
|
-Generate addresses 1-11 of seed 89ABCDEF using the mnemonic instead of the
|
|
|
-wallet:
|
|
|
-
|
|
|
- $ mmgen-addrgen 89ABCDEF.mmwords 1-11
|
|
|
- ...
|
|
|
- Address data saved to file '89ABCDEF[1-11].addrs'
|
|
|
-
|
|
|
-Compare the first ten addresses with those earlier generated by the wallet.
|
|
|
-You'll see they're the same.
|
|
|
-
|
|
|
-Regenerate a lost wallet using the mnemonic:
|
|
|
-
|
|
|
- $ mmgen-walletgen 89ABCDEF.mmwords
|
|
|
- ...
|
|
|
- Wallet saved to file '89ABCDEF-01234567[256,3].mmdat'
|
|
|
-
|
|
|
-Note that the regenerated wallet has a different Key ID but of course the same
|
|
|
-Seed ID.
|
|
|
-
|
|
|
-Seed files bear the extension `.mmseed` and are listed on the command line the
|
|
|
-same way mnemonic files are.
|
|
|
-
|
|
|
-A seed file for a 256-bit seed looks like this:
|
|
|
-
|
|
|
- $ cat 8B7392ED.mmseed
|
|
|
- f4c84b C5ZT wWpT Jsoi wRVw 2dm9 Aftd WLb8 FggQ eC8h Szjd da9L
|
|
|
-
|
|
|
-And for a 128-bit seed:
|
|
|
-
|
|
|
- $ cat 8E0DFB78.mmseed
|
|
|
- 0fe02f XnyC NfPH piuW dQ2d nM47 VU
|
|
|
-
|
|
|
-As you can see, the latter file is short enough to be memorized. From the unix
|
|
|
-command line, you can test your memory using the seed's checksum ("0fe02f" in
|
|
|
-this example) as follows:
|
|
|
-
|
|
|
- $ echo -n XnyCNfPHpiuWdQ2dnM47VU | sha256sum | cut -c 1-6
|
|
|
- 0fe02f
|
|
|
-
|
|
|
-#### Mnemonics and seeds — additional information:
|
|
|
-
|
|
|
-With the `'-m'` or `'-s'` option, MMGen commands that take mnemonic and seed
|
|
|
-data may receive the data from a prompt instead of a file.
|
|
|
-
|
|
|
-MMGen commands that produce mnemonic and seed data may be forced to print it to
|
|
|
-standard output instead of file with the `'-S'` option. This feature has
|
|
|
-intentionally been made optional to safeguard against looking-over-the-shoulder,
|
|
|
-Van Eyck phreaking and other side-channel attacks. MMGen commands never print
|
|
|
-private data to the screen unless explicitly asked to.
|
|
|
-
|
|
|
-The output of any MMGen command may be written to a directory of your choice
|
|
|
-using the `'-d'` option. For example, on a Linux system you could use
|
|
|
-`'-d /dev/shm'` to write key and seed data to volatile memory instead of disk.
|
|
|
-This also has obvious security benefits, ensuring that no sensitive data
|
|
|
-remains on disk after your computer's been powered down.
|
|
|
-
|
|
|
-### Test suite:
|
|
|
-
|
|
|
-The test suite can be run from within the MMGen source directory. You might
|
|
|
-find the following tests to be of interest:
|
|
|
-
|
|
|
-#### Bitcoin module:
|
|
|
-
|
|
|
-> Show available tests:
|
|
|
-
|
|
|
- mmgen/tests/bitcoin.py
|
|
|
-
|
|
|
-> Compare 10 addresses generated by 'keyconv' with mmgen's internally-generated
|
|
|
-> ones:
|
|
|
-
|
|
|
- mmgen/tests/bitcoin.py keyconv_compare_randloop 10
|
|
|
-
|
|
|
-> Convert a string to base 58 and back:
|
|
|
-
|
|
|
- mmgen/tests/bitcoin.py strtob58 'a string'
|
|
|
-
|
|
|
-> Convert a hex number to base 58 and back:
|
|
|
-
|
|
|
- mmgen/tests/bitcoin.py hextob58 deadbeef
|
|
|
-
|
|
|
-> Perform 1000 hex -> base58 -> hex conversions, comparing results stringwise:
|
|
|
-
|
|
|
- mmgen/tests/bitcoin.py hextob58_pad_randloop 1000
|
|
|
-
|
|
|
-#### Mnemonic module:
|
|
|
-
|
|
|
-> Show available tests:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py
|
|
|
-
|
|
|
-> Generate a 12-word mnemonic from a random 128-bit seed:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py random128
|
|
|
-
|
|
|
->> or an 18-word mnemonic from a random 192-bit seed:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py random192
|
|
|
-
|
|
|
->> or a 24-word mnemonic from a random 256-bit seed:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py random256
|
|
|
-
|
|
|
-> Show statistics for the Electrum wordlist:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py electrum
|
|
|
-
|
|
|
-> Print the Electrum wordlist:
|
|
|
-
|
|
|
- mmgen/tests/mnemonic.py electrum_print
|