示例#1
0
文件: expr.py 项目: miamiruby/vyper
    def number(self):
        orignum = get_original_if_0_prefixed(self.expr, self.context)

        if orignum is None and isinstance(self.expr.n, int):

            # Literal becomes int128
            if (SizeLimits.MINNUM <= self.expr.n <= SizeLimits.MAXNUM):
                return LLLnode.from_list(self.expr.n, typ=BaseType('int128', None, is_literal=True), pos=getpos(self.expr))
            # Literal is large enough, becomes uint256.
            elif 0 <= self.expr.n <= SizeLimits.MAX_UINT256:
                return LLLnode.from_list(self.expr.n, typ=BaseType('uint256', None, is_literal=True), pos=getpos(self.expr))
            else:
                raise InvalidLiteralException("Number out of range: " + str(self.expr.n), self.expr)

        elif isinstance(self.expr.n, float):
            numstring, num, den = get_number_as_fraction(self.expr, self.context)
            if not (SizeLimits.MINNUM * den < num < SizeLimits.MAXNUM * den):
                raise InvalidLiteralException("Number out of range: " + numstring, self.expr)
            if DECIMAL_DIVISOR % den:
                raise InvalidLiteralException("Too many decimal places: " + numstring, self.expr)
            return LLLnode.from_list(num * DECIMAL_DIVISOR // den, typ=BaseType('decimal', None), pos=getpos(self.expr))
        # Binary literal.
        elif orignum[:2] == '0b':
            str_val = orignum[2:]
            total_bits = len(orignum[2:])
            total_bits = total_bits if total_bits % 8 == 0 else total_bits + 8 - (total_bits % 8)  # ceil8 to get byte length.
            if total_bits != len(orignum[2:]):  # add necessary zero padding.
                pad_len = total_bits - len(orignum[2:])
                str_val = pad_len * '0' + str_val
            byte_len = int(total_bits / 8)
            placeholder = self.context.new_placeholder(ByteArrayType(byte_len))
            seq = []
            seq.append(['mstore', placeholder, byte_len])
            for i in range(0, total_bits, 256):
                section = str_val[i:i + 256]
                int_val = int(section, 2) << (256 - len(section))  # bytes are right padded.
                seq.append(
                    ['mstore', ['add', placeholder, i + 32], int_val])
            return LLLnode.from_list(['seq'] + seq + [placeholder],
                typ=ByteArrayType(byte_len), location='memory', pos=getpos(self.expr), annotation='Create ByteArray (Binary literal): %s' % str_val)
        elif len(orignum) == 42:
            if checksum_encode(orignum) != orignum:
                raise InvalidLiteralException("Address checksum mismatch. If you are sure this is the "
                                              "right address, the correct checksummed form is: " +
                                              checksum_encode(orignum), self.expr)
            return LLLnode.from_list(self.expr.n, typ=BaseType('address', is_literal=True), pos=getpos(self.expr))
        elif len(orignum) == 66:
            return LLLnode.from_list(self.expr.n, typ=BaseType('bytes32', is_literal=True), pos=getpos(self.expr))
        else:
            raise InvalidLiteralException("Cannot read 0x value with length %d. Expecting 42 (address incl 0x) or 66 (bytes32 incl 0x)"
                                          % len(orignum), self.expr)
示例#2
0
文件: expr.py 项目: siromivel/vyper
    def number(self):
        orignum = get_original_if_0_prefixed(self.expr, self.context)

        if orignum is None and isinstance(self.expr.n, int):
            # Literal (mostly likely) becomes int128
            if SizeLimits.in_bounds('int128', self.expr.n) or self.expr.n < 0:
                return LLLnode.from_list(self.expr.n, typ=BaseType('int128', unit={}, is_literal=True), pos=getpos(self.expr))
            # Literal is large enough (mostly likely) becomes uint256.
            else:
                return LLLnode.from_list(self.expr.n, typ=BaseType('uint256', unit={}, is_literal=True), pos=getpos(self.expr))

        elif isinstance(self.expr.n, float):
            numstring, num, den = get_number_as_fraction(self.expr, self.context)
            # if not SizeLimits.in_bounds('decimal', num // den):
            # if not SizeLimits.MINDECIMAL * den <= num <= SizeLimits.MAXDECIMAL * den:
            if not (SizeLimits.MINNUM * den < num < SizeLimits.MAXNUM * den):
                raise InvalidLiteralException("Number out of range: " + numstring, self.expr)
            if DECIMAL_DIVISOR % den:
                raise InvalidLiteralException("Too many decimal places: " + numstring, self.expr)
            return LLLnode.from_list(num * DECIMAL_DIVISOR // den, typ=BaseType('decimal', unit=None), pos=getpos(self.expr))
        # Binary literal.
        elif orignum[:2] == '0b':
            str_val = orignum[2:]
            total_bits = len(orignum[2:])
            total_bits = total_bits if total_bits % 8 == 0 else total_bits + 8 - (total_bits % 8)  # ceil8 to get byte length.
            if len(orignum[2:]) != total_bits:  # Support only full formed bit definitions.
                raise InvalidLiteralException("Bit notation requires a multiple of 8 bits / 1 byte. {} bit(s) are missing.".format(total_bits - len(orignum[2:])), self.expr)
            byte_len = int(total_bits / 8)
            placeholder = self.context.new_placeholder(ByteArrayType(byte_len))
            seq = []
            seq.append(['mstore', placeholder, byte_len])
            for i in range(0, total_bits, 256):
                section = str_val[i:i + 256]
                int_val = int(section, 2) << (256 - len(section))  # bytes are right padded.
                seq.append(
                    ['mstore', ['add', placeholder, i + 32], int_val])
            return LLLnode.from_list(['seq'] + seq + [placeholder],
                typ=ByteArrayType(byte_len), location='memory', pos=getpos(self.expr), annotation='Create ByteArray (Binary literal): %s' % str_val)
        elif len(orignum) == 42:
            if checksum_encode(orignum) != orignum:
                raise InvalidLiteralException("""Address checksum mismatch. If you are sure this is the
right address, the correct checksummed form is: %s""" % checksum_encode(orignum), self.expr)
            return LLLnode.from_list(self.expr.n, typ=BaseType('address', is_literal=True), pos=getpos(self.expr))
        elif len(orignum) == 66:
            return LLLnode.from_list(self.expr.n, typ=BaseType('bytes32', is_literal=True), pos=getpos(self.expr))
        else:
            raise InvalidLiteralException("Cannot read 0x value with length %d. Expecting 42 (address incl 0x) or 66 (bytes32 incl 0x)"
                                          % len(orignum), self.expr)
示例#3
0
文件: expr.py 项目: elrobles/vyper
 def hexstring(self):
     orignum = self.expr.node_source_code
     if len(orignum) == 42:
         if checksum_encode(orignum) != orignum:
             raise InvalidLiteralException(
                 "Address checksum mismatch. If you are sure this is the "
                 f"right address, the correct checksummed form is: {checksum_encode(orignum)}",
                 self.expr
             )
         return LLLnode.from_list(
             self.expr.n,
             typ=BaseType('address', is_literal=True),
             pos=getpos(self.expr),
         )
     elif len(orignum) == 66:
         return LLLnode.from_list(
             self.expr.n,
             typ=BaseType('bytes32', is_literal=True),
             pos=getpos(self.expr),
         )
     else:
         raise InvalidLiteralException(
             f"Cannot read 0x value with length {len(orignum)}. Expecting 42 (address "
             "incl 0x) or 66 (bytes32 incl 0x)",
             self.expr
         )
示例#4
0
 def from_literal(cls, node: vy_ast.Constant) -> AddressDefinition:
     super().from_literal(node)
     addr = node.value
     if len(addr) != 42:
         raise InvalidLiteral("Invalid literal for type 'address'", node)
     if checksum_encode(addr) != addr:
         # this should have been caught in `vyper.ast.nodes.Hex.validate`
         raise CompilerPanic("Address checksum mismatch")
     return AddressDefinition()
示例#5
0
 def validate(self):
     if len(self.value) % 2:
         raise InvalidLiteral("Hex notation requires an even number of digits", self)
     if len(self.value) == 42 and checksum_encode(self.value) != self.value:
         raise InvalidLiteral(
             "Address checksum mismatch. If you are sure this is the right "
             f"address, the correct checksummed form is: {checksum_encode(self.value)}",
             self,
         )
示例#6
0
def _py_convert(val, i_typ, o_typ):
    """
    Perform conversion on the Python representation of a Vyper value.
    Returns None if the conversion is invalid (i.e., would revert in Vyper)
    """
    i_detail = _parse_type(i_typ)
    o_detail = _parse_type(o_typ)

    if i_detail.type_class == "int" and o_detail.type_class == "int":
        if not SizeLimits.in_bounds(o_typ, val):
            return None
        return val

    if i_typ == "decimal" and o_typ in INTEGER_TYPES:
        return _convert_decimal_to_int(val, o_typ)

    if i_detail.type_class in ("bool", "int") and o_typ == "decimal":
        # Note: Decimal(True) == Decimal("1")
        return _convert_int_to_decimal(val, o_typ)

    val_bits = _to_bits(val, i_typ)

    if i_detail.type_class in ("Bytes", "String"):
        val_bits = val_bits[32:]

    if _padding_direction(i_typ) != _padding_direction(o_typ):
        # subtle! the padding conversion follows the bytes argument
        if i_detail.type_class in ("bytes", "Bytes"):
            n = i_detail.type_bytes
            padding_byte = None
        else:
            # output type is bytes
            n = o_detail.type_bytes
            padding_byte = b"\x00"

        val_bits = _padconvert(val_bits, _padding_direction(o_typ), n,
                               padding_byte)

    if getattr(o_detail.info, "is_signed",
               False) and i_detail.type_class == "bytes":
        n_bits = i_detail.type_bytes * 8
        val_bits = _signextend(val_bits, n_bits)

    try:
        if o_typ == "bool":
            return _from_bits(val_bits, "uint256") != 0

        ret = _from_bits(val_bits, o_typ)

        if o_typ == "address":
            return checksum_encode(ret)
        return ret

    except _OutOfBounds:
        return None
示例#7
0
 def from_literal(cls, node: vy_ast.Constant) -> AddressDefinition:
     super().from_literal(node)
     addr = node.value
     if len(addr) != 42:
         raise InvalidLiteral("Invalid literal for type 'address'", node)
     if checksum_encode(addr) != addr:
         raise InvalidLiteral(
             "Address checksum mismatch. If you are sure this is the right "
             f"address, the correct checksummed form is: {checksum_encode(addr)}",
             node,
         )
     return AddressDefinition()
示例#8
0
文件: expr.py 项目: paolomarin/vyper
 def number(self):
     orignum = get_original_if_0x_prefixed(self.expr, self.context)
     if orignum is None and isinstance(self.expr.n, int):
         if not (SizeLimits.MINNUM <= self.expr.n <= SizeLimits.MAXNUM):
             raise InvalidLiteralException(
                 "Number out of range: " + str(self.expr.n), self.expr)
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('int128', None),
                                  pos=getpos(self.expr))
     elif isinstance(self.expr.n, float):
         numstring, num, den = get_number_as_fraction(
             self.expr, self.context)
         if not (SizeLimits.MINNUM * den < num < SizeLimits.MAXNUM * den):
             raise InvalidLiteralException(
                 "Number out of range: " + numstring, self.expr)
         if DECIMAL_DIVISOR % den:
             raise InvalidLiteralException(
                 "Too many decimal places: " + numstring, self.expr)
         return LLLnode.from_list(num * DECIMAL_DIVISOR // den,
                                  typ=BaseType('decimal', None),
                                  pos=getpos(self.expr))
     elif len(orignum) == 42:
         if checksum_encode(orignum) != orignum:
             raise InvalidLiteralException(
                 "Address checksum mismatch. If you are sure this is the "
                 "right address, the correct checksummed form is: " +
                 checksum_encode(orignum), self.expr)
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('address'),
                                  pos=getpos(self.expr))
     elif len(orignum) == 66:
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('bytes32'),
                                  pos=getpos(self.expr))
     else:
         raise InvalidLiteralException(
             "Cannot read 0x value with length %d. Expecting 42 (address incl 0x) or 66 (bytes32 incl 0x)"
             % len(orignum), self.expr)
