Cree un OP_RETURN tx y valide su existencia en Regtest

Una parte de mi tesis de maestría es almacenar el hash de una cadena con OP_RETURN tx en Blockchain para que exista como prueba.

Mis principales preocupaciones son:

-¿Cómo puedo enviar este tx con éxito a mi red de registro?

-cómo puedo ver (con un RPC) si sucedió este tx

Ya almacené la cadena en un archivo y luego la arrastré. Pero tengo dificultades para conectar mi Java con la red Regtest.

Aquí está mi código:

clase pública Principal {

public static RegTestParams params = RegTestParams.get();
static BlockStore bs;
static Block b;

public static Context context = new Context(params);
public static WalletAppKit bitcoin;

public static void main(String[] args) throws InterruptedException, ExecutionException, BlockStoreException {

    WalletAppKit kit = new WalletAppKit(RegTestParams.get(), new java.io.File("."), "test");
    kit.startAsync();
    Wallet wallet = new Wallet(params);

    BlockChain chain = kit.chain();
    bs = chain.getBlockStore();
    Peer peer = kit.peerGroup().getDownloadPeer();
    b = peer.getBlock(bs.getChainHead().getHeader().getHash()).get();

    peer.addWallet(wallet);

    Address myAddress = new Address(params, "n4MN27Lk7Yh3pwfjCiAbRXtRVjs4Uk67fG");

    Writer w = new Writer();
    final File results = new File("C:\\Users\\Maria\\workspace\\blockInfo\\results.txt");
    File writtenFile;
    Sha256Hash resultHash;

    // write the results of my draw to a file
    writtenFile = w.writeToFile(results);

    // hash the contents of the file
    resultHash = w.hashTheFile(writtenFile);
    System.out.println(resultHash);

    SendRequest req;
    Transaction transaction = new Transaction(RegTestParams.get());

    // the following statement will help to create an OP_RETURN with
    // resultHash as the message
    transaction.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript(resultHash.getBytes()));
    req = SendRequest.forTx(transaction);

}

}

Creo que todavía te faltan algunos pasos, por ejemplo, no puedo ver dónde configuraste el hash de la transacción de financiación. Aparte de eso, puede verificar el mempool de su nodo bitcoin usando: bitcoin-cli -regtest getrawmempool. Si está vacío, su tx no fue aceptado.
@sipwiz, el RPC funcionó y, por supuesto, todavía está vacío. ¿Cómo puedo configurar el hash de la transacción de financiación? ¿Podría proporcionar un fragmento breve de código con OP_RETURN?
Se requieren algunos pasos para trabajar con la red de registro. ¿ Has visto bitcoin.org/en/developer-examples#regtest-mode ?
@sipwiz He visto los ejemplos. Mi problema es cómo establecer una conexión adecuada con Java para capturar los resultados luego en la red de registro. Los RPC pueden funcionar solos aparte del código Java.
Acabo de agregar una respuesta que, con suerte, se acerca a lo que está intentando hacer. Lo principal que debe considerar es obtener una entrada para su transacción. No puede gastar una salida si no financia el tx.

Respuestas (1)

No estoy familiarizado con la API de Java que está utilizando, pero estos son los pasos y una muestra de código C# que utilicé para crear una transacción válida en el registro. La muestra y los pasos son de mis notas de desarrollo preliminares y listas, por lo que puede haber algunos actos de fe (esperemos que no).

