Remix介绍
官网地址
Remix 是一个基于浏览器的 Solidity 开发环境,主要用于编写、测试、调试和部署以太坊智能合约。
Solidity基本数据类型
类型 | 说明 | 示例 |
---|---|---|
uint / int |
无符号 / 有符号整数 | uint256 , int8 , int256 |
bool |
布尔类型(true / false ) |
bool isActive = true; |
address |
以太坊地址(20字节) | address owner; |
string |
字符串 | string name = "Alice"; |
bytes |
定长或变长字节数组 | bytes32 , bytes |
fixed / ufixed |
固定小数类型(未完全实现) | 不常用,建议不用 |
enum |
枚举类型(自定义) | enum Status { Active, Inactive } |
array |
数组 | uint[] memory nums; |
struct |
结构体 | struct Person { string name; uint age; } |
mapping |
映射(键值对) | mapping(address => uint) balances; |
1. 整数类型 uint
/ int
uint
是无符号整数(不能为负)int
是有符号整数- 支持从
8
到256
(每 8 位递增)
uint256 a = 100;
int8 b = -20;
2.布尔类型 bool
bool isOpen = true;
3.地址类型 address
用于存储以太坊地址(例如钱包地址、合约地址)
address owner = msg.sender;
还可以加上 payable 使其可接收 ETH:
- msg.sender 默认是 address 类型,不能直接收 ETH。
- 必须用 payable(…) 转换为 payable address,才可以用 .transfer() 接受或 .send() 发送 ETH
payable(msg.sender).transfer(1 ether);
4.字符串 string
string memory name = "Alice";=
📌 注意:字符串不能直接比较是否相等,需要用 keccak256 哈希后比对。
5.字节数组 bytes
- bytes 是动态字节数组
- bytes1 ~ bytes32 是定长字节数组
bytes32 hash = keccak256(abi.encodePacked("hello"));
- abi.encodePacked(…):将参数打包成二进制格式
- keccak256(…):对打包后的数据进行哈希
👉 结果是一个 bytes32 类型的哈希值
6.枚举 enum
enum Status { Active, Inactive, Pending }
Status public currentStatus;
// 设置状态为 Pending
function setPending() public {
currentStatus = Status.Pending;
}
7.结构体 struct
struct Person {
string name;
uint age;
}
8. 映射 mapping
mapping(address => uint256) public balances;
Solidity 中的数据存储位置
Solidity 中的数据存储位置主要分为三种:storage
、memory
和 calldata
,理解它们对于 gas 优化和正确处理数据非常关键。
🧠 存储类型(关键字)
用于修饰数组(array),结构(struct),字符串(string),字节(bytes),映射(mapping仅storage支持)
存储类型 | 说明 | 生命周期 | 关键字 |
---|---|---|---|
storage |
链上的永久存储 | 持久保存 | 默认状态变量 |
memory |
临时内存(函数调用期间) | 函数执行期间有效 | memory |
calldata |
外部函数参数的只读区域 | 外部调用期间只读 | calldata |
🔸 1. storage
(链上存储)
- 数据保存在区块链上,是持久化的
- 用于合约中的状态变量或引用链上已有变量进行修改
string public myName = "Alice"; // 状态变量 -> 存储在 storage 中
struct Person {
string name;
uint age;
}
Person[] public people;
function updatePerson(uint index) public {
Person storage person = people[index]; // 引用链上的 person
person.age = 30; // 改变的是链上的数据
}
🔸 2. memory
(临时内存)
- 只在函数调用期间有效
- 常用于函数内部的临时数据或函数参数
- 可读写,但函数执行完就被销毁
function getUpper(string memory _name) public pure returns (string memory) {
return _name;
}
🔸 3. calldata
(只读外部输入)
- 用于 external 函数参数
- 只读不可修改
- 相比 memory 更省 gas
function sayHello(string calldata _name) external pure returns (string memory) {
return _name;
}