Firme la transacción con múltiples entradas utilizando las bibliotecas bitcoinj/peercoinj

¡Buen día para todos! Tengo algunos problemas para agregar una entrada firmada a la transacción. Actualmente, estoy trabajando con la moneda altCoin (fork peercoin). Estoy tratando de construir la transacción de la siguiente manera:

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;
        }
}

Pero, desafortunadamente, la respuesta del servidor es:

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

Realmente probé muchas variantes de entradas firmadas de formación, pero supongo que todas son incorrectas.

Entiendo que la respuesta está cerca, pero estoy tratando de resolver este problema en unos pocos días.

Transmisión sin procesar:

0100000084160b5a06b7af2be1d54998ebb7c8c9a53f7aed8db3e26d6d4390b3a4d0e0f7713d5140b5010000006a473044022044d5754340df6eed9a9913e6e71e61a0db5b273918867f192ef66fc362eb50f2022045b24f8af67980c5eb4d064333559b1cc60116b445eb5d7b362bf5162351a41981210367c0f22210f87d68ec1be496cb77e765e4f097f2e3e9341b35fb87b44fcb8256ffffffffefa9337014abe2305c3b4ebe4108b90641d7ed1189ea261200bab95ef67b2787000000006b483045022100b15f66e1978463c0707d23604548088b6a8aa04e52d1f16077fc0419bcbdb7970220418b443f271fa65fa9abefabdc5fbeeb665bd4fd76c00e8d80c51c2a05c890cc812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256bffffffffaa0ff06a1aa85ded544b11108fa59a050c9e7d44a0d87b71fc380c08db7130ee000000006b483045022100b3d510e49df9e6909a1abfb7f572ffe4d112851a69177b8d37a759489e0b0832022044f6c10972cf0e0e73780f99f2619b0c2fe12a0dcd3fbe7ba7a3a6055d673f43812102fce3db7a30d9b67015b52072f73ea975ff974eecdfe8c251d102a704e84fbf34ffffffff99541005ef4fa5813282a5a3b7e50a9d4bcd2afa07c07554d1fbe964162b83d9010000006b483045022100ca4e49c7ff79cdca8feb263dc81b2dfc9e15023d9adfa41c0277f41bc67233fb022040a5d64b3ba4f9a5d76eac6170288e4f8517179e218bc9eb5e72fa5872dbf2808121027e5ac73196444c6a87346a82792f3b4205774bed31b1283036f4f501f8c028e0ffffffff99541005ef4fa5813282a5a3b7e50a9d4bcd2afa07c07554d1fbe964162b83d9000000006b483045022100bb676eb702e20df723522fef2eb5e8e34bf9913a5962f20ce0ebfb22ae5f338a02206ba74c4916b14485b587021971625b12c32fe69b3eab0901f1e364d0b6d0ff33812103f3f7a18e73f575cea92d3d809b2b94b6633644b0f904a01c7b7467d3c694244affffffff7f8deb0bb067bf208a83351a0cb16d2098bbdbf0cd6ea9db7db57fe4f6375eb3000000006b48304502210094c754cd072c04fd0cd7a369395d6f11b9f93141d9e501d8173107b6d08310950220022cd96b40729fa2093c966d202e4e21138e1b5ec8ef5b5735a1c214b479479d812103e046b0cd2efff59790fdeb54404a30f6c82b9a399be88e09e296752b6e0e256bffffffff0210eb0900000000001976a914213d84219682005ec3210b9c383869d44f12943388ac9e2f0000000000001976a91400b1647f6d3f171194e66f399eb6f6e526037ef988ac00000000

Analizando la transacción sin procesar a continuación:

{
"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"
]
}
}
]
}

¿Qué estoy haciendo mal?

¡Por favor ayuda!

¿Funcionaría esta altcoin con la misma estructura tx que bitcoin? Veo muchas palabras familiares, OP, claves... pero la estructura del tx sin procesar ensamblado se ve diferente. ¿Su peercoin bifurcado está usando una estructura tx diferente?
@pebwindkraft esta altcoin funciona con la misma estructura que peercoin. Pero hay una diferencia con la estructura tx de bitcoin: después de 4 bytes para el tiempo de bloqueo, también tiene 4 bytes para el momento de la creación del tx actual. Eso es todo.

Respuestas (2)

¡Buen día! Finalmente encontré una solución, espero que le sea útil a alguien.

El problema fue que traté de firmar entradas antes de agregar salidas y otra información a la transacción. Así que ahora agrego entradas con método addInput(). Antes lo hacía con addSignedInput()método. Después de agregar todas las entradas y salidas en mi TX, trato de firmar cada entrada manualmente:

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));
    }
}

Así que eso es todo. Y, por supuesto, después de eso serializo el tx actual y lo transmito.

Pongo mi comentario aquí, porque no puedo formatear en la sección de comentarios. Descompuse el tx sin procesar y vi unos cuatro bytes después de la versión. Me sale esto hasta la primera firma:

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
#########################################################

Dado que el resto debería ser similar a bitcoin, no puedo encontrar un código de operación "01" para terminar la firma. Aquí tiene hexadecimal 0x81 en su lugar. Quizás esa sea otra diferencia. También he "revisado estrictamente" las firmas en busca de valores incorrectos de R o S, pero eso también está bien. Hasta ahora, eso es todo lo que puedo hacer... ¿Quizás tratar de reducir el tx a una entrada y salida y asegurarme de usar el par de claves de privacidad/pub correcto?

Muchas gracias por su respuesta, pero no es lo que estaba buscando. Encontré una solución y la pondré en la respuesta.