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
Beginner · 30 minutes

Using Java Algorand SDK with Spring Boot

Spring Boot is very popular with Java developers. Using the dependency injection and other features of the Spring Framework, the application can be made more readable and robust. This tutorial is to showcase how to use the Algorand Java SDK and the Spring Framework together.

Requirements

Background

I have selected a simple example to showcase how to interact with the Algorand network. There will be 2 accounts: Bob and Alice. Alice will transfer 1 ALGO to Bob and we verify that the transfer was successful using a Junit test. The example is similar to this tutorial but I use in a Spring idiomatic way. Note that this tutorial is intended for experienced Spring developers, therefore, I do not explain in detail about the Spring Framework.

Steps

1. Install Sandbox

Follow the instruction here to setup a sandbox environment on your computer. Start the sandbox in a private network mode:

./sandbox up

2. Checkout code from GitHub

Checkout the following Spring Boot application from GitHub:

git clone https://github.com/urajbhandari/boot-algorand

Load the code in a Java IDE such as Intellij.

Note that in the Maven’s pom.xml the Java version is specified as 15:

    <properties>
        <java.version>15</java.version>
    </properties>

You can change this version to match the Java version that you have on your computer as long as it is 8 or higher.

3. Create two Algorand accounts

Run com.demo.boot.algorand.util.AccountUtil‘s main method. It will output text similar to the following:

app:
  accounts:
    alice:
      address: 634XGEIC3YHBMEO5P4N7XDUQ3VC7U6MQGG3C5MYEQO5O7WFRBY757PHLKQ
      mnemonic: spare despair spice pottery fuel pledge canyon body urge bridge usual admit father remind ordinary gaze tilt vessel wine split include advance few ability beef
    bob:
      address: H3WZQIYC3MYU7PQRGTGZKGLTK4BWDFTMW5BBYGRW3SZKLTNSWYQWXOHE5U
      mnemonic: moment dog buyer auction myth much police marble slim report runway atom destroy ramp hunt grass divert afford daring melody mouse plug fit abstract road

Paste this content into application.yaml. Note that application.yaml already has accounts setup. The existing values will also work because I pasted the values and checked into git.

4. Transfer ALGOs to Alice

For Alice to transfer ALGOs to Bob, she must have some ALGOs first. In the example above, Alice’s address is 634XGEIC3YHBMEO5P4N7XDUQ3VC7U6MQGG3C5MYEQO5O7WFRBY757PHLKQ (you may have different address). To transfer 100 ALGOs to Alice run the following command line command from the sandbox directory:

./sandbox goal clerk send -a 10000000 -f KWW3LGTW4AVPWEUUERQ4IN2OMCA2WZPEZSACB2HV774U5C5HV6XBLTTXEM -t 634XGEIC3YHBMEO5P4N7XDUQ3VC7U6MQGG3C5MYEQO5O7WFRBY757PHLKQ

When the sandbox private network starts, it comes with a few accounts populated with ALGOs. The from (-f) account above already has ALGOs. To see the list of accounts and the balance you can use the following command:

./sandbox goal account list

5. Run Junit Test

There is one test in com.demo.boot.algorand.service.AlgoTransferServiceTest with the method name testTransferAlgoFromAliceToBob(). Run that test. The test should pass.
This is the test method:

    @Test
    void testTransferAlgoFromAliceToBob() throws Exception {
        Account aliceAccount = accountFactory.getAccountByAlias("alice");
        Long aliceAccountInitialBalance = accountService.getAccountBalance(aliceAccount);
        log.info("Alic account initial balance: " + aliceAccountInitialBalance);
        //if account balance is less than 0.001 (which is equivalent to 1000microAlgo) Algo, fail the test
        if (aliceAccountInitialBalance < 1000) {
            Assertions.fail("Alice account does not have enough balance: " + aliceAccountInitialBalance);
        }
        Account bobAccount = accountFactory.getAccountByAlias("bob");
        Long bobAccountInitialBalance = accountService.getAccountBalance(bobAccount);
        log.info("Bob account initial balance: " + bobAccountInitialBalance);

        //transfer the amount
        int transferAmountMicroAlgos = 1000000;
        String note = "Alice to Bob micro algo transfer: " + transferAmountMicroAlgos;
        PendingTransactionResponse transactionResponse = transferService.transferAlgo(aliceAccount, bobAccount.getAddress(),
                transferAmountMicroAlgos, note);

        //verify the account balances are correct after the transfer
        Long aliceAccountBalanceAfterTransfer = accountService.getAccountBalance(aliceAccount);
        Long bobAccountBalanceAfterTransfer = accountService.getAccountBalance(bobAccount);
        assertThat(aliceAccountBalanceAfterTransfer).isEqualTo(aliceAccountInitialBalance - transferAmountMicroAlgos - 1000);
        assertThat(bobAccountBalanceAfterTransfer).isEqualTo(bobAccountInitialBalance + transferAmountMicroAlgos);
        assertThat(getNote(transactionResponse)).isEqualTo(note);
    }

Initially Alice would have 100 ALGOs and Bob would have 0. The transfer amount in the above code is 1 ALGO (or 1000000 micro ALGOs). After the transfer, we verify that both Alice’s and Bob’s accounts have expected amount of ALGOs.

6. Understanding the code

You can use the Junit test as the starting point to explore the logic implemented. Here are some of the main points:

6.1 AppConfig.java

AlgodClient is specified a Spring bean. AlgodClient enables us to interact with the Algorand network. Because of @EnableConfigurationProperties(AppProperties.class), the values of application.yaml are read into AppProperties.class Spring Bean.

@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
    @Bean
    public AlgodClient algodClient() {
        final String ALGOD_API_ADDR = "localhost";
        final int ALGOD_PORT = 4001;
        final String ALGOD_API_TOKEN = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

        return new AlgodClient(ALGOD_API_ADDR, ALGOD_PORT, ALGOD_API_TOKEN);
    }
}

6.2 AlgoTransferService.java

This is the main logic for transferring ALGOs from fromAccount to toAddress:

public PendingTransactionResponse transferAlgo(Account fromAccount, Address toAddress, long amountMicroAlgos, String note) throws Exception {
    Transaction txn = createTransaction(fromAccount, toAddress, amountMicroAlgos, note);

    SignedTransaction signedTxn = signTransaction(fromAccount, txn);

    String id = submitTransactionToNetwork(signedTxn);

    PendingTransactionResponse pTrx = waitForTxnConfirmation(id, 4);
    log.info("Transaction " + id + " confirmed in round " + pTrx.confirmedRound);

    return pTrx;
}

First we create a transaction. Then we sign the transaction. Then we submit the transaction. Lastly, we wait for the transaction to be confirmed until next 4 rounds.