# 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.