Onchain Write
This overview explains how writing data onchain works in CRE and how the TypeScript SDK handles it.
- Understanding how CRE writes work - The secure write flow
- What you need: A consumer contract - Contract requirements
- The TypeScript write process - Two-step approach overview
- Next steps - Where to go from here
Understanding how CRE writes work
Before diving into code, it's important to understand how CRE handles onchain writes differently than traditional web3 applications.
Why CRE doesn't write directly to your contract
In a traditional web3 app, you'd create a transaction and send it directly to your smart contract. CRE uses a different, more secure approach for three key reasons:
- Decentralization: Multiple nodes in the Decentralized Oracle Network (DON) need to agree on what data to write
- Verification: The blockchain needs cryptographic proof that the data came from a trusted Chainlink network
- Accountability: There must be a verifiable trail showing which workflow and owner created the data
The secure write flow (4 steps)
Here's the journey your workflow's data takes to reach the blockchain:
- Report generation: Your workflow generates a report—your data is ABI-encoded and wrapped in a cryptographically signed "package"
- DON consensus: The DON reaches consensus on the report's contents
- Forwarder submission: A designated node submits the report to a Chainlink
KeystoneForwardercontract - Delivery to your contract: The Forwarder validates the report's signatures and calls your consumer contract's
onReport()function with the data
In your workflow code, this process involves two steps: calling runtime.report() to generate the signed report, then calling evmClient.writeReport() to submit it to the blockchain.
What you need: A consumer contract
Before you can write data onchain, you need a consumer contract. This is the smart contract that will receive your workflow's data.
What is a consumer contract?
A consumer contract is your smart contract that implements the IReceiver interface. This interface defines an onReport() function that the Chainlink Forwarder calls to deliver your workflow's data.
Think of it as a mailbox that's designed to receive packages (reports) from Chainlink's secure delivery service (the Forwarder contract).
Key requirement:
Your contract must implement the IReceiver interface. This single requirement ensures your contract has the necessary onReport(bytes metadata, bytes report) function that the Chainlink Forwarder calls to deliver data.
Getting started:
- Don't have a consumer contract yet? Follow the Building Consumer Contracts guide to create one.
- Already have one deployed? Great! Make sure you have its address and ABI ready for encoding your data.
The TypeScript write process
The TypeScript SDK uses a simple, two-step process for writing data onchain:
Step 1: Generate a signed report
Use runtime.report() to:
- ABI-encode your data using viem's
encodeAbiParameters() - Convert the encoded data to base64 format
- Generate a cryptographically signed report
Step 2: Submit the report
Use evmClient.writeReport() to submit the signed report to your consumer contract address.
Key features:
- Use viem directly for ABI operations
- Manual but flexible - Full control over encoding and submission
- Type-safe - TypeScript and viem ensure compile-time safety
- Works for any data - Single values, structs, arrays, etc.
Next steps
Now that you understand the concepts, follow these guides to implement onchain writes:
- Building Consumer Contracts - Create a Solidity contract to receive your workflow's data
- Writing Data Onchain - Complete step-by-step guide with examples for single values and structs
Additional resources:
- EVM Client Reference - Complete API documentation
- Onchain Read - Reading data from smart contracts