asm.go 1.01 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
package ethchain

import (
	"fmt"
	"github.com/ethereum/eth-go/ethutil"
	"math/big"
)

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!)
		op := OpCode(val)

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

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

31
			data := script[pc.Int64() : pc.Int64()+a]
32 33
			if len(data) == 0 {
				data = []byte{0}
34
			}
obscuren's avatar
obscuren committed
35
			asm = append(asm, fmt.Sprintf("%04v: 0x%x", pc, data))
36

37
			pc.Add(pc, big.NewInt(a-1))
38 39 40 41 42
		}

		pc.Add(pc, ethutil.Big1)
	}

43
	return asm
44
}