Nervos Fans

存储租金、合约休眠/唤醒机制、分片三则

2019-01-24  本文已影响0人  526ba0512193

为想创建项目的朋友搭建创业平台,请感兴趣的朋友加乐乐微信:sensus113

NervosFans 微信公号:Nervosfans

谢谢!


改善租金用户体验:睡/醒机制

/醒(sleeping/waking),不是睡醒。此方案旨在改善因存储租金导致合约可能被删除的用户体验。方法如下:

1. 可随意规定任意合约的生存期(time to live/TTL),简单起见,这里以区块编号表示。 向合约中充值ETH即可延长此TTL。

2. 若当前区块编号超过合约TTL,“戳一下”即可让合约进入休眠状态。

唤醒休眠状态的合约,需提交(i)能证明合约被删除时所处状态的Merkle证明,以及(ii)一组能证明合约尚未被( 任何区块)唤醒的Merkle证明(或者一个能证明合约尚未被一系列区块唤醒的证明)。这么做是为了防止合约在T1时间死亡,在T2时间被复活,在T3时间死亡,然后又被T1的Merkle证明复活,注意,此处复活合约应使用T3的Merkle证明。

得益于合约创建地址机制,这波操作可以相当安全的在layer 2上进行,且不用对基础层协议作出变更。用CREATE创建的合约地址是 sha3(creator+ code + salt)[12:],所以专门搞一个工厂创建合约的话,验证合约是否由该工厂创建就会变得十分简单。对于休眠合约来说,只有这个工厂才能在相同的地址上重新创建(也就是唤醒)的操作。

工厂可以从事以下两种方式的合约创建:

1. createNew(code,_salt): 用 salt = sha3(_salt, block.number)调用CREATE

2. wake(address,proof):  检查Merkle证明且在证明有效时唤醒合约

对createNew 区块编号的依赖则保证了已有代码的地址上无法使用这个函数创建合约,而且唤醒过程需要有Merkle证明表明函数唤醒合约的操作正确。 假设我们规定某个已创建合约一周之内不能‘死’(意思是想做合约状态修改至少等一周),那么Merkle证明就是一个以周为单位证明合约不存在的Merkle分支。 若区块头包含跳跃表,其中每个区块都指向前一周的区块,那么证明的大小约1000字节/周,也就是每20年约1 MB。 若Merkle证明大小 > 块大小限制,则可在多个区块中跨多笔交易提交。

那么,用户体验如下:

默认下,会抛出对空地址的跨合约调用;如此,出现类似访问列表以及历史调用堆栈深度限制产生的那种安全模型,这个模型中合约需要假设自己调用的任何合约都不一定可用。若用户想执行调用,同时认为调用依赖目前处于休眠状态的合约,就需要找到相关的历史数据(这些数据或来自位于Layer 2的某种市场或直接请求存档节点)构造相应的Merkle证明,而后发送多笔交易:第一笔/批交易发送的是执行唤醒操作所需的Merkle证明,最后一笔交易是用户的计划要做的事情。

保留合约状态(存储租金)可以被看成一种既收益于任意动态状态访问的抗审查属性,同时‘花点小钱(gas成本)避开提交Merkle证明’即可访问合约的操作。


最小状态执行提案

这个提案旨在创建一个能与大量layer 2基础设施配合使用的至简layer 1状态执行框架;特意让不同设置相互竞争,以产生工作方式迥异的各种合约类型, 譬如以太坊1.0风格的合约交互或UTXO风等等。

这里假设有个叫“EWASM”的VM,以代码及数据为输入,运行代码,并最终以返回值或错误代码退出,然后我们还能指定外部函数接口。

1. 存在全局状态值 TOTALFEE。 默认下, TOTALFEE随每个区块增加1 gwei,有需要的话也是可以把规则定的更复杂一些的。

2. 存在一种帐户类型,即合约。 每个合约都有一段代码(一个字节数组)、一块存储(另一个字节数组);合约地址是自己initcode的哈希加上一个salt(同CREATE2中)。 合约还会在最后一次被修改时存储 TOTALFEE的值(TOTALFEE_WHEN_LAST_MODIFIED)。

[if !supportLists]l [endif]合约根据总大小支付租金。 意思是,若合约已存储TOTALFEE_WHEN_LAST_MODIFIED F1,且在全局TOTALFEE 为F2时被修改,则合约的ETH余额减少(F2 - F1) * (100 + len(code) + len(storage)),合约TOTALFEE_WHEN_LAST_MODIFIED更新为F2。 新余额小于0时,合约被删除。

3. 存在“戳一下(poke)”这个特殊操作,(poke的)gas成本为0但每个区块的调用次数有限。Poke对某些目标来说是空操作(no-op),但仍属于“修改”操作。Poke可用于删除未支付租金的合约。 一般来说,我们依靠矿工的自愿poke操作清除旧帐户。

