构建你自己的Rollup——BYOR 项目一览

OKX欧易app

OKX欧易app

欧易交易所app是全球排名第一的虚拟货币交易所,注册领取6万元盲盒礼包!

APP下载   官网注册

编译:登链翻译计划

你是否曾经想要深入了解 Rollup 的运作原理?理论很好,但亲身实践经验总是更可取的。不幸的是,现有的项目并不总是让人轻易地查看内部情况。这就是为什么我们创建了 BYOR(Build Your Own Rollup:构建你自己的Rollup)。它是一个具有最小功能的主权 rollup,重点是使代码易于阅读和理解。

我们这个项目的动机是让人们(无论是外部人员还是内部人员)更好地理解我们周围的 rollup 实际上在做什么。你可以在 Holesky 的已部署的BYOR上玩耍,或者阅读GitHub 上的源代码。

BYOR是什么?

BYOR 项目是一个简化版本的主权 rollup。与乐观和零知识证明的 rollup 相比,主权 rollup 不会在以太坊上验证状态根,只依赖于以太坊上的数据可用性和共识。这样可以防止 L1 和 BYOR 之间的信任最小化桥,但极大地简化了代码,非常适合教育目的。

代码库由三个程序组成:智能合约、节点和钱包。当它们一起部署时,它们允许最终用户与网络进行交互。有趣的是,网络的状态完全由链上数据确定,这意味着实际上可以运行多个节点。每个节点也可以作为排序器(Sequencer)独立地发布数据。

下面是 BYOR 中实现的完整功能列表:

费用排序

将状态发布到 L1 并从 L1 获取状态

丢弃无效的交易

查看账户余额

发送交易

查看交易状态

使用钱包

在钱包应用中,它充当网络的前端,用户可以提交交易,并检查账户的状态或交易的状态。在登陆页面上,你会看到一个概览,其中提供了有关 rollup 当前状态的一些统计信息,然后是你的账户状态。很可能,这里仅有一个按钮用来连接你选择的钱包,并有关于代币水龙头的消息。在下面,有一个搜索栏,你可以粘贴某人的地址或交易哈希来探索 L2 的当前状态。最后,有两个交易列表:第一个是 L2 内存池中的交易列表,第二个是发布到 L1 的交易列表。

要开始,请使用 WalletConnect 按钮连接你的钱包。连接后,你可能会收到一个通知,提示你的钱包连接到了错误的网络。如果你的应用程序支持网络切换,请点击“切换网络”按钮切换到 Holesky 测试网络。否则,请手动切换。

现在,你可以通过提供接收者的地址、要发送的代币数量和所需手续费来向某人发送代币。发送后,钱包应用程序会提示你签署消息。如果成功签署,消息将被发送到 L2 节点的内存池中,等待被发布到 L1。交易被捆绑到批次发布中所需的时间可能会有所不同。每 10 秒,L2 节点会检查是否有待发布的内容。手续费较高的交易会优先发送,因此如果你指定了较低的手续费并且有大量交易流量,你可能会遇到较长的等待时间。

工作原理

构建你自己的Rollup——BYOR 项目一览
Rollup 架构图

技术栈

我们使用以下技术构建了每个组件:

节点: Node.js, TypeScript, tRPC, Postgres, viem, drizzle-orm

钱包: TypeScript, tRPC, Next.js, WalletConnect

代码深入解析

BYOR 代码专门设计成通过查看代码库就能轻松理解。请随意探索我们的代码库!首先阅读README.md,了解项目结构请阅读ARCHITECTURE.md文件。

以下是代码中的一些有趣亮点:

智能合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Inputs {
event BatchAppended(address sender);
function appendBatch(bytes calldata) external {
require(msg.sender == tx.origin);
emit BatchAppended(msg.sender);
}
}

这是唯一需要的智能合约。它的名称源于这个事实:将输入存储到状态转换函数中。该合约的唯一目的是为了方便地存储所有交易。序列化的批次作为 calldata 发布到这个智能合约,并且它会发出一个带有批次发布者地址的 BatchAppended 事件。虽然我们可以设计系统,使其将交易直接发布到 EOA 而不是合约,但通过发出事件可以轻松通过 JSON-RPC 获取数据。这个智能合约的唯一要求是它不应该从另一个智能合约中调用,而应该直接从 EOA 中调用。

数据库模式

CREATETABLE`accounts`(
`address`textPRIMARYKEYNOTNULL,
`balance`integerDEFAULT0NOTNULL,
`nonce`integerDEFAULT0NOTNULL
);

CREATETABLE`transactions`(
`id`integer,
`from`textNOTNULL,
`to`textNOTNULL,
`value`integerNOTNULL,
`nonce`integerNOTNULL,
`fee`integerNOTNULL,
`feeReceipent`textNOTNULL,
`l1SubmittedDate`integerNOTNULL,
`hash`textNOTNULL
PRIMARYKEY(`from`,`nonce`)
);

--Thistablehasasinglerow
CREATETABLE`fetcherStates`(
`chainId`integerPRIMARYKEYNOTNULL,
`lastFetchedBlock`integerDEFAULT0NOTNULL
);

这是用于存储关于 Rollup 的信息的整个数据库模式。你可能会想当所有必要的数据都存储在 L1 上,为什么我们需要一个数据库。虽然这是正确的,但是将数据存储在本地可以通过避免重复获取来节省时间和资源。将在此模式中存储的所有数据视为状态、交易哈希和其他计算信息的备忘录。

fetcherStates 表用于跟踪我们在搜索 BatchAppended 事件时获取的最后一个块。当节点关闭并重新启动时,这非常有用;它知道从哪里恢复搜索。

状态转换函数

constDEFAULT_ACCOUNT={balance:0,nonce:0}

functionexecuteTransaction(state,tx,feeRecipient){
constfromAccount=getAccount(state,tx.from,DEFAULT_ACCOUNT)
consttoAccount=getAccount(state,tx.to,DEFAULT_ACCOUNT)
//Step1.Updatenonce
fromAccount.nonce=tx.nonce
//Step2.Transfervalue
fromAccount.balance-=tx.value
toAccount.balance+=tx.value
//Step3.Payfee
fromAccount.balance-=tx.fee
feeRecipientAccount.balance+=tx.fee
}

上面显示的函数是 BYOR 中状态转换机制的核心。它假设交易可以安全地执行,具有正确的 nonce 和足够的余额来进行定义的支出。由于这个假设,在这个函数内部没有错误处理或验证步骤。相反,这些步骤在调用函数之前执行。每个账户状态都存储在一个映射中。如果一个账户在这个映射中还不存在,它将被设置为代码清单顶部可见的默认值。使用的三个账户,nonce 被更新,余额被分配。

交易签名

构建你自己的Rollup——BYOR 项目一览
交易签名

我们使用EIP-712标准来对类型化数据进行签名。这使我们能够清楚地向用户显示他们正在签名的内容。如上所示,当发送一笔交易时,我们可以以用户友好的方式显示接收者、金额和手续费。

L1 事件获取

function getNewStates() {
const lastBatchBlock = getLastBatchBlock()
const events = getLogs(lastBatchBlock)
const calldata = getCalldata(events)
const timestamps = getTimestamps(events)
const posters = getTransactionPosters(events)
updateLastFetchedBlock(lastBatchBlock)
return zip(posters, timestamps, calldata)
}

为了获取新的事件,我们从 Inputs 合约中检索从上次获取的区块开始的所有 BatchAppended 事件。我们检索的事件数量最多为最新的区块或上次获取的区块加上批量大小限制。在检索所有事件之后,我们从每个交易中提取 calldata、时间戳和发布者地址。将我们获取的最后一个区块更新为我们正在获取的最后一个区块。然后,将提取的 calldata、时间戳和发布者打包在一起,并从函数中返回以进行进一步处理。

内存池及其费用排序

function popNHighestFee(txPool, n) {
txPool.sort((a, b) => b.fee - a.fee))
return txPool.splice(0, n)
}

内存池是一个管理已签名交易数组的对象。最有趣的方面是它如何确定交易被发布到 L1 的顺序。如上所示的代码,交易是根据它们的费用进行排序的。这让系统中位数费用价格会根据链上活动而波动。

即使你指定了高费用,如果它们需要被附加到当前状态,交易仍然需要产生一个有效的状态。因此,你不能仅仅因为费用高就提交无效的交易。

BYOR 是否真正扩展了以太坊?

乐观和 ZK rollup 已经建立了系统来证明发布的状态根与状态转换函数和它们提交的数据是一致的,但主权 rollup 没有。因此,这种类型的 rollup 无法扩展以太坊,这一点可能一开始看起来有些违反直觉。然而,当我们意识到其他类型的 rollup 可以仅使用 L1 来证明发布的状态根是正确的时,这就变得合理了。要区分主权 rollup 的数据是否正确,我们需要运行一个 L1 节点以及额外的软件,以形式化 L2 节点来执行状态转换函数,从而增加了计算负载。

未来展望

对我们来说,构建这个项目是一次很好的学习经验,我们希望你也会发现我们的努力有价值。我们希望将来能够回到 BYOR,为其添加一个欺诈证明系统。这将使它成为一个真正的乐观 rollup,并再次成为我们日常使用的系统内部工作方式的教训。

本站所有软件信息均由用户上传发布,版权归原著所有。如有侵权/违规内容,敬请来信告知邮箱:764327034@qq.com,我们将及时撤销! 转载请注明出处:https://czxurui.com/zx/91438.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年10月18日
下一篇 2023年10月18日

相关推荐

  • 高效使用QQ:聊天记录管理和好友在线状态查询技巧

    随着社交网络的普及,聊天成为人们交流的重要渠道,而在线聊天则成为人们日常生活中必需的沟通方式之一。在这个数字时代,人们的社交范围被扩大,好友也在不断增多。因此,管理在线qq的聊天记录和查看qq好友的在线状态成为每个在线qq用户和经验丰富的内

    2023-11-15 06:00:33
    101 0
  • MPT 下岗?智能合约区块链的优化

    作者:KJ,LXDAO 背景和动机 在开始讲对 MPT 的改进之前,我们先谈一谈进行这项研究的背景。 本人在读博并且做公链设计。这条公链除了核心的共识升级:有用的工作量证明以外,另一个重要的任务是实现兼容 ETH 的智能合约系统。我们目前已

    2023-10-19 10:00:06
    63 0
  • 「金色财经」L2BEAT推出Build Your Own Rollup工具

    「金色财经」10月13日,Layer2技术研究和数据网站L2BEAT宣布推出Buildyourownrollup(BYOR)工具。BYOR是Rollup主权的简化版,使代码易于阅读和理解。BYOR目前部署在Holesky测试网络上,可实现的

    2023-10-13 12:00:01
    73 0
  • 「金色财经」WorldCoin发布状态桥更新:可实现与WORLD ID免许可集成

    「金色财经」据金融报道,WorldCoin发布了状态桥更新,更新后的状态桥架构采用模块化、免费、高效的Gas设计,允许开发人员和团队开发和运营自己的状态桥,并将WorldID与其首选的区块链和应用程序集成,新的状态桥架构还允许使用从L1到L

    2023-10-11 23:00:03
    68 0
  • OP Stack + 零知识证明 = L2的终局游戏?

    作者:Bill Qian、Yongxin Song、Bonan Yuan,Cypher Capital Layer2的终局游戏 如今的Layer2赛道厮杀异常激烈,前有Arbitrum, Optimism, Base 等基于optimist

    2023-10-10 10:00:23
    62 0
  • 长推:Solana的过去、现在和未来

    作者:Nansen;编译:Yvonne,MarsBit 我们很高兴地发布了我们对Solana生态系统的全面深入研究。内容涵盖生态系统的催化剂、风险、优势、链上数据,以及网络发展等。 自今年年初以来,Solana TVL几乎翻了一番,达30

    2023-10-10 10:00:21
    83 0

发表回复

8206
验证码

评论列表(0条)

    暂无评论

ok交易所
已有100万用户加入ok交易所

立即下载