區塊鏈應用案例 —— 身份驗證與認證

一、引言

在數位化時代,身份驗證與認證是保障資訊安全和隱私的關鍵環節。傳統身份驗證方式存在諸多問題,如資訊易被篡改、洩露,驗證流程繁瑣等。區塊鏈技術以其去中心化、不可篡改、透明性等特點,為身份驗證與認證提供了新的解決方案。本文將通過實際開發案例,詳細探討區塊鏈在身份驗證與認證中的應用。

二、區塊鏈技術簡介

區塊鏈是一種分佈式帳本技術,通過密碼學原理將資料以區塊形式連結,形成不可篡改、可追溯的資料庫。其核心特點包括:

  • 去中心化:資料儲存在多個節點上,無單一控制中心。
  • 不可篡改:資料一旦寫入,無法修改。
  • 透明性:所有交易記錄對參與者透明。
  • 隱私保護:通過加密技術保護使用者隱私。

這些特性使得區塊鏈在身份驗證與認證中具有獨特優勢。

三、開發案例:基於以太坊的簡單身份認證系統

3.1 項目背景

開發一個基於以太坊智能合約的簡單身份認證系統,使用者可以註冊並驗證自己的身份資訊,身份資訊以加密形式儲存在區塊鏈上,確保安全性和隱私性。

3.2 技術堆疊

  • 智能合約語言:Solidity
  • 區塊鏈平台:以太坊
  • 開發工具:Remix IDE(用於編寫和部署智能合約)
  • 前端框架:React(用於建構使用者介面)
  • 後端框架:Node.js(用於與智能合約互動)

3.3 智能合約開發

3.3.1 智能合約程式碼

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title DigitalIdentity
 * @dev 基於以太坊的簡單數字身份驗證系統。
 */
contract DigitalIdentity {
    /**
     * @dev 用於儲存使用者身份資訊的結構體。
     */
    struct Identity {
        string name;       // 使用者姓名
        string email;      // 使用者信箱
        bool isRegistered; // 標記使用者是否已註冊
    }

    /**
     * @dev 通過使用者地址對應到其身份資訊。
     */
    mapping(address => Identity) private identities;

    /**
     * @dev 當使用者註冊身份時觸發的事件。
     * @param user 使用者地址
     * @param name 使用者姓名
     * @param email 使用者信箱
     */
    event IdentityRegistered(address indexed user, string name, string email);

    /**
     * @dev 當使用者身份被驗證時觸發的事件。
     * @param user 使用者地址
     * @param success 驗證是否成功
     */
    event IdentityVerified(address indexed user, bool success);

    /**
     * @dev 註冊使用者身份。
     * @param _name 使用者姓名
     * @param _email 使用者信箱
     */
    function registerIdentity(string memory _name, string memory _email) public {
        require(!identities[msg.sender].isRegistered, "Identity already registered.");
        identities[msg.sender] = Identity(_name, _email, true);
        emit IdentityRegistered(msg.sender, _name, _email);
    }

    /**
     * @dev 驗證使用者身份。
     * @param _user 使用者地址
     * @return 是否驗證成功
     */
    function verifyIdentity(address _user) public view returns (bool) {
        if (identities[_user].isRegistered) {
            emit IdentityVerified(_user, true);
            return true;
        } else {
            emit IdentityVerified(_user, false);
            return false;
        }
    }

    /**
     * @dev 獲取使用者身份資訊(僅使用者本人可訪問)。
     * @return 使用者姓名和信箱
     */
    function getIdentity() public view returns (string memory, string memory) {
        require(identities[msg.sender].isRegistered, "Identity not registered.");
        return (identities[msg.sender].name, identities[msg.sender].email);
    }
}

3.4 部署與測試

3.4.1 部署步驟

  1. 安裝 Remix IDE:訪問 Remix IDE。
  2. 建立新檔案:在 Remix 中建立一個新的 Solidity 檔案,貼上上述程式碼。
  3. 編譯合約:點選“編譯”按鈕,確保程式碼無錯誤。
  4. 部署合約:選擇“部署”選項卡,選擇一個測試網路(如 Ropsten),點選“部署”按鈕,將合約部署到區塊鏈上。

3.4.2 測試流程

1. 註冊身份

    • 呼叫 registerIdentity 函數,輸入姓名和信箱,完成身份註冊。
    • 例如,呼叫 registerIdentity("John Doe", "john.doe@example.com")

2. 驗證身份

    • 呼叫 verifyIdentity 函數,輸入使用者地址,驗證身份是否已註冊。
    • 例如,呼叫 verifyIdentity(0x1234567890abcdef),返回 true 或 false

