Error when serializing and broadcasting transaction

I am getting error messages when trying to serialize or broadcast a transaction. Any help with this would be appreciated.

I get an error when I try serializing a transaction. I do not get the error message when I pass in true or the disableAll flag in as an argument for serialize(). Non of the other flags prevent the error for serialize().

The error message is:

bitcore.ErrorTransactionUnableToVerifySignature:
Unable to verify signature: Unrecognized script kind, or not enough information to execute script.This usually happens when creating a transaction from a serialized transaction

I get three error messages if I pass in true or the disableAll flag as arguments for serialize() and then pass the serialized transaction to broadcast(). These are:

In the console:

bitcore.ErrorTransactionUnableToVerifySignature:
Unable to verify signature: Unrecognized script kind, or not enough information to execute script.This usually happens when creating a transaction from a serialized transaction

The returned err from broadcast():

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

The post response from the insight server:

POST https://test-insight.bitpay.com/api/tx/send 400 Bad Request
Response: TX decode failed (code -22)

Both:

Script.Interpreter().verify()

and

transaction.verify()

are evaluating to true.

Here is the code that I have written:

<!DOCTYPE html>
<html>
<head></head>
<body>
    <script src="bitcore/bitcore.min.js"></script>
    <script src="bitcore-explorers/bitcore-explorers.min.js"></script>
    
    <script>
        
        var bitcore = require('bitcore');
        bitcore.Transaction = require('bitcore').Transaction;
        bitcore.Script = require('bitcore').Script;
        bitcore.Buffer = require('bitcore').Buffer;        
        bitcore.Address = require('bitcore').Address;
        
        var network = "testnet";
        var lockingScript = "";
        var unlockingScript = "";        
        var toAddress = "n1yigjdP1sKUm6n3ZvdAjA5xwY3MeyiMNZ";
        var g_utxos = [{"address":"2MwEv1p64YJJowC8HzUtsBDyweKWgutmqv1","txid":"cb0573919f768f8bead54168b9ab49de3ef811d168e7d0fbe41008b9ce7eff40","vout":0,"ts":1426187331,"scriptPubKey":"a9142bd17fded06462cfad6402f4b86ccc06e5c543e587","amount":0.01,"confirmations":4,"confirmationsFromCache":false}];
        var amount = 990000;
        var transaction = "";
        var serializedTransaction = "";

        //get scripts
        getScripts();
        
        transaction = createTransaction();
    
        serializedTransaction = serialize(transaction);
        
        broadcast(serializedTransaction);
        
        //create script using Bitcore
        function getScripts(){
            
            var Buffer = require('bitcore').Buffer;
            var Script = require('bitcore').Script;

            //create redeam script
            var redeamScript = new Script();
            redeamScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn OP_EQUAL"));

            //create locking script using toScriptHashOut()
            var initialLockingScript = redeamScript.toScriptHashOut();
            
            lockingScript = new Script();
            lockingScript.add(new bitcore.deps.Buffer("OP_HASH160"));
            var hashedRedeamScriptBuffer = initialLockingScript.chunks[1].buf;
            
            lockingScript.add(new bitcore.deps.Buffer(hashedRedeamScriptBuffer));
            lockingScript.add(new bitcore.deps.Buffer("OP_EQUAL"));

            //create unlocking script
            unlockingScript = new Script();            
            unlockingScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn"));
            unlockingScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn OP_EQUAL"));
            
            //verify unlocking and locking script
            var verified = bitcore.Script.Interpreter().verify(unlockingScript, lockingScript);
            
        }
        
        //create transactions using Bitcore
        function createTransaction(){            
            
            var prevTxId = new bitcore.deps.Buffer(g_utxos[0].txid);
            var outputIndex = g_utxos[0].vout
            var sequenceNumber = 4294967295;
            
            var param = {};
            param.prevTxId = prevTxId;
            param.outputIndex = outputIndex;
            param.sequenceNumber = sequenceNumber;
            param.script = unlockingScript;
            var input = new bitcore.Transaction.Input(param);
            
            var transaction = new bitcore.Transaction();
            transaction = transaction.fee(0.0001*100000000);
            transaction = transaction.to(toAddress, amount);
            transaction = transaction.addInput(input, unlockingScript, 1000000);
            
            var verify = transaction.verify();
            
            return transaction;
        }
        
        //serialize transaction using Bitcore
        function serialize(transaction){
            
            var flags = {};
            flags.disableAll = true;    

            var serializedTransaction = transaction.serialize(flags);
            return serializedTransaction;
            
        }
        
        //broadcast transaction using Bitcore
        function broadcast(transaction){
            
            var Insight = require('bitcore-explorers').Insight;
            var insight = new Insight("https://test-insight.bitpay.com", "testnet");

            insight.broadcast(transaction, function(err, returnedTxId){
                if (err) {
                    console.log(err);
                } else {
                    console.log(returnedTxId);
                }
            });
        }

    </script>
    
