diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index 411df5686166119a7067ee09a5b7989b4b0e78d0..264d55cb92c436d4c6db6f8e99e186c8222eabe1 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -1,9 +1,25 @@
 package vm
 
-import "gopkg.in/fatih/set.v0"
+import (
+	"math/big"
 
-func analyseJumpDests(code []byte) (dests *set.Set) {
-	dests = set.New()
+	"gopkg.in/fatih/set.v0"
+)
+
+type destinations struct {
+	set *set.Set
+}
+
+func (d *destinations) Has(dest *big.Int) bool {
+	return d.set.Has(string(dest.Bytes()))
+}
+
+func (d *destinations) Add(dest *big.Int) {
+	d.set.Add(string(dest.Bytes()))
+}
+
+func analyseJumpDests(code []byte) (dests *destinations) {
+	dests = &destinations{set.New()}
 
 	for pc := uint64(0); pc < uint64(len(code)); pc++ {
 		var op OpCode = OpCode(code[pc])
@@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) {
 
 			pc += a
 		case JUMPDEST:
-			dests.Add(pc)
+			dests.Add(big.NewInt(int64(pc)))
 		}
 	}
 	return
diff --git a/core/vm/common.go b/core/vm/common.go
index 5226f482831e79fdf667e622cbaa905762025c65..5ff4e05f2d9b61f3a8efb3b42055bcd6eea72cee 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -33,6 +33,7 @@ var (
 	S256 = common.S256
 
 	Zero = common.Big0
+	One  = common.Big1
 
 	max = big.NewInt(math.MaxInt64)
 )
diff --git a/core/vm/context.go b/core/vm/context.go
index e4b94b6009fe2d0166d12393f7c0462e95bfae71..29bb9f74e1941207301ad41cd9933574201df9d1 100644
--- a/core/vm/context.go
+++ b/core/vm/context.go
@@ -1,7 +1,6 @@
 package vm
 
 import (
-	"math"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int
 	return c
 }
 
-func (c *Context) GetOp(n uint64) OpCode {
+func (c *Context) GetOp(n *big.Int) OpCode {
 	return OpCode(c.GetByte(n))
 }
 
-func (c *Context) GetByte(n uint64) byte {
-	if n < uint64(len(c.Code)) {
-		return c.Code[n]
+func (c *Context) GetByte(n *big.Int) byte {
+	if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 {
+		return c.Code[n.Int64()]
 	}
 
 	return 0
 }
 
-func (c *Context) GetBytes(x, y int) []byte {
-	return c.GetRangeValue(uint64(x), uint64(y))
-}
-
-func (c *Context) GetRangeValue(x, size uint64) []byte {
-	x = uint64(math.Min(float64(x), float64(len(c.Code))))
-	y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
-
-	return common.RightPadBytes(c.Code[x:y], int(size))
-}
-
 func (c *Context) Return(ret []byte) []byte {
 	// Return the remaining gas to the caller
 	c.caller.ReturnGas(c.Gas, c.Price)
diff --git a/core/vm/vm.go b/core/vm/vm.go
index eceb6e3a905127565cbb0c2fd963ccd5b191b1cf..6c3dd240a05df88a6c8fc3eb703bf62ec14a3344 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -72,23 +72,20 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 	var (
 		op OpCode
 
-		destinations        = analyseJumpDests(context.Code)
-		mem                 = NewMemory()
-		stack               = newStack()
-		pc           uint64 = 0
-		step                = 0
-		statedb             = self.env.State()
-
-		jump = func(from uint64, to *big.Int) error {
-			p := to.Uint64()
-
-			nop := context.GetOp(p)
-			if !destinations.Has(p) {
-				return fmt.Errorf("invalid jump destination (%v) %v", nop, p)
+		destinations = analyseJumpDests(context.Code)
+		mem          = NewMemory()
+		stack        = newStack()
+		pc           = new(big.Int)
+		statedb      = self.env.State()
+
+		jump = func(from *big.Int, to *big.Int) error {
+			nop := context.GetOp(to)
+			if !destinations.Has(to) {
+				return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
 			}
 
 			self.Printf(" ~> %v", to)
-			pc = to.Uint64()
+			pc = to
 
 			self.Endl()
 
@@ -105,7 +102,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 		// The base for all big integer arithmetic
 		base := new(big.Int)
 
-		step++
 		// Get the memory location of pc
 		op = context.GetOp(pc)
 
@@ -428,22 +424,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 
 			self.Printf(" => %v", value)
 		case CALLDATALOAD:
-			var (
-				offset  = stack.pop()
-				data    = make([]byte, 32)
-				lenData = big.NewInt(int64(len(callData)))
-			)
-
-			if lenData.Cmp(offset) >= 0 {
-				length := new(big.Int).Add(offset, common.Big32)
-				length = common.BigMin(length, lenData)
-
-				copy(data, callData[offset.Int64():length.Int64()])
-			}
+			data := getData(callData, stack.pop(), common.Big32)
 
 			self.Printf(" => 0x%x", data)
 
-			stack.push(common.BigD(data))
+			stack.push(common.Bytes2Big(data))
 		case CALLDATASIZE:
 			l := int64(len(callData))
 			stack.push(big.NewInt(l))
@@ -542,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 
 			// 0x50 range
 		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:
-			a := uint64(op - PUSH1 + 1)
-			byts := context.GetRangeValue(pc+1, a)
+			a := big.NewInt(int64(op - PUSH1 + 1))
+			byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a)
 			// push value to stack
-			stack.push(common.BigD(byts))
-			pc += a
-
-			step += int(op) - int(PUSH1) + 1
+			stack.push(common.Bytes2Big(byts))
+			pc.Add(pc, a)
 
 			self.Printf(" => 0x%x", byts)
 		case POP:
@@ -628,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 
 		case JUMPDEST:
 		case PC:
-			stack.push(big.NewInt(int64(pc)))
+			//stack.push(big.NewInt(int64(pc)))
+			stack.push(pc)
 		case MSIZE:
 			stack.push(big.NewInt(int64(mem.Len())))
 		case GAS:
@@ -734,7 +718,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 			return nil, fmt.Errorf("Invalid opcode %x", op)
 		}
 
-		pc++
+		pc.Add(pc, One)
 
 		self.Endl()
 	}