Rust智能合约升级指南:从数据迁移到安全考量

robot
摘要生成中

Rust 智能合约养成日记(9)合约升级

智能合约本质上是程序,缺陷难以避免。即使经过大量测试和审计的智能合约,仍可能存在漏洞。合约漏洞一旦被攻击者利用,可能导致用户资产损失,后果严重。漏洞修复通常需要通过合约升级实现。除了修复漏洞,添加新功能也需要升级合约。因此合约的可升级性非常重要。本文将介绍Rust合约的升级方式。

1. Solidity合约常见升级方式

以太坊智能合约具有不可变性,部署后无法更改。如果合约存在漏洞或需要新功能,只能将新合约部署到区块链上。

这种方法面临的挑战是,每次部署合约后都会分配一个新地址。所有使用该合约的DApp都需要修改合约地址以适配新合约。另外,旧版本合约中的状态需要迁移到新版本,复杂合约的状态迁移工作量大且容易出错。

因此,通常采用数据和逻辑分离的架构,将数据保存在一个不处理逻辑的状态合约中,所有逻辑在另一个逻辑合约中实现。这样升级时只需更新逻辑合约,无需考虑状态迁移。

为解决这个问题,可以使用代理合约(Proxy Contract)。代理合约用于存储数据,并使用delegatecall调用逻辑合约A,这样合约A读写的数据都存储在代理合约中。升级时,部署新的合约B,然后发送交易让代理合约指向新的逻辑合约B即可。

2. NEAR 合约升级常用方法

以StatusMessage项目为例,介绍NEAR合约的常用升级方法。

2.1 合约数据结构未被修改

如果只修改合约逻辑,不涉及数据结构修改,可以直接使用near deploy部署新代码。旧合约中的数据可以成功读取。

2.2 合约数据结构被修改

如果修改了合约的数据结构,直接重新部署会导致无法反序列化合约状态。这是因为合约状态以序列化数据形式持久化存储,重新部署后代码中的数据结构变了,但状态没变,新的数据结构无法匹配旧状态。

2.3 Migrate升级智能合约

NEAR提供了Migrate方法帮助升级合约。在新合约中加入migrate方法:

rust #[private] #[init(ignore_state)] pub fn migrate() -> Self { let old_state: OldStatusMessage = env::state_read().expect('failed'); Self { taglines: old_state.records, bios: LookupMap::new(b'b'.to_vec()), } }

重新部署合约时调用migrate方法:

near deploy
--wasmFile target/wasm32-unknown-unknown/release/status_message.wasm
--initFunction 'migrate'
--initArgs '{}'
--accountId statusmessage.blocksec_upgrade.testnet

这样可以成功部署新合约并迁移旧数据。

3. 合约升级的安全考量

合约安全升级首先要考虑权限控制,一般合约只能由开发者或DAO升级。升级函数应为only owner函数,确保只能由owner调用。

建议将合约的owner设置为DAO,通过提案和投票来共同管理合约。个人账户作为owner会导致合约高度中心化,owner可以随意修改合约数据,还存在私钥丢失的风险。

此外,开发者在进行合约迁移时,可以考虑以下建议:

  • 在迁移函数前加入#[init(ignore_state)],确保执行迁移函数前不加载状态。
  • 迁移完成后删除迁移函数,确保迁移函数只被调用一次。
  • 新增的数据结构在迁移时完成初始化。

NEAR-7.13%
此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 6
  • 分享
评论
0/400
TrustlessMaximalistvip
· 07-19 20:31
老传统合约 漏洞太多啦
回复0
MetaDreamervip
· 07-19 20:29
权限不分散根本不安全,这事我懂
回复0
YieldChaservip
· 07-19 20:21
重要通知建议要分级部署吧!
回复0
MEV之泪vip
· 07-19 20:17
跑路就删代码,简单!
回复0
不明觉厉分析员vip
· 07-19 20:12
还好吧 也就掌握了这招
回复0
薅毛致富vip
· 07-19 20:04
漏洞修复有多重要 能懂
回复0
交易,随时随地
qrCode
扫码下载 Gate APP
社群列表
简体中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)