Vyper语言中的数据类型详解
vyper 项目地址: https://gitcode.com/gh_mirrors/vyp/vyper
Vyper作为区块链智能合约开发语言,采用静态类型系统,要求所有变量(包括状态变量和局部变量)的类型必须在编译时确定。本文将全面解析Vyper支持的各种数据类型及其特性。
值类型(Value Types)
值类型变量在传递时会进行值拷贝,主要包括以下几种基础类型:
布尔类型(bool)
布尔类型用于存储逻辑值,仅有两个可能值:
True
:真值False
:假值
支持的操作符:
- 逻辑运算:
not
(非)、and
(与)、or
(或) - 比较运算:
==
(等于)、!=
(不等于)
布尔运算符遵循Python的短路求值规则。
有符号整数(intN)
N位有符号整数,N必须是8到256之间的8的倍数(如int8、int128等)。
取值范围:-2^(N-1) 到 2^(N-1)-1
操作符:
- 比较运算:
<
,<=
,==
,!=
,>=
,>
- 算术运算:
+
,-
,*
,//
(整除),**
(幂),%
(取模) - 位运算:
&
(与),|
(或),^
(异或) - 位移运算:
<<
(左移),>>
(右移)
注意事项:
- 整数除法对负数采用向零取整(与Python不同)
- 位移运算仅支持256位类型
- 编译时会检查位移越界问题
无符号整数(uintN)
N位无符号整数,N必须是8到256之间的8的倍数(如uint8、uint256等)。
取值范围:0 到 2^N-1
操作符与有符号整数基本相同,额外支持:
- 位取反操作:
~x
(仅uint256支持)
定点小数(decimal)
用于存储高精度定点小数,精度为10位小数。
取值范围:-2^167/10^10 到 (2^167-1)/10^10
特点:
- 字面量必须包含小数点才能被识别为decimal类型
- 支持标准算术运算和比较运算
- 除法运算结果为decimal类型
地址类型(address)
存储20字节的区块链地址,字面量必须为带0x前缀的校验和地址。
成员属性:
balance
:地址余额(uint256)codehash
:合约代码哈希(bytes32)codesize
:合约代码大小(uint256)is_contract
:是否为合约(bool)code
:合约字节码(Bytes)
注意事项:
- 地址成员属性可能因合约自毁或CREATE2操作而改变
- 访问
code
属性需要使用slice
函数明确指定范围
复合类型(Reference Types)
复合类型支持对其成员进行单独修改,主要包括:
固定大小字节数组(bytesM)
M字节长度的字节数组,如bytes32表示32字节数组。
操作:
keccak256(x)
:计算Keccak256哈希concat(x,...)
:连接多个字节数组slice(x, start, len)
:提取子数组
字节数组(Bytes[N])
最大长度为N的动态字节数组,ABI类型为bytes。
字符串(String[N])
最大长度为N的字符串,ABI类型为string。
枚举类型(flag)
自定义枚举类型,最多支持256个成员,每个成员对应一个uint256值(2^n)。
操作:
- 比较运算:
==
,!=
,in
,not in
- 位运算:
&
,|
,^
,~
- 成员检查:
a in (Roles.ADMIN | Roles.USER)
典型应用:权限管理系统中角色权限的组合与检查。
固定大小数组
声明语法:类型[长度]
,如int128[3]
表示3个元素的int128数组。
特点:
- 支持多维数组(声明顺序与访问顺序相反)
- 数组大小超过2^64可能导致安全问题
动态数组(DynArray)
大小可变的数组,但有最大长度限制。
声明语法:DynArray[类型, 最大长度]
操作:
append(x)
:添加元素pop()
:移除并返回最后一个元素- 访问元素:
array[index]
注意事项:
- 越界访问会导致REVERT
- 迭代过程中禁止修改数组
类型系统设计理念
Vyper的类型系统设计体现了以下原则:
- 显式优于隐式:所有变量必须明确指定类型
- 安全性优先:编译时进行严格类型检查,运行时防止常见错误
- 确定性:所有操作结果在EVM中可精确预测
- 简洁性:避免复杂类型带来的理解负担
理解这些数据类型及其操作是编写安全高效Vyper智能合约的基础。开发者应根据实际需求选择最合适的类型,并注意各类型的边界条件和特殊行为。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考