Assume there's a contract written in near-sdk-rs, deployed, has state defined as:
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct NFT {
pub tokens: UnorderedMap<TokenId, Token>,
}
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Token {
pub owner: AccountId
}
Now there're some usage of this contract, as a result some records of tokens
stored on chain.
Then I'd like to update this contract by adding a field to Token
:
pub struct Token {
pub owner: AccountId
pub name: String // For existing ones, this will be set to ""
}
How to do this with existing state kept (similar of doing a database migration)?
You can also see how some of the examples we've created use versioning.
See BerryClub:
#[derive(BorshDeserialize, BorshSerialize)]
pub struct AccountVersionAvocado {
pub account_id: AccountId,
pub account_index: AccountIndex,
pub balance: u128,
pub num_pixels: u32,
pub claim_timestamp: u64,
}
impl From<AccountVersionAvocado> for Account {
fn from(account: AccountVersionAvocado) -> Self {
Self {
account_id: account.account_id,
account_index: account.account_index,
balances: vec![account.balance, 0],
num_pixels: account.num_pixels,
claim_timestamp: account.claim_timestamp,
farming_preference: Berry::Avocado,
}
}
}
https://github.com/evgenykuzyakov/berryclub/blob/ad2b37045b14fa72181ab92831fb741a7c40234b/contract-rs/pixel-board/src/account.rs#L19-L39
There are others but will have to come back to this once I find them
So far I can only suggest to deploy a temporary contract with old Token
struct kept as is, and NewToken
implement NewToken::from_token
, and a change method:
impl Token {
pub fn migrate(&mut self) {
near_sdk::env::storage_write(
"STATE",
NewToken::from_token(self).try_into_vec().unwrap()
);
}
}
After you migrate the state, you can deploy a contract with the NewToken
instead of Token
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With