通过CREATE2获得合约地址:解决交易所充值账号问题

2020-07-24 21:05 栏目:经验之谈 来源:网络整理 查看()

CREATE2是2019年2月28日由位于君士坦丁堡硬分叉[1]的以太网引入的新操作码。根据EIP 1014 [2],create2操作码主要用于状态通道,但是,我们也可以解决其他问题。

例如,交换机需要为每个用户提供一个以太网地址,以便用户可以对其进行充值。我们称这些地址为“充值地址”。当当代硬币进入充值地址时,我们需要将它们聚合到一个钱包(热门钱包)中。

让我们分析一下,当没有CREATE2操作码时,如何解决上述问题,以及为什么这些方案不适用。如果你只对最终结果感兴趣,你可以跳到最后一部分:最终计划[3]。

淘汰方案:直接使用以太网地址

最简单的解决方案是为新用户生成以太网帐户地址作为用户充值地址。必要时,在后台使用充值地址的私钥签名呼叫转移(),将用户钱包收集到exchange hot wallet中。

这种方法有以下优点:

这很简单

将代币从用户的充值地址转移到热门钱包的成本与呼叫转移的成本相同()(译者注:这与以后需要部署合同的其他方案相关)

但是,我们决定放弃这个方案,因为它有一个很大的缺陷:在某些地方总是需要保存私钥,这不仅是私钥可能丢失的问题,而且私钥的访问权限也要小心管理。如果其中一个私钥被盗,该用户的令牌将无法被收集到热钱包中。

淘汰方案:为用户创建独立的智能合同

每个用户创建一个单独的智能合同[4],并使用合同地址作为用户的充值地址,这避免了在服务器上保存地址的私钥,并通过调用智能合同来收集令牌。

但是,我们还是没有选择这个方案,因为用户不能在合同部署之前显示充值地址(这实际上是可能的,但是会很复杂,还有一些其他的缺陷)。作为交换,用户应该能够创建任意数量的帐户,这意味着他们需要在合同部署上浪费金钱,并且不确定用户是否会使用该帐户。

改进:使用CREATE2操作码预先计算合同地址

为了解决上一节无法显示充值地址的问题,我们决定使用CREATE2操作码,它允许我们提前计算要部署的合同地址。地址计算公式如下:

keccak256 (0xff地址salt keccak 256(init _ code))[12:]

描述:

地址—调用CREATE2的智能合同的地址

盐—随机数

init_code—要部署的合同的字节码

因此,可以确保提供给用户的合同地址包含预期的合同字节码。此外,可以在需要时部署合同。例如,当用户决定使用钱包时。

此外,合同的地址可以在不保存地址的情况下随时计算,因为在公式中:

地址:是一个常量,它是部署钱包的工厂合同地址

Salt:使用用户id的哈希

Init_code:它也是一个常量,因为总是部署相同的契约

继续改进

上述解决方案仍有一个缺陷:交易所需要付费来部署智能合同。然而,这是可以避免的。您可以在合同构造函数中调用transfer()函数,然后调用自毁()。这将返回部署智能合同部分的气体。与常见的误解相反,您实际上可以使用CREATE2操作码在同一个地址多次部署智能合同。这是因为CREATE2检查目标地址的随机数是否为零(它在构造函数的开头将其设置为1)。在这种情况下,自毁()功能每次都会重置地址的随机数。因此,如果调用CREATE2来再次创建具有相同参数的合同,则随机数的检查可以通过。

该解决方案类似于使用以太网地址的方案,但不需要存储私钥。因为我们不支付智能合同部署的费用,所以将资金从充值地址转移到热钱包的成本大约等于调用transfer()函数的成本。

最终计划

初始准备:

由用户_id获取随机值(盐)函数

调用CREATE2操作码(使用适当的随机数(的智能合约

具有如下构造函数的充值钱包合约的字节码:

构造函数()

地址HotWallet=0x…;

地址标记=0x…;

token.transfer (hotWallet,token。(地址(本)));

自毁(地址(0));

{}

对于每个新用户,我们通过下面的公式计算其充值钱包地址:

keccak 256(0x ff fabric _ addr hash(user _ id)keccak 256(wallet _ init _ code))[12:]

当用户将代币转入其充值钱包地址时,后台系统会监控到转移事件,并且目标参数(_to)是充值地址。此时,在实际部署充值钱包合约前,已经可以增加用户在交易所的余额了。

当用户充值钱包中累积了足够的代币时,我们就可以将所有币一次性转入平台热钱包。为此,后台调用工厂合约的如下方法:

函数deployWallet (uint256 salt) {

字节内存钱包字节码=…;

//用充值钱包合约的字节码及盐调用CREATE2

{}

此时充值钱包智能合约的构造函数被调用,这会将所有代币转入热钱包然后自动销毁。

以下是完整代码:

//请注意,这不是产品代码

杂注稠度0 .5 .6 .

"导入" ./IERC20。“索尔”;

合同钱包{

地址内部令牌=0x123.热门_钱包_地址

地址内部hotWallet=0x321.热门_钱包_地址

构造函数()公共{

//将此合同中的所有令牌发送到hotwallet

IERC20(令牌).转移(

hotWallet,

IERC20(令牌).平衡(地址(此))

);

//自毁接收气体退款并将随机数重置为0

自毁(地址(0x 0));

{}

{}

合同面料{

函数createContract(uint256 salt)公共{

//获取钱包初始化代码

字节内存字节码=类型(钱包).创建代码

程序集{

让代码大小:=mload(字节码)//获取init _字节码的大小

让新地址:=create2(

0,//0威

添加(字节码,32),//字节码本身从第二个槽开始。第一个槽包含阵列长度

代码大小,//初始化代码的大小

函数参数中的盐//盐

{}

{}

{}。注意,这不是我们的生产环境代码,因为我们还要优化钱包合约的字节码,并且使用操作码编写了。

原文[5]由SmartDec[6]创作,专门从事静态代码分析,反编译和安全开发的安全团队。本翻译得到登链社区[7]及细胞网络[8]支持。

参考资料

[1]君士坦丁堡(君士坦丁堡(硬分叉: https://learnblockchain.cn/2019/06/15/eth-history1#大都会-君士坦丁堡-君士坦丁堡-硬分叉- 2019年年年2月28日

[2]https://learnblockchain.cn/docs/eips/EIP-1014 . html环境影响评价1014:

[3]最终方案: #最终方案

[4]智能合约: https://learnblockchain。cn/2018/01/04/谅解智能合同

[5]原文: https://博客。smart dec . net/如何定义-smart-contract-address-before-create 2-use-case-for-distributed-exchange-52 B7阿达7873 b

[6]smart dec : https://www.smartcontracts.smartdec.net/

[7]登链社区: https://learnblockchain.cn/

[8]蜂窝网络: https://www.cellnetwork.io/?utm_souce=learnblockchain

微信二维码
售前客服二维码

文章均源于网络收集编辑侵删

提示:仅接受技术开发咨询!

郑重申明:资讯文章为网络收集整理,官方公告以外的资讯内容与本站无关!
NFT开发,NFT交易所开发,DAPP开发 Keywords: NFT开发 NFT交易所开发 DAPP开发