// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include using namespace std; using namespace boost; #include "script.h" #include "keystore.h" #include "bignum.h" #include "key.h" #include "main.h" #include "sync.h" #include "util.h" bool CheckSig(vector vchSig, const vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); static const valtype vchFalse(0); static const valtype vchZero(0); static const valtype vchTrue(1, 1); static const CBigNum bnZero(0); static const CBigNum bnOne(1); static const CBigNum bnFalse(0); static const CBigNum bnTrue(1); static const size_t nMaxNumSize = 4; CBigNum CastToBigNum(const valtype& vch) { if (vch.size() > nMaxNumSize) throw runtime_error("CastToBigNum() : overflow"); // Get rid of extra leading zeros return CBigNum(CBigNum(vch).getvch()); } bool CastToBool(const valtype& vch) { for (unsigned int i = 0; i < vch.size(); i++) { if (vch[i] != 0) { // Can be negative zero if (i == vch.size()-1 && vch[i] == 0x80) return false; return true; } } 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); } // // Script is a stack machine (like Forth) that evaluates a predicate // returning a bool indicating valid or not. There are no loops. // #define stacktop(i) (stack.at(stack.size()+(i))) #define altstacktop(i) (altstack.at(altstack.size()+(i))) static inline void popstack(vector& stack) { if (stack.empty()) throw runtime_error("popstack() : stack empty"); stack.pop_back(); } const char* GetTxnOutputType(txnouttype t) { switch (t) { case TX_NONSTANDARD: return "nonstandard"; case TX_PUBKEY: return "pubkey"; case TX_PUBKEY_DROP: return "pubkeydrop"; case TX_PUBKEYHASH: return "pubkeyhash"; case TX_SCRIPTHASH: return "scripthash"; case TX_MULTISIG: return "multisig"; case TX_NULL_DATA: return "nulldata"; } return NULL; } 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"; case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_CHECKSEQUENCEVERIFY : return "OP_CHECKSEQUENCEVERIFY"; // 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_SUBSTR : return "OP_SUBSTR"; case OP_LEFT : return "OP_LEFT"; case OP_RIGHT : return "OP_RIGHT"; 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"; // expanson case OP_NOP1 : return "OP_NOP1"; 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"; // template matching params case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; case OP_PUBKEY : return "OP_PUBKEY"; case OP_SMALLDATA : return "OP_SMALLDATA"; case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; default: return "OP_UNKNOWN"; } } bool IsCanonicalPubKey(const valtype &vchPubKey, unsigned int flags) { if (!(flags & SCRIPT_VERIFY_STRICTENC)) return true; if (vchPubKey.size() < 33) return error("Non-canonical public key: too short"); if (vchPubKey[0] == 0x04) { if (vchPubKey.size() != 65) return error("Non-canonical public key: invalid length for uncompressed key"); } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { if (vchPubKey.size() != 33) return error("Non-canonical public key: invalid length for compressed key"); } else { return error("Non-canonical public key: compressed nor uncompressed"); } return true; } bool IsDERSignature(const valtype &vchSig, bool fWithHashType, bool fCheckLow) { // See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 // A canonical signature exists of: <30> <02> <02> // Where R and S are not negative (their first byte has its highest bit not set), and not // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, // in which case a single 0 byte is necessary and even required). if (vchSig.size() < 9) return error("Non-canonical signature: too short"); if (vchSig.size() > 73) return error("Non-canonical signature: too long"); if (vchSig[0] != 0x30) return error("Non-canonical signature: wrong type"); if (vchSig[1] != vchSig.size() - (fWithHashType ? 3 : 2)) return error("Non-canonical signature: wrong length marker"); if (fWithHashType) { unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) return error("Non-canonical signature: unknown hashtype byte"); } unsigned int nLenR = vchSig[3]; if (5 + nLenR >= vchSig.size()) return error("Non-canonical signature: S length misplaced"); unsigned int nLenS = vchSig[5+nLenR]; if ((nLenR + nLenS + (fWithHashType ? 7 : 6)) != vchSig.size()) return error("Non-canonical signature: R+S length mismatch"); const unsigned char *R = &vchSig[4]; if (R[-2] != 0x02) return error("Non-canonical signature: R value type mismatch"); if (nLenR == 0) return error("Non-canonical signature: R length is zero"); if (R[0] & 0x80) return error("Non-canonical signature: R value negative"); if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) return error("Non-canonical signature: R value excessively padded"); const unsigned char *S = &vchSig[6+nLenR]; if (S[-2] != 0x02) return error("Non-canonical signature: S value type mismatch"); if (nLenS == 0) return error("Non-canonical signature: S length is zero"); if (S[0] & 0x80) return error("Non-canonical signature: S value negative"); if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) return error("Non-canonical signature: S value excessively padded"); if (fCheckLow) { unsigned int nLenR = vchSig[3]; unsigned int nLenS = vchSig[5+nLenR]; const unsigned char *S = &vchSig[6+nLenR]; // If the S value is above the order of the curve divided by two, its // complement modulo the order could have been used instead, which is // one byte shorter when encoded correctly. if (!CKey::CheckSignatureElement(S, nLenS, true)) return error("Non-canonical signature: S value is unnecessarily high"); } return true; } bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { if (!(flags & SCRIPT_VERIFY_STRICTENC)) return true; return IsDERSignature(vchSig, true, (flags & SCRIPT_VERIFY_LOW_S) != 0); } bool CheckLockTime(const int64_t& nLockTime, const CTransaction &txTo, unsigned int nIn) { // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nLockTime < LOCKTIME_THRESHOLD. // // We want to compare apples to apples, so fail the script // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( (txTo.nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || (txTo.nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) )) return false; // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. if (nLockTime > (int64_t)txTo.nLockTime) return false; // Finally the nLockTime feature can be disabled and thus // CHECKLOCKTIMEVERIFY bypassed if every txin has been // finalized by setting nSequence to maxint. The // transaction would be allowed into the blockchain, making // the opcode ineffective. // // Testing if this vin is not final is sufficient to // prevent this condition. Alternatively we could test all // inputs, but testing just this input minimizes the data // required to prove correct CHECKLOCKTIMEVERIFY execution. if (SEQUENCE_FINAL == txTo.vin[nIn].nSequence) return false; return true; } bool CheckSequence(const int64_t& nSequence, const CTransaction &txTo, unsigned int nIn) { // Relative lock times are supported by comparing the passed // in operand to the sequence number of the input. const int64_t txToSequence = (int64_t)txTo.vin[nIn].nSequence; // Sequence numbers with their most significant bit set are not // consensus constrained. Testing that the transaction's sequence // number do not have this bit set prevents using this property // to get around a CHECKSEQUENCEVERIFY check. if (txToSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG) return false; // Mask off any bits that do not have consensus-enforced meaning // before doing the integer comparisons const uint32_t nLockTimeMask = SEQUENCE_LOCKTIME_TYPE_FLAG | SEQUENCE_LOCKTIME_MASK; const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; const int64_t nSequenceMasked = nSequence & nLockTimeMask; // There are two kinds of nSequence: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. // // We want to compare apples to apples, so fail the script // unless the type of nSequenceMasked being tested is the same as // the nSequenceMasked in the transaction. if (!( (txToSequenceMasked < SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < SEQUENCE_LOCKTIME_TYPE_FLAG) || (txToSequenceMasked >= SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= SEQUENCE_LOCKTIME_TYPE_FLAG) )) { return false; } // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. if (nSequenceMasked > txToSequenceMasked) return false; return true; } bool EvalScript(vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) { CAutoBN_CTX pctx; CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); opcodetype opcode; valtype vchPushValue; vector vfExec; vector altstack; if (script.size() > 10000) return false; int nOpCount = 0; try { while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // // Read instruction // if (!script.GetOp(pc, opcode, vchPushValue)) return false; if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) return false; if (opcode > OP_16 && ++nOpCount > 201) return false; if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) return false; // Disabled opcodes. if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) stack.push_back(vchPushValue); else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CBigNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); } break; // // Control // case OP_NOP: case OP_NOP1: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_IF: case OP_NOTIF: { // if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack.size() < 1) return false; valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } vfExec.push_back(fValue); } break; case OP_ELSE: { if (vfExec.empty()) return false; vfExec.back() = !vfExec.back(); } break; case OP_ENDIF: { if (vfExec.empty()) return false; vfExec.pop_back(); } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) return false; bool fValue = CastToBool(stacktop(-1)); if (fValue) popstack(stack); else return false; } break; case OP_RETURN: { return false; } break; case OP_CHECKLOCKTIMEVERIFY: { // CHECKLOCKTIMEVERIFY // // (nLockTime -- nLockTime) if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { // treat as a NOP2 if not enabled break; } if (stack.size() < 1) return false; CBigNum nLockTime = CastToBigNum(stacktop(-1)); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use // 0 MAX CHECKLOCKTIMEVERIFY. if (nLockTime < 0) return false; // Actually compare the specified lock time with the transaction. if (!CheckLockTime(nLockTime.getuint64(), txTo, nIn)) return false; break; } case OP_CHECKSEQUENCEVERIFY: { if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { // treat as a NOP3 not enabled break; } if (stack.size() < 1) return false; // nSequence, like nLockTime, is a 32-bit unsigned integer // field. See the comment in CHECKLOCKTIMEVERIFY regarding // 5-byte numeric operands. CBigNum nSequence = CastToBigNum(stacktop(-1)); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use // 0 MAX CHECKSEQUENCEVERIFY. if (nSequence < 0) return false; // To provide for future soft-fork extensibility, if the // operand has the disabled lock-time flag set, // CHECKSEQUENCEVERIFY behaves as a NOP. if ((nSequence.getint32() & SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) break; // Compare the specified sequence number with the input. if (!CheckSequence(nSequence.getuint64(), txTo, nIn)) return false; break; } // // Stack ops // case OP_TOALTSTACK: { if (stack.size() < 1) return false; altstack.push_back(stacktop(-1)); popstack(stack); } break; case OP_FROMALTSTACK: { if (altstack.size() < 1) return false; stack.push_back(altstacktop(-1)); popstack(altstack); } break; case OP_2DROP: { // (x1 x2 -- ) if (stack.size() < 2) return false; popstack(stack); popstack(stack); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return false; valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return false; valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return false; valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return false; valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return false; swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } break; case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); } break; case OP_DEPTH: { // -- stacksize CBigNum bn((uint16_t) stack.size()); stack.push_back(bn.getvch()); } break; case OP_DROP: { // (x -- ) if (stack.size() < 1) return false; popstack(stack); } break; case OP_DUP: { // (x -- x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); stack.push_back(vch); } break; case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return false; stack.erase(stack.end() - 2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return false; valtype vch = stacktop(-2); stack.push_back(vch); } break; case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) return false; int n = CastToBigNum(stacktop(-1)).getint32(); popstack(stack); if (n < 0 || n >= (int)stack.size()) return false; valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); stack.push_back(vch); } break; case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) return false; swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return false; swap(stacktop(-2), stacktop(-1)); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return false; valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } break; case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return false; CBigNum bn((uint16_t) stacktop(-1).size()); stack.push_back(bn.getvch()); } break; // // Bitwise logic // case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { // (x1 x2 - bool) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; popstack(stack); popstack(stack); stack.push_back(fEqual ? vchTrue : vchFalse); if (opcode == OP_EQUALVERIFY) { if (fEqual) popstack(stack); else return false; } } break; // // Numeric // case OP_1ADD: case OP_1SUB: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return false; CBigNum bn = CastToBigNum(stacktop(-1)); switch (opcode) { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; default: assert(!"invalid opcode"); break; } popstack(stack); stack.push_back(bn.getvch()); } break; case OP_ADD: case OP_SUB: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return false; CBigNum bn1 = CastToBigNum(stacktop(-2)); CBigNum bn2 = CastToBigNum(stacktop(-1)); CBigNum bn; switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; case OP_SUB: bn = bn1 - bn2; 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; case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; case OP_LESSTHAN: bn = (bn1 < bn2); break; case OP_GREATERTHAN: bn = (bn1 > bn2); break; case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; default: assert(!"invalid opcode"); break; } popstack(stack); popstack(stack); stack.push_back(bn.getvch()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) popstack(stack); else return false; } } break; case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return false; CBigNum bn1 = CastToBigNum(stacktop(-3)); CBigNum bn2 = CastToBigNum(stacktop(-2)); CBigNum bn3 = CastToBigNum(stacktop(-1)); bool fValue = (bn2 <= bn1 && bn1 < bn3); popstack(stack); popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); } break; // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) SHA1(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA256) SHA256(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_HASH160) { uint160 hash160 = Hash160(vch); memcpy(&vchHash[0], &hash160, sizeof(hash160)); } else if (opcode == OP_HASH256) { uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } popstack(stack); stack.push_back(vchHash); } break; case OP_CODESEPARATOR: { // Hash starts after the code separator pbegincodehash = pc; } break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return false; valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); ////// debug print //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; if ((int)stack.size() < i) return false; int nKeysCount = CastToBigNum(stacktop(-i)).getint32(); if (nKeysCount < 0 || nKeysCount > 20) return false; nOpCount += nKeysCount; if (nOpCount > 201) return false; int ikey = ++i; i += nKeysCount; if ((int)stack.size() < i) return false; int nSigsCount = CastToBigNum(stacktop(-i)).getint32(); if (nSigsCount < 0 || nSigsCount > nKeysCount) return false; int isig = ++i; i += nSigsCount; if ((int)stack.size() < i) return false; // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Check signature bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); if (fOk) { isig++; nSigsCount--; } ikey++; nKeysCount--; // If there are more signatures left than keys left, // then too many signatures have failed if (nSigsCount > nKeysCount) fSuccess = false; } while (i-- > 1) popstack(stack); // A bug causes CHECKMULTISIG to consume one extra argument // whose contents were not checked in any way. // // Unfortunately this is a potential source of mutability, // so optionally verify it is exactly equal to zero prior // to removing it from the stack. if (stack.size() < 1) return false; if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size()) return error("CHECKMULTISIG dummy argument not null"); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; default: return false; } // Size limits if (stack.size() + altstack.size() > 1000) return false; } } catch (...) { return false; } if (!vfExec.empty()) return false; return true; } uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { if (nIn >= txTo.vin.size()) { printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); return 1; } CTransaction txTmp(txTo); // In case concatenating two scripts ends up with two codeseparators, // or an extra one at the end, this prevents all those possible incompatibilities. scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); // Blank out other inputs' signatures for (unsigned int i = 0; i < txTmp.vin.size(); i++) txTmp.vin[i].scriptSig = CScript(); txTmp.vin[nIn].scriptSig = scriptCode; // Blank out some of the outputs if ((nHashType & 0x1f) == SIGHASH_NONE) { // Wildcard payee txTmp.vout.clear(); // Let the others update at will for (unsigned int i = 0; i < txTmp.vin.size(); i++) if (i != nIn) txTmp.vin[i].nSequence = 0; } else if ((nHashType & 0x1f) == SIGHASH_SINGLE) { // Only lock-in the txout payee at same index as txin unsigned int nOut = nIn; if (nOut >= txTmp.vout.size()) { printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); return 1; } txTmp.vout.resize(nOut+1); for (unsigned int i = 0; i < nOut; i++) txTmp.vout[i].SetNull(); // Let the others update at will for (unsigned int i = 0; i < txTmp.vin.size(); i++) if (i != nIn) txTmp.vin[i].nSequence = 0; } // Blank out other inputs completely, not recommended for open transactions if (nHashType & SIGHASH_ANYONECANPAY) { txTmp.vin[0] = txTmp.vin[nIn]; txTmp.vin.resize(1); } // Serialize and hash CDataStream ss(SER_GETHASH, 0); ss.reserve(10000); ss << txTmp << nHashType; return Hash(ss.begin(), ss.end()); } // Valid signature cache, to avoid doing expensive ECDSA signature checking // twice for every transaction (once when accepted into memory pool, and // again when accepted into the block chain) class CSignatureCache { private: // sigdata_type is (signature hash, signature, public key): typedef boost::tuple, CPubKey > sigdata_type; std::set< sigdata_type> setValid; boost::shared_mutex cs_sigcache; public: bool Get(const uint256 &hash, const std::vector& vchSig, const CPubKey& pubKey) { boost::shared_lock lock(cs_sigcache); sigdata_type k(hash, vchSig, pubKey); std::set::iterator mi = setValid.find(k); if (mi != setValid.end()) return true; return false; } void Set(const uint256 &hash, const std::vector& vchSig, const CPubKey& pubKey) { // DoS prevention: limit cache size to less than 10MB // (~200 bytes per cache entry times 50,000 entries) // Since there are a maximum of 20,000 signature operations per block // 50,000 is a reasonable default. int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); if (nMaxCacheSize <= 0) return; boost::shared_lock lock(cs_sigcache); while (static_cast(setValid.size()) > nMaxCacheSize) { // Evict a random entry. Random because that helps // foil would-be DoS attackers who might try to pre-generate // and re-use a set of valid signatures just-slightly-greater // than our cache size. uint256 randomHash = GetRandHash(); std::vector unused; std::set::iterator it = setValid.lower_bound(sigdata_type(randomHash, unused, unused)); if (it == setValid.end()) it = setValid.begin(); setValid.erase(*it); } sigdata_type k(hash, vchSig, pubKey); setValid.insert(k); } }; bool CheckSig(vector vchSig, const vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags) { static CSignatureCache signatureCache; CKey key; if (!key.SetPubKey(vchPubKey)) return false; CPubKey pubkey = key.GetPubKey(); if (!pubkey.IsValid()) return false; // Hash type is one byte tacked on to the end of the signature if (vchSig.empty()) return false; if (nHashType == 0) nHashType = vchSig.back(); else if (nHashType != vchSig.back()) return false; vchSig.pop_back(); uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); if (signatureCache.Get(sighash, vchSig, pubkey)) return true; if (!key.Verify(sighash, vchSig)) return false; if (!(flags & SCRIPT_VERIFY_NOCACHE)) signatureCache.Set(sighash, vchSig, pubkey); return true; } // // Return public keys or hashes from scriptPubKey, for 'standard' transaction types. // bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutionsRet) { // Templates static map mTemplates; if (mTemplates.empty()) { // Standard tx, sender provides pubkey, receiver adds signature mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG)); if (fTestNet || GetTime() > SMALLDATA_SWITCH_TIME) { // Malleable pubkey tx hack, sender provides generated pubkey combined with R parameter. The R parameter is dropped before checking a signature. mTemplates.insert(make_pair(TX_PUBKEY_DROP, CScript() << OP_PUBKEY << OP_PUBKEY << OP_DROP << OP_CHECKSIG)); } // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG)); // Sender provides N pubkeys, receivers provides M signatures mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG)); // Empty, provably prunable, data-carrying output mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA)); } vSolutionsRet.clear(); // Shortcut for pay-to-script-hash, which are more constrained than the other types: // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL if (scriptPubKey.IsPayToScriptHash()) { typeRet = TX_SCRIPTHASH; vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); vSolutionsRet.push_back(hashBytes); return true; } // Provably prunable, data-carrying output // // So long as script passes the IsUnspendable() test and all but the first // byte passes the IsPushOnly() test we don't care what exactly is in the // script. if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) { typeRet = TX_NULL_DATA; return true; } // Scan templates const CScript& script1 = scriptPubKey; BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates) { const CScript& script2 = tplate.second; vSolutionsRet.clear(); opcodetype opcode1, opcode2; vector vch1, vch2; // Compare CScript::const_iterator pc1 = script1.begin(); CScript::const_iterator pc2 = script2.begin(); while (true) { if (pc1 == script1.end() && pc2 == script2.end()) { // Found a match typeRet = tplate.first; if (typeRet == TX_MULTISIG) { // Additional checks for TX_MULTISIG: unsigned char m = vSolutionsRet.front()[0]; unsigned char n = vSolutionsRet.back()[0]; if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n) return false; } return true; } if (!script1.GetOp(pc1, opcode1, vch1)) break; if (!script2.GetOp(pc2, opcode2, vch2)) break; // Template matching opcodes: if (opcode2 == OP_PUBKEYS) { while (vch1.size() >= 33 && vch1.size() <= 120) { vSolutionsRet.push_back(vch1); if (!script1.GetOp(pc1, opcode1, vch1)) break; } if (!script2.GetOp(pc2, opcode2, vch2)) break; // Normal situation is to fall through // to other if/else statements } if (opcode2 == OP_PUBKEY) { if (vch1.size() < 33 || vch1.size() > 120) break; vSolutionsRet.push_back(vch1); } else if (opcode2 == OP_PUBKEYHASH) { if (vch1.size() != sizeof(uint160)) break; vSolutionsRet.push_back(vch1); } else if (opcode2 == OP_SMALLINTEGER) { // Single-byte small integer pushed onto vSolutions if (opcode1 == OP_0 || (opcode1 >= OP_1 && opcode1 <= OP_16)) { char n = (char)CScript::DecodeOP_N(opcode1); vSolutionsRet.push_back(valtype(1, n)); } else break; } else if (opcode2 == OP_INTEGER) { // Up to four-byte integer pushed onto vSolutions try { CBigNum bnVal = CastToBigNum(vch1); if (bnVal <= 16) break; // It's better to use OP_0 ... OP_16 for small integers. vSolutionsRet.push_back(vch1); } catch(...) { break; } } else if (opcode2 == OP_SMALLDATA) { // small pushdata, <= 1024 bytes if (vch1.size() > (GetTime() > SMALLDATA_SWITCH_TIME ? 1024 : 80)) break; } else if (opcode1 != opcode2 || vch1 != vch2) { // Others must match exactly break; } } } vSolutionsRet.clear(); typeRet = TX_NONSTANDARD; return false; } bool Sign1(const CKeyID& address, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) { CKey key; if (!keystore.GetKey(address, key)) return false; vector vchSig; if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); scriptSigRet << vchSig; return true; } bool SignR(const CPubKey& pubKey, const CPubKey& R, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) { CKey key; if (!keystore.CreatePrivKey(pubKey, R, key)) return false; vector vchSig; if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); scriptSigRet << vchSig; return true; } bool SignN(const vector& multisigdata, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) { int nSigned = 0; int nRequired = multisigdata.front()[0]; for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++) { const valtype& pubkey = multisigdata[i]; CKeyID keyID = CPubKey(pubkey).GetID(); if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) ++nSigned; } return nSigned==nRequired; } // // Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. // Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), // unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. // Returns false if scriptPubKey could not be completely satisfied. // bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, const uint256& hash, int nHashType, CScript& scriptSigRet, txnouttype& whichTypeRet) { scriptSigRet.clear(); vector vSolutions; if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) return false; CKeyID keyID; switch (whichTypeRet) { case TX_NONSTANDARD: case TX_NULL_DATA: return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); return Sign1(keyID, keystore, hash, nHashType, scriptSigRet); case TX_PUBKEY_DROP: { CPubKey key = CPubKey(vSolutions[0]); CPubKey R = CPubKey(vSolutions[1]); return SignR(key, R, keystore, hash, nHashType, scriptSigRet); } case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) return false; else { CPubKey vch; keystore.GetPubKey(keyID, vch); scriptSigRet << vch; } return true; case TX_SCRIPTHASH: return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet); case TX_MULTISIG: scriptSigRet << OP_0; // workaround CHECKMULTISIG bug return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet)); } return false; } int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions) { switch (t) { case TX_NONSTANDARD: return -1; case TX_NULL_DATA: return 1; case TX_PUBKEY: case TX_PUBKEY_DROP: return 1; case TX_PUBKEYHASH: return 2; case TX_MULTISIG: if (vSolutions.size() < 1 || vSolutions[0].size() < 1) return -1; return vSolutions[0][0] + 1; case TX_SCRIPTHASH: return 1; // doesn't include args needed by the script } return -1; } bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) { vector vSolutions; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == TX_MULTISIG) { unsigned char m = vSolutions.front()[0]; unsigned char n = vSolutions.back()[0]; // Support up to x-of-3 multisig txns as standard if (n < 1 || n > 3) return false; if (m < 1 || m > n) return false; } return whichType != TX_NONSTANDARD; } unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) { unsigned int nResult = 0; BOOST_FOREACH(const valtype& pubkey, pubkeys) { CKeyID keyID = CPubKey(pubkey).GetID(); if (keystore.HaveKey(keyID)) ++nResult; } return nResult; } class CKeyStoreIsMineVisitor : public boost::static_visitor { private: const CKeyStore *keystore; public: CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { } bool operator()(const CNoDestination &dest) const { return false; } bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); } bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } }; isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) { CScript script; script.SetDestination(dest); return IsMine(keystore, script); } isminetype IsMine(const CKeyStore &keystore, const CBitcoinAddress& dest) { CScript script; script.SetAddress(dest); return IsMine(keystore, script); } isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) { vector vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) return MINE_WATCH_ONLY; return MINE_NO; } CKeyID keyID; switch (whichType) { case TX_NONSTANDARD: case TX_NULL_DATA: break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); if (keystore.HaveKey(keyID)) return MINE_SPENDABLE; break; case TX_PUBKEY_DROP: { CPubKey key = CPubKey(vSolutions[0]); CPubKey R = CPubKey(vSolutions[1]); if (keystore.CheckOwnership(key, R)) return MINE_SPENDABLE; } break; case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (keystore.HaveKey(keyID)) return MINE_SPENDABLE; break; case TX_SCRIPTHASH: { CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { isminetype ret = IsMine(keystore, subscript); if (ret == MINE_SPENDABLE) return ret; } break; } case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the // keys involved. multi-signature transactions that are // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); if (HaveKeys(keys, keystore) == keys.size()) return MINE_SPENDABLE; break; } } if (keystore.HaveWatchOnly(scriptPubKey)) return MINE_WATCH_ONLY; return MINE_NO; } bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { vector vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == TX_PUBKEY) { addressRet = CPubKey(vSolutions[0]).GetID(); return true; } else if (whichType == TX_PUBKEYHASH) { addressRet = CKeyID(uint160(vSolutions[0])); return true; } else if (whichType == TX_SCRIPTHASH) { addressRet = CScriptID(uint160(vSolutions[0])); return true; } // Multisig txns have more than one address... return false; } class CAffectedKeysVisitor : public boost::static_visitor { private: const CKeyStore &keystore; CAffectedKeysVisitor& operator=(CAffectedKeysVisitor const&); std::vector &vKeys; public: CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {} void Process(const CScript &script) { txnouttype type; std::vector vDest; int nRequired; if (ExtractDestinations(script, type, vDest, nRequired)) { BOOST_FOREACH(const CTxDestination &dest, vDest) boost::apply_visitor(*this, dest); } } void operator()(const CKeyID &keyId) { if (keystore.HaveKey(keyId)) vKeys.push_back(keyId); } void operator()(const CScriptID &scriptId) { CScript script; if (keystore.GetCScript(scriptId, script)) Process(script); } void operator()(const CNoDestination &none) {} }; void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector &vKeys) { CAffectedKeysVisitor(keystore, vKeys).Process(scriptPubKey); } bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector& addressRet, int& nRequiredRet) { addressRet.clear(); typeRet = TX_NONSTANDARD; vector vSolutions; if (!Solver(scriptPubKey, typeRet, vSolutions)) return false; if (typeRet == TX_NULL_DATA) { nRequiredRet = 0; return true; } if (typeRet == TX_MULTISIG) { nRequiredRet = vSolutions.front()[0]; for (unsigned int i = 1; i < vSolutions.size()-1; i++) { CTxDestination address = CPubKey(vSolutions[i]).GetID(); addressRet.push_back(address); } } else { nRequiredRet = 1; if (typeRet == TX_PUBKEY_DROP) return true; CTxDestination address; if (!ExtractDestination(scriptPubKey, address)) return false; addressRet.push_back(address); } return true; } bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) { vector > stack, stackCopy; if (!EvalScript(stack, scriptSig, txTo, nIn, flags, nHashType)) return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags, nHashType)) return false; if (stack.empty()) return false; if (CastToBool(stack.back()) == false) return false; // Additional validation for spend-to-script-hash transactions: if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { if (!scriptSig.IsPushOnly()) // scriptSig must be literals-only return false; // or validation fails // stackCopy cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with // an empty stack and the EvalScript above would return false. assert(!stackCopy.empty()); const valtype& pubKeySerialized = stackCopy.back(); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stackCopy); if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags, nHashType)) return false; if (stackCopy.empty()) return false; return CastToBool(stackCopy.back()); } return true; } bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType) { assert(nIn < txTo.vin.size()); CTxIn& txin = txTo.vin[nIn]; // Leave out the signature from the hash, since a signature can't sign itself. // The checksig op will also drop the signatures from its hash. uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType); txnouttype whichType; if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType)) return false; if (whichType == TX_SCRIPTHASH) { // Solver returns the subscript that need to be evaluated; // the final scriptSig is the signatures from that // and then the serialized subscript: CScript subscript = txin.scriptSig; // Recompute txn hash using subscript in place of scriptPubKey: uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType); txnouttype subType; bool fSolved = Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH; // Append serialized subscript whether or not it is completely signed: txin.scriptSig << static_cast(subscript); if (!fSolved) return false; } // Test solution return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STRICT_FLAGS, 0); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType) { assert(nIn < txTo.vin.size()); CTxIn& txin = txTo.vin[nIn]; assert(txin.prevout.n < txFrom.vout.size()); assert(txin.prevout.hash == txFrom.GetHash()); const CTxOut& txout = txFrom.vout[txin.prevout.n]; return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); } static CScript PushAll(const vector& values) { CScript result; BOOST_FOREACH(const valtype& v, values) result << v; return result; } static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const vector& vSolutions, vector& sigs1, vector& sigs2) { // Combine all the signatures we've got: set allsigs; BOOST_FOREACH(const valtype& v, sigs1) { if (!v.empty()) allsigs.insert(v); } BOOST_FOREACH(const valtype& v, sigs2) { if (!v.empty()) allsigs.insert(v); } // Build a map of pubkey -> signature by matching sigs to pubkeys: assert(vSolutions.size() > 1); unsigned int nSigsRequired = vSolutions.front()[0]; unsigned int nPubKeys = (unsigned int)(vSolutions.size()-2); map sigs; BOOST_FOREACH(const valtype& sig, allsigs) { for (unsigned int i = 0; i < nPubKeys; i++) { const valtype& pubkey = vSolutions[i+1]; if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0, 0)) { sigs[pubkey] = sig; break; } } } // Now build a merged CScript: unsigned int nSigsHave = 0; CScript result; result << OP_0; // pop-one-too-many workaround for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) { if (sigs.count(vSolutions[i+1])) { result << sigs[vSolutions[i+1]]; ++nSigsHave; } } // Fill any missing with OP_0: for (unsigned int i = nSigsHave; i < nSigsRequired; i++) result << OP_0; return result; } static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const txnouttype txType, const vector& vSolutions, vector& sigs1, vector& sigs2) { switch (txType) { case TX_NONSTANDARD: case TX_NULL_DATA: // Don't know anything about this, assume bigger one is correct: if (sigs1.size() >= sigs2.size()) return PushAll(sigs1); return PushAll(sigs2); case TX_PUBKEY: case TX_PUBKEY_DROP: case TX_PUBKEYHASH: // Signatures are bigger than placeholders or empty scripts: if (sigs1.empty() || sigs1[0].empty()) return PushAll(sigs2); return PushAll(sigs1); case TX_SCRIPTHASH: if (sigs1.empty() || sigs1.back().empty()) return PushAll(sigs2); else if (sigs2.empty() || sigs2.back().empty()) return PushAll(sigs1); else { // Recur to combine: valtype spk = sigs1.back(); CScript pubKey2(spk.begin(), spk.end()); txnouttype txType2; vector > vSolutions2; Solver(pubKey2, txType2, vSolutions2); sigs1.pop_back(); sigs2.pop_back(); CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2); result << spk; return result; } case TX_MULTISIG: return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2); } return CScript(); } CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2) { txnouttype txType; vector > vSolutions; Solver(scriptPubKey, txType, vSolutions); vector stack1; EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); vector stack2; EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); } unsigned int CScript::GetSigOpCount(bool fAccurate) const { unsigned int n = 0; const_iterator pc = begin(); opcodetype lastOpcode = OP_INVALIDOPCODE; while (pc < end()) { opcodetype opcode; if (!GetOp(pc, opcode)) break; if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY) n++; else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY) { if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) n += DecodeOP_N(lastOpcode); else n += 20; } lastOpcode = opcode; } 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(); vector data; while (pc < scriptSig.end()) { opcodetype opcode; if (!scriptSig.GetOp(pc, opcode, data)) return 0; if (opcode > OP_16) return 0; } /// ... and return its opcount: CScript subscript(data.begin(), data.end()); return subscript.GetSigOpCount(true); } bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: return (this->size() == 23 && this->at(0) == OP_HASH160 && this->at(1) == 0x14 && this->at(22) == OP_EQUAL); } bool CScript::HasCanonicalPushes() const { const_iterator pc = begin(); while (pc < end()) { opcodetype opcode; std::vector 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 { private: CScript *script; public: CScriptVisitor(CScript *scriptin) { script = scriptin; } bool operator()(const CNoDestination &dest) const { script->clear(); return false; } bool operator()(const CKeyID &keyID) const { script->clear(); *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; return true; } bool operator()(const CScriptID &scriptID) const { script->clear(); *script << OP_HASH160 << scriptID << OP_EQUAL; return true; } }; void CScript::SetDestination(const CTxDestination& dest) { boost::apply_visitor(CScriptVisitor(this), dest); } void CScript::SetAddress(const CBitcoinAddress& dest) { this->clear(); if (dest.IsScript()) *this << OP_HASH160 << dest.GetData() << OP_EQUAL; else if (dest.IsPubKey()) *this << OP_DUP << OP_HASH160 << dest.GetData() << OP_EQUALVERIFY << OP_CHECKSIG; else if (dest.IsPair()) { // Pubkey pair address, going to generate // new one-time public key. CMalleablePubKey mpk; if (!mpk.setvch(dest.GetData())) return; CPubKey R, pubKeyVariant; mpk.GetVariant(R, pubKeyVariant); *this << pubKeyVariant << R << OP_DROP << OP_CHECKSIG; } } void CScript::SetMultisig(int nRequired, const std::vector& keys) { this->clear(); *this << EncodeOP_N(nRequired); BOOST_FOREACH(const CKey& key, keys) *this << key.GetPubKey(); *this << EncodeOP_N((int)(keys.size())) << OP_CHECKMULTISIG; }