安全最佳实践 #

一、代码规范 #

1.1 命名约定 #

solidity
contract BestPractices {
    // 状态变量:小驼峰
    uint256 public totalSupply;
    address public owner;
    
    // 常量:全大写下划线
    uint256 public constant MAX_SUPPLY = 1000000;
    bytes32 public constant DOMAIN_SEPARATOR = keccak256("...");
    
    // 私有变量:下划线前缀
    uint256 private _balance;
    
    // 事件:大驼峰
    event Transfer(address indexed from, address indexed to, uint256 value);
    
    // 修饰器:小驼峰
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    // 函数:小驼峰
    function transfer(address to, uint256 amount) public returns (bool) {
        return true;
    }
    
    // 内部函数:下划线前缀
    function _validateAddress(address addr) internal pure returns (bool) {
        return addr != address(0);
    }
}

1.2 代码组织 #

solidity
contract CodeOrganization {
    // 1. 状态变量
    uint256 public value1;
    uint256 public value2;
    
    // 2. 事件
    event ValueChanged(uint256 newValue);
    
    // 3. 修饰器
    modifier validValue(uint256 _value) {
        require(_value > 0, "Invalid value");
        _;
    }
    
    // 4. 构造函数
    constructor() {
        value1 = 100;
    }
    
    // 5. 接收函数
    receive() external payable {}
    
    // 6. 回退函数
    fallback() external payable {}
    
    // 7. external函数
    function externalFunction() external pure returns (uint256) {
        return 1;
    }
    
    // 8. public函数
    function publicFunction() public pure returns (uint256) {
        return 1;
    }
    
    // 9. internal函数
    function internalFunction() internal pure returns (uint256) {
        return 1;
    }
    
    // 10. private函数
    function privateFunction() private pure returns (uint256) {
        return 1;
    }
}

二、安全检查清单 #

2.1 部署前检查 #

检查项 说明
编译器版本 使用最新稳定版本
优化设置 确认优化参数
测试覆盖 确保测试覆盖所有功能
审计报告 获取专业审计
文档完整 确保文档齐全

2.2 代码检查 #

solidity
contract SecurityChecklist {
    // ✓ 使用最新的Solidity版本
    // pragma solidity ^0.8.20;
    
    // ✓ 明确指定可见性
    function transfer(address to, uint256 amount) public returns (bool) {
        return true;
    }
    
    // ✓ 使用NatSpec注释
    /**
     * @notice 转账代币
     * @param to 接收地址
     * @param amount 转账数量
     * @return 是否成功
     */
    function transferWithDocs(address to, uint256 amount) public returns (bool) {
        return true;
    }
    
    // ✓ 检查参数
    function safeTransfer(address to, uint256 amount) public returns (bool) {
        require(to != address(0), "Invalid recipient");
        require(amount > 0, "Invalid amount");
        return true;
    }
    
    // ✓ 使用自定义错误
    error InsufficientBalance(uint256 available, uint256 required);
    
    function withdraw(uint256 amount) public view {
        uint256 balance = 100;
        if (balance < amount) {
            revert InsufficientBalance(balance, amount);
        }
    }
}

三、测试最佳实践 #

3.1 单元测试 #

javascript
const { expect } = require("chai");

describe("Token", function () {
    let token;
    let owner;
    let addr1;
    
    beforeEach(async function () {
        [owner, addr1] = await ethers.getSigners();
        const Token = await ethers.getContractFactory("Token");
        token = await Token.deploy("Test", "TST", 18, 1000000);
    });
    
    it("Should have correct name", async function () {
        expect(await token.name()).to.equal("Test");
    });
    
    it("Should transfer tokens", async function () {
        await token.transfer(addr1.address, 100);
        expect(await token.balanceOf(addr1.address)).to.equal(100);
    });
    
    it("Should fail if insufficient balance", async function () {
        await expect(
            token.connect(addr1).transfer(owner.address, 100)
        ).to.be.reverted;
    });
});

3.2 模糊测试 #

solidity
contract FuzzTest {
    function testAdd(uint256 a, uint256 b) public pure {
        uint256 result = a + b;
        assert(result >= a);  // 溢出检查
    }
}

四、部署最佳实践 #

4.1 部署脚本 #

javascript
const { ethers } = require("hardhat");

async function main() {
    const Token = await ethers.getContractFactory("Token");
    
    console.log("Deploying Token...");
    const token = await Token.deploy("Test", "TST", 18, 1000000);
    await token.deployed();
    
    console.log("Token deployed to:", token.address);
    
    // 验证合约
    await hre.run("verify:verify", {
        address: token.address,
        constructorArguments: ["Test", "TST", 18, 1000000],
    });
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});

4.2 部署检查 #

solidity
contract DeploymentCheck {
    address public owner;
    bool public initialized;
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    modifier onlyOnce() {
        require(!initialized, "Already initialized");
        _;
    }
    
    constructor() {
        owner = msg.sender;
    }
    
    function initialize() public onlyOwner onlyOnce {
        initialized = true;
        // 初始化逻辑
    }
}

五、监控与维护 #

5.1 事件监控 #

solidity
contract MonitoredContract {
    event CriticalOperation(address indexed operator, uint256 amount);
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
    
    function criticalOperation(uint256 amount) public {
        // 操作逻辑
        emit CriticalOperation(msg.sender, amount);
    }
}

5.2 紧急响应 #

solidity
contract EmergencyResponse {
    address public owner;
    bool public paused;
    
    event EmergencyShutdown(address indexed operator, uint256 timestamp);
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    function emergencyShutdown() public onlyOwner {
        paused = true;
        emit EmergencyShutdown(msg.sender, block.timestamp);
    }
    
    function recoverFunds() public onlyOwner {
        payable(owner).transfer(address(this).balance);
    }
}

六、总结 #

最佳实践要点:

类别 要点
代码规范 命名、组织、注释
安全检查 部署前、代码检查
测试 单元测试、模糊测试
部署 脚本、验证、检查
维护 监控、紧急响应

接下来,让我们学习开发框架!

最后更新:2026-03-27