Document Registry
The core contract for document identity and lifecycle management.
Overview
The IntegraDocumentRegistry is the heart of the Integra platform - an immutable smart contract that manages document identity, ownership, and service attachments. Every document registered in Integra receives a unique integraHash identifier that serves as its permanent identity across all chains and services.
Key Features
Immutable Document Identity
Each registered document receives:
struct Document {
bytes32 integraHash; // Unique identifier
bytes32 documentHash; // Content hash (SHA-256)
bytes32 referenceHash; // Storage reference (IPFS CID)
address owner; // Document controller
address tokenizer; // Associated tokenizer
address executor; // Authorized automation agent
bytes32 processHash; // Workflow correlation
bytes32 identityExtension; // Additional identity data
bytes32 primaryResolverId; // Primary service
bytes32[] additionalResolverIds; // Additional services
}Document Registration
function registerDocument(
bytes32 documentHash,
bytes32 referenceHash,
address tokenizer,
address executor,
bytes32 processHash,
bytes32 identityExtension,
bytes32 primaryResolverId,
bytes32[] calldata additionalResolverIds
) external returns (bytes32 integraHash);Parameters:
documentHash- SHA-256 hash of document contentreferenceHash- IPFS CID or storage referencetokenizer- Address of tokenizer contract (or zero for no tokenization)executor- Address authorized for automated operationsprocessHash- Workflow identifier for off-chain correlationidentityExtension- Additional identity dataprimaryResolverId- Primary resolver (must succeed)additionalResolverIds- Additional resolvers (best-effort)
Ownership Management
// Transfer document ownership
function transferOwnership(
bytes32 integraHash,
address newOwner,
string calldata reason
) external;
// Query current owner
function getDocumentOwner(bytes32 integraHash)
external view returns (address);Resolver Management
// Set primary resolver
function setPrimaryResolver(
bytes32 integraHash,
bytes32 resolverId
) external;
// Add additional resolver
function addAdditionalResolver(
bytes32 integraHash,
bytes32 resolverId
) external;
// Lock resolver configuration (permanent)
function lockResolvers(bytes32 integraHash) external;Registration Flow
1. Prepare document
├── Hash document content
└── Upload to IPFS/storage
2. Call registerDocument()
├── Registry validates inputs
├── Generates unique integraHash
├── Stores document metadata
├── Calls resolver hooks
└── Emits DocumentRegistered event
3. Receive integraHash
└── Use for all future operationsEvents
event DocumentRegistered(
bytes32 indexed integraHash,
bytes32 documentHash,
address indexed owner,
address tokenizer,
bytes32 processHash
);
event OwnershipTransferred(
bytes32 indexed integraHash,
address indexed oldOwner,
address indexed newOwner,
string reason
);
event ResolverAdded(
bytes32 indexed integraHash,
bytes32 resolverId,
bool isPrimary
);Code Examples
Basic Registration
import { IntegraDocumentRegistry } from '@integra/sdk';
const registry = new IntegraDocumentRegistry(registryAddress, signer);
// Hash your document
const documentHash = ethers.utils.sha256(documentContent);
const referenceHash = ipfsCIDToBytes32(cid);
// Register
const tx = await registry.registerDocument(
documentHash,
referenceHash,
ownershipTokenizerAddress,
ethers.constants.AddressZero, // No executor
ethers.constants.HashZero, // No process hash
ethers.constants.HashZero, // No identity extension
contactResolverId, // Primary resolver
[] // No additional resolvers
);
const receipt = await tx.wait();
const integraHash = receipt.events[0].args.integraHash;With Resolvers
// Register with multiple resolvers
const tx = await registry.registerDocument(
documentHash,
referenceHash,
rentalTokenizerAddress,
automationBotAddress, // Executor for automation
processHash, // Link to CRM workflow
ethers.constants.HashZero,
complianceResolverId, // Primary: compliance checks
[contactResolverId, lifecycleResolverId] // Additional services
);Query Document
// Get document details
const doc = await registry.getDocument(integraHash);
console.log('Owner:', doc.owner);
console.log('Tokenizer:', doc.tokenizer);
console.log('Document Hash:', doc.documentHash);
// Check if document exists
const exists = await registry.documentExists(integraHash);Security Considerations
Access Control
- Only owner can transfer ownership
- Only owner can modify resolvers
- Once locked, resolvers cannot be changed
- Executors have limited permissions
Immutability
integraHashnever changesdocumentHashnever changes- Registration timestamp is permanent
- Core identity is immutable
Resolver Protection
- Gas limits prevent DOS attacks
- Primary resolver failures revert transaction
- Additional resolver failures are logged but don’t revert
Best Practices
- Always verify document hash before registration
- Use meaningful processHash for workflow tracking
- Consider resolver needs at registration time
- Test on testnet before mainnet deployment
- Lock resolvers when configuration is final
Related Documentation
- Architecture Overview - System architecture
- Resolver Composition - Resolver patterns
- Integration Guide - Integration walkthrough
- Document-Token Binding - Binding mechanics