Python Blockchain 简明教程
Python Blockchain - Transaction Class
在本章中,让我们创建一个 Transaction 类,以便客户端能够向某人汇款。请注意,客户端既可以是发件人,也可以是收件人。当您希望收款时,其他发件人将创建一个交易并在其内指定您的 public 地址。我们定义一个交易类的初始化如下 −
def __init__(self, sender, recipient, value):
self.sender = sender
self.recipient = recipient
self.value = value
self.time = datetime.datetime.now()
init 方法采用三个参数 − 发件人的 public 密钥,收件人的 public 密钥以及要发送的金额。这些存储在实例变量中以供其他方法使用。此外,我们还创建了一个用于存储交易时间的变量。
接下来,我们编写一个名为 to_dict 的实用程序方法,该方法将上述四个实例变量组合在一个字典对象中。这仅仅是为了将整个交易信息放在一个变量中访问。
您从前面的教程中知道,区块链中的第一个块是 Genesis 块。Genesis 块包含区块链创建者发起的第一次交易。此人的身份可能像比特币的情况一样保密。因此,当创建第一次交易时,创建者可能会将他的身份发送为 Genesis 。因此,在创建字典时,我们会检查发件人是否为 Genesis ,如果为真,则我们只为身份变量分配某个字符串值;否则,我们将发件人的身份分配给 identity 变量。
if self.sender == "Genesis":
identity = "Genesis"
else:
identity = self.sender.identity
我们使用以下代码行构建字典
return collections.OrderedDict({
'sender': identity,
'recipient': self.recipient,
'value': self.value,
'time' : self.time})
完整 to_dict 方法的代码如下 −
def to_dict(self):
if self.sender == "Genesis":
identity = "Genesis"
else:
identity = self.sender.identity
return collections.OrderedDict({
'sender': identity,
'recipient': self.recipient,
'value': self.value,
'time' : self.time})
最后,我们将使用发件人的私钥对这个字典对象签名。和以前一样,我们使用内置的具有 SHA 算法的 PKI。生成的签名被解码以得到 ASCII 表示以供打印并将其存储到我们的区块链中。 sign_transaction 方法代码显示如下 −
def sign_transaction(self):
private_key = self.sender._private_key
signer = PKCS1_v1_5.new(private_key)
h = SHA.new(str(self.to_dict()).encode('utf8'))
return binascii.hexlify(signer.sign(h)).decode('ascii')
我们现在将测试这个 Transaction 类。
Testing Transaction Class
为此,我们将创建两个用户,称为 Dinesh 和 Ramesh 。Dinesh 将向 Ramesh 发送 5 TPCoin。为此,我们首先创建名为 Dinesh 和 Ramesh 的客户端。
Dinesh = Client()
Ramesh = Client()
请记住,当您实例化 Client 类时,将创建客户端唯一的 public and 私钥。由于 Dinesh 要向 Ramesh 发送付款,因此他将需要使用客户端的身份属性获取 Ramesh 的公钥。
因此,我们将使用以下代码创建交易实例 −
t = Transaction(
Dinesh,
Ramesh.identity,
5.0
)
请注意,第一个参数是发件人,第二个参数是收件人的公钥,第三个参数是要转账的金额。 sign_transaction 方法从第一个参数中检索发件人的私钥以签署交易。
交易对象创建后,您将通过调用其 sign_transaction 方法对其进行签名。此方法以可打印的格式返回生成的签名。我们使用以下两行代码生成并打印签名 −
signature = t.sign_transaction()
print (signature)
当您运行上述代码时,您将看到类似于此的输出 −
7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972
现在,由于我们创建客户端和交易的基本基础设施已经就绪,我们现在将像现实生活中一样执行多个客户端和多个交易。