slogan3

Implementeer Role-Based Access Control (RBAC) in Solidity Smart Contracts

description

Met deze prompt kan de gebruiker veilige en onderhoudbare Solidity smart contracts bouwen door fijnmazige toegangscontrole te implementeren. Het lost het veelvoorkomende probleem van ongeautoriseerde contractinteracties op en verhoogt de contractbeveiliging. Vergeleken met algemene contractontwerp-prompts richt het zich specifiek op permissiebeheer, een cruciaal aspect voor veel gedecentraliseerde applicaties.

prompt

Help me een Solidity smart contract te maken dat rolgebaseerde toegangscontrole implementeert. Voeg functies toe zoals het definiëren van rollen, het toewijzen en intrekken van rollen aan adressen, en het beperken van functie-toegang op basis van rollen. Leg uit hoe ik OpenZeppelin's AccessCo ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Hier is een voorbeeld van een Solidity smart contract dat rolgebaseerde toegangscontrole (RBAC) implementeert met behulp van OpenZeppelin's AccessControl. Dit contract definieert drie rollen: ADMIN, MINTER en standaardgebruiker. Het bevat functies voor het toewijzen en intrekken van rollen, en functies zoals mint en burn die alleen door bepaalde rollen kunnen worden uitgevoerd. **Stap 1: Installatie van OpenZeppelin's Contracts** Zorg dat je OpenZeppelin Contracts hebt geïnstalleerd via npm: ```bash npm install @openzeppelin/contracts ``` **Stap 2: Solidity Contract** ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/AccessControl.sol"; contract MyToken is AccessControl { // Definieer rollen met keccak256 hashes bytes32 public constant ADMIN_ROLE = keccak256("ADMIN"); bytes32 public constant MINTER_ROLE = keccak256("MINTER"); // Balansen van adressen mapping(address => uint256) private balances; // Events event Transfer(address indexed from, address indexed to, uint256 amount); event Mint(address indexed to, uint256 amount); event Burn(address indexed from, uint256 amount); event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); constructor() { // Geef de deployer de ADMIN en MINTER rollen _setupRole(ADMIN_ROLE, msg.sender); _setupRole(MINTER_ROLE, msg.sender); // Verhoog het admin van alle rollen naar de DEFAULT_ADMIN_ROLE _setRoleAdmin(ADMIN_ROLE, DEFAULT_ADMIN_ROLE); _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE); } // Modifier om te controleren op ADMIN rol modifier onlyAdmin() { require(hasRole(ADMIN_ROLE, msg.sender), "Geen admin rechten"); _; } // Modifier om te controleren op MINTER rol modifier onlyMinter() { require(hasRole(MINTER_ROLE, msg.sender), "Geen minter rechten"); _; } // Functie om rollen toe te wijzen function grantRole(bytes32 role, address account) public onlyAdmin { grantRole(role, account); } // Functie om rollen in te trekken function revokeRole(bytes32 role, address account) public onlyAdmin { revokeRole(role, account); } // Mint functie, alleen toegankelijk voor MINTERS function mint(address to, uint256 amount) public onlyMinter { balances[to] += amount; emit Mint(to, amount); emit Transfer(address(0), to, amount); } // Burn functie, alleen toegankelijk voor adressen met voldoende balans function burn(uint256 amount) public { require(balances[msg.sender] >= amount, "Onvoldoende balans"); balances[msg.sender] -= amount; emit Burn(msg.sender, amount); emit Transfer(msg.sender, address(0), amount); } // Lees saldo van een adres function balanceOf(address account) public view returns (uint256) { return balances[account]; } } ``` --- ### Uitleg - **AccessControl** van OpenZeppelin wordt gebruikt voor rolbeheer. - **Rollen** worden gedefinieerd met `keccak256` hashes: `ADMIN_ROLE`, `MINTER_ROLE`. - De **constructor** geeft de deployer de ADMIN- en MINTER-rollen. - **`grantRole` en `revokeRole`** functies maken het mogelijk rollen toe te wijzen en in te trekken, maar alleen door een **ADMIN**. - **`mint`** kan alleen door adressen met de MINTER-rol worden uitgevoerd. - **`burn`** wordt door de eigenaar zelf uitgevoerd en vermindert hun eigen balans. - Rollen kunnen worden beheerd via de functies en zorgen voor een veilige rol-gebaseerde permissie. --- ### Hoe gebruik je dit contract? 1. Deploy het contract. 2. Verleen extra rollen aan adressen met `grantRole`. 3. Alleen adressen met de juiste rollen kunnen minten of andere beheertaken uitvoeren. 4. Rollen kunnen worden ingetrokken of toegekend via de bijbehorende functies. --- Als je liever je eigen RBAC-systeem wilt implementeren zonder OpenZeppelin, kun je bijvoorbeeld een `mapping(bytes32 => mapping(address => bool))` gebruiken om rollen bij te houden en eigen functies schrijven voor toewijzen, intrekken en controle. Maar OpenZeppelin biedt een veilige en beproefde basis voor dit soort functionaliteit.
provider: deepseek
model: deepseek-chat
Zeker! Ik help je met het maken van een Solidity smart contract met rolgebaseerde toegangscontrole. Ik zal beide benaderingen uitleggen: gebruik van OpenZeppelin's AccessControl en een eenvoudige eigen implementatie. ## Optie 1: Gebruik van OpenZeppelin AccessControl (Aanbevolen) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MyTokenWithRBAC is ERC20, AccessControl { // Definieer rol constants als bytes32 bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); constructor() ERC20("MyToken", "MTK") { // Stel de deployer in als de eerste admin _grantRole(ADMIN_ROLE, msg.sender); // ADMIN_ROLE kan MINTER_ROLE en BURNER_ROLE beheren _setRoleAdmin(MINTER_ROLE, ADMIN_ROLE); _setRoleAdmin(BURNER_ROLE, ADMIN_ROLE); } // Mint functie - alleen voor MINTER_ROLE function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { _mint(to, amount); } // Burn functie - alleen voor BURNER_ROLE function burn(address from, uint256 amount) external onlyRole(BURNER_ROLE) { _burn(from, amount); } // Admin functie om rollen toe te wijzen function assignRole(bytes32 role, address account) external onlyRole(ADMIN_ROLE) { grantRole(role, account); } // Admin functie om rollen in te trekken function revokeRole(bytes32 role, address account) external onlyRole(ADMIN_ROLE) { revokeRole(role, account); } // Hulpfunctie om rollen te controleren function hasRole(bytes32 role, address account) public view override returns (bool) { return super.hasRole(role, account); } } ``` ## Optie 2: Eigen RBAC Implementatie ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract CustomRBAC { // Rol definities string public constant ADMIN = "ADMIN"; string public constant MINTER = "MINTER"; string public constant BURNER = "BURNER"; // Eigenaar van het contract address public owner; // Mapping van adres naar rollen mapping(address => mapping(string => bool)) private roles; // Events voor transparantie event RoleGranted(string indexed role, address indexed account, address indexed sender); event RoleRevoked(string indexed role, address indexed account, address indexed sender); modifier onlyOwner() { require(msg.sender == owner, "Alleen eigenaar"); _; } modifier onlyRole(string memory role) { require(hasRole(role, msg.sender), "Toegang geweigerd: rol vereist"); _; } constructor() { owner = msg.sender; // Stel de eigenaar in als admin _grantRole(ADMIN, msg.sender); } // Rol toewijzen (alleen voor admins) function grantRole(string memory role, address account) external onlyRole(ADMIN) { _grantRole(role, account); } // Rol intrekken (alleen voor admins) function revokeRole(string memory role, address account) external onlyRole(ADMIN) { _revokeRole(role, account); } // Interne functie voor roltoewijzing function _grantRole(string memory role, address account) internal { roles[account][role] = true; emit RoleGranted(role, account, msg.sender); } // Interne functie voor rolintrekking function _revokeRole(string memory role, address account) internal { roles[account][role] = false; emit RoleRevoked(role, account, msg.sender); } // Controleer of adres een rol heeft function hasRole(string memory role, address account) public view returns (bool) { return roles[account][role]; } // Voorbeeld functies met rolbeperkingen function mint() external onlyRole(MINTER) { // Mint logica hier } function burn() external onlyRole(BURNER) { // Burn logica hier } // Admin-only functie voor beheer function adminFunction() external onlyRole(ADMIN) { // Admin-specifieke logica } } ``` ## Gebruiksvoorbeelden en Implementatie ### 1. Contract Deployen ```javascript // Na deployen heeft de deployer automatisch ADMIN_ROLE const contract = await MyTokenWithRBAC.deploy(); ``` ### 2. Rollen Toewijzen ```javascript // Als admin, wijs MINTER_ROLE toe aan een adres await contract.assignRole(contract.MINTER_ROLE, "0x123..."); // Of gebruik de OpenZeppelin functie direct await contract.grantRole(contract.MINTER_ROLE, "0x123..."); ``` ### 3. Rollen Controleren ```javascript // Check of een adres een rol heeft const hasMinterRole = await contract.hasRole(contract.MINTER_ROLE, "0x123..."); ``` ### 4. Beveiligde Functies Gebruiken ```solidity // Alleen MINTER_ROLE kan deze functie aanroepen function mintTokens(address to, uint256 amount) public onlyRole(MINTER_ROLE) { // Mint logica } // Alleen BURNER_ROLE kan deze functie aanroepen function burnTokens(address from, uint256 amount) public onlyRole(BURNER_ROLE) { // Burn logica } ``` ## Aanbevelingen en Best Practices 1. **Gebruik OpenZeppelin AccessControl** - Dit is de veiligste en meest geteste aanpak 2. **Role Hierarchie** - Stel in dat ADMIN_ROLE andere rollen kan beheren 3. **Events** - Log alle rolwijzigingen voor transparantie 4. **Access Control Checks** - Voer checks uit aan het begin van functies 5. **Minimal Privilege** - Geef alleen de benodigde rechten ## Installatie OpenZeppelin ```bash npm install @openzeppelin/contracts ``` De OpenZeppelin implementatie is aanbevolen omdat deze: - Uitgebreid getest en geaudit is - Gas-efficient is - Standaard ERC-165 ondersteuning heeft - Flexibele rolhiërarchie ondersteunt Heb je nog specifieke vragen over de implementatie?