Looking for pyteal functions of smart contract app

I am looking for some Pyteal / AlgoSDK functions:

  1. The function writing the global states of specified external contracts.

Currently, the function of App.globalPut in pyteal is only able to write global state inside the given contract. I think the functionality I am looking for looks like App.globalExPut.

  1. The function returning the creator account public address of the smart contract.

This means I am finding something similar to App.getCreator().

  1. The function listing the opted accounts of a given application.

  2. The function returning all transactions engaging inside the noted application.

Any advice?

For security reasons, a smart contract can only modify its own state. Otherwise, you could bypass the logic of any other smart contract by creating your own smart contract. What you can do however, is allowing creating a group of transactions with calls to multiple smart contracts. The smart contracts can then check each other and modify together their states.

I don’t think 2 is currently possible. Do you have a concrete use case where you would need it?

3 and 4 are impossible with layer-1 smart contract for performance reasons.
You can however obtain this information out-of-chain via the indexer: Algorand Developer Docs

If this is no confidential, what kind of dapps are you trying to build?
We can help designing it around the above restrictions.

Thanks @fabrice for your reply.

I think the function listing all opted accounts will be really helpful to my project. However, the app searching functions, like indexer.applications and indexer.search_application, do not return the results that I want. Is there any other function showing the opted accounts?

Also, I have some questions about what you mentioned in your previous answer.

“What you can do however, is allowing creating a group of transactions with calls to multiple smart contracts”. Here, what is creating a group of transaction means? Is that meaning making transactions modifying the global states of several apps at the same time?

Regarding your question on transaction groups ( or transaction grouping ):
A single transaction is trivial. It ensures that once the transaction is submitted and included in a block, the content of the transaction is applied.
Transactions groups extends that to multiple transactions - it allows you to create series of transactions and place them in an “envelope”. Once submitted, the transactions would all get executed ( in the same block ), or would not get executed at all.

Transaction groups allow you to implement more complicated applications as you can have multiple “conditions”, each in it’s own transaction. The transaction group would be included only of all these conditions are met.

Note that this is unrelated to app calls. App calls are just a type of transaction.

Hi fabrice and tsachi, thank you for your help! Our goal is to store many users’ information on Algorand. This can be achieved by asking users to opt in one app where we deploy our smart contract and use their local states as storage of individual user’s information. However, if anyone who wants to see information of all users opted in this app, it’s that possible to achieve this goal using the algosdk?

Regrading the question of modifying other app’s global state, the purpose of this is that if there are operations relying on global states from both apps.

For example, if we need to modify app1’s global state based on the global state of app2. In the current design, we will have to (1) read app2’s global state (2) use app2’s global state to modify app1’s global state.

However, for a malicious user, he can use false app2’s global state (i.e. not the real global state of app2) to update app1’s global state. Do the transaction groups you mentioned above ensure that in step (2) no one can use false app2’s global state. Also, I did not see the transaction group anywhere, do you have any pointers to this?

Thanks again for your continuous help!

However, if anyone who wants to see information of all users opted in this app, it’s that possible to achieve this goal using the algosdk?

Yes, this is possible. You can use the indexer for that purpose. See the REST call there: Algorand Developer Docs
The SDKs support this call.

However, for a malicious user, he can use false app2’s global state (i.e. not the real global state of app2) to update app1’s global state.

Application 1 can directly read application 2 global state using App.globalGetEx State Access and Manipulation — PyTeal documentation
The application 2 global state cannot be faked in that case.
You do not even need group transactions.

Group transactions can however be useful to force both states to be updated together.
Concretely, if you want that after an update to application 2 state, you absolutely want application 1 state to be updated too, you need to group the two application calls transactions together.
This ensures that either both transactions are committed (i.e., both states are updated together) or none of the transactions are committed (i.e., nothing happens).

Group transactions are often just called atomic transfers. (But I prefer personally the name group transactions as they are not limited to transfers.)
See Algorand Developer Docs

1 Like

Thank you so much fabrice! I will try out what you have suggested to see if that works.

Thank fabrice for your reply.

I am wondering about the function displaying all info about opted-in users. I believe there should be some functions of algoSDK wrapping the REST call you have mentioned. But, as far as I know, the indexer functions in algosdk, including indexer.account_info, indexer.application and indexer.search_application, are not able to show the opted-in accounts.

Is it possible to use functions in algoSDK to show all opted-in accounts? If so, could you please point me out the exact indexer function? Thanks in advance!

You need to use “Search Accounts”.
See Algorand Developer Docs

The second example filters by assetID.
Just replace assetID by applicationID, and remove currencyGreaterThan.

Concretely, in JS, something like:

(async () => {
    let applicationID = 312769;
    let accountInfo = await indexerClient.searchAccounts()
        .applicationID(applicationID)
        .do();
    console.log("Information for Account Info for Appliccation: " + JSON.stringify(accountInfo, undefined, 2));
})().catch(e => {
    console.log(e);
    console.trace();
});

take a look at this example to see parsing individual state values for accounts opted into stateful smart contracts: smart-contracts/dex.js at master · algorand/smart-contracts · GitHub

Thanks @JasonW and @fabrice .

Based on what you have mentioned, I find out that python algoSDK function “indexer.accounts” is similar to the JS function “indexerClient.searchAccounts”.

But, when I am trying this “indexer.account” function, it always returns IndexerHTTP error about missing authentication token.

I am not sure about the meaning of this error message, and I have never met this kind of error in using other indexer functions before.

Any thoughts about what is going wrong here?

I also tried JS fucntions introduced by @fabrice .

The results are not promising. It shows forbidden in code 403. There is what happened.

Maybe there is some bugs in my code. I will put it over here.

Any ideas on this error?

In the JS code, you need to make the following changes:

  • the URL should end with idx2 instead of ps2 (the URL ending with ps2 is just for algod, not indexer)
  • port should be "" instead of 8080
  • const client = new algosdk.Indexer(header, server, port);

See PureStake Developer Portal for details.
The above website also give Python examples.

PS1: It is easier for us if you copy the code as text between triple backquotes, like

```js
const token = “…”;
const server = “…”;
```

which prints as:

const token = "...";
const server = "...";

PS2: Since you included your PureStake token in the post, you may want to use a different token for production, as this one can be abused by anyone.

Thank you for your prompt reply @fabrice .

Your answer solves me question perfectly. But I still have some questions on indexer.

In my previous experiment, I assumed the indexer address as “https://testnet-algorand.api.purestake.io/ps2”. Under this settings, the function like indexer.applicaiton and indexer.account_info could run smoothly, while functions of indexer.accounts was not able to run.

So, I am curious about the reason why some indexer functions is only available to run in idx2, when other functions are able to run both in idx2 and ps2.

Could you briefly explain that?

I believe this is because both the indexer and algod provide the functions you mentioned above, while only the indexer allows to search for accounts.
However, the indexer’s responses are much more detailed and contain more fields.