Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 7

}

return n;

unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const

if (!IsPayToScriptHash())

return GetSigOpCount(true);

// This is a pay-to-script-hash scriptPubKey;

// get the last item that the scriptSig

// pushes onto the stack:

const_iterator pc = scriptSig.begin();

std::vector<unsigned char> vData;

while (pc < scriptSig.end())

opcodetype opcode;

if (!scriptSig.GetOp(pc, opcode, vData))

return 0;

if (opcode > OP_16)

return 0;

/// ... and return its opcount:

CScript subscript(vData.begin(), vData.end());


return subscript.GetSigOpCount(true);

bool CScript::IsPayToScriptHash() const

// Extra-fast test for pay-to-script-hash CScripts:

return (this->size() == 23 &&

(*this)[0] == OP_HASH160 &&

(*this)[1] == 0x14 &&

(*this)[22] == OP_EQUAL);

bool CScript::IsPayToWitnessScriptHash() const

// Extra-fast test for pay-to-witness-script-hash CScripts:

return (this->size() == 34 &&

(*this)[0] == OP_0 &&

(*this)[1] == 0x20);

// A witness program is any valid CScript that consists of a 1-byte push opcode

// followed by a data push between 2 and 40 bytes.

bool CScript::IsWitnessProgram(int& version, std::vector<unsigned char>& program)


const

{
if (this->size() < 4 || this->size() > 42) {

return false;

if ((*this)[0] != OP_0 && ((*this)[0] < OP_1 || (*this)[0] > OP_16)) {

return false;

if ((size_t)((*this)[1] + 2) == this->size()) {

version = DecodeOP_N((opcodetype)(*this)[0]);

program = std::vector<unsigned char>(this->begin() + 2, this->end());

return true;

return false;

bool CScript::IsPushOnly(const_iterator pc) const

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/BIP62 as the scriptSig would fail prior to

// the P2SH special validation code being executed.

if (opcode > OP_16)

return false;
}

return true;

bool CScript::IsPushOnly() const

return this->IsPushOnly(begin());

std::string CScriptWitness::ToString() const

std::string ret = "CScriptWitness(";

for (unsigned int i = 0; i < stack.size(); i++) {

if (i) {

ret += ", ";

ret += HexStr(stack[i]);

return ret + ")";

bool CScript::HasValidOps() const

CScript::const_iterator it = begin();

while (it < end()) {


opcodetype opcode;

std::vector<unsigned char> item;

if (!GetOp(it, opcode, item) || opcode > MAX_OPCODE || item.size() >


MAX_SCRIPT_ELEMENT_SIZE) {

return false;

return true;

bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end,


opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet)

opcodeRet = OP_INVALIDOPCODE;

if (pvchRet)

pvchRet->clear();

if (pc >= end)

return false;

// Read instruction

if (end - pc < 1)

return false;

unsigned int opcode = *pc++;

// Immediate operand
if (opcode <= OP_PUSHDATA4)

unsigned int nSize = 0;

if (opcode < OP_PUSHDATA1)

nSize = opcode;

else if (opcode == OP_PUSHDATA1)

if (end - pc < 1)

return false;

nSize = *pc++;

else if (opcode == OP_PUSHDATA2)

if (end - pc < 2)

return false;

nSize = ReadLE16(&pc[0]);

pc += 2;

else if (opcode == OP_PUSHDATA4)

if (end - pc < 4)

return false;

nSize = ReadLE32(&pc[0]);

pc += 4;

if (end - pc < 0 || (unsigned int)(end - pc) < nSize)


return false;

if (pvchRet)

pvchRet->assign(pc, pc + nSize);

pc += nSize;

opcodeRet = static_cast<opcodetype>(opcode);

return true;

 © 2019 GitHub, Inc.


 Terms
 Privacy
 Security
 Status
 Help

 Contact GitHub
 Pricing
 API
 Training
 Blog
 About

You might also like