How does wrap.near contract operate in NEAR Protocol? - nearprotocol

It seems wNEAR is baked by wrap.near contract, but how does it work?

wrap.near holds w-near contract, which is FT [fungible token] implementation based on NEP-141 standard.
The idea is simple, you send native NEAR tokens and the contract keeps track of the balance of the sender account in its local storage, and there is a reverse operation which allows you to instruct the contract to send NEAR tokens back.
This FT always matches native NEAR token 1:1. "Wrapped" prefix in the name (wrapped NEAR or wNEAR) implies that it just turns native token into FT token. It was created to be compatible with Rainbow Bridge (Aurora) interfaces which allows to transfer FT across NEAR network <> Ethereum network (by locking the tokens in a contract on one network and unlocking the equivalent amount of tokens from a contract that is deployed on the other network).
So getting back to the technical implementation of w-near contract, you can find three core methods:
near_deposit expects NEAR native tokens attached to the function call, and those attached tokens will be deposited to wrap.near account, and in exchange the contract implementation will save a record in the storage that those tokens belong to the account that sent them
near_withdraw deducts the amount of tokens recorded for the account that called this function and sends a transfer of native NEAR tokens back to the caller
ft_transfer (it is implemented by near-sdk-rs helper) virtually transfers the wNEAR FT tokens by updating the records inside the contract storage. NOTE: there is no native transfer involved here, so the transaction will go from tokens sender to wrap.near contract, which will update the balances of the sender and receiver accordingly, and the receiver account will never receive a native NEAR call or NEAR tokens (until he/she calls near_withdraw)

Related

Why the transferable to smart contract is deducted?

I uploaded and created a new smart contract. I sent 1000 units to this smart contract.
However when the contract is deployed the transferable is not equal to 1000.
And when I execute any function it also deducts the transferable.
Is there any way to prevent this. I want to deduct user token instead of the smart contract token. In Ethereum, the user token is deducted.
I want to deduct user token instead of the smart contract token. In Ethereum, the user token is deducted.
I think there is a misunderstanding here, you probably understood the deducted tokens as gas. But gas is deducted from the instantiating account (what you referred to as "user token"), same as in Ethereum.
The amount that is deducted from the contract here is state rent ‒ i.e. the contract has to regularly pay for the amount of state and code storage it uses. This is a concept which is currently used by the contracts pallet to reduce state bloat. I won't link to the documentation here though, since a new paradigm will be introduced soon, making it obsolete.

How to see the storage usage in NEAR protocol?

I learned that data storage on NEAR protocol requires to stake NEAR tokens. Is there a way to monitor the total amount of data stored on chain? Didn't find it on NEAR Explorer (or perhaps didn't look at the right place)
The increase/decrease in storage use automatically locks some of the tokens on the account. Explorer displays "STORAGE USED" on the account details page (example). mainnet is configured (see EXPERIMENTAL_protocol_config JSON RPC method for other config options) to have "storage_amount_per_byte": "100000000000000000000", which means that 100kb of data (smart contract code, smart contract state, account access keys, and profile data [liquid balance, locked balance, account id]) locks 1 NEAR on your account (so you just cannot transfer/spend those tokens unless you remove something from the storage).

How to view data in NEAR protocol contract for free?

Should I pay for every read from NEAR protocol?
How do I view the value stored in NEAR protocol smart contract? (e.g. staking pool fees)
What is the difference between view and change methods?
Should I pay for every read from NEAR protocol?
TL;DR: No, you should not.
In NEAR protocol there are to ways to interact with smart contracts:
Submit a transaction with a FunctionCall action, which will get the specified method executed on the chunk producing nodes and the result will be provable through the blockchain (in terms of near-api-js these are "change methods")
Call query(call_function) JSON RPC method, which will get the specified method executed on the RPC node itself in a read-only environment, and the call will never be recorded/proved through the blockchain (in terms of near-api-js these are "view methods")
You can change the state and chained operations (e.g. cross-contract calls, tokens transfer, or access key addition/deletion) only through the first approach since blockchain expects the user to cover the execution costs, so the user should sign their transaction, and they will get charged for the execution.
Sometimes, you don't need to change the state, instead, you only want to read a value stored on the chain, and paying for it is suboptimal (though if you need to prove that the operation has been made it might still be desirable). In this case, you would prefer the second approach. Calling a method through JSON RPC is free of charge and provides a limited context during the contract execution, but it is enough in some scenarios (e.g. when you want to check what is the staking pool fee, or who is the owner of the contract, etc).

Dealing with promise chain failures in NEAR blockchain

I am writing a set of interacting smart contracts for a NEAR blockchain. Let's imagine the the following scenario
User sends a token to an exchange smart contract
Token smart contract calls exchange smart contract
Exchange smart contract calls fee smart contract
Exchange smart contract calls another token contract to send back another set token in the trade
Unlike a single shard Ethereum, NEAR does cross contract calls with promises. Whereas a single tripped require() automatically rolls back to the whole Ethereum transactions, in the sharded nature to NEAR smart contracts themselves are responsible for rolling back state changes if the promise they triggered does not complete successfully.
My question is how to safely handle failures in the chain of promises between NEAR smart contracts
What are the failure modes (smart contract function panics, target account does not contain code, out of gas)
How to catch the different errors above and deal with different error modes
Is there already a pattern that allows writing promise chains safely in an easy manner, similar to try {} catch {} in JavaScript await/async model
How I can track between different promises what was the original initiating user transaction that caused the chain of promises to trigger
How smart contracts are forwarding gas and ensuring there is enough gas for the whole chain of promises to complete
Generally you can only tell whether a promise has succeeded without knowing what goes wrong in the case of an error. An example of such a check can be found here https://github.com/near/core-contracts/blob/4f245101d7d029ffb3450c560770db244fc7b3ce/lockup/src/utils.rs#L7. What is the use case of reacting differently to different error that you have in mind?

How to attach value (deposit) to transaction with Nearlib?

Let's say I have a contract function that expects a certain amount of near to be send with a certain transaction, the function is called create_order, create_order takes a couple arguments.
I have my contract setup in the frontend under the name myContract.
I want to call myContract.create_order({...}) but the transaction fails because this method call doesn't have the right amount of NEAR tokens attached.
How do I assign a certain value of deposit to a transaction?
It's possible to use account.functionCall directly (without sugar for RPCs) to either attach amount or specify gas allowance for the call.
See Account#functionCall in nearlib.
Nearlib supports it using account.functionCall(..., amount). But it might not work, because of the design of the access keys with function calls. Default authorized access keys towards applications only allows function calls without attached token deposits (only prepaid gas). It's done this way to prevent apps from automatically using your balance without your explicit approval. Details on access keys are here: https://github.com/nearprotocol/NEPs/blob/master/text/0005-access-keys.md
The way to attach a deposit for the transaction should be done with the explicit approval from the wallet. The app should create a request for the wallet, redirect to the wallet for the approval (or through the popup). Once user approves the transaction, it's signed with full access key from the wallet directly and broadcasted. But I'm afraid we don't have this API on the wallet yet. Issue for this: https://github.com/nearprotocol/near-wallet/issues/56
AFAIK it is not supported at the moment. It will be available after this NEP https://github.com/nearprotocol/NEPs/pull/13 lands.

Resources