diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/FungibleAsset.kt b/core/src/main/kotlin/com/r3corda/core/contracts/FungibleAsset.kt new file mode 100644 index 0000000000..5f6be7908d --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/contracts/FungibleAsset.kt @@ -0,0 +1,66 @@ +package com.r3corda.core.contracts + +import java.security.PublicKey + +class InsufficientBalanceException(val amountMissing: Amount<*>) : Exception() { + override fun toString() = "Insufficient balance, missing $amountMissing" +} + +/** + * Interface for contract states representing assets which are fungible, countable and issued by a + * specific party. States contain assets which are equivalent (such as cash of the same currency), + * so records of their existence can be merged or split as needed where the issuer is the same. For + * instance, dollars issued by the Fed are fungible and countable (in cents), barrels of West Texas + * crude are fungible and countable (oil from two small containers can be poured into one large + * container), shares of the same class in a specific company are fungible and countable, and so on. + * + * See [Cash] for an example contract that implements currency using state objects that implement + * this interface. + * + * @param T a type that represents the asset in question. This should describe the basic type of the asset + * (GBP, USD, oil, shares in company , etc.) and any additional metadata (issuer, grade, class, etc.). + */ +interface FungibleAsset : OwnableState { + /** + * Where the underlying asset backing this ledger entry can be found. The reference + * is only intended for use by the issuer, and is not intended to be meaningful to others. + */ + val deposit: PartyAndReference + val issuanceDef: Issued + val amount: Amount> + /** + * There must be an ExitCommand signed by these keys to destroy the amount. While all states require their + * owner to sign, some (i.e. cash) also require the issuer. + */ + val exitKeys: Collection + /** There must be a MoveCommand signed by this key to claim the amount */ + override val owner: PublicKey + fun move(newAmount: Amount>, newOwner: PublicKey): FungibleAsset + + // Just for grouping + interface Commands : CommandData { + 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 : IssueCommand, Commands + + /** + * A command stating that money has been withdrawn from the shared ledger and is now accounted for + * in some other way. + */ + interface Exit : Commands { val amount: Amount> } + } +} + + +// Small DSL extensions. + +/** Sums the asset states in the list, returning null if there are none. */ +fun Iterable.sumFungibleOrNull() = filterIsInstance>().map { it.amount }.sumOrNull() + +/** Sums the asset states in the list, returning zero of the given token if there are none. */ +fun Iterable.sumFungibleOrZero(token: Issued) = filterIsInstance>().map { it.amount }.sumOrZero(token) + 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 015d738f36..61ad26b0eb 100644 --- a/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt @@ -468,66 +468,4 @@ interface Attachment : NamedByHash { } } -class InsufficientBalanceException(val amountMissing: Amount<*>) : Exception() { - override fun toString() = "Insufficient balance, missing $amountMissing" -} - -/** - * Interface for contract states representing assets which are fungible, countable and issued by a - * specific party. States contain assets which are equivalent (such as cash of the same currency), - * so records of their existence can be merged or split as needed where the issuer is the same. For - * instance, dollars issued by the Fed are fungible and countable (in cents), barrels of West Texas - * crude are fungible and countable (oil from two small containers can be poured into one large - * container), shares of the same class in a specific company are fungible and countable, and so on. - * - * See [Cash] for an example contract that implements currency using state objects that implement - * this interface. - * - * @param T a type that represents the asset in question. This should describe the basic type of the asset - * (GBP, USD, oil, shares in company , etc.) and any additional metadata (issuer, grade, class, etc.). - */ -interface FungibleAsset : OwnableState { - /** - * Where the underlying asset backing this ledger entry can be found. The reference - * is only intended for use by the issuer, and is not intended to be meaningful to others. - */ - val deposit: PartyAndReference - val issuanceDef: Issued - val amount: Amount> - /** - * There must be an ExitCommand signed by these keys to destroy the amount. While all states require their - * owner to sign, some (i.e. cash) also require the issuer. - */ - val exitKeys: Collection - /** There must be a MoveCommand signed by this key to claim the amount */ - override val owner: PublicKey - fun move(newAmount: Amount>, newOwner: PublicKey): FungibleAsset - - // Just for grouping - interface Commands : CommandData { - 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 : IssueCommand, Commands - - /** - * A command stating that money has been withdrawn from the shared ledger and is now accounted for - * in some other way. - */ - interface Exit : Commands { val amount: Amount> } - } -} - - -// Small DSL extensions. - -/** Sums the asset states in the list, returning null if there are none. */ -fun Iterable.sumFungibleOrNull() = filterIsInstance>().map { it.amount }.sumOrNull() - -/** Sums the asset states in the list, returning zero of the given token if there are none. */ -fun Iterable.sumFungibleOrZero(token: Issued) = filterIsInstance>().map { it.amount }.sumOrZero(token) -