¿Dónde y cuándo se debe agregar la transacción de la base de monedas (incluida la clave del minero)?

Estoy haciendo un programa de demostración simple, más o menos un clon de bitcoin simplificado basado principalmente en el documento técnico original.

Tenga paciencia conmigo, porque no he encontrado una manera de describir el problema de manera más concisa.

Mi cadena de bloques se basa en este tutorial.

Sin embargo, ignora por completo la parte de la transacción, por lo que basé las transacciones en esta parte de la documentación original: Una sección del documento técnico original de bitcoincomo se especifica aquí, mis transacciones consisten en la clave pública del siguiente propietario y la firma de la última transacción firmada por el propietario anterior. También agregué la cantidad que se transfiere (no estoy usando el sistema de entrada/salida por simplicidad).

Dado que cada transacción necesita un hash de una anterior, también creé una transacción de base de monedas. Solo contiene la cantidad minada y la clave pública del minero (para saber a quién darle la cantidad minada). Esto permite que la primera transacción regular en un bloque tenga una transacción anterior para codificar y firmar.

Sin embargo, eso también significa que la clave del minero debe especificarse antes de realizar la primera transacción (ya que todas las transacciones futuras requieren que el hash de la base de monedas permanezca igual). Al mismo tiempo, no tiene sentido especificar el minero antes de que haya extraído un bloque. En otras palabras, esto requeriría que el usuario de la transacción sepa a priori quién extraerá el bloque con su transacción.

Mi suposición hasta ahora era que una transacción de base de monedas se agrega a la lista de transacciones no confirmadas después de que se extrae el bloque anterior, y las nuevas transacciones se refieren a él. Luego, toda la lista se coloca en un bloque que luego se extrae. Sin embargo, esa suposición condujo a los problemas antes mencionados.

La única solución posible que se me ocurrió es usar el hash de la última transacción del bloque anterior para firmar una nueva transacción, omitiendo efectivamente la transacción de la base de monedas. Pero eso no me parece bien.

Por favor, dime si me estoy perdiendo algo o tengo una idea equivocada en alguna parte.

¿Dónde y cuándo se debe agregar la transacción de la base de monedas (incluida la clave del minero)?

¿O debería descartar esa idea por completo y usar el método de "desvío"?

PD. Ya intenté buscar en varios wikis y preguntas, pero nada realmente me dio una solución clara a esto. Especialmente, esta respuesta es demasiado vaga.

Respuestas (2)

Tiene la idea equivocada: cada transacción no necesita hacer referencia a la transacción anterior en un determinado bloque, debe hacer referencia a la transacción que creó los productos que ahora está gastando. Esta 'cadena de transacciones' se refiere al seguimiento del historial de ciertas salidas a lo largo del tiempo, no solo a la ordenación arbitraria de transacciones dentro de un bloque.

Entonces, la segunda transacción en un bloque (primera transacción sin base de monedas) hará referencia a las transacciones que crearon los productos que está gastando. No hará referencia a la transacción de coinbase.

¡Gracias! Lo descubrí usando la respuesta anterior y buscando en los exploradores de bloques, pero ahora tengo la confirmación de que mis conclusiones eran correctas.

La transacción de coinbase se crea cuando el minero crea la plantilla para el bloque que intenta extraer. A diferencia de las transacciones regulares, no tiene entradas regulares. El minero simplemente especifica las salidas para gastar las monedas, donde la suma de los montos de salida debe ser menor o igual a la cantidad total de tarifas en el bloque más el subsidio. La base de monedas siempre se posiciona como la primera transacción en el bloque.

La transacción de coinbase tiene la misma estructura que las transacciones normales, pero para cada una txInde ellas, cualquiera txOutPointdebe tener un valor cero (no hay un valor anterior txidal que referirse). Pueden scriptSigcontener información arbitraria, ya que los mineros no necesitan firmar nada. Los mineros agregan información como scriptSigsu nombre o una fuente adicional de entropía para la minería. Además, algunas reglas de consenso que se han bifurcado en Bitcoin requieren que scriptSigcontenga la altura del bloque y una raíz Merkle de wtxids(para segwit).

El proceso es más o menos así:

  • Miner crea una plantilla de base de monedas que gasta una cantidad de dinero aún no conocida en una o más salidas.

  • Miner ordena las transacciones en el mempool por la tarifa de pago más alta por unidad de peso (por byte en el original) y elige una cantidad de transacciones de modo que su tamaño serializado más el tamaño serializado de la base de monedas no sea mayor que el límite de tamaño del bloque.

  • Suman todas las tarifas pagadas en las transacciones incluidas y las agregan al subsidio para crear una cantidad que vale el bloque.

  • Actualizan la plantilla de coinbase gastando como máximo esta cantidad (es posible no reclamar el monto total de las tarifas o el subsidio, pero reclamar en exceso produce un bloque no válido).

  • El minero calcula la raíz Merkle de todas estas transacciones txids(donde txides el doble SHA de la transacción serializada), tomada como un árbol binario ordenado por la posición en que se serializa la transacción en el bloque. La base de monedas es explícitamente la primera transacción.

  • El minero inserta esta raíz merkle en un encabezado de bloque con los otros 5 campos obligatorios (versión, prevBlockHash, objetivo, nonce y marca de tiempo) y lo serializa.

  • El minero intenta repetidamente duplicar SHA256 en el encabezado del bloque hasta que el resumen resultante, cuando se toma como un número entero, es numéricamente menor o igual a lo que requiere el targetencabezado. El minero modifica el nonce, u ocasionalmente timestamppara cada intento doble-SHA256 para que se produzca un resumen diferente, pero los otros campos del encabezado permanecen sin cambios.

  • En algún intervalo regular, si el minero aún no ha encontrado un hash exitoso, o si se recibe un nuevo bloque, calcula una nueva plantilla iniciando este proceso desde el principio, que puede tomar nueva información y puede proporcionar una recompensa mayor. Descartan la plantilla anterior en la que estaban trabajando. Si se encuentra un nuevo bloque, todas las transacciones que se incluyeron en el bloque se eliminan del mempool.

Gracias, esto fue informativo y me ayudó a encontrar la solución exacta yo mismo.