Product Authenticity Verification
What it does:
Verifies and records the authenticity and provenance of products on-chain, ensuring buyers and stakeholders can trust origin, ownership, and history.
Why it matters:
Prevents counterfeiting, improves transparency in supply chains, and builds consumer confidence in product authenticity.
How it works:
-
Manufacturers or suppliers register products with metadata, serial numbers, and provenance details
-
Each product is assigned a unique on-chain identifier or NFT
-
Ownership transfers, supply chain events, and certifications are logged immutably
-
Buyers and auditors can verify authenticity and trace the product journey
-
Smart contracts can trigger alerts for counterfeit detection
-
Integrates with marketplaces, warranty systems, or logistics tracking
-
Public dashboards display provenance history and authenticity status
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title ProductAuthenticityVerification
* @author Nam
* @notice Tracks product authenticity and provenance on-chain using NFTs
*/
contract ProductAuthenticityVerification is ERC721, Ownable {
struct Product {
string metadataURI; // e.g., IPFS or product info
uint256 creationTimestamp;
address currentOwner;
}
mapping(uint256 => Product) public products;
uint256 public productCount;
// -------------------- EVENTS --------------------
event ProductRegistered(uint256 indexed productId, address indexed manufacturer);
event OwnershipTransferred(uint256 indexed productId, address indexed from, address indexed to);
// -------------------- CONSTRUCTOR --------------------
constructor() ERC721("ProductAuthenticityNFT", "PANFT") {}
// -------------------- PRODUCT MANAGEMENT --------------------
function registerProduct(address _manufacturer, string calldata _metadataURI) external onlyOwner {
require(_manufacturer != address(0), "Invalid manufacturer");
productCount += 1;
uint256 productId = productCount;
_safeMint(_manufacturer, productId);
products[productId] = Product({
metadataURI: _metadataURI,
creationTimestamp: block.timestamp,
currentOwner: _manufacturer
});
emit ProductRegistered(productId, _manufacturer);
}
// -------------------- OWNERSHIP TRACKING --------------------
function transferProduct(uint256 _productId, address _to) external {
require(ownerOf(_productId) == msg.sender, "Not the product owner");
require(_to != address(0), "Invalid recipient");
_transfer(msg.sender, _to, _productId);
products[_productId].currentOwner = _to;
emit OwnershipTransferred(_productId, msg.sender, _to);
}
// -------------------- VIEW FUNCTIONS --------------------
function getProduct(uint256 _productId) external view returns (Product memory) {
return products[_productId];
}
function verifyOwnership(uint256 _productId, address _user) external view returns (bool) {
return ownerOf(_productId) == _user;
}
}