当我们部署和调用合约的时候,EVM都在做些什么?
如果你开发过以太坊智能合约,想必你应该熟悉这样的操作(此处以remix为例):
编写solidity代码->编译->部署->交互。合约的编写与部署似乎并不是一件很麻烦的操作:编写阶段就不说了,Solidity语言大家都应该会;到了编译阶段,本地的solc编译器会把Solidity代码编译成字节码;而在部署阶段,部署者通过发起一笔特殊交易calldata带上编译后的字节码,等交易上链之后,就完成了合约的部署;而合约交互,就是call合约里的某个函数,等待函数的响应和返回,一切就是这样的简单。
但是正如开车一样,当你踩住油门后,车辆开始前进。然而这看似简单的操作背后是汽油爆燃、活塞往复、数百个齿轮啮合传动、轮胎与地面滚动摩擦的复杂行为。部署和调用合约也是如此,它涉及到EVM的堆栈操作,内存读写,存储访问等一系列底层操作。当部署合约时,EVM把收到的calldata翻译成操作指令,把它们按照给定的长度和参数读入内存;当调用合约时,EVM又根据收到的calldata,通过函数选择器来确定调用哪一段代码,并返回数值。如果只讲理论未免过于枯燥,为了便于讲解,我们这次用ethernaut的一道题目作为例子,详细了解EVM是如何部署和运行合约的,以及如何充当人肉编译器,徒手编写智能合约。
币安完成wXRP集成,并已在以太坊网络上开放充值:据官方公告,币安已完成wXRP集成,并在以太坊(ERC20)上为wXRP开放充值。币安将于稍后在以太坊网络(ERC20)上为wXRP开放提款。[2022/1/17 8:54:49]
这个题目是这样的:我们需要部署一个合约,当我们调用合约**whatIsTheMeaningOfLife()**函数的时候,它需要返回一个数字“42”。看起来很简单对吧?我们分分钟编写完毕:
慢着,题目后面还有个小小的附加要求:“所部署的合约大小不超过10个操作码”。好吧,这个要求的确够“小”,要知道连合约头部的“函数选择器”都不止10个操作码好吧?可是“函数选择器”是什么,为什么会出现在合约里面呢?带着你的疑问,继续向下看。
我们通过./solc--asm--bintarget.sol来看看这个合约的最终编译结果:
608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063650500c114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea26469706673582212206ef8c7b5177952a701b3b46b69cb3ec296f4c54c946692e8ec901f5e43c1e78a64736f6c63430008110033
以太坊创始人Vitalik购买价值50ETH的UBI并进行销毁:10月20日消息,据链上数据,以太坊创始人Vitalik Buterin钱包购买了价值50ETH的UBI并进行销毁。据悉,Proof of Humanity 是引入人性论证的 DAO,使用社交验证的登记系统,公开参与、真正民主的一人一票治理系统,$UBI是Proof of Humanity的代币。[2021/10/20 20:42:02]
这么一大坨十六进制数据,就是上述Solidity程序编译之后的字节码。当我们部署合约时,把这一堆data发给以太坊节点,等广播完成后,合约就部署完毕了。这是solc编译器编译Solidity程序得到的代码,看似杂乱无章的的数据,其实都是和opcodes一一对应的。我们来一段一段地看这些代码:
合约部署代码:
608060405234801561001057600080fd5b5060b68061001f6000396000f3fe
合约运行代码:
6080604052348015600f57600080fd5b506004361060285760003560e01c8063650500c114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fe
以太坊24h链上交易量上升85.74%:金色财经消息,据欧科云链OKLink数据显示,截至下午2时,以太坊24h链上活跃地址数逾63.22万,环比上升15.17%;链上交易量达398.84万ETH,环比上升85.74%;当前以太坊建议Gas费用为99.96Gwei,环比上升42.82%。[2020/12/17 15:31:27]
auxdata:
a26469706673582212206ef8c7b5177952a701b3b46b69cb3ec296f4c54c946692e8ec901f5e43c1e78a64736f6c63430008110033
我们先简单地把这堆代码分为合约的部署代码、运行代码、auxdata三部分,如何理解这三种代码呢?我觉得可以理解为向太空发射卫星:“部署代码”就是运载火箭,而“运行代码”就是卫星。运载火箭只在发射卫星时才起到作用,一旦卫星进入轨道,火箭就废弃了,只留下卫星在太空中与地球通信。部署合约也是如此,在部署合约时,部署代码把一些初始化工作作完之后,就把合约的运行代码送入EVM,只留下运行代码在链上与用户进行交互。
那么言归正传,我们题目要求我们合约运行代码的opcedes不超过10条,那么,这段代码对应的opcodes是多少条呢?答:71条。
V神:以太坊平台和以太资产的发展是一致的:V神在一场播客活动中表示,以太坊一直以来是一个金融应用平台,以太坊平台和以太资产的发展是一致的(所谓以太资产,V神将之定义为以太坊平台上并非其本人或者以太基金会创造的资产)。如果以太坊平台不安全,那么以太资产也无法维持其价值,如果以太资产没有价格,那么以太坊平台很容易遭受攻击,如果有很多人用以太坊平台,那么交易费用将推动以太资产价格上涨。[2020/8/17]
那么问题来了,如何把71条opcodes精简到10条以内呢?这就需要我们对EVM运行智能合约的方式有着一定的了解。如果不了解也没关系,拿起你手边的EVM指令集,我们一起来看看吧:
首先我们要知道,EVM执行代码时是按照自上而下的顺序执行的,代码中没有其他入口点,始终从顶部(也就是第一行opcode)开始执行。。也就是说,当我们部署合约时,EVM会从第一个bytecode开始读起。
所以我们看字节码最前面的部分,也就是它的部署代码:608060405234801561001057600080fd5b5060b68061001f6000396000f3fe
对照EVM指令,我们可以识别出这段代码的含义:
动态 | Blockade Games上线首款兼容以太坊和闪电网络支付的区块链游戏:8月30日,游戏初创公司Blockade Games宣布上线一款兼容以太坊和闪电网络支付的区块链游戏The Ledger of Szabo。游戏中隐藏8个独立的比特币和以太坊谜题,成功解开谜题的玩家可获得1个比特币的奖励,该奖金由The Pineapple Fund提供。[2019/9/2]
然后我们看合约的运行代码:
6080604052348015600f57600080fd5b506004361060285760003560e01c8063650500c114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fe
综合以上可以发现,合约的运行代码的架构是这样的:
初始化操作、函数选择器这些,是solc在编译Solidity程序的时候自动生成的。如果我们砍掉这些复杂的东西,直接把我们想要的核心功能编码上去,不就可以在10条以内opcodes实现既定功能了吗?
通过分析图4的whatIsTheMeaningOfLife()函数调用栈可以得知,让智能合约返回“42”(十六进制0x2a)的关键在于先用mstore指令将0x2a放入Memory,再用return指令将内存里的0x2a返回即可。至于那些函数名称和函数签名,只是高级语言的编译产物,直接用汇编实现的话,我们直接用这段代码读写内存,完全没有必要搞那些花里胡哨:
以上代码相当于构造了一个十分小的合约“运行代码”。前面我们说过,EVM执行代码时是按照自上而下的顺序执行的,代码中没有其他入口点,始终从顶部(也就是第一行opcode)开始执行。而且我们编写的代码并没有函数选择器,也就是说,当外部账户调用该它时,无论传递给它什么样的参数、什么样的函数签名,EVM都只会从它的处开始执行,老老实实地走到,然后return给我们一个0x20.
但这只是运行代码,还记得本文开头说的那三段字节码吗?是的,我们还差一个“运载火箭”,把这段运行代码给发射出去:
部署代码的结构基本没怎么变,之前已有解析,此处就不罗嗦了,唯一的区别是把复制到内存的长度由b6改为0a?:608060405234801561001057600080fd5b50600a8061001f6000396000f3fe
然后把他们拼接到一起,记得部署代码在前、运行代码在后,最后我们把这段代码发射出去就OK了:
你将得到一个超级小巧、只有10个字节、无论传递什么参数都只会返回?42?的“智能合约”
全文完。
关于作者:
https://twitter.com/0xNezha
来源:bress
在2022年中国国际服务贸易交易会首钢园区文旅服务专题展,小朋友在进行VR体验。新华社记者鞠焕宗摄新华社北京10月2日电?题:元宇宙应用解锁中国人文旅生活新方式漫步于艺术馆长廊,一边欣赏来自世界.
1900/1/1 0:00:00原文标题:《WEB3VC排行榜解读:TO5VC有何竞争优势?》原文作者:CODY9月27日,,加密研究组织?GCR?与?Clearblock?联合推出?Web3?VC?排行榜.
1900/1/1 0:00:00作者:北辰2016年,顶级风投USV的JoelMonegro发表了《Fat-protocols》,这是一篇非常经典的crypto论文,对比了互联网和区块链在技术栈上的区别.
1900/1/1 0:00:00从帮助汇集志同道合伙伴的社交类DAOFriendswithBenefits、对版权类内容价格和交易方式拥有极大自主权的媒体类BanklessDAO.
1900/1/1 0:00:00金色财经报道?区块链9月23日讯?Layer1区块链公司Zilliqa宣布推出Web3Console游戏机,这款设备支持基于Zilliqa协议的游戏、Web3钱包和挖矿APP.
1900/1/1 0:00:00原文标题:《LayerZero的多链野心》原文作者:Tiga,W3.Hitchhiker;修订:?Evelyn.
1900/1/1 0:00:00