PEPE0.00 8.66%
SUI4.65 6.50%
TON5.34 -0.31%
TRX0.25 0.86%
DOGE0.33 5.86%
XRP2.26 1.02%
SOL186.51 -1.86%
BNB665.33 -0.47%
ETH3393.33 0.22%
BTC97574.39 0.27%
PEPE0.00 8.66%
SUI4.65 6.50%
TON5.34 -0.31%
TRX0.25 0.86%
DOGE0.33 5.86%
XRP2.26 1.02%
SOL186.51 -1.86%
BNB665.33 -0.47%
ETH3393.33 0.22%
BTC97574.39 0.27%
ETH Gas7.96 Gwei
贪婪 73
撰文:Blade Research、Delphinus Lab
太长不看版:
Blade Games 和 Delphinus Lab 合作打造了一个基于 WebAssembly 和 zkWASM 的去信任化zk游戏引擎(trustless game engine)。
我们的zk游戏引擎可以支持塔防、RPG 等低速实时游戏类别,以及放置游戏、卡牌/自走棋游戏和互动小说等游戏类型。简单来说,我们把游戏的逻辑放置在zkWASM内运行(一个处理计算的“zk服务器”),每局的游戏结果将会生成zkSNARK 证明而发布。这个游戏引擎还支持 C++、Go、Rust 等语言,并且即将推出 C# 和 Unity 支持。
拿塔防游戏举个例子,对于典型的 6 分钟长、100 波怪物的一局塔防游戏,总共的zkSNARK证明生成时间约为 3 分钟。这还只是初步结果,我们正在快速优化证明生成时间。 (100万条指令的ZKP生成时间为19秒,每个怪物波是8万个指令,每局游戏800万条指令,8个zkSNARK证明在云化的计算端,生成时间是3分钟左右)。
在基于 ZKVM 的去信任游戏中,维护成本主要来自 ZK 证明生成、RPC/调用数据访问服务以及链上验证和结算费用。 随着坎昆升级(EIP 4844)在 L2 上生效,运行去信任游戏的成本已经显着降低了。
此外,通过未来实施 zkSNARK 证明递归(proof recursion)以及 Nebra 的证明聚合服务(proof aggregation),我们可以进一步降低 ZKP 的成本。
我们的游戏合作伙伴包括:
Dune Factory(@BladeGamesHQ):一款废土朋克风格的基地建设+塔防策略游戏
0xPioneer:类似《饥荒》的多人在线模拟生存游戏
Craftpunk:一款以太空为主题的开放世界RPG游戏,具有可改装的宇宙飞船和程序生成的地图
正文:
本ZK游戏引擎由Blade Games和Delphinus Lab联合开发,本篇文章由双方联合撰写,旨在使更多web2游戏开发者、全链游戏开发者了解ZK游戏引擎的优势和开发路径。
这是一份关于去信任化的Web3浏览器游戏开发的指南。(另有内容在youtube上展示,相关链接)
随着Web3的进一步发展,全链游戏再次进入我们的视野。它们声称在去中心化、透明度、无信任和社区治理方面更加优越。然而,全链游戏也继承了区块链的去中心化、安全性、可扩展性困境 — — 这意味着游戏开发者在全链游戏的叙事中面临着游戏内容、互动频率、去中心化、无信任和社区公平性管理的难题。
因此,在上个周期,游戏开发者在架构层面达成了一些妥协,并引入了一种被广泛称为Web2.5游戏架构的实践中的最佳架构。
更确切地说,Web2.5是一个混合了Web3和传统游戏的综合术语。Web2.5强调游戏玩法的内容,因为他们相信游戏的主要受众仍然根植于Web2。同时,他们在游戏中添加了Web3的元素(NFT、经济模型、游戏赚取)以使他们的游戏脱颖而出。
标准的Web2.5游戏架构可能如下所示:
左侧图示展示了游戏引擎对游戏的状态机的控制与对玩家活动做出的反应。右侧图示展示了游戏状态的某些部分变化,并揭示了链上最有价值的那些数据。
游戏核心玩法大多在一个集中式的游戏服务器上运行,而最有价值的数据(NFT、代币奖励、记录等)则在区块链上被跟踪。
这种架构的优势在于,游戏服务器可以在处理大量用户交易的集中模式下运行,而这些交易可以在几秒钟内完成。此外,集中式服务器可以处理复杂且持续的游戏玩法,通常在原生区块链中处理这些玩法的成本太高了。
然而,在这种架构中,游戏引擎和链上协议之间的通信渠道通常由签名进行保护,因此并不是去信任的。此外,游戏内容可能会在没有与社区达成共识的情况下进行更改,这有时可能会损害现有玩家的既得利益(例如游戏经济更新、内容更新甚至奖励制度更新)。
此外,链上数据很难检查传递到区块链的数据是否是游戏玩法的有效结果。服务器可以利用职务之便对玩家行为进行区别化处理(例如有倾向性地对待游戏开发商的私人帐户)。
由于Web2游戏通常在其内容和游戏玩法上表现出色,因此将平衡和公平交给游戏提供商是可以接受的。然而,当Web2游戏决定进入Web3生态系统时,它可能需要吸引更多关心经济、所有权和在游戏过程中捕获价值的加密原生玩家。这些玩家们不仅享受通过游戏获得丰富结果的过程,而且希望他们在游戏中取得的结果能够具有一定的意义(例如“可持续性)”,甚至是增值的属性。相对的,这种对具有“可持续性”的增值效应的期待使玩家更加认真地对待他们在游戏中的选择 — — 这意味着玩家在游戏中的思考和决策成本更高,进一步加深了他们对游戏规则公平性和可预测性的期望。
最终,玩家将要求他们能以某种方式控制游戏的“Web3特性” — — 公平和去信任化的特性不应该由运营商/游戏开发者而是由一套写定的代码来执行,从而达成一个更加去中心化的、完全构建于链上的游戏。
有关于此,一个简单的措施是将上面图示种左侧的所有内容都移到右侧图示(区块链)上,使架构如下所示:
显然,这个举措会导致游戏玩法的许多“退化”:
这是否意味着我们必须放弃复杂但丰富的内容以追求“全链哲学”呢?
在零知识虚拟机技术出现之前,答案可能是“是”。然而,基于零知识虚拟机技术现在已经被广泛研究和应用的事实,我们有了“第三种方法”,即将完全链上的游戏与去信任化计算相结合。这是如何实现的呢?
ZKVM,即零知识虚拟机,是一种将零知识证明与虚拟机技术相结合的概念。要理解它,让我们拆解以下两个模块:
将这两点结合起来看:零知识虚拟机(ZKVM)首先是一个虚拟机,它可以执行程序或合约,并提供零知识证明的隐私和安全优势。这意味着我们可以在zkVM内运行游戏引擎(或游戏服务器),并使用zkVM生成ZK证明,向区块链证明状态不同数据的执行结果是由游戏逻辑强制执行的。因此,游戏服务器没有办法调整发送到底层区块链的数据。
有鉴于此,全链游戏的综合架构可能如下所示:
我们这样称呼此类去信任化的全链游戏:Trustless Game。
游戏开发通常被认为是一件困难的事,因为它涉及到复杂的技术、珍贵的创意和项目管理等问题。当我们将ZKVM技术应用于Trustless Game时,可能涉及到的因素如下:
技术复杂性:在Trustless Game中,游戏的逻辑需要与游戏的可视化分开,并且逻辑需要是确定性的,以便ZKVM生成一个证明。此外,由于证明是在需要被执行的语言段上生成的,游戏开发者需要将游戏玩法分成执行段,并定期与链上合约同步执行。
艺术和设计:一般而言,艺术家和设计师们的工作在Trustless Game与其他游戏中并无不同,因为他们的工作内容不属于需要被证明的逻辑。在Trustless Game中,可视化开发需要基于游戏的全局状态,而UI/UX也被用作收集玩家活动的工具。
整体的游戏体验:与一般意义上的全链游戏不同,玩家不必在每次移动时签署链上行为,这增强了创建“频繁交互型游戏”的可能性 — — 它们指那些需要或鼓励玩家频繁地进行交互的游戏。
然而,受到ZKVM证明生成时间的限制,高频率交互对于在ZKVM中运行的Trustless Game游戏仍然是不可行的,例如RTS(即时战略游戏)和MOBA(例如DOTA)、在这些游戏里,玩家必须持续对单位和资源进行操作并调整策略以击败对手,这种类型的游戏很难基于ZKVM被开发。
相对的,在模拟类游戏和放置/农场类游戏中,玩家需要定期调配资源、参与市场行为或操作角色以实现在游戏中的成长 — — 此类游戏体裁就非常适合Trustless Game。
此外,交互式故事游戏和视觉小说也是个不错的选择。此类游戏可能不需要持续的交互,但它们通过不断出现的决策点来吸引玩家、塑造故事并鼓励频繁交互以查看玩家们的选择所导致的结果。
下面,让我们来聊聊货币化和可持续性。
一般而言,游戏的内容会随着时间的推移而发展,以此吸引新玩家并留住老玩家。这使得游戏玩法的逻辑变得动态,从而影响了在ZKVM中运行的程序 — — 由此带来的一个结果是验证合约可能会更改并需要更新。
有以下两种方法可以避免频繁更改需要ZK验证的合约:
例如,我们有以下游戏循环:
zkgame {
// Game logic
output(events)
}
它生成的事件将成为执行的证明实例。因此,我们可以将callbacks添加到合约中:
游戏逻辑主要在两个地方运行:前端或服务器端。
将游戏逻辑放在前端相对于客户端-服务器(Client-Server)结构简化了游戏的架构。这种方法允许前端模拟游戏并在执行轨迹建立后生成零知识证明(zk-proof)。随后,它使用本地zk-prover或远程证明服务为零知识虚拟机(ZKVM)生成ZK证明。然后,将该证明上传到底层区块链以触发结算合约。
相对的,将游戏逻辑放在服务器端意味着把游戏模拟和用户之间的交互转移到一个更专用的组件(游戏服务器)中。这可以在以下方面改善整体游戏体验:
对于不需要历史数据并且具有较简单顺序逻辑的单人PVE游戏(或多人PVP游戏),将所有内容放在前端是一个不错的选择。对于像多人SLG(模拟游戏)或AW(自治世界)游戏这样复杂的游戏,服务器端游戏的表现更好。
由于我们将传统游戏开发与ZKVM相结合,我们需要仔细考虑工具选择。
1.开发语言
首先我们需要决定是使用传统编程语言如C#、Rust、C、C ++、Go来开发游戏,还是要使用特定于ZKVM的语言。
传统编程语言的后端字节码通常是MIPS、WASM、RISC-V、x86。由于没有多少ZKVM支持这些字节码,如果你的程序可以编译成RISC-V字节码,则可以选择Risc0作为底层ZKVM,如果它可以编译为WASM,则可以选择zkWASM作为底层ZKVM。
WebAssembly(WASM)是一种低级字节码格式,用作高级语言(如C、C ++、Rust等)的编译目标。它旨在使使用这些语言编写的代码在网络上以接近本机的速度运行。WebAssembly提供了一种在Web浏览器中运行性能关键代码的方式,而不会牺牲Web应用程序的安全性或速度。它是现代Web技术堆栈的关键部分,通过允许开发人员利用除JavaScript之外的其他语言进行Web开发,从而补充了JavaScript。
2. 游戏引擎
一旦选择了编程语言,我们可以根据选择的语言选择基于该语言的游戏引擎。如果选择了特定于ZKVM的语言,则可能需要创建自己的游戏开发框架,因为可能不存在成熟的框架用于该语言。如果使用的是rust、C、typescript等语言,则有很多框架可供选择,其中我们推荐Unity和Cocos2D。
3. 证明生成成本
通常,证明成本是以100万条指令的证明时间来衡量的。因此,它取决于游戏玩法的执行轨迹(每个游戏玩法交互的指令数量)、后端字节码的字长以及ZKVM的证明性能。对于简单的指令集,有一些ZKVM可以在几秒钟内生成100万条指令的证明(Miden)。对于复杂的指令集(RISCV 32位、WASM 64位),ZKVM可以在GPU中在12秒内生成100万条指令的证明(Risc0)到大约30秒(zkWASM)的证明。
模型-视图-控制器(MVC)模式虽然一般与Web/企业应用程序开发相关联,也可以应用于游戏开发 — — 尽管需要一些调整。以下是MVC组件在游戏开发环境中的运行方式:
模型(Model):
在游戏开发中,模型代表游戏的数据和逻辑。这包括游戏状态(如分数、级别和玩家统计)、游戏对象以及管理游戏世界的规则。模型负责管理游戏的数据和状态,通常它不知道这些数据将如何呈现或显示。
视图(View):
在游戏开发中,视图负责向玩家展示游戏状态。这涉及到渲染游戏图形、播放声音以及显示诸如分数、生命条和菜单等UI元素。视图观察模型并更新游戏世界的视觉和听觉表示以向玩家展示。在许多游戏引擎中,视图可能被封装在渲染引擎和UI系统中。
控制器(Controller):
控制器解释来自键盘、鼠标、游戏手柄或其他输入设备的用户输入,并将其转换为游戏内的动作。例如,当玩家按下按钮使角色跳跃时,控制器会处理此输入并将动作传达给模型。游戏中的控制器充当输入设备和游戏逻辑之间的中介。
在游戏开发中应用MVC具有以下的显著优点:
假设控制器与模型连接,并具有一组模型处理程序。接下来,我们可以为控制器和处理程序添加一个命令编码/解码层,如下所示:
我们可以将游戏玩法的一部分视为对处理程序的一系列控制器的调用。因此,游戏玩法的去信任化ZK证明是以下代码:
fn execution(cs: Vec<command>) {
for command in cs {
global_state = handler(command);
}
}
在游戏过程中,我们很难确定控制器发送的最后一个命令,并且很难将所有命令处理放入单个ZK证明中。因此,最佳做法是将命令拆分为多个部分并对它们进行证明,然后将它们批处理在一起生成单个证明,以便在链上进行进一步验证。
注:请注意,上述方法中存在两个缺失的部分:
在接下来的章节中,我们会简要介绍多玩家序列化(sequencing)和数据可访问性(DA)。由于每个主题都可以深入探讨,我们计划在其他单独的笔记中提供更详细的内容。
在模块化区块链的语境中,序列化器是负责在交互最终确认之前对其进行排序的组件或节点。模块化区块链架构将区块链功能的不同层次(例如执行、共识和数据可用性)分离为不同的组件。这种方法旨在通过允许每个层独立优化来提高可扩展性、安全性和效率。
在开发多玩家游戏时,我们也需要一个组件来帮助对不同用户之间的交互进行排序。因此,我们二次使用了模块化区块链中的序列化术语。
由于游戏需要较低的延迟,最好选择一个产生快速排序结果的集中式序列化器。游戏引擎也可以与序列化器紧密配合,同时获取排序后的交易。
在这里(见下图),我们从玩家角度描述了一个交互协议。在用户交易中,用户描述了他的输入,并通过公共输入和见证输入证明了自己的身份,这些输入可以具有以下布局:
公共输入与见证输入:
交互处理逻辑:
pub fn zkmain() -> i64 {
let mut hasher = Sha256::new();
// get the command length
let commands_len = unsafe {wasm_input(0)};
// processing all commands and
// hash the commands for furture signature verification
for _ in 0..commands_len {
let command = unsafe {wasm_input(0)};
hasher.update(command.to_le_bytes());
step(command);
}
let msghash = hasher.finalize();
let pk = unsafe {BabyJubjubPoint {
x: U256([
wasm_input(0),
wasm_input(0),
wasm_input(0),
wasm_input(0),
]),
y: U256([
wasm_input(0),
wasm_input(0),
wasm_input(0),
wasm_input(0),
]),
}};
zkwasm_rust_sdk::dbg!(“process sig\n”);
let sig = unsafe {JubjubSignature {
sig_r: BabyJubjubPoint {
x: U256([
wasm_input(0),
wasm_input(0),
wasm_input(0),
wasm_input(0),
]),
y: U256([
wasm_input(0),
wasm_input(0),
wasm_input(0),
wasm_input(0),
]),
},
sig_s: [
wasm_input(0),
wasm_input(0),
wasm_input(0),
wasm_input(0),
]
}};
let msghash_u64 = [
u64::from_be_bytes(msghash[24..32].try_into().unwrap()),
u64::from_be_bytes(msghash[16..24].try_into().unwrap()),
u64::from_be_bytes(msghash[8..16].try_into().unwrap()),
u64::from_be_bytes(msghash[0..8].try_into().unwrap()),
];
sig.verify(&pk, &msghash_u64);
在基于ZKVM的去信任化全链游戏中,主要的维护成本来自于ZK证明生成、快速数据RPC服务、调用数据访问服务以及链上验证和结算费用。随着坎昆升级(EIP 4844)在 L2 上生效,运行去信任游戏的成本已经显着降低了。此外,通过未来实施 zkSNARK 证明递归(proof recursion)以及 Nebra 的证明聚合服务(proof aggregation),我们可以进一步降低 ZKP 的成本。
首先,ZKVM运行应用程序并生成执行轨迹(execution trace)。这个轨迹是较为基础的,因为ZKVM需要证明:
假设我们使用的ZKVM使用预编译指令作为系统调用(或ZKWASM中的主机API)来处理Merkle证明。生成ZK证明的整体成本如下:
证明成本 = ZKVMGuest证明成本 + Merkle证明成本 + 批处理证明成本(BatchProofCost)
通常,等式右边的第一和第三项不会引入额外的成本,除了纯ZK证明。然而,第二项的成本有一些微妙,因为它需要一些数据存储服务的支持。
让我们回顾一下Merkle证明的组成部分:
1.Merkle树的设置
我们将全局数据抽象成块,并单独对它们进行哈希处理。这些哈希成为目标树的叶节点。然后,将叶节点的对进行哈希处理以形成下一级节点,并重复此过程直到顶部只有一个哈希为止,称为Merkle根。Merkle根是树中所有数据块的唯一表示。
2. 数据包含证明
该证明由问题中的特定数据块、其哈希以及来自Merkle树的少量额外哈希组成。这些额外的哈希是使验证器能够独立计算数据集的Merkle根所必需的最小值。
3. 验证证明
验证者知道数据集的Merkle根但不一定知道其中所有数据的验证器,他使用提供的数据块和额外的哈希来重建到Merkle根的哈希路径。如果计算出的Merkle根与已知的Merkle根匹配,则证明有效,确认该数据块确实是数据集的一部分,且未被篡改。
要维护一个具有状态的ZK游戏,需要一个Merkle数据数据库来跟踪Merkle树的树叶,并提供快速的数据查询服务。这种服务不太可能完全托管在链上,因为数据的修改频率非常高,访问(读取/写入)需求也很高。
一旦交易完成,调用数据和最终状态(由新的Merkle树根表示)需要是可访问的。这通常通过DA层或链上txdata存储来实现。
根据Blade Games的分析并参考ZKWASM、Eth Storage、BNB Greenfield DA存储成本计算器和谷歌云存储计算器,我们可以得出以下结论:使用zk协处理器方法运行一个拥有5,000个玩家(假设他们一刻不停的玩,这样的日活用户其实要比5000高很多)的链上游戏,预计每月成本约为90,000美元,这个成本类似与运行一个高防,反DDOS的MMORPG游戏服务器成本类似。
Blade Games的估算方法如下:他们将Unity中发布的用户事件转换为二进制代码,并在ZKWASM内运行(ZKWASM是由Delphinuslab开发的支持WASM字节码的ZKVM)。然后,ZKWASM将生成执行轨迹,并将压缩的轨迹发布到DA层,与此同时,他们将在链上发布轨迹哈希,并用数字签名进行不可变性验证。
根据ETHstorage和zkwasm的测试运行,运行1秒钟的wasm二进制文件将生成100万行轨迹,每行大小为40字节。
我们可以选择在链上证明所有的轨迹,或者只保存轨迹,如果用户选择挑战结果,则进行证明。
1.证明所有轨迹的ZK方法
如果我们选择证明所有的轨迹,那么100万字节码大约需要在单个RTX4090图形卡上花费25秒,成本可能是0.5美分(成本为每美元的2000M指令)。在这种解决方案中,成本主要来自证明能力费用、链上验证费用以及DA的调用数据存储费用。使用这种方法来支持一个每小时有1000亿条轨迹的多人游戏,将每小时花费约50美元(每月36,000美元)作为证明成本。
2. 欺诈证明方法
假设一共有5000名玩家,他们平均每人连续游戏2小时,且每个玩家每小时产生86.4万亿条轨迹。因此,每天消耗的存储量为60秒 * 60分钟 * 2小时 * 5000名玩家 * 100万字节码 = 36,000,000,000,000条轨迹。根据ETHstorage和zkwasm的测试,每条轨迹消耗的存储空间为40字节。因此,对于一个有5,000名玩家的游戏(平均在线时间为2小时),它每天将消耗1,440TB的存储空间。
如果以合理的比率10倍压缩轨迹,那么每天我们将消耗144TB的谷歌云存储空间,这相当于一个月的4,320TB,成本估计为90,120美元/月(在归档存储层,标准存储层允许更高的数据访问频率,成本将为每月185,000美元)。此外,每GB在BNB Greenfield上存储签名数据的月成本为0.0001 BNB,约合0.03美元。在这种方法中,观察节点可以检查轨迹的一致性,并触发ZKFraud证明来报告不诚实的交易。
基于上述讨论,我们可以得出结论:运行一款大玩家量级游戏的总成本,与运行一个高防反DDOS的MMORPG游戏服务器成本类似。
一个成功的游戏通常具有动态的游戏内容,因此需要定期更新其引擎。这似乎与加密原生社区中流行的“代码即法律”的理念相矛盾。
然而,这个挑战有潜在的解决方案。
通过采用一种设计模式,将可维护的规则放在区块链上,可以确保对游戏玩法的升级或修改符合这些基本规则。鉴于在游戏架构语境下这个主题的复杂性,我们使用以下图表进行简明的解释:
随着zkVM和相关基础设施的出现,全链游戏开发者可以兼顾复杂但丰富的内容,以及“全链哲学”。我们认为此类“去信任化游戏”,将会有广阔的市场前景和空间。
结合zkVM和模块化的执行层概念,游戏的市场策略(GTM)也会变得异常灵活,想象一下游戏玩家同时可以与Eigenlayer, zkWASM, Berachain等热门项目交互,获得空投,同时还可以获得游戏内本身的收益,这将会给游戏的早期冷启动带来巨大的帮助。
对于读者“开发成本是不是依然很高”的疑问:我们认为在基于 ZKVM 的去信任游戏中,随着坎昆升级(EIP 4844)在 L2 上生效,递归证明、证明聚合的应用,以及本身的zkVM的优化,运行去信任游戏的成本已经显着降低了。
如果你感兴趣开发Trustless Game,请在twitter(bladegamesHQ)上dm我们,我们会提供相应的游戏开发、代码、GTM的帮助。
欢迎加入深潮TechFlow官方社群
2024.12.20
2024.12.20
2024.12.18
2024.12.16