数据类型
值类型
值类型的变量在赋值或作为函数参数传递时会被复制。
- 布尔类型:
bool
- 整数类型:
- 无符号:
uint8
、uint16
、…、uint256
(uint256
可简写为uint
) - 有符号:
int8
、int16
、…、int256
(int256
可简写为int
)
- 无符号:
- 地址类型:
address
(存储以太坊地址,占 20 字节) - 定长字节类型:
bytes1
、bytes2
、…、bytes32
- 枚举类型:用于为一组相关的常量赋予可读的标签,示例
enum Status { Pending, Rejected, Approved }
contract Demo {
// 布尔类型
bool public isActive; // 默认为 false
// 有符号整数类型
int public signedInt; // 默认为 0
// 无符号整数类型
uint public unsignedInt; // 默认为 0
// 地址类型
address public owner; // 默认为 0x0000000000000000000000000000000000000000
// 定长字节数组类型
bytes1 public dataHash1; // 默认为 0x00
bytes2 public dataHash2; // 默认为 0x0000
// 枚举类型
enum Status { Pending, Rejected, Approved }
Status public status; // 默认为 Pending, 即 0
}
在 Solidity 中可以直接通过 API 获取指定数字类型的最大最小值:
contract Demo {
uint public maxUint = type(uint).max; // 2^256-1
uint public minUint = type(uint).min; // 0
int public maxInt = type(int).max; // 2^255-1
int public minInt = type(int).min; // -2^255
}
引用类型
引用类型的变量在赋值或作为函数参数传递时不会被复制,而是传递引用。
- 字符串类型:
string
- 动态字节数组类型:
bytes
- 数组类型:
- 固定大小数组:
uint[5]
表示包含 5 个无符号整数的数组 - 动态大小数组:
uint[]
表示大小可变的无符号整数数组
- 固定大小数组:
- 映射类型:存储键值对,示例
mapping(address => uint)
表示从地址到无符号整数的映射 - 结构体类型:用于将不同类型的数据组合在一起,示例
struct Person { string name; uint age; }
contract Demo {
// 字符串类型
string public stringData;
// 动态字节数组类型
bytes public byteData;
// 固定大小数组类型
uint[3] public fixedArray;
// 动态大小数组类型
uint[] public dynamicArray;
// 映射类型
mapping(address => uint) public balances;
// 结构体类型
struct Person {
string name;
uint age;
}
Person public person;
}
变量
状态变量
状态变量是存储在区块链上的数据。
contract Demo {
uint public count;
}
局部变量
局部变量是在函数内部声明的变量,只在函数执行期间存在。
contract Demo {
function calculateSum(uint a, uint b) public pure returns (uint) {
uint sum = a + b;
return sum;
}
}
全局变量
全局变量是 Solidity 提供的特殊变量,用于获取区块链相关的信息。
- 区块属性
block.basefee (uint)
:当前区块的基础费用。block.chainid (uint)
:当前链的 ID。block.coinbase (address)
:当前区块的矿工地址。block.difficulty (uint)
:当前区块的难度。block.gaslimit (uint)
:当前区块的 gas 限额。block.number (uint)
:当前区块号。block.timestamp (uint)
:当前区块的时间戳。
- 交易属性
tx.gasprice (uint)
:交易的 gas 价格。tx.origin (address)
:交易发起者的地址。
- 消息属性
msg.data (bytes)
:完整的调用数据 (calldata)。msg.sender (address)
:调用者的地址。msg.sig (bytes4)
:调用数据的前 4 个字节 (即函数选择器)。msg.value (uint)
:随调用发送的以太币数量 (以 wei 为单位)。
- 编码 & 解码
abi.encode(...) returns (bytes)
:对给定的参数进行 ABI 编码。abi.decode(bytes memory encodedData, (...)) returns (...)
:对给定的参数进行 ABI 解码。
- 其他函数
gasleft() returns (uint)
:返回当前剩余的 gas 数量。blockhash(uint blockNumber) returns (bytes32)
:返回指定区块的哈希值(仅适用于最近的 256 个区块)。
contract Demo {
function getGlobalVariables() public view returns (address, uint) {
address sender = msg.sender; // 调用者的地址
uint timestamp = block.timestamp; // 当前区块的时间戳
return (sender, timestamp);
}
}
流程控制
条件判断
if-else:
function testIf(uint a, uint b) public pure returns (uint) {
if (a > b) {
return a;
} else {
return b;
}
}
三元运算符:
function testTernary(uint a, uint b) public pure returns (uint) {
return a > b ? a : b;
}
注意:Solidity 不支持 switch-case 语句
循环
for 循环:
function forLoop() public pure returns (uint) {
uint sum = 0;
for (uint i = 0; i < 10; i++) {
if (i == 3) continue;
if (i == 5) break;
sum += i;
}
return sum;
}
while 循环:
function whileLoop() public pure returns (uint) {
uint sum = 0;
uint i = 0;
while (i < 10) {
if (i == 3) {
i++;
continue;
}
if (i == 5) break;
sum += i;
i++;
}
return sum;
}
do while 循环:
function doWhileLoop() public pure returns (uint) {
uint sum = 0;
uint i = 0;
do {
if (i == 3) { i++; continue; }
if (i == 5) break;
sum += i;
i++;
} while (i < 10);
return sum;
}
注意:在 Solidity 中需要控制好循环的次数,因为循环得越多 消耗的 gas 就越多 ~