Vyper 不可重入锁漏洞事后分析技术报告

互联网 阅读 1468 2023-08-16 09:25:00
编者按:Vyper 被黑的时间线和反思[1]从审计的角度重现并提醒开发者注意考虑项目的依赖,本文从开发的角度深度分析并总结了这次漏洞的前因后果
Vperlang 团队特别感谢 Omniscia 团队

2023 年 7 月 30 日,由于 Vyper 编译器(特别是 0.2.15、0.2.16 和 0.3.0 版本)中的一个潜在漏洞,多个 Curve.Fi 流动池被利用。虽然 v0.3.1 版本发现并修补了该漏洞,但当时并未意识到该漏洞对使用易受攻击编译器的协议的影响,也未明确通知这些协议。该漏洞本身是一个有问题的重入保护,在某些特定条件下可以被绕过,我们将在本报告中深入探讨。

虽然包括 Curve.Fi 官方报告在内的其他报告已经充分报道了黑客攻击事件本身,但我们还是想深入探讨一下 Vyper 编译器本身到底出了什么问题,为什么漏洞难以被发现,以及整个生态系统能从这些事件中学到什么。

如果你熟悉区块链领域以及 Vyper 的存在原因,我们建议你跳过背景部分,因为其中包含的基本信息很可能你已经了解。

背景

Vyper

Vyper 是以以太坊虚拟机(EVM)为目标的,面向合约的,特定领域的 pythonic 编程语言。Vyper 目标和原则是语言和编译器的简单性、安全性和可审计性。

EVM:一个单线程非并发的机器

在 EVM 上部署代码的一个常见问题是重入概念。与传统程序不同的是,"区块链程序" 的控制流会被让给正在执行的 "活动" 程序。"区块链程序" 也称为合约。

详细来说,我们可以认为所有区块链程序都在一个单线程上运行,不支持并发。每当一个程序调用其他程序时,整个控制流会传递给被调用的程序。

重入:一个广泛存在于 Web 3.0 的问题

这意味着,在外部调用期间原始调用者的执行流基本上被冻结,直到被调用程序执行结束,调用者才会重新回到原来的位置。这种方式会导致不同类型的漏洞,其中最著名的就是重入漏洞。

当控制流传递让给被调用合约时,被调用的合约可以在冻结时重新进入原始调用者。容易受到此类攻击的合约会在外部合约调用的重入时更新状态更新,这意味着它们被冻结时的状态已过时且不正确。

解决办法

生态里的应用提出了两种方法来对抗重入攻击,并从根本上使重入失效:Checks-Effects-Interactions(CEI)模式和重入防护。

Checks-Effects-Interactions(CEI)模式

CEI 模式是一种编程方法,它规定函数代码应首先执行安全检查(Checks),然后执行存储中的影响(Effects)- 修改状态,最后在函数结束时执行与外部合约的交互(Interactions)。

如果严格遵守这一模式,"交互"(即传递控制流)期间的合约状态将是最新且正确的,从而使任何可能的重入合约利用变得不可能。

重入防护

在大多数情况下,CEI 模式就足够了,但 DeFi 生态系统是多方面的,函数往往依赖外部调用的结果来继续自己的执行。在这种情况下,CEI 模式就不适用了,必须设置重入防护

安全是 Vyper 语言的核心原则之一, Vyper 决定通过特定的@nonreentrant函数修饰器在语言级别直接引入重入防护。自 Vyper 早期版本之一 v0.1.0-beta.9 发布以来,重入防护就一直是该语言的核心功能。

重入防护的核心功能是在两种状态(activated, inactive)之间设置一个存储值。当标记为@nonreentrant的函数被调用时,flag 会:

  • 确保处于非激活状态
  • 设置为激活状态(activated)

一旦函数调用结束后,flag :

  • 设置为非激活状态(inactive)

有了这种机制,@nonreentrant用户就可以确保只有在函数结束后才能重新调用它,也就是说,无论执行何种外部调用,都不会发生重入。还有更复杂的重入攻击形式存在(如view重入、跨合约重入),但就本漏洞而言,基本情况才是最重要的。

Vyper 漏洞历史时间线

@nonreentrant基于标签的重入防护

自引入以来,@nonreentrant一直支持设置 ``[2],这与只在合约级全局应用的不可重入锁相比,它提供了更大的灵活性。

