Esempio n. 1
0
def UnaryOp(opcode, stack):
    if len(stack) < 1:
        return False
    bn = CastToBigNum(stack.pop())

    if opcode == OP_1ADD:
        bn += 1

    elif opcode == OP_1SUB:
        bn -= 1

    elif opcode == OP_2MUL:
        bn <<= 1

    elif opcode == OP_2DIV:
        bn >>= 1

    elif opcode == OP_NEGATE:
        bn = -bn

    elif opcode == OP_ABS:
        if bn < 0:
            bn = -bn

    elif opcode == OP_NOT:
        bn = long(bn == 0)

    elif opcode == OP_0NOTEQUAL:
        bn = long(bn != 0)

    else:
        return False

    stack.append(bn2vch(bn))

    return True
Esempio n. 2
0
def UnaryOp(opcode, stack):
    if len(stack) < 1:
        return False
    bn = CastToBigNum(stack.pop())

    if opcode == OP_1ADD:
        bn += 1

    elif opcode == OP_1SUB:
        bn -= 1

    elif opcode == OP_2MUL:
        bn <<= 1

    elif opcode == OP_2DIV:
        bn >>= 1

    elif opcode == OP_NEGATE:
        bn = -bn

    elif opcode == OP_ABS:
        if bn < 0:
            bn = -bn

    elif opcode == OP_NOT:
        bn = long(bn == 0)

    elif opcode == OP_0NOTEQUAL:
        bn = long(bn != 0)

    else:
        return False

    stack.append(bn2vch(bn))

    return True
