Vitalik Buterin:以太坊协议是否应该「封装」更多功能?

    编译:念银思唐,Odaily星球日报特别感谢JustinDrake、TinaZhen和YoavWeiss的回馈和审查。从以太坊专案开始,就有一个强烈的理念,即试图使核心以太坊尽可能简单,并透过在其上建立协议来尽可能实现这一点。在区块链领域,「在L1上建立」与「专注于L2」的争论通常被认为主要是关于扩展的,但实际上,在满足多种以太坊用户的需求方面存在类似的问题:数位资产交换、隐私、使用者名称、进阶加密、帐户安全、抗审查、抢先交易保护,等等。然而,最近有一些谨慎的想法愿意将更多这些功能封装(enshrine)进核心以太坊协议中。这篇文章将深入探讨最初的最小封装哲学背后的一些哲学推理,以及一些最近思考这些想法的方法。目标将是开始建立一个框架,以便更好地确定可能的目标,在这些目标中,封装某些功能可能值得考虑。内容目录关于协议极简主义的早期哲学封装ERC-4337我们能从这个例子学到什么,什么时候更普遍地进行封装?封装ZK-EVM封装提议者与建造者分离(ePBS)封装私有记忆体池封装流动性质押封装更多预编译我们从这一切中学到了什么?关于协议极简主义的早期哲学在当时被称为「以太坊2.0」的早期历史中,人们强烈希望创建一个干净,简单和美观的协议,该协议尽可能少地尝试通过自身来构建,并将几乎所有这类工作都留给用户。理想情况下,协议只是一个虚拟机,而验证一个区块只是一个虚拟机呼叫。这是我和GavinWood在2015年初绘制白板图的近似重建,当时我在谈论以太坊2.0的样子。「状态转换函数」(处理区块的函数)将只是单一VM调用,所有其他逻辑将透过合约发生:一些系统级合约,但主要是由用户提供的合约。这个模型的一个非常好的功能是,即使是整个硬分叉也可以被描述为对于区块处理器合约而言的单笔交易,该交易将通过链下或链上治理进行批准,然后以升级的权限运行。2015年的这些讨论特别适用于我们考虑的两个领域:帐户抽象和扩充。在扩容的情况下,我们的想法是尝试创建一个最大程度的抽象形式的扩容,感觉就像上面图表的自然扩展。合约可以调用大多数以太坊节点未储存的数据,协议将检测到这一点,并透过某种非常通用的扩展计算功能来解决呼叫。从虚拟机器的角度来看,该呼叫将进入某个单独的子系统,然后一段时间后神奇地返回正确的答案。我们对这种思路进行了简短的探索,但很快就放弃了,因为我们太专注于验证任何类型的区块链扩容都是可能的。尽管我们稍后会看到,数据可用性采样和ZK-EVM的结合意味著以太坊扩容的一个可能的未来实际上看起来非常接近这个愿景!另一方面,对于帐户抽象,我们从一开始就知道某种实现是可能的,因此研究立即开始尝试使一些尽可能接近「交易只是一个调用」的纯粹出发点的东西变为现实。在处理交易和从发送方位址发出实际的底层EVM呼叫之间,会出现大量的样板程式码,之后还会出现更多的样板程式码。我们如何将这些程式码尽可能减少到接近零?这里的主要程式码之一是validate_transaction(state,tx),它负责检查交易的nonce和签章是否正确。从一开始,帐户抽象的实际目标就是允许用户用自己的验证逻辑替换基本的非增量验证和ECDSA验证,这样用户就可以更轻松地使用社交恢复和多签名钱包等功能。因此,找到一种方法将apply_transaction重新架构为一个简单的EVM调用,这不仅仅是一个「为了使程式码干净而使程式码干净」的任务;相反,它是关于将逻辑移动到用户的帐户程式码中,为使用者提供所需的灵活性。然而,坚持让apply_transaction包含尽可能少的固定逻辑的做法最终带来了许多挑战。我们可以看下最早的帐户抽象提案之一EIP-86。如果按原样包含EIP-86,它将降低EVM的复杂性,代价是大量增加以太坊堆叠其他部分的复杂性,需要在其他地方编写本质上完全相同的程式码,除了引入全新的怪异类别之外,例如具有相同杂凑值的相同交易可能会在链中多次出现,更不用说多重失效问题了。帐户抽像中的多重失效问题。在链上包含的一笔交易可能会使内存池中的数千笔其他交易无效,从而使内存池很容易被廉价地充斥。从那时起,帐户抽象化分阶段发展。EIP-86后来变成了EIP-208,最终出现了实际可行的EIP-2938。然而,EIP-2938一点也不简约。其内容包括:新的交易类型三个新交易范围的全域变数两个新的操作码,包括非常笨拙的PAYgas操作码,用于处理gas价格和gas限制检查,作为EVM执行断点,以及临时存储ETH以一次性支付费用一组复杂的挖矿和转播策略,包括交易验证阶段禁止的操作码列表为了在不涉及以太坊核心开发人员(专注于优化以太坊客户端和实现合并)的情况下实现帐户抽象,EIP-2938最终被重新架构为完全是协议外的ERC-4337。ERC-4337。它确实完全依赖EVM呼叫!因为这是一个ERC,它不需要硬分叉,并且在技术上存在于「以太坊协议之外」。

    所以……问题解决了吗?事实证明并非如此。ERC-4337目前的中期路线图实际上涉及最终将ERC-4337的大部分转变为一系列协议功能,这是一个有用的指导范例,可以了解为什么要考虑这条路径。封装ERC-4337有几个关键原因讨论了最终将ERC-4337重新纳入协议:gas效率:在EVM内部进行的任何操作都会导致一定程度的虚拟机开销,包括在使用诸如存储槽之类gas费昂贵的功能时效率低下。目前,这些额外的低效率加起来至少要消耗2万gas,甚至更多。将这些组件放入协定中是消除这些问题的最简单方法。代码bug风险:如果ERC-4337「入口点合约」有一个足够可怕的bug,所有与ERC-4337相容的钱包都可能看到他们所有的资金枯竭。以协议内功能取代合约会产生一种隐含的责任,即透过硬分叉修复程式码错误,从而消除用户的资金枯竭风险。支援EVM操作码,如txt.origin。ERC-4337本身使txt.origin传回将一组使用者操作打包到交易中的「捆绑器(bundler)」的位址。原生帐户抽象化可以解决这个问题,方法是让txt.origin指向发送交易的实际帐户,使其运作方式与EOA相同。抗审查:提议者/建构者分离的挑战之一是审查单笔交易变得更容易。在以太坊协议可以识别单笔交易的世界中,包含清单可以极大地缓解这个问题,该清单允许提议者指定在几乎所有情况下必须包含在接下来两个插槽中的交易清单。但是协议外的ERC-4337将「用户操作」封装在单笔交易中,使得用户操作对以太坊协议不透明;因此,以太坊协议提供的包含清单将无法对ERC-4337用户操作提供审查阻力。封装ERC-4337,并使使用者操作成为一种「适当的」交易类型,将解决这个问题。值得一提的是,在目前的形式下,ERC-4337比「基本」以太坊交易要贵得多:交易成本为21,000gas,而ERC-4337的成本约为42,000gas。理论上,应该有可能对EVMgas成本系统进行调整,直到协议内成本和协议外访问存储的成本相匹配;当其他类型的存储编辑操作更便宜时,转移ETH没有理由需要花费9000gas。事实上,与即将到来的Verkle树转换相关的两个EIP实际上试图做到这一点。但是,即使我们这样做了,有一个显而易见的原因可以解释为什么无论EVM变得多么高效,封装的协定功能都将不可避免地比EVM程式码便宜得多:封装程式码不需要为预先载入支付gas。功能齐全的ERC-4337钱包很大,编译并放到链上的这个实现占用了约12,800位元组。当然,你可以一次部署这段程式码,并使用DELEGATECALL来允许每个单独的钱包呼叫它,但仍然需要在使用它的每个区块中存取该程式码。在Verkle树gas成本EIP下,12,800位元组将组成413个chunk,存取这些chunk将需要支付2倍的witnessbranch_cost(总共3,800gas)和413倍的witnesschunk_cost(总共82,600gas)。这甚至还没有开始提到ERC-4337入口点本身,在0.6.0版本中,链上有23,689位元组(根据Verkle树EIP规则,约有158,700个gas要载入)。这就导致了一个问题:实际存取这些代码的gas成本必须以某种方式在交易中分摊。ERC-4337使用的当前方法不是很好:bundle中的第一笔交易消耗了一次性储存/代码读取成本,使其比其他交易昂贵得多。协议内封装将允许这些公共共享库成为协议的一部分,所有人都可以免费存取。我们能从这个例子学到什么,什么时候更普遍地进行封装?在这个例子中,我们看到了在协议中封装帐户抽象化方面的一些不同的基本原理。当固定成本较高时,「将复杂性推向边缘」的基于市场的方法最容易失败。事实上,长期的帐户抽象路线图看起来每个区块都有许多固定的成本。244,100gas用于加载标准化钱包代码是一回事;但是聚合可能会为ZK-SNARK验证增加数十万的gas,以及证明验证的链上成本。没有一种方法可以在不引入大量市场低效率的情况下向用户收取这些成本,而将其中一些功能转化为所有人都可以免费访问的协议功能则可以很好地解决这个问题。社区范围内对程式码bug的回应。如果一些程式码片段被所有用户或非常广泛的用户使用,那么区块链社群承担硬分叉的责任来修复出现的任何错误通常更有意义。ERC-4337引入了大量的全域共享程式码,从长远来看,透过硬分叉修复程式码中的错误无疑比导致用户损失大量ETH更合理。有时,可以透过直接利用协议的功能来实现其更强形式。这里的关键例子是协议内的抗审查功能,例如包含列表:协议内的包含列表可以比协议外的方法更好地保证审查阻力,为了使用户级操作真正受益于协议内的包含列表,单个用户级操作需要对协定「易读」。

    另一个鲜为人知的例子是,2017年时代的以太坊权益证明设计对权益密钥进行了帐户抽象,这被放弃了并转而支持封装BLS,因为BLS支持一种「聚合」机制,必须在协定和网路层面实现,这可以使处理大量签章的效率更高。但重要的是要记住,与现状相比,即使是封装协议内帐户抽象,仍然是一种巨大的「去封装化」。如今,顶级以太坊交易只能从外部拥有的帐户(EOA)发起,这些帐户使用单一secp256k1椭圆曲线签名进行验证。帐户抽象消除了这一点,并将验证条件留给使用者自行定义。因此,在这个关于帐户抽象的故事中,我们也看到了反对封装的最大理由:灵活地满足不同使用者的需求。让我们透过查看最近被考虑封装的其他几个特征范例来进一步充实这个故事。我们将特别关注:ZK-EVM,提议者-建构者分离,私有记忆体池,流动性质押和新的预编译。封装ZK-EVM让我们把注意力转移到以太坊协议的另一个潜在封装目标:ZK-EVM。目前,我们有大量的ZK-rollup,它们都必须编写相当相似的程式码来验证ZK-SNARK中类似以太坊区块的执行。有一个相当多样化的独立实现生态系统:PSEZK-EVM、Kakarot、PolygonZK-EVM、Linea、Zeth等等。EVMZK-rollup领域最近的一个争议与如何处理ZK程式码中可能出现的bug有关。目前,所有这些正在运行的系统都有某种形式的「安全理事会」机制,可以在出现bug的情况下控制证明系统。去年,我试图创建一个标准化的框架,以鼓励计划明确他们对证明系统的信任程度,以及对安全理事会的信任程度,并随著时间的推移,逐渐减少对该组织的权力。从中期来看,rollup可能依赖多个证明系统,而安全理事会只有在两个不同的证明系统产生分歧的极端情况下才有权力。然而,有一种感觉是,其中一些工作感觉是多余的。我们已经有了以太坊基础层,它有一个EVM,我们已经有了一个处理实作中bug的工作机制:如果有bug,客户端将进行更新来修复,然后链继续运作。从有bug的客户端角度来看,似乎已经最终确认的区块将不再确认,但至少我们不会看到用户损失资金。同样,如果rollup只是想保持与EVM等同的作用,那么它们需要实施自己的治理来不断更改其内部ZK-EVM规则以匹配对以太坊基础层的升级,这感觉是错误的,因为最终它们是在以太坊基础层本身之上构建的,它知道何时升级以及根据什么新规则。由于这些L2ZK-EVM基本上使用与以太坊完全相同的EVM,我们能否以某种方式将「验证EVM在ZK中的执行」纳入协议功能,并透过应用以太坊的社会共识来处理异常情况,如bug和升级,就像我们已经为基础层EVM执行本身所做的那样?这是一个重要而富有挑战性的议题。关于原生ZK-EVM中资料可用性的一个可能的争论主题是有状态性(statefulness)。如果ZK-EVM不需要携带「见证(witness)」数据,它们的数据效率就会高得多。也就是说,如果某个特定的资料已经在先前的某个区块中读取或写入,我们可以简单地假设证明者可以存取它,并且不必再次使它可用。这不仅仅是不重新载入储存和程式码;事实证明,如果一个rollup正确地压缩了数据,那么与无状态压缩相比,有状态压缩最多可以节省3倍的资料。这意味著对于ZK-EVM预编译,我们有两个选项:1.预编译要求所有资料在同一区块中可用。这意味著prover可以是无状态的,但也意味著使用这种预先编译的ZK-rollup比使用自订程式码的rollup要昂贵得多。2.预编译允许pointer指向先前执行使用或产生的资料。这使得ZK-rollup接近最优,但它更复杂,并引入了一种必须由prover储存的新状态。我们能从中学到什么?以某种方式将ZK-EVM验证封装有一个很好的理由:rollup已经在建立自己的自订版本,而以太坊愿意将其多个实现和链下社会共识的权重置于L1上执行EVM,这感觉是错误的,但是做完全相同工作的L2必须实现涉及安全理事会的复杂小工具。但另一方面,细节中有一个大问题:有不同版本的ZK-EVM,它们的成本和收益不同。有状态和无状态的区分只是触及了表面;尝试支援「近EVM(almost-EVM)」,这些定制程式码已经被其他系统证明,这可能会暴露出更大的设计空间。因此,封装ZK-EVM既带来了希望,也带来了挑战。封装提议者与建造者分离(ePBS)MEV的兴起使区块生产成为一种大规模经济活动,复杂的参与者能够生产出比预设演算法产生更多收入的区块,而预设演算法只是观察交易的记忆体池并包含它们。到目前为止,以太坊社群试图透过使用MEV-Boost等协议外的提议者-建构者分离(proposer-builderseparation)方案来解决这个问题,该方案允许常规验证者(「提议者」)将区块建构外包给专门的参与者(「建构者」)。然而,MEV-Boost在一个新的参与者类别中进行了信任假设,称为中继(relay)。在过去的两年里,有很多人提议创建「封装PBS」。

    这样做的好处是什么?在这种情况下,答案非常简单:直接使用协议功能构建的PBS比不使用它们构建的PBS更强大(在具有更弱的信任假设的意义上)。这与封装协议内价格预言机的情况类似——尽管在这种情况下,也存在强烈的反对意见。封装私有记忆体池当用户发送交易时,该交易立即公开并对所有人可见,甚至在它被包含在链上之前。这使得许多应用程式的用户容易受到经济攻击,例如抢先交易。最近,有许多项目专门致力于创建「私有记忆体池」(或「加密记忆体池」),它将用户的交易加密,直到它们被不可逆转地被接受到一个区块中。然而,问题是,这样的方案需要一种特殊的加密:为了防止用户涌入系统并率先进行解密,加密必须在交易确实被不可逆转地被接受后自动解密。为了实现这种形式的加密,有各种不同权衡的技术。JonCharbonneau曾做过很好的描述:对中心化运营商进行加密,例如FlashbotsProtect。时间锁加密,该加密形式经过一定的顺序计算步骤后,任何人都可以解密,并且不能并行化;阈值加密,信任一个诚实的多数委员会来解密资料。具体建议请参阅封闭信标链概念。可信任硬件,如SGX。不幸的是,每一种加密方式都有不同的弱点。虽然对于每个解决方案,都有一部分使用者愿意信任它,但没有一个解决方案的信任程度足以让它实际上被Layer1接受。因此,至少在延迟加密得到完善或其他一些技术突破之前,在Layer1封装反提前交易功能似乎是一个困难的命题,即使它是一个足够有价值的功能,许多应用程式解决方案已经出现。封装流动性质押以太坊DeFi用户的一个共同需求是能够同时使用他们的ETH进行质押和作为其他应用程式中的抵押品。另一个常见的需求只是为了方便:使用者希望能够在没有运行节点并保持其始终在线的复杂性的情况下进行质押(并保护线上质押金钥)。到目前为止,满足这两种需求的最简单质押「接口」只是一种ERC20代币:将你的ETH转换为「质押ETH」,持有它,然后再转换回来。事实上,Lido和RocketPool等流动性质押提供者已经开始这么做了。然而,流动性质押有一些自然的中心化机制在起作用:人们自然会进入最大版本的质押ETH,因为它是最熟悉和最具流动性的。每个版本的质押ETH都需要有一些机制来确定谁可以成为底层节点运营商。它不能是无限制的,因为这样攻击者就会加入并利用使用者的资金扩大攻击。目前,排名前两位的是Lido和RocketPool,前者拥有DAO白名单节点运营商,后者允许任何人在存入8枚ETH的情况下运行一个节点。这两种方法有不同的风险:RocketPool方法允许攻击者对网路进行51%的攻击,并迫使用户支付大部分成本;至于DAO方法,如果某质押代币占主导地位,就会导致单一的、可能受到攻击的治理小工具控制所有以太坊验证者的很大一部分。值得肯定的是,像Lido这样的协议已经实施了防范措施,但一层防御可能还不够。在短期内,一种选择是鼓励生态系统参与者使用多样化的流动性质押提供商,以减少一家独大带来系统性风险的可能性。然而,从长期来看,这是一种不稳定的平衡,过度依赖道德压力来解决问题是危险的。一个自然的问题出现了:在协议中封装某种功能以使流动性质押不那么中心化是否有意义?这里的关键问题是:什么样的协定内功能?简单地创建一个协议内可替代的「质押ETH」代币存在一个问题,即它要么必须有一个封装以太坊范围内治理来选择谁来运行节点,要么是开放的,但这会把它变成攻击者的工具。一个有趣的想法是DankradFeist关于流动性质押最大化的文章。首先,我们咬紧牙关,如果以太坊受到51%攻击,可能只有5%的攻击ETH被罚没。这是一个合理的权衡;目前有超过2600万枚ETH被质押,其中三分之一(约800万枚ETH)的攻击成本是过度的,特别是考虑到有多少种「模型外」攻击可以以更低的成本完成。事实上,类似的权衡已经在「超级委员会」关于实施single-slotfinality的提案中进行了探讨。如果我们接受只有5%的攻击ETH被罚没,那么超过90%的质押ETH将不会受到罚没的影响,因此它们可以作为协议内可替代流动性质押代币,然后被其他应用程式使用。这条路径很有趣。但它仍然留下了一个问题:具体封装什么?

    RocketPool的运作方式与此非常相似:每个节点业者提供一些资金,流动性质押者提供其余的资金。我们可以简单地调整一些常数,将最大罚没惩罚限制为2只ETH,RocketPool现有的rETH将变得无风险。透过简单的协议调整,我们还可以做其他聪明的事情。例如,假设我们想要一个系统,有两种「层」的质押:节点运营商(高抵押品要求)和储户(没有最低抵押品要求,可以随时加入和离开),但我们仍然希望透过赋予一个随机抽样的储户委员会权力来防止节点运营商的中心化,例如建议必须包括的交易清单(出于抗审查的原因),在不活动泄漏期间控制分叉选择,或需要在区块上签名。这可以透过一种基本上脱离协议的方式来实现,方法是调整协议,要求每个验证器提供(i)一个常规的质押密钥,以及(ii)一个ETH位址,该位址可以在每个槽间被调用以输出二级质押密钥。该协议将赋予这两项金钥权力,但在每个槽中选择第二个金钥的机制可以留给质押池协定。直接封装一些功能可能仍然更好,但值得注意的是,这种「包含一些东西,把其他东西留给使用者」的设计空间是存在的。封装更多预编译预编译(或称「预先编译合约」)是实现复杂加密操作的以太坊合约,其逻辑在客户端程式码中原生实现,而不是EVM智慧合约程式码。预编码是以太坊开发之初采用的一种折衷方案:由于虚拟机的开销对于某些非常复杂和高度专业化的代码来说太大了,我们可以在本地代码中实现一些对重要应用程序有价值的关键操作,以使其更快。如今,这基本上包括一些特定的杂凑函数和椭圆曲线运算。目前有人在推动为secp256r1添加预编译,这是一种与用于基本以太坊帐户的secp256k1略有不同的椭圆曲线,因为它得到了可信硬体模组的良好支持,因此广泛使用它可以提高钱包安全性。近年来,社群也推动为BLS-12-377、BW6-761、广义配对和其他功能添加预编译。对这些要求更多预编译档案的反驳是,先前加入的许多预编译(例如RIPEMD和BLAKE)最终的使用量远低于预期,我们应该从中学习。与其为特定操作添加更多的预编译,我们也许应该专注于一种更温和的方法,该方法基于EVM-MAX和休眠但始终可恢复的SIMD提案等思想,这将使EVM实现能够以更低的成本执行广泛的程式码类别。也许即使是现有的很少使用的预编译也可以被删除,并用相同函数的EVM程式码实现(不可避免地效率较低)代替。也就是说,仍然有可能存在特定的加密操作,这些操作的价值足以加速,因此将它们作为预编译添加是有意义的。我们从这一切中学到了什么?尽可能少封装的愿望是可以理解的,也是好的;它源自Unix哲学传统,即创建极简的软体,可以轻松适应用户的不同需求,避免软体膨胀的诅咒。然而,区块链不是个人运算作业系统,而是社会系统。这意味著在协定中封装某些功能是有意义的。在许多情况下,这些其他的例子与我们在帐户抽像中看到的类似。但我们也学到了一些新的教训:封装功能可以帮助避免堆叠中其他区域的中心化风险:通常,保持基本协议的最小化和简单性会将复杂性推到一些协议之外的生态系统。从Unix哲学的角度来看,这很好。然而,有时存在协议外生态系统将中心化的风险,通常(但不仅仅是)因为高固定成本。封装有时可以减少事实上的中心化。封装太多内容,可能会过度扩大协议的信任和治理负担:这是前一篇关于「不要让以太坊共识过载」文章的主题:如果封装一个特定的功能削弱了信任模型,并使以太坊作为一个整体变得更加「主观」,这就削弱了以太坊的可信中立性。在这些情况下,最好将特定功能作为以太坊之上的机制,而不是试图将其引入以太坊本身。在这里,加密记忆体池是最好的例子,它可能有点难以封装,至少在延迟加密技术改进之前是如此。封装太多内容可能会使协议过于复杂:协定复杂性是一种系统性风险,在协定中添加太多功能会增加这种风险。预编译就是最好的例子。长期来看,封装功能可能会适得其反,因为使用者的需求是不可预测的:一个很多人认为很重要并且会被很多用户使用的功能,很可能在实践中并没有被经常使用。此外,流动性质押、ZK-EVM和预编译案例显示了一条中间道路的可能性:最小可行封装(minimalviableenshrinement)。协议不需要封装整个功能,而可以包含解决关键挑战的特定部分,使该功能易于实现,而不会过于偏执或过于狭隘。这样的例子包括:与其封装一个完整的流动性质押系统,不如改变质押惩罚规则,让去信任流动性质押更可行;与其封装更多的预编译器,不如封装EVM-MAX和/或SIMD,以使更广泛的操作类别更容易有效地实现;可以简单地封装EVM验证,而不是封装rollup的整个概念。我们可以将前面的图表扩展如下:有时候,去封装一些东西是有意义的,去除很少使用的预编译就是一个例子。帐户抽象化作为一个整体,如前面提到的,也是一种重要的去封装形式。如果我们想要支援现有用户的向后相容性,那么该机制实际上可能与去封装预编译的机制惊人地相似:其中一个提案是EIP-5003,它将允许EOA将其帐户转换为具有相同(或更好)功能的合约。哪些功能应该被引入协议,哪些功能应该留给生态系统的其他层,这是一个复杂的权衡。随著我们对用户需求的理解以及可用想法和技术套件的不断改进,这种权衡有望随著时间的推移而继续改进。(以上内容获合作伙伴MarsBit)声明:文章仅代表作者个人观点意见,不代表区块客观点和立场,所有内容及观点仅供参考,不构成投资建议。投资者应自行决策与交易,对投资者交易形成的直接间接损失作者及区块客将不承担任何责任。

Pixel Artist Pixel Artist
Happy Kittens Puzzle Happy Kittens Puzzle
Penguin Cafe Penguin Cafe
Animal Connection Animal Connection
Snakes N Ladders Snakes N Ladders
Pixel Skate Pixel Skate
BeeLine BeeLine
Draw Parking Draw Parking
Draw Racing Draw Racing
Soccer Balls Soccer Balls
Happy Fishing Happy Fishing
Crashy Cat Crashy Cat

FREE GAMES FOR KIDS ONLINE