In this chapter, let us create a Transaction class so that a client will be able to send money to somebody. Note that a client can be both a sender or a recipient of the money. When you want to receive money, some other sender will create a transaction and specify your public address in it. We define the initialization of a transaction class as follows −
def __init__(self, sender, recipient, value): self.sender = sender self.recipient = recipient self.value = value self.time = datetime.datetime.now()
The init method takes three parameters − the sender’s public key, the recipient’s public key, and the amount to be sent. These are stored in the instance variables for use by other methods. Additionally, we create one more variable for storing the time of transaction.
Next, we write a utility method called to_dict that combines all the four above-mentioned instance variables in a dictionary object. This is just to put the entire transaction information accessible through a single variable.
As you know from the earlier tutorial that the first block in the blockchain is a Genesis block. The Genesis block contains the first transaction initiated by the creator of the blockchain. The identity of this person may be kept a secret like in the case of Bitcoins. So when this first transaction is created, the creator may just send his identity as Genesis. Thus, while creating the dictionary, we check if the sender is Genesis and if so we simply assign some string value to the identity variable; else, we assign the sender’s identity to the identity variable.
if self.sender == "Genesis": identity = "Genesis" else: identity = self.sender.identity
We construct the dictionary using following line of code
return collections.OrderedDict({ 'sender': identity, 'recipient': self.recipient, 'value': self.value, 'time' : self.time})
The entire code for the to_dict method is shown below −
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})
Finally, we will sign this dictionary object using the private key of the sender. As before, we use the built-in PKI with SHA algorithm. The generated signature is decoded to get the ASCII representation for printing and storing it in our blockchain. The sign_transaction method code is shown here −
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')
We will now test this Transaction class.
For this purpose, we will create two users, called Dinesh and Ramesh. Dinesh will send 5 TPCoins to Ramesh. For this first we create the clients called Dinesh and Ramesh.
Dinesh = Client() Ramesh = Client()
Remember that when you instantiate a Client class, the public and private keys unique to the client would be created. As Dinesh is sending payment to Ramesh, he will need the public key of Ramesh which is obtained by using the identity property of the client.
Thus, we will create the transaction instance using following code −
t = Transaction( Dinesh, Ramesh.identity, 5.0 )
Note that the first parameter is the sender, the second parameter is the public key of the recipient and the third parameter is the amount to be transferred. The sign_transaction method retrieves the sender’s private key from the first parameter for singing the transaction.
After the transaction object is created, you will sign it by calling its sign_transaction method. This method returns the generated signature in the printable format. We generate and print the signature using following two lines of code −
signature = t.sign_transaction() print (signature)
When you run the above code, you will see the output similar to this −
7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7 13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0 0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5 c6363dc511222fb2416036ac04eb972
Now as our basic infrastructure of creating a client and a transaction is ready, we will now have multiple clients doing multiple transactions as in a real life situation.