Each fact that Relic Protocol uses must be examined by a prover. Provers provide the means to cryptographically verify information so that applications need worry the data may be inaccurate. The Reliquary maintains a list of all known provers to ensure that data is only accepted from those explicitly allowed.
Relic Protocol has been designed to keep a balance of forward compatibility and security. Moreover, it is designed to be trustless, so that even if the Relic Protocol maintainers were to be hacked or turn malicious, applications could operate safely.
When the Relic maintainers wish to introduce a new prover, they must initiate a proposal request to the Reliquary. Rather than immediately accepting the prover, a mandatory waiting period is initiated. This period is set to a minimum of two days in the Reliquary contract, guaranteeing no new provers can be added instantly (though before the Reliquary was initialized, there was no delay). The separate Relic maintenance contract may also be configured later to impose longer delays, based on community feedback. Additionally, a
PendingProverAdded event is emitted when a prover is proposed to make it easy to observe. All provers must be assigned a unique identifier, and this identifier is set when a prover is first introduced.
During this period, users and developers are encouraged to look over the proposed prover. Any potential issues should be brought up to the Relic maintainers. If a prover was proposed which developers believe does not meet the proper standards for trustworthiness, they may update their own applications to reject provers with the unique identifier they distrust. To make this simpler, Relic Protocol maintainers plan to make the prover identifications change in a predictable way over time (for example, incrementing by one with each new prover), this means developers worried about faulty provers can parameterize their applications by the most recent prover identifier they trust.
After the proposal period is over, Relic Protocol maintainers may activate a prover. This will emit the event
NewProver. Once activated, provers are authorized to add data to the Reliquary. The specifics of which types of proofs they verify all depend on the code in the actual prover contract.
Only provers in the active state are permitted to prove facts, and all facts proven are accompanied by the specific prover identifier that was first introduced in the proposal phase.
If it is deemed necessary by Relic Protocol maintainers, a prover may be revoked. Revoked provers are banished from the Reliquary and no longer permitted to issue proofs.
Revocation may happen for any reason. For example, if the Relic Protocol maintainers believe a prover should not be trusted for future proofs due to a bug found in the proving logic, it will be revoked. This may also happen for more benign reasons, such as if a new prover supersedes an older one, and Relic maintainers strongly prefer the use of the new prover, perhaps because it interacts better with other Relic services.
It is important to note that facts stored from a revoked prover are not removed from the Reliquary. This is intentional, as provers may be revoked when their logic is still sound, or when theoretical attacks are found that can not be practically executed. If the Relic maintainers believe a prover has been abused to issue false facts, they may take action to remove those facts from the Reliquary.
As a dApp maintainer, one may choose to reject facts from all revoked provers easily using the checkProver function.
The status of provers can be seen in the Relic Explorer. For example, the Multi Storage Slot Prover was proposed on February 7, 2023 and accepted on February 9, 2023 (UTC).
The easiest way to create a proof is to use the Relic Client SDK. By using the particular prover needed, one can simply call the relevant prove function, which will build and send the proper transaction, including any necessary fees and calls to APIs to generate proof data. Most provers also provide a
proveEphemeral method which does not store data, however, ephemeral proofs are generally easier to perform when proven from within a dApp directly.
Because Relic may update provers over time, the best practice is for dApps that need to make proofs is to not hardcode the prover addresses that they wish to use. Instead, on-chain applications should accept a prover address and a proof, verify the prover using the checkProver Reliquary function, and then call the prove or proveBatch function. Once the proof is returned, the dApp should verify the fact signature matches the expected results.
Developers who wish to be extra cautious while still allowing for forward compatibility for new Relic provers should set a maximum version for Relic provers that they have trusted. When new provers are introduced and explicitly trusted, the developers can update the version to reflect their new beliefs. This way if Relic maintainers are compromised or act maliciously in the future, applications will still not be vulnerable.
Due to the cost of maintaining Relic both on-chain and off, fees may be charged to perform certain proofs. The prove functions for all provers are payable to permit the accepting of fees, denominated in ETH. The current fees for provers can be seen in the Relic Explorer, for example the Multi Storage Slot Prover which currently has no fee.
Best practices for developing Web3 Relic applications is to use the getFee function to determine the applicable fee for a query, and send that value along with the message when performing a proof.