Ensure "OP_0" and "false" have the same represenstation on stack

During the script execution via `executeScript()` certain operations
add boolean values to the stack.

Boolean values, which are added to the stack as result, are represented
as follows in Bitcoin Core:

- `true`: as vector with one element: `[1]`
- `false`: as empty vector with zero elements: `[]`

See:

- 48efbdbe98/src/script/interpreter.cpp (L244)
- 48efbdbe98/src/script/interpreter.cpp (L246)

However, in BitcoinJ the representation of `false` differs in some
cases, where it is represented as Byte array with one element, which
is zero: `[0]`

See:

- `OP_EQUAL`: 5dcf643975/core/src/main/java/org/bitcoinj/script/Script.java (L1025)
- `OP_CHECKSIG`: 5dcf643975/core/src/main/java/org/bitcoinj/script/Script.java (L1304)
- `OP_CHECKMULTISIG`: 5dcf643975/core/src/main/java/org/bitcoinj/script/Script.java (L1381)

At minimum this has an impact on the behavior of `OP_EQUAL` and
`OP_EQUALVERIFY`, when comparing something with `OP_FALSE`/`OP_0`.

This commit attemps to fix the issue, to mirror the verification
behavior of Bitcoin Core, by adding empty Byte arrays to the stack,
instead of Byte arrays with `0`.
This commit is contained in:
dexX7
2015-09-30 00:11:00 +02:00
parent 9b860f14de
commit a3d378bae6

View File

@@ -1022,7 +1022,7 @@ public class Script {
case OP_EQUAL:
if (stack.size() < 2)
throw new ScriptException("Attempted OP_EQUALVERIFY on a stack with size < 2");
stack.add(Arrays.equals(stack.pollLast(), stack.pollLast()) ? new byte[] {1} : new byte[] {0});
stack.add(Arrays.equals(stack.pollLast(), stack.pollLast()) ? new byte[] {1} : new byte[] {});
break;
case OP_EQUALVERIFY:
if (stack.size() < 2)
@@ -1301,7 +1301,7 @@ public class Script {
}
if (opcode == OP_CHECKSIG)
stack.add(sigValid ? new byte[] {1} : new byte[] {0});
stack.add(sigValid ? new byte[] {1} : new byte[] {});
else if (opcode == OP_CHECKSIGVERIFY)
if (!sigValid)
throw new ScriptException("Script failed OP_CHECKSIGVERIFY");
@@ -1378,7 +1378,7 @@ public class Script {
throw new ScriptException("OP_CHECKMULTISIG(VERIFY) with non-null nulldummy: " + Arrays.toString(nullDummy));
if (opcode == OP_CHECKMULTISIG) {
stack.add(valid ? new byte[] {1} : new byte[] {0});
stack.add(valid ? new byte[] {1} : new byte[] {});
} else if (opcode == OP_CHECKMULTISIGVERIFY) {
if (!valid)
throw new ScriptException("Script failed OP_CHECKMULTISIGVERIFY");