Skip to content

codatta/codattaOnchainDataVerify

Repository files navigation

1. Purpose

Scope: Tasks from the Binance Booster Campaign.

Goal: Let contributors independently verify that their valid data contributions were correctly, completely, and tamper-proof recorded on-chain by comparing data fingerprints for consistency.

2. Preparation

2.1 Retrieve your on-chain fingerprint via the block explorer

Steps

  • Open the block explorer https://basescan.org/address/0xd0A4950C096daC5Ae5A0f74Ff3eE316d74558974#readContract.
  • Call the getUserRecords method.
  • Enter parameters:
    • user: your wallet address
    • page: page index, enter 0
    • size: items per page, enter 1000
  • Click Query to get the result:
    • rets: an array that may contain multiple records, in the shape [[submissionID, fingerprint]], where:
      • submissionID: e.g., 2025082903351000xxxxxx
      • fingerprint: e.g.,0x3f287de1fac99c807b8b23e67fa41b6e8547c45a7c37868f71457b1400xxxxxx
    • end: whether the query is finished
      • true: finished
      • false: not finished — increase page and repeat until end is true. Note:
  • 1 fingerprint = 1 valid contribution.
  • The number of fingerprints equals the number of valid contributions recorded for that address.

2.2 Aggregate your contribution data

Your contribution consists of X-Data and Y-Data.

  • X-Data: original/raw data
  • Y-Data: annotated/label data Example (food labeling task)
  • X-Data
    • Image (the original food image you uploaded)
  • Y-Data
    • Food Name
    • Food Category
    • Brand / Store
    • Region
    • Quantity of food

All of the above are user-submitted. You can reconstruct and save them yourself. Fill the template exactly as originally submitted

(replace the values in <>; if it was empty, use an empty string ""). Case, spaces, punctuation, and brackets must match exactly.

{
  "brand": "<brand/store at the time; empty string if none>",
  "images": [
    {
      "hash": "e6b024a0a5b3f202667300f3621190e666a52cadfd715664cd2e082cb0d3e03a"
    }
  ],
  "region": "the region you selected, e.g. PK",
  "foodName": "the Food Name you entered at the time",
  "quantity": "the exact dropdown text, e.g. Individual (1 person)",
  "foodCategory": "the exact category text you selected"
}

Image hashing:

Because raw images are large, we typically include their SHA-256 hash in the fingerprint input.

  • Use an online tool (drag the image to the input box to get a SHA-256 hash), or
  • Compute it yourself with a script/tool of your choice.

2.3 Collect auxiliary fields

Alongside the contribution JSON, two auxiliary fields are used to generate the fingerprint:

  • Address* — your on-chain wallet address (identity).
  • Quality — the rating of your contribution. After task review, the Codatta platform evaluates authenticity/completeness and assigns a rating. Only rated contributions are considered valid and recorded. For the food labeling example, ratings (high → low) are: S, A, B, C, D.

Notes & strictness

  • Key names must mirror the task form exactly (e.g., foodName, foodCategory, region, quantity). Case and spelling must match the original form labels.
  • Include all fields you completed on the task form. If you filled fields not listed in the template, add them with the exact original labels and values.
  • Strict equality: any difference in key names / values / order (including spaces, case, punctuation) will change the fingerprint.
  • If you forgot your original entries, you may look them up on the Codatta platform (if available).

3. Generate the fingerprint (JCS → ABI.encode → keccak256)

Reconstruct the exact JSON from what you originally entered/uploaded in the form, then recompute the fingerprint locally using the public rules and compare it with the on-chain fingerprint, entry by entry, to complete independent verification.

Step 1 | JCS-canonicalize the contribution JSON → produce submissionData

Step 2 | ABI-encode the contribution data together with the auxiliary fields (Solidity) → produce encodedData

Encode the tuple using Solidity ABI. You can implement this with ethers.js; an example is shown below (running it will output encodedData).

const encodedData = ethers.AbiCoder.defaultAbiCoder().encode(
        ["address", "string", "string"],
        [address, quality, submissionData]
    );

quality accepts "S","A","B","C","D"," (use empty string "" if the task had no rating) You can follow the https://github.com/codatta/submission-data-fingerprint/blob/main/tools/fingerprint.js#L8 to implement this。

Step 3 | Compute keccak256 → obtain the local fingerprint localFingerprint

Compute it with the following ethers.js code.

const hash = ethers.keccak256(encodedData);

The calculation yields a 0x… value — that is the localFingerprint.

You can follow the https://github.com/codatta/submission-data-fingerprint/blob/main/tools/fingerprint.js#L14 to implement this。

Step 4 — Verify

Using the on-chain fingerprint obtained in Step 2.1, compare it with localFingerprint:

Result semantics

  • localFingerprint == onChainFingerprint → Verification successful This JSON matches the fingerprint recorded on-chain; your data has not been tampered with.
  • No on-chain fingerprint found for the specified address / submission → This address has no contribution attested on-chain.
  • localFingerprint != onChainFingerprint → Verification failed A step may be incorrect; please recheck your JSON/address/quality or contact support.

When your locally recomputed fingerprints match the on-chain records entry by entry, it proves that all corresponding contributions have been completely, correctly, and immutably recorded on-chain.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages