diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go
index 505d536cf2ced18767aaebffb3c00b9cc3ead2d1..5ebd4807252a273b665359ffe6925e6f0fe7455d 100644
--- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go
+++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go
@@ -166,6 +166,7 @@ const (
 	CALL
 	CALLCODE
 	RETURN
+	DELEGATECALL
 
 	// 0x70 range - other
 	SUICIDE = 0xff
@@ -316,10 +317,11 @@ var opCodeToString = map[OpCode]string{
 	LOG4:   "LOG4",
 
 	// 0xf0 range
-	CREATE:   "CREATE",
-	CALL:     "CALL",
-	RETURN:   "RETURN",
-	CALLCODE: "CALLCODE",
+	CREATE:       "CREATE",
+	CALL:         "CALL",
+	RETURN:       "RETURN",
+	CALLCODE:     "CALLCODE",
+	DELEGATECALL: "DELEGATECALL",
 
 	// 0x70 range - other
 	SUICIDE: "SUICIDE",
diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
index f3d02f21591e4d8396f0265207929df178cef146..f79a3d28734bc69ceaa0a8139d52fb2ad1b5d633 100644
--- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
+++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
@@ -147,6 +147,30 @@ func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas
 	return
 }
 
+// DelegateCall is executed by the DELEGATECALL opcode, introduced as off Ethereum Homestead.
+// The intent of delegate call is to run the code of the callee in the storage context of the caller;
+// while preserving the original caller to the previous callee.
+// Different to the normal CALL or CALLCODE, the value does not need to be transferred to the callee.
+func (vm *VM) DelegateCall(caller, callee *Account, code, input []byte, value int64, gas *int64) (output []byte, err error) {
+
+	exception := new(string)
+	// fire the post call event (including exception if applicable)
+	defer vm.fireCallEvent(exception, &output, caller, callee, input, value, gas)
+
+	// DelegateCall does not transfer the value to the callee.
+
+	if len(code) > 0 {
+		vm.callDepth += 1
+		output, err = vm.call(caller, callee, code, input, value, gas)
+		vm.callDepth -= 1
+		if err != nil {
+			*exception = err.Error()
+		}
+	}
+
+	return
+}
+
 // Try to deduct gasToUse from gasLeft.  If ok return false, otherwise
 // set err and return true.
 func useGasNegative(gasLeft *int64, gasToUse int64, err *error) bool {
@@ -745,12 +769,21 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 				stack.Push(newAccount.Address)
 			}
 
-		case CALL, CALLCODE: // 0xF1, 0xF2
+		case CALL, CALLCODE, DELEGATECALL: // 0xF1, 0xF2, 0xF4
 			if !HasPermission(vm.appState, callee, ptypes.Call) {
 				return nil, ErrPermission{"call"}
 			}
 			gasLimit := stack.Pop64()
-			addr, value := stack.Pop(), stack.Pop64()
+			addr := stack.Pop()
+			// NOTE: for DELEGATECALL value is preserved from the original
+			// caller, as such it is not stored on stack for the address
+			// to be called; for CALL and CALLCODE value is stored on stack
+			// and needs to be overwritten from the given value.
+			// TODO: [ben] assert that malicious code cannot produce
+			// new value.
+			if op != DELEGATECALL {
+				value = stack.Pop64()
+			}
 			inOffset, inSize := stack.Pop64(), stack.Pop64()   // inputs
 			retOffset, retSize := stack.Pop64(), stack.Pop64() // outputs
 			dbg.Printf(" => %X\n", addr)
@@ -799,6 +832,11 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 						return nil, firstErr(err, ErrUnknownAddress)
 					}
 					ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
+				} else if op == DELEGATECALL {
+					if acc == nil {
+						return nil, firstErr(err, ErrUnknownAddress)
+					}
+					ret, err = vm.DelegateCall(caller, callee, acc.Code, args, value, gas)
 				} else {
 					// nil account means we're sending funds to a new account
 					if acc == nil {