Esempio n. 3
0
def EvalScript(stack, scriptIn, txTo, inIdx, hashtype):
    altstack = []
    vfExec = []
    script = CScript(scriptIn)
    while script.pc < script.pend:
        if not script.getop():
            return False
        sop = script.sop

        fExec = CheckExec(vfExec)

        if fExec and sop.op <= OP_PUSHDATA4:
            stack.append(sop.data)
            continue

        elif fExec and sop.op == OP_1NEGATE or ((sop.op >= OP_1) and (sop.op <= OP_16)):
            v = sop.op - (OP_1 - 1)
            stack.append(bn2vch(v))

        elif fExec and sop.op in ISA_BINOP:
            if not BinOp(sop.op, stack):
                return False

        elif fExec and sop.op in ISA_UNOP:
            if not UnaryOp(sop.op, stack):
                return False

        elif fExec and sop.op == OP_2DROP:
            if len(stack) < 2:
                return False
            stack.pop()
            stack.pop()

        elif fExec and sop.op == OP_2DUP:
            if len(stack) < 2:
                return False
            v1 = stack[-2]
            v2 = stack[-1]
            stack.append(v1)
            stack.append(v2)

        elif fExec and sop.op == OP_2OVER:
            if len(stack) < 4:
                return False
            v1 = stack[-4]
            v2 = stack[-3]
            stack.append(v1)
            stack.append(v2)

        elif fExec and sop.op == OP_2SWAP:
            if len(stack) < 4:
                return False
            tmp = stack[-4]
            stack[-4] = stack[-2]
            stack[-2] = tmp

            tmp = stack[-3]
            stack[-3] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_3DUP:
            if len(stack) < 3:
                return False
            v1 = stack[-3]
            v2 = stack[-2]
            v3 = stack[-1]
            stack.append(v1)
            stack.append(v2)
            stack.append(v3)

        elif fExec and sop.op == OP_CHECKMULTISIG or sop.op == OP_CHECKMULTISIGVERIFY:
            tmpScript = CScript(script.vch[script.pbegincodehash:script.pend])
            ok = CheckMultiSig(sop.op, tmpScript, stack, txTo,
                       inIdx, hashtype)
            if not ok:
                return False

        elif fExec and sop.op == OP_CHECKSIG or sop.op == OP_CHECKSIGVERIFY:
            if len(stack) < 2:
                return False
            vchPubKey = stack.pop()
            vchSig = stack.pop()
            tmpScript = CScript(script.vch[script.pbegincodehash:script.pend])

            # FIXME: find-and-delete vchSig

            ok = CheckSig(vchSig, vchPubKey, tmpScript,
                      txTo, inIdx, hashtype)
            if ok:
                if sop.op != OP_CHECKSIGVERIFY:
                    stack.append(b"\x01")
            else:
                if sop.op == OP_CHECKSIGVERIFY:
                    return False
                stack.append(b"\x00")

        elif fExec and sop.op == OP_CODESEPARATOR:
            script.pbegincodehash = script.pc

        elif fExec and sop.op == OP_DEPTH:
            bn = len(stack)
            stack.append(bn2vch(bn))

        elif fExec and sop.op == OP_DROP:
            if len(stack) < 1:
                return False
            stack.pop()

        elif fExec and sop.op == OP_DUP:
            if len(stack) < 1:
                return False
            v = stack[-1]
            stack.append(v)

        elif sop.op == OP_ELSE:
            if len(vfExec) == 0:
                return false
            vfExec[-1] = not vfExec[-1]

        elif sop.op == OP_ENDIF:
            if len(vfExec) == 0:
                return false
            vfExec.pop()

        elif fExec and sop.op == OP_EQUAL or sop.op == OP_EQUALVERIFY:
            if len(stack) < 2:
                return False
            v1 = stack.pop()
            v2 = stack.pop()

            is_equal = (v1 == v2)
            if is_equal:
                stack.append(b"\x01")
            else:
                stack.append(b"\x00")

            if sop.op == OP_EQUALVERIFY:
                if is_equal:
                    stack.pop()
                else:
                    return False

        elif fExec and sop.op == OP_FROMALTSTACK:
            if len(altstack) < 1:
                return False
            v = altstack.pop()
            stack.append(v)

        elif fExec and sop.op == OP_HASH160:
            if len(stack) < 1:
                return False
            stack.append(ser_uint160(Hash160(stack.pop())))

        elif fExec and sop.op == OP_HASH256:
            if len(stack) < 1:
                return False
            stack.append(ser_uint256(Hash(stack.pop())))

        elif sop.op == OP_IF or sop.op == OP_NOTIF:
            val = False

            if fExec:
                if len(stack) < 1:
                    return False
                vch = stack.pop()
                val = CastToBool(vch)
                if sop.op == OP_NOTIF:
                    val = not val

            vfExec.append(val)

        elif fExec and sop.op == OP_IFDUP:
            if len(stack) < 1:
                return False
            vch = stack[-1]
            if CastToBool(vch):
                stack.append(vch)

        elif fExec and sop.op == OP_NIP:
            if len(stack) < 2:
                return False
            del stack[-2]

        elif fExec and sop.op == OP_NOP or (sop.op >= OP_NOP1 and sop.op <= OP_NOP10):
            pass

        elif fExec and sop.op == OP_OVER:
            if len(stack) < 2:
                return False
            vch = stack[-2]
            stack.append(vch)

        elif fExec and sop.op == OP_PICK or sop.op == OP_ROLL:
            if len(stack) < 2:
                return False
            n = CastToBigNum(stack.pop())
            if n < 0 or n >= len(stack):
                return False
            vch = stack[-n-1]
            if sop.op == OP_ROLL:
                del stack[-n-1]
            stack.append(vch)

        elif fExec and sop.op == OP_RETURN:
            return False

        elif fExec and sop.op == OP_RIPEMD160:
            if len(stack) < 1:
                return False

            h = hashlib.new('ripemd160')
            h.update(stack.pop())
            stack.append(h.digest())

        elif fExec and sop.op == OP_ROT:
            if len(stack) < 3:
                return False
            tmp = stack[-3]
            stack[-3] = stack[-2]
            stack[-2] = tmp

            tmp = stack[-2]
            stack[-2] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_SIZE:
            if len(stack) < 1:
                return False
            bn = len(stack[-1])
            stack.append(bn2vch(bn))

        elif fExec and sop.op == OP_SHA256:
            if len(stack) < 1:
                return False
            stack.append(hashlib.sha256(stack.pop()).digest())

        elif fExec and sop.op == OP_SWAP:
            if len(stack) < 2:
                return False
            tmp = stack[-2]
            stack[-2] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_TOALTSTACK:
            if len(stack) < 1:
                return False
            v = stack.pop()
            altstack.append(v)

        elif fExec and sop.op == OP_TUCK:
            if len(stack) < 2:
                return False
            vch = stack[-1]
            stack.insert(len(stack) - 2, vch)

        elif fExec and sop.op == OP_VERIFY:
            if len(stack) < 1:
                return False
            v = CastToBool(stack[-1])
            if v:
                stack.pop()
            else:
                return False

        elif fExec and sop.op == OP_WITHIN:
            if len(stack) < 3:
                return False
            bn3 = CastToBigNum(stack.pop())
            bn2 = CastToBigNum(stack.pop())
            bn1 = CastToBigNum(stack.pop())
            v = (bn2 <= bn1) and (bn1 < bn3)
            if v:
                stack.append(b"\x01")
            else:
                stack.append(b"\x00")

        elif fExec:
            #print("Unsupported opcode", OPCODE_NAMES[sop.op])
            return False

    return True
