I want to delete the current contract and burn its NEAR balance when a condition is triggered.
Here's the Solidity version:
selfdestruct(address(0));
I found Promise::delete_account in the Rust SDK but it has a beneficiary_address field. Ideally the funds should be gone forever and not transferred to an owned address.
Promise::new(env::current_account_id()).delete_account(beneficiary_address);
address(0) is address 0x0, a black hole address used to burn Ether.
Currently there is no API to burn NEAR tokens directly. One workaround is to set the beneficiary account id to system. system is an account that can never be created and is used internally for refunds. When the beneficiary account does not exist, the tokens transferred through account deletion are automatically burnt.
I think that is like this:
#[payable]
pub fn burn() {
Promise::new("system".to_string()).transfer(env::attached_deposit());
}
First importing:
use near_sdk::{Promise};
Related
Try to transfer tokens to one of the account declared in remaining_accounts list.
Here's the way I create CpiContext:
let cpi_context = CpiContext::new(ctx.accounts.token_program.to_account_info(),
Transfer {
from: ctx.accounts.account_x.to_account_info(),
to: ctx.remaining_accounts.first().unwrap().to_account_info(),
authority: ctx.accounts.owner.to_account_info().clone()
});
I got error related to CpiContext lifetime mismatch. Exact log error: lifetime mismatch ...but data from ctx flows into ctx here.
Why I want to use remaining accounts to transfer tokens? This transfer is optional depending on whether user decides to pass the account (referral links/affiliation). Other methods than passing account as remaining accounts to implement the optional transfer will be also highly appreciated.
Make sure that you help out Rust's lifetime inference in your instruction:
pub fn your_instruction<'info>(ctx: Context<'_, '_, '_, 'info, YourContext<'info>>, ...)
My smart contract owns the SFT HAT-a1a1a1-01.
The SFT HAT-a1a1a1-02 also exists but isn't owned by the SC.
When I add local quantity to the SFT with the 02 nonce through a function, my transaction fails with this error:
new NFT data on sender
Do I need to own the SFT HAT-a1a1a1-02 to mint it?
I got an answer in another group:
Yes, you need to own at least 1 to AddQuantity, since otherwise, you wouldn't have the attributes. When you send an NFT/SFT, if your balance after is 0, the metadata is erased from your account.
Considering that
get_esdt_token_data(address: &ManagedAddress, token_id: &TokenIdentifier, nonce: u64) -> EsdtTokenData<Self::Api>
always returns an EsdtTokenData rather than an option. What will this object look like if the address does not own the specified token?
The execution will fail as the VM will not return anything to the smart contract if it doesn't find the token.
The typical usage for this function is to get the data for the payment tokens the smart contract receives from the caller. If you're trying to use it freely, you might get into this situation, so this type of "free" usage is not really advised.
I noticed that the near top level account on NEAR MainNet has got this access key associated with it:
{
"public_key": "ed25519:5zset1JX4qp4PcR3N9KDSY6ATdgkrbBW5wFBGWC4ZjnU",
"access_key": {
"nonce": 1568,
"permission": "FullAccess"
}
}
This key is hard-coded in the genesis.
From what I understand, this effectively means that an entity in possession of the corresponding private key may at any time delete any account that has its ID ending with .near, transferring all funds from that account wherever they choose. This includes all accounts created via the official NEAR web wallet or by otherwise calling near.create_account().
I'd like to know if my understanding is correct, whether this is absolutely required for the network to function or not, and what security implications this might have for a typical user.
I'm pretty sure you cannot affect a subaccount from the parent like this. If someone deletes the near account, your account would not be affected. and unless the near account itself is holding a FullAccess key to subaccounts, it doesn't control them
This would also be easy to test. On TestNet try creating a subaccount and deleting it from the parent. If you don't have a FullAccess key to an account then your DeleteAccount action will be rejected by the network.
I want to store all the blockchain data in offchain database.
rpc has a function called EXPERIMENTAL_changes, I was told that I can do that by http polling of this method but I am unable to find out how to use it.
http post https://rpc.testnet.near.org jsonrpc=2.0 id=dontcare method=EXPERIMENTAL_changes \ params:='{ "changes_type": "data_changes", "account_ids": ["guest-book.testnet"], "key_prefix_base64": "", "block_id": 19450732 }'
For example here the results give:
"change": { "account_id": "guest-book.testnet", "key_base64": "bTo6Mzk=", "value_base64": "eyJwcmVtaXVtIjpmYWxzZSwic2VuZGVyIjoiZmhyLnRlc3RuZXQiLCJ0ZXh0IjoiSGkifQ==" }
What is key_base64?
Decoding it to string gives m::39
What is m::39?
For example, I have the following state data in the rust structure.
pub struct Demo {
user_profile_map: TreeMap<u128, User>,
user_products_map: TreeMap<u128, UnorderedSet<u128>>, // (user_id, set<product_id>)
product_reviews_map: TreeMap<u128, UnorderedSet<u128>>, // (product_id, set<review_id>)
product_check_bounty: LookupMap<u128, Vector<u64>>
}
How to know anything gets changed in these variables?
Will I have to check every block id for the point the contract is deployed, to know where there is the change?
I want to store all the blockchain data in offchain database.
If so, I recommend you take a look at the Indexer Framework, which allows you to get a stream of blocks and handle them. We use it to build Indexer for Wallet (keeps track of every added and deleted access key, and stores those into Postgres) and Indexer for Explorer (keeps track of every block, chunk, transaction, receipt, execution outcome, state changes, accounts, and access keys, and stores all of that in Postgres)
What is m::39?
Contracts in NEAR Protocol have access to the key-value storage (state), so at the lowest-level, you operate with key-value operations (NEAR SDK for AssemblyScript defines Storage class with get and set operations, and NEAR SDK for Rust has storage_read and storage_write calls to preserve data).
Guest Book example uses a high-level abstraction called PersistentVector, which automatically reads and writes its records from/to NEAR key-value storage (state). As you can see:
export const messages = new PersistentVector<PostedMessage>("m");
Guest Book defines the messages to be stored in the storage with m prefix, hense you see m::39, which basically means it is messages[39] stored in the key-value storage.
What is key_base64?
As key-value storage implies, the data is stored and accessed by keys, and the key can be binary, so base64 encoding is used to enable JSON-RPC API users with a way to query those binary keys as well (there is no way you can pass a raw binary blob in JSON).
How to know anything gets changed in these variables? Will I have to check every block id for the point the contract is deployed, to know where there is the change?
Correct, you need to follow every block, and check the changes. That is why we have built the Indexer Framework in order to enable community building services on top of that (we chose to build applications Indexer for Wallet and Indexer for Explorer, but others may decide to build GraphQL service like TheGraph)