Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bitcoin address generator in bash
#!/bin/bash
#
# This is free and unencumbered software released into the public domain.
#
# Requires bc, dc, openssl, xxd
#
# by grondilu from https://bitcointalk.org/index.php?topic=10970.msg156708#msg156708
base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})
bitcoinregex="^[$(printf "%s" "${base58[@]}")]{34}$"
if [ `uname -s` = 'Darwin' ]; then
TAC="tail -r "
else
TAC="tac"
fi
decodeBase58() {
local s=$1
for i in {0..57}
do s="${s//${base58[i]}/ $i}"
done
dc <<< "16o0d${s// /+58*}+f"
}
encodeBase58() {
# 58 = 0x3A
echo -n "$1" | sed -e's/^\(\(00\)*\).*/\1/' -e's/00/1/g' | tr -d '\n'
dc -e "16i ${1^^} [3A ~r d0<x]dsxx +f" |
while read -r n; do echo -n "${base58[n]}"; done
}
checksum() {
xxd -p -r <<<"$1" |
openssl dgst -sha256 -binary |
openssl dgst -sha256 -binary |
xxd -p -c 80 |
head -c 8
}
checkBitcoinAddress() {
if [[ "$1" =~ $bitcoinregex ]]
then
h=$(decodeBase58 "$1")
checksum "00${h::${#h}-8}" |
grep -qi "^${h: -8}$"
else return 2
fi
}
hash160() {
openssl dgst -sha256 -binary |
openssl dgst -rmd160 -binary |
xxd -p -c 80
}
hash160ToAddress() {
printf "%34s\n" "$(encodeBase58 "00$1$(checksum "00$1")")" |
sed "y/ /1/"
}
publicKeyToAddress() {
hash160ToAddress $(
openssl ec -pubin -pubout -outform DER |
tail -c 65 |
hash160
)
}
echo -n "Public key: "
openssl ecparam -name secp256k1 -genkey | tee priv.pem | openssl ec -pubout | publicKeyToAddress
echo ""
echo -n "Private key: "
cat priv.pem
echo ""
@ejpusa

This comment has been minimized.

Copy link

@ejpusa ejpusa commented Mar 28, 2014

Hi, I am trying to learn how to generate address on a Mac. I'm getting this error:

writing EC key
./address.sh: line 28: ibase=16; n=${1^^}; while(n>0) { n%3A ; n/=3A }: bad substitution
1111111111111111111111111111111111

Any pointers appreciated. Thanks! :-)

@gmelika

This comment has been minimized.

Copy link

@gmelika gmelika commented Mar 29, 2014

Just replace line 28 with:

bc <<<"ibase=16; n=$(tr '[:lower:]' '[:upper:]' <<< "$1"); while(n>0) { n%3A ; n/=3A }" |
@Rello

This comment has been minimized.

Copy link

@Rello Rello commented Dec 22, 2016

Hello @colindean,
just testing your script - but somehow don´t understand the output.
Public is a valid BC-Address.
But I am not getting a valid private key out of it.

thank you

$ sudo bash bc_bash.sh 
Public key: read EC key
writing EC key
read EC key
writing EC key
1HZB4eYki5cMLgPsR7kimnL6FxL7N1uhe9

Private key: -----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDpK9zS2PFpfhez6pnT0qgxEt9Jnlwtt72H7rQE57DY2oAcGBSuBBAAK
oUQDQgAERsSuogXokFJn9dE43n0k2jOzt75hMR9zQjy3bNNTPimswupUFATnHtwu
/qN5s0irxXFM+BHzGN4xBVXEuydLzA==
-----END EC PRIVATE KEY-----
@liushooter

This comment has been minimized.

Copy link

@liushooter liushooter commented Jun 24, 2017

@Rello
I thinke you should:

Get private key:

openssl ec -in priv.pem -outform DER|tail -c +8|head -c 32|xxd -p -c 32

Get public key:

openssl ec -in priv.pem -pubout -outform DER|tail -c 65|xxd -p -c 65

from https://bitcoin.stackexchange.com/a/11843

@esolitos

This comment has been minimized.

Copy link

@esolitos esolitos commented Aug 10, 2017

Am I not understanding something?
I did some tests and the address i get on generation doesn't seems to match the key?

Here are the steps taken:

  • Generate the address: generate_bitcoin_address.sh [Key at the end of this post]
  • Import the address to blockchain.info/wallet all good
  • Send a tiny payment to the address, still all good (as expected)
  • Generate the btc-private key from the EC using @shooterman oneliner: openssl ec -in priv.pem -outform DER |tail -c +8 |head -c 32 |xxd -p -c 32 ==> f68f38a156d9da6747ea4318c3cc2513159e4fa9224c106ff946d900022f4e11
  • Import this private key to blockchain.info/wallet, and here's the weirdness: I do actually manage to import the wallet, but I get a different address!!!

Help?

Attached data

Key generation:

# ./generate_bitcoin_address.sh
Public key: 1Ho5y31HGWViGVtj4J4J2gVrn9kHhbD11z

Private key:
 -----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIGktBoOg2mOYqf91vKHOwLge36XyFjRwrGFlC964uzXXoAcGBSuBBAAK
oUQDQgAEovoPa1wLZrGh0xJuoe9FA9iWrYsuqXOcg/5SYv/Fr0K0m9K/JcY0TtUZ
xPFAyU5yAjS2pVRLevjmQb0RHocDKw==
-----END EC PRIVATE KEY-----

Imported address in blockchain.info/wallet:
image

Retrive the btc-key:

