我怎样才能建立一个比特币钱包?
How can I build a bitcoin wallet?
我将要从事一个我们想要构建比特币钱包的项目,例如 mycelium、coinbase 等,但我不知道我们应该使用哪些 api 直接连接到比特币区块链 1could你给我关于这方面文档的建议。谢谢
以下是 step-by-step 通过 Linux 命令行创建比特币地址的指南。
Warning! See Edit #1 at the end.
通过这种方式,您将了解如何创建生成比特币地址的应用程序(钱包)。
钱包和 public 地址是不同的东西:钱包是一个创建和存储私钥并使 public 密钥可用作接收硬币的加密地址的应用程序。
请注意,步骤是递增的。下一步总是有上一步的副本。
# a1) Prerequisite of installed applications.
apt-get install -y openssl base58 grep xxd
# a2) Choose a password.
PASSWORD="my-difficult-passphrase"
# a3) Hash SHA256 over the password.
# Don't use echo because it adds \n to the end.
PASSWORD="my-difficult-passphrase"; printf $PASSWORD | openssl sha256
# a4) Keep only the hex output. We're going to use this often.
PASSWORD="my-difficult-passphrase"; printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# a5) Add two magic numbers...
# - at the beginning: 302e0201010420
# - and at the end: a00706052b8104000a
# They relate to secp256k1 refers to the parameters of the elliptic curve used in Bitcoin's cryptography.
PASSWORD="my-difficult-passphrase"; printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a"
# a6) Get the bytes of this hex.
PASSWORD="my-difficult-passphrase"; printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps
# a7) Generate the Elliptic-curve key pair.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps)
# At this point we have the key pair.
# b) With the public key we will make the bitcoin address.
# c) The private key is converted to WIF format (Wallet Import Format)
# b1) Extract the hex value from the public key.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n'
# b2) Convert to bytes.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps
# b3) Hash SHA256.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256
# b4) Keep only the hex output.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b5) Convert to bytes.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# b6) Hash RIPEMD-160.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160
# b7) Keep only the hex output.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}"
# b8) We prefix the hex with "00".
# Bitcoin P2PKH addresses begin with the version byte value 0x00.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")"
# Now get a checksum by passing the SHA256 hash twice in the hex bytes.
# b9) Checksum loop 1. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps
# b10) Checksum loop 1. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256
# b11) Checksum loop 1. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b12) Checksum loop 2. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# b13) Checksum loop 2. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256
# b14) Checksum loop 2. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b15) Get the first 4 bytes (or 8 chars) of the checksum.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}"
# Checksum completed here.
# b16) Add the checksum to the end of the
# hex prefixed with "00" in step b8.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")"
# b17) Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps
# b18) Encode with Base58.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps | base58
# Here the bitcoin address ends
# c1) Extract the hex value from the private key.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n'
# c2) Ensures length of 32 bytes (or 64 chars) by padding with zeros.
PASSWORD="my-difficult-passphrase"; printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$"
# c3) We prefix the hex with "80".
# The magic number 0x80 signals the version of the private key.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")"
# Again: Now get a checksum by passing the SHA256 hash twice in the hex bytes.
# c4) Checksum loop 1. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps
# c5) Checksum loop 1. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256
# c6) Checksum loop 1. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# c7) Checksum loop 2. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# c8) Checksum loop 2. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256
# c9) Checksum loop 2. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# c10) Get the first 4 bytes (or 8 chars) of the checksum.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}"
# Checksum completed here.
# c11) Add the checksum to the end of the
# hex prefixed with "80" in step c3.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")"
# c12) Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps
# c13) Encode with Base58.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps | base58
# Here the private key as WIF ends
下面是 Bash 的一行命令中相同的步骤序列:
PASSWORD="my-difficult-passphrase"; printf "\nBitcoin Wallet\n\nPassword:\n$PASSWORD\n\nPrivate Key:\n$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | sha256sum | sed 's/[^a-z0-9]//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')\n\nPrivate Key, WIF:\n$(printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')" | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | sed 's/\(.\{8\}\).*//')" | xxd -r -ps | base58)\n\nPublic Key:\n$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | sha256sum | sed 's/[^a-z0-9]//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n')\n\nPublic Key, Wallet:\n$(printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl ripemd160 | sed 's/.*\s//' | awk 'ORS=" "' | sed 's/\W//g')")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl ripemd160 | sed 's/.*\s//' | awk 'ORS=" "' | sed 's/\W//g')" | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | sed 's/\(.\{8\}\).*//')" | xxd -r -ps | base58)\n\n"
此命令的输出:
现在相同的 PowerShell 的一行命令(可能 Windows)。
$password="my-difficult-passphrase"; $tempFile="$env:temp/btcaddress.tmp"; [System.IO.File]::WriteAllText($tempFile, $password); $passwordSha256=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; $passwordSha256Secp256k1="302e0201010420${passwordSha256}a00706052b8104000a"; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($passwordSha256Secp256k1)); $keys=$($(openssl ec -inform DER -text -noout -in $tempFile | Select-String "(?<=^\s+)[0-9a-f:]+").Matches | Select-Object -Property Value | ForEach-Object -Process {$_.Value.Replace(":", "")}); $keyPrivate=$keys[0]+$keys[1]+$keys[2]; $keyPublic=$keys[3]+$keys[4]+$keys[5]+$keys[6]+$keys[7]; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublic)); $keyPublicSha256=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256)); $keyPublicSha256Ripemd160=$(openssl ripemd160 $tempFile | Select-String "[0-9a-f]{40}").Matches[0].Value; $keyPublicSha256Ripemd160Prefixed="00"+$keyPublicSha256Ripemd160; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256Ripemd160Prefixed)); $keyPublicSha256Ripemd160Checksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256Ripemd160Checksum)); $keyPublicSha256Ripemd160Checksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value.Substring(0, 8); $bitcoinKeyPublic="$keyPublicSha256Ripemd160Prefixed$keyPublicSha256Ripemd160Checksum"; $keyPrivatePrefixed="80"+$keyPrivate.PadLeft(64, '0'); [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPrivatePrefixed)); $keyPrivateChecksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPrivateChecksum)); $keyPrivateChecksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value.Substring(0, 8); $bitcoinKeyPrivate="$keyPrivatePrefixed$keyPrivateChecksum"; function Base58 { param ([parameter(valuefrompipeline=$true)] [string]) $i=[bigint]::Parse(,"AllowHexSpecifier"); $chars=@(); $index =@('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); if (().length % 2 -ne 0 -OR $i -lt 0) { ="0"; $i=[bigint]::Parse(, "AllowHexSpecifier"); } while($i -gt 0) { $m=([bigInt]$i % 58); $i=([bigInt]$i / 58); $chars+=$index[$m]; } [array]::reverse($chars); $i=$chars -join (''); -split "(..)" | ForEach-Object { if ($_ -match "00") { $i=("1"+$i); } else { return; } }; $chars=@(); $chars.clear(); $index=@(); $index.clear(); return $i; }; $bitcoinKeyPrivateBase58=Base58($bitcoinKeyPrivate); $bitcoinKeyPublicBase58=Base58($bitcoinKeyPublic); [System.IO.File]::Delete($tempFile); Write-Output "Bitcoin Wallet`n`nPassword:`n$password`n`nPrivate Key:`n$keyPrivate`n`nPrivate Key, WIF:`n$bitcoinKeyPrivateBase58`n`nPublic Key:`n$keyPublic`n`nPublic Key, Wallet:`n$bitcoinKeyPublicBase58`n`n"
此命令的输出:
对于上述命令,只需复制并粘贴到终端即可。
您可以在其他网站上查看生成的数据。在 Brain Wallet 模式下使用相同的密码并取消选中“压缩地址”。
BitAddress.org
Coinb.in
编辑#1
在步骤 a4 和 a5 之间,我们得到了一个非常大的数字。但并非 2^256
范围内的所有数字都在数学上 secp256k1 elliptic curve used for finding a matching public key. The range, is actually from 0
to 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
(in decimal: 115792089237316195423570985008687907852837564279074904382605163141518161494337
), as defined in the SEC2 standard. Read more about DOES THAT MEAN THERE ARE 2^256 POSSIBLE PRIVATE KEYS?.
检查哈希值是否小于该值。以下命令以十进制数字格式显示散列值:
PASSWORD="my-difficult-passphrase"; echo "ibase=16; $(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}" | tr a-z A-Z)" | bc | awk 'ORS=" "' | sed 's/\W//g'
我将要从事一个我们想要构建比特币钱包的项目,例如 mycelium、coinbase 等,但我不知道我们应该使用哪些 api 直接连接到比特币区块链 1could你给我关于这方面文档的建议。谢谢
以下是 step-by-step 通过 Linux 命令行创建比特币地址的指南。
Warning! See Edit #1 at the end.
通过这种方式,您将了解如何创建生成比特币地址的应用程序(钱包)。
钱包和 public 地址是不同的东西:钱包是一个创建和存储私钥并使 public 密钥可用作接收硬币的加密地址的应用程序。
请注意,步骤是递增的。下一步总是有上一步的副本。
# a1) Prerequisite of installed applications.
apt-get install -y openssl base58 grep xxd
# a2) Choose a password.
PASSWORD="my-difficult-passphrase"
# a3) Hash SHA256 over the password.
# Don't use echo because it adds \n to the end.
PASSWORD="my-difficult-passphrase"; printf $PASSWORD | openssl sha256
# a4) Keep only the hex output. We're going to use this often.
PASSWORD="my-difficult-passphrase"; printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# a5) Add two magic numbers...
# - at the beginning: 302e0201010420
# - and at the end: a00706052b8104000a
# They relate to secp256k1 refers to the parameters of the elliptic curve used in Bitcoin's cryptography.
PASSWORD="my-difficult-passphrase"; printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a"
# a6) Get the bytes of this hex.
PASSWORD="my-difficult-passphrase"; printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps
# a7) Generate the Elliptic-curve key pair.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps)
# At this point we have the key pair.
# b) With the public key we will make the bitcoin address.
# c) The private key is converted to WIF format (Wallet Import Format)
# b1) Extract the hex value from the public key.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n'
# b2) Convert to bytes.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps
# b3) Hash SHA256.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256
# b4) Keep only the hex output.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b5) Convert to bytes.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# b6) Hash RIPEMD-160.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160
# b7) Keep only the hex output.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}"
# b8) We prefix the hex with "00".
# Bitcoin P2PKH addresses begin with the version byte value 0x00.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")"
# Now get a checksum by passing the SHA256 hash twice in the hex bytes.
# b9) Checksum loop 1. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps
# b10) Checksum loop 1. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256
# b11) Checksum loop 1. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b12) Checksum loop 2. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# b13) Checksum loop 2. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256
# b14) Checksum loop 2. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# b15) Get the first 4 bytes (or 8 chars) of the checksum.
PASSWORD="my-difficult-passphrase"; printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}"
# Checksum completed here.
# b16) Add the checksum to the end of the
# hex prefixed with "00" in step b8.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")"
# b17) Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps
# b18) Encode with Base58.
PASSWORD="my-difficult-passphrase"; printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | grep -o "[0-9a-f]" | tr -d '\n' | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl ripemd160 | grep -o "[0-9a-f]\{40\}")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps | base58
# Here the bitcoin address ends
# c1) Extract the hex value from the private key.
PASSWORD="my-difficult-passphrase"; openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n'
# c2) Ensures length of 32 bytes (or 64 chars) by padding with zeros.
PASSWORD="my-difficult-passphrase"; printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$"
# c3) We prefix the hex with "80".
# The magic number 0x80 signals the version of the private key.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")"
# Again: Now get a checksum by passing the SHA256 hash twice in the hex bytes.
# c4) Checksum loop 1. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps
# c5) Checksum loop 1. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256
# c6) Checksum loop 1. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# c7) Checksum loop 2. Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps
# c8) Checksum loop 2. Hash SHA256.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256
# c9) Checksum loop 2. Keep only the hex output.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}"
# c10) Get the first 4 bytes (or 8 chars) of the checksum.
PASSWORD="my-difficult-passphrase"; printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}"
# Checksum completed here.
# c11) Add the checksum to the end of the
# hex prefixed with "80" in step c3.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")"
# c12) Convert to bytes.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps
# c13) Encode with Base58.
PASSWORD="my-difficult-passphrase"; printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}")a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | grep -o "[0-9a-f]" | tr -d '\n')" | grep -o "[0-9a-f]\{64\}$")" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | xxd -r -ps | openssl sha256 | grep -o "[0-9a-f]\{64\}" | grep -o "^[0-9a-f]\{8\}")" | xxd -r -ps | base58
# Here the private key as WIF ends
下面是 Bash 的一行命令中相同的步骤序列:
PASSWORD="my-difficult-passphrase"; printf "\nBitcoin Wallet\n\nPassword:\n$PASSWORD\n\nPrivate Key:\n$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | sha256sum | sed 's/[^a-z0-9]//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')\n\nPrivate Key, WIF:\n$(printf "$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf $PASSWORD | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')")$(printf "80$(printf "0000000000000000000000000000000000000000000000000000000000000000$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -10 | head -3 | sed 's/[ :]//g' | tr -d '\n')" | sed 's/.*\(.\{64\}$\)//')" | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | sed 's/\(.\{8\}\).*//')" | xxd -r -ps | base58)\n\nPublic Key:\n$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | sha256sum | sed 's/[^a-z0-9]//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n')\n\nPublic Key, Wallet:\n$(printf "$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl ripemd160 | sed 's/.*\s//' | awk 'ORS=" "' | sed 's/\W//g')")$(printf "00$(openssl ec -inform DER -text -noout -in <(printf "302e0201010420$(printf "$PASSWORD" | openssl sha256 | sed 's/^.*\s//g')a00706052b8104000a" | xxd -r -ps) 2>/dev/null | tail -6 | head -5 | sed 's/[ :]//g' | tr -d '\n' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl ripemd160 | sed 's/.*\s//' | awk 'ORS=" "' | sed 's/\W//g')" | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | xxd -r -ps | openssl sha256 | sed 's/^.*\s//g' | awk 'ORS=" "' | sed 's/\W//g' | sed 's/\(.\{8\}\).*//')" | xxd -r -ps | base58)\n\n"
此命令的输出:
现在相同的 PowerShell 的一行命令(可能 Windows)。
$password="my-difficult-passphrase"; $tempFile="$env:temp/btcaddress.tmp"; [System.IO.File]::WriteAllText($tempFile, $password); $passwordSha256=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; $passwordSha256Secp256k1="302e0201010420${passwordSha256}a00706052b8104000a"; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($passwordSha256Secp256k1)); $keys=$($(openssl ec -inform DER -text -noout -in $tempFile | Select-String "(?<=^\s+)[0-9a-f:]+").Matches | Select-Object -Property Value | ForEach-Object -Process {$_.Value.Replace(":", "")}); $keyPrivate=$keys[0]+$keys[1]+$keys[2]; $keyPublic=$keys[3]+$keys[4]+$keys[5]+$keys[6]+$keys[7]; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublic)); $keyPublicSha256=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256)); $keyPublicSha256Ripemd160=$(openssl ripemd160 $tempFile | Select-String "[0-9a-f]{40}").Matches[0].Value; $keyPublicSha256Ripemd160Prefixed="00"+$keyPublicSha256Ripemd160; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256Ripemd160Prefixed)); $keyPublicSha256Ripemd160Checksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPublicSha256Ripemd160Checksum)); $keyPublicSha256Ripemd160Checksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value.Substring(0, 8); $bitcoinKeyPublic="$keyPublicSha256Ripemd160Prefixed$keyPublicSha256Ripemd160Checksum"; $keyPrivatePrefixed="80"+$keyPrivate.PadLeft(64, '0'); [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPrivatePrefixed)); $keyPrivateChecksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value; [System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromHexString($keyPrivateChecksum)); $keyPrivateChecksum=$(openssl sha256 $tempFile | Select-String "[0-9a-f]{64}").Matches[0].Value.Substring(0, 8); $bitcoinKeyPrivate="$keyPrivatePrefixed$keyPrivateChecksum"; function Base58 { param ([parameter(valuefrompipeline=$true)] [string]) $i=[bigint]::Parse(,"AllowHexSpecifier"); $chars=@(); $index =@('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); if (().length % 2 -ne 0 -OR $i -lt 0) { ="0"; $i=[bigint]::Parse(, "AllowHexSpecifier"); } while($i -gt 0) { $m=([bigInt]$i % 58); $i=([bigInt]$i / 58); $chars+=$index[$m]; } [array]::reverse($chars); $i=$chars -join (''); -split "(..)" | ForEach-Object { if ($_ -match "00") { $i=("1"+$i); } else { return; } }; $chars=@(); $chars.clear(); $index=@(); $index.clear(); return $i; }; $bitcoinKeyPrivateBase58=Base58($bitcoinKeyPrivate); $bitcoinKeyPublicBase58=Base58($bitcoinKeyPublic); [System.IO.File]::Delete($tempFile); Write-Output "Bitcoin Wallet`n`nPassword:`n$password`n`nPrivate Key:`n$keyPrivate`n`nPrivate Key, WIF:`n$bitcoinKeyPrivateBase58`n`nPublic Key:`n$keyPublic`n`nPublic Key, Wallet:`n$bitcoinKeyPublicBase58`n`n"
此命令的输出:
对于上述命令,只需复制并粘贴到终端即可。
您可以在其他网站上查看生成的数据。在 Brain Wallet 模式下使用相同的密码并取消选中“压缩地址”。
BitAddress.org
Coinb.in
编辑#1
在步骤 a4 和 a5 之间,我们得到了一个非常大的数字。但并非 2^256
范围内的所有数字都在数学上 secp256k1 elliptic curve used for finding a matching public key. The range, is actually from 0
to 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
(in decimal: 115792089237316195423570985008687907852837564279074904382605163141518161494337
), as defined in the SEC2 standard. Read more about DOES THAT MEAN THERE ARE 2^256 POSSIBLE PRIVATE KEYS?.
检查哈希值是否小于该值。以下命令以十进制数字格式显示散列值:
PASSWORD="my-difficult-passphrase"; echo "ibase=16; $(printf $PASSWORD | openssl sha256 | grep -o "[0-9a-f]\{64\}" | tr a-z A-Z)" | bc | awk 'ORS=" "' | sed 's/\W//g'