Blockchain Python - classe de transação

Neste capítulo, vamos criar um Transactionclasse para que um cliente possa enviar dinheiro para alguém. Observe que um cliente pode ser remetente ou destinatário do dinheiro. Quando você deseja receber dinheiro, algum outro remetente irá criar uma transação e especificar o seupublicendereço nele. Definimos a inicialização de uma classe de transação da seguinte forma -

def __init__(self, sender, recipient, value):
   self.sender = sender
   self.recipient = recipient
   self.value = value
   self.time = datetime.datetime.now()

o init método leva três parâmetros - o do remetente public chave, do destinatário publicchave, e o valor a ser enviado. Eles são armazenados nas variáveis ​​de instância para uso por outros métodos. Além disso, criamos mais uma variável para armazenar o tempo da transação.

Em seguida, escrevemos um método utilitário chamado to_dictque combina todas as quatro variáveis ​​de instância mencionadas acima em um objeto de dicionário. Isso é apenas para colocar todas as informações da transação acessíveis por meio de uma única variável.

Como você sabe do tutorial anterior, que o primeiro bloco no blockchain é um Genesisquadra. O bloco Genesis contém a primeira transação iniciada pelo criador do blockchain. A identidade dessa pessoa pode ser mantida em segredo, como no caso dos Bitcoins. Então, quando esta primeira transação é criada, o criador pode apenas enviar sua identidade comoGenesis. Assim, ao criar o dicionário, verificamos se o remetente éGenesise se for assim, simplesmente atribuímos algum valor de string à variável de identidade; caso contrário, atribuímos a identidade do remetente aoidentity variável.

if self.sender == "Genesis":
   identity = "Genesis"
else:
   identity = self.sender.identity

Construímos o dicionário usando a seguinte linha de código

return collections.OrderedDict({
   'sender': identity,
   'recipient': self.recipient,
   'value': self.value,
   'time' : self.time})

Todo o código para o to_dict método é mostrado abaixo -

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})

Finalmente, assinaremos este objeto de dicionário usando a chave privada do remetente. Como antes, usamos a PKI embutida com algoritmo SHA. A assinatura gerada é decodificada para obter a representação ASCII para impressão e armazenamento em nosso blockchain. osign_transaction o código do método é mostrado aqui -

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')

Agora vamos testar isso Transaction classe.

Teste de classe de transação

Para tanto, iremos criar dois usuários, chamados Dinesh e Ramesh. Dinesh enviará 5 TPCoins para Ramesh. Para isso, primeiro criamos os clientes chamados Dinesh e Ramesh.

Dinesh = Client()
Ramesh = Client()

Lembre-se de que quando você instancia um Client classe, o public andchaves privadas exclusivas para o cliente seriam criadas. Como Dinesh está enviando o pagamento para Ramesh, ele precisará da chave pública de Ramesh, que é obtida usando a propriedade de identidade do cliente.

Assim, vamos criar a instância da transação usando o seguinte código -

t = Transaction(
   Dinesh,
   Ramesh.identity,
   5.0
)

Observe que o primeiro parâmetro é o remetente, o segundo parâmetro é a chave pública do destinatário e o terceiro parâmetro é a quantidade a ser transferida. osign_transaction método recupera a chave privada do remetente do primeiro parâmetro para cantar a transação.

Depois que o objeto de transação for criado, você o assinará chamando seu sign_transactionmétodo. Este método retorna a assinatura gerada no formato para impressão. Geramos e imprimimos a assinatura usando as duas linhas de código a seguir -

signature = t.sign_transaction()
print (signature)

Ao executar o código acima, você verá uma saída semelhante a esta -

7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972

Agora que nossa infraestrutura básica de criação de um cliente e uma transação está pronta, agora teremos vários clientes fazendo várias transações como em uma situação da vida real.