Sign transaction with multiple inputs using bitcoinj/peercoinj libraries

0

1

Good day for everyone! I have some troubles with adding signed Input to the transaction. Currently, I'm working with altCoin (fork peercoin) currency. I'm trying build the transaction in the following way:

for (UTXO utxo : mUTXOs) {

        if (!done) {
            utxosValue += utxo.getValue().longValue();

            TransactionOutPoint outPoint = new TransactionOutPoint(params, utxo.getIndex(), utxo.getHash());
            byte[] privKeyBytes = HEX.decode(privKeyAsHex);
            ECKey ecKey = ECKey.fromPrivate(privKeyBytes);


            transaction.addSignedInput(outPoint, utxo.getScript(), ecKey, Transaction.SigHash.ALL, true);

            //here is adding outputs
            ....
            ....

            //serialization of the transaction and getting raw transaction
            byte[] bytesRawTransaction = transaction.peercoinSerialize();
            String rawTransaction = HEX.encode(bytesRawTransaction);

            // and here is broadcasting
            ....
            ....

            done = true;
        }
}

But, unfortunately, the server response is :

16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)

I really tried a lot of variants of formation signedInputs, but all of them are incorrect I guess.

I understand that the answer is close, but I'm trying to solve this problem near few days.

Raw Tx:

0100000084160b5a06b7af2be1d54998ebb7c8c9a53f7aed8db3e26d6d4390b3a4d0e0f7713d5140b5010000006a473044022044d5754340df6eed9a9913e6e71e61a0db5b273918867f192ef66fc362eb50f2022045b24f8af67980c5eb4d064333559b1cc60116b445eb5d7b362bf5162351a41981210367c0f22210f87d68ec1be496cb77e765e4f097f2e3e9341b35fb87b44fcb8256ffffffffefa9337014abe2305c3b4ebe4108b90641d7ed1189ea261200bab95ef67b2787000000006b483045022100b15f66e1978463c0707d23604548088b6a8aa04e52d1f16077fc0419bcbdb7970220418b443f271fa65fa9abefabdc5fbeeb665bd4fd76c00e8d80c51c2a05c890cc812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256bffffffffaa0ff06a1aa85ded544b11108fa59a050c9e7d44a0d87b71fc380c08db7130ee000000006b483045022100b3d510e49df9e6909a1abfb7f572ffe4d112851a69177b8d37a759489e0b0832022044f6c10972cf0e0e73780f99f2619b0c2fe12a0dcd3fbe7ba7a3a6055d673f43812102fce3db7a30d9b67015b52072f73ea975ff974eecdfe8c251d102a704e84fbf34ffffffff99541005ef4fa5813282a5a3b7e50a9d4bcd2afa07c07554d1fbe964162b83d9010000006b483045022100ca4e49c7ff79cdca8feb263dc81b2dfc9e15023d9adfa41c0277f41bc67233fb022040a5d64b3ba4f9a5d76eac6170288e4f8517179e218bc9eb5e72fa5872dbf2808121027e5ac73196444c6a87346a82792f3b4205774bed31b1283036f4f501f8c028e0ffffffff99541005ef4fa5813282a5a3b7e50a9d4bcd2afa07c07554d1fbe964162b83d9000000006b483045022100bb676eb702e20df723522fef2eb5e8e34bf9913a5962f20ce0ebfb22ae5f338a02206ba74c4916b14485b587021971625b12c32fe69b3eab0901f1e364d0b6d0ff33812103f3f7a18e73f575cea92d3d809b2b94b6633644b0f904a01c7b7467d3c694244affffffff7f8deb0bb067bf208a83351a0cb16d2098bbdbf0cd6ea9db7db57fe4f6375eb3000000006b48304502210094c754cd072c04fd0cd7a369395d6f11b9f93141d9e501d8173107b6d08310950220022cd96b40729fa2093c966d202e4e21138e1b5ec8ef5b5735a1c214b479479d812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256bffffffff0210eb0900000000001976a914213d84219682005ec3210b9c383869d44f12943388ac9e2f0000000000001976a91400b1647f6d3f171194e66f399eb6f6e526037ef988ac00000000

