|
@@ -1,261 +1,436 @@
|
|
|
-# mmgen = Multi-Mode GENerator
|
|
|
-## a Bitcoin cold storage solution for the command line
|
|
|
+MMGen = Multi-Mode GENerator
|
|
|
+============================
|
|
|
|
|
|
-NOTE: Parts of this README are now **out of date**. In particular, the
|
|
|
-new transaction scripts automate the process of offline signing, so that
|
|
|
-your private keys never touch the online machine. An updated README is
|
|
|
-on the way. For the time being, consult the `--help` option of the
|
|
|
-`mmgen-tx*` scripts.
|
|
|
+a Bitcoin cold storage solution for the command line
|
|
|
+----------------------------------------------------
|
|
|
|
|
|
-NOTE: For the time being, MMGen should be considered experimental software.
|
|
|
-Downloading and testing it out is easy, risk-free and encouraged.
|
|
|
-However, spending significant amounts of BTC into your mmgen-generated
|
|
|
-addresses is done at your own risk.
|
|
|
+### Description
|
|
|
|
|
|
-### Features:
|
|
|
+MMGen is implemented as a suite of lightweight Python command-line
|
|
|
+scripts that require only a bare minimum of system resources.
|
|
|
+The scripts function in tandem with a modified
|
|
|
+bitcoind running on an online computer and a standard
|
|
|
+bitcoind running offline to provide a robust solution for securely
|
|
|
+storing, tracking, spending and receiving your Bitcoins. "Non-MMGen"
|
|
|
+addresses can be tracked and spent as well, creating an easy migration
|
|
|
+path from other wallets.
|
|
|
|
|
|
-> As with all deterministic wallets, mmgen can generate an unlimited number
|
|
|
-> of address/key pairs from a single seed. You back up your wallet only once.
|
|
|
+The online bitcoin daemon is modified to support watch-only addresses,
|
|
|
+a feature soon to be included in the mainline Satoshi build.
|
|
|
+In the meantime, instructions are provided below for compiling the
|
|
|
+watch-only bitcoind, which under Linux is surprisingly easy.
|
|
|
|
|
|
-> With MMGen you can choose from four different ways to access your Bitcoins:
|
|
|
+MMGen uses the reference Satoshi daemon, rather than less-reliable
|
|
|
+third-party software, to do all the "heavy lifting" of tracking and
|
|
|
+signing transactions.
|
|
|
+And unlike other online/offline wallet solutions, the MMGen system is
|
|
|
+completely self-contained, relying on no external server to do its
|
|
|
+work; no third party will know which addresses you're tracking.
|
|
|
|
|
|
->> 1) an encrypted wallet (the AES 256 key is generated from your
|
|
|
->> password using the crack-resistant scrypt hash function. The
|
|
|
->> wallet's password and hash strength can be changed);
|
|
|
+Like all deterministic wallets, MMGen can generate a virtually
|
|
|
+unlimited number of address/key pairs from a single seed. Your wallet
|
|
|
+never changes, so you need back it up only once.
|
|
|
+Transactions are signed offline: your private keys never touch an
|
|
|
+online computer.
|
|
|
|
|
|
->> 2) a short, human-readable seed file (unencrypted);
|
|
|
+At the heart of the MMGen system is the seed, the "master key"
|
|
|
+providing access to all your Bitcoins. The seed can be stored in four
|
|
|
+different ways:
|
|
|
|
|
|
->> 3) an Electrum-like mnemonic of 12, 18 or 24 words; or
|
|
|
+> 1) as a wallet with a password
|
|
|
+> encrypted using the crack-resistant scrypt hash function.
|
|
|
+> Scrypt's parameters can be adjusted on the command line, making your
|
|
|
+> wallet's password virtually impossible to crack should it fall into the wrong
|
|
|
+> hands. The wallet is a tiny text file
|
|
|
+> suitable for printing or even writing out by hand;
|
|
|
|
|
|
->> 4) a brainwallet password (recommended for expert users only).
|
|
|
+> 2) as a seed file: a one-line base-58 representation of your
|
|
|
+> unencrypted seed plus a checksum;
|
|
|
|
|
|
-> Furthermore, these methods can all be combined. If you forget your
|
|
|
-> mnemonic, for example, you can regenerate it and your keys from a
|
|
|
-> stored wallet or seed. Correspondingly, a lost wallet or seed can be
|
|
|
-> recovered from the mnemonic.
|
|
|
+> 3) as an Electrum-like mnemonic of 12, 18 or 24 words; or
|
|
|
|
|
|
-> The wallet and seed are short, simple text files suitable for printing
|
|
|
-> or even writing out by hand. Built-in checksums are used to verify
|
|
|
-> they've been correctly copied. The base-58-encoded seed is short
|
|
|
-> enough to memorize, providing another brain storage alternative.
|
|
|
+> 4) as a brainwallet password (this option is recommended for expert
|
|
|
+> users only).
|
|
|
|
|
|
-> Implemented as a suite of lightweight Python scripts with a
|
|
|
-> command-line interface, MMGen demands practically no system resources.
|
|
|
-> Yet in tandem with a bitcoind enabled for watch-only addresses
|
|
|
-> (see below), it provides a complete solution for securely
|
|
|
-> storing Bitcoins offline and tracking and spending them online.
|
|
|
+The best part is that all these methods can be combined. If you
|
|
|
+forget your mnemonic, for example, you can regenerate it and your keys
|
|
|
+from the stored wallet or seed file. Correspondingly, a lost wallet can
|
|
|
+be regenerated from the mnemonic or seed or a lost seed from the wallet or
|
|
|
+mnemonic.
|
|
|
|
|
|
|
|
|
-### Instructions for Linux/Unix:
|
|
|
+### Download/Install
|
|
|
|
|
|
-### Download/Install:
|
|
|
-> Install required Python modules:
|
|
|
+> #### [Install on Microsoft Windows](doc/MMGenWindowsInstall.md)
|
|
|
|
|
|
- sudo pip install ecdsa scrypt pycrypto bitcoin-python
|
|
|
+> #### [Install on Debian/Ubuntu Linux](doc/MMGenLinuxInstall.md)
|
|
|
|
|
|
-> Install mmgen:
|
|
|
|
|
|
- git clone https://github.com/mmgen/mmgen.git
|
|
|
- cd mmgen; sudo ./setup.py install
|
|
|
+### Using MMGen
|
|
|
|
|
|
-> Install vanitygen (optional but recommended):
|
|
|
+#### Generate a wallet (offline computer):
|
|
|
|
|
|
- git clone https://github.com/samr7/vanitygen.git
|
|
|
- (build and put the 'keyconv' executable in your path)
|
|
|
+On your offline computer, generate a wallet with a random seed:
|
|
|
|
|
|
-### Getting Started:
|
|
|
-> On your offline computer:
|
|
|
+ $ mmgen-walletgen
|
|
|
+ ...
|
|
|
+ Wallet saved to file '89ABCDEF-76543210[256,3].mmdat'
|
|
|
|
|
|
-> Generate a wallet with a random seed:
|
|
|
+"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.
|
|
|
|
|
|
- $ mmgen-walletgen
|
|
|
- ...
|
|
|
- Wallet saved to file '89ABCDEF-76543210[256,3].dat'
|
|
|
+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.
|
|
|
|
|
|
-> "89ABCDEF" is the Seed ID; "76543210" is the Key ID. These are
|
|
|
-> randomly generated, so your IDs will naturally be different than the
|
|
|
-> fictitious ones used in this example.
|
|
|
+"256" is the seed length; "3" is the scrypt hash preset. These values
|
|
|
+are configurable: type `mmgen-walletgen --help` for details.
|
|
|
|
|
|
-> The Seed ID never changes and will be used to identify all
|
|
|
-> keys/addresses generated by this wallet. The Key ID changes when the
|
|
|
-> wallet's password or hash preset are changed.
|
|
|
+#### Generate addresses (offline computer):
|
|
|
|
|
|
-> "256" is the seed length; "3" is the scrypt hash preset. These are
|
|
|
-> configurable.
|
|
|
+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 plus 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.
|
|
|
|
|
|
-> Generate ten addresses with the wallet:
|
|
|
+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.
|
|
|
+You've chosen to provide the addresses with the labels "Donations",
|
|
|
+"Storage 1", "Storage 2" and "Storage 3" for convenient identification.
|
|
|
|
|
|
- $ mmgen-addrgen 89ABCDEF-76543210[256,3].dat 1-10
|
|
|
- ...
|
|
|
- Address data saved to file '89ABCDEF[1-10].addrs'
|
|
|
+Make a copy of the file:
|
|
|
|
|
|
+ $ cp '89ABCDEF[1-10].addrs' my_addrs_for_import
|
|
|
|
|
|
-> Note that the address range, "1-10", is included in the resulting filename.
|
|
|
+and edit the copy using your favorite text editor. The result will
|
|
|
+look something like this:
|
|
|
|
|
|
- $ 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
|
|
|
- }
|
|
|
+ $ cat my_addrs_for_import
|
|
|
+ 89ABCDEF {
|
|
|
+ 1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations
|
|
|
+ 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
|
|
+ 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
|
|
+ 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
|
|
+ }
|
|
|
|
|
|
+Note that rows in the list may be arranged in any order; addresses
|
|
|
+need not be consecutive.
|
|
|
|
|
|
-> To store your Bitcoins, spend them into these addresses from whatever
|
|
|
-> wallets/software you're currently using. If you have lots of BTC,
|
|
|
-> generate many addresses so that each address will have only a
|
|
|
-> relatively small balance.
|
|
|
+Copy this file onto a USB stick and transfer it to your online
|
|
|
+computer.
|
|
|
|
|
|
-### Spending your stored coins:
|
|
|
-> Take address 1 out of cold storage by generating a key for it:
|
|
|
+#### Import addresses (online computer):
|
|
|
|
|
|
- $ mmgen-keygen 89ABCDEF-76543210[256,3].dat 1
|
|
|
- ...
|
|
|
- Key data saved to file '89ABCDEF[1].akeys'
|
|
|
+On your online computer, start bitcoind and import the addresses into
|
|
|
+the tracking wallet:
|
|
|
|
|
|
- $ cat 89ABCDEF[1].akeys
|
|
|
- 89ABCDEF {
|
|
|
- 1 sec: 5JCAfK1pjRoJgmpmd2HEMNwHxAzprGIXeQt8dz5qt3iLvU2KCbS
|
|
|
- addr: 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE
|
|
|
- }
|
|
|
+ $ mmgen-addrimport my_addrs_for_import
|
|
|
|
|
|
-> Save the .akeys file to a USB stick and transfer it to your online computer.
|
|
|
+These addresses are now being "tracked". Any BTC transferred
|
|
|
+to them will show up in our listing of unspent outputs.
|
|
|
|
|
|
-> On your online computer, import the secret key into a running bitcoind
|
|
|
-> or bitcoin-qt:
|
|
|
+You'll want to track your existing addresses with balances too.
|
|
|
+Make a plain list of these addresses, one address per line, and import
|
|
|
+the list into the tracking wallet using the same command
|
|
|
+with the `'-l'` option:
|
|
|
|
|
|
- $ bitcoind importprivkey 5JCAfK1pjRoJgmpmd2HEMNwHxAzprGIXeQt8dz5qt3iLvU2KCbS
|
|
|
+ $ mmgen-addrimport -l my_existing_addrs_with_balances
|
|
|
|
|
|
-> You're done! This address' balance can now be spent.
|
|
|
+Since the importing process is slow, you may want to do it in stages,
|
|
|
+a few addresses at a time.
|
|
|
|
|
|
-> OPTIONAL: To track balances without exposing secret keys on your
|
|
|
-> online computer, download and compile sipa's bitcoind patched for
|
|
|
-> watch-only addresses:
|
|
|
+For your convenience, comments beginning with a '#' symbol may be
|
|
|
+included in address lists.
|
|
|
+Continue in this fashion until you've imported all addresses with
|
|
|
+balances into your tracking wallet.
|
|
|
|
|
|
- $ git clone https://github.com/sipa/bitcoin
|
|
|
- $ git branch mywatchonly remotes/origin/watchonly
|
|
|
- $ git checkout mywatchonly
|
|
|
- (build, install)
|
|
|
- (You may have to install libboost-all-dev for the build to succeed)
|
|
|
+#### 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 probably 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 spending your 39.72 BTC balance into your shiny new
|
|
|
+MMGen wallet with seed ID 89ABCDEF.
|
|
|
|
|
|
-> With your newly-compiled bitcoind running, import the addresses from
|
|
|
-> '89ABCDEF[1-10].addrs' to track their balances:
|
|
|
+Before doing anything else, you should back up your MMGen wallet 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 control of one of
|
|
|
+your backups can easily steal your coins.
|
|
|
|
|
|
- $ bitcoind importaddress 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE
|
|
|
- $ bitcoind importaddress 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc
|
|
|
- $ ...
|
|
|
+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.
|
|
|
+You've decided to begin by breaking up your
|
|
|
+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:1, 89ABCDEF:2 and 89ABCDEF:3).
|
|
|
|
|
|
-### Using the mnemonic and seed features:
|
|
|
+To refresh our memory, here are the three addresses in question:
|
|
|
|
|
|
-> Continuing our example above,
|
|
|
+ 89ABCDEF {
|
|
|
+ 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
|
|
+ 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
|
|
+ 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
|
|
+ }
|
|
|
|
|
|
-> Generate a mnemonic from the wallet:
|
|
|
+The following command will send 3.3 BTC to the first two addresses and
|
|
|
+the remainder of the transaction's inputs to the third, subtracting a
|
|
|
+default transaction fee of 0.001 BTC:
|
|
|
|
|
|
- $ mmgen-walletchk -m '89ABCDEF-76543210[256,3].dat'
|
|
|
- ...
|
|
|
- Mnemonic data saved to file '89ABCDEF.words'
|
|
|
+ $ mmgen-txcreate 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,3.3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N,3.3 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
|
|
|
|
|
|
- $ cat 89ABCDEF.words
|
|
|
- pleasure tumble spider laughter many stumble secret bother
|
|
|
- after search float absent path strong curtain savior
|
|
|
- worst suspend bright touch away dirty measure thorn
|
|
|
+The third address has the amount left out, making it a **change
|
|
|
+address**.
|
|
|
+MMGen will compute the change amount (3.399 BTC in this case) automatically.
|
|
|
|
|
|
-> Note: a 128- or 192-bit seed will generate a shorter mnemonic of 12 or
|
|
|
-> 18 words. You may generate a wallet with a these seed lengths by
|
|
|
-> using the `-l` option of `mmgen-walletgen`. Whether you consider
|
|
|
-> 128 bits of entropy enough is your call. It's probably adequate for
|
|
|
-> the foreseeable future.
|
|
|
+Alternatively, and more conveniently, you can write the
|
|
|
+addresses in MMGen format:
|
|
|
|
|
|
-> Generate addresses 1-11 using the mnemonic instead of the wallet:
|
|
|
+ $ mmgen-txcreate -a addrs 89ABCDEF:2,3.3 89ABCDEF:3,3.3 89ABCDEF:4
|
|
|
|
|
|
- $ mmgen-addrgen -m 89ABCDEF.words 1-11
|
|
|
- ...
|
|
|
- Address data saved to file '89ABCDEF[1-11].addrs'
|
|
|
+'addrs' is an MMGen address file containing the requested output
|
|
|
+addresses. Any unneeded addresses in the file will be ignored.
|
|
|
|
|
|
-> Compare the first ten addresses with those earlier generated from the
|
|
|
-> wallet. You'll see they're the same.
|
|
|
+Now hit ENTER, choose the
|
|
|
+transaction's input from the list (10 BTC, address
|
|
|
+1F9495H8EJLb54wirgZkVgI47SP7M2RQWv, txid 04f97185...,2),
|
|
|
+and confirm.
|
|
|
+If all goes well, the command will exit with a message like this:
|
|
|
|
|
|
-> Recover a lost wallet using the mnemonic:
|
|
|
+ Transaction data saved to file 'tx_1EDCBA[6.6].raw'
|
|
|
|
|
|
- $ mmgen-walletgen -m 89ABCDEF.words
|
|
|
- ...
|
|
|
- Wallet saved to file '89ABCDEF-01234567[256,3].dat'
|
|
|
+Note that the transaction has a unique ID, and the non-change output
|
|
|
+amount, 6.6 BTC, is conveniently included in the filename.
|
|
|
|
|
|
-> Note that the regenerated wallet has a different Key ID but
|
|
|
-> of course the same Seed ID.
|
|
|
+#### Sign the transaction (offline computer):
|
|
|
|
|
|
-> Seeds are generated and input the same way as mnemonics. Just change
|
|
|
-> the `-m` option to `-s` in the preceding commands.
|
|
|
+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,
|
|
|
+1F9495H8EJLb54wirgZkVgI47SP7M2RQWv. If the key in question is in a
|
|
|
+bitcoin 'wallet.dat', there's an included command that will
|
|
|
+conveniently extract the key for you:
|
|
|
|
|
|
-> A seed file for a 256-bit seed looks like this:
|
|
|
+ $ mmgen-pywallet -k wallet.dat
|
|
|
+ ...
|
|
|
+ wallet.dat secret keys saved to file wd_EDBC983A[102].keys
|
|
|
|
|
|
- $ cat 8B7392ED.mmseed
|
|
|
- f4c84b C5ZT wWpT Jsoi wRVw 2dm9 Aftd WLb8 FggQ eC8h Szjd da9L
|
|
|
+You've in fact extracted a list of all of the wallet's 102 keys here,
|
|
|
+but that's not a problem, as the unused keys will be ignored.
|
|
|
+Now go ahead and sign the transaction using this list of keys.
|
|
|
|
|
|
-> And for a 128-bit seed:
|
|
|
+ $ mmgen-txsign -k wd_EDBC983A[102].keys tx_1EDCBA[6.6].raw
|
|
|
+ ...
|
|
|
+ Signed transaction saved to file tx_1EDCBA[6.6].sig
|
|
|
|
|
|
- $ cat 8E0DFB78.mmseed
|
|
|
- 0fe02f XnyC NfPH piuW dQ2d nM47 VU
|
|
|
+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 concatenate them into a single file which you
|
|
|
+can use to sign all your future transactions involving wallet.dat
|
|
|
+inputs:
|
|
|
|
|
|
-> The latter is short enough to be memorized or written down.
|
|
|
+ $ mmgen-pywallet -k wallet1.dat
|
|
|
+ $ mmgen-pywallet -k wallet2.dat
|
|
|
+ $ mmgen-pywallet -k wallet3.dat
|
|
|
+ $ cat wd_*.keys > all_keys
|
|
|
|
|
|
-> The first word in the seed file is a checksum.
|
|
|
-> To check that you've written or memorized the seed correctly (should
|
|
|
-> you choose to do so), compare it with the first 6 characters of a
|
|
|
-> sha256 hash of the remainder of the line (with spaces removed).
|
|
|
+For transactions whose inputs are MMGen addresses, an MMGen
|
|
|
+seed source (i.e. wallet, mnemonic or seed file) is listed on the
|
|
|
+command line after the transaction file, and the required keys are
|
|
|
+automatically generated:
|
|
|
|
|
|
-#### Mnemonics and seeds — additional information:
|
|
|
-> Mnemonic and seed data may be entered at a prompt instead of from a
|
|
|
-> file. Just omit the filename on the command line.
|
|
|
+ $ 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 to deal with keys again. MMGen just generates them
|
|
|
+on the fly as the need arises.
|
|
|
+
|
|
|
+#### Send the transaction (online computer):
|
|
|
+
|
|
|
+Now we're ready for the final step: broadcasting the transaction to
|
|
|
+the network. Copy the \*.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 and they'll be displayed in MMGen format.
|
|
|
+
|
|
|
+Congratulations! You've performed your first MMGen transaction.
|
|
|
+
|
|
|
+### 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 a 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.
|
|
|
|
|
|
-> Mnemonic and seed data may be printed to standard output instead of a
|
|
|
-> file using the `-S` option of `mmgen-walletchk`.
|
|
|
+NOTE: MMGen mnemonics are generated from the Electrum wordlist, only
|
|
|
+using ordinary base conversion instead of Electrum's more complicated
|
|
|
+algorithm.
|
|
|
|
|
|
-> Mnemonic and seed files may be output to a directory of your choice
|
|
|
-> using the `-d` option of `mmgen-walletchk`.
|
|
|
+Generate addresses 1-11 using the mnemonic instead of the wallet:
|
|
|
|
|
|
-> Bear in mind that mnemonic and seed data is unencrypted. If it's
|
|
|
-> compromised, your Bitcoins can easily be stolen. Make sure no one's
|
|
|
-> looking over your shoulder when you print mnemonic or seed data to
|
|
|
-> screen. Securely delete your mnemonic and seed files. In Linux, you
|
|
|
-> can achieve additional security by writing the files to volatile
|
|
|
-> memory in '/dev/shm' instead of disk.
|
|
|
+ $ mmgen-addrgen 89ABCDEF.mmwords 1-11
|
|
|
+ ...
|
|
|
+ Address data saved to file '89ABCDEF[1-11].addrs'
|
|
|
|
|
|
-### Vanitygen note:
|
|
|
-> When available, the 'keyconv' utility from the vanitygen package is
|
|
|
-> used to generate addresses as it's much faster than the Python ecdsa
|
|
|
-> library.
|
|
|
+Compare the first ten addresses with those earlier generated by the
|
|
|
+wallet. You'll see they're the same.
|
|
|
+
|
|
|
+Recover 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 as 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 is short enough to practically 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 was intentionally 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 file 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:
|
|
|
-> To see what tests are available, run the scripts in the 'tests'
|
|
|
-> directory with no arguments. Among others, you might find the
|
|
|
-> following tests to be of interest:
|
|
|
|
|
|
->> Compare 10 addresses generated by 'keyconv' with mmgen's
|
|
|
->> internally-generated ones:
|
|
|
->>> `tests/bitcoin.py keyconv_compare_randloop 10`
|
|
|
+To see what tests are available, run the scripts in the 'tests'
|
|
|
+directory with no arguments. You might find the following tests to be
|
|
|
+of interest:
|
|
|
+
|
|
|
+> Compare 10 addresses generated by 'keyconv' with mmgen's
|
|
|
+> internally-generated ones:
|
|
|
+>> `tests/bitcoin.py keyconv_compare_randloop 10`
|
|
|
|
|
|
->> Convert a string to base 58 and back:
|
|
|
->>> `tests/bitcoin.py strtob58 'a string'`
|
|
|
+> Convert a string to base 58 and back:
|
|
|
+>> `tests/bitcoin.py strtob58 'a string'`
|
|
|
|
|
|
->> Convert a hex number to base 58 and back:
|
|
|
->>> `tests/bitcoin.py hextob58 deadbeef`
|
|
|
+> Convert a hex number to base 58 and back:
|
|
|
+>> `tests/bitcoin.py hextob58 deadbeef`
|
|
|
|
|
|
->> Perform 1000 hex -> base58 -> hex conversions, comparing results stringwise:
|
|
|
->>> `tests/bitcoin.py hextob58_pad_randloop 1000`
|
|
|
+> Perform 1000 hex -> base58 -> hex conversions, comparing results stringwise:
|
|
|
+>> `tests/bitcoin.py hextob58_pad_randloop 1000`
|
|
|
|
|
|
->> Generate a 12-word mnemonic from a random 128-bit seed:
|
|
|
->>> `tests/mnemonic.py random128`
|
|
|
+> Generate a 12-word mnemonic from a random 128-bit seed:
|
|
|
+>> `tests/mnemonic.py random128`
|
|
|
|
|
|
->> or an 18-word mnemonic from a random 192-bit seed:
|
|
|
->>> `tests/mnemonic.py random192`
|
|
|
+> or an 18-word mnemonic from a random 192-bit seed:
|
|
|
+>> `tests/mnemonic.py random192`
|
|
|
|
|
|
->> or a 24-word mnemonic from a random 256-bit seed:
|
|
|
->>> `tests/mnemonic.py random256`
|
|
|
+> or a 24-word mnemonic from a random 256-bit seed:
|
|
|
+>> `tests/mnemonic.py random256`
|