﻿# Candid serialization

> For the complete documentation index, see [llms.txt](/llms.txt)

Candid is an interface description language and serialization format designed specifically for the Internet Computer Protocol. Candid serves as the standard communication protocol between canisters. When one canister calls another, the arguments are serialized to Candid, transmitted, and then deserialized by the receiving canister. This standardization enables developers to create frontends in languages like JavaScript that can easily interact with backend canisters written in Motoko or Rust. Candid uses strong typing to guarantee accurate data interpretation and an efficient binary format for encoding data, making it ideal for network transmission. Importantly, Candid's design allows for backwards-compatible upgrades of canister interfaces.

Motoko automatically generates Candid interfaces for canisters and provides built-in functions like `to_candid` and `from_candid` for easy serialization and deserialization of data to and from Candid format.

## Autogenerated Candid interfaces

When Motoko code is compiled, a Candid interface file [(`.did`)](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/using-candid#the-did-file) for the canister's public methods is automatically generated. This file is used to ensure data passed into and returned from these methods is automatically encoded to and decoded from Candid’s binary format.

Motoko canisters automatically handle the serialization and deserialization of data when the canister interacts with [inter-canister calls or ingress messages](https://internetcomputer.org/docs/building-apps/essentials/message-execution).

## Candid operators

Motoko provides the `to_candid` and `from_candid` functions for serializing and deserializing Candid-encoded data.

:::danger
It's important to note that there are many valid Candid encodings, and therefore many different `Blob` representations, for the same value. As a result, `to_candid` does not guarantee that the same input will always produce the same `Blob`. You should never use the output of `to_candid` to compare values for equality or to compute hashes.
:::

In most cases, explicit serialization using `to_candid` and `from_candid` is unnecessary during regular development. These functions are typically reserved for advanced scenarios, such as:

- Making dynamic calls to arbitrary canisters.

- Handling raw binary data for storage or transmission.

- Managing stable data formats during canister upgrades.

For most common interactions, Candid serialization is handled automatically by the Motoko compiler.

### `to_candid`

The `to_candid` serializes Motoko values into a Candid-encoded binary `Blob`. This is useful when explicitly encoding data for storage, transmission between canisters, or dynamic inter-canister calls. The `to_candid` function can accept one or multiple arguments separated by commas.

```motoko no-repl
let encoding =  to_candid(true, "hello", 68, -90) // (Bool, Text, Nat, Int)
```

Each argument must be composed of sharable types. The resulting `Blob` precisely represents the original Motoko values according to Candid specifications.

```motoko no-repl
import Debug "mo:core/Debug";

actor {
  public type User = {
    userId : Nat;
    name : Text;
  };
  
  public func serializeUser(user : User) : async Blob {
    let encodedData : Blob = to_candid(user);
    Debug.print("User data serialized successfully.");
    encodedData;
  };
}
```

### `from_candid`

The `from_candid` function deserializes a Candid-encoded binary `Blob` back into Motoko values. This explicit decoding is useful in scenarios where serialized data needs to be processed or restored, such as reading from stable storage or handling dynamic input.

To decode a `Blob` correctly, `from_candid` requires an explicit type annotation or a clear type context. The result is returned as an optional (`?`) value, allowing you to safely handle potential failures caused by type mismatches or malformed data.

```motoko no-repl
import Debug "mo:core/Debug";

actor {
  public type User = {
    userId : Nat;
    name : Text;
  };

  public func deserializeUser(encodedData : Blob) : async ?User {
    let decodedUser : ?User = from_candid(encodedData);

    switch decodedUser {
      case (?user) {
        Debug.print("User data deserialized successfully.");
        return ?user;
      };
      case null {
        Debug.print("Deserialization failed: Invalid blob or type mismatch.");
        return null;
      };
    };
  };
}
```

## Dynamic calls

Although most canisters on ICP support Candid, this is not a requirement enforced by the network. At the protocol level, canisters communicate in raw binary data. Candid is just a common interpretation of that data that allows canisters written in different languages to interoperate.

Most users should never need to use `to_candid` and `from_candid`, however one scenario in which these operations are useful is when canister methods are called **dynamically** using the `call` function from the `InternetComputer` core module. The `call` function takes a canister `Principal`, the name of a method as `Text`, and a raw binary `Blob`, then returns a future containing the result of the call, also as a raw binary `Blob`. Typically, you might use `to_candid` to prepare the argument of a call and `from_candid` to process its result.

Dynamic calls are particularly useful when working with canisters or services that have complex or non-standard interfaces, or when you need fine-grained control over the calling process. However, they require manual handling of binary encoding and decoding, which is more error-prone than using the high-level abstractions provided by Motoko.

In this example, use the imported `call` function to make a dynamic call on the actor:

``` motoko no-repl
import Principal "mo:core/Principal";
import { call } "mo:core/InternetComputer";

persistent actor MyActor {

   public func concat(ts : [Text]) : async Text {
      var r = "";
      for (t in ts.values()) { r #= t };
      r
   };

   public func test() : async Text {
       let arguments = to_candid (["a", "b", "c"]);
       let results = await call(Principal.fromActor(MyActor), "concat", arguments);
       let ?t = from_candid(results) : ?Text;
       t
   }

}
```

:::danger
While dynamic calls offer more flexibility, they should be used judiciously. In most cases, the standard inter-canister call mechanisms and automatic Candid handling in Motoko provide a safer and more convenient approach to canister interactions.
:::

## Resources

For more detailed information on Candid, refer to:

- [What is Candid?](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/candid-concepts)
- [Using Candid](https://internetcomputer.org/docs/building-apps/interact-with-canisters/candid/using-candid)
- [Candid Specification](https://internetcomputer.org/docs/references/candid-ref)
