我发现区块链迷人,因为它将开源软件开发扩展到开源+状态。这似乎是计算范式的真正/令人兴奋的创新;我们不仅仅是分享代码,我们可以分享一个正在运行的计算机,任何人随时随地都可以以打开和权限的方式使用它。这场革命的种子可以使用比特币开始,所以我变得好奇,详细介绍了它,以便直观地了解它的工作原理。本着“我无法创造的东西我不明白的精神”,这比从头开始实现这一点更好的方法?
我们将在纯Python中创建,数字签名和广播比特币事务,从头开始,依赖于零依赖性。在此过程中,我们将学习比特币代表价值的一点。我们去取得它。
(BTW如果此帖子的视觉格式烦恼您,请参阅jupyter笔记本版本,具有相同的内容)。
首先,我们希望生成一个全新的加密身份,这只是私人公共键馆。比特币使用椭圆曲线加密而不是更常见的东西,如RSA来保护事务。在这里,我不会完整介绍ECC,因为其他人已经做了明显更好的工作,例如更好的工作。我发现Andrea Corbellini的博客文章系列是一个特殊的资源。在这里,我们只是写代码,但要理解为什么它有效地工作,您需要通过该系列。
好吧,所以比特币使用secp256k1曲线。作为一个新手,我发现这部分令人着迷 - 有些不同的曲线图书馆您可以选择提供不同的专业人员和缺点和属性。 NIST发布了有关哪些使用的建议,但人们更喜欢使用不太可能在其内置后门的其他曲线(如SECP256K1)。无论如何,椭圆曲线是一个相当低的数学数学对象,只需3个整数来定义:
来自__future__导入注释#pep 563:推迟评估dataclasses导入dataclass#https://docs.python.org/3/library/dataclasses.html我喜欢这些很多@ dataclass类曲线:"&# 34;"椭圆曲线在整数模型的整数领域。曲线上的点满足Y ^ 2 = x ^ 3 + a * x + b(mod p)。 """ p:int#的有限字段的主要模量a:int b:int#secp256k1使用a = 0,b = 7,所以我们'重新处理曲线Y ^ 2 = x ^ 3 + 7(mod p (P = 0x = 0x000000600/6000000/7800300c600c600c600c600ca,#a = 0 b = 0x000000600/380000c0000c0000c0000c0000c0000c0000c0000c0000c000000ca,#a = 0 b = 0x00000000c0000c0000c0000c0000c0000c0000c000000c600c600ca,#a = 0 b = 0x0000000000/3000000ca,#a = 0 b = 0x00000000000000/3000000capp = 7)
除了实际曲线之外,我们除了曲线周期上的一个固定的“起点”,它还可以定义一个发电机点,这些曲线上的一些固定的“起始点”用于在曲线周围启动“随机行走”。发电机是公开的,并同意持续:
@ dataclass类点:"""曲线上的整数点(x,y)"""曲线:曲线X:INT Y:INT G =点(bitcoin_curve,X = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,Y = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)#我们可以验证该发电机点的确是曲线,即,Y 1 2 = X ^ 3 + 7(MOD p)打印("发电机在曲线上:"(g。y ** 2 - g.x ** 3 - 7)%bitcoin_curve。p == 0)#一些其他完全随机的点当然不会在曲线上,_MOST_可能会随机进口。种子(1337)x =随机。 RandRange(0,比特币_Curve。P)Y =随机。 RandRange(0,比特币_Curve。P)打印("完全随机点不是:"(y ** 2 - x ** 3 - 7)%比特币_curve。p == 0)
最后,已知生成点G的顺序,并且有效地是我们在曲线周围的周期上的(x,y)整数元组方面使用的“设置的大小”。我喜欢将此信息组织成一个更多的数据结构,我会调用生成器:
@ dataclass类生成器:"""曲线上的发电机:初始点和(预计)秩序""" g:点#曲线上的发电点n:int#发电点的顺序,所以0 * g = n * g = inf bitcoin_gen =生成器(g = g,#g的顺序是已知的并且可以在数学上派生N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBAAEDCE6AF48A03BBFD25E8CD0364141
请注意,到目前为止,我们还没有完成任何事情,这一切都只是对某些数据结构的定义,并用与比特币中使用的椭圆曲线相关的公知常数填充它们。这即将改变,因为我们已准备好生成我们的私钥。私钥(或“秘密密钥”如我所说的)即将到来)只是满足1< = key<的随机整数。 n(召回n是g的顺序):
#secret_key = random.randrange(1,bitcoin_gen.nn)#这是_would_ do secret_key = int的方式。 from_bytes(B' Andrej很酷:P',' Big')#这是我将如何为再现性assert 1< secret_key<比特币_gen。 n打印(secret_key)
这是我们的秘密密钥 - 它是一个非常突出的整数,但任何知道它可以控制与它相关的比特币区块链中拥有的所有资金。在最简单的,最常见的vanilla用例的比特币是控制您帐户的单个“密码”。当然,在我上面的一些其他Andrej手动生成了他们的秘密密钥的情况下,与这个秘密密钥相关的钱包很可能是零比特币的平衡:)。如果它没有,我们确实非常幸运。
我们现在要生成公钥,这是事情开始变得有趣的地方。公钥是曲线上的点,从添加发电机点到自身的秘密时间。即,我们有:public_key = g + g + g +(秘密键时)+ g = secret_key * G.请注意,这里的'+'(添加)和'*'(次)符号都非常特别,略微混淆。秘密密钥是一个整数,但是发电机点G是一个(x,y)元组,它是曲线上的点,导致(x,y)元组公钥,再次曲线上的一个点。这是我们必须在椭圆曲线上实际定义加法运算符的地方。它具有一个非常具体的定义和几何解释(见上面的Andrea的发布),但实际实现相对简单:
Warning: Can only detect less than 5000 characters
Warning: Can only detect less than 5000 characters