Disclaimer: As @Gary_Verhaegen pointed it out, users should consider contract IDs as opaque blocks.
In earlier SDKs, contract IDs were ledger-specific strings assigned before committing the transaction on the ledger but after DAML evaluation. Concretely, during evaluation of a DAML program, the engine was using special placeholders (called relative contract IDs) to identify contracts created within the transaction being built. Those relative contract IDs were later substituted with their final value by the ledger implementation.
The main drawback of this approach was that the contract IDs could not be ordered in a stable way. Because it was not known at interpretation time to which string a relative contract ID will be assigned, it was not possible to compare in a stable way a relative contract ID with another contract ID.
Staring from SDK 1.0.0, contract IDs are built from a cryptography hash (called a discriminator), computed during evaluation via a deterministic derivation scheme from an initial high-entropy number (called a submission seed) picked at submission time. The scheme leaves the ledger implementation free to suffix the contract ID as its convenience before committing the transaction. Without entering too much into the details, the derivation scheme guarantees that if the submission seed was never used before, (1) the discriminators of contract IDs created by the transaction are globally unique and (2) that no information about the transaction can be inferred from one of the discriminators given alone.
Assuming a participant is honest and chooses a proper high-entropy submission seed for each of its submissions, the uniqueness property we describe above ensures that only the discriminators, not the suffix are needed to order the contract IDs of created contracts w.r.t. other contract IDs. Upcoming SDKs will take advantage of this, and provide new builtins to order contract IDs and a new kind of ordered map where keys can contain arbitrary serializable values, including contract IDs.
Additionally, this new scheme makes it easier for a particular ledger implementation to limit information leakage through contract IDs. For instance, Sandbox, which chooses itself a fresh submission seed for each submission, uses the discriminator without a suffix, hence leaking (almost) no information through the contract IDs it generates. Though, exact security properties rely on a particular ledger implementation and how it uses contract ID suffixes.
I’m very much interested to know how I could order the new contract ids by created time. It’s often a concern in UIs where I want to display contracts in the order they’ve been created. Adding a field on the contracts just for that seems an overkill. The previous implementation (#1:0, #2:0, …) made this straight forward.
Concerning the benefits of the new scheme from a users’ perspective I read:
Contract IDs can soon be used as part of map keys.
DAML-LF now enforces for all ledger implementations that contract IDs do not leak information about the transaction. (Previously, this was only true for some ledger implementations.)
@georg all contracts have two timestamps: Record Time and Ledger Effective Time. We also have an offset, which is the order in which things are output through the Ledger API
Both are monotonous with causality on the ledger,
Ledger Effective Time is available in DAML via getTime
RecordTime is more likely to be comonotonous with ledger offset
Is what you are after is have one of those available through the Ledger API so you can sort by them.
@bernhard yes, it’s just about having some way to order them provided through the JSON API, respectively the JS libraries. LET would work just fine for that. I just thought if there’s a way to order contract ids (which @Remy seems to be hinting at) we might not even need that.
The ordering Rémy is talking about is not wtr to contract creation time. It’s just some stable ordering that you can use to implement things like ordered maps.
@Leonid_Shlyapnikov. Contract IDs are simply compared lexicographically. The discriminator being a cryptographic hash (it looks like random), the resulting ordering does not have any special property. As stated by @MatthiasSchmalz this is important to not leak information.
Sorting contract IDs from a DAML program will be available soon in an upcoming SDK. To sort contract IDs in a client, one can simply compare them lexicographically and it will obtain the same result than in DAML.
As stated before, users should consider contract IDs as opaque blocks and not try to scrutinize them. In other words one should not try to extract discriminator from a contract ID.
Concerning your first question, Yes, it will be soon possible to use Contract IDs as map keys.
Concerning your second question, unfortunately no. Contract IDs in a particular ledger implementation may still leak information. This all depends on how contract ID are suffixed. However for ledger implementations that do not have to suffix contract ID (like Sandbox and vDAML) this property is guaranteed.
I did not mention it before, but the new scheme makes it also difficult for an attacker to guess the IDs of contracts that actually exist on the ledger. This adds a level of security in to all DAML ledger implementations.
@georg Take in consideration that nothing in the design of DAML enforces that a contract ID actually refers to a contract existing on the ledger. Dishonest participants can use arbitrary contract IDs inside their requests.
Furthermore it will be too costly (and very impractical in client side) to have to fetch contracts every-time one have to compare two contract IDs.