Web-3.0(Solidity)基础教程
Solidity 是 以太坊智能合约编程语言,用于编写 去中心化应用(DApp)。如果你想开发 Web3.0 应用,Solidity 是必学的。
Remix - Ethereum IDE(在线编写 Solidity)
特性 | Remix IDE | Hardhat |
---|---|---|
适用场景 | 适合 初学者 和 小项目测试 | 适合 专业开发 和 大项目 |
使用方式 | 在线工具(浏览器) | 本地开发(命令行) |
环境 | 无需安装,直接在线使用 | 需要 Node.js + NPM |
调试工具 | 内置调试器(Debugger) | Hardhat Network(本地测试链) |
测试方式 | 手动测试,运行合约函数 | 自动化测试(Mocha / Chai) |
本地节点 | 无本地测试链 | 自带本地以太坊节点 |
部署方式 | 点击 Deploy 按钮,适合测试 | 支持自动部署脚本(更灵活) |
适合的开发者 | 初学者、简单测试 | 开发者、团队项目 |
Solidity 语法基础
📌 1. Solidity 代码结构
// SPDX-License-Identifier: MIT // 许可证声明(推荐加上)
pragma solidity ^0.8.0; // 指定 Solidity 版本
contract MyContract { // 定义一个智能合约
uint public myNumber = 10; // 公开变量(自动生成 getter)
}
✅ pragma solidity ^0.8.0;
👉 指定 Solidity 版本(避免兼容性问题)
✅ contract MyContract {}
👉 定义一个智能合约
✅ public
👉 允许外部访问变量(自动生成 getter
方法)
📌 2. 数据类型
类型 | 说明 | 示例 |
---|---|---|
uint | 无符号整数(正数) | uint256 number = 100; |
int | 有符号整数(正负数) | int256 number = -50; |
bool | 布尔值(true/false) | bool isActive = true; |
string | 字符串 | string name = "Web3"; |
address | 以太坊地址 | address owner = msg.sender; |
mapping | 映射(键值对) |
|
contract DataTypes {
uint public myUint = 100; // 只能存正整数
int public myInt = -50; // 允许负数
bool public isActive = true; // 布尔类型
string public myString = "Hello, Web3!"; // 字符串
address public myAddress = msg.sender; // 以太坊地址
}
📌 3. 变量(状态变量 & 局部变量)
contract Variables {
uint public stateVar = 10; // 状态变量(存储在区块链上)
function myFunction() public pure {
uint localVar = 20; // 局部变量(只在函数内部有效)
}
}
✅ 状态变量 👉 stateVar
存储在区块链上(有 Gas 费)
✅ 局部变量 👉 localVar
只在函数内部(不消耗 Gas)
📌 4. 函数
contract MyContract {
uint public myNumber;
// 写入函数(修改状态变量,需要 Gas)
function setNumber(uint _num) public {
myNumber = _num;
}
// 读取函数(view 关键字,不消耗 Gas)
function getNumber() public view returns (uint) {
return myNumber;
}
}
✅ public
👉 允许外部访问
✅ view
👉 只读取数据,不修改状态(不消耗 Gas)
✅ returns (uint)
👉 指定返回值类型
📌 5. 修饰符(modifier
)
contract MyContract {
address public owner;
constructor() {
owner = msg.sender; // 记录合约创建者
}
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_; // 继续执行原函数
}
function setOwner(address _newOwner) public onlyOwner {
owner = _newOwner; // 只有合约创建者可以修改
}
}
✅ modifier onlyOwner()
👉 仅限管理员调用
✅ require(msg.sender == owner, "Not the owner")
👉 检查调用者身份
✅ _;
👉 继续执行原函数
📌 6. 交易 & 以太币(payable
)
contract PaymentContract {
address public owner;
constructor() {
owner = msg.sender;
}
// 允许合约接收 ETH
receive() external payable {}
// 提取合约余额
function withdraw() public {
require(msg.sender == owner, "Not the owner");
payable(owner).transfer(address(this).balance);
}
// 查询合约余额
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
✅ receive() external payable {}
👉 允许合约接收 ETH
✅ payable(owner).transfer(address(this).balance);
👉 提取 ETH
📌 7. 事件(Event)
contract EventExample {
event MessageUpdated(address indexed sender, string oldMessage, string newMessage);
string public message = "Hello, Web3!";
function updateMessage(string memory _newMessage) public {
string memory oldMessage = message;
message = _newMessage;
emit MessageUpdated(msg.sender, oldMessage, _newMessage);
}
}
✅ event MessageUpdated()
👉 定义事件
✅ emit MessageUpdated(msg.sender, oldMessage, _newMessage);
👉 触发事件
📌 8. mapping
(键值对存储)
contract MappingExample {
mapping(address => uint) public balances;
function setBalance(uint _amount) public {
balances[msg.sender] = _amount;
}
function getBalance(address _addr) public view returns (uint) {
return balances[_addr];
}
}
✅ mapping(address => uint)
👉 存储 地址 -> 余额
✅ balances[msg.sender] = _amount;
👉 设置余额
📌 9. struct
(自定义数据类型)
contract StructExample {
struct User {
string name;
uint age;
}
mapping(address => User) public users;
function setUser(string memory _name, uint _age) public {
users[msg.sender] = User(_name, _age);
}
function getUser(address _addr) public view returns (string memory, uint) {
User memory user = users[_addr];
return (user.name, user.age);
}
}
✅ struct User
👉 自定义用户数据结构
✅ mapping(address => User) public users;
👉 存储 地址 -> 用户信息