以太坊上交易最终都会由EVM进行解析存入数据库,今天就来探讨一下,一笔交易是如何别EVM执行的。我们可以把交易分为三种。(注意,和交易相关的模块很多,交易的生命周期存在于整个以太坊中,我们这次只是分析和EVM相关的部分。)

1、以太币转移,两个账户之间只发生了以太币的转移。

2、合约创建,用户创建智能合约的交易。这类交易的to地址都是空着的。

3、调用合约,用户去调用智能合约中的某个函数,这类交易中data信息包含了需要调用的函数hash值的前4个字节,以及参数。例如基于ERC20的Token转账就是这种类型,前四个字节是0xa9059cbb表示transfer(address _to, uint256 _value),后边跟了两个参数,to地址和交易数量。

最好结合代码理解一下。

https://github.com/ethereum/go-ethereum/blob/461291882edce0ac4a28f64c4e8725b7f57cbeae/core/vm/evm.go

以太币转移

先看一下以太币转移类型的交易,这类交易比较简单,主要函数是由context中的两个函数完成的,CanTransfer CanTransferFunc。

type Context struct {
// 账户余额够不够
CanTransfer CanTransferFunc
// 把eth转移给另外一个账户
Transfer TransferFunc
// 对入参n返回一个hash
GetHash GetHashFunc

// Message information
Origin common.Address // Provides information for ORIGIN
GasPrice *big.Int // Provides information for GASPRICE

// Block information
Coinbase common.Address // Provides information for COINBASE
GasLimit uint64 // Provides information for GASLIMIT
BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY
}

下边具体分析一下怎么实现的。

func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
return db.GetBalance(addr).Cmp(amount) >= 0
}

func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
db.SubBalance(sender, amount)
db.AddBalance(recipient, amount)
}
    怎么样是不是so easy,一眼就看出来了;就是调用数据接口,实现数据库的数据的修改就可以了,对账户的余额进行增加、减少和查询;当然实际情况并非这么简单,之所以看着这么简单,就是我们常说的解耦;后续我会继续分析state和数据库等模块,那会儿我们就会有更清晰的认识。

合约创建\调用合约

合约创建,evm.Create的逻辑和Call方法比较类似的。

call和create几点不同:

1)由于智能合约的创建是没有to地址的,所以SetCallCode方法的参数是从直接有用户传进去的的;而call则不一样,例如你转账erc20代币的时候,to地址是合约地址,所以SetCallCode方法的入参则是从to地址的关联的code中获取的。

2)智能合约创建是一个从无到有的过程,所以statedb中没有合约的地址和账户,所以创建合约地址和账户是必然的过程。

3)call()的input类型为[]byte,和create()的code类型同样为[]byte;这两者从交易的角度是一样的;但是当系统解析到to地址时,才有了分化;to地址不为空,则tx.data被当作contract的input,to地址为空的时候,则tx.data被当作contract的code。

还有后续继续分析一下,交易是如何被解释器具体分析执行的。

以太坊 EVM内交易执行分析(一)的更多相关文章

  1. 以太坊 EVM内交易执行分析(二)

    接着上次的分析,分析一下run方法是如何执行智能合约的.至于以太币的交易,在上一篇中,已经由分析的那两个函数完成了: 合约的运行是从run开始的,go-ethereum/core/vm/evm.go  ...

  2. 以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  3. 以太坊EVM在安全性方面的考虑

    以太坊上用户编写的合约是不可控的,要保证这些合约能够正确执行并且不会影响区块链的稳定,虚拟机需要做安全方面的考虑. 1 在程序执行过程中采取的每个计算步骤都必须提前支付费用, 从而防止DoS攻击.先消 ...

  4. 以太坊中的账户、交易、Gas和区块Gas Limit等概念

    什么是账户 以太坊账户与我们所知的账户概念有一定相似之处,却又有很大的区别,更不同于比特币中UTXO. 账户分两类: - 外部拥有账户(EOA),也就是普通账户 - 合约账户 普通账户 所谓的普通账户 ...

  5. 死磕以太坊源码分析之txpool

    死磕以太坊源码分析之txpool 请结合以下代码阅读:https://github.com/blockchainGuide/ 写文章不易,也希望大家多多指出问题,交个朋友,混个圈子哦 交易池概念原理 ...

  6. 以太坊智能合约虚拟机(EVM)原理与实现

    以太坊 EVM原理与实现 以太坊底层通过EVM模块支持合约的执行与调用,调用时根据合约地址获取到代码,生成环境后载入到EVM中运行.通常智能合约的开发流程是用solidlity编写逻辑代码,再通过编译 ...

  7. 以太坊挖矿源码:clique算法

    上文我们总结了以太坊最主要的共识算法:ethash算法,本文将重点分析以太坊的另一个共识算法:clique. 关键字:clique,共识算法,puppeth,以太坊地址原理,区块校验,认证结点,POA ...

  8. 以太坊开发DApp入门教程——区块链投票系统(一)

    概述 对初学者,首先要了解以太坊开发相关的基本概念.   学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...

  9. EOS与以太坊有哪些区别?

    以太坊是一个专门为开发和运行去中心化应用(DAPP)搭建的智能合约平台:EOS与以太坊类似,同样是基于智能合约和区块链而搭建.但是,从技术和设计理念等方面来看,这两者之间实际上存在明显的区别. 那么E ...

随机推荐

  1. js总结(二):函数、作用域和this

    function Container( properties ) { var objthis = this; for ( var i in properties ) { (function(){ // ...

  2. jquery的ajax和getJson跨域获取json数据

    目前浏览器端跨域访问常用的两种方法有两种: 1.通过jQuery的ajax进行跨域,这其实是采用的jsonp的方式来实现的. jsonp是英文json with padding的缩写.它允许在服务器端 ...

  3. private、protected和public的区别

    private 是完全私有的,只有当前类中的成员能访问到. protected 是受保护的,只有当前类的成员与继承该类的类才能访问. 这两个是访问类中成员权限的限制符.在类外如果想使用类中的成员,只能 ...

  4. 【HDOJ6342】Expression in Memories(模拟)

    题意: 给定一个由0123456789+* ?组成的表达式,其中?可以被改为任意其它字符,问修改问号后是否有方案使得表达式合法 len<=5e2,sumlen<=1e5 思路: #incl ...

  5. poj -1185 炮兵阵地 (经典状压dp)

    http://poj.org/problem?id=1185 参考博客:http://poj.org/problem?id=1185 大神博客已经讲的很清楚了,注意存状态的时候是从1开始的,所以初始化 ...

  6. [Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)

    1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3629  Solved: 1432[Submit][Sta ...

  7. Linux后台运行命令nohub输出pid到文件(转)

    用nohup可以启动一个后台进程.让一个占用前台的程序在后台运行,并静默输出日志到文件: nohup command > logfile.txt & 但是如果需要结束这个进程,一般做法是 ...

  8. DTrace C++ Mysteries Solved 转

      I’ve been using DTrace on Leopard in my recent work, and while it’s a great tool, the C++ support ...

  9. spring mvc get请求也可以接受DTO对象

    spring mvc get请求也可以接受DTO对象,比如:url上面你还是将参数&符号连接起来,并自动封装进一个DTO对象里. 只有@RequestBody注解spring mvc才会从ht ...

  10. iterm2退出时保存会话状态,下次打开恢复

    可以保存已经打开的窗口,本机进入的目录 无法保存ssh连接状态,无法保存ipython状态等 设置方法: 1.这里设置为yes,据说,反复修改一次,重启才起作用,实在有问题就试试 2.这里设置一下 3 ...