305 Blockchain for IoT: Interactive Lab and Knowledge Check
305.1 Learning Objectives
By the end of this chapter, you will be able to:
- Build a working blockchain system on ESP32 microcontroller
- Implement block structure, hash chains, and tamper detection
- Experience Proof-of-Work mining and understand difficulty adjustment
- Test your understanding of blockchain concepts through knowledge checks
- Apply blockchain decision frameworks to IoT scenarios
305.2 Interactive Lab: Blockchain for IoT
305.2.1 Introduction
In this hands-on lab, you’ll build a working blockchain system on an ESP32 microcontroller that demonstrates core blockchain concepts applied to IoT sensor data. This simulation implements:
- Block structure: Linked data structures with cryptographic hashing
- Hash chain verification: Tamper detection through chain integrity checks
- Simplified Proof-of-Work: Mining blocks with difficulty adjustment
- IoT transactions: Recording sensor readings as blockchain transactions
- Tampering detection: Automatic detection of data manipulation attempts
This lab provides concrete experience with blockchain fundamentals at the embedded systems level–showing both the power and limitations of running blockchain on resource-constrained IoT devices.
305.2.2 Lab Overview
The ESP32 runs a complete mini-blockchain that:
- Generates IoT sensor data from temperature and light sensors (simulated)
- Creates transactions representing sensor readings
- Mines blocks using simplified Proof-of-Work consensus
- Validates chain integrity by verifying hash linkages
- Detects tampering by checking if blocks have been modified
- Displays blockchain state via serial monitor and OLED display
You’ll see real-time blockchain operations, experiment with different mining difficulties, and observe what happens when someone tries to tamper with historical data.
305.2.3 Wokwi Simulation
Pre-built Code (copy this into the Wokwi editor):
/*
* Blockchain for IoT - ESP32 Demonstration
*
* This code implements a simplified blockchain on ESP32 to demonstrate:
* - Block structure with cryptographic hashing
* - Proof-of-Work mining with difficulty adjustment
* - Hash chain validation and tamper detection
* - IoT sensor data as blockchain transactions
*
* Hardware: ESP32, simulated sensors
* Concepts: SHA-256 hashing, merkle trees, consensus, immutability
*/
#include <Arduino.h>
#include <mbedtls/sha256.h>
#include <time.h>
// ==================== BLOCKCHAIN CONFIGURATION ====================
#define MAX_BLOCKS 20 // Maximum blocks in our mini-blockchain
#define MAX_TRANSACTIONS 5 // Max transactions per block
#define DIFFICULTY 2 // Mining difficulty (leading zeros in hash)
#define BLOCK_TIME_TARGET 5000 // Target block time in ms (5 seconds)
#define GENESIS_TIMESTAMP 1640995200 // Genesis block timestamp (Jan 1, 2022)
// ==================== DATA STRUCTURES ====================
// Transaction structure representing IoT sensor reading
struct Transaction {
unsigned long timestamp;
char sensorType[16]; // "temperature", "humidity", "light"
float value;
char deviceId[16]; // Device identifier
bool valid; // Transaction validity flag
};
// Block structure in our blockchain
struct Block {
int index; // Block number
unsigned long timestamp; // When block was created
Transaction transactions[MAX_TRANSACTIONS]; // Array of transactions
int transactionCount; // Number of transactions in block
char previousHash[65]; // Hash of previous block (64 hex + null)
char hash[65]; // Hash of this block
unsigned long nonce; // Proof-of-Work nonce
int difficulty; // Mining difficulty for this block
bool mined; // Whether block has been mined
};
// ==================== GLOBAL VARIABLES ====================
Block blockchain[MAX_BLOCKS]; // The blockchain array
int blockchainLength = 0; // Current number of blocks
Transaction pendingTransactions[10]; // Transactions waiting to be mined
int pendingCount = 0; // Number of pending transactions
unsigned long lastBlockTime = 0; // Timestamp of last block
unsigned long lastDisplayUpdate = 0; // Last time we updated display
bool chainValid = true; // Is the blockchain valid?
// Statistics
unsigned long totalHashesComputed = 0;
int blocksMinedCount = 0;
// ==================== CRYPTOGRAPHIC FUNCTIONS ====================
// Convert binary hash to hexadecimal string
void hashToHex(unsigned char* hash, char* outputBuffer) {
for (int i = 0; i < 32; i++) {
sprintf(&outputBuffer[i * 2], "%02x", hash[i]);
}
outputBuffer[64] = '\0';
}
// Compute SHA-256 hash of block data
void calculateBlockHash(Block* block, char* outputHash) {
// Concatenate all block data into single string for hashing
char blockData[512];
snprintf(blockData, sizeof(blockData),
"%d%lu%s%d%lu",
block->index,
block->timestamp,
block->previousHash,
block->transactionCount,
block->nonce);
// Append transaction data
for (int i = 0; i < block->transactionCount; i++) {
char txData[128];
snprintf(txData, sizeof(txData), "%lu%s%.2f%s",
block->transactions[i].timestamp,
block->transactions[i].sensorType,
block->transactions[i].value,
block->transactions[i].deviceId);
strncat(blockData, txData, sizeof(blockData) - strlen(blockData) - 1);
}
// Compute SHA-256
unsigned char hash[32];
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts(&ctx, 0); // 0 = SHA-256 (not SHA-224)
mbedtls_sha256_update(&ctx, (unsigned char*)blockData, strlen(blockData));
mbedtls_sha256_finish(&ctx, hash);
mbedtls_sha256_free(&ctx);
// Convert to hex string
hashToHex(hash, outputHash);
}
// Check if hash meets difficulty requirement (leading zeros)
bool hashMeetsDifficulty(const char* hash, int difficulty) {
for (int i = 0; i < difficulty; i++) {
if (hash[i] != '0') {
return false;
}
}
return true;
}
// ==================== BLOCKCHAIN CORE FUNCTIONS ====================
// Create the genesis block (first block in chain)
void createGenesisBlock() {
Block genesis;
genesis.index = 0;
genesis.timestamp = GENESIS_TIMESTAMP;
genesis.transactionCount = 0;
strcpy(genesis.previousHash, "0000000000000000000000000000000000000000000000000000000000000000");
genesis.nonce = 0;
genesis.difficulty = DIFFICULTY;
genesis.mined = false;
// Add genesis transaction
Transaction genesisTx;
genesisTx.timestamp = GENESIS_TIMESTAMP;
strcpy(genesisTx.sensorType, "genesis");
genesisTx.value = 0.0;
strcpy(genesisTx.deviceId, "GENESIS");
genesisTx.valid = true;
genesis.transactions[0] = genesisTx;
genesis.transactionCount = 1;
// Mine genesis block
Serial.println("\n=== MINING GENESIS BLOCK ===");
unsigned long startTime = millis();
do {
genesis.nonce++;
calculateBlockHash(&genesis, genesis.hash);
totalHashesComputed++;
} while (!hashMeetsDifficulty(genesis.hash, genesis.difficulty));
genesis.mined = true;
unsigned long miningTime = millis() - startTime;
Serial.printf("Genesis block mined! Nonce: %lu, Time: %lu ms\n",
genesis.nonce, miningTime);
Serial.printf("Hash: %s\n", genesis.hash);
blockchain[0] = genesis;
blockchainLength = 1;
lastBlockTime = millis();
}
// Add a new transaction to pending pool
bool addTransaction(const char* sensorType, float value, const char* deviceId) {
if (pendingCount >= 10) {
Serial.println("Transaction pool full!");
return false;
}
Transaction tx;
tx.timestamp = millis();
strncpy(tx.sensorType, sensorType, sizeof(tx.sensorType) - 1);
tx.value = value;
strncpy(tx.deviceId, deviceId, sizeof(tx.deviceId) - 1);
tx.valid = true;
pendingTransactions[pendingCount++] = tx;
Serial.printf("Transaction added: %s = %.2f from %s\n",
sensorType, value, deviceId);
return true;
}
// Mine a new block with pending transactions
bool mineBlock() {
if (blockchainLength >= MAX_BLOCKS) {
Serial.println("Blockchain full!");
return false;
}
if (pendingCount == 0) {
Serial.println("No pending transactions to mine");
return false;
}
Block newBlock;
newBlock.index = blockchainLength;
newBlock.timestamp = millis();
newBlock.difficulty = DIFFICULTY;
newBlock.nonce = 0;
newBlock.mined = false;
// Copy previous block hash
strcpy(newBlock.previousHash, blockchain[blockchainLength - 1].hash);
// Add pending transactions (up to MAX_TRANSACTIONS)
newBlock.transactionCount = min(pendingCount, MAX_TRANSACTIONS);
for (int i = 0; i < newBlock.transactionCount; i++) {
newBlock.transactions[i] = pendingTransactions[i];
}
// Remove added transactions from pending pool
for (int i = newBlock.transactionCount; i < pendingCount; i++) {
pendingTransactions[i - newBlock.transactionCount] = pendingTransactions[i];
}
pendingCount -= newBlock.transactionCount;
// PROOF-OF-WORK MINING
Serial.printf("\n=== MINING BLOCK #%d ===\n", newBlock.index);
Serial.printf("Difficulty: %d leading zeros required\n", newBlock.difficulty);
Serial.printf("Transactions: %d\n", newBlock.transactionCount);
unsigned long startTime = millis();
unsigned long hashCount = 0;
// Keep incrementing nonce until hash meets difficulty
do {
newBlock.nonce++;
calculateBlockHash(&newBlock, newBlock.hash);
hashCount++;
totalHashesComputed++;
// Show progress every 1000 hashes
if (hashCount % 1000 == 0) {
Serial.printf("Hashes computed: %lu\n", hashCount);
}
} while (!hashMeetsDifficulty(newBlock.hash, newBlock.difficulty));
newBlock.mined = true;
unsigned long miningTime = millis() - startTime;
blocksMinedCount++;
Serial.println("BLOCK MINED SUCCESSFULLY!");
Serial.printf("Nonce found: %lu\n", newBlock.nonce);
Serial.printf("Hash: %s\n", newBlock.hash);
Serial.printf("Mining time: %lu ms (%lu hashes)\n", miningTime, hashCount);
Serial.printf("Hash rate: %.2f hashes/sec\n",
(float)hashCount / (miningTime / 1000.0));
blockchain[blockchainLength++] = newBlock;
lastBlockTime = millis();
return true;
}
// Validate the entire blockchain
bool validateBlockchain() {
Serial.println("\n=== VALIDATING BLOCKCHAIN ===");
for (int i = 1; i < blockchainLength; i++) {
Block* currentBlock = &blockchain[i];
Block* previousBlock = &blockchain[i - 1];
// Check 1: Previous hash matches
if (strcmp(currentBlock->previousHash, previousBlock->hash) != 0) {
Serial.printf("Block #%d: Previous hash mismatch!\n", i);
Serial.printf(" Expected: %s\n", previousBlock->hash);
Serial.printf(" Got: %s\n", currentBlock->previousHash);
return false;
}
// Check 2: Hash is valid
char recalculatedHash[65];
calculateBlockHash(currentBlock, recalculatedHash);
if (strcmp(currentBlock->hash, recalculatedHash) != 0) {
Serial.printf("Block #%d: Hash invalid (data tampered)!\n", i);
Serial.printf(" Stored hash: %s\n", currentBlock->hash);
Serial.printf(" Calculated: %s\n", recalculatedHash);
return false;
}
// Check 3: Hash meets difficulty
if (!hashMeetsDifficulty(currentBlock->hash, currentBlock->difficulty)) {
Serial.printf("Block #%d: Hash doesn't meet difficulty!\n", i);
return false;
}
Serial.printf("Block #%d valid\n", i);
}
Serial.println("BLOCKCHAIN VALID");
return true;
}
// Tamper with a block (for demonstration)
void tamperWithBlock(int blockIndex) {
if (blockIndex >= blockchainLength || blockIndex < 0) {
Serial.println("Invalid block index");
return;
}
Serial.printf("\n=== TAMPERING WITH BLOCK #%d ===\n", blockIndex);
Block* block = &blockchain[blockIndex];
// Modify a transaction value
if (block->transactionCount > 0) {
float oldValue = block->transactions[0].value;
block->transactions[0].value = oldValue + 100.0; // Add 100 to value
Serial.printf("Changed transaction value: %.2f -> %.2f\n",
oldValue, block->transactions[0].value);
}
Serial.println("Block data modified. Run validation to detect tampering!");
}
// Display blockchain status
void displayBlockchainStatus() {
Serial.println("\n========================================");
Serial.println(" BLOCKCHAIN STATUS");
Serial.println("========================================");
Serial.printf("Blocks: %d / %d\n", blockchainLength, MAX_BLOCKS);
Serial.printf("Pending Transactions: %d\n", pendingCount);
Serial.printf("Chain Valid: %s\n", chainValid ? "YES" : "NO");
Serial.printf("Total Hashes Computed: %lu\n", totalHashesComputed);
Serial.printf("Blocks Mined: %d\n", blocksMinedCount);
Serial.println("========================================");
// Display last 3 blocks
int startBlock = max(0, blockchainLength - 3);
for (int i = startBlock; i < blockchainLength; i++) {
Block* b = &blockchain[i];
Serial.printf("\n--- Block #%d ---\n", b->index);
Serial.printf("Timestamp: %lu\n", b->timestamp);
Serial.printf("Transactions: %d\n", b->transactionCount);
Serial.printf("Nonce: %lu\n", b->nonce);
Serial.printf("Hash: %s\n", b->hash);
if (i > 0) {
Serial.printf("Prev: %s\n", b->previousHash);
}
// Show transactions
for (int j = 0; j < b->transactionCount; j++) {
Transaction* tx = &b->transactions[j];
Serial.printf(" TX%d: %s = %.2f (%s)\n",
j, tx->sensorType, tx->value, tx->deviceId);
}
}
Serial.println("========================================\n");
}
// ==================== SENSOR SIMULATION ====================
// Generate simulated sensor reading
float generateSensorReading(const char* sensorType) {
if (strcmp(sensorType, "temperature") == 0) {
return 20.0 + (random(0, 1000) / 100.0); // 20-30C
} else if (strcmp(sensorType, "humidity") == 0) {
return 40.0 + (random(0, 4000) / 100.0); // 40-80%
} else if (strcmp(sensorType, "light") == 0) {
return random(0, 1024); // 0-1023 lux
}
return 0.0;
}
// ==================== INTERACTIVE COMMANDS ====================
void processSerialCommand() {
if (!Serial.available()) return;
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "help") {
Serial.println("\n=== AVAILABLE COMMANDS ===");
Serial.println("add temp - Add temperature transaction");
Serial.println("add hum - Add humidity transaction");
Serial.println("add light - Add light sensor transaction");
Serial.println("mine - Mine a new block");
Serial.println("validate - Validate blockchain integrity");
Serial.println("tamper N - Tamper with block N");
Serial.println("status - Display blockchain status");
Serial.println("stats - Show mining statistics");
Serial.println("help - Show this help");
Serial.println("==========================\n");
} else if (command.startsWith("add temp")) {
float value = generateSensorReading("temperature");
addTransaction("temperature", value, "ESP32-TEMP-01");
} else if (command.startsWith("add hum")) {
float value = generateSensorReading("humidity");
addTransaction("humidity", value, "ESP32-HUM-01");
} else if (command.startsWith("add light")) {
float value = generateSensorReading("light");
addTransaction("light", value, "ESP32-LIGHT-01");
} else if (command == "mine") {
mineBlock();
} else if (command == "validate") {
chainValid = validateBlockchain();
} else if (command.startsWith("tamper ")) {
int blockNum = command.substring(7).toInt();
tamperWithBlock(blockNum);
} else if (command == "status") {
displayBlockchainStatus();
} else if (command == "stats") {
Serial.println("\n=== MINING STATISTICS ===");
Serial.printf("Total Blocks Mined: %d\n", blocksMinedCount);
Serial.printf("Total Hashes Computed: %lu\n", totalHashesComputed);
if (blocksMinedCount > 0) {
Serial.printf("Average Hashes/Block: %lu\n",
totalHashesComputed / blocksMinedCount);
}
Serial.printf("Current Difficulty: %d\n", DIFFICULTY);
Serial.println("========================\n");
} else {
Serial.println("Unknown command. Type 'help' for available commands.");
}
}
// ==================== AUTO-DEMO MODE ====================
unsigned long lastAutoAction = 0;
int autoStep = 0;
void autoDemoMode() {
if (millis() - lastAutoAction < 10000) return; // Action every 10 seconds
lastAutoAction = millis();
switch(autoStep) {
case 0:
Serial.println("\n>>> AUTO-DEMO: Adding temperature transaction");
addTransaction("temperature", generateSensorReading("temperature"), "ESP32-01");
break;
case 1:
Serial.println("\n>>> AUTO-DEMO: Adding humidity transaction");
addTransaction("humidity", generateSensorReading("humidity"), "ESP32-01");
break;
case 2:
Serial.println("\n>>> AUTO-DEMO: Mining block");
mineBlock();
break;
case 3:
Serial.println("\n>>> AUTO-DEMO: Validating blockchain");
chainValid = validateBlockchain();
displayBlockchainStatus();
break;
case 4:
if (blockchainLength >= 3) {
Serial.println("\n>>> AUTO-DEMO: Tampering with block 1");
tamperWithBlock(1);
}
break;
case 5:
Serial.println("\n>>> AUTO-DEMO: Validating after tampering");
chainValid = validateBlockchain();
break;
}
autoStep = (autoStep + 1) % 6;
}
// ==================== SETUP & LOOP ====================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n\n");
Serial.println("========================================");
Serial.println(" BLOCKCHAIN FOR IoT - ESP32 DEMO");
Serial.println("========================================");
Serial.println("Demonstrating:");
Serial.println("- Block structure & hashing");
Serial.println("- Proof-of-Work mining");
Serial.println("- Chain validation");
Serial.println("- Tamper detection");
Serial.println("========================================\n");
randomSeed(analogRead(0));
// Initialize blockchain with genesis block
createGenesisBlock();
Serial.println("\nBlockchain initialized!");
Serial.println("Type 'help' for available commands");
Serial.println("Auto-demo mode active (actions every 10 seconds)\n");
displayBlockchainStatus();
}
void loop() {
// Process serial commands
processSerialCommand();
// Run auto-demo mode
autoDemoMode();
// Periodic status update
if (millis() - lastDisplayUpdate > 30000) {
displayBlockchainStatus();
lastDisplayUpdate = millis();
}
delay(100);
}305.2.4 Challenge Exercises
After running the simulation, try these challenges to deepen your understanding:
Challenge 1: Difficulty Adjustment - Modify DIFFICULTY from 2 to 3 or 4 - Observe how mining time increases exponentially - Calculate the average hash rate and time-to-mine for each difficulty level - Question: If difficulty=2 takes ~5 seconds, how long does difficulty=4 take? Why?
Challenge 2: Tamper Detection 1. Add several blocks to the chain 2. Use tamper 1 to modify block #1 3. Run validate and observe the error messages 4. Question: Why does changing block #1 invalidate the entire chain after it?
Challenge 3: Transaction Throughput - Add 10 transactions rapidly - Mine a single block - Question: How many transactions fit in one block? What happens to the remaining transactions?
Challenge 4: 51% Attack Simulation - After tampering with a block, try to “fix” it by re-mining that block and all subsequent blocks - Implement a function remineFrom(blockIndex) that recalculates hashes for all blocks from a given index - Question: What does this teach you about blockchain security and the importance of distributed consensus?
Challenge 5: Merkle Tree Implementation - Modify the code to compute a Merkle root of all transactions in a block - Store only the Merkle root in the block hash (not individual transaction data) - Question: How does this change affect verification complexity and scalability?
305.2.5 Expected Outcomes
After completing this lab, you should understand:
- Block Structure: How blocks contain data (transactions), timestamps, nonces, and cryptographic links to previous blocks
- Hash Chains: How each block’s hash depends on its content AND the previous block’s hash, creating tamper-evidence
- Proof-of-Work: The computational cost of mining makes it expensive to alter history
- Validation: Anyone can verify chain integrity by recalculating hashes and checking linkages
- Resource Constraints: Mining even simple blocks on ESP32 demonstrates why IoT devices cannot run full blockchain nodes
Real-World Implications:
- Why gateways are needed: ESP32 struggles with difficulty=4; imagine Ethereum’s difficulty (billions of hashes)
- Why off-chain storage matters: Our blockchain holds only 5 transactions per block; real IoT generates thousands per second
- Why consensus is expensive: Proof-of-Work wastes computation by design–necessary for trustless systems but incompatible with battery-powered devices
- Why private blockchains exist: Removing mining and using known validators (like this lab) is how Hyperledger Fabric achieves 10,000+ TPS
305.2.6 Key Takeaways
This lab demonstrates blockchain fundamentals at the embedded level, revealing both the power of cryptographic immutability and the practical limitations for IoT:
- Immutability works: Tampering is immediately detectable through hash verification
- Mining is expensive: Even low difficulty requires significant computation
- IoT devices cannot mine: ESP32 at difficulty=2 is manageable; Ethereum-level mining is impossible
- Architectural patterns are essential: Real IoT-blockchain systems need gateways, off-chain storage, and lightweight verification
Next steps: Explore how production systems solve these challenges through Hyperledger Fabric (no mining), IOTA (DAG instead of chain), and hybrid on-chain/off-chain architectures.
305.3 Knowledge Check
Test your understanding of blockchain concepts for IoT applications.
305.4 Summary
Blockchain and distributed ledger technology offer compelling solutions for IoT trust, auditability, and automation challenges–but only when applied appropriately:
Key takeaways:
Blockchain provides: Immutability, decentralization, transparency, and smart contract automation–valuable for multi-party IoT ecosystems requiring trust without intermediaries.
Blockchain types matter: Public blockchains (Bitcoin, Ethereum) are too slow and expensive for most IoT. Private blockchains (Hyperledger Fabric) offer enterprise-grade performance and privacy. IoT-optimized ledgers (IOTA) enable feeless microtransactions.
Architectural patterns are essential: IoT devices cannot run full nodes. Successful deployments use gateways, hybrid on-chain/off-chain storage, periodic anchoring, and lightweight verification.
Scalability is the primary challenge: No blockchain handles millions of TPS. Batch aggregation, Merkle trees, and off-chain computation are necessary for large-scale IoT.
Real-world successes exist: IBM Food Trust (supply chain traceability), MediLedger (pharmaceutical verification), MOBI (vehicle identity), and Helium (decentralized connectivity) demonstrate proven value.
Critical thinking required: Blockchain is not suitable for real-time control, high-frequency data streams, or scenarios where central authority is acceptable. Evaluate whether decentralization genuinely adds value or just complexity.
Decision framework:
Use blockchain for IoT when you need: - Multi-organizational trust without central authority - Immutable audit trails for compliance - Automated enforcement of agreements (smart contracts) - Micropayments between devices
Avoid blockchain for IoT when: - Single organization controls the system - Real-time performance is critical (<1 second) - Traditional databases meet requirements - Decentralization adds cost without benefit
Explore blockchain concepts interactively:
- Knowledge Gaps Hub: Common blockchain-IoT misconceptions (public vs private, scalability myths, smart contract limitations)
- Simulations Hub: Interactive blockchain consensus simulator comparing Proof of Work vs Proof of Stake energy consumption and finality times
- Videos Hub: Blockchain fundamentals playlist covering cryptographic hashing, Merkle trees, and consensus mechanisms
- Quizzes Hub: Test your understanding of blockchain types, smart contracts, and architectural patterns with scenario-based questions
Foundational concepts: - Edge-Fog Computing - Edge computing complements blockchain by handling real-time processing while blockchain provides trust layer - IoT Reference Models - Where blockchain fits in IoT architecture stacks
Security and trust: - IoT Device and Network Security - Device identity and key management for blockchain participation - Encryption Architecture - Cryptographic foundations underlying blockchain
Networking protocols: - MQTT Fundamentals - Integrating MQTT pub/sub with blockchain for IoT messaging - CoAP Fundamentals - Lightweight protocols for resource-constrained blockchain clients
Data management: - Data in the Cloud - Hybrid cloud-blockchain architectures for IoT data - Multi-Sensor Data Fusion - Combining multiple sensor streams for blockchain anchoring
Applications: - Application Domains - Industry-specific blockchain-IoT use cases (supply chain, smart cities, healthcare)
Learning resources: - Simulations Hub - Blockchain consensus simulation (proof of work vs proof of stake) - Videos Hub - Blockchain fundamentals and IoT integration tutorials
The following AI-generated figures provide alternative visual representations of concepts covered in this chapter. These “phantom figures” offer different artistic interpretations to help reinforce understanding.
305.4.1 Blockchain Architecture
305.4.2 Identity & Security
305.4.3 IoT Integration
305.5 What’s Next?
You’ve completed the blockchain for IoT series! Here are recommended next steps:
Fog Fundamentals: Understand how fog computing complements blockchain by providing edge intelligence and reducing latency for time-sensitive IoT operations that can’t wait for blockchain finality.
M2M Fundamentals: Dive into machine-to-machine communication protocols that enable autonomous device interactions–enhanced by blockchain-based micropayments and smart contracts.
Production Architecture Management: Learn how to deploy and manage production IoT systems at scale, integrating blockchain components with traditional architectures.
Practice exercises:
Design a blockchain-based smart parking system: How would you track spot occupancy, handle payments, and prevent fraud?
Compare gas costs: Calculate Ethereum transaction costs for different IoT anchoring strategies (per-reading, hourly batch, daily batch).
Implement a simple smart contract: Use Remix IDE to create and test a temperature monitoring contract with breach detection.
Evaluate IOTA vs Hyperledger Fabric: For a fleet management system with 5,000 vehicles, which blockchain would you choose and why?