2019-10-07 15:58:12 +02:00
|
|
|
"""
|
|
|
|
Calculates bitcoin and testnet address from pubkey
|
|
|
|
"""
|
|
|
|
|
2013-06-21 11:10:13 +02:00
|
|
|
import hashlib
|
2019-10-07 15:58:12 +02:00
|
|
|
|
|
|
|
from debug import logger
|
2013-06-21 13:58:36 +02:00
|
|
|
from pyelliptic import arithmetic
|
2013-06-21 11:10:13 +02:00
|
|
|
|
2019-10-07 15:58:12 +02:00
|
|
|
|
2013-06-21 11:10:13 +02:00
|
|
|
def calculateBitcoinAddressFromPubkey(pubkey):
|
2019-10-07 15:58:12 +02:00
|
|
|
"""Calculate bitcoin address from given pubkey (65 bytes long hex string)"""
|
2013-06-21 11:10:13 +02:00
|
|
|
if len(pubkey) != 65:
|
2019-10-07 15:58:12 +02:00
|
|
|
logger.error('Could not calculate Bitcoin address from pubkey because'
|
|
|
|
' function was passed a pubkey that was'
|
|
|
|
' %i bytes long rather than 65.', len(pubkey))
|
2013-06-21 11:10:13 +02:00
|
|
|
return "error"
|
|
|
|
ripe = hashlib.new('ripemd160')
|
|
|
|
sha = hashlib.new('sha256')
|
|
|
|
sha.update(pubkey)
|
|
|
|
ripe.update(sha.digest())
|
|
|
|
ripeWithProdnetPrefix = '\x00' + ripe.digest()
|
|
|
|
|
|
|
|
checksum = hashlib.sha256(hashlib.sha256(
|
|
|
|
ripeWithProdnetPrefix).digest()).digest()[:4]
|
|
|
|
binaryBitcoinAddress = ripeWithProdnetPrefix + checksum
|
|
|
|
numberOfZeroBytesOnBinaryBitcoinAddress = 0
|
|
|
|
while binaryBitcoinAddress[0] == '\x00':
|
|
|
|
numberOfZeroBytesOnBinaryBitcoinAddress += 1
|
|
|
|
binaryBitcoinAddress = binaryBitcoinAddress[1:]
|
|
|
|
base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58)
|
|
|
|
return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded
|
|
|
|
|
|
|
|
|
|
|
|
def calculateTestnetAddressFromPubkey(pubkey):
|
2019-10-07 15:58:12 +02:00
|
|
|
"""This function expects that pubkey begin with the testnet prefix"""
|
2013-06-21 11:10:13 +02:00
|
|
|
if len(pubkey) != 65:
|
2019-10-07 15:58:12 +02:00
|
|
|
logger.error('Could not calculate Bitcoin address from pubkey because'
|
|
|
|
' function was passed a pubkey that was'
|
|
|
|
' %i bytes long rather than 65.', len(pubkey))
|
2013-06-21 11:10:13 +02:00
|
|
|
return "error"
|
|
|
|
ripe = hashlib.new('ripemd160')
|
|
|
|
sha = hashlib.new('sha256')
|
|
|
|
sha.update(pubkey)
|
|
|
|
ripe.update(sha.digest())
|
|
|
|
ripeWithProdnetPrefix = '\x6F' + ripe.digest()
|
|
|
|
|
|
|
|
checksum = hashlib.sha256(hashlib.sha256(
|
|
|
|
ripeWithProdnetPrefix).digest()).digest()[:4]
|
|
|
|
binaryBitcoinAddress = ripeWithProdnetPrefix + checksum
|
|
|
|
numberOfZeroBytesOnBinaryBitcoinAddress = 0
|
|
|
|
while binaryBitcoinAddress[0] == '\x00':
|
|
|
|
numberOfZeroBytesOnBinaryBitcoinAddress += 1
|
|
|
|
binaryBitcoinAddress = binaryBitcoinAddress[1:]
|
|
|
|
base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58)
|
|
|
|
return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded
|