Evm升级最新Yolo功能概览和问题定位

Uniswap部署依赖Istanbul中的chainid,从君士坦丁堡升级到YoloV1最新版本,就可以在链上正常部署。本文讲粗略讲一下升级涉及功能和问题的定位解决。

**Istanbul升级** * `1344中`添加`chainid`的`opcode`获取链的当前chainid * `1884`中添加`balance`的`opcede`查询调用方余额 * `2200`中状态加载和存储的`gas`费增加更新 **YoloV1升级** * `2315`的`subroutines`,包含如下opcode `BEGINSUB`,`RETURNSUB`,`JUMPSUB` **功能点** 整合`gas`各个版本的升级,删除了`params`的`gas_table` 不同版本更新`opcode`的`gas`费用,提高了状态加载和存储的费用如`SLOAD` `BALANCE` `EXTCODEHASH` 常量`gas`费从`opcode`对应的函数中移除,赋值给`constantGas` 操作数`big.Int`类型为`uint256.Int`,提高`25%`执行效率 整合`内存拷贝`和`内存创建`的`gas计算`和`溢出检查` 减少`zk`使用的`bn256` gas费,添加`blake2F`和`bls预编译合约` 增加`ReturnStack`可返回`错误结果`方便`debug` > `SLOAD` `BALANCE` `EXTCODEHASH` 存储访问操作码,16年因为`EXTCODESIZE`被dos攻击,状态读取和存储异常耗时,需要提高gas费。 ### 错误输出 之前合约执行错误只会输出`execution reverted`,现在可以打印哪里报错 “` execution reverted: TransferHelper: TRANSFER_FROM_FAILED “` 在`sol`里面找到如下报错,为对方`Approve`金额较低导致。 “` require(success && (data.length == 0 || abi.decode(data, (bool))), ‘TransferHelper: TRANSFER_FROM_FAILED’); “` ### 容易出错的地方 * `opcode`中`gas`费计算错误 * `constantGas` 常量已从`gas_table`中移除,直接在代码中根据解析器分支使用不同的`opcode gas`费 * `dynamicGas` 计算在内存占用费用 ### Evm测试TraceLog * 跟旧版本是否兼容,需要重新同步旧的历史块 * 功能是否完善,Uniswap应用是否可部署成功 ### 合约解析器 下面规定了不同的分叉使用的`EVMInterpreter`解析器是不一样的。 “` // NewEVMInterpreter returns a new instance of the Interpreter. func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // We use the STOP instruction whether to see // the jump table was initialised. If it was not // we’ll set the default jump table. if cfg.JumpTable[STOP] == nil { var jt JumpTable switch { case evm.chainRules.IsYoloV1: jt = yoloV1InstructionSet case evm.chainRules.IsIstanbul: jt = istanbulInstructionSet case evm.chainRules.IsConstantinople: jt = constantinopleInstructionSet case evm.chainRules.IsByzantium: jt = byzantiumInstructionSet default: jt = frontierInstructionSet } cfg.JumpTable = jt } return &EVMInterpreter{ evm: evm, cfg: cfg, } } “` ### 预编译合约 不同的升级使用的`PrecompiledContract`预编译合约也不一样的,预编译合约主要是处理一些复杂的数学计算,这类计算evm执行起来较慢,所以以预编译合约的形式加入到evm里面,合约执行的过程不是汇编执行而是具体代码 “` func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { var precompiles map[common.Address]PrecompiledContract switch { case evm.chainRules.IsYoloV1: precompiles = PrecompiledContractsYoloV1 case evm.chainRules.IsIstanbul: precompiles = PrecompiledContractsIstanbul case evm.chainRules.IsByzantium: precompiles = PrecompiledContractsByzantium default: precompiles = PrecompiledContractsHomestead } p, ok := precompiles[addr] return p, ok } “` 这是升级中加的一些预编译合约,很多是支持零知识证明的,椭圆配对曲线称为BLS12-381,为过渡eth2.0提供基础,该预编译使精简客户端成为可能。 “` // PrecompiledContractsYoloV1 contains the default set of pre-compiled Ethereum // contracts used in the Yolo v1 test release. var PrecompiledContractsYoloV1 = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{5}): &bigModExp{}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{10}): &bls12381G1Add{}, common.BytesToAddress([]byte{11}): &bls12381G1Mul{}, common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{}, common.BytesToAddress([]byte{13}): &bls12381G2Add{}, common.BytesToAddress([]byte{14}): &bls12381G2Mul{}, common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{}, common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, } “` ### 新旧版本问题 合约执行中如果计算的`gas`不一致,区块验证就会报错。这个问题相当严重 #### 问题查找 抓取合约执行过程的`Trace log`分析不同点,截取了如下日志。 “` {“pc”:2373,”op”:84,”gas”:”0xeddb6″,”gasCost”:”0x320″,”memory”:”0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x1bf73a65″,”0x181″,”0x2de96ad91d62a796c4ba80e0a862520f9c8a7805″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x0″,”0x47f37265329d36000″,”0x1″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x1137c4082672bb033743321bcc426da68e2052bc996d994df96a0e1cd48b5b60″],”returnStack”:[],”returnData”:null,”depth”:1,”refund”:0,”opName”:”SLOAD”,”error”:””} {“pc”:2374,”op”:144,”gas”:”0xeda96″,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x1bf73a65″,”0x181″,”0x2de96ad91d62a796c4ba80e0a862520f9c8a7805″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x0″,”0x47f37265329d36000″,”0x1″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x1″],”returnStack”:[],”returnData”:null,”depth”:1,”refund”:0,”opName”:”SWAP1″,”error”:””} “` 将上面的`0xeddb6`和`0xeda96`相减是`800`十六进制为`0x320` “` {“pc”:2373,”op”:84,”gas”:”0xeddb6″,”gasCost”:”0xc8″,”memory”:”0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x1bf73a65″,”0x181″,”0x2de96ad91d62a796c4ba80e0a862520f9c8a7805″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x0″,”0x47f37265329d36000″,”0x1″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x1137c4082672bb033743321bcc426da68e2052bc996d994df96a0e1cd48b5b60″],”depth”:1,”refund”:0,”opName”:”SLOAD”,”error”:””} {“pc”:2374,”op”:144,”gas”:”0xedcee”,”gasCost”:”0xc8″,”memory”:”0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x1bf73a65″,”0x181″,”0x2de96ad91d62a796c4ba80e0a862520f9c8a7805″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x0″,”0x47f37265329d36000″,”0x1″,”0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1″,”0x0″,”0x1″],”depth”:1,”refund”:0,”opName”:”SWAP1″,”error”:””} “` 这个是升级前的日志,相减得`200`十六进制为`0xc8` 查询`84`的`opcode`是`0x54` `SLOAD`在`Istanbul`后`SloadGasEIP1884`调节到了`800`,这个由于分叉高度设置太低导致使用`yoloV1InstructionSet`解析器,其实是没问题的,调节`YoloV1Block`高度即可 “` “YOLOv1”: { ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(0), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), YoloV1Block: big.NewInt(0), }, “` ### 功能不完善问题 eth部署合约正确的指令流程 “` {“pc”:23,”op”:96,”gas”:”0x278abc”,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”PUSH1″,”error”:””} {“pc”:25,”op”:81,”gas”:”0x278ab9″,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x40″],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”MLOAD”,”error”:””} {“pc”:26,”op”:70,”gas”:”0x278ab6″,”gasCost”:”0x2″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x80″],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”CHAINID”,”error”:””} {“pc”:27,”op”:144,”gas”:”0x278ab4″,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x80″,”0x539″],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”SWAP1″,”error”:””} “` 升级后evm的流程 “` {“pc”:23,”op”:96,”gas”:”0x5c54030″,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”PUSH1″,”error”:””} {“pc”:25,”op”:81,”gas”:”0x5c5402d”,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x40″],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”MLOAD”,”error”:””} {“pc”:26,”op”:70,”gas”:”0x5c5402a”,”gasCost”:”0x3″,”memory”:”0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080″,”memSize”:96,”stack”:[“0x80″],”returnStack”:[],”returnData”:null,”depth”:3,”refund”:0,”opName”:”CHAINID”,”error”:”invalid opcode: CHAINID”} {“pc”:1507,”op”:96,”gas”:”0x17740a”,”gasCost”:”0x3″,”memory”:””,”memSize”:11904,”stack”:[“0xc9c65396″,”0x95″,”0x537e697c7ab75a26f9ecf0ce810e3154dfcaaf44″,”0x3a220f351252089d385b29beca14e27f204c296a”,”0x0″,”0x3a220f351252089d385b29beca14e27f204c296a”,”0x537e697c7ab75a26f9ecf0ce810e3154dfcaaf44″,”0x80″,”0xb81ff3c7140db37a05a85068ea614a23c0d72ec176588a2f45c5dd53550b6c88″,”0x0″],”returnStack”:[],”returnData”:null,”depth”:2,”refund”:0,”opName”:”PUSH1″,”error”:””} “` 从`pc`指针可以看`操作码70`后结果开始不一样了,`70`对于的`opcode`是`CHAINID`,而`CHAINID`是`Istanbul`后加入的,由于`IstanbulBlock`高度设置较高,功能为开启,所以跳转不一样。 `trace log`也有报错`”opName”:”CHAINID”,”error”:”invalid opcode: CHAINID”`。 #### 总结 两个问题都是`YoloV1Block`未正确设置导致加载的`EVMInterpreter`解析器不对导致