一个简单的实现是用mapping来获取key并设置相关的重入 flag,但这种方法会因mapping查找的keccak256gas 消耗而产生额外费用。

由于 Vyper 是一种不向用户提供原始存储访问的语言,因此在编译时它会完全了解合约使用的所有存储 slot 。因此,Vyper 会负责分配存储 slot ,包括确保存储变量和重入 key 锁的 slot 不会重叠。

PR#1264[3]在 Vyperv0.1.0-beta.9版本中引入了这个功能,用了一种简单的方法来确保不重叠,即在合约原始 slot 的特定偏移量(准确的说是 0xFFFFFF)处存储重入 flag 。

重构编译器

在开发新功能的同时,从 2018 年开始,Vyper 编译器开始了长达数年的重构工作[4],将当时的单通道架构重构为多通道架构,该架构将类型检查和语义分析的关注点分离到前端,与代码生成后端不同。与大多数大型重构项目一样,这项工作是渐进和零碎的,与其他错误修复和功能开发同时进行,直到 2023 年的PR#3390[5]才最终完成。

位置优化: 更智能地分配存储 slot

PR#2308[6]是 Vyperv0.2.9版本的一部分,其目的是在处理完合约的常规存储变量的所有 slot 后,利用第一个可用的未分配存储 slot ,而不是从0xFFFFFF常量开始作为重入锁 flag ,从而更智能地分配存储空间。这将节省字节码空间,因为在字节码中,加载或存储不可重入键的存储槽位置可以使用更少的字节。

避免损坏:正确的抵消计算

上述v0.2.9版本的 PR 运行良好,只要在(物理的)存储布局前面按顺序分配的变量不跨越多个顺序 slot ,就能保证重入防护 flag slot 和存储 slot 之间没有重叠。

由于 Vyper 语言和代码库当时正在进行重大重构,PR#2361[7](v0.2.13版本的一部分)引入了一种更有效的方法,优化合约中存储跨多个存储 slot (32 字节)的变量。作为更大规模重构工作的一部分,它还将常规存储变量的槽计算从代码生成(codegen)后端通道到了新的前端通道中,但保留了重入 key 的 slot 计算。由于重入 key 的 slot 计算依赖于常规存储变量的分配结果,因此最终在前端和代码生成(codegen)通道之间保留了两种不同的常规存储变量分配器实现。这导致PR#2308[8]的偏移计算不正确,需要更新。

PR#2379[9]引入了这个更新(v0.2.14版本的一部分),其目的是通过考虑在存储中声明的变量的正确大小,而不是假设所有变量都占用一个 slot (在早期实现中确实如此),来正确计算重入 flag 的存储偏移量。不过,第二次更新仍有一个 bug,源于前端和代码生成(codegen) 分配器实现之间的差异,我们将在下文中加以说明。

由于这些 bug,v0.2.13和v0.2.14版本在发布后不久就被 "撤回(yanked)" 。

简而言之,"yanking "指的是为历史目的在版本库中提供标签,但不发布和提供下载。有关详细信息,请参阅PEP-592[10]。

决定性事件:v0.2.14版本中的 "重入防护损坏"

v0.2.14发布后不久,一位 Vyper 用户在 Vyper GitHub 代码库中打开了issue #2393[11],指出在 Yearn vault 代码升级到0.2.14时,重入防护测试失败。

截取该用户提交问题时Yearn 最新可用版本[12]的快照,用v0.2.14编译,并用EtherVM 反编译器[13]检查反编译后的字节码(伪代码),会发现存储偏移storage[0x2e]被用作@nonreentrant("withdraw")的 "flag",应用于Vault.vy文件的def deposit和def withdraw实例中。

然而,合约级别的managementFee变量使用了相同的存储偏移量,这可以通过评估managementFee()getter 函数和setManagementFee()setter 函数的反编译函数来验证,这两个函数将重复使用相同的存储偏移量。

用v0.2.13版本编译相同的代码库时发现,重入防护按预期运行,并且没有出现存储重叠。不过,v0.2.14版本的PR#2379[14]并未完全解决重入防护损坏问题。

v0.2.14版本中为@nonreentrant修饰器分配存储 slot 的代码仍然会在新的前端代码和当时的 codegen 分配器之间产生不正确的交互。由于前端和 codegen 分配器之间映射类型的分配策略不同,重入 slot 最终仍会与常规存储变量重叠。**v0.2.14版的数据损坏代码如下**:

defget_nonrentrant_counter(self,key):

"""

Nonrentrantlocksuseaprefixwithacountertominimisedeploymentcostofacontract.

We'reabletosettheinitialre-entrantcounterusingthesumofthesizes

ofallthestorageslotsbecauseallstorageslotsareallocatedwhileparsing

themodule-scope,andre-entrancylocksaren'tallocateduntillaterwhenparsing

individualfunctionscopes.Thisreliesonthedeprecated_globalsattribute

becausethenewwayofdoingthings(set_data_positions)doesn'texposethe

nextunallocatedstoragelocation.

"""

ifkeyinself._nonrentrant_keys:

returnself._nonrentrant_keys[key]

else:

counter=(

sum(v.sizeforvinself._globals.values()ifnotisinstance(v.typ,MappingType))

+self._nonrentrant_counter

)

self._nonrentrant_keys[key]=counter

self._nonrentrant_counter+=1

returncounter

将其与当时计算常规存储变量存储布局的前端代码进行比较。

available_slot=0

fornodeinvyper_module.get_children(vy_ast.AnnAssign):

type_=node.target._metadata["type"]

type_.set_position(StorageSlot(available_slot))

available_slot+=math.ceil(type_.size_in_bytes/32)

虽然这段代码可以正确地消耗key值,并为相同的key值生成相同的@nonreentrant存储偏移量,但它却错误地计算了存储偏移量。

具体来说,旧的分配器没有为MappingType条目(即HashMap)分配存储 slot ,而新的分配器则分配了存储槽。MappingType存储条目永远不会被写入,而是被编译器保留(参考:Issue 2436[15])。这导致了不可重入 key 分配器与前端分配器之间的不一致,从而导致了所报告的存储损坏。

引入漏洞:v0.2.15版中失效的重入锁

在v0.2.14被撤回之后,为了修正v0.2.14版本中的重入防护损坏问题,v0.2.15版本中的PR#2391[16]通过将重入 key 移动到常规存储变量前面进行物理分配,修复了之前提到的PR#2379[17]中引入的 bug。此外,为了减少此类问题再次出现的概率,该版本还将存储 slot 分配逻辑移至前端中与常规存储变量分配相同的函数中,从而完成了将存储 slot 分配逻辑从 codegen 通道中移除的工作。不过,这样做的同时,也删除了旧的self._nonreentrant_keys数据结构,更重要的是,删除了确保每个不可重入 key 只分配一个锁的相应逻辑:

ifkeyinself._nonrentrant_keys:

#-->SAFE.onlyallocateoneslotperkey<--

returnself._nonrentrant_keys[key]

实际漏洞出现在v0.2.15版本的以下代码中:

#Allocatestorageslotsfrom0

#notestorageisword-addressable,notbyte-addressable

storage_slot=0

fornodeinvyper_module.get_children(vy_ast.FunctionDef):

type_=node._metadata["type"]

iftype_.nonreentrantisnotNone:

#-->BUG!shouldchecknonreentrantkeynotalreadyallocated<--

type_.set_reentrancy_key_position(StorageSlot(storage_slot))

#TODOuseonebyte-orbit-perreentrancykey

#requireseitheranextraSLOADorcachingthevalueofthe

#locationinmemoryatentrance

storage_slot+=1

该漏洞是由于重入 key 的storage_slot偏移忽略了@nonreentrant(<key>)修饰器的实际<key>,而只是简单的为每个看到的@nonreentrant修饰器预留一个新 slot ,而不管用的是什么 "key"。

潜伏:v0.2.15、v0.2.16和v0.3.0

v0.2.15中引入的漏洞在v0.2.16和v0.3.0临时版本中未被检测到,原因是当时 Vyper 代码库中没有足够的测试来检测该漏洞,这段时间为 2021 年 7 月 21 日至 2021 年 11 月 30 日之间的 4 个月。

所有使用v0.2.15、v0.2.16和v0.3.0版本编译的 Vyper 合约都会受到重入防护功能故障的影响。

修复:v0.3.1版

v0.3.1版通过调整编译器为合约中每个变量分配数据 slot 的方式,解决了此漏洞。该漏洞在两个不同的 PR中得到修复。