Deberá ajustar los pasos a continuación para sus propias rutas/SO/configuración.

  • Paso 1: la línea de comando utilizada para el nodo completo de bitcoin local en el modo de prueba de regresión ( https://bitcoin.org/en/developer-examples#regtest-mode ):

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoind" printtoconsole -datadir=f:\temp\bitcoind -server -regtest -debug=1
  • Paso 2: La línea de comando utilizada para solicitar al demonio bitcoin que genere una cadena de bloques de 101 alturas:

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest generar 101
  • Paso 3: si el nodo del servidor bitcoin se inicializó con una cadena de bloques vacía, el comando getbalance ahora debería mostrar 50.00000000, que representa la cantidad base de monedas del primer bloque que sigue al bloque génesis.

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getbalance
  • Paso 4: Para encontrar las transacciones disponibles para gastar.

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest listunspent
    • ["C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getrawtransaction true]
  • Paso 5: para obtener la clave privada para firmar una transacción de gasto (ASEGÚRESE DE QUE SE ESPECIFIQUE -regtest DE LO CONTRARIO, PODRÍA EXPORTAR SU CLAVE PRIVADA EN VIVO Y POTENCIALMENTE PERDER $$$).

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest dumpprivkey
  • Paso 6: Después de enviar una transacción, verifique si fue aceptada como válida y agregada al mempool.

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getrawmempool
  • Paso 7: si la transacción se valida y acepta con éxito en el mempool, el siguiente paso es generar un bloque que la incluya.

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest generar 1
  • Paso 8: La dirección a la que se enviaron las monedas se puede verificar para verificar que se recibieron las monedas (no puede usar getbalance a menos que la clave privada de la dirección de envío se importe a la billetera).

    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest importaddress mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk reescanear
    • "C:\Archivos de programa\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getreceivedbyaddress mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk

En el ejemplo de código a continuación, debe reemplazar las claves con las que extrajo utilizando los pasos de bitcoin-cli anteriores. Sin duda, hay una manera más fácil de hacer esto y estas notas son de mis primeras semanas jugando con Bitcoin.

using System;
using System.Threading;
using NBitcoin;
using NBitcoin.Protocol;
using log4net;

namespace SpendTransaction_WithCli
{
    class Program
    {
        static ILog logger = log4net.LogManager.GetLogger("default");
        static Network _network = Network.RegTest;

        static string _unspentTxId = "5d1db816efc865ab33eb8d5c9f0238501dfd849fc67cc941565236b36e43b234";    // Need to get this from bitcoin-cli (see Step 4 above).
        static string _unspentScriptPubKey = "03c1a1a614c8549373b2ec35f586aa8b33a3bf5ac3e0a1b8cf27e650bdb5a126f0 OP_CHECKSIG"; // Need to get this from bitcoin-cli (see Step 4 above).
        static string _sendFromPrivateKey = "cQYdUpoeJZP7FmxUeiaKSLPo9eHsDAYbWs17DgY44yHX2sATK2Cw";         // Need to get this from bitcoin-cli (see Step 5 above).
        static string _receiveToPrivateKey = "cR7X4Nd5WqA5mNwgX67th4Jo3K9vTTm28w8njLL9JT8hHPdbstL8";        // This is an arbitrary key that is used to send some coins to.

        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();

            // Set up the private keys and addresses for the sender and receiver.
            Key sendFromPrivKey = Key.Parse(_sendFromPrivateKey, _network);
            BitcoinPubKeyAddress sendFromAddr = sendFromPrivKey.PubKey.GetAddress(_network);

            Key receiveToPrivKey = Key.Parse(_receiveToPrivateKey, _network);
            BitcoinPubKeyAddress receiveToAddr = receiveToPrivKey.PubKey.GetAddress(_network);

            logger.DebugFormat("Sending from {0} to {1}.", sendFromAddr, receiveToAddr);

            logger.Debug(sendFromPrivKey.ScriptPubKey);
            logger.Debug(sendFromPrivKey.PubKey);

            // Create the transaction to spend the bitcoin.
            OutPoint spending = new OutPoint(uint256.Parse(_unspentTxId), 0);
            Script spendScriptPubKey = new Script(_unspentScriptPubKey);

            var spendTx = new Transaction();
            spendTx.Inputs.Add(new TxIn(spending, spendScriptPubKey));
            spendTx.Outputs.Add(new TxOut(Money.Parse("49"), receiveToAddr.ScriptPubKey));  

            spendTx.Sign(sendFromPrivKey, false);

            logger.Debug(spendTx.ToString(RawFormat.BlockExplorer));

            // Send the transaction to the local bitcoin node.
            using (var node = Node.ConnectToLocal(_network))
            {
                node.VersionHandshake();
                node.SendMessage(new InvPayload(InventoryType.MSG_TX, spendTx.GetHash()));
                node.SendMessage(new TxPayload(spendTx));
                Thread.Sleep(500);
            }

            Console.WriteLine("Press q to quit...");

            while (true)
            {
                var keyPress = Console.ReadKey();
                if (keyPress.KeyChar == 'q')
                {
                    break;
                }
            }

            Console.WriteLine("Exiting...");
        }
    }
}
muy útil, especialmente los pasos para RPC. Intentaré adaptar los pasos a mi código java y ejecutar.