import Tabs from ‘@theme/Tabs’;
import TabItem from ‘@theme/TabItem’;
import TableAs from "./table.as.md";
import TableRs from "./table.rs.md";
import TableJs from "./table.js.md";
Every method execution has a environment associated with information such as:
- Who called the method
- How much money is attached to the call
- How many computational resources are available
- The current timestamp
Who is Calling? Who am I?
The environment gives you access to 3 important users: the
predecessor, and the
current_account contains the address in which your contract is deployed. This is very useful to implement ownership, e.g. making a public method only callable by the contract itself.
Predecessor and Signer
predecessor is the account that called the method in the contract. Meanwhile, the
signer is the account that signed the initial transaction.
During a simple transaction (no cross-contract calls) the
predecessor is the same as the
signer. For example, if alice.near calls contract.near, from the contract’s perspective, alice.near is both the
signer and the
predecessor. However, if contract.near creates a cross-contract call, then the
predecessor changes down the line. In the example bellow, when pool.near executes, it would see contract.near as the
predecessor and alice.near as the
- You can access information about the users interacting with your smart contract
In most scenarios you will only need to know the predecessor. However, there are situations in which the signer is very useful. For example, when adding NFTs into this marketplace, the contract checks that the
signer, i.e. the person who generated the transaction chain, is the NFT owner.
Balances and Attached NEAR
The environment gives you access to 3 token-related parameters, all expressed in yoctoNEAR (1 Ⓝ = 1024yⓃ):
attached_deposit represents the amount of yoctoNEAR the predecessor attached to the call.
- This amount is already deposited in your contract’s account, and is automatically returned to the
predecessorif your method panics.
account_balance represents the balance of your contract (
It includes the
attached_deposit, since it was deposited when the method execution started.
If the contract has any locked $NEAR, it will appear in
storage_usedrepresents the amount of storage that is currently being used by your contract.
If you want to know how much storage a structure uses, print the storage before and after storing it.
Telling the Time
The environment exposes three different ways to tell the pass of time, each representing a different dimension of the underlying blockchain.
timestamp attribute represents the approximated UNIX timestamp at which this call was executed. It quantifies time passing in a human way, enabling to check if a specific date has passed or not.
The NEAR blockchain groups blocks in Epochs. The
current_epoch attribute measures how many epochs have passed so far. It is very useful to coordinate with other contracts that measure time in epochs, such as the validators.
block_index represents the index of the block in which this transaction will be added to the blockchain.
Your contract has a limited number of computational resources to use on each call. Such resources are measured in Gas.
Gas can be thought of as wall time, where 1 PetaGas (1_000 TGas) is ~1 second of compute time.
Each code instruction costs a certain amount of Gas, and if you run out of it the execution halts with the error message
Exceeded the prepaid gas.
The environment gives you access to two gas-related arguments:
prepaid_gas represents the amount of Gas the
predecessor attached to this call. It cannot exceed the limit 300TGas (300 * 1012 Gas).
used_gascontains the amount of Gas that has been used so far. It is useful to estimate the Gas cost of running a method.
During cross-contract calls always make sure the callback has enough Gas to fully execute.
If you already estimated the Gas a method needs, you can ensure it never runs out of Gas by using
const REQUIRED_GAS: Gas = Gas(20_000_000_000_000); // 20 TGas
assert!(env::prepaid_gas() >= REQUIRED_GAS, “Please attach at least 20 TGas”);
const TGas: u64 = 1000000000000;
assert(context.prepaidGas >= 20*TGas, “Please attach at least 20 TGas”);