How to create identity authentication?

I want to authenticate the user in access control, first check whether the user has the role, if has,success, if not, failed.
If a user fails more than three times, he is blacklisted.

:computer: Environment

:memo:Details

I keep try and try,there always has error,please help me figure out…thank you :grinning:
:1234: Code to reproduce

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract MyContract is Ownable,AccessControl {

    struct Person {
        address adr;
        int count;
    }

    mapping(address => Person) public illegalBehavior;

    event Successful(address account);
    event Failed(address account);

    constructor() public {
    _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}

    function checkUser(bytes32 role,address _account) public{
        if(_roles[role].members.contains(_account)){
            emit Successful(_account);
        }else{
            emit Failed(_account);
            illegalBehavior[_account].adr = _account;
            illegalBehavior[_account].count += 1;
            while(illegalBehavior[_account].count>3){
                emit Blacklisted(address _account);
        }
        }

    }
}
1 Like

Hi @wangyuyue,

The contract you provided didn’t compile.

I made some minor modifications to get it to compile and to work.
Though the code as is counts failures for an address for any role.

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract MyContract is Ownable, AccessControl {
    struct Person {
        address adr;
        int256 count;
    }

    mapping(address => Person) public illegalBehavior;

    event Successful(address account);
    event Failed(address account);
    event Denied(address account);

    bytes32 public constant SPECIAL_ROLE = keccak256("SPECIAL_ROLE");

    constructor() public {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }

    function checkUser(bytes32 role, address account) public {
        if (hasRole(role, msg.sender)) {
            emit Successful(account);
        } else {
            emit Failed(account);
            illegalBehavior[account].adr = account;
            illegalBehavior[account].count += 1;
            if (illegalBehavior[account].count > 3) {
                emit Denied(account);
            }
        }
    }
}

Doing a manual test, on the fourth attempt Denied is emitted.

$ npx oz send-tx
? Pick a network development
? Pick an instance MyContract at 0xD833215cBcc3f914bD1C9ece3EE7BF8B14f841bb
? Select which function checkUser(role: bytes32, account: address)
? role: bytes32: 0x3f12a51c1a5d4235e47a0365ddc220be1678ccffcdf71bfd6ee9c417f801e008
? account: address: 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0
✓ Transaction successful. Transaction hash: 0x5fa4fbbaa30b441dfcc75ef0bf5bef77e5e6bf394ab688841477849638a7f01f
Events emitted:
 - Failed(0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0)
 - Denied(0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0)

There has a error,when input correct account and role ,it still return Failed.
I've tried it a few times before, and I've always gotten Failed.

$ npx oz send-tx
? Pick a network development
? Pick an instance MyContract at 0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab
? Select which function checkUser(role: bytes32, account: address)
? role: bytes32: 0x3f12a51c1a5d4235e47a0365ddc220be1678ccffcdf71bfd6ee9c417f801e
008
? account: address: 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0
✓ Transaction successful. Transaction hash: 0xd8aadac5ec2d04cdaaea061db41dc4228430e44028693ddf19c41e691d581ccf
Events emitted:

  • Failed(0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0)
1 Like

It is figure out ,change msg.sender into address ,
successful !!! thank you

1 Like

Hi @wangyuyue,

Glad you were able to resolve. I hadn’t tested the success path so still had msg.sender.

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract MyContract is Ownable, AccessControl {
    struct Person {
        address adr;
        int256 count;
    }

    mapping(address => Person) public illegalBehavior;

    event Successful(address account);
    event Failed(address account);
    event Denied(address account);

    bytes32 public constant SPECIAL_ROLE = keccak256("SPECIAL_ROLE");

    constructor() public {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }

    function checkUser(bytes32 role, address account) public {
        if (hasRole(role, account)) {
            emit Successful(account);
        } else {
            emit Failed(account);
            illegalBehavior[account].adr = account;
            illegalBehavior[account].count += 1;
            if (illegalBehavior[account].count > 3) {
                emit Denied(account);
            }
        }
    }
}
1 Like