PR#2439: 修复未使用的存储 slot

第一个部分修复漏洞的 PR 是PR#2439[18],其中包含以下描述:

这不是一个语义漏洞,而是一个优化漏洞 我们分配的 slot 比实际需要的多,导致 slot 出现 "漏洞"。分配器--已分配但未使用的 slot 。

这种描述实际上并没有清楚地说明问题所在。关于 "漏洞"的描述是通过观察编译输出的layout是如何为每个重入 key 生成单个slot值而得出的。为了更好地理解发生了什么,让我们来看看v0.3.0中的数据分配函数:

fornodeinvyper_module.get_children(vy_ast.FunctionDef):

type_=node._metadata["type"]

iftype_.nonreentrantisnotNone:

type_.set_reentrancy_key_position(StorageSlot(storage_slot))

#TODOthiscouldhavebettertypingbutleaveituntypeduntil

#wenaildowntheformatbetter

variable_name=f"nonreentrant.{type_.nonreentrant}"

ret[variable_name]={

"type":"nonreentrantlock",

"location":"storage",

"slot":storage_slot,

}

#TODOuseonebyte-orbit-perreentrancykey

#requireseitheranextraSLOADorcachingthevalueofthe

#locationinmemoryatentrance

storage_slot+=1

这段代码的问题在于,它将每个type_(即单个@nonreentrantkey)的重入 key 位置设置为storage_slot的最新值,并在每次迭代时递增。这意味着@nonreentrant(<key>)的相同实例会使用不同的storage_slot值,但variable_name的ret变量在每次迭代时都会被覆盖。

因此,编译器的layout输出包含单个nonreentrant.<key>条目和单个存储偏移,这意味着检查编译器的输出似乎只是简单的 "跳过" 连续的@nonreentrant(<key>)声明的存储 slot ,这与PR 最初的逻辑[19]是一致的。

v0.3.1版本中部分修补的,无漏洞代码:

fornodeinvyper_module.get_children(vy_ast.FunctionDef):

type_=node._metadata["type"]

iftype_.nonreentrantisNone:

continue

variable_name=f"nonreentrant.{type_.nonreentrant}"

#anonreentrantkeycanappearmanytimesinamodulebutit

#onlytakesoneslot.ignoreitafterthefirsttimeweseeit.

ifvariable_nameinret:

continue

type_.set_reentrancy_key_position(StorageSlot(storage_slot))

#TODOthiscouldhavebettertypingbutleaveituntypeduntil

#wenaildowntheformatbetter

ret[variable_name]={

"type":"nonreentrantlock",

"location":"storage",

"slot":storage_slot,

}

#TODOuseonebyte-orbit-perreentrancykey

#requireseitheranextraSLOADorcachingthevalueofthe

#locationinmemoryatentrance

storage_slot+=1

现在,代码会在第一次识别到重复的重入 key 时分配一个单一的storage_slot。但是,它不会在有相同偏移量的每个type_上调用set_reentrancy_key_position函数,这就意味着除了第一个外,其他任何@nonreentrant(<key>)条目都将使用 "未定义 "的存储偏移量。

这导致编译器在尝试编译带有@nonreentrant修饰器的合约时出现 panic 。为了纠正这一问题,有必要进一步修改,以确保所有@nonreentrant修饰器都能正确认识到它们需要操作的存储 slot 。

panic: 也就是说,编译器会直接出错,而不会生成任何代码。编译器 "panic" 虽然会让用户感到恼火,但被认为是一种 "安全" 错误,因为它不会生成代码。︎

PR#2514: 修复 在使用不可重入键时 codegen 失败的问题

PR#2514[20]是缓解@nonreentrant漏洞的最后一份 PR。具体来说,它扩展了上述代码段,以确保set_reentrancy_key_position函数被正确调用,并为给定的@nonreentrant锁分配正确的 slot。

v0.3.1版本 Vyper 的最终无漏洞代码如下:

fornodeinvyper_module.get_children(vy_ast.FunctionDef):

type_=node._metadata["type"]

iftype_.nonreentrantisNone:

continue

variable_name=f"nonreentrant.{type_.nonreentrant}"

#anonreentrantkeycanappearmanytimesinamodulebutit

#onlytakesoneslot.afterthefirsttimeweseeit,donot

#incrementthestorageslot.

ifvariable_nameinret:

_slot=ret[variable_name]["slot"]

type_.set_reentrancy_key_position(StorageSlot(_slot))

continue

type_.set_reentrancy_key_position(StorageSlot(storage_slot))

#TODOthiscouldhavebettertypingbutleaveituntypeduntil

#wenaildowntheformatbetter

ret[variable_name]={

"type":"nonreentrantlock",

"location":"storage",

"slot":storage_slot,

}

#TODOuseonebyte-orbit-perreentrancykey

#requireseitheranextraSLOADorcachingthevalueofthe

#locationinmemoryatentrance

storage_slot+=1

正如我们在上述片段中看到的,set_reentrancy_key_position现在可以正确调用每个nonreentrant的type_条目,而且只要在@nonreentrant(<key>)修饰器中指定了相同的key,就会正确使用相同的storage_slot。

此外,除了上述修复之外,PR 还包含了 Vyper 代码库中一个急需但遗漏的测试;一个专门检查跨函数重入的单元测试:

@external

@nonreentrant('protect_special_value')

defprotected_function(val:String[100],do_callback:bool)->uint256:

self.special_value=val

ifdo_callback:

self.callback.updated_protected()

return1

else:

return2

@external

@nonreentrant('protect_special_value')

defprotected_function2(val:String[100],do_callback:bool)->uint256:

self.special_value=val

ifdo_callback:

#callotherfunctionwithsamenonreentrancykey

#-->(revertexpectedhere)<--

Self(self).protected_function(val,False)

return1

return2

然而,虽然在编译器代码库中发现、修复并测试了该错误,但当时并未意识到其对正式合约的影响,也没有明确通知可能使用相关编译器版本的协议。

在@nonreentrant修饰器中重复使用的相同<key>值的概念只有一个目的:跨函数重入防护。在 Vyper0.3.1版本发布之前,Vyper 存储库中一直缺少这样的测试,这也是导致该漏洞被引入并长期未被发现的原因之一。

漏洞总结

  • 受影响版本:v0.2.15、v0.2.16、v0.3.0
  • 根本原因:对v0.2.13中引入的重入防护数据损坏问题的补救不当
  • 漏洞简介:Vyper 合约中的所有@nonreentrant修饰器都将使用唯一的存储偏移量(无论其key如何),这意味着在使用易受影响版本编译的所有合约上都可能出现跨函数重入。

利用漏洞的条件

虽然漏洞本身很容易识别,而且在各种合约中都能观察到,但其要利用它却需要满足的一系列非常特殊的条件。具体来说:

  • 使用以下任一 vyper 版本编译的.vy合约:0.2.15,0.2.16,0.3.0
  • 使用@nonreentrant修饰器并带有特定key的主要函数,且未严格遵循 CEI 模式(即在存储更新前有对不可信任方的外部调用)。
  • 使用相同key的次要函数,会受到主函数导致的不正常状态的影响

不幸的是,这些条件正是在Curve.Fi 流动性池[21]中被利用的条件,因为它们需要在敏感的存储更新之前,在函数中执行原生ETH的分发(在 EVM 上,这只能通过执行上下文转移 CALL来完成),原本这些函数应该受到正常运行的@nonreentrant的保护。

从技术上讲,还有其他方法可以发送以太币,但在本文撰写时并不适用。EIP-5920[22]可能是这方面的一个积极进展。︎

总结和启示

对于任何大型生产型软件项目来说,错误都是一个不幸而严峻的现实。我们能做的就是尽最大可能减少错误及其相关风险。

我们可以采取几个切实可行的步骤来提高使用 Vyper 编译的智能合约的正确性:

1、改进编译器的测试,包括继续提高覆盖率、将编译器输出与语言规范进行比较,以及利用形式化验证(FV)工具进行编译器字节码验证。2、为开发人员提供工具,使他们更容易采取多方面的方法来测试代码,包括源代码和字节码级测试。3、使用 Vyper 对协议进行更严密的双向反馈

但是,仅仅关注最新版本编译器的正确性是不够的;由于智能合约的不可更改性,使用 Vyper 过去版本编译的合约可能会存在风险。

因此,确保 Vyper 过去版本的安全是另一个重要的新焦点,我们将在未来投入大量资源。这与为最新版本引入新功能、提供错误修复和重构一样重要。

最终,我们希望从最近发生的事件中吸取教训,确保 Vyper 成为世界上最稳固、最安全的智能合约语言和编译器项目。因此,这些目标将得到我们团队内外各种与安全相关的新举措的支持,这些举措包括:

  • 与 Codehawks 合作进行短期竞争性审计,重点关注 Vyper 的最新版本
  • 与 Immunefi 合作开展短期和长期(开放式)漏洞赏金计划,涵盖 Vyper 编译器的所有版本
  • Vyper 安全联盟,这是一个协调一致的多协议悬赏计划,旨在帮助发现当前和过去的编译器漏洞,这些漏洞会影响 Vyper 的实时 TVL 安全版本
  • 与包括 ChainSecurity、OtterSec、Statemind 和 Certora 在内的多家审计公司合作,审查 Vyper 过去的版本,以确保大量实时 TVL 的安全,并帮助对编译器进行持续审查。
  • 扩大团队;包括一个专门的安全工程角色,旨在全面改进 Vyper 的安全工具,包括内部工具和面向用户的工具
  • 与为 Solidity 提供的现有安全工具包合作,使 Vyper 生态系统受益匪浅
  • 设计语言规范,这将有助于正式验证和帮助编译器本身的测试工作
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
上一篇:Cobo:DeFi 挖矿安全的最佳实践 下一篇:BuidlerDAO:ERC-4337 如何助力 Mass Adoption 的技术向讨论

