コード例 #1
0
def create_forwarder_to(expr, args, kwargs, context):

    value = kwargs['value']
    if value != zero_value:
        enforce_units(value.typ, get_keyword(expr, 'value'),
                      BaseType('uint256', {'wei': 1}))
    if context.is_constant():
        raise ConstancyViolationException(
            f"Cannot make calls from {context.pp_constancy()}",
            expr,
        )
    placeholder = context.new_placeholder(ByteArrayType(96))

    kode = get_create_forwarder_to_bytecode()
    high = bytes_to_int(kode[:32])
    low = bytes_to_int((kode + b'\x00' * 32)[47:79])

    return LLLnode.from_list(
        [
            'seq',
            ['mstore', placeholder, high],
            ['mstore', ['add', placeholder, 27], ['mul', args[0], 2**96]],
            ['mstore', ['add', placeholder, 47], low],
            ['clamp_nonzero', ['create', value, placeholder, 96]],
        ],
        typ=BaseType('address'),
        pos=getpos(expr),
        add_gas_estimate=11000,
    )
コード例 #2
0
def keccak256_helper(expr, to_hash, context):
    _check_byteslike(to_hash.typ, expr)

    # Can hash literals
    # TODO this is dead code.
    if isinstance(to_hash, bytes):
        return IRnode.from_list(bytes_to_int(keccak256(to_hash)),
                                typ=BaseType("bytes32"))

    # Can hash bytes32 objects
    if is_base_type(to_hash.typ, "bytes32"):
        return IRnode.from_list(
            [
                "seq",
                ["mstore", MemoryPositions.FREE_VAR_SPACE, to_hash],
                ["sha3", MemoryPositions.FREE_VAR_SPACE, 32],
            ],
            typ=BaseType("bytes32"),
            add_gas_estimate=_gas_bound(1),
        )

    to_hash = ensure_in_memory(to_hash, context)

    with to_hash.cache_when_complex("buf") as (b1, to_hash):
        data = bytes_data_ptr(to_hash)
        len_ = get_bytearray_length(to_hash)
        return b1.resolve(
            IRnode.from_list(
                ["sha3", data, len_],
                typ="bytes32",
                annotation="keccak256",
                add_gas_estimate=_gas_bound(ceil(to_hash.typ.maxlen / 32)),
            ))
コード例 #3
0
def _sha3(expr, args, kwargs, context):
    sub = args[0]
    # Can hash literals
    if isinstance(sub, bytes):
        return LLLnode.from_list(bytes_to_int(sha3(sub)), typ=BaseType('bytes32'), pos=getpos(expr))
    # Can hash bytes32 objects
    if is_base_type(sub.typ, 'bytes32'):
        return LLLnode.from_list(
            ['seq', ['mstore', MemoryPositions.FREE_VAR_SPACE, sub], ['sha3', MemoryPositions.FREE_VAR_SPACE, 32]], typ=BaseType('bytes32'),
            pos=getpos(expr)
        )
    # Copy the data to an in-memory array
    if sub.location == "memory":
        # If we are hashing a value in memory, no need to copy it, just hash in-place
        return LLLnode.from_list(
            ['with', '_sub', sub, ['sha3', ['add', '_sub', 32], ['mload', '_sub']]], typ=BaseType('bytes32'),
            pos=getpos(expr)
        )
    elif sub.location == "storage":
        lengetter = LLLnode.from_list(['sload', ['sha3_32', '_sub']], typ=BaseType('int128'))
    else:
        # This should never happen, but just left here for future compiler-writers.
        raise Exception("Unsupported location: %s" % sub.location)  # pragma: no test
    placeholder = context.new_placeholder(sub.typ)
    placeholder_node = LLLnode.from_list(placeholder, typ=sub.typ, location='memory')
    copier = make_byte_array_copier(placeholder_node, LLLnode.from_list('_sub', typ=sub.typ, location=sub.location))
    return LLLnode.from_list(
        ['with', '_sub', sub, ['seq', copier, ['sha3', ['add', placeholder, 32], lengetter]]], typ=BaseType('bytes32'),
        pos=getpos(expr)
    )
コード例 #4
0
def keccak256_helper(expr, ir_arg, context):
    sub = ir_arg  # TODO get rid of useless variable
    _check_byteslike(sub.typ, expr)

    # Can hash literals
    # TODO this is dead code.
    if isinstance(sub, bytes):
        return IRnode.from_list(bytes_to_int(keccak256(sub)),
                                typ=BaseType("bytes32"))

    # Can hash bytes32 objects
    if is_base_type(sub.typ, "bytes32"):
        return IRnode.from_list(
            [
                "seq",
                ["mstore", MemoryPositions.FREE_VAR_SPACE, sub],
                ["sha3", MemoryPositions.FREE_VAR_SPACE, 32],
            ],
            typ=BaseType("bytes32"),
            add_gas_estimate=_gas_bound(1),
        )

    sub = ensure_in_memory(sub, context)

    return IRnode.from_list(
        [
            "with",
            "_buf",
            sub,
            ["sha3", ["add", "_buf", 32], ["mload", "_buf"]],
        ],
        typ=BaseType("bytes32"),
        annotation="keccak256",
        add_gas_estimate=_gas_bound(ceil(sub.typ.maxlen / 32)),
    )
コード例 #5
0
ファイル: conftest.py プロジェクト: Shawnsxh/eth.py
 def fake_tx():
     address = inject_tx(
         "0xf9035b808506fc23ac0083045f788080b903486103305660006109ac5260006109cc527f0100000000000000000000000000000000000000000000000000000000000000600035046109ec526000610a0c5260006109005260c06109ec51101515585760f86109ec51101561006e5760bf6109ec510336141558576001610a0c52610098565b60013560f76109ec51036020035260005160f66109ec510301361415585760f66109ec5103610a0c525b61022060016064818352015b36610a0c511015156100b557610291565b7f0100000000000000000000000000000000000000000000000000000000000000610a0c5135046109ec526109cc5160206109ac51026040015260016109ac51016109ac5260806109ec51101561013b5760016109cc5161044001526001610a0c516109cc5161046001376001610a0c5101610a0c5260216109cc51016109cc52610281565b60b86109ec5110156101d15760806109ec51036109cc51610440015260806109ec51036001610a0c51016109cc51610460013760816109ec5114156101ac5760807f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350410151558575b607f6109ec5103610a0c5101610a0c5260606109ec51036109cc51016109cc52610280565b60c06109ec51101561027d576001610a0c51013560b76109ec510360200352600051610a2c526038610a2c5110157f01000000000000000000000000000000000000000000000000000000000000006001610a0c5101350402155857610a2c516109cc516104400152610a2c5160b66109ec5103610a0c51016109cc516104600137610a2c5160b66109ec5103610a0c510101610a0c526020610a2c51016109cc51016109cc5261027f565bfe5b5b5b81516001018083528114156100a4575b5050601f6109ac511115155857602060206109ac5102016109005260206109005103610a0c5261022060016064818352015b6000610a0c5112156102d45761030a565b61090051610a0c516040015101610a0c51610900516104400301526020610a0c5103610a0c5281516001018083528114156102c3575b50506109cc516109005101610420526109cc5161090051016109005161044003f35b61000461033003610004600039610004610330036000f31b2d4f"
     )
     assert vyper_utils.bytes_to_int(
         address) == vyper_utils.RLP_DECODER_ADDRESS
     return address
コード例 #6
0
def pack_logging_topics(event_id, args, expected_topics, context):
    topics = [event_id]
    for pos, expected_topic in enumerate(expected_topics):
        typ = expected_topic.typ
        arg = args[pos]
        value = parse_expr(arg, context)
        if isinstance(typ, ByteArrayType) and (
                isinstance(arg, ast.Str) or
            (isinstance(arg, ast.Name) and arg.id not in reserved_words)):
            if value.typ.maxlen > typ.maxlen:
                raise TypeMismatchException(
                    "Topic input bytes are to big: %r %r" % (value.typ, typ))
            if isinstance(arg, ast.Str):
                bytez, bytez_length = string_to_bytes(arg.s)
                if len(bytez) > 32:
                    raise InvalidLiteralException(
                        "Can only log a maximum of 32 bytes at a time.")
                topics.append(
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                size = context.vars[arg.id].size
                topics.append(byte_array_to_num(value, arg, 'uint256', size))
        else:
            value = unwrap_location(value)
            value = base_type_conversion(value, value.typ, typ)
            topics.append(value)
    return topics
コード例 #7
0
    def ann_assign(self):
        self.context.set_in_assignment(True)
        typ = parse_type(self.stmt.annotation, location='memory', custom_units=self.context.custom_units, custom_structs=self.context.structs)
        if isinstance(self.stmt.target, ast.Attribute):
            raise TypeMismatchException('May not set type for field %r' % self.stmt.target.attr, self.stmt)
        varname = self.stmt.target.id
        pos = self.context.new_variable(varname, typ)
        o = LLLnode.from_list('pass', typ=None, pos=pos)
        if self.stmt.value is not None:
            sub = Expr(self.stmt.value, self.context).lll_node

            # Disallow assignment to None
            if isinstance(sub.typ, NullType):
                raise InvalidLiteralException('Assignment to None is not allowed, use a default value or built-in `clear()`.', self.stmt)

            # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
            if isinstance(sub.typ, ByteArrayType) and sub.typ.maxlen == 32 and isinstance(typ, BaseType) and typ.typ == 'bytes32':
                bytez, bytez_length = string_to_bytes(self.stmt.value.s)
                sub = LLLnode(bytes_to_int(bytez), typ=BaseType('bytes32'), pos=getpos(self.stmt))

            self._check_valid_assign(sub)
            self._check_same_variable_assign(sub)
            variable_loc = LLLnode.from_list(pos, typ=typ, location='memory', pos=getpos(self.stmt))
            o = make_setter(variable_loc, sub, 'memory', pos=getpos(self.stmt))
        # o.pos = getpos(self.stmt) # TODO: Should this be here like in assign()?
        self.context.set_in_assignment(False)
        return o
コード例 #8
0
ファイル: stmt.py プロジェクト: ProGamerCode/vyper
    def parse_AnnAssign(self):
        typ = parse_type(
            self.stmt.annotation,
            sigs=self.context.sigs,
            custom_structs=self.context.structs,
        )
        varname = self.stmt.target.id
        pos = self.context.new_variable(varname, typ)
        if self.stmt.value is None:
            return

        sub = Expr(self.stmt.value, self.context).ir_node

        is_literal_bytes32_assign = (isinstance(sub.typ, ByteArrayType)
                                     and sub.typ.maxlen == 32
                                     and isinstance(typ, BaseType)
                                     and typ.typ == "bytes32"
                                     and sub.typ.is_literal)

        # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
        if is_literal_bytes32_assign:
            sub = IRnode(
                util.bytes_to_int(self.stmt.value.s),
                typ=BaseType("bytes32"),
            )

        variable_loc = IRnode.from_list(pos, typ=typ, location=MEMORY)

        ir_node = make_setter(variable_loc, sub)

        return ir_node
コード例 #9
0
ファイル: stmt.py プロジェクト: spencerbh/vyper
 def ann_assign(self):
     self.context.set_in_assignment(True)
     typ = parse_type(self.stmt.annotation,
                      location='memory',
                      custom_units=self.context.custom_units)
     if isinstance(self.stmt.target,
                   ast.Attribute) and self.stmt.target.value.id == 'self':
         raise TypeMismatchException('May not redefine storage variables.',
                                     self.stmt)
     varname = self.stmt.target.id
     pos = self.context.new_variable(varname, typ)
     o = LLLnode.from_list('pass', typ=None, pos=pos)
     if self.stmt.value is not None:
         sub = Expr(self.stmt.value, self.context).lll_node
         # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
         if isinstance(
                 sub.typ,
                 ByteArrayType) and sub.typ.maxlen == 32 and isinstance(
                     typ, BaseType) and typ.typ == 'bytes32':
             bytez, bytez_length = string_to_bytes(self.stmt.value.s)
             sub = LLLnode(bytes_to_int(bytez),
                           typ=BaseType('bytes32'),
                           pos=getpos(self.stmt))
         self._check_valid_assign(sub)
         self._check_same_variable_assign(sub)
         variable_loc = LLLnode.from_list(pos,
                                          typ=typ,
                                          location='memory',
                                          pos=getpos(self.stmt))
         o = make_setter(variable_loc, sub, 'memory', pos=getpos(self.stmt))
     self.context.set_in_assignment(False)
     return o
コード例 #10
0
def pack_logging_topics(event_id, args, expected_topics, context, pos):
    topics = [event_id]
    for pos, expected_topic in enumerate(expected_topics):
        expected_type = expected_topic.typ
        arg = args[pos]
        value = parse_expr(arg, context)
        arg_type = value.typ

        if isinstance(arg_type, ByteArrayType) and isinstance(expected_type, ByteArrayType):
            if arg_type.maxlen > expected_type.maxlen:
                raise TypeMismatchException("Topic input bytes are too big: %r %r" % (arg_type, expected_type), pos)
            if isinstance(arg, ast.Str):
                bytez, bytez_length = string_to_bytes(arg.s)
                if len(bytez) > 32:
                    raise InvalidLiteralException("Can only log a maximum of 32 bytes at a time.", pos)
                topics.append(bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                if value.location == "memory":
                    size = ['mload', value]
                elif value.location == "storage":
                    size = ['sload', ['sha3_32', value]]
                topics.append(byte_array_to_num(value, arg, 'uint256', size))
        else:
            value = unwrap_location(value)
            value = base_type_conversion(value, arg_type, expected_type, pos=pos)
            topics.append(value)

    return topics
コード例 #11
0
ファイル: expr.py プロジェクト: williamremor/vyper
 def string(self):
     bytez, bytez_length = string_to_bytes(self.expr.s)
     placeholder = self.context.new_placeholder(ByteArrayType(bytez_length))
     seq = []
     seq.append(['mstore', placeholder, bytez_length])
     for i in range(0, len(bytez), 32):
         seq.append(['mstore', ['add', placeholder, i + 32], bytes_to_int((bytez + b'\x00' * 31)[i: i + 32])])
     return LLLnode.from_list(['seq'] + seq + [placeholder], typ=ByteArrayType(bytez_length), location='memory', pos=getpos(self.expr))
コード例 #12
0
def create_with_code_of(expr, args, kwargs, context):
    value = kwargs['value']
    if value != zero_value:
        enforce_units(value.typ, get_keyword(expr, 'value'),
                      BaseType('int128', {'wei': 1}))
    if context.is_constant:
        raise ConstancyViolationException("Cannot make calls from a constant function", expr)
    placeholder = context.new_placeholder(ByteArrayType(96))
    kode = b'`.`\x0c`\x009`.`\x00\xf36`\x00`\x007a\x10\x00`\x006`\x00s\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\xf4\x15XWa\x10\x00`\x00\xf3'
    assert len(kode) <= 64
    high = bytes_to_int(kode[:32])
    low = bytes_to_int((kode + b'\x00' * 32)[47:79])
    return LLLnode.from_list(['seq',
                                ['mstore', placeholder, high],
                                ['mstore', ['add', placeholder, 27], ['mul', args[0], 2**96]],
                                ['mstore', ['add', placeholder, 47], low],
                                ['clamp_nonzero', ['create', value, placeholder, 64]]], typ=BaseType('address'), pos=getpos(expr), add_gas_estimate=10000)
コード例 #13
0
ファイル: expr.py プロジェクト: siromivel/vyper
 def _make_bytelike(self, btype, bytez, bytez_length):
     placeholder = self.context.new_placeholder(btype)
     seq = []
     seq.append(['mstore', placeholder, bytez_length])
     for i in range(0, len(bytez), 32):
         seq.append(['mstore', ['add', placeholder, i + 32], bytes_to_int((bytez + b'\x00' * 31)[i: i + 32])])
     return LLLnode.from_list(['seq'] + seq + [placeholder],
         typ=btype, location='memory', pos=getpos(self.expr), annotation='Create %r: %s' % (btype, bytez))
コード例 #14
0
    def ann_assign(self):
        with self.context.assignment_scope():
            typ = parse_type(
                self.stmt.annotation,
                location='memory',
                custom_units=self.context.custom_units,
                custom_structs=self.context.structs,
                constants=self.context.constants,
            )
            if isinstance(self.stmt.target, ast.Attribute):
                raise TypeMismatchException(
                    f'May not set type for field {self.stmt.target.attr}',
                    self.stmt,
                )
            varname = self.stmt.target.id
            pos = self.context.new_variable(varname, typ)
            o = LLLnode.from_list('pass', typ=None, pos=pos)
            if self.stmt.value is None:
                raise StructureException(
                    'New variables must be initialized explicitly',
                    self.stmt)

            sub = Expr(self.stmt.value, self.context).lll_node

            # Disallow assignment to None
            if isinstance(sub.typ, NullType):
                raise InvalidLiteralException(
                    (
                        'Assignment to None is not allowed, use a default '
                        'value or built-in `clear()`.'
                    ),
                    self.stmt
                )

            is_valid_bytes32_assign = (
                isinstance(sub.typ, ByteArrayType) and sub.typ.maxlen == 32
            ) and isinstance(typ, BaseType) and typ.typ == 'bytes32'

            # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
            if is_valid_bytes32_assign:
                sub = LLLnode(
                    bytes_to_int(self.stmt.value.s),
                    typ=BaseType('bytes32'),
                    pos=getpos(self.stmt),
                )

            self._check_valid_assign(sub)
            self._check_same_variable_assign(sub)
            variable_loc = LLLnode.from_list(
                pos,
                typ=typ,
                location='memory',
                pos=getpos(self.stmt),
            )
            o = make_setter(variable_loc, sub, 'memory', pos=getpos(self.stmt))
            # o.pos = getpos(self.stmt) # TODO: Should this be here like in assign()?

            return o
コード例 #15
0
    def from_declaration(cls, code, custom_units=None):
        name = code.target.id
        pos = 0

        if not is_varname_valid(name, custom_units=custom_units):
            raise EventDeclarationException("Event name invalid: " + name)
        # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...
        args = []
        indexed_list = []
        topics_count = 1
        if code.annotation.args:
            keys = code.annotation.args[0].keys
            values = code.annotation.args[0].values
            for i in range(len(keys)):
                typ = values[i]
                arg = keys[i].id
                is_indexed = False
                # Check to see if argument is a topic
                if isinstance(typ, ast.Call) and typ.func.id == 'indexed':
                    typ = values[i].args[0]
                    indexed_list.append(True)
                    topics_count += 1
                    is_indexed = True
                else:
                    indexed_list.append(False)
                if isinstance(typ, ast.Subscript) and getattr(
                        typ.value, 'id', None
                ) == 'bytes' and typ.slice.value.n > 32 and is_indexed:
                    raise EventDeclarationException(
                        "Indexed arguments are limited to 32 bytes")
                if topics_count > 4:
                    raise EventDeclarationException(
                        "Maximum of 3 topics {} given".format(topics_count -
                                                              1), arg)
                if not isinstance(arg, str):
                    raise VariableDeclarationException("Argument name invalid",
                                                       arg)
                if not typ:
                    raise InvalidTypeException("Argument must have type", arg)
                if not is_varname_valid(arg, custom_units):
                    raise VariableDeclarationException(
                        "Argument name invalid or reserved: " + arg, arg)
                if arg in (x.name for x in args):
                    raise VariableDeclarationException(
                        "Duplicate function argument name: " + arg, arg)
                parsed_type = parse_type(typ, None, custom_units=custom_units)
                args.append(VariableRecord(arg, pos, parsed_type, False))
                if isinstance(parsed_type, ByteArrayType):
                    pos += ceil32(typ.slice.value.n)
                else:
                    pos += get_size_of_type(parsed_type) * 32
        sig = name + '(' + ','.join([
            canonicalize_type(arg.typ, indexed_list[pos])
            for pos, arg in enumerate(args)
        ]) + ')'  # noqa F812
        event_id = bytes_to_int(sha3(bytes(sig, 'utf-8')))
        return cls(name, args, indexed_list, event_id, sig)
コード例 #16
0
def keccak256_helper(expr, args, kwargs, context):
    sub = args[0]
    # Can hash literals
    if isinstance(sub, bytes):
        return LLLnode.from_list(bytes_to_int(keccak256(sub)),
                                 typ=BaseType("bytes32"),
                                 pos=getpos(expr))
    # Can hash bytes32 objects
    if is_base_type(sub.typ, "bytes32"):
        return LLLnode.from_list(
            [
                "seq",
                ["mstore", MemoryPositions.FREE_VAR_SPACE, sub],
                ["sha3", MemoryPositions.FREE_VAR_SPACE, 32],
            ],
            typ=BaseType("bytes32"),
            pos=getpos(expr),
        )
    # Copy the data to an in-memory array
    if sub.location == "memory":
        # If we are hashing a value in memory, no need to copy it, just hash in-place
        return LLLnode.from_list(
            [
                "with", "_sub", sub,
                ["sha3", ["add", "_sub", 32], ["mload", "_sub"]]
            ],
            typ=BaseType("bytes32"),
            pos=getpos(expr),
        )
    elif sub.location == "storage":
        lengetter = LLLnode.from_list(["sload", ["sha3_32", "_sub"]],
                                      typ=BaseType("int128"))
    else:
        # This should never happen, but just left here for future compiler-writers.
        raise Exception(
            f"Unsupported location: {sub.location}")  # pragma: no test
    placeholder = context.new_internal_variable(sub.typ)
    placeholder_node = LLLnode.from_list(placeholder,
                                         typ=sub.typ,
                                         location="memory")
    copier = make_byte_array_copier(
        placeholder_node,
        LLLnode.from_list("_sub", typ=sub.typ, location=sub.location),
    )
    return LLLnode.from_list(
        [
            "with", "_sub", sub,
            ["seq", copier, ["sha3", ["add", placeholder, 32], lengetter]]
        ],
        typ=BaseType("bytes32"),
        pos=getpos(expr),
    )
コード例 #17
0
    def from_declaration(cls, class_node, global_ctx):
        name = class_node.name
        pos = 0

        check_valid_varname(
            name,
            global_ctx._structs,
            global_ctx._constants,
            pos=class_node,
            error_prefix="Event name invalid. ",
            exc=EventDeclarationException,
        )

        args = []
        indexed_list = []
        if len(class_node.body) != 1 or not isinstance(class_node.body[0],
                                                       vy_ast.Pass):
            for node in class_node.body:
                arg_item = node.target
                arg = node.target.id
                typ = node.annotation

                if isinstance(typ,
                              vy_ast.Call) and typ.get("func.id") == "indexed":
                    indexed_list.append(True)
                    typ = typ.args[0]
                else:
                    indexed_list.append(False)
                check_valid_varname(
                    arg,
                    global_ctx._structs,
                    global_ctx._constants,
                    pos=arg_item,
                    error_prefix="Event argument name invalid or reserved.",
                )
                if arg in (x.name for x in args):
                    raise TypeCheckFailure(
                        f"Duplicate function argument name: {arg}")
                # Can struct be logged?
                parsed_type = global_ctx.parse_type(typ, None)
                args.append(VariableRecord(arg, pos, parsed_type, False))
                if isinstance(parsed_type, ByteArrayType):
                    pos += ceil32(typ.slice.value.n)
                else:
                    pos += get_size_of_type(parsed_type) * 32

        sig = (name + "(" + ",".join([
            canonicalize_type(arg.typ, indexed_list[pos])
            for pos, arg in enumerate(args)
        ]) + ")")  # noqa F812
        event_id = bytes_to_int(keccak256(bytes(sig, "utf-8")))
        return cls(name, args, indexed_list, event_id, sig)
コード例 #18
0
def pack_logging_topics(event_id, arg_nodes, arg_types, context):
    topics = [event_id]
    for node, typ in zip(arg_nodes, arg_types):
        value = Expr(node, context).lll_node

        if isinstance(typ, ArrayValueAbstractType):
            if isinstance(node, (vy_ast.Str, vy_ast.Bytes)):
                # for literals, generate the topic at compile time
                value = node.value
                if isinstance(value, str):
                    value = value.encode()
                topics.append(bytes_to_int(keccak256(value)))

            elif value.location == "memory":
                topics.append(["sha3", ["add", value, 32], ["mload", value]])

            else:
                # storage or calldata
                placeholder = context.new_internal_variable(value.typ)
                placeholder_node = LLLnode.from_list(placeholder, typ=value.typ, location="memory")
                copier = make_byte_array_copier(
                    placeholder_node,
                    LLLnode.from_list("_sub", typ=value.typ, location=value.location),
                )
                lll_node = [
                    "with",
                    "_sub",
                    value,
                    ["seq", copier, ["sha3", ["add", placeholder, 32], ["mload", placeholder]]],
                ]
                topics.append(lll_node)

        elif isinstance(typ, ArrayDefinition):
            size = typ.size_in_bytes
            if value.location == "memory":
                topics.append(["sha3", value, size])

            else:
                # storage or calldata
                placeholder = context.new_internal_variable(value.typ)
                placeholder_node = LLLnode.from_list(placeholder, typ=value.typ, location="memory")
                setter = make_setter(placeholder_node, value, "memory", value.pos)
                lll_node = ["seq", setter, ["sha3", placeholder, size]]
                topics.append(lll_node)

        else:
            value = unwrap_location(value)
            topics.append(value)

    return topics
コード例 #19
0
ファイル: stmt.py プロジェクト: 6pakla/vyper
    def ann_assign(self):
        with self.context.assignment_scope():
            typ = parse_type(
                self.stmt.annotation,
                location='memory',
                custom_structs=self.context.structs,
                constants=self.context.constants,
            )
            if isinstance(self.stmt.target, vy_ast.Attribute):
                raise TypeMismatch(
                    f'May not set type for field {self.stmt.target.attr}',
                    self.stmt,
                )
            varname = self.stmt.target.id
            pos = self.context.new_variable(varname, typ)
            if self.stmt.value is None:
                raise StructureException(
                    'New variables must be initialized explicitly',
                    self.stmt)

            sub = Expr(self.stmt.value, self.context).lll_node

            is_literal_bytes32_assign = (
                isinstance(sub.typ, ByteArrayType)
                and sub.typ.maxlen == 32
                and isinstance(typ, BaseType)
                and typ.typ == 'bytes32'
                and sub.typ.is_literal
            )

            # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
            if is_literal_bytes32_assign:
                sub = LLLnode(
                    bytes_to_int(self.stmt.value.s),
                    typ=BaseType('bytes32'),
                    pos=getpos(self.stmt),
                )

            self._check_valid_assign(sub)
            self._check_same_variable_assign(sub)
            variable_loc = LLLnode.from_list(
                pos,
                typ=typ,
                location='memory',
                pos=getpos(self.stmt),
            )
            o = make_setter(variable_loc, sub, 'memory', pos=getpos(self.stmt))

            return o
コード例 #20
0
 def _make_bytelike(self, btype, bytez, bytez_length):
     placeholder = self.context.new_internal_variable(btype)
     seq = []
     seq.append(["mstore", placeholder, bytez_length])
     for i in range(0, len(bytez), 32):
         seq.append([
             "mstore",
             ["add", placeholder, i + 32],
             bytes_to_int((bytez + b"\x00" * 31)[i:i + 32]),
         ])
     return IRnode.from_list(
         ["seq"] + seq + [placeholder],
         typ=btype,
         location=MEMORY,
         annotation=f"Create {btype}: {bytez}",
     )
コード例 #21
0
 def _make_bytelike(self, btype, bytez, bytez_length):
     placeholder = self.context.new_placeholder(btype)
     seq = []
     seq.append(["mstore", placeholder, bytez_length])
     for i in range(0, len(bytez), 32):
         seq.append([
             "mstore",
             ["add", placeholder, i + 32],
             bytes_to_int((bytez + b"\x00" * 31)[i:i + 32]),  # noqa: E203
         ])
     return LLLnode.from_list(
         ["seq"] + seq + [placeholder],
         typ=btype,
         location="memory",
         pos=getpos(self.expr),
         annotation=f"Create {btype}: {bytez}",
     )
コード例 #22
0
def pack_logging_topics(event_id, args, expected_topics, context, pos):
    topics = [event_id]
    code_pos = pos
    for pos, expected_topic in enumerate(expected_topics):
        expected_type = expected_topic.typ
        arg = args[pos]
        value = Expr(arg, context).lll_node
        arg_type = value.typ

        if isinstance(arg_type, ByteArrayLike) and isinstance(
                expected_type, ByteArrayLike):
            if arg_type.maxlen > expected_type.maxlen:
                raise TypeMismatch(
                    f"Topic input bytes are too big: {arg_type} {expected_type}",
                    code_pos)
            if isinstance(arg, vy_ast.Str):
                bytez, bytez_length = string_to_bytes(arg.s)
                if len(bytez) > 32:
                    raise InvalidLiteral(
                        "Can only log a maximum of 32 bytes at a time.",
                        code_pos)
                topics.append(
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                if value.location == "memory":
                    size = ['mload', value]
                elif value.location == "storage":
                    size = ['sload', ['sha3_32', value]]
                topics.append(byte_array_to_num(value, arg, 'uint256', size))
        else:
            if arg_type != expected_type:
                raise TypeMismatch(
                    f"Invalid type for logging topic, got {arg_type} expected {expected_type}",
                    value.pos)
            value = unwrap_location(value)
            value = base_type_conversion(value,
                                         arg_type,
                                         expected_type,
                                         pos=code_pos)
            topics.append(value)

    return topics
コード例 #23
0
ファイル: stmt.py プロジェクト: erdnaag/vyper
    def parse_AnnAssign(self):
        with self.context.assignment_scope():
            typ = parse_type(
                self.stmt.annotation,
                location="memory",
                custom_structs=self.context.structs,
                constants=self.context.constants,
            )
            varname = self.stmt.target.id
            pos = self.context.new_variable(varname, typ, pos=self.stmt)
            if self.stmt.value is None:
                return

            sub = Expr(self.stmt.value, self.context).lll_node

            is_literal_bytes32_assign = (isinstance(sub.typ, ByteArrayType)
                                         and sub.typ.maxlen == 32
                                         and isinstance(typ, BaseType)
                                         and typ.typ == "bytes32"
                                         and sub.typ.is_literal)

            # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
            if is_literal_bytes32_assign:
                sub = LLLnode(
                    bytes_to_int(self.stmt.value.s),
                    typ=BaseType("bytes32"),
                    pos=getpos(self.stmt),
                )

            variable_loc = LLLnode.from_list(
                pos,
                typ=typ,
                location="memory",
                pos=getpos(self.stmt),
            )
            lll_node = make_setter(variable_loc,
                                   sub,
                                   "memory",
                                   pos=getpos(self.stmt))

            return lll_node
コード例 #24
0
def sha256(expr, args, kwargs, context):
    sub = args[0]
    # Literal input
    if isinstance(sub, bytes):
        return LLLnode.from_list(
            bytes_to_int(hashlib.sha256(sub).digest()),
            typ=BaseType('bytes32'),
            pos=getpos(expr)
        )
    # bytes32 input
    elif is_base_type(sub.typ, 'bytes32'):
        return LLLnode.from_list(
            [
                'seq',
                ['mstore', MemoryPositions.FREE_VAR_SPACE, sub],
                _make_sha256_call(
                    inp_start=MemoryPositions.FREE_VAR_SPACE,
                    inp_len=32,
                    out_start=MemoryPositions.FREE_VAR_SPACE,
                    out_len=32
                ),
                ['mload', MemoryPositions.FREE_VAR_SPACE]  # push value onto stack
            ],
            typ=BaseType('bytes32'),
            pos=getpos(expr),
            add_gas_estimate=SHA256_BASE_GAS + 1 * SHA256_PER_WORD_GAS
        )
    # bytearay-like input
    if sub.location == "storage":
        # Copy storage to memory
        placeholder = context.new_placeholder(sub.typ)
        placeholder_node = LLLnode.from_list(placeholder, typ=sub.typ, location='memory')
        copier = make_byte_array_copier(
            placeholder_node,
            LLLnode.from_list('_sub', typ=sub.typ, location=sub.location),
        )
        return LLLnode.from_list(
            [
                'with', '_sub', sub, [
                    'seq',
                    copier,
                    _make_sha256_call(
                        inp_start=['add', placeholder, 32],
                        inp_len=['mload', placeholder],
                        out_start=MemoryPositions.FREE_VAR_SPACE,
                        out_len=32
                    ),
                    ['mload', MemoryPositions.FREE_VAR_SPACE]
                ],
            ],
            typ=BaseType('bytes32'),
            pos=getpos(expr),
            add_gas_estimate=SHA256_BASE_GAS + sub.typ.maxlen * SHA256_PER_WORD_GAS
        )
    elif sub.location == "memory":
        return LLLnode.from_list(
            [
                'with', '_sub', sub, [
                    'seq',
                    _make_sha256_call(
                        inp_start=['add', '_sub', 32],
                        inp_len=['mload', '_sub'],
                        out_start=MemoryPositions.FREE_VAR_SPACE,
                        out_len=32
                    ),
                    ['mload', MemoryPositions.FREE_VAR_SPACE]
                ]
            ],
            typ=BaseType('bytes32'),
            pos=getpos(expr),
            add_gas_estimate=SHA256_BASE_GAS + sub.typ.maxlen * SHA256_PER_WORD_GAS
        )
    else:
        # This should never happen, but just left here for future compiler-writers.
        raise Exception("Unsupported location: %s" % sub.location)  # pragma: no test
コード例 #25
0
def pack_logging_topics(event_id, args, expected_topics, context, pos):
    topics = [event_id]
    code_pos = pos
    for pos, expected_topic in enumerate(expected_topics):
        expected_type = expected_topic.typ
        arg = args[pos]
        value = Expr(arg, context).lll_node
        arg_type = value.typ

        if isinstance(arg_type, ByteArrayLike) and isinstance(expected_type, ByteArrayLike):
            if arg_type.maxlen > expected_type.maxlen:
                raise TypeMismatch(
                    f"Topic input bytes are too big: {arg_type} {expected_type}", code_pos
                )

            if isinstance(arg, (vy_ast.Str, vy_ast.Bytes)):
                # for literals, generate the topic at compile time
                value = arg.value
                if isinstance(value, str):
                    value = value.encode()
                topics.append(bytes_to_int(keccak256(value)))

            elif value.location == "memory":
                topics.append(["sha3", ["add", value, 32], ["mload", value]])

            else:
                # storage or calldata
                placeholder = context.new_internal_variable(value.typ)
                placeholder_node = LLLnode.from_list(placeholder, typ=value.typ, location="memory")
                copier = make_byte_array_copier(
                    placeholder_node,
                    LLLnode.from_list("_sub", typ=value.typ, location=value.location),
                )
                lll_node = [
                    "with",
                    "_sub",
                    value,
                    ["seq", copier, ["sha3", ["add", placeholder, 32], ["mload", placeholder]]],
                ]
                topics.append(lll_node)

        elif isinstance(arg_type, ListType) and isinstance(expected_type, ListType):
            size = get_size_of_type(value.typ) * 32
            if value.location == "memory":
                topics.append(["sha3", value, size])

            else:
                # storage or calldata
                placeholder = context.new_internal_variable(value.typ)
                placeholder_node = LLLnode.from_list(placeholder, typ=value.typ, location="memory")
                setter = make_setter(placeholder_node, value, "memory", value.pos)
                lll_node = ["seq", setter, ["sha3", placeholder, size]]
                topics.append(lll_node)

        else:
            if arg_type != expected_type:
                raise TypeMismatch(
                    f"Invalid type for logging topic, got {arg_type} expected {expected_type}",
                    value.pos,
                )
            value = unwrap_location(value)
            value = base_type_conversion(value, arg_type, expected_type, pos=code_pos)
            topics.append(value)

    return topics
コード例 #26
0
ファイル: event_signature.py プロジェクト: vaniisgh/vyper
    def from_declaration(cls, code, global_ctx):
        name = code.target.id
        pos = 0

        check_valid_varname(name,
                            global_ctx._custom_units,
                            global_ctx._structs,
                            global_ctx._constants,
                            pos=code,
                            error_prefix="Event name invalid. ",
                            exc=EventDeclarationException)

        # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...
        args = []
        indexed_list = []
        topics_count = 1
        if code.annotation.args:
            keys = code.annotation.args[0].keys
            values = code.annotation.args[0].values
            for i in range(len(keys)):
                typ = values[i]
                if not isinstance(keys[i], ast.Name):
                    raise EventDeclarationException(
                        'Invalid key type, expected a valid name.',
                        keys[i],
                    )
                if not isinstance(typ, (ast.Name, ast.Call, ast.Subscript)):
                    raise EventDeclarationException(
                        'Invalid event argument type.', typ)
                if isinstance(typ,
                              ast.Call) and not isinstance(typ.func, ast.Name):
                    raise EventDeclarationException(
                        'Invalid event argument type', typ)
                arg = keys[i].id
                arg_item = keys[i]
                is_indexed = False

                # Check to see if argument is a topic
                if isinstance(typ, ast.Call) and typ.func.id == 'indexed':
                    typ = values[i].args[0]
                    indexed_list.append(True)
                    topics_count += 1
                    is_indexed = True
                else:
                    indexed_list.append(False)
                if isinstance(typ, ast.Subscript) and getattr(
                        typ.value, 'id', None
                ) == 'bytes' and typ.slice.value.n > 32 and is_indexed:  # noqa: E501
                    raise EventDeclarationException(
                        "Indexed arguments are limited to 32 bytes")
                if topics_count > 4:
                    raise EventDeclarationException(
                        f"Maximum of 3 topics {topics_count - 1} given",
                        arg,
                    )
                if not isinstance(arg, str):
                    raise VariableDeclarationException("Argument name invalid",
                                                       arg)
                if not typ:
                    raise InvalidTypeException("Argument must have type", arg)
                check_valid_varname(
                    arg,
                    global_ctx._custom_units,
                    global_ctx._structs,
                    global_ctx._constants,
                    pos=arg_item,
                    error_prefix="Event argument name invalid or reserved.",
                )
                if arg in (x.name for x in args):
                    raise VariableDeclarationException(
                        "Duplicate function argument name: " + arg,
                        arg_item,
                    )
                # Can struct be logged?
                parsed_type = global_ctx.parse_type(typ, None)
                args.append(VariableRecord(arg, pos, parsed_type, False))
                if isinstance(parsed_type, ByteArrayType):
                    pos += ceil32(typ.slice.value.n)
                else:
                    pos += get_size_of_type(parsed_type) * 32
        sig = name + '(' + ','.join([
            canonicalize_type(arg.typ, indexed_list[pos])
            for pos, arg in enumerate(args)
        ]) + ')'  # noqa F812
        event_id = bytes_to_int(keccak256(bytes(sig, 'utf-8')))
        return cls(name, args, indexed_list, event_id, sig)