V tomto čánku bych rád popsal, jak je možné vygenerovat funkční bitcoinovou adresu "vlastními silami", z příkazové řádky linuxu, tedy pomocí nástrojů, které s Bitcoinem nemají vlastně nic společného a jsou běžnou součástí operačních systémů.
Wallet Import Format
Obecně, bitcoinová peněženka není nic jiného než aplikace (pro PC či telefon), která nám spravuje veřejné a privátní klíče, umí z veřejného klíče generovat adresu a pomocí privátního klíče podepisovat transakce a poslat je do mempoolu.
Pokud chceme uchovat svoje bitcoiny "na papíře", nic nám nebrání si klíče a adresy vytisknout na papír. K tomuto účelu se standardizoval Wallet Import Format - speciální formát pro privátní klíč, kterému elektronické peněženky rozumí a umožní nám BTC utratit. Nutno podotknout, že Bitcoin používá šifrování nad eliptickými křivkami, kde lze z privátního klíče odvodit klíč veřejný, takže stačí uchovat jen privátní klíč. Vytisknutému papíru s kódem ve WIF formátu a s odpovídající veřejnou adresou, se běžně říká "papírová peněženka".
Použíté nástroje
K vyvoření WIF peněženky budeme potřebovat tyto nástroje:
- OpenSSL - nástroj na kryptografii použitelný z příkazové řádky.
- Bash včetně obvyklých nástrojů - cat, head, xxd, sed, tr, sha256sum...
- Bitcoin Bash Tools- sada funkcí pro sofistikované generování WIF...
Naposledy uvedený nástroj Bitcoin Bash Tools, nutno říci, kompletně řeší záležitosti kolem adres a generování peněženky:) Z edukativních důvodů však z toolu užijem "jen" base58.
Jdeme na to!
Prvním krokem vygenerujem privátní klíč do souboru key.pem
openssl ecparam -genkey -name secp256k1 -noout -out key.pem
Hned potom můžem z privátního klíče vyrobit veřejný klíč a oba uložit v hexadecimální podobě do souboru key.plain.
openssl ec -in ./key.pem -text -out keys.plain 2> /dev/null
Pokud si prohlédnem obsah souboru keys.plain, uvidíme oba klíče v hex formátu.
Private-Key: (256 bit)
priv:
6f:91:ac:0d:5e:a6:04:16:9c:98:d7:56:0c:ba:91:
09:a2:45:e3:43:86:0e:21:61:50:06:f7:c0:5d:17:
64:e6
pub:
04:fd:ed:80:48:09:60:92:a5:ed:6c:2a:45:6c:f1:
5b:e5:fe:84:90:65:ae:24:5b:66:7f:b2:ae:24:41:
40:83:47:43:67:7c:ed:58:29:54:99:8c:5e:08:59:
bb:be:e4:fb:ba:c9:df:b4:52:96:88:5b:48:25:e9:
a5:82:8e:bb:d2
ASN1 OID: secp256k1
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIG+RrA1epgQWnJjXVgy6kQmiReNDhg4hYVAG98BdF2TmoAcGBSuBBAAK
oUQDQgAE/e2ASAlgkqXtbCpFbPFb5f6EkGWuJFtmf7KuJEFAg0dDZ3ztWClUmYxe
CFm7vuT7usnftFKWiFtIJemlgo670g==
-----END EC PRIVATE KEY-----
Všiměme si, že privární klíč je o proti veřejnému klíči asi poloviční (32bytu v.s. 65bytů).
Nejprve se soustřeďme na důležitější, privátní klíč, ze kterého vyrobíme WIF a začneme odstraněním dvojteček a prázdných bílých znaků:
cat ./keys.plain | sed -n '3,5p' | sed 's/[:[:space:]]//g' | tr -d '\n' > private-key.hex
Skvělé, klíč je ve hexadecimálním formátu v souboru private-key.hex.
6f91ac0d5ea604169c98d7560cba9109a245e343860e21615006f7c05d1764e6
Připravmě si do proměnné EXT_PRIVATE_KEY_HEX privátní klíč rozšířený o byte pro identifikaci btc sítě. Tedy řekneme, že vyrábíme WIF pro Mainnet (znak 0x80) a ne Testnet (znak 0xef)
EXT_PRIVATE_KEY_HEX="80$(cat ./private-key.hex)"
Kontrolni součet je dalších 4 bytes spočtených právě z EXT_PRIVATE_KEY_HEX. Musíme tuto proměnnou převést do binárního tvaru a 2x zahashovat. K tomu nám poslouží příkazy xxd, sha256sum a head pro odstranění přebytečného výstupu:echo $EXT_PRIVATE_KEY_HEX | xxd -r -p | sha256sum | head -c 64 | xxd -r -p | sha256sum | head -c 64 > double-sha256.hex
Obsah souboru double-sha256.hex je 66e5fd257cd7489c70282607d636acf1c1028af34ea1db0d1a5e2253795cb1b3. Máme 2xhash, teď vzit jen 4 byte (8 znaků) a je kontrolní součet:
encodeBase58 $WIF_ADDRESS_HEX > wif_address.base58
qrencode "5JfRTnhsKR9WczygHaUVhjfcLCc3F8XKUZWv48CrPiXPDqodvUL" -o paper-wallet.png
Výsledkem je pak fungující QR kód pro utracení:V dalším díle se vrhnem na generování veřejné adresy, kterou můžem sdílet s ostatními a na níž se můžou posílat bitcoiny. K tomu použijem existující soubor s veřejným klíčem keys.plain.
Poznámka na závěr: Článek má edukativní charakter. Pro správu privátních klíčů k Vaším BTC doporučuji použít sofistikované rešení zavedených peněženek. Jinak může dojít ke ztrátě Vašich klíčů a tím i BTC.
Použité zdroje:
- https://en.bitcoin.it/wiki/Wallet_import_format
- http://gobittest.appspot.com/Address
- http://gobittest.appspot.com/PrivateKey
- https://en.bitcoin.it/wiki/Invoice_address
- https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
- https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations#Generating_EC_Keys_and_Parameters
- https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html