Istanbul升级

  • 1344中添加chainidopcode获取链的当前chainid
  • 1884中添加balanceopcede查询调用方余额
  • 2200中状态加载和存储的gas费增加更新

YoloV1升级

  • 2315subroutines,包含如下opcode BEGINSUB,RETURNSUB,JUMPSUB

功能点

整合gas各个版本的升级,删除了paramsgas_table 不同版本更新opcodegas费用,提高了状态加载和存储的费用如SLOAD BALANCE EXTCODEHASH 常量gas费从opcode对应的函数中移除,赋值给constantGas 操作数big.Int类型为uint256.Int,提高25%执行效率 整合内存拷贝内存创建gas计算溢出检查 减少zk使用的bn256 gas费,添加blake2Fbls预编译合约 增加ReturnStack可返回错误结果方便debug

SLOAD BALANCE EXTCODEHASH 存储访问操作码,16年因为EXTCODESIZE被dos攻击,状态读取和存储异常耗时,需要提高gas费。

错误输出

之前合约执行错误只会输出execution reverted,现在可以打印哪里报错

execution reverted: TransferHelper: TRANSFER_FROM_FAILED

sol里面找到如下报错,为对方Approve金额较低导致。

require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');

容易出错的地方

  • opcodegas费计算错误
  • constantGas 常量已从gas_table中移除,直接在代码中根据解析器分支使用不同的opcode gas
  • dynamicGas 计算在内存占用费用

