diff --git a/ethvm/types.go b/ethvm/types.go
index bb67359931c2c106a68a17a82085778f5169e348..9cddd7c33f091cc9511c8ad70133f8c213295cdd 100644
--- a/ethvm/types.go
+++ b/ethvm/types.go
@@ -49,6 +49,8 @@ const (
 	CODESIZE     = 0x38
 	CODECOPY     = 0x39
 	GASPRICE     = 0x3a
+	EXTCODECOPY  = 0x3b
+	EXTCODESIZE  = 0x3c
 
 	// 0x40 range - block operations
 	PREVHASH   = 0x40
@@ -142,10 +144,11 @@ const (
 	SWAP16 = 0x9f
 
 	// 0xf0 range - closures
-	CREATE = 0xf0
-	CALL   = 0xf1
-	RETURN = 0xf2
-	POST   = 0xf3
+	CREATE        = 0xf0
+	CALL          = 0xf1
+	RETURN        = 0xf2
+	POST          = 0xf3
+	CALLSTATELESS = 0xf4
 
 	// 0x70 range - other
 	LOG     = 0xfe // XXX Unofficial
@@ -197,12 +200,14 @@ var opCodeToString = map[OpCode]string{
 	GASPRICE:     "TXGASPRICE",
 
 	// 0x40 range - block operations
-	PREVHASH:   "PREVHASH",
-	COINBASE:   "COINBASE",
-	TIMESTAMP:  "TIMESTAMP",
-	NUMBER:     "NUMBER",
-	DIFFICULTY: "DIFFICULTY",
-	GASLIMIT:   "GASLIMIT",
+	PREVHASH:    "PREVHASH",
+	COINBASE:    "COINBASE",
+	TIMESTAMP:   "TIMESTAMP",
+	NUMBER:      "NUMBER",
+	DIFFICULTY:  "DIFFICULTY",
+	GASLIMIT:    "GASLIMIT",
+	EXTCODESIZE: "EXTCODESIZE",
+	EXTCODECOPY: "EXTCODECOPY",
 
 	// 0x50 range - 'storage' and execution
 	POP: "POP",
@@ -288,9 +293,11 @@ var opCodeToString = map[OpCode]string{
 	SWAP16: "SWAP16",
 
 	// 0xf0 range
-	CREATE: "CREATE",
-	CALL:   "CALL",
-	RETURN: "RETURN",
+	CREATE:        "CREATE",
+	CALL:          "CALL",
+	RETURN:        "RETURN",
+	POST:          "POST",
+	CALLSTATELESS: "CALLSTATELESS",
 
 	// 0x70 range - other
 	LOG:     "LOG",
@@ -343,7 +350,12 @@ var OpCodes = map[string]byte{
 	"CALLVALUE":    0x34,
 	"CALLDATALOAD": 0x35,
 	"CALLDATASIZE": 0x36,
-	"GASPRICE":     0x38,
+	"CALLDATACOPY": 0x37,
+	"CODESIZE":     0x38,
+	"CODECOPY":     0x39,
+	"GASPRICE":     0x3a,
+	"EXTCODECOPY":  0x3b,
+	"EXTCODESIZE":  0x3c,
 
 	// 0x40 range - block operations
 	"PREVHASH":   0x40,
@@ -436,10 +448,11 @@ var OpCodes = map[string]byte{
 	"SWAP16": 0x9f,
 
 	// 0xf0 range - closures
-	"CREATE": 0xf0,
-	"CALL":   0xf1,
-	"RETURN": 0xf2,
-	"POST":   0xf3,
+	"CREATE":        0xf0,
+	"CALL":          0xf1,
+	"RETURN":        0xf2,
+	"POST":          0xf3,
+	"CALLSTATELESS": 0xf4,
 
 	// 0x70 range - other
 	"LOG":     0xfe,
diff --git a/ethvm/vm.go b/ethvm/vm.go
index 924a861ca2ea50bd0cdc56958e0c2e9a13314e1f..2acf52f92c81f789a3cd6cb9e03152a7bbdc511c 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -197,6 +197,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			require(3)
 
 			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
+		case EXTCODECOPY:
+			require(4)
+
+			newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64()
 		case CALL:
 			require(7)
 			gas.Set(GasCall)
@@ -550,14 +554,32 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			code := closure.Args[cOff : cOff+l]
 
 			mem.Set(mOff, l, code)
-		case CODESIZE:
-			l := big.NewInt(int64(len(closure.Code)))
+		case CODESIZE, EXTCODESIZE:
+			var code []byte
+			if op == EXTCODECOPY {
+				addr := stack.Pop().Bytes()
+
+				code = self.env.State().GetCode(addr)
+			} else {
+				code = closure.Code
+			}
+
+			l := big.NewInt(int64(len(code)))
 			stack.Push(l)
 
 			self.Printf(" => %d", l)
-		case CODECOPY:
+		case CODECOPY, EXTCODECOPY:
+			var code []byte
+			if op == EXTCODECOPY {
+				addr := stack.Pop().Bytes()
+
+				code = self.env.State().GetCode(addr)
+			} else {
+				code = closure.Code
+			}
+
 			var (
-				size = int64(len(closure.Code))
+				size = int64(len(code))
 				mOff = stack.Pop().Int64()
 				cOff = stack.Pop().Int64()
 				l    = stack.Pop().Int64()
@@ -570,9 +592,9 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 				l = 0
 			}
 
-			code := closure.Code[cOff : cOff+l]
+			codeCopy := code[cOff : cOff+l]
 
-			mem.Set(mOff, l, code)
+			mem.Set(mOff, l, codeCopy)
 		case GASPRICE:
 			stack.Push(closure.Price)