diff --git a/ethvm/stack.go b/ethvm/stack.go
index f4b0be3938be7dfd750076a3ec22f88cea038667..82dd612c2b020cb62c304a9937aee7fe8781de0c 100644
--- a/ethvm/stack.go
+++ b/ethvm/stack.go
@@ -64,6 +64,18 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) {
 	return ints[0], ints[1]
 }
 
+func (st *Stack) Swapn(n int) (*big.Int, *big.Int) {
+	st.data[n], st.data[0] = st.data[0], st.data[n]
+
+	return st.data[n], st.data[0]
+}
+
+func (st *Stack) Dupn(n int) *big.Int {
+	st.Push(st.data[n])
+
+	return st.Peek()
+}
+
 func (st *Stack) Push(d *big.Int) {
 	st.data = append(st.data, new(big.Int).Set(d))
 }
diff --git a/ethvm/types.go b/ethvm/types.go
index 1c3f66139cd97ad839caf78057e102f4b7895fd6..99dc0672deae17e468944f60c882185a97ff76e3 100644
--- a/ethvm/types.go
+++ b/ethvm/types.go
@@ -105,6 +105,40 @@ const (
 	PUSH31 = 0x7e
 	PUSH32 = 0x7f
 
+	DUP1  = 0x80
+	DUP2  = 0x81
+	DUP3  = 0x82
+	DUP4  = 0x83
+	DUP5  = 0x84
+	DUP6  = 0x85
+	DUP7  = 0x86
+	DUP8  = 0x87
+	DUP9  = 0x88
+	DUP10 = 0x89
+	DUP11 = 0x8a
+	DUP12 = 0x8b
+	DUP13 = 0x8c
+	DUP14 = 0x8d
+	DUP15 = 0x8e
+	DUP16 = 0x8f
+
+	SWAP1  = 0x90
+	SWAP2  = 0x91
+	SWAP3  = 0x92
+	SWAP4  = 0x93
+	SWAP5  = 0x94
+	SWAP6  = 0x95
+	SWAP7  = 0x96
+	SWAP8  = 0x97
+	SWAP9  = 0x98
+	SWAP10 = 0x99
+	SWAP11 = 0x9a
+	SWAP12 = 0x9b
+	SWAP13 = 0x9c
+	SWAP14 = 0x9d
+	SWAP15 = 0x9e
+	SWAP16 = 0x9f
+
 	// 0xf0 range - closures
 	CREATE = 0xf0
 	CALL   = 0xf1
diff --git a/ethvm/vm.go b/ethvm/vm.go
index ddad0d366e7bd5f062b430ab208c3cd90332f389..b274175863e16306774a4d42a1b411100bb06972 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -600,16 +600,20 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		case POP:
 			require(1)
 			stack.Pop()
-		case DUP:
-			require(1)
-			stack.Push(stack.Peek())
+		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
+			n := int(op - DUP1 + 1)
+			stack.Dupn(n)
+
+			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
+		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
+			n := int(op - SWAP1 + 1)
+			x, y := stack.Swapn(n)
 
-			self.Printf(" => 0x%x", stack.Peek().Bytes())
+			self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
+		case DUP:
+			// NOP
 		case SWAP:
-			require(2)
-			x, y := stack.Popn()
-			stack.Push(y)
-			stack.Push(x)
+			// NOP
 		case MLOAD:
 			require(1)
 			offset := stack.Pop()
diff --git a/peer.go b/peer.go
index d841b2ad3c52d9fe1774acb0b151c64c8899b50f..ab17466e1019d630f278b04df2d59fbbbd9d74dd 100644
--- a/peer.go
+++ b/peer.go
@@ -24,7 +24,7 @@ const (
 	// The size of the output buffer for writing messages
 	outputBufferSize = 50
 	// Current protocol version
-	ProtocolVersion = 27
+	ProtocolVersion = 28
 	// Interval for ping/pong message
 	pingPongTimer = 2 * time.Second
 )