Skip to content

Instantly share code, notes, and snippets.

@ilyar
Last active January 24, 2024 18:37
Show Gist options
  • Save ilyar/19bdc04d1aa09ae0fc84eb4297df1a1d to your computer and use it in GitHub Desktop.
Save ilyar/19bdc04d1aa09ae0fc84eb4297df1a1d to your computer and use it in GitHub Desktop.
How do clear the state of a contract on Near protocol?

How do clear the state of a contract on Near protocol?

Prepare

source neardev/dev-account.env
export CONTRACT_NAME=$CONTRACT_NAME

View state

near view-state $CONTRACT_NAME --finality final

Getting only keys:

// file: view_state_keys.js
const nearAPI = require('near-api-js')
const { connect, keyStores } = nearAPI
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(__dirname);
const config = {
  keyStore,
  networkId: 'testnet',
  nodeUrl: 'https://rpc.testnet.near.org',
  walletUrl: 'https://wallet.testnet.near.org',
  helperUrl: 'https://helper.testnet.near.org',
  explorerUrl: 'https://explorer.testnet.near.org',
}

async function main () {
  const near = await connect(config)
  const response = await near.connection.provider.query({
    request_type: 'view_state',
    finality: 'final',
    account_id: process.env.CONTRACT_NAME,
    prefix_base64: '',
  })
  console.log(JSON.stringify({
    // TODO add calc size of data for limit burning 200TGas for one call on contract
    keys: response.values.map(it => it.key)
  }))
}

main().catch(reason => {
  console.error(reason)
})

Add method clean into contract

for more info see near/core-contracts#171

use near_sdk::json_types::Base64VecU8;
#[near_bindgen]
impl Contract {
    #[private]
    #[init(ignore_state)]
    pub fn clean(keys: Vec<Base64VecU8>) {
        for key in keys.iter() {
            env::storage_remove(&key.0);
        }
    }
}

Build and deploy contract:

near deploy ${CONTRACT_NAME} out/main.wasm

Clean state

near --accountId $CONTRACT_NAME call $CONTRACT_NAME clean --base64 "$(node view_state_keys.js | base64 -w0)" --gas 300000000000000
@wackazong
Copy link

For other people landing here: you can prevent the error State of contract _____.near is too large to be viewed when calling view-state via the JSON RPC API if you select an alternative RPC provider from this list (also works for testnet if you replace testnet with mainnet in some of the URLs): docs.near.org/api/rpc/providers I was successful with OOMNIA: endpoints.omniatech.io/v1/near/testnet/public

@tolinwei
Copy link

tolinwei commented Dec 7, 2023

After adding the clean() method/function to the contract implementation (based on the NFT test kit: https://docs.near.org/tutorials/nfts/minting-nfts#minting-your-nfts), I got a compile run error:

error: Init methods must return the contract state
  --> nft/src/lib.rs:54:12
   |
54 |     pub fn clean(keys: Vec<Base64VecU8>) {
   |            ^^^^^

error: could not compile `non-fungible-token` due to previous error

Does anyone know how to fix this?

@tolinwei
Copy link

tolinwei commented Dec 7, 2023

After adding the clean() method/function to the contract implementation (based on the NFT test kit: https://docs.near.org/tutorials/nfts/minting-nfts#minting-your-nfts), I got a compile run error:

error: Init methods must return the contract state
  --> nft/src/lib.rs:54:12
   |
54 |     pub fn clean(keys: Vec<Base64VecU8>) {
   |            ^^^^^

error: could not compile `non-fungible-token` due to previous error

Does anyone know how to fix this?

For those who encounter the same problem after me, here are some solutions:

  1. Remove the #[init(ignore_state)] on top of the clean() function. You can still call into the function without this.
  2. Place the .js file in the same directly as where you run the near CLI, the .js file is not part of the smart contract that gets deployed, it's something to be called locally
  3. On Mac, the base64 implementation is different from the one in Linux, there's no -w0 parameter and by default it generates the same output as when you attach -w0 in Linux (reference: https://stackoverflow.com/questions/46463027/base64-doesnt-have-w-option-in-mac)

I ran into the issue when following the NFT example on: https://docs.near.org/tutorials/nfts/minting-nfts#minting-your-nfts. I wasn't satisfied with the default NFT contract metadata and wanted to update it but got the error that the contract has already been initialized. This post helped me to clear the state and I was able to generate the NFT contract metadata again. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment