|
|
|
@ -1863,6 +1863,51 @@ bool CScript::IsPayToScriptHash() const
@@ -1863,6 +1863,51 @@ bool CScript::IsPayToScriptHash() const
|
|
|
|
|
this->at(22) == OP_EQUAL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool CScript::IsPushOnly() const |
|
|
|
|
{ |
|
|
|
|
const_iterator pc = begin(); |
|
|
|
|
while (pc < end()) |
|
|
|
|
{ |
|
|
|
|
opcodetype opcode; |
|
|
|
|
if (!GetOp(pc, opcode)) |
|
|
|
|
return false; |
|
|
|
|
// Note that IsPushOnly() *does* consider OP_RESERVED to be a
|
|
|
|
|
// push-type opcode, however execution of OP_RESERVED fails, so
|
|
|
|
|
// it's not relevant to P2SH as the scriptSig would fail prior to
|
|
|
|
|
// the P2SH special validation code being executed.
|
|
|
|
|
if (opcode > OP_16) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool CScript::HasCanonicalPushes() const |
|
|
|
|
{ |
|
|
|
|
const_iterator pc = begin(); |
|
|
|
|
while (pc < end()) |
|
|
|
|
{ |
|
|
|
|
opcodetype opcode; |
|
|
|
|
std::vector<unsigned char> data; |
|
|
|
|
if (!GetOp(pc, opcode, data)) |
|
|
|
|
return false; |
|
|
|
|
if (opcode > OP_16) |
|
|
|
|
continue; |
|
|
|
|
if (opcode < OP_PUSHDATA1 && opcode > OP_0 && (data.size() == 1 && data[0] <= 16)) |
|
|
|
|
// Could have used an OP_n code, rather than a 1-byte push.
|
|
|
|
|
return false; |
|
|
|
|
if (opcode == OP_PUSHDATA1 && data.size() < OP_PUSHDATA1) |
|
|
|
|
// Could have used a normal n-byte push, rather than OP_PUSHDATA1.
|
|
|
|
|
return false; |
|
|
|
|
if (opcode == OP_PUSHDATA2 && data.size() <= 0xFF) |
|
|
|
|
// Could have used an OP_PUSHDATA1.
|
|
|
|
|
return false; |
|
|
|
|
if (opcode == OP_PUSHDATA4 && data.size() <= 0xFFFF) |
|
|
|
|
// Could have used an OP_PUSHDATA2.
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class CScriptVisitor : public boost::static_visitor<bool> |
|
|
|
|
{ |
|
|
|
|
private: |
|
|
|
|