This is my first time trying out the NBitcoin library to create a transaction. I am trying to create an OP_RETURN
transaction, but every time I try to execute the Version Handshake
with the node I get the error: The node is not in a connected state
.
This is self explanatory, but I've tried a number of what are considered reliable nodes.
I guess this is a four part question:
When attempting an
OP_RETURN
transaction in NBitcoin, is it necessary to add the miner fees into the TransactionBuilder manually?Is there a way to use
Node.Connect
so it will just search for available nodes, rather than specifying a specific node?Is it an issue that I have the OP_RETURN and not anything else? Do I need to create another output with no value and add the miner fees in order to send it? There are libraries in PHP, Python, and Javascript to do this, but I am trying to figure out how to do this with NBitcoin.
If I wanted to store the incoming hash in the OP_RETURN script, am I doing it correctly? The byte stream seems to be too long.
Heres my code, which is in a .NET MVC4 Controller Action:
[HttpPost]
public ActionResult NewTransaction(string hash)
{
var paymentSecret = new BitcoinSecret("//Private Key");
// Example hash is "45e114a7f2c6122c9c1dabbd4df187e66545c17ca0bd28de732499dbee476811"
var message = hash;
var bytes = Encoding.UTF8.GetBytes(message);
var blockr = new BlockrTransactionRepository();
var fundingTransaction = blockr.Get("60db94bfb43dd0d98ba7fdfbbg4f29a850f7s5ea7d79a32c4r954096f2945b04");
var payment = new Transaction();
payment.Inputs.Add(new TxIn()
{
PrevOut = new OutPoint(fundingTransaction.GetHash(), 1)
});
payment.Outputs.Add(new TxOut()
{
Value = Money.Zero,
ScriptPubKey = TxNullDataTemplate.Instance.GenerateScriptPubKey(bytes)
});
payment.Inputs[0].ScriptSig = paymentSecret.ScriptPubKey;
payment.Sign(paymentSecret, false);
using (var node = Node.Connect(Network.Main, "67.221.193.55", new NodeConnectionParameters()
{
IsTrusted = true,
IsRelay = false
}))
{
// Always fails on the handshake
node.VersionHandshake();
node.SendMessage(new InvPayload(InventoryType.MSG_TX, payment.GetHash()));
node.SendMessage(new TxPayload(payment));
Thread.Sleep(500);
}
return View("Index");
}
EDIT
I tried to actually use the TransactionBuilder
, but still came up with the same error. This time I am actually setting the fee amount. I am also using a different node and specifying the port. Here is the attempt:
var paymentSecret = new BitcoinSecret("//Private Key");
// Example hash is "45e114a7f2c6122c9c1dabbd4df187e66545c17ca0bd28de732499dbee476811"
var message = hash;
var bytes = Encoding.UTF8.GetBytes(message);
var funding = new Transaction()
{
Outputs =
{
new TxOut("0.01", paymentSecret.GetAddress())
}
};
var coins = funding
.Outputs
.Select((o, i) => new Coin(new OutPoint(funding.GetHash(), i), o))
.ToArray();
var txBuilder = new TransactionBuilder();
var tx = txBuilder
.AddCoins(coins)
.AddKeys(paymentSecret.PrivateKey)
.Send(TxNullDataTemplate.Instance.GenerateScriptPubKey(bytes), Money.Zero)
.SendFees("0.00001")
.SetChange(paymentSecret.PubKey)
.BuildTransaction(true);
txBuilder.Verify(tx);
using (var node = Node.Connect(Network.Main, "67.221.193.55:8333", new NodeConnectionParameters()
{
IsTrusted = true,
IsRelay = false
}))
{
node.VersionHandshake();
node.SendMessage(new InvPayload(InventoryType.MSG_TX, tx.GetHash()));
node.SendMessage(new TxPayload(tx));
Thread.Sleep(500);
}
Could anyone help out. There is a lack of documentation specifying how to conduct an OP_RETURN
transaction. Thanks.