How the HASH ID System in 3DPass Protects Against Object Copying: A Technical Deep Dive
The HASH ID system in 3DPass prevents unauthorized object copying by generating deterministic cryptographic fingerprints for 3D assets, enforcing on-chain uniqueness through duplicate hash detection, and requiring explicit permissions with valid serial numbers for any authorized replication.
The 3DPass blockchain protocol ensures digital scarcity for three-dimensional objects through a robust identification mechanism implemented in the 3dpass/3dp repository. This system leverages the p3d recognition toolkit to create immutable HASH IDs that serve as unique on-chain fingerprints, establishing an enforced one-to-one mapping between physical 3D assets and their digital representations.
Cryptographic Fingerprint Generation
Every tokenized object begins with a deterministic hash calculation that produces its unique identity. When a user invokes put_object or inspect_put_object, the pallet executes the calc_hashes function located in pallets/poscan/src/lib.rs (lines ≈ 1620‑1630).
This function calls poscan_algo::hashable_object::calc_obj_hashes_n, which processes the raw 3D object data through the p3d algorithm to generate a deterministic list of H256 hashes. These hashes constitute the object's HASH ID—a cryptographic fingerprint derived entirely from the object's shape and geometric properties. Because the algorithm is deterministically tied to the object's physical geometry, any identical copy will produce an identical hash sequence.
Duplicate Detection and Uniqueness Enforcement
Before any object enters permanent storage, the pallet enforces strict uniqueness through the find_dup helper function (lines ≈ 1698‑1708). This function iterates over all existing approved objects in the Objects storage map, comparing the leading hashes of the candidate object against the HASH IDs of stored assets.
If find_dup identifies a match—indicating that an approved object with identical geometric properties already exists—the transaction aborts immediately with Error::DuplicatedHashes. This check occurs within the validation logic of put_object and inspect_put_object (lines ≈ 94‑96), creating an absolute barrier against unauthorized duplication.
Controlled Replication Through Permission Verification
The architecture distinguishes between unauthorized copies and authorized replicas. While raw copying is blocked, controlled replication is permitted only when the original object explicitly grants permission through three verification layers implemented in the replica branch of put_object (lines ≈ 94‑122):
- Hash Correlation: The system verifies that the replica's HASH ID matches at least one hash from the original object (
hashes.iter().any(|h| orig.hashes.contains(h))), ensuring geometric similarity (lines ≈ 100‑104). - Serial Number Validation: The creator must hold a valid serial number that is neither expired nor previously used, checked against the
SerialNumbersinterface defined intraits/serial-numbers/src/lib.rs(lines ≈ 22‑34). - Private Object Permissions: If the original is marked private, the pallet validates that the caller holds specific
PrivateObjectPermissionsbefore allowing replication (lines ≈ 107‑119).
Failure of any check results in immediate transaction rejection, ensuring that replicas exist only through legitimate, traceable channels.
Implementation Examples
Storing a New 3D Object
The following example demonstrates successful object storage, where the pallet automatically generates and validates the HASH ID:
// Runtime environment with signed origin `alice`
let result = Poscan::put_object(
Origin::signed(alice.clone()),
ObjectCategory::Objects3D(Algo3D::Grid2dLow),
false, // is_private
obj_data, // BoundedVec<u8, …> containing raw 3D file
5, // approvals required
None, // let pallet calculate hashes
props, // property vector
false, // not a replica
None, // no original index
None, // no serial number
false, // not self-proved
None, // no pre-computed proof
None, // no IPFS link
);
assert!(result.is_ok()); // succeeds only if HASH ID is unique
Under the hood, calc_hashes produces the H256 hash list, find_dup confirms no approved duplicates exist, and the object receives a permanent, non-fungible HASH ID.
Blocking Duplicate Submissions
Attempting to store identical geometric data triggers the duplication defense:
// `bob` submits the exact same 3D data that `alice` stored
let dup = Poscan::put_object(
Origin::signed(bob.clone()),
ObjectCategory::Objects3D(Algo3D::Grid2dLow),
false,
obj_data.clone(),
5,
None,
props.clone(),
false,
None,
None,
false,
None,
None,
);
assert!(matches!(dup, Err(Error::<Test>::DuplicatedHashes)));
The call fails at the find_dup check, preventing blockchain bloat and preserving asset scarcity.
Creating an Authorized Replica
Authorized replication requires explicit permissions and valid serial numbers:
// `alice` owns object #42 and granted permission to `bob`
let replica = Poscan::put_object(
Origin::signed(bob.clone()),
ObjectCategory::Objects3D(Algo3D::Grid2dLow),
false,
replica_data,
5,
None,
props.clone(),
true, // is_replica = true
Some(42), // original_obj index
Some(7), // serial number (must be unused)
false,
None,
None,
);
assert!(replica.is_ok());
This succeeds only after the pallet verifies the original's approved status, hash correlation, serial number validity through SerialNumbers::is_serial_number_used, and private object permissions.
Summary
- Deterministic HASH IDs: The p3d algorithm generates unique H256 fingerprints from object geometry in
pallets/poscan/src/lib.rs, ensuring physical-to-digital verifiability. - Absolute Duplicate Prevention: The
find_dupfunction enforces one-to-one mapping by rejecting any object whose HASH ID matches an existing approved asset. - Permissioned Replication: Authorized replicas require hash correlation, valid serial numbers from
traits/serial-numbers/src/lib.rs, and explicit private object permissions. - Non-repudiation Guarantees: Together, these mechanisms enforce digital scarcity and provenance tracking for 3D assets on the 3DPass blockchain.
Frequently Asked Questions
How does the HASH ID system generate unique identifiers for 3D objects?
The system uses the calc_hashes function in pallets/poscan/src/lib.rs to invoke poscan_algo::hashable_object::calc_obj_hashes_n, which processes the object's geometric data through the p3d recognition algorithm. This produces a deterministic list of H256 hashes that serve as the object's cryptographic fingerprint. Any geometrically identical object will produce identical hashes, enabling precise duplication detection.
What prevents someone from simply copying a 3D file and tokenizing it again?
The find_dup function scans all approved objects for matching HASH IDs before any new object enters storage. If the geometric fingerprint already exists on-chain, the transaction aborts with Error::DuplicatedHashes. This architectural constraint ensures that identical geometric data cannot be tokenized twice, regardless of who submits the file or what filename they use.
What is the difference between a copy and a replica in the 3DPass system?
A copy is an unauthorized duplicate that fails the uniqueness check and is blocked by find_dup. A replica is an authorized derivation that requires the original object's permission, verified through hash correlation, valid serial numbers, and private object permissions. Replicas maintain provenance links to their originals, while copies are cryptographically impossible to create without changing the object's geometry.
Why are serial numbers required for creating replicas?
Serial numbers, managed through traits/serial-numbers/src/lib.rs, provide granular control over replication rights and prevent infinite printing of authorized replicas. Each serial number can be used only once and may carry expiration dates, allowing original creators to issue limited edition derivatives while maintaining scarcity and audit trails for their 3D assets.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →