虚拟货币开发专题(如何实现匿名技术)

来源:互联网 发布:ubuntu 14.04 阿里源 编辑:程序博客网 时间:2024/05/17 02:58

区块链爱好者(QQ:53016353)


虚拟币用户可以开多个虚拟币地址,并且地址跟他现实生活中的真实身份也没有任何联系,因而具有一定匿名性,被广泛运用于洗钱和违禁物品交易,不过这一特性实为“伪匿名”,虚拟币的交易仍可以追本溯源到交易者本身。







虚拟币的交易历史是完全公开的,所有人都可以通过你的钱包地址在区块链中查询你的钱包现金流入与流出,并可向上追溯至这些虚拟币的终极起源,即从区块生成后发送到的那个地址。这对个人隐私构成了巨大威胁。


虚拟币协议为上述问题提供了两种解决方案:(1)所有的虚拟币交易使用公共密钥,而无须个人身份证明;(2)虚拟币客户端可以生成无数个公共密钥,以帮助用户防止跟踪。


然而,越来越多的研究表明,这些保护措施是不够的。如果通过一些社会工程学手段,使得某个虚拟币钱包的物理地址(如IP地址)暴露,再配以大数据分析,那么,资金的来龙去脉与关系网将无从遁形。在《大数据时代》一书中,作者举了个例子证明大数据分析的威力:通过对美国在线(AOL)2006年8月公布的2000万匿名搜索查询记录的分析,《纽约书包》发现数据库中的4417749号样本代表的是佐治亚州的一名妇女。


德国和瑞士学者的一项研究显示,约40%虚拟币用户的真实身份可被发现,这其中有些用户还使用了官方推荐的隐私保护措施。加州大学圣地亚哥分校研究者即将发表的一篇论文中称,虚拟币交易网络对少数大账户的依赖性与日俱增,这使得用户的身份安全性大大降低。日后,通过大宗交易追踪到交易者的真实身份将变得容易,这最终可能会使得如今被大量用于洗钱等非法活动的虚拟币不再受宠。乔治梅森大学的研究人员发布了一篇涉及到监管虚拟币的入门书,书中的评价大大降低了它的匿名性。Vice发表了一篇“描述研究人员成功地把一些虚拟币交易去匿名化”的文章,并且第二天一篇类似的文章登上了商业周刊。






比特币地址的结构比特币地址和私钥是由ECDSA椭圆曲线加密算法计算出来的,由ECDSA私钥计算出我们常用的Bitcoin-qt格式比特币地址需要有十个步骤。
第一步,产生ECDSA私钥,如:
18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
第二步,计算出ECDSA公钥,
0450863AD64A87AE8A2FE8….82BA6
第三步,对公钥进行SHA256运算
600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408
第四步,对第三步结果进行RIPEMD-160运算
010966776006953D5567439E5E39F86A0D273BEE
第五步,在第四步结果上加上版本号
00010966776006953D5567439E5E39F86A0D273BEE
第六步,对第五步结果进行SHA256运算
445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094
第七步,对第六步结果进行SHA256运算
D61967F63C7DD183914A4AE452C9F6AD5D462CE3D277798075B107615C1A8A30
第八步,提出第七步结果的前四个字节
D61967F6
第九步,将第八步的结果加到第五步结果最后面
00010966776006953D5567439E5E39F86A0D273BEED61967F6
第十步,对第九步结果进行Base58编码
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
我们由上面的十个步骤可以看出。第八步中的四个字节是拿出来做checksum检查的。检查一个地址是否有效,我们只需要将第十步的结果做逆运算,去掉最后四个字节得到第四步的结果,然后做两次SHA256运算看看能否重新计算出的结果是否以这四个字节开头就行了。


procedure


所以当你输入一个比特币地址的时候,Blockchain这样的在线钱包就会用上面的方法检查这个地址是否正确。当然,我们一般都是粘贴比特币地址,所以出错的可能性就更小了。Checksum也不是100%保证能够查出错误地址的,有人计算过,手工输入比特币地址能逃过检查的概率为三十二万分之一。
比特币地址检查代码为了更好的理解这一过程,下面提供一个用python写的比特币地址的检查程序。


from hashlib import sha256
 
digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
 
def decode_base58(bc, length):
    n = 0
    for char in bc:
        n = n * 58 + digits58.index(char)
    return n.to_bytes(length, 'big')
 
def check_bc(bc):
    bcbytes = decode_base58(bc, 25)
    return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]
 
if __name__ == '__main__':
    bc = '1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i'
    assert check_bc(bc)
    assert not check_bc( bc.replace('N', 'P', 1) )
    assert check_bc('1111111111111111111114oLvT2')
    assert check_bc("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j")

0 0