前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >How to Get Pubkey From a Transaction

How to Get Pubkey From a Transaction

作者头像
happy123.me
发布2018-06-04 12:30:52
6020
发布2018-06-04 12:30:52
举报
文章被收录于专栏:乐享123乐享123

比如1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD,这个地址,有转出过,如何得到公钥

原理很简单,但是实践起来比较烦:

首先我们找一下这个地址的随便一笔花费,比如这个:

https://btc.com/0998ef06442994c147aec242e6973dfe3d512b05bde880793051a48bd021fc33

然后需要一个工具通过交易hash解析一下这笔交易

推荐用这个 libbitcoin/libbitcoin-explorer

执行

bx-windows-x64-icu.exe fetch-tx 0998ef06442994c147aec242e6973dfe3d512b05bde880793051a48bd021fc33

得到了这笔交易解析后的完整输出:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

transaction { hash 0998ef06442994c147aec242e6973dfe3d512b05bde880793051a48bd021fc33 inputs { input { address_hash b4a5d3960471568c3883046eec3b41b4953d61a1 previous_output { hash 5fb9f0e7f520163e4afe0baa440fe93999273e95d9e345e0488a0802ed62674f index 0 } script "[3045022100e4a4695ecbe6f507ec7181a2f321f489c7a3bd7eea032c75e4e1eba89174183c022019555aa917be6191db14da72e5c234a4b628f321b917ea334bcf9c122296cd5901] [044da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126da0a0909f11998130c2d0e86a485f4e79ee466a183a476c432c68758ab9e630b]" sequence 4294967295 } } lock_time 0 outputs { output { address_hash c621cbfd778e6109e26046d96738c7af75e7b78b script "dup hash160 [c621cbfd778e6109e26046d96738c7af75e7b78b] equalverify checksig" value 43103 } } version 1 }

注意script那一段,就是分成了两部分,前面一个中括号里面是签名,后面是公钥。

然后仔细看看这还是个老钱包生成的地址,没有压缩;

写个小脚本parse一下这个公钥,就可以看看是不是和地址对应啦:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

#!/usr/bin/env python from hashlib import * from base58 import * def SHA256D(bstr): return sha256(sha256(bstr).digest()).digest() def ConvertPKHToAddress(prefix, addr): data = prefix + addr return b58encode(data + SHA256D(data)[:4]) def PubkeyToAddress(pubkey_hex): pubkey = bytearray.fromhex(pubkey_hex) round1 = sha256(pubkey).digest() h = new('ripemd160') h.update(round1) pubkey_hash = h.digest() return ConvertPKHToAddress(b'\x00', pubkey_hash) pubkey = "044da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126da0a0909f11998130c2d0e86a485f4e79ee466a183a476c432c68758ab9e630b" print(len(pubkey)) print("Address: %s" % PubkeyToAddress(pubkey))

输出是这样的:

1 2

130 Address: 1HUBHMij46Hae75JPdWjeZ5Q7KaL7EFRSD

OK,打完收工。

如果一个地址只收币,从来没消费币,公钥是不会广播到网上的,所以这种地址拿不到公钥。一定要有花费,才能得到公钥。

所以有人推荐每次花费币之后就不要再用老地址了,每次交易都用新地址,避免将来出现什么黑科技(比如量子计算机之类的)穷举破解。 其实我觉的无所谓,大不了有人喊ECDSA挂了我再转移一下就行了,人家富豪榜里面都有好几个大佬也不在乎这点事。

PS:更新自打脸一下,我还是觉得每次交易用新地址是一定要做的,理论上HASH碰撞的概率有2160,但是我现在觉得这个量级不能简单的推算为1/2160;毕竟不是所有的钱包实现熵值都足够大。尽可能每次交易用新地址会增加碰撞库更新的难度。

再强调一遍,每次交易用新地址是一个必须养成的习惯。

另外公钥有两种形式:压缩与非压缩。一把私钥其实可以搞出两个地址哈。早期比特币均使用非压缩公钥,现大部分客户端已默认使用压缩公钥。早期openssl库的文档写的比较糙,导致Satoshi以为必须使用非压缩的完整公钥,后来大家发现其实公钥的左右两个32字节是有关联的,左侧(X)可以推出右侧(Y)的平方值,有左侧(X)就可以了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 再强调一遍,每次交易用新地址是一个必须养成的习惯。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档