# Construyendo Bitcoin: Estructura de bloques **Nota:** Todo se muestra en Python, pero puedes elegir el lenguajes con el que te sientas más cómodo o cómoda. También puedes cambiar los tipos de variables a tu discreción. En esta actividad, vamos a crear una clase para definir un bloque con estructura similar a los bloques de Bitcoin y generar un hash en SHA-256. ## Estructura de bloques de Bitcoin * [Estructura de un bloque de Bitcoin](https://i.imgur.com/lW1RtT4.png) * [Encabezado de un bloque de Bitcoin](https://i.imgur.com/V9ZsYt1.png) * [Ejemplo de un bloque de Bitcoin](https://i.imgur.com/VZBQCqD.png) ## Contexto: Generando hashes criptográficos con Python Revisemos un ejemplo de cómo generar hashes. Para este ejercicio vamos a utilizar la librería [hashlib](https://docs.python.org/3/library/hashlib.html). 1. Importa la librería hashlib. ``` >>> import hashlib ``` 2. Crea un objeto SHA-256. ``` >>> m = hashlib.sha256() ``` 3. Una vez creado el objeto SHA-256, hashlib te permite generar hashes criptográficos a partir de objetos bytes utilizando el método `update()`. ``` >>> m.update(b"0") # representación en byte object ``` 4. Para ver el hash del objeto, puedes ver su digest (resúmen). ``` >>> m.hexdigest() '5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9' ``` Ahora generemos hashes más complejos. 5. Declaremos las siguientes variables ``` >>> name = "satoshi" >>> last = "nakamoto" >>> age = 37 ``` La función `update()` toma solo un argumento, por lo que no podemos hashear las 3 variables juntas. ``` >>> m.update(name, last, age) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: update() takes exactly 1 argument (3 given) ``` Tampoco podemos concatenarlas, ya que tenemos dos variables de tipo string y una variable de tipo int. ``` >>> all = name + last + age Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate str (not "int") to str ``` Para poder hashear variables de múltiples tipos, tenemos que codificarlas con algún tipo de encoding (por ejemplo, UTF-8). ``` # Creamos una representación en string de todas las variables all = (str(name) + str(last) + str(age)) # Codificamos el string en formato UTF-8 (default) all = all.encode() ``` Ahora sí podemos hashear las variables. 6. Hashea el string codificado en UTF-8. ``` m.update(all) ``` 7. Revisa el digest hexadecimal. ``` >>> m.hexdigest() 'b806c5fb957a7910b169cba8c987991d2260671a7befff5da656842c4e65f9da' ``` ## Actividad: Construyendo bloques 1. Comienza con la siguiente definición de clase: ``` class Block(): def __init__(): pass ``` 2. Declara las siguientes variables en el constructor: | Field | Type | Description | | -------- | -------- | -------- | | `height` | Integer | Altura del bloque | | `timestamp` | String | Timestamp del bloque | | `tx` | String | Lista de transacciones incluidas en el bloque| | `nonce` | Integer | Dificultad del bloque (default=0) | | `prev_blockhash` | String | Hash SHA-256 del bloque anterior | | `curr_blockhash` | String | Hash SHA-256 del bloque actual | 3. Agrega un método llamado `hash_block` que genere un hash criptográfico a partir de todas las variables definidas en la tabla de arriba (excepto `curr_blockhash`). Una vez creado, guarda el hash en la variable de instancia `curr_blockhash`. ``` class Block(): def __init__(): # Tu código aquí pass def hash_block() -> String: pass ``` Puedes probar con la función con el siguiente método: ``` def test_block_hash(height, timestamp, tx, nonce, prev_blockhash) blockhash = hash_block(height, timestamp, tx, nonce, prev_blockhash) return blockhash height = 0 timestamp = '2021-02-25 11:59:59.134365' tx = 'Alice, Bob, 10' nonce = 0 # Hash de bytes(0) utilizando SHA-256 prev_blockhash = '3af366504b556c3802248387ee16eb51ffee5ba52906bae95f0eff7ea454218e' hash = "25ce50cbc8594188fc14aeec1a64699d9e4bf942695a72c4c984d84ca7dca2e2" assert test_blockhash(height, timestamp, tx, nonce, prev_blockhash) == hash ``` 4. Listo. Sube tu código en Canvas. No olvides agregar la documentación necesaria para que pueda entender tu código y ejecutarlo.