DEV Community


Posted on

Account Authorization using Soroban AssemblyScript SDK

Hi! In my previous posts, i already covered many things such as storing data, logging contract, and defining error code. In this post I will take it to the next level, authorization. Authorization is one of security measure used in smart contracts, it can be used to various things such as allowing specific verified users to call a function, allowing specific users access stored data, and many more.

In this post i will explain Account authorization smart contract example that implements authorization control and updating account values stored in chain state.

The Contract Code

The contract code will be similar to my previous post with additional code to do account authorization. Let's dive into the code:

import {AddressObject, MapObject, RawVal, fromU32, toU32} from 'as-soroban-sdk/lib/value';
import {Map} from 'as-soroban-sdk/lib/map';
import * as ledger from 'as-soroban-sdk/lib/ledger';
import * as address from 'as-soroban-sdk/lib/address';
Enter fullscreen mode Exit fullscreen mode

In this section, we import the necessary modules from the as-soroban-sdk library. The ledger module provides functions for interacting with the blockchain's storage. The RawVal, toU32, fromU32, AddressObject, and MapObject type is imported from the value module. Map imported from map module to act as stored data format. ledger and address module imported for any operation regarding ledger dan address operations.

export function increment(user: AddressObject, value: RawVal): MapObject {

  var counter = 0;

  if (ledger.hasData(user)) {
    let dataValue = ledger.getData(user);
    counter = toU32(dataValue);

  counter += toU32(value);
  let counterVal = fromU32(counter);
  ledger.putData(user, counterVal);

  let map = new Map();
  map.put(user, counterVal);

  return map.getHostObject();
Enter fullscreen mode Exit fullscreen mode

The purpose of this function is to increment a counter associated with a given user's address in the Soroban ledger. The address.requireAuth(user) call at the beginning of the function ensures that the user has authorized the transaction before it can proceed.

The next block of code checks whether the user already has data associated with their address in the ledger using the ledger.hasData(user) function. If the user has data, it retrieves the current value of the counter using ledger.getData(user) and converts it to a 32-bit unsigned integer using the toU32 function. If the user does not have data, the counter is initialized to zero.

The counter variable is then incremented by the value of value, which is also converted to a 32-bit unsigned integer using toU32. The updated value of counter is then converted back to a RawVal value using fromU32 and stored in the ledger using the ledger.putData(user, counterVal) function.

Finally, a new Map is created and the updated counter value is added to it using map.put(user, counterVal). The Map is then returned as a MapObjectusing map.getHostObject().

Next, create contract.json file in your project directory, this file contains metadata for the contract.

    "name": "Store and Retrieve Data Contract (Account Auth)",
    "version": "0.1.0",
    "description": "example",
    "host_functions_version": 29,
    "functions": [
            "name" : "increment",
            "arguments": [
                {"name": "user", "type": "address"},
                {"name": "value", "type": "u32"}
            "returns" : "map[address, u32]"
Enter fullscreen mode Exit fullscreen mode

Before compiling the contract, we need to edit the asconfig.json file of your project. Replace its content with the following:

  "extends": "as-soroban-sdk/sdkasconfig",
  "targets": {
    "release": {
      "outFile": "build/release.wasm",
      "textFile": "build/release.wat"
    "debug": {
      "outFile": "build/debug.wasm",
      "textFile": "build/debug.wat"
Enter fullscreen mode Exit fullscreen mode

The asconfig.json file is used by the AssemblyScript compiler (asc) to define the configuration for your project.

Compiling the Contract

You need to compile it into WebAssembly first. To do this, you'll use the following command :

npx asc assembly/index.ts --target release
Enter fullscreen mode Exit fullscreen mode

Now you should see two new files in the build/ directory: release.wasm and release.wat.

We will use 2 different account to invoke this contract.Let's run the contract to see if it's works, we're gonna run the contract using soroban-cli on sandbox using the following command :

soroban contract invoke \
    --id 1 \
    --wasm build/release.wasm \
    --fn increment \
    -- \
    --value 10
Enter fullscreen mode Exit fullscreen mode

You can run it a couple of times with any desired --value. And invoke the function using another account :

soroban contract invoke \
    --id 1 \
    --wasm build/release.wasm \
    --fn increment \
    -- \
    --value 5
Enter fullscreen mode Exit fullscreen mode

And after couple of times invoking the function with 2 different accounts, you can check all stored data on that contract using this command:

soroban contract read --id 1
Enter fullscreen mode Exit fullscreen mode

You should get similar output to:

Enter fullscreen mode Exit fullscreen mode

Contract Storage


Overall, this code provides a simple example of how Account Authorization works using the AssemblyScript SDK. By using the address.requireAuth and address.requireAuthForArgs functions, this code ensures that only authorized users can modify the counter associated with their address. Happy Sorobaning!

Top comments (0)