全新深度解读“V神”以太坊2.0第二阶段提案:如何转移你的钱
金色财经 比特币5月20讯 本文作者是ConsenSys研究员威尔·维拉纽瓦(Will Villanueva),他此前曾担任以太坊及ERC20代币支付公司Bounties Network联合创始人兼首席科技官。最近,威尔·维拉纽瓦对“V神”Vitalik Buterin提出的以太坊2.0第二阶段提案进行了解读,金色财经将其全文编译如下:
以太坊联合创始人“V神”Vitalik Buterin最近围绕了以太坊2.0第二阶段提出了一个公开提案和额外的抽象概念。事实上,外界已经有很多对此进行解读的文章,但笔者希望从更高层次上对“V神”的提案进行总结,并让人们以一种“广度优先”(breadth-first)的方式去探索全新的思维空间。
首先,与业内普遍存在的一些看法不同,以太坊升级从“0阶段”到“2阶段”并不需要按顺序进行,每个阶段其实是可以并行处理的。
一般来说,阅读本文可能需要对以太坊2.0升级有一些基本的了解,如果你还是一个“区块链小白”,那么金色财经建议你可以先研究下面这些材料,或许对理解以太坊这次最重要的升级工作有所帮助:
https://docs.ethhub.io/ethereum-roadmap/ethereum-2.0/eth-2.0-phases/
https://media.consensys.net/exploring-the-ethereum-2-0-design-goals-fd2d901b4c01
https://media.consensys.net/state-of-ethereum-protocol-2-the-beacon-chain-c6b6a9a69129
https://github.com/ethereum/wiki/wiki/Sharding-roadmap
https://www.youtube.com/watch?v=S262StTwkmo
为了支持初始发布,以太坊2.0开发工作被拆分成了三个阶段:
1、“0阶段”侧重于构建信标链(beacon chain),并为另外两个阶段打下核心部分的基础,比如网络、签名方案、随机性等等。
2、“1阶段”专注于开发独立运行的1024分片链的机制。
3、“2阶段”的重点是执行引擎、交易思想空间、账户模型等。从本质上来说,这一阶段将会把以太坊2.0带入到实际应用之中,同时也将开启状态执行和计算。
在“V神”的第一个提案里,我们可以看到他可能受到了以太坊核心开发人员Casey Detrio的一些影响,“V神”提出了一种与人们最初假设完全不同的方法,他希望构建一个“轻量级第1层”协议,然后重点关注分片链中的第2层。实际上,第2层并不代表扩容方案Plasma或状态通道,而是专注于以一种更通用、更开放形式运行的分片链。这种方法是一种普遍的范式转化,因此可能需要你具备一些专业知识才能真正消化并掌握。然而,“V神”最新提案的优势在于为以太坊网络提供了高度灵活性,而随着研究的不断深入,未来以太坊区块链如果要引入新的变化也会变得更加简单。事实上,这与以太坊1.0形成了鲜明的对比,因为以太坊1.0将整个系统锁定在一个模型里面,所以所有系统更新或改变都只能在协议范围内进行,具有较大的局限性。在对更基础的知识有了理解之后,本文最后部分会深入探讨这个新系统的优点和缺点。
在开始全面展开本文全部内容之前,笔者会首先解释如何将你的资金从旧系统转移到分片链上。下面,就让金色财经和大家一起开始看看威尔·维拉纽瓦是如何开始的吧。
从以太坊1.0移入以太坊2.0
为了将你的以太坊从旧的以太坊1.0区块链迁移到以太坊2.0区块链中,你需要先通过把自己的以太币(ether)存入在旧区块链智能合约里燃烧掉。新区块链具有协议和投票期,以识别你的存款,并将你的以太币重新移入信标链中。除了在旧区块链的智能合约里存入以太币之外,你不需要做任何其他事情。当前协议的投票/包容系统将自动将你的资金带入到信标链。随着时间的推移,旧的区块链将会变得越来越不活跃,新系统就会逐步将另一个系统给淘汰掉。但是,这种转变最终究竟会以什么形式呈现目前仍在讨论之中。
在现有规范中,只要你存入至少32 ETH,那么就会自动成为验证人/权益人(staker)。但是,大多数人可能希望将他们的以太币带入到分片链里,以便能在很多应用程序、合约或钱包里使用。在“V神”的提案中,你可以通过多个步骤完成此操作。但最重要的是,你首先要了解在任何分片链中都没有原生以太币的概念。这个想法,其实就是分片链内第2曾结构开始浮出水面的地方。因此在深入讨论如何将以太币带入分片链之前,我们需要先介绍一些背景知识。
信标链合约
现在,存储智能合约的信标链已经被称作为“信标链合约”,这些合约与你在以太坊1.0上应用程序部署的常规智能合约类似(或是在eth2账户抽象方案中设置为代表你账户的多重签名钱包的智能合约类似),也都会在分片链中上线。相比之下,信标链合约将代表整个执行环境或交易框架。举个例子,你可以拥有一个不同的信标链合约,它可以代表以太坊的不同实现或框架。一个可以代表基于账户的以太坊交易/存储模型,而另一个,则可以代表基于未花费交易输出(UTXO)的以太坊模型。在实际应用的过程中,其实并不应该有太多信标链合约,而是应该保持较少的数量——特别是在开始阶段。
但是,在构建这个新系统的思维模型的时候要特别谨慎。在上面的解释中,您可以假设每个信标链合约会代表不同的虚拟机,但这种假设其实是不正确的。相反,合约定义/强制执行状态、以及纯函数有些类似于当前以太坊1.0上的预编译(precompiles)。通过这篇文章,你会发现这个模型应该更有意义。
在如今很多关于以太坊2.0的讨论中,执行人(executor)和执行环节也可以作为一个整体用于指代信标链合约。
接受一个框架
现在我们已经有了一点背景知识了,让我们继续这趟深入了解以太坊2.0的旅程把。好了,我们已经决定把自己的以太币带入到基于可接受账户的以太坊模型里。我们可以说,这个模型是在信标链合约0中被定义的(或者是存在于合约列表的第0个索引中)。此外,我们已经将以太币从以太坊1.0带入到了信标链,这个模型中会有一个验证人/staking账户,但我们会选择不去成为一个活跃的验证人。相反,我们希望自己的以太币能够从表层渗透到一个特定的分片。在这种情况下,我们更愿意说自己对于带入到分片5(我最喜欢的加密猫应用程序就在那里,而且我真的特别喜欢玩这个游戏)更感兴趣。
为了把我们的以太币带入到分片4,我们需要将信标链以太币转换成为信标链合约0.值得庆幸的是,一个新的交易类型会被引入到名为“withdrawToContract”的信标链中。我们可以在此调用新增额外的数据。在我们的例子中,我们会把包含之前发送以太币的分片地址添加到分片号码5里,我们需要发送的数据也会在信标链合约中被定义。
{
# 你在信标链中持有以太币的账户
"validator_index": uint64,
"data": {
shard: 5,
address: address
},
"pubkey": BLSPubkey,
"signature": BLSSignature
}
在现实中,该数据会被发布到信标链中的一个接收方中,而且还会通过区块提议人(proposer)被包含在信标链区块数据里。基本上,信标链存储每个区块的接收列表。
现在,我们的以太币已经被锁定了,而且可以在分片5中使用这些以太币。在深入了解索要这些以太币的过程之前,依然还是需要再深入了解更多背景信息,因为我们必须要知道更多分片链和信标链合约之间的关系。
分片链合约和状态执行
如上所述,分片链并没有原生以太币的概念。事实上,你需要把自己的以太币锁定到信标链和阅历,然后在分片链上使用。想要理解这个过程,最好的办法就是分析理解分片链和信标链合约之间的关系。从本质上来说,分片链机器状态执行函数将是信标链合约中定义框架的反映和集合。
在每个分片链区块里,会生成一个全局状态。分片链中的状态会始终直接映射到信标链合约,让我们先从“V神”使用的示例开始:
{
# 你所认为的实际“状态”
"objects": [[StateObject, 2**256], 2**64],
# Receipts
"receipts": [Receipt],
"next_receipt_index": uint64,
# Current slot
"slot": uint64,
...
}
对象列表中的每个索引都会被映射到每个信标链合约索引之中,如果有两个信标链合约,那么对象就只会有两个实体。乳沟基于账户的以太坊是信标链合约0,而未支付交易输出是合约1,那么索引0和索引1将会分别映射每一个状态。Slot只是分片上区块编号的另一个名字,在每个索引中,我们会有[StateObject, 2**256],这只是一个担忧2²⁵⁶(256比特)密钥选项的密钥价值存储。每个StateObject都包含以下域:
{
# 以便将来兼容的版本号
"version": uint64,
# Contents
"storage": bytes,
# StateObject can be removed if it expires (ie. now > ttl)
"ttl": uint64
}
我们稍后会聊聊上面代码里的“ttl”,它代表了状态到期,以及围绕租金的更多讨论。(金色财经注:TTL是 Time To Live的缩写,该字段指定IP包被路由器丢弃之前允许通过的最大网段数量。TTL是IPv4包头的一个8 bit字段。TTL的作用是限制IP数据包在计算机网络中的存在的时间。TTL的最大值是255,TTL的一个推荐值是64。)存储只是一个任意的字节数组,它将由信标链合约中规定的框架构成或定义。然而,最近有研究提出了一个全新的方法,我们可能甚至根本不需要节点来存储状态,这可能意味着在协议层并不需要严格地定义“ttl”。这个问题其实可以展开很多内容.......但是现在,还是让我们先把以太币转移到分片链上吧!
将以太币转移到分片链
信标链合约有一个叫做“depositToShard”的函数代码,如下:
def depositToShard(state: BeaconState,
receipt: WithdrawalReceipt,
proof: WithdrawalReceiptRootProof):
# Verify Merkle proof of the withdrawal receipt
assert verify_withdrawal_receipt_root_proof(
get_recent_beacon_state_root(proof.root_slot),
receipt,
proof
)
# Interpret receipt data as an object in our own format
receipt_data = deserialize(receipt.withdrawal.data, FormattedReceiptData)
# Check that this function is being executed on the right shard
assert receipt_data.shard_id == getShard()
# Check that the account does not exist yet
assert getStorageValue(hash(receipt_data.pubkey)) == b''
# Set its storage
setStorage(hash(receipt_data.pubkey), serialize(EthAccount(
pubkey=receipt_data.pubkey,
nonce=0,
value=receipt.amount
)))
上述代码里的评论应该是提供了一些背景数据,所以在此我们并不需要做较为深入的解读。基本上,我们只要提交打印在信标链上的原始提款收据就可以了。这个函数是在分片中执行的,同时还会执行Merkle可信树校样来确保收据有效。如果有效的话,你就可以做好准备,因为带有你账户的数据已经被写入到新存储里了。(金色财经注:Merkle 可信树是为了解决多重一次签名中的认证问题而产生的,Merkle 可信树结构具有一次签名大量认证的优点,在认证方面具有显著的优势。如今,Merkle 可信树的树形结构已经被广泛应用到了信息安全的各个领域,比如证书撤销、源组播认证、群密钥协商等等。并且基于 Merkle 可信树的数字签名方案在安全性上仅仅依赖于哈希函数的安全性,且不需要太多的理论假设,这使得基于 Merkle 可信树的数字签名更加安全、实用。)
EthAccount {
pubkey: BLSPubkey,
nonce: 0,
value: 32eth
}
转移资金
到了这一阶段,我们已经在分片链上有了一个账户,那么接下来的工作就是要把一些我们的钱转移到另一个账户里。其实这并不难,只需要在信标链和阅历添加另一个函数代码:
def transfer(sender: bytes32,
nonce: uint64,
target: bytes32,
amount: uint64,
signature: BLSSignature):
sender_account = deserialize(getStorageValue(sender), EthAccount)
target_account = deserialize(getStorageValue(target), EthAccount)
assert nonce == sender_account.nonce
assert sender_account.value >= amount
assert bls_verify(
pubkey=sender_account.pubkey,
message_hash=hash(nonce, target, amount),
signature=signature
)
setStorage(sender, EthAccount(
pubkey=sender_account.pubkey,
nonce=sender_account.nonce + 1,
value=sender_account.value - amount
))
setStorage(target, EthAccount(
pubkey=target_account.pubkey,
nonce=target_account.nonce,
value=target_account.value + amount
))
需要再次提醒的是,这里其实并不需要你做太深入的理解,因为这个函数只会减少旧账户的余额并增加新收款账户的余额。但需要记住的是,这些函数都是在分片的共识层上执行的。此处会使用BLSSignature签名模式来确保与信标链上的当前工作一致,但同时,这里也可以使用其他签名模式。实际上,如果没有供接收账户使用的存储,那么应该需要额外的代码来创建新账户。我们的图表获得了一个不错的更新。
到了这里,不妨让我们先来回顾一下此前完成了哪些工作吧。
回顾截至目前的工作
到目前为止,我们已经拿走了以太币,并且将其从以太坊1.0区块链中转移到了以太坊2.0信标链中。我们还会把这些以太币岁定在一个信标链合约之中,这个合约将让我们在分片5上使用这些以太币。最后,我们会把我们的一些以太币转移到该分片的另一个账户里。
现在,事情开始变得更简单了。
当前框架仅代表具有余额的基本账户模型,我们当然可以让它变得更复杂,而且还能在其中纳入智能合约和复杂的状态执行,但先让我们缓一缓。我想再给大家普及一些基础知识,之后再讨论更复杂的交易模型。
费用市场
在这篇文章中,我们已经说过分片链没有任何原生以太币的概念。实际上,根据你所在的框架或信标链合约,你的以太币会以不同的方式进入分片链。而这,很可能会引发其他一些问题。比如,假设没有原生代币,区块生产者该如何获得报酬?在我们的示例中,这个框架与信标链以太币1:1锚定的。因此,区块生产者可能不介意接受以太币、或是信标链合约中定义的其他代币。然而,这么一来又会产生更多的问题。
这是否意味着区块生产者需要接受已建立的每个执行环节或框架?区块生产者是否为了确保交易是值得的,需要在每个信标链合约框架上建立验证、转换和安全分析?对于区块生产者来说,这些问题会让事情变得非常麻烦,而且效率也会变得很低。
这个主题非常有趣,而且“V神”随后也深入探讨了这些问题。总的来说,以太坊2.0会带来一些范式转换,责任会转移到许多中继器(也有人称之为运营者),而不是过去管理内存池(mempool)网络的节点。
如果你希望包含交易,那么可以把你的交易广播到中继器(relayer)网络——与当前向运行内存池的节点进行广播的过程不同。这些中继器将负责组织、订购和验证他们收到的交易,并且从中挑选最有利可图的交易,而那些支付费用最高的交易会最先被验证。在一组交易被组织进入到一个暂定的区块之后,中继器将会估算其gas支出会有多少。在这种情况下,如果区块生产者包括了自己的交易集合,那么在中继器将愿意为区块生产者支付固定的费用;如果不包括的话,区块生产者就可以直接从运营者(也就是前文所说的中继器的另一种说法)那里直接收取费用。在此,我们暂时不会考虑太多实际实际投产实施时的细节问题,比如为了偿还区块生产者,可能会直接添加一个函数到主以太坊信标链合约里或一个分片链里。但现在,我们暂时不去考虑这些,而是通过一个例子来简化基本国策。
我们假设用户在信标链合约0下的基本交易非常简单,如下所示:
{
'to': address,
'from': address,
'amount': uint64,
'gas_price': uint64,
'signature': bytes
}
此时我们假设中继器提交了一个区块提案 BlockProposal (他们已经组织了自己的交易清单):
{
'transactions': [Transaction],
'signature': bytes,
'fee': uint64
}
反过来,我们再将在信标链合约中包含一个额外的函数代码:
def process_block(block: BlockProposal):
assert verify_signature(block, block.signature)
for transaction in transactions:
process_transfer(transaction)
其中process_transfer 的函数代码如下:
def proccess_transfer(tx):
assert verify_signature(tx, tx.signature)
to = get_storage(tx.to)
to.balance += tx.amount
gas_fee = TRANSFER_GAS * tx.gas_price
from = get_storage(tx.from)
from.balance -= (tx.amount + gas_fee)
relayer = get_storage(get_relayer())
relayer.balance += gas_fee
set_storage(tx.to, to)
set_storage(tx.from, from)
set_storage(get_relayer(), relayer)
由于围绕交易费用和gas费用支出的实际账户抽象模型仍在不断发展,我们将保持基本费用的简单表达:TRANSFER_GAS。
很快,我们将进一步讨论如何扩展这个模型来处理生产环境下的代码执行和账户抽象。此外,上面还跳过了一个小细节——笔者并未描述process_transfer函数是如何正确执行的(在合约中需要运行额外的wasm代码),这个问题我们会稍后讨论,先让我们再添加一层复杂性,并且深入讨论一下如何从分片链中彻底去除“状态”这个概念。
分片链不需要状态
为了更深入地理解分片链不需要“状态”这个概念,你可以先学习一下“V神”之前发布的提案,其中他介绍了下面两个想法:
1、我们之前描述的“状态”或“对象”字段并不需要在分片节点内维护,但是这些概念可能依然会存在于以太坊2.0里。但是,这些概念将存在于应用层而不是共识层了,对“插入”到某些特定执行环境不感兴趣的节点没有知道这些概念的必要。
2、信标链上的“签入”(checkins)和跨链连接会被压缩状态签入(比如Merkle哈希)。
这个概念,会让之前围绕存储ttl、poking、以及到期的讨论变得毫无用处。由于没有“状态”被存储起来,因此在以太坊2.0里可能并不需要考虑协议到期问题,但是为了减少中继器网络上的存储要求,我们仍然需要“分片链不需要状态”这个概念。
笔者暂时不想深入研究无状态客户的概念,因为这个问题是非常复杂的,如果要讨论话肯定需要专门再写一篇文章了。但是,我们在此会对这个问题做出一个比较简短的总结。在上面的例子中,你会注意到我们使用了get_storage函数,该函数很可能会映射到一个runtime函数(EEI),该函数会把存储在本地数据库运行节点里的一个值连接到ewasm或Web聚合环境中,这时将会与以太坊虚拟机(EVM)操作码SLOAD保持一致。
一个无状态系统意味着你不需要在节点中维护存储或“状态”信息,事实上,此时你可以在交易数据中包含所有函数需要访问的存储。从本质上来说,这些交易其实会提交自己的数据库,而且还包含了这个数据库证明。例如,如果我们将以下内容作为关联我们信标链合约0的执行环节存储:
[
...,
EthAccount{
nonce: 3,
value: 1232,
pub_key: BLSPubkey
},
EthAccount{
nonce: 12,
value: 22,
pub_key: BLSPubkey
},
...
]
我们可以假设有大量实体,然后将存储列表“Merkle化”,这样我们就可以从数据中生成Merkle根哈希。接下来,我们可以只存储Merkle根数据,而不是把整个“状态”数据存储在每一个分片之中,比如我们可以只包含witness_data数据,而不仅仅是在交易中包含签名。witness_data数据将包含签名和Merkle分支组合,以证明账户的当前状态和交易的接收账户,我只需要为交易访问的状态值提供Merkle分支就可以了。在资金转移中,你只需要确认自己的账户状态和接收账户的状态,节点也不再需要保留当前活动存储的海量数据库了。相反,节点现在可以将每个交易中的witness_data数据当做是数据库。“无状态客户”这个概念很有吸引力,我建议大家可以阅读这篇文章深入了解一下。
你或许会问,如果节点不再追踪存储,是否意味着需要用户自己去追踪它呢?或者,用户会将交易存储直接保存在本地?如果他们丢失了数据而且无法再提高witness_data会发生什么状况?是否意味着用户从此就无法获得资金和自己的账户了呢?
上面这些问题都非常好,而笔者给出的答案也会很酷——为提交拟议区块给区块生产者的中继器提供激励机制,让他们去保存存储。其他类型的节点也可以作为独立第三方存在,此外用户还可以在本地存储自己的状态,只有当他们本地存储丢失的时候才有必要请求第三方或中继器的帮助,此时第三方或中继器可以收取适当的费用提供此服务。从本质上来说,存储和存储费用可以完全从核心协议中删除,所有核心协议需求都是Merkle哈希或是其他压缩值。为了继续保持灵活性,我们可以根据执行环节或每个信标链合约来定义见证格式(witness format)。
使用全新的无状态解决方案还有另一个好处,那就是我们可以在信标链跨链连接中检查这些状态根(state roots),也将带来巨大的好处,为什么呢?让我们继续分析下去。
信标链跨链连接
每隔6分钟,每个分片链的当前区块哈希就会被检入到信标链中,这个数据检入动作被称为跨链连接,这个操作可以建立不可改变性(finality)。实质上,当单独的分片之间存在通信、或者信标链需要验证特定分片上的接收人时,它可以等待通过等待跨链出现在信标链上来确立不可改变性。此时,Merkle证明将会被一直生成,以确定该分片上的所有收据或交易确实发生。这里,我们先稍微讨论一下有关跨链分片通信的细节。
在全新的无状态模式里,我们可以使当前阶段0和阶段1中的实现变得更加高效,因为在新模式里不再需要单独改组委员会。
为了更加深入地解释这个问题,我们在此将做进一步分析。
最初的阶段0规范创建了一个证明人永久委员会(persistent committee)和一个证明人阶段委员会(epoch committee)。作为验证人或权益人,你将会有两个任务,一个任务是作为阶段委员会的成员去验证插入信标链的slot,另一个是作为永久委员会的成员去验证插入分配了的slot。永久委员会将会在很长一段时间内(大约1-2周)来管理分片链上的证明、投票和验证工作,直到一个分片链上的交易全部转移到另一个分片上;另一方面,阶段委员会将在一个时期内的一个时段内投票支持特定分片上的跨链和不可变性。该委员会会在每个时间段(大约6分钟)进行改组,每次改组之后都会验证一个独立分片链跨链。
现在你会发现,我们已经不需要在分片链上维护存储了,此时就可以把这两个委员会进行合并。最初这两个委员会是分开的,因为一个全节点在某个持续时间段之后可能需要数天/小时才能验证新分片。在无状态客户模式中,我们可以把这段时间大幅减少,现在每隔1-2个小时就能改组一次,这样也会带来一些其他好处,比如:
1、减少分片链上的改组时间,可以为我们提供更好的安全性和便捷性(无需花费好几天时间来同步全阶段,并且权益人之间的沟通也需要更少时间就能完成);
2、跨链/信标链委员会的改组时间更长的话,也会为我们带来更多网络稳定性,并且减少每隔6分钟同步更新一次客户端的负担。
跨分片(Cross shard)交易
实际上,跨分片交易很大程度上已经超出了本文涉及的业务范围,我们正在编写一些概念证明,并希望在这一领域里积极展开研究,预计很快就会关于这个主题的分析文章,这里先推荐两篇比较不错的博客文章:
https://ethresear.ch/t/fast-cross-shard-transfers-via-optimistic-receipt-roots/5337
https://ethresear.ch/t/phase-2-pre-spec-cross-shard-mechanics/4970
需要注意的一点是,在大多数情况下,你不需要真的等待6分钟来确认每个分片链把当前区块哈希检入到信标链中,乐观地看,其实你可以将多个分片上的交易组合在一起检入。
拓展到完整状态执行(Full State Execution)
当做到了这一步,恭喜你!你已经吸收了很多有价值的信息了。但走到这一步,也意味着你真的需要认真读一读“V神”的提案(他对完整状态执行进行了概述)。当然,如果你不想花太多力气研读,也可以直接看看“V神”的结论,其中覆盖了他提案的优点和缺点。在此,笔者将给出一个简短的分析解读。
以太坊2.0中的执行环节将在ewasm上运行,ewasm是Web聚合的一个子集,旨在与能够映射到特定op_codes的节点runtime函数一起运行。Web聚合运行和op_codes都会被计量,执行引擎也将为区块计算代码被执行需要多少gas费用。为了更深入地了解gas机制如何运作,其术语账户抽象(term account abstraction)解读会指导你朝着正确的方向发展。此外,每个执行环节或信标链合约都可以构建自己的账户抽象gas机制。
但首先,让我们先来看看它会是什么样子。
EthAccount可能会添加一个额外的域,代码:
EthAccount {
pubkey: BLSPubkey,
nonce: 0,
value: uint64,
code: bytes
}
虽然这里会有一些变化,但其实并不会区分合约账户和外部拥有账户(EOA)。在当前的以太坊1.0中,一个钱包管理的账户(比如MetaMask)存储和一个已部署的合约存储还是有所不同的,你可以点击此处了解更多信息。
接下来,你必须要更新我们之前描述的process_block函数,此时可能需要一系列包装函数来创建适当的调用环境,包括设置tx.sender,tx.executor等。另外,你还可以定义账户抽象、gas限制规则等。“V神”的提案里包含了一组EEI函数,该函数可以添加到执行环境或信标链合约中。在process_block和包装函数集中,你将使用:
executeCode(code: bytes, data: bytes) -> bytes
包装函数可能会从适当的EthAccount中自动抽象和加载代码。
通过位阈(Bitfields)进行双重支付保护
第二阶段提案有一部分是将信标链和分片链添加到一个交易接收方列表里,这个交易接收方是非常重要的,比如我们会使用depositToShard函数调用信标链里的交易接收方信息。此外,分片链还会将交易接收方信息存储在区块里,分片链接收方信息将用于以下两个目的:
1、通过merkle证明验证跨分片交易
将资金发送到接收方分片需要在源分片上烧掉资金,接收方分片需要运行一个验证,确保资金的确已经被烧毁了;
2、验证资金已经返回到信标链里
除了最初通过depositToShard索取资金的机制之外,还应用与上述相同的机制。
分片链上的aReceipt结构代码如下:
{
# Unique nonce
"receipt_index": uint64,
# Execution Script (beacon chain contract index) that the receipt is created by
"executor": uint64,
# Address that it is intended for
"target": bytes32,
# Data
"data": bytes
}
这些方法中存在的一个主要问题,就是不会两次使用一个接收方——特别是在无状态模式中。由于你不能再每个区块上包含“排除证明”(exclusion proof)——这是不可能的,所以就必须采用另一种方式。“V神”在提案中创建了一个check_and_set_bitfield函数,旨在追踪已经使用过的接收方,该函数如下:
check_and_set_bitfield_bit(bitfield_id: uint64, bit: uint64)
上述函数中的“id”将映射接收方索引,每个分片链和信标链在每个已发布的接收方上递增接收方索引。“bit argument”将映射到一个辅助标识符,信标链接收方可以通过“bit=0”来追踪,每个分片链可以通过“bit = SHARD_COUNT + 1”来追踪。拥有辅助标识符很重要,因为每个分片链和信标链在接收方索引上总发生冲突。调用该函数可以将位阈块中的bit设置为1,如果它已经为1,则会声明错误。 这意味着已经该接收方已经被消费了且正在尝试进行双重支付。(金色财经注:bitfield 计算机术语,译为“位阈”(见谭浩强《C语言程序设计》),指用一个字节中不同的二进制位表示不同的信息。比如cpu中的程序状态字PSW,字节中不同的位表示不同的状态信息,称位标志位。)
总结
不可否认,这篇文章的内容非常多,希望它能够帮助你更深入地了解目前、以及未来不断发展的以太坊第二阶段规范。 “V神”的最新提案也是一个不错的辅助资源,如果你能仔细阅读一下或许对于理解整个以太坊2.0也非常有帮助。
最后,我将列出“V神”总结的提案优点和缺点,你可以将其和第1层协议级别严格设置的规则对比一下。
优点:
1、共识分叉的风险更小;
2、更快的升级更新部署时间(现在只需更新执行/信标链合约,而以太坊1.0必须要更新核心协议和客户端代码);
3、没有硬分叉治理政策,未来更容易升级环境;
4、在不同客户电子实现代码编写和代码重复的操作更少;
5、能够在同一基础层上并行测试不同的方法。
缺点:
1、执行环境/信标链合约必须要仔细审核,以确保没有错误/问题;
2、硬分叉“政治”虽然少了,但是标准化“政治”却更多了;
3、共识层、第2层、中继网络和次级环境的整体复杂性风险变得更大了。
文章编译自 Medium