智能合约反编译查错经验汇编

问题:为什么需要比较不同版本的solc编译器

  • EVM在不断升级中,有些指令是后来加入的,比如revert,还有returndatasize

  • 同样的solidity代码,鹏飞在0.4.22编译出来后,就在未升级过的北京银行项目环境上运行报错,因为没有returndatasize这个指令(推测是同样的函数,后面的编译器版本动作不一样了,比如要先返回到buffer了,间接返回returndatasize;而不是像之前直接返回数据本身)

旧版本的solc remix

1.solidity如何反编译查错

etherscan上的服务

我用0.4.22来编译simple合约,发现有如下的fd(revert指令),如果用旧版本(比如0.4.2的呢??)

这里写图片描述

选择低版本,成功通过

我在家中编译器,选择了0.4.2版本,编译部署出二进制代码,果然没有fd指令了


所用源代码


pragma solidity ^0.4.10;



contract Simple {

    uint public number;

    uint public n =50;

    uint public sum;

    event Added(uint indexed count, uint total);



    function Simple() public {

        number = 100;

    }



    function setNum(uint _number) public {

        sum = 0; 

        for (uint i=0; i< n; i++) {

            sum += i;

        }

        emit Added(n, sum);

        number = sum + _number;

    }



    function setDirect(uint _number) public {

        number = _number;

    }



    function getNum() public constant returns (uint) {

        return number;

    }

}

2.solidity升级很频繁

emit EventName是在0.4.21才有,所以昨天编译报错,是因为我用了0.4.20

查看历史版本改动之处,比如0.4.20和0.4.2的区别

  • 去掉了var关键字(因为安全的原因) 0.4.20

  • 库中的非只读的函数不能直接被调用(也是安全的原因)0.4.20

  • 增加了内联函数 0.4.19

  • 增加了实验性质的0.5.0的特性 最近几个版本路线在增加

  • 将constant改为view(如果你的合约只读区块链数据,但是不修改,可以用view);如果连读都不读,可以用pure 0.4.17

  • 修改了ecrecover函数的bug,某些特定情况下可能返回无效数据绕过校验

  • 不要throw了,但是用require assert和revert来代替 0.4.13

  • SHA3代替keccak256 0.4.12

  • 用transfer(value)来代替原来的函数来发送以太币 0.4.10

  • invalid成为一个opcode 0.4.9

  • 当将msg.value用在非payable的函数中,会得到一个警告 0.4.7

  • 同时支持suicide和selfdestruct两种opcode(之前只支持前者),keccak256作为sha3的别名(后来更是代替了) 0.4.3

  • 0.4.2还是很好的版本,尤其是修正了the dao事件后payable的库函数

solidity语言编译器变化历史

对策是熟读变化历史,了解每个指令作用,但是还有问题是怎么知道不同编译器版本编译的指令变化


猜你喜欢

转载自blog.csdn.net/wxid2798226/article/details/80511069