Example: Governance And Compliance Library

Role-Based Access Control (RBAC) is a fundamental component of our governance framework. It allows organizations to regulate access to network resources based on individual user roles, ensuring that only authorized personnel can perform sensitive operations or access critical data, thereby enhancing security and compliance.

This library can be integrated into a smart contract to ensure that only authorized personnel can access or perform specific actions, aligning with the governance and compliance frameworks of the DePIN system.

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

/**
 * @dev A library to provide governance and compliance functionalities in a DePIN framework.
 */
library GovernanceAndCompliance {

    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    struct GovernanceData {
        mapping(bytes32 => RoleData) roles;
        bytes32 DEFAULT_ADMIN_ROLE;
    }

    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    modifier onlyRole(GovernanceData storage gd, bytes32 role) {
        require(hasRole(gd, role, msg.sender), "GovernanceAndCompliance: Access denied");
        _;
    }

    /**
     * @dev Initialize the default admin role.
     */
    function initialize(GovernanceData storage gd) internal {
        gd.DEFAULT_ADMIN_ROLE = 0x00;
    }

    /**
     * @dev Grants a role to an account.
     * @param role The role to be granted.
     * @param account The account to which the role is granted.
     */
    function grantRole(GovernanceData storage gd, bytes32 role, address account) internal onlyRole(gd, gd.roles[role].adminRole) {
        if (!hasRole(gd, role, account)) {
            gd.roles[role].members[account] = true;
            emit RoleGranted(role, account, msg.sender);
        }
    }

    /**
     * @dev Revokes a role from an account.
     * @param role The role to be revoked.
     * @param account The account from which the role is revoked.
     */
    function revokeRole(GovernanceData storage gd, bytes32 role, address account) internal onlyRole(gd, gd.roles[role].adminRole) {
        if (hasRole(gd, role, account)) {
            gd.roles[role].members[account] = false;
            emit RoleRevoked(role, account, msg.sender);
        }
    }

    /**
     * @dev Checks if an account has a specific role.
     * @param role The role to check.
     * @param account The account to be checked.
     * @return bool True if the account has the role, false otherwise.
     */
    function hasRole(GovernanceData storage gd, bytes32 role, address account) internal view returns (bool) {
        return gd.roles[role].members[account];
    }

    /**
     * @dev Sets a new admin role for a given role.
     * @param role The role for which to set the new admin role.
     * @param adminRole The new admin role.
     */
    function setRoleAdmin(GovernanceData storage gd, bytes32 role, bytes32 adminRole) internal onlyRole(gd, gd.roles[role].adminRole) {
        bytes32 previousAdminRole = gd.roles[role].adminRole;
        gd.roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }
}

Features

  1. Manages permissions based on user roles.

  2. Allows for the assignment and revocation of roles.

  3. Checks if an account holds a specific role.

  4. Emits events for role changes, enhancing transparency and traceability.

Example of Usage:

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

import "./DePINFW/GovernanceAndCompliance.sol";

/**
 * @title DePINAssetManagement
 * @dev A comprehensive smart contract for managing assets in a Decentralized Physical Infrastructure Network (DePIN) with governance and compliance features.
 */