Parsing raw transaction below:

{
"txid": "d2407dd195c6367f037c2c5a97ccff8b38aa246ce405a6fc1cb3132f59b92210",
"version": 1,
"locktime": 0,
"time": 1510676100,
"vin": [
{
"txid": "b540513d71f7e0d0a4b390436d6de2b38ded7a3fa5c9c8b7eb9849d5e12bafb7",
"vout": 1,
"scriptSig": {
"asm": "3044022044d5754340df6eed9a9913e6e71e61a0db5b273918867f192ef66fc362eb50f2022045b24f8af67980c5eb4d064333559b1cc60116b445eb5d7b362bf5162351a41981 0367c0f22210f87d68ec1be496cb77e765e4f097f2e3e9341b35fb87b44fcb8256",
"hex": "473044022044d5754340df6eed9a9913e6e71e61a0db5b273918867f192ef66fc362eb50f2022045b24f8af67980c5eb4d064333559b1cc60116b445eb5d7b362bf5162351a41981210367c0f22210f87d68ec1be496cb77e765e4f097f2e3e9341b35fb87b44fcb8256"
},
"sequence": 4294967295
}, 
{
"txid": "87277bf65eb9ba001226ea8911edd74106b90841be4e3b5c30e2ab147033a9ef",
"vout": 0,
"scriptSig": {
"asm": "3045022100b15f66e1978463c0707d23604548088b6a8aa04e52d1f16077fc0419bcbdb7970220418b443f271fa65fa9abefabdc5fbeeb665bd4fd76c00e8d80c51c2a05c890cc81 03e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256b",
"hex": "483045022100b15f66e1978463c0707d23604548088b6a8aa04e52d1f16077fc0419bcbdb7970220418b443f271fa65fa9abefabdc5fbeeb665bd4fd76c00e8d80c51c2a05c890cc812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256b"
},
"sequence": 4294967295
}, 
{
"txid": "ee3071db080c38fc717bd8a0447d9e0c059aa58f10114b54ed5da81a6af00faa",
"vout": 0,
"scriptSig": {
"asm": "3045022100b3d510e49df9e6909a1abfb7f572ffe4d112851a69177b8d37a759489e0b0832022044f6c10972cf0e0e73780f99f2619b0c2fe12a0dcd3fbe7ba7a3a6055d673f4381 02fce3db7a30d9b67015b52072f73ea975ff974eecdfe8c251d102a704e84fbf34",
"hex": "483045022100b3d510e49df9e6909a1abfb7f572ffe4d112851a69177b8d37a759489e0b0832022044f6c10972cf0e0e73780f99f2619b0c2fe12a0dcd3fbe7ba7a3a6055d673f43812102fce3db7a30d9b67015b52072f73ea975ff974eecdfe8c251d102a704e84fbf34"
},
"sequence": 4294967295
}, 
{
"txid": "d9832b1664e9fbd15475c007fa2acd4b9d0ae5b7a3a5823281a54fef05105499",
"vout": 1,
"scriptSig": {
"asm": "3045022100ca4e49c7ff79cdca8feb263dc81b2dfc9e15023d9adfa41c0277f41bc67233fb022040a5d64b3ba4f9a5d76eac6170288e4f8517179e218bc9eb5e72fa5872dbf28081 027e5ac73196444c6a87346a82792f3b4205774bed31b1283036f4f501f8c028e0",
"hex": "483045022100ca4e49c7ff79cdca8feb263dc81b2dfc9e15023d9adfa41c0277f41bc67233fb022040a5d64b3ba4f9a5d76eac6170288e4f8517179e218bc9eb5e72fa5872dbf2808121027e5ac73196444c6a87346a82792f3b4205774bed31b1283036f4f501f8c028e0"
},
"sequence": 4294967295
}, 
{
"txid": "d9832b1664e9fbd15475c007fa2acd4b9d0ae5b7a3a5823281a54fef05105499",
"vout": 0,
"scriptSig": {
"asm": "3045022100bb676eb702e20df723522fef2eb5e8e34bf9913a5962f20ce0ebfb22ae5f338a02206ba74c4916b14485b587021971625b12c32fe69b3eab0901f1e364d0b6d0ff3381 03f3f7a18e73f575cea92d3d809b2b94b6633644b0f904a01c7b7467d3c694244a",
"hex": "483045022100bb676eb702e20df723522fef2eb5e8e34bf9913a5962f20ce0ebfb22ae5f338a02206ba74c4916b14485b587021971625b12c32fe69b3eab0901f1e364d0b6d0ff33812103f3f7a18e73f575cea92d3d809b2b94b6633644b0f904a01c7b7467d3c694244a"
},
"sequence": 4294967295
}, 
{
"txid": "b35e37f6e47fb57ddba96ecdf0dbbb98206db10c1a35838a20bf67b00beb8d7f",
"vout": 0,
"scriptSig": {
"asm": "304502210094c754cd072c04fd0cd7a369395d6f11b9f93141d9e501d8173107b6d08310950220022cd96b40729fa2093c966d202e4e21138e1b5ec8ef5b5735a1c214b479479d81 03e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256b",
"hex": "48304502210094c754cd072c04fd0cd7a369395d6f11b9f93141d9e501d8173107b6d08310950220022cd96b40729fa2093c966d202e4e21138e1b5ec8ef5b5735a1c214b479479d812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256b"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.650000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 213d84219682005ec3210b9c383869d44f129433 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914213d84219682005ec3210b9c383869d44f12943388ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"ELBfV8YApvz34RUkaYQ5XP7LLyJxZh7qZu"
]
}
}, 
{
"value": 0.012190,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 00b1647f6d3f171194e66f399eb6f6e526037ef9 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a91400b1647f6d3f171194e66f399eb6f6e526037ef988ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"EHDa133N3U9Q1a3Pwib21xLTcHHVihCDsd"
]
}
}
]
}

What I'm doing wrong?

Please, help!

Timur Panzhiev

Posted 2017-11-14T16:45:28.067

Reputation: 21

would this altcoin work with the same tx structure as bitcoin? I see many familiar words, OPs, keys... but the strucure of the assembled raw tx looks different. Is your forked peercoin using a different tx structure?pebwindkraft 2017-11-14T21:30:55.087

@pebwindkraft this altcoin work with the same structure as peercoin. But have one difference with bitcoin tx structure - after 4 bytes for locktime it has also 4 bytes for time of creation current tx. That's all.Timur Panzhiev 2017-11-15T08:35:45.380

Answers

2

Good day! Finally I found a solution, I hope it will useful to someone.

The problem was that I tried to sign inputs before adding outputs and other info into transaction. So now I add inputs with method addInput(). Before I did it with addSignedInput() method. After adding all inputs and outputs in my TX I try to sign every input manually:

for (int i = 0; i < transaction.getInputs().size(); i++) {
    TransactionInput transactionInput = transaction.getInput(i);
    byte[] privKeyBytes = HEX.decode(privKeyHex);
    ECKey ecKey = ECKey.fromPrivate(privKeyBytes);

    Script scriptPubKey = ScriptBuilder.createOutputScript(Address.fromBase58(params, mUTXOs.get(i).getAddress()));

    Sha256Hash hash = transaction.hashForSignature(i, scriptPubKey, Transaction.SigHash.ALL, true);
    ECKey.ECDSASignature ecSig = ecKey.sign(hash);
    TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, true);
    if (scriptPubKey.isSentToRawPubKey()) {
        transactionInput1.setScriptSig(ScriptBuilder.createInputScript(txSig));
    } else {
        if (!scriptPubKey.isSentToAddress()) {
            throw new ScriptException("Don\'t know how to sign for this kind of scriptPubKey: " + scriptPubKey);
        }
    transactionInput.setScriptSig(ScriptBuilder.createInputScript(txSig, ecKey));
    }
}

