Skip to main content

FDC by hand

In this guide, we will demonstrate how FDC workflow can be performed almost entirely without the use of any script. The purpose of this guide is to familiarize the reader with the FDC workflow and introduce them to tooling surrounding FDC. This is not how the FDC is intended to be used. Nonetheless, the tools described in this guide may prove useful when debugging the actual code.

Request data

In this guide, we will check whether the string rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe is a valid XRPL testnet address. This is an example of the AddressValidity attestation request. We chose it for demonstration purposes because it requires a single input parameter, but the same process would work for any of the FDC attestation types.

Preparing the request

The FDC accepts requests as byte strings, encoded in a special way. These can be produced manually, but an easier way to do it is through a verifier server. A verifier server checks the validity of input data and returns an abiEncodedRequest that can be passed on to the FDC.

In this guide, we will use the Flare-hosted verifier server. Its interactive documentation is available at the address.

The interface requires authentication; the key 00000000-0000-0000-0000-000000000000 can be used. To authenticate, click Authorize in the top right corner, and input the above key.

Verifier server authorize dialogVerifier server authorize dialog
Verifier server authorize dialogVerifier server authorize dialog
Verifier server authorizedVerifier server authorized

Once authenticated, scroll down to the AddressValidity section, and expand the /verifier/xrp/AddressValidity/prepareRequest item. Click on the Try it out button in the upper right corner of the expanded card, and a Request body field will appear.

Verifier AddressValidity prepareRequest expandedVerifier AddressValidity prepareRequest expanded
Verifier Try it outVerifier Try it out

Replace the addressStr field value with the above address rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe, and ensure that the form matches:

Request body
{
"attestationType": "0x4164647265737356616c69646974790000000000000000000000000000000000",
"sourceId": "0x7465737458525000000000000000000000000000000000000000000000000000",
"requestBody": {
"addressStr": "r3wvdzNDkNJ3e5ut1RJfWtBxDHT9sddQRQ"
}
}
Verifier executed with dataVerifier executed with data

Then click Execute. The abiEncodedRequest will appear under the Response body section below, along with the request status which should be VALID.

Verifier response with abiEncodedRequestVerifier response with abiEncodedRequest
Response body
{
"status": "VALID",
"abiEncodedRequest": "0x4164647265737356616c696469747900000000000000000000000000000000007465737458525000000000000000000000000000000000000000000000000000cf6de269807c522f39f90e9a84ec13993f58d5473fe918acbe6197efb5a17c2e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002272337776647a4e446b4e4a336535757431524a665774427844485439736464515251000000000000000000000000000000000000000000000000000000000000"
}

There are two additional values within the request body that we have not yet properly explained. They are the UTF8 hex-encoded strings of AddressValidity and testXRP respectively, zero-padded to 32 bytes. These will be different for each attestation type and source. The full list of values is available below.

Interactive documentation for all attestation types, and the corresponding values for the attestationType and sourceId fields.

Input the appropriate value into the encoder bellow.

To Hex Converter

Encoded string:

Submitting the request

We submit the attestation request to the FDC through the FdcHub contract. It is one of the official Flare contracts, and it is deployed on each of the Flare chains. We will submit the attestation request to the FdcHub contract on Coston2. Either Flare Explorer or Flarescan can be used.

First, we must navigate to the Contract tab on the chosen explorer, and then to Write contract (Flare Explorer, Flarescan). We can then open the requestAttestation function widget. Here we input the abiEncodedRequest value that we received from the verifier server, as well as the fee that needs to be paid to the contract.

FdcHub contract FdcHub contract

The request fee can be queried from the FdcRequestFeeConfigurations contract, through its getRequestFee function (Flare Explorer, Flarescan). The input parameter for this function is the abiEncodedRequest from the verifier server.

FdcRequestFeeConfigurations contract FdcRequestFeeConfigurations contract

To execute the requestAttestation call, we need to connect the wallet. We input the abiEncodedRequest value, and the amount returned by the getRequestFee function.

After the transaction has been executed successfully, we need to open it up in the explorer. We should remember its block number for later.

Links to FdcHub and FdcRequestFeeConfigurations contracts on all Flare chains.

Waiting for the voting round to finalize

Before we can retrieve the proof and data, we must wait for the voting round in which the request was made to be finalized. To check whether the round has been finalized, we need to know the block in which the attestation request transaction was made; or more precisely, we need the timestamp of that block.

We can calculate the voting round ID from the transaction timestamp using the following formula.

votingRoundId=transactionTimestampfirsVotingRoundStartTsvotingEpochDurationSeconds\text{votingRoundId} = \frac{\text{transactionTimestamp} - \text{firsVotingRoundStartTs}}{\text{votingEpochDurationSeconds}}

Here, the transactionTimestamp represents the timestamp of the transaction in which we submitted the attestation request. The other two values are:

firsVotingRoundStartTs=1658430000votingEpochDurationSeconds=90\text{firsVotingRoundStartTs} = 1658430000 \qquad \text{votingEpochDurationSeconds} = 90

The following form calculates the round ID for you.

