值类型 #

一、值类型概述 #

Solidity中的值类型是指变量直接存储其值,而不是存储引用。值类型在赋值时会创建副本。

text
值类型特点:
- 直接存储值
- 赋值时创建副本
- 包含:整数、地址、布尔、字节、定长数组、枚举、函数类型

二、整数类型 #

2.1 有符号整数 int #

solidity
// 有符号整数:带正负号的整数
int8 public myInt8;    // 8位,范围: -128 到 127
int16 public myInt16;  // 16位,范围: -32768 到 32767
int32 public myInt32;  // 32位,范围: -2^31 到 2^31-1
int64 public myInt64;  // 64位
int128 public myInt128;  // 128位
int256 public myInt256;  // 256位,默认类型

2.2 无符号整数 uint #

solidity
// 无符号整数:非负整数
uint8 public myUint8;    // 8位,范围: 0 到 255
uint16 public myUint16;  // 16位,范围: 0 到 65535
uint32 public myUint32;  // 32位,范围: 0 到 2^32-1
uint64 public myUint64;  // 64位
uint128 public myUint128;  // 128位
uint256 public myUint256;  // 256位,默认类型

2.3 默认类型 #

solidity
// 不指定大小时,默认使用 uint256 和 int256
uint public count = 100;    // 等价于 uint256
int public balance = -50;   // 等价于 int256

2.4 取值范围 #

类型 最小值 最大值
int8 -128 127
int16 -32768 32767
int32 -2147483648 2147483647
int64 -2^63 2^63-1
int128 -2^127 2^127-1
int256 -2^255 2^255-1
uint8 0 255
uint16 0 65535
uint32 0 2^32-1
uint64 0 2^64-1
uint128 0 2^128-1
uint256 0 2^256-1

2.5 使用示例 #

solidity
contract IntegerDemo {
    uint256 public totalSupply = 1000000;
    int256 public temperature = -10;
    uint8 public level = 5;
    
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }
    
    function subtract(int256 a, int256 b) public pure returns (int256) {
        return a - b;
    }
}

三、地址类型 address #

3.1 address #

solidity
// address:20字节(160位),存储以太坊地址
address public owner;
address public recipient = 0x1234567890123456789012345678901234567890;

3.2 address payable #

solidity
// address payable:可以发送ETH的地址
address payable public payer;
address payable public recipientPayable;

// 地址赋值
address public normalAddress = 0x123...;
address payable public payableAddress = payable(normalAddress);

3.3 地址成员 #

solidity
address public addr = 0x123...;

// 获取余额
uint256 balance = addr.balance;

// 发送ETH(已废弃,不推荐)
addr.transfer(100);  // 2300 gas,失败会revert
addr.send(100);     // 2300 gas,返回bool

// 调用合约(推荐)
(bool success, bytes memory data) = addr.call{value: 100}("");
(bool success, ) = addr.call{value: 0}("");

3.4 address成员详细说明 #

成员 说明 示例
.balance 地址的ETH余额 addr.balance
.transfer(uint256) 发送ETH,失败revert addr.transfer(1 ether)
.send(uint256) 发送ETH,返回bool addr.send(1 ether)
.call(bytes) 低级调用 addr.call{value:1}("")
.delegatecall(bytes) 委托调用 -
.staticcall(bytes) 静态调用 -

3.5 address使用示例 #

solidity
contract AddressDemo {
    address public owner;
    address payable public vault;
    
    constructor() {
        owner = msg.sender;
        vault = payable(address(this));
    }
    
    function getBalance() public view returns (uint256) {
        return address(this).balance;
    }
    
    function getOwnerBalance() public view returns (uint256) {
        return owner.balance;
    }
    
    function sendToVault() public payable {
        require(msg.value > 0, "Must send ETH");
        vault.transfer(msg.value);
    }
}

四、布尔类型 bool #

solidity
// bool:true 或 false
bool public isActive = true;
bool public isPaused = false;

// 布尔运算
bool public result1 = true && false;   // false
bool public result2 = true || false;  // true
bool public result3 = !true;           // false

五、字节类型 #

5.1 定长字节数组 #

solidity
// 定长字节数组:1-32字节
bytes1 public b1;   // 1字节
bytes2 public b2;   // 2字节
bytes3 public b3;   // 3字节
bytes4 public b4;   // 4字节
bytes8 public b8;   // 8字节
bytes16 public b16;  // 16字节
bytes32 public b32;  // 32字节

// 赋值
bytes32 public hash = 0x123456789012345678901234567890123456789012345678901234567890abcd;

// 长度
uint256 public length = b32.length;  // 32

5.2 字节数组操作 #

