eip: 734
title: Key Manager
author: Fabian Vogelsteller (@frozeman)
discussions-to: https://github.com/ethereum/EIPs/issues/734
status: WIP
type: Standards Track
category: ERC
created: 2017-10-02
NOTE!!: This standard is deprecated and was superseeded by LSP6-KeyManager.
A contract for key management of a blockchain proxy account.
The following describes standard functions for a key manager to be used in conjunction with ERC725. This contract can hold keys to sign actions (transactions, documents, logins, access, etc), as well as execute instructions through an ERC725 proxy account.
This key manager standard allows for more complex management of an ERC725 proxy account.
keys
: Keys are public keys from either external accounts, or contracts' addresses.claim issuer
: is another smart contract or external account, which issues claims about this identity. The claim issuer can be an identity contract itself.claim
: For details about claims see #ERC735
Keys are cryptographic public keys, or contract addresses associated with this identity. The structure should be as follows:
key
: A public key owned by this identitypurpose
:uint256[]
Array of the key types, like 1 = MANAGEMENT, 2 = EXECUTIONkeyType
: The type of key used, which would be auint256
for different key types. e.g. 1 = ECDSA, 2 = RSA, etc.key
:bytes32
The public key. // for non-hex and long keys, its the Keccak256 hash of the key
struct Key {
uint256[] purposes;
uint256 keyType;
bytes32 key;
}
Returns the full key data, if present in the identity.
function getKey(bytes32 _key) external view returns(uint256[] purposes, uint256 keyType, bytes32 key);
Returns TRUE
if a key is present and has the given purpose. If the key is not present it returns FALSE
.
function keyHasPurpose(bytes32 _key, uint256 purpose) external view returns(bool exists);
Returns an array of public key bytes32 held by this identity.
function getKeysByPurpose(uint256 _purpose) external view returns(bytes32[] keys);
Adds a _key
to the identity. The _purpose
specifies the purpose of the key. Initially, we propose four purposes:
1
: MANAGEMENT keys, which can manage the identity2
: EXECUTION keys, which perform executions in this identity's name (signing, logins, transactions, etc.)
MUST only be done by keys of purpose 1
, or the identity itself. If it's the identity itself, the approval process will determine its approval.
Triggers Event: KeyAdded
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) returns (bool success)
Removes _key
from the identity.
MUST only be done by keys of purpose 1
, or the identity itself. If it's the identity itself, the approval process will determine its approval.
Triggers Event: KeyRemoved
function removeKey(bytes32 _key, uint256 _purpose) returns (bool success)
Changes the keys required to perform an action for a specific purpose. (This is the n in an n of m multisig approval process.)
MUST only be done by keys of purpose 1
, or the identity itself. If it's the identity itself, the approval process will determine its approval.
Triggers Event: KeysRequiredChanged
function changeKeysRequired(uint256 purpose, uint256 number) external
Returns number of keys required for purpose.
function getKeysRequired(uint256 purpose) external view returns(uint256)
Passes an execution instruction to the keymanager.
SHOULD require approve
to be called with one or more keys of purpose 1
or 2
to approve this execution.
Execute COULD be used as the only accessor for addKey
, removeKey
and replaceKey
and removeClaim
.
Returns executionId
: SHOULD be sent to the approve
function, to approve or reject this execution.
Triggers Event: ExecutionRequested Triggers on direct execution Event: Executed
function execute(address _to, uint256 _value, bytes _data) returns (uint256 executionId)
Approves an execution or claim addition.
This SHOULD require n
of m
approvals of keys purpose 1
, if the _to
of the execution is the identity contract itself, to successfully approve an execution.
And COULD require n
of m
approvals of keys purpose 2
, if the _to
of the execution is another contract, to successfully approve an execution.
Triggers Event: Approved Triggers on successfull execution Event: Executed Triggers on successfull claim addition Event: ClaimAdded
function approve(uint256 _id, bool _approve) returns (bool success)
MUST be triggered when addKey
was successfully called.
event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType)
MUST be triggered when removeKey
was successfully called.
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType)
MUST be triggered when execute
was successfully called.
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data)
MUST be triggered when approve
was called and the execution was successfully approved.
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data)
MUST be triggered when approve
was successfully called.
event Approved(uint256 indexed executionId, bool approved)
MUST be triggered when changeKeysRequired
was successfully called.
event KeysRequiredChanged(uint256 purpose, uint256 number)
This specification was chosen to allow most flexibility and experimentation around verifiable accounts. By having a separate contract as proxy on chain allows for cross greater compatibility, as well as extra and altered functionality for new use cases.
pragma solidity ^0.4.18;
contract ERC734 {
uint256 constant MANAGEMENT_KEY = 1;
uint256 constant EXECUTION_KEY = 2;
event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
event Approved(uint256 indexed executionId, bool approved);
event KeysRequiredChanged(uint256 purpose, uint256 number);
struct Key {
uint256 purpose; //e.g., MANAGEMENT_KEY = 1, EXECUTION_KEY = 2, etc.
uint256 keyType; // e.g. 1 = ECDSA, 2 = RSA, etc.
bytes32 key;
}
function getKey(bytes32 _key) public external view returns(uint256[] purposes, uint256 keyType, bytes32 key);
function keyHasPurpose(bytes32 _key, uint256 _purpose) public external view returns (bool exists);
function getKeysByPurpose(uint256 _purpose) public external view returns (bytes32[] keys);
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) public returns (bool success);
function removeKey(bytes32 _key, uint256 _purpose) public returns (bool success);
function changeKeysRequired(uint256 purpose, uint256 number) external;
function getKeysRequired(uint256 purpose) external view returns(uint256);
function execute(address _to, uint256 _value, bytes _data) public returns (uint256 executionId);
function approve(uint256 _id, bool _approve) public returns (bool success);
}
Copyright and related rights waived via CC0.