3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Transaction: Fix hashForSignature() by making sure no witnesses get into the sighash and old serialization is forced.

This commit is contained in:
Andreas Schildbach 2019-02-18 22:42:41 +01:00
parent e68a24e6bc
commit ff76b50ae2
2 changed files with 12 additions and 3 deletions

View File

@ -1161,7 +1161,9 @@ public class Transaction extends ChildMessage {
// transaction that step isn't very helpful, but it doesn't add much cost relative to the actual // transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
// EC math so we'll do it anyway. // EC math so we'll do it anyway.
for (int i = 0; i < tx.inputs.size(); i++) { for (int i = 0; i < tx.inputs.size(); i++) {
tx.inputs.get(i).clearScriptBytes(); TransactionInput input = tx.inputs.get(i);
input.clearScriptBytes();
input.setWitness(null);
} }
// This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR // This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR
@ -1217,8 +1219,8 @@ public class Transaction extends ChildMessage {
tx.inputs.add(input); tx.inputs.add(input);
} }
ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(tx.length == UNKNOWN_LENGTH ? 256 : tx.length + 4); ByteArrayOutputStream bos = new ByteArrayOutputStream(tx.length);
tx.bitcoinSerialize(bos); tx.bitcoinSerializeToStream(bos, false);
// We also have to write a hash type (sigHashType is actually an unsigned char) // We also have to write a hash type (sigHashType is actually an unsigned char)
uint32ToByteStreamLE(0x000000ff & sigHashType, bos); uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
// Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out

View File

@ -337,6 +337,8 @@ public class TransactionTest {
assertEquals("00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1", HEX.encode(scriptPubKey1.getProgram())); assertEquals("00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1", HEX.encode(scriptPubKey1.getProgram()));
txIn1.connect(new TransactionOutput(TESTNET, null, Coin.COIN.multiply(6), scriptPubKey1.getProgram())); txIn1.connect(new TransactionOutput(TESTNET, null, Coin.COIN.multiply(6), scriptPubKey1.getProgram()));
assertEquals("63cec688ee06a91e913875356dd4dea2f8e0f2a2659885372da2a37e32c7532e",
tx.hashForSignature(0, scriptPubKey0, Transaction.SigHash.ALL, false).toString());
TransactionSignature txSig0 = tx.calculateSignature(0, key0, TransactionSignature txSig0 = tx.calculateSignature(0, key0,
scriptPubKey0, scriptPubKey0,
Transaction.SigHash.ALL, false); Transaction.SigHash.ALL, false);
@ -347,6 +349,8 @@ public class TransactionTest {
assertEquals("1976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac", assertEquals("1976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac",
HEX.encode(scriptCode.getProgram())); HEX.encode(scriptCode.getProgram()));
assertEquals("c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670",
tx.hashForSignatureWitness(1, scriptCode, txIn1.getValue(), Transaction.SigHash.ALL, false).toString());
TransactionSignature txSig1 = tx.calculateWitnessSignature(1, key1, TransactionSignature txSig1 = tx.calculateWitnessSignature(1, key1,
scriptCode, txIn1.getValue(), scriptCode, txIn1.getValue(),
Transaction.SigHash.ALL, false); Transaction.SigHash.ALL, false);
@ -421,6 +425,9 @@ public class TransactionTest {
assertEquals("1976a91479091972186c449eb1ded22b78e40d009bdf008988ac", assertEquals("1976a91479091972186c449eb1ded22b78e40d009bdf008988ac",
HEX.encode(scriptCode.getProgram())); HEX.encode(scriptCode.getProgram()));
assertEquals("64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6",
tx.hashForSignatureWitness(0, scriptCode, Coin.COIN.multiply(10), Transaction.SigHash.ALL, false)
.toString());
TransactionSignature txSig = tx.calculateWitnessSignature(0, key, TransactionSignature txSig = tx.calculateWitnessSignature(0, key,
scriptCode, Coin.COIN.multiply(10), scriptCode, Coin.COIN.multiply(10),
Transaction.SigHash.ALL, false); Transaction.SigHash.ALL, false);