asm.go 1.16 KB
Newer Older
obscuren's avatar
obscuren committed
1
package core
2 3 4 5

import (
	"fmt"
	"math/big"
6

obscuren's avatar
obscuren committed
7
	"github.com/ethereum/go-ethereum/common"
obscuren's avatar
obscuren committed
8
	"github.com/ethereum/go-ethereum/core/vm"
9 10 11 12 13 14 15 16 17 18 19 20
)

func Disassemble(script []byte) (asm []string) {
	pc := new(big.Int)
	for {
		if pc.Cmp(big.NewInt(int64(len(script)))) >= 0 {
			return
		}

		// Get the memory location of pc
		val := script[pc.Int64()]
		// Get the opcode (it must be an opcode!)
obscuren's avatar
obscuren committed
21
		op := vm.OpCode(val)
22

obscuren's avatar
obscuren committed
23
		asm = append(asm, fmt.Sprintf("%04v: %v", pc, op))
24 25

		switch op {
obscuren's avatar
obscuren committed
26 27 28 29 30
		case vm.PUSH1, vm.PUSH2, vm.PUSH3, vm.PUSH4, vm.PUSH5, vm.PUSH6, vm.PUSH7, vm.PUSH8,
			vm.PUSH9, vm.PUSH10, vm.PUSH11, vm.PUSH12, vm.PUSH13, vm.PUSH14, vm.PUSH15,
			vm.PUSH16, vm.PUSH17, vm.PUSH18, vm.PUSH19, vm.PUSH20, vm.PUSH21, vm.PUSH22,
			vm.PUSH23, vm.PUSH24, vm.PUSH25, vm.PUSH26, vm.PUSH27, vm.PUSH28, vm.PUSH29,
			vm.PUSH30, vm.PUSH31, vm.PUSH32:
obscuren's avatar
obscuren committed
31
			pc.Add(pc, common.Big1)
obscuren's avatar
obscuren committed
32
			a := int64(op) - int64(vm.PUSH1) + 1
33
			if int(pc.Int64()+a) > len(script) {
34
				return
35 36
			}

37
			data := script[pc.Int64() : pc.Int64()+a]
38 39
			if len(data) == 0 {
				data = []byte{0}
40
			}
obscuren's avatar
obscuren committed
41
			asm = append(asm, fmt.Sprintf("%04v: 0x%x", pc, data))
42

43
			pc.Add(pc, big.NewInt(a-1))
44 45
		}

obscuren's avatar
obscuren committed
46
		pc.Add(pc, common.Big1)
47 48
	}

49
	return asm
50
}