您可能感兴趣

  • 解读CKB版 “闪电网络” Fiber Network:比特币可编程性扩展的另一种思路
    解读CKB版 “闪电网络” Fiber Network:比特币可编程性扩展的另一种思路

    作者:NingNing行业周期与宏观金融周期共振,加密行业正处在与 2019 年相似的整体性迷茫之中,现阶段不仅流动性枯竭,叙事貌似也在枯竭。市场不但对 VC 叙事兴趣阙如,对反 VC 的 Meme 叙事也已经疲倦。就像每次哲学危机,人们都会回归柏拉图寻找出路,当加密行业危机时,我们也需要回归比特币、回归中本聪。正如 CKB 生态 RGB++ 协议创始人 Cipher 在最新 Blog 里所阐述的,加密行业需要对以太坊 “链上计算” 的路径依赖进行反思,回归P2P经济学,让计算归于链下,让验证归于链上。因

    每日资讯 2024-09-02 12:06 1292
  • 面对NFL球员工会起诉,“退圈”的DraftKings竟主动承认NFT是证券?
    面对NFL球员工会起诉,“退圈”的DraftKings竟主动承认NFT是证券?

    作者:Zen,PANews近日,美国国家橄榄球联盟球员协会 (NFLPA) 指控数字体育娱乐和游戏公司DraftKings 逃避了其 NFT 球员许可协议的付款义务。在放弃NFT业务后,涉嫌出售未注册证券而遭到集体诉讼的DraftKings又背上了一起官司。而有趣的是,在与NFLPA的纠纷中,DraftKings的立场似乎已从反驳转变为积极承认“NFT就是证券”。放弃NFT业务:驳回集体诉讼的动议遭到否决今年7月底,Draftkings在给用户的电子邮件中表示:“经过慎重考虑,DraftKings 决定终

    每日资讯 2024-09-02 12:06 1400
  • 简析两种最新比特币智能合约实现方案:OP_NET与Arch有何区别?
    简析两种最新比特币智能合约实现方案:OP_NET与Arch有何区别?

    作者:Cookie过去半个月,OP_NET 与 Arch 这两个比特币主网上的智能合约实现方案引发了较多的讨论。有意思的事情是,OP_NET 这个名字与大家熟悉的 OP_CAT 很像,都以「OP_」开头,具有很强的、让大家认为这哥俩差不多的迷惑性。所以,在开篇要和大家先提一嘴 OP_CAT。首先,OP_CAT 是比特币操作码,从去年开始有以「量子猫」Quantum Cats,也就是「大巫师」Taproot Wizards 的创始人 Udi Wertheimer 为首的社区力量一直在呼喊要「复活」OP_CA

    每日资讯 2024-09-02 12:06 1302
  • 争议不断,以太坊正在失去“万链之王”的权威
    争议不断,以太坊正在失去“万链之王”的权威

    作者:Climber,金色财经近期围绕以太坊的话题和争议越来越多,不仅 Vitalik 本人需要下场解释观点,就连以太坊基金会也要发布公告来平息社区的质疑声。在本轮牛市周期中,以太坊的表现可谓平平。而美国以太坊现货 ETF 的通过也并未让 ETH 走势如投资者期待般爆发,相反却在币价方面越走越低。这就不免让有着「万链之王」美誉的以太坊逐渐失去投资者和社区的尊重,进而质疑起有关以太坊的方方面面。争议不断,以太坊亟需重塑权威最近一段时间以来社区成员对 Vitalik 言论观点、以太坊基金会乃至以太坊生态系统的

    每日资讯 2024-09-02 12:06 1002
  • 从《黑神话:悟空》谈起,GameFi何时能取得真经?
    从《黑神话:悟空》谈起,GameFi何时能取得真经?

    作者:YBB Capital Researcher Zeke前言本文是市场垃圾时间中的一些闲聊,需要对传统游戏市场有一定程度了解。大家可以把这篇文章当作日记或者随想观看,这些只是我在游玩《黑神话:悟空》之后对GameFi的一些粗浅思考,以及对这个赛道未来的看法。一、游戏科学的九九八十一难三天全网销量破千万、Steam玩家同时在线峰值破235万、多家品牌联名周边销售爆火、国家级媒体多次采访、多个游戏取景地可凭游戏通关记录终身免费进入、86版《西游记》YouTube观看量超400万。以上,是《黑神话:悟空》上

    每日资讯 2024-09-02 12:06 691
  • Gavin Wood:如何防止女巫攻击进行有效空投?
    Gavin Wood:如何防止女巫攻击进行有效空投?

    演讲:Gavin WoodGavin 近期一直在关注的女巫攻击(civil resistance)的问题,PolkaWorld 回顾了 Gavin Wood 博士在 Polkadot Decoded 2024 上的主题演讲,想要探究 Gavin 在如何防止女巫攻击上的一些见解。什么是女巫攻击?你们可能知道,我一直在研究一些项目,我在编写灰皮书,专注于 JAM 项目,也在这个方向上做了一些代码的工作。实际上,在过去的两年时间里,我一直在思考一个非常关键的问题,这个问题在这个领域中非常重要,那就是如何防止女巫

    每日资讯 2024-09-02 12:06 1248
  • 市场热议,链抽象将成加密新叙事?
    市场热议,链抽象将成加密新叙事?

    2024年,加密货币领域的技术创新持续加速,链抽象(Chain Abstraction)逐渐成为行业内的焦点。链抽象技术的核心在于通过隐藏底层技术的复杂性,让用户能够更加便捷地在多个区块链之间进行操作。传统的区块链技术通常要求用户掌握不同链的操作流程,并需要应对跨链操作中的技术难题,这极大地吸引了新用户的进入。而链抽象的出现,则为这些问题提供了有效的解决方案,成为Web3建设不可忽视的重要一环。01、什么是链抽象及其作用链抽象能够将不同的区块链之间的差异整合在一个统一的操作界面中,使得用户只需一个账户即可

    每日资讯 2024-09-02 12:05 540
  • 今日日报|马斯克和特斯拉赢得“被指控操纵狗狗币”的诉讼;稳定币支付平台Bridge完成5800万美元融资
    今日日报|马斯克和特斯拉赢得“被指控操纵狗狗币”的诉讼;稳定币支付平台Bridge完成5800万美元融资

    今日要闻提示:马斯克和特斯拉赢得驳回指控他们操纵狗狗币的诉讼OpenAI和Anthropic已同意将其主要新AI模型在发布前共享给美国政府OKX将上线Hamster Kombat(HMSTR)现货交易X平台纽约总部将于9月13日关闭,预计将迁往得州萨尔瓦多总统布克尔成为《时代》杂志最新一期封面人物稳定币支付公司Bridge完成5800万美元融资数据:MATIC、SHIB、UNI代币头部地址持仓均超50%网龙今年上半年通过出售2.9亿元的加密货币,获利5100万元人民币监管消息美国众议院计划在9月举行多场加

    每日资讯 2024-09-02 12:05 1041