# 5.1 Composability

On blockchains, single programs living on their own are not usually the norm. In fact, part of what's interesting about developing on a blockchain is that, in theory, anyone can build their own applications leveraging other's tokens, state, features... Things get more interesting when multiple programs work together. This is what we usually call program composability.

## Importing a program

On Aleo a transition from a program can call a transition from another program. Here is how it works in practice.

Let's have a first program example, `arithmetic.aleo`, with a transition that computes the square value of an input.

```bash
leo new arithmetic
cd arithmetic
```

And let's update `arithmentic/src/main.leo` with the following code:

```rust
program arithmetic.aleo {
    transition square_u64(a: u64) -> u64 {
        return a*a;
    }
}
```

Now let's create another program, quadratic residue, that computes the quadratic residue of a number mod another one, using our first transition.

```bash
cd ..
leo new quadratic
cd quadratic
```

Now we need first to add the other program to our list of external dependencies:

```bash
leo add arithmetic --local ../arithmetic
```

`local` argument here is the path to the local Leo folder of the project. If you want to use a program  deployed on chain already, use instead:

```bash
leo add your_program_id.aleo --network testnet # Or mainnet depending on the network
```

Our source file for that program, `quadratic/src/main.leo` will include the following content:

```rust
import arithmetic.aleo;

program quadratic.aleo {
    transition residue(a: u64, n: u64) -> u64 {
        let squared: u64 = arithmetic.aleo/square_u64(a);
        return squared.mod(n);
    }
}
```

First, notice the line on top, outside of the program code block.

```rust
import arithmetic.aleo;
```

Then, inside of the `residue` transition, notice the external call:

```rust
let squared: u64 = arithmetic.aleo/square_u64(a);
```

As you can see, external transition calls have almost the same syntax as calling an internal function. The difference is the function identifier includes the imported program ID then the functon name, separated by a slash.

{% hint style="warning" %}
On Aleo there is no such thing as "call by address", as you would do in Solidity, at the moment this course is being written. This means it is not possible to depend dynamically on any arbitrary program implementing a certain interface, then providing that program address as one of the argument of the caller function.
{% endhint %}

### Signer vs Caller

Within a transition you can get the address of the direct caller of the transition, wether it's a program address or a user account address.

```rust
    transition get_caller() -> address {
        let direct_caller: address = self.caller;
        return direct_caller;
    }
```

For instance, for the following chain of calls:\
`User → Program A → Program B`

* `self.caller` within program B would be program A's address.
* `self.signer` within program B would be user's account address.

Here is an example. The function `direct_calls_only` defined below could only be called directly from a user would fail otherwise, if called from a program importing it.

```rust
    transition direct_calls_only() {
        let direct_caller: address = self.caller;
        let transaction_signer: address = self.signer;
        assert_eq(direct_caller, transaction_signer);
    }
```

{% hint style="success" %}
You can use a program ID directly in Leo to get its address, for instance for getting the address of `my_program.aleo`:

```rust
let my_program_address: address = my_program.aleo;
```

{% endhint %}

### External Records

Let's update our imported program so it includes a counter record, to count the amount of times it has been called from `quadratic.aleo` already:

```rust
program arithemtic.aleo {
    record Counter {
        owner: address,
        amount: u64
    }
    
    transition create() -> Counter {
        let counter: Counter = Counter {
            owner: self.signer,
            amount: 0u64
        };
        return counter;
    }
    
    // Square function now includes a Counter record input/output.
    transition square_u64(a: u64, in_counter: Counter) -> (u64, Counter) {
        let out_counter: Counter = Counter {
            owner: in_counter.owner,
            amount: in_counter.amount + 1u64
        };
        return (a*a, out_counter);
    }
}
```

Here's how `quadratic.aleo`  can now provide those external records

```rust
import arithmetic.aleo;

program quadratic.aleo {
    transition residue(
        a: u64, n: u64, in_counter: arithmetic.aleo/Counter
    ) -> (u64, arithmetic.aleo/Counter) {
        let (squared, out_counter): (
            u64, arithmetic.aleo/Counter
        ) = arithmetic.aleo/square_u64(a, arithmetic.aleo/Counter);
        let out_residue: u64 = squared.mod(n);
        return (out_residue, out_counter);
    }
}
```

Notice that before every record name, the imported program ID is provided before the slash.

{% hint style="warning" %}
Having a external record as an output of a program does not mean it will necessarily consume that record. The record will only be consumed if it is used as an input of a transition of the initial program it was defined in.
{% endhint %}

### Imported structs

When importing a program that defines `struct` data types, make sure you redefine those structs in the importing program as this could lead to errors. Contrary to records, you don't add the program ID prior to the imported struct name.

Here's an example of a program defining and using a struct:

```rust
program arithemtic.aleo {
    struct Point {
        x: u64,
        y: u64
    }
    
    transition add_points(a: Point, b: Point) -> Point {
        let c: Point = Point {
            x: a.x + b.x,
            y: a.y + b.y
        };
        return c;
    }
}
```

And here's how the importing program can use those structs:

```rust
import arithmetic.aleo;

program quadratic.aleo {
    // Redefine the struct with the same name and fields
    struct Point {
        x: u64,
        y: u64
    }

    // Use struct as a normal struct
    transition double_point(a: Point) -> Point {
        let doubled: Point = quadratic.aleo/add_points(a, a);
        return doubled;
    }
}
```

### Call an Async Transition

Async transition calls are slightly different than the non-async calls that we just went discovered. The reason for this is that there are both the on-chain and off-chain executed code. For each of those, we can decide independently if the caller program's code must be run before/after the imported code.

To understand this let's explore the syntax through an example first. Our arithmetic program will now store the counter of times its been called using a mapping.

```rust
program arithemtic.aleo {
    mapping counter: u8 => u64;
    
    // Square function now includes a Counter record input/output.
    async transition square_u64(a: u64) -> (u64, Future) {
        let square_u64_future: Future = finalize_square_u64();
        return (a*a, square_u64_future);
    }
    async function finalize_square_u64(){
        let amount: u64 = counter.get_or_use(0u8, 0u64);
        amount += 1u64;
        counter.set(0u8, amount);
    }
}
```

Let's see how to call it from the `quadratic.aleo` program:

```rust
import arithmetic.aleo;

program quadratic.aleo {
    async transition residue(a: u64, n: u64) -> (u64, Future) {
        let (squared, square_u64_future): (
            u64, Future
        ) = arithmetic.aleo/square_u64(a, arithmetic.aleo/Counter);
        let out_residue: u64 = squared.mod(n);
        
        let residue_future: Future = finalize_residue(square_u64_future);
        return (out_residue, residue_future);
    }
    async function finalize_residue(square_u64_future: Future){
        // Do anything...
        square_u64_future.await(); // Await the future
        // Do anything else...
    }
}
```

As you can notice, the future returned by the async external call is passed as an argument to the on-chain executed function.

All async external calls future must be passed to an async function and awaited this way. They cannot be returned directly. If there are multiple async external calls, each must be passed and awaited.

```rust
    async transition calls_2transitions() -> Future {
        let foo_future: Future = external.aleo/foo();
        let bar_future: Future = external.aleo/bar();
        let out_future: Future = finalize_calls_2transitions(foo_future, bar_future);
        return out_future;
    }
    async function finalize_calls_2transitions(future1: Future, future2: Future){
        future1.await();
        future2.await();
    }
```

All the function instructions, mapping reads, writes etc... are sequentially executed in the same order as their future are awaited.

Notice that the futures can be awaited in a different orders than the off-chain execution are made. The following body for the `finalize_calls_2transitions` function above would be valid as well:

```rust
        future2.await();
        future1.await();
```

### Reading external mappings

While a mapping cannot be updated directly by another program, it is possible to read its value. Here's an example:

```rust
import arithmetic.aleo;

program quadratic.aleo {
    async transition read_external_mapping() -> (Future) {
        return finalize_read_external_mapping();
    }
    async function finalize_read_external_mapping(){
        let count: u64 = arithmetic.aleo/counter.get(0u8);
        assert_neq(count, 0u64);
    }
}
```

You can use the `contains` and `get_or_use` mapping functions this way as well.
