update documentation from wiki
This commit is contained in:
parent
4f3f031a3b
commit
ca41862f60
14 changed files with 1367 additions and 907 deletions
|
|
@ -7,27 +7,35 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
|
||||
> Make sure the required boost library development packages are installed:
|
||||
|
||||
sudo apt-get install libboost-system-dev libboost-filesystem-dev libboost-program-options-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev
|
||||
```text
|
||||
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:
|
||||
|
||||
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libdb-dev libdb++-dev libevent-dev
|
||||
```text
|
||||
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:
|
||||
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
```text
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
```
|
||||
|
||||
> Configure and build:
|
||||
|
||||
$ git tag # look for your desired version in the tag list
|
||||
$ git checkout <version>
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
```text
|
||||
$ git tag # look for your desired version in the tag list
|
||||
$ git checkout <version>
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
```
|
||||
|
||||
> 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
|
||||
|
|
@ -40,16 +48,20 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
> 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
|
||||
$ sudo install -sv bitcoind bitcoin-cli /usr/local/bin
|
||||
```text
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind bitcoin-cli /usr/local/bin
|
||||
```
|
||||
|
||||
### Compile and install Bitcoin Cash Node (optional):
|
||||
|
||||
> If you want to transact BCH, also known as “Bitcoin Cash Node”, then first
|
||||
> clone the Bitcoin Cash Node repository:
|
||||
|
||||
$ git clone https://github.com/bitcoin-cash-node/bitcoin-cash-node
|
||||
$ cd bitcoin-cash-node
|
||||
```text
|
||||
$ git clone https://github.com/bitcoin-cash-node/bitcoin-cash-node
|
||||
$ cd bitcoin-cash-node
|
||||
```
|
||||
|
||||
> Then configure and build using the same configure and build steps as with
|
||||
> Bitcoin Core above.
|
||||
|
|
@ -57,8 +69,10 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
> The resulting executable is also named 'bitcoind', so you must install it
|
||||
> under a different name to avoid overwriting your Core daemon:
|
||||
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind /usr/local/bin/bitcoind-bchn
|
||||
```text
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind /usr/local/bin/bitcoind-bchn
|
||||
```
|
||||
|
||||
> From now on, you’ll invoke the daemon as 'bitcoind-bchn' instead of 'bitcoind'.
|
||||
|
||||
|
|
@ -66,14 +80,18 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
|
||||
> Clone the Litecoin Core repository:
|
||||
|
||||
$ git clone https://github.com/litecoin-project/litecoin.git
|
||||
$ cd litecoin
|
||||
```text
|
||||
$ git clone https://github.com/litecoin-project/litecoin.git
|
||||
$ cd litecoin
|
||||
```
|
||||
|
||||
> Configure and build using the configure and build steps for Bitcoin Core,
|
||||
> and then install as follows:
|
||||
|
||||
$ cd src
|
||||
$ sudo install -sv litecoind litecoin-cli /usr/local/bin
|
||||
```text
|
||||
$ cd src
|
||||
$ sudo install -sv litecoind litecoin-cli /usr/local/bin
|
||||
```
|
||||
|
||||
Refer to [Run][02] on the binary installation page for instructions on running
|
||||
your coin daemon(s).
|
||||
|
|
@ -82,8 +100,10 @@ Alternatively, you may download and use the node start and stop scripts from the
|
|||
MMGenLive project, which simplify starting and stopping multiple daemons on the
|
||||
same machine:
|
||||
|
||||
$ curl -O 'https://raw.githubusercontent.com/mmgen/MMGenLive/master/home.mmgen/bin/mmlive-node-{start,stop}'
|
||||
$ sudo install -v mmlive-node-{start,stop} /usr/local/bin
|
||||
```text
|
||||
$ curl -O 'https://raw.githubusercontent.com/mmgen/MMGenLive/master/home.mmgen/bin/mmlive-node-{start,stop}'
|
||||
$ sudo install -v mmlive-node-{start,stop} /usr/local/bin
|
||||
```
|
||||
|
||||
[01]: Install-Bitcoind
|
||||
[02]: Install-Bitcoind#a_r
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ synchronize often (once a week, for example) and take care to import your
|
|||
addresses **before** spending into them, then it’s possible to get by with a
|
||||
more low-powered computer as your online machine.
|
||||
|
||||
### <a name='a_d'>Download:</a>
|
||||
### <a id="a_d">Download:</a>
|
||||
|
||||
> **Bitcoin Core:**
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ more low-powered computer as your online machine.
|
|||
>> versions appropriate for your online and offline computers. Windows users
|
||||
>> should choose the executable installer.
|
||||
|
||||
### <a name='a_i'>Install (both online and offline computers):</a>
|
||||
### <a id="a_i">Install (both online and offline computers):</a>
|
||||
|
||||
> **Bitcoin Core:**
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ more low-powered computer as your online machine.
|
|||
>> **Linux:** Unpack the archive and copy the `litecoind` and
|
||||
>> `litecoin-cli` binaries to `/usr/local/bin`.
|
||||
|
||||
### <a name='a_r'>Run (both online and offline computers):</a>
|
||||
### <a id="a_r">Run (both online and offline computers):</a>
|
||||
|
||||
> **Windows:**
|
||||
|
||||
|
|
@ -77,15 +77,17 @@ more low-powered computer as your online machine.
|
|||
>> background, so to run multiple daemons simultaneously you must start each
|
||||
>> one in a separate terminal window. Start your daemons like this:
|
||||
|
||||
# Bitcoin Core:
|
||||
$ bitcoind
|
||||
```text
|
||||
# Bitcoin Core:
|
||||
$ bitcoind
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir $APPDATA/Bitcoin-Cash-Node
|
||||
$ bitcoind-bchn --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin-Cash-Node --usecashaddr=0
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir $APPDATA/Bitcoin-Cash-Node
|
||||
$ bitcoind-bchn --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin-Cash-Node --usecashaddr=0
|
||||
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
```
|
||||
|
||||
>> Note that the `--listen=0` argument is required only when running Bitcoin
|
||||
>> Core and Bitcoin Cash Node simultaneously.
|
||||
|
|
@ -94,26 +96,30 @@ more low-powered computer as your online machine.
|
|||
|
||||
>> Linux users start their daemons like this:
|
||||
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
```text
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir ~/.bitcoin-bchn
|
||||
$ bitcoind-bchn --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-bchn --usecashaddr=0
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir ~/.bitcoin-bchn
|
||||
$ bitcoind-bchn --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-bchn --usecashaddr=0
|
||||
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
```
|
||||
|
||||
> Communicate with your daemons like this:
|
||||
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
```text
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ bitcoin-cli-bchn --rpcport=8442 help
|
||||
# Bitcoin Cash Node:
|
||||
$ bitcoin-cli-bchn --rpcport=8442 help
|
||||
|
||||
# Litecoin:
|
||||
$ litecoin-cli help
|
||||
# Litecoin:
|
||||
$ litecoin-cli help
|
||||
```
|
||||
|
||||
> Warning: If you’re using an existing Bitcoin or Litecoin installation, **move
|
||||
> your wallet.dat out of harm’s way** before starting the daemon. The new
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
*NOTE: the instructions on this page are for a Bitcoin-only setup. For
|
||||
altcoin support, additional installation steps are required. See
|
||||
[**Altcoin and Forkcoin Support**][af] for more information.*
|
||||
altcoin support, additional installation steps are required. See*
|
||||
[**Altcoin and Forkcoin Support**][af] *for more information.*
|
||||
|
||||
### Perform the following steps on both your online and offline computers:
|
||||
|
||||
|
|
@ -10,27 +10,40 @@ For computers with no Internet connection, see **Note for offline machines** bel
|
|||
|
||||
##### Debian/Ubuntu:
|
||||
|
||||
$ sudo apt-get install curl git gcc libtool make autoconf libgmp-dev libssl-dev libpcre3-dev libmpfr-dev libmpc-dev python3-dev python3-pip
|
||||
```text
|
||||
$ sudo apt-get install curl git gcc libtool make autoconf libgmp-dev libssl-dev libpcre3-dev libmpfr-dev libmpc-dev python3-dev python3-pip
|
||||
```
|
||||
|
||||
##### Arch Linux:
|
||||
|
||||
$ sudo pacman -S curl git gcc libtool make autoconf automake autogen pcre python-pip
|
||||
```text
|
||||
$ sudo pacman -S curl git gcc libtool make autoconf automake autogen pcre python-pip
|
||||
```
|
||||
|
||||
#### Upgrade the build tools:
|
||||
|
||||
$ python3 -m pip install --user --upgrade pip setuptools build wheel
|
||||
```text
|
||||
$ python3 -m pip install --user --upgrade pip setuptools build wheel
|
||||
```
|
||||
|
||||
If you get an ‘externally-managed-environment’ error (with Debian bookworm,
|
||||
for example), add --break-system-packages to the command line. Note that this
|
||||
will not in fact break any system packages, as pip installs all packages under
|
||||
the user’s home directory when --user is in effect.
|
||||
|
||||
#### Install MMGen:
|
||||
|
||||
Make sure that `~/.local/bin` is in `PATH`. Existing MMGen users should delete
|
||||
any old installations under `/usr` or `/usr/local`.
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen
|
||||
$ git checkout stable_linux # see 'Note' below
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user --upgrade dist/*.whl # see 'Install Note' below
|
||||
$ cd ..
|
||||
```text
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen
|
||||
$ git checkout stable_linux # see 'Note' below
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user --upgrade dist/*.whl # see 'Install Note' below
|
||||
$ cd ..
|
||||
```
|
||||
|
||||
**Note:** if you want to use features that have appeared since the latest
|
||||
`stable_linux` release, then you can omit the `git checkout` step and remain on
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ synchronize often (once a week, for example) and take care to import your
|
|||
addresses **before** spending into them, then it’s possible to get by with a
|
||||
more low-powered computer as your online machine.
|
||||
|
||||
### <a name='a_d'>Download:</a>
|
||||
### <a id="a_d">Download:</a>
|
||||
|
||||
> **Bitcoin Core:**
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ more low-powered computer as your online machine.
|
|||
>> versions appropriate for your online and offline computers. Windows users
|
||||
>> should choose the executable installer.
|
||||
|
||||
### <a name='a_i'>Install (both online and offline computers):</a>
|
||||
### <a id="a_i">Install (both online and offline computers):</a>
|
||||
|
||||
> **Bitcoin Core:**
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ more low-powered computer as your online machine.
|
|||
>> **Linux:** Unpack the archive and copy the `litecoind` and
|
||||
>> `litecoin-cli` binaries to `/usr/local/bin`.
|
||||
|
||||
### <a name='a_r'>Run (both online and offline computers):</a>
|
||||
### <a id="a_r">Run (both online and offline computers):</a>
|
||||
|
||||
> **Windows:**
|
||||
|
||||
|
|
@ -77,15 +77,17 @@ more low-powered computer as your online machine.
|
|||
>> background, so to run multiple daemons simultaneously you must start each
|
||||
>> one in a separate terminal window. Start your daemons like this:
|
||||
|
||||
# Bitcoin Core:
|
||||
$ bitcoind
|
||||
```text
|
||||
# Bitcoin Core:
|
||||
$ bitcoind
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir $APPDATA/Bitcoin-Cash-Node
|
||||
$ bitcoind-bchn --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin-Cash-Node --usecashaddr=0
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir $APPDATA/Bitcoin-Cash-Node
|
||||
$ bitcoind-bchn --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin-Cash-Node --usecashaddr=0
|
||||
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
```
|
||||
|
||||
>> Note that the `--listen=0` argument is required only when running Bitcoin
|
||||
>> Core and Bitcoin Cash Node simultaneously.
|
||||
|
|
@ -94,26 +96,30 @@ more low-powered computer as your online machine.
|
|||
|
||||
>> Linux users start their daemons like this:
|
||||
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
```text
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir ~/.bitcoin-bchn
|
||||
$ bitcoind-bchn --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-bchn --usecashaddr=0
|
||||
# Bitcoin Cash Node:
|
||||
$ mkdir ~/.bitcoin-bchn
|
||||
$ bitcoind-bchn --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-bchn --usecashaddr=0
|
||||
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
```
|
||||
|
||||
> Communicate with your daemons like this:
|
||||
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
```text
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
|
||||
# Bitcoin Cash Node:
|
||||
$ bitcoin-cli-bchn --rpcport=8442 help
|
||||
# Bitcoin Cash Node:
|
||||
$ bitcoin-cli-bchn --rpcport=8442 help
|
||||
|
||||
# Litecoin:
|
||||
$ litecoin-cli help
|
||||
# Litecoin:
|
||||
$ litecoin-cli help
|
||||
```
|
||||
|
||||
> Warning: If you’re using an existing Bitcoin or Litecoin installation, **move
|
||||
> your wallet.dat out of harm’s way** before starting the daemon. The new
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
* [1. Install MSYS2](#a_ms)
|
||||
* [2. Set up PowerShell as your MSYS2 terminal](#a_ps)
|
||||
* [3. Upgrade MSYS2](#a_ug)
|
||||
* [Online users](#a_ug1)
|
||||
* [Offline install](#a_ug2)
|
||||
* [Online users](#a_ug1)
|
||||
* [Offline install](#a_ug2)
|
||||
* [4. Install MSYS2 MMGen dependencies](#a_md)
|
||||
* [Offline install](#a_md1)
|
||||
* [Offline install](#a_md1)
|
||||
* [5. Set up your environment](#a_ev)
|
||||
* [6. Install the Python ECDSA library (offline install only)](#a_ec)
|
||||
* [7. Install the standalone scrypt package (required for strong password hashing)](#a_sc)
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
* [MSYS2](#a_us)
|
||||
* [MMGen](#a_um)
|
||||
|
||||
## <a name='a_i'>Introduction</a>
|
||||
## <a id="a_i">Introduction</a>
|
||||
|
||||
MMGen is supported on Microsoft Windows via [MSYS2][mh], which provides a
|
||||
Unix-like command-line environment within Windows. Windows 7 and later versions
|
||||
|
|
@ -53,9 +53,9 @@ that’s *already* offline. These steps will be additionally outlined in
|
|||
sections entitled **Offline install.** When doing an online install you may
|
||||
skip over these sections.
|
||||
|
||||
## <a name='a_m'>Install MSYS2 and MMGen</a>
|
||||
## <a id="a_m">Install MSYS2 and MMGen</a>
|
||||
|
||||
### <a name='a_ms'>1. Install MSYS2</a>
|
||||
### <a id="a_ms">1. Install MSYS2</a>
|
||||
|
||||
Download the MSYS2 executable installer for your architecture from the [MSYS2
|
||||
homepage][mh], but ignore the installation instructions there.
|
||||
|
|
@ -63,7 +63,7 @@ homepage][mh], but ignore the installation instructions there.
|
|||
Run the installer, accepting all defaults. At the end of the installation,
|
||||
uncheck “Run MSYS2 now” and click Finish.
|
||||
|
||||
### <a name='a_ps'>2. Set up PowerShell as your MSYS2 terminal</a>
|
||||
### <a id="a_ps">2. Set up PowerShell as your MSYS2 terminal</a>
|
||||
|
||||
MMGen is incompatible with the terminal provided by the MSYS2 project. However,
|
||||
it works just fine with Windows’ native PowerShell.
|
||||
|
|
@ -79,19 +79,22 @@ PowerShell. From now on, all your work will be done in this terminal.
|
|||
Note that the root of your MSYS2 installation is located in `C:\\msys64`, so the
|
||||
following commands, for example, will produce a listing of the same directory:
|
||||
|
||||
$ ls /etc # the path as seen within MSYS2
|
||||
$ ls 'C:\\msys64\etc' # the path as seen by Windows
|
||||
```text
|
||||
$ ls /etc # the path as seen within MSYS2
|
||||
$ ls 'C:\\msys64\etc' # the path as seen by Windows
|
||||
```
|
||||
|
||||
### <a id="a_ug">3. Upgrade MSYS2</a>
|
||||
|
||||
### <a name='a_ug'>3. Upgrade MSYS2</a>
|
||||
|
||||
#### <a name='a_ug1'>Online users:</a>
|
||||
#### <a id="a_ug1">Online users:</a>
|
||||
|
||||
> Optionally edit your mirror lists as described in **Offline install** below.
|
||||
|
||||
> Update the package database and core system packages:
|
||||
|
||||
$ pacman -Syu
|
||||
```text
|
||||
$ pacman -Syu
|
||||
```
|
||||
|
||||
> Exit and restart the terminal. If you’re using modified mirror lists, they
|
||||
> may have been overwritten by the update operation, in which case you should
|
||||
|
|
@ -99,9 +102,11 @@ following commands, for example, will produce a listing of the same directory:
|
|||
|
||||
> Now complete upgrading the system:
|
||||
|
||||
$ pacman -Su
|
||||
```text
|
||||
$ pacman -Su
|
||||
```
|
||||
|
||||
#### <a name='a_ug2'>Offline install:</a>
|
||||
#### <a id="a_ug2">Offline install:</a>
|
||||
|
||||
> You must now download the required database and package files from the
|
||||
> Internet on your online computer and copy them to your offline box. A USB
|
||||
|
|
@ -115,13 +120,17 @@ following commands, for example, will produce a listing of the same directory:
|
|||
> first in the list. For this you may use a text editor such as Notepad or
|
||||
> Nano:
|
||||
|
||||
$ nano /etc/pacman.d/mirrorlist.msys
|
||||
... repeat for remaining mirrorlist files ...
|
||||
```text
|
||||
$ nano /etc/pacman.d/mirrorlist.msys
|
||||
... repeat for remaining mirrorlist files ...
|
||||
```
|
||||
|
||||
> You need to update your database files as well. The database files and their
|
||||
> associated signature files can be listed by issuing the following command:
|
||||
|
||||
$ ls /var/lib/pacman/sync
|
||||
```text
|
||||
$ ls /var/lib/pacman/sync
|
||||
```
|
||||
|
||||
> Download up-to-date versions of these files from a fast MSYS2 mirror:
|
||||
|
||||
|
|
@ -135,6 +144,8 @@ following commands, for example, will produce a listing of the same directory:
|
|||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/clang64/clang64.db.sig>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/clang32/clang32.db>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/clang32/clang32.db.sig>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/clangarm64/clangarm64.db>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/clangarm64/clangarm64.db.sig>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/ucrt64/ucrt64.db>
|
||||
>> <https://mirror.yandex.ru/mirrors/msys2/mingw/ucrt64/ucrt64.db.sig>
|
||||
|
||||
|
|
@ -143,7 +154,9 @@ following commands, for example, will produce a listing of the same directory:
|
|||
|
||||
> Now issue the following command:
|
||||
|
||||
$ pacman -Sup > urls.txt
|
||||
```text
|
||||
$ pacman -Sup > urls.txt
|
||||
```
|
||||
|
||||
> This command may cause your MSYS terminal window to close. If so, just
|
||||
> reopen another one.
|
||||
|
|
@ -154,14 +167,18 @@ following commands, for example, will produce a listing of the same directory:
|
|||
|
||||
> Create a new folder on your offline machine:
|
||||
|
||||
$ mkdir packages1
|
||||
```text
|
||||
$ mkdir packages1
|
||||
```
|
||||
|
||||
Transfer the downloaded package files to the offline machine and place them in
|
||||
this folder.
|
||||
|
||||
> Now issue the following command to install the packages:
|
||||
|
||||
$ pacman -U packages1/*
|
||||
```text
|
||||
$ pacman -U packages1/*
|
||||
```
|
||||
|
||||
> When the process is finished, close your terminal window and reopen another
|
||||
> one.
|
||||
|
|
@ -172,12 +189,12 @@ this folder.
|
|||
|
||||
> Your system upgrade is now complete.
|
||||
|
||||
### <a name='a_md'>4. Install MSYS2 MMGen dependencies</a>
|
||||
### <a id="a_md">4. Install MSYS2 MMGen dependencies</a>
|
||||
|
||||
Now that your system’s fully up to date, you’re ready to install the packages
|
||||
specifically required by MMGen.
|
||||
|
||||
#### <a name='a_md1'>Offline install:</a>
|
||||
#### <a id="a_md1">Offline install:</a>
|
||||
|
||||
> As you’ve probably noticed by now, the command `pacman -S <pgknames>`
|
||||
> installs MSYS2 packages and their dependencies, while `pacman -Sp
|
||||
|
|
@ -189,118 +206,128 @@ specifically required by MMGen.
|
|||
|
||||
Install the MMGen requirements and their dependencies:
|
||||
|
||||
$ pacman -S tar git vim autoconf automake-wrapper autogen libtool cygrunsrv \
|
||||
mingw-w64-x86_64-python-build \
|
||||
mingw-w64-x86_64-python-wheel \
|
||||
mingw-w64-x86_64-python-pip \
|
||||
mingw-w64-x86_64-libltdl \
|
||||
mingw-w64-x86_64-gcc \
|
||||
mingw-w64-x86_64-make \
|
||||
mingw-w64-x86_64-pcre \
|
||||
mingw-w64-x86_64-libsodium \
|
||||
mingw-w64-x86_64-python-cryptography \
|
||||
mingw-w64-x86_64-python-six \
|
||||
mingw-w64-x86_64-python-pexpect \
|
||||
mingw-w64-x86_64-python-gmpy2 \
|
||||
mingw-w64-x86_64-python-pynacl \
|
||||
mingw-w64-x86_64-python-pysocks \
|
||||
mingw-w64-x86_64-python-requests \
|
||||
mingw-w64-x86_64-python-aiohttp \
|
||||
mingw-w64-x86_64-python-pyreadline3
|
||||
```text
|
||||
$ pacman -S tar git vim autoconf automake-wrapper autogen libtool cygrunsrv \
|
||||
mingw-w64-x86_64-python-build \
|
||||
mingw-w64-x86_64-python-wheel \
|
||||
mingw-w64-x86_64-python-pip \
|
||||
mingw-w64-x86_64-libltdl \
|
||||
mingw-w64-x86_64-gcc \
|
||||
mingw-w64-x86_64-make \
|
||||
mingw-w64-x86_64-pcre \
|
||||
mingw-w64-x86_64-libsodium \
|
||||
mingw-w64-x86_64-python-cryptography \
|
||||
mingw-w64-x86_64-python-six \
|
||||
mingw-w64-x86_64-python-pexpect \
|
||||
mingw-w64-x86_64-python-gmpy2 \
|
||||
mingw-w64-x86_64-python-pynacl \
|
||||
mingw-w64-x86_64-python-pysocks \
|
||||
mingw-w64-x86_64-python-requests \
|
||||
mingw-w64-x86_64-python-aiohttp \
|
||||
mingw-w64-x86_64-python-pyreadline3
|
||||
```
|
||||
|
||||
### <a name='a_ev'>5. Set up your environment</a>
|
||||
### <a id="a_ev">5. Set up your environment</a>
|
||||
|
||||
Create the `/usr/local/bin` directory. This is where you’ll place various
|
||||
binaries required by MMGen:
|
||||
|
||||
$ mkdir -p /usr/local/bin # seen by Windows as 'C:\\msys64\usr\local\bin'
|
||||
```text
|
||||
$ mkdir -p /usr/local/bin # seen by Windows as 'C:\\msys64\usr\local\bin'
|
||||
```
|
||||
|
||||
Open your shell’s runtime configuration file in a text editor:
|
||||
|
||||
$ nano ~/.bashrc
|
||||
```text
|
||||
$ nano ~/.bashrc
|
||||
```
|
||||
|
||||
Add the following two lines to the end of the file (if this is a Bitcoin-only
|
||||
installation, you may omit the Litecoin and Bitcoin Cash Node components of the
|
||||
path):
|
||||
|
||||
export PATH="$HOMEPATH/.local/bin:/mingw64/bin:$PATH:/c/Program Files/Bitcoin/daemon:/c/Program Files/Litecoin/daemon:/c/Program Files/Bitcoin-Cash-Node/daemon"
|
||||
export PYTHONUTF8=1
|
||||
```bash
|
||||
export PATH="$HOMEPATH/.local/bin:/mingw64/bin:$PATH:/c/Program Files/Bitcoin/daemon:/c/Program Files/Litecoin/daemon:/c/Program Files/Bitcoin-Cash-Node/daemon"
|
||||
export PYTHONUTF8=1
|
||||
```
|
||||
|
||||
Save and exit. Close and reopen the terminal window to update your working
|
||||
environment.
|
||||
|
||||
### <a name='a_ec'>6. Install the Python ECDSA library (offline install only)</a>
|
||||
### <a id="a_ec">6. Install the Python ECDSA library (offline install only)</a>
|
||||
|
||||
On your online machine:
|
||||
|
||||
$ pip3 download ecdsa
|
||||
```text
|
||||
$ pip3 download ecdsa
|
||||
```
|
||||
|
||||
Copy the downloaded file to your offline machine and install:
|
||||
|
||||
$ pip3 install --user ecdsa-*.whl
|
||||
```text
|
||||
$ pip3 install --user ecdsa-*.whl
|
||||
```
|
||||
|
||||
### <a name='a_sc'>7. Install the standalone scrypt package (required for strong password hashing)</a>
|
||||
### <a id="a_sc">7. Install the standalone scrypt package (required for strong password hashing)</a>
|
||||
|
||||
Thanks to a faulty implementation of the `scrypt` function included in Python’s
|
||||
`hashlib`, the standalone `scrypt` module is required for stronger-than-default
|
||||
password hashing, i.e. hash presets greater than `3`. Installing the package is
|
||||
therefore highly recommended.
|
||||
|
||||
On your online machine, download the tar archive:
|
||||
On your online machine, clone the Py-Scrypt source repository:
|
||||
|
||||
$ pip3 download --no-deps scrypt==0.8.20
|
||||
```text
|
||||
$ git clone https://github.com/holgern/py-scrypt.git
|
||||
```
|
||||
|
||||
On your offline machine, unpack and enter the archive:
|
||||
Copy the cloned repo to your offline machine.
|
||||
|
||||
$ tar fax scrypt-0.8.20.tar.gz
|
||||
$ cd scrypt-0.8.20
|
||||
On both online and offline machines, enter the repo root and install:
|
||||
|
||||
Open the file `setup.py` in your text editor. Right before the line reading:
|
||||
```text
|
||||
$ cd py-scrypt
|
||||
$ python3 setup.py install --user
|
||||
```
|
||||
|
||||
elif sys.platform.startswith('win32'):
|
||||
|
||||
insert the following lines, carefully preserving indentation:
|
||||
|
||||
elif os.environ.get('MSYSTEM') == 'MSYS':
|
||||
define_macros = []
|
||||
includes = ['/mingw64/include']
|
||||
libraries = ['libcrypto']
|
||||
CFLAGS.append('-O2')
|
||||
|
||||
Save the file and exit the editor. Now build and install:
|
||||
|
||||
$ python3 setup.py install --user
|
||||
|
||||
### <a name='a_se'>8. Clone and copy the secp256k1 library (offline install only)</a>
|
||||
### <a id="a_se">8. Clone and copy the secp256k1 library (offline install only)</a>
|
||||
|
||||
On your online machine, clone the secp256k1 repository from Github:
|
||||
|
||||
$ git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
```text
|
||||
$ git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
```
|
||||
|
||||
On your offline machine, create a magic location and copy the cloned secp256k1
|
||||
directory into it:
|
||||
|
||||
$ mkdir -p ~/.cache/mmgen
|
||||
$ cp -a /path/to/secp256k1/repo/secp256k1 ~/.cache/mmgen
|
||||
$ ls ~/.cache/mmgen/secp256k1/autogen.sh # check that the location is correct
|
||||
```text
|
||||
$ mkdir -p ~/.cache/mmgen
|
||||
$ cp -a /path/to/secp256k1/repo/secp256k1 ~/.cache/mmgen
|
||||
$ ls ~/.cache/mmgen/secp256k1/autogen.sh # check that the location is correct
|
||||
```
|
||||
|
||||
### <a name='a_mm'>9. Install MMGen</a>
|
||||
### <a id="a_mm">9. Install MMGen</a>
|
||||
|
||||
Now you’re ready to install MMGen itself. On your online machine, clone the
|
||||
repository:
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen
|
||||
Cloning into ’mmgen’...
|
||||
```text
|
||||
$ git clone https://github.com/mmgen/mmgen
|
||||
Cloning into ’mmgen’...
|
||||
```
|
||||
|
||||
If you’re doing an offline install, then copy the cloned mmgen directory to
|
||||
your offline machine.
|
||||
|
||||
Enter the repo directory, build and install:
|
||||
|
||||
$ cd mmgen
|
||||
$ git checkout stable_msys2 # See 'Note' below
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user --upgrade dist/*.whl
|
||||
```text
|
||||
$ cd mmgen
|
||||
$ git checkout stable_msys2 # See 'Note' below
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user --upgrade dist/*.whl
|
||||
```
|
||||
|
||||
**Note:** if you want to use features that have appeared since the latest
|
||||
`stable_msys2` release, then you can omit the `git checkout stable_msys2`
|
||||
|
|
@ -316,23 +343,29 @@ documentation.
|
|||
occasion. Note that MMGen has a test suite. Refer to the [Test Suite][ts]
|
||||
wiki page for details.
|
||||
|
||||
### <a name='a_pe'>10. Install Python Ethereum dependencies (Ethereum users only)</a>
|
||||
### <a id="a_pe">10. Install Python Ethereum dependencies (Ethereum users only)</a>
|
||||
|
||||
If you’ll be using MMGen with Ethereum, then you must install a few
|
||||
dependencies. From the MMGen repository root, type the following:
|
||||
|
||||
$ pip3 install --no-deps --user -r eth-requirements.txt
|
||||
```text
|
||||
$ pip3 install --no-deps --user -r eth-requirements.txt
|
||||
```
|
||||
|
||||
For an offline install, do this instead:
|
||||
|
||||
$ pip3 download --no-deps -r eth-requirements.txt
|
||||
```text
|
||||
$ pip3 download --no-deps -r eth-requirements.txt
|
||||
```
|
||||
|
||||
Then transfer the downloaded files to your offline machine, `cd` to the
|
||||
directory containing the files and install them as follows:
|
||||
|
||||
$ pip3 install --no-deps --user *.whl
|
||||
```text
|
||||
$ pip3 install --no-deps --user *.whl
|
||||
```
|
||||
|
||||
### <a name='a_cd'>11. Install and launch your coin daemons</a>
|
||||
### <a id="a_cd">11. Install and launch your coin daemons</a>
|
||||
|
||||
At this point your MMGen installation will be able to generate wallets, along
|
||||
with keys and addresses for all supported coins. However, if you intend to do
|
||||
|
|
@ -358,7 +391,7 @@ Please note that Ethereum daemons perform rather poorly under Windows due to
|
|||
threading limitations. Unless you have very fast hardware, transacting and
|
||||
syncing the blockchain might be painfully slow.
|
||||
|
||||
### <a name='a_do'>12. You’re done!</a>
|
||||
### <a id="a_do">12. You’re done!</a>
|
||||
|
||||
Congratulations, your installation is now complete, and you can proceed to
|
||||
[**Getting Started with MMGen**][gs]. Note that all features supported by
|
||||
|
|
@ -371,9 +404,9 @@ Please be aware of the following, however:
|
|||
+ The Bitcoin Cash Node daemon cannot handle non-ASCII pathnames. This is an
|
||||
issue with the Bitcoin Cash Node implementation for Windows, not MMGen.
|
||||
|
||||
## <a name='a_u'>Keeping your installation up to date</a>
|
||||
## <a id="a_u">Keeping your installation up to date</a>
|
||||
|
||||
### <a name='a_us'>MSYS2</a>
|
||||
### <a id="a_us">MSYS2</a>
|
||||
|
||||
You should periodically upgrade your MSYS2 installation, especially when [new
|
||||
releases][mh] of the installer appear. You can check your currently installed
|
||||
|
|
@ -386,7 +419,7 @@ parts relating to downloading and editing mirrorlists.
|
|||
Note that [Step 4](#a_md) need not be performed, as the MMGen dependencies
|
||||
are already in `pacman`’s database.
|
||||
|
||||
### <a name='a_um'>MMGen</a>
|
||||
### <a id="a_um">MMGen</a>
|
||||
|
||||
You should periodically upgrade your MMGen installation from the MMGen public
|
||||
repository, especially when [new releases][mr] appear. You can check your
|
||||
|
|
@ -396,13 +429,15 @@ currently installed version of MMGen by issuing the command `mmgen-tool
|
|||
To perform the upgrade, enter the MMGen repository root on your online
|
||||
computer and issue the following commands:
|
||||
|
||||
$ git checkout master
|
||||
$ git pull
|
||||
$ git checkout stable_msys2 # See 'Note' to step 9
|
||||
$ rm -rf dist build
|
||||
$ rm -r /mingw64/lib/python*/site-packages/{mmgen,MMGen}*
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --upgrade dist/*.whl
|
||||
```text
|
||||
$ git checkout master
|
||||
$ git pull
|
||||
$ git checkout stable_msys2 # See 'Note' to step 9
|
||||
$ rm -rf dist build
|
||||
$ rm -r /mingw64/lib/python*/site-packages/{mmgen,MMGen}*
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --upgrade dist/*.whl
|
||||
```
|
||||
|
||||
To update your offline installation, copy the updated repository (after `git
|
||||
pull`) to your offline machine, `cd` to the root of the copied repository and
|
||||
|
|
@ -411,14 +446,14 @@ continue from the `git checkout stable_msys2` step.
|
|||
[mh]: https://www.msys2.org
|
||||
[mp]: https://sourceforge.net/projects/msys2
|
||||
[mw]: https://github.com/msys2/msys2/wiki
|
||||
[ov]: https://github.com/mmgen/mmgen/releases/tag/v0.9.8
|
||||
[ov]: ../releases/tag/v0.9.8
|
||||
[sd]: https://download.sysinternals.com/files/SDelete.zip
|
||||
[og]: https://github.com/openethereum/openethereum/releases
|
||||
[mr]: https://github.com/mmgen/mmgen/releases
|
||||
[mr]: ../releases
|
||||
[di]: Deprecated-MSWin-Installation
|
||||
[ib]: Install-Bitcoind
|
||||
[gs]: Getting-Started-with-MMGen
|
||||
[pl]: Altcoin-and-Forkcoin-Support#a_oe
|
||||
[ax]: autosign-[MMGen-command-help]
|
||||
[ax]: command-help-autosign
|
||||
[mc]: Altcoin-and-Forkcoin-Support#a_xmr
|
||||
[ts]: Test-Suite
|
||||
|
|
|
|||
|
|
@ -16,26 +16,28 @@
|
|||
|
||||
#### [Key/address generation for 144 Bitcoin-derived altcoins](#a_kg)
|
||||
|
||||
### <a name='a_g'>Introduction</a>
|
||||
### <a id="a_g">Introduction</a>
|
||||
|
||||
Depending on your setup, the instructions on this page may apply to your
|
||||
offline machine, your online machine, or both. If you’re confused as to
|
||||
which, please familiarize yourself with the basics of MMGen by reading the
|
||||
[**Getting Started**][gs] guide.
|
||||
|
||||
### <a name='a_eth'>Ethereum (ETH), Ethereum Classic (ETC) and ERC20 Tokens</a>
|
||||
### <a id="a_eth">Ethereum (ETH), Ethereum Classic (ETC) and ERC20 Tokens</a>
|
||||
|
||||
MMGen supports all operations for Ethereum, Ethereum Classic and ERC20 tokens.
|
||||
In addition, ERC20 token creation and deployment are supported via the
|
||||
`create-token.py` script.
|
||||
|
||||
#### <a name='a_ed'>Install the Ethereum dependencies</a>
|
||||
#### <a id="a_ed">Install the Ethereum dependencies</a>
|
||||
|
||||
From the MMGen repository root, type:
|
||||
|
||||
$ python3 -m pip install --no-deps --user -r eth-requirements.txt
|
||||
```text
|
||||
$ python3 -m pip install --no-deps --user -r eth-requirements.txt
|
||||
```
|
||||
|
||||
#### <a name='a_oe'>Install and run Geth, Parity or OpenEthereum</a>
|
||||
#### <a id="a_oe">Install and run Geth, Parity or OpenEthereum</a>
|
||||
|
||||
MMGen can use either Go-Ethereum (Geth) or OpenEthereum to communicate with
|
||||
the Ethereum network. For information on installing Geth or OE on your
|
||||
|
|
@ -48,7 +50,9 @@ needn’t install them on your offline machine.
|
|||
|
||||
For Geth, the following command-line options are required:
|
||||
|
||||
--http --http.api=eth,web3,txpool --http.port=8745
|
||||
```text
|
||||
--http --http.api=eth,web3,txpool --http.port=8745
|
||||
```
|
||||
|
||||
Geth and OE have dropped support for Ethereum Classic, but MMGen supports
|
||||
transacting ETC via the legacy [Parity][pd] daemon. Invoke Parity with
|
||||
|
|
@ -58,7 +62,9 @@ same as for OpenEthereum.
|
|||
If you’re running OE or Parity on a different machine from MMGen, add the
|
||||
following options to the daemon command line:
|
||||
|
||||
--jsonrpc-hosts=all --jsonrpc-interface=<daemon IP address>
|
||||
```text
|
||||
--jsonrpc-hosts=all --jsonrpc-interface=<daemon IP address>
|
||||
```
|
||||
|
||||
To run OE or Parity offline, use `--mode=offline`, otherwise `--mode=active`.
|
||||
|
||||
|
|
@ -70,7 +76,7 @@ section below.
|
|||
You may require other options as well. Invoke your daemon with the `--help`
|
||||
switch for more complete information.
|
||||
|
||||
#### <a name='a_tx'>Transacting and other basic operations</a>
|
||||
#### <a id="a_tx">Transacting and other basic operations</a>
|
||||
|
||||
Basic operations with ETH, ETC and ERC20 tokens work as described in the
|
||||
[Getting Started][bo] guide, with some differences. Please note the following:
|
||||
|
|
@ -96,11 +102,15 @@ must be replaced with real ones.*
|
|||
|
||||
Generate some ETH addresses with your default wallet:
|
||||
|
||||
$ mmgen-addrgen --coin=eth 1-5
|
||||
```text
|
||||
$ mmgen-addrgen --coin=eth 1-5
|
||||
```
|
||||
|
||||
Create an EOS token tracking wallet and import the addresses into it:
|
||||
|
||||
$ mmgen-addrimport --coin=eth --token-addr=86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 ABCDABCD-ETH[1-5].addrs
|
||||
```text
|
||||
$ mmgen-addrimport --coin=eth --token-addr=86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 ABCDABCD-ETH[1-5].addrs
|
||||
```
|
||||
|
||||
*Unlike the case with BTC and derivatives, ETH and ETC tracking wallets are
|
||||
created and managed by MMGen itself and located under the MMGen data directory.
|
||||
|
|
@ -112,25 +122,33 @@ Now send 10+ EOS from an exchange or another wallet to address `ABCDABCD:E:1`.
|
|||
Then create a TX sending 10 EOS to third-party address `aabbccdd...`, with
|
||||
change to `ABCDABCD:E:2`:
|
||||
|
||||
$ mmgen-txcreate --coin=eth --token=eos aabbccddaabbccddaabbccddaabbccddaabbccdd,10 ABCDABCD:E:2
|
||||
```text
|
||||
$ mmgen-txcreate --coin=eth --token=eos aabbccddaabbccddaabbccddaabbccddaabbccdd,10 ABCDABCD:E:2
|
||||
```
|
||||
|
||||
On your offline machine, sign the TX:
|
||||
|
||||
$ mmgen-txsign --coin=eth --token=eos ABC123-EOS[10,50000].rawtx
|
||||
```text
|
||||
$ mmgen-txsign --coin=eth --token=eos ABC123-EOS[10,50000].rawtx
|
||||
```
|
||||
|
||||
*You can also set up and use [autosigning][X] on the offline machine.*
|
||||
|
||||
On your online machine, send the TX:
|
||||
|
||||
$ mmgen-txsend --coin=eth --token=eos ABC123-EOS[10,50000].sigtx
|
||||
```text
|
||||
$ mmgen-txsend --coin=eth --token=eos ABC123-EOS[10,50000].sigtx
|
||||
```
|
||||
|
||||
View your EOS tracking wallet:
|
||||
|
||||
$ mmgen-tool --coin=eth --token=eos twview
|
||||
```text
|
||||
$ mmgen-tool --coin=eth --token=eos twview
|
||||
```
|
||||
|
||||
To transact ETH instead of EOS, omit the `--token` and `--token-addr` arguments.
|
||||
|
||||
#### <a name='a_dt'>Creating and deploying ERC20 tokens</a>
|
||||
#### <a id="a_dt">Creating and deploying ERC20 tokens</a>
|
||||
|
||||
##### Install the Solidity compiler
|
||||
|
||||
|
|
@ -141,15 +159,17 @@ correct version is to compile it from source.
|
|||
|
||||
Clone the repository and build:
|
||||
|
||||
$ git clone --recursive https://github.com/ethereum/solidity.git
|
||||
$ cd solidity
|
||||
$ git checkout v0.8.7
|
||||
$ ./scripts/install_deps.sh
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DUSE_CVC4=OFF -DUSE_Z3=OFF ..
|
||||
$ make -j4 solc
|
||||
$ sudo install -v --strip solc/solc /usr/local/bin
|
||||
```text
|
||||
$ git clone --recursive https://github.com/ethereum/solidity.git
|
||||
$ cd solidity
|
||||
$ git checkout v0.8.7
|
||||
$ ./scripts/install_deps.sh
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DUSE_CVC4=OFF -DUSE_Z3=OFF ..
|
||||
$ make -j4 solc
|
||||
$ sudo install -v --strip solc/solc /usr/local/bin
|
||||
```
|
||||
|
||||
##### Create and deploy a token
|
||||
|
||||
|
|
@ -158,16 +178,20 @@ must replace them with real ones.*
|
|||
|
||||
Create a token 'MFT' with default parameters, owned by `ddeeff...` (`ABCDABCD:E:1`):
|
||||
|
||||
# Do this in the MMGen repository root:
|
||||
$ scripts/create-token.py --coin=ETH --symbol=MFT --name='My First Token' ddEEFFDdEEFfddEeffDDEefFdDeeFFDDEeFFddEe
|
||||
```text
|
||||
# Do this in the MMGen repository root:
|
||||
$ scripts/create-token.py --coin=ETH --symbol=MFT --name='My First Token' ddEEFFDdEEFfddEeffDDEefFdDeeFFDDEeFFddEe
|
||||
```
|
||||
|
||||
Deploy the token on the ETH blockchain:
|
||||
|
||||
$ mmgen-txdo --coin=eth --tx-gas=200000 --contract-data=SafeMath.bin
|
||||
$ mmgen-txdo --coin=eth --tx-gas=250000 --contract-data=Owned.bin
|
||||
$ mmgen-txdo --coin=eth --tx-gas=1100000 --contract-data=Token.bin
|
||||
...
|
||||
Token address: abcd1234abcd1234abcd1234abcd1234abcd1234
|
||||
```text
|
||||
$ mmgen-txdo --coin=eth --tx-gas=200000 --contract-data=SafeMath.bin
|
||||
$ mmgen-txdo --coin=eth --tx-gas=250000 --contract-data=Owned.bin
|
||||
$ mmgen-txdo --coin=eth --tx-gas=1100000 --contract-data=Token.bin
|
||||
...
|
||||
Token address: abcd1234abcd1234abcd1234abcd1234abcd1234
|
||||
```
|
||||
|
||||
*These Gas amounts seem to work for these three contracts, but feel free to
|
||||
experiment. Make sure you understand the difference between Gas amount and Gas
|
||||
|
|
@ -175,16 +199,20 @@ price!*
|
|||
|
||||
Create an MFT token tracking wallet and import your ETH addresses into it:
|
||||
|
||||
$ mmgen-addrimport --coin=eth --token-addr=abcd1234abcd1234abcd1234abcd1234abcd1234 ABCDABCD-ETH[1-5].addrs
|
||||
```text
|
||||
$ mmgen-addrimport --coin=eth --token-addr=abcd1234abcd1234abcd1234abcd1234abcd1234 ABCDABCD-ETH[1-5].addrs
|
||||
```
|
||||
|
||||
View your MFT tracking wallet:
|
||||
|
||||
$ mmgen-tool --coin=eth --token=mft twview
|
||||
```text
|
||||
$ mmgen-tool --coin=eth --token=mft twview
|
||||
```
|
||||
|
||||
Other token parameters can be customized too. Type `scripts/create-token.py --help`
|
||||
for details.
|
||||
|
||||
### <a name='a_bch'>Bitcoin Cash Node (BCH) and Litecoin (LTC)</a>
|
||||
### <a id="a_bch">Bitcoin Cash Node (BCH) and Litecoin (LTC)</a>
|
||||
|
||||
Bitcoin Cash Node (BCH) and Litecoin are fully supported by MMGen, on the same
|
||||
level as Bitcoin.
|
||||
|
|
@ -200,7 +228,7 @@ MMGen requires that the bitcoin-bchn daemon be listening on non-standard
|
|||
Then just add the `--coin=bch` or `--coin=ltc` option to all your MMGen
|
||||
commands. It’s that simple!
|
||||
|
||||
### <a name='a_xmr'>Monero (XMR)</a>
|
||||
### <a id="a_xmr">Monero (XMR)</a>
|
||||
|
||||
MMGen’s Monero support includes automated wallet creation/syncing and
|
||||
transaction creation/relaying via the `mmgen-xmrwallet` command. Make sure
|
||||
|
|
@ -215,7 +243,9 @@ private data on your online machine.*
|
|||
To generate five Monero key/address pairs from your default wallet, invoke the
|
||||
following, making sure to answer ‘y’ at the Encrypt prompt:
|
||||
|
||||
$ mmgen-keygen --coin=xmr 1-5
|
||||
```text
|
||||
$ mmgen-keygen --coin=xmr 1-5
|
||||
```
|
||||
|
||||
In addition to spend and view keys, the resulting key/address file also
|
||||
includes a wallet password for each address (the double SHA256 hash of the
|
||||
|
|
@ -224,19 +254,25 @@ spend key, truncated to 16 bytes).
|
|||
Now create a Monero wallet for each address in the file by invoking the
|
||||
following command:
|
||||
|
||||
$ mmgen-xmrwallet create *XMR*.akeys.mmenc
|
||||
```text
|
||||
$ mmgen-xmrwallet create *XMR*.akeys.mmenc
|
||||
```
|
||||
|
||||
Each wallet will be uniquely named using the address index and encrypted with
|
||||
the address’ unique wallet password. No user interaction is required during
|
||||
the creation process. By default, wallets are synced to the current block
|
||||
height, as they’re assumed to be empty, but this behavior can be overridden:
|
||||
|
||||
$ mmgen-xmrwallet --restore-height=123456 create *XMR*.akeys.mmenc
|
||||
```text
|
||||
$ mmgen-xmrwallet --restore-height=123456 create *XMR*.akeys.mmenc
|
||||
```
|
||||
|
||||
To keep your wallets in sync as the Monero blockchain grows, use the `sync`
|
||||
subcommand:
|
||||
|
||||
$ mmgen-xmrwallet sync *XMR*.akeys.mmenc
|
||||
```text
|
||||
$ mmgen-xmrwallet sync *XMR*.akeys.mmenc
|
||||
```
|
||||
|
||||
No user interaction is required here either, which is very helpful when you
|
||||
have multiple wallets requiring long sync times.
|
||||
|
|
@ -244,13 +280,15 @@ have multiple wallets requiring long sync times.
|
|||
`mmgen-xmrwallet` supports transacting via the `sweep` and `transfer`
|
||||
subcommands. Type `mmgen-xmrwallet --help` for details.
|
||||
|
||||
### <a name='a_zec'>Key/address generation for Zcash (ZEC)</a>
|
||||
### <a id="a_zec">Key/address generation for Zcash (ZEC)</a>
|
||||
|
||||
MMGen’s enhanced support for Zcash includes generation of **z-addresses.**
|
||||
|
||||
Generate ten Zcash z-address key/address pairs from your default wallet:
|
||||
|
||||
$ mmgen-keygen --coin=zec --type=zcash_z 1-10
|
||||
```text
|
||||
$ mmgen-keygen --coin=zec --type=zcash_z 1-10
|
||||
```
|
||||
|
||||
The addresses’ view keys are included in the output file as well.
|
||||
|
||||
|
|
@ -261,39 +299,50 @@ non-standard Scrypt hash preset, take care to remember it.
|
|||
|
||||
To generate Zcash t-addresses, just omit the `--type` argument:
|
||||
|
||||
$ mmgen-keygen --coin=zec 1-10
|
||||
```text
|
||||
$ mmgen-keygen --coin=zec 1-10
|
||||
```
|
||||
|
||||
### <a name='a_kg'>Key/address generation for 144 Bitcoin-derived altcoins</a>
|
||||
### <a id="a_kg">Key/address generation for 144 Bitcoin-derived altcoins</a>
|
||||
|
||||
To generate key/address pairs for these coins, just specify the coin’s symbol
|
||||
with the `--coin` argument:
|
||||
|
||||
# For DASH:
|
||||
$ mmgen-keygen --coin=dash 1-10
|
||||
# For Emercoin:
|
||||
$ mmgen-keygen --coin=emc 1-10
|
||||
```text
|
||||
# For DASH:
|
||||
$ mmgen-keygen --coin=dash 1-10
|
||||
|
||||
# For Emercoin:
|
||||
$ mmgen-keygen --coin=emc 1-10
|
||||
```
|
||||
|
||||
For compressed public keys, add the `--type=compressed` option:
|
||||
|
||||
$ mmgen-keygen --coin=dash --type=compressed 1-10
|
||||
```text
|
||||
$ mmgen-keygen --coin=dash --type=compressed 1-10
|
||||
```
|
||||
|
||||
If it’s just the addresses you want, then use `mmgen-addrgen` instead:
|
||||
|
||||
$ mmgen-addrgen --coin=dash --type=compressed 1-10
|
||||
```text
|
||||
$ mmgen-addrgen --coin=dash --type=compressed 1-10
|
||||
```
|
||||
|
||||
Regarding encryption of key/address files, see the note for Zcash above.
|
||||
|
||||
Here’s a complete list of supported altcoins as of this writing:
|
||||
|
||||
2give,42,611,ac,acoin,alf,anc,apex,arco,arg,aur,bcf,blk,bmc,bqc,bsty,btcd,
|
||||
btq,bucks,cann,cash,cat,cbx,ccn,cdn,chc,clam,con,cpc,crps,csh,dash,dcr,dfc,
|
||||
dgb,dgc,doge,doged,dope,dvc,efl,emc,emd,enrg,esp,fai,fc2,fibre,fjc,flo,flt,
|
||||
fst,ftc,gcr,good,grc,gun,ham,html5,hyp,icash,infx,inpay,ipc,jbs,judge,lana,
|
||||
lat,ldoge,lmc,ltc,mars,mcar,mec,mint,mobi,mona,moon,mrs,mue,mxt,myr,myriad,
|
||||
mzc,neos,neva,nka,nlg,nmc,nto,nvc,ok,omc,omni,onion,onx,part,pink,pivx,pkb,
|
||||
pnd,pot,ppc,ptc,pxc,qrk,rain,rbt,rby,rdd,ric,sdc,sib,smly,song,spr,start,
|
||||
sys,taj,tit,tpc,trc,ttc,tx,uno,via,vpn,vtc,wash,wdc,wisc,wkc,wsx,xcn,xgb,
|
||||
xmg,xpm,xpoke,xred,xst,xvc,zet,zlq,zoom,zrc,bch,etc,eth,ltc,xmr,zec
|
||||
```text
|
||||
2give,42,611,ac,acoin,alf,anc,apex,arco,arg,aur,bcf,blk,bmc,bqc,bsty,btcd,
|
||||
btq,bucks,cann,cash,cat,cbx,ccn,cdn,chc,clam,con,cpc,crps,csh,dash,dcr,dfc,
|
||||
dgb,dgc,doge,doged,dope,dvc,efl,emc,emd,enrg,esp,fai,fc2,fibre,fjc,flo,flt,
|
||||
fst,ftc,gcr,good,grc,gun,ham,html5,hyp,icash,infx,inpay,ipc,jbs,judge,lana,
|
||||
lat,ldoge,lmc,ltc,mars,mcar,mec,mint,mobi,mona,moon,mrs,mue,mxt,myr,myriad,
|
||||
mzc,neos,neva,nka,nlg,nmc,nto,nvc,ok,omc,omni,onion,onx,part,pink,pivx,pkb,
|
||||
pnd,pot,ppc,ptc,pxc,qrk,rain,rbt,rby,rdd,ric,sdc,sib,smly,song,spr,start,
|
||||
sys,taj,tit,tpc,trc,ttc,tx,uno,via,vpn,vtc,wash,wdc,wisc,wkc,wsx,xcn,xgb,
|
||||
xmg,xpm,xpoke,xred,xst,xvc,zet,zlq,zoom,zrc,bch,etc,eth,ltc,xmr,zec
|
||||
```
|
||||
|
||||
Note that support for most of these coins is EXPERIMENTAL. Many of them have
|
||||
received only minimal testing, or no testing at all. At startup you’ll be
|
||||
|
|
@ -306,8 +355,7 @@ the MMGen Project.
|
|||
[y]: https://github.com/ethereum/pyethereum
|
||||
[P]: https://pypi.org/project/pip
|
||||
[M]: https://getmonero.org/downloads/#linux
|
||||
[U]: https://github.com/mmgen/MMGenLive/blob/master/home.mmgen/bin/mmlive-daemon-upgrade
|
||||
[X]: autosign-[MMGen-command-help]
|
||||
[X]: command-help-autosign
|
||||
[gs]: Getting-Started-with-MMGen
|
||||
[bo]: Getting-Started-with-MMGen#a_bo
|
||||
[si]: Install-Bitcoind-from-Source-on-Debian-or-Ubuntu-Linux
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,27 +12,35 @@ This tutorial provides a quick, hands-on introduction.
|
|||
|
||||
1. Initialize MMGen regtest mode and start the regtest daemon:
|
||||
|
||||
$ mmgen-regtest setup
|
||||
$ mmgen-regtest start
|
||||
```text
|
||||
$ mmgen-regtest setup
|
||||
$ mmgen-regtest start
|
||||
```
|
||||
|
||||
2. Generate Bob’s MMGen wallet:
|
||||
|
||||
$ mmgen-walletgen --bob
|
||||
...
|
||||
Make this wallet your default and move it to the data directory? (Y/n): y
|
||||
```text
|
||||
$ 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, yours will be different
|
||||
```text
|
||||
$ 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, yours 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
|
||||
```text
|
||||
$ mmgen-addrimport --bob 1163DDF1-C[1-3].addrs
|
||||
...
|
||||
Type uppercase 'YES' to confirm: YES
|
||||
```
|
||||
|
||||
Since your Bob has a different Seed ID, your address filename will of course
|
||||
be different than this one.
|
||||
|
|
@ -40,63 +48,79 @@ This tutorial provides a quick, hands-on introduction.
|
|||
5. List the addresses in Bob’s tracking wallet. You’ll 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
|
||||
```text
|
||||
$ 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
|
||||
```
|
||||
|
||||
Note that regtest mode uses testnet-format addresses, which differ from the
|
||||
familiar mainnet addresses beginning with ’1’.
|
||||
|
||||
6. Fund one of the addresses (let’s choose the first one) with some BTC:
|
||||
|
||||
$ mmgen-regtest send mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ 500
|
||||
```text
|
||||
$ mmgen-regtest send mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ 500
|
||||
```
|
||||
|
||||
Don’t forget to substitute your `C:1` address for the one above!
|
||||
|
||||
7. Make sure the funds reached their destination:
|
||||
|
||||
$ 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
|
||||
TOTAL: 500 BTC
|
||||
```text
|
||||
$ 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
|
||||
TOTAL: 500 BTC
|
||||
```
|
||||
|
||||
8. You can view Bob’s total balance this way too:
|
||||
|
||||
$ mmgen-tool --bob getbalance
|
||||
```text
|
||||
$ 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
|
||||
```text
|
||||
$ 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'
|
||||
```text
|
||||
$ 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 change the address filename and send address to suit. The result of
|
||||
step 7 will 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
|
||||
```text
|
||||
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 make the output quieter:
|
||||
|
||||
$ mmgen-txdo --alice --tx-fee=20s --quiet 9304C211:S:2,300 9304C211:S:3
|
||||
...
|
||||
Type uppercase 'YES' to confirm: YES
|
||||
Transaction sent: 78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076
|
||||
```text
|
||||
$ mmgen-txdo --alice --tx-fee=20s --quiet 9304C211:S:2,300 9304C211:S:3
|
||||
...
|
||||
Type uppercase 'YES' to confirm: YES
|
||||
Transaction sent: 78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076
|
||||
```
|
||||
|
||||
Don’t forget to use your Alice’s Seed ID here, instead of `9304C211`.
|
||||
|
||||
|
|
@ -108,34 +132,44 @@ step 7 will look something like this:
|
|||
|
||||
13. View the transaction in the mempool:
|
||||
|
||||
$ mmgen-regtest mempool
|
||||
['78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076']
|
||||
```text
|
||||
$ mmgen-regtest mempool
|
||||
['78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076']
|
||||
```
|
||||
|
||||
14. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
```text
|
||||
$ mmgen-regtest generate
|
||||
```
|
||||
|
||||
15. Check the mempool again:
|
||||
|
||||
$ mmgen-regtest mempool
|
||||
[]
|
||||
```text
|
||||
$ mmgen-regtest 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
|
||||
```text
|
||||
$ 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 and 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
|
||||
...
|
||||
```text
|
||||
$ 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
|
||||
|
|
@ -144,38 +178,50 @@ step 7 will look something like this:
|
|||
|
||||
18. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
```text
|
||||
$ 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
|
||||
```text
|
||||
$ 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
|
||||
```text
|
||||
$ 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'
|
||||
```text
|
||||
$ 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
|
||||
```text
|
||||
$ mmgen-tool --bob listaddresses
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 500
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf From Alice 10
|
||||
TOTAL: 510 BTC
|
||||
```
|
||||
|
||||
22. When you’re finished, stop the regtest daemon:
|
||||
|
||||
$ mmgen-regtest stop
|
||||
```text
|
||||
$ mmgen-regtest stop
|
||||
```
|
||||
|
||||
[G]: Getting-Started-with-MMGen#a_ct
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
## Table of Contents
|
||||
* [Introduction](#a_i)
|
||||
* [Obtaining the binary seed](#a_rs)
|
||||
* [Convert the seed to binary (legacy uncompressed addresses)](#a_ss)
|
||||
* [Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)](#a_cs)
|
||||
* [Convert the seed to binary (legacy uncompressed addresses)](#a_ss)
|
||||
* [Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)](#a_cs)
|
||||
* [Generating the keys](#a_gk)
|
||||
* [Checking the result (optional, address example)](#a_cr)
|
||||
* [Checking the result (optional, address example)](#a_cr)
|
||||
* [Converting the hex value to a password (password example)](#a_hpw)
|
||||
* [Hex to WIF by hand (address example)](#a_hw)
|
||||
* [Base-conversion utility](#a_bcu)
|
||||
* [Base-conversion utility](#a_bcu)
|
||||
* [Converting an MMGen mnemonic to hexadecimal format](#a_mh)
|
||||
|
||||
#### <a name='a_i'>Introduction</a>
|
||||
#### <a id="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:
|
||||
|
|
@ -27,7 +27,7 @@ combination of circumstances ever occurs.
|
|||
In addition to private keys, this tutorial can also be used to recover passwords
|
||||
generated with the `mmgen-passgen` command.
|
||||
|
||||
#### <a name='a_rs'>Obtaining the binary seed</a>
|
||||
#### <a id="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
|
||||
|
|
@ -39,20 +39,24 @@ Okay, so let’s say you have a 128-bit seed with Seed ID `FE3C6545` and funds i
|
|||
the first three legacy uncompressed (`L`) addresses of this seed. Here are the
|
||||
addresses:
|
||||
|
||||
FE3C6545 {
|
||||
1 1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL
|
||||
2 15EfKymfe3v7mqCaL174hTWSgBLFAHvtaR
|
||||
3 1CUDd6nPHdP5pT7nN8k2AA5WdKRaKPjmea
|
||||
}
|
||||
```text
|
||||
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
|
||||
}
|
||||
```text
|
||||
FE3C6545 SEGWIT {
|
||||
1 3LpkKqtGkcCukRrgEFWyCajSApioiEWeTw
|
||||
2 3FYZQyWqBJcCjaSjCV9ZVj3gKyB9u8AYCX
|
||||
3 37wM8hwt69qwH7hZHAMn6RVdc8vMuM1CwJ
|
||||
}
|
||||
```
|
||||
|
||||
Keys for compressed (`C`), Bech32 (`B`) and altcoin addresses, as well as
|
||||
passwords, are generated in a way analogous to Segwit keys, so for them you’ll
|
||||
|
|
@ -61,7 +65,9 @@ proceed as with the Segwit case.
|
|||
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
|
||||
```text
|
||||
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:
|
||||
|
|
@ -73,16 +79,18 @@ 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 uncompressed addresses)</a>
|
||||
#### <a id="a_ss">Convert the seed to binary (legacy uncompressed 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
|
||||
```bash
|
||||
$ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin
|
||||
```
|
||||
|
||||
#### <a name='a_cs'>Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)</a>
|
||||
#### <a id="a_cs">Scramble the seed and save to binary (non-legacy and altcoin addresses and passwords)</a>
|
||||
|
||||
Other address types and passwords are generated by first “scrambling” the
|
||||
seed with a unique identifier, or “scramble string”, using the HMAC-SHA256
|
||||
|
|
@ -126,60 +134,79 @@ Once we’ve determined the correct string, we scramble our seed with it as
|
|||
follows using the `openssl` utility available by default on any Unix-based
|
||||
system:
|
||||
|
||||
# E.g. for LTC Segwit addresses:
|
||||
$ scramble_str='ltc:segwit'
|
||||
```bash
|
||||
# e.g. for LTC Segwit addresses:
|
||||
$ scramble_str='ltc:segwit'
|
||||
|
||||
# E.g. for default-format passwords for Alice’s email account at fubar.io:
|
||||
$ scramble_str='b58:20:alice@fubar.io'
|
||||
# e.g. for default-format passwords for Alice’s email account at fubar.io:
|
||||
$ scramble_str='b58:20:alice@fubar.io'
|
||||
|
||||
$ echo -n "$scramble_str" | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > scrambled-round0.bin
|
||||
$ echo -n "$scramble_str" | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > scrambled-round0.bin
|
||||
```
|
||||
|
||||
Now add the ten rounds of sha256:
|
||||
|
||||
$ for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
openssl dgst -sha256 -binary scrambled-round${i}.bin > scrambled-round$((i+1)).bin
|
||||
done
|
||||
$ mv scrambled-round10.bin myseed.bin
|
||||
```bash
|
||||
$ for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
openssl dgst -sha256 -binary scrambled-round${i}.bin > scrambled-round$((i+1)).bin
|
||||
done
|
||||
|
||||
#### <a name='a_gk'>Generating the keys</a>
|
||||
$ mv scrambled-round10.bin myseed.bin
|
||||
```
|
||||
|
||||
#### <a id="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
|
||||
```bash
|
||||
$ 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
|
||||
```bash
|
||||
$ sha256sum link1.bin | xxd -r -p | sha256sum
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
```
|
||||
|
||||
# or, for the Segwit example:
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0
|
||||
Or, for the Segwit example:
|
||||
|
||||
# or, for the password example:
|
||||
bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
|
||||
```text
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0
|
||||
```
|
||||
|
||||
#### <a name='a_cr'>Checking the result (optional, address example)</a>
|
||||
Or, for the password example:
|
||||
|
||||
```text
|
||||
bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
|
||||
```
|
||||
|
||||
#### <a id="a_cr">Checking the result (optional, address example)</a>
|
||||
|
||||
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
|
||||
```bash
|
||||
$ mmgen-tool hex2wif 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
|
||||
$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
|
||||
```
|
||||
|
||||
Or, for the Segwit example:
|
||||
|
||||
$ mmgen-tool hex2wif b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 compressed=1
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
```bash
|
||||
$ 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
|
||||
# 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
|
||||
|
|
@ -192,78 +219,103 @@ passwords). 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
|
||||
9b59cec2e5d4f2a74f0d4eb2400efcf854f5a893bef0e9bf1ee83f72ca1118c3 # password example
|
||||
```bash
|
||||
$ sha512sum link1.bin | xxd -r -p > link2.bin
|
||||
|
||||
$ sha256sum link2.bin | xxd -r -p | sha256sum
|
||||
5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 # uncompressed example
|
||||
42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d # Segwit example
|
||||
9b59cec2e5d4f2a74f0d4eb2400efcf854f5a893bef0e9bf1ee83f72ca1118c3 # password example
|
||||
```
|
||||
|
||||
And so on and so forth, until we’ve generated all the keys we need: three, in our case.
|
||||
|
||||
If we’re generating keys for Ethereum and Monero, our work is done: the raw
|
||||
hexadecimal keys are all we need. Otherwise, read on.
|
||||
|
||||
#### <a name='a_hpw'>Converting the hex value to a password (password example)</a>
|
||||
#### <a id="a_hpw">Converting the hex value to a password (password example)</a>
|
||||
|
||||
If it’s passwords we’re generating, we must now convert our hex key to the
|
||||
desired password format, base58 in our case. For this we can use the homemade
|
||||
`hex2b58.py` [Base-conversion utility](#a_bcu) described below:
|
||||
|
||||
# bd60b8... is the double sha256 of our link1.bin from above
|
||||
$ ./hex2b58.py bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
|
||||
DkFbZk2fDKQ7C55ASHQjhwcCdTsCiRq4ZLMMD5WQVAvv
|
||||
```bash
|
||||
# bd60b8... is the double sha256 of our link1.bin from above
|
||||
$ ./hex2b58.py bd60b8ba034bbb40498667ee600bc0cc0b99eb19164e8d412a48f16da4e00d6b
|
||||
DkFbZk2fDKQ7C55ASHQjhwcCdTsCiRq4ZLMMD5WQVAvv
|
||||
```
|
||||
|
||||
The password is just the last 20 characters of the output:
|
||||
|
||||
dTsCiRq4ZLMMD5WQVAvv
|
||||
```text
|
||||
dTsCiRq4ZLMMD5WQVAvv
|
||||
```
|
||||
|
||||
#### <a name='a_hw'>Hex to WIF by hand (address example)</a>
|
||||
#### <a id="a_hw">Hex to WIF by hand (address example)</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)
|
||||
```bash
|
||||
# uncompressed example
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
|
||||
# Segwit example
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0
|
||||
```
|
||||
|
||||
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
|
||||
```bash
|
||||
# uncompressed example:
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
|
||||
# Segwit example (Segwit uses compressed public keys):
|
||||
80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a001
|
||||
# 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 SHA256 of the above result:
|
||||
|
||||
|
||||
# uncompressed example:
|
||||
$ echo 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 | xxd -r -p | sha256sum | xxd -r -p | sha256sum | cut -c 1-8
|
||||
7b818629
|
||||
```bash
|
||||
# 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
|
||||
# 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)
|
||||
```bash
|
||||
# uncompressed example
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
|
||||
|
||||
# Segwit example
|
||||
80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
```
|
||||
|
||||
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
|
||||
```text
|
||||
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
|
||||
```text
|
||||
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.
|
||||
|
|
@ -272,19 +324,21 @@ 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:
|
||||
$ python3
|
||||
>>> 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
|
||||
```python
|
||||
# uncompressed example:
|
||||
$ python3
|
||||
>>> 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
|
||||
# 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 hexadecimal by Python’s `int()` function; the third
|
||||
|
|
@ -295,40 +349,48 @@ 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
|
||||
```python
|
||||
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)
|
||||
result = numtob58(num)
|
||||
```
|
||||
|
||||
#### <a name='a_bcu'>Base-conversion utility</a>
|
||||
#### <a id="a_bcu">Base-conversion utility</a>
|
||||
|
||||
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 python3
|
||||
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'))
|
||||
```python
|
||||
$ cat hex2b58.py
|
||||
#!/usr/bin/env python3
|
||||
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
|
||||
```text
|
||||
$ ./hex2b58.py 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ ./hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
$ ./hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
```
|
||||
|
||||
#### <a name='a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
|
||||
#### <a id="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
|
||||
```text
|
||||
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
|
||||
|
|
@ -336,27 +398,35 @@ 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
|
||||
```text
|
||||
4 x 1 +
|
||||
3 x 10 +
|
||||
2 x 100 +
|
||||
1 x 1000
|
||||
```
|
||||
|
||||
Or in exponential notation:
|
||||
|
||||
4 x 10⁰ +
|
||||
3 x 10¹ +
|
||||
2 x 10² +
|
||||
1 x 10³
|
||||
```text
|
||||
4 x 10⁰ +
|
||||
3 x 10¹ +
|
||||
2 x 10² +
|
||||
1 x 10³
|
||||
```
|
||||
|
||||
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) ...
|
||||
```text
|
||||
able (0), about (1), above (2), abuse (3), accept (4) ...
|
||||
```
|
||||
|
||||
and ends like this:
|
||||
|
||||
yet (1621), young (1622), yours (1623), yourself (1624), youth (1625)
|
||||
```text
|
||||
yet (1621), young (1622), yours (1623), yourself (1624), youth (1625)
|
||||
```
|
||||
|
||||
(Type `mmgen-tool mn_printlist enum=true` to see the full enumerated list)
|
||||
|
||||
|
|
@ -365,60 +435,70 @@ just like the ten digits of 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
|
||||
```text
|
||||
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
|
||||
```text
|
||||
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 the base and
|
||||
sum the results, just as we did in our ‘1234’ example above:
|
||||
|
||||
200 x 1626⁰ +
|
||||
59 x 1626¹ +
|
||||
1384 x 1626² +
|
||||
221 x 1626³ +
|
||||
379 x 1626⁴ +
|
||||
1493 x 1626⁵ +
|
||||
1433 x 1626⁶ +
|
||||
1348 x 1626⁷ +
|
||||
1459 x 1626⁸ +
|
||||
386 x 1626⁹ +
|
||||
562 x 1626¹⁰ +
|
||||
439 x 1626¹¹
|
||||
```text
|
||||
200 x 1626⁰ +
|
||||
59 x 1626¹ +
|
||||
1384 x 1626² +
|
||||
221 x 1626³ +
|
||||
379 x 1626⁴ +
|
||||
1493 x 1626⁵ +
|
||||
1433 x 1626⁶ +
|
||||
1348 x 1626⁷ +
|
||||
1459 x 1626⁸ +
|
||||
386 x 1626⁹ +
|
||||
562 x 1626¹⁰ +
|
||||
439 x 1626¹¹
|
||||
```
|
||||
|
||||
While we could theoretically do the math with a calculator, a few lines of
|
||||
Python will make our work much easier:
|
||||
|
||||
$ python3
|
||||
>>> sum = exp = 0
|
||||
>>> for word in (200,59,1384,221,379,1493,1433,1348,1459,386,562,439):
|
||||
>>> sum += word * 1626 ** exp
|
||||
>>> exp += 1
|
||||
>>> print(hex(sum))
|
||||
0x456d7f5f1c4bfe3bc916b87560ae6a3e # the result in hexadecimal: matches our original hex seed above
|
||||
```python
|
||||
$ python3
|
||||
>>> sum = exp = 0
|
||||
>>> for word in (200,59,1384,221,379,1493,1433,1348,1459,386,562,439):
|
||||
>>> sum += word * 1626 ** exp
|
||||
>>> exp += 1
|
||||
>>> print(hex(sum))
|
||||
0x456d7f5f1c4bfe3bc916b87560ae6a3e # 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:
|
||||
|
||||
$ python3
|
||||
>>> 1626**12 >= 2**128
|
||||
True
|
||||
>>> 1625**12 >= 2**128
|
||||
False
|
||||
```python
|
||||
$ python3
|
||||
>>> 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
|
||||
|
|
|
|||
|
|
@ -24,42 +24,50 @@ may be used.
|
|||
If you have a default wallet installed, you may view the Seed IDs of its
|
||||
subwallets like this:
|
||||
|
||||
$ mmgen-tool list_subseeds 1-5
|
||||
Parent Seed: DF449DA4 (256 bits)
|
||||
```text
|
||||
$ mmgen-tool list_subseeds 1-5
|
||||
Parent Seed: DF449DA4 (256 bits)
|
||||
|
||||
Long Subseeds Short Subseeds
|
||||
------------- --------------
|
||||
1L: FC9A8735 1S: 930E1AD5
|
||||
2L: 62B02F54 2S: DF14AB49
|
||||
3L: 9E884E99 3S: AD3ABD98
|
||||
4L: DB595AE1 4S: 3E885EC4
|
||||
5L: 36D5A0D1 5S: 30D66FF5
|
||||
Long Subseeds Short Subseeds
|
||||
------------- --------------
|
||||
1L: FC9A8735 1S: 930E1AD5
|
||||
2L: 62B02F54 2S: DF14AB49
|
||||
3L: 9E884E99 3S: AD3ABD98
|
||||
4L: DB595AE1 4S: 3E885EC4
|
||||
5L: 36D5A0D1 5S: 30D66FF5
|
||||
```
|
||||
|
||||
Here a range of 1-5 was chosen. Indexes of up to one million are allowed, which
|
||||
means every wallet has a total of two million potential subwallets.
|
||||
|
||||
Subwallets may be referenced either by their Subseed Index or Seed ID:
|
||||
|
||||
$ mmgen-tool get_subseed 4S
|
||||
3E885EC4
|
||||
```text
|
||||
$ mmgen-tool get_subseed 4S
|
||||
3E885EC4
|
||||
|
||||
$ mmgen-tool get_subseed_by_seed_id 3E885EC4
|
||||
4S
|
||||
$ mmgen-tool get_subseed_by_seed_id 3E885EC4
|
||||
4S
|
||||
```
|
||||
|
||||
### Subwallet generation
|
||||
|
||||
To generate a subwallet, use the `mmgen-subwalletgen` command. For example,
|
||||
you’d generate your default wallet’s 4th short subwallet as follows:
|
||||
|
||||
$ mmgen-subwalletgen 4S
|
||||
...
|
||||
MMGen wallet written to file '3E885EC4-ABCDEF00[128,3].mmdat'
|
||||
```text
|
||||
$ mmgen-subwalletgen 4S
|
||||
...
|
||||
MMGen wallet written to file '3E885EC4-ABCDEF00[128,3].mmdat'
|
||||
```
|
||||
|
||||
And view its seed phrase like this:
|
||||
|
||||
$ mmgen-walletconv -qS -o words 3E885EC4-ABCDEF00[128,3].mmdat
|
||||
...
|
||||
peaceful marry wrong surround treasure sort use favorite enough wolf suspend path
|
||||
```text
|
||||
$ mmgen-walletconv -qS -o words 3E885EC4-ABCDEF00[128,3].mmdat
|
||||
...
|
||||
peaceful marry wrong surround treasure sort use favorite enough wolf suspend path
|
||||
```
|
||||
|
||||
Since wallets generated by `mmgen-subwalletgen` are just ordinary wallets, you
|
||||
can use them anywhere you’d use an ordinary MMGen wallet.
|
||||
|
|
@ -86,39 +94,49 @@ A parent wallet may be used to generate keys and addresses for its associated
|
|||
subwallets. Given our above example (a default wallet having subwallet `4S` with
|
||||
Seed ID `3E885EC4`), the following two commands are equivalent:
|
||||
|
||||
# Generate ten bech32 addresses from the subwallet:
|
||||
$ mmgen-addrgen --type=bech32 3E885EC4-ABCDEF00[128,3].mmdat 1-10
|
||||
```text
|
||||
# Generate ten bech32 addresses from the subwallet:
|
||||
$ mmgen-addrgen --type=bech32 3E885EC4-ABCDEF00[128,3].mmdat 1-10
|
||||
|
||||
# Do the same thing, but using the parent wallet:
|
||||
$ mmgen-addrgen --type=bech32 --subwallet=4S 1-10
|
||||
# Do the same thing, but using the parent wallet:
|
||||
$ mmgen-addrgen --type=bech32 --subwallet=4S 1-10
|
||||
```
|
||||
|
||||
The same goes for transaction signing. Consider a transaction that spends to
|
||||
and from addresses in the subwallet:
|
||||
|
||||
$ mmgen-txcreate 3E885EC4:B:2
|
||||
(choose an input from subwallet 3E885EC4)
|
||||
Transaction written to file '<something>.rawtx'
|
||||
```text
|
||||
$ mmgen-txcreate 3E885EC4:B:2
|
||||
(choose an input from subwallet 3E885EC4)
|
||||
Transaction written to file '<something>.rawtx'
|
||||
```
|
||||
|
||||
This transaction can now be signed either with the subwallet itself:
|
||||
|
||||
$ mmgen-txsign *.rawtx 3E885EC4-ABCDEF00[128,3].mmdat
|
||||
...
|
||||
Signed transaction written to file '<something>.sigtx'
|
||||
```text
|
||||
$ mmgen-txsign *.rawtx 3E885EC4-ABCDEF00[128,3].mmdat
|
||||
...
|
||||
Signed transaction written to file '<something>.sigtx'
|
||||
```
|
||||
|
||||
Or with its parent wallet:
|
||||
|
||||
$ mmgen-txsign *.rawtx
|
||||
...
|
||||
Found subseed 3E885EC4 (DF449DA4:4S)
|
||||
...
|
||||
Signed transaction written to file '<something>.sigtx'
|
||||
```text
|
||||
$ mmgen-txsign *.rawtx
|
||||
...
|
||||
Found subseed 3E885EC4 (DF449DA4:4S)
|
||||
...
|
||||
Signed transaction written to file '<something>.sigtx'
|
||||
```
|
||||
|
||||
The latter command works “by magic” because by default each wallet scans its
|
||||
first 100 subwallets for Seed IDs. For a transaction containing addresses from
|
||||
a subwallet with an index higher than 100, say 144, we must extend the parent
|
||||
wallet’s search like this:
|
||||
|
||||
$ mmgen-txsign --subseeds=144 *.rawtx
|
||||
```text
|
||||
$ mmgen-txsign --subseeds=144 *.rawtx
|
||||
```
|
||||
|
||||
This is basically all you need to know about subwallets. For live versions of
|
||||
the above examples that can be run as-is, see commits [`7538a94`][c1],
|
||||
|
|
@ -127,7 +145,7 @@ the above examples that can be run as-is, see commits [`7538a94`][c1],
|
|||
For more detailed usage information, see the [`mmgen-subwalletgen` help
|
||||
screen][sh].
|
||||
|
||||
[c1]: https://github.com/mmgen/mmgen/commit/7538a9460e897b9b23d8ac58853c33713334043f
|
||||
[c2]: https://github.com/mmgen/mmgen/commit/d1b8aefde6d3a13337cbe3147d9913eb09b6765b
|
||||
[c3]: https://github.com/mmgen/mmgen/commit/82086c9936843dc43c1892b672cdf1680763ee84
|
||||
[sh]: https://github.com/mmgen/mmgen/wiki/subwalletgen-[MMGen-command-help]
|
||||
[c1]: ../commit/7538a9460e897b9b23d8ac58853c33713334043f
|
||||
[c2]: ../commit/d1b8aefde6d3a13337cbe3147d9913eb09b6765b
|
||||
[c3]: ../commit/82086c9936843dc43c1892b672cdf1680763ee84
|
||||
[sh]: command-help-subwalletgen
|
||||
|
|
|
|||
|
|
@ -22,44 +22,60 @@ The test suite requires the `/dev/loopX` devices to exist and be enabled. If
|
|||
you’re running in an LXC container, note that only privileged containers allow
|
||||
loop devices. You may enable them in the config file as follows:
|
||||
|
||||
lxc.cgroup2.devices.allow = b 7:0 rwm # /dev/loop0
|
||||
lxc.cgroup2.devices.allow = b 7:1 rwm # /dev/loop1
|
||||
lxc.cgroup2.devices.allow = b 7:2 rwm # /dev/loop2
|
||||
```text
|
||||
lxc.cgroup2.devices.allow = b 7:0 rwm # /dev/loop0
|
||||
lxc.cgroup2.devices.allow = b 7:1 rwm # /dev/loop1
|
||||
lxc.cgroup2.devices.allow = b 7:2 rwm # /dev/loop2
|
||||
```
|
||||
|
||||
Every time the container is started, you may need to create the files afresh:
|
||||
|
||||
# mknod /dev/loop0 b 7 0
|
||||
# mknod /dev/loop1 b 7 1
|
||||
# mknod /dev/loop2 b 7 2
|
||||
```text
|
||||
# mknod /dev/loop0 b 7 0
|
||||
# mknod /dev/loop1 b 7 1
|
||||
# mknod /dev/loop2 b 7 2
|
||||
```
|
||||
|
||||
### BTC-only testing
|
||||
|
||||
Clone the Bitcoin Core repo somewhere on your system:
|
||||
|
||||
$ git clone https://github.com/bitcoin/bitcoin
|
||||
```text
|
||||
$ git clone https://github.com/bitcoin/bitcoin
|
||||
```
|
||||
|
||||
Install the Bitcoin Core daemon [(source)][sd] [(binaries)][bd].
|
||||
|
||||
Point the test suite to your copy of the Bitcoin Core repo:
|
||||
|
||||
$ export CORE_REPO_ROOT=/path/to/bitcoin/core/repo
|
||||
```text
|
||||
$ export CORE_REPO_ROOT=/path/to/bitcoin/core/repo
|
||||
```
|
||||
|
||||
Install Pycoin:
|
||||
|
||||
$ python3 -m pip install --user pycoin
|
||||
```text
|
||||
$ python3 -m pip install --user pycoin
|
||||
```
|
||||
|
||||
CD to the MMGen repository root and build without installing:
|
||||
|
||||
$ cd path/to/mmgen/repo
|
||||
$ python3 setup.py build_ext --inplace
|
||||
```text
|
||||
$ cd path/to/mmgen/repo
|
||||
$ python3 setup.py build_ext --inplace
|
||||
```
|
||||
|
||||
Run the following if upgrading from a previous version of MMGen:
|
||||
|
||||
$ test/test.py clean
|
||||
```text
|
||||
$ test/test.py clean
|
||||
```
|
||||
|
||||
Run the test suite in fast mode, skipping altcoin tests:
|
||||
|
||||
$ test/test-release.sh -F noalt
|
||||
```text
|
||||
$ test/test-release.sh -FA
|
||||
```
|
||||
|
||||
### Complete testing (BTC plus all supported altcoins)
|
||||
|
||||
|
|
@ -84,52 +100,66 @@ steps:
|
|||
|
||||
Open PowerShell as administrator, and at the DOS prompt, execute:
|
||||
|
||||
system32> net user administrator /active:yes
|
||||
system32> C:\\msys64\usr\bin\bash.exe --login
|
||||
```text
|
||||
system32> net user administrator /active:yes
|
||||
system32> C:\\msys64\usr\bin\bash.exe --login
|
||||
```
|
||||
|
||||
Now, at the MSYS2 prompt, cd to the MMGen repository root and run the setup
|
||||
script:
|
||||
|
||||
$ scripts/msys2-sshd-setup.sh
|
||||
```text
|
||||
$ scripts/msys2-sshd-setup.sh
|
||||
```
|
||||
|
||||
The daemon should now start automatically every time the system is booted. It
|
||||
may also be started and stopped manually at the DOS or MSYS2 prompt as follows
|
||||
(PowerShell must be running with admin privileges):
|
||||
|
||||
# net start msys2_sshd
|
||||
# net stop msys2_sshd
|
||||
```text
|
||||
# net start msys2_sshd
|
||||
# net stop msys2_sshd
|
||||
```
|
||||
|
||||
#### Monero-Python
|
||||
|
||||
$ python3 -m pip install --user pycryptodomex ipaddress varint
|
||||
$ python3 -m pip install --user --no-deps monero
|
||||
```text
|
||||
$ python3 -m pip install --user pycryptodomex ipaddress varint
|
||||
$ python3 -m pip install --user --no-deps monero
|
||||
```
|
||||
|
||||
#### Vanitygen PlusPlus (forked from Vanitygen Plus)
|
||||
|
||||
$ git clone https://github.com/10gic/vanitygen-plusplus
|
||||
$ cd vanitygen-plusplus
|
||||
$ git checkout -b vanitygen-plus e7858035d092 # rewind to fork commit
|
||||
$ make keyconv # ‘mingw32-make.exe keyconv’ for MSYS2
|
||||
$ sudo install --strip keyconv /usr/local/bin # ‘keyconv.exe’ for MSYS2
|
||||
$ cd ..
|
||||
```text
|
||||
$ git clone https://github.com/10gic/vanitygen-plusplus
|
||||
$ cd vanitygen-plusplus
|
||||
$ git checkout -b vanitygen-plus e7858035d092 # rewind to fork commit
|
||||
$ make keyconv # ‘mingw32-make.exe keyconv’ for MSYS2
|
||||
$ sudo install --strip keyconv /usr/local/bin # ‘keyconv.exe’ for MSYS2
|
||||
$ cd ..
|
||||
```
|
||||
|
||||
#### Zcash-Mini
|
||||
|
||||
$ sudo apt-get install golang # skip this if Go is already installed
|
||||
$ git clone https://github.com/FiloSottile/zcash-mini
|
||||
$ cd zcash-mini
|
||||
$ go mod init zcash-mini
|
||||
$ go mod tidy
|
||||
$ go build -mod=mod # or just ’go build’
|
||||
$ sudo install --strip ./zcash-mini /usr/local/bin
|
||||
$ cd ..
|
||||
```text
|
||||
$ sudo apt-get install golang # skip this if Go is already installed
|
||||
$ git clone https://github.com/FiloSottile/zcash-mini
|
||||
$ cd zcash-mini
|
||||
$ go mod init zcash-mini
|
||||
$ go mod tidy
|
||||
$ go build -mod=mod # or just ’go build’
|
||||
$ sudo install --strip ./zcash-mini /usr/local/bin
|
||||
$ cd ..
|
||||
```
|
||||
|
||||
#### Ethkey
|
||||
|
||||
On Arch Linux and ArchLinuxArm systems, the ‘ethkey’ utility is included in the
|
||||
OpenEthereum package:
|
||||
|
||||
$ pacman -S openethereum
|
||||
```text
|
||||
$ pacman -S openethereum
|
||||
```
|
||||
|
||||
For 64-bit Windows and Linux systems, ‘ethkey’ can be found in the zip archives
|
||||
distributed with [this release][oz].
|
||||
|
|
@ -146,7 +176,9 @@ If you experience such a failure, just restart the test.
|
|||
|
||||
Now you can run the test suite for all coins:
|
||||
|
||||
$ test/test-release.sh -F
|
||||
```text
|
||||
$ test/test-release.sh -F
|
||||
```
|
||||
|
||||
## Overview of the individual tests
|
||||
|
||||
|
|
|
|||
|
|
@ -6,68 +6,76 @@ call signatures.
|
|||
|
||||
### Initialize:
|
||||
|
||||
from mmgen.tool.api import tool_api
|
||||
tool = tool_api()
|
||||
```python
|
||||
from mmgen.tool.api import tool_api
|
||||
tool = tool_api()
|
||||
```
|
||||
|
||||
### Key/address generation:
|
||||
|
||||
# List available coins:
|
||||
print(' '.join(tool.coins))
|
||||
```python
|
||||
# List available coins:
|
||||
print(' '.join(tool.coins))
|
||||
|
||||
# Initialize a coin/network pair:
|
||||
proto = tool.init_coin('btc','mainnet')
|
||||
# Initialize a coin/network pair:
|
||||
proto = tool.init_coin('btc','mainnet')
|
||||
|
||||
# Print the available address types for current coin/network, along with a
|
||||
# description. If tool.addrtype is unset, the first-listed will be used:
|
||||
tool.print_addrtypes()
|
||||
# Print the available address types for current coin/network, along with a
|
||||
# description. If tool.addrtype is unset, the first-listed will be used:
|
||||
tool.print_addrtypes()
|
||||
|
||||
# Set the address type to P2PKH with compressed public key:
|
||||
tool.addrtype = 'compressed'
|
||||
# Set the address type to P2PKH with compressed public key:
|
||||
tool.addrtype = 'compressed'
|
||||
|
||||
# Skip user entropy gathering (not recommended)
|
||||
tool.usr_randchars = 0
|
||||
# Skip user entropy gathering (not recommended)
|
||||
tool.usr_randchars = 0
|
||||
|
||||
# Generate a random hex secret:
|
||||
hexsec = tool.randhex()
|
||||
# Generate a random hex secret:
|
||||
hexsec = tool.randhex()
|
||||
|
||||
# Generate the key and address:
|
||||
wif = tool.hex2wif(hexsec)
|
||||
addr = tool.wif2addr(wif)
|
||||
# Generate the key and address:
|
||||
wif = tool.hex2wif(hexsec)
|
||||
addr = tool.wif2addr(wif)
|
||||
|
||||
# Generate an LTC regtest Segwit key and address:
|
||||
proto = tool.init_coin('ltc','regtest')
|
||||
tool.addrtype = 'segwit'
|
||||
wif = tool.hex2wif(hexsec)
|
||||
addr = tool.wif2addr(wif)
|
||||
# Generate an LTC regtest Segwit key and address:
|
||||
proto = tool.init_coin('ltc','regtest')
|
||||
tool.addrtype = 'segwit'
|
||||
wif = tool.hex2wif(hexsec)
|
||||
addr = tool.wif2addr(wif)
|
||||
|
||||
# Generate a random LTC regtest Bech32 key/address pair:
|
||||
tool.addrtype = 'bech32'
|
||||
wif,addr = tool.randpair()
|
||||
# Generate a random LTC regtest Bech32 key/address pair:
|
||||
tool.addrtype = 'bech32'
|
||||
wif,addr = tool.randpair()
|
||||
```
|
||||
|
||||
### Mnemonic seed phrase generation:
|
||||
|
||||
# Generate an MMGen native mnemonic seed phrase:
|
||||
mmgen_seed = tool.hex2mn(hexsec)
|
||||
```python
|
||||
# Generate an MMGen native mnemonic seed phrase:
|
||||
mmgen_seed = tool.hex2mn(hexsec)
|
||||
|
||||
# Generate a BIP39 mnemonic seed phrase:
|
||||
bip39_seed = tool.hex2mn(hexsec,fmt='bip39')
|
||||
# Generate a BIP39 mnemonic seed phrase:
|
||||
bip39_seed = tool.hex2mn(hexsec,fmt='bip39')
|
||||
```
|
||||
|
||||
### Utility methods:
|
||||
|
||||
# Reverse the hex string:
|
||||
hexsec_rev = tool.hexreverse(hexsec)
|
||||
```python
|
||||
# Reverse the hex string:
|
||||
hexsec_rev = tool.hexreverse(hexsec)
|
||||
|
||||
# Get the HASH160 of the value:
|
||||
sec_hash160 = tool.hash160(hexsec)
|
||||
# Get the HASH160 of the value:
|
||||
sec_hash160 = tool.hash160(hexsec)
|
||||
|
||||
# Convert the value to base58 format:
|
||||
sec_b58 = tool.hextob58(hexsec)
|
||||
# Convert the value to base58 format:
|
||||
sec_b58 = tool.hextob58(hexsec)
|
||||
|
||||
# Convert the value to base58 check format:
|
||||
sec_b58chk = tool.hextob58chk(hexsec)
|
||||
# Convert the value to base58 check format:
|
||||
sec_b58chk = tool.hextob58chk(hexsec)
|
||||
|
||||
# Convert the byte specification '4G' to an integer:
|
||||
four_g = tool.bytespec('4G')
|
||||
# Convert the byte specification '4G' to an integer:
|
||||
four_g = tool.bytespec('4G')
|
||||
|
||||
# Convert the byte specification '4GB' to an integer:
|
||||
four_gb = tool.bytespec('4GB')
|
||||
# Convert the byte specification '4GB' to an integer:
|
||||
four_gb = tool.bytespec('4GB')
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ been spent to your MMGen wallet.
|
|||
Make a plain list of the addresses, one address per line, and import the list
|
||||
into the tracking wallet:
|
||||
|
||||
$ mmgen-addrimport --rescan -l my_existing_addrs
|
||||
```text
|
||||
$ mmgen-addrimport --rescan -l my_existing_addrs
|
||||
```
|
||||
|
||||
NOTE: The '--rescan' option forces a rescan of the entire block chain, which is
|
||||
required for all addresses with existing balances. The rescanning process is
|
||||
|
|
@ -25,7 +27,9 @@ need their corresponding private keys.
|
|||
If the key or keys in question are in a bitcoind wallet ('wallet.dat'), you can
|
||||
extract them to a keylist file using the 'bitcoin-cli dumpwallet' command:
|
||||
|
||||
$ bitcoin-cli dumpwallet my_secret.keys
|
||||
```text
|
||||
$ bitcoin-cli dumpwallet my_secret.keys
|
||||
```
|
||||
|
||||
This will write the keylist file 'my_secret.keys' to your home directory (or
|
||||
maybe to your Bitcoin data directory, results may vary). If you want it written
|
||||
|
|
@ -46,13 +50,17 @@ After creating a transaction that spends from one of your ordinary Bitcoin
|
|||
addresses, transfer the raw transaction file to your offline computer and sign
|
||||
it with the keylist file:
|
||||
|
||||
$ mmgen-txsign -k my_secret.keys F9DCBA[6.6].rawtx
|
||||
...
|
||||
Signed transaction written to file 'F9DCBA[6.6].sigtx'
|
||||
```text
|
||||
$ mmgen-txsign -k my_secret.keys F9DCBA[6.6].rawtx
|
||||
...
|
||||
Signed transaction written to file 'F9DCBA[6.6].sigtx'
|
||||
```
|
||||
|
||||
If your transaction also contains MMGen inputs, you’ll need to provide a wallet
|
||||
for them too, listing it at the end of the command line, like this:
|
||||
|
||||
$ mmgen-txsign -k my_secret.keys F9DCBA[6.6].rawtx 89ABCDEF-76543210[256,3].mmdat
|
||||
```text
|
||||
$ mmgen-txsign -k my_secret.keys F9DCBA[6.6].rawtx 89ABCDEF-76543210[256,3].mmdat
|
||||
```
|
||||
|
||||
That’s it! Your signed transaction is ready to broadcast.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
- [Master Shares](#a_ms)
|
||||
+ [Seed Splitting with MMGen](#a_ss)
|
||||
|
||||
### <a name="a_xor">XOR Seed Splitting: A Theoretical Introduction</a>
|
||||
### <a id="a_xor">XOR Seed Splitting: A Theoretical Introduction</a>
|
||||
|
||||
The bitwise exclusive-or operation (usually denoted as `XOR`, or “![⊕]”)
|
||||
has interesting properties that make it very useful in cryptography.
|
||||
|
|
@ -94,7 +94,7 @@ Join shares 1 through *n* to recover the seed:
|
|||
|
||||
Knowledge of any combination of *n*-1 shares reveals nothing about the seed.
|
||||
|
||||
#### <a name="a_ds">Deterministic Shares</a>
|
||||
#### <a id="a_ds">Deterministic Shares</a>
|
||||
|
||||
So we’ve seen that the mathematics behind XOR seed splitting is basically
|
||||
trivial. In practice, though, there are several issues that need to be
|
||||
|
|
@ -134,14 +134,14 @@ to just keep hashing:
|
|||
![]["share2 = SHA256(share1), share3 = SHA256(share2), ..."]
|
||||
|
||||
But you may have already spotted the mistake here: the owner of the first share
|
||||
can generate all the successive shares up to *n*-1. Without the final *n*’th
|
||||
can generate all the successive shares up to *n*-1. Without the final <em>n</em>’th
|
||||
share he can’t recover the seed, but the whole benefit of having the additional
|
||||
shares has been nullified.
|
||||
|
||||
***Important disclaimer:*** *there are other reasons, beyond the scope of this
|
||||
discussion, why using a bare hash of the seed as our random number source might
|
||||
not be a good idea. Bear in mind that this is a simplified **theoretical**
|
||||
introduction, and the examples presented herein are not suitable for
|
||||
not be a good idea. Bear in mind that this is a simplified* **theoretical**
|
||||
*introduction, and the examples presented herein are not suitable for
|
||||
implementation in real production code.*
|
||||
|
||||
The above example illustrates what happens when we violate the golden rule of
|
||||
|
|
@ -160,7 +160,7 @@ algorithm is ideally suited for this:
|
|||
Using these unique pseudorandom values, we can now split and rejoin our seed in
|
||||
the manner described at the end of the previous section.
|
||||
|
||||
#### <a name="a_ns">Named Splits</a>
|
||||
#### <a id="a_ns">Named Splits</a>
|
||||
|
||||
Now, we’d like to use seed splitting as part of our backup strategy, entrusting
|
||||
shares of our seed with various people we know. Multiple 2-way splits seems
|
||||
|
|
@ -197,7 +197,7 @@ Create a 4-way split “friends” with Bob, Alice and Carol:
|
|||
|
||||
Thus we’ve ensured the uniqueness of all shares across all possible splits.
|
||||
|
||||
#### <a name="a_ms">Master Shares</a>
|
||||
#### <a id="a_ms">Master Shares</a>
|
||||
|
||||
As the number of splits we create grows, the question of how to store our shares
|
||||
becomes especially problematic. Each new split creates another new share that
|
||||
|
|
@ -235,7 +235,7 @@ Also note that an additional field, `master<n>`, has been appended to the share
|
|||
identifiers. This is to ensure that the shares of each master share split are
|
||||
unique, and differ from their non-master-share counterparts.
|
||||
|
||||
### <a name="a_ss">Seed Splitting with MMGen</a>
|
||||
### <a id="a_ss">Seed Splitting with MMGen</a>
|
||||
|
||||
The MMGen wallet implements the seed splitting and joining functionality
|
||||
described above via the commands [`mmgen-seedsplit`][SS] and
|
||||
|
|
@ -246,37 +246,43 @@ Shares can be made from and exported to all supported MMGen wallet formats.
|
|||
This means you can split a BIP39 seed phrase, for example, and output the share
|
||||
back to BIP39 in one easy command:
|
||||
|
||||
# Create share 1 of a 2-way split of the provided BIP39 seed phrase:
|
||||
$ mmgen-seedsplit -o bip39 sample.bip39 1:2
|
||||
```text
|
||||
# Create share 1 of a 2-way split of the provided BIP39 seed phrase:
|
||||
$ mmgen-seedsplit -o bip39 sample.bip39 1:2
|
||||
```
|
||||
|
||||
Each share of a split has a unique share ID. The share IDs are displayed by
|
||||
`mmgen-seedsplit` so that the user may record them for later reference. They
|
||||
may also be viewed with the `mmgen-tool list_shares` command:
|
||||
|
||||
# List the share IDs of a 2-way named split 'alice' of your default wallet:
|
||||
$ mmgen-tool list_shares 2 id_str=alice
|
||||
```bash
|
||||
# List the share IDs of a 2-way named split 'alice' of your default wallet:
|
||||
$ mmgen-tool list_shares 2 id_str=alice
|
||||
|
||||
Seed: 71CA5049 (256 bits)
|
||||
Split Type: 2-of-2 (XOR)
|
||||
ID String: alice
|
||||
Seed: 71CA5049 (256 bits)
|
||||
Split Type: 2-of-2 (XOR)
|
||||
ID String: alice
|
||||
|
||||
Shares
|
||||
------
|
||||
1: D0BBD210
|
||||
2: 25F0BD65
|
||||
Shares
|
||||
------
|
||||
1: D0BBD210
|
||||
2: 25F0BD65
|
||||
```
|
||||
|
||||
# List the share IDs of a 3-way default split of provided BIP39 seed phrase:
|
||||
$ mmgen-tool list_shares 3 wallet=sample.bip39
|
||||
```bash
|
||||
# List the share IDs of a 3-way default split of provided BIP39 seed phrase:
|
||||
$ mmgen-tool list_shares 3 wallet=sample.bip39
|
||||
|
||||
Seed: 03BAE887 (128 bits)
|
||||
Split Type: 3-of-3 (XOR)
|
||||
ID String: default
|
||||
Seed: 03BAE887 (128 bits)
|
||||
Split Type: 3-of-3 (XOR)
|
||||
ID String: default
|
||||
|
||||
Shares
|
||||
------
|
||||
1: 83B9AF74
|
||||
2: 109485F4
|
||||
3: 424522DC
|
||||
Shares
|
||||
------
|
||||
1: 83B9AF74
|
||||
2: 109485F4
|
||||
3: 424522DC
|
||||
```
|
||||
|
||||
Share IDs are handy for checking the correctness of shares when rejoining a
|
||||
split. Let’s say you’ve decided to rejoin your 2-way split with Alice, whose
|
||||
|
|
@ -294,8 +300,10 @@ First, each share must be converted to hexadecimal data. If your shares are in
|
|||
BIP39 format, for example, there are command-line tools available to do this.
|
||||
Then a single line of Python code is all that’s required to finish the job:
|
||||
|
||||
$ python3
|
||||
>>> seed_hex = hex(int(share1_hex,16) ^ int(share2_hex,16)) # rejoin a 2-way split
|
||||
```python
|
||||
$ python3
|
||||
>>> seed_hex = hex(int(share1_hex,16) ^ int(share2_hex,16)) # rejoin a 2-way split
|
||||
```
|
||||
|
||||
(Note that the XOR operator in Python is `^`.)
|
||||
|
||||
|
|
@ -338,5 +346,5 @@ example will be provided in a future version of this document.
|
|||
[wm]: https://en.wikipedia.org/wiki/Modular_arithmetic
|
||||
[otp]: https://en.wikipedia.org/wiki/One-time_pad
|
||||
[sc]: https://en.wikipedia.org/wiki/Stream_cipher
|
||||
[SS]: seedsplit-[MMGen-command-help]
|
||||
[SJ]: seedjoin-[MMGen-command-help]
|
||||
[SS]: command-help-seedsplit
|
||||
[SJ]: command-help-seedjoin
|
||||
Loading…
Add table
Add a link
Reference in a new issue