system-methods
- Proposal Name: System methods in runtime API
- Start Date: 2019-09-03
- NEP PR: nearprotocol/neps#0013
Summary
Adds new ability for contracts to perform some system functions:
- create new accounts (with possible code deploy and initialization)
- deploy new code (or redeploying code for upgrades)
- batched function calls
- transfer money
- stake
- add key
- delete key
- delete account
Motivation
Contracts should have the ability to create new accounts, transfer money without calling code and stake. It will enable full functionality of contract-based accounts.
Reference
We introduce additional promise APIs to support batched actions.
Firstly, we enable ability to create empty promises without any action. They act similarly to traditional promises, but don't contain function call action.
Secondly, we add API to append individual actions to promises. For example we can create
a promise with a function_call first using promise_create
and then attach a transfer action on top
of this promise. So the transfer will only deposit tokens if the function call succeeds. Another example
is how we create accounts now using batched actions. To create a new account, we create a transaction with
the following actions: create_account
, transfer
, add_key
. It creates a new account, deposit some funds on it and the adds a new key.
For more examples see NEP#8: https://github.com/nearprotocol/NEPs/pull/8/files?short_path=15b6752#diff-15b6752ec7d78e7b85b8c7de4a19cbd4
NOTE: The existing promise API is a special case of the batched promise API.
- Calling
promise_batch_create
and thenpromise_batch_action_function_call
will produce the same promise as callingpromise_create
directly. - Calling
promise_batch_then
and thenpromise_batch_action_function_call
will produce the same promise as callingpromise_then
directly.
Promises API
promise_batch_create(account_id_len: u64, account_id_ptr: u64) -> u64
Creates a new promise towards given account_id
without any actions attached to it.
Panics
- If
account_id_len + account_id_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
Returns
- Index of the new promise that uniquely identifies it within the current execution of the method.
promise_batch_then(promise_idx: u64, account_id_len: u64, account_id_ptr: u64) -> u64
Attaches a new empty promise that is executed after promise pointed by promise_idx
is complete.
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If
account_id_len + account_id_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
Returns
- Index of the new promise that uniquely identifies it within the current execution of the method.
promise_batch_action_create_account(promise_idx: u64)
Appends CreateAccount
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R48
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
.
promise_batch_action_deploy_contract(promise_idx: u64, code_len: u64, code_ptr: u64)
Appends DeployContract
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R49
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If
code_len + code_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_function_call(promise_idx: u64,
method_name_len: u64,
method_name_ptr: u64,
arguments_len: u64,
arguments_ptr: u64,
amount_ptr: u64,
gas: u64)
Appends FunctionCall
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R50
NOTE: Calling promise_batch_create
and then promise_batch_action_function_call
will produce the same promise as calling promise_create
directly.
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If
account_id_len + account_id_ptr
ormethod_name_len + method_name_ptr
orarguments_len + arguments_ptr
oramount_ptr + 16
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_transfer(promise_idx: u64, amount_ptr: u64)
Appends Transfer
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R51
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If
amount_ptr + 16
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_stake(promise_idx: u64,
amount_ptr: u64,
public_key_len: u64,
public_key_ptr: u64)
Appends Stake
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R52
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If the given public key is not a valid public key (e.g. wrong length)
InvalidPublicKey
. - If
amount_ptr + 16
orpublic_key_len + public_key_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_add_key_with_full_access(promise_idx: u64,
public_key_len: u64,
public_key_ptr: u64,
nonce: u64)
Appends AddKey
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R54
The access key will have FullAccess
permission, details: [0005-access-keys.md#guide-level-explanation](click here)
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If the given public key is not a valid public key (e.g. wrong length)
InvalidPublicKey
. - If
public_key_len + public_key_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_add_key_with_function_call(promise_idx: u64,
public_key_len: u64,
public_key_ptr: u64,
nonce: u64,
allowance_ptr: u64,
receiver_id_len: u64,
receiver_id_ptr: u64,
method_names_len: u64,
method_names_ptr: u64)
Appends AddKey
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-156752ec7d78e7b85b8c7de4a19cbd4R54
The access key will have FunctionCall
permission, details: [0005-access-keys.md#guide-level-explanation](click here)
- If the
allowance
value (not the pointer) is0
, the allowance is set toNone
(which means unlimited allowance). And positive value represents aSome(...)
allowance. - Given
method_names
is autf-8
string with,
used as a separator. The vm will split the given string into a vector of strings.
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If the given public key is not a valid public key (e.g. wrong length)
InvalidPublicKey
. - if
method_names
is not a validutf-8
string, fails withBadUTF8
. - If
public_key_len + public_key_ptr
,allowance_ptr + 16
,receiver_id_len + receiver_id_ptr
ormethod_names_len + method_names_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_delete_key(promise_idx: u64,
public_key_len: u64,
public_key_ptr: u64)
Appends DeleteKey
action to the batch of actions for the given promise pointed by promise_idx
.
Details for the action: https://github.com/nearprotocol/NEPs/pull/8/files#diff-15b6752ec7d78e7b85b8c7de4a19cbd4R55
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If the given public key is not a valid public key (e.g. wrong length)
InvalidPublicKey
. - If
public_key_len + public_key_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.
promise_batch_action_delete_account(promise_idx: u64,
beneficiary_id_len: u64,
beneficiary_id_ptr: u64)
Appends DeleteAccount
action to the batch of actions for the given promise pointed by promise_idx
.
Action is used to delete an account. It can be performed on a newly created account, on your own account or an account with
insufficient funds to pay rent. Takes beneficiary_id
to indicate where to send the remaining funds.
Panics
- If
promise_idx
does not correspond to an existing promise panics withInvalidPromiseIndex
. - If the promise pointed by the
promise_idx
is an ephemeral promise created bypromise_and
. - If
beneficiary_id_len + beneficiary_id_ptr
points outside the memory of the guest or host, withMemoryAccessViolation
.