智能合约 ✅ 验证通过
Solidity = 以太坊智能合约的官方语言,由Gavin Wood提出,Christian Reitwiessner主导开发。它是静态类型、面向合约的高级语言,编译后运行在EVM上。
pragma solidity ^0.8.19; — 0.8.19 ≤ version < 0.9.0pragma solidity >=0.8.0 <0.9.0; — 精确范围pragma solidity 0.8.19; — 固定版本(推荐生产环境)// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/// @title 计数器合约 - Solidity基础完整示例
/// @author Web3课程
/// @notice 实现计数、权限管理、ETH接收功能
contract Counter {
// ===== 状态变量 =====
uint256 private _count;
address public owner;
uint256 public lastModified;
uint256 public totalDeposits;
// ===== 事件 =====
event CountIncremented(uint256 newCount, address indexed caller);
event CountDecremented(uint256 newCount, address indexed caller);
event CountReset(address indexed caller);
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
event DepositReceived(address indexed from, uint256 amount);
// ===== 自定义错误 =====
error Unauthorized(address caller, address required);
error CountAlreadyZero();
error ZeroAddress();
// ===== 修饰符 =====
modifier onlyOwner() {
if (msg.sender != owner) {
revert Unauthorized(msg.sender, owner);
}
_;
}
modifier countNotZero() {
if (_count == 0) revert CountAlreadyZero();
_;
}
// ===== 构造函数 =====
constructor() {
owner = msg.sender;
_count = 0;
lastModified = block.timestamp;
}
// ===== 读函数 (view - 不消耗Gas) =====
function getCount() public view returns (uint256) {
return _count;
}
function getContractBalance() public view returns (uint256) {
return address(this).balance;
}
function getTimeSinceLastModify() public view returns (uint256) {
return block.timestamp - lastModified;
}
// ===== 写函数 (消耗Gas) =====
function increment() public {
_count += 1;
lastModified = block.timestamp;
emit CountIncremented(_count, msg.sender);
}
function decrement() public countNotZero {
_count -= 1;
lastModified = block.timestamp;
emit CountDecremented(_count, msg.sender);
}
function reset() public onlyOwner {
_count = 0;
lastModified = block.timestamp;
emit CountReset(msg.sender);
}
function batchIncrement(uint256 times) public {
require(times > 0 && times <= 100, "Times must be 1-100");
for (uint256 i = 0; i < times; i++) {
_count += 1;
}
lastModified = block.timestamp;
emit CountIncremented(_count, msg.sender);
}
// ===== 特殊函数 =====
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner == address(0)) revert ZeroAddress();
address oldOwner = owner;
owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
// ===== 接收ETH =====
receive() external payable {
totalDeposits += msg.value;
emit DepositReceived(msg.sender, msg.value);
}
fallback() external payable {
totalDeposits += msg.value;
}
// ===== 提取函数 =====
function withdraw() public onlyOwner {
uint256 balance = address(this).balance;
(bool success, ) = payable(owner).call{value: balance}("");
require(success, "Withdrawal failed");
}
}
// ✅ 验证通过 - Remix IDE编译部署测试
| 可见性 | 合约内部 | 继承合约 | 外部调用 | 默认 | 说明 |
|---|---|---|---|---|---|
| public | ✅ | ✅ | ✅ | 函数默认 | 最开放,任何地方可调用 |
| external | ❌ | ❌ | ✅ | — | 仅外部调用,Gas更低 |
| internal | ✅ | ✅ | ❌ | 状态变量默认 | 合约内部+子合约可访问 |
| private | ✅ | ❌ | ❌ | — | 仅本合约内部 |
| 关键字 | 读状态 | 写状态 | 外部调用Gas | 说明 |
|---|---|---|---|---|
| view | ✅ | ❌ | 免费 | 只读,不修改任何状态 |
| pure | ❌ | ❌ | 免费 | 纯计算,不读也不写 |
| 无修饰 | ✅ | ✅ | 需要Gas | 可读写状态 |
| payable | ✅ | ✅ | 需要Gas | 可接收ETH |
1. Solidity合约的构造函数在什么时候执行?
2. view和pure函数的核心区别?
3. Solidity中private变量的数据是否真的私有?
4. calldata相比memory的优势?
5. modifier中的 _; 代表什么?
你已迈出智能合约开发第一步——从合约结构到函数可见性到数据位置!
这是构建Web3应用的基石。
✅ 合约结构 ✅ 函数可见性 ✅ 状态可变性 ✅ 数据位置