Evm测试TraceLog

  • 跟旧版本是否兼容,需要重新同步旧的历史块
  • 功能是否完善,Uniswap应用是否可部署成功

合约解析器

下面规定了不同的分叉使用的EVMInterpreter解析器是不一样的。

// NewEVMInterpreter returns a new instance of the Interpreter.
func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
    // We use the STOP instruction whether to see
    // the jump table was initialised. If it was not
    // we'll set the default jump table.
    if cfg.JumpTable[STOP] == nil {
        var jt JumpTable
        switch {
        case evm.chainRules.IsYoloV1:
            jt = yoloV1InstructionSet
        case evm.chainRules.IsIstanbul:
            jt = istanbulInstructionSet
        case evm.chainRules.IsConstantinople:
            jt = constantinopleInstructionSet
        case evm.chainRules.IsByzantium:
            jt = byzantiumInstructionSet
        default:
            jt = frontierInstructionSet
        }
        cfg.JumpTable = jt
    }
    return &EVMInterpreter{
        evm: evm,
        cfg: cfg,
    }
}

预编译合约

不同的升级使用的PrecompiledContract预编译合约也不一样的,预编译合约主要是处理一些复杂的数学计算,这类计算evm执行起来较慢,所以以预编译合约的形式加入到evm里面,合约执行的过程不是汇编执行而是具体代码

