【问题标题】:In NearProtocol, how to migrate contract stateNearProtocol中,如何迁移合约状态
【发布时间】:2021-07-06 13:26:05
【问题描述】:

假设有一个用 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
}

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

pub struct Token {
   pub owner: AccountId
   pub name: String // For existing ones, this will be set to ""
}

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

【问题讨论】:

    标签: nearprotocol near-sdk-rs


    【解决方案1】:

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

    见 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

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

    【讨论】:

    • 好例子,为了让这个例子更完整,在 berryclub 中还有这个:``` /// 在合约的结构中:pub legacy_accounts: Vector, pub accounts: LookupMap, ``` 这样你就可以在合约中保存两个版本的账户并在代码中处理这两个版本
    【解决方案2】:

    到目前为止,我只能建议部署一个临时合约,保留旧的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()
            );
        }
    }
    

    迁移状态后,您可以使用NewToken 而不是Token 部署合约。

    【讨论】:

    • 这更接近迁移的想法。但是,如果 state 变得非常大,调用 migrate 会超过块 gas 限制吗?
    • 对于大状态,一种可能的解决方案是分块运行迁移。
    猜你喜欢
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 2022-01-07
    • 2017-06-23
    • 2018-11-14
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多