Vyper 一种类python的以太坊开发语言

资料仓库  收藏
0 / 1016

Vyper是一种全新的以太坊开发语言。在vyper之前,编写智能合约最常用的语言是solidity。相较于solidity,vyper是一种更简单、更安全、更易审核的智能合约语言。它的出现并不是为了完全替代solidity,它砍掉了很多复杂的、易出错的功能(比如:修饰符、类继承、函数重载、无限长循环等 ),所以当你需要编写很复杂的应用程序时,还需要使用solidity。但是对于绝大多数应用程序,尤其是和金钱相关对安全性更为重视的程序时,更推荐使用vyper进行编写。

语言特点

  • Security
  • Language and compiler simplicity
  • Auditability

一、它在逻辑上类似于Solidity,在语法上类似于Python

Vyper是被丢弃的Serpent语言的升级版,在逻辑上类似于Solidity,在语法上类似于Python 可以说95%类似。与Solidity一样,Vyper会编译到以太坊虚拟机(EVM)字节码。

二、Vyper最显著的两大特点是:安全和简单

以太坊是一个价值网络,构建于以太坊之上的应用大多需要进行价值的转移,因此安全性尤其重要。像The DAO事件、Parity的多重签名电子钱包漏洞等,给以太坊的生态发展带来了严重的伤害,也对用户的财产造成了重大的损失。最近的一项研究发现,超过34000个智能合约存在安全漏洞。Vyper有在以太坊的未来扮演重要角色的潜力。

安全是硬道理,谁都希望自己钱包里的钱是安全的。一个不能保证安全的网络是无法让用户每天晚上安稳睡觉的,随时都要提心吊胆,担心会被黑客攻击。这样的网络自然无法对更多的潜在用户形成吸引力,甚至会造成已有用户的大量流失。

而很多的合约漏洞,或者说不安全的因素,都是来自于复杂。规则越简单,越容易理解,系统就越强壮。

Vyper就是基于这样的原则,摒弃了很多Solidity语法中的类继承,函数重载,运算符重载、递归、内联汇编等特性,把所有不必要的花哨的元素都去掉,让开发者的花式炫技无处安放,但是让审计者的工作大大简化。从而更容易地理解智能合约、减少攻击点和提高透明度。

用Vyper开发者自己的话说,Vyper为了提高安全性的目标,它会故意禁止一些事情或者让事情变得更难。

这里的更难是针对开发者来说的,比如说用递归可以把一个原本需要用10行代码解决的事情,仅用4-5行代码就解决掉。但是为了安全以及容易审计,Vyper牺牲了开发者的便利性,禁用递归,采用更原始但是更安全的办法来实现。虽然少了一些所谓的高级功能,这种做法却使得Vyper的学习曲线大幅平缓,代码阅读或审计更加轻松易容。而且为了钱安全的存储,开发者应该也不会有太多怨言。

因此,相比较于语法类似Javascript的Solidity,Vype或许对开发者来说失去了很多灵活性,会让开发者觉得受到束缚,但是对于审计人员等阅读者来说,却是大大降低了难度。

这体现了安全性至上、读者的简单性比作者的简单性更重要的设计原则,所以Vyper是一门更加安全、简单的以太坊语言,更适合于处理电子病历、金融交易等安全性要求极高的业务。

三、Vyper如何入门

前面说了那么多,都是在介绍Vyper的特点,但是学习并使用这门语言呢?这就需要有一定的Solidity和Python基础了。Vyper对以太坊的各种操作都跟Solidity一样,而语法与Python几乎一样。可以说Vyper具有了Python的形和Solidity的神,了解Solidity和Python,就可以毫无难度的掌握Vyper。

当然,掌握一门语言的最有效的途径就是动手做项目。

在线编译

安装Vyper本地环境不是必须的,推荐使用在线编译器编译和部署合约,方便且快捷,易于上手。
官方推荐的vyper在线编译网站:vyper.online
我在使用的时候这个网站上不去了,不过没关系,solidity在线编译器 Remix 已经支持Vyper合约的编译和部署,你所需要做的就是添加一个Vyper插件即可。

安装Vyper环境

linux下:
pip install vyper

Successfully installed asttokens-2.0.4 vyper-0.2.16

或者通过源码安装

下载vyper源码

git clone https://github.com/vyperlang/vyper.git
cd vyper
make
make dev-deps
make test
安装完成后可以尝试去编译一个示例合约

vyper -f abi_python crowdfund.vy

[{"stateMutability": "nonpayable", "type": "constructor", "inputs": [{"name": "_beneficiary", "type": "address"}, {"name": "_goal", "type": "uint256"}, {"name": "_timelimit", "type": "uint256"}], "outputs": []}, {"stateMutability": "payable", "type": "function", "name": "participate", "inputs": [], "outputs": [], "gas": 109976}, {"stateMutability": "nonpayable", "type": "function", "name": "finalize", "inputs": [], "outputs": [], "gas": 31822}, {"stateMutability": "nonpayable", "type": "function", "name": "refund", "inputs": [], "outputs": [], "gas": 3648290}, {"stateMutability": "view", "type": "function", "name": "deadline", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2478}, {"stateMutability": "view", "type": "function", "name": "goal", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2508}, {"stateMutability": "view", "type": "function", "name": "timelimit", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "gas": 2538}]

vyper examples/crowdfund.vy

0x606061030661014039602061030660c03960c05160a01c610301576101405160025542610180518181830110610301578082019050905060035561018051600655610160516004556102e956600436101561000d57610292565b600035601c5260005163d11711a28114156100b5576003544210610070576308c379a0610140526020610160526016610180527f646561646c696e65206e6f74206d6574202879657429000000000000000000006101a05261018050606461015cfd5b6001546101405260006101405160e05260c052604060c0203381553460018201555061014051600180820180607f1d8160801d14156102985780905090509050600155005b3461029857634bb278f381141561016a57600354421015610115576308c379a0610140526020610160526013610180527f646561646c696e652068617320706173736564000000000000000000000000006101a05261018050606461015cfd5b600454471015610164576308c379a0610140526020610160526019610180527f74686520676f616c20686173206265656e2072656163686564000000000000006101a05261018050606461015cfd5b600254ff005b63590e1ae381141561024857600354421061018957600454471061018c565b60005b15610298576005546101405261016061014051601e818352015b60015461016051126101be5760015460055560006000f35b6000600060006000600160006101605160e05260c052604060c020015460006101605160e05260c052604060c020546000f1156102985760006101605160e05260c052604060c0206000815560006001820155505b81516001018083528114156101a6575b505061014051601e80820180607f1d8160801d14156102985780905090509050600555005b6329dcb0cf8114156102605760035460005260206000f35b63401938838114156102785760045460005260206000f35b6387963f8e8114156102905760065460005260206000f35b505b60006000fd5b600080fd5b61004c6102e90361004c60003961004c6102e9036000f35b600080fd

关键改进1:简易

Vyper不包含大多数程序员所熟悉的结构:类继承、函数重载、操作符重载和递归。从技术上说,这些结构对图灵完整的语言来说都不是必要的,它们通过增加复杂性来表示安全风险。由于这种复杂性,这些结构一个外行人难以理解和审计智能合约,而这些结构在Solidity智能合约中是普遍存在的。

Vyper中不太常见的也不包括的结构有装饰符(它们使编写误导性代码变得太容易)、内联汇编二进制不动点(通常需要使用二进制不动点进行近似)。

关键改进2:安全

用Vyper开发人员自己的话说,Vyper

“为了增加安全,它会故意禁止或使事情变得更困难。”

因此,Vyper并不是一个Solidity的彻底替代品,而是一种很优秀的、适合在安全至上场景使用的语言,比如处理患者健康元数据的智能合约或分散人工智能的模型梯度。

Vyper代码和语法差异

在设计上,Vyper与Python极为相似,同时在努力实现安全性简单性目标。因此,总体上,语言与Python是大致相似的,但还是存在一些不同之处的。

执行一个文件

当执行一个Python脚本时,是这样:

,而编译一个Vyper脚本时,是这样:

状态变量

状态变量是永久存储在合约仓库中的值,类型多样,例如:

映射

Vyper合约中包含合约存储域,例如Token平衡映射:

它是一个定义键和相关值的状态变量。

Vyper映射基本上是初始化的哈希表,所以

“每个可能的键都存在,并被映射到一个字节表示均为默认值零的数值中。”

键数据不是存储在映射中,而是由keccak256散列来查找相关值。

在定义balance时,给出了type public(),后面是映射语法:首先给出wei_value的值类型,然后是方括号中的键(地址)——类似于Python中对数组的处理。

定义

你将注意到Vyper在定义names(比如balance)时使用了冒号,而不是Python中使用的等号,尽管Python 3.6在变量注释中包含了相同的语法:

这里的冒号语法用于变量注释,冒号用作赋值操作符,只分配一个类型注释。Vyper使用这种语法进行真正的赋值。

整型

Vyper只有两个整型:uint256(对于非负整数)和int128(对于有符号整数)——与之相对的是Solidity的uint8到uint256,int8到int256也是如此(这意味着int类型有64个不同的关键字)。

布尔值、运算符、比较和函数

Vyper中的大多数操作符的语法与Python几乎相同,包括:

以及一些类似的内置功能:

和一些新的功能:

列表

Vyper中的列表是使用_name: _ValueType[_Integer]格式声明的,而设置值和返回语句的语法与Python相同。

例如:

结构体

struct是自定义的用来变量分组并使用struct.argname访问的数据类型,在一定程度上类似于Python中的字典:

定义方法

合约方法在Python和Vyper中的定义方式是相同的:

除了Python提供的内容之外,Vyper还包括特定的以太坊装饰器,比如用于合约接受交易的@payable和采用布尔表达式的@assert:

通过def function_name(arg1, arg2, …, argx)->output: syntax:定义一个函数。与Python不同,Vyper在->之后的def行中显式地定义了输出类型。

构造器函数

构造器函数遵循与Python相同的约定,并在区块链上实例化给定的合约和参数。初始化程序并只执行一次。例如:

与Python中一样,self用于声明实例变量。上面的函数通过@public decorator装饰,以使其具有公共可见性,并允许外部实体调用它。

装饰器@constant用于装饰只读取状态的方法,而@ payable使任何方法都可以通过支付调用。

事件

你可以在索引结构中使用__log__来记录事件,如下:

5分钟,手把手教你写一个Vyper智能合约

现在,让我们写几个简单的智能合约。下面的代码片段允许合约接收一个NFT(不可替换的Token),并能够针对该Token发送信息。

下面演示了@public decorator,定义一个具有单个参数的函数,该参数是显式给定的类型,以及一个简单的代码主体,它使用assert语句来验证用户是否有权作为“委托”程序的一部分进行投票:

在讨论了语法和逻辑上的区别之后,Vyper代码显得并不是很难理解。vyper。online通过使用包含选民和提案的结构提供**“voting with delegation”**项目的完整源代码,以及以下命名恰当的功能:

与任何编程语言一样,预先规划主要结构(在本例中是函数合约)可以使编程更加容易。与其他语言相比,Vyper、缺少OOP范式。在当前开发阶段,还不能进行外部代码调用。

允许外部代码调用的命令能从以下开发意见中看到:

#外部合约A:

在最简单的例子中,合约B调用合约A,包括A中的方法。

运行Vyper

如果要继续编写代码,就访问vyper.online,在“Source Code”标签下编写代码示例,准备好后单击“Compile”。

Vyper实现和测试执行最常用的客户机(尽管仍处于初期测试版)是Py-EVM,它最初是由Vitalik自己开发的,它允许用户添加操作码或修改现有的操作码,而无需更改核心库,与典型的客户机相比,它支持更大的模块化和可扩展性。

要获得Py-EVM,只需使用pip install Py-EVM =0.2.0a16。

部署Vyper合约

虽然Py-EVM目前处于初期测试阶段,并且可能很难启动和运行,但是有两个更简单的方法可以将Vyper合约部署到公共测试网:

将 vyper.online生成的字节码粘贴到Mist或者Geth中

使用myetherwallet合约菜单在当前浏览器中部署

将来,Vyper将与Populus集成,这允许你轻松部署Vyper合约

为了简单起见,我们将使用、Mist(与基于终端的Geth相对的Geth上的新UI)部署合约。由于Vyper编译为与Solidity相同的字节码,因此我们不需要任何Vyper特定的客户端,并且可以按照以下步骤进行:

进入vyper.online,在预先写入的投票“Source Code”下,点击“Compile”;

在“Bytecode”标签下复制所有内容;

如果你之前还没有安装Mist,需要在你的操作系统中安装Mist;

允许节点下载和同步(这是自动发生的);

在Mist设置中选择“USE THE TEST NETWORK”;

创建一个密码(记住它…);

输入合约;

在Mist界面中选择“Contracts”;

选择“DEPLOY NEW CONTRACT”;

转到“CONTRACT BYTE CODE”标签;

将你从vyper.online复制的字节码粘贴进去。

部署合约

选择“DEPLOY”并输入密码;

确认Vyper合约已经部署好;

在Mist中进入“Wallets”标签;

向下滚动到“Latest Transactions”;

你就看到了我们刚刚部署的合约!

OK,一个简单的Vyper智能合约已经完成啦!

本指南提供了一份完整的Vyper逻辑上和语法上的介绍,允许以太坊爱好者进行编程和部署合约。通过学习Vyper指南,你也可以为Vyper及其文档的开发做出贡献,并通过在Vyper.online上编写代码做到持续学习。

Vyper并不是要取代Solidity,但正如一项研究发现的,以太坊上有超过34000份易受攻击的智能合约,这对更强安全性的需求比以往任何时候都大,这就让Vyper在以太坊上拥有一个非常好的应用前景。

来,抓紧入手Vyper吧!

Vyper并不支持以下功能

不过,值得注意的是,由于Vyper仍处在实验开发阶段,虽然很强大,但不包含以下功能。

修改器堆栈:在Solidity下,你可以很轻易地使用function foo() mod1 { ... }语句,其中,mod1可以对任何检查进行定义,检查可以在执行前和执行后运行。Vyper并不包含这一功能,因为mod1太容易被无用。

类继承:类继承需要开发者在逻辑冲突时同时参考多个文件才能明白当前谁在优先执行。因此,这对代码测试十分不友好。

内联汇编:内联汇编无法实现特定变量的搜索。

函数重载:方法重载会引起混淆,有时候不容易搞清楚调用的是哪个函数。

运算符重载:运算符重载会经常引起写入错误。

最后,Vyper确实是一个不错的语言,开发者在学习过程中,除了官方文档、GitHub等全面的学习资源之外,以下资源也具有一定的学习价值,仅供大家参考。

Vyper’s Community Gitter

Vyper Tools and Resources

“Ethereum Book” pages on Vyper

Study: “Finding The Greedy, Prodigal, and Suicidal Contracts at Scale”

“Step-by-Step Guide: Getting Started with Ethereum Mist Wallet”

Testing and Deploying Vyper Contracts

“Build Your First Ethereum Smart Contract with Solidity — Tutorial”

Vyper的Github网址: https://github.com/ethereum/vyper

https://github.com/vyperlang/vyper

Vyper的在线编译器: https://vyper.online/#