func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
    var precompiles map[common.Address]PrecompiledContract
    switch {
    case evm.chainRules.IsYoloV1:
        precompiles = PrecompiledContractsYoloV1
    case evm.chainRules.IsIstanbul:
        precompiles = PrecompiledContractsIstanbul
    case evm.chainRules.IsByzantium:
        precompiles = PrecompiledContractsByzantium
    default:
        precompiles = PrecompiledContractsHomestead
    }
    p, ok := precompiles[addr]
    return p, ok
}

这是升级中加的一些预编译合约,很多是支持零知识证明的,椭圆配对曲线称为BLS12-381,为过渡eth2.0提供基础,该预编译使精简客户端成为可能。

// PrecompiledContractsYoloV1 contains the default set of pre-compiled Ethereum
// contracts used in the Yolo v1 test release.
var PrecompiledContractsYoloV1 = map[common.Address]PrecompiledContract{
    common.BytesToAddress([]byte{1}):  &ecrecover{},
    common.BytesToAddress([]byte{2}):  &sha256hash{},
    common.BytesToAddress([]byte{3}):  &ripemd160hash{},
    common.BytesToAddress([]byte{4}):  &dataCopy{},
    common.BytesToAddress([]byte{5}):  &bigModExp{},
    common.BytesToAddress([]byte{6}):  &bn256AddIstanbul{},
    common.BytesToAddress([]byte{7}):  &bn256ScalarMulIstanbul{},
    common.BytesToAddress([]byte{8}):  &bn256PairingIstanbul{},
    common.BytesToAddress([]byte{9}):  &blake2F{},
    common.BytesToAddress([]byte{10}): &bls12381G1Add{},
    common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
    common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
    common.BytesToAddress([]byte{13}): &bls12381G2Add{},
    common.BytesToAddress([]byte{14}): &bls12381G2Mul{},
    common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
    common.BytesToAddress([]byte{16}): &bls12381Pairing{},
    common.BytesToAddress([]byte{17}): &bls12381MapG1{},
    common.BytesToAddress([]byte{18}): &bls12381MapG2{},
}

新旧版本问题

合约执行中如果计算的gas不一致,区块验证就会报错。这个问题相当严重

问题查找

抓取合约执行过程的Trace log分析不同点,截取了如下日志。

{"pc":2373,"op":84,"gas":"0xeddb6","gasCost":"0x320","memory":"0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x1bf73a65","0x181","0x2de96ad91d62a796c4ba80e0a862520f9c8a7805","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x0","0x47f37265329d36000","0x1","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x1137c4082672bb033743321bcc426da68e2052bc996d994df96a0e1cd48b5b60"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"SLOAD","error":""}
{"pc":2374,"op":144,"gas":"0xeda96","gasCost":"0x3","memory":"0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x1bf73a65","0x181","0x2de96ad91d62a796c4ba80e0a862520f9c8a7805","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x0","0x47f37265329d36000","0x1","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x1"],"returnStack":[],"returnData":null,"depth":1,"refund":0,"opName":"SWAP1","error":""}

将上面的0xeddb60xeda96相减是800十六进制为0x320

