gpt4 book ai didi

rust - 我应该如何处理 NEAR 协议(protocol)中的智能合约结构变更?

转载 作者:行者123 更新时间:2023-12-05 05:47:30 24 4
gpt4 key购买 nike

假设我有一份契约(Contract)

...
pub struct Contract {
collection_a: Vector<String>,
}

在我部署这个版本之后,当我改变我的智能合约的数据结构时,例如

pub struct Contract {
collection_a: Vector<String>,
collection_b: Vector<String>,
}

我在与合约交互时遇到了错误

       Failure [dev-1644158197214-15380220543819]: Error: {"index":0,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: \"Unexpected length of input\" }', /workspace/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46"}}
ServerTransactionError: {"index":0,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: \"Unexpected length of input\" }', /workspace/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46"}}
at Object.parseResultError (/home/gitpod/.nvm/versions/node/v16.13.0/lib/node_modules/near-cli/node_modules/near-api-js/lib/utils/rpc_errors.js:31:29)
at Account.signAndSendTransactionV2 (/home/gitpod/.nvm/versions/node/v16.13.0/lib/node_modules/near-cli/node_modules/near-api-js/lib/account.js:160:36)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async scheduleFunctionCall (/home/gitpod/.nvm/versions/node/v16.13.0/lib/node_modules/near-cli/commands/call.js:57:38)
at async Object.handler (/home/gitpod/.nvm/versions/node/v16.13.0/lib/node_modules/near-cli/utils/exit-on-error.js:52:9) {
type: 'FunctionCallError',
context: undefined,
index: 0,
kind: {
ExecutionError: `Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidInput, error: "Unexpected length of input" }', /workspace/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-3.1.0/src/environment/env.rs:786:46`
},
transaction_outcome: {
proof: [ [Object], [Object] ],
block_hash: '5mPRmggsyL9cNsgS4a6mzRT7ua9Y8SS8XJbW9psawdDr',
id: '8BeARer3UXLoZ3Vr22QAqkyzsp143D7FCtVssjyYxzs',
outcome: {
logs: [],
receipt_ids: [Array],
gas_burnt: 2427936651538,
tokens_burnt: '242793665153800000000',
executor_id: 'dev-1644158197214-15380220543819',
status: [Object],
metadata: [Object]
}
}
}

当我需要更新结构时,如何处理这种情况?

最佳答案

你要的是storage migration :

#[derive(BorshSerialize, BorshDeserialize)]
pub struct OldContract {
collection_a: Vector<String>,
}

#[near_bindgen]
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Contract {
collection_a: Vector<String>,
collection_b: Vector<String>,
}

#[near_bindgen]
impl Contract {
#[private]
#[init(ignore_state)]
pub fn migrate() -> Self {
let old_storage: OldContract = env::state_read().expect("Couldn't read old state");
Self {
collection_a: old_storage.collection_a,
collection_b: Vec::new(),
}
}
}

首先使用此代码更新您的契约(Contract),然后使用契约(Contract) key 调用 migrate 方法。在下次升级时,您可以删除该方法和 OldContract 结构以节省存储空间。

您可能遇到的一个问题是不适合单个 block 的存储迁移。 AFAIK,没有解决方案。然而,Borsh 序列化是确定性的,因此只要您将数据结构保持为枚举,您就应该能够重新解释当前链存储并将迁移拆分为多个部分迁移。确保对此进行彻底测试,否则您将面临无法恢复地搞砸契约(Contract)状态的风险。

关于rust - 我应该如何处理 NEAR 协议(protocol)中的智能合约结构变更?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71008470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com