# The factory chain: sending and receiving · Event-driven multi-chain dapps with ICMF · Learn Chromia

> The factory chain is the last chain in the example. It listens for production orders that the order chain emits and announces when an order is ready to…

Source: https://chromia.com/learn/icmf-course/factory-chain/

Event-driven multi-chain dapps with ICMFLesson 6 of 7

1. [01Event-driven multi-chain dapps with ICMF](https://chromia.com/learn/icmf-course/introduction/)
2. [02Set up your project](https://chromia.com/learn/icmf-course/setup/)
3. [03Define messages](https://chromia.com/learn/icmf-course/defining-messages/)
4. [04Order chain (send message)](https://chromia.com/learn/icmf-course/order-chain/)
5. [05Delivery chain (receive message)](https://chromia.com/learn/icmf-course/delivery-chain/)
6. [06The factory chain: sending and receiving](https://chromia.com/learn/icmf-course/factory-chain/)
7. [07Test the dapp](https://chromia.com/learn/icmf-course/manual-testing/)

[Learn](https://chromia.com/learn/)[Event-driven multi-chain dapps with ICMF](https://chromia.com/learn/icmf-course/)

06 / 07Advanced

# The factory chain: sending and receiving

The factory chain is the last chain in the example. It listens for production orders that the order chain emits and announces when an order is ready to ship. A real system would probably split these into separate steps, but the example keeps them together for simplicity.

Here, "manufacturing" a product means increasing its value and emitting the message again right away. The database model has just one entity. Put the logic for this blockchain in a new module, `factory_chain`, inside the `src/factory_chain` directory, with this content:

src/factory\_chain/module.rell

```
module;

import lib.icmf.{ send_message };
import lib.icmf.receiver.{ receive_icmf_message };
import messages.{ topic.*, msg };
```

In `src/factory_chain/entities.rell`, define the matching entity for manufactured products:

src/factory\_chain/entities.rell

```
entity manufactured_product {
    key id: integer;
    mutable quantity: integer;
}
```

Next, add two queries to `src/factory_chain/queries.rell`. One returns the quantity of a manufactured product, and the other returns the total count of manufactured products.

src/factory\_chain/queries.rell

```
query get_total_manufactured(id: integer) = manufactured_product @? { id }.quantity;

query get_total_manufactured_products() = manufactured_product @* {} ( $.to_struct() );
```

## Sending and receiving a message

Configuring a chain to both send and receive messages builds on the configuration from earlier sections. In `chromia.yml`, add a `factory_chain` property with its configuration under the `blockchains` section. This defines the new blockchain.

chromia.yml

```
blockchains:
  # ↓↓↓ Add this code snippet ↓↓↓
  factory_chain:
    module: factory_chain
    config:
      <<: *sender_receiver
      icmf:
        receiver:
          local:
            - topic: "L_production"
              brid: null
  # ↑↑↑ Add this code snippet ↑↑↑
```

To handle the messages, add this code to `functions.rell`:

src/factory\_chain/functions.rell

```
@extend(receive_icmf_message)
function (sender: byte_array, topic: text, body: gtv) {
    when (topic) {
        PRODUCTION_ORDER -> {
            val order = msg.production_details.from_gtv(body);
            for (product in order.products) manufacture_product(product);
            send_message(SHIPMENT_READY, msg.shipment_ready(order.order_id).to_gtv());
        }
        else -> log("Message type %s not handled".format(topic));
    }
}

function manufacture_product(product: msg.product) {
    if (not exists(manufactured_product @? { .id == product.id})) {
        create manufactured_product( id = product.id, quantity = product.quantity);
    } else {
        update manufactured_product @ { .id == product.id } (quantity += product.quantity);
    }
}
```

## Testing

Testing the factory chain requires extra configuration in `chromia.yml`. Under the `factory_chain` section, add a `test` property and the related details.

chromia.yml

```
blockchains:
  factory-chain:
    # ↓↓↓ Add this code snippet ↓↓↓
    test:
      modules:
        - test.factory_chain_test
    # ↑↑↑ Add this code snippet ↑↑↑
```

The test emits a message, and the dapp reacts by emitting an event. In the `src/test` directory, create `factory_chain_test.rell` with the following code:

src/test/factory\_chain\_test.rell

```
@test module;

import factory_chain.{ manufactured_product };
import messages.{ msg, topic.* };
import lib.icmf.test.{ test_icmf_message };

function test_manufacture_order() {
    rell.test.tx().op(
            test_icmf_message(
                x"",
                PRODUCTION_ORDER,
                msg.production_details(
                    order_id = 1,
                    products = [msg.product(id = 2, quantity = 10)]
                )
                    .to_gtv()
            )
        )
        .run();
    assert_events(("icmf_message", (topic = SHIPMENT_READY, body = msg.shipment_ready(1).to_gtv()).to_gtv_pretty()));
    assert_equals(manufactured_product @ { .id == 2 }.quantity, 10);
}
```

Run `chr test` and check the results.

bash

```
Running tests for chain: factory-chain
TEST: factory_chain_test:test_manufacture_order
OK: factory_chain_test:test_manufacture_order (0.688s)

------------------------------------------------------------
TEST RESULTS:

OK factory_chain_test:test_manufacture_order

SUMMARY: 0 FAILED / 1 PASSED / 1 TOTAL (0.688s)

***** OK *****
```

You now have a dapp built on three separate blockchains. The final section covers running the blockchains locally and testing the complete flow.

For reference, the project structure and the full `chromia.yml` configuration after these changes are shown below. Use them to compare against your own project at this point in the course:

Project structure

text

```
order-system-example/ ├── build/ ├── src/ │   ├── delivery_chain/ │   │   ├── entities.rell │   │   ├── functions.rell │   │   ├── module.rell │   │   ├── operations.rell │   │   └── queries.rell │   ├── factory_chain/ │   │   ├── entities.rell │   │   ├── functions.rell │   │   ├── module.rell │   │   └── queries.rell │   ├── lib/ │   ├── order_chain/ │   │   ├── entities.rell │   │   ├── functions.rell │   │   ├── module.rell │   │   ├── operations.rell │   │   └── queries.rell │   ├── test/ │   │   ├── delivery_chain_test.rell │   │   ├── factory_chain_test.rell │   │   └── order_chain_test.rell │   └── messages.rell ├── .gitignore └── chromia.yml
```

Final version of the `chromia.yml` file

chromia.yml

```
definitions:
  - &sender # Configuration for a chain that sends messages
    gtx:
      modules:
        - "net.postchain.d1.icmf.IcmfSenderGTXModule"
  - &receiver # Base configuration for a chain that receives messages
    gtx:
      modules:
        - "net.postchain.d1.icmf.IcmfReceiverGTXModule"
    sync_ext:
      - "net.postchain.d1.icmf.IcmfReceiverSynchronizationInfrastructureExtension"
  - &sender_receiver # Base configuration for a chain that will both send and receive messages
    gtx:
      modules:
        - "net.postchain.d1.icmf.IcmfSenderGTXModule"
        - "net.postchain.d1.icmf.IcmfReceiverGTXModule"
    sync_ext:
      - "net.postchain.d1.icmf.IcmfReceiverSynchronizationInfrastructureExtension"
blockchains:
  order_chain:
    module: order_chain
    config:
      <<: *sender
    test:
      modules:
        - test.order_chain_test
  delivery_chain:
    module: delivery_chain
    config:
      <<: *receiver
      icmf:
        receiver:
          local:
            - topic: "L_delivery"
              brid: null
            - topic: "L_shipment_ready"
              brid: null
    test:
      modules:
        - test.delivery_chain_test
  factory-chain:
    module: factory_chain
    config:
      <<: *sender_receiver
      icmf:
        receiver:
          local:
            - topic: "L_production"
              brid: null
    test:
      modules:
        - test.factory_chain_test
compile:
  rellVersion: 0.14.9
database:
  schema: schema_order_system_example
libs:
  icmf:
    registry: https://gitlab.com/chromaway/core/directory-chain
    path: src/lib/icmf
    tagOrBranch: 1.90.1
    rid: x"B56524EE85B679371EAB1A069B03BE6A3E94F36993DEA900747BA5BAE8B99122"
```

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Previous**Delivery chain (receive message)**](https://chromia.com/learn/icmf-course/delivery-chain/)[Next →**Test the dapp**](https://chromia.com/learn/icmf-course/manual-testing/)

On this page

* [Sending and receiving a message](#sending-and-receiving-a-message)
* [Testing](#testing)
