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']
Vojtěch Strnad
  • 5,623
  • 1
  • 8
  • 31
Nigan
  • 19
  • 2

1 Answers1

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.

Andrew Chow
  • 67,209
  • 5
  • 76
  • 149