Skip to main content

Verification Process

Ensuring the authenticity of a physical object is the primary function of Tokentagged. Our architecture supports two levels of verification:

  1. Local Verification (Off-chain): Immediate cryptographic check of the hardware's authenticity and origin via the Web App.
  2. On-chain Verification: A blockchain transaction that cryptographically proves the presence of the physical tag at a specific time and block, emitting a permanent event.

1. Local Verification (Trust Chain Check)

When a user scans a Tokentag or Swap Card, the Web App performs an instant validation of the "Trust Chain" described in the Key Generation section.

This process involves verifying three distinct signatures provided by the chip:

  1. Attestation Signature: Verifies that the Master Key was authorized by the Manufacturer (Issuer).
  2. Card Attestation Signature: Verifies that the Card/Wallet Key was derived from that valid Master Key.
  3. Challenge Signature: Verifies that the chip physically present holds the private Card/Wallet Key.

If all three signatures are valid, the Web App confirms: "This is a genuine Tokentag, and it corresponds to the displayed digital asset."

2. On-chain Verification (Proof of Presence)

For higher security requirements, history tracking, or DApp integration, Tokentagged offers an on-chain verification method. This allows a user to broadcast a proof to the Ethereum blockchain that they successfully scanned the physical tag.

The Mechanism

To prevent replay attacks (e.g., copying a signature and using it later or on another chain), the signature generated by the Tokentag for on-chain verification must include specific dynamic context data.

The Smart Contract function verifyTokentag performs the check using ecrecover.

Data Schema for Signing

The chip must sign a hash constructed from the following data points:

Data PointTypeDescription
Token IDuint256The full ID of the token (which includes the Tag Address).
OperatoraddressThe address of the user sending the transaction (msg.sender).
CollectionaddressThe address of the NFT Smart Contract (Collection) where the item is minted.
Blockhashbytes32The hash of a recent block (for time-bounding).
Chain IDuint256The ID of the blockchain (e.g., 1 for Mainnet) to prevent cross-chain replays.

The Hashing Logic (Solidity):

bytes32 messageHash = keccak256(
abi.encodePacked(id, operator, address(this), blockhash, block.chainid)
);
bytes32 ethSignedMessageHash = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)
);

Time-Bounded Validity

To ensure the proof is recent, the Smart Contract enforces a time limit based on the blockhash.

  • The signature must reference a block number that is not in the future.
  • The block must be within the last 80 blocks (approx. 16 minutes on Ethereum).
Expiration

If the transaction is pending for too long (e.g., due to low gas fees), the signature will expire because the referenced blockhash becomes too old or unreachable by the EVM (blockhash only works for the last 256 blocks).

The Event: TokentagVerified

If the signature is valid and matches the Tag ID embedded in the Token ID, the contract emits an event. External systems (indexers, the Web App) listen for this event to update the asset's status (e.g., "Physically Verified on [Date]").

event TokentagVerified(
uint256 indexed id,
address indexed operator,
uint256 timestamp,
bytes data
);

Workflow Diagram

The following diagram illustrates the data flow for the On-chain verification.