示例#9
0
 def parse_Hex(self):
     orignum = self.expr.value
     if len(orignum) == 42 and checksum_encode(orignum) == orignum:
         return LLLnode.from_list(
             int(self.expr.value, 16),
             typ=BaseType("address", is_literal=True),
             pos=getpos(self.expr),
         )
     elif len(orignum) == 66:
         return LLLnode.from_list(
             int(self.expr.value, 16),
             typ=BaseType("bytes32", is_literal=True),
             pos=getpos(self.expr),
         )
def test_uint256_clamping(get_contract, assert_tx_failed):
    test_fails = 2**160
    test_passing = test_fails - 1

    test_bytes_to_address = """
@external
def foo(x: uint256) -> address:
    return convert(x, address)
    """

    c = get_contract(test_bytes_to_address)

    assert_tx_failed(lambda: c.foo(test_fails))
    assert c.foo(test_passing) == checksum_encode("0x" + "ff" * 20)
def test_bytes32_clamping(get_contract, assert_tx_failed):
    test_passing = (b"\xff" * 20).rjust(32, b"\x00")
    test_fails = (b"\x01" + b"\xff" * 20).rjust(32, b"\x00")

    test_bytes_to_address = """
@external
def foo(x: bytes32) -> address:
    return convert(x, address)
    """

    c = get_contract(test_bytes_to_address)

    assert_tx_failed(lambda: c.foo(test_fails))
    assert c.foo(test_passing) == checksum_encode("0x" + "ff" * 20)
