Update documentation from wiki (mostly formatting)
This commit is contained in:
parent
6b9df0ea44
commit
58f4af6966
7 changed files with 288 additions and 250 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 -H 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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -864,7 +864,8 @@ 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!
|
||||
|
|
@ -894,25 +895,34 @@ Generate ten Monero address pairs from your default wallet:
|
|||
$ mmgen-keygen --coin=xmr 1-10
|
||||
|
||||
In addition to spend and view keys, Monero key/address files also include a
|
||||
wallet password for each address (the password is the double Sha256 of the spend
|
||||
key, truncated to 16 bytes). This allows you to easily generate wallets for
|
||||
each address by running the following command
|
||||
wallet password for each address (the password is the double SHA256 of the spend
|
||||
key, truncated to 16 bytes). This allows you to generate a wallet from each
|
||||
key in the key/address file by running the following command:
|
||||
|
||||
$ monero-wallet-cli --generate-from-spend-key MyMoneroWallet
|
||||
|
||||
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 is completely automated by the `mmgen-tool` utility:
|
||||
To save your time and labor, the `mmgen-tool` utility includes a command that
|
||||
completely automates this process:
|
||||
|
||||
$ mmgen-tool keyaddrlist2monerowallet *XMR*.akeys.mmenc
|
||||
$ mmgen-tool keyaddrlist2monerowallets *XMR*.akeys.mmenc
|
||||
|
||||
This will generate Monero wallets for each key/address pair in the key/address
|
||||
file and encrypt them with their respective passwords. No user interaction is
|
||||
required. By default, wallets are synced to the current block height, as
|
||||
they're assumed to be empty. This behavior can be overridden:
|
||||
This will generate a uniquely-named Monero wallet for each key/address pair in
|
||||
the key/address file and encrypt it with its respective password. No user
|
||||
interaction is required. By default, wallets are synced to the current block
|
||||
height, as they're assumed to be empty, but this behavior can be overridden:
|
||||
|
||||
$ mmgen-tool keyaddrlist2monerowallet *XMR*.akeys.mmenc blockheight=123456
|
||||
$ mmgen-tool keyaddrlist2monerowallets *XMR*.akeys.mmenc blockheight=123456
|
||||
|
||||
To keep your wallets in sync as the Monero blockchain grows, `mmgen-tool`
|
||||
includes another utility:
|
||||
|
||||
$ mmgen-tool syncmonerowallets *XMR*.akeys.mmenc
|
||||
|
||||
This command also requires no user interaction, a very handy feature when you
|
||||
have a large batch of wallets requiring long sync times.
|
||||
|
||||
#### <a name='a_kg'>Key/address generation support for ETH, ETC and 144 Bitcoin-derived altcoins</a>
|
||||
|
||||
|
|
@ -924,6 +934,10 @@ with the `--coin` argument:
|
|||
# For Emercoin:
|
||||
$ mmgen-keygen --coin=emc 1-10
|
||||
|
||||
For compressed public keys, add the `--type=compressed` option:
|
||||
|
||||
$ mmgen-keygen --coin=dash --type=compressed 1-10
|
||||
|
||||
If it's just the addresses you want, then use `mmgen-addrgen` instead:
|
||||
|
||||
$ mmgen-addrgen --coin=dash 1-10
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* <a href='#a_i'>Introduction</a>
|
||||
* <a href='#a_rs'>Obtaining the binary seed</a>
|
||||
* <a href='#a_ss'>Convert the seed to binary (legacy addresses)</a>
|
||||
* <a href='#a_cs'>Cook the seed and save to binary (Segwit and compressed addresses)</a>
|
||||
* <a href='#a_cs'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
|
||||
* <a href='#a_gk'>Generating the keys</a>
|
||||
* <a href='#a_hw'>Hex to WIF by hand</a>
|
||||
* <a href='#a_mh'>Converting an MMGen mnemonic to hexadecimal format</a>
|
||||
|
|
@ -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,32 +73,56 @@ 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>
|
||||
> #### <a name='a_cs'>Scramble the seed and save to binary (compressed addresses, Segwit addresses and passwords)</a>
|
||||
|
||||
> For the other address types, we first “cook” the seed with an identifier
|
||||
> string using the HMAC-SHA256 algorithm, add ten rounds of SHA256, and save the
|
||||
> result in binary form. This can be done with the 'openssl' utility, also
|
||||
> included by default on Unix-based systems:
|
||||
> Other address types and passwords are generated by first “scrambling” the
|
||||
> seed with a unique identifier, or “scramble string”, using the HMAC-SHA256
|
||||
> algorithm. The scrambled seed is then given ten rounds of SHA256 to create the
|
||||
> base seed used to generate our keys.
|
||||
|
||||
$ echo -n segwit | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > cooked-seed.bin
|
||||
> Our first task then is to find out the correct scramble string for our coin
|
||||
> and address type (or password). For BTC and BTC fork coins, the string will
|
||||
> be simply the address type: 'compressed' or 'segwit'. For Bitcoin-derived
|
||||
> altcoins, the string is the coin symbol and address type separated by a colon,
|
||||
> e.g. 'ltc:legacy'. The strings for non-Bitcoin-derived altcoins are irregular
|
||||
> and are listed in the table below. For passwords, the string is the password
|
||||
> format, e.g. 'b58'; the password length, e.g. '20'; and the password ID
|
||||
> string, e.g. 'alice@fubar.io', all separated by colons:
|
||||
|
||||
> If your addresses are of the compressed ('C') type, just use the string
|
||||
> 'compressed' instead of 'segwit' as the 'echo' command's argument.
|
||||
> | Coin+Addrtype / Passwd type+length+ID | | | Scramble String |
|
||||
> |:----------------------------------------|-|-|:-------------------------|
|
||||
> | BTC compressed | | | `compressed` |
|
||||
> | BTC Segwit | | | `segwit` |
|
||||
> | LTC legacy | | | `ltc:legacy` |
|
||||
> | LTC compressed | | | `ltc:compressed` |
|
||||
> | LTC Segwit | | | `ltc:segwit` |
|
||||
> | DASH legacy | | | `dash:legacy` |
|
||||
> | DASH compressed | | | `dash:compressed` |
|
||||
> | ETH | | | `eth` |
|
||||
> | ETC | | | `etc` |
|
||||
> | XMR | | | `xmr:monero` |
|
||||
> | ZEC-T | | | `zec:legacy` |
|
||||
> | ZEC-Z | | | `zec:zcash_z` |
|
||||
> | Base58 passwords for Alice's email acct.| | | `b58:20:alice@fubar.io` |
|
||||
> | Same as above, half-length passwords | | | `b58:10:alice@fubar.io` |
|
||||
> | Same as above, Base32 passwords | | | `b32:24:alice@fubar.io` |
|
||||
> | Hex seed for Alice's PGP key | | | `hex:64:alice@gnupg` |
|
||||
|
||||
> Once we've determined the correct string, we scramble our seed with it as
|
||||
> follows using the `openssl` utility, which is included by default on all
|
||||
> Unix-based systems:
|
||||
|
||||
# E.g. for LTC Segwit addresses:
|
||||
$ echo -n 'ltc:segwit' | openssl dgst -r -sha256 -mac hmac -macopt hexkey:456d7f5f1c4bfe3bc916b87560ae6a3e | xxd -r -p > scrambled-round0.bin
|
||||
|
||||
> 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
|
||||
$ for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
openssl dgst -sha256 -binary scrambled-round${i}.bin > scrambled-round$((i+1)).bin
|
||||
done
|
||||
$ mv scrambled-round10.bin myseed.bin
|
||||
|
||||
#### <a name='a_gk'>Generating the keys</a>
|
||||
|
||||
|
|
@ -107,34 +131,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 +170,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 +183,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 +232,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 +255,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,91 +294,91 @@ 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⁰ +
|
||||
3 x 10¹ +
|
||||
2 x 10² +
|
||||
1 x 10³
|
||||
|
||||
An MMGen seed mnemonic is a number too, only the “digits” it's comprised of come
|
||||
from an alphabetically sorted series of 1626 words, the [Electrum wordlist][03],
|
||||
which begins like this:
|
||||
|
||||
able (0), about (1), above (2), abuse (3), accept (4) ...
|
||||
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)
|
||||
|
||||
The words of the Electrum wordlist thus make up a base-1626 numbering system,
|
||||
just like the ten digits that make up our familiar base-10 system.
|
||||
just like the ten digits of our familiar base-10 system.
|
||||
|
||||
Here's the mnemonic of our seed (FE3C6545):
|
||||
|
||||
dude foot desperate tie stood themselves trip descend cease suicide apple busy
|
||||
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⁰ +
|
||||
59 x 1626¹ +
|
||||
1384 x 1626² +
|
||||
221 x 1626³ +
|
||||
379 x 1626⁴ +
|
||||
1493 x 1626⁵ +
|
||||
1433 x 1626⁶ +
|
||||
1348 x 1626⁷ +
|
||||
1459 x 1626⁸ +
|
||||
386 x 1626⁹ +
|
||||
562 x 1626¹⁰ +
|
||||
439 x 1626¹¹
|
||||
|
||||
While we could do this with pencil and paper, a few lines of Python code will
|
||||
make life much easier:
|
||||
While we could theoretically do the math with pencil and paper, a few lines of
|
||||
Python will make our work 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 = exp = 0
|
||||
>>> for word in 200,59,1384,221,379,1493,1433,1348,1459,386,562,439:
|
||||
>>> sum += word * 1626 ** exp
|
||||
>>> exp += 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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue