[英]Getting Hash160 bitcoin address in python
tl; dr应该如何使用大多数基本的python工具执行Hash160?
================================================== ==
嗨,
我想弄清楚交易如何在比特币中运作。
当我为新tx选择输入时,我想确保它们属于特定地址。 但是,现有的txs不指定先前输出的地址,而是指定包含地址的散列。
例如:
>> bx fetch-tx 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c --config /home/theo/Desktop/bx-testnet.cfg
{
hash 11a1b7ac0a65bd50b7094c720aecd77cfd83d84b1707960fd00dd82a888aab5c
inputs
{
input
{
address_hash f3b7278583827a049d6be894bf7f516178a0c8e6
previous_output
{
hash 4a3532061d43086299ae9b2409a456bb9638dff32e0858c4ccda27203fb2e4f6
index 1
}
script "[30440220146b8b5b014245a9e27e21122d4dded04c3f39c3a49ac2494743d6f6ae8efff602206d417a4be9c7431ea69699132438510ade1cf8d746607f77d114907762ed1eb301] [023dd2e892290e41bb78efce6ea30a97015ef13eaaa9ebb7b0514485fc365cc391]"
sequence 4294967295
}
}
lock_time 0
outputs
{
output
{
address_hash a73706385fffbf18855f2aee2a6168f29dbb597e
script "dup hash160 [a73706385fffbf18855f2aee2a6168f29dbb597e] equalverify checksig"
value 130000000
}
output
{
address_hash ad6e80394af99ece5d7701bf2f457480b93965b7
script "dup hash160 [ad6e80394af99ece5d7701bf2f457480b93965b7] equalverify checksig"
value 49525957813
}
}
version 1
}
说,我想检查哪些输出可以从地址mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa
发送所以我在Python中使用它的Hash160:
>> hashlib.new('ripemd160', hashlib.sha256("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa".encode('utf-8')).digest()).hexdigest()
'748598cd9b004aecf8a2d97464fb1f2a90562ffe'
那不是我预期的结果: a73706385fffbf18855f2aee2a6168f29dbb597e
同时, 此在线服务正确计算哈希值。
我如何在Python中使用Hash160比特币地址?
最后我做到了。 我的答案中的一些启示对你来说可能看起来很明显和基本,但我希望它们对比特币(比如我)全新的ppl有所帮助。
========
维基说我可以通过扭转地址生成的最后一步来获得Hash160
此步骤使用base58字母编码字节字符串
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
这个字母表缺少0,I,l,O,因为这些符号很容易混淆。 当一个错误的符号可能导致损失大量金钱时,这是你想要做的最后一件事。
因此,我们需要将mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa
转换为字节串。 字节以十六进制格式表示,范围可以是0x00
(0十进制)到0xff
(十进制255)。 并且请注意我们有一个特殊的b58字母表来处理:用utf-8或其他编码标准解码地址会产生废话。
起初我以为我可以使用此功能轻松解码地址:
def decode(addr):
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
decoded = ''
for i in addr:
temp = hex(b58.index(i))
if len(temp) == 3:
temp = '0' + temp[-1]
else:
temp = temp[2:]
decoded += (temp)
return (decoded)
decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')
>> '2c352c06030e090b212127390803312a1d22152c1d010d2c2811242c0d0f23372f21'
但结果与我在事务中查找的哈希( a73706385fffbf18855f2aee2a6168f29dbb597e
)完全不同。 这样我就知道我不知道如何解码。 如果Hash160有0xff
怎么办? 在b58中没有这样的符号,因为十六进制中的58只是0x3a
。 在解码b58时,我们无法独立处理每个符号。 整个地址组成了一个用base58数值系统编写的巨大数字(其第一个数字对应于58 ** 34)。
为了获得字节字符串,我首先将此数字转换为十进制数,然后再将其转换为字节字符串。
如果你知道如何避免这种绕道并直接得到字节 - 请评论
def decode(addr):
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def base58_to_dec(addr):
dec = 0
for i in range(len(addr)):
dec = int(dec * 58 + b58.index(addr[i]))
print('Decimal representation')
print(dec)
return(dec)
def dec_to_byte(dec):
out = ''
while dec != 0:
print(dec)
remn = dec % 256
dec = int((dec - remn) / 256)
temp = hex(remn)
if len(temp) == 3:
temp = '0' + temp[-1]
else:
temp = temp[2:]
out = temp + out
return(out)
dec = base58_to_dec(addr)
out = dec_to_byte(dec)
return (out)
decode("mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa")
>> Decimal representation
>> 700858390993795610399098743129153130886272689085970101576715
>> '6fa7370638600000000000000000000000000000000000000b'
那个输出看起来有点像我需要的东西( a7370638...
),但有太多的零。 不要看第一个字节( 6f
)不匹配:它与我们需要的Hash160无关,只是协议版本。
这可能是精度错误。 为了解决这个问题,我使用了mpmath
,它可以让你精确地操作整数。
from mpmath import *
mp.dps = 1000
def decode(addr):
b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def base58_to_dec(addr):
dec = 0
for i in range(len(addr)):
dec = int(dec * 58 + b58.index(addr[i]))
return(dec)
def dec_to_byte(dec):
out = ''
while dec != 0:
remn = mpf(dec % 256)
dec = mpf((dec - remn) / 256)
temp = hex(int(remn))
if len(temp) == 3:
temp = '0' + temp[-1]
else:
temp = temp[2:]
out = temp + out
return (out)
dec = base58_to_dec(addr)
out = dec_to_byte(dec)
return (out)
应用精确的模运算,我们终于可以得到Hash160。 只需确保修剪带有胖指检查的第一个和最后4个字节。
x = decode('mvm74FACaagz94rjWbNmW2EmhJdmEGcxpa')
print(x)
>> 6fa73706385fffbf18855f2aee2a6168f29dbb597ef59c240b
print(x[2:-8])
>> a73706385fffbf18855f2aee2a6168f29dbb597e
好极了! 就像在交易中一样!
看起来你在尝试自己做这件事时遇到了很多麻烦,我也不认为你的解决方案在性能方面会很有效率。
您遵循的逻辑是正确的,但事情可以更好地完成,因为知道在base58中有一个解码和编码的包,它被称为base58
python -m pip install base58
下面是获取base58(python 2.7)中编码的比特币地址的ripemd160哈希的简单方法:
>>>import base58
>>>adr58 = '1Q2TWHE3GMdB6BZKafqwxXtWAWgFt5Jvm3'
>>>adr160 = base58.b58decode_check(adr58).encode('hex')[2:]
>>>print (adr160)
fc916f213a3d7f1369313d5fa30f6168f9446a2d
注意decod_check考虑校验和和[2:]去掉零
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.