示例#12
0
def test_create_minimal_proxy_to_create(get_contract):
    code = """
main: address

@external
def test() -> address:
    self.main = create_minimal_proxy_to(self)
    return self.main
    """

    c = get_contract(code)

    address_bits = int(c.address, 16)
    nonce = 1
    rlp_encoded = rlp.encode([address_bits, nonce])
    expected_create_address = keccak256(rlp_encoded)[12:].rjust(20, b"\x00")
    assert c.test() == checksum_encode("0x" + expected_create_address.hex())
示例#13
0
    def parse_Hex(self):
        hexstr = self.expr.value

        if len(hexstr) == 42:
            # sanity check typechecker did its job
            assert checksum_encode(hexstr) == hexstr
            typ = BaseType("address")
            # TODO allow non-checksum encoded bytes20
            return IRnode.from_list(int(self.expr.value, 16), typ=typ)

        else:
            n_bytes = (len(hexstr) - 2) // 2  # e.g. "0x1234" is 2 bytes
            # TODO: typ = new_type_to_old_type(self.expr._metadata["type"])
            #       assert n_bytes == typ._bytes_info.m

            # bytes_m types are left padded with zeros
            val = int(hexstr, 16) << 8 * (32 - n_bytes)

            typ = BaseType(f"bytes{n_bytes}", is_literal=True)
            typ.is_literal = True
            return IRnode.from_list(val, typ=typ)