For my Master's thesis, I am trying to create a decentralized file storage system using ethereum, solidity and ipfs. I want to code the smart contract with attribute-based access control but do not have much knowledge on this. Most of the links I have seen so far are of role-based access control. Could someone please guide me with a few links or a simple code explanation?


Attribute-Based Access Control (ABAC) is all about the attributes (or characteristics) of a user. For e.g., you may only allow users owning 100+ tokens to vote to decide whether an ERC-20 based token should be migrated to its own blockchain. Other attributes could be external data like IP address (or its geo-location) used to issue a transaction (as verified by an oracle), user category (as specified in a registry contract), or off-chain secret (proved using a hash or zero-knowledge proof).

What matter is you specify how these attributes should be validated within your smart contract. For e.g. Ether balance can be checked like,

if (address.balance >= 100){
    can_vote = true;

If it's ERC-20 use balanceOf(account) >= 100

A simple, but more detailed example is available at https://blockgeeks.com/introduction-to-solidity-acl-and-events-part-2/


Maybe something like this:

A library:

library Roles {
    enum Flag {

    function isAuthorizedToRole1(uint256 _flags) internal pure returns (bool) {return isAuthorized(_flags, Flag.Role1);}
    function isAuthorizedToRole2(uint256 _flags) internal pure returns (bool) {return isAuthorized(_flags, Flag.Role2);}
    function isAuthorizedToRole3(uint256 _flags) internal pure returns (bool) {return isAuthorized(_flags, Flag.Role3);}
    function isAuthorized(uint256 _flags, Flag _flag) private pure returns (bool) {return ((_flags >> uint256(_flag)) & 1) == 1;}

A contract:

contract Users {
    address public owner;
    mapping(address => uint256) public roles;

    constructor() {
        owner = msg.sender;

    function getRole(address _user) external view returns (uint256) {
        return roles[_user];

    function setRole(address _user, uint256 _role) external {
        require(msg.sender == owner, "illegal caller");
        roles[_user] = _role;

Then, any other contract can utilize the above in order to manage access-control; for example:

contract Manager {
    using Roles for uint256;

    Users public users;

    constructor(Users _users) public {
        users = _users;

    function isAuthorizedToRole1(address _user) external view returns (bool) {
        return users.getRole(_user).isAuthorizedToRole1();

    function isAuthorizedToRole2(address _user) external view returns (bool) {
        return users.getRole(_user).isAuthorizedToRole2();

    function isAuthorizedToRole3(address _user) external view returns (bool) {
        return users.getRole(_user).isAuthorizedToRole3();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.