搭建僵尸工厂 - Solidity学习笔记
📖 课程概览
完成度: 100% ✅
课程来源: CryptoZombies教程
技术栈: Solidity, 智能合约开发
🎯 学习目标
- 掌握Solidity智能合约基础语法
- 理解以太坊智能合约的工作原理
- 学会创建和部署简单的智能合约
- 实现一个完整的僵尸工厂游戏合约
📝 核心知识点
1. Solidity基础语法
合约结构
pragma solidity >=0.5.0 <0.6.0;
contract ZombieFactory {
// 状态变量
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
// 结构体
struct Zombie {
string name;
uint dna;
}
// 数组
Zombie[] public zombies;
// 映射
mapping (uint => address) public zombieToOwner;
mapping (address => uint) ownerZombieCount;
// 事件
event NewZombie(uint zombieId, string name, uint dna);
}
数据类型详解
- uint: 无符号整数,默认uint256
- string: 字符串类型
- address: 以太坊地址类型
- mapping: 哈希表,类似字典
- array: 数组,可以是动态或固定大小
2. 核心功能实现
僵尸创建函数
function _createZombie(string memory _name, uint _dna) internal {
uint id = zombies.push(Zombie(_name, _dna)) - 1;
zombieToOwner[id] = msg.sender;
ownerZombieCount[msg.sender]++;
emit NewZombie(id, _name, _dna);
}
function _generateRandomDna(string memory _str) private view returns (uint) {
uint rand = uint(keccak256(abi.encodePacked(_str)));
return rand % dnaModulus;
}
function createRandomZombie(string memory _name) public {
require(ownerZombieCount[msg.sender] == 0);
uint randDna = _generateRandomDna(_name);
randDna = randDna - randDna % 100;
_createZombie(_name, randDna);
}
3. 重要概念解析
函数修饰符
public
: 任何人都可以调用private
: 只有合约内部可以调用internal
: 合约内部和继承合约可以调用external
: 只能从合约外部调用
函数状态修饰符
view
: 只读函数,不修改状态pure
: 纯函数,不读取也不修改状态payable
: 可以接收以太币的函数
特殊变量
msg.sender
: 调用函数的地址msg.value
: 发送的以太币数量block.timestamp
: 当前区块时间戳
4. 安全性考虑
require语句
function createRandomZombie(string memory _name) public {
require(ownerZombieCount[msg.sender] == 0, "User already has a zombie");
// 函数逻辑...
}
访问控制
modifier onlyOwnerOf(uint _zombieId) {
require(msg.sender == zombieToOwner[_zombieId]);
_;
}
function changeName(uint _zombieId, string calldata _newName) external onlyOwnerOf(_zombieId) {
zombies[_zombieId].name = _newName;
}
🛠️ 完整合约代码
pragma solidity >=0.5.0 <0.6.0;
contract ZombieFactory {
event NewZombie(uint zombieId, string name, uint dna);
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
uint32 level;
uint32 readyTime;
uint16 winCount;
uint16 lossCount;
}
Zombie[] public zombies;
mapping (uint => address) public zombieToOwner;
mapping (address => uint) ownerZombieCount;
function _createZombie(string memory _name, uint _dna) internal {
uint id = zombies.push(Zombie(_name, _dna, 1, uint32(now + cooldownTime), 0, 0)) - 1;
zombieToOwner[id] = msg.sender;
ownerZombieCount[msg.sender]++;
emit NewZombie(id, _name, _dna);
}
function _generateRandomDna(string memory _str) private view returns (uint) {
uint rand = uint(keccak256(abi.encodePacked(_str)));
return rand % dnaModulus;
}
function createRandomZombie(string memory _name) public {
require(ownerZombieCount[msg.sender] == 0);
uint randDna = _generateRandomDna(_name);
randDna = randDna - randDna % 100;
_createZombie(_name, randDna);
}
}
🤔 学习心得与思考
技术收获
- 智能合约思维: 学会了用去中心化的思维设计应用逻辑
- Gas优化: 理解了Gas机制,学会编写高效的合约代码
- 安全编程: 掌握了智能合约的安全最佳实践
实际应用场景
- 数字收藏品 (NFT): 僵尸可以作为NFT进行交易
- 游戏开发: 区块链游戏的基础架构
- DeFi应用: 质押、治理等机制的基础
遇到的挑战
- Gas费用: 每次交易都需要支付Gas费用
- 不可修改性: 智能合约部署后难以修改
- 调试困难: 相比传统开发,调试更加复杂
🔗 相关资源
- Solidity官方文档 (opens in a new tab)
- CryptoZombies教程 (opens in a new tab)
- Remix IDE (opens in a new tab) - 在线Solidity开发环境
- OpenZeppelin (opens in a new tab) - 安全的智能合约库
📅 后续学习计划
- 学习更高级的Solidity特性(继承、接口、库)
- 深入研究DeFi协议的实现原理
- 学习智能合约测试框架(Truffle, Hardhat)
- 探索Layer 2解决方案(Polygon, Optimism)
- 学习前端与智能合约的交互(Web3.js, Ethers.js)
🏆 项目成果
通过这个课程,我成功:
- ✅ 创建了第一个智能合约
- ✅ 理解了区块链开发的基本概念
- ✅ 掌握了Solidity的核心语法
- ✅ 学会了智能合约的部署和交互
这个项目为我进入Web3开发领域打下了坚实的基础!
最后更新时间: 2025/8/9