Tutorial: ¿Cómo crear una transacción usando bitcoin-cli para hacer pruebas?
En este tutorial aprendemos a usar la línea de comandos del cliente de “Bitcoin Core” para que con tu propio nodo puedas hacer transacciones de manera manual y así entender más claramente cómo se ejecutan las transacciones en el sistema de Bitcoin.
Autor
Entre Plancton y Ballenas. Twitter para correcciones, comentarios o sugerencias: @entreplanctony1.
💡 ¿Tienes un nodo de bitcoin?En este tutorial explicamos cómo usar la línea de comando de Bitcoin Core (bitcoin-cli), por lo que debes tener un nodo de Bitcoin. Estos pasos sirven igual para testnet o mainnet. Si no has instalado un nodo o no sabes cómo utilizar la testnet puedes hacerlo consultando los Tutoriales sobre Nodos de Bitcoin. NOTA: Los ejemplos de este tutorial se corren en testnet. También se asume que tienes una wallet inicializada y cargada. Si no sabes cómo crear una wallet puedes ver el tutorial para Configurar una wallet en Bitcoin Core.
Videotutorial
Si lo prefieres, puedes ver la siguiente clase en vivo basada en este tutorial:
Ubica el balance que tienes dentro de tu wallet
El subcomando getbalance te muestra la cantidad total de satoshis disponibles para gastar en tu wallet, sumando todas las UTXO que tienes disponibles.
$ bitcoin-cli getbalance 0.00008500
¿Cuánto vas a gastar?
Debes verificar la cantidad a gastar, para este ejemplo, quiero hacer un pago simple de 0.00008000 bitcoin. Por lo que debo identificar si hay alguna UTXO dentro de mi wallet en la que tenga el saldo suficiente para hacer este pago.
El subcomando “listunspent” nos despliega las UTXO que se tienen disponibles para gastar.
De la salida resultante arriba, debemos identificar los siguientes campos para construir nuestra transacción:
“txid” es el identificador de nuestro UTXO [líneas 4 y 17]
“vout” es el índice que corresponde a la dirección que nos pertenece (la transacción pudo haber sido creada con más de un destinatario) [líneas 5 y 18]
“amount” es la cantidad disponible en cada UTXO [líneas 9 y 22]
En mi wallet tengo 2 UTXO, la primera con 0.00004500 y la segunda con 0.00004000, por lo que ninguna de las 2 tiene suficiente saldo para cubrir el pago que quiero hacer, sin embargo, la suma de ambas sí puede cubrir la cantidad que necesito pagar 0.00008000.
Ahora que conocemos las cantidades disponibles, podemos declarar las variables para las transacciones que necesitamos:
De la primera línea utxo_txid solo es el nombre que yo escogí para introducir un valor en la memoria de mi terminal (puedes darle a cada variable el nombre que tú quieras), el símbolo “=” indica el valor que va a tener la variable, y así sucesivamente en cada línea. En este caso ambos UTXO que tengo disponibles están declarados dentro de la misma transacción (txid en la salida de listunspent) por lo que solo necesito declarar un txid dentro de mis variables y el resto de las variables solo son los montos que tiene cada UTXO y el monto a pagar.
En cualquier momento puedes verificar que tus variables tengan los valores correctos ejecutando el comando “echo” y añade el carácter “$” al nombre de tu variable.
Debido a que las UTXO se deben “gastar” en su totalidad para poder ser utilizadas, necesito consumir ambas UTXO que tengo en mi wallet para hacer el pago deseado, pero como la suma de ambas no da la cantidad exacta del pago, necesito calcular tanto mi “cambio” como el “fee” (la cuota) a pagar a la red para garantizar que mi transacción sea verificada.
El cálculo de los fee es complejo, por lo que para este ejemplo estoy asumiendo que es algo simple y solo quiero pagar una cuota de 0.00000300:
echo es un comando que despliega en la terminal lo que escribes frente a él.
El carácter | (pipe) indica que a la salida resultante del comando de la izquierda se le va a aplicar el comando de la derecha.
bc solo es para indicar que quiero hacer una operación con valores de número flotante.
cambio= Aquí guardo en memoria el valor obtenido.
En total necesito definir 2 montos de salida en mi transacción, una salida que contenga el valor definido en montopago y otra salida que será mi cambio. El fee de transacción, aunque debemos siempre calcularlo, en Bitcoin el sobrante de tus operaciones de salida ya está implícito que será tu pago a los mineros.
⚠️ Si no declaras en tu transacción un monto de salida para definir tu “cambio” el sistema asume que cualquier valor sobrante es lo que vas a pagar de fee a los mineros.
Por último, necesitamos las direcciones a las cuales vamos a depositar el monto de pago y el cambio (para este último estoy creando una nueva dirección dentro de mi wallet):
El subcomando createrawtransaction es utilizado para crear las transacciones en crudo (en hexadecimal). Se debe introducir un arreglo JSON para listar las UTXO que está gastando y otro para listar las salidas (destinatarios).
La estructura del comando podemos entenderla con el siguiente diagrama:
Las entradas y las salidas se deben agrupar en un orden definido para que el comando las reconozca y deben contar con la siguiente sintaxis de objetos JSON, si usamos las variables que hemos definido previamente nos quedaría lo siguiente:
El comando bitcoin-cli utiliza un RPC JSON, por lo que la sintaxis del subcomando createrawtransaction podemos explicarla as:
Las 3 comillas ‘’’ y los símbolos [ ] en las líneas 2 y 9 representan el inicio y el final del arreglo JSON para las transacciones de entrada. Mientras que en las líneas 11 y 17 representan el inicio y el final del arreglo de salidas.
Los corchetes { } delimitan el inicio y final de cada uno de los valores de entrada y salida.
Las comas al final del corchete de cierre }, solo indican que hay más de un valor de entrada o salida y no son necesarias cuando se tiene una sola entrada y una sola salida.
Las comillas " " indican que estás pasándole un valor de texto al comando.
Con estas reglas de sintaxis para este comando es suficiente para definir nuestra transacción y la misma quedaría de la siguiente manera:
Sin embargo, podemos también usar las variables que definimos anteriormente, ya que la idea es que tú puedas copiar y pegar estos comandos y experimentar con ellos con las UTXO que tengas en tu wallet.
Para usar las variables cargadas en la memoria de nuestra terminal, necesitamos pasar otros caracteres para que el comando pueda leer lo que tenemos en nuestras variables. Las comillas simples ’ ’ ejecutan lo que está dentro de ellas y el $ es para indicar que el texto frente a este símbolo es un apuntador a un valor que está en memoria.
El siguiente comando crea la transacción usando nuestras variables y el valor hexadecimal resultante queda almacenado en una variable nueva llamada txhex:
Usa el comando decoderawtransaction para verificar que todos los campos que acabas de construir con createrawtransaction están correctos. Notarás que el comando ha agregado varios campos por ti de manera automática.
⚠️ Verifica cuidadosamente que la sección de vin tenga las UTXO correctas, y que la sección de vout tenga las direcciones y los montos a pagar correctos, si cometes un error y gastas una UTXO equivocada o si depositas a una dirección incorrecta y la transacción es aceptada por la red, no hay forma de revertir los cambios en la cadena de bloques. El comando createrawtransaction no calcula que los montos de entrada y salida sean correctos, solo valida que la sintaxis con la que la escribiste esté correcta, por lo que aún podría ser rechazada tu transacción si cometiste errores de cálculo.
Si en este punto todos los valores están correctos, entonces ahora puedes firmar la transacción con el comando signrawtransaction
El comando devuelve un valor en hexadecimal llamado “hex”, esta es tu transacción ya firmada con tu wallet. El valor “complete”, si devuelve valor true, significa que tu transacción no tiene errores (tu wallet si puede firmar la dirección de la UTXO), si hay algún problema con tu transacción verás los mensajes de error aquí. El valor lo guardamos en una variable llamada txfirmada.
Comment
Puedes correr el comando decoderawtransaction y verás como ahora existen los campos de “txinwitness” dentro de tus vin, estos contienen las firmas de tu wallet.
$ bitcoin-cli decoderawtransaction $txfirmada
💡 Puedes firmar tu transacción sin conexión Como puedes ver hasta este punto, la transacción no ha sido enviada a la red de bitcoin, por lo que el paso de crear y firmar la transacción pueden ejecutarse en una computadora distinta o incluso sin conexión a internet para aumentar tu seguridad.
Envía tu transacción a la red
El último paso es enviar la transacción a la red de bitcoin, para esto usamos el comando sendrawtransaction
Al cabo de unos minutos, si nuestros valores fueron correctos, podremos ver que la transacción ya está confirmada (línea 62, número de confirmaciones) y en qué bloque lo fue (línea 61 muestra el hash del bloque). También puedes visualizar la transacción en tu wallet con el comando listtransactions, y el saldo total en tu cartera deberá cambiar en getbalance.
👏 ¡Felicidades, ya puedes usar tu nodo para hacer transacciones de prueba!