Create Publication

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Article Thumbnail

Algorand Unlimited Assets and Smart Contracts


With the 3.5.1 release, Algorand now supports unlimited Assets and Smart Contracts per address! This upgrade will open up additional options and application scenarios for developers. This article covers some of these as well as additional API changes and constraints that developers should be aware of.

Note

In order to support this much more flexible model, the engineering team invested significant time optimizing the underlying database structure to improve the performance of the ledger. Because of this refactoring, when the node or indexer is updating it will take longer than normal to complete the upgrade. During this time, the node will not participate in consensus or respond to REST calls. These times are estimated below but are largely dependent on your specific hardware.

  • 3.5.1 Algod MainNet non-archival node - ~15 minutes
  • 3.5.1 Algod MainNet archival node - ~60 minutes
  • 2.10.0 Indexer MainNet - ~30 minutes

Unlimited Assets and Applications

In prior releases, Algorand limited the number of Assets and Applications (ie Contracts) that a specific account could create or opt into. This constraint was largely for performance reasons but made building large-scale projects more challenging. This release represents the culmination of a great deal of work to address the performance concerns and allow these limits to be removed.

With this change, developers can easily create larger scale NFT projects, event-based ticketing apps, music and video rights, on-chain software licensing, gaming digital assets or currencies, and many others. Additionally, this allows single accounts to participate in an unlimited set of applications (i.e. DeFi Apps), NFT collections, and marketplaces.

Algod and Indexer API Changes

With the change comes some modifications and new APIs available to manipulate large asset and contract data lists. Examples shown are using curl, but are also available in all the SDKs. These changes are summarized below. See the REST API (Algod and Indexer) schemas for additional information. Also, see the developer documentation for the Indexer to get more details on calling and parsing the results using the Indexer SDK APIs.

Algod REST API Modifications

The Algod REST API GET /v2/account/{address} was changed to support the new unlimited model. A new flag is available to the call to support displaying a reduced set of information. The parameter exclude can be set to all or none.

Example abbreviated account record returned for the exclude flag set to none or the flag is omitted.

{
   "address":"W6R…Y",
   "amount":3999999999998000,
   "amount-without-pending-rewards":3999999999998000,
   "apps-local-state":[
      {
         "id":25,
         "schema":{
            "num-byte-slice":0,
            "num-uint":0
         }
      }
   ],
   //Smart Contracts Opted Into - Local State
   "apps-total-schema":{
      "num-byte-slice":0,
      "num-uint":0
   },
   //Assets Opted Into
   "assets":[
      {
         "amount":0,
         "asset-id":31,
         "is-frozen":false
      }
   ],
   //Created Applications(Contracts)
   "created-apps":[

   ],
   //Created Assets
   "created-assets":[

   ],
   "min-balance":300000,
   "participation":{
      "selection-participation-key":"wkf0Z8hDERFDW65KEMCDHzacP1D/d0yxYlWoG5rJYcw=",
      "state-proof-key":"tMABZKNjOxaadSfsIKglZr/FUwUTQmYwKP3O8kISHtSn5LFQW/NJX+usLVQVxo/0YKKpf27Nuyt7/TgyMtnJbQ==",
      "vote-first-valid":0,
      "vote-key-dilution":10000,
      "vote-last-valid":10000,
      "vote-participation-key":"E6s7WQ6GLIcC0/udcMX2yEN4KuByjTp9pG60r8lX5ZU="
   },
   "pending-rewards":0,
   "reward-base":0,
   "rewards":0,
   "round":25,
   "status":"Online",
   //Totalized Assets and Contracts
   "total-apps-opted-in":1,
   "total-assets-opted-in":1,
   "total-created-apps":0,
   "total-created-assets":0
}

When set to all, account details are returned but the assets and applications created or opted into by the account are removed from the list. You will still get a totalized number of assets and applications created or opted into, but no additional details.

curl "$BASE_URL/accounts/$ASSET_ACCOUNT?exclude=all" -H "$TOKEN_HEADER"

When set to none, the lists of assets and applications the user has created or opted into are displayed. This will also contain asset and contract configuration information. If this list returns more than 100K (default) items, the REST call will automatically generate a 400 error code and fail. This maximum can be configured ( using the MaxAPIResourcesPerAccount node setting) specifically for a node to raise this limit if needed.

curl "$BASE_URL/accounts/$ASSET_ACCOUNT?exclude=none" -H "$TOKEN_HEADER"

New Algod REST Calls

Two new REST API calls are available within the Algod REST endpoint. One to retrieve asset data (GET /v2/accounts/{address}/assets/{ID}) and one to return application data (GET /v2/accounts/{address}/application/{ID}) for a specific account and ID.

The GET /v2/accounts/{address}/assets/{ID} REST endpoint returns the account’s holding amount and the frozen status of the asset. If the user also created the asset, creation configuration information is also returned. Additionally, the current round number is returned.

curl "$BASE_URL/accounts/$ASSET_ACCOUNT/assets/$ASSET_ID" -H "$TOKEN_HEADER"

The GET /v2/accounts/{address}/application/{ID} REST endpoint returns the account’s local state for the application if the account has opted into the contract. If the user created the contract, the contract’s configuration parameters are also returned. Additionally, the current round number is returned..

curl "$BASE_URL/accounts/$APP_ACCOUNT/applications/$APPLICATION_ID" -H "$TOKEN_HEADER"

Indexer REST API Modifications

The Indexer REST API call GET /v2/accounts/{address} has been modified to support large data sets.

If this call returns more than 1K (default) items, the REST call will automatically generate a 400 error code and fail. This maximum can be configured ( using the MaxAPIResourcesPerAccount indexer setting) specifically for the indexer to raise this limit if needed. Additionally, this call supports pagination if you supply a limit parameter and use the next-token field. See Paginated Results for more information.

Below is an example of an abbreviated account record returned by the Indexer.

{
   "account":{
      "address":"OUN…",
      "amount":"....",
      //Smart Contracts Opted Into - Local State
      "apps-local-state":[
         {
            "deleted":false,
            "id":25,
            "opted-in-at-round":24,
            "schema":{
               "num-byte-slice":0,
               "num-uint":0
            }
         }
      ],
      //Assets Opted Into
      "assets":[
         {
            "amount":10,
            "asset-id":31,
            "deleted":false,
            "is-frozen":false,
            "opted-in-at-round":23
         }
      ],
      //Created Applications(Contracts)
      "created-apps":[
         {
            "created-at-round":19,
            "deleted":false,
            "id":25,
            "params":{
               "approval-program":"BiAC…Q==",
               "clear-state-program":"BoEBQw==",
               "creator":"OUN….",
               "global-state-schema":{
                  "num-byte-slice":0,
                  "num-uint":0
               },
               "local-state-schema":{
                  "num-byte-slice":0,
                  "num-uint":0
               }
            }
         }
      ],
      //Created Assets
      "created-assets":[
         {
            "created-at-round":23,
            "deleted":false,
            "index":31,
            "params":{
               "clawback":"OUN…",
               "creator":"OUN…..",
               "decimals":0,
               "default-frozen":false,
               "freeze":"OUN…",
               "manager":"OUN…",
               "name":"tester",
               "name-b64":"dGVzdGVy",
               "reserve":"OUN…",
               "total":10
            }
         }
      ],
      "created-at-round":0,
      "deleted":false,
      "participation":{
         "selection-participation-key":"tLi0x…4=",
         "state-proof-key":"dz….w==",
         "vote-first-valid":0,
         "vote-key-dilution":10000,
         "vote-last-valid":10000,
         "vote-participation-key":"pA…Y="
      },
      "pending-rewards":0,
      "reward-base":0,
      "rewards":0,
      "round":23,
      "sig-type":"sig",
      "status":"Online",
      //Totalized Assets and Contracts
      "total-apps-opted-in":1,
      "total-assets-opted-in":1,
      "total-created-apps":1,
      "total-created-assets":1
   },
   "current-round":23
}

A new flag is available that will reduce the amount of data this call returns. The parameter exclude can be set to all, created-apps, created-assets, apps-local-state, assets, or none.

With the flag set to all, this call will return account information for the specific address but will not return any asset or contract detailed information. Totalized numbers of assets and applications opted into or created will be returned though.

curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT?exclude=all" -H "$TOKEN_HEADER"

When the filter is set to none all account information is returned. The return set will include assets opted into, assets created, local state for applications opted into, and created applications.

If the flag is set to created-assets, the account details will be returned but will exclude any information on created assets. Applications created or opted into will still be returned. Assets opted into will still be returned.

curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT?exclude=created-assets" -H "$TOKEN_HEADER"

If the flag is set to created-apps, the account details will be returned but will exclude any information on created applications. Assets created or opted into will still be returned. Local state for applications opted into will still be returned.

curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT?exclude=created-apps" -H "$TOKEN_HEADER"

If the flag is set to app-local-state, the account details will be returned but will exclude any information on local state of applications the account has opted into. Assets created or opted into will still be returned. Created applications will still be returned.

If the flag is set to assets, the account details will be returned but will exclude any information on assets the account has opted into. Applications created or opted into will still be returned. Created assets will still be returned.

Note

The creator field has also been removed from the assets section of the account record.

New Indexer REST Calls

Individual sections of the account record can be retrieved as well, using one of several new Indexer REST API calls. These calls GET /v2/accounts/{address]/created-apps, GET /v2/accounts/{address}/created-assets, GET /v2/accounts/{address}/assets, and GET /v2/accounts/{address}/apps-local-state retrieve the individual sections of the account record.

#created apps
curl "$INDEXER_URL/accounts/$APP_ACCOUNT/created-apps" -H "$TOKEN_HEADER"
#created assets
curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT/created-assets" -H "$TOKEN_HEADER"
#local state for applications opted into
curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT/apps-local-state" -H "$TOKEN_HEADER"
#Assets opted into
curl "$INDEXER_URL/accounts/$ASSET_ACCOUNT/assets" -H "$TOKEN_HEADER"

These new calls can also be filtered using a few new query flags. The results can be returned for a specific ID if set using the asset-id or application-id flags.

The number of results is still restricted to the MaxAPIResourcesPerAccount indexer setting but can be limited using the limit flag and paginated using the next-token result field. See Paginated Results for more information. By default, the results only show current Assets and Applications that have been created or opted into. Deleted assets and applications are not returned. By using the include-all flag and setting it to true, these calls will return all items including deleted applications, destroyed assets, opted-out asset holdings, and closed-out application local states.