Skip to main content

Automatic Proof Delivery

Boundless supports proof delivery to application contracts through callbacks. When requesting a proof, you can specify a contract address that implements the IBoundlessMarketCallback interface. When the proof is fulfilled, the Boundless Market will automatically call this contract with the proof data. The callback contract must implement the following interface:
We provide a template for implementing the IBoundlessMarketCallback interface: BoundlessMarketCallback.sol. This implements best practices for implementing the handleProof function.

Some Callback Considerations

Boundless does not guarantee the success of callback execution.

Callbacks are executed as part of a try-catch block using the specified gas limit. Successful execution of the callback is not required for a request to be marked as fulfilled. It is important for requestors to set a high enough gas limit to ensure the callback can execute to completion.

Callbacks have at-least-once delivery semantics.

Proof request submission is permissionless in Boundless. Any user can submit a request that causes any contract’s callback to be executed, potentially re-using proofs that have been previously submitted. It is important for callbacks to be robust to multiple invocations.

Callback invocation does not specify which Requirements were used to generate the proof.

Proofs are submitted to the callback with the journal and seal generated by the prover. When the callback is invoked, it does not specify which Requirements used to generate the proof. It is important for the callback to verify the image ID and journal are as expected before accepting the callback as valid.

Example: Counter with callback

The Counter with callback example submits a request to the market for a proof that “4” is an even number, and specifies that the proof should be delivered to the Counter contract. When creating the proof request, the requestor specifies the callback contract address and a gas limit:
Our Counter contract implements the handleProof function, which checks if we’ve already seen this proof, and if not, increments a counter and emits an event:
[Counter.sol]
Once the proof is fulfilled, our example checks the counter contract and confirms that the value was incremented by the callback: