Fungible Token
+Version 0.2.0
Summary
A standard interface for fungible tokens allowing for ownership, escrow and transfer, specifically targeting third-party marketplace integration.
+Changelog
+0.2.0
+-
+
- Introduce storage deposits. Make every change method payable (able receive attached deposits with the function calls). It requires the caller to attach enough deposit to cover potential storage increase. See core-contracts/#47 +
- Replace
set_allowance
withinc_allowance
anddec_allowance
to address the issue of allowance front-running. See core-contracts/#49
+ - Validate
owner_id
account ID. See core-contracts/#54
+ - Enforce that the
new_owner_id
is different from the currentowner_id
for transfer. See core-contracts/#55
+
Motivation
NEAR Protocol uses an asynchronous sharded Runtime. This means the following:
-
@@ -196,6 +205,10 @@
- All amounts, balances and allowance are limited by U128 (max value
2**128 - 1
).
+ - All amounts, balances and allowance are limited by
U128
(max value2**128 - 1
). - Token standard uses JSON for serialization of arguments and results.
- Amounts in arguments and results have are serialized as Base-10 strings, e.g.
"100"
. This is done to avoid JSON limitation of max integer value of2**53
.
+ - The contract tracks the change in storage before and after the call. If the storage increases, +the contract requires the caller of the contract to attach enough deposit to the function call +to cover the storage cost. +This is done to prevent a denial of service attack on the contract by taking all available storage. +It's because the gas cost of adding new escrow account is cheap, many escrow allowances can be added until the contract +runs out of storage. +If the storage decreases, the contract will issue a refund for the cost of the released storage. +The unused tokens from the attached deposit are also refunded, so it's safe to attach more deposit than required. +
- To prevent the deployed contract from being modified or deleted, it should not have any access +keys on its account.
Simple transfer
Alice wants to send 5 wBTC tokens to Bob.
Assumptions
@@ -298,13 +311,23 @@Reference-level explanation -
The full implementation in Rust can be found there: https://github.com/nearprotocol/near-sdk-rs/blob/master/examples/fungible-token/src/lib.rs
+The full implementation in Rust can be found here: fungible-token
NOTES:
-
-
Interface:
@@ -314,9 +337,21 @@
The sum of all the stakes of
-next_bps
in the previous epoch istotal_stake
referred to in (5) above.The signatures in the
LightClientBlockView::approvals_after_next
are signatures onapproval_message
. Thei
-th signature inapprovals_after_next
, if present, must validate against thei
-th public key innext_bps
from the previous epoch.approvals_after_next
can contain fewer elements thannext_bps
in the previous epoch.Proof Verification
-[transaction-outcome-proof](Transaction Outcome Proofs)
Transaction Outcome Proofs
To verify that a transaction or receipt happens on chain, a light client can request a proof through rpc by providing
id
, which is of type@@ -1003,7 +1002,23 @@
}
which includes everything that a light client needs to prove the execution outcome of the given transaction or receipt. -The proof verification can be broken down into two steps, execution outcome root verification and block merkle root +Here
+ExecutionOutcomeWithIdView
is++#![allow(unused_variables)] +fn main() { +pub struct ExecutionOutcomeWithIdView { + /// Proof of the execution outcome + pub proof: MerklePath, + /// Block hash of the block that contains the outcome root + pub block_hash: CryptoHash, + /// Id of the execution (transaction or receipt) + pub id: CryptoHash, + /// The actual outcome + pub outcome: ExecutionOutcomeView, +} +} +
The proof verification can be broken down into two steps, execution outcome root verification and block merkle root verification.
Execution Outcome Root Verification
If the outcome root of the transaction or receipt is included in block
H
, thenoutcome_proof
includes the block hash @@ -1041,11 +1056,13 @@Light C
A standalone light client would bootstrap by requesting next blocks until it receives an empty result, and then periodically request the next light client block.
A smart contract-based light client that enables a bridge to NEAR on a different blockchain naturally cannot request blocks itself. Instead external oracles query the next light client block from one of the full nodes, and submit it to the light client smart contract. The smart contract-based light client performs the same checks described above, so the oracle doesn't need to be trusted.
Light Client Proof
-The following rpc end-point returns
-RpcLightClientExecutionProofResponse
that a light client needs for verifying execution outcomes:http post http://127.0.0.1:3030/ jsonrpc=2.0 method=EXPERIMENTAL_light_client_proof params:="{"type": <proof_type>, "id": <id>, "sender": <sender>, "light_client_head": <light_client_head>}" id="dontcare" +
The following rpc end-point returns
+RpcLightClientExecutionProofResponse
that a light client needs for verifying execution outcomes.For transaction execution outcome, the rpc is
++http post http://127.0.0.1:3030/ jsonrpc=2.0 method=EXPERIMENTAL_light_client_proof params:="{"type": "transaction", "transaction_hash": <transaction_hash>, "sender_id": <sender_id>, "light_client_head": <light_client_head>}" id="dontcare" +
For receipt execution outcome, the rpc is
+-http post http://127.0.0.1:3030/ jsonrpc=2.0 method=EXPERIMENTAL_light_client_proof params:="{"type": "receipt", "receipt_id": <receipt_id>, "receiver_id": <receiver_id>, "light_client_head": <light_client_head>}" id="dontcare"
Note that the above command shows the case for querying proof for transaction outcome. For receipt outcome, "sender" should -be replaced by "receiver".
Runtime Specification
Function Call
In this section we provide an explanation how the
@@ -3464,8 +3481,17 @@FunctionCall
action execution works, what are the inputs and what are the outputs. Suppose runtime received the following ActionReceipt:Standards
Fungible Token Standard Fungible Token
+Version
0.2.0
Summary
A standard interface for fungible tokens allowing for ownership, escrow and transfer, specifically targeting third-party marketplace integration.
+Changelog
++
0.2.0
+
- Introduce storage deposits. Make every change method payable (able receive attached deposits with the function calls). It requires the caller to attach enough deposit to cover potential storage increase. See core-contracts/#47
+- Replace
+set_allowance
withinc_allowance
anddec_allowance
to address the issue of allowance front-running. See core-contracts/#49- Validate
+owner_id
account ID. See core-contracts/#54- Enforce that the
+new_owner_id
is different from the currentowner_id
for transfer. See core-contracts/#55Motivation
NEAR Protocol uses an asynchronous sharded Runtime. This means the following:
@@ -3509,6 +3535,10 @@
Simple transfer
Alice wants to send 5 wBTC tokens to Bob.
Assumptions
@@ -3611,13 +3641,23 @@Reference-level explanation
The full implementation in Rust can be found there: https://github.com/nearprotocol/near-sdk-rs/blob/master/examples/fungible-token/src/lib.rs
+The full implementation in Rust can be found here: fungible-token
NOTES:
-
- All amounts, balances and allowance are limited by U128 (max value
+2**128 - 1
).- All amounts, balances and allowance are limited by
U128
(max value2**128 - 1
).- Token standard uses JSON for serialization of arguments and results.
- Amounts in arguments and results have are serialized as Base-10 strings, e.g.
+"100"
. This is done to avoid JSON limitation of max integer value of2**53
.- The contract tracks the change in storage before and after the call. If the storage increases, +the contract requires the caller of the contract to attach enough deposit to the function call +to cover the storage cost. +This is done to prevent a denial of service attack on the contract by taking all available storage. +It's because the gas cost of adding new escrow account is cheap, many escrow allowances can be added until the contract +runs out of storage. +If the storage decreases, the contract will issue a refund for the cost of the released storage. +The unused tokens from the attached deposit are also refunded, so it's safe to attach more deposit than required.
+- To prevent the deployed contract from being modified or deleted, it should not have any access +keys on its account.
Interface:
@@ -3627,9 +3667,21 @@
).","breadcrumbs":"Runtime specification » Components » Bindings Specification","id":"105","title":"Bindings Specification"},"106":{"body":"Registers allow the host function to return the data into a buffer located inside the host oppose to the buffer located on the client. A special operation can be used to copy the content of the buffer into the host. Memory pointers can then be used to point either to the memory on the guest or the memory on the host, see below. Benefits: We can have functions that return values that are not necessarily used, e.g. inserting key-value into a trie can also return the preempted old value, which might not be necessarily used. Previously, if we returned something we would have to pass the blob from host into the guest, even if it is not used; We can pass blobs of data between host functions without going through the guest, e.g. we can remove the value from the storage and insert it into under a different key; It makes API cleaner, because we don't need to pass buffer_len and buffer_ptr as arguments to other functions; It allows merging certain functions together, see storage_iter_next; This is consistent with other APIs that were created for high performance, e.g. allegedly Ewasm have implemented SNARK-like computations in Wasm by exposing a bignum library through stack-like interface to the guest. The guest can manipulate then with the stack of 256-bit numbers that is located on the host. Host → host blob passing The registers can be used to pass the blobs between host functions. For any function that takes a pair of arguments *_len: u64, *_ptr: u64 this pair is pointing to a region of memory either on the guest or the host: If *_len != u64::MAX it points to the memory on the guest; If *_len == u64::MAX it points to the memory under the register *_ptr on the host. For example: storage_write(u64::MAX, 0, u64::MAX, 1, 2) -- insert key-value into storage, where key is read from register 0, value is read from register 1, and result is saved to register 2. Note, if some function takes register_id then it means this function can copy some data into this register. If register_id == u64::MAX then the copying does not happen. This allows some micro-optimizations in the future. Note, we allow multiple registers on the host, identified with u64 number. The guest does not have to use them in order and can for instance save some blob in register 5000 and another value in register 1. Specification read_register(register_id: u64, ptr: u64) Writes the entire content from the register register_id into the memory of the guest starting with ptr. Panics If the content extends outside the memory allocated to the guest. In Wasmer, it returns MemoryAccessViolation error message; If register_id is pointing to unused register returns InvalidRegisterId error message. Undefined Behavior If the content of register extends outside the preallocated memory on the host side, or the pointer points to a wrong location this function will overwrite memory that it is not supposed to overwrite causing an undefined behavior. register_len(register_id: u64) -> u64 Returns the size of the blob stored in the given register. Normal operation If register is used, then returns the size, which can potentially be zero; If register is not used, returns u64::MAX","breadcrumbs":"Runtime specification » Components » Bindings Specification » Registers API","id":"106","title":"Registers API"},"107":{"body":"Here we provide a specification of trie API. After this NEP is merged, the cases where our current implementation does not follow the specification are considered to be bugs that need to be fixed. storage_write(key_len: u64, key_ptr: u64, value_len: u64, value_ptr: u64, register_id: u64) -> u64 Writes key-value into storage. Normal operation If key is not in use it inserts the key-value pair and does not modify the register; If key is in use it inserts the key-value and copies the old value into the register_id. Returns If key was not used returns 0; If key was used returns 1. Panics If key_len + key_ptr or value_len + value_ptr exceeds the memory container or points to an unused register it panics with MemoryAccessViolation. (When we say that something panics with the given error we mean that we use Wasmer API to create this error and terminate the execution of VM. For mocks of the host that would only cause a non-name panic.) If returning the preempted value into the registers exceed the memory container it panics with MemoryAccessViolation; Current bugs External::storage_set trait can return an error which is then converted to a generic non-descriptive StorageUpdateError, here however the actual implementation does not return error at all, see ; Does not return into the registers. storage_read(key_len: u64, key_ptr: u64, register_id: u64) -> u64 Reads the value stored under the given key. Normal operation If key is used copies the content of the value into the register_id, even if the content is zero bytes; If key is not present then does not modify the register. Returns If key was not present returns 0; If key was present returns 1. Panics If key_len + key_ptr exceeds the memory container or points to an unused register it panics with MemoryAccessViolation; If returning the preempted value into the registers exceed the memory container it panics with MemoryAccessViolation; Current bugs This function currently does not exist. storage_remove(key_len: u64, key_ptr: u64, register_id: u64) -> u64 Removes the value stored under the given key. Normal operation Very similar to storage_read: If key is used, removes the key-value from the trie and copies the content of the value into the register_id, even if the content is zero bytes. If key is not present then does not modify the register. Returns If key was not present returns 0; If key was present returns 1. Panics If key_len + key_ptr exceeds the memory container or points to an unused register it panics with MemoryAccessViolation; If the registers exceed the memory limit panics with MemoryAccessViolation; If returning the preempted value into the registers exceed the memory container it panics with MemoryAccessViolation; Current bugs Does not return into the registers. storage_has_key(key_len: u64, key_ptr: u64) -> u64 Checks if there is a key-value pair. Normal operation If key is used returns 1, even if the value is zero bytes; Otherwise returns 0. Panics If key_len + key_ptr exceeds the memory container it panics with MemoryAccessViolation; storage_iter_prefix(prefix_len: u64, prefix_ptr: u64) -> u64 DEPRECATED, calling it will result result in HostError::Deprecated error. Creates an iterator object inside the host. Returns the identifier that uniquely differentiates the given iterator from other iterators that can be simultaneously created. Normal operation It iterates over the keys that have the provided prefix. The order of iteration is defined by the lexicographic order of the bytes in the keys. If there are no keys, it creates an empty iterator, see below on empty iterators; Panics If prefix_len + prefix_ptr exceeds the memory container it panics with MemoryAccessViolation; storage_iter_range(start_len: u64, start_ptr: u64, end_len: u64, end_ptr: u64) -> u64 DEPRECATED, calling it will result result in HostError::Deprecated error. Similarly to storage_iter_prefix creates an iterator object inside the host. Normal operation Unless lexicographically start < end, it creates an empty iterator. Iterates over all key-values such that keys are between start and end, where start is inclusive and end is exclusive. Note, this definition allows for start or end keys to not actually exist on the given trie. Panics: If start_len + start_ptr or end_len + end_ptr exceeds the memory container or points to an unused register it panics with MemoryAccessViolation; storage_iter_next(iterator_id: u64, key_register_id: u64, value_register_id: u64) -> u64 DEPRECATED, calling it will result result in HostError::Deprecated error. Advances iterator and saves the next key and value in the register. Normal operation If iterator is not empty (after calling next it points to a key-value), copies the key into key_register_id and value into value_register_id and returns 1; If iterator is empty returns 0. This allows us to iterate over the keys that have zero bytes stored in values. Panics If key_register_id == value_register_id panics with MemoryAccessViolation; If the registers exceed the memory limit panics with MemoryAccessViolation; If iterator_id does not correspond to an existing iterator panics with InvalidIteratorId If between the creation of the iterator and calling storage_iter_next any modification to storage was done through storage_write or storage_remove the iterator is invalidated and the error message is IteratorWasInvalidated. Current bugs Not implemented, currently we have storage_iter_next and data_read + DATA_TYPE_STORAGE_ITER that together fulfill the purpose, but have unspecified behavior.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Trie API","id":"107","title":"Trie API"},"108":{"body":"promise_create(account_id_len: u64, account_id_ptr: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: u64) -> u64 Creates a promise that will execute a method on account with given arguments and attaches the given amount. amount_ptr point to slices of bytes representing u128. Panics If account_id_len + account_id_ptr or method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. Returns Index of the new promise that uniquely identifies it within the current execution of the method. promise_then(promise_idx: u64, account_id_len: u64, account_id_ptr: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: u64) -> u64 Attaches the callback that is executed after promise pointed by promise_idx is complete. Panics If promise_idx does not correspond to an existing promise panics with InvalidPromiseIndex. If account_id_len + account_id_ptr or method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. Returns Index of the new promise that uniquely identifies it within the current execution of the method. promise_and(promise_idx_ptr: u64, promise_idx_count: u64) -> u64 Creates a new promise which completes when time all promises passed as arguments complete. Cannot be used with registers. promise_idx_ptr points to an array of u64 elements, with promise_idx_count denoting the number of elements. The array contains indices of promises that need to be waited on jointly. Panics If promise_ids_ptr + 8 * promise_idx_count extend outside the guest memory with MemoryAccessViolation; If any of the promises in the array do not correspond to existing promises panics with InvalidPromiseIndex. If called in a view function panics with ProhibitedInView. Returns Index of the new promise that uniquely identifies it within the current execution of the method. promise_results_count() -> u64 If the current function is invoked by a callback we can access the execution results of the promises that caused the callback. This function returns the number of complete and incomplete callbacks. Note, we are only going to have incomplete callbacks once we have promise_or combinator. Normal execution If there is only one callback promise_results_count() returns 1; If there are multiple callbacks (e.g. created through promise_and) promise_results_count() returns their number. If the function was called not through the callback promise_results_count() returns 0. Panics If called in a view function panics with ProhibitedInView. promise_result(result_idx: u64, register_id: u64) -> u64 If the current function is invoked by a callback we can access the execution results of the promises that caused the callback. This function returns the result in blob format and places it into the register. Normal execution If promise result is complete and successful copies its blob into the register; If promise result is complete and failed or incomplete keeps register unused; Returns If promise result is not complete returns 0; If promise result is complete and successful returns 1; If promise result is complete and failed returns 2. Panics If result_idx does not correspond to an existing result panics with InvalidResultIndex. If copying the blob exhausts the memory limit it panics with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. Current bugs We currently have two separate functions to check for result completion and copy it. promise_return(promise_idx: u64) When promise promise_idx finishes executing its result is considered to be the result of the current function. Panics If promise_idx does not correspond to an existing promise panics with InvalidPromiseIndex. Current bugs The current name return_promise is inconsistent with the naming convention of Promise 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, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If account_id_len + account_id_ptr points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If code_len + code_ptr points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If account_id_len + account_id_ptr or method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If amount_ptr + 16 points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. promise_batch_action_stake(promise_idx: u64, amount_ptr: u64, bls_public_key_len: u64, bls_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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If the given BLS public key is not a valid BLS public key (e.g. wrong length) InvalidPublicKey. If amount_ptr + 16 or bls_public_key_len + bls_public_key_ptr points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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: https://github.com/nearprotocol/NEPs/blob/master/text/0005-access-keys.md#guide-level-explanation Panics If promise_idx does not correspond to an existing promise panics with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_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, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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: https://github.com/nearprotocol/NEPs/blob/master/text/0005-access-keys.md#guide-level-explanation If the allowance value (not the pointer) is 0, the allowance is set to None (which means unlimited allowance). And positive value represents a Some(...) allowance. Given method_names is a utf-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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If the given public key is not a valid public key (e.g. wrong length) InvalidPublicKey. if method_names is not a valid utf-8 string, fails with BadUTF8. If public_key_len + public_key_ptr, allowance_ptr + 16, receiver_id_len + receiver_id_ptr or method_names_len + method_names_ptr points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_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, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView. 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 with InvalidPromiseIndex. If the promise pointed by the promise_idx is an ephemeral promise created by promise_and. If beneficiary_id_len + beneficiary_id_ptr points outside the memory of the guest or host, with MemoryAccessViolation. If called in a view function panics with ProhibitedInView.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Promises API","id":"108","title":"Promises API"},"109":{"body":"Context API mostly provides read-only functions that access current information about the blockchain, the accounts (that originally initiated the chain of cross-contract calls, the immediate contract that called the current one, the account of the current contract), other important information like storage usage. Many of the below functions are currently implemented through data_read which allows to read generic context data. However, there is no reason to have data_read instead of the specific functions: data_read does not solve forward compatibility. If later we want to add another context function, e.g. executed_operations we can just declare it as a new function, instead of encoding it as DATA_TYPE_EXECUTED_OPERATIONS = 42 which is passed as the first argument to data_read; data_read does not help with renaming. If later we decide to rename signer_account_id to originator_id then one could argue that contracts that rely on data_read would not break, while contracts relying on signer_account_id() would. However the name change often means the change of the semantics, which means the contracts using this function are no longer safe to execute anyway. However there is one reason to not have data_read -- it makes API more human-like which is a general direction Wasm APIs, like WASI are moving towards to. current_account_id(register_id: u64) Saves the account id of the current contract that we execute into the register. Panics If the registers exceed the memory limit panics with MemoryAccessViolation; signer_account_id(register_id: u64) All contract calls are a result of some transaction that was signed by some account using some access key and submitted into a memory pool (either through the wallet using RPC or by a node itself). This function returns the id of that account. Normal operation Saves the bytes of the signer account id into the register. Panics If the registers exceed the memory limit panics with MemoryAccessViolation; If called in a view function panics with ProhibitedInView. Current bugs Currently we conflate originator_id and sender_id in our code base. signer_account_pk(register_id: u64) Saves the public key fo the access key that was used by the signer into the register. In rare situations smart contract might want to know the exact access key that was used to send the original transaction, e.g. to increase the allowance or manipulate with the public key. Panics If the registers exceed the memory limit panics with MemoryAccessViolation; If called in a view function panics with ProhibitedInView. Current bugs Not implemented. predecessor_account_id(register_id: u64) All contract calls are a result of a receipt, this receipt might be created by a transaction that does function invocation on the contract or another contract as a result of cross-contract call. Normal operation Saves the bytes of the predecessor account id into the register. Panics If the registers exceed the memory limit panics with MemoryAccessViolation; If called in a view function panics with ProhibitedInView. Current bugs Not implemented. input(register_id: u64) Reads input to the contract call into the register. Input is expected to be in JSON-format. Normal operation If input is provided saves the bytes (potentially zero) of input into register. If input is not provided does not modify the register. Returns If input was not provided returns 0; If input was provided returns 1; If input is zero bytes returns 1, too. Panics If the registers exceed the memory limit panics with MemoryAccessViolation; Current bugs Implemented as part of data_read. However there is no reason to have one unified function, like data_read that can be used to read all block_index() -> u64 Returns the current block height from genesis. block_timestamp() -> u64 Returns the current block timestamp (number of non-leap-nanoseconds since January 1, 1970 0:00:00 UTC). epoch_height() -> u64 Returns the current epoch height from genesis. storage_usage() -> u64 Returns the number of bytes used by the contract if it was saved to the trie as of the invocation. This includes: The data written with storage_* functions during current and previous execution; The bytes needed to store the account protobuf and the access keys of the given account.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Context API","id":"109","title":"Context API"},"11":{"body":"Data for an single account is collocated in one shard. The account data consists of the following: Balance Locked balance (for staking) Code of the contract Key-value storage of the contract. Stored in a ordered trie Access Keys Postponed ActionReceipts Received DataReceipts Balances Total account balance consists of unlocked balance and locked balance. Unlocked balance is tokens that the account can use for transaction fees, transfers staking and other operations. Locked balance is the tokens that are currently in use for staking to be a validator or to become a validator. Locked balance may become unlocked at the beginning of an epoch. See [Staking] for details. Contracts A contract (AKA smart contract) is a program in WebAssembly that belongs to a specific account. When account is created, it doesn't have a contract. A contract has to be explicitly deployed, either by the account owner, or during the account creation. A contract can be executed by anyone who calls a method on your account. A contract has access to the storage on your account. Storage Every account has its own storage. It's a persistent key-value trie. Keys are ordered in lexicographical order. The storage can only be modified by the contract on the account. Current implementation on Runtime only allows your account's contract to read from the storage, but this might change in the future and other accounts's contracts will be able to read from your storage. NOTE: Accounts are charged recurrent rent for the total storage. This includes storage of the account itself, contract code, contract storage and all access keys. Access Keys An access key grants an access to a account. Each access key on the account is identified by a unique public key. This public key is used to validate signature of transactions. Each access key contains a unique nonce to differentiate or order transactions signed with this access key. An access keys have a permission associated with it. The permission can be one of two types: Full permission. It grants full access to the account. Function call permission. It grants access to only issue function call transactions. See [Access Keys] for more details.","breadcrumbs":"Data Structures » Account","id":"11","title":"Account"},"110":{"body":"Accounts own certain balance; and each transaction and each receipt have certain amount of balance and prepaid gas attached to them. During the contract execution, the contract has access to the following u128 values: account_balance -- the balance attached to the given account. This includes the attached_deposit that was attached to the transaction; attached_deposit -- the balance that was attached to the call that will be immediately deposited before the contract execution starts; prepaid_gas -- the tokens attached to the call that can be used to pay for the gas; used_gas -- the gas that was already burnt during the contract execution and attached to promises (cannot exceed prepaid_gas); If contract execution fails prepaid_gas - used_gas is refunded back to signer_account_id and attached_deposit is refunded back to predecessor_account_id. The following spec is the same for all functions: account_balance(balance_ptr: u64)\nattached_deposit(balance_ptr: u64) -- writes the value into the u128 variable pointed by balance_ptr. Panics If balance_ptr + 16 points outside the memory of the guest with MemoryAccessViolation; If called in a view function panics with ProhibitedInView. Current bugs Use a different name; prepaid_gas() -> u64\nused_gas() -> u64 Panics If called in a view function panics with ProhibitedInView.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Economics API","id":"110","title":"Economics API"},"111":{"body":"random_seed(register_id: u64) Returns random seed that can be used for pseudo-random number generation in deterministic way. Panics If the size of the registers exceed the set limit MemoryAccessViolation; sha256(value_len: u64, value_ptr: u64, register_id: u64) Hashes the random sequence of bytes using sha256 and returns it into register_id. Panics If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation. keccak256(value_len: u64, value_ptr: u64, register_id: u64) Hashes the random sequence of bytes using keccak256 and returns it into register_id. Panics If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation. keccak512(value_len: u64, value_ptr: u64, register_id: u64) Hashes the random sequence of bytes using keccak512 and returns it into register_id. Panics If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Math API","id":"111","title":"Math API"},"112":{"body":"value_return(value_len: u64, value_ptr: u64) Sets the blob of data as the return value of the contract. Panics If value_len + value_ptr exceeds the memory container or points to an unused register it panics with MemoryAccessViolation; panic() Terminates the execution of the program with panic GuestPanic(\"explicit guest panic\"). panic_utf8(len: u64, ptr: u64) Terminates the execution of the program with panic GuestPanic(s), where s is the given UTF-8 encoded string. Normal behavior If len == u64::MAX then treats the string as null-terminated with character '\\0'; Panics If string extends outside the memory of the guest with MemoryAccessViolation; If string is not UTF-8 returns BadUtf8. If string length without null-termination symbol is larger than config.max_log_len returns BadUtf8. log_utf8(len: u64, ptr: u64) Logs the UTF-8 encoded string. Normal behavior If len == u64::MAX then treats the string as null-terminated with character '\\0'; Panics If string extends outside the memory of the guest with MemoryAccessViolation; If string is not UTF-8 returns BadUtf8. If string length without null-termination symbol is larger than config.max_log_len returns BadUtf8. log_utf16(len: u64, ptr: u64) Logs the UTF-16 encoded string. len is the number of bytes in the string. See https://stackoverflow.com/a/5923961 that explains that null termination is not defined through encoding. Normal behavior If len == u64::MAX then treats the string as null-terminated with two-byte sequence of 0x00 0x00. Panics If string extends outside the memory of the guest with MemoryAccessViolation; abort(msg_ptr: u32, filename_ptr: u32, line: u32, col: u32) Special import kept for compatibility with AssemblyScript contracts. Not called by smart contracts directly, but instead called by the code generated by AssemblyScript.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Miscellaneous API","id":"112","title":"Miscellaneous API"},"113":{"body":"In the future we can have some of the registers to be on the guest. For instance a guest can tell the host that it has some pre-allocated memory that it wants to be used for the register, e.g. set_guest_register(register_id: u64, register_ptr: u64, max_register_size: u64) will assign register_id to a span of memory on the guest. Host then would also know the size of that buffer on guest and can throw a panic if there is an attempted copying that exceeds the guest register size.","breadcrumbs":"Runtime specification » Components » Bindings Specification » Future Improvements","id":"113","title":"Future Improvements"},"114":{"body":"","breadcrumbs":"GenesisConfig","id":"114","title":"GenesisConfig"},"115":{"body":"type: u32 Protocol version that this genesis works with.","breadcrumbs":"protocol_version","id":"115","title":"protocol_version"},"116":{"body":"type: DateTime Official time of blockchain start.","breadcrumbs":"genesis_time","id":"116","title":"genesis_time"},"117":{"body":"type: String ID of the blockchain. This must be unique for every blockchain. If your testnet blockchains do not have unique chain IDs, you will have a bad time.","breadcrumbs":"chain_id","id":"117","title":"chain_id"},"118":{"body":"type: u32 Number of block producer seats at genesis.","breadcrumbs":"num_block_producers","id":"118","title":"num_block_producers"},"119":{"body":"type: [ValidatorId] Defines number of shards and number of validators per each shard at genesis.","breadcrumbs":"block_producers_per_shard","id":"119","title":"block_producers_per_shard"},"12":{"body":"Access key provides an 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 to multiple access keys. pub struct AccessKey { /// The nonce for this access key. /// NOTE: In some cases the access key needs to be recreated. If the new access key reuses the /// same public key, the nonce of the new access key should be equal to the nonce of the old /// access key. It's required to avoid replaying old transactions again. pub nonce: Nonce, /// Defines permissions for this access key. pub permission: AccessKeyPermission,\n} There are 2 types of AccessKeyPermission in Near currently: FullAccess and FunctionCall. FunctionCall grants a permission to issue any action on account like DeployContract , Transfer tokens to other account, call functions FunctionCall , Stake and even delete account DeleteAccountAction . FullAccess also allow to manage access keys. AccessKeyPermission::FunctionCall limits to do only contract calls. pub enum AccessKeyPermission { FunctionCall(FunctionCallPermission), FullAccess,\n}","breadcrumbs":"Data Structures » Access Keys","id":"12","title":"Access Keys"},"120":{"body":"type: [ValidatorId] Expected number of fisherman per shard.","breadcrumbs":"avg_fisherman_per_shard","id":"120","title":"avg_fisherman_per_shard"},"121":{"body":"type: bool Enable dynamic re-sharding.","breadcrumbs":"dynamic_resharding","id":"121","title":"dynamic_resharding"},"122":{"body":"type: BlockIndex, Epoch length counted in blocks.","breadcrumbs":"epoch_length","id":"122","title":"epoch_length"},"123":{"body":"type: Gas, Initial gas limit for a block","breadcrumbs":"gas_limit","id":"123","title":"gas_limit"},"124":{"body":"type: Balance, Initial gas price","breadcrumbs":"gas_price","id":"124","title":"gas_price"},"125":{"body":"type: u8 Criterion for kicking out block producers (this is a number between 0 and 100)","breadcrumbs":"block_producer_kickout_threshold","id":"125","title":"block_producer_kickout_threshold"},"126":{"body":"type: u8 Criterion for kicking out chunk producers (this is a number between 0 and 100)","breadcrumbs":"chunk_producer_kickout_threshold","id":"126","title":"chunk_producer_kickout_threshold"},"127":{"body":"type: Fraction Gas price adjustment rate","breadcrumbs":"gas_price_adjustment_rate","id":"127","title":"gas_price_adjustment_rate"},"128":{"body":"type: RuntimeConfig Runtime configuration (mostly economics constants).","breadcrumbs":"runtime_config","id":"128","title":"runtime_config"},"129":{"body":"type: [AccountInfo] List of initial validators.","breadcrumbs":"validators","id":"129","title":"validators"},"13":{"body":"Grants limited permission to make FunctionCall to a specified receiver_id and methods of a particular contract with a limit of allowed balance to spend. pub struct FunctionCallPermission { /// Allowance is a balance limit to use by this access key to pay for function call gas and /// transaction fees. When this access key is used, both account balance and the allowance is /// decreased by the same value. /// `None` means unlimited allowance. /// NOTE: To change or increase the allowance, the old access key needs to be deleted and a new /// access key should be created. pub allowance: Option
, /// The access key only allows transactions with the given receiver's account id. pub receiver_id: AccountId, /// A list of method names that can be used. The access key only allows transactions with the /// function call of one of the given method names. /// Empty list means any method name can be used. pub method_names: Vec ,\n}","breadcrumbs":"Data Structures » AccessKeyPermission::FunctionCall","id":"13","title":"AccessKeyPermission::FunctionCall"},"130":{"body":"type: Vec< StateRecord > Records in storage at genesis (get split into shards at genesis creation).","breadcrumbs":"records","id":"130","title":"records"},"131":{"body":"type: u64 Number of blocks for which a given transaction is valid","breadcrumbs":"transaction_validity_period","id":"131","title":"transaction_validity_period"},"132":{"body":"type: Fraction Developer reward percentage.","breadcrumbs":"developer_reward_percentage","id":"132","title":"developer_reward_percentage"},"133":{"body":"type: Fraction Protocol treasury percentage.","breadcrumbs":"protocol_reward_percentage","id":"133","title":"protocol_reward_percentage"},"134":{"body":"type: Fraction Maximum inflation on the total supply every epoch.","breadcrumbs":"max_inflation_rate","id":"134","title":"max_inflation_rate"},"135":{"body":"type: Balance Total supply of tokens at genesis.","breadcrumbs":"total_supply","id":"135","title":"total_supply"},"136":{"body":"type: u64 Expected number of blocks per year","breadcrumbs":"num_blocks_per_year","id":"136","title":"num_blocks_per_year"},"137":{"body":"type: AccountId Protocol treasury account","breadcrumbs":"protocol_treasury_account","id":"137","title":"protocol_treasury_account"},"138":{"body":"For the specific economic specs, refer to Economics Section .","breadcrumbs":"protocol economics","id":"138","title":"protocol economics"},"139":{"body":"The structure that holds the parameters of the runtime, mostly economics.","breadcrumbs":"GenesisConfig » RuntimeConfig","id":"139","title":"RuntimeConfig"},"14":{"body":"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.","breadcrumbs":"Data Structures » Account without access keys","id":"14","title":"Account without access keys"},"140":{"body":"type: Balance The cost to store one byte of storage per block.","breadcrumbs":"GenesisConfig » storage_cost_byte_per_block","id":"140","title":"storage_cost_byte_per_block"},"141":{"body":"type: Balance Costs of different actions that need to be performed when sending and processing transaction and receipts.","breadcrumbs":"GenesisConfig » storage_cost_byte_per_block","id":"141","title":"storage_cost_byte_per_block"},"142":{"body":"type: BlockIndex The minimum number of blocks of storage rent an account has to maintain to prevent forced deletion.","breadcrumbs":"GenesisConfig » poke_threshold","id":"142","title":"poke_threshold"},"143":{"body":"type: RuntimeFeesConfig Costs of different actions that need to be performed when sending and processing transaction and receipts.","breadcrumbs":"GenesisConfig » transaction_costs","id":"143","title":"transaction_costs"},"144":{"body":"type: VMConfig , Config of wasm operations.","breadcrumbs":"GenesisConfig » wasm_config","id":"144","title":"wasm_config"},"145":{"body":"type: Balance The baseline cost to store account_id of short length per block. The original formula in NEP#0006 is 1,000 / (3 ^ (account_id.length - 2)) for cost per year. This value represents 1,000 above adjusted to use per block","breadcrumbs":"GenesisConfig » account_length_baseline_cost_per_block","id":"145","title":"account_length_baseline_cost_per_block"},"146":{"body":"Economic parameters for runtime","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeesConfig","id":"146","title":"RuntimeFeesConfig"},"147":{"body":"type: Fee Describes the cost of creating an action receipt, ActionReceipt, excluding the actual cost of actions.","breadcrumbs":"GenesisConfig » RuntimeConfig » action_receipt_creation_config","id":"147","title":"action_receipt_creation_config"},"148":{"body":"type: DataReceiptCreationConfig Describes the cost of creating a data receipt, DataReceipt.","breadcrumbs":"GenesisConfig » RuntimeConfig » data_receipt_creation_config","id":"148","title":"data_receipt_creation_config"},"149":{"body":"type: ActionCreationConfig Describes the cost of creating a certain action, Action. Includes all variants.","breadcrumbs":"GenesisConfig » RuntimeConfig » action_creation_config","id":"149","title":"action_creation_config"},"15":{"body":"","breadcrumbs":"Data Structures » Transaction","id":"15","title":"Transaction"},"150":{"body":"type: StorageUsageConfig Describes fees for storage rent","breadcrumbs":"GenesisConfig » RuntimeConfig » storage_usage_config","id":"150","title":"storage_usage_config"},"151":{"body":"type: Fraction Fraction of the burnt gas to reward to the contract account for execution.","breadcrumbs":"GenesisConfig » RuntimeConfig » burnt_gas_reward","id":"151","title":"burnt_gas_reward"},"152":{"body":"Describes the cost of creating an access key.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » AccessKeyCreationConfig","id":"152","title":"AccessKeyCreationConfig"},"153":{"body":"type: Fee Base cost of creating a full access access-key.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » full_access_cost","id":"153","title":"full_access_cost"},"154":{"body":"type: Fee Base cost of creating an access-key restricted to specific functions.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » function_call_cost","id":"154","title":"function_call_cost"},"155":{"body":"type: Fee Cost per byte of method_names of creating a restricted access-key.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » function_call_cost_per_byte","id":"155","title":"function_call_cost_per_byte"},"156":{"body":"Describes the cost of creating a specific action, Action. Includes all variants.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » action_creation_config","id":"156","title":"action_creation_config"},"157":{"body":"type: Fee Base cost of creating an account.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » create_account_cost","id":"157","title":"create_account_cost"},"158":{"body":"type: Fee Base cost of deploying a contract.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » deploy_contract_cost","id":"158","title":"deploy_contract_cost"},"159":{"body":"type: Fee Cost per byte of deploying a contract.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » deploy_contract_cost_per_byte","id":"159","title":"deploy_contract_cost_per_byte"},"16":{"body":"Near node consists roughly of a blockchain layer and a runtime layer. These layers are designed to be independent from each other: the blockchain layer can in theory support runtime that processes transactions differently, has a different virtual machine (e.g. RISC-V), has different fees; on the other hand the runtime is oblivious to where the transactions are coming from. It is not aware whether the blockchain it runs on is sharded, what consensus it uses, and whether it runs as part of a blockchain at all. The blockchain layer and the runtime layer share the following components and invariants:","breadcrumbs":"Architecture","id":"16","title":"Architecture"},"160":{"body":"type: Fee Base cost of calling a function.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » function_call_cost","id":"160","title":"function_call_cost"},"161":{"body":"type: Fee Cost per byte of method name and arguments of calling a function.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » function_call_cost_per_byte","id":"161","title":"function_call_cost_per_byte"},"162":{"body":"type: Fee Base cost of making a transfer.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » transfer_cost","id":"162","title":"transfer_cost"},"163":{"body":"type: Fee Base cost of staking.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » stake_cost","id":"163","title":"stake_cost"},"164":{"body":"type: AccessKeyCreationConfig Base cost of adding a key.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » add_key_cost:","id":"164","title":"add_key_cost:"},"165":{"body":"type: Fee Base cost of deleting a key.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » delete_key_cost","id":"165","title":"delete_key_cost"},"166":{"body":"type: Fee Base cost of deleting an account.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » delete_account_cost","id":"166","title":"delete_account_cost"},"167":{"body":"Describes the cost of creating a data receipt, DataReceipt.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » DataReceiptCreationConfig","id":"167","title":"DataReceiptCreationConfig"},"168":{"body":"type: Fee Base cost of creating a data receipt.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » base_cost","id":"168","title":"base_cost"},"169":{"body":"type: Fee Additional cost per byte sent.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » cost_per_byte","id":"169","title":"cost_per_byte"},"17":{"body":"Transactions and receipts are a fundamental concept in Near Protocol. Transactions represent actions requested by the blockchain user, e.g. send assets, create account, execute a method, etc. Receipts, on the other hand is an internal structure; think of a receipt as a message which is used inside a message-passing system. Transactions are created outside the Near Protocol node, by the user who sends them via RPC or network communication. Receipts are created by the runtime from transactions or as the result of processing other receipts. Blockchain layer cannot create or process transactions and receipts, it can only manipulate them by passing them around and feeding them to a runtime.","breadcrumbs":"Transactions and Receipts","id":"17","title":"Transactions and Receipts"},"170":{"body":"Describes cost of storage per block","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » StorageUsageConfig","id":"170","title":"StorageUsageConfig"},"171":{"body":"type: Gas Base storage usage for an account","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » account_cost","id":"171","title":"account_cost"},"172":{"body":"type: Gas Base cost for a k/v record","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » data_record_cost","id":"172","title":"data_record_cost"},"173":{"body":"type: Gas Cost per byte of key","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » key_cost_per_byte:","id":"173","title":"key_cost_per_byte:"},"174":{"body":"type: Gas Cost per byte of value","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » value_cost_per_byte: Gas","id":"174","title":"value_cost_per_byte: Gas"},"175":{"body":"type: Gas Cost per byte of contract code","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » code_cost_per_byte: Gas","id":"175","title":"code_cost_per_byte: Gas"},"176":{"body":"Costs associated with an object that can only be sent over the network (and executed by the receiver).","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » Fee","id":"176","title":"Fee"},"177":{"body":"Fee for sending an object from the sender to itself, guaranteeing that it does not leave","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » send_sir","id":"177","title":"send_sir"},"178":{"body":"Fee for sending an object potentially across the shards.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » send_not_sir","id":"178","title":"send_not_sir"},"179":{"body":"Fee for executing the object.","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » execution","id":"179","title":"execution"},"18":{"body":"Similar to Ethereum, Near Protocol is an account-based system. Which means that each blockchain user is roughly associated with one or several accounts (there are exceptions though, when users share an account and are separated through the access keys). The runtime is essentially a complex set of rules on what to do with accounts based on the information from the transactions and the receipts. It is therefore deeply aware of the concept of account. Blockchain layer however is mostly aware of the accounts through the trie (see below) and the validators (see below). Outside these two it does not operate on the accounts directly.","breadcrumbs":"Account-Based System","id":"18","title":"Account-Based System"},"180":{"body":"","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » Fraction","id":"180","title":"Fraction"},"181":{"body":"type: u64","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » numerator","id":"181","title":"numerator"},"182":{"body":"type: u64","breadcrumbs":"GenesisConfig » RuntimeConfig » RuntimeFeeConfig » denominator","id":"182","title":"denominator"},"183":{"body":"Config of wasm operations.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig","id":"183","title":"VMConfig"},"184":{"body":"type: ExtCostsConfig Costs for runtime externals","breadcrumbs":"GenesisConfig » RuntimeConfig » ext_costs:","id":"184","title":"ext_costs:"},"185":{"body":"type: u32 Gas cost of a growing memory by single page.","breadcrumbs":"GenesisConfig » RuntimeConfig » grow_mem_cost","id":"185","title":"grow_mem_cost"},"186":{"body":"type: u32 Gas cost of a regular operation.","breadcrumbs":"GenesisConfig » RuntimeConfig » regular_op_cost","id":"186","title":"regular_op_cost"},"187":{"body":"type: Gas Max amount of gas that can be used, excluding gas attached to promises.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_gas_burnt","id":"187","title":"max_gas_burnt"},"188":{"body":"type: u32 How tall the stack is allowed to grow?","breadcrumbs":"GenesisConfig » RuntimeConfig » max_stack_height","id":"188","title":"max_stack_height"},"189":{"body":"type: u32","breadcrumbs":"GenesisConfig » RuntimeConfig » initial_memory_pages","id":"189","title":"initial_memory_pages"},"19":{"body":"Every account at NEAR belongs to some shard. All the information related to this account also belongs to the same shard. The information includes: Balance Locked balance (for staking) Code of the contract Key-value storage of the contract All Access Keys Runtime assumes, it's the only information that is available for the contract execution. While other accounts may belong to the same shards, the Runtime never uses or provides them during contract execution. We can just assume that every account belongs to its own shard. So there is no reason to intentionally try to collocate accounts.","breadcrumbs":"Assume every account belongs to its own shard","id":"19","title":"Assume every account belongs to its own shard"},"190":{"body":"type: u32 The initial number of memory pages. What is the maximal memory pages amount is allowed to have for a contract.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_memory_pages","id":"190","title":"max_memory_pages"},"191":{"body":"type: u64 Limit of memory used by registers.","breadcrumbs":"GenesisConfig » RuntimeConfig » registers_memory_limit","id":"191","title":"registers_memory_limit"},"192":{"body":"type: u64 Maximum number of bytes that can be stored in a single register.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_register_size","id":"192","title":"max_register_size"},"193":{"body":"type: u64 Maximum number of registers that can be used simultaneously.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_number_registers","id":"193","title":"max_number_registers"},"194":{"body":"type: u64 Maximum number of log entries.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_number_logs","id":"194","title":"max_number_logs"},"195":{"body":"type: u64 Maximum length of a single log, in bytes.","breadcrumbs":"GenesisConfig » RuntimeConfig » max_log_len","id":"195","title":"max_log_len"},"196":{"body":"","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » ExtCostsConfig","id":"196","title":"ExtCostsConfig"},"197":{"body":"type: Gas Base cost for calling a host function.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » base","id":"197","title":"base"},"198":{"body":"type: Gas Base cost for guest memory read","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » read_memory_base","id":"198","title":"read_memory_base"},"199":{"body":"type: Gas Cost for guest memory read","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » read_memory_byte","id":"199","title":"read_memory_byte"},"2":{"body":"","breadcrumbs":"Terminology","id":"2","title":"Terminology"},"20":{"body":"Near Protocol is a stateful blockchain -- there is a state associated with each account and the user actions performed through transactions mutate that state. The state then is stored as a trie, and both the blockchain layer and the runtime layer are aware of this technical detail. The blockchain layer manipulates the trie directly. It partitions the trie between the shards to distribute the load. It synchronizes the trie between the nodes, and eventually it is responsible for maintaining the consistency of the trie between the nodes through its consensus mechanism and other game-theoretic methods. The runtime layer is also aware that the storage that it uses to perform the operations on is a trie. In general it does not have to know this technical detail and in theory we could have abstracted out the trie as a generic key-value storage. However, we allow some trie-specific operations that we expose to the smart contract developers so that they utilize Near Protocol to its maximum efficiency.","breadcrumbs":"Trie","id":"20","title":"Trie"},"200":{"body":"type: Gas Base cost for guest memory write","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » write_memory_base","id":"200","title":"write_memory_base"},"201":{"body":"type: Gas Cost for guest memory write per byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » write_memory_byte","id":"201","title":"write_memory_byte"},"202":{"body":"type: Gas Base cost for reading from register","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » read_register_base","id":"202","title":"read_register_base"},"203":{"body":"type: Gas Cost for reading byte from register","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » read_register_byte","id":"203","title":"read_register_byte"},"204":{"body":"type: Gas Base cost for writing into register","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » write_register_base","id":"204","title":"write_register_base"},"205":{"body":"type: Gas Cost for writing byte into register","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » write_register_byte","id":"205","title":"write_register_byte"},"206":{"body":"type: Gas Base cost of decoding utf8.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » utf8_decoding_base","id":"206","title":"utf8_decoding_base"},"207":{"body":"type: Gas Cost per bye of decoding utf8.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » utf8_decoding_byte","id":"207","title":"utf8_decoding_byte"},"208":{"body":"type: Gas Base cost of decoding utf16.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » utf16_decoding_base","id":"208","title":"utf16_decoding_base"},"209":{"body":"type: Gas Cost per bye of decoding utf16.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » utf16_decoding_byte","id":"209","title":"utf16_decoding_byte"},"21":{"body":"Even though tokens is a fundamental concept of the blockchain, it is neatly encapsulated inside the runtime layer together with the gas, fees, and rewards. The only way the blockchain layer is aware of the tokens and the gas is through the computation of the exchange rate and the inflation which is based strictly on the block production mechanics.","breadcrumbs":"Tokens and gas","id":"21","title":"Tokens and gas"},"210":{"body":"type: Gas Cost of getting sha256 base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » sha256_base","id":"210","title":"sha256_base"},"211":{"body":"type: Gas Cost of getting sha256 per byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » sha256_byte","id":"211","title":"sha256_byte"},"212":{"body":"type: Gas Cost of getting keccak256 base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » keccak256_base","id":"212","title":"keccak256_base"},"213":{"body":"type: Gas Cost of getting keccak256 per byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » keccak256_byte","id":"213","title":"keccak256_byte"},"214":{"body":"type: Gas Cost of getting keccak512 base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » keccak512_base","id":"214","title":"keccak512_base"},"215":{"body":"type: Gas Cost of getting keccak512 per byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » keccak512_byte","id":"215","title":"keccak512_byte"},"216":{"body":"type: Gas Cost for calling logging.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » log_base","id":"216","title":"log_base"},"217":{"body":"type: Gas Cost for logging per byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » log_byte","id":"217","title":"log_byte"},"218":{"body":"","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » Storage API","id":"218","title":"Storage API"},"219":{"body":"type: Gas Storage trie write key base cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_write_base","id":"219","title":"storage_write_base"},"22":{"body":"Both the blockchain layer and the runtime layer are aware of a special group of participants who are responsible for maintaining the integrity of the Near Protocol. These participants are associated with the accounts and are rewarded accordingly. The reward part is what the runtime layer is aware of, while everything around the orchestration of the validators is inside the blockchain layer.","breadcrumbs":"Validators","id":"22","title":"Validators"},"220":{"body":"type: Gas Storage trie write key per byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_write_key_byte","id":"220","title":"storage_write_key_byte"},"221":{"body":"type: Gas Storage trie write value per byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_write_value_byte","id":"221","title":"storage_write_value_byte"},"222":{"body":"type: Gas Storage trie write cost per byte of evicted value.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_write_evicted_byte","id":"222","title":"storage_write_evicted_byte"},"223":{"body":"type: Gas Storage trie read key base cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_read_base","id":"223","title":"storage_read_base"},"224":{"body":"type: Gas Storage trie read key per byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_read_key_byte","id":"224","title":"storage_read_key_byte"},"225":{"body":"type: Gas Storage trie read value cost per byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_read_value_byte","id":"225","title":"storage_read_value_byte"},"226":{"body":"type: Gas Remove key from trie base cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_remove_base","id":"226","title":"storage_remove_base"},"227":{"body":"type: Gas Remove key from trie per byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_remove_key_byte","id":"227","title":"storage_remove_key_byte"},"228":{"body":"type: Gas Remove key from trie ret value byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_remove_ret_value_byte","id":"228","title":"storage_remove_ret_value_byte"},"229":{"body":"type: Gas Storage trie check for key existence cost base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_has_key_base","id":"229","title":"storage_has_key_base"},"23":{"body":"Interestingly, the following concepts are for the blockchain layer only and the runtime layer is not aware of them: Sharding -- the runtime layer does not know that it is being used in a sharded blockchain, e.g. it does not know that the trie it works on is only a part of the overall blockchain state; Blocks or chunks -- the runtime does not know that the receipts that it processes constitute a chunk and that the output receipts will be used in other chunks. From the runtime perspective it consumes and outputs batches of transactions and receipts; Consensus -- the runtime does not know how consistency of the state is maintained; Communication -- the runtime don't know anything about the current network topology. Receipt has only a receiver_id (a recipient account), but knows nothing about the destination shard, so it's a responsibility of a blockchain layer to route a particular receipt.","breadcrumbs":"Blockchain Layer Concepts","id":"23","title":"Blockchain Layer Concepts"},"230":{"body":"type: Gas Storage trie check for key existence per key byte","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_has_key_byte","id":"230","title":"storage_has_key_byte"},"231":{"body":"type: Gas Create trie prefix iterator cost base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_create_prefix_base","id":"231","title":"storage_iter_create_prefix_base"},"232":{"body":"type: Gas Create trie prefix iterator cost per byte.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_create_prefix_byte","id":"232","title":"storage_iter_create_prefix_byte"},"233":{"body":"type: Gas Create trie range iterator cost base","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_create_range_base","id":"233","title":"storage_iter_create_range_base"},"234":{"body":"type: Gas Create trie range iterator cost per byte of from key.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_create_from_byte","id":"234","title":"storage_iter_create_from_byte"},"235":{"body":"type: Gas Create trie range iterator cost per byte of to key.","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_create_to_byte","id":"235","title":"storage_iter_create_to_byte"},"236":{"body":"type: Gas Trie iterator per key base cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_next_base","id":"236","title":"storage_iter_next_base"},"237":{"body":"type: Gas Trie iterator next key byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_next_key_byte","id":"237","title":"storage_iter_next_key_byte"},"238":{"body":"type: Gas Trie iterator next key byte cost","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » storage_iter_next_value_byte","id":"238","title":"storage_iter_next_value_byte"},"239":{"body":"type: Gas Cost per touched trie node","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » touching_trie_node","id":"239","title":"touching_trie_node"},"24":{"body":"Fees and rewards -- fees and rewards are neatly encapsulated in the runtime layer. The blockchain layer, however has an indirect knowledge of them through the computation of the tokens-to-gas exchange rate and the inflation.","breadcrumbs":"Runtime Layer Concepts","id":"24","title":"Runtime Layer Concepts"},"240":{"body":"","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » Promise API","id":"240","title":"Promise API"},"241":{"body":"type: Gas Cost for calling promise_and","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » promise_and_base","id":"241","title":"promise_and_base"},"242":{"body":"type: Gas Cost for calling promise_and for each promise","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » promise_and_per_promise","id":"242","title":"promise_and_per_promise"},"243":{"body":"type: Gas Cost for calling promise_return","breadcrumbs":"GenesisConfig » RuntimeConfig » VMConfig » promise_return","id":"243","title":"promise_return"},"244":{"body":"type: Enum Enum that describes one of the records in the state storage.","breadcrumbs":"GenesisConfig » RuntimeConfig » StateRecord","id":"244","title":"StateRecord"},"245":{"body":"type: Unnamed struct Record that contains account information for a given account ID.","breadcrumbs":"GenesisConfig » RuntimeConfig » Account","id":"245","title":"Account"},"246":{"body":"type: AccountId The account ID of the account.","breadcrumbs":"GenesisConfig » RuntimeConfig » account_id","id":"246","title":"account_id"},"247":{"body":"type: Account The account structure. Serialized to JSON. U128 types are serialized to strings.","breadcrumbs":"GenesisConfig » RuntimeConfig » account","id":"247","title":"account"},"248":{"body":"type: Unnamed struct Record that contains key-value data record for a contract at the given account ID.","breadcrumbs":"GenesisConfig » RuntimeConfig » Data","id":"248","title":"Data"},"249":{"body":"type: AccountId The account ID of the contract that contains this data record.","breadcrumbs":"GenesisConfig » RuntimeConfig » account_id","id":"249","title":"account_id"},"25":{"body":"TBD","breadcrumbs":"Chain Specification","id":"25","title":"Chain Specification"},"250":{"body":"type: Vec Data Key serialized in Base64 format. NOTE: Key doesn't contain the data separator.","breadcrumbs":"GenesisConfig » RuntimeConfig » data_key","id":"250","title":"data_key"},"251":{"body":"type: Vec Value serialized in Base64 format.","breadcrumbs":"GenesisConfig » RuntimeConfig » value","id":"251","title":"value"},"252":{"body":"type: Unnamed struct Record that contains a contract code for a given account ID.","breadcrumbs":"GenesisConfig » RuntimeConfig » Contract","id":"252","title":"Contract"},"253":{"body":"type: AccountId The account ID of that has the contract.","breadcrumbs":"GenesisConfig » RuntimeConfig » account_id","id":"253","title":"account_id"},"254":{"body":"type: Vec WASM Binary contract code serialized in Base64 format.","breadcrumbs":"GenesisConfig » RuntimeConfig » code","id":"254","title":"code"},"255":{"body":"type: Unnamed struct Record that contains an access key for a given account ID.","breadcrumbs":"GenesisConfig » RuntimeConfig » AccessKey","id":"255","title":"AccessKey"},"256":{"body":"type: AccountId The account ID of the access key owner.","breadcrumbs":"GenesisConfig » RuntimeConfig » account_id","id":"256","title":"account_id"},"257":{"body":"type: [PublicKey] The public key for the access key in JSON-friendly string format. E.g. ed25519:5JFfXMziKaotyFM1t4hfzuwh8GZMYCiKHfqw1gTEWMYT","breadcrumbs":"GenesisConfig » RuntimeConfig » public_key","id":"257","title":"public_key"},"258":{"body":"type: AccessKey The access key serialized in JSON format.","breadcrumbs":"GenesisConfig » RuntimeConfig » access_key","id":"258","title":"access_key"},"259":{"body":"type: Box< Receipt > Record that contains a receipt that was postponed on a shard (e.g. it's waiting for incoming data). The receipt is in JSON-friendly format. The receipt can only be an ActionReceipt. NOTE: Box is used to decrease fixed size of the entire enum.","breadcrumbs":"GenesisConfig » RuntimeConfig » PostponedReceipt","id":"259","title":"PostponedReceipt"},"26":{"body":"","breadcrumbs":"Chain specification » Consensus","id":"26","title":"Consensus"},"260":{"body":"type: Unnamed struct Record that contains information about received data for some action receipt, that is not yet received or processed for a given account ID. The data is received using DataReceipt before. See Receipts for details.","breadcrumbs":"GenesisConfig » RuntimeConfig » ReceivedData","id":"260","title":"ReceivedData"},"261":{"body":"type: AccountId The account ID of the receiver of the data.","breadcrumbs":"GenesisConfig » RuntimeConfig » account_id","id":"261","title":"account_id"},"262":{"body":"type: [CryptoHash] Data ID of the data in base58 format.","breadcrumbs":"GenesisConfig » RuntimeConfig » data_id","id":"262","title":"data_id"},"263":{"body":"type: Option > Optional data encoded as base64 format or null in JSON.","breadcrumbs":"GenesisConfig » RuntimeConfig » data","id":"263","title":"data"},"264":{"body":"type: Box< Receipt > Record that contains a receipt that was delayed on a shard. It means the shard was overwhelmed with receipts and it processes receipts from backlog. The receipt is in JSON-friendly format. See Delayed Receipts for details. NOTE: Box is used to decrease fixed size of the entire enum.","breadcrumbs":"GenesisConfig » RuntimeConfig » DelayedReceipt","id":"264","title":"DelayedReceipt"},"265":{"body":"This is under heavy development","breadcrumbs":"Economics","id":"265","title":"Economics"},"266":{"body":"Name Value yoctoNEAR smallest undividable amount of native currency NEAR . NEAR 10**24 yoctoNEAR block smallest on-chain unit of time gas unit to measure usage of blockchain","breadcrumbs":"Units","id":"266","title":"Units"},"267":{"body":"Name Value INITIAL_SUPPLY 10**33 yoctoNEAR MIN_GAS_PRICE 10**5 yoctoNEAR REWARD_PCT_PER_YEAR 0.05 EPOCH_LENGTH 43,200 blocks EPOCHS_A_YEAR 730 epochs INITIAL_MAX_STORAGE 10 * 2**40 bytes == 10 TB TREASURY_PCT 0.1 TREASURY_ACCOUNT_ID treasury CONTRACT_PCT 0.3 INVALID_STATE_SLASH_PCT 0.05 ADJ_FEE 0.001 TOTAL_SEATS 100 ONLINE_THRESHOLD_MIN 0.9 ONLINE_THRESHOLD_MAX 0.99 BLOCK_PRODUCER_KICKOUT_THRESHOLD 0.9 CHUNK_PRODUCER_KICKOUT_THRESHOLD 0.6","breadcrumbs":"General Parameters","id":"267","title":"General Parameters"},"268":{"body":"Name Description Initial value totalSupply[t] Total supply of NEAR at given epoch[t] INITIAL_SUPPLY gasPrice[t] The cost of 1 unit of gas in NEAR tokens (see Transaction Fees section below) MIN_GAS_PRICE storageAmountPerByte[t] keeping constant, INITIAL_SUPPLY / INITIAL_MAX_STORAGE ~9.09 * 10**19 yoctoNEAR","breadcrumbs":"General Variables","id":"268","title":"General Variables"},"269":{"body":"The protocol sets a ceiling for the maximum issuance of tokens, and dynamically decreases this issuance depending on the amount of total fees in the system. Name Description reward[t] totalSupply[t] * ((1 - REWARD_PCT_PER_YEAR) ** (1/EPOCHS_A_YEAR) - 1) epochFee[t] sum([(1 - DEVELOPER_PCT_PER_YEAR) * block.txFee + block.stateFee for block in epoch[t]]) issuance[t] The amount of token issued at a certain epoch[t], issuance[t] = reward[t] - epochFee[t] Where totalSupply[t] is the total number of tokens in the system at a given time t . If epochFee[t] > reward[t] the issuance is negative, thus the totalSupply[t] decreases in given epoch.","breadcrumbs":"Issuance","id":"269","title":"Issuance"},"27":{"body":"For the purpose of maintaining consensus, transactions are grouped into blocks . There is a single preconfigured block \\(G\\) called genesis block . Every block except \\(G\\) has a link pointing to the previous block \\(prev(B)\\), where \\(B\\) is the block, and \\(G\\) is reachable from every block by following those links (that is, there are no cycles). The links between blocks give rise to a partial order: for blocks \\(A\\) and \\(B\\), \\(A < B\\) means that \\(A \\ne B\\) and \\(A\\) is reachable from \\(B\\) by following links to previous blocks, and \\(A \\le B\\) means that \\(A < B\\) or \\(A = B\\). The relations \\(>\\) and \\(\\ge\\) are defined as the reflected versions of \\(<\\) and \\(\\le\\), respectively. Finally, \\(A \\sim B\\) means that either \\(A < B\\), \\(A = B\\) or \\(A > B\\), and \\(A \\nsim B\\) means the opposite. A chain \\(chain(T)\\) is a set of blocks reachable from block \\(T\\), which is called its tip . That is, \\(chain(T) = \\{B | B \\le T\\}\\). For any blocks \\(A\\) and \\(B\\), there is a chain that both \\(A\\) and \\(B\\) belong to iff \\(A \\sim B\\). In this case, \\(A\\) and \\(B\\) are said to be on the same chain . Each block has an integer height \\(h(B)\\). It is guaranteed that block heights are monotonic (that is, for any block \\(B \\ne G\\), \\(h(B) > h(prev(B))\\)), but they need not be consecutive. Also, \\(h(G)\\) may not be zero. Each node keeps track of a valid block with the largest height it knows about, which is called its head . Blocks are grouped into epochs . In a chain, the set of blocks that belongs to some epoch forms a contiguous range: if blocks \\(A\\) and \\(B\\) such that \\(A < B\\) belong to the same epoch, then every block \\(X\\) such that \\(A < X < B\\) also belongs to that epoch. Epochs can be identified by sequential indices: \\(G\\) belongs to an epoch with index \\(0\\), and for every other block \\(B\\), the index of its epoch is either the same as that of \\(prev(B)\\), or one greater. Each epoch is associated with a set of block producers that are validating blocks in that epoch, as well as an assignment of block heights to block producers that are responsible for producing a block at that height. A block producer responsible for producing a block at height \\(h\\) is called block proposer at \\(h\\) . This information (the set and the assignment) for an epoch with index \\(i \\ge 2\\) is determined by the last block of the epoch with index \\(i-2\\). For epochs with indices \\(0\\) and \\(1\\), this information is preconfigured. Therefore, if two chains share the last block of some epoch, they will have the same set and the same assignment for the next two epochs, but not necessarily for any epoch after that. The consensus protocol defines a notion of finality . Informally, if a block \\(B\\) is final, any future final blocks may only be built on top of \\(B\\). Therefore, transactions in \\(B\\) and preceding blocks are never going to be reversed. Finality is not a function of a block itself, rather, a block may be final or not final in some chain it is a member of. Specifically, \\(final(B, T)\\), where \\(B \\le T\\), means that \\(B\\) is final in \\(chain(T)\\). A block that is final in a chain is final in all of its extensions: specifically, if \\(final(B, T)\\) is true, then \\(final(B, T')\\) is also true for all \\(T' \\ge T\\).","breadcrumbs":"Chain specification » Definitions and notation","id":"27","title":"Definitions and notation"},"270":{"body":"Each transaction before inclusion must buy gas enough to cover the cost of bandwidth and execution. Gas unifies execution and bytes of bandwidth usage of blockchain. Each WASM instruction or pre-compiled function gets assigned an amount of gas based on measurements on common-denominator computer. Same goes for weighting the used bandwidth based on general unified costs. For specific gas mapping numbers see ??? . Gas is priced dynamically in NEAR tokens. At each block t, we update gasPrice[t] = gasPrice[t - 1] * (gasUsed[t - 1] / gasLimit[t - 1] - 0.5) * ADJ_FEE. Where gasUsed[t] = sum([sum([gas(tx) for tx in chunk]) for chunk in block[t]]). gasLimit[t] is defined as gasLimit[t] = gasLimit[t - 1] + validatorGasDiff[t - 1], where validatorGasDiff is parameter with which each chunk producer can either increase or decrease gas limit based on how long it to execute the previous chunk. validatorGasDiff[t] can be only within ±0.1% of gasLimit[t] and only if gasUsed[t - 1] > 0.9 * gasLimit[t - 1].","breadcrumbs":"Transaction Fees","id":"270","title":"Transaction Fees"},"271":{"body":"Amount of NEAR on the account represents right for this account to take portion of the blockchain's overall global state. Transactions fail if account doesn't have enough balance to cover the storage required for given account. def check_storage_cost(account): # Compute requiredAmount given size of the account. requiredAmount = sizeOf(account) * storageAmountPerByte return Ok() if account.amount + account.locked < requiredAmount else Error(requiredAmount) # Check when transaction is received to verify that it is valid.\ndef verify_transaction(tx, signer_account): # ... # Updates signer's account with the amount it will have after executing this tx. update_post_amount(signer_account, tx) result = check_storage_cost(signer_account) # If enough balance OR account is been deleted by the owner. if not result.ok() or DeleteAccount(tx.signer_id) in tx.actions: assert LackBalanceForState(signer_id: tx.signer_id, amount: result.err()) # After account touched / changed, we check it still has enough balance to cover it's storage.\ndef on_account_change(block_height, account): # ... execute transaction / receipt changes ... # Validate post-condition and revert if it fails. result = check_storage_cost(sender_account) if not result.ok(): assert LackBalanceForState(signer_id: tx.signer_id, amount: result.err()) Where sizeOf(account) includes size of account_id, account structure and size of all the data stored under the account. Account can end up with not enough balance in case it gets slashed. Account will become unusable as all orginating transactions will fail (including deletion). The only way to recover it in this case is by sending extra funds from a different accounts.","breadcrumbs":"State Stake","id":"271","title":"State Stake"},"272":{"body":"NEAR validators provide their resources in exchange for a reward epochReward[t], where [t] represents the considered epoch Name Description epochReward[t] = coinbaseReward[t] + epochFee[t] coinbaseReward[t] The maximum inflation per epoch[t], as a function of REWARD_PCT_PER_YEAR / EPOCHS_A_YEAR","breadcrumbs":"Validators","id":"272","title":"Validators"},"273":{"body":"Name Description proposals: Proposal[] The array of all new staking transactions that have happened during the epoch (if one account has multiple only last one is used) current_validators The array of all existing validators during the epoch epoch[T] The epoch when validator[v] is selected from the proposals auction array seat_price The minimum stake needed to become validator in epoch[T] stake[v] The amount in NEAR tokens staked by validator[v] during the auction at the end of epoch[T-2], minus INCLUSION_FEE shard[v] The shard is randomly assigned to validator[v] at epoch[T-1], such that its node can download and sync with its state num_allocated_seats[v] Number of seats assigned to validator[v], calculated from stake[v]/seatPrice validatorAssignments The resulting ordered array of all proposals with a stake higher than seatPrice struct Proposal { account_id: AccountId, stake: Balance, public_key: PublicKey,\n} During the epoch, outcome of staking transactions produce proposals, which are collected, in the form of Proposals. At the end of every epoch T, next algorithm gets executed to determine validators for epoch T + 2: For every validator in current_validators determine num_blocks_produced, num_chunks_produced based on what they produced during the epoch. Remove validators, for whom num_blocks_produced < num_blocks_expected * BLOCK_PRODUCER_KICKOUT_THRESHOLD or num_chunks_produced < num_chunks_expected * CHUNK_PRODUCER_KICKOUT_THRESHOLD. Add validators from proposals, if validator is also in current_validators, considered stake of the proposal is 0 if proposal.stake == 0 else proposal.stake + reward[proposal.account_id]. Find seat price seat_price = findSeatPrice(current_validators - kickedout_validators + proposals, num_seats), where each validator gets floor(stake[v] / seat_price) seats and seat_price is highest integer number such that total number of seats is at least num_seats. Filter validators and proposals to only those with stake greater or equal than seat price. For every validator, replicate them by number of seats they get floor(stake[v] / seat_price). Randomly shuffle (TODO: define random number sampler) with seed from randomness generated on the last block of current epoch (via VRF(block_producer.private_key, block_hash)). Cut off all seats which are over the num_seats needed. Use this set for block producers and shifting window over it as chunk producers. def findSeatPrice(stakes, num_seats): \"\"\"Find seat price given set of stakes and number of seats required. Seat price is highest integer number such that if you sum `floor(stakes[i] / seat_price)` it is at least `num_seats`. \"\"\" stakes = sorted(stakes) total_stakes = sum(stakes) assert total_stakes >= num_seats, \"Total stakes should be above number of seats\" left, right = 1, total_stakes + 1 while True: if left == right - 1: return left mid = (left + right) // 2 sum = 0 for stake in stakes: sum += stake // mid if sum >= num_seats: left = mid break right = mid","breadcrumbs":"Validator Selection","id":"273","title":"Validator Selection"},"274":{"body":"Name Value epochFee[t] sum([(1 - DEVELOPER_PCT_PER_YEAR) * txFee[i]]), where [i] represents any considered block within the epoch[t] Note: all calculations are done in Rational numbers first with final result converted into integer with rounding down. Total reward every epoch t is equal to: reward[t] = totalSupply * ((1 + REWARD_PCT_PER_YEAR) ** (1 / EPOCHS_A_YEAR) - 1) Uptime of a specific validator is computed: pct_online[t][j] = (num_produced_blocks[t][j] / expected_produced_blocks[t][j] + num_produced_chunks[t][j] / expected_produced_chunks[t][j]) / 2\nif pct_online > ONLINE_THRESHOLD: uptime[t][j] = min(1., (pct_online[t][j] - ONLINE_THRESHOLD_MIN) / (ONLINE_THRESHOLD_MAX - ONLINE_THRESHOLD_MIN))\nelse: uptime[t][j] = 0. Where expected_produced_blocks and expected_produced_chunks is the number of blocks and chunks respectively that is expected to be produced by given validator j in the epoch t. The specific validator[t][j] reward for epoch t is then proportional to the fraction of stake of this validator from total stake: validatorReward[t][j] = (uptime[t][j] * stake[t][j] * reward[t]) / total_stake[t]","breadcrumbs":"Rewards Calculation","id":"274","title":"Rewards Calculation"},"275":{"body":"ChunkProofs # Check that chunk is invalid, because the proofs in header don't match the body.\ndef chunk_proofs_condition(chunk): # TODO # At the end of the epoch, run update validators and\n# determine how much to slash validators.\ndef end_of_epoch_update_validators(validators): # ... for validator in validators: if validator.is_slashed: validator.stake -= INVALID_STATE_SLASH_PCT * validator.stake ChunkState # Check that chunk header post state root is invalid, # because the execution of previous chunk doesn't lead to it.\ndef chunk_state_condition(prev_chunk, prev_state, chunk_header): # TODO # At the end of the epoch, run update validators and\n# determine how much to slash validators.\ndef end_of_epoch(..., validators): # ... for validator in validators: if validator.is_slashed: validator.stake -= INVALID_STATE_SLASH_PCT * validator.stake","breadcrumbs":"Slashing","id":"275","title":"Slashing"},"276":{"body":"Treasury account TREASURY_ACCOUNT_ID receives fraction of reward every epoch t: # At the end of the epoch, update treasury\ndef end_of_epoch(..., reward): # ... accounts[TREASURY_ACCOUNT_ID].amount = TREASURY_PCT * reward","breadcrumbs":"Protocol Treasury","id":"276","title":"Protocol Treasury"},"277":{"body":"Fungible Token Standard","breadcrumbs":"Standards","id":"277","title":"Standards"},"278":{"body":"","breadcrumbs":"Standards » Fungible Token","id":"278","title":"Fungible Token"},"279":{"body":"A standard interface for fungible tokens allowing for ownership, escrow and transfer, specifically targeting third-party marketplace integration.","breadcrumbs":"Standards » Summary","id":"279","title":"Summary"},"28":{"body":"The fields in the Block header relevant to the consensus process are: struct BlockHeader { ... prev_hash: BlockHash, height: BlockHeight, epoch_id: EpochId, last_final_block_hash: BlockHash, approvals: Vec