# openssl ec -in priv.pem -outform DER |tail -c +8 |head -c 32 |xxd -p -c 32
692d0683a0da6398a9ff75bca1cec0b81edfa5f2163470ac61650bdeb8bb35d7

Import to blockchain.info/wallet
image

EDIT

In pursuit of the right tool i found here an alternative in python (Note you need ecdsa from pip, before you can run it).

@Rotsor

This comment has been minimized.

Copy link

@Rotsor Rotsor commented Nov 30, 2017

This prints a wrong number of leading '1' characters in the address. For example, it prints 11wv6n4DaLQLHqfAUXzchLVBVv1P5CrSoH instead of 1wv6n4DaLQLHqfAUXzchLVBVv1P5CrSoH when encoding 000a62c98943feeb9ea0572ebac7bd323bc54cada0b87ca958.

@arno01

This comment has been minimized.

Copy link

@arno01 arno01 commented Dec 8, 2017

@Rotsor looks like an extra leading space problem... I think this should fix that, at least it works for me:

hash160ToAddress() {
    printf "%34s\n" "$(encodeBase58 "00$1$(checksum "00$1")")" |
    sed -e 's/^  / /' |
    sed "y/ /1/"
}

Edit

Or rather use this function, apparently it encodes the leading 00 properly:

base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z});

function encodeBase58() {
    echo -n "$1" | sed -e's/^\(\(00\)*\).*/\1/' -e's/00/1/g' | tr -d '\n'
    dc -e "16i ${1^^} [3A ~r d0<x]dsxx +f" |
    while read -r n; do echo -n "${base58[n]}"; done
}

Found at https://github.com/grondilu/bitcoin-bash-tools/blob/master/bitcoin.sh

@Pablo36

This comment has been minimized.

Copy link

@Pablo36 Pablo36 commented Mar 31, 2018

Hello, I have a question on how to generate the key of the given address, please and any info if I can give you a btc helper. I have no idea how to do this and info on priv or email zarabaniaprzeznecik@gmail.com. I have btc to pay, but I do not have a private kucza please help

@colindean

This comment has been minimized.

Copy link
Owner Author

@colindean colindean commented Jun 23, 2019

After far too many years of not knowing that I was getting comments on this, I've updated it a with @arno01's recommendation.

@MichaelMichaelMichaelMichaelMichael

This comment has been minimized.

Copy link

@MichaelMichaelMichaelMichaelMichael MichaelMichaelMichaelMichaelMichael commented Oct 6, 2019

Hi, with the edited encodeBase58 function, from time to time, it's still generating addresses with a prefix 11.
Examples:

address: 11NVGRNwpqYCUiJ42TJ5iLdHt8wALLyRyV secret:  0527fee5b586ddea8837cdbf58e6f9b334e10bb95c20519db63561eda3861f01
address: 11BC84pND1z7ekq12FF7LLDKmRmQT6QhxB secret:  bb35d58aecd49a012587a6093de0ffd2d4c143242fe60196900fa4e88a72480e
address: 11PgGJsvRZBynVcfSTMAnZQXLx2pnGSCNk secret:  3096e3fc4027e63cc3ca46b208b45581ded83773f798658a9b3b5fcdcb9ab3a3
address: 11PZLAC8yDV76gLv2EN7BykAS3Kor8Fcym secret:  29a7cef80bdf63571f8b93a629943475f50aa1f9e4cebc911e8ee0f3e19baa20
address: 11Bp95CTxgyWecEXxV6m3UzUiT6JutJ8VN secret:  0d5c20fd922cb9c134aecf9a4bd992af429f16b8742d91d056aeab22f2a08392
address: 11AWP79DdTHmogAiuvyokDK28LQoq1QnB2 secret:  d698fd92748de1a484bcb18d1f5c9bd4f066a30eb7f56c92b6281cf68e7d7127
address: 11R1T3jv92emkonrjfkUDJdeWR7naDVuR3 secret:  51a37515a5964f5c293733a179f1072d6918249bf0c264ca903bbe8267a4a352
address: 11MNiiYjA57xKfTZo6cTCZV5Q6n3kyMFma secret:  79bbd8bd40a3e3f581aad528bc0320c525ec8a92717070d7327c879c1a597c1c
address: 11kUJeGjdUnubuuxECmWdzzMpCGLzhYBZU secret:  8ad77d1b6695cb5bce4654110aa30b62cf16e46db5d97189604019d1200f8943
address: 11wMeBcQW2QNuLXE7rfdC1KA1x6E8Bio7A secret:  25ca9ec03fa6935ed4ce36edb817fc6fd30864309520af99051a14376d623595
address: 11Nu6WymbKBmZKpiSyJEAwMM9MT495BHGZ secret:  a1b55bd7d2c449a5480b67e84f774f8c1372b431b16408430cdac5626878a23b
address: 11ec8HgPZZxHkGR1og79QPwLSkuhqTNDma secret:  fd93585c1fafa30ebdfc068da8579001764a4c75bb9b8bba532331f5df621e2a
address: 11yhkhxVD73YmmW7vtB153TDLdPHvBnvhZ secret:  3f8f89f30acf1e08f129d3a5d725189fdd6384cb5178c5901432c25207742b02
address: 11a6eEoWH47KCf2w5pEYbLGQ4Rn31wjxiJ secret:  0a6cfd67b4cc859321f450e6d020a6b9abbdd838a0ec4afa30976a72344f0292

Just to let you know that this issue still exists.

@colindean

This comment has been minimized.

Copy link
Owner Author

@colindean colindean commented Oct 6, 2019

I welcome suggestions. I don't have the bandwidth available right now to debug it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.