aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/vm.go
diff options
context:
space:
mode:
Diffstat (limited to 'ethchain/vm.go')
-rw-r--r--ethchain/vm.go98
1 files changed, 77 insertions, 21 deletions
diff --git a/ethchain/vm.go b/ethchain/vm.go
index dce972cc7..fbe0d0439 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -2,7 +2,7 @@ package ethchain
import (
_ "bytes"
- _ "fmt"
+ "fmt"
"github.com/ethereum/eth-go/ethutil"
_ "github.com/obscuren/secp256k1-go"
_ "math"
@@ -33,13 +33,13 @@ type Vm struct {
}
type RuntimeVars struct {
- origin []byte
- blockNumber uint64
- prevHash []byte
- coinbase []byte
- time int64
- diff *big.Int
- txData []string
+ Origin []byte
+ BlockNumber uint64
+ PrevHash []byte
+ Coinbase []byte
+ Time int64
+ Diff *big.Int
+ TxData []string
}
func NewVm(state *State, vars RuntimeVars) *Vm {
@@ -65,9 +65,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
// The base for all big integer arithmetic
base := new(big.Int)
- if ethutil.Config.Debug {
- ethutil.Config.Log.Debugf("# op\n")
- }
+ /*
+ if ethutil.Config.Debug {
+ ethutil.Config.Log.Debugf("# op\n")
+ }
+ */
for {
step++
@@ -75,9 +77,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
val := closure.Get(pc)
// Get the opcode (it must be an opcode!)
op := OpCode(val.Uint())
- if ethutil.Config.Debug {
- ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
- }
+ /*
+ if ethutil.Config.Debug {
+ ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
+ }
+ */
// TODO Get each instruction cost properly
gas := new(big.Int)
@@ -270,7 +274,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
case oBALANCE:
stack.Push(closure.Value)
case oORIGIN:
- stack.Push(ethutil.BigD(vm.vars.origin))
+ stack.Push(ethutil.BigD(vm.vars.Origin))
case oCALLER:
stack.Push(ethutil.BigD(closure.Callee().Address()))
case oCALLVALUE:
@@ -286,15 +290,15 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
// 0x40 range
case oPREVHASH:
- stack.Push(ethutil.BigD(vm.vars.prevHash))
+ stack.Push(ethutil.BigD(vm.vars.PrevHash))
case oCOINBASE:
- stack.Push(ethutil.BigD(vm.vars.coinbase))
+ stack.Push(ethutil.BigD(vm.vars.Coinbase))
case oTIMESTAMP:
- stack.Push(big.NewInt(vm.vars.time))
+ stack.Push(big.NewInt(vm.vars.Time))
case oNUMBER:
- stack.Push(big.NewInt(int64(vm.vars.blockNumber)))
+ stack.Push(big.NewInt(int64(vm.vars.BlockNumber)))
case oDIFFICULTY:
- stack.Push(vm.vars.diff)
+ stack.Push(vm.vars.Diff)
case oGASLIMIT:
// TODO
@@ -406,7 +410,59 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte {
pc.Add(pc, ethutil.Big1)
if hook != nil {
- hook(op)
+ hook(op, mem, stack)
+ }
+ }
+}
+
+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)
+
+ asm = append(asm, fmt.Sprintf("%v", op))
+
+ switch op {
+ case oPUSH: // Push PC+1 on to the stack
+ pc.Add(pc, ethutil.Big1)
+ data := script[pc.Int64() : pc.Int64()+32]
+ val := ethutil.BigD(data)
+
+ var b []byte
+ if val.Int64() == 0 {
+ b = []byte{0}
+ } else {
+ b = val.Bytes()
+ }
+
+ asm = append(asm, fmt.Sprintf("0x%x", b))
+
+ pc.Add(pc, big.NewInt(31))
+ case oPUSH20:
+ pc.Add(pc, ethutil.Big1)
+ data := script[pc.Int64() : pc.Int64()+20]
+ val := ethutil.BigD(data)
+ var b []byte
+ if val.Int64() == 0 {
+ b = []byte{0}
+ } else {
+ b = val.Bytes()
+ }
+
+ asm = append(asm, fmt.Sprintf("0x%x", b))
+
+ pc.Add(pc, big.NewInt(19))
}
+
+ pc.Add(pc, ethutil.Big1)
}
+
+ return
}