Author

Topic: Pubkey/address help needed (Python) (Read 205 times)

copper member
Activity: 250
Merit: 412
Building A Crypto Empire
January 12, 2022, 09:24:24 AM
#7
Do you have any suggestions for a new well maintained Bitcoin python library for production use instead of testing?
I'm not a python programmer to be familiar with the libraries and their pros and cons but I've seen bitcoinlib be used in a couple of places and it seems to be actively developed. It also has a doc you could read.
Depending on your use case you may want to look into using Electrum wallet software too. It is written in python and it can handle address creation and much more.

Thanks @pooya87 I have heard about Bitcoinlib and have tested with it in the past. Its not what I am looking for, yes Electrum is good totally agree with that.

Do you have any suggestions for a new well maintained Bitcoin python library for production use instead of testing?
I'm not a python programmer to be familiar with the libraries and their pros and cons but I've seen bitcoinlib be used in a couple of places and it seems to be actively developed. It also has a doc you could read.

pycoin is also quite popular and partially support altcoin as well. The documentation also exist, although i find it's not easy to read.

Thanks @ETFbitcoin I tried pycoin in the past its a really good library, but again its not what I am looking for. I just need a library that can do this specific task it doesn’t need to provide too many things.

There is a helpful blog post at https://matthewdowney.github.io/create-segwit-address.htmlwhich provides the code to generate the P2SH address from a public key with minimal dependencies.

This is the only thing that needs to be installed:

Code:
(base) zenulabidin@artanis:~/Documents$  pip install git+https://github.com/matthewdowney/bip32utils
Collecting git+https://github.com/matthewdowney/bip32utils
  Cloning https://github.com/matthewdowney/bip32utils to /tmp/pip-req-build-bqskxgsa
  Running command git clone -q https://github.com/matthewdowney/bip32utils /tmp/pip-req-build-bqskxgsa
Requirement already satisfied: ecdsa in /home/zenulabidin/anaconda3/lib/python3.8/site-packages/ecdsa-0.16.1-py3.8.egg (from bip32utils==0.3.post3) (0.16.1)
Requirement already satisfied: six>=1.9.0 in /home/zenulabidin/anaconda3/lib/python3.8/site-packages (from ecdsa->bip32utils==0.3.post3) (1.15.0)
Building wheels for collected packages: bip32utils
  Building wheel for bip32utils (setup.py) ... done
  Created wheel for bip32utils: filename=bip32utils-0.3.post3-py3-none-any.whl size=10415 sha256=105abc933ae4057dd876b844ec6efc2167c31c9679e6997d187bd8ae186d16a4
  Stored in directory: /tmp/pip-ephem-wheel-cache-7_7ylb1d/wheels/04/0c/5b/e5ed2d7087a4d71bcfb1491071e94c657e4b3eeeb09bb362d2
Successfully built bip32utils
Installing collected packages: bip32utils
Successfully installed bip32utils-0.3.post3

Then you can run the code in the link:

Code:
import hashlib
def hash160(x): # Both accepts & returns bytes
    return hashlib.new('ripemd160', hashlib.sha256(x).digest()).digest()

from bip32utils import Base58

def p2wpkh_in_p2sh_addr(pk, testnet=False):
    """
    Compressed public key (hex string) -> p2wpkh nested in p2sh address. 'SegWit address.'
    """
    # Script sig is just PUSH(20){hash160(cpk)}
    push_20 = bytes.fromhex("0014")
    script_sig = push_20 + hash160(bytes.fromhex(pk))
   
    # Address is then prefix + hash160(script_sig)
    prefix = b"\xc4" if testnet else b"\x05"
    address = Base58.check_encode(prefix + hash160(script_sig))
    return address

>>> pub = "03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
>>> p2wpkh_in_p2sh_addr(pub)
"36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"
>>> p2wpkh_in_p2sh_addr(pub, testnet=True)
"2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2"

I ran the examples above and I was able to reproduce them (there is a small function error in the original post, hash160_bytes should be just hash160).

Thanks @NotATether the code does work  Wink, thats what I was looking for specifically.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
January 11, 2022, 05:28:24 AM
#6
There is a helpful blog post at https://matthewdowney.github.io/create-segwit-address.htmlwhich provides the code to generate the P2SH address from a public key with minimal dependencies.

This is the only thing that needs to be installed:

Code:
(base) zenulabidin@artanis:~/Documents$  pip install git+https://github.com/matthewdowney/bip32utils
Collecting git+https://github.com/matthewdowney/bip32utils
  Cloning https://github.com/matthewdowney/bip32utils to /tmp/pip-req-build-bqskxgsa
  Running command git clone -q https://github.com/matthewdowney/bip32utils /tmp/pip-req-build-bqskxgsa
