程序维护中的一个基本问题是——缺陷修复总会以%的机率引入新的bug。所以整个过程是前进两步,后退一步。——布鲁克斯《人月神话》
1.合约升级的必要性
智能合约本质上是程序,既然是程序,缺陷就不可避免。即便是经过大量测试和审计的智能合约,仍然可能会有漏洞。合约的漏洞如果被攻击者利用,可能造成用户资产的损失,导致严重的后果。漏洞的修复往往需要通过合约升级来实现。除了漏洞修复,新特性的加入也需要合约升级。因此合约的可升级性非常有必要。本期Rust智能合约养成日记,将为大家介绍Rust合约的升级方式。
2.Solidity合约常见升级方式
以太坊中,智能合约具有不可变性,一旦被部署到链上,没有人可以改变它。
那么如果合约存在漏洞或合约需要添加新功能,该如何修改合约的代码?解决方案是将新的合约部署到区块链上。
该方法面临的挑战是,solidity每次部署合约后,合约都会被分配一个唯一的地址。因此所有用到了该合约的DApps都需要修改合约地址来适配新的合约。此外,旧版本合约中的状态需要迁移到新版本合约中,状态较为复杂的合约迁移的工作量很大,容易出错,而且复制数据的Gas费用高。
伊隆·马斯克:虽然Discord使用Rust,但我更喜欢C语言:金色财经报道,伊隆·马斯克在推特上表示,虽然加密社区Discord使用的是可以更好扩展的Rust编程语言,而且他本人也是Rust粉丝,但如果要获得最佳性能,没有什么能比C语言更好了。此外,马斯克还透露特斯拉主要使用的是C++和Python语言。[2022/2/23 10:11:29]
因此,我们通常采用数据和逻辑分离的架构,将数据保存在一个不处理任何逻辑的合约中,所有的逻辑在另一个合约中实现。通常合约升级修改的是逻辑,使用该架构只需要升级逻辑合约,不需要担心状态迁移。
为了解决这个问题,可以使用代理合约,具体架构如下图所示。
代理合约用来来存储数据,并且使用delegatecall调用逻辑合约A,这样合约A读写的数据都存储在代理合约中。如果需要升级逻辑合约,部署新的合约B,然后发一条交易给代理合约,让代理合约指向新的逻辑合约B即可。
3.NEAR合约升级常用方法
Crust Network赢得第19次Kusama平行链插槽拍卖:12月28日消息,Kusama第19次竞拍已结束,Crust Network以锁定30,026个KSM成功赢得Kusama的第21个插槽,接入Kusama中继链,以平行链的方式出块。据悉,第17个插槽后加入了Statemine和Encointer。[2021/12/28 8:09:24]
接下来我们将以StatusMessage项目为例,给大家介绍NEAR合约的常用升级方法,如下是StatusMessage的合约代码
我们先将编译好的合约部署在测试网上。
transaction如下
Trusted computing将开展NFT相关业务:据官方消息,Trusted computing(TCP)宣布在NFT领域进行多项开发,综合数据隐私属性推出NFT市场平台 、NFT挖矿 、NFT生成工具等。[2021/10/22 20:49:30]
接着我们调用set_status方法,向合约中存储数据
transaction如下
接下来我们详细讨论两种不同的合约升级情况
3.1合约数据结构未被修改
例如我们增加一个函数:
编译后使用deploy重新部署:
TrustBase对NFT平台Liquidifty进行战略投资:据官方消息,TrustBase宣布对NFT平台Liquidifty进行战略投资,意在共同丰富NFT生态发展。
TrustBase是基于Substrate框架,自主开发Subscript智能合约语言,支持多种工具插件及智能合约应用的Polkadot平行链。作为Polkadot生态系统中的基建类项目,TrustBase已获得了Web3 Foundation Grant的认证扶持,同时Subscript智能合约语言已经向Web3基金会交付了第一期的开发成果。
Liquidifty-该平台旨在为NFT市场带来更多的流动性,为用户提供更多使用案例,以支持他们的NFT有更多的使用场景。目前该项目已经获得AU21、 PartOne Capital机构的投资。[2021/4/15 20:23:09]
编译后使用deploy重新部署:
现场丨基于蚂蚁链的国际贸易和金融服务平台Trusple发布:金色财经现场报道,9月25日下午,外滩大会区块链产业峰会在上海开幕。在现场,基于蚂蚁链的国际贸易和金融服务平台Trusple由法国巴黎银行、花旗银行、星展银行、德意志银行、渣打银行、蚂蚁链共同启动。
Trusple是基于蚂蚁链技术构建的全新数字化国际贸易和金融服务平台,通过连接买卖双方、国内外银行及国际贸易链路中的核心节点,结合区块链技术,提供智能支付及付款承诺的支付方式,实现智能履约,为买卖双方提供了从订单到付款、端到端的贸易保障及金融服务。
该平台将有助于解决跨境贸易中的信任问题,更好地服务小微企业。Trusple平台实现新生态:服务于SMEs的数字化贸易生态网络;展现出新标准:新技术驱动贸易金融服务创新和变革。[2020/9/25]
接着我们调用get_status方法读取之前写入的数据
原来合约中的数据能成功读取:
这是因为NEAR合约可以重复部署,如果一个账户已经部署过合约,再次调用neardeploy命令可以将新的合约代码部署到该账户上。如果我们只修改合约逻辑,不涉及数据结构的修改,可以直接使用neardeploy部署新的代码。
3.2合约数据结构被修改
我们将该合约升级,修改了原来的数据结构,去除了records,新增了taglines和bios
我们尝试再次重新部署:
合约还是成功部署了:
但是我们调用get_tagline方法读取存储的数据:
会发现出错了,错误提示如下:
Cannotdeserializethecontractstate.
具体的transaction见:
https://explorer.testnet.near.org/transactions/4hQQ1zAwU5bsbfb6tA6DQDqjmFcHsBwaBctdHaPiCKHu
这是因为合约的状态是以序列化数据的形式进行持久化存储的,重新部署合约后,代码中的数据结构变了,状态没有变,新的数据结构匹配不上旧状态,就出错了。
3.3Migrate升级智能合约
NEAR提供了Migrate方法去帮助我们对合约进行升级,针对3.2中所出现的错误,我们在新的合约中加入migrate方法:
代码中的#表示在migrate函数执行前不要加载状态。接着,我们重新部署合约,但是在部署的同时调用migrate方法
如下所示,该合约被成功部署:
我们尝试调用合约新增的方法get_tagline去获取新增的数据taglines
可以看到方法被成功调用,旧的合约数据也被迁移到新的合约
4.合约升级的安全考量
合约安全升级首先要考虑权限控制,一般合约只能由开发者或DAO升级。上一期Rust智能合约养成日记合约安全之权限控制介绍了特权函数的访问控制,一般合约的升级函数为onlyowner函数,确保只能由owner调用。
我们推荐尽可能将合约的owner设置为DAO,通过提案和投票来共同管理合约。因为owner设置为个人账户,合约高度中心化,owner可以随意修改合约数据,还存在owner私钥丢失的风险。
除此之外,开发者在做合约迁移时,还可以考虑以下几点建议
在迁移函数前加入#,确保执行迁移函数前不加载状态。
迁移完成后尽量删除迁移函数,确保迁移函数只被调用一次。
新增的数据结构在迁移时完成初始化。
目前NFT市场遍地开花,截止到今天,以太坊链上NFT销售总额突破240亿美元,创下历史新高,较1月份增速20%,链上交易数量突破900万笔.
1900/1/1 0:00:00Mar.2022,VincyDataSource:FootprintAnalytics-GameFiDatabyChainGameFi的热度在持续发酵着,涌现许多公链和游戏项目.
1900/1/1 0:00:00TetherCTO:Tether没有上市计划5月5日消息,Tether的CTOPaoloArdoino在采访时表示,计划做的是继续做我们正在做的事情,也就是说,真正成为人民的工具.
1900/1/1 0:00:00SupraOracles很高兴地宣布与myMessage建立合作伙伴关系,myMessage是一种具有用户激励功能的去中心化社交媒体和数据存储协议.
1900/1/1 0:00:002022/3/17,BoredApeYachtClub在推特发布与之有关的生态治理系统代币ApeCoin正式推出.
1900/1/1 0:00:002022年1月31日,WorldMobile“除夕不眠夜”活动已完美结束,共抽取四名幸运粉丝,目前空投已全部发放完毕.
1900/1/1 0:00:00