solidity
bytes32 public data = 0x68656c6c6f20776f726c64; // "hello world"

// 访问单个字节
bytes1 public firstByte = data[0];  // 0x68

// 切片(返回bytes memory)
bytes2 public slice = bytes2(data[:2]);  // 0x6865

5.3 bytes vs string #

solidity
// string:动态长度UTF-8字符串
string public name = "Hello";
string public empty = "";

// bytes:动态长度字节数组
bytes public data = "Hello";
bytes public hexData = hex"48656c6c6f";

// 区别
// - string 只能存储UTF-8字符串
// - bytes 可以存储任意字节数据
// - bytes 可以直接索引和切片
// - string 转换为bytes较复杂

六、定长数组 #

6.1 定长数组声明 #

solidity
// 类型[长度] 数组名
uint256[5] public scores;           // 5个uint256的数组
address[3] public players;           // 3个地址的数组
bool[2] public flags = [true, false];  // 带初始值
uint256[3] public amounts = [1, 2, 3];

6.2 数组字面量 #

solidity
// 固定长度数组
uint256[3] memory arr1 = [1, 2, 3];
uint256[2] memory arr2 = [uint256(1), 2];  // 需要显式类型

// 动态长度数组
uint256[] memory dynamicArr = new uint256[](3);

七、函数类型 #

solidity
// 函数类型
function (uint256) returns (uint256) public funcType;

// 赋值
function add(uint256 a, uint256 b) public pure returns (uint256) {
    return a + b;
}

function getAdder() public pure returns (function(uint256, uint256) returns (uint256)) {
    return add;
}

八、类型转换 #

8.1 隐式转换 #

solidity
// 小类型到大类型可以隐式转换
uint8 a = 10;
uint256 b = a;  // 隐式转换

int8 c = -5;
int256 d = c;  // 隐式转换

address e = 0x123...;
address payable f = payable(e);  // address可以转为address payable

8.2 显式转换 #

solidity
// 不同整数类型间转换
uint32 a = 10;
uint8 b = uint8(a);  // 显式转换,可能截断

// 地址转换
address addr = 0x123...;
bytes20 addrBytes = bytes20(addr);  // 地址转字节

// 字节转地址
bytes20 addrBytes2 = 0x00000000000000000000000012345678901234567890;
address addr2 = address(addrBytes2);  // 字节转地址

8.3 地址转换注意事项 #

solidity
address public addr = 0x123...;

// 不安全的转换
address unsafe = address(uint160(uint256(1)));

// 安全转换(OpenZeppelin库)
import "@openzeppelin/contracts/utils/Address.sol";
Address.isContract(addr);

九、特殊字面量 #

9.1 时间单位 #

solidity
uint256 public oneSecond = 1 seconds;
uint256 public oneMinute = 60 seconds;
uint256 public oneHour = 60 minutes;
uint256 public oneDay = 24 hours;
uint256 public oneWeek = 7 days;

9.2 货币单位 #

solidity
uint256 public oneWei = 1 wei;
uint256 public oneGwei = 1 gwei;  // 10^9 wei
uint256 public oneEther = 1 ether;  // 10^18 wei

9.3 地址字面量 #

solidity
address public addr1 = 0x1234567890123456789012345678901234567890;  // 合法的地址字面量
// address public addr2 = 0x123...;  // 太短,不是合法地址

十、最佳实践 #

10.1 选择合适的整数大小 #

solidity
// 推荐:使用默认的uint256
uint256 public balance;      // ✓ 推荐
uint128 public amount;       // 在确定不会超过uint128时使用

// 不推荐:使用过小的类型导致溢出
uint8 public counter = 0;
counter++;  // 当counter=255时,再++会溢出

10.2 地址使用 #

solidity
// 推荐:明确区分address和address payable
address public governance;           // 不能收ETH
address payable public treasury;    // 可以收ETH

// 赋值时注意转换
treasury = payable(governance);

10.3 避免类型混淆 #

solidity
// 不推荐
uint public amount = 100;  // 不清晰,应该是100个最小单位

// 推荐:使用明确单位
uint256 public amount = 100 wei;
uint256 public price = 1 ether;

十一、总结 #

值类型一览:

类型 说明 示例
int/uint 整数,有符号/无符号 uint256, int8
address 以太坊地址 address, address payable
bool 布尔值 true, false
bytes1-bytes32 定长字节数组 bytes32
函数类型 函数引用 function(...) returns (...)

使用建议:

  • 默认使用uint256
  • 注意整数溢出(0.8.x已内置保护)
  • 明确区分address和address payable
  • 使用有意义的变量名

接下来,让我们学习引用类型!

最后更新:2026-03-27