Voting Round ID Calculator

Round ID:

Once we know the voting round ID, we can go to the Finalizations tab of the Coston2 Systems Explorer. When the round has been finalized, its ID will appear on the list.

Details

Links to all System Explorers Coston - Coston2 - Songbird - Flare

Preparing the proof request

Once the round has been finalized, we can prepare the proof request using the Flare Data Availability Client interactive documentation. As in the previous step, we first need to authenticate using the same API key, 00000000-0000-0000-0000-000000000000. We can then expand the /api/v1/fdc/proof-by-request-round widget, and click Try it out.

Flare Data Availability Client - proof-by-request-round expandedFlare Data Availability Client - proof-by-request-round expanded Flare Data Availability Client - Try it outFlare Data Availability Client - Try it out

We input the voting round ID of our request under the votingRoundId field, and the abiEncodedRequest under the requestBytes field. Then we click on the Execute button. The proof response will appear under the Response body section.

Flare Data Availability Client - Response bodyFlare Data Availability Client - Response body
Response body
{
"response": {
"attestationType": "0x4164647265737356616c69646974790000000000000000000000000000000000",
"sourceId": "0x7465737458525000000000000000000000000000000000000000000000000000",
"votingRound": 1028678,
"lowestUsedTimestamp": 18446744073709552000,
"requestBody": {
"addressStr": "r3wvdzNDkNJ3e5ut1RJfWtBxDHT9sddQRQ"
},
"responseBody": {
"isValid": true,
"standardAddress": "r3wvdzNDkNJ3e5ut1RJfWtBxDHT9sddQRQ",
"standardAddressHash": "0x1e2adcb99103f6396903f33db1526fa66aedfbfee4405def0ef69e0fcd949f47"
}
},
"proof": [
"0x5422093333fabcdd137138efa611efcbb932e65184b12415d2f74d511c1f27b9",
"0x28b15d5e07d2249c7acd8b6deae1706e01be84231264bc66d99553970dbf3bde",
"0x486452aac82578f8b2b9a88df400e80a33d9945111d503f2b205d4209279f225",
"0xc7188d9db7d522ba2b9a84d7aec34745e6acde1a5118372b53aa072d1ad61894"
]
}

The Data Availability Client informs us that the address is, indeed, a valid XRPL address. But the above response is not entirely correct; the timestamp is off by 385. This is a JavaScript rounding error. To get the right response, we need to use the curl command in a terminal.

The curl command is displayed as the first part of the Responses section. In this case, it is:

curl -X 'POST' \
'https://ctn2-data-availability.flare.network/api/v1/fdc/proof-by-request-round' \
-H 'accept: application/json' \
-H 'x-api-key: 00000000-0000-0000-0000-000000000000' \
-H 'Content-Type: application/json' \
-H 'X-CSRFTOKEN: rYJ04UxDuekdzYgChGXRIfQI904VD8qK2UtiBwZ1uMLlkAEwPgNrxvCLsNS5PdYX' \
-d '{
"votingRoundId": 1028678,
"requestBytes": "0x4164647265737356616c696469747900000000000000000000000000000000007465737458525000000000000000000000000000000000000000000000000000cf6de269807c522f39f90e9a84ec13993f58d5473fe918acbe6197efb5a17c2e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002272337776647a4e446b4e4a336535757431524a665774427844485439736464515251000000000000000000000000000000000000000000000000000000000000"
}'

The output of the curl command is then:

{
"response": {
"attestationType": "0x4164647265737356616c69646974790000000000000000000000000000000000",
"sourceId": "0x7465737458525000000000000000000000000000000000000000000000000000",
"votingRound": 1028678,
"lowestUsedTimestamp": 18446744073709551615,
"requestBody": {
"addressStr": "r3wvdzNDkNJ3e5ut1RJfWtBxDHT9sddQRQ"
},
"responseBody": {
"isValid": true,
"standardAddress": "r3wvdzNDkNJ3e5ut1RJfWtBxDHT9sddQRQ",
"standardAddressHash": "0x1e2adcb99103f6396903f33db1526fa66aedfbfee4405def0ef69e0fcd949f47"
}
},
"proof": [
"0x5422093333fabcdd137138efa611efcbb932e65184b12415d2f74d511c1f27b9",
"0x28b15d5e07d2249c7acd8b6deae1706e01be84231264bc66d99553970dbf3bde",
"0x486452aac82578f8b2b9a88df400e80a33d9945111d503f2b205d4209279f225",
"0xc7188d9db7d522ba2b9a84d7aec34745e6acde1a5118372b53aa072d1ad61894"
]
}
Details

Links to all Data Availability Clients Coston - Coston2 - Songbird - Flare

Verifying the data

The last thing remaining is to verify the proof returned by the Data Availability Client. We do so through the FdcVerification contract (Flare Explorer Flarescan).

FdcVerification contractFdcVerification contract

We input the above Response body data as parameters to the verifyAddressValidity function of the FdcVerification contract. When we Read the function, we get back true, which means that the proof is valid.

Details

Flarescan

Flarescan

Flarescan

Flarescan