我想用openzeppelin的AccessControl实现一个白名单。假设我有以下设置:
合同A:它正在做一些事情,但只对那些被白名单的用户。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract ContractA is ERC20, Ownable {
address _whitelist;
constructor(
address whitelist,
) ERC20("ContractA", "CTRCT") {
_whitelist = whitelist;
...
}
function checkRoleWithDelegateCall(address someUser) public returns (bool) {
(bool success, bytes memory result) = _whitelist.delegatecall(abi.encodeWithSignature("hasRole(bytes32,address)", "ROLE_WHITELIST", someUser));
return abi.decode(result, (bool));
}
function doSomething(address[] memory someUsers) public onlyOwner {
// Abort the transaction if a chosen user is not on the whitelist.
for(uint256 i = 0; i < recipients.length; i++) {
require(checkRoleWithDelegateCall(recipients[i]), "At least one recipient is not on the whitelist");
}
<<some irrelevant code >>
}}合同白名单:它管理白名单,也就是说,它存储用户是否在白名单上:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Whitelist is AccessControl, Ownable {
// Create a new role that allows accounts with that role to trade bonds
bytes32 public constant ROLE_WHITELIST = keccak256("ROLE_WHITELISTE");
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function grantWhitelistingRole(address[] memory someUsers) public onlyRole(DEFAULT_ADMIN_ROLE) {
bytes32 role = BOND_WHITELISTED_ROLE;
for (uint i=0; i<accounts.length; i++) {
grantRole(role, accounts[i]);
}
}}我首先部署白名单契约,并将其地址传递给ContractA的部署。然后,我将ROLE_WHITELIST授予userA,它根据我所做的测试工作。但是,当我用硬帽子测试doSomething函数时,它就不起作用了:契约A不将userA解释为拥有ROLE_WHITELIST,并从require语句返回“至少有一个收件人不在白名单上”。
可以这样做吗?如果没有,那么更好的方法是什么呢?
提前感谢!
发布于 2023-01-31 14:09:16
问题在于Keccak-256散列: ROLE_WHITELIST必须作为ROLE_WHITELIST =keccak256("ROLE_WHITELIST")在checkRoleWithDelegateCall中使用。
https://ethereum.stackexchange.com/questions/143998
复制相似问题