En la entrada anterior se ha introducido el concepto de prueba de esfuerzo. Para que un usuario pueda agregar un nuevo bloque a la cadena este ha de resolver un problema, lo que se conoce como minado. De este modo, la dificultad de minado se puede utilizar para fijar el tiempo promedio entre bloques.
El tiempo medio necesario para añadir un nuevo bloque a la cadena de bloques es el que se tarda en resolver la prueba de esfuerzo. De este modo, si aumenta la potencia de cálculo se reduce el tiempo, mientras que si se reduce aumentara el tiempo entre bloques. Generalmente interesa que el tiempo entre bloques sea constante. Para conseguir esto, simplemente se ha de medir el entre bloques e ir ajustando la dificultad de minado según sea menor o mayor de lo deseado.
En la cadena de bloques se han de incluir dos nuevas propiedades para poder gestionar el tiempo que se desde que transcurran entre la inclusión de dos bloques. La primera es el tiempo deseado (block_interval) y la segunda es cada cúantos bloques se reevaluará la dificultad de la prueba de esfuerzo (difficulty_interval).
Para la tarea de agregar un nuevo bloque a la cadena de bloques y gestionar el intervalo entre bloques se creará el método next_block. Este método se le introducirán los datos, se evaluará la dificultad actualizándola cuando sea necesario, se minará el bloque y se agregara a la cadena. Será necesario comprobar también que la fecha del nuevo bloque es posterior a la del ultimo existente en la cadena de bloques. Este proceso se puede ver en el siguiente código:
class BlockChain:
def __init__(self, block):
self.block_interval = 120
self.difficulty_interval = 2
self.chain = [block]
def add_block(self, block):
self.chain.append(block)
def next_block(self, data, timestamp, mining = True):
if self.chain[-1].timestamp > timestamp:
return
difficulty = self.chain[-1].difficulty
if len(self.chain) > self.difficulty_interval and len(self.chain) % self.difficulty_interval == 0:
interval = self.chain[-1].timestamp - self.chain[-self.difficulty_interval-1].timestamp
interval = interval.total_seconds() / self.difficulty_interval
if interval > self.block_interval:
difficulty = difficulty - 1
elif interval < self.block_interval:
difficulty = difficulty + 1
block = Block(self.chain[-1].index + 1, data, self.chain[-1].hash, timestamp, difficulty)
if mining:
block.mining()
self.add_block(block)
def is_valid(self):
if self.chain:
for step in range(len(self.chain) - 1, 0, -1):
if not self.chain[step].is_valid():
return False
elif self.chain[step].previous_hash != self.chain[step - 1].hash:
return False
elif self.chain[step].index != self.chain[step - 1].index + 1:
return False
return True
return False Para poder probar el código con facilidad se ha utilizado valores bajos para la frecuencia y el tiempo entre evaluaciones. Concretamente se ha indicado que el intervalo promedio en el que se desea que se añada un bloque es de 120 segundos (block_interval = 120) y que la evaluación se realizará cada 2 bloques (difficulty_interval = 2).
El comportamiento se puede ver en la siguiente pieza de código en la que inicialmente se generan los bloques cada minuto, por lo que la dificultad se vera reducida cada dos bloques. Posteriormente los bloques se agregarán cada 3 minutos, de modo que se reducirá cada dos bloques
from datetime import datetime
block = Block(0, None, None, datetime(2000, 1, 1, 0, 0, 0))
block.mining()
blockchain = BlockChain(block)
for minutes in range(1, 10):
blockchain.next_block(None, datetime(2000, 1, 1, 0, minutes, 0))
for minutes in range(11, 40, 3):
blockchain.next_block(None, datetime(2000, 1, 1, 0, minutes, 0))
print('Increase', blockchain.chain[3].difficulty, 'to', blockchain.chain[4].difficulty)
print('Increase', blockchain.chain[5].difficulty, 'to', blockchain.chain[6].difficulty)
print('Decrease', blockchain.chain[11].difficulty, 'to', blockchain.chain[12].difficulty)
print('Decrease', blockchain.chain[13].difficulty, 'to', blockchain.chain[14].difficulty) Imágenes: Pixabay (mmi9)
En la era del dato, las organizaciones se enfrentan al reto de gestionar volúmenes masivos…
En la serie Creación de una API REST con Express y TypeScript construimos una API…
Durante la Segunda Guerra Mundial, la Fuerza Aérea de Estados Unidos quería reforzar sus aviones…
En muchas situaciones —ya sea para grabar un tutorial, tomar capturas de pantalla profesionales, probar…
Imagínate en una sala con un grupo de personas, por ejemplo, en una oficina, un…
En el trabajo diario con ordenadores, es común encontrarse con tareas repetitivas: realizar copias de…
This website uses cookies.