网页与网站设计实验报告,数据表和网站建设的关系,外国人在中国做视频网站,湖南门户网站设计公司1. 引言
前序博客#xff1a;
Optimism的Fault proof
用户将资产从OP主网转移到以太坊主网时需要等待一周的时间。这段时间称为挑战期#xff0c;有助于保护 OP 主网上存储的资产。 而OP测试网的挑战期仅为60秒#xff0c;以简化开发过程。 2. OP与L1数据交互 L1#xf…1. 引言
前序博客
Optimism的Fault proof
用户将资产从OP主网转移到以太坊主网时需要等待一周的时间。这段时间称为挑战期有助于保护 OP 主网上存储的资产。 而OP测试网的挑战期仅为60秒以简化开发过程。 2. OP与L1数据交互 L1以太坊上的合约可通过“bridging”与L2OP主网上合约进行交互。
同一网络内的Solidity合约调用类似为
contract MyContract {function doTheThing(address myContractAddress, uint256 myFunctionParam) public {MyOtherContract(myContractAddress).doSomething(myFunctionParam);}
}MyContract.doTheThing会触发调用MyOtherContract.doSomething。在底层Solidity通过向MyOtherContract合约发送ABI encoded call来触发调用doSomething函数。为简化开发者体验此处抽象掉了很多这种复杂性。也可手工encoding以更底层call和abi.encodeCall函数来实现相同的功能如
contract MyContract {function doTheThing(address myContractAddress, uint256 myFunctionParam) public {myContractAddress.call(abi.encodeCall(MyOtherContract.doSomething,(myFunctionParam)));}
}以上两种调用方式等价。由于Solidity的限制OP Stack的bridging接口被设计为看起来像第二个代码片段即采用更底层的表达方式。
2.1 L1与L2之间的基础通讯
从高层来看L1与L2之间的数据发送流程与以太坊上2个合约间的发送流程类似。L1与L2的通讯可通过一组特殊的名为“messenger”的合约来实现。L1和L2有各自的messenger合约用于抽象掉一些更底层的通讯细节非常像HTTP库抽象掉物理网络连接。
每个messenger合约都有sendMessage函数来向另一层的合约发送一个消息
function sendMessage(address _target, //所调用的目标层上的合约bytes memory _message, //所发送的内容uint32 _minGasLimit //在目标层执行内容的最小gas limit
) public;其等价为
address(_target).call{gas: _gasLimit}(_message);从而可调用个不同网络上的合约。 这掩盖了许多技术细节这些细节使整件事在幕后运作但这应该足以让你开始。想从以太坊上的合约调用OP主网上的合约吗非常简单
// Pretend this is on L2
contract MyOptimisticContract {function doSomething(uint256 myFunctionParam) public {// ... some sort of code goes here}
}// And pretend this is on L1
contract MyContract {function doTheThing(address myOptimisticContractAddress, uint256 myFunctionParam) public {messenger.sendMessage(myOptimisticContractAddress,abi.encodeCall(MyOptimisticContract.doSomething,(myFunctionParam)),1000000 // or use whatever gas limit you want)}
}具体可查看OP主网和测试网上合约地址 中的L1CrossDomainMessenger合约 和 L2CrossDomainMessenger合约。
2.2 通讯速度
不同于同一链上的合约调用以太坊和OP主网间的调用不是即时的。跨链交易的通讯速度取决于方向
1对于由L1-L2的交易交易由L1以太坊到L2OP主网需约1到3分钟。因Sequencer需等待包含该L1-L2交易区块之后的一定数量的L1区块以避免烦人的reorg问题。2对于由L2-L1的交易交易由L2OP主网到L1以太坊需要约7天。原因在于L1上的bridge合约需等待该L2状态to be proven to the L1 chain之后才能relay该message。 由L2-L1的交易分为4个不同的步骤 2.1Step 1将“给L1发送message”的L2交易发送给Sequencer。这与其它L2交易类似仅需数秒就可由Sequencer确认。2.2Step 2包含该L2交易的L2区块被提交给L1。这通常用时20分钟。2.3Step 3向L1上的OptimismPortal合约 提交该交易的proof。可在上面Step 2完成之后的任意时间提交。 /// notice Proves a withdrawal transaction.
/// param _tx Withdrawal transaction to finalize.
/// param _l2OutputIndex L2 output index to prove against.
/// param _outputRootProof Inclusion proof of the L2ToL1MessagePasser contracts storage root.
/// param _withdrawalProof Inclusion proof of the withdrawal in L2ToL1MessagePasser contract.
function proveWithdrawalTransaction(Types.WithdrawalTransaction memory _tx,uint256 _l2OutputIndex,Types.OutputRootProof calldata _outputRootProof,bytes[] calldata _withdrawalProof
)externalwhenNotPaused
{// Prevent users from creating a deposit transaction where this address is the message// sender on L2. Because this is checked here, we do not need to check again in// finalizeWithdrawalTransaction.require(_tx.target ! address(this), OptimismPortal: you cannot send messages to the portal contract);// Get the output root and load onto the stack to prevent multiple mloads. This will// revert if there is no output root for the given block number.bytes32 outputRoot l2Oracle.getL2Output(_l2OutputIndex).outputRoot;// Verify that the output root can be generated with the elements in the proof.require(outputRoot Hashing.hashOutputRootProof(_outputRootProof), OptimismPortal: invalid output root proof);// Load the ProvenWithdrawal into memory, using the withdrawal hash as a unique identifier.bytes32 withdrawalHash Hashing.hashWithdrawal(_tx);ProvenWithdrawal memory provenWithdrawal provenWithdrawals[withdrawalHash];// We generally want to prevent users from proving the same withdrawal multiple times// because each successive proof will update the timestamp. A malicious user can take// advantage of this to prevent other users from finalizing their withdrawal. However,// since withdrawals are proven before an output root is finalized, we need to allow users// to re-prove their withdrawal only in the case that the output root for their specified// output index has been updated.require(provenWithdrawal.timestamp 0|| l2Oracle.getL2Output(provenWithdrawal.l2OutputIndex).outputRoot ! provenWithdrawal.outputRoot,OptimismPortal: withdrawal hash has already been proven);// Compute the storage slot of the withdrawal hash in the L2ToL1MessagePasser contract.// Refer to the Solidity documentation for more information on how storage layouts are// computed for mappings.bytes32 storageKey keccak256(abi.encode(withdrawalHash,uint256(0) // The withdrawals mapping is at the first slot in the layout.));// Verify that the hash of this withdrawal was stored in the L2toL1MessagePasser contract// on L2. If this is true, under the assumption that the SecureMerkleTrie does not have// bugs, then we know that this withdrawal was actually triggered on L2 and can therefore// be relayed on L1.require(SecureMerkleTrie.verifyInclusionProof(abi.encode(storageKey), hex01, _withdrawalProof, _outputRootProof.messagePasserStorageRoot),OptimismPortal: invalid withdrawal inclusion proof);// Designate the withdrawalHash as proven by storing the outputRoot, timestamp, and// l2BlockNumber in the provenWithdrawals mapping. A withdrawalHash can only be// proven once unless it is submitted again with a different outputRoot.provenWithdrawals[withdrawalHash] ProvenWithdrawal({outputRoot: outputRoot,timestamp: uint128(block.timestamp),l2OutputIndex: uint128(_l2OutputIndex)});// Emit a WithdrawalProven event.emit WithdrawalProven(withdrawalHash, _tx.sender, _tx.target);
}2.4Step 4仅当fault挑战期当前OP主网为7天 结束之后该交易才在L1上固化。该等待期是OP Stack安全模型的核心无法规避。
2.3 访问msg.sender
合约会频繁使用msg.sender来基于calling address做决定。如许多合约使用Ownable模式来选择性地约束对特定函数的访问。因为消息本质上是通过messenger合约在L1和L2之间穿梭的所以当你接收到其中一条消息时你会看到的 msg.sender将是与你所在的层相对应的messenger合约。 为此每个messenger合约内均有xDomainMessageSender函数 /// notice Retrieves the address of the contract or wallet that initiated the currently/// executing message on the other chain. Will throw an error if there is no message/// currently being executed. Allows the recipient of a call to see who triggered it./// return Address of the sender of the currently executing message on the other chain.function xDomainMessageSender() external view returns (address) {require(xDomainMsgSender ! Constants.DEFAULT_L2_SENDER, CrossDomainMessenger: xDomainMessageSender is not set);return xDomainMsgSender;}若你的合约被其中一个messenger合约调用则可使用该函数来看实际上究竟是谁在发送该消息。在L2上实现onlyOwner modifier示例为
modifier onlyOwner() {require(msg.sender address(messenger) messenger.xDomainMessageSender() owner);_;
}2.4 L1与L2之间发送数据的手续费
对于L1-L2交易
L1-L2交易的大部分开销源自L1上合约的执行。当发送L1-L2交易时实际是调用了L1上的L1CrossDomainMessenger合约然后调用L1上的OptimismPortal合约。这些在L1上的执行会花费gas。L1-L2交易的总开销最终由以太坊上的gas费决定。L1-L2交易会触发L2上的合约执行。OptimismPortal合约会为L2执行代为收取费用——burn掉动态量的L1 gas具体量取决于所请求L2的gas limit。当更多人发送L1-L2交易时所收取的L1 gas费会增加。当更少发送L1-L2交易时所收取的L1 gas费会减少。 由于代收取的L2执行gas量是动态的所burn的gas在各个区块会各不相同。为避免gas燃尽应总是为L1-L2交易gas limit增加至少20%的buffer。
对于L2-L1方向
由L2-L1的每个消息需要3笔交易 1L2交易发起L2-L1启动交易其定价与OP主网上的任何其他交易相同。2L1证明交易证明该L2交易。只有在L1上提交了包括该L2交易在内的L2区块后才能提交此L1证明交易。该交易是昂贵的因为它包括验证L1上的Merkle trie包含证明。3L1固化交易用于固化该L2交易。仅在该L2交易超过7天挑战期之后才能提交L1固化交易。 L2-L1发送单个消息的总开销包括1笔L2启动交易和2笔L1交易开销。L1 proof交易和L1固化交易通常要比L2启动交易贵得多。
2.5 挑战期
由L2-L1的消息至少需要7天才能relay。这即意味着由L2发送的任意消息只能过了一周的挑战期之后才能在L1上收到。称其为“挑战期”的原因在于在该期间交易可被a fault proof挑战。 Optimistic Rollups是“乐观的”因为其核心思想为将某交易的结果发送到以太坊而不在以太坊上实际执行该交易。在“乐观”情况下该交易结果是正确的可完全避免在以太坊上执行复杂且昂贵的逻辑。
但是仍需要某种方式来避免发布不正确的而不是正确的交易结果。为此引入了“fault proof”。当某交易结果发布后可将其看成“pending”一段时间又名挑战期。在挑战期任何人都可在以太坊上重新执行该交易以试图证明所发布的结果是不正确的。
若某人证明该交易结果是错误的则该结果将被删除任何人都可以在该位置发布另一个结果希望这次是正确的结果经济惩罚会使错误的结果对发布者来说代价高昂。一旦给定交易结果的窗口完全通过而没有受到质疑则该结果可被视为完全有效否则会有人对其提出质疑。
无论如何这里的重点是在这个挑战期结束之前不从L1上的智能合约内部对L1交易结果做出决定。否则可能会根据无效的交易结果做出决策。结果L2-L1 使用standard messenger合约发送的L1消息在等待整个挑战期之后才能被relay。
3. OP原理
为使L1gas开销最小化OP Bedrock中的L2区块存储在以太坊链的非合约地址内https://etherscan.io/address/0xff00000000000000000000000000000000000010。 这些L2区块作为交易calldata提交到以太坊当该“交易”被包含在某具有足够attestations的区块内则没法对其仅需修改或审查。从而OP主网可继承以太坊的可用性和完整性。
为降低开销写入L1内的L2区块为压缩格式 以压缩格式来在以太坊上存储L2区块这很重要因为写入到L1是OP主网交易的主要开销。
3.1 区块生成
Optimism区块生产主要由称为“Sequencer”的单一方管理Sequencer主要提供如下服务
提供交易确认和状态更新。构建和执行 L2 区块。将用户交易提交到 L1。
在 Bedrock 中Sequencer确实像以太坊那样有一个mempool但该内存池是私有的以避免为 MEV 提供机会。在 OP 主网中区块每两秒生成一次无论它们是空的无交易、被交易填充到区块 Gas limit、还是介于两者之间。
交易通过两种方式到达Sequencer
1在 L1 上提交的交易称为存款包含在适当的 L2 链区块中。每个 L2 块都由“epoch”它对应的 L1 块通常发生在 L2 区块之前几分钟及其在该epoch内的序列号来标识。该epoch的第一个区块包含其对应的 L1 区块中发生的所有存款。如果epoch试图忽略合法的 L1 交易它最终会得到与Verifier不一致的状态就像epoch试图通过其他方式伪造状态一样。这为 OP 主网提供了 L1 以太坊级别的抗审查能力。 可在协议规范Deriving the Transaction List中阅读有关此机制的更多信息。2交易直接提交给Sequencer。这些交易的提交成本要低得多因为不需要单独的 L1 交易费用但它们当然不能抵抗审查因为Sequencer是唯一了解它们的参与者。
目前Optimism基金会在 OP 主网上运行唯一的区块生产者。有关未来计划对 Sequencer 角色进行去中心化。 基本工作流程为
1用户将交易发送到主处理程序Sequencer然后主处理程序在其版本的第 2 层 (L2) 链上处理这些交易。2处理后Sequencer将交易详细信息和更新的第 2 层状态发送到第 1 层 (L1)。3然后其他第 2 层节点使用此交易更新其第 2 层链的版本。4为了检查准确性Verifier验证者节点将其更新状态与排序器提交的状态进行比较。
3.2 区块执行
op-geth组件所实现的执行引擎使用两种机制接收区块
1执行引擎可以使用对等网络与其他执行引擎进行自我更新。这与 L1 执行客户端通过网络同步状态的方式相同。具体见happy-path sync。2op_node组件所实现的rollup节点从 L1 派生出 L2 区块。这种机制速度较慢但具有抗审查性。具体见Worst-case sync。
3.3 在各层之间bridge ETH或token
Optimism 的设计目的是让用户可以在 L2OP 主网、OP Sepolia 等和底层 L1以太坊主网、Sepolia 等上的智能合约之间发送任意消息。这使得在两个网络之间传输 ETH 或代币包括 ERC20 代币成为可能。这种通信发生的确切机制根据消息发送的方向而有所不同。
OP 主网在标准桥中使用此功能允许用户将代币从以太坊存入 OP 主网也允许将代币从 OP 主网提取回以太坊。详情见Using the Standard Bridge。
1从以太坊迁移到 OP 主网从以太坊L1到 OP 主网L2的交易称为存款。使用L1CrossDomainMessenger合约 或 L1StandardBridge合约存款交易成为与存款所在的 L1 区块相对应的“epoch”的第一个 L2 区块中规范区块链的一部分。该 L2 块通常会在相应的 L1 块几分钟后创建。详情见Deposits。2从 OP 主网迁移到以太坊提款分为3个阶段【详情见Withdrawals】 2.1通过 L2 交易初始化提款。2.2等待下一个输出根提交到L1然后使用 提交提款证明proveWithdrawalTransaction。这一新步骤可以对提款进行链下监控从而更容易识别不正确的提款或输出根。这可保护 OP 主网用户免受一系列潜在的桥接漏洞的影响。2.3故障挑战期结束后主网一周比测试网短完成提现。
3.4 Fault proof 故障证明
在 Optimistic Rollup 中状态承诺被发布到 L1OP 主网的以太坊没有任何直接证据证明这些承诺的有效性。相反这些承诺被视为在一段时间内悬而未决称为“挑战窗口”。如果拟议的状态承诺在挑战窗口当前设置为 7 天期间没有受到挑战则该承诺将被视为最终承诺。一旦承诺被认为是最终的以太坊上的智能合约就可以安全地接受基于该承诺的有关 OP 主网状态的提款证明。
当状态承诺受到质疑时可以通过“fault proof”过程使其无效。如果该承诺被成功质疑那么它将被从承诺中删除StateCommitmentChainSCC最终被另一个提议的承诺所取代。值得注意的是成功的挑战不会回滚 OP 主网本身只会回滚有关链状态的已发布承诺。交易的顺序和 OP 主网的状态不会因故障证明挑战而改变。 SCC状态承诺链SCC合约包含提议的状态根列表提议者断言这些状态根是规范交易链CTC中每笔交易的结果。这里的元素与CTC中的交易一一对应。CTC规范交易链CTC是必须应用于 OVM 状态的交易协议。OVM乐观虚拟机是一个符合第 2 层 (L2) 要求的执行框架使汇总实现能够与以太坊的主区块链进行通信。GETHGeth 是以太坊区块链的执行客户端用于处理交易。智能合约的部署和执行包括内置的 EVM。
作为 2021 年 11 月 11 日EVM 等效性的副作用fault proof流程目前正在进行重大重新开发更新。
4. 为什么 Optimistic Rollup 挑战期为 7 天
提款延迟是 Optimistic Rollup 的基本组成部分。当用户向以太坊提出有关 Optimistic Rollup 状态的声明时就会开始提款。 如这个声明可能是“我在 Optimism 上烧掉了 20 个代币所以让我在以太坊上提取 20 个代币。” 由于 Optimistic Rollup 的重点在于 L1 并未实际执行 L2 链因此 L1 不知道此声明是否有效。ZK Rollups 通过为 L1 提供一个加密证明来证明给定的声明是有效的从而解决了这个问题。乐观汇总通过要求声明必须通过挑战期才能被视为有效来解决此问题。每个claim必须等待一段挑战期在此期间挑战者可以声明该claim无效。如果有人对某个主张提出质疑那么就会开始一些链上游戏来确定该主张是否真正有效。
由于某人检测无效声明并提交挑战可能需要一些时间因此我们不可避免地需要挑战期大于零。毕竟如果挑战期的持续时间是零秒那么就没有机会提交挑战了。那么我们的问题就变成了挑战期应该是多长
最终状态的现代乐观汇总挑战游戏本质上采取提出主张的用户和质疑该主张的用户之间来回的形式实际上这些协议通常被设计为允许任何人参与要么是“团队”但现在让我们保持简单。为了举例我们假设整个过程中有大约 10 个来回步骤确切的数量有所不同但在这里并不重要。
如果双方都非常非常快那么整个挑战过程至少需要 10 个以太坊区块2 分钟。当然用户并不是像这样完全快因此您可能需要添加一些至少是基线数字 10 倍的填充即大约 100 个块20 分钟。尽管如此100 个区块还是比进入 7 天挑战期的 50400 多个区块要短得多。这里一定还有别的东西。
攻击者可以用他们的钱做什么攻击者的目标是阻止挑战者将他们的挑战交易包含在链上。毕竟如果挑战交易成功那么攻击就会失败。攻击者基本上有三种潜在的策略
1对挑战者进行直接 DoS 攻击首先阻止他们与 L1 网络交互2通过昂贵的交易向 L1 网络发送垃圾邮件以推高 Gas 价格并阻止挑战者进行交易3通过控制大量验证者来直接审查挑战者
为什么挑战期是7天
因为它比保守的餐巾纸数学下限要长得多也许更重要的是它为整个以太坊社区留下了足够的时间陷入大规模困境。简而言之利用 Optimistic Rollup 所需的攻击类型会在很长一段时间内显着降低以太坊上的交易体验。每个人都会非常生气。诚实的验证者会突然出现愿意提交挑战交易以阻止攻击。一周给了我们足够的时间来协调社交层面的这种恢复。
更多详细内容见
Why is the Optimistic Rollup challenge period 7 days?
5. OP发展历程
OP发展历程为
2019年 6 月Plasma Group 开发人员创建了一个名为 Optimism Rollup 的可扩展性解决方案 2020年 2月兼容EVM的乐观虚拟机OVM上线测试阶段9月推出带有Optimism Rollup解决方案的测试网 2021年 一月份Optimism 推出了 Alpha 版本10月EVM主网升级启动8 月以太坊和 Optimism 之间的成熟区块链桥梁启动。该桥此前只允许传输已启用的 ERC-20 代币12 月加密世界庆祝 Optimism 主网发布 2022年 4月宣布成立乐观集体治理实验并进行了多次空投。由于这一治理变化乐观主义人民银行被解散并创建了一个非营利组织——乐观主义基金会5 月$OP 币开始分配
参考资料
[1] 2023年4月 为什么从 OP 主网转出资产需要等待一周 [2] Sending Data Between L1 and L2 [3] L2IV RESEARCH 2024年1月29日 Why we invested in Rome Protocol? The Solana-Based Shared Sequencer [4] Dispute Game [5] Rollup Protocol Overview [6] Withdrawal Flow [7] Why is the Optimistic Rollup challenge period 7 days? [8] 2023年10月博客 Ethereum’s Optimistic Future: An Introduction to Optimistic Rollups [9] Optimism