diff --git a/neps/nep-0342.md b/neps/nep-0342.md new file mode 100644 index 000000000..4043d769c --- /dev/null +++ b/neps/nep-0342.md @@ -0,0 +1,41 @@ +--- +NEP: 297 +Title: Delegate Keys +Author: Illia Polosukhin +DiscussionsTo: https://gov.near.org/t/proposal-extending-nears-account-with-aliases-and-delegated-keys/9450 +Status: Draft +Type: +Category: Runtime +Created: 28-Mar-2022 +--- + +## Summary + +Delegate keys allow to assign permissions to another account instead of a key. +This allows to delegate ownership of an account by giving set of permissions that are usually restricted only to FullAccessKey. + +## Motivation + +Issue that became evident trying to develop upgradability patterns for contracts is complexity of going from full access key on the contract to a contract managed by multisig or a DAO. + +Right now it is required to implement a complex logic of upgrading contract and managing assets/control inside the contract in the first version to allow “owner” account to call these methods. + +## Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +## Specification + +See updates to AccessKey.md and Actions.md + +## Reference Implementation + +TBD + +## Drawbacks + +This adds complexity to the account model. + +## Copyright +[copyright]: #copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/specs/DataStructures/AccessKey.md b/specs/DataStructures/AccessKey.md index 9ec66c3ae..96c641880 100644 --- a/specs/DataStructures/AccessKey.md +++ b/specs/DataStructures/AccessKey.md @@ -1,6 +1,6 @@ # Access Keys -Access key provides an access for a particular account. Each access key belongs to some account and +Access key provides access for a particular account. Each access key belongs to some account and is identified by a unique (within the account) public key. Access keys are stored as `account_id,public_key` in a trie state. Account can have from [zero](#account-without-access-keys) to multiple access keys. ```rust @@ -21,6 +21,7 @@ There are 2 types of `AccessKeyPermission` in Near currently: `FullAccess` and ` pub enum AccessKeyPermission { FunctionCall(FunctionCallPermission), FullAccess, + DelegateCall(DelegateCallPermission), } ``` @@ -48,6 +49,35 @@ pub struct FunctionCallPermission { } ``` +## AccountKeyPermission::DelegateCall + +Grants limited permission to make some type of actions from a specified `sender_id`. + +```rust +/// Permission per each type of `Action`. +pub enum ActionPermission { + CreateAccount, + DeployContract, + FunctionCall, + Transfer, + Stake, + AddKey, + DeleteKey, + DeleteAccount, + DelegateAction, +} + +pub struct DelegateCallPermission { + /// The access key only allows actions from the given set from given sender account id. + pub sender_id: AccountId, + + /// Set of allowed actions by given `sender_id`. + pub allowed: Set, +} +``` + ## Account without access keys -If account has no access keys attached it means that it has no owner who can run transactions from its behalf. However, if such accounts has code it can be invoked by other accounts and contracts. +If account has no access keys attached it means that it has no external party who can run transactions from its behalf. +However, if such account has code, it can be invoked by other accounts and contracts. +Contract code can also add and remove keys or call actions on the account it's deployed. diff --git a/specs/RuntimeSpec/Actions.md b/specs/RuntimeSpec/Actions.md index 7c5622533..04bcdbd21 100644 --- a/specs/RuntimeSpec/Actions.md +++ b/specs/RuntimeSpec/Actions.md @@ -12,6 +12,7 @@ pub enum Action { AddKey(AddKeyAction), DeleteKey(DeleteKeyAction), DeleteAccount(DeleteAccountAction), + DelegateAction(DelegateAction), } ``` @@ -276,3 +277,29 @@ DeleteAccountStaking { account_id: AccountId } **Execution Error**: - If state or storage is corrupted, a `StorageError` is returned. + +## DelegateAction + +Delegate action allows to execute an action on antoher account. + +```rust +pub struct DelegateAction { + /// Which account to delegate given action. + pub delegatee_id: AccountId, + /// Specific action to call on the delegatee account. + pub action: Action, +} +``` + +**Outcomes**: +- A new receipt is created toward `delegatee_id` with `action`. Receiver will consider permissions (delegated keys) when receipt arrives which will result in execution of such action or failure. + +### Errors + +**Validation Error** +- If `delegatee_id` is not a valid account id, the following error will be returned +```rust +/// Invalid account ID. +InvalidAccountId { account_id: AccountId }, +``` +