以太坊虚拟机(EVM)是一个256位、基于堆栈、全球可访问的图灵机。由于架构与其他虚拟机和物理机的明显不同,EVM需要领域特定语言DSL。
在本文中,我们将研究EVMDSL设计的最新技术,介绍六种语言Solidity、Vyper、Fe、Huff、Yul和ETK。
语言版本
Solidity:0.8.19
Vyper:0.3.7
Fe:0.21.0
Huff:0.3.1
ETK:0.2.1
Yul:0.8.19
阅读本文,需要你对EVM、堆栈和编程有基本的了解。
以太坊虚拟机概述
EVM是一个基于256位堆栈的图灵机。然而,在深入研究它的编译器之前,应该介绍一些功能特性。
由于EVM是「图灵完备」的,它会受到「停机问题」的困扰。简而言之,在程序执行之前,没有办法确定它未来是否会终止。EVM解决这个问题的方法是通过「Gas」计量计算单位,一般来说,这与执行指令所需的物理资源成比例。每个交易的Gas量是有限制的,交易的发起者必须支付与交易消耗的Gas成比例的ETH。这个策略的影响之一是,如果有两个功能上相同的智能合约,消耗更少Gas的合约将被更多采用。这导致协议竞争极端的Gas效率,工程师努力最小化特定任务的Gas消耗。
此外,当调用一个合约时,它会创建一个执行上下文。在这个上下文中,合约有一个堆栈用于操作和处理,一个线性内存实例用于读写,一个本地持久性存储用于合约读写,并且附加到调用的数据「calldata」可以被读取但不能被写入。
Solana智能手机Saga将于4月13日发售:金色财经报道,Solana Labs 子公司 Solana Mobile 宣布,支持 Web3 功能的Saga智能手机将于 4 月 13 日发售。[2023/4/8 13:51:10]
关于内存的一个重要说明是,虽然它的大小没有确定的「上限」,但仍然是有限的。扩展内存的Gas成本是动态:一旦达到阈值,扩展内存的成本将呈二次方增长,也就是说Gas成本与额外内存分配的平方成正比。
合约也可以使用一些不同的指令来调用其他合约。「call」指令将数据和可选的ETH发送到目标合约,然后创建自己的执行上下文,直到目标合约的执行停止。「staticcall」指令与「call」相同,但增加了一个检查,即在静态调用完成之前,断言全局状态的任何部分都未被更新。最后,「delegatecall」指令的行为类似于「call」,只是它会保留先前上下文的一些环境信息。这通常用于外部库和代理合约。
为什么语言设计很重要
在与非典型架构交互时,特定领域语言是必要的。虽然存在诸如LLVM之类的编译器工具链,但是依赖它们来处理智能合约,在程序正确性和计算效率至关重要的情况下,不太理想。
程序正确性非常重要,因为智能合约默认是不可变的,并且鉴于区块链虚拟机的属性,智能合约是金融应用程序的热门选择。虽然存在针对EVM的升级性解决方案,但它充其量只是一个补丁,最坏的情况是任意代码执行漏洞。
计算效率也非常关键,因为最小化计算具有经济优势,但不能以安全为代价。
简而言之,EVMDSL必须平衡程序正确性和Gas效率,在不牺牲太多灵活性的情况下通过做出不同的取舍来实现其中之一。
语言概览
Solana生态衍生品交易平台01主网将于1月27日上线:1月14日,Solana生态去中心化衍生品交易平台01将于1月27日发布主网。01表示将推出具有深度流动性的永续合约,能够支持100个不同的衍生品市场和50种不同的抵押品。同时还将推出第一个有限订单簿模式的Power Perps产品SQUOL。[2022/1/14 8:49:07]
对于每种语言,我们将描述它们的显着特性和设计选择,并包括一个简单的计数功能智能合约。言语流行度是根据DefiLlama上的总锁定价值(TVL)数据确定的。
Solidity
Solidity是一种高级语言,其语法类似于C、Java和Javascript。它是按TVL计算最受欢迎的语言,其TVL是第二名的十倍。为了代码重用,它使用面向对象模式,智能合约被视为类对象,利用了多重继承。编译器采用C++编写,计划在将来迁移到Rust。
可变的合约字段存储在持久性存储中,除非它们的值在编译时或部署时已知。合约内声明的方法可以声明为pure、view、payable,或默认情况下是non-payable但状态可修改。pure方法不会从执行环境中读取数据,也不能读取或写入持久性存储;也就是说,给定相同的输入,pure方法将始终返回相同的输出,它们不会产生副作用。view方法可以从持久性存储或执行环境中读取数据,但它们不能写入持久性存储,也不能创建副作用,例如附加事务日志。payable方法可以读写持久性存储,从执行环境中读取数据,产生副作用,并且可以接收附加在调用中的ETH。non-payable方法与payable方法相同,但具有运行时检查,以断言当前执行上下文中没有附加ETH。
注意:将ETH附加到交易中与支付Gas费用是分开的,附加的ETH由合约接收,可以通过恢复上下文选择接受或拒绝它。
Pyth Network将在Solana主网上线 提供机构级市场数据:跨链预言机项目Pyth Network宣布将在Solana主网上线。开发者将能够在现有和新的DeFi平台和应用程序中集成Pyth实时喂价。除了在Solana高速区块链上构建,Pyth在未来几周内将能够通过Wormhole网络广播市场数据,以便通过以太坊、币安智能链(BSC)和Terra生态系统与DApp进行通信。
据悉,Pyth Network能够提供实时机构级市场数据的跨链预言机。Pyth Network提供加密货币、美国股票、外汇和商品市场的高保真数据流。[2021/8/26 22:37:29]
在合约的范围内声明时,方法可以指定以下四种可见性修饰符:private、internal、public或external。private方法可以通过当前合约内的「jump」指令在内部访问。任何继承的合约都不能直接访问private方法。internal方法也可以通过「jump」指令在内部访问,但继承的合约可以直接使用内部方法。public方法可以通过「call」指令由外部合约访问,创建一个新的执行上下文,并在直接调用方法时通过跳转进行内部访问。public方法也可以通过在方法调用前加上「this.」来在新的执行上下文中从同一合约中访问。external方法只能通过「call」指令访问,无论是来自不同的合约还是在同一合约内,都需要在方法调用前加上「this.」。
注意:「jump」指令操作程序计数器,「call」指令为目标合约的执行期间创建一个新的执行上下文。在可能的情况下,使用「jump」而不是「call」更加节约Gas。
Solidity还提供了三种定义库的方式。第一种是外部库,它是一个无状态的合约,单独部署到链上,在调用合约时动态链接,并通过「delegatecall」指令访问。这是最不常见的方法,因为外部库的工具支持不足,「delegatecall」很昂贵,它必须从持久存储中加载额外的代码,并且需要多个事务进行部署。内部库的定义方式与外部库相同,只是每个方法必须定义为内部方法。在编译时,内部库被嵌入到最终合约中,并且在死代码分析阶段,库中未使用的方法将被删除。第三种方式与内部库类似,但不是在库内定义数据结构和功能,而是在文件级别定义,并且可以直接导入和在最终合约中使用。第三种方法提供了更好的人机交互性,可以使用自定义数据结构,将函数应用于全局作用域中,并一定限程度上将别名运算符应用于某些函数。
韦氏评级:正在审查Solana共识算法:加密评级机构韦氏评级(Weiss Crypto Ratings)在推特发文称:我们正在审查Solana共识算法。这个“领导”业务是什么?似乎很中心化。很遗憾地看到,通过简单地引入中心化化元素来加速进度,项目宣称其优于ETH。这就是为什么我们仍然喜欢ADA。它的团队在发布这些东西之前确实做过研究。我们打Solana开发人员甚至都没有想到过这里存在未知的攻击媒介。[2020/10/9]
编译器提供两个优化通道。第一个是指令级优化器,对最终的字节码执行优化操作。第二个是近期增加使用Yul语言作为编译过程中的中间表示,然后对生成的Yul代码进行优化操作。
为了与合约中的公共和外部方法交互,Solidity规定了一种应用程序二进制接口标准来与其合约交互。目前,SolidityABI被视为EVMDSL的事实标准。指定外部接口的以太坊ERC标准都按照Solidity的ABI规范和风格指南来执行。其他语言也遵循Solidity的ABI规范,很少出现偏差。
Solidity还提供了内联Yul块,允许对EVM指令集进行低级别访问。Yul块包含Yul功能的子集,详细信息请参见Yul部分。这通常用于进行Gas优化,利用高级语法不支持的功能,并自定义存储、内存和calldata。
由于Solidity的流行,开发人员工具非常成熟且设计精良,Foundry是在这方面突出的代表。
以下是用Solidity编写的一个简单合约:
Vyper
Vyper是一种语法类似于Python的高级语言。它几乎是Python的一个子集,只有一些小的不同。它是第二受欢迎的EVMDSL。Vyper针对安全性、可读性、审计能力和Gas效率进行了优化。它不采用面向对象模式、内联汇编,并且不支持代码重用。它的编译器是用Python编写的。
动态 | VanEck及SolidX未因SEC推迟决定而感到吃惊:据CoinDesk报道,美国证券交易委员会(SEC)上周推迟了对VanEck和SolidX的比特币ETF提案做出决定的时间。VanEck数字资产战略总监Gabor Gurbacs表示,此次延迟完全是在“预期”中的,他向CoinDesk重申该公司向市场推出“流动、保险及受到适当监管的物理比特币ETF”的承诺仍然是坚决的。SolidX首席执行官 Dan Gallancy也表达了同样的观点,他也认为SEC上周四的决定对于他对提案的看法没有影响。彭博资深ETF分析师Eric Balchunas也表示,他对批准几率的预测没有改变。在2018年底之前,比特币ETF被批准的概率在5%到10%之间。[2018/9/27]
存储在持久性存储器中的变量是在文件级别声明的。如果它们的值在编译时已知,可以将它们声明为「constant」;如果它们的值在部署时已知,则可以将它们声明为「immutable」;如果它们被标记为public,则最终合约将为该变量公开一个只读函数。常量和不变量的值通过它们的名称在内部访问,但是持久性存储器中的可变量可以通过在名称前面添加「self.」来访问。这对于防止存储变量、函数参数和局部变量之间的命名空间冲突非常有用。
和Solidity类似,Vyper也使用函数属性来表示函数的可见性和可变性。被标记为「@external」的函数可以通过「call」指令从外部合约访问。被标记为「@internal」的函数只能在同一合约中访问,并且必须以「self.」为前缀。被标记为「@pure」的函数不能从执行环境或持久存储中读取数据,也不能写入持久存储或创建任何副作用。被标记为「@view」的函数可以从执行环境或持久存储中读取数据,但不能写入持久存储或创建副作用。被标记为「@payable」的函数可以读取或写入持久存储,创建副作用,接受收ETH。没有声明这个可变性属性的函数默认为non-payable,也就是说,它们和payable函数一样,但不能接收ETH。
Vyper编译器还选择将局部变量存储在内存中而不是堆栈上。这使得合约更加简单和高效,并解决了其他高级语言中常见的「堆栈过深」的问题。但是,这也带来了一些折衷。
另外,由于内存布局必须在编译时知道,因此动态类型的最大容量也必须在编译时知道,这是一个限制。此外,分配大量内存会导致非线性的Gas消耗,正如EVM概述部分中提到的。但是,对于许多用例来说,这个Gas成本可以忽略不计。
虽然Vyper不支持内联汇编,但它提供了更多内置函数,以确保几乎每个Solidity和Yul中的功能在Vyper中也可以实现。通过内置函数可以访问低级位运算、外部调用和代理合约操作,通过编译时提供覆盖文件可以实现自定义存储布局。
Vyper没有丰富的的开发工具套件,但它有更紧密集成的工具,并且也可以插入到Solidity开发工具中。值得关注的Vyper工具包括Titanaboa解释器,它具有许多与EVM和Vyper相关的内置工具,可用于实验和开发,以及Dasy,一种基于Vyper的Lisp,具有编译时代码执行功能。
下面是用Vyper编写的一个简单合约:
Fe
Fe是一种类似Rust的高级语言,目前正在积极开发中,大部分功能尚未推出。它的编译器主要用Rust编写,但使用Yul作为其中间表示形式,依赖于用C++编写的Yul优化器。随着Rust原生后端Sonatina的加入,这一点有望改变。Fe使用模块进行代码共享,因此不使用面向对象的模式,而是通过基于模块的系统重用代码,在模块内声明变量、类型和函数,可以以类似于Rust的方式进行导入。
持久存储变量在合约级别声明,如果没有手动定义的getter函数则不可公开访问。常量可以在文件或模块级别声明,并且可以在合约内部访问。当前不支持不可变的部署时变量。
方法可以在模块级别或合约内声明,默认是pure和private。要使合约方法公开,必须在定义前加上「pub」关键字,这使得它可以在外部访问。要从持久化存储变量中读取,方法的第一个参数必须是「self」,在变量名前加上「self.」,使该方法具有只读访问本地存储变量的权限。要读取和写入持久化存储,第一个参数必须是「mutself」。「mut」关键字表示合约的存储在方法执行期间是可变的。访问环境变量是通过将「Context」参数传递给方法来完成的,通常命名为「ctx」。
函数和自定义类型可以在模块级别声明。默认情况下,模块项都是私有的,除非加上「pub」关键字才能访问。但是,不要和合约级别的「pub」关键字混淆。模块的公共成员只能在最终合约或其他模块内部访问。
Fe暂时不支持内联汇编,相反,指令由编译器内部函数或在编译时解析为指令的特殊函数包装。
Fe遵循Rust的语法和类型系统,支持类型别名、带有子类型的枚举、特征和泛型。目前这方面的支持还有限,但正在进行中。特征可以针对不同类型进行定义和实现,但不支持泛型,也不支持特征约束。枚举支持子类型,并可以在其上实现方法,但不能在外部函数中对其进行编码。尽管Fe的类型系统仍在发展中,但它在为开发人员编写更安全、编译时检查的代码方面显示出了很大的潜力。
下面是用Fe编写的一个简单的合约:
Huff
Huff是一种汇编语言,具有手动堆栈控制和对EVM指令集的最小化抽象。通过「Billions项目组definefn」指令定义,可以接受模板参数以提高灵活性,并指定函数开始和结束时的预期堆栈深度。由于这些函数是内部的,因此无法从外部访问,在内部访问需要使用「jump」指令。
其他控制流程,例如条件语句和循环语句可以使用跳转目标定义。跳转目标是由标识符后跟冒号定义的。可以通过将标识符压入堆栈并执行跳转指令来跳转到这些目标。这在编译时解析为字节码偏移量。
宏由「Billions项目组、Swift和Kotlin到Solidity、Sway和Cairo。学习在这些语言之间无缝切换为软件工程职业提供了无与伦比的灵活性。最后,重要的是要了解每一种语言背后都需要付出大量的工作。没有人是完美的,但无数有才华的人付出了大量努力,为像我们这样的开发者创造安全愉快的体验。
刷推特、看研报累不累?脱水大字报帮你筛选和梳理每日重要市场观点和研报。该内容由几位交易员和分析师志愿者利用业余时间完成,请大家关注点赞给予鼓励.
比特币价格将在今年年底超过16.5万美元,并在2023年基本持平,因为交易者的情绪仍然疲软。 比特币价格可能会在今年年底突破16.5万美元的关键支撑位.
新兴技术会经历周期性的演变,加密货币领域也不例外,其中包括高活跃期和所谓的加密冬季。在我们现在的《加密行业年度报告》所标记的时期内,一个普通的观察者很容易忽视加密行业正在取得的快速进展.
流行的memecoin加密货币狗狗币(DOGE)见证了每日交易量的大幅飙升,超过比特币,据报道总交易量为628.209k。狗狗币价格飙升,上涨1.42%.
我们日常使用的HD钱包或多链钱包,通常只可以通过一个公钥进行存储。这意味着,无论是谁,只要获悉了与该公钥匹配的私钥,就能够支配该公钥链上所持有的资产.
2022年加密行业充满了衰退和动荡,然而在这样的市场行情下,L2的成长曲线一枝独秀,是生态发展爆发的一年,让人很难不重视它.