4. 合约代码为带有READ_STORAGE、 SET_STORAGE以及 CALL 等公开操作的EWASM,CALL在同一个分片上调用合约并向其发送规定数量的ETH。

5. 每个分片的某个特定地址(譬如0x10)上存在一个返回环境数据(如区块编号、区块哈希、时间戳等等)的合约。

6. 每个分片的某个特定地址(譬如0x20)上存在一个具有两个函数的合约。第一个函数是generateReceipt,以ETH数量、目标分片、目标地址以及calldata作输入;第二个函数是claimReceipt,以Merkle分支作输入。 跨分片的合约间通信主要依靠对这两个函数的调用。

多说两句:

我们还可以向合约FFI添加一个 “yank(拖拽)”操作,(yank)在删除合约的同时创建一个收据,这个收据能触发另一个分片上使用相同代码、存储以及ETH余额的合约创建(详见跨分片拖拽)。

我们还可以添加个能够轻松构建库的DELEGATECALL操作。

对于租金来说,也有个其他方案:合约维持TOTALFEE_TTL值,当前的全局TOTALFEE超过TOTALFEE_TTL时,合约可以销毁。 合约被触及时,会多消耗G 个gas; G *

MINFEE(“minfee”概念见此处)被添加至合约TOTALFEE_TTL中。

底层协议不变,以下操作均能在layer 2完成:

1. 睡眠 - 唤醒机制

2. 跨分片调用

3. 用于存储的高级语言方案,譬如,这个,实施可使用智能合约作数据存储(data stores)

4. ZEXE及其他智能合约框架使用Merkle树做储存的合约

5. 用带有未包含证明累加器做储存的合约


防双花:跨分片收据及休眠/唤醒

跨分片交易的一般过程是(以转5 ETH为例):

1. 分片A上销毁5 ETH,创建一个收据包含(i)目标分片,(ii)目标地址,(iii)值 (5 ETH),(iv)唯一ID(即,(Merkle)根被提交至该区块状态根的Merkle分支)

2. 分片B知晓分片A的状态根后,提交能证明该收据已进入分片B的Merkle分支。若Merkle分支验证无误且该收据尚未被花掉,(分片B)生成5 ETH给与接收人。

为防止双花,需要在存储中跟踪哪些收据已被花掉。 那么为提高效率,需要为收据指定顺序ID。 具体而言,就是在每个源分片中为每个目标分片存一个叫‘下个序列号(next-sequence-number)’的东东,用源分片A和目标分片B创建完新收据时,(收据)序列号就是分片A中分片B 的下个序列号(这个‘下个序列号’必须是递增的,否则会出现重复使用的情况)。也就是说,为防止双花,目标分片中只需要跟踪对应(每个)源分片的SHARD_COUNT位字段(bitfield),那么每笔跨分片交易的存储成分就只有1位。

注意,把两个机制统一一下,就有可能实现协议的简化:干脆把合约的休眠/唤醒过程搞成强制性跨分片交易,源和目标(分片)相同即可。唤醒合约时,跨分片交易的后半部分(即收据发布)自然发生。

但是,这个方案有个问题:跨分片交易(以及休眠/唤醒过程)会产生永久存储,虽然说只有1位吧,也是永久的。假设每个分片每秒进来10笔跨分片交易+休眠,年存储算下来就是315M 位,大概39MB的样子。

看上去也能忍对吧,但是可以不用忍的。

我们把时间分成以N个区块为单位的周期(好比,N个区块= 1年)。 假设目前在k周期,我们在状态中存储k-1到k期间已消耗序列ID的列表。 周期增至k+1时,从状态中删除k-1期间的列表,并将该列表的Merkle根存为收据(详细见DBMADouble-batched Merkle log accumulator)。

k期间时,想要花掉/消耗掉某个 j 期间(j<k-1)生成的收据,需要提供j 到k-2之间各个周期的Merkle证明,表明该收据(在此期间)尚未被消耗掉。

所以,此方案具有如下属性:

1. 最大存储要求:每个分片小几百MB;最好的情况是一个时间段内所有人都在消耗收据,那么存储需求只有39 MB;若经常出现消耗老旧收据的情况,这个数值(即存储要求)可能变大,原因是某段时间内约4亿个ID编号被消耗掉的总熵会变得更高(注:熵用来度量不确定性)。

2. Merkle证明的最大长度约1 kb/年。

这里面有个自然的线性tradeoff,意思是说通过缩短周期长度,存储减少10倍,用来唤醒老旧合约的Merkle证明长度就会增加10倍。


https://ethresear.ch/t/improving-the-ux-of-rent-with-a-sleeping-waking-mechanism/1480

https://ethresear.ch/t/a-minimal-state-execution-proposal/4445

https://ethresear.ch/t/cross-shard-receipt-and-hibernation-waking-anti-double-spending/4748

上一篇下一篇

猜你喜欢

热点阅读