Esempio n. 4
0
def BinOp(opcode, stack):
    if len(stack) < 2:
        return False

    bn2 = CastToBigNum(stack.pop())
    bn1 = CastToBigNum(stack.pop())

    if opcode == OP_ADD:
        bn = bn1 + bn2

    elif opcode == OP_SUB:
        bn = bn1 - bn2

    elif opcode == OP_LSHIFT:
        if bn2 < 0 or bn2 > 2048:
            return False
        bn = bn1 << bn2

    elif opcode == OP_RSHIFT:
        if bn2 < 0 or bn2 > 2048:
            return False
        bn = bn1 >> bn2

    elif opcode == OP_BOOLAND:
        bn = long(bn1 != 0 and bn2 != 0)

    elif opcode == OP_BOOLOR:
        bn = long(bn1 != 0 or bn2 != 0)

    elif opcode == OP_NUMEQUAL or opcode == OP_NUMEQUALVERIFY:
        bn = long(bn1 == bn2)

    elif opcode == OP_NUMNOTEQUAL:
        bn = long(bn1 != bn2)

    elif opcode == OP_LESSTHAN:
        bn = long(bn1 < bn2)

    elif opcode == OP_GREATERTHAN:
        bn = long(bn1 > bn2)

    elif opcode == OP_LESSTHANOREQUAL:
        bn = long(bn1 <= bn2)

    elif opcode == OP_GREATERTHANOREQUAL:
        bn = long(bn1 >= bn2)

    elif opcode == OP_MIN:
        if bn1 < bn2:
            bn = bn1
        else:
            bn = bn2

    elif opcode == OP_MAX:
        if bn1 > bn2:
            bn = bn1
        else:
            bn = bn2

    else:
        return False            # unknown binop opcode

    stack.append(bn2vch(bn))

    if opcode == OP_NUMEQUALVERIFY:
        if CastToBool(stack[-1]):
            stack.pop()
        else:
            return False

    return True
Esempio n. 5
0
def EvalScript(stack, scriptIn, txTo, inIdx, hashtype):
    altstack = []
    vfExec = []
    script = CScript(scriptIn)
    while script.pc < script.pend:
        if not script.getop():
            return False
        sop = script.sop

        fExec = CheckExec(vfExec)

        if fExec and sop.op <= OP_PUSHDATA4:
            stack.append(sop.data)
            continue

        elif fExec and sop.op == OP_1NEGATE or ((sop.op >= OP_1) and
                                                (sop.op <= OP_16)):
            v = sop.op - (OP_1 - 1)
            stack.append(bn2vch(v))

        elif fExec and sop.op in ISA_BINOP:
            if not BinOp(sop.op, stack):
                return False

        elif fExec and sop.op in ISA_UNOP:
            if not UnaryOp(sop.op, stack):
                return False

        elif fExec and sop.op == OP_2DROP:
            if len(stack) < 2:
                return False
            stack.pop()
            stack.pop()

        elif fExec and sop.op == OP_2DUP:
            if len(stack) < 2:
                return False
            v1 = stack[-2]
            v2 = stack[-1]
            stack.append(v1)
            stack.append(v2)

        elif fExec and sop.op == OP_2OVER:
            if len(stack) < 4:
                return False
            v1 = stack[-4]
            v2 = stack[-3]
            stack.append(v1)
            stack.append(v2)

        elif fExec and sop.op == OP_2SWAP:
            if len(stack) < 4:
                return False
            tmp = stack[-4]
            stack[-4] = stack[-2]
            stack[-2] = tmp

            tmp = stack[-3]
            stack[-3] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_3DUP:
            if len(stack) < 3:
                return False
            v1 = stack[-3]
            v2 = stack[-2]
            v3 = stack[-1]
            stack.append(v1)
            stack.append(v2)
            stack.append(v3)

        elif fExec and sop.op == OP_CHECKMULTISIG or sop.op == OP_CHECKMULTISIGVERIFY:
            tmpScript = CScript(script.vch[script.pbegincodehash:script.pend])
            ok = CheckMultiSig(sop.op, tmpScript, stack, txTo, inIdx, hashtype)
            if not ok:
                return False

        elif fExec and sop.op == OP_CHECKSIG or sop.op == OP_CHECKSIGVERIFY:
            if len(stack) < 2:
                return False
            vchPubKey = stack.pop()
            vchSig = stack.pop()
            tmpScript = CScript(script.vch[script.pbegincodehash:script.pend])

            # FIXME: find-and-delete vchSig

            ok = CheckSig(vchSig, vchPubKey, tmpScript, txTo, inIdx, hashtype)
            if ok:
                if sop.op != OP_CHECKSIGVERIFY:
                    stack.append(b"\x01")
            else:
                if sop.op == OP_CHECKSIGVERIFY:
                    return False
                stack.append(b"\x00")

        elif fExec and sop.op == OP_CODESEPARATOR:
            script.pbegincodehash = script.pc

        elif fExec and sop.op == OP_DEPTH:
            bn = len(stack)
            stack.append(bn2vch(bn))

        elif fExec and sop.op == OP_DROP:
            if len(stack) < 1:
                return False
            stack.pop()

        elif fExec and sop.op == OP_DUP:
            if len(stack) < 1:
                return False
            v = stack[-1]
            stack.append(v)

        elif sop.op == OP_ELSE:
            if len(vfExec) == 0:
                return false
            vfExec[-1] = not vfExec[-1]

        elif sop.op == OP_ENDIF:
            if len(vfExec) == 0:
                return false
            vfExec.pop()

        elif fExec and sop.op == OP_EQUAL or sop.op == OP_EQUALVERIFY:
            if len(stack) < 2:
                return False
            v1 = stack.pop()
            v2 = stack.pop()

            is_equal = (v1 == v2)
            if is_equal:
                stack.append(b"\x01")
            else:
                stack.append(b"\x00")

            if sop.op == OP_EQUALVERIFY:
                if is_equal:
                    stack.pop()
                else:
                    return False

        elif fExec and sop.op == OP_FROMALTSTACK:
            if len(altstack) < 1:
                return False
            v = altstack.pop()
            stack.append(v)

        elif fExec and sop.op == OP_HASH160:
            if len(stack) < 1:
                return False
            stack.append(ser_uint160(Hash160(stack.pop())))

        elif fExec and sop.op == OP_HASH256:
            if len(stack) < 1:
                return False
            stack.append(ser_uint256(Hash(stack.pop())))

        elif sop.op == OP_IF or sop.op == OP_NOTIF:
            val = False

            if fExec:
                if len(stack) < 1:
                    return False
                vch = stack.pop()
                val = CastToBool(vch)
                if sop.op == OP_NOTIF:
                    val = not val

            vfExec.append(val)

        elif fExec and sop.op == OP_IFDUP:
            if len(stack) < 1:
                return False
            vch = stack[-1]
            if CastToBool(vch):
                stack.append(vch)

        elif fExec and sop.op == OP_NIP:
            if len(stack) < 2:
                return False
            del stack[-2]

        elif fExec and sop.op == OP_NOP or (sop.op >= OP_NOP1
                                            and sop.op <= OP_NOP10):
            pass

        elif fExec and sop.op == OP_OVER:
            if len(stack) < 2:
                return False
            vch = stack[-2]
            stack.append(vch)

        elif fExec and sop.op == OP_PICK or sop.op == OP_ROLL:
            if len(stack) < 2:
                return False
            n = CastToBigNum(stack.pop())
            if n < 0 or n >= len(stack):
                return False
            vch = stack[-n - 1]
            if sop.op == OP_ROLL:
                del stack[-n - 1]
            stack.append(vch)

        elif fExec and sop.op == OP_RETURN:
            return False

        elif fExec and sop.op == OP_RIPEMD160:
            if len(stack) < 1:
                return False

            h = hashlib.new('ripemd160')
            h.update(stack.pop())
            stack.append(h.digest())

        elif fExec and sop.op == OP_ROT:
            if len(stack) < 3:
                return False
            tmp = stack[-3]
            stack[-3] = stack[-2]
            stack[-2] = tmp

            tmp = stack[-2]
            stack[-2] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_SIZE:
            if len(stack) < 1:
                return False
            bn = len(stack[-1])
            stack.append(bn2vch(bn))

        elif fExec and sop.op == OP_SHA256:
            if len(stack) < 1:
                return False
            stack.append(hashlib.sha256(stack.pop()).digest())

        elif fExec and sop.op == OP_SWAP:
            if len(stack) < 2:
                return False
            tmp = stack[-2]
            stack[-2] = stack[-1]
            stack[-1] = tmp

        elif fExec and sop.op == OP_TOALTSTACK:
            if len(stack) < 1:
                return False
            v = stack.pop()
            altstack.append(v)

        elif fExec and sop.op == OP_TUCK:
            if len(stack) < 2:
                return False
            vch = stack[-1]
            stack.insert(len(stack) - 2, vch)

        elif fExec and sop.op == OP_VERIFY:
            if len(stack) < 1:
                return False
            v = CastToBool(stack[-1])
            if v:
                stack.pop()
            else:
                return False

        elif fExec and sop.op == OP_WITHIN:
            if len(stack) < 3:
                return False
            bn3 = CastToBigNum(stack.pop())
            bn2 = CastToBigNum(stack.pop())
            bn1 = CastToBigNum(stack.pop())
            v = (bn2 <= bn1) and (bn1 < bn3)
            if v:
                stack.append(b"\x01")
            else:
                stack.append(b"\x00")

        elif fExec:
            #print("Unsupported opcode", OPCODE_NAMES[sop.op])
            return False

    return True
