3
#[derive(BorshSerialize, BorshDeserialize)]
pub struct NotesDs {
    pub own: Vec<String>,
    pub shared: UnorderedMap<AccountId,Vec<String>>,
}

impl NotesDs{
    pub fn new() -> Self {
        assert!(env::state_read::<Self>().is_none(), "Already initialized");
        Self {
            own: Vec:: new(),
            shared: UnorderedMap::new(b"w".to_vec()),
        }
    }
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Note {
    pub note_list : UnorderedMap<AccountId,NotesDs>, 
}

impl Default for Note {
    fn default() -> Self {
        // Check incase the contract is not initialized
        env::panic(b"The contract is not initialized.")
    }
}

#[near_bindgen]
impl Note {
    /// Init attribute used for instantiation.
    #[init]
    pub fn new() -> Self {
        assert!(env::state_read::<Self>().is_none(), "Already initialized");
        Self {
            note_list: UnorderedMap::new(b"h".to_vec()),
        }
    }
    pub fn add_notes2(&mut self, status: String){
        if self.note_list.get(&env::predecessor_account_id()).is_none() {
            let mut temp = NotesDs:: new();
            let mut vec = Vec:: new();
            let mut vec2 = Vec:: new();
            vec.push(status.clone());
            temp.own = vec;
            temp.shared = vec2;
            self.note_list.insert(&env::predecessor_account_id(), &temp);
        }
        else {
            let mut temp1 = self.note_list.get(&env::predecessor_account_id()).unwrap();
            let mut vec1 = temp1.own;
            vec1.push(status.clone());
            temp1.own = vec1;
            self.note_list.insert(&env::predecessor_account_id(), &temp1);
        }      
    }
} 

I am getting the following error

 Failure [share.meghaha.testnet]: Error: {"index":0,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: \"Unexpected length of input\" }', /home/meghaa105/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46"}}
ServerTransactionError: {"index":0,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: \"Unexpected length of input\" }', /home/meghaa105/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46"}}
    at Object.parseResultError (/usr/lib/node_modules/near-cli/node_modules/near-api-js/lib/utils/rpc_errors.js:31:29) 
    at Account.signAndSendTransactionV2 (/usr/lib/node_modules/near-cli/node_modules/near-api-js/lib/account.js:160:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async scheduleFunctionCall (/usr/lib/node_modules/near-cli/commands/call.js:57:38)
    at async Object.handler (/usr/lib/node_modules/near-cli/utils/exit-on-error.js:52:9) {
  type: 'FunctionCallError',
  context: undefined,
  index: 0,
  kind: {
    ExecutionError: `Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: "Unexpected length of input" }', /home/meghaa105/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46`
  },
  transaction_outcome: {
    block_hash: 'EesG3NjqXdbYZqEYE22nC12AYpU3gkC9uaC7rSjToGSA',
    id: '89g7HhiXgZFZRLntMzFCPk82TQ5m8diwW2nh6jVnEgKz',
    outcome: {
      executor_id: 'share.meghaha.testnet',
      gas_burnt: 2428050684172,
      logs: [],
      metadata: [Object],
      receipt_ids: [Array],
      status: [Object],
      tokens_burnt: '242805068417200000000'
    },
    proof: [ [Object], [Object] ]
  }
}

This error comes for the query
near calladd_notes2 '{"status" : "Trying out writing a smart contract" }'

I have even tried deleting and creating a new account with same or different names. I even tried redeploying the smart contract. Further, I also have added the serialize and deserialize dependencies. I don't know what is going wrong.

Megha Agarwal
  • 81
  • 1
  • 7

1 Answers1

2

Edit: The original answer (which is marked correct) said that the standard Rust Vec can't be used in a NEAR contract. It can along with all the Rust types in https://docs.rs/borsh/0.2.9/borsh/ser/trait.BorshSerialize.html. The NEAR collections https://docs.rs/near-sdk/2.0.1/near_sdk/collections/index.html are recommended for bigger collections as they are more storage efficient, but have few features and are less familiar than Rust built ins.

Something else must have fixed the issue. Usually "can't deserialize the contract state" in NEAR happens when new contract code is deployed on an existing contract and is not compatible with the data that has been previously stored by the contract.

Original Answer

The following code may help to resolve the error. NEAR has it's own datatypes that persist the state of the contract.

near_sdk::collections::Vector is used in place of Vec.

The code below replaces Vec with the persistent NEAR Vector:

/// New imports...
use near_sdk::collections::{ UnorderedMap, Vector };
use near_sdk::{ BorshStorageKey };

#[derive(BorshSerialize, BorshStorageKey)]
enum StorageKeyNotes {
    MapKey,
    OwnKey,
    SharedKey
}

#[derive(BorshSerialize, BorshDeserialize)]
pub struct NotesDs {
    pub own: Vector<String>,
    pub shared: UnorderedMap<AccountId, Vector<String>>,
}

impl NotesDs{
    pub fn new() -> Self {
        assert!(env::state_read::<Self>().is_none(), "Already initialized");
        let mut notesDs = Self {
            own: Vector::new(StorageKeyNotes::OwnKey),
            shared: UnorderedMap::<AccountId, Vector<String>>::new(StorageKeyNotes::MapKey)
        };

        notesDs
    }
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Note {
    pub note_list : UnorderedMap<AccountId,NotesDs>, 
}

impl Default for Note {
    fn default() -> Self {
        // Check incase the contract is not initialized
        env::panic(b"The contract is not initialized.")
    }
}

#[near_bindgen]
impl Note {
    /// Init attribute used for instantiation.
    #[init]
    pub fn new() -> Self {
        assert!(env::state_read::<Self>().is_none(), "Already initialized");
        Self {
            note_list: UnorderedMap::new(b"h".to_vec()),
        }
    }
    pub fn add_notes2(&mut self, status: String){
        if self.note_list.get(&env::predecessor_account_id()).is_none() {
            let mut temp = NotesDs:: new();
            let mut vec = Vector::new(StorageKeyNotes::OwnKey);
            let mut vec2 = Vector::new(StorageKeyNotes::SharedKey);
            vec.push(&status.clone());
            temp.own = vec;
            temp.shared.insert(&String::from("Max Power"), &vec2);
            self.note_list.insert(&env::predecessor_account_id(), &temp);
        }
        else {
            let mut temp1 = self.note_list.get(&env::predecessor_account_id()).unwrap();
            let mut vec1 = temp1.own;
            vec1.push(&status.clone());
            temp1.own = vec1;
            self.note_list.insert(&env::predecessor_account_id(), &temp1);
        }      
    }
} 

The code hasn't been tested on chain but could help with solving the error.

For anybody searching for the similar error:

Smart contract panicked: panicked at 'Cannot deserialize the contract
 state.: Custom { kind: InvalidData, error: "Not all bytes read" }

It usually means that a new contract has been deployed that does not work with the data that a previous contract stored.

See Not All Bytes Read Common Solutions

Ben Razor
  • 111
  • 4
  • Can you please explain why do we have to create an enum. And why is the initialization done in a different way? – Megha Agarwal Feb 23 '22 at 10:33
  • I'm new to near/rust, but the way I understand it is that for each piece of data stored for a contract you need a key that identifies it. The enum defines those keys and ensures that they are unique. The initialization is different because you have to pass the key to tell near: "store this Vector alongside this key". I based the code off the [near nft example](https://github.com/near-examples/NFT/blob/master/nft/src/lib.rs) but there might be different/better ways to do this for your case in other docs / examples. – Ben Razor Feb 23 '22 at 11:51