结构体(Struct)是Solidity中用于定义自定义数据类型的重要特性,可以将多个不同类型的字段组合在一起。本文详细介绍结构体的定义、使用方法和实际应用场景。

Solidity Struct


一、什么是结构体

一、1 基本概念

结构体(Struct)是一种用户定义的数据类型,可以将多个不同类型的字段组合在一起,形成一个逻辑单元。结构体类似于其他语言中的类或记录类型。

二、2 结构体的特点

1
组合数据:
  • 将相关数据组合
  • 逻辑清晰
  • 易于管理
  • 提高可读性
1
类型灵活:
  • 可以包含各种类型
  • 可以嵌套结构体
  • 可以包含数组和映射
  • 灵活组合
1
存储位置:
  • 需要指定storage或memory
  • storage持久化存储
  • memory临时存储
  • 影响Gas消耗

二、如何定义和使用结构体

三、1 基本定义

1
简单结构体:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.8.0;

contract StructExample {
struct Person {
string name;
uint256 age;
address wallet;
bool isActive;
}

Person[] public people;
mapping(address => Person) public personByAddress;
}

1
结构体字段:
  • 可以包含任何类型
  • 字段有名称和类型
  • 可以设置默认值
  • 可以嵌套

四、2 创建结构体实例

1
2
使用命名参数:
function addPerson(
string memory _name,
uint256 _age,
address _wallet
1
2
3
4
5
6
7
) public {
Person memory newPerson = Person({
name: _name,
age: _age,
wallet: _wallet,
isActive: true
});
1
2
people.push(newPerson);
personByAddress[_wallet] = newPerson;

}
使用位置参数:solidity

1
2
function addPersonSimple(
Person memory newPerson = Person(_name, _age, _wallet, true);

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

### 五、3 访问和修改

访问字段:
function getPerson(uint256 index) public view returns (
string memory,
uint256,
address,
bool
) {
Person memory p = people[index];
return (p.name, p.age, p.wallet, p.isActive);
}

function getPersonName(uint256 index) public view returns (string memory) {
return people[index].name;
}
`修改字段:`solidity
function updatePersonAge(uint256 index, uint256 _age) public {
people[index].age = _age;
}

function deactivatePerson(uint256 index) public {
people[index].isActive = false;
}

六、4 存储位置

1
2
3
4
storage引用:
function updateStorage(uint256 index) public {
Person storage p = people[index]; // 引用storage
p.age = 30; // 修改会影响原数据

}
memory副本:solidity

1
2
3
4
5
function processMemory(uint256 index) public {
Person memory p = people[index]; // 创建副本
p.age = 30; // 修改不影响原数据
// 需要显式写回
people[index] = p;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

## 三、应用场景

### 七、1 用户管理

用户信息:
contract UserManagement {
struct User {
uint256 registrationTime;
uint256 balance;
bool isVerified;
}

mapping(address => User) public users;
address[] public userList;

function register(string memory _name) public {
require(users[msg.sender].wallet == address(0), "Already registered");

users[msg.sender] = User({
registrationTime: block.timestamp,
wallet: msg.sender,
balance: 0,
isVerified: false
});

userList.push(msg.sender);
}

function verifyUser(address user) public {
users[user].isVerified = true;
}

八、2 订单系统

1
2
3
4
5
6
7
8
9
10
11
订单信息:
contract OrderSystem {
struct Order {
uint256 orderId;
address buyer;
address seller;
uint256 amount;
uint256 timestamp;
bool isPaid;
bool isShipped;
bool isCompleted;
}
1
2
mapping(uint256 => Order) public orders;
uint256 public orderCount;
1
2
3
4
5
6
7
8
9
10
11
12
13
function createOrder(address seller, uint256 amount) public returns (uint256) {
orderCount++;
orders[orderCount] = Order({
orderId: orderCount,
buyer: msg.sender,
seller: seller,
amount: amount,
timestamp: block.timestamp,
isPaid: false,
isShipped: false,
isCompleted: false
});
return orderCount;
}
1
2
3
4
5
function payOrder(uint256 orderId) public payable {
Order storage order = orders[orderId];
require(order.buyer == msg.sender, "Not buyer");
require(msg.value == order.amount, "Wrong amount");
require(!order.isPaid, "Already paid");
1
order.isPaid = true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

### 九、3 投票系统

提案和投票:
contract VotingSystem {
struct Proposal {
string description;
uint256 voteCount;
uint256 deadline;
bool executed;
mapping(address => bool) hasVoted;
}

struct Vote {
address voter;
bool support;
}

Proposal[] public proposals;
mapping(uint256 => Vote[]) public proposalVotes;

function createProposal(string memory description, uint256 duration) public {
proposals.push(Proposal({
description: description,
voteCount: 0,
deadline: block.timestamp + duration,
executed: false
}));

function vote(uint256 proposalId, bool support) public {
Proposal storage proposal = proposals[proposalId];
require(block.timestamp < proposal.deadline, "Proposal expired");
require(!proposal.hasVoted[msg.sender], "Already voted");

proposal.hasVoted[msg.sender] = true;
if (support) {
proposal.voteCount++;
}

proposalVotes[proposalId].push(Vote({
voter: msg.sender,
support: support,
timestamp: block.timestamp
}));

十、4 NFT元数据

1
2
3
4
5
6
7
8
9
NFT信息:
contract NFTContract {
struct NFT {
uint256 tokenId;
string imageURI;
address creator;
uint256 creationTime;
uint256 price;
bool forSale;
}
1
2
mapping(uint256 => NFT) public nfts;
uint256 public tokenCount;
1
function mint(
    string memory name,
    string memory description,
    string memory imageURI
1
2
3
4
5
6
7
8
9
10
tokenCount++;
nfts[tokenCount] = NFT({
tokenId: tokenCount,
name: name,
imageURI: imageURI,
creator: msg.sender,
creationTime: block.timestamp,
price: 0,
forSale: false
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

## 四、高级用法

### 十一、1 嵌套结构体

嵌套定义:
contract NestedStruct {
struct Address {
string street;
string city;
string country;
}

Address homeAddress;
Address workAddress;
}

mapping(address => Person) public people;

function setPerson(
string memory street,
string memory city
people[msg.sender] = Person({
homeAddress: Address({
street: street,
city: city,
country: "China"
}),
workAddress: Address({
street: "",
city: "",
country: ""
})
});

十二、2 结构体数组

1
2
3
4
数组操作:
contract StructArray {
struct Item {
bool available;
}
1
Item[] public items;
1
2
3
4
5
function addItem(string memory name, uint256 price) public {
items.push(Item({
price: price,
available: true
}));
1
2
function getAllItems() public view returns (Item[] memory) {
return items;
}
1
2
3
4
function getAvailableItems() public view returns (Item[] memory) {
uint256 count = 0;
for (uint256 i = 0; i < items.length; i++) {
if (items[i].available) count++;
    }
    
1
2
3
4
5
Item[] memory available = new Item[](count);
uint256 index = 0;
if (items[i].available) {
available[index] = items[i];
index++;
        }
1
return available;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

### 十三、3 结构体映射

映射使用:
contract StructMapping {
struct Account {
uint256 transactionCount;
}

mapping(address => Account) public accounts;

function deposit() public payable {
Account storage account = accounts[msg.sender];
account.balance += msg.value;
account.transactionCount++;
account.isActive = true;
}

function withdraw(uint256 amount) public {
require(account.balance >= amount, "Insufficient balance");
account.balance -= amount;

payable(msg.sender).transfer(amount);
}

五、最佳实践

十四、1 设计原则

1
相关数据组合:
  • 将逻辑相关的数据组合
  • 避免过度嵌套
  • 保持结构清晰
  • 易于理解
1
2
3
4
5
字段命名:
// 好的命名
string userName;
uint256 registrationDate;
address walletAddress;

}

1
2
3
4
5
// 避免模糊命名
struct Data {
string s1;
uint256 n1;
address a1;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

### 十五、2 Gas优化

打包存储:
// 优化前:多个存储槽
struct Unpacked {
uint256 value1; // 存储槽1
uint256 value2; // 存储槽2
bool flag1; // 存储槽3
bool flag2; // 存储槽4
}

// 优化后:打包存储
struct Packed {
uint128 value1; // 存储槽1的前128位
uint128 value2; // 存储槽1的后128位
bool flag1; // 存储槽2
bool flag2; // 存储槽2
}
`使用memory:`solidity
function process(uint256 index) public {
Person memory p = people[index]; // 使用memory
// 处理逻辑
// 如果需要修改,最后写回
}

十六、3 安全考虑

1
2
3
4
输入验证:
function addPerson(string memory _name, uint256 _age) public {
require(bytes(_name).length > 0, "Name cannot be empty");
require(_age > 0 && _age < 150, "Invalid age");
1
2
people.push(Person({
}));

边界检查:solidity

1
2
function updatePerson(uint256 index, uint256 _age) public {
require(index < people.length, "Index out of bounds");

}


## 六、总结

结构体是Solidity中组织和管理复杂数据的重要工具。关键要点:

定义使用:
- 组合多个字段
- 支持嵌套和复杂类型
- 需要指定存储位置
- 灵活的数据组织

应用场景:
- 用户管理
- 订单系统
- 投票系统
- NFT元数据

最佳实践:
- 合理设计结构
- 优化Gas消耗
- 验证输入数据
- 提高代码可读性

通过合理使用结构体,可以更好地组织数据,提高代码的可读性和可维护性,构建更复杂的智能合约应用。

本文标题: Solidity结构体类型

发布时间: 2024年06月27日 00:00

最后更新: 2025年12月30日 08:54

原始链接: https://haoxiang.eu.org/2d1903cd/

版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

× 喜欢就赞赏一下呗!
打赏二维码