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.

Tutorial Thumbnail
Intermediate · 30 minutes

Algo Builder Tutorial Part 3: Stateful Smart Contracts

This is the third tutorial from the Algo Builder series:

In this tutorial we present how our algob helps the developers to wield the power of Stateful Smart Contracts with TEAL.

Requirements

  • Good knowledge about Blockchain and Algorand.
  • Detailed introduction to algob
  • Detailed knowledge about assets, accounts, transactions and signatures.
  • Brief Stateful Smart Contracts

Steps

1. Creating TEAL files

In the algob project structure, the TEAL and PyTEAL code files are always placed in the /assets directory:

algob project:
├── assets
   ├── TEAL files
   ├── PyTEAL files
├── scripts
 ├── deploy.ts
   ├── run.ts
├── package.json

Example

We will create a simple stateful smart contract which will:
- Have a global variable counter
- Will increment counter each time we call the application.

Full example can be found here

2. Create a file with Approval Program

We will create a approval program which has global counter and it is incremented when we call the application. Put the code below in /assets/approval_program.teal:

#pragma version 2

int NoOp
txn OnCompletion
==

bnz application_call

int 1
return

application_call:

// read global state
byte "counter"
dup
app_global_get

// increment the value
int 1
+

// store to scratch space
dup
store 0

// update global state
app_global_put

// load return value as approval
load 0
return

This program has a single global key/value pair to store the number of times the program was called. The key is the string “counter” and the value will be defined as an integer when the application is created.

3. Create a file with Clear Program

Now, we will create clear program. This program does not evaluate any conditions and simply approves the call. Put the code below in /assets/clear_program.teal:

#pragma version 2

int 1
return

4. Deploy New Application

To deploy the contract use the following code in a new file named deploy.js in scripts folder of your project directory:

Create user accounts

  const masterAccount = deployer.accountsByName.get('master-account');
  const creatorAccount = deployer.accountsByName.get('alice');

  const algoTxnParams = {
    type: types.TransactionType.TransferAlgo,
    sign: types.SignType.SecretKey,
    fromAccount: masterAccount,
    toAccountAddr: creatorAccount.addr,
    amountMicroAlgos: 200000000,
    payFlags: {}
  };
  // transfer some algos to creator account
  await executeTransaction(deployer, algoTxnParams);

In the code above we declare user accounts and fund creatorAccount account. masterAccount is the default account used in algob private net.

Deploy stateful contract

Firstly we need to put some money into the contract. master account will fund it:

  // Create Application
  // Note: An Account can have maximum of 10 Applications.
  const sscInfo = await deployer.deploySSC(
    'approval_program.teal', // approval program
    'clear_program.teal', // clear program
    {
      sender: creatorAccount,
      localInts: 1,
      localBytes: 1,
      globalInts: 1,
      globalBytes: 1
    }, {});

  console.log(sscInfo);

Parameters passed are:
- Approval Program
- Clear Program
- SSC(stateful smart contract) arguments which includes sender and details for storage usage.
- Transaction parameters

  • In above code we have deployed a new application.

  • After deploying application you will get the following information on your terminal:

Created new app-id: 189
{
  creator: 'EDXG4GGBEHFLNX6A7FGT3F6Z3TQGIU6WVVJNOXGYLVNTLWDOCEJJ35LWJY',
  txId: 'BCP3ZKT26K2BEB475OMKQHOMBEFVWEHESRS3XMAWQEVASFP6JFUA',
  confirmedRound: 13899,
  appID: 189
}

5. Opt-In to Application

To Opt-In to an application use the following code in one of your scripts (in ./scripts):

    await deployer.optInAccountToSSC(creatorAccount, sscInfo.appID, {}, {}); 

where Account is the account you want to opt-in and applicationID is application index.

6. Call Application

To call an application use the following code in one of your scripts (in ./scripts):

    const tx = {
      type: types.TransactionType.CallNoOpSSC,
      sign: types.SignType.SecretKey,
      fromAccount: creatorAccount,
      appId: applicationID,
      payFlags: {}
    }

    await executeTransaction(deployer, tx);

In tx there are following parameters:
- we set the type which is CallNoOpSSC - Call to stateful smart contract
- set the sign to SecretKey
- provide fromAccount details
- provide application index of SSC
- provide payment flags. If any (fee, firstValid, lastvalid etc)

Calling application each time will increase the stateful counter by 1.
To view the global state of the application you can use the following code:

  // Retreive Global State
  let globalState = await readGlobalStateSSC(deployer, creatorAccount.addr, applicationID);
  console.log(globalState);

Output:

[ { key: 'Y291bnRlcg==', value: { bytes: '', type: 2, uint: 2 } } ]
[ { key: 'Y291bnRlcg==', value: { bytes: '', type: 2, uint: 3 } } ]

here key ‘Y291bnRlcg==’ is converted form of counter.

7. Update Application

To update application you can use the code below in your script:

 const updatedRes = await deployer.updateSSC(
    creatorAccount,
    {}, // pay flags
    applicationID,
    'new_approval.teal',
    'new_clear.teal',
    {}
  );
 console.log('Application Updated: ', updatedRes);

8. Delete Application

To delete application you can use the code below in your script:

    const tx = {
      type: types.TransactionType.DeleteSSC,
      sign: types.SignType.SecretKey,
      fromAccount: creatorAccount,
      appId: applicationID,
      payFlags: {},
      appArgs: []
    }

    await executeTransaction(deployer, tx);