当前位置:首页 > 物联网 > 区块链
[导读] 1.智能合约的源起 区块链技术自比特币诞生之日起便受到了广泛的关注。最初,区块链仅仅作为记录用户交易的底层账本,不支持用户订制其它功能。 比特币为了实现交易,即用户间转账的功能,

1.智能合约的源起

区块链技术自比特币诞生之日起便受到了广泛的关注。最初,区块链仅仅作为记录用户交易的底层账本,不支持用户订制其它功能。

比特币为了实现交易,即用户间转账的功能,设计了一套基于栈的简单脚本语言。这套语言不支持循环,不具备图灵完备性,仅限于比特币客户端内部使用,且只围绕交易这一项功能,一般被称之为“Bitcoin Script”。

如果大家去查看比特币区块链中的每一笔交易记录,那么会发现交易内容其实是一串字节码,这串字节码就是Bitcoin Script。比特币对Bitcoin Script书写的交易代码的格式进行了限制,这种做法保证了交易的合法性与资金的安全性,但牺牲了整个系统的可编程性与灵活性。

一般情况下,一套语言能实现成千上万种功能,如果设计一套语言只是实现了一个功能,未免有些可惜。或许Vitalik Buterin正是发现了区块链中脚本语言的可能性,于是他在以太坊中把语言请到了舞台中央,供用户创建与调用,这也成为了以太坊最具魅力的特性——智能合约。

与比特币的Bitcoin Script对应,以坊中脚本语言名字叫EVM语言(Ethereum Virtual Machine Code)。EVM语言也是基于栈的语言,但它是图灵完备的语言,且以太坊设计了专门的虚拟机EVM来为其提供运行环境,这和Bitcoin Script有明显的区别。

2.智能合约的使用以交易为接口

为了明确系统的功能,以太坊扩充了交易的概念。在比特币中,交易一般指用户之间的转账操作,在以太坊中,交易除了转账,还包括创建或者调用智能合约。因此可以说EVM语言也是为了交易而存在,但它服务的交易的内容广泛得多。

我们先补充一些必要的概念。以太坊中账户分为外部账户与合约账户,外部账户就是用户使用的账户,其中包括了用户的私钥和钱包等重要信息;合约账户用来存放一个智能合约,通常是由外部账户创建的。

用户发送到以太坊区块链上的每一笔交易中都包含几个关键字段:“from”表示交易发起者,“to”表示交易接收者,“value”表示交易金额,“data”表示附带的信息。

上文提及的三种操作的交易格式如下:

1) 普通转账操作:“from A, to B, value C”表示从外部账户A向外部账户B转账,转账金额为C;

2) 智能合约创建操作:“from A, to (空), value C, data D”表示外部账户A创建一个智能合约,向该合约账户里转账C, 合约的代码为D;

3) 智能合约调用操作:“from A, to E, data F”表示外部账户A调用合约账户E的智能合约,本次调用传入的参数为F。

3一笔交易的处理流程

下面我们来分析一笔交易在以太坊区块链中是如何被处理与执行的。

这部分在以太坊的源码中十分清晰,因此我们跟随源码里的函数调用流程来进行说明。以太坊Go版本源码地址:https://github.com/ethereum/go-ethereum。

首先先定位,我们可以从core/blockchain.go中找到执行的core/state_processor.go中Process()方法,在Process()方法中可以找到如下一行代码:

receipt, _,err:= ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)

根据这个函数名字我们知道已经找到了执行交易的入口。

3.1 创建EVM虚拟机

浏览在core/state_processor.go中的ApplyTransacTIon()方法,可发现如下三行关键代码:

context := NewEVMContext(msg, header, bc, author)

vmenv := vm.NewEVM(context, statedb, config, cfg)

_, gas, failed, err := ApplyMessage(vmenv, msg, gp)

第一行是创建新的EVM的执行上下文环境,第二行是创建新的EVM,第三行是用新创建的EVM来处理交易消息。由此可知,每一笔交易在执行之前以太坊都会创建一个EVM虚拟机来负责该交易的执行。

继续浏览core/state_transiTIon.go中的ApplyMessage()方法,发现该方法只有一行代码:

return NewStateTransiTIon(evm, msg, gp).TransiTIonDb()

继续看core/state_transition.go中的TransitionDb()方法,发现方法中有一个重要的分支:

if contractCreation {

ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)

} else {

st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)

ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value)

}

这段代码的意思是先判断是不是创建合约的操作,如果是,则调用Create()方法,如果不是,则调用Call()方法。由此可知,交易的三种操作中,创建合约使用的方法是Create(),而调用合约与转账使用的方法是Call()。

