任何在EVM运行的代码都必须是非常高效的,以尽可能减少执行智能合约过程中消耗的Gas。同时,智能合约也需要一定的安全性、透明性。
Vyper是一种通用的、实验性的编程语言。Vyper的设计初衷是极大地简化将代码编译为EVM字节码这个过程,以便创建更容易理解的智能合约,使合约对相关各方都更加透明,攻击入口点也更少。
Vyper在逻辑上类似于Solidity,在语法上类似于Python,所以上手十分容易。截止到2018年6月,Vyper仅仅为1.0-beta版本!也许,从现在开始学习Vyper语言,你成为世界级的Vyper开发人员。
十分钟!了解下这份全面的灵活、全新以太坊语言Vyper的学习指南?
编译 | kou
全新的以太坊语言Vyper已经发布,并在社交媒体上引起热议。Vyper是由废弃语言Serpent升级而来,为开发者们提供了可以替代Solidity语言的一种选择。
如果你了解 Python和Solidity,Vyper也不是很难
在这里,我们将详细介绍为何选择“Vyper”的理由:
关键改进1:简易
Vyper不包含大多数程序员所熟悉的结构:类继承、函数重载、操作符重载和递归。从技术上说,这些结构对图灵完整的语言来说都不是必要的,它们通过增加复杂性来表示安全风险。由于这种复杂性,这些结构一个外行人难以理解和审计智能合约,而这些结构在Solidity智能合约中是普遍存在的。
Vyper中不太常见的也不包括的结构有装饰符(它们使编写误导性代码变得太容易)、内联汇编和二进制不动点(通常需要使用二进制不动点进行近似)。
关键改进2:安全
用Vyper开发人员自己的话说,Vyper
“为了增加安全,它会故意禁止或使事情变得更困难。”
因此,Vyper并不是一个Solidity的彻底替代品,而是一种很优秀的、适合在安全至上场景使用的语言,比如处理患者健康元数据的智能合约或分散人工智能的模型梯度。
Vyper代码和语法差异
在设计上,Vyper与Python极为相似,同时在努力实现安全性和简单性目标。因此,总体上,语言与Python是大致相似的,但还是存在一些不同之处的。
执行一个文件
当执行一个Python脚本时,是这样:
python file_name.py
,而编译一个Vyper脚本时,是这样:
vyper file_name.vy.
状态变量
状态变量是永久存储在合约仓库中的值,类型多样,例如:
exampleStateVariable: int256.
映射
Vyper合约中包含合约存储域,例如Token平衡映射:
balance: public(wei_vaue[address])
它是一个定义键和相关值的状态变量。
Vyper映射基本上是初始化的哈希表,所以
“每个可能的键都存在,并被映射到一个字节表示均为默认值零的数值中。”
键数据不是存储在映射中,而是由keccak256散列来查找相关值。
在定义balance时,给出了type public(),后面是映射语法:首先给出wei_value的值类型,然后是方括号中的键(地址)——类似于Python中对数组的处理。
定义
你将注意到Vyper在定义names(比如balance)时使用了冒号,而不是Python中使用的等号,尽管Python 3.6在变量注释中包含了相同的语法:
context = {} # empty dictionary context["a"]: 2 # annotate dictionary variable
这里的冒号语法用于变量注释,冒号用作赋值操作符,只分配一个类型注释。Vyper使用这种语法进行真正的赋值。
整型
Vyper只有两个整型:uint256(对于非负整数)和int128(对于有符号整数)——与之相对的是Solidity的uint8到uint256,int8到int256也是如此(这意味着int类型有64个不同的关键字)。
布尔值、运算符、比较和函数
Vyper中的大多数操作符的语法与Python几乎相同,包括:
true and false booleans; not, and, or, ==, and != operators; <,
<=, ==, !=, >=, and > comparisons; and +, -, *, /, **, and %
arithmetic operators (only for int128)
以及一些类似的内置功能:
len(x) to return the length of an int; floor(x) to round a
decimal down to nearest int; and ceil(x) to round a decimal up to
the nearest int
和一些新的功能:
sha3(x) to return the sha3 hash as bytes 32; concat(x, ...) to
concatenate multiple inputs; slice(x, start=_start, len=_len) to
return slice of _len starting at _start
列表
Vyper中的列表是使用_name: _ValueType[_Integer]格式声明的,而设置值和返回语句的语法与Python相同。
例如:
lst: int128[3] # define a list lst = [1, 2, 3] # set the values
lst[2] = 5 # set a value by index return lst[0] # returns 1
结构体
struct是自定义的用来变量分组并使用struct.argname访问的数据类型,在一定程度上类似于Python中的字典:
struct: { # define the struct
arg1: int128, arg2: decimal
} struct.arg1 = 1 #access arg1 in struct
定义方法
合约方法在Python和Vyper中的定义方式是相同的:
def method():
do_something()
除了Python提供的内容之外,Vyper还包括特定的以太坊装饰器,比如用于合约接受交易的@payable和采用布尔表达式的@assert:
通过def function_name(arg1, arg2, …, argx) -> output: syntax:定义一个函数。与Python不同,Vyper在->之后的def行中显式地定义了输出类型。
构造器函数
构造器函数遵循与Python相同的约定,并在区块链上实例化给定的合约和参数。初始化程序并只执行一次。例如:
@public def __init__(_name: bytes32, _decimals: uint256,
_initialSupply: uint256):
self.name = _name self.decimals = _decimals self.totalSupply =
uint256_mul(_initialSupply, uint256_exp(convert(5, 'uint256'),
_decimals))
与Python中一样,self用于声明实例变量。上面的函数通过@public decorator装饰,以使其具有公共可见性,并允许外部实体调用它。
装饰器@constant用于装饰只读取状态的方法,而@ payable使任何方法都可以通过支付调用。
事件
你可以在索引结构中使用__log__来记录事件,如下:
payment: __log__({amount: uint256, param2: indexed(address)})
tot_payment: uint256 @public def pay():
self.tot_payment += msg.value log.payment(msg.value, msg.sender)
5分钟,手把手教你写一个Vyper智能合约
现在,让我们写几个简单的智能合约。下面的代码片段允许合约接收一个NFT(不可替换的Token),并能够针对该Token发送信息。
@public def safeTransferFrom(_from: address, _to: address,
_tokenId: uint256):
self._validateTransferFrom(_from, _to, _tokenId, msg.sender)
self._doTransfer(_from, _to, _tokenId) if(_to.codesize > 0):
returnValue: bytes[4] = raw_call(_to, 'xf0xb9xe5xba', outsize=4,
gas=msg.gas)
assert returnValue == 'xf0xb9xe5xba'
下面演示了@public decorator,定义一个具有单个参数的函数,该参数是显式给定的类型,以及一个简单的代码主体,它使用assert语句来验证用户是否有权作为“委托”程序的一部分进行投票:
# Give a voter the right to vote on this ballot # This may only
be called by the chairperson @public def give_right_to_vote
(voter: address):
assert msg.sender == self.chairperson # throw if sender is not
chairperson assert not self.voters[voter].voted # throw if voter
has already voted assert self.voters[voter].weight == 0 # throw
if voter's voting weight isn't 0
self.voters[voter].weight = 1 self.voter_count += 1
在讨论了语法和逻辑上的区别之后,Vyper代码显得并不是很难理解。vyper。online通过使用包含选民和提案的结构提供“voting with delegation”项目的完整源代码,以及以下命名恰当的功能:
def delegated(addr: address) -> bool def directly_voted(addr:
address) -> bool def __init__(_proposalNames: bytes32[2]) def
give_right_to_vote(voter: address) def forward_weight
(delegate_with_weight_to_forward: address) def delegate(to:
address) def vote(proposal: int128) def winning_proposal() ->
int128 def winner_name() -> bytes32
与任何编程语言一样,预先规划主要结构(在本例中是函数合约)可以使编程更加容易。与其他语言相比,Vyper、缺少OOP范式。在当前开发阶段,还不能进行外部代码调用。
允许外部代码调用的命令能从以下开发意见中看到:
#外部合约A:
def foo(): constant def bar(): modifying # This contract contract
B: a: A def baz(): a.foo() a.bar()
在最简单的例子中,合约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”
原文链接:
https://blockgeeks.com/guides/understanding-vyper/
最新热文:
透过8个行业,带你了解Web3.0区块链网络时代的颠覆性,你的行业会被颠覆吗?
拐点临近!从反抗到接受,西方的挖矿观点,正在被一家叫做比特大陆的公司所改造,接下来的影响是…
从360首席科学家到区块链创业者,苦钻代码、强迫自己看白皮书,原来这个圈子都是这么努力的 | 人物志
20行代码,带你了解未来颠覆性的工作模式
扫码加入区块链大本营读者群,群满加微信 qk15732632926 入群
了解更多区块链技术及应用内容
敬请关注: