Options fixes in 'mmgen-pywallet'
Added copies of wiki pages to doc/ for offline viewing Added INSTALL and SIGNING_KEY.pub
This commit is contained in:
parent
cd7f757a62
commit
9cbc2b13d0
16 changed files with 1049 additions and 73 deletions
13
INSTALL
Normal file
13
INSTALL
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
MMGen is written in Pure Python and runs on MS Windows and Linux.
|
||||
|
||||
Instructions for installation and use reside on MMGen's Github wiki:
|
||||
|
||||
To install MMGen:
|
||||
https://github.com/mmgen/mmgen/wiki/
|
||||
|
||||
To use MMGen:
|
||||
https://github.com/mmgen/mmgen/wiki/Getting-Started-with-MMGen
|
||||
|
||||
The wiki pages are duplicated under this distribution's doc directory for
|
||||
offline reading.
|
||||
52
SIGNING_KEY.pub
Normal file
52
SIGNING_KEY.pub
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.11 (GNU/Linux)
|
||||
|
||||
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
|
||||
dRrWK1eeHDwJ7AnLSfwxBGc=
|
||||
=Amww
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Make sure that the following development packages for the boost library are
|
||||
installed (package names may vary; the version should be 1.48 or greater, and
|
||||
version 1.54 on Ubuntu 13.10 is reported not to work):
|
||||
|
||||
libboost-system-dev
|
||||
libboost-filesystem-dev
|
||||
libboost-program-options-dev
|
||||
libboost-chrono-dev
|
||||
libboost-test-dev
|
||||
libboost-thread-dev
|
||||
|
||||
You'll also need the standard build tools such as automake, autoconf and
|
||||
libtool, but these are probably already on your system if you've done any
|
||||
compiling from source.
|
||||
|
||||
Clone the bitcoin repository from Github, configure, and build:
|
||||
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
$ cd bitcoin
|
||||
$ ./autogen.sh
|
||||
$ ./configure --without-gui
|
||||
$ make -j4
|
||||
|
||||
If 'configure' complains about a missing libdb version 4.8, you have
|
||||
two options: either install the libdb4.8-dev package or use the add the
|
||||
'--with-incompatible-bdb' option to the 'configure' command line. Be warned
|
||||
that the latter option will result in your 'wallet.dat' files being incompatible
|
||||
with the binary build of bitcoind.
|
||||
|
||||
Your freshly compiled daemon is now in the src/ directory. Refer to **Run:** on
|
||||
the [binary installation page][01] for running instructions.
|
||||
|
||||
[01]: Install-Bitcoind
|
||||
[dl]: https://bitcoin.org/en/download
|
||||
[gs]: Getting-Started-with-MMGen
|
||||
63
doc/wiki/install-linux/Install-Bitcoind.md
Normal file
63
doc/wiki/install-linux/Install-Bitcoind.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#### Note:
|
||||
|
||||
> The bitcoin daemon on the **offline computer** is used solely to sign
|
||||
> transactions and runs without a blockchain. Thus even a low-powered computer
|
||||
> such as a netbook will suffice as your offline machine.
|
||||
>
|
||||
> The bitcoin daemon on the **online computer** requires a complete and
|
||||
> up-to-date blockchain for tracking addresses. Since its work is more CPU and
|
||||
> disk intensive, a more powerful computer is recommended here. You'll also
|
||||
> need plenty of free disk space for the rapidly growing blockchain (~30GB at
|
||||
> the time of writing).
|
||||
>
|
||||
> Two blockchain operations are especially resource-intensive: **synchronizing
|
||||
> the blockchain** and **importing existing addresses with balances**. If you
|
||||
> synchronize often (once a week, for example) and take care to import your
|
||||
> addresses **before** spending into them, then it's possible to use a
|
||||
> low-powered netbook as your online machine.
|
||||
|
||||
#### Download:
|
||||
|
||||
> For the time being, Windows installers and Linux binary tarballs can be
|
||||
> obtained [here][00]. Once version 0.10 is released, get them from Bitcoin
|
||||
> Core's [main download page][01] instead. Choose the 32-bit or 64-bit versions
|
||||
> appropriate for your respective computers.
|
||||
|
||||
#### Install:
|
||||
|
||||
> **On both the online and offline computers:**
|
||||
|
||||
> Windows users: run the Windows installer. Linux users: unpack the tar archive
|
||||
> and copy the bitcoind executable in bin/ to your execution path or just run it
|
||||
> in place.
|
||||
|
||||
#### Run:
|
||||
|
||||
> **On the online computer:**
|
||||
|
||||
> Open a terminal and start bitcoind with the command:
|
||||
|
||||
$ bitcoind -daemon
|
||||
|
||||
> Warning: If you already have Bitcoin Core installed, **move your existing
|
||||
> wallet.dat out of harm's way** before starting bitcoind. The new wallet
|
||||
> now created will be used as your **tracking wallet**.
|
||||
|
||||
> If you're connected to the Internet, bitcoind will begin downloading and
|
||||
> verifying the blockchain. This can take many hours if you're downloading the
|
||||
> blockchain from scratch. To speed up the process you may want to use the
|
||||
> [bootstrap.dat][bd] torrent provided by the Bitcoin Core developers.
|
||||
> Instructions are provided on the linked page.
|
||||
|
||||
> **On the offline computer:**
|
||||
|
||||
> Open a terminal and start bitcoind with the command:
|
||||
|
||||
$ bitcoind -daemon -maxconnections=0 -listen=0
|
||||
|
||||
> Note that in the absence of a blockchain the daemon starts very quickly and
|
||||
> uses practically no CPU once running.
|
||||
|
||||
[00]: https://bitcoin.org/bin/0.10.0/test/
|
||||
[01]: https://bitcoin.org/en/download
|
||||
[bd]: https://bitcoin.org/bin/blockchain/
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#### Perform the following steps on both your online and offline computers:
|
||||
|
||||
Install the pip Python installer:
|
||||
|
||||
$ sudo apt-get install python-pip
|
||||
|
||||
Install required Python modules:
|
||||
|
||||
$ sudo pip install ecdsa scrypt pycrypto bitcoin-python pexpect
|
||||
|
||||
Install MMGen:
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen.git
|
||||
$ cd mmgen; sudo ./setup.py install
|
||||
|
||||
Install vanitygen (optional but recommended):
|
||||
|
||||
$ git clone https://github.com/samr7/vanitygen.git
|
||||
(build and put the "keyconv" executable in your path)
|
||||
|
||||
Install bitcoind:
|
||||
|
||||
> To install prebuilt binaries, click [here][01]. To install from source,
|
||||
> click [here][02].
|
||||
|
||||
**NB:** If your offline machine is already disconnected from the Internet,
|
||||
do the following:
|
||||
|
||||
> From your online machine, download the 'python-pip' package from Debian or
|
||||
> Ubuntu and the Python packages from pypi.python.org/pypi/<packagename>.
|
||||
> Transfer these files and the git repositories you've cloned to your offline
|
||||
> computer using a USB stick or other means at your disposal. Now install
|
||||
> 'python-pip' with 'sudo dpkg -i', unpack each Python module and install it
|
||||
> using 'sudo ./setup.py install', and install MMGen and vanitygen from the
|
||||
> copied git repositories as described above.
|
||||
|
||||
Congratulations, your installation is now complete! Now proceed to [**Getting
|
||||
Started with MMGen**][gs].
|
||||
|
||||
[01]: Install-Bitcoind
|
||||
[02]: Install-Bitcoind-from-Source-on-Debian-or-Ubuntu-Linux
|
||||
[gs]: Getting-Started-with-MMGen
|
||||
63
doc/wiki/install-mswin/Install-Bitcoind.md
Normal file
63
doc/wiki/install-mswin/Install-Bitcoind.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#### Note:
|
||||
|
||||
> The bitcoin daemon on the **offline computer** is used solely to sign
|
||||
> transactions and runs without a blockchain. Thus even a low-powered computer
|
||||
> such as a netbook will suffice as your offline machine.
|
||||
>
|
||||
> The bitcoin daemon on the **online computer** requires a complete and
|
||||
> up-to-date blockchain for tracking addresses. Since its work is more CPU and
|
||||
> disk intensive, a more powerful computer is recommended here. You'll also
|
||||
> need plenty of free disk space for the rapidly growing blockchain (~30GB at
|
||||
> the time of writing).
|
||||
>
|
||||
> Two blockchain operations are especially resource-intensive: **synchronizing
|
||||
> the blockchain** and **importing existing addresses with balances**. If you
|
||||
> synchronize often (once a week, for example) and take care to import your
|
||||
> addresses **before** spending into them, then it's possible to use a
|
||||
> low-powered netbook as your online machine.
|
||||
|
||||
#### Download:
|
||||
|
||||
> For the time being, Windows installers and Linux binary tarballs can be
|
||||
> obtained [here][00]. Once version 0.10 is released, get them from Bitcoin
|
||||
> Core's [main download page][01] instead. Choose the 32-bit or 64-bit versions
|
||||
> appropriate for your respective computers.
|
||||
|
||||
#### Install:
|
||||
|
||||
> **On both the online and offline computers:**
|
||||
|
||||
> Windows users: run the Windows installer. Linux users: unpack the tar archive
|
||||
> and copy the bitcoind executable in bin/ to your execution path or just run it
|
||||
> in place.
|
||||
|
||||
#### Run:
|
||||
|
||||
> **On the online computer:**
|
||||
|
||||
> Open a terminal and start bitcoind with the command:
|
||||
|
||||
$ bitcoind -daemon
|
||||
|
||||
> Warning: If you already have Bitcoin Core installed, **move your existing
|
||||
> wallet.dat out of harm's way** before starting bitcoind. The new wallet
|
||||
> now created will be used as your **tracking wallet**.
|
||||
|
||||
> If you're connected to the Internet, bitcoind will begin downloading and
|
||||
> verifying the blockchain. This can take many hours if you're downloading the
|
||||
> blockchain from scratch. To speed up the process you may want to use the
|
||||
> [bootstrap.dat][bd] torrent provided by the Bitcoin Core developers.
|
||||
> Instructions are provided on the linked page.
|
||||
|
||||
> **On the offline computer:**
|
||||
|
||||
> Open a terminal and start bitcoind with the command:
|
||||
|
||||
$ bitcoind -daemon -maxconnections=0 -listen=0
|
||||
|
||||
> Note that in the absence of a blockchain the daemon starts very quickly and
|
||||
> uses practically no CPU once running.
|
||||
|
||||
[00]: https://bitcoin.org/bin/0.10.0/test/
|
||||
[01]: https://bitcoin.org/en/download
|
||||
[bd]: https://bitcoin.org/bin/blockchain/
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
##### Note: The following instructions assume you'll be unpacking all archives to `C:\`, the root directory on most Windows installations. If you choose to unpack to another location, the `cd` commands must be adjusted accordingly.
|
||||
|
||||
#### 1. Install the Python interpreter:
|
||||
|
||||
Grab the [Windows 32-bit installer][09] and run it, accepting the defaults.
|
||||
Add the Python base and Scripts directories to your [path][08], e.g.
|
||||
`C:\Python27;C:\Python27\Scripts`.
|
||||
|
||||
#### 2. Build OpenSSL:
|
||||
|
||||
Grab the [latest tarball][06] from the [openssl.org download page][05] and unpack
|
||||
it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/openssl-1.0.1g
|
||||
$ ./config --openssldir=/usr
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
#### 3. Build the Scrypt Python module:
|
||||
|
||||
Grab the [latest tarball][07] from python.org and unpack it. At the MSYS prompt,
|
||||
run:
|
||||
|
||||
$ cd /c/scrypt-0.6.1
|
||||
|
||||
Open `setup.py` in your text editor and make the following changes:
|
||||
|
||||
> Change the line:
|
||||
|
||||
library_dirs = ['c:\OpenSSL-Win32\lib\MinGW']
|
||||
|
||||
> to read:
|
||||
|
||||
library_dirs = ['c:\msys\lib','c:\WINDOWS\system32']
|
||||
|
||||
> Change the line:
|
||||
|
||||
includes = ['c:\OpenSSL-Win32\include']
|
||||
|
||||
> to read:
|
||||
|
||||
includes = ['c:\msys\include']
|
||||
|
||||
Save the file. At the MSYS prompt, run:
|
||||
|
||||
$ python setup.py build --compiler=mingw32
|
||||
|
||||
Ignore the warning messages at the end and run:
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
#### 4. Install the Pycrypto Python module:
|
||||
|
||||
Source code is available from the [Pycrypto home page][00], but it appears to
|
||||
build only with MS Visual Studio, not MinGW. Until this situation is fixed,
|
||||
you can install the precompiled binaries available from [Voidspace][01].
|
||||
Download and run the [Windows installer][02], accepting the defaults.
|
||||
|
||||
#### 5. Install the ecdsa Python module:
|
||||
|
||||
Grab the [tarball][03] and unpack it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/ecdsa-0.11
|
||||
$ python setup.py install
|
||||
|
||||
#### 6. Install the bitcoin-python Python module:
|
||||
|
||||
Grab the [tarball][04] and unpack it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/bitcoin-python-0.3
|
||||
$ cp -a src/bitcoinrpc /c/Python27/Lib/site-packages
|
||||
|
||||
This is a workaround for a dependency issue with the package's setup script.
|
||||
If your Python is installed in a different location, you'll have to adjust the
|
||||
destination path accordingly.
|
||||
|
||||
#### 7. Install MMGen:
|
||||
|
||||
Get the [zip archive][10] from GitHub and unpack it. At the MSYS prompt, run:
|
||||
|
||||
$ cd /c/mmgen-master
|
||||
$ sudo ./setup.py install
|
||||
|
||||
Type:
|
||||
|
||||
$ echo $PATH
|
||||
|
||||
The `C:\Python27;C:\Python27\Scripts` you added to your path in Step 1 of this
|
||||
page should be included in your PATH variable. If not, then exit MSYS and open
|
||||
a new MSYS window to update your path.
|
||||
|
||||
[00]: https://www.dlitz.net/software/pycrypto/
|
||||
[01]: http://www.voidspace.org.uk/python/modules.shtml#pycrypto
|
||||
[02]: http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe)
|
||||
[03]: https://pypi.python.org/pypi/ecdsa
|
||||
[04]: https://pypi.python.org/pypi/bitcoin-python/0.3
|
||||
[09]: https://www.python.org/ftp/python/2.7.6/python-2.7.6.msi
|
||||
[08]: Editing-the-user-path-in-Windows
|
||||
[07]: https://pypi.python.org/pypi/scrypt/
|
||||
[06]: http://www.openssl.org/source/openssl-1.0.1g.tar.gz
|
||||
[05]: http://www.openssl.org/source/
|
||||
[10]: https://github.com/mmgen/mmgen/archive/master.zip
|
||||
[11]: http://slproweb.com/download/Win32OpenSSL-1_0_1f.exe
|
||||
[12]: http://www.openssl.org/related/binaries.html
|
||||
[13]: Getting-Started-with-MMGen
|
||||
14
doc/wiki/install-mswin/Install-MMGen-on-Microsoft-Windows.md
Normal file
14
doc/wiki/install-mswin/Install-MMGen-on-Microsoft-Windows.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Install MMGen on Windows by completing the following three steps:
|
||||
|
||||
> 1. [Install MinGW and MSYS][01], if you haven't already;
|
||||
> 2. [Install MMGen's dependencies (excluding the bitcoin daemons) and
|
||||
> MMGen itself][02]; and
|
||||
> 3. [Install the offline and online bitcoin daemons (bitcoind)][07].
|
||||
|
||||
Congratulations, your MMGen installation is now complete! Now move on to
|
||||
[**Getting Started with MMGen**][08].
|
||||
|
||||
[01]: Install-MinGW-and-MSYS-on-Microsoft-Windows
|
||||
[02]: Install-MMGen-and-Its-Dependencies-on-Microsoft-Windows
|
||||
[07]: Install-Bitcoind
|
||||
[08]: Getting-Started-with-MMGen
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
MinGW (Minimal GNU for Windows) provides the gcc compiler and related tools for
|
||||
compiling source code into Windows binaries. MSYS provides a Unix-like
|
||||
environment with basic Unix shell commands. MinGW and MSYS are part of the
|
||||
same project and are designed to be used together.
|
||||
|
||||
Complete hypertexed lists of the required MinGW and MSYS archive files are
|
||||
provided below for convenient downloading. Save the archives into two separate
|
||||
temporary directories (`mingw` and `msys`, for example).
|
||||
|
||||
> * [MinGW archive list][02]
|
||||
> * [MSYS archive list][03]
|
||||
|
||||
##### Note: these lists were up to date at the time of writing (April 2014). More recent versions may be available in the [MinGW repository][01] as you read this, but hunting for them isn't likely to be worth your time.
|
||||
|
||||
|
||||
Unpack the basic-bsdtar archive (in the MinGW archives) and copy the executable
|
||||
`basic-bsdtar.exe` to your path (e.g. `C:\WINDOWS\system32`).
|
||||
|
||||
From the DOS prompt, run `mkdir C:\mingw` to create the directory `C:\mingw`.
|
||||
Run `cd C:\mingw` to move to the directory. Unpack each of the MinGW archives
|
||||
(except for `basic-bsdtar`) as follows:
|
||||
|
||||
basic-bsdtar -xf <path to archive>
|
||||
|
||||
Create a `C:\msys` directory the same way, move to it and repeat the above
|
||||
unpacking procedure with the MSYS archives.
|
||||
|
||||
Add `C:\mingw\bin` to your user path. Consult [this page][05] for instructions
|
||||
on editing your user path.
|
||||
|
||||
Close the command prompt window and open a new one. Launch the MSYS shell with
|
||||
the command `C:\msys\bin\bash.exe --login`. You'll now be in the home
|
||||
directory of your MSYS environment.
|
||||
|
||||
If you want be able to launch MSYS from an icon instead of typing the above
|
||||
command all the time, then do the following: Make a copy of the "Command Line"
|
||||
icon on your desktop and rename it to "MSYS". Right click on the icon, select
|
||||
"Properties" and change the highlighted command path to `C:\msys\bin\bash.exe
|
||||
--login`. You may also want to change the "Home Folder" field to your MSYS home
|
||||
directory, `C:\msys\home\Admin` for the Admin user.
|
||||
|
||||
Note: At this point you're advised to read [**A word on text editors**][00]
|
||||
before proceeding further with your installation.
|
||||
|
||||
Run the command `mount c:/mingw /mingw` to include your MinGW installation in
|
||||
the MSYS tree. So you won't have to run this command every time you log in to
|
||||
MSYS, open the file `/etc/fstab` in your text editor and add the line `c:/mingw
|
||||
/mingw` (if it's not already there).
|
||||
|
||||
#### Unix commands and environment:
|
||||
|
||||
If you're new to Unix, you should learn a few key commands:
|
||||
|
||||
> * `ls` - view directory contents (`ls -l` for a long view)
|
||||
> * `rm` - remove files (`rm -r` to remove entire directory trees)
|
||||
> * `rmdir` - remove an empty directory
|
||||
> * `cp` - copy a file (`cp -a` to copy directory trees)
|
||||
> * `mv` - move a file or directory
|
||||
> * `cat` - output a file to screen
|
||||
> * `less` - view a file page-by-page, with scrollback
|
||||
|
||||
Command help texts can be accessed with the `--help` switch. The MSYS root
|
||||
directory is `/`. Drive letter `C:` can be accessed as `/c/`.
|
||||
|
||||
Environmental variables may be viewed with the `env` command. Individual
|
||||
variables may be displayed like this:
|
||||
|
||||
$ echo $PATH
|
||||
|
||||
and set like this:
|
||||
|
||||
$ set PATH=$PATH:/home/Admin/bin
|
||||
|
||||
Sometimes variables must be exported to be visible to called programs:
|
||||
|
||||
$ export PATH
|
||||
|
||||
[00]: A-word-on-text-editors
|
||||
[01]: http://sourceforge.net/projects/mingw/files/
|
||||
[02]: Required-MinGW-Archives
|
||||
[03]: Required-MSYS-Archives
|
||||
[05]: Editing-the-user-path-in-Windows
|
||||
495
doc/wiki/using-mmgen/Getting-Started-with-MMGen.md
Normal file
495
doc/wiki/using-mmgen/Getting-Started-with-MMGen.md
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
## Table of Contents
|
||||
|
||||
#### <a href=#01>Basic Operations</a>
|
||||
* <a href=#02>Generate a wallet</a>
|
||||
* <a href=#03>Generate addresses</a>
|
||||
* <a href=#04>Import addresses</a>
|
||||
* <a href=#05>Create a transaction</a>
|
||||
* <a href=#06>Sign a transaction</a>
|
||||
* <a href=#07>Send a transaction</a>
|
||||
|
||||
#### <a href=#10>Additional Features</a>
|
||||
* <a href=#11>Using the mnemonic and seed features</a>
|
||||
* <a href=#12>Mnemonics and seeds — additional information</a>
|
||||
* <a href=#13>Incognito wallets</a>
|
||||
|
||||
|
||||
### <a name=01>Basic Operations</a>
|
||||
|
||||
#### <a name=02>Generate a wallet (offline computer):</a>
|
||||
|
||||
On your offline computer, generate a wallet with a random seed:
|
||||
|
||||
$ mmgen-walletgen
|
||||
...
|
||||
Wallet saved to file '89ABCDEF-76543210[256,3].mmdat'
|
||||
|
||||
"89ABCDEF" is the Seed ID; "76543210" is the Key ID. These are randomly
|
||||
generated, so your IDs will of course be different than the fictitious ones used
|
||||
here.
|
||||
|
||||
The Seed ID never changes and will be used to identify all keys/addresses
|
||||
generated by this seed. The Key ID changes when the wallet's password or hash
|
||||
preset are changed.
|
||||
|
||||
"256" is the seed length; "3" is the scrypt hash preset. These values are
|
||||
configurable: type 'mmgen-walletgen --help' for details.
|
||||
|
||||
#### <a name=03>Generate addresses (offline computer):</a>
|
||||
|
||||
Now generate ten addresses with your just-created wallet:
|
||||
|
||||
$ mmgen-addrgen 89ABCDEF-76543210[256,3].mmdat 1-10
|
||||
...
|
||||
Address data saved to file '89ABCDEF[1-10].addrs'
|
||||
|
||||
$ cat '89ABCDEF[1-10].addrs'
|
||||
89ABCDEF {
|
||||
1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE
|
||||
2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc
|
||||
3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N
|
||||
4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
|
||||
5 1PeI55vtp2bX2uKDkAAR2c6ekHNYe4Hcq7
|
||||
6 1FEqfEsSILwXPfMvVvVuUovzTaaST62Mnf
|
||||
7 1LTTzuhMqPLwQ4IGCwwugny6ZMtUQJSJ1
|
||||
8 1F9495H8EJLb54wirgZkVgI47SP7M2RQWv
|
||||
9 1JbrCyt7BdxRE9GX1N7GiEct8UnIjPmpYd
|
||||
10 1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
|
||||
}
|
||||
|
||||
Note that the address range, "1-10", is reflected in the resulting filename.
|
||||
MMGen addresses are identified by their seed ID and index number, separated by a
|
||||
colon. In this example, "89ABCDEF:1" is the MMGen equivalent of Bitcoin address
|
||||
16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE, "89ABCDEF:2" the equivalent of
|
||||
1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc, and so forth.
|
||||
|
||||
Let's say you've decided to transfer some BTC into the first four addresses
|
||||
above. Your first step, then, will be to import these addresses into the
|
||||
tracking wallet on your online machine so their balances will be visible.
|
||||
For convenient identification, you've chosen to provide the addresses with the
|
||||
labels "Donations", "Storage 1", "Storage 2" and "Storage 3".
|
||||
|
||||
Make a copy of the file:
|
||||
|
||||
$ cp '89ABCDEF[1-10].addrs' my.addrs
|
||||
|
||||
and edit the copy using your favorite text editor to look like this:
|
||||
|
||||
$ cat my.addrs
|
||||
# My first MMGen addresses
|
||||
89ABCDEF {
|
||||
1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations
|
||||
2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
||||
3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
||||
4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
||||
}
|
||||
|
||||
Note the comment beginning with a '#' symbol. Comments may be placed at the
|
||||
ends of lines as well. Note also that rows in the list may be arranged in any
|
||||
order: addresses need not be consecutive.
|
||||
|
||||
Copy this file onto a USB stick and transfer it to your online computer.
|
||||
|
||||
#### <a name=04>Import addresses (online computer):</a>
|
||||
|
||||
On your online computer, go to your bitcoind data directory and move any
|
||||
existing 'wallet.dat' file out of the way. Start bitcoind and let it generate
|
||||
a new 'wallet.dat', which you'll use as your **tracking wallet**. Import your
|
||||
four addresses into the new tracking wallet with the command:
|
||||
|
||||
$ mmgen-addrimport my.addrs
|
||||
|
||||
These addresses will now be tracked by bitcoind. Any BTC transferred to them
|
||||
will show up in your listing of address balances. Balances can be viewed with
|
||||
the 'mmgen-tool' utility:
|
||||
|
||||
$ mmgen-tool listaddresses
|
||||
No addresses with balances!
|
||||
|
||||
The 'showempty' option shows all tracked addresses, even ones with no balances,
|
||||
so the four imported addresses should now show up on the listing:
|
||||
|
||||
$ mmgen-tool listaddresses showempty=1
|
||||
ADDRESS COMMENT BALANCE
|
||||
89ABCDEF:1 Donations 0
|
||||
89ABCDEF:2 Storage 1 0
|
||||
89ABCDEF:3 Storage 2 0
|
||||
89ABCDEF:4 Storage 3 0
|
||||
|
||||
If you have any existing addresses with balances, you'll want to track them too.
|
||||
Make a plain list of these addresses, one address per line, and import the list
|
||||
into the tracking wallet using 'mmgen-addrimport -l'.
|
||||
|
||||
$ mmgen-addrimport --rescan -l my_existing_addrs_with_balances
|
||||
|
||||
NOTE: The '--rescan' option forces a rescan of the entire block chain, which is
|
||||
required for all addresses with existing balances. Since the rescanning process
|
||||
is very slow, you'll save yourself a great deal of time by always importing
|
||||
new addresses BEFORE spending into them.
|
||||
|
||||
Continue in this fashion until you've imported all addresses with balances into
|
||||
your tracking wallet.
|
||||
|
||||
#### <a name=05>Create a transaction (online computer):</a>
|
||||
|
||||
Now that your existing addresses are imported, you're ready to create a test
|
||||
transaction using the 'mmgen-txcreate' command. Note that transactions are
|
||||
harmless until they're signed and broadcast to the network, so feel free to
|
||||
experiment with different transactions using different combinations of inputs
|
||||
and outputs.
|
||||
|
||||
First of all you'll want to examine your balances. Note that 'mmgen-tool
|
||||
listaddresses' shows only MMGen address balances; to view **all** balances,
|
||||
including your non-MMGen ones, use the 'mmgen-txcreate' command:
|
||||
|
||||
$ mmgen-txcreate -i
|
||||
|
||||
A list of all unspent outputs will appear, along with a menu allowing you to
|
||||
sort the outputs by four criteria: transaction ID, address, amount and
|
||||
transaction age. Your overall balance in BTC appears at the top of the screen.
|
||||
The list may be viewed in a pager or printed to file. For a wallet with ten
|
||||
unspent outputs, the display might look something like this:
|
||||
|
||||
UNSPENT OUTPUTS (sort order: reverse amount) Total BTC: 39.72
|
||||
Num TX id Vout Address Amount (BTC) Age(days)
|
||||
1) 04f97185... 2 1F93Znz8PI5Pnvv8ZAJsb74EzKpmRMLFbk 10 320
|
||||
2) dd900544... 1 194Fceqx86jqIWumphUmfVyFMjAAbMLcSE 9.9287435 7
|
||||
3) 7ec81a8f... 0 1FhIkRabPSZhhUsA6qvukmfK4T4PZLbC4M 7.26 17
|
||||
4) 64094b55... 0 16JSUJdGMbxUBEQatAR5sGE89tbSIsLHqg 3.15 140
|
||||
5) fd687c65... 1 1QKAtU66aUntCBx9m6TfEIf3gQuCNWCVDY 3.15 140
|
||||
6) 9a8f20e2... 1 1FMNDFz1yUywjJSprjvYY9t1yxkE8GGIwT 3.15 140
|
||||
7) 03a7c51a... 3 1svxnSdKVIcMs6qWYA7qLzA29orXbzXUm 1.6382466 54
|
||||
8) 9955f06c... 2 18nWPLQGUzI7X1Rcm4zmVV6Z3xhokdYx9G 1.2 27
|
||||
9) 8a4ab4f5... 0 13S9HNu7PQn1aJ4qILfhqRSakXwvSTnbwJ 0.23033 3
|
||||
10) 5bfe5621... 1 1FV1Lhs6Dnc9gMxjJTo6h4nTeIjJbQ1PgV 0.01 42
|
||||
|
||||
Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [M]mgen addr
|
||||
View options: [g]roup, show [m]mgen addr
|
||||
(Type 'q' to quit sorting, 'p' to print to file, 'v' to view in pager):
|
||||
|
||||
Now let's actually create a transaction. Let's say you've decided to gradually
|
||||
begin moving your 39.72 BTC balance into your shiny new MMGen wallet with seed
|
||||
ID 89ABCDEF.
|
||||
|
||||
Before moving any funds into your MMGen wallet, you should back it up in several
|
||||
places and possibly on several media too: paper, flash memory or CD-ROM, for
|
||||
example. Of course the wallet should have a passphrase. Otherwise, anyone who
|
||||
gains physical access to one of your backups can easily steal your coins.
|
||||
|
||||
Recall that there's no limit to the number of addresses you can generate with
|
||||
your seed. You've wisely determined that having many addresses with relatively
|
||||
small balances is a Good Idea. So you've decided to begin by breaking up the
|
||||
address with the largest balance, 10 BTC, into three roughly equal parts,
|
||||
sending it to the addresses labeled "Storage 1", "Storage 2" and "Storage 3"
|
||||
(89ABCDEF:2, 89ABCDEF:3 and 89ABCDEF:4).
|
||||
|
||||
To refresh your memory, here are the three addresses in question:
|
||||
|
||||
$ cat my.addrs
|
||||
# My first MMGen addresses
|
||||
89ABCDEF {
|
||||
1 16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE Donations
|
||||
2 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc Storage 1
|
||||
3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N Storage 2
|
||||
4 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s Storage 3
|
||||
}
|
||||
|
||||
The following command will send 3.3 BTC to the first two addresses and the
|
||||
remainder of the transaction's 10 BTC input to the third, subtracting a default
|
||||
transaction fee of 0.001 BTC:
|
||||
|
||||
$ mmgen-txcreate 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,3.3 1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N,3.3 14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s
|
||||
|
||||
The bare address with no amount is the **change address**. MMGen will compute
|
||||
the change amount (3.399 BTC in this case) automatically.
|
||||
|
||||
Note that the above transaction can be written much more elegantly and concisely
|
||||
using MMGen addresses in place of their Bitcoin equivalents:
|
||||
|
||||
$ mmgen-txcreate 89ABCDEF:2,3.3 89ABCDEF:3,3.3 89ABCDEF:4
|
||||
|
||||
After hitting ENTER you'll be presented with the same display produced by the
|
||||
'-i' option above, plus an interactive menu. After quitting with 'q', you'll
|
||||
be prompted to choose the transaction's inputs.
|
||||
|
||||
Enter a range or space-separated list of outputs to spend:
|
||||
|
||||
Find the input with the 10 BTC balance in the list. This is input 1), so type
|
||||
'1' and ENTER. After several more prompts and confirmations 'mmgen-txcreate'
|
||||
will exit with the message:
|
||||
|
||||
Transaction data saved to file 'tx_1EDCBA[6.6].raw'
|
||||
|
||||
Note that the transaction has a unique ID, and the non-change spend amount, 6.6
|
||||
BTC, is conveniently included in the filename.
|
||||
|
||||
#### <a name=06>Sign a transaction (offline computer):</a>
|
||||
|
||||
Now copy the raw transaction you've just created to a USB stick and transfer it
|
||||
to your offline computer for signing. You need to find the key for your
|
||||
transaction's one input address, 1F9495H8EJL.... If the key in question is in a
|
||||
bitcoin 'wallet.dat', there's an included command (a modified version of the
|
||||
well-known pywallet utility) that will conveniently extract it for you:
|
||||
|
||||
$ mmgen-pywallet -k wallet.dat
|
||||
...
|
||||
wallet.dat secret keys saved to file wd_EDBC983A[102].keys
|
||||
|
||||
You've in fact extracted a list of all of the wallet's 102 keys here, but that's
|
||||
not a problem, since the unused keys will be ignored (you can extract only the
|
||||
keys you need using the '--keys-for-addrs' option). Now go ahead and sign the
|
||||
transaction using this list of keys.
|
||||
|
||||
$ mmgen-txsign -k wd_EDBC983A[102].keys tx_1EDCBA[6.6].raw
|
||||
...
|
||||
Signed transaction saved to file tx_ABCDEF[0.1].sig
|
||||
|
||||
Note that 'mmgen-pywallet's output is just a flat list of keys. So if you have
|
||||
several Bitcoin wallets with balances, you can just dump all their keys and
|
||||
merge them into a single file which you can use to sign all future transactions
|
||||
with wallet.dat inputs:
|
||||
|
||||
$ mmgen-pywallet -k wallet1.dat
|
||||
$ mmgen-pywallet -k wallet2.dat
|
||||
$ mmgen-pywallet -k wallet3.dat
|
||||
$ cat wd_*.keys > all_keys
|
||||
|
||||
For your future transactions with MMGen address inputs, you'll list the MMGen
|
||||
seed source (wallet, mnemonic or seed file) on the command line after the
|
||||
transaction file, and the required keys will be generated automatically, as in
|
||||
this example:
|
||||
|
||||
$ mmgen-txsign tx_9D2C3A[1.23].raw B73B58EA-125FB230[256,3].mmdat
|
||||
...
|
||||
Signed transaction saved to file tx_9D2C3A[1.23].sig
|
||||
|
||||
Transactions may contain a mixture of MMGen and non-MMGen inputs as well as
|
||||
inputs with more than one MMGen seed ID. Just provide a seed source for each
|
||||
seed ID on the command line.
|
||||
|
||||
Eventually, when you've placed all your BTC under MMGen control, you'll never
|
||||
have deal with keys directly again, because MMGen generates all keys on the fly
|
||||
using the seed.
|
||||
|
||||
#### <a name=07>Send a transaction (online computer):</a>
|
||||
|
||||
Now you're ready for the final step: broadcasting the transaction to the network.
|
||||
Copy the 'tx_*.sig' file to your online computer, start bitcoind, if it's not
|
||||
running, and execute the command:
|
||||
|
||||
$ mmgen-txsend tx_1EDCBA[6.6].sig
|
||||
|
||||
Like all MMGen commands, 'mmgen-txsend' is interactive, so you'll be asked for
|
||||
confirmation before the transaction is actually sent.
|
||||
|
||||
Once the transaction's confirmed by the network, your three new MMGen addresses
|
||||
will appear on the listing of 'mmgen-txcreate -i'. Type 'm' at the menu to
|
||||
see them displayed in MMGen format.
|
||||
|
||||
Congratulations! You've performed your first MMGen transaction and placed your
|
||||
first funds under MMGen's control.
|
||||
|
||||
### <a name=10>Additional Features</a>
|
||||
|
||||
#### <a name=11>Using the mnemonic and seed features:</a>
|
||||
|
||||
Continuing our example above, generate a mnemonic from the wallet:
|
||||
|
||||
$ mmgen-walletchk -m '89ABCDEF-76543210[256,3].mmdat'
|
||||
...
|
||||
Mnemonic data saved to file '89ABCDEF.mmwords'
|
||||
|
||||
$ cat 89ABCDEF.mmwords
|
||||
pleasure tumble spider laughter many stumble secret bother after search
|
||||
float absent path strong curtain savior worst suspend bright touch away
|
||||
dirty measure thorn
|
||||
|
||||
Note: a 128- or 192-bit seed will generate a shorter mnemonic of 12 or 18
|
||||
words. You may generate a wallet with these seed lengths using the '-l'
|
||||
option to 'mmgen-walletgen'.
|
||||
|
||||
Though some consider 128 bits of entropy to provide adequate security for the
|
||||
foreseeable future, you should stick to the default 256-bit seed length if
|
||||
you're not planning to use the mnemonic feature.
|
||||
|
||||
NOTE: MMGen mnemonics are generated from the Electrum wordlist, but using
|
||||
ordinary base conversion instead of Electrum's more complicated algorithm.
|
||||
|
||||
Generate addresses 1-11 of seed 89ABCDEF using the mnemonic instead of the
|
||||
wallet:
|
||||
|
||||
$ mmgen-addrgen 89ABCDEF.mmwords 1-11
|
||||
...
|
||||
Address data saved to file '89ABCDEF[1-11].addrs'
|
||||
|
||||
Compare the first ten addresses with those earlier generated by the wallet.
|
||||
You'll see they're the same.
|
||||
|
||||
Regenerate a lost wallet using the mnemonic:
|
||||
|
||||
$ mmgen-walletgen 89ABCDEF.mmwords
|
||||
...
|
||||
Wallet saved to file '89ABCDEF-01234567[256,3].mmdat'
|
||||
|
||||
Note that the regenerated wallet has a different Key ID but of course the same
|
||||
Seed ID.
|
||||
|
||||
Seed files bear the extension '.mmseed' and are listed on the command line the
|
||||
same way mnemonic files are.
|
||||
|
||||
A seed file for a 256-bit seed looks like this:
|
||||
|
||||
$ cat 8B7392ED.mmseed
|
||||
f4c84b C5ZT wWpT Jsoi wRVw 2dm9 Aftd WLb8 FggQ eC8h Szjd da9L
|
||||
|
||||
And for a 128-bit seed:
|
||||
|
||||
$ cat 8E0DFB78.mmseed
|
||||
0fe02f XnyC NfPH piuW dQ2d nM47 VU
|
||||
|
||||
As you can see, the latter file is short enough to be memorized or written down
|
||||
on a scrap of paper. From the unix command line, you can test your memory using
|
||||
the seed's checksum ("0fe02f" in this example) as follows:
|
||||
|
||||
$ echo -n XnyC NfPH piuW dQ2d nM47 VU | tr -d ' ' |sha256sum |cut -c 1-6
|
||||
0fe02f
|
||||
|
||||
Or better yet, use 'mmgen-tool' to do the same thing:
|
||||
|
||||
$ mmgen-tool str2id6 'XnyC NfPH piuW dQ2d nM47 VU'
|
||||
0fe02f
|
||||
|
||||
#### <a name=12>Mnemonics and seeds — additional information:</a>
|
||||
|
||||
With the '-m' or '-s' option, MMGen commands that take mnemonic and seed
|
||||
data may receive the data from a prompt instead of a file.
|
||||
|
||||
MMGen commands that produce mnemonic and seed data may be forced to print it to
|
||||
standard output instead of file with the '-S' option. This feature has
|
||||
intentionally been made optional to safeguard against looking-over-the-shoulder,
|
||||
Van Eyck phreaking and other side-channel attacks. MMGen commands never print
|
||||
private data to the screen unless explicitly asked to.
|
||||
|
||||
The output of any MMGen command may be written to a directory of your choice
|
||||
using the '-d' option. For example, on a Linux system you can use
|
||||
'-d /dev/shm' to write key and seed data to volatile memory instead of disk.
|
||||
This also has obvious security benefits, ensuring that no sensitive data
|
||||
remains on disk after your computer's been powered down.
|
||||
|
||||
#### <a name=13><a name=incog>Incognito wallets</a>
|
||||
|
||||
A wallet exported to incognito format is indistinguishable from random data,
|
||||
allowing you to hide your wallet at an offset within a random-filled file or
|
||||
partition. Thus both the location and nature of the data are unknown to a
|
||||
potential attacker, who in addition cannot be sure that the file or partition
|
||||
contains anything useful at all, barring any inside knowledge.
|
||||
|
||||
An incognito wallet with a reasonably secure password could even be hidden on
|
||||
unencrypted cloud storage. Hiding your wallet at some offset in a 1 GB file
|
||||
increases the difficulty of any attack by a factor of one billion, assuming
|
||||
a potential attacker even knows or suspects you have an MMGen wallet hidden
|
||||
there.
|
||||
|
||||
If you plan to store your incognito wallet in an insecure location such as cloud
|
||||
storage, you're advised to use a strong scrypt preset and a strong password.
|
||||
These can be changed using the 'mmgen-passchg' utility:
|
||||
|
||||
$ mmgen-passchg -p 5 89ABCDEF-01234567[256,3].mmdat
|
||||
...
|
||||
Hash preset has changed (3 -> 5)
|
||||
Enter new passphrase: <my new strong passphrase>
|
||||
...
|
||||
Wallet saved to file '89ABCDEF-87654321[256,5].mmdat'
|
||||
|
||||
The new scrypt preset is indicated by the numeral '5' after the comma in the new
|
||||
wallet filename. Now export your new strengthened wallet to incognito format:
|
||||
|
||||
$ mmgen-walletchk -g 89ABCDEF-87654321[256,5].mmdat
|
||||
...
|
||||
Incognito wallet data saved to file '89ABCDEF-87654321-ECA86420[256,5].mmincog'
|
||||
|
||||
'ECA86420' is the Incog ID. This can be used by the 'mmgen-tool' utility to
|
||||
search through a file or partition and locate your wallet if you've forgotten
|
||||
where you hid it (see below).
|
||||
|
||||
Repeat the same export operation, but output to hexadecimal:
|
||||
|
||||
$ mmgen-walletchk -X 89ABCDEF-87654321[256,5].mmdat
|
||||
...
|
||||
Incognito wallet data saved to file '89ABCDEF-87654321-CA86420E[256,5].mmincox'
|
||||
|
||||
$ cat 89ABCDEF-87654321-1EE402F4[256,5].mmincox
|
||||
6772 edb2 10cf ad0d c7dd 484b cc7e 42e9
|
||||
4fe6 e07a 1ce2 da02 6da7 94e4 c068 57a8
|
||||
3706 c5ce 56e0 7590 e677 6c6e 750a d057
|
||||
b43a 21f9 82c7 6bd1 fe96 bad9 2d54 c4c0
|
||||
|
||||
Note that the Incog ID is different here: it's generated from the init vector,
|
||||
which is a different random number each time, making the incog data as a whole
|
||||
different as well. This allows you to store your incog data in multiple
|
||||
insecure locations without having repeated "random" wallet data give you away.
|
||||
|
||||
As you can see, this data is ideally suited for a paper wallet. Just print it
|
||||
out on a printer and you're ready to go.
|
||||
|
||||
Your incognito wallet (whether hex or binary) can be used just like any other
|
||||
MMGen wallet, mnemonic or seed file. Generate addresses with it like this:
|
||||
|
||||
$ mmgen-addrgen 89ABCDEF-87654321-CA86420E[256,5].mmincox 100-110
|
||||
...
|
||||
Generated 10 addresses
|
||||
Addresses written to file '89ABCDEF[100-110].addrs'
|
||||
|
||||
|
||||
Or sign a transaction like this:
|
||||
|
||||
$ mmgen-txsign tx_FABCDE[0.3].raw 89ABCDEF-87654321-CA86420E[256,5].mmincox
|
||||
...
|
||||
Signed transaction saved to file tx_FABCDE[0.3].sig
|
||||
|
||||
You can create an incognito wallet and hide it at a specified offset in a file or
|
||||
partition in one convenient operation using the '-G' ('--export-incog-hidden')
|
||||
option. Here's how you'd hide a wallet in a 1GB file filled with random data.
|
||||
First create the random file:
|
||||
|
||||
$ dd if=/dev/urandom of=random.dat bs=1K count=1M
|
||||
|
||||
Or better yet, use 'mmgen-tool' to do the same job but with some additional user
|
||||
entropy and a progress meter:
|
||||
|
||||
$ mmgen-tool -r40 rand2file random.dat 1G
|
||||
|
||||
Now export your wallet to hidden incognito format, hiding it in this 1GB random
|
||||
file at offset 123456789:
|
||||
|
||||
$ mmgen-walletchk -G random.dat,123456789 89ABCDEF-87654321[256,5].mmdat
|
||||
...
|
||||
Incog ID: ED1F2ACB
|
||||
Data written to file 'random.dat' at offset 123456789
|
||||
|
||||
The altered random file can now be uploaded to a cloud storage service, for
|
||||
example, or some other, preferably non-public, location on the Net (in a
|
||||
real-life situation you'll choose a less obvious offset than '123456789'
|
||||
though, won't you?).
|
||||
|
||||
If at some point in the future you download this file to recover your wallet
|
||||
data but find you've forgotten the offset, you can recover it using the saved
|
||||
Incog ID as follows:
|
||||
|
||||
$ mmgen-tool find_incog_data random.dat ED1F2ACB
|
||||
...
|
||||
Incog data for ID ED1F2ACB found at offset 123456789
|
||||
|
||||
Hidden incog wallets are almost as convenient to use as ordinary ones.
|
||||
Generating ten addresses with your hidden incog data is as easy as this:
|
||||
|
||||
$ mmgen-addrgen -G random.dat,123456789,256 32-42
|
||||
|
||||
Use the same syntax to sign a transaction:
|
||||
|
||||
$ mmgen-txsign -G random.dat,123456789,256 tx_ABCDEE[0.1].raw
|
||||
...
|
||||
Signed transaction saved to file tx_ABCDEE[0.1].sig
|
||||
|
||||
Note that the seed length parameter here will always be '256' unless you're
|
||||
using a non-default seed length.
|
||||
|
|
@ -291,7 +291,11 @@ class AddrInfo(object):
|
|||
|
||||
def set_comment(self,idx,comment):
|
||||
for e in self.addrdata:
|
||||
if idx == e.idx: e.comment = comment
|
||||
if idx == e.idx:
|
||||
if is_valid_tx_comment(comment):
|
||||
e.comment = comment
|
||||
else:
|
||||
sys.exit(2)
|
||||
|
||||
def make_reverse_dict(self,btcaddrs):
|
||||
d = {}
|
||||
|
|
@ -302,58 +306,67 @@ class AddrInfo(object):
|
|||
except: pass
|
||||
return d
|
||||
|
||||
|
||||
def make_addrdata_chksum(self):
|
||||
nchars = 24
|
||||
lines = [" ".join([str(e.idx),e.addr]+([e.wif] if self.has_keys else []))
|
||||
for e in self.addrdata]
|
||||
self.checksum = make_chksum_N(" ".join(lines), nchars, sep=True)
|
||||
|
||||
def fmt_data(self):
|
||||
|
||||
fs = " {:<%s} {}" % len(str(self.addrdata[-1].idx))
|
||||
def fmt_data(self,enable_comments=False):
|
||||
|
||||
# Header
|
||||
have_addrs,have_wifs,have_secs = True,True,True
|
||||
# Check data integrity - either all or none must exist for each attr
|
||||
attrs = ['addr','wif','sec']
|
||||
status = [0,0,0]
|
||||
for i in range(self.num_addrs):
|
||||
for j,attr in enumerate(attrs):
|
||||
try:
|
||||
getattr(self.addrdata[i],attr)
|
||||
status[j] += 1
|
||||
except: pass
|
||||
|
||||
try: self.addrdata[0].addr
|
||||
except: have_addrs = False
|
||||
for i,s in enumerate(status):
|
||||
if s != 0 and s != self.num_addrs:
|
||||
msg("%s missing %s in addr data"% (self.num_addrs-s,attrs[i]))
|
||||
sys.exit(3)
|
||||
|
||||
try: self.addrdata[0].wif
|
||||
except: have_wifs = False
|
||||
|
||||
try: self.addrdata[0].sec
|
||||
except: have_secs = False
|
||||
|
||||
if not (have_addrs or have_wifs):
|
||||
msg("No addresses or wifs in addr data!")
|
||||
if status[0] == None and status[1] == None:
|
||||
msg("Addr data contains neither addresses nor keys")
|
||||
sys.exit(3)
|
||||
|
||||
# Header
|
||||
out = []
|
||||
if have_addrs:
|
||||
from mmgen.addr import addrmsgs
|
||||
out.append(addrmsgs['addrfile_header'] + "\n")
|
||||
w = "Key-address" if have_wifs else "Address"
|
||||
out.append("# {} data checksum for {}[{}]: {}".format(
|
||||
w, self.seed_id, self.idxs_fmt, self.checksum))
|
||||
out.append("# Record this value to a secure location\n")
|
||||
|
||||
from mmgen.addr import addrmsgs
|
||||
out.append(addrmsgs['addrfile_header'] + "\n")
|
||||
w = "Key-address" if status[1] else "Address"
|
||||
out.append("# {} data checksum for {}[{}]: {}".format(
|
||||
w, self.seed_id, self.idxs_fmt, self.checksum))
|
||||
out.append("# Record this value to a secure location\n")
|
||||
out.append("%s {" % self.seed_id)
|
||||
|
||||
# Body
|
||||
fs = " {:<%s} {:<34}{}" % len(str(self.addrdata[-1].idx))
|
||||
for e in self.addrdata:
|
||||
if have_addrs: # First line with idx
|
||||
out.append(fs.format(e.idx, e.addr))
|
||||
c = ""
|
||||
if enable_comments:
|
||||
try: c = " "+e.comment
|
||||
except: pass
|
||||
if status[0]: # First line with idx
|
||||
out.append(fs.format(e.idx, e.addr,c))
|
||||
else:
|
||||
out.append(fs.format(e.idx, "wif: "+e.wif))
|
||||
out.append(fs.format(e.idx, "wif: "+e.wif,c))
|
||||
|
||||
if have_wifs: # Subsequent lines
|
||||
if have_secs:
|
||||
out.append(fs.format("", "hex: "+e.sec))
|
||||
if have_addrs:
|
||||
out.append(fs.format("", "wif: "+e.wif))
|
||||
if status[1]: # Subsequent lines
|
||||
if status[2]:
|
||||
out.append(fs.format("", "hex: "+e.sec,c))
|
||||
if status[0]:
|
||||
out.append(fs.format("", "wif: "+e.wif,c))
|
||||
|
||||
out.append("}")
|
||||
|
||||
return "\n".join(out)
|
||||
return "\n".join([l.rstrip() for l in out])
|
||||
|
||||
|
||||
def fmt_addr_idxs(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ addr_label_symbols = tuple([chr(i) for i in range(0x20,0x7f)])
|
|||
max_addr_label_len = 32
|
||||
|
||||
wallet_label_symbols = addr_label_symbols
|
||||
max_wallet_label_len = 32
|
||||
max_wallet_label_len = 48
|
||||
|
||||
#addr_label_punc = ".","_",",","-"," ","(",")"
|
||||
#addr_label_symbols = tuple(ascii_letters + digits) + addr_label_punc
|
||||
|
|
|
|||
|
|
@ -20,21 +20,21 @@
|
|||
main.py - Script launcher for the MMGen suite
|
||||
"""
|
||||
|
||||
def launch_addrgen(): import mmgen.main_addrgen
|
||||
def launch_addrimport(): import mmgen.main_addrimport
|
||||
def launch_keygen(): import mmgen.main_addrgen
|
||||
def launch_passchg(): import mmgen.main_passchg
|
||||
def launch_pywallet(): import mmgen.main_pywallet
|
||||
def launch_tool(): import mmgen.main_tool
|
||||
def launch_txcreate(): import mmgen.main_txcreate
|
||||
def launch_txsend(): import mmgen.main_txsend
|
||||
def launch_txsign(): import mmgen.main_txsign
|
||||
def launch_walletchk(): import mmgen.main_walletchk
|
||||
def launch_walletgen(): import mmgen.main_walletgen
|
||||
|
||||
def launch(what):
|
||||
def launch_addrgen(): import mmgen.main_addrgen
|
||||
def launch_addrimport(): import mmgen.main_addrimport
|
||||
def launch_keygen(): import mmgen.main_addrgen
|
||||
def launch_passchg(): import mmgen.main_passchg
|
||||
def launch_pywallet(): import mmgen.main_pywallet
|
||||
def launch_tool(): import mmgen.main_tool
|
||||
def launch_txcreate(): import mmgen.main_txcreate
|
||||
def launch_txsend(): import mmgen.main_txsend
|
||||
def launch_txsign(): import mmgen.main_txsign
|
||||
def launch_walletchk(): import mmgen.main_walletchk
|
||||
def launch_walletgen(): import mmgen.main_walletgen
|
||||
|
||||
try: import termios
|
||||
except: globals()["launch_"+what]() # Windows
|
||||
except: locals()["launch_"+what]() # Windows
|
||||
else:
|
||||
import sys,atexit
|
||||
fd = sys.stdin.fileno()
|
||||
|
|
@ -42,7 +42,7 @@ def launch(what):
|
|||
def at_exit():
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
||||
atexit.register(at_exit)
|
||||
try: globals()["launch_"+what]()
|
||||
try: locals()["launch_"+what]()
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write("\nUser interrupt\n")
|
||||
except EOFError:
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ import random
|
|||
import math
|
||||
|
||||
import mmgen.config as g
|
||||
from mmgen.Opts import *
|
||||
from mmgen.util import msg
|
||||
import mmgen.opt as opt
|
||||
from mmgen.util import msg,msgrepr,msgrepr_exit
|
||||
|
||||
max_version = 60000
|
||||
addrtype = 0
|
||||
|
|
@ -69,8 +69,7 @@ json_db = {}
|
|||
private_keys = []
|
||||
password = None
|
||||
|
||||
help_data = {
|
||||
'prog_name': g.prog_name,
|
||||
opts_data = {
|
||||
'desc': "Dump contents of a bitcoind wallet to file",
|
||||
'usage': "[opts] <bitcoind wallet file>",
|
||||
'options': """
|
||||
|
|
@ -86,20 +85,17 @@ help_data = {
|
|||
"""
|
||||
}
|
||||
|
||||
opts,cmd_args = parse_opts(sys.argv,help_data)
|
||||
from mmgen.Opts import warn_incompatible_opts
|
||||
warn_incompatible_opts(opts,('json','keys','addrs','keysforaddrs'))
|
||||
cmd_args = opt.opts.init(opts_data)
|
||||
opt.opts.warn_incompatible_opts(['json','keys','addrs','keysforaddrs'])
|
||||
|
||||
if len(cmd_args) == 1:
|
||||
from mmgen.util import check_infile
|
||||
check_infile(cmd_args[0])
|
||||
else:
|
||||
usage(help_data)
|
||||
|
||||
if ('json' not in opts and 'keys' not in opts
|
||||
and 'addrs' not in opts and 'keysforaddrs' not in opts):
|
||||
usage(help_data)
|
||||
opt.opts.usage(opts_data)
|
||||
|
||||
if (not opt.json and not opt.keys and not opt.addrs and not opt.keysforaddrs):
|
||||
opt.opts.usage(opts_data)
|
||||
|
||||
# from the SlowAES project, http://code.google.com/p/slowaes (aes.py)
|
||||
|
||||
|
|
@ -1544,10 +1540,9 @@ def read_wallet(json_db, db_env, db_file, print_wallet, print_wallet_transaction
|
|||
mkey['vchOtherDerivationParameters'] = d['vchOtherDerivationParameters'].encode('hex')
|
||||
json_db['mkey'] = mkey
|
||||
|
||||
if password == None and \
|
||||
('json' in opts or 'keysforaddrs' in opts or 'keys' in opts):
|
||||
if password == None and (opt.json or opt.keysforaddr or opt.keys):
|
||||
from mmgen.util import get_bitcoind_passphrase
|
||||
password = get_bitcoind_passphrase("Enter password: ",opts)
|
||||
password = get_bitcoind_passphrase("Enter password: ")
|
||||
|
||||
if password != None:
|
||||
global crypter
|
||||
|
|
@ -1640,21 +1635,21 @@ if json_db.get('minversion') > max_version:
|
|||
|
||||
wallet_addrs = [i['addr'] for i in json_db['keys']]
|
||||
|
||||
if 'json' in opts:
|
||||
if opt.json:
|
||||
data = [json.dumps(json_db, sort_keys=True, indent=4)]
|
||||
ext,what = "json","json dump"
|
||||
|
||||
elif 'keys' in opts:
|
||||
elif opt.keys:
|
||||
data = sorted([i['sec'] for i in json_db['keys']])
|
||||
ext,what = "keys","private keys"
|
||||
|
||||
elif 'addrs' in opts:
|
||||
elif opt.addrs:
|
||||
data = sorted([i['addr'] for i in json_db['keys']])
|
||||
ext,what = "addrs","addresses"
|
||||
|
||||
elif 'keysforaddrs' in opts:
|
||||
elif opt.keysforaddrs:
|
||||
from mmgen.util import get_lines_from_file
|
||||
usr_addrs = set(get_lines_from_file(opts['keysforaddrs'],"addresses",trim_comments=True))
|
||||
usr_addrs = set(get_lines_from_file(opt.keysforaddrs,"addresses",trim_comments=True))
|
||||
data = [i['sec'] for i in json_db['keys'] if i['addr'] in usr_addrs]
|
||||
ext,what = "keys","private keys"
|
||||
if len(data) < len(usr_addrs):
|
||||
|
|
@ -1664,14 +1659,15 @@ len_arg = "%s" % len(wallet_addrs) \
|
|||
if len(data) == len(wallet_addrs) or ext == "json" \
|
||||
else "%s:%s" % (len(data),len(wallet_addrs))
|
||||
|
||||
from mmgen.util import make_chksum_8,write_walletdat_dump_to_file,write_to_stdout
|
||||
from mmgen.util import make_chksum_8,write_to_file,write_to_stdout
|
||||
wallet_id = make_chksum_8(str(sorted(wallet_addrs)))
|
||||
|
||||
data = "\n".join(data) + "\n"
|
||||
|
||||
# Output data
|
||||
if 'stdout' in opts or not sys.stdout.isatty():
|
||||
conf = not ('addrs' in opts or not sys.stdout.isatty())
|
||||
if opt.stdout or not sys.stdout.isatty():
|
||||
conf = not (opt.addrs or not sys.stdout.isatty())
|
||||
write_to_stdout(data,"secret keys",conf)
|
||||
else:
|
||||
write_walletdat_dump_to_file(wallet_id, data, len_arg, ext, what, opts)
|
||||
of = "wd_%s[%s].%s" % (wallet_id,len_arg,ext)
|
||||
write_to_file(of, data, what, confirm_overwrite=True,verbose=True)
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -20,7 +20,7 @@ from distutils.core import setup
|
|||
|
||||
setup(
|
||||
name = 'mmgen',
|
||||
decription = 'A complete Bitcoin cold-storage solution for the command line',
|
||||
description = 'A complete Bitcoin cold-storage solution for the command line',
|
||||
version = '0.7.9',
|
||||
author = 'Philemon',
|
||||
author_email = 'mmgen-py@yandex.com',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ non_mmgen_fn = "btckey"
|
|||
cfgs = {
|
||||
'6': {
|
||||
'name': "reference wallet check",
|
||||
'wallet_label': "test.py reference wallet (password 'abc')",
|
||||
'bw_passwd': "abc",
|
||||
'bw_hashparams': "256,1",
|
||||
'key_id': "98831F3A",
|
||||
|
|
@ -671,7 +672,9 @@ class MMGenTestSuite(object):
|
|||
ok()
|
||||
|
||||
def refwalletgen(self,name):
|
||||
args = ["-q","-d",cfg['tmpdir'],"-p1","-r10","-b"+cfg['bw_hashparams']]
|
||||
label = cfg['wallet_label']
|
||||
args = ["-q","-d",cfg['tmpdir'],"-p1","-r10",
|
||||
"-b"+cfg['bw_hashparams'],"-L",label]
|
||||
t = MMGenExpect(name,"mmgen-walletgen", args)
|
||||
t.expect("passphrase: ",cfg['bw_passwd']+"\n")
|
||||
t.usr_rand(10)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue