Integrating Blockchain with Enterprise Systems
Enterprise systems — ERP, CRM, WMS, SCM — designed for centralized data model. Blockchain offers opposite: data distributed, state verified mathematically, transactions immutable. Tension point arises here: ERP wants mutable records with transactional rollbacks, blockchain says "written cannot be erased".
Before designing integration answer: what exactly should live in blockchain, what in enterprise system? Storing all ERP data in blockchain — technically and economically wrong. Right answer: in blockchain only what requires verification by multiple parties or immutable audit trail. Ownership documents, supplier audit results, origin certificates — yes. Current warehouse balances — no.
Integration Patterns
1. Blockchain as Audit Log
Most common pattern. ERP remains system of record, blockchain is immutable audit log for critical events.
ERP event → Event Hook → Blockchain Writer Service → Smart Contract
↓
Hash(event_data) + metadata
Store not data itself but hash:
contract AuditLog {
struct AuditRecord {
bytes32 dataHash;
string systemId; // "SAP-PROD-001"
string eventType; // "INVOICE_APPROVED"
uint256 timestamp;
address submitter;
}
mapping(bytes32 => AuditRecord) public records;
event RecordAnchored(
bytes32 indexed recordId,
bytes32 dataHash,
string eventType,
uint256 timestamp
);
function anchor(
bytes32 recordId,
bytes32 dataHash,
string calldata systemId,
string calldata eventType
) external onlyAuthorized {
require(records[recordId].timestamp == 0, "Record exists");
records[recordId] = AuditRecord({
dataHash: dataHash,
systemId: systemId,
eventType: eventType,
timestamp: block.timestamp,
submitter: msg.sender
});
emit RecordAnchored(recordId, dataHash, eventType, block.timestamp);
}
function verify(bytes32 recordId, bytes32 dataHash) external view returns (bool) {
return records[recordId].dataHash == dataHash;
}
}
Verify: take ERP record, hash it, compare with on-chain hash. If matches — record unchanged since anchoring.
2. Asset Tokenization: Corporate Registry
Asset registry (equipment, vehicles, property) in blockchain. ERP/EAM syncs with on-chain state.
ERP Asset Record ←→ Blockchain Token (ERC-721 or ERC-1155)
[mutable] [immutable history]
Key decision: who can mint/burn tokens? Usually authorized corporate accounts via multisig or timelock. Smart contract with role-based access (AccessControl):
bytes32 public constant ASSET_MANAGER_ROLE = keccak256("ASSET_MANAGER_ROLE");
bytes32 public constant AUDITOR_ROLE = keccak256("AUDITOR_ROLE");
function mintAsset(
address to,
uint256 tokenId,
string calldata externalId, // ID in ERP system
bytes calldata metadata
) external onlyRole(ASSET_MANAGER_ROLE) {
// ...
}
3. Smart Contract-Triggered Workflows
Blockchain event triggers corporate system process. Example: smart contract confirms goods receipt → auto-create invoice in ERP.
Smart Contract Event
↓
Event Listener Service
↓
Message Queue (Kafka/RabbitMQ)
↓
ERP Integration Adapter
↓
ERP API (REST/SOAP/EDI)
Middleware: Key Integration Component
Direct ERP ↔ blockchain interaction — almost always bad idea. SAP, Oracle, 1C don't have native blockchain connectors (or primitive). Need middleware layer:
class BlockchainIntegrationMiddleware {
private eventQueue: KafkaProducer;
private erpAdapter: ERPAdapter;
private blockchainService: BlockchainService;
// ERP → Blockchain: anchor event
async anchorERPEvent(event: ERPEvent): Promise<AnchorResult> {
// 1. Data normalization
const normalized = this.normalizeEvent(event);
// 2. Hash for anchoring
const dataHash = ethers.keccak256(
ethers.toUtf8Bytes(JSON.stringify(normalized))
);
// 3. Write to blockchain
const tx = await this.blockchainService.anchor(
event.id,
dataHash,
event.systemId,
event.type
);
// 4. Save result in ERP (tx hash, block number)
await this.erpAdapter.updateAnchorInfo(event.id, {
txHash: tx.hash,
blockNumber: tx.blockNumber,
network: 'ethereum-mainnet',
anchoredAt: new Date(),
});
return { txHash: tx.hash, dataHash };
}
// Blockchain → ERP: process on-chain event
async processBlockchainEvent(event: BlockchainEvent): Promise<void> {
// Idempotency: don't process twice
if (await this.isAlreadyProcessed(event.transactionHash)) return;
await this.eventQueue.send({
topic: `erp-integration.${event.type}`,
messages: [{
key: event.transactionHash,
value: JSON.stringify(event)
}],
});
await this.markAsProcessed(event.transactionHash);
}
}
SAP Integration: Practical Details
SAP provides several integration points:
BAPI/RFC — business functions callable via RFC protocol. Library node-rfc for Node.js.
SAP Integration Suite (BTP) — cloud integration platform with visual flow constructor. Supports REST/SOAP/OData adapters.
IDocs — async document exchange. Classic pattern for EDI integrations.
SAP Event Mesh — Kafka-compatible message broker from SAP.
// Example via SAP RFC (BAPI)
import { Client } from 'node-rfc';
const client = new Client({
ashost: process.env.SAP_HOST!,
sysnr: '00',
client: '100',
user: process.env.SAP_USER!,
passwd: process.env.SAP_PASSWORD!,
lang: 'EN',
});
await client.open();
// Get order data for anchoring
const result = await client.call('BAPI_SALESORDER_GETLIST', {
CUSTOMER_NUMBER: customerId,
MATERIAL: materialId,
});
// Format data for blockchain anchoring
const orderData = result.SALES_ORDERS.map(order => ({
id: order.VBELN,
date: order.ERDAT,
amount: order.NETWR,
currency: order.WAERK,
}));
Managing Transactionality and Errors
Main problem: blockchain transaction confirmed mid-business-process, after which ERP operation failed. Or vice versa.
Saga pattern for distributed transactions:
class AssetRegistrationSaga {
async execute(assetData: AssetData): Promise<void> {
const sagaId = uuid();
// Step 1: Write to ERP (reversible)
const erpAssetId = await this.erpAdapter.createAsset(assetData);
await this.saveSagaState(sagaId, 'ERP_CREATED', { erpAssetId });
try {
// Step 2: Mint token in blockchain (irreversible after finality)
const tokenId = await this.blockchainService.mintAsset(
erpAssetId, assetData
);
await this.saveSagaState(sagaId, 'TOKEN_MINTED', { tokenId });
// Step 3: Update ERP with blockchain reference
await this.erpAdapter.updateAssetBlockchainRef(erpAssetId, tokenId);
await this.saveSagaState(sagaId, 'COMPLETED');
} catch (blockchainError) {
// Compensating transaction: rollback ERP
await this.erpAdapter.deleteAsset(erpAssetId);
await this.saveSagaState(sagaId, 'COMPENSATED');
throw blockchainError;
}
}
}
Identification and PKI
Corporate users shouldn't manage private keys manually. Solutions:
- HSM (Hardware Security Module) — Azure Dedicated HSM, AWS CloudHSM. Keys generated and stored in hardware module, signing happens inside.
- Key Management Service — AWS KMS, Azure Key Vault. Software analog of HSM with IAM management.
- Enterprise Wallet — Fireblocks, Copper — enterprise-grade custody with MPC (Multi-Party Computation), workflow approvals, audit logs.
For corporate integration Fireblocks is gold standard: API for programmatic transaction creation, policy engine for auto-approval/rejection, Active Directory integration.
Typical Project Phases
| Phase | Content | Time |
|---|---|---|
| Discovery & Architecture | Analyze ERP systems, determine blockchain data, pattern selection | 2–3 weeks |
| Smart Contracts | Development, tests, audit | 2–4 weeks |
| Middleware Development | Integration service, event processing, ERP adapters | 3–5 weeks |
| ERP Configuration | Setup webhooks, RFC/API, IDocs | 1–2 weeks |
| Key Management | HSM / enterprise wallet integration | 1–2 weeks |
| Testing | E2E scenarios, load testing, failover | 2–3 weeks |
| Pilot | Limited run on real data | 2–4 weeks |
| Production & Monitoring | Deployment, monitoring, documentation | 1–2 weeks |
Total: 3–6 months, depending on ERP landscape complexity. Multi-system projects (SAP + Oracle + legacy WMS) — closer to 6 months.







