Vyper logo

Vyper

Vyper 是一种面向合约的、类 Python 编程语言,它以 以太坊虚拟机 (EVM) 为目标。

原则和目标

  • 安全性:在 Vyper 中构建安全的智能合约应该既可行又自然。

  • 语言和编译器简单性:语言和编译器实现应该力求简单。

  • 可审计性:Vyper 代码应该最大程度地易于人类阅读。此外,编写误导性代码应该尽可能困难。对读者的简单性比对作者的简单性更重要,对那些对 Vyper(以及对一般编程)经验不足的读者的简单性尤其重要。

因此,Vyper 提供了以下功能

  • 边界和溢出检查:在数组访问和算术运算中。

  • 支持有符号整数和小数定点数字

  • 可判定性:可以计算任何 Vyper 函数调用的燃气消耗的上限。

  • 强类型

  • 小而易于理解的编译器代码

  • 对纯函数的有限支持:任何标记为常量的函数都不得更改状态。

遵循这些原则和目标,Vyper 提供以下功能

  • 修饰符:例如,在 Solidity 中,你可以定义 function foo() mod1 { ... },其中 mod1 可以定义在代码中的其他地方以包含执行之前执行的检查、执行之后执行的检查、一些状态更改,或者可能是其他事情。Vyper 没有这个,因为它很容易编写误导性代码。mod1 看起来太无害了,无法添加任意前提条件、后置条件或状态更改。此外,它鼓励人们编写代码,使执行跳转到整个文件,从而损害可审计性。修饰符的常见用例是在程序执行之前执行单一检查;我们建议简单地将这些检查内联为断言。

  • 类继承:类继承要求人们在多个文件之间跳转以了解程序在做什么,并且要求人们了解优先级规则(如果有冲突,“哪个类的函数 X 是实际使用的那个?”)。因此,它使代码变得过于复杂,难以理解,从而对可审计性产生负面影响。

  • 内联汇编:添加内联汇编将不再可能搜索变量名称以找到读取或修改该变量的所有实例。

  • 函数重载:这会导致大量混乱,无法确定在任何给定时间调用哪个函数。因此,更容易编写误导性代码(foo("hello") 记录“hello”,但 foo("hello", "world") 窃取你的资金)。函数重载的另一个问题是它使代码更难搜索,因为你必须跟踪哪个调用引用哪个函数。

  • 运算符重载:运算符重载使编写误导性代码成为可能。例如,+ 可以被重载,以便它执行第一眼看不见的命令,例如发送用户不想发送的资金。

  • 递归调用:递归调用使得无法为燃气限制设置上限,从而为燃气限制攻击打开了大门。

  • 无限循环:与递归调用类似,无限循环使得无法为燃气限制设置上限,从而为燃气限制攻击打开了大门。

  • 二进制定点:小数定点更好,因为任何以文字形式写成的十进制定点值在代码中都有一个精确的表示,而在二进制定点中,通常需要近似值(例如 (0.2)10 = (0.001100110011…)2,这需要被截断),导致结果不直观,例如,在 Python 中,0.3 + 0.3 + 0.3 + 0.1 != 1。

Vyper 努力成为 Solidity 可以完成的每件事的 100% 替代品;如果认为这样做有利于提高安全性,它将故意禁止某些事情或使某些事情变得更难。