創建一個 OP_RETURN tx 並驗證它在 Regtest 中的存在
我的碩士論文的一部分是將帶有 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..."); } } }