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