class UnicumGenerator extends AnyRef
Generates ContractSalts and Unicums for contract IDs such that the Unicum is a cryptographic commitment to the following:
- The com.digitalasset.canton.topology.DomainId of the transaction that creates the contract
- The com.digitalasset.canton.topology.MediatorId of the mediator that handles the transaction request
- The
UUID
of the transaction that creates the contract - The com.digitalasset.canton.data.ViewPosition of the view whose core creates the contract
- The index of the create node within the view
- The ledger time when the contract was created
- The template ID and the template arguments of the contract, including the agreement text
The commitment is implemented as a blinded hash with the view action salt as the blinding factor.
The above data is split into two groups:
- com.digitalasset.canton.topology.DomainId, com.digitalasset.canton.topology.MediatorId, the
UUID
, the com.digitalasset.canton.data.ViewPosition, and the index contribute to the blinded hash of the ContractSalt. - The ledger time and the template arguments
The Unicum is then the cryptographic hash of the ContractSalt and the second group.
The ContractSalt contains all the information that ensures uniqueness of contract IDs in Canton. The second group contains the information that is relevant for using the contract in transactions. The commitment to the information in the second group can be opened by revealing the ContractSalt. Since the ContractSalt is a blinded hash, such an opening does not reveal information about the data in the first group.
Properties
- If a transaction is added to the virtual domain ledger for a given domain, then the [[Unicum]] is globally unique unless a hash collision occurs.
Contracts with the same Unicum must run over the same domain, have the same transaction UUID, and are handled by the same mediator. The definition of the virtual domain ledger ensures that transaction UUIDs are unique within the com.daml.api.util.LedgerEffectiveTimeTolerance and within the mediator handling the request, and that the sequencing time deviates from the ledger time by at most this tolerance. So two contracts with the same Unicum must be generated by the same transaction. However, the com.digitalasset.canton.data.ViewPosition and the create index uniquely identify the node in the transaction that creates the contract.
We include both the com.digitalasset.canton.topology.DomainId and the com.digitalasset.canton.topology.MediatorId in the ContractSalt because we cannot exclude that mediators on different domains happen to have the same identifier and there may be mupltiple mediators on a domain.
- If the submitter is honest and chooses a random transaction seed,
the [[Unicum]] does not leak information about template arguments.
The transaction seed's randomness propagates to the action seed through the seed derivation scheme. Since the honest submitter does not leak the transaction seed and shows the action seed only to the witnesses of the view, the ContractSalt looks random to non-witnesses of the view. Accordingly, the ContractSalt blinds the template arguments. - The [[Unicum]] authenticates the contract details (ledger time and template arguments)
if the hash function is preimage resistant.
By checking the hash of the ContractSalt and the contract details against the Unicum, everyone can verify that they fit together. As the hash function is preimage resistant, it is therefore computationally infeasible for a participant to find a different ContractSalt such that different contract details lead to the same hash. - Participants learning about the contract only through divulgence or disclosure do not learn in which transaction the contract was created
unless the submitter or witnesses of the creation leak this information.
By the honesty assumption, the action seed is a random value to those participants. Accordingly, since the ContractSalt contains all the information that ties the contract to a particular transaction, the participants cannot say which transaction with the same ledger time created the contract. - The [[Unicum]] does not leak the contract details when a contract ID is shown to a third party
if the submitter and all witnesses and divulgees are honest.
By the honesty assumption, the action seed is a random value to the third party, and so is the ContractSalt. This entropy hides the contract details to the third party.
- Alphabetic
- By Inheritance
- UnicumGenerator
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native() @HotSpotIntrinsicCandidate()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def generateSaltAndUnicum(domainId: DomainId, mediator: MediatorRef, transactionUuid: UUID, viewPosition: ViewPosition, viewParticipantDataSalt: Salt, createIndex: Int, ledgerTime: CantonTimestamp, metadata: ContractMetadata, suffixedContractInstance: SerializableRawContractInstance, contractIdVersion: CantonContractIdVersion): (ContractSalt, Unicum)
Creates the ContractSalt and Unicum for a create node.
Creates the ContractSalt and Unicum for a create node.
- domainId
the domain on which this transaction is sequenced
- mediator
the mediator that is responsible for handling the request that creates the contract
- transactionUuid
the UUID of the transaction
- viewPosition
the position of the view whose core creates the contract
- viewParticipantDataSalt
the salt of the com.digitalasset.canton.data.ViewParticipantData of the view whose core creates the contract
- createIndex
the index of the node creating the contract (starting at 0). Only create nodes and only nodes that belong to the core of the view with salt
viewActionSalt
have an index.- ledgerTime
the ledger time at which the contract is created
- metadata
contract metadata
- suffixedContractInstance
the serializable raw contract instance of the contract where contract IDs have already been suffixed.
- contractIdVersion
version of contract ID used
- See also
UnicumGenerator for the construction details and the security properties
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @HotSpotIntrinsicCandidate()
- def recomputeUnicum(contractSalt: Salt, ledgerTime: CantonTimestamp, metadata: ContractMetadata, suffixedContractInstance: SerializableRawContractInstance, contractIdVersion: CantonContractIdVersion): Either[String, Unicum]
Re-computes a contract's Unicum based on the provided salt.
Re-computes a contract's Unicum based on the provided salt. Used for authenticating contracts.
- contractSalt
the ContractSalt computed when the original contract id was generated.
- ledgerTime
the ledger time at which the contract is created
- metadata
contract metadata
- suffixedContractInstance
the serializable raw contract instance of the contract where contract IDs have already been suffixed.
- contractIdVersion
version of contract ID used
- returns
the unicum if successful or a failure if the contract salt size is mismatching the predefined size.
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])