Solidity 角色管理系统开发指南

一、基础角色控制合约

1. 最简单的管理员权限控制

solidity
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract BasicRoleControl {
    address public admin;
    mapping(address => bool) public isManager;

    constructor() {
        admin = msg.sender; // 部署者设为管理员
    }

    // 修饰器:仅管理员可调用
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // 添加管理员
    function addManager(address _manager) external onlyAdmin {
        isManager[_manager] = true;
    }

    // 移除管理员
    function removeManager(address _manager) external onlyAdmin {
        isManager[_manager] = false;
    }
}

2. 实际应用案例:资金保险柜

solidity
复制
contract Vault is BasicRoleControl {
    uint256 public totalFunds;

    // 存款功能:所有人可用
    function deposit() external payable {
        totalFunds += msg.value;
    }

    // 提款功能:仅管理员可用
    function withdraw(uint256 _amount) external onlyAdmin {
        require(_amount <= totalFunds, "Insufficient balance");
        payable(msg.sender).transfer(_amount);
        totalFunds -= _amount;
    }
}

二、多角色管理系统

1. 支持多种角色的进阶版本

solidity
复制
contract MultiRoleSystem {
    enum Role { NONE, ADMIN, FINANCE, AUDITOR }

    mapping(address => Role) public userRoles;

    constructor() {
        userRoles[msg.sender] = Role.ADMIN; // 初始化管理员
    }

    // 通用角色检查修饰器
    modifier onlyRole(Role _requiredRole) {
        require(userRoles[msg.sender] == _requiredRole, "Permission denied");
        _;
    }

    // 角色分配功能(仅管理员可用)
    function assignRole(address _user, Role _role) external onlyRole(Role.ADMIN) {
        userRoles[_user] = _role;
    }

    // 财务专用功能
    function financialReport() external onlyRole(Role.FINANCE) {
        // 生成财务报告的逻辑
    }

    // 审计专用功能
    function auditCheck() external onlyRole(Role.AUDITOR) {
        // 执行审计检查的逻辑
    }
}

三、Gas优化技巧

1. 使用位掩码实现高效权限管理

solidity
复制
contract BitmaskRoles {
    // 权限定义(使用二进制位)
    uint8 constant CAN_MINT = 1 << 0; // 00000001
    uint8 constant CAN_BURN = 1 << 1; // 00000010
    uint8 constant CAN_TRADE = 1 << 2; // 00000100

    mapping(address => uint8) public permissions;

    // 设置权限
    function setPermissions(address _user, uint8 _perms) external {
        require(_user != address(0), "Invalid address");
        permissions[_user] = _perms;
    }

    // 权限检查修饰器
    modifier hasPermission(uint8 _required) {
        require(permissions[msg.sender] & _required == _required, 
                "Missing permission");
        _;
    }

    function mintToken() external hasPermission(CAN_MINT) {
        // 铸币逻辑
    }

    function burnToken() external hasPermission(CAN_BURN) {
        // 销毁逻辑
    }
}

四、最佳实践建议

  1. 最小权限原则:仅授予必要权限

  2. 事件日志记录:记录关键权限变更

    solidity
    复制
    event RoleChanged(address indexed user, string role, bool status);
  3. 权限回收机制:添加权限有效期检查

  4. 多签验证:重要操作需多地址确认

  5. 使用成熟库:推荐 OpenZeppelin 的 AccessControl 合约


五、完整示例:NFT 铸造权限控制

solidity
复制
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract ControlledNFT is ERC721 {
    address public admin;
    mapping(address => bool) public minters;

    constructor() ERC721("ControlledNFT", "CNFT") {
        admin = msg.sender;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "Admin only");
        _;
    }

    function addMinter(address _minter) external onlyAdmin {
        minters[_minter] = true;
    }

    modifier onlyMinter() {
        require(minters[msg.sender], "Minter only");
        _;
    }

    function safeMint(address to, uint256 tokenId) external onlyMinter {
        _safeMint(to, tokenId);
    }
}

通过以上代码示例,您可以快速实现以下功能:

  • 基础权限分层管理

  • 多角色协同控制

  • 高效权限验证机制

  • 实际业务场景整合

建议在 Remix IDE 中测试这些合约,并通过单元测试验证权限逻辑的正确性。实际部署前请务必进行安全审计。

posted @ 2025-03-26 11:07  若-飞  阅读(62)  评论(0)    收藏  举报