contract DePINAssetManagement {
    using GovernanceAndCompliance for GovernanceAndCompliance.GovernanceData;

    GovernanceAndCompliance.GovernanceData private governanceData;

    struct Asset {
        string name;
        string location;
        uint256 value;
        address owner;
        bool isActive;
    }

    mapping(uint256 => Asset) private assets;
    uint256 private assetCounter;

    event AssetCreated(uint256 indexed assetId, string name, address indexed owner);
    event AssetTransferred(uint256 indexed assetId, address indexed previousOwner, address indexed newOwner);
    event AssetUpdated(uint256 indexed assetId, string name, string location, uint256 value);
    event AssetDeactivated(uint256 indexed assetId);

    modifier onlyAdmin() {
        require(governanceData.hasRole(governanceData.DEFAULT_ADMIN_ROLE, msg.sender), "DePINAssetManagement: Access denied, only admin");
        _;
    }

    modifier onlyAssetOwner(uint256 assetId) {
        require(assets[assetId].owner == msg.sender, "DePINAssetManagement: Access denied, only asset owner");
        _;
    }

    constructor(address initialAdmin) {
        governanceData.initialize();
        governanceData.grantRole(governanceData.DEFAULT_ADMIN_ROLE, initialAdmin);
    }

    /**
     * @dev Function to create a new asset.
     * @param name Name of the asset.
     * @param location Location of the asset.
     * @param value Value of the asset.
     */
    function createAsset(string memory name, string memory location, uint256 value) public onlyAdmin returns (uint256) {
        assetCounter++;
        assets[assetCounter] = Asset(name, location, value, msg.sender, true);
        emit AssetCreated(assetCounter, name, msg.sender);
        return assetCounter;
    }

    /**
     * @dev Function to transfer ownership of an asset.
     * @param assetId ID of the asset.
     * @param newOwner Address of the new owner.
     */
    function transferAsset(uint256 assetId, address newOwner) public onlyAssetOwner(assetId) {
        require(newOwner != address(0), "DePINAssetManagement: New owner is the zero address");
        address previousOwner = assets[assetId].owner;
        assets[assetId].owner = newOwner;
        emit AssetTransferred(assetId, previousOwner, newOwner);
    }

    /**
     * @dev Function to update asset details.
     * @param assetId ID of the asset.
     * @param name New name of the asset.
     * @param location New location of the asset.
     * @param value New value of the asset.
     */
    function updateAsset(uint256 assetId, string memory name, string memory location, uint256 value) public onlyAssetOwner(assetId) {
        Asset storage asset = assets[assetId];
        asset.name = name;
        asset.location = location;
        asset.value = value;
        emit AssetUpdated(assetId, name, location, value);
    }

    /**
     * @dev Function to deactivate an asset.
     * @param assetId ID of the asset.
     */
    function deactivateAsset(uint256 assetId) public onlyAdmin {
        assets[assetId].isActive = false;
        emit AssetDeactivated(assetId);
    }

    /**
     * @dev Function to grant a role to an account.
     * @param role The role to be granted.
     * @param account The account to which the role is granted.
     */
    function grantRole(bytes32 role, address account) public onlyAdmin {
        governanceData.grantRole(role, account);
    }

    /**
     * @dev Function to revoke a role from an account.
     * @param role The role to be revoked.
     * @param account The account from which the role is revoked.
     */
    function revokeRole(bytes32 role, address account) public onlyAdmin {
        governanceData.revokeRole(role, account);
    }

    /**
     * @dev Function to set a new admin role for a given role.
     * @param role The role for which to set the new admin role.
     * @param adminRole The new admin role.
     */
    function setRoleAdmin(bytes32 role, bytes32 adminRole) public onlyAdmin {
        governanceData.setRoleAdmin(role, adminRole);
    }

    /**
     * @dev Function to check if an account has a specific role.
     * @param role The role to check.
     * @param account The account to be checked.
     * @return bool True if the account has the role, false otherwise.
     */
    function hasRole(bytes32 role, address account) public view returns (bool) {
        return governanceData.hasRole(role, account);
    }

    /**
     * @dev Function to get asset details.
     * @param assetId ID of the asset.
     * @return Asset details including name, location, value, owner, and status.
     */
    function getAssetDetails(uint256 assetId) public view returns (string memory, string memory, uint256, address, bool) {
        Asset memory asset = assets[assetId];
        return (asset.name, asset.location, asset.value, asset.owner, asset.isActive);
    }

    /**
     * @dev Function to get the total number of assets.
     * @return uint256 Total number of assets.
     */
    function getTotalAssets() public view returns (uint256) {
        return assetCounter;
    }
}

Explanation

  1. Governance and Compliance Integration: The DePINAssetManagement contract uses the GovernanceAndCompliance library to handle role-based access control, ensuring only authorized users can perform specific actions.

  2. Asset Management: The contract includes functions to create, transfer, update, and deactivate assets, maintaining a comprehensive record of asset ownership and status.

  3. Events: Events are emitted for significant actions like asset creation, transfer, updates, and deactivation, enhancing transparency and enabling easy tracking of changes.

  4. Modifiers: Modifiers are used to enforce role-based access control and ensure only authorized users can execute certain functions.

  5. Ownership and Administration: The contract includes functions to manage roles, allowing for dynamic administration and ensuring compliance with governance protocols.

This contract demonstrates a robust implementation for managing physical infrastructure assets within a DePIN framework, ensuring governance and compliance are maintained through the use of the provided library.

Last updated