solidity基础-变量基础
基础知识
默认初始值
bool public b; // false
int8 public i; // 0
uint8 public u; // 0
string public str; // ""
address public ads; // 0x0000000000000000000000000000000000000000
bytes public bs; // 0x
bytes4 public b4; // 0x00000000
uint8[] public arr; // []
可以使用 delete 操作符使变量恢复默认值
作用域和声明
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Demo {
uint8 a = 32;
function getArr() external view returns(uint8){
uint8 b = 33;
// 内部可以使用外部的变量
return a;
}
// uint8 c = b; // 外部不能使用内部的变量
// 函数参数(修改器参数,catch参数等),只在函数内部有效
}
变量的三种状态
- 状态变量:创建在非函数内,永久存储在区块链上
- 局部变量:定义在函数内部
- 全局变量:保存在全局命名空间中,不需要开发者定义,直接使用,比如msg.sender
常量
- 普通变量和常量:常量更省 gas
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Demo {
// 预计 24465 gas
string public str1 = "b00l"; // 变量
// 预计 21793 gas
string public constant str2 = "b00l"; // 常量
}
- 常量的名字一般全大写(约定)
- 常量赋值后不可修改
- 常量必须在声明的时候赋值
- 常量可以在合约外定义
常量的值和储存原理
- 在编译器中确定,所以不能在函数内执行
- 不允许在函数内定义
- 编译器不会为 constant 在 storage 中预留空间。每次出现的时候,都被替换为相应的常量 / 常量表达式
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Demo {
string str1 = "b00l";
string constant str2 = "b00l";
function getStr1() external view returns (string memory) {
return str1;
}
// 读取常量可以使用pure,代表我们没有读取状态变量,侧面说明了常量没有存储在 storage 中
function getStr2() external pure returns (string memory) {
return str2;
}
}
常见的赋值方式
- 运算符赋值
- 通过密码学的函数赋值
- 不允许使用全局变量
immutable 不可变量
- 声明 / 赋值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Demo {
// 声明和初始化一起
uint8 public immutable u1 = 123;
uint8 public immutable u2;
// 先声明,然后在 constructor 中赋值
constructor() {
u2 = 123;
}
}
- 部署后不可修改
- 不能在赋值前读取
- 不支持引用类型
与常量(constant)的区别
值的确定时期不一样
- constant:编译时确定
- immutable:部署时确定
变量名的命名规则
- 禁止使用保留关键字作为变量名
- 变量名必须以字母或下划线开头
- 变量名大小写敏感
变量的可见性
可见性仅存在于状态变量和函数中
- 局部变量仅限于定义它们的函数
- 函数有四种可见性:private、external、 internal、public
- 状态变量有三种可见性:public、internal、public
全局时间单位
- 秒是缺省时间单位,可以不写
- 数字后面带有 seconds、minutes、hours、days、weeks 可进行换算
基本换算关系
- 1 == 1 seconds
- 1 minutes == 60 seconds
- 1 hours == 60 minutes
- 1 days == 24 hours
- 1 weeks == 7days
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Demo {
uint256 public time = 1; // 1
function addSeconds() external view returns (uint256) {
return time + 1 seconds; // 2
}
function addMinute() external view returns (uint256) {
return time + 1 minutes; // 61
}
function addDays() external view returns (uint256) {
return time + 1 days; // 86401
}
function addWeeks() external view returns (uint256) {
return time + 1 weeks; // 86401
}
}
- 注意:由于润秒,不是每年都是365天,也不是每天都是24小时,所以会出现不够精确的情况
区块和交易属性
block
- block.coinbase (address): 当前块的矿工的地址
- block.difficulty (uint):当前块的难度系数
- block.gaslimit (uint):当前块gas的上限
- block.number (uint):当前块编号
- block.blockhash (function(uint) returns (bytes32)):函数,返回指定块的哈希值,已经被内建函数blockhash所代替
- block.timestamp (uint):当前块的时间戳
msg
- msg.sender:当前合约的调用者
- msg.value:当前交易的以太币
- msg.data:函数的信息,不接收参数时等于 msg.sig
- msg.sig:函数签名/标识符
tx
- origin:交易的发送方
- gasprice:交易价格
- blockhash()
- gasleft()