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.
Environment
Details
I keep try and try,there always has error,please help me figure out…thank you
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