This project demonstrates access token approach for control call rights different contract-functions.
Main goal of the project is to provide easy common call access control over different contracts-functions for one project or many projects for any users.
contract1-{func1, func2 ... funcX} -------> \
contract2-{func1, func2 ... funcY} -------> \ --> Access.sol
... /
contractY-{func1, func2 ... funcZ} -------> /
Access grant realized by owning ERC721 token. Every token is one access role.
+------+ --------------------
|NFT_01| --> / Role of Some Action /
+------+ --------------------
+------+ -----------------------
|NFT_02| --> / Role of Another Action /
+------+ -----------------------
User can owns some different token roles at once and get access for role allowed function.
+------+
|NFT_01|
+------+
O / +------+ --------------- || contrac1.func1 ||
-|- --> ----- |NFT_02| -- / Role of Action / ---> || contrac1.func2 ||
/ \ \ +------+ --------------- || contrac2.func1 ||
Alice +------+
|NFT_03|
+------+
Contract-function can be bound with different roles at once.
--------------------
/ Role of Some Action /
/ --------------------
|| contrac1.func2 || -->
\
-----------------------
/ Role of Another Action /
-----------------------
Every role represented by bit in 256 bits (32 bytes) access vector. There are 256 roles at access smart contract. Access is granted by matching user access role bits and bound function role bits
O Role Action1 [NFT_01]
-|- | Role Action2 [NFT_02]
/ \ | |
Alice [1 0 0 ................ 1]
|
<match>
|
|| contrac1.func2 || [1 0 0 ................ 0]
|
--------------------
/ Role of Some Action /
--------------------
import "./interface/IAccess.sol";
...
// access modifier
modifier onlyAccess(bytes4 selector) {
access.checkAccess(msg.sender, address(this), selector);
_;
}
...
// use access modifier with function selector parameter
function func1(uint256 someValue)
external
onlyAccess(this.func1.selector)
{
//some code
}
function addRole(string memory roleName)
* roleName string stored as fixed length type bytes32, so use short names to fit 32 characters (UTF-8 strings)
struct RoleData {
address target;
bytes4 selector;
uint8 roleId;
}
function bindRole(RoleData calldata role) external onlyOwner
or for multiple roles
function bindRoles(RoleData[] calldata RoleDatas) external onlyOwner
function grantRole(address user, uint8 roleId, false)
function grantRole(address user, uint8 roleId, true)
// {IERC721-transferFrom}
function transferFrom(address from, address to, uint256 tokenId)
function burn(uint256 tokenId)
function burn(uint256 tokenId)
function burnToken(uint256 tokenId)
function changeTokenTransferability(uint256 tokenId, bool isNonTransferable)
function changeBatchTokenTransferability(TokenTransferability[] calldata tokens)
npx hardhat compile
npx hardhat test
Some access tokens with different granted roles
Role id 0
- Role name Role for some sensitive action
Role id 1
- Role name Role for public action, is safe
Role id 2
- Role name Maintainer action role, settings
https://opensea.io/assets/matic/0x8a58b0547f8391ae7380bd25383d055fc85fd8e9