主页 > imtoken官网版下载地址 > 阅读如何在一篇文章中实现智能合约迁移

阅读如何在一篇文章中实现智能合约迁移

imtoken官网版下载地址 2023-07-09 05:14:47

批量查询以太坊账户余额_以太坊联盟和以太坊的关系_以太坊转账验证账户

点击上方“统一时代”订阅!

unitimes.io

以太坊转账验证账户_以太坊联盟和以太坊的关系_批量查询以太坊账户余额

全球视野,独到见解

智能合约也可能受到损害:如果存在错误,如果合约所有者的钱包被盗,或者如果某种错误的设置导致僵局。 如果您为自己的企业开发智能合约,则必须为类似事件做好计划。 在许多情况下,唯一的解决方案是部署一个新的合约实例并将数据迁移到其中。

如果你打算开发一个可升级的合约,迁移过程将有助于避免可升级机制的潜在危险[1]。

本文旨在详细讲解如何实现合约迁移。

您需要嵌入合约迁移功能

即使是零漏洞合约也可能被偷来的私钥劫持。 之前的 Bancor [2] 和 KICKICO [3] 黑客攻击表明攻击者可以破坏智能合约钱包。 在这些攻击中,即使合约具有可升级机制,也可能无法修复已部署的智能合约。 唯一的解决办法是重新部署并正确初始化新的合约实例以恢复用户的功能。

因此,所有智能合约开发者都必须在合约设计阶段集成迁移程序。 此外,企业必须准备好在发生合同损害事件时进行迁移。

迁移过程有两个步骤:

恢复要迁移的数据

将数据写入新合约

让我们深入了解细节、成本和运营后果。

以太坊联盟和以太坊的关系_批量查询以太坊账户余额_以太坊转账验证账户

第一步:数据恢复

您需要从区块链的特定块读取数据。 要从妥协事件(黑客攻击或故障)中恢复数据,您需要在事件发生之前使用块,或过滤攻击者的操作。

如果可以,请暂停合同。 这对用户来说更加透明和公平,并且可以防止攻击者针对不知道迁移的用户。

数据恢复的具体操作取决于你的数据结构。

对于简单类型(如 uint 或 address)的公共变量,通过它们的 getter 获取特定值就足够了。 而对于私有变量(private variables),可以依赖事件,也可以计算变量的内存偏移量,然后使用getStorageAt[4]函数取回它的值。

数组也很容易恢复,因为元素的数量是已知的。

您可以使用上述任何技术。

至于映射,情况有点复杂。 由于在映射过程中键(Keys)并没有被存储,所以需要将它们还原才能访问对应的值(Values)。 为了简化链下跟踪的过程,我们建议在地图中存储值时发出事件。

在ERC20代币合约中,可以通过追踪代币Transfer事件的地址来获取代币持有者列表。 过程很艰难。

为此,我们准备了两种解决方案来提供帮助:第一,您可以扫描区块链并自行检索持有者; 其次,您可以依赖以太坊区块链的公共 GoogBigTable 档案。

如果您不熟悉 web3 API,则无法从区块链中提取信息。 然后你可以使用ethereum-etl [5],它提供了一系列脚本来简化数据提取的过程。

如果您没有同步区块链,则可以使用 Google BigQuery API。 图 1 显示了如何使用 BigQuery 收集特定令牌的所有地址:

以太坊转账验证账户_批量查询以太坊账户余额_以太坊联盟和以太坊的关系

图 1:利用 Google BigQuery 恢复所有具有与地址 0x41424344 处的令牌关联的传输事件的地址

以太坊联盟和以太坊的关系_以太坊转账验证账户_批量查询以太坊账户余额

BigQuery 提供对区块编号的访问,因此您可以定制查询结果以返回特定区块的交易。

恢复所有代币持有者的地址后,您可以离线查询 balanceOf 函数 [6] 以恢复与每个持有者关联的余额,同时过滤掉余额为零的账户。

现在我们知道如何检索将要迁移的数据,我们需要将数据写入新合约。

第二步:数据写入

完成数据收集后,您需要打开一个新的合约。

对于简单的变量,可以通过合约的构造函数设置相应的值。

如果你的数据不能保存在一个单一的交易中,那就有点复杂,也稍微贵一点。 每笔交易都包含在某个区块中批量查询以太坊账户余额,这限制了其交易可以使用的气体总量(即所谓的 GasLimit)。 如果交易的 gas 成本接近或超过此限制,矿工将不会将其包含在区块中。 因此,如果要迁移大量数据,必须将数据迁移拆分成多个事务。

针对这种情况的解决方法是:在合约中添加初始化状态,只有合约所有者可以更改状态变量批量查询以太坊账户余额,用户不能进行任何操作。

对于 ERC20 代币,上述过程将需要以下步骤:

在初始化状态下部署合约,

转移余额,

将合同状态转移到生产状态。

初始化状态可以通过使用OpenZeppelin提供的Pausable函数[7]和一个表示初始化状态的布尔值(boolean)来实现。

为了降低成本,我们可以使用batchTransfer(批量转账)功能(该功能允许您在单笔交易中设置多个账户)实现余额迁移:

以太坊转账验证账户_以太坊联盟和以太坊的关系_批量查询以太坊账户余额

以太坊转账验证账户_以太坊联盟和以太坊的关系_批量查询以太坊账户余额

图 2:batchTransfer 函数示例

对移民的担忧

迁移合约时,会出现两个主要问题:

1. 迁移费用是多少?

2、对交易所有什么影响?

迁移成本

数据恢复是在链下完成的,因此是免费的; Ethereum-etl [8] 也可以在本地使用; Google 的 BigQuery API [9] 提供足够的免费积分来支付其使用费用。

但是,发送到网络的每笔交易和新合约存储的每个字节都有成本。

使用图2中的batchTransfer函数,向200个账户转账的成本约为2.4M gas,按照撰写本文时的平均gas价格(10 Gwei)约为5.04美元(也可以使用ETH加油站 [10] 重新计算最新值)。 粗略计算,每转一笔余额需要 0.025 美元。

如果我们按市值 [11] 查看前五个 ERC20 代币的持有者数量,我们会得到:

以太坊转账验证账户_批量查询以太坊账户余额_以太坊联盟和以太坊的关系

如果要迁移其他信息(比如allowance[12]函数),那么成本会更高。 即便如此,与这些代币持有的金额和升级失败的潜在成本相比,所需的成本还是很小的。

交换

批量查询以太坊账户余额_以太坊联盟和以太坊的关系_以太坊转账验证账户

部署新合约可能会产生一些操作后果。 对于基于代币的合约,运营团队在迁移期间与交易所合作以确保新合约有效而旧合约被弃用非常重要。

幸运的是,之前的代币迁移事件(如 Augur [13]、Vechain [14] 和 Tron [15])表明交易所基本上会合作。

合同迁移与可升级合同

在之前的博文[16]中,我们探讨了智能合约设计的趋势:即在合约内部加入升级机制。

可升级合约有几个缺点:

如果有强有力的论据,合同应该只有一个可升级机制,例如:

合约迁移在实现升级带来的优势的同时,也避免了很多劣势。 与迁移相比,升级的主要优势是升级成本更低。 然而,这一成本不足以弥补其所有缺点。

建议

在合约部署之前做好迁移程序的功课。

使用事件来提高数据跟踪的效率。

如果你想部署可升级的合约,那么你必须准备好迁移程序,因为你的密钥可能会被泄露,或者你的合约可能会被错误且不可逆转地操纵。

智能合约带来了新的开发范式——它们的不变性要求用户重新思考他们构建应用程序的方式,并且需要更彻底和全面的设计和开发过程。

文中提到的链接:

[1]:

以太坊联盟和以太坊的关系_以太坊转账验证账户_批量查询以太坊账户余额

[2]:

[3]: @kickico/kickico-security-breach-issue-under-control-all-kickcoins-will-be-returned-ebe65a491dec

[4]:#web3ethgetstorageat

[5]:

[6]:#balanceof

[7]:

[8]:

[9]:

[10]:

[11]:

[12]:#津贴

[13]:@AugurProject/deployment-details-rep-migration-e5413ff9fb65

[14]: @vechainofficial/vechainthor-wallet-ama-5650dea84ccb

[15]:

[16]: