// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "script.h" #include "script_flags.h" #include "tinyformat.h" #include "utilstrencodings.h" #include #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wsign-conversion" #pragma clang diagnostic ignored "-Wshorten-64-to-32" #pragma clang diagnostic ignored "-Wunused-parameter" #endif namespace bitcoin { const char *GetOpName(opcodetype opcode) { switch (opcode) { // push value case OP_0: return "0"; case OP_PUSHDATA1: return "OP_PUSHDATA1"; case OP_PUSHDATA2: return "OP_PUSHDATA2"; case OP_PUSHDATA4: return "OP_PUSHDATA4"; case OP_1NEGATE: return "-1"; case OP_RESERVED: return "OP_RESERVED"; case OP_1: return "1"; case OP_2: return "2"; case OP_3: return "3"; case OP_4: return "4"; case OP_5: return "5"; case OP_6: return "6"; case OP_7: return "7"; case OP_8: return "8"; case OP_9: return "9"; case OP_10: return "10"; case OP_11: return "11"; case OP_12: return "12"; case OP_13: return "13"; case OP_14: return "14"; case OP_15: return "15"; case OP_16: return "16"; // control case OP_NOP: return "OP_NOP"; case OP_VER: return "OP_VER"; case OP_IF: return "OP_IF"; case OP_NOTIF: return "OP_NOTIF"; case OP_VERIF: return "OP_VERIF"; case OP_VERNOTIF: return "OP_VERNOTIF"; case OP_ELSE: return "OP_ELSE"; case OP_ENDIF: return "OP_ENDIF"; case OP_VERIFY: return "OP_VERIFY"; case OP_RETURN: return "OP_RETURN"; // stack ops case OP_TOALTSTACK: return "OP_TOALTSTACK"; case OP_FROMALTSTACK: return "OP_FROMALTSTACK"; case OP_2DROP: return "OP_2DROP"; case OP_2DUP: return "OP_2DUP"; case OP_3DUP: return "OP_3DUP"; case OP_2OVER: return "OP_2OVER"; case OP_2ROT: return "OP_2ROT"; case OP_2SWAP: return "OP_2SWAP"; case OP_IFDUP: return "OP_IFDUP"; case OP_DEPTH: return "OP_DEPTH"; case OP_DROP: return "OP_DROP"; case OP_DUP: return "OP_DUP"; case OP_NIP: return "OP_NIP"; case OP_OVER: return "OP_OVER"; case OP_PICK: return "OP_PICK"; case OP_ROLL: return "OP_ROLL"; case OP_ROT: return "OP_ROT"; case OP_SWAP: return "OP_SWAP"; case OP_TUCK: return "OP_TUCK"; // splice ops case OP_CAT: return "OP_CAT"; case OP_SPLIT: return "OP_SPLIT"; case OP_NUM2BIN: return "OP_NUM2BIN"; case OP_BIN2NUM: return "OP_BIN2NUM"; case OP_SIZE: return "OP_SIZE"; // bit logic case OP_INVERT: return "OP_INVERT"; case OP_AND: return "OP_AND"; case OP_OR: return "OP_OR"; case OP_XOR: return "OP_XOR"; case OP_EQUAL: return "OP_EQUAL"; case OP_EQUALVERIFY: return "OP_EQUALVERIFY"; case OP_RESERVED1: return "OP_RESERVED1"; case OP_RESERVED2: return "OP_RESERVED2"; // numeric case OP_1ADD: return "OP_1ADD"; case OP_1SUB: return "OP_1SUB"; case OP_2MUL: return "OP_2MUL"; case OP_2DIV: return "OP_2DIV"; case OP_NEGATE: return "OP_NEGATE"; case OP_ABS: return "OP_ABS"; case OP_NOT: return "OP_NOT"; case OP_0NOTEQUAL: return "OP_0NOTEQUAL"; case OP_ADD: return "OP_ADD"; case OP_SUB: return "OP_SUB"; case OP_MUL: return "OP_MUL"; case OP_DIV: return "OP_DIV"; case OP_MOD: return "OP_MOD"; case OP_LSHIFT: return "OP_LSHIFT"; case OP_RSHIFT: return "OP_RSHIFT"; case OP_BOOLAND: return "OP_BOOLAND"; case OP_BOOLOR: return "OP_BOOLOR"; case OP_NUMEQUAL: return "OP_NUMEQUAL"; case OP_NUMEQUALVERIFY: return "OP_NUMEQUALVERIFY"; case OP_NUMNOTEQUAL: return "OP_NUMNOTEQUAL"; case OP_LESSTHAN: return "OP_LESSTHAN"; case OP_GREATERTHAN: return "OP_GREATERTHAN"; case OP_LESSTHANOREQUAL: return "OP_LESSTHANOREQUAL"; case OP_GREATERTHANOREQUAL: return "OP_GREATERTHANOREQUAL"; case OP_MIN: return "OP_MIN"; case OP_MAX: return "OP_MAX"; case OP_WITHIN: return "OP_WITHIN"; // crypto case OP_RIPEMD160: return "OP_RIPEMD160"; case OP_SHA1: return "OP_SHA1"; case OP_SHA256: return "OP_SHA256"; case OP_HASH160: return "OP_HASH160"; case OP_HASH256: return "OP_HASH256"; case OP_CODESEPARATOR: return "OP_CODESEPARATOR"; case OP_CHECKSIG: return "OP_CHECKSIG"; case OP_CHECKSIGVERIFY: return "OP_CHECKSIGVERIFY"; case OP_CHECKMULTISIG: return "OP_CHECKMULTISIG"; case OP_CHECKMULTISIGVERIFY: return "OP_CHECKMULTISIGVERIFY"; case OP_CHECKDATASIG: return "OP_CHECKDATASIG"; case OP_CHECKDATASIGVERIFY: return "OP_CHECKDATASIGVERIFY"; // expansion case OP_NOP1: return "OP_NOP1"; case OP_CHECKLOCKTIMEVERIFY: return "OP_CHECKLOCKTIMEVERIFY"; case OP_CHECKSEQUENCEVERIFY: return "OP_CHECKSEQUENCEVERIFY"; case OP_NOP4: return "OP_NOP4"; case OP_NOP5: return "OP_NOP5"; case OP_NOP6: return "OP_NOP6"; case OP_NOP7: return "OP_NOP7"; case OP_NOP8: return "OP_NOP8"; case OP_NOP9: return "OP_NOP9"; case OP_NOP10: return "OP_NOP10"; case OP_INVALIDOPCODE: return "OP_INVALIDOPCODE"; // Note: // The template matching params OP_SMALLINTEGER/etc are defined in // opcodetype enum as kind of implementation hack, they are *NOT* // real opcodes. If found in real Script, just let the default: // case deal with them. default: return "OP_UNKNOWN"; } } bool CScriptNum::IsMinimallyEncoded(const std::vector &vch, const size_t nMaxNumSize) { if (vch.size() > nMaxNumSize) { return false; } if (vch.size() > 0) { // Check that the number is encoded with the minimum possible number // of bytes. // // If the most-significant-byte - excluding the sign bit - is zero // then we're not minimal. Note how this test also rejects the // negative-zero encoding, 0x80. if ((vch.back() & 0x7f) == 0) { // One exception: if there's more than one byte and the most // significant bit of the second-most-significant-byte is set it // would conflict with the sign bit. An example of this case is // +-255, which encode to 0xff00 and 0xff80 respectively. // (big-endian). if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) { return false; } } } return true; } bool CScriptNum::MinimallyEncode(std::vector &data) { if (data.size() == 0) { return false; } // If the last byte is not 0x00 or 0x80, we are minimally encoded. uint8_t last = data.back(); if (last & 0x7f) { return false; } // If the script is one byte long, then we have a zero, which encodes as an // empty array. if (data.size() == 1) { data = {}; return true; } // If the next byte has it sign bit set, then we are minimaly encoded. if (data[data.size() - 2] & 0x80) { return false; } // We are not minimally encoded, we need to figure out how much to trim. for (size_t i = data.size() - 1; i > 0; i--) { // We found a non zero byte, time to encode. if (data[i - 1] != 0) { if (data[i - 1] & 0x80) { // We found a byte with it sign bit set so we need one more // byte. data[i++] = last; } else { // the sign bit is clear, we can use it. data[i - 1] |= last; } data.resize(i); return true; } } // If we the whole thing is zeros, then we have a zero. data = {}; return true; } uint32_t CScript::GetSigOpCount(uint32_t flags, bool fAccurate) const { uint32_t n = 0; const_iterator pc = begin(); opcodetype lastOpcode = OP_INVALIDOPCODE; while (pc < end()) { opcodetype opcode; if (!GetOp(pc, opcode)) { break; } switch (opcode) { case OP_CHECKSIG: case OP_CHECKSIGVERIFY: n++; break; case OP_CHECKDATASIG: case OP_CHECKDATASIGVERIFY: if (flags & SCRIPT_ENABLE_CHECKDATASIG) { n++; } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) { n += DecodeOP_N(lastOpcode); } else { n += MAX_PUBKEYS_PER_MULTISIG; } break; default: break; } lastOpcode = opcode; } return n; } uint32_t CScript::GetSigOpCount(uint32_t flags, const CScript &scriptSig) const { if ((flags & SCRIPT_VERIFY_P2SH) == 0 || !IsPayToScriptHash()) { return GetSigOpCount(flags, 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 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(flags, 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::IsCommitment(const std::vector &data) const { // To ensure we have an immediate push, we limit the commitment size to 64 // bytes. In addition to the data themselves, we have 2 extra bytes: // OP_RETURN and the push opcode itself. if (data.size() > 64 || this->size() != data.size() + 2) { return false; } if ((*this)[0] != OP_RETURN || (*this)[1] != data.size()) { return false; } for (size_t i = 0; i < data.size(); i++) { if ((*this)[i + 2] != data[i]) { return false; } } return true; } // 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 &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(this->begin() + 2, this->end()); return true; } return false; } // Wrapper returning only the predicate bool CScript::IsWitnessProgram() const { int version; std::vector program; return IsWitnessProgram(version, program); } 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()); } } // end namespace bitcoin #ifdef __clang__ #pragma clang diagnostic pop #endif