## Table of Contents #### Basic Operations * Generate a wallet * Generate addresses * Import addresses * Create a transaction * Sign a transaction * Send a transaction #### Additional Features * Using the mnemonic and seed features * Mnemonics and seeds — additional information * Incognito wallets * Hidden incognito wallets IMPORTANT NOTE: The following primer presupposes you have MMGen installed on two computers, one offline and one online. However, if you have an online computer and a few Bitcoin addresses with small balances, it's perfectly possible to practice the operations decribed below on a single machine. If you're just looking to get your feet wet, wallet generation, wallet format conversions, address and key generation, and address import may all be practiced on an online or offline computer with no blockchain and no Bitcoin balance. ### Basic Operations #### Generate a wallet (offline computer): On your offline computer, generate a wallet with a random seed: $ mmgen-walletgen ... MMGen wallet written 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. #### Generate addresses (offline computer): Now generate ten addresses with your just-created wallet: $ mmgen-addrgen 89ABCDEF-76543210[256,3].mmdat 1-10 ... Addresses written 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. #### Import addresses (online computer): On your online computer, go to your bitcoind data directory and move any existing 'wallet.dat' file out of harm's way. Start bitcoind and let it generate a new 'wallet.dat', which you'll use as your **tracking wallet**. Import your four addresses into the new 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 address balances. Balances can be viewed with the 'mmgen-tool' utility: $ mmgen-tool listaddresses No addresses with balances! The 'showempty' option shows all tracked addresses, even ones with no balances, so the four imported addresses should now show up on the listing: $ mmgen-tool listaddresses showempty=1 ADDRESS COMMENT BALANCE 89ABCDEF:1 Donations 0 89ABCDEF:2 Storage 1 0 89ABCDEF:3 Storage 2 0 89ABCDEF:4 Storage 3 0 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 --rescan -l my_existing_addrs_with_balances NOTE: The '--rescan' option forces a rescan of the entire block chain, which is required for all addresses with existing balances. Since the rescanning process is very slow, you'll save yourself a great deal of time by always importing new addresses BEFORE spending into them. Continue in this fashion until you've imported all addresses with balances into your tracking wallet. #### 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. Note that 'mmgen-tool listaddresses' shows only MMGen address balances; to view **all** balances, including your non-MMGen ones, use the 'mmgen-txcreate' command: $ mmgen-txcreate -i A list of all 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 optionally be viewed in a pager or printed to file. For a wallet with ten unspent outputs, the display might 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. You're advised to use a passphrase on your wallet. 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 your address with the largest balance, 10 BTC, address 1F93Znz..., into three roughly equal parts and send them 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 destination addresses in question: $ cat my.addrs | grep -v Donations # My first MMGen addresses 89ABCDEF { 2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1 3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2 4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3 } The following command does just this, sending 6.6 BTC of the transaction's 10 BTC input to the first two addresses and the remainder to the third address, for which no amount has been specified: $ mmgen-txcreate 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,3.3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N,3.3 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s The address with no amount is the **change address**; MMGen will calculate the amount sent to it automatically by subtracting the sum of the outputs plus transaction fee, if any, from the inputs. In our example, 3.39995 BTC (10 BTC - (3.3 + 3.3 BTC) - .00005 BTC default transaction fee) will go to this address. Note that the above transaction can be expressed much more concisely by replacing the Bitcoin addresses with their MMGen equivalents: $ mmgen-txcreate 89ABCDEF:2,3.3 89ABCDEF:3,3.3 89ABCDEF:4 For this to work, the addresses must be imported into your tracking wallet, which they should be in any case. After hitting ENTER you'll be presented with the same UNSPENT OUTPUTS display as with the '-i' option above. In our example, note that the output with 10 BTC which you wish to spend, 1F93Znz..., is listed as number '1'. Remember this. After quitting the menu with 'q' you'll see the following prompt: Enter a range or space-separated list of outputs to spend: Type your remembered '1' here and hit ENTER. After several more prompts and confirmations, your transaction will be saved: Transaction written to file 'tx_FEDCBA[6.6].raw' Note that the transaction has a unique ID, and the non-change spend amount of 6.6 BTC is included in the filename. #### Create a keylist file (online computer): To sign your transaction, you'll need the Bitcoin private key corresponding to its input address, '1F93Znz....' If the key in question is in a bitcoind wallet ('wallet.dat'), you'll want to extract the key (along with all the other keys in the wallet) to a keylist file. This is done using the 'bitcoin-cli dumpwallet' command with bitcoind running. $ bitcoin-cli dumpwallet my_secret.keys This will write the keylist file 'my_secret.keys' (or whatever filename you've chosen) to your home directory (or maybe to your Bitcoin data directory, results may vary). If you want it written to another location, provide an absolute path. Note that the keylist file lists your private keys in *unencrypted* form, even if your 'wallet.dat' was encrypted. Therefore, it should be backed up to a safe location—to a USB stick, say, or to your offline computer. After you've backed it up, securely delete all copies of it on your online computer. You'll use this keylist file to sign all transactions that spend from addresses in your bitcoind wallet. If the key/address pair in question came from another source, you may create your own file 'my_secret.keys' (or whatever) in a plain text editor and just list the key in this file. In the case of multiple keys, just list them all, one key per line. In our example, the file will have one line containing a single private key corresponding to the address '1F93Znz....' #### Sign a transaction (offline computer): Now transfer the the raw transaction file and just-created keylist file to your offline computer and run: $ mmgen-txsign -k my_secret.keys tx_FEDCBA[6.6].raw ... Signed transaction written to file 'tx_FEDCBA[6.6].sig' The signed transaction is written to a new file whose name differs from the raw transaction file only by its '.sig' extension. NOTE: once you've migrated your funds to MMGen, the keylist file will no longer be needed. Instead, you'll sign transactions by listing an MMGen seed source (wallet, mnemonic or seed file) on the command line after the transaction, and the required keys will be generated on the fly, as in the following example: $ mmgen-txsign tx_ABCDE[1].raw my_mmgen_wallet.mmdat NOTE: transactions may contain a mixture of MMGen and non-MMGen inputs, as well as inputs with more than one MMGen Seed ID. Just list a seed source for each MMGen input on the command line after the transaction, as in this example: $ mmgen-txsign -k my_secret.keys my_tx.raw a.mmdat b.mmwords c.mmseed #### Send a transaction (online computer): Now you're ready for the final step: broadcasting the transaction to the network. Copy the just-created signed transaction file to your online computer, start bitcoind and issue the command: $ mmgen-txsend tx_FEDCBA[6.6].sig Like all MMGen commands, 'mmgen-txsend' is interactive, so you'll be prompted before the transaction is actually sent. Once the transaction is broadcast to the network, you can view your three new MMGen addresses and their balances: $ mmgen-tool listaddresses minconf=0 ADDRESS COMMENT BALANCE 89ABCDEF:2 Storage 1 3.3 89ABCDEF:3 Storage 2 3.3 89ABCDEF:4 Storage 3 3.39995 Your total MMGen balance will also now be visible: $ mmgen-tool getbalance minconf=0 Wallet Unconfirmed <0 confirms >=0 confirms 89ABCDEF: 0 BTC 0 BTC 9.99995 BTC TOTAL: 0 BTC 0 BTC 9.99995 BTC To verify that your transaction's received its first, second, third, and so on, confirmation, increase the 'minconf' value to 1, 2, 3 and so forth. 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-walletconv -o words '89ABCDEF-76543210[256,3].mmdat' ... Mnemonic data written 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, it's advisable to 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. The mnemonic file may be used any place you'd use a MMGen wallet with the same Seed ID. You can generate ten addresses with it just as you did with the wallet, for example: $ mmgen-addrgen 89ABCDEF.mmwords 1-10 ... Address data written to file '89ABCDEF[1-10].addrs' The resulting address file will be identical to one generated by any wallet with Seed ID '89ABCDEF'. The mnemonic can be used to regenerate a lost wallet: $ mmgen-walletconv 89ABCDEF.mmwords ... MMGen wallet written 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 generated and used exactly the same way as mnemonic files: $ mmgen-walletconv -o seed '89ABCDEF-76543210[256,3].mmdat' ... Seed data written to file '89ABCDEF.mmseed' And they can also be used to regenerate a wallet: $ mmgen-walletconv 89ABCDEF.mmseed ... MMGen wallet written to file '89ABCDEF-23456701[256,3].mmdat' Here's a sample seed file for a 256-bit wallet: $ cat 8B7392ED.mmseed f4c84b C5ZT wWpT Jsoi wRVw 2dm9 Aftd WLb8 FggQ eC8h Szjd da9L And for a 128-bit wallet: $ cat 8E0DFB78.mmseed 0fe02f XnyC NfPH piuW dQ2d nM47 VU As you can see, seed files are short enough to be easily written out by hand or even memorized. And their built-in checksum makes it easy to test your memory using a simple Unix shell command: $ echo -n XnyC NfPH piuW dQ2d nM47 VU | tr -d ' '| sha256sum | cut -c 1-6 0fe02f Or you can do the same thing with 'mmgen-tool': $ mmgen-tool str2id6 'XnyC NfPH piuW dQ2d nM47 VU' 0fe02f #### Mnemonics and seeds — additional information: MMGen commands that take mnemonic and seed data may receive the data from a prompt instead of a file. Just omit the file name and specify the input format: $ mmgen-walletconv -i words ... Enter mnemonic data: With the '-S' option, MMGen commands may be requested to print wallet data to screen instead of a file. To safeguard against over-the-shoulder, Van Eck phreaking and other side-channel attacks, you'll be prompted before this sensitive data is actually displayed. MMGen never prints unencrypted private data to screen by default. 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 can use '-d /dev/shm' to write keys and seeds to volatile memory instead of disk, ensuring that no trace of this sensitive data remains once your computer's been powered down. #### Incognito wallets An incognito format wallet is indistinguishable from random data, allowing you to hide your wallet at an offset within a random-data-filled file or partition. Barring any inside knowledge, a potential attacker has no way of knowing where the wallet is hidden, or whether the file or partition contains anything of interest at all for that matter. An incognito wallet with a reasonably secure password could even be hidden on unencrypted cloud storage. Hiding your wallet at some offset in a 1 GB file increases the difficulty of any attack by a factor of one billion, assuming again that any potential attacker even knows or suspects you have an MMGen wallet hidden there. If you plan to store your incognito wallet in an insecure location such as cloud storage, you're advised to use a strong scrypt (hash) preset and a strong password. These can be changed using the 'mmgen-passchg' utility: $ mmgen-passchg -p 5 89ABCDEF-01234567[256,3].mmdat ... Hash preset of wallet: '3' Enter old passphrase for MMGen wallet: ... Hash preset changed to '5' Enter new passphrase for MMGen wallet: ... MMGen wallet written to file '89ABCDEF-87654321[256,5].mmdat' The scrypt preset is the numeral in the wallet filename following the seed length. As you can see, it's now changed to '5'. Now export your new toughened wallet to incognito format, using the '-k' option to leave the passphrase unchanged: $ mmgen-walletconv -k -o incog 89ABCDEF-87654321[256,5].mmdat ... Reusing passphrase at user request ... New Incog Wallet ID: ECA86420 ... Incognito data written to file '89ABCDEF-87654321-ECA86420[256,5].mmincog' Incog wallets have a special identifier, the Incog ID, which can be used to locate the wallet data if you've forgotten where you hid it (see the example below). Naturally, an attacker could use this ID to find the data too, so it should be kept secret. Incog wallets can also be output to hexadecimal format: $ mmgen-walletconv -k -o incox 89ABCDEF-87654321[256,5].mmdat ... Hex incognito data written to file '89ABCDEF-87654321-CA86420E[256,5].mmincox' $ cat 89ABCDEF-87654321-1EE402F4[256,5].mmincox 6772 edb2 10cf ad0d c7dd 484b cc7e 42e9 4fe6 e07a 1ce2 da02 6da7 94e4 c068 57a8 3706 c5ce 56e0 7590 e677 6c6e 750a d057 b43a 21f9 82c7 6bd1 fe96 bad9 2d54 c4c0 Note that the Incog ID is different here: it's generated from an init vector, which is a different random number each time, making the incog data as a whole different as well. This allows you to store your incog data in multiple public locations without having repeated "random" wallet data give you away. Indistinguishable from any random hex dump, this data is ideally suited for a paper wallet that could potentially fall into the wrong hands. Your incognito wallet (whether hex or binary) can be used just like any other MMGen wallet, mnemonic or seed file to generate addresses and sign transactions: $ mmgen-addrgen 89ABCDEF-87654321-CA86420E[256,5].mmincox 101-110 ... Generated 10 addresses Addresses written to file '89ABCDEF[101-110].addrs' $ mmgen-txsign tx_FABCDE[0.3].raw 89ABCDEF-87654321-CA86420E[256,5].mmincox ... Signed transaction written to file tx_FABCDE[0.3].sig ##### Hidden incognito wallets With the '-o hincog' option, incognito wallet data can be created and hidden at a specified offset in a file or partition in a single convenient operation, with the random file being created automatically if required. Here's how you'd create a 1GB file 'random.dat' and hide a wallet in it at offset 123456789: $ mmgen-walletconv -k -o hincog -J random.dat,123456789 89ABCDEF-87654321[256,5].mmdat ... New Incog Wallet ID: ED1F2ACB ... Requested file 'random.dat' does not exist. Create? (Y/n): Y Enter file size: 1G ... Data written to file 'random.dat' at offset 123456789 Your "random" file can now be uploaded to a cloud storage service, for example, or some other, preferably non-public, location on the Net (in a real-life situation you will choose a less obvious offset than '123456789' though, won't you?). Now let's say at some point in the future you download this file to recover your wallet and realize you've forgotten the offset where the data is hidden. If you've saved your Incog ID, you're in luck: $ mmgen-tool find_incog_data random.dat ED1F2ACB ... Incog data for ID ED1F2ACB found at offset 123456789 The search process can be slow, so patience is required. In addition, on large files 'false positives' are a distinct possibility, in which case you'll need to use the 'keep_searching=1' parameter to keep going until you find the real offset. Hidden incog wallets are nearly as convenient to use as ordinary ones. Generating ten addresses with your hidden incog data is as easy as this: $ mmgen-addrgen -H random.dat,123456789 101-110 Transaction signing uses the same syntax: $ mmgen-txsign -H random.dat,123456789 tx_ABCDEF[0.1].raw ... Signed transaction written to file 'tx_ABCDEF[0.1].sig'