github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/asm/asm.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:34</date>
    10  //</624450077141766144>
    11  
    12  
    13  //为处理EVM装配说明(例如,拆卸它们)提供支持。
    14  package asm
    15  
    16  import (
    17  	"encoding/hex"
    18  	"fmt"
    19  
    20  	"github.com/ethereum/go-ethereum/core/vm"
    21  )
    22  
    23  //反汇编EVM指令的迭代器
    24  type instructionIterator struct {
    25  	code    []byte
    26  	pc      uint64
    27  	arg     []byte
    28  	op      vm.OpCode
    29  	error   error
    30  	started bool
    31  }
    32  
    33  //
    34  func NewInstructionIterator(code []byte) *instructionIterator {
    35  	it := new(instructionIterator)
    36  	it.code = code
    37  	return it
    38  }
    39  
    40  //如果有下一条指令并继续,则返回true。
    41  func (it *instructionIterator) Next() bool {
    42  	if it.error != nil || uint64(len(it.code)) <= it.pc {
    43  //我们以前遇到过一个错误或结束。
    44  		return false
    45  	}
    46  
    47  	if it.started {
    48  //由于迭代已经开始,我们将转到下一条指令。
    49  		if it.arg != nil {
    50  			it.pc += uint64(len(it.arg))
    51  		}
    52  		it.pc++
    53  	} else {
    54  //我们从第一条指令开始迭代。
    55  		it.started = true
    56  	}
    57  
    58  	if uint64(len(it.code)) <= it.pc {
    59  //我们到了终点。
    60  		return false
    61  	}
    62  
    63  	it.op = vm.OpCode(it.code[it.pc])
    64  	if it.op.IsPush() {
    65  		a := uint64(it.op) - uint64(vm.PUSH1) + 1
    66  		u := it.pc + 1 + a
    67  		if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u {
    68  			it.error = fmt.Errorf("incomplete push instruction at %v", it.pc)
    69  			return false
    70  		}
    71  		it.arg = it.code[it.pc+1 : u]
    72  	} else {
    73  		it.arg = nil
    74  	}
    75  	return true
    76  }
    77  
    78  //返回可能遇到的任何错误。
    79  func (it *instructionIterator) Error() error {
    80  	return it.error
    81  }
    82  
    83  //返回当前指令的PC。
    84  func (it *instructionIterator) PC() uint64 {
    85  	return it.pc
    86  }
    87  
    88  //返回当前指令的操作码。
    89  func (it *instructionIterator) Op() vm.OpCode {
    90  	return it.op
    91  }
    92  
    93  //返回当前指令的参数。
    94  func (it *instructionIterator) Arg() []byte {
    95  	return it.arg
    96  }
    97  
    98  //将所有反汇编的EVM指令打印到stdout。
    99  func PrintDisassembled(code string) error {
   100  	script, err := hex.DecodeString(code)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	it := NewInstructionIterator(script)
   106  	for it.Next() {
   107  		if it.Arg() != nil && 0 < len(it.Arg()) {
   108  			fmt.Printf("%05x: %v 0x%x\n", it.PC(), it.Op(), it.Arg())
   109  		} else {
   110  			fmt.Printf("%05x: %v\n", it.PC(), it.Op())
   111  		}
   112  	}
   113  	return it.Error()
   114  }
   115  
   116  //以可读的格式返回所有反汇编的EVM指令。
   117  func Disassemble(script []byte) ([]string, error) {
   118  	instrs := make([]string, 0)
   119  
   120  	it := NewInstructionIterator(script)
   121  	for it.Next() {
   122  		if it.Arg() != nil && 0 < len(it.Arg()) {
   123  			instrs = append(instrs, fmt.Sprintf("%05x: %v 0x%x\n", it.PC(), it.Op(), it.Arg()))
   124  		} else {
   125  			instrs = append(instrs, fmt.Sprintf("%05x: %v\n", it.PC(), it.Op()))
   126  		}
   127  	}
   128  	if err := it.Error(); err != nil {
   129  		return nil, err
   130  	}
   131  	return instrs, nil
   132  }
   133