{"pc":2373,"op":84,"gas":"0xeddb6","gasCost":"0xc8","memory":"0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x1bf73a65","0x181","0x2de96ad91d62a796c4ba80e0a862520f9c8a7805","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x0","0x47f37265329d36000","0x1","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x1137c4082672bb033743321bcc426da68e2052bc996d994df96a0e1cd48b5b60"],"depth":1,"refund":0,"opName":"SLOAD","error":""}
{"pc":2374,"op":144,"gas":"0xedcee","gasCost":"0xc8","memory":"0x000000000000000000000000735bce5ecc8455eb9bf8270aa138ce05e069b4c1656502bc70f67e407a17d7e0cba13a8b062e13793501bed56cecc8aee887bd7d0000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x1bf73a65","0x181","0x2de96ad91d62a796c4ba80e0a862520f9c8a7805","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x0","0x47f37265329d36000","0x1","0x735bce5ecc8455eb9bf8270aa138ce05e069b4c1","0x0","0x1"],"depth":1,"refund":0,"opName":"SWAP1","error":""}

这个是升级前的日志,相减得200十六进制为0xc8

查询84opcode0x54 SLOADIstanbulSloadGasEIP1884调节到了800,这个由于分叉高度设置太低导致使用yoloV1InstructionSet解析器,其实是没问题的,调节YoloV1Block高度即可

    "YOLOv1": {
        ChainID:             big.NewInt(1),
        HomesteadBlock:      big.NewInt(0),
        EIP150Block:         big.NewInt(0),
        EIP155Block:         big.NewInt(0),
        EIP158Block:         big.NewInt(0),
        ByzantiumBlock:      big.NewInt(0),
        ConstantinopleBlock: big.NewInt(0),
        PetersburgBlock:     big.NewInt(0),
        IstanbulBlock:       big.NewInt(0),
        YoloV1Block:         big.NewInt(0),
    },

功能不完善问题

eth部署合约正确的指令流程

{"pc":23,"op":96,"gas":"0x278abc","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":[],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"PUSH1","error":""}
{"pc":25,"op":81,"gas":"0x278ab9","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x40"],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"MLOAD","error":""}
{"pc":26,"op":70,"gas":"0x278ab6","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x80"],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"CHAINID","error":""}
{"pc":27,"op":144,"gas":"0x278ab4","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x80","0x539"],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"SWAP1","error":""}

升级后evm的流程

{"pc":23,"op":96,"gas":"0x5c54030","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":[],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"PUSH1","error":""}
{"pc":25,"op":81,"gas":"0x5c5402d","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x40"],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"MLOAD","error":""}
{"pc":26,"op":70,"gas":"0x5c5402a","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080","memSize":96,"stack":["0x80"],"returnStack":[],"returnData":null,"depth":3,"refund":0,"opName":"CHAINID","error":"invalid opcode: CHAINID"}
{"pc":1507,"op":96,"gas":"0x17740a","gasCost":"0x3","memory":"","memSize":11904,"stack":["0xc9c65396","0x95","0x537e697c7ab75a26f9ecf0ce810e3154dfcaaf44","0x3a220f351252089d385b29beca14e27f204c296a","0x0","0x3a220f351252089d385b29beca14e27f204c296a","0x537e697c7ab75a26f9ecf0ce810e3154dfcaaf44","0x80","0xb81ff3c7140db37a05a85068ea614a23c0d72ec176588a2f45c5dd53550b6c88","0x0"],"returnStack":[],"returnData":null,"depth":2,"refund":0,"opName":"PUSH1","error":""}

pc指针可以看操作码70后结果开始不一样了,70对于的opcodeCHAINID,而CHAINIDIstanbul后加入的,由于IstanbulBlock高度设置较高,功能为开启,所以跳转不一样。 trace log也有报错"opName":"CHAINID","error":"invalid opcode: CHAINID"

总结

两个问题都是YoloV1Block未正确设置导致加载的EVMInterpreter解析器不对导致

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2020-08-26 23:59
  • 阅读 ( 238 )
  • 学分 ( 18 )
  • 分类:Geth

该内容来自于互联网公开内容,非区块链原创内容,如若转载,请注明出处:https://htzkw.com/archives/27772

联系我们

aliyinhang@gmail.com