1

I am trying to convert the 12 words into BTC addresses, but they do not match the ones shown to me by Safepal, Coinomi, and Trust Wallet. I have tried using several libraries and doing it manually.

I managed to successfully convert to SegWit, but P2PKH and P2SH still do not match.

The words (they are for testing purposes) are:

false deal abstract advance buffalo clock auto banana offer arena wage stumble

The code I am using to convert using the two methods that are not working is as follows:

################# P2PKH ##############

seed = hashlib.pbkdf2_hmac('sha512', mnemonic.encode('utf-8'), b'mnemonic', 2048)
private_key = seed[:32]
public_key = hashlib.sha256(private_key).digest()
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(public_key)
hash160 = ripemd160.digest()
version = b"\x00" # version for P2PKH addresses on Bitcoin mainnet
address_bytes = version + hash160
checksum = hashlib.sha256(hashlib.sha256(address_bytes).digest()).digest()[:4]
addressP2PKH = base58.b58encode(address_bytes + checksum).decode('utf-8')

################ P2SH ##############

seed = hashlib.pbkdf2_hmac('sha512', mnemonic.encode('utf-8'), b'mnemonic', 2048)
private_key = seed[:32]
sk = SigningKey.from_string(private_key, curve=SECP256k1)
vk = sk.get_verifying_key()
public_key_bytes = vk.to_string()
hashed_public_key = hashlib.sha256(public_key_bytes).digest()
ripe_hash = hashlib.new('ripemd160', hashed_public_key).digest()
prefix = b'\x05'
prefixed_ripe_hash = prefix + ripe_hash
address_bytes = hashlib.sha256(prefixed_ripe_hash).digest()
address_bytes = hashlib.sha256(address_bytes).digest()
checksum = address_bytes[:4]
raw_address = prefixed_ripe_hash + checksum
addressP2SH = base58.b58encode(raw_address).decode()

print(['segwitAddress', 'addressP2PKH', 'addressP2SH'])

The output is:

['bc1qfev3mh2mz3cuvsfn3wt6rwv78qjlkcy7dj27dk', '14ZowctPoxYtaUa55XKpUq8h2VWzPvLQ84', '37qZKk7ZpFFX63fR4HLPRaU5jtdhckmcnP']

But it should be:

['bc1qfev3mh2mz3cuvsfn3wt6rwv78qjlkcy7dj27dk', '1D9P3s1Daa3dmLq88QAky3uv4vjT6WZRCV', '3HojBjoLmEHjrHfiiUKAL1NCVXEcmAf7iY']

1 Answer 1

1

For P2PKH, you've hashed the private key rather than the public key.

For P2SH, you've hashed the public key and used the P2SH version number, however that is not what a P2SH address should be. Rather P2SH encodes the hash of a script that can be executed - public keys are not scripts. Presumably you mean P2SH wrapped P2WPKH, so the script is the hash of the segwit script (0x0016<pubkey hash>) encoded with Base58Check.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.