net.corda.v5.ledger.utxo.token.selection heading-link-icon

The Token Selection API enables a flow Communication between participants in an application network is peer-to-peer using flows. to exclusively select a set of states An immutable object representing a fact known by one or more participants at a specific point in time. You can use states to represent any type of data, and any kind of fact. to potentially use as input states in a UTXO Unspent Transaction Output. The unspent output of a cryptocurrency transaction, representing the amount of digital currency that has not been spent and is available for use in future transactions. transaction A transaction is a proposal to update the ledger. . Although this can be achieved with simple vault A database containing all data from the ledger relevant to a participant. The database tracks spent and unspent (consumed and unconsumed) states. queries, the selection API offers the following key features that improve the performance and reliability of the flows:

  • Exclusivity: In an environment where multiple instances of a flow are running in parallel, it is important that each flow can exclusively claim states to spend. Without this, there is a high chance that multiple flows could attempt to spend the same states at the same time, causing transactions to fail during notarization, due to an attempt to spend a state that has already been spent.
  • Target Amount Selection: When selecting fungible states to spend, it is usual to select multiple states that sum to at least the target value of the proposed transaction. The selection API provides an explicit model for achieving this, which would be difficult to achieve using standard vault queries.
  • Performance: Providing a dedicated API for this specific type of state selection allows implementations that are not coupled to the vault query API and therefore can be optimized for the specific query patterns.

The API defines a generic token A type of programmable digital asset that can represent value and be traded. Tokens can be fungible or non-fungible. that is used to represent a state. The purpose of the token is to allow a consistent model for querying user-defined states. Attributes of the token are partly derived by the platform and partly derived by the CorDapp Corda Distributed Application. A Java (or any JVM targeting language) application built using the Corda build toolchain and CorDapp API to solve some problem that is best solved in a decentralized manner. using an implementation of UtxoTokenTransactionStateObserver or UtxoLedgerTokenStateObserver (now deprecated) for the given state. The following table describes these attributes:

Attribute
Type
Provided By
Description
StateRefStateRefPlatformThe reference to the state linked to this token.
Notary X500 NameMemberX500NamePlatformThe notary Corda’s uniqueness consensus service. The notary’s primary role is to prevent double-spends by ensuring each transaction contains only unique unconsumed input states. of the state linked to this token.
Token TypeStringBothBy default, the platform sets this to the FQN name of the Java Type of the state class this token is linked to. As a CorDapp Developer, you can override this with your own definition.
Issuer HashSecureHashUserThe hash of the issuer of the state, as defined by the CorDapp Developer.
SymbolStringUserThe user-defined symbol for the token.
AmountBigDecimalUserThe amount/value of the state linked to this token.
TagStringUserAn optional string that can be searched using a regular expression when selecting tokens.
Owner HashSecureHashUserAn optional hash of the owner of the state.

Tokens are grouped into pools using the following fields as the key:

  • Notary
  • Type
  • Symbol
  • Issuer

The API allows a flow to claim tokens from a single pool of tokens for a given query. It is not possible to select tokens from multiple pools in a single query.

A token observer converts a custom state into a token when a transaction is finalized and persisted in the vault. The CorDapp Developer implements the UtxoTokenTransactionStateObserver or the UtxoLedgerTokenStateObserver (now deprecated) interfaces for a state type that is required for selection. The platform uses these observers to generate a token for each produced state when persisting a finalized transaction to the vault.

When a flow needs to select fungible states to spend, it can execute a claim query using the TokenSelection API. The API supports a single method tryClaim that takes a TokenClaimCriteria describing the target amount required and the type of tokens required.

When a flow executes a successful query to select tokens via the selection API, it receives a Token Claim. The claim represents a list of tokens that have been exclusively claimed and can be used as inputs to a new transaction. Once the flow has completed (successfully or not), it should release the claim, signaling which tokens, if any, were consumed in a transaction. Any unused tokens are released back to the pool for others to use.

As described, a token is a representation of state that is available to be spent. The following rules control the eligibility of a token/state for selection:

  • Consumed/Unconsumed Status: Only tokens that are unconsumed are eligible for selection. When a transaction is finalized, all the input states for that transaction are considered consumed and immediately become ineligible for selection. Conversely, any output states of a finalized transaction, become available for selection, if the other criteria below are met.
  • Visibility: By default, a state is visible if the holding identity A group’s addressable identity on a network, plus its X.500 name. (node) is a participant in the transaction. However, you can control the visibility of a state by implementing the isVisible method on the states’ contract. Only visible output states are available for selection.
  • State Observer: Only states that have an associated implementation of UtxoLedgerTokenStateObserver are available for selection.

Was this page helpful?

Thanks for your feedback!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.

We're sorry this page wasn't helpful. Let us know how we can make it better!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Create an issue

Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.