1. Solidity 是什么?🤔
Solidity 是一种面向合约的编程语言,主要用于以太坊智能合约开发。可以理解为:
- 就像在手机上写 App
- 但是是在区块链上写"程序"
- 这个"程序"叫做智能合约
2. 基础语法 📝
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// 这是一个简单的合约
contract MyFirstContract {
// 状态变量
uint public myNumber; // 类似存款余额
address public owner; // 账户地址
// 构造函数:合约部署时执行
constructor() {
owner = msg.sender; // msg.sender 是调用者的地址
myNumber = 0;
}
// 函数
function setNumber(uint _number) public {
myNumber = _number;
}
}
3. 数据类型详解 📊
3.1 基本类型
contract DataTypes {
// 1. 整数
uint public unsignedInt = 123; // 正整数
int public signedInt = -123; // 可以为负数
// 2. 布尔
bool public flag = true; // true/false
// 3. 地址
address public userAddress; // 以太坊地址
// 4. 字节
bytes32 public data; // 固定长度字节
// 5. 字符串
string public message = "Hello"; // 文本
}
3.2 复杂类型
contract ComplexTypes {
// 1. 数组
uint[] public numbers; // 动态数组
uint[5] public fixedNumbers; // 固定长度数组
// 2. 映射(类似字典)
mapping(address => uint) public balances; // 地址=>余额
// 3. 结构体
struct User {
string name;
uint age;
address wallet;
}
User public user;
}
4. 函数详解 🛠️
4.1 函数类型
contract Functions {
// 1. 基本函数
function normalFunction() public {
// 可以改变状态
}
// 2. 查看函数(不修改状态)
function viewFunction() public view returns (uint) {
return 123;
}
// 3. 纯函数(不读取状态)
function pureFunction(uint x) public pure returns (uint) {
return x * 2;
}
// 4. 支付函数(可以接收以太币)
function payableFunction() public payable {
// 可以接收ETH
}
}
4.2 函数修饰符
contract Modifiers {
address public owner;
// 自定义修饰符
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_; // 继续执行函数
}
// 使用修饰符的函数
function restrictedFunction() public onlyOwner {
// 只有owner才能调用
}
}
5. 事件和日志 📢
contract Events {
// 定义事件
event Transfer(
address indexed from,
address indexed to,
uint amount
);
function transfer(address to, uint amount) public {
// 触发事件
emit Transfer(msg.sender, to, amount);
}
}
6. 继承和接口 🔗
// 接口定义
interface IERC20 {
function transfer(address to, uint amount) external returns (bool);
}
// 基础合约
contract Base {
uint public x;
function setX(uint _x) public {
x = _x;
}
}
// 继承合约
contract Child is Base {
function getX() public view returns (uint) {
return x;
}
}
7. 实用工具和库 🔧
// 使用 SafeMath 库
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract SafeMathExample {
using SafeMath for uint;
function add(uint a, uint b) public pure returns (uint) {
return a.add(b); // 安全的加法
}
}
8. 常见应用场景 💡
8.1 代币合约
contract SimpleToken {
mapping(address => uint) public balances;
// 铸造代币
function mint(address to, uint amount) public {
balances[to] += amount;
}
// 转账
function transfer(address to, uint amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
8.2 众筹合约
contract Crowdfunding {
address public creator;
uint public goal;
uint public endTime;
mapping(address => uint) public contributions;
constructor(uint _goal, uint _duration) {
creator = msg.sender;
goal = _goal;
endTime = block.timestamp + _duration;
}
function contribute() public payable {
require(block.timestamp < endTime, "Crowdfunding ended");
contributions[msg.sender] += msg.value;
}
}
9. 安全考虑 🔒
contract SecurityExample {
// 重入锁
bool private locked;
modifier noReentrant() {
require(!locked, "No reentrancy");
locked = true;
_;
locked = false;
}
// 安全的提款函数
function withdraw() public noReentrant {
uint amount = balances[msg.sender];
require(amount > 0, "No balance");
// 先更新状态,后发送以太币
balances[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
}
10. Gas优化技巧 ⛽
contract GasOptimization {
// 使用 uint256 而不是 uint8
uint256 public largeNumber;
// 打包结构体
struct PackedStruct {
uint8 small;
uint8 another;
uint256 large;
}
// 避免在循环中修改状态变量
function optimizedLoop() public {
uint256 localVar = largeNumber;
for(uint i = 0; i < 100; i++) {
localVar += i;
}
largeNumber = localVar;
}
}
11. 开发工具 🛠️
-
开发环境
- Remix IDE(在线编辑器)
- Truffle(开发框架)
- Hardhat(开发环境)
-
测试网络
- Ganache(本地测试网络)
- Ropsten, Rinkeby(公共测试网络)
-
前端集成
- Web3.js
- Ethers.js
12. 最佳实践 ✨
-
代码规范
- 使用最新的编译器版本
- 明确的变量命名
- 适当的注释
-
安全建议
- 使用 OpenZeppelin 合约
- 进行安全审计
- 测试覆盖率要高
-
优化建议
- 减少存储操作
- 优化循环
- 合理使用事件
这是 Solidity 的基础知识框架,建议:
- 先理解基础概念
- 动手写简单合约
- 学习安全开发
- 实践实际项目