NearProtocol中,如何迁移合约状态
Posted
技术标签:
【中文标题】NearProtocol中,如何迁移合约状态【英文标题】:In NearProtocol, how to migrate contract state 【发布时间】: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 ""
如何在保留现有状态的情况下执行此操作(类似于进行数据库迁移)?
【问题讨论】:
【参考方案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到目前为止,我只能建议部署一个临时合约,保留旧的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 限制吗?
对于大状态,一种可能的解决方案是分块运行迁移。以上是关于NearProtocol中,如何迁移合约状态的主要内容,如果未能解决你的问题,请参考以下文章