浅析Vyper:一款受开发者欢迎的智能合约编程语言

    昨夜开始,Curve因受Vyper个别版本的重入锁故障影响,导致旗下alETH/msETH/pETH等稳定池被黑客攻击,由此引发一系列的DeFi次生灾害与加密世界震荡,至今仍在持续发酵中。这也是DeFi世界罕见地直面针对智能合约语言层Bug的攻击事件。不过相比于加密世界中常常见诸报端的Solidity语言,Vyper其实并不那么为人所熟知。那Vyper究竟是什么,它在DeFi世界中扮演着怎样的角色,为什么它的Bug又会引起行业的高度关注?本篇文章ForesightNews就带大家来了解一下目前正处于风口浪尖的Vyper语言。Vyper:第二受欢迎的智能合约编程语言Vyper创建于2017年,在此之前,开发人员编写智能合约最常用的语言是Solidity。

    而Vyper和Solidity一样,都是一种面向智能合约的编程语言,可编译为以太坊虚拟机(EVM)的字节代码,运行在EVM上。不过Vyper的编译器使用Python进行编写,是一种基于Python且兼容EVM的编程语言,具有强类型、小型编译器代码和高效的字节码生成的特点,这也使其成为想要进入Web3的Python开发人员的最佳选择之一。这导致从采用率角度看,目前的Vyper也是仅次于Solidity的「第二大兼容EVM的智能合约编程语言」,截至此次攻击事件发生前的DeFiLlama最新统计数据显示:在目前的DeFi开发格局中(TVL占比维度),Solidity以94.71%的市场份额占据绝对垄断地位,而Vyper以3.04%的市场份额位列第二名。而第三名开始往后的Rust(0.9%)、Cairo(0.53%)、Haskell(0.26%)已经是断崖式下降。除了基于Python的特点之外,Vyper不采用面向对象模式、内联汇编,并且不支持代码重用、修饰符、继承、函数重载、递归调用、无限长度循环和二进制定长浮点等。此外它还针对安全性、可读性、可审核性和Gas效率进行了优化:安全性:支持在Vyper中构建安全的智能合约;可读性:Vyper的智能合约语言和编译器实现力求简单,以提高代码的可读性,尤其是对于没有使用Vyper经验的用户以及一般没有编程经验的用户;可审核性:Vyper代码最大限度地让人可读,且其简单架构减少了软件错误,提升了智能合约的可审计性;Vyper的创始人JohnMaxSkaller曾表示,构建Vyper有两个原因:「首先,我喜欢Python,特别是它的简单性,但我不喜欢它缺乏范围确定性,凡事都需要做大量更改来取得进展,因此我决定在保留与Python兼容性的同时,通过建造高级得多的编程语言,并在其中建造函数性编程语言的某些概念来改正这些问题。

    第二个原因是性能。我有一个称之为interscript的主要Python程序,一个有读写能力的编程工具,它受到Python中缺乏良好结构和性能问题的困扰」。总的来说,Vyper的设计初衷是为了创建出智能合约参与方易懂的透明智能合约简化流程,以主打可读性与可审核性,从而确保安全。Vyper的优劣势本章节谈及的Vyper优劣势,主要是相比Solidity语言,毕竟从上文提到的市场份额维度,其它的智能合约语言暂时还未形成较大的气候。首先,Vyper相比Solidity的最大优势之一,就是它基于Python开发的特性,因此虽然Vyper的功能和流行程度不如Solidity,但对于熟悉Python的开发人员来说,它是理想的可选语言。同时,Vyper编译器还选择将局部变量存储在内存中而不是堆栈上,这使得合约更加简单和高效,并解决了其他高级语言中常见的「堆栈过深」的问题。

    Vyper也提供了更多内置函数,以确保几乎每个Solidity和Yul中的功能在Vyper中也可以实现。开发者通过内置函数可以访问低级位运算、外部调用和代理合约操作,通过编译时提供覆盖文件可以实现自定义存储布局。而Vyper相比Solidity的劣势也很明显,主要源于它是一种相对Solidity较新的语言,所以首当其冲自然是开发者维护和社区工具层面的短板:Vyper至今仍然缺乏Solidity所拥有的广泛社区支持——Solidity有大量优秀的开发工具可供使用,像OpenZeppelin为安全的智能合约开发提供开源库,以及Remix在线IDE和本地开发人员环境Hardhat等IDE,为其提供了允许轻松开发DApp的工具和功能。截至发文时,GitHub数据显示,Solidity的贡献者为568人,而Vyper为189人,相差3倍。不过Vyper虽然没有丰富的的开发工具套件,但它有更紧密集成的工具,并且也可以插入到Solidity开发工具中——如Titanaboa解释器,具有许多与EVM和Vyper相关的内置工具,可用于实验和开发;Dasy,作为一种基于Vyper的Lisp,具有编译时代码执行功能。此外从技术细节角度,Vyper缺少修饰符、类继承和递归调用,并且编程语言不是图灵完备的。

    当然这些大部分是Vyper特意提供更少的功能,旨在提升安全性和可审计性,以使合约更安全和易于审核,但这也使得开发人员需要额外的工作来解决这些限制,从而意味着本就不占人力优势的Vyper注定开发效能偏低。Vyper的影响力从何而来?目前来看,此次Vyper故障只涉及0.2.15、0.2.16和0.3.0等几个特定版本,且从上文也可知,使用Vyper编写的头部DeFi项目的体量并不大,仅占不到5%的TVL市场份额。那为何此次Vyper的故障却造成了如此大的影响?简言之,虽然在主流DeFi协议中,主动使用Vyper语言进行开发的项目并不多,且此次出现问题的是Vyper的几个特定版本,但有一个头部DeFi项目却是基于Vyper开发:没错,正是Curve,主要原因似乎与上文提到的Gas优化特性有关——因为Curve合约较为复杂,Vyper使得这些复杂性变得更易于管理,并进一步节省Gas(其它基于Vyper开发的知名项目则屈指可数,如Uniswapv1版本、第一个ETH2.0存款合约等)。由于Curve已经成为DeFi世界甚至整个链上金融的关键基础设施,所以在层层嵌套之下,Curve的稳定池本质上就是绝大部分协议的底层资金与收益来源,这也是此次安全事件发生至今,JPEG'd、Alchemix、Metronome、deBridge、EllipsisFinance等余震不断的关键原因。不过Vyper的新版本已经修复这个漏洞,但由于受影响的Curve稳定池合约不可升级,因此无法进行部署升级,只能选择废弃对应合约,将资金撤出。小结总的来看,此次安全事件之所以大家会心有余悸,主要是因为智能合约语言层的Bug风险,已经远超DeFi协议本身或者说智能合约逻辑的范畴。试想一下,如果此次不只是Vyper,而是连Solidity也同样出了问题,那么链上所有的DeFi协议可能都几难幸免,我们甚至会真的面临「DeFi不存在了」的风险。但祸兮福之所倚,这次Curve也算被动掀开了对智能合约语言层进行攻击的问题盖子,让大家意识到了这个可能,对DeFi世界而言,是一次大考,也是一场自我救赎的机会。