Identity Factory¶
The Identity Factory is a specialized contract deployment system for creating ERC-734/ERC-735 compliant identity contracts. It provides standardized deployment of identity contracts with key management and claim verification capabilities.
Overview¶
The Identity Factory provides:
- Identity Deployment: Deploy ERC-734/ERC-735 identity contracts
- Key Management Setup: Initialize identity contracts with management keys
- Claim Integration: Setup trusted issuer relationships
- Registry Integration: Automatic registration with identity registries
- Template Management: Manage different identity contract templates
Key Features¶
Identity Contract Deployment¶
- ERC-734 Compliance: Deploy key manager compliant contracts
- ERC-735 Compliance: Deploy claim holder compliant contracts
- Combined Implementation: Deploy contracts supporting both standards
- Custom Configuration: Support custom identity configurations
Key Management Integration¶
- Management Keys: Setup initial management keys
- Action Keys: Configure action-specific keys
- Claim Keys: Setup claim signing keys
- Encryption Keys: Configure encryption capabilities
Registry Integration¶
- Automatic Registration: Register identities with central registry
- Trusted Issuer Setup: Configure trusted issuer relationships
- Claim Verification: Setup claim verification mechanisms
- Identity Linking: Link identities to external systems
Core Interface¶
interface IIdentityFactory {
struct IdentityConfig {
address owner;
bytes32[] managementKeys;
bytes32[] actionKeys;
bytes32[] claimKeys;
address[] trustedIssuers;
bool registerWithRegistry;
}
struct IdentityTemplate {
string name;
string version;
address implementation;
bytes initCode;
bool active;
}
event IdentityDeployed(
address indexed identity,
address indexed owner,
string templateName
);
event TemplateRegistered(
string indexed name,
string version,
address indexed creator
);
function deployIdentity(
string calldata templateName,
IdentityConfig calldata config
) external returns (address identity);
function registerTemplate(IdentityTemplate calldata template) external;
function getTemplate(string calldata name) external view returns (IdentityTemplate memory);
function predictIdentityAddress(
string calldata templateName,
IdentityConfig calldata config
) external view returns (address);
}
Core Functions¶
deployIdentity()¶
Deploys a new identity contract using a registered template.
Parameters:
- templateName: Name of the template to use
- config: Identity configuration including keys and settings
Returns:
- address: Address of the deployed identity contract
Usage:
IIdentityFactory.IdentityConfig memory config = IIdentityFactory.IdentityConfig({
owner: msg.sender,
managementKeys: [keccak256(abi.encodePacked(msg.sender))],
actionKeys: [keccak256(abi.encodePacked(actionKey))],
claimKeys: [keccak256(abi.encodePacked(claimKey))],
trustedIssuers: [trustedIssuerAddress],
registerWithRegistry: true
});
address identity = IIdentityFactory(factory).deployIdentity("StandardIdentity", config);
registerTemplate()¶
Registers a new identity template for deployment.
Parameters:
- template: Template configuration including implementation and initialization
Access Control: - Restricted to authorized template creators
predictIdentityAddress()¶
Predicts the address of an identity contract before deployment.
Parameters:
- templateName: Name of the template
- config: Identity configuration
Returns:
- address: Predicted identity address
Implementation Example¶
Basic Identity Factory¶
contract IdentityFactory is IIdentityFactory {
using Clones for address;
mapping(string => IdentityTemplate) private templates;
mapping(address => bool) public templateCreators;
address public identityRegistry;
modifier onlyTemplateCreator() {
require(templateCreators[msg.sender] || msg.sender == owner(), "Not authorized");
_;
}
function deployIdentity(
string calldata templateName,
IdentityConfig calldata config
) external override returns (address identity) {
IdentityTemplate memory template = templates[templateName];
require(template.active, "Template not active");
require(config.owner != address(0), "Invalid owner");
// Deploy identity using minimal proxy pattern
bytes32 salt = keccak256(abi.encodePacked(config.owner, block.timestamp));
identity = template.implementation.cloneDeterministic(salt);
// Initialize identity with configuration
_initializeIdentity(identity, config, template);
// Register with identity registry if requested
if (config.registerWithRegistry && identityRegistry != address(0)) {
IIdentityRegistry(identityRegistry).registerIdentity(identity, config.owner);
}
emit IdentityDeployed(identity, config.owner, templateName);
}
function _initializeIdentity(
address identity,
IdentityConfig memory config,
IdentityTemplate memory template
) internal {
// Initialize with template-specific logic
if (template.initCode.length > 0) {
(bool success,) = identity.call(
abi.encodePacked(template.initCode, abi.encode(config))
);
require(success, "Identity initialization failed");
}
// Setup management keys
for (uint i = 0; i < config.managementKeys.length; i++) {
IERC734(identity).addKey(
config.managementKeys[i],
1, // MANAGEMENT purpose
1 // ECDSA key type
);
}
// Setup action keys
for (uint i = 0; i < config.actionKeys.length; i++) {
IERC734(identity).addKey(
config.actionKeys[i],
2, // ACTION purpose
1 // ECDSA key type
);
}
// Setup claim keys
for (uint i = 0; i < config.claimKeys.length; i++) {
IERC734(identity).addKey(
config.claimKeys[i],
3, // CLAIM purpose
1 // ECDSA key type
);
}
// Setup trusted issuers
for (uint i = 0; i < config.trustedIssuers.length; i++) {
IERC735(identity).addTrustedIssuer(config.trustedIssuers[i]);
}
}
}
Advanced Identity Factory with Governance¶
contract GovernanceIdentityFactory {
struct GovernanceConfig {
uint256 requiredApprovals;
address[] governors;
uint256 votingPeriod;
}
mapping(address => GovernanceConfig) public identityGovernance;
function deployGovernedIdentity(
string calldata templateName,
IdentityConfig calldata config,
GovernanceConfig calldata governance
) external returns (address identity) {
identity = deployIdentity(templateName, config);
// Setup governance structure
identityGovernance[identity] = governance;
// Initialize governance contract
address governanceContract = _deployGovernanceContract(identity, governance);
// Transfer identity ownership to governance contract
IOwnable(identity).transferOwnership(governanceContract);
emit GovernedIdentityDeployed(identity, governanceContract);
}
function _deployGovernanceContract(
address identity,
GovernanceConfig memory config
) internal returns (address governance) {
// Deploy governance contract for the identity
governance = Clones.clone(governanceImplementation);
IGovernance(governance).initialize(
identity,
config.governors,
config.requiredApprovals,
config.votingPeriod
);
}
}
Template Patterns¶
Standard Identity Template¶
function createStandardIdentityTemplate() internal pure returns (IdentityTemplate memory) {
return IdentityTemplate({
name: "StandardIdentity",
version: "1.0.0",
implementation: standardIdentityImplementation,
initCode: abi.encodeWithSignature("initialize(address)", address(0)),
active: true
});
}
Corporate Identity Template¶
function createCorporateIdentityTemplate() internal pure returns (IdentityTemplate memory) {
return IdentityTemplate({
name: "CorporateIdentity",
version: "1.0.0",
implementation: corporateIdentityImplementation,
initCode: abi.encodeWithSignature(
"initializeCorporate(address,string,string)",
address(0), "", ""
),
active: true
});
}
Multi-Signature Identity Template¶
function createMultiSigIdentityTemplate() internal pure returns (IdentityTemplate memory) {
return IdentityTemplate({
name: "MultiSigIdentity",
version: "1.0.0",
implementation: multiSigIdentityImplementation,
initCode: abi.encodeWithSignature(
"initializeMultiSig(address[],uint256)",
new address[](0), 0
),
active: true
});
}
Integration Patterns¶
Registry Integration¶
contract IdentityRegistryIntegration {
address public identityRegistry;
address public trustedIssuersRegistry;
function deployWithRegistration(
string calldata templateName,
IdentityConfig calldata config
) external returns (address identity) {
// Deploy identity
identity = deployIdentity(templateName, config);
// Register with identity registry
IIdentityRegistry(identityRegistry).registerIdentity(identity, config.owner);
// Setup trusted issuer relationships
for (uint i = 0; i < config.trustedIssuers.length; i++) {
ITrustedIssuersRegistry(trustedIssuersRegistry).addTrustedIssuer(
identity,
config.trustedIssuers[i]
);
}
emit IdentityRegistered(identity, config.owner);
}
}
KYC Integration¶
contract KYCIdentityFactory {
mapping(address => bool) public kycProviders;
function deployKYCIdentity(
string calldata templateName,
IdentityConfig calldata config,
bytes calldata kycProof
) external returns (address identity) {
// Verify KYC proof
require(_verifyKYCProof(config.owner, kycProof), "Invalid KYC proof");
// Deploy identity with KYC claim
identity = deployIdentity(templateName, config);
// Add KYC claim
bytes32 claimId = keccak256("KYC_VERIFIED");
IERC735(identity).addClaim(
claimId,
1, // KYC claim type
msg.sender, // issuer
kycProof,
"", // claim data
"" // URI
);
emit KYCIdentityDeployed(identity, config.owner);
}
function _verifyKYCProof(address user, bytes memory proof) internal view returns (bool) {
// Implement KYC proof verification logic
return kycProviders[msg.sender];
}
}
Security Considerations¶
Access Control¶
- Template Creation: Restrict template registration to authorized users
- Deployment Permissions: Control who can deploy identities
- Key Management: Secure initial key setup
- Registry Integration: Validate registry interactions
Identity Security¶
- Key Validation: Validate all provided keys
- Trusted Issuer Verification: Verify trusted issuer addresses
- Initialization Safety: Ensure secure initialization process
- Ownership Transfer: Secure ownership assignment
Factory Security¶
- Template Validation: Validate template implementations
- Implementation Security: Ensure implementation contract security
- Upgrade Safety: Consider factory upgrade mechanisms
- Event Logging: Log all deployments for auditing
Best Practices¶
Template Design¶
- Standard Compliance: Ensure ERC-734/735 compliance
- Modular Design: Create reusable template components
- Security Audits: Audit all template implementations
- Documentation: Document template capabilities
Factory Management¶
- Access Controls: Implement proper access controls
- Template Validation: Validate all template configurations
- Event Logging: Log all deployments and changes
- Upgrade Planning: Plan for factory upgrades
Identity Deployment¶
- Key Management: Secure key generation and storage
- Registry Integration: Integrate with identity registries
- Claim Setup: Setup initial claims and trusted issuers
- Governance: Consider governance mechanisms
Related Documentation¶
- ERC-734 Interface
- ERC-735 Interface
- Identity Registry Facet
- Trusted Issuers Registry Facet
- Integrator's Guide: Authentication
- Developer Guides: Automated Testing Setup (as a proxy for
kyc-integrationas no direct doc exists)
Standards Compliance¶
- ERC-734: Key Manager Standard
- ERC-735: Claim Holder Standard
- EIP-1167: Minimal Proxy Standard
- EIP-1014: CREATE2 for deterministic addresses
- Factory Pattern: Standard factory design patterns