Esempio n. 6
0
def BinOp(opcode, stack):
    if len(stack) < 2:
        return False

    bn2 = CastToBigNum(stack.pop())
    bn1 = CastToBigNum(stack.pop())

    if opcode == OP_ADD:
        bn = bn1 + bn2

    elif opcode == OP_SUB:
        bn = bn1 - bn2

    elif opcode == OP_LSHIFT:
        if bn2 < 0 or bn2 > 2048:
            return False
        bn = bn1 << bn2

    elif opcode == OP_RSHIFT:
        if bn2 < 0 or bn2 > 2048:
            return False
        bn = bn1 >> bn2

    elif opcode == OP_BOOLAND:
        bn = long(bn1 != 0 and bn2 != 0)

    elif opcode == OP_BOOLOR:
        bn = long(bn1 != 0 or bn2 != 0)

    elif opcode == OP_NUMEQUAL or opcode == OP_NUMEQUALVERIFY:
        bn = long(bn1 == bn2)

    elif opcode == OP_NUMNOTEQUAL:
        bn = long(bn1 != bn2)

    elif opcode == OP_LESSTHAN:
        bn = long(bn1 < bn2)

    elif opcode == OP_GREATERTHAN:
        bn = long(bn1 > bn2)

    elif opcode == OP_LESSTHANOREQUAL:
        bn = long(bn1 <= bn2)

    elif opcode == OP_GREATERTHANOREQUAL:
        bn = long(bn1 >= bn2)

    elif opcode == OP_MIN:
        if bn1 < bn2:
            bn = bn1
        else:
            bn = bn2

    elif opcode == OP_MAX:
        if bn1 > bn2:
            bn = bn1
        else:
            bn = bn2

    else:
        return False  # unknown binop opcode

    stack.append(bn2vch(bn))

    if opcode == OP_NUMEQUALVERIFY:
        if CastToBool(stack[-1]):
            stack.pop()
        else:
            return False

    return True