Read state with a parameter


I’m trying to create an NFT project on Algorand, and I wonder if it is possible to create a function in a contract that will allow me to read token URI with a specific parameter that I pass. Is there maybe an example of a function like the one I just described (in pyTeal)?

You can easily access in the smart contract the URL:

However, there is no way to read the content of the URL from the smart contract.
Smart contracts (in essentially all the existing public blockchains) cannot access data from the outside world (including websites) directly.
For that purpose, oracles are required.

In some cases, one solution is to have the metadatahash be the hash of the data pointed by the URL and have the caller of the smart contract provide the content pointed by the URL as an application argument.

Thanks for your detailed explanation, @fabrice. I think I understand what you mean in the context of the NFT. But let us consider a more generic case. If I would like to create a method in a smart contract that will allow me to pass a parameter and read a global/local state depending on that parameter, is something like this possible? As far as I understand now, I only can define state variables in the “on_creation” and then query their global / local state, and the only parameter I can pass is account address in a case of local state. Please, correct me if I’m not accurate.

In short yes, you can do all of that.

You can define global / local key / value anytime you want with the restriction that local state can only be set for opt-in accounts.
You can compute the key of the global / local state you want to access / set from anything you want.
For example, you can pass parameters in the “application parameters” array, which is the usual way to specify parameters to an application call.
Usually first parameter is actually the “method” you want to call.
(Soon it will be formally defined as part of the ABI: ARCs/ at main · algorandfoundation/ARCs · GitHub)

The on_creation is just part of a classical skeleton but it does not actually appear in the actual code (the code is completely flattened).

Thanks for making it clear @fabrice. Just to confirm if I understand you correctly, let me take this use case as an example.

Assuming I have a variable balance that equals 100$. Also, I have a condition that I can only use 80% of my balance. In Solidity, I would have a read function that allows me to read balance and perform calculation 100$ * 0.8 and return the result of this operation. I do not need to trigger a write function and update the state for it, I can just call read function and retrieve the result without paying a fee.

In comparison, if I understand correctly, for Algorand, I need to have a separate variable allowed_to_spend_balance that initially will be 0, and later updated to (balance * 0.8) after I trigger a write function. So, I need to call a write method and pay fee for it, and only then I can read a global/local state of this allowed_to_spend_balance. Please, let me know if I can do it without triggering a write function, and how should I do it.

Currently indeed there is no easy way to have read-only methods on Algorand and the only thing you can read easily is the global/local state key/value (what I think you call variable).

You can in theory simulate read-only methods using dry-run endpoints but it’s not straightforward.

This is a known limitation of the current tools that should be fixed soon. (It’s not a limitation of the blockchain itself because you don’t need to record anything on the blockchain for read-only operations.)