3

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:

  1. When attempting an OP_RETURN transaction in NBitcoin, is it necessary to add the miner fees into the TransactionBuilder manually?

  2. Is there a way to use Node.Connect so it will just search for available nodes, rather than specifying a specific node?

  3. 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.

  4. 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.

  • Based on the reason you posted, it looks like the remote node is timing out. Is this connected to a bitcoin node on your local network, or one over the internet? – Nick ODell Nov 20 '15 at 0:33
  • One on the Internet. It is timing out...but I've tried a number of reliable nodes with open ports with the same result. That leads me to believe I am not creating the transaction correctly. – cfly24 Nov 20 '15 at 0:55
1

I think the problem is that there is only OP_RETURN, I remember seeing in the Bitcoin code that only OP_RETURN without anything else is forbidden.

Except that, your code looks like what is in my book https://blockchainprogramming.azurewebsites.net/ so I'm almost sure it is the problem.

EDIT : You are crashing during Handshake, can you check Node.DisconnectReason ?

  • OP_RETURN without a push is okay. See the tests: github.com/bitcoin/bitcoin/blob/… Of course, you can disable OP_RETURN standardness entirely by passing datacarrier=0 in bitcoin's config file. – Nick ODell Nov 19 '15 at 4:47
  • I just checked Node.DisconnectReason. The Reason is Unexpected exception while connecting to socket and the exception is Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. – cfly24 Nov 19 '15 at 16:25
  • I think your problem is more simpler : your node does not accept new connection. It can happen if there is already too much for it and you are not whitelisted. – Nicolas Dorier Nov 20 '15 at 5:43
  • @NickODell, yes but a OP_RETURN without any other TxOut is not ok. But he crashes before sending the transaction, so it should not be the problem. – Nicolas Dorier Nov 20 '15 at 5:44
  • @NicolasDorier I think that's okay too. See how the test has only one item in vout? – Nick ODell Nov 20 '15 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.