Retrieve the "write" transaction id for a specific key in a map

Hey peers!

I have a simple function that writes maps (string -> string).

  stateful entrypoint set_map(new_map : map(string, string)) : bool =
      only_owner()
      filter_put(set_map_at_index, Map.to_list(new_map), [])
      true

Every set_map call returns a transaction Id.

The question:
Is that somehow possible to retrieve a transaction id of the latest set_map call for a specific Map key?

E.g.

  • first we call set_map with { "key1": "value1"} and as a result it returns a transaction id (let’s call it txid_1 )
  • then we call set_map with { "key1": "value1_altered"} and as a result it returns a transaction id (let’s call it txid_2 )
  • we want to have a function which accepts "key1" string as an argument and returns us txid_2 from the latest set_map call.

Hello @markin.io

@botanicalcarebot.chain or @hanssv.chain, can you please help here?

Thank you,
Albena

1 Like

If I am reading your code correctly set_map will return a boolean (and it will always be true) not sure what transaction id you are referring to?

I’m sorry I can’t figure out what you are trying to do, where does txid_1 come from?

Hello, Hans.

The transaction ids I’m referring to (txid_1, txid_2, txid_n) are being returned by the JavaScript SDK after the successful invocations of the set_map function.

const map = {
    "key1": "value_1",
    "key2": "value_2
}

contractInstance.call("set_map", [map]).then(contractResult => {
    const transactionId = contractResult.hash
})

Let’s say, that we would like to show this transaction ID to a user of our system, but due to some limitations we can store transaction ids within our database only for a limited period of time.

Hence the necessity for the retrieving a transaction ID by the map key.

I’m not very familiar with the JS SDK, but if you want to store the hash of the contract result on-chain I guess you have to make another call to (another) contract - the caveat is that the result of the contract call can’t be available in the call itself (chicken and egg problem).

It sounds like a somewhat strange use case, but nothing stops you from having another contract (or another map in the same contract) where you can write down {"key1" : transactionId }

I’m sorry for not being clear. We haven’t considered storing the hash of the contract result on-chain.
The transaction is there already after the set_map call, so if we know hash, we can check the transaction via æternity Explorer, and that’s the actual business logic - we want to provide a link to the transaction for the end-user.

The problem here is that transaction ids are being wiped out from our database within a week, hence we we can’t display the transaction URL to a user after this period.

But we still know the keys of the map which has been written using the set_map method.
So, having this in mind is that somehow possible to say via smart contract:

Aeternity, please give me the hash of the latest transaction that has been created by set_map function, and the map key was “key1”

? :slight_smile:

This was the bit that mainly confused me, why you remember some things but not others…

In a smart contract context, I don’t think the transaction hash is available while running the transaction, so you would have to do it after the fact, like I suggested by keeping a second map in a contract that connects map-key and transaction hash. Extending the runtime environment of the (FATE) VM with the current transaction hash could be done, it would make your task easier.

In a node context, it isn’t part of the basic node (and will never be) :slight_smile: It sounds very much like some sort of chain indexing functionality… I don’t think the middleware/aeternal has this yet, but perhaps something like this is feasible as an add-on?!

2 Likes

I guess @markin.io is talking about functionality similar to what etherscan offers for contract call transactions, but in sort-of reverse order (?)

Example:

(off-chain implementation): Currently you can implement it by having as script which connects to a middleware instance -> and looks for all of the transactions (contractCalls) for your particular contract address. Then lookup the event log (you need to properly emit on-chain events via Chain.event in your sophia contract) -> decode (via the js-sdk), filter the results -> get your answer.

1 Like

Hey Milen. Nice to hear from you.

As I understand, this solution assumes fetching of the whole transaction history for a specific contract. Is that correct?

I’m asking because I’m concerned about the possible peformance impact of this method since we are expecting a huge amount of transactions to happen.

Hey,

As @hanssv.chain already mentioned such indexing is not yet implemented, so the solution I proposed is just a workaround you can DIY for your use-case (not sure how performant it will be).

If you want you can as well extend the middleware functionality as well.

1 Like

Thank you very much for the assistance. We are going to use this solution.