-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from rarimo/reference/polygonid-integration
PolygonID x Rarimo
- Loading branch information
Showing
4 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
--- | ||
sidebar_label: Polygon ID State Replication | ||
--- | ||
|
||
# Polygon ID State Replication | ||
|
||
This page contains technical resources related to the [Polygon ID State Replication](/use-cases/polygon-id). | ||
|
||
## Demo DApp | ||
|
||
Users can check out how the state replication works using our demo DApp. Leveraging the state replication lets users submit a Polygon ID zero-knowledge proof on Ethereum. Users get an SBT as a reward. | ||
|
||
Testnet(Sepolia): https://polygon.mainnet-beta.rarimo.com/ | ||
|
||
## Identity Relayer | ||
|
||
This service replicates GIST roots and identity states on demand. | ||
Call it before submitting proof on the destination chain. | ||
|
||
- Github: https://github.com/rarimo/identity-relayer-svc | ||
- API Reference: https://rarimo.github.io/rarimo-core/docs/common/bridging/002-identity.html | ||
- Testnet URI: https://api.mainnet-beta.rarimo.com | ||
|
||
### Relayer endpoints | ||
|
||
To perform state publishing, you can execute POST `/integrations/relayer/state/relay` request with the following body: | ||
|
||
```json | ||
{ | ||
"chain": "Ethereum", | ||
"hash": "0x212bc6f8194aa63eee97b0566b7cd65c66bb57cc4936c11e611f1042bb0b7118", | ||
"waitConfirm": true | ||
} | ||
``` | ||
|
||
To perform GIST publishing, you can execute POST `/integrations/relayer/gist/relay` request with the following body: | ||
|
||
```json | ||
{ | ||
"chain": "Ethereum", | ||
"hash": "0x1e4b74c14388fbfca27496828d24c248637792eb0286e7519860abb3ec01bc70", | ||
"waitConfirm": true | ||
} | ||
``` | ||
|
||
- `"chain": "chain_name"` - chain, to which the state (or gist) will be relayed; | ||
- `"hash": "0x..."` - hash of the state (or gist) to relay. Same as on the state contract in 0x... hex format; | ||
- `"waitConfirm": true` indicates whether the request should wait until the transaction is included in the block (`false` by default); | ||
|
||
The response codes: | ||
- `200` - successful relay, body contains tx hash; | ||
- `404` - the state is not transferred yet; try to repeat the request later; | ||
- `400` - state has been relayed before; | ||
|
||
## Smart Contracts | ||
|
||
<!-- TODO: Add mainnet contracts addresses --> | ||
|
||
### `LightweightStateV2` | ||
|
||
It's a modified state contract meant for the destination chains. | ||
It checks a TSS from the Rarimo validators instead of a ZKP to transit the state and only holds a partial history. | ||
The relayer service lazily updates the contract whenever a user wants to submit ZKP on a particular chain. | ||
|
||
#### Deployments | ||
|
||
|Chain| ChainID| Address| | ||
| --- | --- | --- | | ||
| Sepolia | `11155111` | `0x4EaEdFbD2156f5D77b11c4fE073032c4D90Dd315` \([Etherscan](https://sepolia.etherscan.io/address/0x4EaEdFbD2156f5D77b11c4fE073032c4D90Dd315)\) | | ||
|
||
#### Interface | ||
|
||
```solidity | ||
contract LightweightStateV2 is ILightweightStateV2, UUPSSignableUpgradeable, Signers { | ||
address public override sourceStateContract; | ||
|
||
uint256 internal _currentGistRoot; | ||
|
||
mapping(uint256 => GistRootData) internal _gistsRootData; | ||
|
||
mapping(uint256 => IdentityInfo) internal _identitiesInfo; | ||
|
||
function signedTransitGISTData( | ||
uint256 prevGist_, | ||
GistRootData calldata gistData_, | ||
bytes calldata proof_ | ||
) external override { | ||
// ... | ||
|
||
emit SignGISTDataTransited(gistData_.root, prevGist_); | ||
} | ||
|
||
function signedTransitStateData( | ||
uint256 prevState_, | ||
StateData calldata stateData_, | ||
bytes calldata proof_ | ||
) external override { | ||
// ... | ||
|
||
emit SignStateDataTransited(stateData_.id, stateData_.state, prevState_); | ||
} | ||
} | ||
|
||
``` | ||
|
||
- `sourceStateContract` — address of the state contract on the source chain (Rarimo); | ||
- `_currentGistRoot` — the latest transferred GIST root; | ||
- `_gistsRootData` — mapping of the GIST roots to their data. | ||
Data stores two roots, one that replaced the other, timestamp and block number; | ||
- `_identitiesInfo` — mapping of the identity IDs to the information about this identity. | ||
Information has the latest identity state and the history of the states with timestamps; | ||
- `signedTransitGISTData()` — adds the GIST root to the history and changes the current root variable if the proposed one is newer; | ||
- `signedTransitStateData(...)` — adds the state to the history and sets the last state of the identity to the provided one if it's newer; | ||
|
||
Both functions require proof of change — TSS of Rarimo signature providers. | ||
Also, core functions emit events, which contain the data about changes: | ||
- `SignGISTDataTransited` contains the data about roots, the previous one and the provided one; | ||
- `SignStateDataTransited` contains the provided identity state, previous state, and identity ID; | ||
|
||
Full implementation can be found [here](https://github.com/rarimo/polygonid-integration-contracts/blob/master/contracts/LightweightStateV2.sol). | ||
|
||
### `QueryVerifier` | ||
|
||
It's an implementation of a verifier contract that inherits Iden3 [ZKPVerifier](https://github.com/iden3/contracts/blob/master/contracts/verifiers/ZKPVerifier.sol) that mints an SBT. | ||
It is configured to work with the KYCAge demo credential. | ||
|
||
#### Deployments | ||
|
||
|Chain| ChainID| Address| | ||
| --- | --- | --- | | ||
| Sepolia | `11155111` | `0xb95734f64f242E976E155594E1E15D39700Cbb26` \([Etherscan](https://sepolia.etherscan.io/address/0xb95734f64f242E976E155594E1E15D39700Cbb26)\) | | ||
|
||
#### Interface | ||
|
||
```solidity | ||
contract QueryVerifier is IQueryVerifier, ZKPVerifier { | ||
uint256 public constant AGE_VERIFY_REQUEST_ID = 1; | ||
|
||
IVerifiedSBT public override sbtContract; | ||
|
||
mapping(address => uint256) public override addressToUserId; | ||
|
||
mapping(uint256 => VerificationInfo) internal _verificationsInfo; | ||
|
||
function _beforeProofSubmit( | ||
uint64, | ||
uint256[] memory inputs_, | ||
ICircuitValidator | ||
) internal override { | ||
require( | ||
!isUserVerified(_getIdentityId(inputs_)), | ||
"QueryVerifier: identity with this identifier has already been verified" | ||
); | ||
require( | ||
addressToUserId[msg.sender] == 0, | ||
"QueryVerifier: current address has already been used to verify another identity" | ||
); | ||
} | ||
|
||
function _afterProofSubmit( | ||
uint64, | ||
uint256[] memory inputs_, | ||
ICircuitValidator | ||
) internal override { | ||
uint256 tokenId_ = sbtContract.nextTokenId(); | ||
uint256 userId_ = _getIdentityId(inputs_); | ||
|
||
_verificationsInfo[userId_] = VerificationInfo(msg.sender, tokenId_); | ||
addressToUserId[msg.sender] = userId_; | ||
|
||
sbtContract.mint(msg.sender); | ||
|
||
emit Verified(userId_, msg.sender, tokenId_); | ||
} | ||
} | ||
``` | ||
|
||
- `AGE_VERIFY_REQUEST_ID` — hard-coded KYC demo request ID; | ||
- `sbtContract` — address of the SBT contract, which will be called to mint Soulbound token; | ||
- `addressToUserId` — mapping of addresses to user's identity ID; | ||
- `_verificationsInfo` — mapping of user's identity ID to the verification information, which contains the prover address and minted token ID; | ||
- `_beforeProofSubmit` — hook that performs some necessary security checks; | ||
- `_afterProofSubmit` — another hook, which mints the SBT in case of valid verification; | ||
|
||
The function that verifies the ZKP - `verify(...)` is inherited from the [ZKPVerifier](https://github.com/iden3/contracts/blob/master/contracts/verifiers/ZKPVerifier.sol) contract. | ||
|
||
Full implementation can be found [here](https://github.com/rarimo/polygonid-integration-contracts/blob/master/contracts/QueryVerifier.sol). | ||
|
||
### `VerifiedSBT` | ||
|
||
The SBT is awarded to users who complete the Polygon ID x Rarimo demo. | ||
|
||
#### Deployments | ||
|
||
|Chain| ChainID| Address| | ||
| --- | --- | --- | | ||
| Sepolia | `11155111` | `0x8A55c9CfDCbCeDcA1A543295a3F54351C335A20f` \([Etherscan](https://sepolia.etherscan.io/address/0x8A55c9CfDCbCeDcA1A543295a3F54351C335A20f)\) | | ||
|
||
#### Interface | ||
|
||
```solidity | ||
contract VerifiedSBT is | ||
IVerifiedSBT, | ||
UUPSUpgradeable, | ||
ERC721EnumerableUpgradeable, | ||
OwnableUpgradeable | ||
{ | ||
address public override verifier; | ||
uint256 public override nextTokenId; | ||
string public override tokensURI; | ||
|
||
// ... | ||
|
||
function mint(address recipientAddr_) external override onlyVerifier {} | ||
|
||
function _beforeTokenTransfer( | ||
address from_, | ||
address to_, | ||
uint256 firstTokenId_, | ||
uint256 batchSize_ | ||
) internal override { | ||
// ... | ||
} | ||
} | ||
``` | ||
|
||
- `verifier` — address of the verifier's (`QueryVerifier`) contract; | ||
- `nextTokenId` — nonce that is incremented each time a new SBT is created; | ||
- `tokensURI` — token's picture URI; | ||
- `onlyVerifier()` — modifier that allows calls only by the verifier contract; | ||
- `mint(address)` — mints the SBT for the given address; | ||
- `_beforeTokenTransfer(...)` — prevents the token from being transferred (only burn and mint are available); | ||
|
||
Full implementation can be found [here](https://github.com/rarimo/polygonid-integration-contracts/blob/master/contracts/VerifiedSBT.sol). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters