Blog
Blockchain: Almacenando transacciones en bloques
- Publicado por: Hebert
- Categoría: Blog
Un bloque consta de un número variable de transacciones en un blockchain, pero para en nuestro caso para simplificar todo esto lo haremos suponiendo que el bloque consta de un número fijo de transacciones y para este caso lo haremos con 3 transacciones. Como el bloque necesita almacenar la lista de estas tres transacciones, declararemos una variable global de instancia que se llamará transacciones_verificadas
de la siguiente manera:
self.transacciones_verificadas = []
Hemos llamado esta variable de esta forma para indicar que solo las transacciones que estén verificadas sean añadidas al bloque, cada bloque también esperará el valor del hash del bloque anterior para que la cadena de bloques pueda volverse inmutable y para almacenar el hash del bloque anterior tenemos que crear una variable de instancia de la siguiente manera:
self.hash_bloque_anterior = ""
Finalmente, debemos declarar una variable más, a esta la llamaremos nonce
para poder almacenar el nonce creado por el minero durante el proceso de minado, un nonce es un número arbitrario que se puede usar solo una vez en una comunicación criptográfica:
self.Nonce = ""
La definición completa de nuesta clase Bloque es la siguiente:
class Bloque(): def __init__(self): self.transacciones_verificadas = [] self.hash_bloque_anterior = "" self.Nonce = ""
Como cada bloque necesita el valor del hash del bloque anterior, debemos declarar una variable global a la que llamaremos hash_ultimo_bloque
, esta variable la podemos declarar debajo de nuestra otra variable global transacciones_en_cola
.
hash_ultimo_bloque = ""
Ahora, vamos a proceder a crear nuestro primer bloque en nuestro blockchain al primer bloque de una cadena de bloques se le llama bloque génesis (genesis block), entonces nosotros vamos a proceder a crearlo y para esto necesitaremos asumir lo siguiente; un cliente envía 350 Unipy a un cliente conocido, para esto voy a instanciar un nuevo cliente:
Daniela = Cliente() t0 = Transaccion( "Genesis", Daniela.identity, 350.0 )
Ahora, creamos la instancia del bloque:
bloque0 = Bloque()
Ahora debemos llamar al méto hash_bloque_anterior
y crear una variable None e igualar ambos a None, esto se hace porque es la primera transacción que será almacenada en nuestra cadena de bloques:
bloque0.hash_bloque_anterior = None Nonce = None
Ahora debemos agregar el bloque a las transacciones verificadas, recordemos que estas transacciones se deben guardar en la variable de instancia transacciones_verificadas
luego de agregar el bloque en nuestra variable de instancia, sabemos que la red blockchain requiere el hash del bloque anterior siempre, para este caso por ser la primera transacción no aplica el hash del bloque anterior pero a partir de este bloque si que cuenta y es por ello que debemos guardar el hash de este bloque para que los bloques que siguen a partir de acá lo puedan usar, este hash lo guardaremos en una variable llamada digest
y por último esta misma variable guardarla en la variable global que creamos, la variable hash_ultimo_bloque
:
bloque0.transacciones_verificadas.append(t0) digest = hash(bloque0) hash_ultimo_bloque = digest
Una cadena de bloques contiene una lista de bloques encadenados entre sí. Para almacenar la lista completa, lo haremos creando una variable global llamada Unipy que es el nombre que le dimos a nuestra criptomoneda:
Unipy = []
Ahora debemos crear una función que nos ayude a registrar el contenido del bloque entrante en nuestra red blockchain a esta función la llamaremos registrar_bloque
:
def registrar_bloque(Unipy): print("Número de bloques en la cadena: " + str(len(Unipy))) for i in range(len(Unipy)): bloque_temporal = Unipy[i] print("Bloque número " + str(i)) for transaccion in bloque_temporal.transacciones_verificadas: mostrar_transacciones_en_cola(transaccion) print('--------------') print('=====================================')
Tenga en cuenta que a medida que pasa el tiempo, el número de bloques en nuestro blockchain sería extraordinariamente alto como para imprimirlos por pantalla. Por lo tanto, cuando imprimimos el contenido de la cadena de bloques, debemos decidir sobre el rango que nos gustaría examinar. En el siguiente código, vamos a imprimir toda la cadena de bloques, ya que obviamente no estamos agregando demasiados bloques en este pequeño script que tiene como finalidad mostrar las funciones básicas de como funciona la red blockchain. Para iterar a través de la cadena, configuramos un bucle for donde cada bloque referenciado se copia en una variable temporal llamada bloque_temporal
.
Luego imprimimos por pantalla el número de bloque como un encabezado para cada bloque. Debemos tener en cuenta que los números comenzarían con cero, el primer bloque es el bloque génesis el cual está enumerado con cero.
Ahora debemos agregar el bloque que se ha creado a la lista que hemos creado en la variable global Unipy
y luego registrar dicha lista con la función que creamos anteriormente:
Unipy.append(bloque0) registrar_bloque(Unipy)
Hasta ahora nuestro script luce de la siguiente manera:
transacciones_en_cola = [] hash_ultimo_bloque = "" Unipy = [] class Cliente(): def __init__(self): random = Crypto.Random.new().read self._clave_privada = RSA.generate(1024, random) self._clave_publica = self._clave_privada.publickey() self._signer = PKCS1_v1_5.new(self._clave_privada) @property def identidad(self): return binascii.hexlify(self._clave_publica.exportKey(format='DER')).decode('ascii') class Transaccion(): def __init__(self, cliente_envia, cliente_recibe, importe): self.cliente_envia = cliente_envia self.cliente_recibe = cliente_recibe self.importe = importe self.fecha = datetime.datetime.now() def diccionario(self): if self.cliente_envia == "Genesis": identidad = "Genesis" else: identidad = self.cliente_envia.identidad return collections.OrderedDict({'cliente_envia': identidad, 'cliente_recibe': self.cliente_recibe, 'importe': self.importe, 'fecha': self.fecha}) def firmar_transaccion(self): clave_privada = self.cliente_envia._clave_privada firma = PKCS1_v1_5.new(clave_privada) h = SHA.new(str(self.diccionario()).encode('utf8')) return binascii.hexlify(firma.sign(h)).decode('ascii') class Bloque(): def __init__(self): self.transacciones_verificadas = [] self.hash_bloque_anterior = "" self.Nonce = "" def mostrar_transacciones_en_cola(transacciones_en_cola): # for transaction in transacciones_en_cola: dict = transacciones_en_cola.diccionario() print("Cliente que envia: " + dict['cliente_envia']) print('-----') print("Cliente que recibe: " + dict['cliente_recibe']) print('-----') print("Importe: " + str(dict['importe'])) print('-----') print("Fecha: " + str(dict['fecha'])) print('-----') def registrar_bloque(Unipy): print("Número de bloques en la cadena: " + str(len(Unipy))) for i in range(len(Unipy)): bloque_temporal = Unipy[i] print("Bloque número " + str(i)) for transaccion in bloque_temporal.transacciones_verificadas: mostrar_transacciones_en_cola(transaccion) print('--------------') print('=====================================') Daniela = Cliente() t0 = Transaccion( "Genesis", Daniela.identidad, 350.0 ) bloque0 = Bloque() bloque0.hash_bloque_anterior = None Nonce = None bloque0.transacciones_verificadas.append(t0) digest = hash(bloque0) hash_ultimo_bloque = digest Unipy.append(bloque0) registrar_bloque(Unipy) """ Juan = Cliente() Jose = Cliente() Luis = Cliente() Miguel = Cliente() t1 = Transaccion( Juan, Jose.identidad, 15.0 ) t1.firmar_transaccion() transacciones_en_cola.append(t1) t2 = Transaccion( Luis, Miguel.identidad, 6.0 ) t2.firmar_transaccion() transacciones_en_cola.append(t2) t3 = Transaccion( Miguel, Juan.identidad, 2.0 ) t3.firmar_transaccion() transacciones_en_cola.append(t3) t4 = Transaccion( Miguel, Jose.identidad, 4.0 ) t4.firmar_transaccion() transacciones_en_cola.append(t4) t5 = Transaccion( Juan, Miguel.identidad, 7.0 ) t5.firmar_transaccion() transacciones_en_cola.append(t5) t6 = Transaccion( Miguel, Luis.identidad, 100.0 ) t6.firmar_transaccion() transacciones_en_cola.append(t6) t7 = Transaccion( Jose, Miguel.identidad, 23.0 ) t7.firmar_transaccion() transacciones_en_cola.append(t7) t8 = Transaccion( Luis, Juan.identidad, 65.0 ) t8.firmar_transaccion() transacciones_en_cola.append(t8) t9 = Transaccion( Jose, Juan.identidad, 324.0 ) t9.firmar_transaccion() transacciones_en_cola.append(t9) for transaccion in transacciones_en_cola: mostrar_transacciones_en_cola(transaccion) print('--------------') """
Fijate que he comentado las transacciones anteriores, las he comentado y no las he borrado porque haremos uso de ellas más adelante, en este punto si ejecutamos este código deberíamos de obtener lo siguiente:
λ python blockhain.py Número de bloques en la cadena: 1 Bloque número 0 Cliente que envia: Genesis ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100c158ff833675dfc619c1b10d564a2f1e6d286af7b0477a17608f9e652ccd1f4995222eed94deddb91df1453166a0c429a1302ee4a51888af977f86dc1e777321c899d261d7620238aa3c1f2acd990dabad1134dc2e3ab5e7718d3f97d8bce18aef43b7cfd02a63d735dcbd308d623e588e9b7ccb05ae5317a8446122c760a4970203010001 ----- Importe: 350.0 ----- Fecha: 2020-03-26 13:31:53.809073 ----- -------------- =====================================
En este punto, el sistema blockchain está listo para usar. Ahora habilitaremos a los clientes que estén interesados en ser mineros, para que puedan convertirse en mineros proporcionándoles una funcionalidad de minería.
Para realizar esto debemos programar una función que nos permita realizar dicha minería, la funcionalidad minera necesita recibir dos argumentos el mensaje y la dificultad, el mensaje es un resumen del trabajo dado encriptado bajo sha256 la dificultad por defecto será 1 pero también podría ser mayor a este.
Antes de construir la función para minar, debemos construir la función que encriptará el mensaje bajo sha256 y a esta función la llamaremos sha256
:
def sha256(mensaje): return hashlib.sha256(mensaje.encode('ascii')).hexdigest()
Ahora desarrollaremos la función para minar que implementará nuestra propia estrategia de minería. Nuestra estrategia en este caso sería generar un hash con el mensaje que recibe la función y si se especifica un nivel de dificultad de 2, el hash generado en un mensaje dado debería comenzar con dos numero 1, como 11xxxxxxxx. Si el nivel de dificultad es 3, el hash generado debería comenzar con tres numero 1, como 111xxxxxxxx. Dados estos requisitos, ahora desarrollaremos nuestra función:
def minar(mensaje, dificultad=1): assert dificultad >= 1 prefijo = '1' * dificultad for i in range(1000): digest = sha256(str(hash(mensaje)) + str(i)) if digest.startswith(prefijo): print("Después de " + str(i) + " iteraciones se ha encontrado el nonce: " + digest) return digest
Analizando el código de la función el nivel de dificultad debe ser mayor o igual a 1, lo aseguramos con la declaración assert
y creamos una prefijo
usando el nivel de dificultad establecido, el código a partir de aquí entra en el bucle for en un rango de 1000 iteraciones, el bucle for se encargara de verificar si cada iteración tiene un prefijo establecido anteriormente y lo hace a través de if digest.startswith(prefijo)
si la condición no se cumple volverá a iterar en el bloque y si se cumple entraría a imprimir por pantalla la cantidad de iteraciones que se han realizado más el nonce encontrado y también lo retornará como valor.
Ahora solo resta probar la función minar
, vamos a llamarla y le pasamos un mensaje:
minar("mensaje de prueba", 2)
Si ejecutamos ahora nuestro código obtendríamos algo parecido a esto:
λ python blockchain.py Después de 66 iteraciones se ha encontrado el nonce: 11fec06ed573e9f43f78ca31bd11f0c028436c0f92fa971a2d8c97de3cfdc3c0
Ahora debemos agregar más bloques, cada minero recogerá las transacciones de un grupo de transacciones creado previamente y
para rastrear el número de mensajes ya extraídos, tenemos que crear una variable global a la que llamaremos indice_ultima_transaccion
:
indice_ultima_transaccion = 0
Es hora de agregar un nuevo bloque a nuestra red block chain, pero esta vez haciendo uso de la función minar
vamos a instanciar un nuevo bloque y con ayuda de un blucle for vamos a registrar 3 transacciones en dicho bloque:
bloque = Bloque() for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 bloque.hash_bloque_anterior = hash_ultimo_bloque bloque.Nonce = minar(bloque, 2) digest = hash(bloque) Unipy.append (bloque) hash_ultimo_bloque = digest
Antes de agregar la transacción al bloque, el minero debe verificar la validez de la transacción. La validez de la transacción se verifica probando la igualdad del hash proporcionado por el remitente con el hash generado por el minero utilizando la clave pública del remitente. También, el minero verificará que el remitente tenga saldo suficiente para pagar el monto de la transacción. Pero por brevedad, no hemos incluido esta funcionalidad en el script. Después de que la transacción es validada, la agregamos a la lista de transacciones_verificadas
en la instancia del bloque.
En este punto se agrega el hash del bloque anterior a la variable global hash_utlimo_bloque
, continua haciendo uso de la función minar
que recibe el bloque como mensaje y una nivel de dificultad de 2, se vuelve a obtener el digest del bloque y luego se registra el bloque en la variable global Unipy
y volvemos a registrar el hash del bloque en la variable hash_ultimo_bloque
.
Ahora voy a proceder a agregar más bloques:
# Bloque 2 for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 bloque.hash_bloque_anterior = hash_ultimo_bloque bloque.Nonce = minar(bloque, 2) digest = hash(bloque) Unipy.append (bloque) hash_ultimo_bloque = digest # Bloque 3 for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 dump_blockchain(Unipy)
Es importante volver a destacar que cada bloque contiene 3 transacciones, no confundir las transacciones con los bloques, ahora voy a proceder a desconmentar las transacciones y ejecutar el código, al ejecutarlo deberíamos de obtener lo siguiente:
λ python blockchain.py Después de 29 iteraciones se ha encontrado el nonce: 11a784be443ba1af232dc219ac7cc2cf64eabf563a922ea68f6929359bc87ba4 Después de 29 iteraciones se ha encontrado el nonce: 11a784be443ba1af232dc219ac7cc2cf64eabf563a922ea68f6929359bc87ba4 Después de 29 iteraciones se ha encontrado el nonce: 11a784be443ba1af232dc219ac7cc2cf64eabf563a922ea68f6929359bc87ba4 Número de bloques en la cadena: 3 Bloque número 0 Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 15.0 ----- Fecha: 2020-03-26 16:26:53.318397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 6.0 ----- Fecha: 2020-03-26 16:26:53.324397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 2.0 ----- Fecha: 2020-03-26 16:26:53.329400 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 4.0 ----- Fecha: 2020-03-26 16:26:53.332397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 7.0 ----- Fecha: 2020-03-26 16:26:53.336398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Importe: 100.0 ----- Fecha: 2020-03-26 16:26:53.340397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 23.0 ----- Fecha: 2020-03-26 16:26:53.344398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 65.0 ----- Fecha: 2020-03-26 16:26:53.348398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 324.0 ----- Fecha: 2020-03-26 16:26:53.352398 ----- -------------- ===================================== Bloque número 1 Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 15.0 ----- Fecha: 2020-03-26 16:26:53.318397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 6.0 ----- Fecha: 2020-03-26 16:26:53.324397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 2.0 ----- Fecha: 2020-03-26 16:26:53.329400 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 4.0 ----- Fecha: 2020-03-26 16:26:53.332397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 7.0 ----- Fecha: 2020-03-26 16:26:53.336398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Importe: 100.0 ----- Fecha: 2020-03-26 16:26:53.340397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 23.0 ----- Fecha: 2020-03-26 16:26:53.344398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 65.0 ----- Fecha: 2020-03-26 16:26:53.348398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 324.0 ----- Fecha: 2020-03-26 16:26:53.352398 ----- -------------- ===================================== Bloque número 2 Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 15.0 ----- Fecha: 2020-03-26 16:26:53.318397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 6.0 ----- Fecha: 2020-03-26 16:26:53.324397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 2.0 ----- Fecha: 2020-03-26 16:26:53.329400 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Importe: 4.0 ----- Fecha: 2020-03-26 16:26:53.332397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 7.0 ----- Fecha: 2020-03-26 16:26:53.336398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Importe: 100.0 ----- Fecha: 2020-03-26 16:26:53.340397 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f273c7ed42d533f99979824848e76cb9eccc3f836d3af3243a0e5602b835175690d1db38b467cf803e0b1f735e30c7911c660fe5731080459076de47eb9ee726f81fbded40925f3e2bc9b44f64a66b3fd7cb898cdceaa893972416b293f19213f907c56d6300ff14b4c99ded1bd3829f148d17f9c0dae2fd7c1ada68380249f50203010001 ----- Importe: 23.0 ----- Fecha: 2020-03-26 16:26:53.344398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d003081890281810093e9faf72010bbec888ccff7cd3f724e6f01355efd079a71fb0d45e1a5d69d3508de2f1b60223646634fdcd21ca741ea0b404430244cd4edd5ad068e1d68810a14b019b384459cfcf4e134f97db9befb6970d2d7532b1b00985d6321148967d61bb4e4d3503d9d26153a6b09e6cfce4dd5e22b0f1ef34f8bee4fa2e5add4f8e10203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 65.0 ----- Fecha: 2020-03-26 16:26:53.348398 ----- -------------- ===================================== Cliente que envia: 30819f300d06092a864886f70d010101050003818d0030818902818100bdc143c9185818ec19a22feaf98829e44c379918e276edb612a6277afc5b1ed13c8c4ebfc86df24b2893aeaad19a184a87f72d0878a3fa71063627aa5b9f4a4dc4446c58b129eda710693ac305a417193682d848f1edeb35bb0d30bf439bab2ec21d5ee71369ef888c52ba0540796b49b54528d945254f6fbef8f112349592350203010001 ----- Cliente que recibe: 30819f300d06092a864886f70d010101050003818d0030818902818100f319391d72ed5d5db2b981e8c13c35699b820ed71e7eae206cab36c464f78dedb2b92704a9ea251573fc32e5ab7eb2520997a547544d19f68670fec7b018d03cf35b3cc05d73f0ff08ad2f06a1273ee7cacc58edd4ab1c770019ab36dff5ec081c844e880ee890bb0b335a91bf1b3b560e600fc63c302f6f91a98ee59d601bd90203010001 ----- Importe: 324.0 ----- Fecha: 2020-03-26 16:26:53.352398 ----- -------------- =====================================
Primero nos muestra el Nonce de cada bloque y luego nos muestra cada una de las 3 transacciones por bloque. Esta es la manera en como funciona la red blockchain, si que aún faltan muchas otras funciones. Pero es importante entender su principal función que es esta que exponemos mediante este script, teniendo en cuenta como programar una pequeña red blockchain en python; en las próximas lecciones del curso estaremos construyendo una API haciendo uso del blockchain para proteger datos de texto y para poder leerlos tenemos que realizar el común proceso de minar.
Con esto construiremos una pequeña aplicación que nos permita proteger los datos de texto gracias al blockchain.
El código final de este script es el siguiente:
import hashlib import random import binascii import datetime import collections import Crypto import Crypto.Random from Crypto.Hash import SHA from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 transacciones_en_cola = [] hash_ultimo_bloque = "" Unipy = [] indice_ultima_transaccion = 0 class Cliente(): def __init__(self): random = Crypto.Random.new().read self._clave_privada = RSA.generate(1024, random) self._clave_publica = self._clave_privada.publickey() self._signer = PKCS1_v1_5.new(self._clave_privada) @property def identidad(self): return binascii.hexlify(self._clave_publica.exportKey(format='DER')).decode('ascii') class Transaccion(): def __init__(self, cliente_envia, cliente_recibe, importe): self.cliente_envia = cliente_envia self.cliente_recibe = cliente_recibe self.importe = importe self.fecha = datetime.datetime.now() def diccionario(self): if self.cliente_envia == "Genesis": identidad = "Genesis" else: identidad = self.cliente_envia.identidad return collections.OrderedDict({'cliente_envia': identidad, 'cliente_recibe': self.cliente_recibe, 'importe': self.importe, 'fecha': self.fecha}) def firmar_transaccion(self): clave_privada = self.cliente_envia._clave_privada firma = PKCS1_v1_5.new(clave_privada) h = SHA.new(str(self.diccionario()).encode('utf8')) return binascii.hexlify(firma.sign(h)).decode('ascii') class Bloque(): def __init__(self): self.transacciones_verificadas = [] self.hash_bloque_anterior = "" self.Nonce = "" def mostrar_transacciones_en_cola(transacciones_en_cola): # for transaction in transacciones_en_cola: dict = transacciones_en_cola.diccionario() print("Cliente que envia: " + dict['cliente_envia']) print('-----') print("Cliente que recibe: " + dict['cliente_recibe']) print('-----') print("Importe: " + str(dict['importe'])) print('-----') print("Fecha: " + str(dict['fecha'])) print('-----') def registrar_bloque(Unipy): print("Número de bloques en la cadena: " + str(len(Unipy))) for i in range(len(Unipy)): bloque_temporal = Unipy[i] print("Bloque número " + str(i)) for transaccion in bloque_temporal.transacciones_verificadas: mostrar_transacciones_en_cola(transaccion) print('--------------') print('=====================================') def sha256(mensaje): return hashlib.sha256(mensaje.encode('ascii')).hexdigest() def minar(mensaje, dificultad=1): assert dificultad >= 1 prefijo = '1' * dificultad for i in range(1000): digest = sha256(str(hash(mensaje)) + str(i)) if digest.startswith(prefijo): print("Después de " + str(i) + " iteraciones se ha encontrado el nonce: " + digest) return digest """ Daniela = Cliente() t0 = Transaccion( "Genesis", Daniela.identidad, 350.0 ) bloque0 = Bloque() bloque0.digest_anterior = None Nonce = None bloque0.transacciones_verificadas.append(t0) digest = hash(bloque0) hash_ultimo_bloque = digest Unipy.append(bloque0) registrar_bloque(Unipy) minar("mensaje de prueba", 2) """ Juan = Cliente() Jose = Cliente() Luis = Cliente() Miguel = Cliente() t1 = Transaccion( Juan, Jose.identidad, 15.0 ) t1.firmar_transaccion() transacciones_en_cola.append(t1) t2 = Transaccion( Luis, Miguel.identidad, 6.0 ) t2.firmar_transaccion() transacciones_en_cola.append(t2) t3 = Transaccion( Miguel, Juan.identidad, 2.0 ) t3.firmar_transaccion() transacciones_en_cola.append(t3) t4 = Transaccion( Miguel, Jose.identidad, 4.0 ) t4.firmar_transaccion() transacciones_en_cola.append(t4) t5 = Transaccion( Juan, Miguel.identidad, 7.0 ) t5.firmar_transaccion() transacciones_en_cola.append(t5) t6 = Transaccion( Miguel, Luis.identidad, 100.0 ) t6.firmar_transaccion() transacciones_en_cola.append(t6) t7 = Transaccion( Jose, Miguel.identidad, 23.0 ) t7.firmar_transaccion() transacciones_en_cola.append(t7) t8 = Transaccion( Luis, Juan.identidad, 65.0 ) t8.firmar_transaccion() transacciones_en_cola.append(t8) t9 = Transaccion( Jose, Juan.identidad, 324.0 ) t9.firmar_transaccion() transacciones_en_cola.append(t9) bloque = Bloque() for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 bloque.hash_bloque_anterior = hash_ultimo_bloque bloque.Nonce = minar(bloque, 2) digest = hash(bloque) Unipy.append(bloque) hash_ultimo_bloque = digest # Bloque 2 for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 bloque.hash_bloque_anterior = hash_ultimo_bloque bloque.Nonce = minar(bloque, 2) digest = hash(bloque) Unipy.append(bloque) hash_ultimo_bloque = digest # Bloque 3 for i in range(3): transaccion_temporal = transacciones_en_cola[indice_ultima_transaccion] # validamos la transacción # si es válida, es decir se encuentra en las transacciones en cola bloque.transacciones_verificadas.append(transaccion_temporal) indice_ultima_transaccion += 1 bloque.hash_bloque_anterior = hash_ultimo_bloque bloque.Nonce = minar(bloque, 2) digest = hash(bloque) Unipy.append(bloque) hash_ultimo_bloque = digest registrar_bloque(Unipy)
➡ ¡Enhorabuena! Continúa aprendiendo con nuestro Curso de Blockchain: