modified: Getting-Started-with-MMGen.md
parent
58c1088eeb
commit
9a015c8185
31 changed files with 492 additions and 457 deletions
|
|
@ -12,10 +12,10 @@ and Its Dependencies**][07].
|
|||
Grab the [latest tarball][08] from the [openssl.org download page][09] and unpack
|
||||
it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/openssl-1.0.1g
|
||||
$ ./config --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
$ cd /c/openssl-1.0.1g
|
||||
$ ./config --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
#### 2. Build the Berkeley Database (v5.0):
|
||||
|
||||
|
|
@ -24,16 +24,16 @@ versions (avoid v4.8, which has issues with Windows; versions newer than 5.0
|
|||
may work, but they're untested by the author). Unpack the archive and run
|
||||
the following at the MSYS prompt:
|
||||
|
||||
$ cd /c/db-5.0.32/build_unix
|
||||
$ ../dist/configure --enable-mingw --enable-cxx --disable-replication --prefix=/usr
|
||||
$ cd /c/db-5.0.32/build_unix
|
||||
$ ../dist/configure --enable-mingw --enable-cxx --disable-replication --prefix=/usr
|
||||
|
||||
Open the source file `db.h` in your editor. Change the statement on line 116:
|
||||
|
||||
typedef pthread_t db_threadid_t;
|
||||
typedef pthread_t db_threadid_t;
|
||||
|
||||
to read:
|
||||
|
||||
typedef u_int32_t db_threadid_t;
|
||||
typedef u_int32_t db_threadid_t;
|
||||
|
||||
**Note:** since `db.h` is created by `configure`, this must be done **after**
|
||||
`configure` is run.
|
||||
|
|
@ -51,10 +51,10 @@ like 7zip, open the cab file inside and the file inside it, which begins with
|
|||
Get the boost [tarball][04] from sourceforge and unpack it. At the DOS prompt,
|
||||
run:
|
||||
|
||||
cd \boost_1_55_0
|
||||
boostrap.bat
|
||||
bjam toolset=gcc link=static threading=single --build-type=minimal stage --with-system --with-filesystem --with-program_options --with-chrono --with-test
|
||||
bjam toolset=gcc link=static threading=multi --build-type=minimal stage --with-thread
|
||||
cd \boost_1_55_0
|
||||
boostrap.bat
|
||||
bjam toolset=gcc link=static threading=single --build-type=minimal stage --with-system --with-filesystem --with-program_options --with-chrono --with-test
|
||||
bjam toolset=gcc link=static threading=multi --build-type=minimal stage --with-thread
|
||||
|
||||
These commands build just the few libraries you need, avoiding the
|
||||
time-consuming process of compiling the whole boost package.
|
||||
|
|
@ -64,37 +64,37 @@ time-consuming process of compiling the whole boost package.
|
|||
Download Sipa's watchonly bitcoind [zip archive][05] (commit #a13f1e8 [[check][]])
|
||||
from GitHub and unpack it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/bitcoin-watchonly
|
||||
$ cd /c/bitcoin-watchonly
|
||||
|
||||
Make the following edits to `src/leveldb/Makefile`:
|
||||
|
||||
> After the the statement `include build_config.mk`, add the following line:
|
||||
|
||||
SOURCES=$(shell echo db/*.cc util/*.cc table/*.cc)
|
||||
SOURCES=$(shell echo db/*.cc util/*.cc table/*.cc)
|
||||
|
||||
> Change the line:
|
||||
|
||||
LIBOBJECTS = $(SOURCES:.cc=.o)
|
||||
LIBOBJECTS = $(SOURCES:.cc=.o)
|
||||
|
||||
> to read:
|
||||
|
||||
LIBOBJECTS = $(SOURCES:.cc=.o) port/port_win.o
|
||||
LIBOBJECTS = $(SOURCES:.cc=.o) port/port_win.o
|
||||
|
||||
> Change the line:
|
||||
|
||||
all: $(SHARED) $(LIBRARY)
|
||||
all: $(SHARED) $(LIBRARY)
|
||||
|
||||
> to read:
|
||||
|
||||
all: $(LIBRARY)
|
||||
all: $(LIBRARY)
|
||||
|
||||
Edit the following files,
|
||||
|
||||
src/rpcdump.cpp
|
||||
src/rpcnet.cpp
|
||||
src/rpcwallet.cpp
|
||||
src/wallet.cpp
|
||||
src/walletdb.cpp
|
||||
src/rpcdump.cpp
|
||||
src/rpcnet.cpp
|
||||
src/rpcwallet.cpp
|
||||
src/wallet.cpp
|
||||
src/walletdb.cpp
|
||||
|
||||
adding the line `#include <winsock2.h>` near the top of each file, above
|
||||
the first `#include` statement.
|
||||
|
|
@ -102,28 +102,28 @@ the first `#include` statement.
|
|||
At the MSYS prompt, run the following commands (this needs to be done just
|
||||
once):
|
||||
|
||||
$ cp /mingw/bin/autoreconf-2.68 /mingw/bin/autoreconf
|
||||
$ cp /mingw/bin/autoconf-2.68 /mingw/bin/autoconf
|
||||
$ cp /mingw/bin/automake-1.11 /mingw/bin/automake
|
||||
$ cp /mingw/bin/aclocal-1.11 /mingw/bin/aclocal
|
||||
$ cp /bin/true.exe /bin/hexdump.exe
|
||||
$ cp /mingw/bin/autoreconf-2.68 /mingw/bin/autoreconf
|
||||
$ cp /mingw/bin/autoconf-2.68 /mingw/bin/autoconf
|
||||
$ cp /mingw/bin/automake-1.11 /mingw/bin/automake
|
||||
$ cp /mingw/bin/aclocal-1.11 /mingw/bin/aclocal
|
||||
$ cp /bin/true.exe /bin/hexdump.exe
|
||||
|
||||
Generate the `configure` script:
|
||||
|
||||
$ sh autogen.sh
|
||||
$ sh autogen.sh
|
||||
|
||||
Edit the just-created `configure` script, adding the line:
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
|
||||
after the line:
|
||||
|
||||
LIBS="$LIBS $BOOST_LIBS $BOOST_CHRONO_LIB"
|
||||
LIBS="$LIBS $BOOST_LIBS $BOOST_CHRONO_LIB"
|
||||
|
||||
From the prompt, run `configure` and `make` with the arguments provided below:
|
||||
|
||||
$ ./configure --without-qt --with-incompatible-bdb CPPFLAGS=-I/usr/include LDFLAGS="-static -L/usr/lib -Wl,--allow-multiple-definition" BOOST_ROOT=/c/boost_1_55_0
|
||||
$ make src/bitcoind.exe
|
||||
$ ./configure --without-qt --with-incompatible-bdb CPPFLAGS=-I/usr/include LDFLAGS="-static -L/usr/lib -Wl,--allow-multiple-definition" BOOST_ROOT=/c/boost_1_55_0
|
||||
$ make src/bitcoind.exe
|
||||
|
||||
Strip the executable (`strip src/bitcoind.exe`), copy it to your path and test
|
||||
that the command `bitcoind` works. You may want to use the `-datadir` option to
|
||||
|
|
|
|||
|
|
@ -149,7 +149,9 @@ printed out on paper.
|
|||
Another highly recommended way to back up your wallet is to generate a mnemonic
|
||||
or seed file <a href='#a_ms'>as described below </a> and memorize it. If you
|
||||
have an average or better memory, you'll find memorizing your mnemonic to be
|
||||
surprisingly easy.
|
||||
surprisingly easy. And the peace of mind that comes with knowing that your coins
|
||||
are recoverable **even if you lose all your physical backups** can't be
|
||||
overestimated.
|
||||
|
||||
#### <a name='a_ga'>Generate addresses (offline computer)</a>
|
||||
|
||||
|
|
@ -862,14 +864,16 @@ and Litecoin daemons are properly installed ([source][si])([binaries][bi]),
|
|||
[running][p8] and synced.
|
||||
|
||||
MMGen requires that the bitcoin-abc daemon be listening on non-standard
|
||||
[RPC port 8442][p8].
|
||||
[RPC port 8442][p8]. If your daemon version is >= 0.16.2, you must use the
|
||||
`--usecashaddr=0` option.
|
||||
|
||||
Then just add the `--coin=bch` or `--coin=ltc` option to all your MMGen
|
||||
commands. It's that simple!
|
||||
|
||||
#### <a name='a_es'>Enhanced key/address generation support for Zcash (ZEC) and Monero (XMR)</a>
|
||||
|
||||
MMGen has complete key/address generation support for Zcash and Monero.
|
||||
MMGen's enhanced key/address generation support for Zcash and Monero includes
|
||||
**Zcash z-addresses** and automated Monero wallet creation.
|
||||
|
||||
Generate ten Zcash z-address key/address pairs from your default wallet:
|
||||
|
||||
|
|
@ -900,7 +904,7 @@ each address by running the following command
|
|||
and pasting in the key and password data when prompted. Monerod must be
|
||||
running and `monero-wallet-cli` be located in your executable path.
|
||||
|
||||
This process can be completely automated with the `mmgen-tool` utility:
|
||||
This process is completely automated by the `mmgen-tool` utility:
|
||||
|
||||
$ mmgen-tool keyaddrlist2monerowallet *XMR*.akeys.mmenc
|
||||
|
||||
|
|
|
|||
|
|
@ -7,22 +7,22 @@ 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
|
||||
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
|
||||
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libdb-dev libdb++-dev libevent-dev
|
||||
|
||||
### Compile and install Bitcoin Core:
|
||||
|
||||
> Clone the Bitcoin Core repository from Github, configure, and build:
|
||||
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
$ ./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
|
||||
|
|
@ -34,8 +34,8 @@ 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
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind bitcoin-cli /usr/local/bin
|
||||
|
||||
### Compile and install Bitcoin ABC (optional):
|
||||
|
||||
|
|
@ -47,17 +47,17 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
> clone the Bitcoin ABC repository, and configure and build exactly as you did
|
||||
> with Bitcoin Core above:
|
||||
|
||||
$ git clone https://github.com/Bitcoin-ABC/bitcoin-abc
|
||||
$ cd bitcoin-abc
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
$ git clone https://github.com/Bitcoin-ABC/bitcoin-abc
|
||||
$ cd bitcoin-abc
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
|
||||
> The resulting executable is also named 'bitcoind', so you must install it
|
||||
> under a different name to avoid overwriting your Core daemon:
|
||||
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind /usr/local/bin/bitcoind-abc
|
||||
$ cd src
|
||||
$ sudo install -sv bitcoind /usr/local/bin/bitcoind-abc
|
||||
|
||||
> From now on, you'll invoke the daemon as 'bitcoind-abc' instead of 'bitcoind'.
|
||||
|
||||
|
|
@ -65,13 +65,13 @@ binaries are available for Bitcoin Core, Bitcoin ABC and Litecoin. See the
|
|||
|
||||
> Clone the Litecoin repository, compile and install:
|
||||
|
||||
$ git clone https://github.com/litecoin-project/litecoin.git
|
||||
$ cd litecoin
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
$ cd src
|
||||
$ sudo install -sv litecoind litecoin-cli /usr/local/bin
|
||||
$ git clone https://github.com/litecoin-project/litecoin.git
|
||||
$ cd litecoin
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui --with-incompatible-bdb
|
||||
$ make -j4
|
||||
$ 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).
|
||||
|
|
@ -80,8 +80,8 @@ 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
|
||||
$ 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
|
||||
|
|
|
|||
|
|
@ -72,15 +72,15 @@ 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
|
||||
# Bitcoin Core:
|
||||
$ bitcoind
|
||||
|
||||
# ABC:
|
||||
$ mkdir $APPDATA/Bitcoin_ABC
|
||||
$ bitcoind-abc --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin_ABC
|
||||
# ABC:
|
||||
$ mkdir $APPDATA/Bitcoin_ABC
|
||||
$ bitcoind-abc --listen=0 --rpcport=8442 --datadir=$APPDATA/Bitcoin_ABC --usecashaddr=0
|
||||
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
# Litecoin
|
||||
$ litecoind
|
||||
|
||||
>> Note that the `--listen=0` argument is required only when running Core and ABC simultaneously.
|
||||
|
||||
|
|
@ -88,26 +88,26 @@ more low-powered computer as your online machine.
|
|||
|
||||
>> Linux users start their daemons like this:
|
||||
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
# Bitcoin Core:
|
||||
$ bitcoind --daemon
|
||||
|
||||
# ABC:
|
||||
$ mkdir ~/.bitcoin-abc
|
||||
$ bitcoind-abc --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-abc
|
||||
# ABC:
|
||||
$ mkdir ~/.bitcoin-abc
|
||||
$ bitcoind-abc --daemon --listen=0 --rpcport=8442 --datadir=$HOME/.bitcoin-abc --usecashaddr=0
|
||||
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
# Litecoin:
|
||||
$ litecoind --daemon
|
||||
|
||||
> Communicate with your daemons like this:
|
||||
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
# Core:
|
||||
$ bitcoin-cli help
|
||||
|
||||
# ABC:
|
||||
$ bitcoin-cli --rpcport=8442 help
|
||||
# ABC:
|
||||
$ bitcoin-cli --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
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ the preferred way for all non-Linux users to run MMGen.***
|
|||
Enter your MSYS environment, create the directory `/build` and move to it.
|
||||
This is where you'll be unpacking and building archives:
|
||||
|
||||
$ mkdir /build
|
||||
$ cd /build
|
||||
$ mkdir /build
|
||||
$ cd /build
|
||||
|
||||
If the machine you're installing on is online, you can download the various
|
||||
tarballs and zipped archives you need from the Internet exactly as described in
|
||||
|
|
@ -27,11 +27,11 @@ archive would thus look something like this:
|
|||
|
||||
Grab the v1.0.x [tarball][06] from openssl.org, unpack and build:
|
||||
|
||||
$ tar -xzf <path to openssl archive>/openssl-1.0.2j.tar.gz
|
||||
$ cd openssl-1.0.2j
|
||||
$ ./Configure mingw64 --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
$ tar -xzf <path to openssl archive>/openssl-1.0.2j.tar.gz
|
||||
$ cd openssl-1.0.2j
|
||||
$ ./Configure mingw64 --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
### 3. Build the Scrypt Python module:
|
||||
|
||||
|
|
@ -39,90 +39,119 @@ The latest scrypt tarball available from [Python][07] at this writing
|
|||
(scrypt-0.8.0.tar.gz) has missing files and doesn't build, so grab the latest
|
||||
[zipfile][07z] from the scrypt source repository, unzip and build:
|
||||
|
||||
$ cd /build
|
||||
$ unzip <path to scrypt archive>/91d194b6a6bd.zip
|
||||
$ cd mhallin-py-scrypt-91d194b6a6bd
|
||||
$ cd /build
|
||||
$ unzip <path to scrypt archive>/91d194b6a6bd.zip
|
||||
$ cd mhallin-py-scrypt-91d194b6a6bd
|
||||
|
||||
Open the file `setup.py` in your text editor. Change the line reading
|
||||
|
||||
from setuptools import setup, Extension
|
||||
from setuptools import setup, Extension
|
||||
|
||||
to read
|
||||
|
||||
from distutils.core import setup, Extension
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
Right before the line beginning with
|
||||
|
||||
scrypt_module = Extension(
|
||||
scrypt_module = Extension(
|
||||
|
||||
add the following lines (with no indentation):
|
||||
|
||||
library_dirs = [r'c:\mingw64\x86_64-w4-mingw32\lib','/msys/lib']
|
||||
includes = [r'c:\msys\include']
|
||||
library_dirs = [r'c:\mingw64\x86_64-w4-mingw32\lib','/msys/lib']
|
||||
includes = [r'c:\msys\include']
|
||||
|
||||
Save `setup.py`, build and install:
|
||||
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
|
||||
Now, to solve a problem with the interpreter not finding the scrypt extension
|
||||
module, we have to do this little fixup:
|
||||
|
||||
$ cd /mingw/opt/lib/python2.7/site-packages
|
||||
$ unzip scrypt*.egg
|
||||
$ cd /mingw/opt/lib/python2.7/site-packages
|
||||
$ unzip scrypt*.egg
|
||||
|
||||
### 4. Build the pycrypto Python module:
|
||||
|
||||
Download the latest pycrypto [tarball][02] from the Python website and unpack it:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pycrypto archive>/pycrypto-2.6.1.tar.gz
|
||||
$ cd pycrypto-2.6.1
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pycrypto archive>/pycrypto-2.6.1.tar.gz
|
||||
$ cd pycrypto-2.6.1
|
||||
|
||||
Open the file `setup.py` in your text editor. Remove *exactly* four spaces at
|
||||
the beginning of this line:
|
||||
|
||||
self.__remove_extensions(["CryptoPublicKey._fastmath"])
|
||||
self.__remove_extensions(["CryptoPublicKey._fastmath"])
|
||||
|
||||
to move it one level of indentation to the left. Save the file and exit the
|
||||
editor. Now build and install:
|
||||
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
|
||||
### 5. Install the ecdsa Python module:
|
||||
|
||||
Grab the latest python-ecdsa [tarball][03], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to ecdsa archive>/ecdsa-0.13.tar.gz
|
||||
$ cd ecdsa-0.13
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to ecdsa archive>/ecdsa-0.13.tar.gz
|
||||
$ cd ecdsa-0.13
|
||||
$ python setup.py install
|
||||
|
||||
### 6. Install the colorama Python module:
|
||||
### 6. Install the ed25519ll Python module (required for Monero address generation):
|
||||
|
||||
Grab the latest ed25519ll [tarball][43], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to ed25519ll archive>/ed25519ll-0.6.tar.gz
|
||||
$ cd ed25519ll-0.6
|
||||
|
||||
Open the file `setup.py` in your text editor. Change the line reading
|
||||
|
||||
plat_name = get_platform().replace('-', '_')
|
||||
|
||||
to read
|
||||
|
||||
plat_name = 'win64'
|
||||
|
||||
Exit the editor and run:
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
### 7. Install the pysha3 Python module (required for Monero and Ethereum address generation):
|
||||
|
||||
Grab the latest pysha3 [tarball][44], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pysha3 archive>/pysha3-1.0.2.tar.gz
|
||||
$ cd pysha3-1.0.2
|
||||
$ python setup.py install
|
||||
|
||||
### 8. Install the colorama Python module:
|
||||
|
||||
Grab the latest colorama [tarball][14], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to colorama archive>/colorama-0.3.7.tar.gz
|
||||
$ cd colorama-0.3.7
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to colorama archive>/colorama-0.3.7.tar.gz
|
||||
$ cd colorama-0.3.7
|
||||
$ python setup.py install
|
||||
|
||||
### 7. Install the pexpect Python module (needed for test suite):
|
||||
### 9. Install the pexpect Python module (needed for test suite):
|
||||
|
||||
Grab the latest pexpect [tarball][15], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pexpect archive>/pexpect-4.2.1.tar.gz
|
||||
$ cd pexpect-4.2.1
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pexpect archive>/pexpect-4.2.1.tar.gz
|
||||
$ cd pexpect-4.2.1
|
||||
$ python setup.py install
|
||||
|
||||
### 8. Install sdelete utility (needed for secure wallet deletion):
|
||||
### 10. Install sdelete utility (needed for secure wallet deletion):
|
||||
|
||||
Grab the latest SDelete [zip archive][16], unzip and copy `sdelete.exe` to
|
||||
your execution path (`c:\windows`, for example).
|
||||
|
||||
### 9. Build libsecp256k1:
|
||||
### 11. Build libsecp256k1:
|
||||
|
||||
Libsecp256k1 requires GNU autotools to build, and they're not included in the
|
||||
MinGW-64 distribution for some reason, so you'll have to retrieve and unpack
|
||||
|
|
@ -134,41 +163,41 @@ them yourself. You'll need these archives:
|
|||
|
||||
Unpack them in your /mingw directory and fix up some filenames:
|
||||
|
||||
$ cd /mingw
|
||||
$ tar -xzf <path to>/autoconf2.5-2.68-1-mingw32-bin.tar.lzma
|
||||
$ tar -xzf <path to>/automake1.11-1.11.1-1-mingw32-bin.tar.lzma
|
||||
$ tar -xzf <path to>/libtool-2.4-1-mingw32-bin.tar.lzma
|
||||
$ cd bin
|
||||
$ cp autoconf-* autoconf
|
||||
$ cp automake-* automake
|
||||
$ cp aclocal-* aclocal
|
||||
$ cp autoreconf-* autoreconf
|
||||
$ cd /mingw
|
||||
$ tar -xzf <path to>/autoconf2.5-2.68-1-mingw32-bin.tar.lzma
|
||||
$ tar -xzf <path to>/automake1.11-1.11.1-1-mingw32-bin.tar.lzma
|
||||
$ tar -xzf <path to>/libtool-2.4-1-mingw32-bin.tar.lzma
|
||||
$ cd bin
|
||||
$ cp autoconf-* autoconf
|
||||
$ cp automake-* automake
|
||||
$ cp aclocal-* aclocal
|
||||
$ cp autoreconf-* autoreconf
|
||||
|
||||
Now get the latest libsecp256k1 [zip archive][11] from GitHub, unpack, build and
|
||||
install:
|
||||
|
||||
$ cd /build
|
||||
$ unzip.exe <path to libsecp256k1 archive>/master.zip
|
||||
$ cd secp256k1-master
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
$ cd /build
|
||||
$ unzip.exe <path to libsecp256k1 archive>/master.zip
|
||||
$ cd secp256k1-master
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
### 10. Install MMGen:
|
||||
### 12. Install MMGen:
|
||||
|
||||
Get the [zip archive][10] of the latest stable version from GitHub, unpack and install:
|
||||
|
||||
$ cd /build
|
||||
$ unzip.exe <path to mmgen archive>/stable_mswin.zip
|
||||
$ cd mmgen-stable_mswin
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ sudo ./setup.py install
|
||||
$ cd /build
|
||||
$ unzip.exe <path to mmgen archive>/stable_mswin.zip
|
||||
$ cd mmgen-stable_mswin
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ sudo ./setup.py install
|
||||
|
||||
After first installing and starting the [Bitcoin daemon][77], you may then run
|
||||
the MMGen test suite to make sure your installation's working:
|
||||
|
||||
$ test/test.py -s
|
||||
$ test/test.py -s
|
||||
|
||||
[02]: https://pypi.python.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz#md5=55a61a054aa66812daf5161a0d5d7eda
|
||||
[03]: https://pypi.python.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz#md5=1f60eda9cb5c46722856db41a3ae6670
|
||||
|
|
@ -185,3 +214,5 @@ the MMGen test suite to make sure your installation's working:
|
|||
[32]: https://sourceforge.net/projects/mingw/files/MinGW/Extension/automake/automake1.11/automake1.11-1.11.1-1/automake1.11-1.11.1-1-mingw32-bin.tar.lzma
|
||||
[33]: https://sourceforge.net/projects/mingw/files/MinGW/Extension/libtool/libtool-2.4-1/libtool-2.4-1-mingw32-bin.tar.lzma
|
||||
[77]: Install-Bitcoind
|
||||
[43]: https://pypi.python.org/packages/8a/34/b27ee501205893cf7cc537b4e6553a557eaaca14c4755aa1eaa500afac57/ed25519ll-0.6.tar.gz#md5=35b3190ffefb631e7c5a45d96d768f80
|
||||
[44]: https://pypi.python.org/packages/73/bf/978d424ac6c9076d73b8fdc8ab8ad46f98af0c34669d736b1d83c758afee/pysha3-1.0.2.tar.gz#md5=59cd2db7a9988c1f3f6aee40145e0c96
|
||||
|
|
|
|||
|
|
@ -18,18 +18,18 @@ Add the Python base and Scripts directories to your [path][08], e.g.
|
|||
Enter your MSYS environment, create the directory `/c/build` and move to it.
|
||||
This is where you'll be unpacking and building archives:
|
||||
|
||||
$ mkdir /build
|
||||
$ cd /build
|
||||
$ mkdir /build
|
||||
$ cd /build
|
||||
|
||||
### 2. Build OpenSSL:
|
||||
|
||||
Grab the v1.0.x [tarball][06] from openssl.org, unpack and build:
|
||||
|
||||
$ tar.exe -xzf <path to openssl archive>/openssl-1.0.2j.tar.gz
|
||||
$ cd openssl-1.0.2j
|
||||
$ ./config --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
$ tar.exe -xzf <path to openssl archive>/openssl-1.0.2j.tar.gz
|
||||
$ cd openssl-1.0.2j
|
||||
$ ./config --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
### 3. Build the Scrypt Python module:
|
||||
|
||||
|
|
@ -37,105 +37,105 @@ The latest scrypt tarball available from [Python][07] at this writing
|
|||
(scrypt-0.8.0.tar.gz) has missing files and doesn't build, so grab the latest
|
||||
[source zipfile][07z] from the scrypt repository, unzip and build:
|
||||
|
||||
$ cd /build
|
||||
$ unzip <path to scrypt archive>/91d194b6a6bd.zip
|
||||
$ cd mhallin-py-scrypt-91d194b6a6bd
|
||||
$ cd /build
|
||||
$ unzip <path to scrypt archive>/91d194b6a6bd.zip
|
||||
$ cd mhallin-py-scrypt-91d194b6a6bd
|
||||
|
||||
Open the file `setup.py` in your text editor. Right before the line beginning
|
||||
with
|
||||
|
||||
scrypt_module = Extension(
|
||||
scrypt_module = Extension(
|
||||
|
||||
add the following lines (with no indentation):
|
||||
|
||||
library_dirs = [r'c:\msys\lib',r'c:\windows\system32']
|
||||
includes = [r'c:\msys\include']
|
||||
library_dirs = [r'c:\msys\lib',r'c:\windows\system32']
|
||||
includes = [r'c:\msys\include']
|
||||
|
||||
Save `setup.py`, build and install:
|
||||
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
|
||||
You can ignore the error messages at the end of the build.
|
||||
|
||||
Now, to solve a problem with the interpreter not finding the scrypt extension
|
||||
module, we have to do this little workaround:
|
||||
|
||||
$ cd /c/Python27/lib/site-packages
|
||||
$ unzip scrypt*.egg
|
||||
$ cd /c/Python27/lib/site-packages
|
||||
$ unzip scrypt*.egg
|
||||
|
||||
### 4. Build the pycrypto Python module:
|
||||
|
||||
Download the latest pycrypto [tarball][02] from the Python website, unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pycrypto archive>/pycrypto-2.6.1.tar.gz
|
||||
$ cd pycrypto-2.6.1
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pycrypto archive>/pycrypto-2.6.1.tar.gz
|
||||
$ cd pycrypto-2.6.1
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
|
||||
### 5. Install the ecdsa Python module:
|
||||
|
||||
Grab the latest python-ecdsa [tarball][03], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to ecdsa archive>/ecdsa-0.13.tar.gz
|
||||
$ cd ecdsa-0.13
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to ecdsa archive>/ecdsa-0.13.tar.gz
|
||||
$ cd ecdsa-0.13
|
||||
$ python setup.py install
|
||||
|
||||
### 7. Install the colorama Python module (optional but recommended):
|
||||
|
||||
Grab the colorama [tarball][14], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to colorama archive>/colorama-0.3.7.tar.gz
|
||||
$ cd /c/colorama-0.3.7
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to colorama archive>/colorama-0.3.7.tar.gz
|
||||
$ cd /c/colorama-0.3.7
|
||||
$ python setup.py install
|
||||
|
||||
### 8. Install the pexpect Python module (needed for test suite):
|
||||
|
||||
Grab the latest pexpect [tarball][15], unpack and build:
|
||||
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pexpect archive>/pexpect-4.2.1.tar.gz
|
||||
$ cd pexpect-4.2.1
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ tar -xzf <path to pexpect archive>/pexpect-4.2.1.tar.gz
|
||||
$ cd pexpect-4.2.1
|
||||
$ python setup.py install
|
||||
|
||||
### 9. Build libsecp256k1:
|
||||
|
||||
First you need to fix up some filenames for your build to work:
|
||||
|
||||
$ cd /mingw/bin
|
||||
$ cp autoconf-* autoconf
|
||||
$ cp automake-* automake
|
||||
$ cp aclocal-* aclocal
|
||||
$ cp autoreconf-* autoreconf
|
||||
$ cd /mingw/bin
|
||||
$ cp autoconf-* autoconf
|
||||
$ cp automake-* automake
|
||||
$ cp aclocal-* aclocal
|
||||
$ cp autoreconf-* autoreconf
|
||||
|
||||
Now get the latest libsecp256k1 [zip archive][11] from GitHub, unpack, build and
|
||||
install:
|
||||
|
||||
$ cd /build
|
||||
$ unzip.exe <path to libsecp256k1 archive>/master.zip
|
||||
$ cd secp256k1-master
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
$ cd /build
|
||||
$ unzip.exe <path to libsecp256k1 archive>/master.zip
|
||||
$ cd secp256k1-master
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
### 10. Install MMGen:
|
||||
|
||||
Get the [zip archive][10] from GitHub, unpack and install:
|
||||
|
||||
$ cd /build
|
||||
$ unzip.exe <path to mmgen archive>/stable_mswin.zip
|
||||
$ cd mmgen-stable_mswin
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
$ cd /build
|
||||
$ unzip.exe <path to mmgen archive>/stable_mswin.zip
|
||||
$ cd mmgen-stable_mswin
|
||||
$ python setup.py build --compiler=mingw32
|
||||
$ python setup.py install
|
||||
|
||||
After first installing and starting the [Bitcoin daemon][77], you may then run
|
||||
the MMGen test suite to make sure your installation's working:
|
||||
|
||||
$ test/test.py
|
||||
$ test/test.py
|
||||
|
||||
[02]: https://pypi.python.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz#md5=55a61a054aa66812daf5161a0d5d7eda
|
||||
[03]: https://pypi.python.org/packages/f9/e5/99ebb176e47f150ac115ffeda5fedb6a3dbb3c00c74a59fd84ddf12f5857/ecdsa-0.13.tar.gz#md5=1f60eda9cb5c46722856db41a3ae6670
|
||||
|
|
|
|||
|
|
@ -2,30 +2,30 @@
|
|||
|
||||
> Install required Debian/Ubuntu packages:
|
||||
|
||||
$ sudo apt-get install python-dev python-pexpect python-ecdsa python-scrypt libssl-dev git autoconf libtool wipe python-setuptools libgmp-dev python-crypto python-nacl python-pysha3 python-pip
|
||||
$ sudo apt-get install python-dev python-pexpect python-ecdsa python-scrypt libssl-dev git autoconf libtool wipe python-setuptools libgmp-dev python-crypto python-nacl python-pysha3 python-pip
|
||||
|
||||
> Install fast ed25519 Python package (optional, but recommended for Monero addresses):
|
||||
|
||||
$ sudo pip install ed25519ll
|
||||
$ sudo pip install ed25519ll
|
||||
|
||||
> Install the secp256k1 library:
|
||||
|
||||
$ git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
$ cd secp256k1
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ sudo ldconfig
|
||||
$ cd ..
|
||||
$ git clone https://github.com/bitcoin-core/secp256k1.git
|
||||
$ cd secp256k1
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ sudo ldconfig
|
||||
$ cd ..
|
||||
|
||||
> Install MMGen:
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen
|
||||
$ git checkout -b stable stable_linux
|
||||
$ sudo ./setup.py install
|
||||
$ cd ..
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen
|
||||
$ git checkout -b stable stable_linux
|
||||
$ sudo ./setup.py install
|
||||
$ cd ..
|
||||
|
||||
> Install the bitcoind daemon(s):
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ doing, then proceed onward. Otherwise, you should install an easier-to use
|
|||
|
||||
Execute the command
|
||||
|
||||
mkdir -p /c/mingw620/x86_64-620-posix-seh-rt_v5-rev1/mingw64
|
||||
mkdir -p /c/mingw620/x86_64-620-posix-seh-rt_v5-rev1/mingw64
|
||||
|
||||
Using your text editor within MSYS, create the file `/etc/fstab.conf` with the
|
||||
following two lines:
|
||||
|
||||
c:/mingw64 /mingw
|
||||
c:/mingw64 /c/mingw620/x86_64-620-posix-seh-rt_v5-rev1/mingw64
|
||||
|
||||
c:/mingw64 /mingw
|
||||
c:/mingw64 /c/mingw620/x86_64-620-posix-seh-rt_v5-rev1/mingw64
|
||||
|
||||
Execute the command `mount /mingw`
|
||||
|
||||
MSYS is a Unix-like environment. If you're new to Unix, you're advised to learn
|
||||
|
|
|
|||
|
|
@ -22,22 +22,22 @@ Unpack the basic-bsdtar archive (in the MinGW archives) and copy the executable
|
|||
From the DOS prompt (i.e. “Command Line”), create the two base directories and
|
||||
move to the first of them:
|
||||
|
||||
> mkdir C:\mingw
|
||||
> mkdir C:\msys
|
||||
> cd C:\mingw
|
||||
> mkdir C:\mingw
|
||||
> mkdir C:\msys
|
||||
> cd C:\mingw
|
||||
|
||||
Unpack all the MinGW archives (except basic-bsdtar) by executing the following
|
||||
command for each archive:
|
||||
|
||||
> basic-bsdtar.exe -xf <path to MinGW archives>/<archive name>
|
||||
> basic-bsdtar.exe -xf <path to MinGW archives>/<archive name>
|
||||
|
||||
Now move the MSYS base directory:
|
||||
|
||||
> cd C:\msys
|
||||
> cd C:\msys
|
||||
|
||||
and unpack each MSYS archive in the same way:
|
||||
|
||||
> basic-bsdtar.exe -xf <path to MSYS archives>/<archive name>
|
||||
> basic-bsdtar.exe -xf <path to MSYS archives>/<archive name>
|
||||
|
||||
Add `C:\mingw\bin` to your user path. Consult [this page][05] for instructions
|
||||
on how to do that.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ binaries can be obtained [here][00].
|
|||
After installation, locate the bitcoind executable, place it on your execution
|
||||
path and start it with the command:
|
||||
|
||||
$ bitcoind -daemon -maxconnections=0
|
||||
$ bitcoind -daemon -maxconnections=0
|
||||
|
||||
Note that in the absence of a blockchain the daemon starts very quickly and
|
||||
uses practically no CPU once running. Thus a low-powered computer such as a
|
||||
|
|
|
|||
|
|
@ -13,26 +13,26 @@ This tutorial provides a quick, hands-on introduction.
|
|||
|
||||
1. Create the regtest blockchain and Bob and Alice's tracking wallets:
|
||||
|
||||
$ mmgen-regtest setup
|
||||
$ mmgen-regtest setup
|
||||
|
||||
2. Generate Bob's MMGen wallet:
|
||||
|
||||
$ mmgen-walletgen --bob
|
||||
...
|
||||
Make this wallet your default and move it to the data directory? (Y/n): y
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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 +40,63 @@ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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'
|
||||
$ 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
|
||||
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 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
|
||||
$ 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 +108,34 @@ Specify a fee of 20 satoshis/byte and make output quieter:
|
|||
|
||||
13. View the transaction in the mempool:
|
||||
|
||||
$ mmgen-regtest show_mempool
|
||||
['78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076']
|
||||
$ mmgen-regtest show_mempool
|
||||
['78ca853816b55527b42ca8784c887a5f482c752522f914d2f17d6afcd8a3b076']
|
||||
|
||||
14. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
$ mmgen-regtest generate
|
||||
|
||||
15. Check the mempool again:
|
||||
|
||||
$ mmgen-regtest show_mempool
|
||||
[]
|
||||
$ mmgen-regtest show_mempool
|
||||
[]
|
||||
|
||||
16. List Alice's addresses. Note that Alice has lost a bit to transaction fees:
|
||||
|
||||
$ mmgen-tool --alice listaddresses showempty=1
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
9304C211:S:1 2N3HhxasbRvrJyHg72JNVCCPi9EUGrEbFnu - 0
|
||||
9304C211:S:2 2N8w8qTupvd9L9wLFbrn6UhdfF1gadDAmFD - 300
|
||||
9304C211:S:3 2NF4y3y4CEjQCcssjX2BDLHT88XHn8z53JS - 199.999967
|
||||
TOTAL: 499.999967 BTC
|
||||
$ 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
|
||||
...
|
||||
$ mmgen-txdo --alice --tx-fee=0.0001 --quiet 9304C211:S:1 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf,10
|
||||
...
|
||||
Enter a range or space-separated list of outputs to spend: 1
|
||||
...
|
||||
|
||||
Note that Alice is reusing address S:1 here, and address reuse is generally a
|
||||
bad idea. You'd be better off generating and importing some new addresses for
|
||||
|
|
@ -144,34 +144,34 @@ address. This time Alice specifies an absolute fee in BTC.
|
|||
|
||||
18. Mine a block:
|
||||
|
||||
$ mmgen-regtest generate
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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'
|
||||
$ 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
|
||||
$ mmgen-tool --bob listaddresses
|
||||
MMGenID ADDRESS COMMENT BALANCE
|
||||
1163DDF1:C:1 mw42oJ94yRA6ZUNSzmMpjZDR74JNyvqzzZ - 500
|
||||
1163DDF1:C:2 n1oszhfAyRrHi7qJupyzaWXTcpMQGsGJEf From Alice 10
|
||||
TOTAL: 510 BTC
|
||||
|
||||
[q]: MMGen-Quick-Start-with-Regtest-Mode
|
||||
|
|
|
|||
|
|
@ -33,20 +33,20 @@ Okay, so let's say you have a 128-bit seed with Seed ID FE3C6545 and funds in
|
|||
the first three legacy uncompressed ('L') addresses of this seed. Here are the
|
||||
addresses:
|
||||
|
||||
FE3C6545 {
|
||||
1 1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL
|
||||
2 15EfKymfe3v7mqCaL174hTWSgBLFAHvtaR
|
||||
3 1CUDd6nPHdP5pT7nN8k2AA5WdKRaKPjmea
|
||||
}
|
||||
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
|
||||
}
|
||||
FE3C6545 SEGWIT {
|
||||
1 3LpkKqtGkcCukRrgEFWyCajSApioiEWeTw
|
||||
2 3FYZQyWqBJcCjaSjCV9ZVj3gKyB9u8AYCX
|
||||
3 37wM8hwt69qwH7hZHAMn6RVdc8vMuM1CwJ
|
||||
}
|
||||
|
||||
Keys for MMGen's compressed ('C') addresses are generated in a similar way as
|
||||
Segwit ones, as you'll see below, so we won't consider that case separately.
|
||||
|
|
@ -54,7 +54,7 @@ Segwit ones, as you'll see below, so we won't consider that case separately.
|
|||
Here's the seed itself in mmhex format, which you've stored in some safe place (on
|
||||
paper in a safe-deposit box, for example):
|
||||
|
||||
afc3fe 456d 7f5f 1c4b fe3b c916 b875 60ae 6a3e
|
||||
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,7 +73,7 @@ Linux or other Unix-like system.
|
|||
> 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
|
||||
$ echo 456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > myseed.bin
|
||||
|
||||
> #### <a name='a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
|
||||
|
||||
|
|
@ -82,23 +82,23 @@ Linux or other Unix-like system.
|
|||
> result in binary form. This can be done with the 'openssl' utility, also
|
||||
> included by default on Unix-based systems:
|
||||
|
||||
$ echo -n segwit | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > cooked-seed.bin
|
||||
$ echo -n segwit | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > cooked-seed.bin
|
||||
|
||||
> If your addresses are of the compressed ('C') type, just use the string
|
||||
> 'compressed' instead of 'segwit' as the 'echo' command's argument.
|
||||
|
||||
> Now add the ten rounds of sha256:
|
||||
|
||||
$ openssl dgst -sha256 -binary cooked-seed.bin > cooked-round1.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round1.bin > cooked-round2.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round2.bin > cooked-round3.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round3.bin > cooked-round4.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round4.bin > cooked-round5.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round5.bin > cooked-round6.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round6.bin > cooked-round7.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round7.bin > cooked-round8.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round8.bin > cooked-round9.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round9.bin > myseed.bin
|
||||
$ openssl dgst -sha256 -binary cooked-seed.bin > cooked-round1.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round1.bin > cooked-round2.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round2.bin > cooked-round3.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round3.bin > cooked-round4.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round4.bin > cooked-round5.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round5.bin > cooked-round6.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round6.bin > cooked-round7.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round7.bin > cooked-round8.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round8.bin > cooked-round9.bin
|
||||
$ openssl dgst -sha256 -binary cooked-round9.bin > myseed.bin
|
||||
|
||||
#### <a name='a_gk'>Generating the keys</a>
|
||||
|
||||
|
|
@ -107,34 +107,34 @@ 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
|
||||
$ 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 -
|
||||
$ sha256sum link1.bin | xxd -r -p | sha256sum
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 -
|
||||
|
||||
Or, in the Segwit case:
|
||||
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 -
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 -
|
||||
|
||||
With 'mmgen-tool', we can easily generate the WIF key and address from this
|
||||
hexadecimal key and see that it's correct:
|
||||
|
||||
$ mmgen-tool hex2wif 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
$ mmgen-tool hex2wif 05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
|
||||
$ mmgen-tool wif2addr 5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
1JVi3qcNcjMM7cTR7y9ihKUG1yDLpKRJfL # matches FE3C6545:L:1 above
|
||||
|
||||
Or, in the Segwit case:
|
||||
|
||||
$ mmgen-tool hex2wif b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 compressed=1
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
$ 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
|
||||
|
|
@ -146,10 +146,10 @@ Meanwhile, let's finish generating hex keys for the rest of our addresses. To
|
|||
get the next key, we generate the next link in the chain from the first link and
|
||||
take its double SHA-256 hash, just as we did for the first one:
|
||||
|
||||
$ sha512sum link1.bin | xxd -r -p > link2.bin
|
||||
$ sha256sum link2.bin | xxd -r -p | sha256sum
|
||||
5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 - (uncompressed example)
|
||||
42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d - (Segwit example)
|
||||
$ sha512sum link1.bin | xxd -r -p > link2.bin
|
||||
$ sha256sum link2.bin | xxd -r -p | sha256sum
|
||||
5db8fe3c8b52ccc98deab5afae780b6fbe56629e7ee1c6ed826fc2d6a81fb144 - (uncompressed example)
|
||||
42f1b998f0f9b7b27b5d0b92ffa8c1c6b96d7202789c41b6e6a6a402e318a04d - (Segwit example)
|
||||
|
||||
And so on and so forth, until we've generated all the keys we need: three, in our case.
|
||||
|
||||
|
|
@ -159,47 +159,47 @@ 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)
|
||||
05d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 (uncompressed example)
|
||||
b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a0 (Segwit example)
|
||||
|
||||
WIF format prepends hex '80' to the beginning of the key. If the key is
|
||||
associated with a compressed public key, it also appends '01':
|
||||
|
||||
# uncompressed example:
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36
|
||||
# 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 SHA-256 of the above result:
|
||||
|
||||
|
||||
# uncompressed example:
|
||||
$ echo 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e36 | xxd -r -p | sha256sum | xxd -r -p | sha256sum | cut -c 1-8
|
||||
7b818629
|
||||
# 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)
|
||||
8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629 (uncompressed example)
|
||||
80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812 (Segwit example)
|
||||
|
||||
The last step is to convert all this into Base 58. Satoshi created Base-58
|
||||
encoding for convenient and error-free writing down and dictating of Bitcoin
|
||||
keys and addresses. He began with a Base-62 alphabet consisting of the ten
|
||||
digits plus the upper and lower case Latin letters (10 + 26 + 26 = 62):
|
||||
|
||||
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijlkmnopqrstuvwxyz
|
||||
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
|
||||
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.
|
||||
|
|
@ -208,19 +208,19 @@ Now all that remains is to convert our hexadecimal key to decimal and then Base
|
|||
58 using this alphabet. This can be done in just four lines of code you can try
|
||||
out at the Python prompt:
|
||||
|
||||
# uncompressed example:
|
||||
$ python
|
||||
>>> b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
>>> num = int('8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629',16)
|
||||
>>> result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
>>> print ''.join(reversed(result)).lstrip('1')
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi # matches key for FE3C6545:L:1 above
|
||||
# uncompressed example:
|
||||
$ python
|
||||
>>> b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
>>> num = int('8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629',16)
|
||||
>>> result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
>>> print ''.join(reversed(result)).lstrip('1')
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi # matches key for FE3C6545:L:1 above
|
||||
|
||||
# Segwit example has the following differences:
|
||||
...
|
||||
>>> num = int('80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812',16)
|
||||
...
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F # matches key for FE3C6545:S:1 above
|
||||
# Segwit example has the following differences:
|
||||
...
|
||||
>>> num = int('80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812',16)
|
||||
...
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F # matches key for FE3C6545:S:1 above
|
||||
|
||||
Explanation: the variable 'b58a' holds the Base 58 alphabet; 'num' holds the key
|
||||
in decimal, converted from hexidecimal by Python's `int()` function; the third
|
||||
|
|
@ -231,38 +231,38 @@ 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
|
||||
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)
|
||||
|
||||
Adapting our code a bit and putting it in a file gives us have a handy
|
||||
conversion utility we can use for any key:
|
||||
|
||||
$ cat hex2b58.py
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
num = int(sys.argv[1],16)
|
||||
result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
print ''.join(reversed(result)).lstrip('1')
|
||||
$ cat hex2b58.py
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
num = int(sys.argv[1],16)
|
||||
result = [b58a[num / 58**e % 58] for e in range(60)]
|
||||
print ''.join(reversed(result)).lstrip('1')
|
||||
|
||||
$ hex2b58.py 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
$ hex2b58.py 8005d7219524b983290138a60ada101370007f59a625c43a46f0f8d92950955e367b818629
|
||||
5HrrmMdQbELyW7iCns5kvSbN9GCPTqEfG7iP1PZiYk49yDDivTi
|
||||
|
||||
$ hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
$ hex2b58.py 80b8e58ded53e9ba5a9f4e279a956c061a7da5487bde6a95f1ede0722d287881a00189bba812
|
||||
L3R8Fn21PsY3PWgT8BMggFwXswA2EZntwEGFS5mfDJpSiLq29a9F
|
||||
|
||||
#### <a name='a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
|
||||
|
||||
Our familiar base-10 system uses a series of ten symbols known as digits to
|
||||
represent numbers from zero to nine:
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
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
|
||||
|
|
@ -270,27 +270,27 @@ 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
|
||||
4 x 1 +
|
||||
3 x 10 +
|
||||
2 x 100 +
|
||||
1 x 1000
|
||||
|
||||
Or in exponential notation:
|
||||
|
||||
4 x 10^0 +
|
||||
3 x 10^1 +
|
||||
2 x 10^2 +
|
||||
1 x 10^3
|
||||
4 x 10^0 +
|
||||
3 x 10^1 +
|
||||
2 x 10^2 +
|
||||
1 x 10^3
|
||||
|
||||
An MMGen seed mnemonic is a number too, only the “digits” it's comprised of come
|
||||
from an alphabetically sorted series of 1626 words, the [Electrum wordlist][03],
|
||||
which begins like this:
|
||||
|
||||
able (0), about (1), above (2), abuse (3), accept (4) ...
|
||||
able (0), about (1), above (2), abuse (3), accept (4) ...
|
||||
|
||||
and ends like this:
|
||||
|
||||
yet (1621), young (1622), yours (1623), yourself (1624), youth (1625)
|
||||
yet (1621), young (1622), yours (1623), yourself (1624), youth (1625)
|
||||
|
||||
(Type `mmgen-tool mn_printlist` to see the full list)
|
||||
|
||||
|
|
@ -299,62 +299,62 @@ just like the ten digits that make up our familiar base-10 system.
|
|||
|
||||
Here's the mnemonic of our seed (FE3C6545):
|
||||
|
||||
dude foot desperate tie stood themselves trip descend cease suicide apple busy
|
||||
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
|
||||
busy - 200
|
||||
apple - 59
|
||||
suicide - 1384
|
||||
cease - 221
|
||||
descend - 379
|
||||
trip - 1493
|
||||
themselves - 1433
|
||||
stood - 1348
|
||||
tie - 1459
|
||||
desperate - 386
|
||||
foot - 562
|
||||
dude - 439
|
||||
|
||||
All that remains is to multiply the values by increasing powers of 1626 and sum
|
||||
the results:
|
||||
|
||||
200 x 1626^0 +
|
||||
59 x 1626^1 +
|
||||
1384 x 1626^2 +
|
||||
221 x 1626^3 +
|
||||
379 x 1626^4 +
|
||||
1493 x 1626^5 +
|
||||
1433 x 1626^6 +
|
||||
1348 x 1626^7 +
|
||||
1459 x 1626^8 +
|
||||
386 x 1626^9 +
|
||||
562 x 1626^10 +
|
||||
439 x 1626^11
|
||||
200 x 1626^0 +
|
||||
59 x 1626^1 +
|
||||
1384 x 1626^2 +
|
||||
221 x 1626^3 +
|
||||
379 x 1626^4 +
|
||||
1493 x 1626^5 +
|
||||
1433 x 1626^6 +
|
||||
1348 x 1626^7 +
|
||||
1459 x 1626^8 +
|
||||
386 x 1626^9 +
|
||||
562 x 1626^10 +
|
||||
439 x 1626^11
|
||||
|
||||
While we could do this with pencil and paper, a few lines of Python code will
|
||||
make life much easier:
|
||||
|
||||
$ python
|
||||
>>> sum = power = 0
|
||||
>>> for word in 200,59,1384,221,379,1493,1433,1348,1459,386,562,439:
|
||||
>>> sum += word * 1626 ** power
|
||||
>>> power += 1
|
||||
>>> print sum
|
||||
92285275468192044354531703963345906238 # the result in decimal
|
||||
>>> print '{:x}'.format(sum)
|
||||
456d7f5f1c4bfe3bc916b87560ae6a3e # the result in hexadecimal: matches our original hex seed above
|
||||
$ python
|
||||
>>> sum = power = 0
|
||||
>>> for word in 200,59,1384,221,379,1493,1433,1348,1459,386,562,439:
|
||||
>>> sum += word * 1626 ** power
|
||||
>>> power += 1
|
||||
>>> print sum
|
||||
92285275468192044354531703963345906238 # the result in decimal
|
||||
>>> print '{:x}'.format(sum)
|
||||
456d7f5f1c4bfe3bc916b87560ae6a3e # the result in hexadecimal: matches our original hex seed above
|
||||
|
||||
In case you're wondering why 1626 was chosen as the base: 1626 is just large
|
||||
enough to allow a 128-bit seed to be represented by twelve words. This can also
|
||||
be demonstrated at the Python prompt:
|
||||
|
||||
$ python
|
||||
>>> 1626**12 >= 2**128
|
||||
True
|
||||
>>> 1625**12 >= 2**128
|
||||
False
|
||||
$ python
|
||||
>>> 1626**12 >= 2**128
|
||||
True
|
||||
>>> 1625**12 >= 2**128
|
||||
False
|
||||
|
||||
[01]: https://github.com/casascius/Bitcoin-Address-Utility
|
||||
[02]: https://github.com/matja/bitcoin-tool
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ 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
|
||||
$ 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 +25,7 @@ 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
|
||||
$ 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 +46,13 @@ 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'
|
||||
$ 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
|
||||
$ 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.
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ separated by `/`, not `\`. The root of the filesystem is `/`. Drive letter
|
|||
Environmental variables may be viewed with the `env` command. Individual
|
||||
variables may be viewed like this:
|
||||
|
||||
$ echo $PATH
|
||||
$ echo $PATH
|
||||
|
||||
and set like this:
|
||||
|
||||
$ PATH=$PATH:/home/<username>/bin
|
||||
$ PATH=$PATH:/home/<username>/bin
|
||||
|
||||
Sometimes variables must be exported to be visible to called programs:
|
||||
|
||||
$ export PATH
|
||||
$ export PATH
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[**Forum**](https://bitcointalk.org/index.php?topic=567069.0) |
|
||||
[Reddit](https://www.reddit.com/user/mmgen-py) |
|
||||
[PGP Public Key](MMGen-Signing-Key) |
|
||||
Donate: 15TLdmi5NYLdqmtCqczUs5pBPkJDXRs83w
|
||||
Donate (BTC,BCH): 15TLdmi5NYLdqmtCqczUs5pBPkJDXRs83w
|
||||
|
|
|
|||
|
|
@ -69,4 +69,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-ADDRGEN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-ADDRGEN(1)
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@
|
|||
|
||||
The --batch and --rescan options cannot be used together.
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-ADDRIMPORT(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-ADDRIMPORT(1)
|
||||
|
|
|
|||
|
|
@ -61,4 +61,4 @@
|
|||
|
||||
This command is currently available only on Linux-based platforms.
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-AUTOSIGN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-AUTOSIGN(1)
|
||||
|
|
|
|||
|
|
@ -73,4 +73,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-KEYGEN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-KEYGEN(1)
|
||||
|
|
|
|||
|
|
@ -43,4 +43,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-PASSCHG(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-PASSCHG(1)
|
||||
|
|
|
|||
|
|
@ -79,4 +79,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-PASSGEN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-PASSGEN(1)
|
||||
|
|
|
|||
|
|
@ -44,4 +44,4 @@
|
|||
behind the timelock, protection is contingent on getting the non-timelocked
|
||||
transaction reconfirmed before the timelock expires. Use at your own risk.
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-SPLIT(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-SPLIT(1)
|
||||
|
|
|
|||
|
|
@ -92,4 +92,4 @@
|
|||
|
||||
Type 'mmgen-tool help <command> for help on a particular command
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TOOL(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TOOL(1)
|
||||
|
|
|
|||
|
|
@ -77,4 +77,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TXBUMP(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TXBUMP(1)
|
||||
|
|
|
|||
|
|
@ -45,4 +45,4 @@
|
|||
a plain decimal number, or as satoshis per byte, using an integer followed by
|
||||
the letter 's'.
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TXCREATE(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TXCREATE(1)
|
||||
|
|
|
|||
|
|
@ -102,4 +102,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TXDO(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TXDO(1)
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@
|
|||
-s, --status Get status of a sent transaction
|
||||
-y, --yes Answer 'yes' to prompts, suppress non-essential output
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TXSEND(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TXSEND(1)
|
||||
|
|
|
|||
|
|
@ -67,4 +67,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-TXSIGN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-TXSIGN(1)
|
||||
|
|
|
|||
|
|
@ -42,4 +42,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-WALLETCHK(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-WALLETCHK(1)
|
||||
|
|
|
|||
|
|
@ -52,4 +52,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-WALLETCONV(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-WALLETCONV(1)
|
||||
|
|
|
|||
|
|
@ -45,4 +45,4 @@
|
|||
SeedFile .mmseed mmseed,seed,s
|
||||
Wallet .mmdat wallet,w
|
||||
|
||||
MMGEN v0.9.599 December 2017 MMGEN-WALLETGEN(1)
|
||||
MMGEN v0.9.6 January 2018 MMGEN-WALLETGEN(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue