|
|
@ -57,16 +57,10 @@ class TxnMallTest(BitcoinTestFramework):
|
|
|
|
clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}]
|
|
|
|
clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}]
|
|
|
|
clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"],
|
|
|
|
clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"],
|
|
|
|
rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]}
|
|
|
|
rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]}
|
|
|
|
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs)
|
|
|
|
clone_locktime = rawtx1["locktime"]
|
|
|
|
|
|
|
|
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)
|
|
|
|
|
|
|
|
|
|
|
|
# 3 hex manipulations on the clone are required
|
|
|
|
# createrawtransaction randomizes the order of its outputs, so swap them if necessary.
|
|
|
|
|
|
|
|
|
|
|
|
# manipulation 1. sequence is at version+#inputs+input+sigstub
|
|
|
|
|
|
|
|
posseq = 2*(4+1+36+1)
|
|
|
|
|
|
|
|
seqbe = '%08x' % rawtx1["vin"][0]["sequence"]
|
|
|
|
|
|
|
|
clone_raw = clone_raw[:posseq] + seqbe[6:8] + seqbe[4:6] + seqbe[2:4] + seqbe[0:2] + clone_raw[posseq + 8:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# manipulation 2. createrawtransaction randomizes the order of its outputs, so swap them if necessary.
|
|
|
|
|
|
|
|
# output 0 is at version+#inputs+input+sigstub+sequence+#outputs
|
|
|
|
# output 0 is at version+#inputs+input+sigstub+sequence+#outputs
|
|
|
|
# 40 BTC serialized is 00286bee00000000
|
|
|
|
# 40 BTC serialized is 00286bee00000000
|
|
|
|
pos0 = 2*(4+1+36+1+4+1)
|
|
|
|
pos0 = 2*(4+1+36+1+4+1)
|
|
|
@ -78,11 +72,6 @@ class TxnMallTest(BitcoinTestFramework):
|
|
|
|
output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len]
|
|
|
|
output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len]
|
|
|
|
clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:]
|
|
|
|
clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:]
|
|
|
|
|
|
|
|
|
|
|
|
# manipulation 3. locktime is after outputs
|
|
|
|
|
|
|
|
poslt = pos0 + 2 * output_len
|
|
|
|
|
|
|
|
ltbe = '%08x' % rawtx1["locktime"]
|
|
|
|
|
|
|
|
clone_raw = clone_raw[:poslt] + ltbe[6:8] + ltbe[4:6] + ltbe[2:4] + ltbe[0:2] + clone_raw[poslt + 8:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
|
|
|
|
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
|
|
|
|
# Don't send the clone anywhere yet
|
|
|
|
# Don't send the clone anywhere yet
|
|
|
|
tx1_clone = self.nodes[0].signrawtransaction(clone_raw, None, None, "ALL|ANYONECANPAY")
|
|
|
|
tx1_clone = self.nodes[0].signrawtransaction(clone_raw, None, None, "ALL|ANYONECANPAY")
|
|
|
|