New and revised documentation in wiki:
new: MMGen Quick Start with Regtest Mode (tutorial) additions: Getting Started with MMGen - compressed addresses additions: Recovering Keys Without MMGen - mnemonic-to-hex instructions
This commit is contained in:
parent
12ea12e4e2
commit
089b182733
10 changed files with 680 additions and 144 deletions
|
|
@ -100,6 +100,8 @@ future use in an address file, which addresses may safely be made public.
|
|||
|
||||
> #### [Getting Started with MMGen][3]
|
||||
|
||||
> #### [MMGen Quick Start with Regtest Mode][q]
|
||||
|
||||
> #### [MMGen command help][6]
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
@ -116,6 +118,7 @@ Donate: 15TLdmi5NYLdqmtCqczUs5pBPkJDXRs83w
|
|||
[4]: https://bitcointalk.org/index.php?topic=567069.0
|
||||
[5]: https://github.com/mmgen/mmgen/wiki/MMGen-Signing-Key
|
||||
[6]: https://github.com/mmgen/mmgen/wiki/MMGen-command-help
|
||||
[q]: https://github.com/mmgen/mmgen/wiki/MMGen-Quick-Start-with-Regtest-Mode
|
||||
[7]: http://bitcoinmagazine.com/8396/deterministic-wallets-advantages-flaw/
|
||||
[8]: https://github.com/mmgen/MMGenLive
|
||||
[9]: https://cloud.githubusercontent.com/assets/6071028/20677261/6ccab1bc-b58a-11e6-8ab6-094f88befef2.jpg
|
||||
|
|
|
|||
|
|
@ -1,41 +1,79 @@
|
|||
Make sure that the following development packages for the boost library are
|
||||
installed (package names may vary; the version should be 1.48 or greater, and
|
||||
version 1.54 on Ubuntu 13.10 is reported not to work):
|
||||
***Note for Raspbian and Armbian users: Compiling the bitcoin daemon will
|
||||
probably fail on a RPi or RPi clone due to insufficient memory. Fortunately,
|
||||
ARM binaries are available for both Bitcoin Core and Bitcoin ABC. See the
|
||||
[binary installation page][01] for details.***
|
||||
|
||||
libboost-system-dev
|
||||
libboost-filesystem-dev
|
||||
libboost-program-options-dev
|
||||
libboost-chrono-dev
|
||||
libboost-test-dev
|
||||
libboost-thread-dev
|
||||
### Install dependencies:
|
||||
|
||||
You'll also need the standard build tools if they're not already on your system:
|
||||
> Make sure the required boost library development packages are installed:
|
||||
|
||||
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
|
||||
sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-program-options-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev
|
||||
|
||||
> You'll also need the following standard dependencies, if they're not already on
|
||||
> your system:
|
||||
|
||||
Clone the bitcoin repository from Github, configure, and build:
|
||||
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libdb-dev libdb++-dev libevent-dev
|
||||
|
||||
### Compile and install Bitcoin Core:
|
||||
|
||||
> Clone the Bitcoin Core repository from Github, configure, and build:
|
||||
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
|
||||
If 'configure' complains about a missing libdb version 4.8, you have two
|
||||
options: either install the libdb4.8-dev and libdb4.8++-dev packages (you may
|
||||
have to obtain them from elsewhere) or install your distribution's current
|
||||
libdbX.X-dev and libdbX.X++-dev packages and add the '--with-incompatible-bdb'
|
||||
option to the 'configure' command line. Be warned that the latter option will
|
||||
result in your 'wallet.dat' files being incompatible with the prebuilt binary
|
||||
version of bitcoind.
|
||||
> The '-j4' option will speed the build process up by using 4 cores of a 4-core
|
||||
> processor, if you have them. If overheating issues are a problem for your CPU
|
||||
> or you're short on memory, you may want to omit it or use '-j2'.
|
||||
|
||||
For more detailed information on this and other dependency issues, consult the
|
||||
file 'doc/build-unix.md' in the bitcoin source repository.
|
||||
> For more detailed build information, consult the file [doc/build-unix.md][bu]
|
||||
> in the bitcoin source repository.
|
||||
|
||||
Your freshly compiled daemon is now in the src/ directory. Refer to **Run:** on
|
||||
the [binary installation page][01] for running instructions.
|
||||
> Your freshly compiled bitcoind daemon is now in the src/ directory. Install
|
||||
> it, along with the 'bitcoin-cli' utility, into your executable path:
|
||||
|
||||
$ cd src
|
||||
$ strip bitcoind bitcoin-cli
|
||||
$ sudo cp bitcoind /usr/local/bin
|
||||
$ sudo cp bitcoin-cli /usr/local/bin
|
||||
|
||||
### Compile and install Bitcoin ABC (optional):
|
||||
|
||||
> *Regard Bitcoin ABC as experimental software. The author of the MMGen project
|
||||
> has only partially reviewed its codebase and makes no guarantees regarding its
|
||||
> safety or reliability.*
|
||||
|
||||
> If you want to transact BCH, also known as “Bitcoin Cash” or “Bcash”, then
|
||||
> clone the Bitcoin ABC repository, and configure and build exactly as you did
|
||||
> with Bitcoin Core above:
|
||||
|
||||
$ git clone https://github.com/Bitcoin-ABC/bitcoin-abc
|
||||
$ cd bitcoin-abc
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
|
||||
> The resulting executable is also named 'bitcoind', so you must install it
|
||||
> under a different name to avoid overwriting your Core daemon:
|
||||
|
||||
$ cd src
|
||||
$ strip bitcoind bitcoin-cli
|
||||
$ sudo cp bitcoind /usr/local/bin/bitcoind-abc
|
||||
|
||||
> From now on, you'll invoke the daemon as 'bitcoind-abc' instead of 'bitcoind'.
|
||||
> Or alternatively, to simplify the starting and stopping of two daemons on the
|
||||
> same machine, download and use the node start and stop scripts from the
|
||||
> MMGenLive project:
|
||||
|
||||
$ curl -O 'https://raw.githubusercontent.com/mmgen/MMGenLive/master/home.mmgen/bin/mmlive-node-{start,stop}'
|
||||
$ sudo install mmlive-node-{start,stop} /usr/local/bin
|
||||
|
||||
Refer to **Run:** on the [binary installation page][01] for instructions on
|
||||
running your freshly compiled bitcoin daemon(s).
|
||||
|
||||
[01]: Install-Bitcoind
|
||||
[dl]: https://bitcoin.org/en/download
|
||||
[gs]: Getting-Started-with-MMGen
|
||||
[bu]: https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md
|
||||
|
|
|
|||
|
|
@ -18,8 +18,21 @@ low-powered netbook as your online machine.
|
|||
|
||||
### Download:
|
||||
|
||||
> Go to the Bitcoin Core [main download page][01]. Choose the 32-bit or 64-bit
|
||||
> versions appropriate for your online and offline computers.
|
||||
> **Bitcoin Core:**
|
||||
|
||||
>> Go to the Bitcoin Core [main download page][01]. Choose the 32-bit or 64-bit
|
||||
>> versions appropriate for your online and offline computers.
|
||||
|
||||
> **Bitcoin ABC (optional):**
|
||||
|
||||
>> If you wish to transact BCH, a.k.a "Bitcoin Cash” or “Bcash”, then download
|
||||
>> the appropriate [Bitcoin ABC binary][abc] for your system as well. Windows
|
||||
>> users should download the zip file rather than the installer. Both Windows
|
||||
>> and Linux users **must** rename the binary to 'bitcoind-abc' before
|
||||
>> installing it in their executable path.
|
||||
|
||||
>> *Regard the Bitcoin ABC binaries as untrusted software. The author of the
|
||||
>> MMGen project makes no guarantees regarding their safety or reliability.*
|
||||
|
||||
### Install (both online and offline computers):
|
||||
|
||||
|
|
@ -66,3 +79,4 @@ low-powered netbook as your online machine.
|
|||
[01]: https://bitcoin.org/en/download
|
||||
[bd]: https://bitcoin.org/bin/blockchain/
|
||||
[05]: Editing-the-user-path-in-Windows
|
||||
[abc]: https://download.bitcoinabc.org/
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#### Perform the following steps on both your online and offline computers:
|
||||
|
||||
Install required Debian/Ubuntu packages:
|
||||
> Install required Debian/Ubuntu packages:
|
||||
|
||||
$ sudo apt-get install python-pip python-dev python-pexpect python-ecdsa python-scrypt libssl-dev git autoconf libtool wipe python-setuptools
|
||||
|
||||
Install the Python Cryptography Toolkit:
|
||||
> Install the Python Cryptography Toolkit:
|
||||
|
||||
$ sudo -H pip install pycrypto
|
||||
|
||||
Install the secp256k1 library:
|
||||
> Install the secp256k1 library:
|
||||
|
||||
$ git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
$ cd secp256k1
|
||||
|
|
@ -19,7 +19,7 @@ Install the secp256k1 library:
|
|||
$ sudo ldconfig
|
||||
$ cd ..
|
||||
|
||||
Install MMGen:
|
||||
> Install MMGen:
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen
|
||||
|
|
@ -27,32 +27,30 @@ Install MMGen:
|
|||
$ sudo ./setup.py install
|
||||
$ cd ..
|
||||
|
||||
Install vanitygen (optional):
|
||||
> Install the bitcoind daemon(s):
|
||||
|
||||
$ sudo apt-get install libpcre3-dev
|
||||
$ git clone https://github.com/samr7/vanitygen.git
|
||||
$ cd vanitygen; make
|
||||
(copy the "keyconv" executable to your execution path)
|
||||
$ cd ..
|
||||
> To install prebuilt binaries, go [here][01]. To install from source, go
|
||||
> [here][02].
|
||||
|
||||
Install bitcoind:
|
||||
#### Note for offline machines:
|
||||
|
||||
> To install prebuilt binaries, click [here][01]. To install from source,
|
||||
> click [here][02].
|
||||
> Naturally, your offline machine must be connected to the Internet to retrieve
|
||||
> and install the above packages as described above. This is normally not a
|
||||
> problem, as you can simply take the machine offline permanently after the
|
||||
> install is done, preferably removing or disabling its network interfaces.
|
||||
|
||||
**NB:** Naturally, your offline machine must be connected to the Internet to
|
||||
retrieve and install the above packages as described above. If your offline
|
||||
machine is already offline and you wish to leave it that way, then you'll be
|
||||
forced to take roughly the following steps:
|
||||
> However, if your machine is already offline and you wish to leave it that way,
|
||||
> or if it lacks a network interface entirely, then you'll need to take roughly
|
||||
> the following steps:
|
||||
|
||||
> From your online machine, download the Debian/Ubuntu packages and their
|
||||
> dependencies manually from packages.debian.org or packages.ubuntu.com, and the
|
||||
> Python packages from pypi.python.org/pypi/<packagename>. Transfer these
|
||||
> files and the git repositories you've cloned to your offline computer using a
|
||||
> USB stick or other means at your disposal. Install the Debian/Ubuntu packages
|
||||
> with 'sudo dpkg -i', unpack each Python module and install it using 'sudo
|
||||
> ./setup.py install', and install MMGen and the secp256k1 library from the
|
||||
> copied git repositories as described above.
|
||||
>> From your online machine, download the Debian/Ubuntu packages and their
|
||||
>> dependencies manually from packages.debian.org or packages.ubuntu.com, and
|
||||
>> the Python packages from pypi.python.org/pypi/<packagename>. Transfer
|
||||
>> these files and the cloned Git repositories to your offline computer using a
|
||||
>> USB stick or other storage medium. Install the Debian/Ubuntu packages with
|
||||
>> 'sudo dpkg -i', unpack each Python module and install it using 'sudo
|
||||
>> ./setup.py install', and install MMGen and the secp256k1 library from the
|
||||
>> copied Git repositories as described above.
|
||||
|
||||
Congratulations, your installation is now complete! Now proceed to [**Getting
|
||||
Started with MMGen**][gs].
|
||||
|
|
|
|||
|
|
@ -18,8 +18,21 @@ low-powered netbook as your online machine.
|
|||
|
||||
### Download:
|
||||
|
||||
> Go to the Bitcoin Core [main download page][01]. Choose the 32-bit or 64-bit
|
||||
> versions appropriate for your online and offline computers.
|
||||
> **Bitcoin Core:**
|
||||
|
||||
>> Go to the Bitcoin Core [main download page][01]. Choose the 32-bit or 64-bit
|
||||
>> versions appropriate for your online and offline computers.
|
||||
|
||||
> **Bitcoin ABC (optional):**
|
||||
|
||||
>> If you wish to transact BCH, a.k.a "Bitcoin Cash” or “Bcash”, then download
|
||||
>> the appropriate [Bitcoin ABC binary][abc] for your system as well. Windows
|
||||
>> users should download the zip file rather than the installer. Both Windows
|
||||
>> and Linux users **must** rename the binary to 'bitcoind-abc' before
|
||||
>> installing it in their executable path.
|
||||
|
||||
>> *Regard the Bitcoin ABC binaries as untrusted software. The author of the
|
||||
>> MMGen project makes no guarantees regarding their safety or reliability.*
|
||||
|
||||
### Install (both online and offline computers):
|
||||
|
||||
|
|
@ -66,3 +79,4 @@ low-powered netbook as your online machine.
|
|||
[01]: https://bitcoin.org/en/download
|
||||
[bd]: https://bitcoin.org/bin/blockchain/
|
||||
[05]: Editing-the-user-path-in-Windows
|
||||
[abc]: https://download.bitcoinabc.org/
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* <a href='#a_bb'>Before you begin</a>
|
||||
* <a href='#a_iv'>Invocation</a>
|
||||
* <a href='#a_cf'>Configuration file</a>
|
||||
* <a href='#a_ts'>Testnet and regtest mode</a>
|
||||
* <a href='#a_ts'>Bob and Alice regtest mode</a>
|
||||
|
||||
#### <a href='#a_bo'>Basic Operations</a>
|
||||
* <a href='#a_gw'>Generate an MMGen wallet</a>
|
||||
|
|
@ -79,7 +79,7 @@ wish to edit at some point to customize MMGen to your needs. These settings
|
|||
include the maximum transaction fee; the user name, password and hostname
|
||||
used for communicating with bitcoind; and a number of others.
|
||||
|
||||
#### <a name='a_ts'>Testnet and regtest mode</a>
|
||||
#### <a name='a_ts'>Bob and Alice regtest mode</a>
|
||||
|
||||
If you just want to quickly try out MMGen, it's possible to perform all wallet
|
||||
generation, wallet format conversion, address and key generation, and address
|
||||
|
|
@ -89,67 +89,14 @@ balance.
|
|||
If you want to practice creating, signing and sending transactions, however, as
|
||||
well as tracking balances, you'll need a fully synced blockchain and some actual
|
||||
coins to play with. To avoid risking real funds, it's *highly recommended* to
|
||||
practice transaction operations on [testnet][04] or in [regtest mode][05] until
|
||||
you feel confident you know what you're doing.
|
||||
practice transaction operations using **Bob and Alice regtest mode** until you
|
||||
feel confident you know what you're doing.
|
||||
|
||||
**Testnet** is just like the real Bitcoin network, but testnet coins have no
|
||||
monetary value. Free testnet coins may be obtained at
|
||||
[https://tpfaucet.appspot.com][02].
|
||||
|
||||
To use MMGen with testnet, you must first start bitcoind with the `-testnet`
|
||||
option and sync the testnet blockchain (about 12GB at the time of writing). To
|
||||
force any MMGen command to use testnet just add the `--testnet=1` option after
|
||||
the command name. Or just set the `testnet` option to `true` in 'mmgen.cfg' to
|
||||
make *all* commands use testnet. With testnet you can safely practice all the
|
||||
operations below, including the offline ones, on an online computer.
|
||||
|
||||
**Regtest mode** is a more convenient alternative to testnet that requires no
|
||||
Internet connection. In regtest mode, bitcoind creates a private blockchain on
|
||||
which you can mine, send and receive transactions. MMGen commands support
|
||||
regtest mode with the `--regtest=1` option or the `regtest` option in
|
||||
`mmgen.cfg`. The following is a brief guide to get you started with regtest
|
||||
mode:
|
||||
|
||||
Start the bitcoin daemon, generate 432 blocks to activate Segwit on the regtest
|
||||
chain and stop:
|
||||
|
||||
$ bitcoind -regtest -daemon
|
||||
$ bitcoin-cli -regtest generate 432
|
||||
$ bitcoin-cli -regtest stop
|
||||
|
||||
Move 'wallet.dat' out of harm's way (**important:** it's the 'wallet.dat' in the
|
||||
'regtest' directory under your bitcoin data directory being referred to here,
|
||||
**not** the one in your bitcoin data directory). Restart the daemon:
|
||||
|
||||
$ bitcoind -regtest -daemon
|
||||
|
||||
A new ‘wallet.dat’ will be created. This is your tracking wallet. Create an
|
||||
MMGen wallet, generate some MMGen addresses and import them into the tracking
|
||||
wallet <a href='#a_bo'>as described below</a>. Stop the daemon again:
|
||||
|
||||
$ bitcoin-cli -regtest stop
|
||||
|
||||
Move your tracking wallet (the new 'wallet.dat') out of harm's way and move the
|
||||
original 'wallet.dat' back. Restart the daemon, send some funds to one of your
|
||||
tracked addresses, mine a block and stop the daemon:
|
||||
|
||||
$ bitcoind -regtest -daemon
|
||||
$ bitcoin-cli -regtest sendtoaddress <a tracked address> 100.00
|
||||
$ bitcoin-cli -regtest generate 1
|
||||
$ bitcoin-cli -regtest stop
|
||||
|
||||
Replace the original 'wallet.dat' with your tracking wallet again, restart
|
||||
bitcoind and list your tracked addresses:
|
||||
|
||||
$ bitcoind -regtest -daemon
|
||||
$ mmgen-tool --regtest=1 listaddresses
|
||||
|
||||
Your address should now have a balance of 100 BTC. You may now practice creating
|
||||
and sending transactions to yourself <a href='#a_ct'>as described below</a>.
|
||||
After sending each transaction, you must mine a new block for the transaction to
|
||||
confirm:
|
||||
|
||||
$ bitcoin-cli -regtest generate 1
|
||||
A convenient frontend for bitcoind's regression test mode, MMGen's Bob and Alice
|
||||
mode creates a private blockchain and a virtual network of two users who can
|
||||
send bitcoins to each other. All of MMGen's functionality is available in this
|
||||
mode, making it an ideal, risk-free way to acquaint yourself with the wallet's
|
||||
features. Refer to [MMGen Quick Start with Regtest Mode][06] to get started.
|
||||
|
||||
### <a name='a_bo'>Basic Operations</a>
|
||||
|
||||
|
|
@ -162,7 +109,7 @@ require a wallet or other seed source.*
|
|||
|
||||
*You may not want this feature if you plan to store your MMGen wallet in a
|
||||
location other than your MMGen data directory. Otherwise, it’s recommended,
|
||||
as it frees you from having to type your wallet file on the command line.*
|
||||
as it frees you from having to type your wallet filename on the command line.*
|
||||
|
||||
*The following examples suppose that you’ve chosen to use a default wallet.
|
||||
If you haven't, then you must include the path to a wallet file or other seed
|
||||
|
|
@ -221,9 +168,14 @@ Now generate ten addresses with your just-created wallet:
|
|||
10 1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
|
||||
}
|
||||
|
||||
NOTE: As of version 0.9.2, MMGen supports Segwit. To generate Segwit addresses,
|
||||
add `--type segwit` to the command line. Segwit address files are distinguished
|
||||
from Legacy ones by the ‘-S’ in the filename:
|
||||
Note that the address range ‘1-10’ specified on the command line is included in
|
||||
the resulting filename.
|
||||
|
||||
NOTE: MMGen supports Segwit addresses as of version 0.9.2 and compressed P2PKH
|
||||
addresses as of version 0.9.3. To generate Segwit or compressed addresses, add
|
||||
`--type=segwit` or `--type=compressed` to the command line. Segwit and
|
||||
compressed address files are distinguished from Legacy ones by an added ‘-S’ and
|
||||
‘-C’ in the filenames:
|
||||
|
||||
$ mmgen-addrgen --type segwit 1-10
|
||||
...
|
||||
|
|
@ -232,8 +184,12 @@ from Legacy ones by the ‘-S’ in the filename:
|
|||
1 32GiSWo9zIQgkCmjAaLIrbPwXhKry2jHhj
|
||||
...
|
||||
|
||||
Note that the address range ‘1-10’ specified on the command line is included in
|
||||
the resulting filename.
|
||||
$ mmgen-addrgen --type compressed 1-10
|
||||
...
|
||||
$ cat '89ABCDEF-C[1-10].addrs'
|
||||
89ABCDEF COMPRESSED {
|
||||
1 13jbRxWjswXtaDzLBJDboMcIe6nLohFb9M
|
||||
...
|
||||
|
||||
To fund your MMGen wallet, first import the addresses into your tracking wallet
|
||||
and then spend some BTC into any of them. If you run out of addresses, generate
|
||||
|
|
@ -287,10 +243,9 @@ Import your ten addresses into the new tracking wallet with the command:
|
|||
These addresses will now be tracked: any BTC transferred to them will show up in
|
||||
your listing of address balances. Balances can be viewed using `mmgen-tool
|
||||
listaddresses` (the `showempty` option requests the inclusion of addresses with
|
||||
empty balances, and `showbtcaddrs` causes Bitcoin addresses to be displayed
|
||||
also).
|
||||
empty balances).
|
||||
|
||||
$ mmgen-tool listaddresses showempty=1 showbtcaddrs=1
|
||||
$ mmgen-tool listaddresses showempty=1
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
89ABCDEF:L:1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations 0
|
||||
89ABCDEF:L:2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1 0
|
||||
|
|
@ -307,10 +262,10 @@ through the network. To use it, you must save the keys corresponding to the
|
|||
addresses where the funds are stored in a separate file to use during signing.*
|
||||
|
||||
Note that each address has a unique ID (the ‘MMGen ID’) consisting of its Seed
|
||||
ID, its address type (‘L’ for Legacy, ‘S’ for Segwit), and its number (index).
|
||||
Legacy and Segwit addresses may be imported into the same tracking wallet;
|
||||
they're generated from different sub-seeds, so you needn't worry about key
|
||||
reuse.
|
||||
ID, its address type (‘L’ for Legacy, ‘S’ for Segwit and ‘C’ for Compressed),
|
||||
and its number (index). Addresses of different types may be imported into the
|
||||
same tracking wallet; since they're generated from different sub-seeds you
|
||||
needn't worry about key reuse.
|
||||
|
||||
Now that your addresses are being tracked, you may go ahead and send some BTC to
|
||||
them over the Bitcoin network. If you send 0.1, 0.2, 0.3 and 0.4 BTC
|
||||
|
|
@ -344,12 +299,9 @@ Note that 'mmgen-txcreate' accepts either MMGen IDs or Bitcoin addresses as
|
|||
arguments.
|
||||
|
||||
IMPORTANT NOTE: For the time being, Legacy addresses are the default, so
|
||||
address ‘89ABCDEF:5’ is equivalent to ‘89ABCDEF:L:5’. In the future, users will
|
||||
have the option to make Segwit addresses the default, so that ‘89ABCDEF:5’ will
|
||||
be equivalent to ‘89ABCDEF:S:5’ and the ‘L’ will be required to specify a legacy
|
||||
address. This may seem confusing, but it was the best possible way to make
|
||||
the MMGen ID backwards-compatible for now while allowing users the option of
|
||||
a non-compatible upgrade in the future.
|
||||
address ‘89ABCDEF:5’ is equivalent to ‘89ABCDEF:L:5’. In the future, users may
|
||||
be given the option to make Segwit (for BTC) or Compressed (for BCH) addresses
|
||||
the default.
|
||||
|
||||
To send 0.1 BTC to each of your addresses 89ABCDEF:6 and 89ABCDEF:7 and return the
|
||||
change to 89ABCDEF:8, you’d do this:
|
||||
|
|
@ -885,3 +837,4 @@ them in turn until you get a confirmation:
|
|||
[03]: Recovering-Keys-Without-MMGen
|
||||
[04]: https://bitcoin.org/en/developer-examples#testnet
|
||||
[05]: https://bitcoin.org/en/developer-examples#regtest-mode
|
||||
[06]: https://github.com/mmgen/mmgen/wiki/MMGen-Quick-Start-with-Regtest-Mode
|
||||
|
|
|
|||
160
doc/wiki/using-mmgen/MMGen-Quick-Start-with-Regtest-Mode.md
Normal file
160
doc/wiki/using-mmgen/MMGen-Quick-Start-with-Regtest-Mode.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
MMGen's regtest mode, also known as Bob and Alice mode, provides a convenient
|
||||
front-end for bitcoind's regression test mode. It creates a private blockchain
|
||||
and a virtual network of two users who can perform all MMGen operations,
|
||||
including sending bitcoins to each other.
|
||||
|
||||
To transact as Bob or Alice, just add the '--bob' or '--alice' option to any
|
||||
MMGen command. MMGen will start and stop the Bitcoin daemon automatically as
|
||||
required. All of MMGen's functionality is available in this mode, making it an
|
||||
ideal, risk-free way to acquaint yourself with the MMGen wallet's features and
|
||||
transacting on the Bitcoin blockchain in general.
|
||||
|
||||
This tutorial provides a quick, hands-on introduction.
|
||||
|
||||
1. Create the blockchain and Bob and Alice's tracking wallets:
|
||||
|
||||
$ mmgen-regtest setup
|
||||
|
||||
2. Generate Bob's MMGen wallet:
|
||||
|
||||
$ mmgen-walletgen --bob
|
||||
...
|
||||
Make this wallet your default and move it to the data directory? (Y/n): y
|
||||
|
||||
3. Generate three type 'C' (compressed) addresses with Bob's MMGen wallet:
|
||||
|
||||
$ mmgen-addrgen --bob --type=compressed 1-3
|
||||
...
|
||||
Addresses written to file '1163DDF1-C[1-3].addrs'
|
||||
# 1163DDF1 is Bob's Seed ID; since it's generated randomly, your Bob's will be different
|
||||
|
||||
4. Import the addresses into Bob's tracking wallet:
|
||||
|
||||
$ mmgen-addrimport --bob 1163DDF1-C[1-3].addrs
|
||||
...
|
||||
Type uppercase 'YES' to confirm: YES
|
||||
|
||||
5. List the addresses in Bob's tracking wallet. You should see the addresses
|
||||
you just imported:
|
||||
|
||||
$ mmgen-tool --bob listaddresses showempty=1
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 0
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf - 0
|
||||
1163DDF1:C:3 mhYYHM7renPpNi8SUj5yeEZ54eAUJ5HyQ1 - 0
|
||||
|
||||
6. Fund one of the addresses (let's choose the first one) with some BTC:
|
||||
|
||||
$ mmgen-regtest send mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ 500
|
||||
|
||||
7. Make sure the funds arrived:
|
||||
|
||||
$ mmgen-tool --bob listaddresses showempty=1
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 500
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf - 0
|
||||
1163DDF1:C:3 mhYYHM7renPpNi8SUj5yeEZ54eAUJ5HyQ1 - 0
|
||||
|
||||
8. You can view Bob's total balance this way too:
|
||||
|
||||
$ mmgen-tool --bob getbalance
|
||||
|
||||
9. Generate Alice's MMGen wallet:
|
||||
|
||||
$ mmgen-walletgen --alice
|
||||
...
|
||||
Make this wallet your default and move it to the data directory? (Y/n): y
|
||||
|
||||
10. Generate three type 'S' (segwit) addresses with Alice's MMGen wallet:
|
||||
|
||||
$ mmgen-addrgen --alice --type=segwit 1-3
|
||||
...
|
||||
Addresses written to file '9304C211-S[1-3].addrs'
|
||||
|
||||
11. Repeat steps 4-7 for Alice by substituting '--bob' for '--alice'. Don't
|
||||
forget to adjust the address filename and send address as well. The result of
|
||||
step 7 should look something like this:
|
||||
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
9304C211:S:1 2N3HhxasbRvrJyHg72JNVCCPi9EUGrEbFnu - 500
|
||||
9304C211:S:2 2N8w8qTupvd9L9wLFbrn6UhdfF1gadDAmFD - 0
|
||||
9304C211:S:3 2NF4y3y4CEjQCcssjX2BDLHT88XHn8z53JS - 0
|
||||
TOTAL: 500 BTC
|
||||
|
||||
12. Split Alice's funds, sending 200 BTC to address S:2 and the change to S:3.
|
||||
Specify a fee of 20 satoshis/byte and '--quiet' for less noisy output:
|
||||
|
||||
$ mmgen-txdo --alice --tx-fee=20s --quiet 9304C211:S:2,300 9304C211:S:3
|
||||
...
|
||||
Type uppercase 'YES' to confirm: YES
|
||||
Transaction sent: 78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076
|
||||
|
||||
13. Check the mempool for the transaction:
|
||||
|
||||
$ mmgen-regtest show_mempool
|
||||
['78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076']
|
||||
|
||||
14. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
|
||||
15. Check the mempool again:
|
||||
|
||||
$ mmgen-regtest show_mempool
|
||||
[]
|
||||
|
||||
16. List Alice's addresses. Note that Alice has lost a bit to transaction fees:
|
||||
|
||||
$ mmgen-tool --alice listaddresses showempty=1
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
9304C211:S:1 2N3HhxasbRvrJyHg72JNVCCPi9EUGrEbFnu - 0
|
||||
9304C211:S:2 2N8w8qTupvd9L9wLFbrn6UhdfF1gadDAmFD - 300
|
||||
9304C211:S:3 2NF4y3y4CEjQCcssjX2BDLHT88XHn8z53JS - 199.999967
|
||||
TOTAL: 499.999967 BTC
|
||||
|
||||
17. Have Alice send 10 BTC to Bob's C:2 address, with the change back to her S:1
|
||||
address. This time Alice specifies an absolute fee in BTC.
|
||||
|
||||
$ mmgen-txdo --alice --tx-fee=0.0001 --quiet 9304C211:S:1 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf,10
|
||||
...
|
||||
Enter a range or space-separated list of outputs to spend: 1
|
||||
...
|
||||
|
||||
Note that Alice is reusing address S:1 here, and address reuse is generally a
|
||||
bad idea. You'd be better off generating and importing some new addresses for
|
||||
Alice by repeating steps 3 and 4 with a different address range. I'll leave
|
||||
that to you as an exercise.
|
||||
|
||||
18. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
|
||||
19. List Alice's addresses, omitting the empty ones:
|
||||
|
||||
$ mmgen-tool --alice listaddresses
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
9304C211:S:1 2N3HhxasbRvrJyHg72JNVCCPi9EUGrEbFnu - 189.999867
|
||||
9304C211:S:2 2N8w8qTupvd9L9wLFbrn6UhdfF1gadDAmFD - 300
|
||||
TOTAL: 489.999867 BTC
|
||||
|
||||
19. List Bob's addresses:
|
||||
|
||||
$ mmgen-tool --bob listaddresses
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 500
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf - 10
|
||||
TOTAL: 510 BTC
|
||||
|
||||
20. Add a label to Bob's tracking wallet:
|
||||
|
||||
$ mmgen-tool --bob add_label 1163DDF1:C:2 'From Alice'
|
||||
|
||||
21. List Bob's addresses:
|
||||
|
||||
$ mmgen-tool --bob listaddresses
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 500
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf From Alice 10
|
||||
TOTAL: 510 BTC
|
||||
|
||||
[q]: MMGen-Quick-Start-with-Regtest-Mode
|
||||
361
doc/wiki/using-mmgen/Recovering-Keys-Without-MMGen.md
Normal file
361
doc/wiki/using-mmgen/Recovering-Keys-Without-MMGen.md
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
## Table of Contents
|
||||
|
||||
* <a href='#a_i'>Introduction</a>
|
||||
* <a href='#a_rs'>Obtaining the binary seed</a>
|
||||
* <a href='#a_ss'>Convert the seed to binary (legacy addresses)</a>
|
||||
* <a href='#a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
|
||||
* <a href='#a_gk'>Generating the keys</a>
|
||||
* <a href='#a_hw'>Hex to WIF by hand</a>
|
||||
* <a href='#a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
|
||||
|
||||
#### <a name='a_i'>Introduction</a>
|
||||
|
||||
If you're considering using MMGen and are a Bitcoiner with a normal, healthy
|
||||
degree of paranoia, then the following question will probably come to mind:
|
||||
“What if I have funds in an MMGen wallet and I lose the software? How do I
|
||||
recover my coins?”
|
||||
|
||||
Let's take this scenario to its logical extreme and assume you've lost all
|
||||
backup copies of the software, MMGen's project page has disappeared from Github
|
||||
(or been hacked) and no other repositories or copies are available on the
|
||||
Internet. The following tutorial will show you how to recover your keys in the
|
||||
event this unlikely combination of circumstances ever occurs.
|
||||
|
||||
#### <a name='a_rs'>Obtaining the binary seed</a>
|
||||
|
||||
To keep things simple, we'll assume you have a copy of your seed in hexadecimal
|
||||
(mmhex) format. If your backup's in mnemonic format, skip to the section
|
||||
'Converting an MMGen mnemonic to hexadecimal format' below and return here when you've
|
||||
finished. If your backup is an MMGen wallet, it will need to be decrypted.
|
||||
That case will be covered in a future tutorial.
|
||||
|
||||
Okay, so let's say you have a 128-bit seed with Seed ID FE3C6545 and funds in
|
||||
the first three legacy uncompressed ('L') addresses of this seed. Here are the
|
||||
addresses:
|
||||
|
||||
FE3C6545 {
|
||||
1 1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL
|
||||
2 15EfKymfe3v7mqCaL174hTWSgBLFAHvtaR
|
||||
3 1CUDd6nPHdP5pT7nN8k2AA5WdKRaKPjmea
|
||||
}
|
||||
|
||||
Since you might have your funds in Segwit ('S') addresses, we'll consider that
|
||||
case too:
|
||||
|
||||
FE3C6545 SEGWIT {
|
||||
1 3LpkKqtGkcCukRrgEFWyCajSApioiEWeTw
|
||||
2 3FYZQyWqBJcCjaSjCV9ZVj3gKyB9u8AYCX
|
||||
3 37wM8hwt69qwH7hZHAMn6RVdc8vMuM1CwJ
|
||||
}
|
||||
|
||||
Keys for MMGen's compressed ('C') addresses are generated in a similar way as
|
||||
Segwit ones, as you'll see below, so we won't consider that case separately.
|
||||
|
||||
Here's the seed itself in mmhex format, which you've stored in some safe place (on
|
||||
paper in a safe-deposit box, for example):
|
||||
|
||||
afc3fe 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e
|
||||
|
||||
Now your task is to generate keys for the addresses so you can spend your coins.
|
||||
This task is divided into two parts:
|
||||
|
||||
1. generating the keys and converting them to hexadecimal format; and
|
||||
2. converting the hex keys to wallet interchange (WIF) format for importation
|
||||
into Bitcoin Core or some other wallet.
|
||||
|
||||
We'll solve this task using standard command-line utilities available on any
|
||||
Linux or other Unix-like system.
|
||||
|
||||
> #### <a name='a_ss'>Convert the seed to binary (legacy addresses)</a>
|
||||
|
||||
> For the legacy addresses, we begin by converting the seed to binary form and
|
||||
> storing it in a file. For that we use 'xxd', a handy tool for converting binary
|
||||
> to hex and vice versa. Don't forget to omit the checksum from the seed and
|
||||
> remove the spaces:
|
||||
|
||||
$ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin
|
||||
|
||||
> #### <a name='a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
|
||||
|
||||
> For the other address types, we first “cook” the seed with an identifier
|
||||
> string using the HMAC-SHA256 algorithm, add ten rounds of SHA256, and save the
|
||||
> result in binary form. This can be done with the 'openssl' utility, also
|
||||
> included by default on Unix-based systems:
|
||||
|
||||
$ echo -n segwit | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > cooked-seed.bin
|
||||
|
||||
> If your addresses are of the compressed ('C') type, just use the string
|
||||
> 'compressed' instead of 'segwit' as the 'echo' command's argument.
|
||||
|
||||
> Now add the ten rounds of sha256:
|
||||
|
||||
$ openssl dgst -sha256 -binary cooked-seed.bin > cooked-round1.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round1.bin > cooked-round2.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round2.bin > cooked-round3.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round3.bin > cooked-round4.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round4.bin > cooked-round5.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round5.bin > cooked-round6.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round6.bin > cooked-round7.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round7.bin > cooked-round8.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round8.bin > cooked-round9.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round9.bin > myseed.bin
|
||||
|
||||
#### <a name='a_gk'>Generating the keys</a>
|
||||
|
||||
The MMGen key-generating algorithm uses a chain of SHA-512 hashes with double
|
||||
SHA-256 branches to generate the keys from which each address is derived. To
|
||||
obtain the chain's first link, we make a single SHA-512 hash of the seed and
|
||||
save it in binary form:
|
||||
|
||||
$ sha512sum myseed.bin | xxd -r -p > link1.bin
|
||||
|
||||
A double SHA-256 hash of the first link gives us the key of our first address:
|
||||
|
||||
$ sha256sum link1.bin | xxd -r -p | sha256sum
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 -
|
||||
|
||||
Or, in the Segwit case:
|
||||
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 -
|
||||
|
||||
With 'mmgen-tool', we can easily generate the WIF key and address from this
|
||||
hexadecimal key and see that it's correct:
|
||||
|
||||
$ mmgen-tool hex2wif 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
|
||||
|
||||
Or, in the Segwit case:
|
||||
|
||||
$ mmgen-tool hex2wif b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 compressed=1
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
|
||||
# for a compressed ('C') address, leave out the 'segwit=1' argument
|
||||
$ mmgen-tool wif2addr L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F segwit=1
|
||||
3LpkKqtGkcCukRrgEFWyCajSApioiEWeTw # matches FE3C6545:S:1 above
|
||||
|
||||
But since we're trying to do this without the MMGen software, we need to find
|
||||
some other way to do the hex-to-WIF conversion. We could use one of many
|
||||
key-manipulation tools available on the Internet, such as [this one][01], or
|
||||
[this one][02]. Or we can do it ourselves: that will be covered in the next
|
||||
section.
|
||||
|
||||
Meanwhile, let's finish generating hex keys for the rest of our addresses. To
|
||||
get the next key, we generate the next link in the chain from the first link and
|
||||
take its double SHA-256 hash, just as we did for the first one:
|
||||
|
||||
$ sha512sum link1.bin | xxd -r -p > link2.bin
|
||||
$ sha256sum link2.bin | xxd -r -p | sha256sum
|
||||
5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 - (uncompressed example)
|
||||
42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d - (Segwit example)
|
||||
|
||||
And so on and so forth, until we've generated all the keys we need: three, in our case.
|
||||
|
||||
#### <a name='a_hw'>Hex to WIF by hand</a>
|
||||
|
||||
Since we've chosen to convert our hex keys to WIF format manually, we have a bit
|
||||
of work ahead of us. Let's begin with our just-generated key #1 from seed
|
||||
FE3C6545:
|
||||
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 (uncompressed example)
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 (Segwit example)
|
||||
|
||||
WIF format prepends hex '80' to the beginning of the key. If the key is
|
||||
associated with a compressed public key, it also appends '01':
|
||||
|
||||
# uncompressed example:
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
|
||||
# Segwit example (Segwit uses compressed public keys):
|
||||
80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a001
|
||||
|
||||
The Base58Check format invented by Satoshi for Bitcoin addresses and keys
|
||||
contains a checksum, which we now generate by taking the first four bytes (eight
|
||||
characters) of the double SHA-256 of the above result:
|
||||
|
||||
|
||||
# uncompressed example:
|
||||
$ echo 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 | xxd -r -p | sha256sum | xxd -r -p | sha256sum | cut -c 1-8
|
||||
7b818629
|
||||
|
||||
# Segwit example:
|
||||
$ echo 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a001 | xxd -r -p | sha256sum | xxd -r -p | sha256sum | cut -c 1-8
|
||||
89bba812
|
||||
|
||||
The checksum gets appended to the end, giving us the following final result:
|
||||
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629 (uncompressed example)
|
||||
80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812 (Segwit example)
|
||||
|
||||
The last step is to convert all this into Base 58. Satoshi created Base-58
|
||||
encoding for convenient and error-free writing down and dictating of Bitcoin
|
||||
keys and addresses. He began with a Base-62 alphabet consisting of the ten
|
||||
digits plus the upper and lower case Latin letters (10 + 26 + 26 = 62):
|
||||
|
||||
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz
|
||||
|
||||
Since '0' (zero) is easily confused with capital 'O' visually, and capital 'I'
|
||||
with lowercase 'l', he dropped those characters, leaving the following 58:
|
||||
|
||||
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
|
||||
|
||||
With '0' gone, '1' now represents decimal zero, '2' represents decimal one, and
|
||||
so forth all the way up to 'z', representing decimal fifty-seven.
|
||||
|
||||
Now all that remains is to convert our hexadecimal key to decimal and then Base
|
||||
58 using this alphabet. This can be done in just four lines of code you can try
|
||||
out at the Python prompt:
|
||||
|
||||
# uncompressed example:
|
||||
$ python
|
||||
>>> b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
>>> num = int('8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629',16)
|
||||
>>> result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
>>> print ''.join(reversed(result)).lstrip('1')
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi # matches key for FE3C6545:L:1 above
|
||||
|
||||
# Segwit example has the following differences:
|
||||
...
|
||||
>>> num = int('80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812',16)
|
||||
...
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F # matches key for FE3C6545:S:1 above
|
||||
|
||||
Explanation: the variable 'b58a' holds the Base 58 alphabet; 'num' holds the key
|
||||
in decimal, converted from hexidecimal by Python's `int()` function; the third
|
||||
line does the base-58 conversion; and the last line formats the result by
|
||||
reversing the order of the digits, converting it to a string and stripping off
|
||||
the leading zeroes ('1's).
|
||||
|
||||
Programmers unfamiliar with Python might find the following base conversion code
|
||||
clearer:
|
||||
|
||||
def numtob58(n):
|
||||
result = []
|
||||
while n:
|
||||
result = result + [b58a[n % 58]] # divide 'n' by 58 and take the remainder
|
||||
n = n / 58
|
||||
return result
|
||||
|
||||
result = numtob58(num)
|
||||
|
||||
Adapting our code a bit and putting it in a file gives us have a handy
|
||||
conversion utility we can use for any key:
|
||||
|
||||
$ cat hex2b58.py
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
num = int(sys.argv[1],16)
|
||||
result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
print ''.join(reversed(result)).lstrip('1')
|
||||
|
||||
$ hex2b58.py 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
|
||||
#### <a name='a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
|
||||
|
||||
Our familiar base-10 system uses a series of ten symbols known as digits to
|
||||
represent numbers from zero to nine:
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
|
||||
If a number has more than one digit, its value is the sum of its digits
|
||||
multiplied by increasing powers of ten, beginning with the rightmost, least
|
||||
significant digit (the “ones column”).
|
||||
|
||||
Thus the number 1234, for example, can be represented as follows:
|
||||
|
||||
4 x 1 +
|
||||
3 x 10 +
|
||||
2 x 100 +
|
||||
1 x 1000
|
||||
|
||||
Or in exponential notation:
|
||||
|
||||
4 x 10^0 +
|
||||
3 x 10^1 +
|
||||
2 x 10^2 +
|
||||
1 x 10^3
|
||||
|
||||
An MMGen seed mnemonic is a number too, only the “digits” it's comprised of come
|
||||
from an alphabetically sorted series of 1626 words, the [Electrum wordlist][03],
|
||||
which begins like this:
|
||||
|
||||
able (0), about (1), above (2), abuse (3), accept (4) ...
|
||||
|
||||
and ends like this:
|
||||
|
||||
yet (1621), young (1622), yours (1623), yourself (1624), youth (1625)
|
||||
|
||||
(Type `mmgen-tool mn_printlist` to see the full list)
|
||||
|
||||
The words of the Electrum wordlist thus make up a base-1626 numbering system,
|
||||
just like the ten digits that make up our familiar base-10 system.
|
||||
|
||||
Here's the mnemonic of our seed (FE3C6545):
|
||||
|
||||
dude foot desperate tie stood themselves trip descend cease suicide apple busy
|
||||
|
||||
To decode it, we begin by listing its words, from least to most significant,
|
||||
along with the value of each word corresponding to its position in the wordlist:
|
||||
|
||||
busy - 200
|
||||
apple - 59
|
||||
suicide - 1384
|
||||
cease - 221
|
||||
descend - 379
|
||||
trip - 1493
|
||||
themselves - 1433
|
||||
stood - 1348
|
||||
tie - 1459
|
||||
desperate - 386
|
||||
foot - 562
|
||||
dude - 439
|
||||
|
||||
All that remains is to multiply the values by increasing powers of 1626 and sum
|
||||
the results:
|
||||
|
||||
200 x 1626^0 +
|
||||
59 x 1626^1 +
|
||||
1384 x 1626^2 +
|
||||
221 x 1626^3 +
|
||||
379 x 1626^4 +
|
||||
1493 x 1626^5 +
|
||||
1433 x 1626^6 +
|
||||
1348 x 1626^7 +
|
||||
1459 x 1626^8 +
|
||||
386 x 1626^9 +
|
||||
562 x 1626^10 +
|
||||
439 x 1626^11
|
||||
|
||||
While we could do this with pencil and paper, a few lines of Python code will
|
||||
make life much easier:
|
||||
|
||||
$ python
|
||||
>>> sum = power = 0
|
||||
>>> for word in 200,59,1384,221,379,1493,1433,1348,1459,386,562,439:
|
||||
>>> sum += word * 1626 ** power
|
||||
>>> power += 1
|
||||
>>> print sum
|
||||
92285275468192044354531703963345906238 # the result in decimal
|
||||
>>> print '{:x}'.format(sum)
|
||||
456d7f5f1c4bfe3bc916b87560ae6a3e # the result in hexadecimal: matches our original hex seed above
|
||||
|
||||
In case you're wondering why 1626 was chosen as the base: 1626 is just large
|
||||
enough to allow a 128-bit seed to be represented by twelve words. This can also
|
||||
be demonstrated at the Python prompt:
|
||||
|
||||
$ python
|
||||
>>> 1626**12 >= 2**128
|
||||
True
|
||||
>>> 1625**12 >= 2**128
|
||||
False
|
||||
|
||||
[01]: https://github.com/casascius/Bitcoin-Address-Utility
|
||||
[02]: https://github.com/matja/bitcoin-tool
|
||||
[03]: https://github.com/spesmilo/electrum/blob/1.9.5/lib/mnemonic.py
|
||||
|
|
@ -39,7 +39,7 @@ opts_data = lambda: {
|
|||
|
||||
AVAILABLE COMMANDS
|
||||
|
||||
setup - setup up system for regtest operation with MMGen
|
||||
setup - set up system for regtest operation with MMGen
|
||||
stop - stop the regtest bitcoind
|
||||
bob - switch to Bob's wallet, starting daemon if necessary
|
||||
alice - switch to Alice's wallet, starting daemon if necessary
|
||||
|
|
|
|||
|
|
@ -16,15 +16,10 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ------------------------------------------------------------------------------
|
||||
# MMGen note: this is a sorted version of the wordlist. The original
|
||||
# can be found at:
|
||||
# https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py
|
||||
# and in the file 'wordlists/mnemonic.py' of the mmgen distribution.
|
||||
# ------------------------------------------------------------------------------
|
||||
# Electrum - lightweight Bitcoin client
|
||||
# Copyright (C) 2011 thomasv@gitorious
|
||||
# list of words from:
|
||||
# http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists/Contemporary_poetry
|
||||
# MMGen note: this is a sorted version of the wordlist.
|
||||
# The original can be found at:
|
||||
# https://github.com/spesmilo/electrum/blob/1.9.5/lib/mnemonic.py
|
||||
# Electrum - lightweight Bitcoin client. Copyright (C) 2011 thomasv@gitorious
|
||||
|
||||
words = """
|
||||
able
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue