Offchain Oracle Workers
Motivation for Offchain Oracle Workers
Section titled “Motivation for Offchain Oracle Workers”When the Creditcoin Oracle provisions data from one chain to another there are three transactions that must be submitted by the user or DApp builder:
- The user submits a transaction on the source chain. Usually this would be a source chain smart contract call emitting some
eventfor which we want to transfer data to the execution chain. - User/Builder submits an oracle query on the
Creditcoinexecution chain. This transaction kicks off the query proving process. After query proving, data from the event emitted in step 1 is proven and available on the execution chain. - User/Builder calls the universal smart contract on the execution chain. This call retrieves the data from the event emitted in step 1 and which has now been made available by the Creditcoin Oracle in step 2. The Universal Smart Contract interprets it, and uses it to trigger DApp business logic in your business logic smart contracts.
The following diagram illustrates the various steps where our bridging process is halted awaiting user/builder input.

Removing Friction
Section titled “Removing Friction”The first transaction must always be submitted by the end user. However, transactions 2 and 3 can be initiated by the DApp builders on behalf of their users. This is preferable for several reasons:
- The fewer transactions your DApp requires users to sign, the better! Signing just one transaction feels much better than signing 3, potentially spaced several minutes apart.
- End users won’t understand why they need to sign 3 different transactions. This can be a cause of anxiety for them or even prevent some users from following through with using your DApp.
- Due to a lack of semantic labeling of oracle query results, it is possible to construct invalid oracle queries, making them incompatible with a DApp’s Universal Smart Contract. For this reason, DApp builders should submit properly formatted queries on behalf of their users.
Designing an Offchain Oracle Worker
Section titled “Designing an Offchain Oracle Worker”As seen above, signing the proving and query transactions on behalf of you end users can drastically improve the UX of your Universal DApp by reducing the number of user interactions needed to trigger core business logic on the
Creditcoin execution chain.
Worker Transaction Flow
Section titled “Worker Transaction Flow”One way of streamlining the execution process is by relying on automated Offchain Workers, as illustrated in the following sequence diagram.
sequenceDiagram autonumber box Execution Chain (Creditcoin) participant BL as Business Logic participant USC participant DO as Decentralized Oracle participant AT as Attestors end participant OW as Offchain Worker box Source Chain participant SC as Smart Contract end USER ->> SC: Calls Note left of USER: User signs a tx<br/>to initiate interaction SC ->> AT: Attestors follow all source chain<br/> blocks, including the block<br/> containing our tx activate AT AT -->> DO: Relays Attestation deactivate AT Note over DO,AT: Only a commitment to the state<br/>of the source chain is relayed. This<br/>commitment can later be used by<br/> the creditcoin oracle to verify<br/> that our source chain<br/> transaction actually took place. loop OW -->> SC: Watches for<br/> events that<br/> should trigger<br/> queries activate SC SC -->> OW: Emits an Event deactivate SC end OW ->> DO: Requests Proof activate DO DO ->> DO: Generates and Stores Proof DO ->> OW: Emits proof completion event deactivate DO activate OW OW ->> USC: Triggers USC use of proof data deactivate OW activate USC USC ->> DO: Requests proof<br/> data from oracle deactivate USC activate DO DO ->> USC: Returns proof<br/> data deactivate DO activate USC USC ->> BL: Dispatches deactivate USC activate BL BL ->> BL: Runs Business Logic Note over BL,USC: All business logic is encapsulated<br/>on execution chain. Source chain<br/>only serves to query the USC. deactivate BL loop USER-->>BL: Watches for events activate BL BL-->>USER: DApp contract emits events deactivate BL activate USER end USER->>USER: Updates UI to reflect state change deactivate USER" fullWidth="true
We can break this down into the same four categories, but with different implications in terms of UX:
- Initial DApp Query from the source chain. This is now the only transaction which has to be signed by the end user. All the rest of your DApp’s logic is handled by the Offchain Worker, providing a truly native feel.
- Proof generation. Steps n˚4 to n˚7 are responsible for generating a proof of the event’s occurrence on the source chain. The Offchain Worker constantly monitors the source chain contract for events. As soon as an event is emitted and made available on the execution chain, it requests a proof from the Creditcoin Oracle. This requires no further user interaction.
- Executing business logic. Next, steps n˚8 till n˚13 are responsible for executing the business logic of your DApp on the execution chain. This is initiated by the Offchain Worker, which queries the Universal Smart Contract on the execution chain on behalf of the user. This requires no further user interaction.
- Aggregating Results. Finally, the results of your DApp’s execution can be retrieved and processed by the user. This does not require further user interaction, but it does require the DApp client to keep watch of the execution chain, either via light client or else by querying a remote RPC endpoint.
Going Further
Section titled “Going Further”This has just been a starting point designed to introduce you to the use of Offchain Workers. Each DApp builder team will likely want to implement their Worker differently to fit the rest of their technology stack.
Keeping this in mind, the main goal of an Offchain Worker should always be robustness. This includes:
- Retaining stored records of queries in progress in the event of a Worker shut down.
- Catching up with any event that might have been missed as result of an unexpected shutdown.
- Avoiding submitting multiple queries or USC calls for the same event.
- Following multiple source chain nodes to listen for events in case a node experiences issues.
- Re-submit valid oracle queries or USC calls in case they fail. A query can fail for many reasons: for example the Prover a query is submitted to to might be experiencing down time or connectivity issues.
Here is an example of the logical flow that a more advanced oracle worker might use.
--- config: theme: neo ---------- stateDiagram s1:New source chain Events? state if_events <<choice>> s3:Request a proof from the prover contract for each event s4:Periodically checking for proof completion, timeout, etc. s5:Timeout or payment reclaimed? state if_escrow_payment_reclaimed <<choice>> s8:Resubmit proof request with reclaimed funds s9:Check for proof completion s10:QueryProofVerified? state if_query_proof_verified <<choice>> s11:Retrieve proof s12:Log successful query s13:Trigger USC use of proof results s14:Success!\ restartVerify:keep waiting
[*] –> s1 s1 –> if_events if_events –> s3:Yes if_events –> s1:No s3 –> s4 s4 –> ProofPaymentReclaimedOrTimedOut note right of ProofPaymentReclaimedOrTimedOut Cron job checks for QuerySubmitted events that exceed timeout. When EscrowPaymentReclaimed event is received the query is either timed out or is failed to be proven. end note
state ProofPaymentReclaimedOrTimedOut { s5 –> if_escrow_payment_reclaimed if_escrow_payment_reclaimed –> s8:Yes if_escrow_payment_reclaimed –> s9:No } s8 –> s3 s9 –> ProofVerify
state ProofVerify { s10 –> if_query_proof_verified if_query_proof_verified –> s11:Yes if_query_proof_verified –> restartVerify:No s11 –> s12 s12 –> s13 s13 –> s14 }
restartVerify –> s4
s14 –> [*]
" fullWidth="trueNext Steps
Section titled “Next Steps”Check out this script for an example of an offchain worker. Here is where the oracle query is submitted to the oracle prover contract, and here is where the query results are submitted to the Universal Smart Contract.