So that is it. And of course after that I serialize current tx and broadcast it.

Timur Panzhiev

Posted 2017-11-14T16:45:28.067

Reputation: 21

0

I put my comment here, cause can't format in the comments section. I decomposed the raw tx, and see some four bytes after the version. I get this up to the first signature:

VERSION
 01000000
Data(?) 84160b5a
TX_IN COUNT [var_int]: hex=06, decimal=6
 TX_IN[0]
  TX_IN[0] OutPoint hash (char[32])
  B540513D71F7E0D0A4B390436D6DE2B38DED7A3FA5C9C8B7EB9849D5E12BAFB7
  TX_IN[0] OutPoint index (uint32_t)
  hex=01000000, reversed=00000001, decimal=1
  TX_IN[0] Script Length (var_int)
  hex=6A, decimal=106
  TX_IN[0] Script Sig (uchar[])
  473044022044D5754340DF6EED9A9913E6E71E61A0DB5B273918867F192EF66FC362EB50F2022045B24F8AF67980C5EB4D064333559B1CC60116B445EB5D7B362BF5162351A41981210367C0F22210F87D68EC1BE496CB77E765E4F097F2E3E9341B35FB87B44FCB8256 
  ##################################################################
  ### tcls_in_sig_script.sh: decode SIG_script OPCODES from a TX ###
  ##################################################################
    47: OP_DATA_0x47:        push hex 47 (decimal 71) bytes on stack
    30: OP_SEQUENCE_0x30:    type tag indicating SEQUENCE, begin sigscript
    44: OP_LENGTH_0x44:      length of R + S
    02: OP_INT_0x02:         type tag INTEGER indicating length
    20: OP_LENGTH_0x20:      this is SIG R (32 Bytes)
        44D5754340DF6EED:9A9913E6E71E61A0
        DB5B273918867F19:2EF66FC362EB50F2
    02: OP_INT_0x02:         type tag INTEGER indicating length
    20: OP_LENGTH_0x20:      this is SIG S (32 Bytes)
        45B24F8AF67980C5:EB4D064333559B1C
        C60116B445EB5D7B:362BF5162351A419
    81: unknown opcode 
    21: OP_DATA_0x21:        length compressed Public Key (X9.63 form, 33 Bytes)
        0367C0F22210F87D:68EC1BE496CB77E7
        65E4F097F2E3E934:1B35FB87B44FCB82
        56
#########################################################
### procedure to strictly check DER-encoded signature ###
#########################################################
Minimum and maximum size constraints                        - ok
scriptsig always starts with 0x30                           - ok
length 138 chars is less than actual sig length (144 chars) - ok
       (hex 0x45, decimal 69, 138 chars)
length of R coordinate (66) >= 0                            - ok
length of S coordinate (64) >= 0                            - ok
S-Value is within scriptsig boundaries                      - ok
Make sure the R & S length covers the entire signature      - ok
checking R-value is less than N/2, R-value is zero padded   - ok
checking S-value is less than N/2, yup...                   - ok
strictly check DER-encoded signature                        - ok
#########################################################

Given that the rest should be similar to bitcoin, I cannot find a "01" opcode to terminate the signature. Here it has hex 0x81 at it's place. Maybe that's another difference. I have also "strictly checked" the signatures for wrong R or S values, but that's ok as well. So far that's all I can do... Maybe try to reduce the tx to one input and output and make sure using the right privacy/pub key pair?

pebwindkraft

Posted 2017-11-14T16:45:28.067

Reputation: 4 568

Thnx a lot for your reply, but it is not what I was looking for. I found a solution and will put it in the answer.Timur Panzhiev 2017-11-23T09:28:34.243