Requirement already satisfied: ecdsa in /home/zenulabidin/anaconda3/lib/python3.8/site-packages/ecdsa-0.16.1-py3.8.egg (from bip32utils==0.3.post3) (0.16.1)
Requirement already satisfied: six>=1.9.0 in /home/zenulabidin/anaconda3/lib/python3.8/site-packages (from ecdsa->bip32utils==0.3.post3) (1.15.0)
Building wheels for collected packages: bip32utils
  Building wheel for bip32utils (setup.py) ... done
  Created wheel for bip32utils: filename=bip32utils-0.3.post3-py3-none-any.whl size=10415 sha256=105abc933ae4057dd876b844ec6efc2167c31c9679e6997d187bd8ae186d16a4
  Stored in directory: /tmp/pip-ephem-wheel-cache-7_7ylb1d/wheels/04/0c/5b/e5ed2d7087a4d71bcfb1491071e94c657e4b3eeeb09bb362d2
Successfully built bip32utils
Installing collected packages: bip32utils
Successfully installed bip32utils-0.3.post3

Then you can run the code in the link:

Code:
import hashlib
def hash160(x): # Both accepts & returns bytes
    return hashlib.new('ripemd160', hashlib.sha256(x).digest()).digest()

from bip32utils import Base58

def p2wpkh_in_p2sh_addr(pk, testnet=False):
    """
    Compressed public key (hex string) -> p2wpkh nested in p2sh address. 'SegWit address.'
    """
    # Script sig is just PUSH(20){hash160(cpk)}
    push_20 = bytes.fromhex("0014")
    script_sig = push_20 + hash160(bytes.fromhex(pk))
   
    # Address is then prefix + hash160(script_sig)
    prefix = b"\xc4" if testnet else b"\x05"
    address = Base58.check_encode(prefix + hash160(script_sig))
    return address

>>> pub = "03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f"
>>> p2wpkh_in_p2sh_addr(pub)
"36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"
>>> p2wpkh_in_p2sh_addr(pub, testnet=True)
"2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2"

I ran the examples above and I was able to reproduce them (there is a small function error in the original post, hash160_bytes should be just hash160).
legendary
Activity: 2870
Merit: 7490
Crypto Swap Exchange
January 10, 2022, 05:02:20 AM
#5
Do you have any suggestions for a new well maintained Bitcoin python library for production use instead of testing?
I'm not a python programmer to be familiar with the libraries and their pros and cons but I've seen bitcoinlib be used in a couple of places and it seems to be actively developed. It also has a doc you could read.

pycoin is also quite popular and partially support altcoin as well. The documentation also exist, although i find it's not easy to read.
legendary
Activity: 3472
Merit: 10611
January 09, 2022, 10:43:43 PM
#4
Do you have any suggestions for a new well maintained Bitcoin python library for production use instead of testing?
I'm not a python programmer to be familiar with the libraries and their pros and cons but I've seen bitcoinlib be used in a couple of places and it seems to be actively developed. It also has a doc you could read.
Depending on your use case you may want to look into using Electrum wallet software too. It is written in python and it can handle address creation and much more.
copper member
Activity: 250
Merit: 412
Building A Crypto Empire
January 09, 2022, 10:44:40 AM
#3
P2SH as the name suggests is created using a script not the public key. So you have to first construct your desired script then compute HASH160 of that serialized script and finally encode it using Base58 using the different version byte.

BTW the library you are using is very old and is obsolete.

Thanks @pooya87 I done more research on everything you have mentioned, it makes all sense now. Do you have any suggestions for a new well maintained Bitcoin python library for production use instead of testing?

Since it's only for testing purpose, this code should do the job. Don't forget to install https://github.com/ofek/bit first.

Code:
>>> from bit import Key
>>> key = Key()
>>> key.address
'1GCfsCqwdtM3BSxj1iXKRE4RpK4qMvZZQn'
>>> key.segwit_address
'3Gkt8rYpVuDKxCDM3dDHGUaaFEeANfqbQo'

I want to generate a P2SH address from the pubkey instead.

If you don't need any specific feature (e.g. timelock or multi-signature), you don't really need P2SH address.

Thanks @ETFbitcoin for providing this library.
legendary
Activity: 3472
Merit: 10611
January 09, 2022, 12:33:06 AM
#2
P2SH as the name suggests is created using a script not the public key. So you have to first construct your desired script then compute HASH160 of that serialized script and finally encode it using Base58 using the different version byte.

BTW the library you are using is very old and is obsolete.
copper member
Activity: 250
Merit: 412
Building A Crypto Empire
January 08, 2022, 08:55:26 PM
#1
Hello guys,

I am using Bitcoin python package for testing purposes  (https://pypi.org/project/bitcoin/)

The function I am calling is:

Code:
pubkey_to_address(pubkey)

Its returning a P2PKH address

I want to generate a P2SH address from the pubkey instead.

Function code:

Code:
def pubkey_to_address(pubkey, magicbyte=0):
     if isinstance(pubkey, (list, tuple)):
         pubkey = encode_pubkey(pubkey, 'bin')
     if len(pubkey) in [66, 130]:
         return bin_to_b58check(
             bin_hash160(binascii.unhexlify(pubkey)), magicbyte)
     return bin_to_b58check(bin_hash160(pubkey), magicbyte)

Have read that I need to change magicbyte to 5 instead of 0 but that is not doing everything else correct 100%, so need a hand with us. If anyone can help edit the code it would be helpful, its this line that needs editing I would think:

Code:
return bin_to_b58check(bin_hash160(binascii.unhexlify(pubkey)), magicbyte)
Jump to: