Overview
Esta página aún no está disponible en tu idioma.
Contract Architecture
The Royal Protocol uses a gateway-registry pattern that separates policy from data storage. This enables flexible governance while maintaining data integrity.
Core Pattern
Each major system (Identities and Provenance) consists of two contracts:
- A Registry contract that stores the data and enforces fundamental rules.
- A Gateway contract that contains the authorization logic and policy decisions.
Loading graph...
graph TD User[User/Application] Gateway[Gateway Contract] Registry[Registry Contract] User -->|Writes| Gateway Gateway -->|Validated Changes| Registry User -->|Reads| Registry
The Registry only accepts changes from its designated Gateway, creating a clear security boundary. The Gateway handles all policy decisions like:
- Fee structures
- Authorization rules
- Delegation validation
- Gas sponsorship via signatures
Key Systems
Identity System
- IdRegistry: Stores user identities and core relationships
- IdGateway: Manages registration, transfers, and recovery
Provenance System
- ProvenanceRegistry: Stores creation claims and NFT relationships
- ProvenanceGateway: Handles claim registration and verification
Delegation Registry
A shared component that enables permission delegation between Royal IDs. This powers key features like automated registration and gas sponsorship.
Upgradeability
This separation serves a practical purpose with regards to upgradeability 🔗:
- Registries store critical data and rarely need updates
- Gateways contain policy logic that may need adjustment as the protocol evolves
All contracts are upgradeable, but Gateway upgrades are expected to be more common to adapt to community needs while Registry upgrades would only address critical issues.
Specific contracts
Contract | Source code | Contract on Base | Contract on Base Sepolia |
---|---|---|---|
IdRegistry | Solidity 🔗 | Base 🔗 | Base Sepolia 🔗 |
IdGateway | Solidity 🔗 | Base 🔗 | Base Sepolia 🔗 |
ProvenanceRegistry | Solidity 🔗 | Base 🔗 | Base Sepolia 🔗 |
ProvenanceGateway | Solidity 🔗 | Base 🔗 | Base Sepolia 🔗 |
DelegateRegistry | Solidity 🔗 | Base 🔗 | Base Sepolia 🔗 |
The data systems
There are two data systems in the Royal Protocol: Royal ID and ProvenanceClaim. In both cases, the data is stored in a registry contract, and can only be manipulated by a gateway contract.
Loading graph...
graph LR User@{ shape: rounded } subgraph Onchain Gateway@{ shape: rounded, label: "Gateway - authorization logic"} Registry@{ shape: rounded, label: "Registry - data store"} end Gateway == Commands ==> Registry User == Writes ==> Gateway User -- Queries --> Registry Registry -- Data --> User User x-. Commands .-x Registry
The registry contract stores the data.
The registry has the address of its gateway, and will refuse requests to change data from any other source.
The gateway contract contains the authorization logic and policy parameters (fees, etc.). This logic is more likely to change in the future, so it is best to leave it as a separate contract to let it be upgraded independently.
Delegate registry
Additionally, there is a delegation registry contract that is inspired by the delegate.xyz delegation code 🔗. The delegation system is based on Royal IDs instead of addresses as the user identifier.
Gas sponsorship
There are two roadblocks to onboarding users who are not used to crypto.
- Wallet installation
- The need to hold ETH to initiate transactions
While the method of wallet installation may vary depending on the application layer (for example a self-custody or custodial wallet), all users must have a wallet in some form to interact with the protocol. However, protocol costs (user registration, content registration, address changes, etc.) don’t need to be paid directly in ETH. For example, a content creation tool could bundle registriation with the other services it provides. Gas sponsorship allows users to delegate transaction costs to a third party, while still keeping the authorization with the users’ wallets.
- The user specifies what to do on the web application.
- The web application asks the user to sign an EIP-712 🔗 message with the appropriate parameters.
- The user signs the request in the wallet (or through a smart wallet). Signing a request does not cost anything.
- The wallet sends the signature back to the website.
- The website sends the request, along with the signature, in an Ethereum transaction to the appropriate gateway contract. This costs money, but at present the cost is usually less than a cent.
- The gateway contract verifies the signature before it forwards the request to the registry.
Almost all the public facing functions in the Royal Protocol come with a ...For
version to enable this functionality.
You can see this process illustrated in the create Royal ID flow.
How do we prevent signature abuse?
A potential problem with this pattern is that web sites can ask for a signature, and then instead of submitting the transaction immediately keep the signature, and submit it at a different time with results the user does not expect. To avoid this problem, all Royal Protocol signatures include a deadline beyond which they are no longer valid.
Additionally, users have a nonce (basically, a counter) on their signatures.
A user can submit a protocol transaction using a different service, and that invalidates any previously signed, but unused, signature.
Users can also issue a transaction 🔗 to increase their nonce, invalidating any unused signature they created.
Note that nonces are tracked separately between IdGateway
and ProvenanceGateway
, so to invalidate all unused Royal Protocol signatures a user needs to issue this transaction to both contracts.