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