接下来我们分别看一下这两个方法。

3.2 智能合约的创建

先看core/vm/evm.go中的Create()方法。该方法只有两行代码:

contractAddr=crypto.CreateAddress(caller.Address(),evm.StateDB.GetNonce(caller.Address()))

return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr)

第一行是根据外部账户的地址和nonce值计算将要创建的合约账户的地址,这个nonce参数用来记录该外部账户已创建的合约的数目。

第二行是将创建的合约账户地址和其它参数一起传给同文件中的create()方法。

继续看create()方法可看到如下三行代码:

nonce := evm.StateDB.GetNonce(caller.Address())

evm.StateDB.SetNonce(caller.Address(), nonce+1)

contractHash := evm.StateDB.GetCodeHash(contractAddr)

第一行是获取想创建合约的外部账户的nonce值。

第二行是将该nonce的值加一后写回去,第三行是计算合约地址的哈希值确保不会发生地址冲突。

在计算出合约地址后,可看到下面一行代码:

evm.StateDB.CreateAccount(contractAddr)

这行代码是根据合约地址创建出了合约账户。合约账户创建完后,可看到下面一行代码:

evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)

创建者从外部账户向合约账户转账,金额为value。至此,合约账户创建工作完成了。

接下来需要创建合约对象并把合约代码跑起来:

contract:=NewContract(caller, AccountRef(contractAddr), value, gas) contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)

第一行是创建合约对象,第二行是将用户定义的智能合约代码绑定到该合约对象上。

合约对象创建完后,用下面一行代码运行该合约:

ret, err = run(evm, contract, nil)

可能有人会疑惑:创建完合约为什么要运行一遍?

这主要有两方面的原因:其一,系统需保证合约代码是能正确运行的,这样在以后的调用中才不会出错;其二,系统需要通过运行才能计算出消耗的gas数量,进而完成对外部账户的创建合约操作的扣费。其实在create()方法中还有检查栈深度、创建快照、出错后回滚、gas计算等代码,因它们不涉及到本文的主要内容,故略过。

3.3 转账与智能合约的调用

然后我们看core/vm/evm.go中的Call()方法,该方法负责合约调用和转账两种交易操作。

Call()方法中不需要创建新的地址,只需要:

to = AccountRef(addr)

该行代码获取交易接收方的地址。之后可看到下面一行代码:

evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)

交易发起者向交易接收方转账value金额。接下来的代码和Create()相像:

contract := NewContract(caller, to, value, gas)

contract.SetCallCode(&addr,evm.StateDB.GetCodeHash(addr),evm.StateDB.GetCode(addr))

第一行创建合约对象,第二行将接收者地址上的智能合约代码绑定到合约对象上。如果是转账操作,接收者地址上没有代码,因此绑定的代码是空,之后的运行会很快结束。绑定完成后,使用run()方法运行该合约完成调用:

ret, err = run(evm, contract, input)

在Call()方法中同样还有检查栈深度、创建快照、出错会滚、gas计算等代码,留给感兴趣的读者自行阅读。

Create()与Call()中最后执行都调用了core/vm/evm.go中的run()方法,而run()方法中可发现:

return interpreter.Run(contract, input, readOnly)

接下来定位到core/vm/interpreter.go中的Run()方法。该方法是EVM中解释器的运行流程,核心逻辑为循环取出合约的代码,查表解析出具体的操作码,再查表计算出需要消耗的gas数目,然后调用操作码相应的处理函数执行。

核心代码如下:

for atomic.LoadInt32(&in.evm.abort) == 0 {

op = contract.GetOp(pc)

operation := in.cfg.JumpTable[op]

cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize)

res, err := operation.execute(&pc, in, contract, mem, stack)

}

至此,一笔交易的运行就结束了。

4. 结语

综上所述,我们能了解到以太坊设计的三种交易背后能给予用户极大的自由度,也充分发挥了EVM语言及其虚拟机的功能。

用户通过Solidity等语言编写智能合约,然后编译成EVM语言,再打包成交易的格式发送到区块链上运行。以太坊得益于这种模式带来的可编程的特性,引领区块链技术进入了2.0时代。

然而,现在智能合约由于EVM的栈深度与gas消耗的限制,多数都是简单且袖珍的程序。即使现在这样的程序已经足够满足需求,但未来必将面临更多更加复杂化的交易场景。

如何去应对这些场景,需要广大开发者们继续努力。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