original: https://www.savjee.be/2018/02/Transactions-and-mining-rewards/
Esta es la parte 3 de mi serie de publicaciones de blog en la que creamos una cadena de bloques en Javascript. En las publicaciones de blog anteriores, creamos una cadena de bloques simple e implementamos una prueba de trabajo para protegerla de los spammers y los atacantes. Sin embargo, hicimos algunos atajos en el camino: nuestra cadena de bloques solo puede almacenar 1 transacción en un bloque y no hay recompensas para los mineros. ¡Arreglemos eso!
Reestructuración de la clase Block
En este momento, un bloque tiene las propiedades index, previousHash, timestamp, data, hash y nonce. La propiedad del
index
no es realmente útil, de hecho, ni siquiera sé por qué lo agregué para empezar. Entonces, eliminemos eso y cambiemos el nombre de los data
a transactions
que tengan más sentido.
Cuando cambiamos nuestra clase Block, también tenemos que cambiar su función
calculateHash()
. En este momento, todavía utiliza las antiguas propiedades de index
y data
, que acabamos de eliminar.Clase de transacción
Dentro de un bloque podremos almacenar múltiples transacciones. Así que definamos también una clase de
Transaction
para que podamos bloquear las propiedades que debe tener una transacción:
En este ejemplo, una transacción será muy simple, solo contendrá un remitente (
fromAddress
) un receptor ( toAddress
) y una cantidad. Si es necesario, puede agregar más campos a una transacción, pero estos son el mínimo absoluto.Adaptando nuestra Blockchain
Ahora viene la tarea más grande de todas: hacer que nuestro
Blockchain
funcione con todos estos nuevos cambios. Lo primero que necesitamos es un lugar para almacenar transacciones pendientes.
Como sabe, las cadenas de bloques crean bloques en un intervalo constante gracias al algoritmo de prueba de trabajo. En el caso de Bitcoin, la dificultad se ajusta para que se creen nuevos bloques aproximadamente cada 10 minutos. Sin embargo, debería ser posible enviar nuevas transacciones entre la creación de dos bloques.
Entonces, para hacer eso, comencemos cambiando nuestro constructor de Blockchain para que tenga un lugar donde almacenar las transacciones pendientes. También crearemos una propiedad que defina cuántas monedas recibe un minero como recompensa:
A continuación, tenemos que adaptar nuestro método
addBlock()
y al adaptarlo quiero decir eliminarlo por completo para volver a escribirlo. No permitiremos que las personas agreguen bloques directamente a nuestra cadena. En su lugar, tienen que agregar transacciones que se incluirán en el siguiente bloque. Así que reemplazaremos el método addBlock()
con createTransaction()
, que tiene más sentido:Bloques mineros
La gente ahora puede agregar nuevas transacciones a la lista de pendientes.Pero de una manera u otra, tenemos que eliminarlos y ponerlos dentro de bloques reales. Entonces, para hacer eso,
minePendingTransactions()
un método minePendingTransactions()
. Este método no solo extraerá un nuevo bloque con todas las transacciones pendientes, sino que también enviará una recompensa minera al minero.
Tenga en cuenta que el método toma un argumento
miningRewardAddress
. Si comienza a extraer, puede pasar su dirección de billetera a este método.Una vez que haya extraído un bloque con éxito, el sistema creará una nueva transacción para darle su recompensa minera (en este caso 100 monedas).
Una cosa a tener en cuenta es que en esta implementación tomamos todas las transacciones pendientes y las agregamos a un bloque. En realidad, sin embargo, eso no funcionará porque el tamaño de un bloque es limitado. En el caso de Bitcoin, hay un límite de tamaño de bloque de 2 mb. Si hay más transacciones que pueden caber en un bloque, el minero puede elegir qué transacción incluye y cuál no (generalmente ganan las que tienen la tarifa más alta).
Balance de una dirección
Antes de que podamos probar nuestro código, ¡hagamos una cosa más! Sería bueno poder verificar los saldos de las direcciones en nuestra cadena de bloques.
Probándolo
¡Bien, hemos terminado y finalmente podemos probar si todo está funcionando! Para hacer eso, creemos algunas transacciones:
Estas transacciones están ahora pendientes y para que se confirmen, tenemos que iniciar el minero:
Cuando iniciamos el minero, también pasamos una dirección en la que queremos recibir la recompensa minera. En este caso, mi dirección es
xaviers-address
(¡bastante complicada!)
Después de eso,
xaviers-address
el saldo de xaviers-address
:
Muestra que mi saldo es cero. ¿Esperar lo? ¿No debería haber obtenido mi recompensa minera? Bueno, si miras detenidamente el código, verás que el sistema crea un nuevo bloque y luego agrega tus recompensas mineras como una nueva transacción pendiente. Esa transacción se incluirá en el siguiente bloque. Entonces, si iniciamos de nuevo al minero, ¡recibiremos nuestra recompensa de 100 monedas!
Limitaciones y conclusión
En este momento, nuestra pequeña cadena de bloques puede almacenar múltiples transacciones en un bloque y otorgar recompensas a los mineros.
Sin embargo, todavía faltan algunas cosas: al enviar dinero no verificamos si el remitente tiene saldo suficiente para realizar esa transacción. Sin embargo, esto es algo fácil de abordar. Tampoco tenemos una forma de crear una nueva billetera y firmar transacciones (tradicionalmente eso se haría con encriptación de clave pública / privada)
Descargo de responsabilidad y código fuente
Quiero señalar que esto de ninguna manera es una implementación completa de blockchain. Todavía carece de muchas características. Esto es solo una prueba de concepto diseñada para ayudarlo a comprender cómo funcionan las cadenas de bloques internamente.
El código fuente de este proyecto está disponible en GitHub .