github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/asm/asm.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2017 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  //为处理EVM装配说明(例如,拆卸它们)提供支持。
    26  package asm
    27  
    28  import (
    29  	"encoding/hex"
    30  	"fmt"
    31  
    32  	"github.com/ethereum/go-ethereum/core/vm"
    33  )
    34  
    35  //反汇编EVM指令的迭代器
    36  type instructionIterator struct {
    37  	code    []byte
    38  	pc      uint64
    39  	arg     []byte
    40  	op      vm.OpCode
    41  	error   error
    42  	started bool
    43  }
    44  
    45  //
    46  func NewInstructionIterator(code []byte) *instructionIterator {
    47  	it := new(instructionIterator)
    48  	it.code = code
    49  	return it
    50  }
    51  
    52  //如果有下一条指令并继续,则返回true。
    53  func (it *instructionIterator) Next() bool {
    54  	if it.error != nil || uint64(len(it.code)) <= it.pc {
    55  //我们以前遇到过一个错误或结束。
    56  		return false
    57  	}
    58  
    59  	if it.started {
    60  //由于迭代已经开始,我们将转到下一条指令。
    61  		if it.arg != nil {
    62  			it.pc += uint64(len(it.arg))
    63  		}
    64  		it.pc++
    65  	} else {
    66  //我们从第一条指令开始迭代。
    67  		it.started = true
    68  	}
    69  
    70  	if uint64(len(it.code)) <= it.pc {
    71  //我们到了终点。
    72  		return false
    73  	}
    74  
    75  	it.op = vm.OpCode(it.code[it.pc])
    76  	if it.op.IsPush() {
    77  		a := uint64(it.op) - uint64(vm.PUSH1) + 1
    78  		u := it.pc + 1 + a
    79  		if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u {
    80  			it.error = fmt.Errorf("incomplete push instruction at %v", it.pc)
    81  			return false
    82  		}
    83  		it.arg = it.code[it.pc+1 : u]
    84  	} else {
    85  		it.arg = nil
    86  	}
    87  	return true
    88  }
    89  
    90  //返回可能遇到的任何错误。
    91  func (it *instructionIterator) Error() error {
    92  	return it.error
    93  }
    94  
    95  //返回当前指令的PC。
    96  func (it *instructionIterator) PC() uint64 {
    97  	return it.pc
    98  }
    99  
   100  //返回当前指令的操作码。
   101  func (it *instructionIterator) Op() vm.OpCode {
   102  	return it.op
   103  }
   104  
   105  //返回当前指令的参数。
   106  func (it *instructionIterator) Arg() []byte {
   107  	return it.arg
   108  }
   109  
   110  //将所有反汇编的EVM指令打印到stdout。
   111  func PrintDisassembled(code string) error {
   112  	script, err := hex.DecodeString(code)
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	it := NewInstructionIterator(script)
   118  	for it.Next() {
   119  		if it.Arg() != nil && 0 < len(it.Arg()) {
   120  			fmt.Printf("%06v: %v 0x%x\n", it.PC(), it.Op(), it.Arg())
   121  		} else {
   122  			fmt.Printf("%06v: %v\n", it.PC(), it.Op())
   123  		}
   124  	}
   125  	return it.Error()
   126  }
   127  
   128  //以可读的格式返回所有反汇编的EVM指令。
   129  func Disassemble(script []byte) ([]string, error) {
   130  	instrs := make([]string, 0)
   131  
   132  	it := NewInstructionIterator(script)
   133  	for it.Next() {
   134  		if it.Arg() != nil && 0 < len(it.Arg()) {
   135  			instrs = append(instrs, fmt.Sprintf("%06v: %v 0x%x\n", it.PC(), it.Op(), it.Arg()))
   136  		} else {
   137  			instrs = append(instrs, fmt.Sprintf("%06v: %v\n", it.PC(), it.Op()))
   138  		}
   139  	}
   140  	if err := it.Error(); err != nil {
   141  		return nil, err
   142  	}
   143  	return instrs, nil
   144  }