Bitcoinj

創建一個 OP_RETURN tx 並驗證它在 Regtest 中的存在

  • November 12, 2017

我的碩士論文的一部分是將帶有 OP_RETURN tx 的字元串的雜湊值儲存在區塊鏈中,以作為證明存在。

我主要擔心的是:

-我怎樣才能成功發送這個 tx 到我的 regtest 網路

  • 如果這個 tx 發生了,我怎麼能看到(使用 RPC)

我已經將字元串儲存到一個文件中,然後對其進行雜湊處理。但是我很難將我的 Java 與 Regtest 網路連接起來。

這是我的程式碼:

公共類主要{

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

}

}

我不熟悉您使用的 Java API,但這裡是我用來在 regtest 上創建有效事務的步驟和 C# 程式碼範例。範例和步驟來自我粗略且現成的開發筆記,因此可能會有一些信念的飛躍(希望不會)。

您需要為自己的路徑/作業系統/設置調整以下步驟。

  • 第一步:回歸測試模式下本地比特幣全節點使用的命令行(<https://bitcoin.org/en/developer-examples#regtest-mode>):

    • “C:\Program Files\Bitcoin\daemon\bitcoind” printtoconsole -datadir=f:\temp\bitcoind -server -regtest -debug=1
  • 第 2 步:用於請求比特幣守護程序生成 101 高度區塊鏈的命令行:

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest 生成 101
  • 第 3 步:如果比特幣伺服器節點是用空區塊鏈初始化的,getbalance 命令現在應該顯示 50.00000000,它代表創世區塊之後的第一個區塊的硬幣基礎金額。

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest getbalance
  • 第 4 步:查找可用於消費的交易。

    • “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]
  • 第 5 步:獲取用於簽署支出交易的私鑰(確保指定了 -regtest,否則您可能會導出您的實時私鑰並可能失去 $$$)。

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest dumpprivkey
  • 第 6 步:發送交易後,檢查它是否被接受為有效並添加到記憶體池中。

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest getrawmempool
  • 第 7 步:如果交易成功驗證並被記憶體池接受,那麼下一步就是生成一個包含它的塊。

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest 生成 1
  • 第 8 步:然後可以檢查發送硬幣的地址以驗證是否收到硬幣(除非將發送地址的私鑰導入錢包,否則您不能使用 getbalance)。

    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest 導入地址 mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk 重新掃描
    • “C:\Program Files\Bitcoin\daemon\bitcoin-cli” -datadir=f:\temp\bitcoind -regtest getreceivedbyaddress mssuKhM1CMDgcCm3LyGunA1o6129FnkHyk

在下面的程式碼範例中,您需要將密鑰替換為您使用上述 bitcoin-cli 步驟提取的密鑰。毫無疑問,有一種更簡單的方法可以做到這一點,這些筆記來自我最初幾週與比特幣混在一起的時間。

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...");
       }
   }
}

引用自:https://bitcoin.stackexchange.com/questions/62370