Skip to main content

Environment

Every method execution has an environment associated with information such as:

  1. Who called the method
  2. How much money is attached to the call
  3. How many computational resources are available
  4. The current timestamp
  5. Helper functions for Public Key derivation, for example

Environment Variablesโ€‹

Variable NameSDK VariableDescription
Predecessornear.predecessorAccountId()Account ID that called this method
Current Accountnear.currentAccountId()Account ID of this smart contract
Signernear.signerAccountId()Account ID that signed the transaction leading to this execution
Attached Depositnear.attachedDeposit()Amount in NEAR attached to the call by the predecessor
Account Balancenear.accountBalance()Balance of this smart contract (including Attached Deposit)
Prepaid Gasnear.prepaidGas()Amount of gas available for execution
Timestampnear.blockTimestamp()Current timestamp (number of non-leap-nanoseconds since January 1, 1970 0:00:00 UTC)
Current Epochnear.epochHeight()Current epoch in the blockchain
Block Indexnear.blockIndex()Current block index (a.k.a. block height)
Storage Usednear.storageUsage()Current storage used by this smart contract
Used Gasnear.usedGas()Amount of gas used for execution
Signer Public Keynear.signerAccountPk()Sender Public Key
Account Locked Balancenear.accountLockedBalance()Balance of this smart contract that is locked

Who is Calling? Who am I?โ€‹

The environment gives you access to 3 important users: the current_account, the predecessor, and the signer.

Current Accountโ€‹

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โ€‹

The 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 below, when pool.near executes, it would see contract.near as the predecessor and alice.near as the signer.

img You can access information about the users interacting with your smart contract

tip

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โ€‹

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 predecessor if your method panics.

warning

If you make a cross-contract call and it panics, the funds are sent back to your contract. See how to handle this situation in the callback section

Account Balanceโ€‹

account_balance represents the balance of your contract (current_account).

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 account_locked_balance.


Storage Usedโ€‹

storage_used represents the amount of storage that is currently being used by your contract.

tip

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โ€‹

The timestamp attribute represents the approximated UNIX timestamp in nanoseconds at which this call was executed. It quantifies time passing in a human way, enabling us to check if a specific date has passed or not.

Current Epochโ€‹

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โ€‹

The block_index represents the index of the block in which this transaction will be added to the blockchain.


Gasโ€‹

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 and used_gas.

Prepaid Gasโ€‹

prepaid_gas represents the amount of Gas the predecessor attached to this call. It cannot exceed the limit 300TGas (300 * 1012 Gas).

Used Gasโ€‹

used_gas contains the amount of Gas that has been used so far. It is useful to estimate the Gas cost of running a method.

warning

During cross-contract calls always make sure the callback has enough Gas to fully execute.

tip

If you already estimated the Gas a method needs, you can ensure it never runs out of Gas by using assert

const REQUIRED_GAS: Gas = Gas(20_000_000_000_000); // 20 TGas
assert!(env::prepaid_gas() >= REQUIRED_GAS, "Please attach at least 20 TGas");

Environment Functionsโ€‹

Besides environmental variables, the SDK also exposes some functions to perform basic cryptographic operations

Function NameSDK methodDescription
SHA 256near.sha256(value)Hashes a sequence of bytes using sha256.
Keccak 256near.keccak256(value)Hashes a sequence of bytes using keccak256.
Keccak 512near.keccak512(value)Hashes a sequence of bytes using keccak512.
RIPEMD 160near.ripemd160(value)Hashes the bytes using the RIPEMD-160 hash function.
EC Recovernear.ecrecover(hash, sig, v, malleabilityFlag)Recovers an ECDSA signer address from a 32-byte message hash and a corresponding signature along with v recovery byte. Takes in an additional flag to check for malleability of the signature which is generally only ideal for transactions. Returns 64 bytes representing the public key if the recovery was successful.
Log Stringnear.log(msg)Logs the string message. This message is stored on chain.
Validator Stakenear.validatorStake(accountId)For a given account return its current stake. If the account is not a validator, returns 0.
Validator Total Stakenear.validatorTotalStake()Returns the total stake of validators in the current epoch.
info

In the JS SDK, throw new Error("message") mimics the behavior of Rust's env::panic_str("message").


Was this page helpful?