CIP67 API
CIP67 (Cardano Improvement Proposal 67) defines a standard for asset name labels on the Cardano blockchain. The Cardano Client Library provides utilities for creating, validating, and working with CIP67-compliant asset names. The utilities keep the rules around padding, CRC8 checksum, and label ranges in one place so you can focus on assembling asset names without re-implementing the bit-twiddling logic.
Key Features
- Label Encoding: Convert decimal labels to CIP67 asset name prefixes
- Label Decoding: Extract labels from CIP67 asset names
- Validation: Verify CIP67 compliance and checksum validation
- CRC8 Checksum: Built-in CRC8 checksum calculation and verification
- Standard Compliance: Full CIP67 specification support
Dependencies
- Group ID: com.bloxbean.cardano
- Artifact ID: cardano-client-cip67
- Dependencies: crypto
Usage Examples
Converting Labels to Asset Name Prefixes
Generate the 4-byte prefix for a given label; you can append your own suffix bytes afterwards.
// Convert a decimal label to CIP67 asset name prefix
int label = 222; // Label range: [0, 65535]
byte[] prefixBytes = CIP67AssetNameUtil.labelToPrefix(label);
// Convert to hex string for display
String prefixHex = HexUtil.encodeHexString(prefixBytes);
System.out.println("Label " + label + " -> Prefix: " + prefixHex);
// Output: Label 222 -> Prefix: 000de140Extracting Labels from Asset Names
Recover the numeric label from the prefix to inspect or validate existing assets.
// Extract label from CIP67 asset name prefix
byte[] prefixBytes = HexUtil.decodeHexString("000de140");
int extractedLabel = CIP67AssetNameUtil.prefixToLabel(prefixBytes);
System.out.println("Prefix 000de140 -> Label: " + extractedLabel);
// Output: Prefix 000de140 -> Label: 222Validating CIP67 Asset Names
Check both padding and checksum to confirm an asset name prefix is CIP67-compliant before using it.
// Validate asset name from bytes
byte[] assetNameBytes = HexUtil.decodeHexString("000de140");
boolean isValidBytes = CIP67AssetNameUtil.isValidAssetName(assetNameBytes);
System.out.println("Asset name valid (bytes): " + isValidBytes);
// Output: Asset name valid (bytes): true
// Validate asset name from integer
int assetNameInt = 0x000de140;
boolean isValidInt = CIP67AssetNameUtil.isValidAssetName(assetNameInt);
System.out.println("Asset name valid (int): " + isValidInt);
// Output: Asset name valid (int): trueWorking with Asset Names in Transactions
Combine the CIP67 prefix with your human-readable suffix to form the final asset name used in minting.
// Create asset name with CIP67 label
int label = 222; // NFT label
byte[] labelPrefix = CIP67AssetNameUtil.labelToPrefix(label);
// Create full asset name by combining prefix with unique suffix
byte[] uniqueSuffix = "MyNFT".getBytes(StandardCharsets.UTF_8);
byte[] fullAssetName = new byte[labelPrefix.length + uniqueSuffix.length];
System.arraycopy(labelPrefix, 0, fullAssetName, 0, labelPrefix.length);
System.arraycopy(uniqueSuffix, 0, fullAssetName, labelPrefix.length, uniqueSuffix.length);
// Create asset with CIP67-compliant name
Asset nftAsset = Asset.builder()
.name(HexUtil.encodeHexString(fullAssetName))
.value(BigInteger.ONE)
.build();Batch Processing of Asset Names
Run validations over multiple asset names and extract labels where valid.
// Process multiple asset names
List<String> assetNameHexes = Arrays.asList(
"000de140", // Valid CIP67 asset name
"000de141", // Invalid padding
"100de140", // Invalid padding
"000de130" // Invalid checksum
);
for (String assetNameHex : assetNameHexes) {
byte[] assetNameBytes = HexUtil.decodeHexString(assetNameHex);
boolean isValid = CIP67AssetNameUtil.isValidAssetName(assetNameBytes);
if (isValid) {
int label = CIP67AssetNameUtil.prefixToLabel(assetNameBytes);
System.out.println(assetNameHex + " -> Valid, Label: " + label);
} else {
System.out.println(assetNameHex + " -> Invalid");
}
}Common Label Examples
Predefined labels are handy for common asset categories; encode them once and reuse.
// Common CIP67 labels
Map<Integer, String> commonLabels = new HashMap<>();
commonLabels.put(222, "NFT Standard");
commonLabels.put(333, "Fungible Token Standard");
commonLabels.put(444, "Rich Fungible Token Standard");
for (Map.Entry<Integer, String> entry : commonLabels.entrySet()) {
int label = entry.getKey();
String description = entry.getValue();
byte[] prefix = CIP67AssetNameUtil.labelToPrefix(label);
String prefixHex = HexUtil.encodeHexString(prefix);
System.out.println("Label " + label + " (" + description + ") -> " + prefixHex);
}API Reference
CIP67AssetNameUtil Class
Utility class for CIP67 asset name operations.
Static Methods
labelToPrefix(int label)
Converts a decimal label to CIP67 asset name prefix.
public static byte[] labelToPrefix(int label)Parameters:
label- Decimal label in range [0, 65535]
Returns: 4-byte prefix array
prefixToLabel(byte[] labelBytes)
Extracts the label from CIP67 asset name prefix.
public static int prefixToLabel(byte[] labelBytes)Parameters:
labelBytes- 4-byte prefix array
Returns: Decimal label
isValidAssetName(int assetName)
Validates a CIP67 asset name from integer value.
public static boolean isValidAssetName(int assetName)Parameters:
assetName- Asset name as integer
Returns: true if valid CIP67 asset name
isValidAssetName(byte[] assetName)
Validates a CIP67 asset name from byte array.
public static boolean isValidAssetName(byte[] assetName)Parameters:
assetName- Asset name as byte array
Returns: true if valid CIP67 asset name
CIP67 Specification Details
Asset Name Structure
CIP67 asset names have the following structure:
- Bits 0-3: Reserved (must be 0000)
- Bits 4-11: CRC8 checksum
- Bits 12-31: Label (20 bits, range 0-1048575, but typically 0-65535)
- Bits 32+: Asset-specific data
Label Constraints
- Range: 0 to 65535 (16-bit range commonly used)
- Encoding: Big-endian format
- Checksum: CRC8 validation required
Validation Rules
- Padding Check: Bits 0-3 must be 0000
- Checksum Verification: CRC8 checksum must match calculated value
- Label Range: Label must be within valid range
Common Label Registry
| Label | Description | Prefix (Hex) |
|---|---|---|
| 222 | NFT Standard | 000de140 |
| 333 | Fungible Token Standard | 0014d140 |
| 444 | Rich Fungible Token Standard | 001bc140 |
Best Practices
- Use Standard Labels: Use established labels (222, 333, 444) for common asset types
- Validate Asset Names: Always validate asset names before using them
- Handle Errors: Check validation results before processing asset names
- Preserve Checksums: Don’t modify asset name prefixes without recalculating checksums
- Document Custom Labels: Document any custom labels used in your application
Integration with Other Standards
With CIP68 (Datum Metadata)
// Create CIP68-compliant asset name
int label = 222; // NFT label for CIP68
byte[] labelPrefix = CIP67AssetNameUtil.labelToPrefix(label);
// Combine with asset-specific data
String assetName = HexUtil.encodeHexString(labelPrefix) + "MyUniqueNFT";With CIP25 (NFT Metadata)
// Create CIP25 NFT with CIP67-compliant name
int label = 222;
byte[] labelPrefix = CIP67AssetNameUtil.labelToPrefix(label);
String assetName = HexUtil.encodeHexString(labelPrefix) + "MyNFT";
CIP25NFT nft = CIP25NFT.create()
.name("My CIP67 NFT")
.image("https://example.com/image.png");
Asset nftAsset = Asset.builder()
.name(assetName)
.value(BigInteger.ONE)
.build();For more information about CIP67, refer to the official CIP67 specification .