# How the HASH ID System in 3DPass Protects Against Object Copying: A Technical Deep Dive

> Discover how 3DPass HASH ID secures 3D assets against copying. Learn about deterministic fingerprints, on-chain uniqueness, and permission-based replication for your digital creations.

- Repository: [3Dpass/3dp](https://github.com/3dpass/3dp)
- Tags: deep-dive
- Published: 2026-02-23

---

**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`](https://github.com/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`](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs) (lines [≈ 1620‑1630](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L1620)).

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](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L1698)). 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](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L94)), 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](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L94)):

- **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](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L100)).
- **Serial Number Validation**: The creator must hold a valid serial number that is neither expired nor previously used, checked against the `SerialNumbers` interface defined in [`traits/serial-numbers/src/lib.rs`](https://github.com/3dpass/3dp/blob/main/traits/serial-numbers/src/lib.rs) (lines [≈ 22‑34](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L22)).
- **Private Object Permissions**: If the original is marked private, the pallet validates that the caller holds specific `PrivateObjectPermissions` before allowing replication (lines [≈ 107‑119](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs#L107)).

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:

```rust
// 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:

```rust
// `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:

```rust
// `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`](https://github.com/3dpass/3dp/blob/main/pallets/poscan/src/lib.rs), ensuring physical-to-digital verifiability.
- **Absolute Duplicate Prevention**: The `find_dup` function 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`](https://github.com/3dpass/3dp/blob/main/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`](https://github.com/3dpass/3dp/blob/main/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`](https://github.com/3dpass/3dp/blob/main/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.