Create an OP_RETURN tx and validate it's existence in Regtest A part of my MSc thesis is storing the hash of a string with OP_RETURN tx in the Blockchain to exist as a proof.

My main concerns are:

-how can i send this tx successfully to my regtest network

-how can i see (with a RPC) if this tx happend

I have already stored the string to a file and hash it afterwards. But I have difficulties with connecting my Java with the Regtest network.

Here is my code:

public class Main {

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);

}


}
I'm not familiar with the Java API you are using but here are the steps and a C# code sample that I used to create a valid transaction on regtest. The sample and steps are from my rough and ready dev notes so there may be a few leaps of faith (hopefully not).

You'll need to adjust the steps below for your own paths/OS/set up.


Step 1: The command line used for the local bitcoin full node in regression test mode (https://bitcoin.org/en/developer-examples#regtest-mode):


"C:\Program Files\Bitcoin\daemon\bitcoind" printtoconsole -datadir=f:\temp\bitcoind -server -regtest -debug=1

Step 2: The command line used to request the bitcoin daemon to generate a 101 height blockchain:


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest generate 101

Step 3: If the bitcoin server node was initialised with an empty blockchains the getbalance command should now display a 50.00000000 which represents the coin base amount from the first block following the genesis block.


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getbalance

Step 4: To find the transactions available for spending.


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest listunspent
["C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getrawtransaction  true]

Step 5: To get the private key to sign a spend transaction (MAKE SURE -regtest IS SPECIFIED OTHERWISE YOU COULD EXPORT YOUR LIVE PRIVATE KEY AND POTENTIALLY LOSE $$$).


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest dumpprivkey 

Step 6: After sending a transaction check whether it was accepted as valid and added to the mempool.


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getrawmempool

Step 7: If the transaction is successfully validated and accepted into the mempool then the next step is to generate a block that includes it.


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest generate 1

Step 8: The address that the coins were sent to can then be checked to verify that the coins were received (not you can't use getbalance unless the send to address's private key is imported into the wallet).


"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest importaddress mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk rescan
"C:\Program Files\Bitcoin\daemon\bitcoin-cli" -datadir=f:\temp\bitcoind -regtest getreceivedbyaddress mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk



In the code sample below you need to replace the keys with the ones you extract using the bitcoin-cli steps above. There's undoubtedly an easier way to do this and these notes are from my first couple of weeks mucking around with 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...");
        }
    }
}