diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt b/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt
index 871972ced3..628ad6e2b5 100644
--- a/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt
+++ b/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt
@@ -69,13 +69,20 @@ class Cash : FungibleAsset<Currency>() {
 
     // Just for grouping
     interface Commands : CommandData {
-        class Move() : TypeOnlyCommandData(), FungibleAsset.Commands.Move
+        /**
+         * A command stating that money has been moved, optionally to fulfil another contract.
+         *
+         * @param contractHash the hash of the contract this cash is settling, to ensure one cash contract cannot be
+         * used to settle multiple contracts. May be null, if this is not relevant to any other contract in the
+         * same transaction
+         */
+        data class Move(override val contractHash: SecureHash? = null) : FungibleAsset.Commands.Move, Commands
 
         /**
          * Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction
          * has a unique ID even when there are no inputs.
          */
-        data class Issue(override val nonce: Long = newSecureRandom().nextLong()) : FungibleAsset.Commands.Issue
+        data class Issue(override val nonce: Long = newSecureRandom().nextLong()) : FungibleAsset.Commands.Issue, Commands
 
         /**
          * A command stating that money has been withdrawn from the shared ledger and is now accounted for
diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt b/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt
index a865e6bcd0..145ef9b0b8 100644
--- a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt
+++ b/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt
@@ -41,13 +41,13 @@ abstract class FungibleAsset<T> : Contract {
 
     // Just for grouping
     interface Commands : CommandData {
-        interface Move : Commands
+        interface Move : MoveCommand, Commands
 
         /**
          * Allows new asset states to be issued into existence: the nonce ("number used once") ensures the transaction
          * has a unique ID even when there are no inputs.
          */
-        interface Issue : Commands { val nonce: Long }
+        interface Issue : IssueCommand, Commands
 
         /**
          * A command stating that money has been withdrawn from the shared ledger and is now accounted for
@@ -89,7 +89,7 @@ abstract class FungibleAsset<T> : Contract {
                             (inputAmount == outputAmount + amountExitingLedger)
                 }
 
-                verifyMoveCommands<Commands.Move>(inputs, tx)
+                verifyMoveCommand<Commands.Move>(inputs, tx)
             }
         }
     }
diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt b/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt
index d7018b9c3e..834fa36dda 100644
--- a/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt
+++ b/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt
@@ -92,7 +92,7 @@ fun List<AuthenticatedObject<CommandData>>.getTimestampByName(vararg names: Stri
  */
 @Throws(IllegalArgumentException::class)
 // TODO: Can we have a common Move command for all contracts and avoid the reified type parameter here?
-inline fun <reified T : CommandData> verifyMoveCommands(inputs: List<OwnableState>, tx: TransactionForContract) {
+inline fun <reified T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, tx: TransactionForContract) {
     // Now check the digital signatures on the move command. Every input has an owning public key, and we must
     // see a signature from each of those keys. The actual signatures have been verified against the transaction
     // data by the platform before execution.
diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt b/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt
index a6e69824fd..eb63e738fc 100644
--- a/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt
+++ b/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt
@@ -228,6 +228,21 @@ data class Command(val value: CommandData, val signers: List<PublicKey>) {
     override fun toString() = "${commandDataToString()} with pubkeys ${signers.map { it.toStringShort() }}"
 }
 
+/** A common issue command, to enforce that issue commands have a nonce value. */
+interface IssueCommand : CommandData {
+    val nonce: Long
+}
+
+/** A common move command for contracts which can change owner. */
+interface MoveCommand : CommandData {
+    /**
+     * Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in
+     * order to settle an obligation contract's state object(s).
+     */
+    // TODO: Replace SecureHash here with a general contract constraints object
+    val contractHash: SecureHash?
+}
+
 /** Wraps an object that was signed by a public key, which may be a well known/recognised institutional key. */
 data class AuthenticatedObject<out T : Any>(
         val signers: List<PublicKey>,
diff --git a/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt b/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt
index e63962ac10..064cfda45b 100644
--- a/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt
+++ b/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt
@@ -16,6 +16,8 @@ import com.r3corda.core.crypto.generateKeyPair
 import com.r3corda.core.crypto.sha256
 import com.r3corda.core.node.AttachmentsClassLoader
 import com.r3corda.core.node.services.AttachmentStorage
+import com.r3corda.core.utilities.NonEmptySet
+import com.r3corda.core.utilities.NonEmptySetSerializer
 import de.javakaffee.kryoserializers.ArraysAsListSerializer
 import net.i2p.crypto.eddsa.EdDSAPrivateKey
 import net.i2p.crypto.eddsa.EdDSAPublicKey
@@ -350,6 +352,9 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
         register(Issued::class.java, ImmutableClassSerializer(Issued::class))
         register(TransactionState::class.java, ImmutableClassSerializer(TransactionState::class))
 
+        // This ensures a NonEmptySetSerializer is constructed with an initial value.
+        register(NonEmptySet::class.java, NonEmptySetSerializer)
+        
         noReferencesWithin<WireTransaction>()
     }
 }
diff --git a/core/src/main/kotlin/com/r3corda/core/utilities/NonEmptySet.kt b/core/src/main/kotlin/com/r3corda/core/utilities/NonEmptySet.kt
index 89739639e5..a12b5c49c7 100644
--- a/core/src/main/kotlin/com/r3corda/core/utilities/NonEmptySet.kt
+++ b/core/src/main/kotlin/com/r3corda/core/utilities/NonEmptySet.kt
@@ -1,12 +1,20 @@
 package com.r3corda.core.utilities
 
+import com.esotericsoftware.kryo.Kryo
+import com.esotericsoftware.kryo.Serializer
+import com.esotericsoftware.kryo.io.Input
+import com.esotericsoftware.kryo.io.Output
+import java.util.*
+
 /**
  * A set which is constrained to ensure it can never be empty. An initial value must be provided at
  * construction, and attempting to remove the last element will cause an IllegalStateException.
+ * The underlying set is exposed for Kryo to access, but should not be accessed directly.
  */
-class NonEmptySet<T>(initial: T, private val set: MutableSet<T> = mutableSetOf()) : MutableSet<T> {
+class NonEmptySet<T>(initial: T) : MutableSet<T> {
+    private val set: MutableSet<T> = HashSet<T>()
+
     init {
-        require (set.isEmpty()) { "Provided set must be empty." }
         set.add(initial)
     }
 
@@ -80,4 +88,28 @@ fun <T> nonEmptySetOf(initial: T, vararg elements: T): NonEmptySet<T> {
     // We add the first element twice, but it's a set, so who cares
     set.addAll(elements)
     return set
+}
+
+/**
+ * Custom serializer which understands it has to read in an item before
+ * trying to construct the set.
+ */
+object NonEmptySetSerializer : Serializer<NonEmptySet<Any>>() {
+    override fun write(kryo: Kryo, output: Output, obj: NonEmptySet<Any>) {
+        // Write out the contents as normal
+        output.writeInt(obj.size)
+        obj.forEach { kryo.writeClassAndObject(output, it) }
+    }
+
+    override fun read(kryo: Kryo, input: Input, type: Class<NonEmptySet<Any>>): NonEmptySet<Any> {
+        val size = input.readInt()
+        require(size >= 1) { "Size is positive" }
+        // TODO: Is there an upper limit we can apply to how big one of these could be?
+        val first = kryo.readClassAndObject(input)
+        // Read the first item and use it to construct the NonEmptySet
+        val set = NonEmptySet(first)
+        // Read in the rest of the set
+        for (i in 2..size) { set.add(kryo.readClassAndObject(input)) }
+        return set
+    }
 }
\ No newline at end of file
diff --git a/core/src/test/kotlin/com/r3corda/core/utilities/NonEmptySetTest.kt b/core/src/test/kotlin/com/r3corda/core/utilities/NonEmptySetTest.kt
index 58f07eefab..eb0567730a 100644
--- a/core/src/test/kotlin/com/r3corda/core/utilities/NonEmptySetTest.kt
+++ b/core/src/test/kotlin/com/r3corda/core/utilities/NonEmptySetTest.kt
@@ -8,6 +8,8 @@ import com.google.common.collect.testing.testers.CollectionAddAllTester
 import com.google.common.collect.testing.testers.CollectionClearTester
 import com.google.common.collect.testing.testers.CollectionRemoveAllTester
 import com.google.common.collect.testing.testers.CollectionRetainAllTester
+import com.r3corda.core.serialization.deserialize
+import com.r3corda.core.serialization.serialize
 import junit.framework.TestSuite
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -17,7 +19,8 @@ import kotlin.test.assertEquals
 @RunWith(Suite::class)
 @Suite.SuiteClasses(
         NonEmptySetTest.Guava::class,
-        NonEmptySetTest.Remove::class
+        NonEmptySetTest.Remove::class,
+        NonEmptySetTest.Serializer::class
 )
 class NonEmptySetTest {
     /**
@@ -93,6 +96,20 @@ class NonEmptySetTest {
             }
         }
     }
+
+    /**
+     * Test serialization/deserialization.
+     */
+    class Serializer {
+        @Test
+        fun `serialize deserialize`() {
+            val expected: NonEmptySet<Int> = nonEmptySetOf(-17, 22, 17)
+            val serialized = expected.serialize().bits
+            val actual = serialized.deserialize<NonEmptySet<Int>>()
+
+            assertEquals(expected, actual)
+        }
+    }
 }
 
 /**