</body>
</html>

Hey @tester! Thanks for the detailed explanation. I’m checking your example out, will report back when I have more info

I tried broadcasting this serialized transaction using bitcoin-qt -testnet.

The result of serialize() with the disableAll flag is:

0100000001303466666537656339623830303134656266306437653836316431313866653365643934626139623836313435646165623866383637663931393337353062630000000033143837506d75365368374c3841476737456533646e1d3837506d75365368374c3841476737456533646e204f505f455155414cffffffff01301b0f00000000001976a914e07262f023181c46a67a3bebd610adae861fb01888ac00000000

When I try in bitcoin-qt -testnet:

    sendrawtransaction 0100000001303466666537656339623830303134656266306437653836316431313866653365643934626139623836313435646165623866383637663931393337353062630000000033143837506d75365368374c3841476737456533646e1d3837506d75365368374c3841476737456533646e204f505f455155414cffffffff01301b0f00000000001976a914e07262f023181c46a67a3bebd610adae861fb01888ac00000000

I get:

> TX decode failed (code -22)

Which is the same error message what I got as a response from the insight server.

The post response from the insight server:

POST https://test-insight.bitpay.com/api/tx/send 400 Bad Request
Response: TX decode failed (code -22)

I also tried:

> decoderawtransaction 0100000001303466666537656339623830303134656266306437653836316431313866653365643934626139623836313435646165623866383637663931393337353062630000000033143837506d75365368374c3841476737456533646e1d3837506d75365368374c3841476737456533646e204f505f455155414cffffffff01301b0f00000000001976a914e07262f023181c46a67a3bebd610adae861fb01888ac00000000

which also returns the same error message:

TX decode failed (code -22)

Looks like the problem could be with serialize().

Alternatively there may be an issue making the scripts or transaction but this seems less likely because:

In case it helps. I looked up the error message in Bitcoin Core’s source code and found it here:
bitcoin/rpcrawtransaction.cpp on Github

Thanks

OK, first problem I found: you’re building the scripts incorrectly:

redeamScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn OP_EQUAL"));

This will create a string with the data you passed in the buffer. I guess you’re trying to use the OP_EQUAL opcode, but in that case you’re just using a OP_PUSHDATA with a string ‘OP_EQUAL’. You can verify this by printing the script to the console:

console.log(redeamScript.toString());
// outputs 29 0x3837506d75365368374c3841476737456533646e204f505f455155414c

What you want to do is:

var redeamScript = new Script();
redeamScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn"));
redeamScript.add("OP_EQUAL");
console.log(redeamScript.toString());
// outputs: 20 0x3837506d75365368374c3841476737456533646e OP_EQUAL

The same goes for all your other scripts. Please fix that and see if it now works

For more info see the Custom Scripts section of http://bitcore.io/guide/script.html

Thanks for your helpful reply.

I have rewritten the function that is creating my scripts so that it uses opcodes.
verify() is returning true.

I am get the same error message when serializing without true or the flag passed in.
I am getting the same three error messages when I try broadcasting.

So this has improved the scripts but it has not fix these error messages.

Further help is appreciated. Thanks

Here is the rewritten function that is creating the scripts:

function getScripts(){
    
    var Buffer = require('bitcore').Buffer;
    var Script = require('bitcore').Script;
    
    //create unlocking script
    unlockingScript = new Script();            
    unlockingScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn"));

    var lockingScript = new Script();
    lockingScript.add("OP_HASH160");
    lockingScript.add(new bitcore.deps.Buffer("87Pmu6Sh7L8AGg7Ee3dn"));        
    lockingScript.add("OP_HASH160");
    lockingScript.add("OP_EQUAL");
    
    //verify unlocking and locking script
    var verified = bitcore.Script.Interpreter().verify(unlockingScript, lockingScript);
    
}

It would help me a lot if you created a gist with the updated full code you’re running, so I can help you with the exact version, and be sure to be able to reproduce your problem (as I have in the previous case).

Here is a gist of the html page I am working with:

I think the problem with your lockingScript is that it is of type p2sh. This means the script interpreter will evaluate the data you’re hashing as a reedeemScript. Look at the additional rules for p2sh: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki

Here is a wrapup on this and related posts see:
manual-creation-of-custom-p2sh-transaction