Reputation: 136
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)?
Upvotes: 6
Views: 613
Reputation: 1591
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,
}
}
}
There are others but will have to come back to this once I find them
Upvotes: 6
Reputation: 7756
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
.
Upvotes: 4