3. 獲取身份資訊

    • 呼叫 getIdentity 函數,獲取當前使用者的身份資訊。
    • 例如,呼叫 getIdentity(),返回 ("John Doe", "john.doe@example.com")

3.5 前端開發

3.5.1 建立 React 應用

1. 安裝 Create React App

npx create-react-app digital-identity
cd digital-identity

2. 安裝 Web3.js

npm install web3

3.5.2 編寫前端程式碼

import React, { useState, useEffect } from'react';
import Web3 from'web3';
import DigitalIdentity from'./contracts/DigitalIdentity.json';

const App = () => {
const [web3, setWeb3] = useState(null);
const [accounts, setAccounts] = useState([]);
const [contract, setContract] = useState(null);
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [registered, setRegistered] = useState(false);

  useEffect(() => {
    loadWeb3();
  }, []);

const loadWeb3 = async () => {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum);
      awaitwindow.ethereum.enable();
      setWeb3(window.web3);
    } elseif (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider);
      setWeb3(window.web3);
    } else {
      window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!');
    }
  };

const loadBlockchainData = async () => {
    const web3 = window.web3;
    const accounts = await web3.eth.getAccounts();
    setAccounts(accounts);

    const networkId = await web3.eth.net.getId();
    const deployedNetwork = DigitalIdentity.networks[networkId];
    const instance = new web3.eth.Contract(
      DigitalIdentity.abi,
      deployedNetwork && deployedNetwork.address,
    );
    setContract(instance);
  };

const registerIdentity = async () => {
    const { contract, accounts } = this.state;
    await contract.methods.registerIdentity(name, email).send({ from: accounts[0] });
    setRegistered(true);
  };

const verifyIdentity = async () => {
    const { contract, accounts } = this.state;
    const isRegistered = await contract.methods.verifyIdentity(accounts[0]).call();
    setRegistered(isRegistered);
  };

const getIdentity = async () => {
    const { contract, accounts } = this.state;
    const identity = await contract.methods.getIdentity().call({ from: accounts[0] });
    setName(identity[0]);
    setEmail(identity[1]);
  };

return (
    <div className="App">
      <h1>Digital Identity</h1>
      <button onClick={loadBlockchainData}>Load Blockchain Data</button>
      <input
        type="text"
        placeholder="Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <input
        type="text"
        placeholder="Email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <button onClick={registerIdentity}>Register Identity</button>
      <button onClick={verifyIdentity}>Verify Identity</button>
      <button onClick={getIdentity}>Get Identity</button>
      {registered ? <p>Identity Registered</p> : <p>Identity Not Registered</p>}
    </div>
  );
};

exportdefault App;

3.6 後端開發

3.6.1 建立 Node.js 項目

1. 初始化項目

mkdir digital-identity-backend
cd digital-identity-backend
npm init -y

2. 安裝依賴

npm install express web3

3.6.2 編寫後端程式碼

const express = require('express');
const Web3 = require('web3');
const app = express();
const port = 3000;

// 取代為你的 Infura 項目 ID
const web3 = new Web3('https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID');
// 取代為你的智能合約地址
const contractAddress = 'YOUR_CONTRACT_ADDRESS';
const contractABI = require('./DigitalIdentity.json').abi;

const contract = new web3.eth.Contract(contractABI, contractAddress);

app.use(express.json());

// 註冊身份
app.post('/register', async (req, res) => {
const { name, email, account } = req.body;
try {
    await contract.methods.registerIdentity(name, email).send({ from: account });
    res.status(200).send('Identity registered');
  } catch (error) {
    res.status(500).send(error.message);
  }
});

// 驗證身份
app.get('/verify/:account', async (req, res) => {
const { account } = req.params;
try {
    const isRegistered = await contract.methods.verifyIdentity(account).call();
    res.status(200).json({ isRegistered });
  } catch (error) {
    res.status(500).send(error.message);
  }
});

// 獲取身份資訊
app.get('/identity/:account', async (req, res) => {
const { account } = req.params;
try {
    const identity = await contract.methods.getIdentity().call({ from: account });
    res.status(200).json({ name: identity[0], email: identity[1] });
  } catch (error) {
    res.status(500).send(error.message);
  }
});

app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});

四、總結

本文通過一個基於以太坊的簡單身份認證系統,詳細介紹了區塊鏈在身份驗證與認證中的應用。通過智能合約、前端和後端的開發,展示了如何實現一個去中心化的身份驗證系統。區塊鏈技術在提升安全性、效率、透明度和隱私保護方面的巨大潛力,使其在身份驗證與認證領域具有廣闊的應用前景。 (技術探索驛站)