|
|
|
@ -54,32 +54,6 @@ bool CastToBool(const valtype& vch)
@@ -54,32 +54,6 @@ bool CastToBool(const valtype& vch)
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// WARNING: This does not work as expected for signed integers; the sign-bit
|
|
|
|
|
// is left in place as the integer is zero-extended. The correct behavior
|
|
|
|
|
// would be to move the most significant bit of the last byte during the
|
|
|
|
|
// resize process. MakeSameSize() is currently only used by the disabled
|
|
|
|
|
// opcodes OP_AND, OP_OR, and OP_XOR.
|
|
|
|
|
//
|
|
|
|
|
void MakeSameSize(valtype& vch1, valtype& vch2) |
|
|
|
|
{ |
|
|
|
|
// Lengthen the shorter one
|
|
|
|
|
if (vch1.size() < vch2.size()) |
|
|
|
|
// PATCH:
|
|
|
|
|
// +unsigned char msb = vch1[vch1.size()-1];
|
|
|
|
|
// +vch1[vch1.size()-1] &= 0x7f;
|
|
|
|
|
// vch1.resize(vch2.size(), 0);
|
|
|
|
|
// +vch1[vch1.size()-1] = msb;
|
|
|
|
|
vch1.resize(vch2.size(), 0); |
|
|
|
|
if (vch2.size() < vch1.size()) |
|
|
|
|
// PATCH:
|
|
|
|
|
// +unsigned char msb = vch2[vch2.size()-1];
|
|
|
|
|
// +vch2[vch2.size()-1] &= 0x7f;
|
|
|
|
|
// vch2.resize(vch1.size(), 0);
|
|
|
|
|
// +vch2[vch2.size()-1] = msb;
|
|
|
|
|
vch2.resize(vch1.size(), 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
@ -361,7 +335,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -361,7 +335,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
opcode == OP_MOD || |
|
|
|
|
opcode == OP_LSHIFT || |
|
|
|
|
opcode == OP_RSHIFT) |
|
|
|
|
return false; |
|
|
|
|
return false; // Disabled opcodes.
|
|
|
|
|
|
|
|
|
|
if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) |
|
|
|
|
stack.push_back(vchPushValue); |
|
|
|
@ -659,64 +633,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -659,64 +633,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Splice ops
|
|
|
|
|
//
|
|
|
|
|
case OP_CAT: |
|
|
|
|
{ |
|
|
|
|
// (x1 x2 -- out)
|
|
|
|
|
if (stack.size() < 2) |
|
|
|
|
return false; |
|
|
|
|
valtype& vch1 = stacktop(-2); |
|
|
|
|
valtype& vch2 = stacktop(-1); |
|
|
|
|
vch1.insert(vch1.end(), vch2.begin(), vch2.end()); |
|
|
|
|
popstack(stack); |
|
|
|
|
if (stacktop(-1).size() > MAX_SCRIPT_ELEMENT_SIZE) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_SUBSTR: |
|
|
|
|
{ |
|
|
|
|
// (in begin size -- out)
|
|
|
|
|
if (stack.size() < 3) |
|
|
|
|
return false; |
|
|
|
|
valtype& vch = stacktop(-3); |
|
|
|
|
int nBegin = CastToBigNum(stacktop(-2)).getint(); |
|
|
|
|
int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); |
|
|
|
|
if (nBegin < 0 || nEnd < nBegin) |
|
|
|
|
return false; |
|
|
|
|
if (nBegin > (int)vch.size()) |
|
|
|
|
nBegin = vch.size(); |
|
|
|
|
if (nEnd > (int)vch.size()) |
|
|
|
|
nEnd = vch.size(); |
|
|
|
|
vch.erase(vch.begin() + nEnd, vch.end()); |
|
|
|
|
vch.erase(vch.begin(), vch.begin() + nBegin); |
|
|
|
|
popstack(stack); |
|
|
|
|
popstack(stack); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_LEFT: |
|
|
|
|
case OP_RIGHT: |
|
|
|
|
{ |
|
|
|
|
// (in size -- out)
|
|
|
|
|
if (stack.size() < 2) |
|
|
|
|
return false; |
|
|
|
|
valtype& vch = stacktop(-2); |
|
|
|
|
int nSize = CastToBigNum(stacktop(-1)).getint(); |
|
|
|
|
if (nSize < 0) |
|
|
|
|
return false; |
|
|
|
|
if (nSize > (int)vch.size()) |
|
|
|
|
nSize = vch.size(); |
|
|
|
|
if (opcode == OP_LEFT) |
|
|
|
|
vch.erase(vch.begin() + nSize, vch.end()); |
|
|
|
|
else |
|
|
|
|
vch.erase(vch.begin(), vch.end() - nSize); |
|
|
|
|
popstack(stack); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_SIZE: |
|
|
|
|
{ |
|
|
|
|
// (in -- in size)
|
|
|
|
@ -731,51 +647,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -731,51 +647,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
//
|
|
|
|
|
// Bitwise logic
|
|
|
|
|
//
|
|
|
|
|
case OP_INVERT: |
|
|
|
|
{ |
|
|
|
|
// (in - out)
|
|
|
|
|
if (stack.size() < 1) |
|
|
|
|
return false; |
|
|
|
|
valtype& vch = stacktop(-1); |
|
|
|
|
for (unsigned int i = 0; i < vch.size(); i++) |
|
|
|
|
vch[i] = ~vch[i]; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// WARNING: These disabled opcodes exhibit unexpected behavior
|
|
|
|
|
// when used on signed integers due to a bug in MakeSameSize()
|
|
|
|
|
// [see definition of MakeSameSize() above].
|
|
|
|
|
//
|
|
|
|
|
case OP_AND: |
|
|
|
|
case OP_OR: |
|
|
|
|
case OP_XOR: |
|
|
|
|
{ |
|
|
|
|
// (x1 x2 - out)
|
|
|
|
|
if (stack.size() < 2) |
|
|
|
|
return false; |
|
|
|
|
valtype& vch1 = stacktop(-2); |
|
|
|
|
valtype& vch2 = stacktop(-1); |
|
|
|
|
MakeSameSize(vch1, vch2); // <-- NOT SAFE FOR SIGNED VALUES
|
|
|
|
|
if (opcode == OP_AND) |
|
|
|
|
{ |
|
|
|
|
for (unsigned int i = 0; i < vch1.size(); i++) |
|
|
|
|
vch1[i] &= vch2[i]; |
|
|
|
|
} |
|
|
|
|
else if (opcode == OP_OR) |
|
|
|
|
{ |
|
|
|
|
for (unsigned int i = 0; i < vch1.size(); i++) |
|
|
|
|
vch1[i] |= vch2[i]; |
|
|
|
|
} |
|
|
|
|
else if (opcode == OP_XOR) |
|
|
|
|
{ |
|
|
|
|
for (unsigned int i = 0; i < vch1.size(); i++) |
|
|
|
|
vch1[i] ^= vch2[i]; |
|
|
|
|
} |
|
|
|
|
popstack(stack); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_EQUAL: |
|
|
|
|
case OP_EQUALVERIFY: |
|
|
|
|
//case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
|
|
|
|
@ -810,8 +681,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -810,8 +681,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
//
|
|
|
|
|
case OP_1ADD: |
|
|
|
|
case OP_1SUB: |
|
|
|
|
case OP_2MUL: |
|
|
|
|
case OP_2DIV: |
|
|
|
|
case OP_NEGATE: |
|
|
|
|
case OP_ABS: |
|
|
|
|
case OP_NOT: |
|
|
|
@ -825,8 +694,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -825,8 +694,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
{ |
|
|
|
|
case OP_1ADD: bn += bnOne; break; |
|
|
|
|
case OP_1SUB: bn -= bnOne; break; |
|
|
|
|
case OP_2MUL: bn <<= 1; break; |
|
|
|
|
case OP_2DIV: bn >>= 1; break; |
|
|
|
|
case OP_NEGATE: bn = -bn; break; |
|
|
|
|
case OP_ABS: if (bn < bnZero) bn = -bn; break; |
|
|
|
|
case OP_NOT: bn = (bn == bnZero); break; |
|
|
|
@ -840,11 +707,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -840,11 +707,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
|
|
|
|
|
case OP_ADD: |
|
|
|
|
case OP_SUB: |
|
|
|
|
case OP_MUL: |
|
|
|
|
case OP_DIV: |
|
|
|
|
case OP_MOD: |
|
|
|
|
case OP_LSHIFT: |
|
|
|
|
case OP_RSHIFT: |
|
|
|
|
case OP_BOOLAND: |
|
|
|
|
case OP_BOOLOR: |
|
|
|
|
case OP_NUMEQUAL: |
|
|
|
@ -873,33 +735,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
@@ -873,33 +735,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
|
|
|
|
bn = bn1 - bn2; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_MUL: |
|
|
|
|
if (!BN_mul(&bn, &bn1, &bn2, pctx)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_DIV: |
|
|
|
|
if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_MOD: |
|
|
|
|
if (!BN_mod(&bn, &bn1, &bn2, pctx)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_LSHIFT: |
|
|
|
|
if (bn2 < bnZero || bn2 > CBigNum(2048)) |
|
|
|
|
return false; |
|
|
|
|
bn = bn1 << bn2.getulong(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_RSHIFT: |
|
|
|
|
if (bn2 < bnZero || bn2 > CBigNum(2048)) |
|
|
|
|
return false; |
|
|
|
|
bn = bn1 >> bn2.getulong(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; |
|
|
|
|
case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; |
|
|
|
|
case OP_NUMEQUAL: bn = (bn1 == bn2); break; |
|
|
|
|