NearProtocol中,如何迁移合约状态

Bo *_*Yao 5 nearprotocol near-sdk-rs

假设有一个用 Near-sdk-rs 编写的合同,已部署,状态定义为:

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct NFT {
    pub tokens: UnorderedMap<TokenId, Token>,
}

#[derive(BorshDeserialize, BorshSerialize)]
pub struct Token {
   pub owner: AccountId
}
Run Code Online (Sandbox Code Playgroud)

现在这个合约有一些用途,因此一些记录tokens存储在链上。然后我想通过添加一个字段来更新这个合同Token

pub struct Token {
   pub owner: AccountId
   pub name: String // For existing ones, this will be set to ""
}
Run Code Online (Sandbox Code Playgroud)

如何在保留现有状态的情况下执行此操作(类似于执行数据库迁移)?

amg*_*ndo 5

您还可以看到我们创建的一些示例如何使用版本控制。

见浆果俱乐部:

#[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,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/evgenykuzyakov/berryclub/blob/ad2b37045b14fa72181ab92831fb741a7c40234b/contract-rs/pixel-board/src/account.rs#L19-L39

还有其他的,但一旦我找到它们就必须回到这里


Vla*_*lov 4

到目前为止,我只能建议部署一个临时合约,并Token保留旧结构,并NewToken实现NewToken::from_token和更改方法:

impl Token {
    pub fn migrate(&mut self) {
        near_sdk::env::storage_write(
            "STATE",
            NewToken::from_token(self).try_into_vec().unwrap()
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

NewToken迁移状态后,您可以使用代替来部署合约Token

  • 这更接近于迁移的想法。但是,如果状态变得非常大,调用“migrate”是否会超过区块gas限制? (2认同)