首页 > 编程语言 >eth evm 源码分析

eth evm 源码分析

时间:2023-01-09 10:46:27浏览次数:45  
标签:evm nil rules gas st 源码 msg eth

ETH 源码分析

入口函数:ransitionDb()

func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
// 首先检查此消息是否满足之前的所有共识规则
// 应用消息。 规则包括这些条款
//
// 1. 消息调用者的随机数是正确的
// 2. 调用方有足够的余额来支付交易费用(gaslimit * gasprice)
// 3. 所需的 gas 数量在区块中是可用的
// 4. 购买的 gas 足以覆盖内部使用
// 5. 计算本征气体时没有溢出
// 6. caller 有足够的余额来支付 **topmost** 调用的资产转移
// 检查条款 1-3,如果一切正确就检测gas  
if err := st.preCheck(); err != nil {
		return nil, err
	}
	if st.evm.Config.Debug {
		st.evm.Config.Tracer.CaptureTxStart(st.initialGas)
		defer func() {
			st.evm.Config.Tracer.CaptureTxEnd(st.gas)
		}()
	}

	var (
		msg              = st.msg
		sender           = vm.AccountRef(msg.From())
		rules            = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil)
		contractCreation = msg.To() == nil
	)

	// Check clauses 4-5, subtract intrinsic gas if everything is correct
    // 检查第 4-5 条,如果一切正确则减去 内部 gas
	gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul)
	if err != nil {
		return nil, err
	}
	if st.gas < gas {
		return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
	}
	st.gas -= gas

	// Check clause 6
// 检查第 6 条
	if msg.Value().Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
		return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex())
	}

	// Execute the preparatory steps for state transition which includes:
	// - prepare accessList(post-berlin)
	// - reset transient storage(eip 1153)
	st.state.Prepare(rules, msg.From(), st.evm.Context.Coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())

	var (
		ret   []byte
		vmerr error // vm errors do not effect consensus and are therefore not assigned to err
	)

当以太坊的交易中to地址为nil时, 意味着部署合约, 那么就会调用evm.Create方法。 否则调用了evm.Call方法。 也就是说分析以太坊虚拟机源码时, 只要从这两个函数作为入口即可。
	if contractCreation {
		ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value)
	} else {
		// Increment the nonce for the next transaction
		st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
		ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
	}

	if !rules.IsLondon {
		// Before EIP-3529: refunds were capped to gasUsed / 2
		st.refundGas(params.RefundQuotient)
	} else {
		// After EIP-3529: refunds are capped to gasUsed / 5
		st.refundGas(params.RefundQuotientEIP3529)
	}
	effectiveTip := st.gasPrice
	if rules.IsLondon {
		effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
	}

	if st.evm.Config.NoBaseFee && st.gasFeeCap.Sign() == 0 && st.gasTipCap.Sign() == 0 {
		// Skip fee payment when NoBaseFee is set and the fee fields
		// are 0. This avoids a negative effectiveTip being applied to
		// the coinbase when simulating calls.
	} else {
		fee := new(big.Int).SetUint64(st.gasUsed())
		fee.Mul(fee, effectiveTip)
		st.state.AddBalance(st.evm.Context.Coinbase, fee)
	}

	return &ExecutionResult{
		UsedGas:    st.gasUsed(),
		Err:        vmerr,
		ReturnData: ret,
	}, nil
}

  

 

标签:evm,nil,rules,gas,st,源码,msg,eth
From: https://www.cnblogs.com/Sunbreaker/p/17036281.html

相关文章

  • prometheus 结合 Alertmanager 实现告警通知
      Alertmanager   prometheus-server触发一条告警的过程:   prometheus--->触发阈值--->超出持续时间--->alertmanager--->分组|抑制|静默--->媒体类型--->邮件|......
  • Input源码解读——从"Show tabs"开始
    Input源码解读——从"Showtabs"开始本文基于AndroidT版本源码,梳理当用户在开发者选项中开启Showtabs功能后显示第点按操作的视觉反馈的原理,来进一步了解AndroidInput......
  • Prometheus基于blackbox_exporter监控
    blackbox_exporter监控组件  blackbox_exporter是Prometheus官方提供的一个exporter,可以监控HTTP、HTTPS,、DNS、TCP、ICMP等目标实例,从而实现对被监控节点进......
  • java弹幕视频网站源码
    简介Java基于ssm的弹幕视频系统,用户注册后可以上传视频进行投稿,也可以浏览视频发送弹幕,在个人中心管理视频、管理弹幕、管理评论等。管理员可以管理视频弹幕评论,查看统计......
  • java食堂库存管理系统源码
    简介Java基于sprinboot开发的食堂库存管理系统,用于统计食堂库存的,包含采购、入库、出库、折损等功能。演示视频https://www.bilibili.com/video/BV1Jf4y1C7vq/?share_s......
  • java基于ssm空气质量检测系统源码网站空气质量监测源码
    简介Java基于ssm的空气质量检测系统,检测设备检测一定范围内的企业空气指数,如果有污染则地图显示红色标记。演示视频https://www.bilibili.com/video/BV1GK4y1W7JB/?shar......
  • Snort IDS 源码安装直播课预告
        本周日上午9:00-9:30,在B站的直播课《从0开始安装SnortIDS》分享课来啦!直播环境UbuntuLinux18.0.4地址:​​https://b23.tv/YhosbC9​​2022年51CTO学堂讲......
  • 自定义prometheus exporter
    packagemainimport( "flag" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/......
  • 基于vue+Element Table封装(纯前端解决方案,附源码)
    (文章目录)前言这个项目是拿来练手的项目,基于VUE+ElementUI,并没有做后端,所以用的是纯前端的解决方案(有更好的办法欢迎提出),主要实现的是对列表数据的查询,筛选,修改这些常......
  • 高级性能01-prometheus常⽤exporter下载地址⼤全
    1.node_exporter下载​​​https://github.com/prometheus/node_exporter/releases​​​2.blackbox_exporter下载​​https://github.com/prometheus/blackbox_exporter/r......