Vyper 入门: 5. 变量数据存储和作用域 在Vyper中,变量根据存储位置分为四类:存储(Storage)、内存(Memory)、不可变量(immutable)和常量(constant)。变量的作用域则是决定了在哪里可以访问这些变量。 数据存储 Vyper中的数据储存位置有四类:Storage、Memory、Immutable和Constant。需要注意的是,与Solidity不同的是,在函数中Vyper不需要通过数据类型的关键字存储数据,而是直接声明。
owner: public(address) balances: uint256
public关键字,代表这个变量是可读的,作用与 view 函数一样,反之则是内部变量。balances: public(uint256) @external def update_balance(_new_balance: uint256): self.balances = _new_balance

balances: public(uint256) @external def update_balance1(): memory_balance: uint256 = self.balance memory_balance += 1

@view @external def update_balance(_new_balance: uint256) -> uint256: balance: uint256 = 100 return balance * _new_balance
immutable 变量在部署合约时在 构造函数 中设定,之后不能更改gas,因为在编译时会被直接替换成相应的值immutable 的变量不能直接被调用,如果需要访问,需要额外编写视图函数调用IMMUTABLENUMBER: immutable(uint256) @payable @external def __init__(): NUMBER = 100 # 额外编写一个访问函数 @view @external def get_immutable_number() -> uint256: return NUMBER

constant 是编译时确定的常数,不占用存储空间immutable一样,声明 constant 的变量不能直接被调用,如果需要访问,需要额外编写视图函数调用CONSTANTOWNER: constant(address) = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE @view @external def get_owner() -> address: return OWNER

环境变量: 环境变量是Vyper预留的关键字,主要用于提供有关区块链或当前交易的信息,不需要声明就可以直接使用自变量:自变量是一个环境变量,用于从自身内部引用合约,通常用 self 来调用自定义常量:Vyper允许自定义全局常量,通常使用 constant 和 immutable 关键字来声明msg.sender、block.number 和 msg.data, 分别代表当前调用者、当前区块号和消息数据。下面列出一些常用的系统关键字,更完整的列表查看文档。block.coinbase: 当前区块矿工地址block.number: 当前区块号block.timestamp: 当前区块的时间戳,按照秒计算chain.id: 链IDmsg.data: 消息数据msg.gas: 剩余gasmsg.sender: 调用者msg.value: 随着消息发送的ETH数量tx.gasprice: 当前交易的Gas价格(单位: wei)@view @external def env_variable() -> (address, uint256, Bytes[255]): caller: address = msg.sender block_number: uint256 = block.number call_data: Bytes[255] = slice(msg.data, 0, 4) return caller, block_number, call_data

self 从自身内部引用合约,允许读取和写入状态变量以及调用合约内的私有函数。下面举例说明 self 两种常用的使用方式:访问合约的状态变量和调用内部函数# 访问合约的状态变量 state_var: uint256 @external def set_var(_value: uint256) -> bool: self.state_var = _value return True @view @external def get_var() -> uint256: return self.state_var # 调用内部函数 @internal def _times_two(_amount: uint256) -> uint256: return _amount * 2 @external def calculate(_amount: uint256) -> uint256: return self._times_two(_amount)

TOTAL_SUPPLY: constant(uint256) = 10000000 DECIMALS: immutable(uint256) total_supply: public(uint256) @external def __init__(): DECIMALS = 18 self.total_supply = TOTAL_SUPPLY
@external def local_variable() -> uint256: num1: uint256 = 100 num2: uint256 = 200 num3: uint256 = num1 + num2 return num3
owner: public(address) @view @external def get_owner() -> address: return self.owner @external def call(): assert msg.sender == self.owner