You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
eip: 1480
title: Modular Access Control Mechanism
author: Matan Tsuberi [email protected], Ben Kaufman [email protected], Adam Levi [email protected], Oren Sokolowsky [email protected]
discussions-to:
status: Draft
type: Standards Track
category: ERC
created: 2018-10-08
requires: 165
Simple Summary
Standard access control mechanism for smart contracts.
Abstract
This EIP presents a generalized mechanism for access control on smart contracts, enabling the use of complex boolean expressions for limiting access to contract's functions. The mechanism utilizes the idea of "keys" for the access limitations. Keys could be transferable, expirable, limited to certain amount of uses or limited to certain fucntion parameters use.
Motivation
Access control is one of the basic components most smart contract applications and frameworks need to have. The ability to limit the access for calling a function to a specific EOA or smart contract account is vital for most systems. The core logic for the access control of a smart contract has a great importance as it is usually the main security risk a contract may have, and if compromised, it can cause fatal issue for the entire system.
There is a vast number of use cases requiring access management for smart contracts. A few popular examples can be:
Ownable - This is probably the most popular access control mechanism used in the Ethereum space. OpenZeppelin's implementation can be found here.
Membership Management - There are much efforts for managing membership on the Ethereum blockchain. A full detailed rationale for that can be found on EIP-1261 - Membership Verification Token. However, this creates a duplication of effort as membership management is just a single aspect of access control. In addition, the current effort lacks some basic properties such as expiration and transferability of memberships.
DAO operations - There are multiple teams working in the DAO space, all facing the problem of access control in a DAO. Thus, there is a lot of duplicated work on the subject with each having its own pros and cons. However, non of them has found a mechanism generalized enough to answer all possible future needs of DAOs.
There is a strong need for an effective generalized way of managing access rights, most importantly in a trustless manner. We would like to propose a generalized mechanism for access control in smart contracts to provide easier interoperability, reduce security risks, and minimize the duplicated effort of teams working in the subject.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Every ERC-1480 compliant contract MUST implement the ERC1480 and ERC165 interfaces (subject to "caveats" below):
pragma solidity^0.4.24;
/// @title ERC1480Interface - Access Control Interface/// @dev basic inteface for access control mechanism/// Note: the ERC-165 identifier for this interface is 0x33f9cb64.interfaceERC1480Interface {
event AssignKey(
bytes32indexed_id,
addressindexed_from,
addressindexed_to,
bool_assignable,
uint_start,
uint_expiration,
uint_uses
);
event RevokeKey(bytes32indexed_id, addressindexed_owner);
/// @dev assign partial or all capabilities from the sender to an account/// @param _id lock id/// @param _to recipient/// @param _assignable can the recipient further assign capabilities to other accounts?/// @param _start the key's start time (block number)/// @param _expiration the key's expiration time (block number)/// @param _uses number of times this key can be used (in `unlock(..)`)function assignKey(
bytes32_id,
address_to,
bool_assignable,
uint_start,
uint_expiration,
uint_uses
) external;
/// @dev assign all capabilities from the sender to an account/// @param _id lock id/// @param _to recipientfunction assignFullKey(bytes32_id, address_to) external;
/// @dev revoke the sender's key/// @param _id lock idfunction revokeKey(bytes32_id) external;
/// @dev does the owner have a valid key for the lock id/// @param _id lock id/// @param _owner owner addressfunction unlockable(bytes32_id, address_owner) externalviewreturns (bool);
/// @dev does the owner have a valid key for the lock id/// @param _id lock id/// @param _owner owner address/// @return the properties of the requested key as a tuplefunction getKey(bytes32_id, address_owner) externalviewreturns (bool, bool, uint, uint, uint);
}
/// @title ERC1480 - Access Control Interface/// @dev contract for access control mechanismcontractERC1480isERC165, ERC1480Interface {
struct Key {
bool exists;
bool assignable;
uint start;
uint expiration;
uint uses;
}
/// @dev Grant capabilities to account (overwrites existing key)/// @param _id lock id/// @param _to recipient/// @param _assignable can the recipient further assignKey his capabilities to other accounts?/// @param _start the key's start time (block timestamp)/// @param _expiration the key's expiration time (block timestamp)/// @param _uses number of times this key can be used (in `unlock(..)`)function grantKey(
bytes32_id,
address_to,
bool_assignable,
uint_start,
uint_expiration,
uint_uses
) internal;
/// @dev Grant full capabilities to account (assignable, no start time, no expiration, infinite uses)/// @param _id lock id/// @param _to recipientfunction grantFullKey(bytes32_id, address_to) internal;
/// @dev unlock a lock if sender has a valid key./// @param _id lock idfunction unlock(bytes32_id) internalreturns (bool);
}
interfaceERC165 {
/// @notice Query if a contract implements an interface/// @param interfaceID The interface identifier, as specified in ERC-165/// @dev Interface identification is specified in ERC-165. This function/// uses less than 30,000 gas./// @return `true` if the contract implements `interfaceID` and/// `interfaceID` is not 0xffffffff, `false` otherwisefunction supportsInterface(bytes4interfaceID) externalviewreturns (bool);
}
The storage extention is RECOMMENDED for ERC-1480 smart contracts (see "caveats", below). This contains the RECOMMENDED data structure for storing the access "keys".
/// @title ERC1480Storage - Access Control, RECOMMENDED data structurecontractERC1480StorageisERC1480 {
mapping(bytes32=>mapping(address=> Key)) public keys;
}
Caveats
The 0.4.24 Solidity interface grammar is not expressive enough to document the ERC-1480 standard. A contract which complies with ERC-1480 MUST also abide by the following:
Solidity issue 3368: Fixes typo of = instead of == #3412: The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: payable, implicit nonpayable, view, and pure. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a payable function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.24 is that you can edit this interface to add stricter mutability before inheriting from your contract.
Solidity issue Added EIP-2330: EXTSLOAD #2330: If a function is shown in this specification as external then a contract will be compliant if it uses public visibility. As a workaround for version 0.4.20, you can edit this interface to switch to public before inheriting from your contract.
If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.
Rationale
There are many approaches which were developed to create an access control mechanism, but each focuses on a relatively specific use case. We tried to create a generalized mechanism allowing for all uses cases to be implemented, while keeping the gas efficiency similar to a more dedicated solution.
We chose to use the concept of "Keys" with the certain properties of: uses limit, expiration time, and (re-)assignablity. This approach allows the use of complex boolean expressions for limiting access to a function such as allowing an account to call a certain function (or multiple functions) 2 times until the end of next month and possibly assign that right to another account.
A more concrete example could be for "Ownership" of a contract. A common use case for the ("Ownable" contract)[https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol] are "safty backdoors" - functions which enable the "owner" of the contract do controversial changes in crisis times. Most teams promise to eliminate their access to those backdoors after their project gets mature enogh, but this requires to trust the team to stand up for this promise. The "Ownable" contract pattern, thus, could benefit from the addition of a trustless expiration date, removing the need of trusting the teams to give up on their "safety backdoors" access when their project matures.
The proposed interface contains functions to allow utilizing the full capabilities of the properties of a key. Which are the ability to grant (by the contract), assign to other account, revoke, and use a key. This also keeps the option for implementations to have their own characteristics and suitable behaviour. For example, it is possible for an implementation to use block number for keys expiration, instead of timestamps. For gas optimizations, we also used 0 values to "disable" the use of certain features, this makes keys which doesn't have, for example, expiration time to have similar gas consumption to another solution with no expiration parameter at all.
Backwards Compatibility
There are no backwards compatibility concerns.
Test Cases
DAOstack ERC-1480 implementation includes test cases written using Truffle.
There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.
This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.
eip: 1480
title: Modular Access Control Mechanism
author: Matan Tsuberi [email protected], Ben Kaufman [email protected], Adam Levi [email protected], Oren Sokolowsky [email protected]
discussions-to:
status: Draft
type: Standards Track
category: ERC
created: 2018-10-08
requires: 165
Simple Summary
Standard access control mechanism for smart contracts.
Abstract
This EIP presents a generalized mechanism for access control on smart contracts, enabling the use of complex boolean expressions for limiting access to contract's functions. The mechanism utilizes the idea of "keys" for the access limitations. Keys could be transferable, expirable, limited to certain amount of uses or limited to certain fucntion parameters use.
Motivation
Access control is one of the basic components most smart contract applications and frameworks need to have. The ability to limit the access for calling a function to a specific EOA or smart contract account is vital for most systems. The core logic for the access control of a smart contract has a great importance as it is usually the main security risk a contract may have, and if compromised, it can cause fatal issue for the entire system.
There is a vast number of use cases requiring access management for smart contracts. A few popular examples can be:
Ownable - This is probably the most popular access control mechanism used in the Ethereum space. OpenZeppelin's implementation can be found here.
Membership Management - There are much efforts for managing membership on the Ethereum blockchain. A full detailed rationale for that can be found on EIP-1261 - Membership Verification Token. However, this creates a duplication of effort as membership management is just a single aspect of access control. In addition, the current effort lacks some basic properties such as expiration and transferability of memberships.
DAO operations - There are multiple teams working in the DAO space, all facing the problem of access control in a DAO. Thus, there is a lot of duplicated work on the subject with each having its own pros and cons. However, non of them has found a mechanism generalized enough to answer all possible future needs of DAOs.
There is a strong need for an effective generalized way of managing access rights, most importantly in a trustless manner. We would like to propose a generalized mechanism for access control in smart contracts to provide easier interoperability, reduce security risks, and minimize the duplicated effort of teams working in the subject.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Every ERC-1480 compliant contract MUST implement the
ERC1480
andERC165
interfaces (subject to "caveats" below):The storage extention is RECOMMENDED for ERC-1480 smart contracts (see "caveats", below). This contains the RECOMMENDED data structure for storing the access "keys".
Caveats
The 0.4.24 Solidity interface grammar is not expressive enough to document the ERC-1480 standard. A contract which complies with ERC-1480 MUST also abide by the following:
=
instead of==
#3412: The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong:payable
, implicit nonpayable,view
, andpure
. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, apayable
function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.24 is that you can edit this interface to add stricter mutability before inheriting from your contract.external
then a contract will be compliant if it usespublic
visibility. As a workaround for version 0.4.20, you can edit this interface to switch topublic
before inheriting from your contract.If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.
Rationale
There are many approaches which were developed to create an access control mechanism, but each focuses on a relatively specific use case. We tried to create a generalized mechanism allowing for all uses cases to be implemented, while keeping the gas efficiency similar to a more dedicated solution.
We chose to use the concept of "Keys" with the certain properties of: uses limit, expiration time, and (re-)assignablity. This approach allows the use of complex boolean expressions for limiting access to a function such as allowing an account to call a certain function (or multiple functions) 2 times until the end of next month and possibly assign that right to another account.
A more concrete example could be for "Ownership" of a contract. A common use case for the ("Ownable" contract)[https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol] are "safty backdoors" - functions which enable the "owner" of the contract do controversial changes in crisis times. Most teams promise to eliminate their access to those backdoors after their project gets mature enogh, but this requires to trust the team to stand up for this promise. The "Ownable" contract pattern, thus, could benefit from the addition of a trustless expiration date, removing the need of trusting the teams to give up on their "safety backdoors" access when their project matures.
The proposed interface contains functions to allow utilizing the full capabilities of the properties of a key. Which are the ability to grant (by the contract), assign to other account, revoke, and use a key. This also keeps the option for implementations to have their own characteristics and suitable behaviour. For example, it is possible for an implementation to use block number for keys expiration, instead of timestamps. For gas optimizations, we also used 0 values to "disable" the use of certain features, this makes keys which doesn't have, for example, expiration time to have similar gas consumption to another solution with no expiration parameter at all.
Backwards Compatibility
There are no backwards compatibility concerns.
Test Cases
DAOstack ERC-1480 implementation includes test cases written using Truffle.
Implementation
DAOstack full implementation is available here.
Copyright
Copyright and related rights waived via CC0.
The text was updated successfully, but these errors were encountered: