Is it possible to get all utxos from address but with specific order for example from the oldest to the newest ones? I am not sure in which order this function utxosAt
returns: https://github.com/input-output-hk/plutus-apps/blob/404af7ac3e27ebcb218c05f79d9a70ca966407c9/plutus-contract/src/Plutus/Contract/Request.hs#L397
-
1I am not familiar with this function, but if you could share a/the result from the function, that might be helpful.– Jacob - SNOWY PoolNov 8, 2021 at 3:40
3 Answers
You could use Time Tokens, this solution is proposed by Minswap team:
An effective way to prevent malicious ordering is to make each batch request hold a time token. A time token can only be created if its asset name is a timestamp that is after the validation range upper bound. This prevents anybody from creating a time token in the past. This BR will only be validated if all BRs in the same transaction are of the same type and are ordered by this time token. This enforces that there would only be one way to order BRs in one transaction.
Here is one way:
If you print out the result of utxosAt
you'll see that each UTxO has a field txValidRange
which is the slot range over which the Tx could have been executed. By default that field is set to
txValidRange = Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound PosInf True}
This isn't helpful in your case, since it means it could have been executed any time.
When constructing a Tx, however, you can constrain the valid range:
Constraints.mustValidateIn (interval (Slot 11) (Slot 11))
Which will change the valid range to:
txValidRange = Interval {ivFrom = LowerBound (Finite (Slot {getSlot = 11})) True, ivTo = UpperBound (Finite (Slot {getSlot = 11})) True}
You can then know that this UTxO was created on slot 11 (if not, the Tx would have failed execution), and use these values to sort the UTxOs.
Notes:
In my experience, the txValidRange
is useful in Plutus scripts, since the execution is deterministic, i.e. you can check the valid range of the tx, but you can't check the current slot from within the script. I'm not sure that means the execution slot isn't knowable after the fact though, outside of the script.
I'm going to dig into the codebase a little and see if there is a way to lookup a UTxO after it's added to the chain to see when it was added. For now the above answer is the best I've got.
The UTxO itself doesn't provide information on the time it was created. However, each UTxO is part of a transaction.
- Using blockfrost.io you could query all UTxOs of an address: https://docs.blockfrost.io/#tag/Cardano-Addresses/paths/~1addresses~1{address}~1utxos/get
This will give you a list of UTxO that look like this:
{
"tx_hash": "39a7a284c2a0948189dc45dec670211cd4d72f7b66c5726c08d9b3df11e44d58",
"output_index": 0,
"amount": [],
"block": "7eb8e27d18686c7db9a18f8bbcfe34e3fed6e047afaa2d969904d15e934847e6",
"data_hash": "9e478573ab81ea7a8e31891ce0648b81229f408d596a3483e6f4f9b92d3cf710"
}
- Using the
tx_hash
of each UTxO, you can query the transactions: https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}/get
Besides other information, you can see the block_time
(UNIX timestamp) there:
{
"hash": "1e043f100dce12d107f679685acd2fc0610e10f72a92d412794c9773d11d8477",
"block": "356b7d7dbb696ccd12775c016941057a9dc70898d87a63fc752271bb46856940",
"block_height": 123456,
"block_time": 1635505891,
"slot": 42000000,
...
With this information you can then order your UTxOs. Hope this helps!