asm.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package core
  2. import (
  3. "fmt"
  4. "math/big"
  5. "github.com/ethereum/go-ethereum/ethutil"
  6. "github.com/ethereum/go-ethereum/vm"
  7. )
  8. func Disassemble(script []byte) (asm []string) {
  9. pc := new(big.Int)
  10. for {
  11. if pc.Cmp(big.NewInt(int64(len(script)))) >= 0 {
  12. return
  13. }
  14. // Get the memory location of pc
  15. val := script[pc.Int64()]
  16. // Get the opcode (it must be an opcode!)
  17. op := vm.OpCode(val)
  18. asm = append(asm, fmt.Sprintf("%04v: %v", pc, op))
  19. switch op {
  20. case vm.PUSH1, vm.PUSH2, vm.PUSH3, vm.PUSH4, vm.PUSH5, vm.PUSH6, vm.PUSH7, vm.PUSH8,
  21. vm.PUSH9, vm.PUSH10, vm.PUSH11, vm.PUSH12, vm.PUSH13, vm.PUSH14, vm.PUSH15,
  22. vm.PUSH16, vm.PUSH17, vm.PUSH18, vm.PUSH19, vm.PUSH20, vm.PUSH21, vm.PUSH22,
  23. vm.PUSH23, vm.PUSH24, vm.PUSH25, vm.PUSH26, vm.PUSH27, vm.PUSH28, vm.PUSH29,
  24. vm.PUSH30, vm.PUSH31, vm.PUSH32:
  25. pc.Add(pc, ethutil.Big1)
  26. a := int64(op) - int64(vm.PUSH1) + 1
  27. if int(pc.Int64()+a) > len(script) {
  28. return
  29. }
  30. data := script[pc.Int64() : pc.Int64()+a]
  31. if len(data) == 0 {
  32. data = []byte{0}
  33. }
  34. asm = append(asm, fmt.Sprintf("%04v: 0x%x", pc, data))
  35. pc.Add(pc, big.NewInt(a-1))
  36. }
  37. pc.Add(pc, ethutil.Big1)
  38. }
  39. return asm
  40. }