内置函数

Vyper 提供了一组在所有合约的全局命名空间中可用的内置函数。

位运算

bitwise_and(x: uint256, y: uint256) uint256

执行“按位与”运算。输出的每个位为 1,如果 xy 的相应位为 1,否则为 0。

@external
@view
def foo(x: uint256, y: uint256) -> uint256:
    return bitwise_and(x, y)
>>> ExampleContract.foo(31337, 8008135)
12353

注意

此函数已从 0.3.4 版开始弃用。请改用 & 运算符。

bitwise_not(x: uint256) uint256

返回 x 的按位补码 - 通过将每个 1 替换为 0 以及每个 0 替换为 1 获得的数字。

@external
@view
def foo(x: uint256) -> uint256:
    return bitwise_not(x)
>>> ExampleContract.foo(0)
115792089237316195423570985008687907853269984665640564039457584007913129639935

注意

此函数已从 0.3.4 版开始弃用。请改用 ~ 运算符。

bitwise_or(x: uint256, y: uint256) uint256

执行“按位或”运算。输出的每个位为 0,如果 xy 的相应位为 0,否则为 1。

@external
@view
def foo(x: uint256, y: uint256) -> uint256:
    return bitwise_or(x, y)
>>> ExampleContract.foo(31337, 8008135)
8027119

注意

此函数已从 0.3.4 版开始弃用。请改用 | 运算符。

bitwise_xor(x: uint256, y: uint256) uint256

执行“按位异或”运算。输出的每个位与 x 中的相应位相同,如果 y 中的该位为 0,并且是 x 中该位的补码,如果 y 中的该位为 1。

@external
@view
def foo(x: uint256, y: uint256) -> uint256:
    return bitwise_xor(x, y)
>>> ExampleContract.foo(31337, 8008135)
8014766

注意

此函数已从 0.3.4 版开始弃用。请改用 ^ 运算符。

shift(x: int256 | uint256, _shift: integer) uint256

返回将位移动 _shift 位的 x。正的 _shift 值等于左移,负值是右移。

@external
@view
def foo(x: uint256, y: int128) -> uint256:
    return shift(x, y)
>>> ExampleContract.foo(2, 8)
512

注意

此函数已从 0.3.8 版开始弃用。请改用 <<>> 运算符。

链交互

Vyper 有三个用于创建合约的内置函数;所有三个合约创建内置函数都依赖于要部署的代码已存储在链上,但它们在调用与部署开销以及是否调用要部署的合约的构造函数方面有所不同。以下列表简要总结了它们之间的差异。

  • create_minimal_proxy_to(target: address, ...)
    • 创建一个不可变的代理到 target

    • 调用开销大(每次调用都会产生一个 DELEGATECALL 开销),创建开销小(因为它只部署 EIP-1167 转发器字节码)

    • 没有调用构造函数的功能

    • 不检查 target 处是否有代码(允许以反事实的方式部署代理)

  • create_copy_of(target: address, ...)
    • 创建存储在 target 处的运行时代码的逐字节复制

    • 调用开销小(没有 DELEGATECALL 开销),创建开销大(每部署一个字节 200 gas)

    • 没有调用构造函数的功能

    • 执行 EXTCODESIZE 检查以检查 target 处是否有代码

  • create_from_blueprint(target: address, ...)
    • 使用存储在 target 处的 initcode 部署合约

    • 调用开销小(没有 DELEGATECALL 开销),创建开销大(每部署一个字节 200 gas)

    • 调用构造函数,要求部署一个特殊的“蓝图”合约

    • 执行 EXTCODESIZE 检查以检查 target 处是否有代码

create_minimal_proxy_to(target: address, value: uint256 = 0[, salt: bytes32]) address

部署一个小的、符合 EIP1167 的“最小代理合约”,该合约复制了 target 处合约的逻辑,但有自己的状态,因为对 target 的每次调用都是使用 DELEGATECALLtarget 进行的。对最终用户而言,这应该与使用与 target 相同代码的独立部署的合约没有区别。

  • target: 要代理到的合约的地址

  • value: 要发送到新合约地址的 wei 值(可选,默认值为 0)

  • salt: 确定性 CREATE2 操作码使用的 bytes32 值(可选,如果未提供,则使用 CREATE

返回新创建的代理合约的地址。如果创建操作失败(例如,在 CREATE2 冲突的情况下),执行将回滚。

@external
def foo(target: address) -> address:
    return create_minimal_proxy_to(target)

注意

至关重要的是,在 target 处部署的合约是您了解并信任的代码,并且不实现 selfdestruct 操作码或具有可升级的代码,因为这会影响代理合约的操作。

注意

没有运行时检查以确保 target 处已部署代码(因为代理可以以反事实的方式部署)。大多数应用程序可能希望插入此检查。

注意

在 0.3.4 版之前,此函数名为 create_forwarder_to

create_copy_of(target: address, value: uint256 = 0[, salt: bytes32]) address

创建 target 处运行时代码的物理副本。在 target 处的代码会逐字节复制到一个新部署的合约中。

  • target: 要复制的合约的地址

  • value: 要发送到新合约地址的 wei 值(可选,默认值为 0)

  • salt: 确定性 CREATE2 操作码使用的 bytes32 值(可选,如果未提供,则使用 CREATE

返回已创建的合约的地址。如果创建操作失败(例如,在 CREATE2 冲突的情况下),执行将回滚。如果 target 处没有代码,执行将回滚。

@external
def foo(target: address) -> address:
    return create_copy_of(target)

注意

create_copy_of 的实现假设 target 处的代码小于 16MB。虽然这远大于 EIP-170 的 24KB 限制,但它是一个保守的尺寸限制,旨在防止部署者合约在 EIP-170 限制解除的情况下出现问题。如果 target 处的代码大于 16MB,则 create_copy_of 的行为未定义。

create_from_blueprint(target: address, *args, value: uint256 = 0, raw_args: bool = False, code_offset: int = 0[, salt: bytes32]) address

target 的代码复制到内存中并作为初始化代码执行。换句话说,此操作将 target 中的代码解释为初始化代码,而不是常规的运行时代码。 *args 被解释为构造函数参数,并被 ABI 编码,并在执行初始化代码时包含在内。

  • target: 要调用的蓝图的地址

  • *args: 要转发到初始化代码的构造函数参数。

  • value: 要发送到新合约地址的 wei 值(可选,默认值为 0)

  • raw_args: 如果为 True*args 必须是一个 Bytes[...] 参数,它将被解释为一个原始字节缓冲区,转发到创建操作(例如,如果预 ABI 编码数据从其他地方传递进来)。(可选,默认值为 False

  • code_offset: EXTCODECOPY 开始的偏移量(可选,默认值为 0)

  • salt: 确定性 CREATE2 操作码使用的 bytes32 值(可选,如果未提供,则使用 CREATE

返回创建的合约的地址。如果创建操作失败(例如,在 CREATE2 冲突的情况下),执行将回滚。如果 code_offset >= target.codesize(例如,如果 target 中没有代码),执行将回滚。

@external
def foo(blueprint: address) -> address:
    arg1: uint256 = 18
    arg2: String[32] = "some string"
    return create_from_blueprint(blueprint, arg1, arg2, code_offset=1)

注意

要正确部署蓝图合约,必须使用特殊的部署字节码。 vyper -f blueprint_bytecode 的输出将产生部署与 ERC-5202 兼容的蓝图的字节码。

警告

建议使用 ERC-5202 前缀 0xFE7100 部署蓝图,以防止它们被当作常规合约调用。这对于工厂来说尤其重要,因为工厂的构造函数有副作用(包括 SELFDESTRUCT!),因为这些副作用可能会被任何直接调用蓝图合约的人执行。提供 code_offset= 关键字参数是为了启用这种模式

@external
def foo(blueprint: address) -> address:
    # `blueprint` is a blueprint contract with some known preamble b"abcd..."
    return create_from_blueprint(blueprint, code_offset=<preamble length>)
raw_call(to: address, data: Bytes, max_outsize: uint256 = 0, gas: uint256 = gasLeft, value: uint256 = 0, is_delegate_call: bool = False, is_static_call: bool = False, revert_on_failure: bool = True) Bytes[max_outsize]

调用指定的以太坊地址。

  • to: 要调用的目标地址

  • data: 要发送到目标地址的数据

  • max_outsize: 从调用返回的字节数组的最大长度。如果返回的调用数据超过此长度,则仅返回此数量的字节。(可选,默认值为 0

  • gas: 附加到调用的汽油量。(可选,默认为 msg.gas)。

  • value: 要发送到该地址的 wei 值(可选,默认为 0

  • is_delegate_call: 如果为 True,则调用将作为 DELEGATECALL 发送(可选,默认为 False

  • is_static_call: 如果为 True,则调用将作为 STATICCALL 发送(可选,默认为 False

  • revert_on_failure: 如果为 True,则调用将在失败时回滚,否则将返回 success(可选,默认为 True

注意

返回调用返回的数据作为 Bytes 列表,max_outsize 作为最大长度。返回数据的实际大小可能小于 max_outsize。可以使用 len 来获取实际大小。

如果省略或设置为 0,则不返回任何内容。

如果 revert_on_failure 设置为 False,则返回一个包含返回值的元组中的 success

@external
@payable
def foo(_target: address) -> Bytes[32]:
    response: Bytes[32] = raw_call(_target, method_id("someMethodName()"), max_outsize=32, value=msg.value)
    return response

@external
@payable
def bar(_target: address) -> Bytes[32]:
    success: bool = False
    response: Bytes[32] = b""
    x: uint256 = 123
    success, response = raw_call(
        _target,
        _abi_encode(x, method_id=method_id("someMethodName(uint256)")),
        max_outsize=32,
        value=msg.value,
        revert_on_failure=False
        )
    assert success
    return response

注意

关于“转发所有汽油”,请注意,虽然 Vyper 会向调用提供 msg.gas,但实际上,在 EVM 上转发所有剩余汽油有一些细微之处,这些细微之处超出了本文档的范围,可能会发生变化。例如,请参阅 EIP-150 中关于“除了六十四分之一以外的所有汽油”的语言。

raw_log(topics: bytes32[4], data: Union[Bytes, bytes32]) None

提供对 LOG 操作码的低级访问,发出日志,而无需指定 ABI 类型。

  • topics: bytes32 日志主题列表。此数组的长度决定了使用哪个操作码。

  • data: 要包含在日志中的未索引事件数据。可以作为 Bytesbytes32 提供。

@external
def foo(_topic: bytes32, _data: Bytes[100]):
    raw_log([_topic], _data)
raw_revert(data: Bytes) None

提供对 REVERT 操作码的低级访问,使用指定的数据返回回滚执行。

  • data: 表示导致回滚的错误消息的数据。

@external
def foo(_data: Bytes[100]):
    raw_revert(_data)
selfdestruct(to: address) None

触发 SELFDESTRUCT 操作码 (0xFF),导致合约被销毁。

  • to: 要将合约的以太余额转发的地址

警告

此方法从区块链中删除合约。与该合约关联的所有非以太资产将被“销毁”,并且该合约不再可访问。

注意

此函数已从 0.3.8 版本开始弃用。底层操作码最终将发生重大更改,因此不建议使用它。

@external
def do_the_needful():
    selfdestruct(msg.sender)
send(to: address, value: uint256, gas: uint256 = 0) None

从合约向指定的以太坊地址发送以太币。

  • to: 要发送以太币的目标地址

  • value: 要发送到该地址的 wei 值

  • gas: 附加到调用的gas量(“津贴”)。如果未设置,津贴默认为0。

注意

发送金额始终以wei指定。

@external
def foo(_receiver: address, _amount: uint256, gas: uint256):
    send(_receiver, _amount, gas=gas)

密码学

ecadd(a: uint256[2], b: uint256[2]) uint256[2]

将 Alt-BN128 曲线上的两个点加在一起。

@external
@view
def foo(x: uint256[2], y: uint256[2]) -> uint256[2]:
    return ecadd(x, y)
>>> ExampleContract.foo([1, 2], [1, 2])
[
    1368015179489954701390400359078579693043519447331113978918064868415326638035,
    9918110051302171585080402603319702774565515993150576347155970296011118125764,
]
ecmul(point: uint256[2], scalar: uint256) uint256[2]

取 Alt-BN128 曲线上的一个点 (p) 和一个标量值 (s),并返回将该点自身加上 s 次的结果,即 p * s

  • point: 要乘以的点

  • scalar: 标量值

@external
@view
def foo(point: uint256[2], scalar: uint256) -> uint256[2]:
    return ecmul(point, scalar)
>>> ExampleContract.foo([1, 2], 3)
[
    3353031288059533942658390886683067124040920775575537747144343083137631628272,
    19321533766552368860946552437480515441416830039777911637913418824951667761761,
]
ecrecover(hash: bytes32, v: uint256 | uint8, r: uint256 | bytes32, s: uint256 | bytes32) address

从给定的椭圆曲线签名中恢复与公钥关联的地址。

  • r: 签名的前 32 个字节

  • s: 签名的后 32 个字节

  • v: 签名的最后 1 个字节

返回关联的地址,或在出错时返回 empty(address)

注意

在 Vyper 0.3.10 之前,ecrecover 函数可能会为 ecrecover 的无效输入返回一个未定义的值(可能非零)。有关更多信息,请参见 GHSA-f5x6-7qgp-jhf3

@external
@view
def foo(hash: bytes32, v: uint8, r:bytes32, s:bytes32) -> address:
    return ecrecover(hash, v, r, s)


@external
@view
def foo(hash: bytes32, v: uint256, r:uint256, s:uint256) -> address:
    return ecrecover(hash, v, r, s)
>>> ExampleContract.foo('0x6c9c5e133b8aafb2ea74f524a5263495e7ae5701c7248805f7b511d973dc7055',
     28,
     78616903610408968922803823221221116251138855211764625814919875002740131251724,
     37668412420813231458864536126575229553064045345107737433087067088194345044408
    )
'0x9eE53ad38Bb67d745223a4257D7d48cE973FeB7A'
keccak256(_value) bytes32

返回给定值的 keccak256 哈希值。

  • _value: 要哈希的值。可以是 StringBytesbytes32

@external
@view
def foo(_value: Bytes[100]) -> bytes32
    return keccak256(_value)
>>> ExampleContract.foo(b"potato")
0x9e159dfcfe557cc1ca6c716e87af98fdcb94cd8c832386d0429b2b7bec02754f
sha256(_value) bytes32

返回给定值的 sha256(SHA2 256 位输出)哈希值。

  • _value: 要哈希的值。可以是 StringBytesbytes32

@external
@view
def foo(_value: Bytes[100]) -> bytes32
    return sha256(_value)
>>> ExampleContract.foo(b"potato")
0xe91c254ad58860a02c788dfb5c1a65d6a8846ab1dc649631c7db16fef4af2dec

数据操作

concat(a, b, *args) Union[Bytes, String]

取 2 个或更多个类型为 bytesMBytesString 的字节数组,并将它们组合成一个值。

如果输入参数是 String,则返回类型是 String。否则返回类型是 Bytes

@external
@view
def foo(a: String[5], b: String[5], c: String[5]) -> String[100]:
    return concat(a, " ", b, " ", c, "!")
>>> ExampleContract.foo("why","hello","there")
"why hello there!"
convert(value, type_) Any

将变量或字面量从一种类型转换为另一种类型。

  • value: 要转换的值

  • type_: 要转换到的目标类型(例如,booldecimalint128uint256bytes32

返回 type_ 指定类型的的值。

有关可用类型转换的更多详细信息,请参见 类型转换

uint2str(value: unsigned integer) String

返回无符号整数的字符串表示形式。

  • value: 要转换的无符号整数。

返回 value 的字符串表示形式。

@external
@view
def foo(b: uint256) -> String[78]:
    return uint2str(b)
>>> ExampleContract.foo(420)
"420"
extract32(b: Bytes, start: uint256, output_type=bytes32) Any

Bytes 列表中提取值。

  • b: 要从中提取的 Bytes 列表

  • start: 要从中提取的起点

  • output_type: 输出类型 (bytesMintegeraddress)。默认为 bytes32

返回 output_type 指定类型的的值。

@external
@view
def foo(b: Bytes[32]) -> address:
    return extract32(b, 0, output_type=address)
>>> ExampleContract.foo("0x0000000000000000000000009f8F72aA9304c8B593d555F12eF6589cC3A579A2")
"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2"
slice(b: Union[Bytes, bytes32, String], start: uint256, length: uint256) Union[Bytes, String]

复制字节列表并返回指定的切片。

  • b: 要切片的 value

  • start: 切片的起始位置

  • length: 切片的长度

如果被切片的 value 是 Bytesbytes32,则返回类型为 Bytes。如果它是 String,则返回类型为 String

@external
@view
def foo(s: String[32]) -> String[5]:
    return slice(s, 4, 5)
>>> ExampleContract.foo("why hello! how are you?")
"hello"

数学

abs(value: int256) int256

返回有符号整数的绝对值。

  • value: 要返回绝对值的整数

@external
@view
def foo(value: int256) -> int256:
    return abs(value)
>>> ExampleContract.foo(-31337)
31337
ceil(value: decimal) int256

将小数向上舍入到最接近的整数。

  • value: 要向上舍入的小数值

@external
@view
def foo(x: decimal) -> int256:
    return ceil(x)
>>> ExampleContract.foo(3.1337)
4
epsilon(typename) Any

返回小数类型的最小非零值。

  • typename: 小数类型的名称(目前只有 decimal

@external
@view
def foo() -> decimal:
    return epsilon(decimal)
>>> ExampleContract.foo()
Decimal('1E-10')
floor(value: decimal) int256

将小数向下舍入到最接近的整数。

  • value: 要向下舍入的小数值

@external
@view
def foo(x: decimal) -> int256:
    return floor(x)
>>> ExampleContract.foo(3.1337)
3
max(a: numeric, b: numeric) numeric

返回 ab 中较大的值。输入值可以是任何数字类型,只要它们都是相同类型。输出值的类型与输入值的类型相同。

@external
@view
def foo(a: uint256, b: uint256) -> uint256:
    return max(a, b)
>>> ExampleContract.foo(23, 42)
42
max_value(type_) numeric

返回由 type_ 指定的数字类型的最大值(例如,int128uint256decimal)。

@external
@view
def foo() -> int256:
    return max_value(int256)
>>> ExampleContract.foo()
57896044618658097711785492504343953926634992332820282019728792003956564819967
min(a: numeric, b: numeric) numeric

返回 ab 中较小的值。输入值可以是任何数字类型,只要它们都是相同类型。输出值的类型与输入值的类型相同。

@external
@view
def foo(a: uint256, b: uint256) -> uint256:
    return min(a, b)
>>> ExampleContract.foo(23, 42)
23
min_value(type_) numeric

返回由 type_ 指定的数字类型的最小值(例如,int128uint256decimal)。

@external
@view
def foo() -> int256:
    return min_value(int256)
>>> ExampleContract.foo()
-57896044618658097711785492504343953926634992332820282019728792003956564819968
pow_mod256(a: uint256, b: uint256) uint256

返回 a ** b % (2 ** 256) 的结果。

此方法用于执行不带溢出检查的指数运算。

@external
@view
def foo(a: uint256, b: uint256) -> uint256:
    return pow_mod256(a, b)
>>> ExampleContract.foo(2, 3)
8
>>> ExampleContract.foo(100, 100)
59041770658110225754900818312084884949620587934026984283048776718299468660736
sqrt(d: decimal) decimal

返回提供的小数的平方根,使用巴比伦平方根算法。

@external
@view
def foo(d: decimal) -> decimal:
    return sqrt(d)
>>> ExampleContract.foo(9.0)
3.0
isqrt(x: uint256) uint256

返回提供整数的(整数)平方根,使用巴比伦平方根算法。舍入模式是向下舍入到最接近的整数。例如,isqrt(101) == 10

@external
@view
def foo(x: uint256) -> uint256:
    return isqrt(x)
>>> ExampleContract.foo(101)
10
uint256_addmod(a: uint256, b: uint256, c: uint256) uint256

返回 (a + b) % c 的模。如果 c == 0,则会回滚。由于此内置函数旨在提供对底层 ADDMOD 操作码的访问,因此根据 EVM 规范,此操作的所有中间计算都不受 2 ** 256 模的影响。

@external
@view
def foo(a: uint256, b: uint256, c: uint256) -> uint256:
    return uint256_addmod(a, b, c)
>>> (6 + 13) % 8
3
>>> ExampleContract.foo(6, 13, 8)
3
uint256_mulmod(a: uint256, b: uint256, c: uint256) uint256

返回 (a * b) % c 的模。如果 c == 0,则会回滚。由于此内置函数旨在提供对底层 MULMOD 操作码的访问,因此根据 EVM 规范,此操作的所有中间计算都不受 2 ** 256 模的影响。

@external
@view
def foo(a: uint256, b: uint256, c: uint256) -> uint256:
    return uint256_mulmod(a, b, c)
>>> (11 * 2) % 5
2
>>> ExampleContract.foo(11, 2, 5)
2
unsafe_add(x: integer, y: integer) integer

xy 相加,不检查溢出。 xy 必须都是相同类型的整数。如果结果超过输入类型的边界,它将被包装。

@external
@view
def foo(x: uint8, y: uint8) -> uint8:
    return unsafe_add(x, y)

@external
@view
def bar(x: int8, y: int8) -> int8:
    return unsafe_add(x, y)
>>> ExampleContract.foo(1, 1)
2

>>> ExampleContract.foo(255, 255)
254

>>> ExampleContract.bar(127, 127)
-2

注意

性能说明:对于 EVM 的本机字类型 uint256int256,这将编译为单个 ADD 指令,因为 EVM 本机地包装了 256 位字上的加法。

unsafe_sub(x: integer, y: integer) integer

xy 相减,不检查溢出。 xy 必须都是相同类型的整数。如果结果下溢出输入类型的边界,它将被包装。

@external
@view
def foo(x: uint8, y: uint8) -> uint8:
    return unsafe_sub(x, y)

@external
@view
def bar(x: int8, y: int8) -> int8:
    return unsafe_sub(x, y)
>>> ExampleContract.foo(4, 3)
1

>>> ExampleContract.foo(0, 1)
255

>>> ExampleContract.bar(-128, 1)
127

注意

性能说明:对于 EVM 的原生字类型 uint256int256,这将编译成单个 SUB 指令,因为 EVM 原生支持对 256 位字进行减法运算。

unsafe_mul(x: integer, y: integer) integer

xy 相乘,不检查溢出。 xy 必须都是相同类型的整数。如果结果超出输入类型的范围,它将被截断。

@external
@view
def foo(x: uint8, y: uint8) -> uint8:
    return unsafe_mul(x, y)

@external
@view
def bar(x: int8, y: int8) -> int8:
    return unsafe_mul(x, y)
>>> ExampleContract.foo(1, 1)
1

>>> ExampleContract.foo(255, 255)
1

>>> ExampleContract.bar(-128, -128)
0

>>> ExampleContract.bar(127, -128)
-128

注意

性能说明:对于 EVM 的原生字类型 uint256int256,这将编译成单个 MUL 指令,因为 EVM 原生支持对 256 位字进行乘法运算。

unsafe_div(x: integer, y: integer) integer

x 除以 y,不检查除以零。 xy 必须都是相同类型的整数。如果除数为零,结果(遵循 EVM 语义)将为零。

@external
@view
def foo(x: uint8, y: uint8) -> uint8:
    return unsafe_div(x, y)

@external
@view
def bar(x: int8, y: int8) -> int8:
    return unsafe_div(x, y)
>>> ExampleContract.foo(1, 1)
1

>>> ExampleContract.foo(1, 0)
0

>>> ExampleContract.bar(-128, -1)
-128

注意

性能说明:这将编译成单个 SDIVDIV 指令,具体取决于输入是带符号的还是无符号的(分别)。

工具

as_wei_value(_value, unit: str) uint256

获取由数字和单位指定的以太币数量,并返回等效的以太币数量。

  • _value:以太币单位的值。可以使用任何数值类型,但值不能为负。

  • unit:以太币单位名称(例如 "wei""ether""gwei" 等),指示 _value 的面值。必须作为字面字符串给出。

@external
@view
def foo(s: String[32]) -> uint256:
    return as_wei_value(1.337, "ether")
>>> ExampleContract.foo(1)
1337000000000000000
blockhash(block_num: uint256) bytes32

返回指定高度的区块的哈希值。

注意

EVM 仅提供对最近 256 个区块的访问权限。如果区块编号大于或等于当前区块编号,或比当前区块落后 256 个以上,则此函数将回滚。

@external
@view
def foo() -> bytes32:
    return blockhash(block.number - 16)
>>> ExampleContract.foo()
0xf3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
empty(typename) Any

返回一个值,该值是其类型的默认值(零值)。对于初始化新的内存变量很有用。

  • typename:类型的名称,除了 HashMap[_KeyType, _ValueType]

@external
@view
def foo():
    x: uint256[2][5] = empty(uint256[2][5])
len(b: Union[Bytes, String, DynArray[_Type, _Integer]]) uint256

返回给定 BytesStringDynArray[_Type, _Integer] 的长度。

@external
@view
def foo(s: String[32]) -> uint256:
    return len(s)
>>> ExampleContract.foo("hello")
5
method_id(method, output_type: type = Bytes[4]) Union[Bytes[4], bytes4]

获取函数声明并返回其 method_id(在数据字段中用于调用它)。

  • method:方法声明,作为字面字符串给出

  • output_type:输出类型(Bytes[4]bytes4)。默认值为 Bytes[4]

返回 output_type 指定类型的的值。

@external
@view
def foo() -> Bytes[4]:
    return method_id('transfer(address,uint256)', output_type=Bytes[4])
>>> ExampleContract.foo()
0xa9059cbb
_abi_encode(*args, ensure_tuple: bool = True) Bytes[<depends on input>]

将可变数量的参数作为输入,并返回 ABIv2 编码的字节字符串。用于将参数打包到 raw_call、EIP712 和需要一致且高效的序列化方法的其他情况下。一旦此函数得到更多使用,我们暂时计划将其放入 ethereum.abi 命名空间中。

  • *args:任意参数

  • ensure_tuple:如果设置为 True,则确保即使单个参数也被编码为元组。换句话说,bytes 被编码为 (bytes,),而 (bytes,) 被编码为 ((bytes,),)。这是 Vyper 和 Solidity 函数的调用约定。除了非常具体的用例,这应该设置为 True。必须是字面值。

  • method_id:要附加到 ABI 编码的字节字符串开头的字面十六进制或 Bytes[4] 值。

返回一个字节字符串,其最大长度由参数决定。例如,编码 Bytes[32] 会导致 Bytes[64](第一个字是字节字符串变量的长度)。

@external
@view
def foo() -> Bytes[132]:
    x: uint256 = 1
    y: Bytes[32] = b"234"
    return _abi_encode(x, y, method_id=method_id("foo()"))
>>> ExampleContract.foo().hex()
"c2985578"
"0000000000000000000000000000000000000000000000000000000000000001"
"0000000000000000000000000000000000000000000000000000000000000040"
"0000000000000000000000000000000000000000000000000000000000000003"
"3233340000000000000000000000000000000000000000000000000000000000"
_abi_decode(b: Bytes, output_type: type_, unwrap_tuple: bool = True) Any

将字节数组作为输入,并根据指定的输出类型返回解码后的值。用于解压缩 ABIv2 编码的值。一旦此函数得到更多使用,我们暂时计划将其放入 ethereum.abi 命名空间中。

  • b:长度介于 output type 的 ABIv2 最小和最大大小范围之间的字节数组。

  • output_type:要解码的输出类型或输出类型的元组的名称。

  • unwrap_tuple: 如果设置为 True,则即使只指定了一种输出类型,输入也将被解码为元组。换句话说,_abi_decode(b, Bytes[32]) 将被解码为 (Bytes[32],)。这是 Vyper 和 Solidity 函数生成的 ABIv2 编码值的约定。除了非常特殊的用例之外,这应该设置为 True。必须是字面量。

返回解码后的值(s),类型由 output_type 指定。

@external
@view
def foo(someInput: Bytes[128]) -> (uint256, Bytes[32]):
    x: uint256 = empty(uint256)
    y: Bytes[32] = empty(Bytes[32])
    x, y =  _abi_decode(someInput, (uint256, Bytes[32]))
    return x, y
print(*args, hardhat_compat=False) None

通过对“console”地址0x000000000000000000636F6E736F6C652E6C6F67发出静态调用来“打印”参数。某些智能合约开发框架支持此功能。

默认模式在 titanoboa 中原生工作。对于 hardhat 风格的框架,请使用 hardhat_compat=True)

注意

发出静态调用与模式无关(即,不会从生产代码中删除),尽管编译器会在使用 print 时发出警告。