Radica Tag
The RadicaTag.sol
contract handles the creation, the storage and the retrieval of the tag certificates.
Create Tag
In order to create a Tag the followning function should be called:
function createTag(
address tagAddr,
Metadata memory metadata,
TracebilityMetadata memory tracebilityMetadata,
bytes32 proofHash
) public onlyOwner {
require(proofHash != 0, "Proof hash cannot be zero");
require(tagAddrToCert[tagAddr].id == 0, "Tag already in use");
uint256 certId = _deriveCertId(msg.sender, tagAddr);
tagAddrToCert[tagAddr] = Certificate({
id: certId,
metadata: metadata,
tracebilityMetadata: tracebilityMetadata
});
(bool success, ) = radicaPropertyAddr.call(
abi.encodeWithSignature(
"setProof(uint256,bytes32)",
certId,
proofHash
)
);
require(success, "Call to setProof failed");
}
The createTag
function takes the following parameters:
tagAddr
: the address of the tagmetadata
: the metadata of the tagtracebilityMetadata
: the tracebility metadata of the tagproofHash
: the hashed proof of the tag (needed to claim the property of the product)
The function can only be called by Radica. This is because it is a root of trust for the system, thus the certificates should be issued by Radica.
Retrieve Certificate
The certificate of a product can be retrieved by the public mapping tagAddrToCert
which maps the tag address to the certificate.
Certificate Format
The certificate is stored in the following format:
struct Metadata {
string serialNumber;
string name;
string description;
string image;
string manufacturer;
string externalUrl;
}
struct TracebilityMetadata {
string batchId;
string supplierChainHash;
}
struct Certificate {
uint256 id;
Metadata metadata;
TracebilityMetadata tracebilityMetadata;
}
The Certificate Id is derived from the tag address and the issuer address. It has type uint256
: the first 96 bit are formed by the Issuer Fingerprint while the last 160 bit are the Tag Address.
function _deriveCertId(
address issuerAddr,
address tagAddr
) private pure returns (uint256) {
uint256 issuerAddrUint = uint256(uint160(issuerAddr));
uint256 tagAddrUint = uint256(uint160(tagAddr));
uint256 issuerFP = issuerAddrUint >> 64;
return (issuerFP << 160) | tagAddrUint;
}
This is needed to make it compatible with multiple Certificate Authorities in the future.