I very much appreciate the BOTG base, and it handles a lot more things than this code does. This is just a way to generate a key with OpenSSL and find its address, so that one can send coins there and then later import the key into a wallet. Any contributions here which are mine I put into the public domain. (And as usual, no warranty, while I've tested it for my purposes and it seems good to me and I plan to use it, there's of course the chance of a subtle bug that will mean you can't get your coins or something.)
To run, just put the code in a file and mark it executable. Pass an argument of "1" if you'd like to see all the details of the OpenSSL key to check everything.
#!/bin/zsh
debug=$1
base58=(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)
capitalizeHex() {
tr "[a-f]" "[A-F]"
}
encodeBase58() {
initialones=$(sed -e 's/\(\(00\)*\).*/\1/' -e 's/00/1/g' <<<$1)
echo -n $initialones
bc <<<"ibase=16; n=$1; while(n>0) { n%3A ; n/=3A }" |
tail -r |
while read n
do echo -n ${base58[n+1]}
done
}
checksum() {
xxd -p -r <<<"$1" |
openssl dgst -sha256 -binary |
openssl dgst -sha256 -binary |
xxd -p -c 80 |
head -c 8 |
capitalizeHex
}
hexToAddress() {
echo "$(encodeBase58 "$2$1$(checksum "$2$1")")"
}
privatekey=$(openssl ecparam -genkey -name secp256k1 -noout)
openssldescription=$(openssl ec -text <<<$privatekey 2>/dev/null)
privatekeyhex=$(head -5 <<<$openssldescription | tail -3 | fmt -120 | sed -e 's/[: ]//g' -e 's/^00//' | awk '{printf "%064s\n", $0}' | capitalizeHex)
publickeyhashhex=$(openssl ec -pubout -outform DER <<<$privatekey 2>/dev/null | tail -c 65 | openssl dgst -sha256 -binary | openssl dgst -rmd160 -binary | xxd -p -c 80 | capitalizeHex)
address=$(hexToAddress $publickeyhashhex "00")
privatekeywif=$(hexToAddress $privatekeyhex "80")
(( $debug )) && echo $openssldescription
echo "Private Key Hex:" $privatekeyhex
echo "Private Key WIF:" $privatekeywif
(( $debug )) && echo "Public Key Hash:" $publickeyhashhex
echo "Address:" $address