ARCx
Search…
Smart Contracts
How ARCx products work on the blockchain

Introduction

The ARCx infrastructure is built on Merkle trees to maintain good security and scalability standards. Therefore, there are two concepts that are important to grasp:
  • Epoch: We update our Merkle tree every epoch (i.e. a set period of time, 24h, 1 week, etc). You can view the current epoch duration directly from the PassportScores contract.
  • Merkle root: Is the combined hash of all the elements in the tree. Each epoch progressively has different Merkle roots as new scores and addresses are indexed. You can verify a score's validity on-chain by providing a Merkle proof to the PassportScores contract.
  • Merkle proof: An array of hashes that can be combined with Merkle leaf to verify if this leaf is in the Merkle tree. The Merkle proof is the path from Merkle root to the Merkle leaf. If you hash the Merkle leaf with its corresponding Merkle proof and obtain the same root and the one saved on-chain, then this leaf is cryptographically verified.
  • Merkle leaf: An object that is hashed and saved on the blockchain. In the context of the ARCx ecosystem, each Merkle leaf has the following format:
1
{
2
"account": "0xcd78358fb5fC823b9e789605B7b4fDc1dEf14A1E",
3
"protocol": "0x617263782e6c6f79616c74790000000000000000000000000000000000000000",
4
"score": "175",
5
}
Copied!
Property
Description
account
The address associated with this score. There can be many different scores for the same address, but each score-address combination will be unique.
protocol
The byte32 encoded representation of the protocol name. This is enforced for Smart Contract memory efficiency. The protocol in this example is the byte32 encoded value of arcx.loyalty.
score
The quantification of each score. This must be a positive value, but can be any number within the scope of a BigNumber.

Verifying a Score

To verify a score, simply get the score that you want to prove from the API. Then you can pass the response directly* to the contract to verify it.
*Drop the metadata attribute if included
Example:
  • Address: 0xcd78358fb5fC823b9e789605B7b4fDc1dEf14A1E
  • Protocol: arcx.loyalty
Get tuple from API:
1
https://api.arcx.money/reputation/0xcd78358fb5fC823b9e789605B7b4fDc1dEf14A1E/arcx.creditScore
Copied!
Result:
1
{
2
"account": "0xcd78358fb5fC823b9e789605B7b4fDc1dEf14A1E",
3
"score": "175",
4
"protocol": "0x617263782e6c6f79616c74790000000000000000000000000000000000000000",
5
"merkleProof": [
6
"0x6b9...5d3",
7
"0x221...f5e",
8
"0xe66...ff5",
9
...
10
]
11
}
Copied!
Then use the resulting tuple within your Solidity code (^0.8.4 compatible). You can make the ISapphirePassportScores and SapphireTypes contracts available through the npm package @arcxgame/contracts.
Example:
1
// SPDX-License-Identifier: MIT
2
pragma solidity 0.8.4;
3
4
import { ISapphirePassportScores } from "@arcxgame/contracts/contracts/sapphire/ISapphirePassportScores.sol";
5
import { SapphireTypes } from "@arcxgame/contracts/contracts/sapphire/SapphireTypes.sol";
6
7
contract ExampleContract {
8
9
ISapphirePassportScores public passportScores;
10
11
constructor(
12
address _passportScoresAddress
13
) {
14
passportScores = _passportScoresAddress;
15
}
16
17
modifier checkScoreProof (
18
SapphireTypes.ScoreProof memory _scoreProof
19
) {
20
// Optional: Enforce verification from the caller only
21
require(
22
msg.sender == _scoreProof.account,
23
"The proof must correspond to sender"
24
);
25
26
passportScores.verify(_scoreProof); // <--- How to verify score
27
_;
28
}
29
30
// Will revert if proof is invalid
31
function doSomethingThatNeedsValidScore(
32
SapphireTypes.ScoreProof _scoreProof
33
)
34
external
35
checkScoreProof(_scoreProof)
36
{
37
// Some code to be executed if the score proof is valid
38
if (_scoreProof.score > 50) {
39
// Do something
40
}
41
}
42
}
Copied!
You can find all types in our contracts npm package.

Help

If you have any questions or suggestions, we'd love your input on our discord server. Happy building! ノ
Last modified 20d ago