# Emitting Outputs

While handling a request your application can emit four kinds of outputs. They differ in what they can do and in what can be *proven* about them on-chain:

| Output | Provable | Purpose |
| --- | --- | --- |
| [Voucher](/cmio/reference/emit-voucher) | yes | Execute a transaction on-chain (transfer assets, call a contract) |
| [Notice](/cmio/reference/emit-notice) | yes | Attest a fact about the application state |
| [Report](/cmio/reference/emit-report) | no | Logs, diagnostics, inspect responses |
| [Exception](/cmio/reference/emit-exception) | no | Signal that the request could not be processed |

Vouchers and notices are added to the application's **outputs merkle tree**, so their existence can later be proven and they can be executed/validated on-chain. Reports are plain data made available off-chain.

## Vouchers: act on-chain

A voucher is a one-shot transaction the application authorizes: when the epoch containing it settles, anyone can execute it through the application contract. Use it to transfer assets out, call DeFi protocols, or trigger any on-chain effect:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
// transfer 1 ETH from the application contract to a user
const index = rollup.emitVoucher({
    destination: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
    value: 1_000_000_000_000_000_000n, // wei
    payload: '0x', // no calldata — plain value transfer
});
```

To call a contract, put the EVM calldata in `payload` — for example an ERC-20 `transfer(address,uint256)`:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
const recipient = 'f39Fd6e51aad88F6F4ce6aB8827279cffFb92266'.padStart(64, '0');
const amount = (10n ** 18n).toString(16).padStart(64, '0');

rollup.emitVoucher({
    destination: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // token contract
    payload: `0xa9059cbb${recipient}${amount}`, // transfer(address,uint256) selector + args
});
```

There is also a [delegate-call variant](/cmio/reference/emit-delegate-call-voucher) that executes the target's code in the application contract's own storage context — an advanced tool for upgrade-style patterns.

## Notices: attest facts

A notice carries no on-chain action — it is a verifiable statement that "the application, having processed inputs up to this point, says X". Typical uses: settlement results, state snapshots, anything an off-chain consumer wants to trust without re-executing the machine:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
const result = { winner: '0xf39F…2266', prize: '1000' };
rollup.emitNotice(Buffer.from(JSON.stringify(result)));
```

## Reports: observe and debug

Reports are for everything that doesn't need a proof: log lines, error messages, and answers to [inspect queries](/cmio/guide/handling-requests#inspect-requests). They cost nothing on-chain and cannot be verified:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
rollup.emitReport(Buffer.from('debug: cache warmed up'));
```

## Exceptions: give up loudly

An exception tells the outside world the request could not be processed at all — a structural failure rather than a business-rule rejection. Prefer returning `false` from a handler (or throwing, which [run](/cmio/reference/run) turns into a report + rejection); reach for [`emitException`](/cmio/reference/emit-exception) only when the application cannot continue in a meaningful way.

## Output indices and proofs

`emitVoucher`, `emitDelegateCallVoucher` and `emitNotice` return the output's **index** — its position among all provable outputs ever produced by the application. Persist or report it if an off-chain component needs to locate the output later to fetch its proof and execute/validate it:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
const index = rollup.emitNotice(Buffer.from('state-root:abc123'));
//     ^?
```

## Byte and number conventions

All payload-like arguments accept three shapes, converted automatically:

```ts twoslash
import { Rollup } from '@deroll/cmio';
const rollup = new Rollup();
// ---cut---
rollup.emitNotice('0xdeadbeef'); // 0x-prefixed hex string
rollup.emitNotice(Buffer.from('hello')); // Buffer
rollup.emitNotice(new Uint8Array([1, 2, 3])); // Uint8Array
```

* **Addresses** (`destination`, `msgSender`, …) must be exactly 20 bytes; as strings they are 0x-prefixed hex.
* **256-bit values** (`value`) accept `bigint`, `number`, or 32 bytes.
* Outgoing data is always `Buffer` (payloads) / `bigint` (numbers) / 0x-hex strings (addresses).

Hex strings are typed as `` `0x${string}` `` ([`Hex`](/cmio/reference/types#input-types)), so values from [viem](https://viem.sh) — `Hex` from `encodeFunctionData`, `Address`, `bigint` from `parseEther` — pass in directly, and request addresses pass back into viem without casts.

Invalid lengths or malformed hex throw `TypeError`/`RangeError` before anything reaches the device.

## When libcmt fails

Every method can throw a `RollupError` carrying the libcmt error code if the underlying call fails — for example emitting an output larger than the machine's output buffer. The negative errno is available on `error.errno` and the failed call name on `error.syscall`.
