您现在的位置是:网站首页 > 区块链应用中的特殊模式需求文章详情

区块链应用中的特殊模式需求

区块链应用中的特殊模式需求

区块链技术带来了去中心化、不可篡改和共识机制等特性,这些特性在传统Web应用中并不常见。JavaScript设计模式需要针对这些特性进行适配和扩展,以满足区块链应用的特殊需求。从智能合约交互到数据同步机制,区块链应用对前端架构提出了独特挑战。

观察者模式与事件监听

区块链的不可变性使得数据变更通知成为关键需求。观察者模式天然适合处理区块链事件订阅:

class BlockchainEventEmitter {
  constructor() {
    this.observers = [];
  }

  subscribe(fn) {
    this.observers.push(fn);
  }

  unsubscribe(fn) {
    this.observers = this.observers.filter(subscriber => subscriber !== fn);
  }

  notify(data) {
    this.observers.forEach(observer => observer(data));
  }
}

// 使用示例
const blockEmitter = new BlockchainEventEmitter();

blockEmitter.subscribe(block => {
  console.log(`New block mined: ${block.number}`);
});

// 模拟新区块到达
setInterval(() => {
  blockEmitter.notify({ number: Math.floor(Math.random() * 1000) });
}, 5000);

以太坊的Web3.js库实际上内置了类似机制:

const Web3 = require('web3');
const web3 = new Web3('wss://mainnet.infura.io/ws');

web3.eth.subscribe('newBlockHeaders', (error, blockHeader) => {
  if (!error) {
    console.log(blockHeader);
  }
});

策略模式与多链适配

不同区块链网络(以太坊、Solana、Polygon等)需要不同的交互策略:

class BlockchainStrategy {
  constructor(strategy) {
    this.strategy = strategy;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

  async sendTransaction(tx) {
    return this.strategy.execute(tx);
  }
}

class EthereumStrategy {
  async execute(tx) {
    // 使用web3.js发送交易
    return window.ethereum.request({
      method: 'eth_sendTransaction',
      params: [tx]
    });
  }
}

class SolanaStrategy {
  async execute(tx) {
    // 使用@solana/web3.js发送交易
    const connection = new Connection(clusterApiUrl('mainnet-beta'));
    return connection.sendTransaction(tx);
  }
}

// 使用示例
const strategy = new BlockchainStrategy(new EthereumStrategy());
await strategy.sendTransaction({ from: '0x...', to: '0x...', value: '0x...' });

// 动态切换链
strategy.setStrategy(new SolanaStrategy());

代理模式与钱包交互

区块链应用需要处理敏感操作,代理模式可以增加安全层:

class WalletProxy {
  constructor(realWallet) {
    this.realWallet = realWallet;
    this.accessLog = [];
  }

  sendTransaction(tx) {
    if (this.validateTx(tx)) {
      this.logAccess(tx);
      return this.realWallet.sendTransaction(tx);
    }
    throw new Error('Invalid transaction');
  }

  validateTx(tx) {
    // 验证逻辑
    return tx.value < 100; // 示例:限制最大转账金额
  }

  logAccess(tx) {
    this.accessLog.push({
      timestamp: new Date(),
      operation: 'sendTransaction',
      details: tx
    });
  }
}

// 使用MetaMask等真实钱包的代理
const walletProxy = new WalletProxy({
  sendTransaction: (tx) => window.ethereum.request({
    method: 'eth_sendTransaction',
    params: [tx]
  })
});

工厂模式与智能合约实例化

不同智能合约需要不同的初始化参数和交互方式:

class ContractFactory {
  static createContract(network, contractAddress, abi) {
    switch (network) {
      case 'ethereum':
        return new web3.eth.Contract(abi, contractAddress);
      case 'solana':
        return new solanaWeb3.Contract(
          programId,
          idl,
          provider
        );
      default:
        throw new Error('Unsupported network');
    }
  }
}

// 使用示例
const erc20Contract = ContractFactory.createContract(
  'ethereum',
  '0x...',
  ERC20_ABI
);

状态模式与交易生命周期

区块链交易有明确的状态流转(pending/confirmed/failed):

class TransactionState {
  constructor(context) {
    this.context = context;
  }

  handle() {}
}

class PendingState extends TransactionState {
  handle() {
    console.log('Transaction pending...');
    // 检查交易状态
    setTimeout(() => {
      if (Math.random() > 0.5) {
        this.context.setState(new ConfirmedState(this.context));
      } else {
        this.context.setState(new FailedState(this.context));
      }
    }, 3000);
  }
}

class ConfirmedState extends TransactionState {
  handle() {
    console.log('Transaction confirmed!');
    this.context.complete();
  }
}

class TransactionContext {
  constructor() {
    this.state = new PendingState(this);
    this.completed = false;
  }

  setState(state) {
    this.state = state;
    this.state.handle();
  }

  complete() {
    this.completed = true;
  }
}

// 使用示例
const tx = new TransactionContext();
tx.state.handle(); // 开始状态处理

备忘录模式与交易回滚

区块链的不可变性使得错误恢复需要特殊处理:

class TransactionMemento {
  constructor(state) {
    this.state = JSON.parse(JSON.stringify(state));
    this.timestamp = new Date();
  }
}

class TransactionOriginator {
  constructor() {
    this.state = {};
  }

  save() {
    return new TransactionMemento(this.state);
  }

  restore(memento) {
    this.state = memento.state;
  }

  async executeOperations(operations) {
    const snapshot = this.save();
    
    try {
      for (const op of operations) {
        await op.execute();
        this.state[op.id] = op.result;
      }
    } catch (error) {
      console.error('Operation failed, rolling back...');
      this.restore(snapshot);
      throw error;
    }
  }
}

装饰器模式与Gas费估算

动态添加Gas费计算功能:

function withGasEstimation(target, property, descriptor) {
  const originalMethod = descriptor.value;
  
  descriptor.value = async function(...args) {
    const tx = args[0];
    const gasEstimate = await this.estimateGas(tx);
    console.log(`Estimated gas: ${gasEstimate}`);
    return originalMethod.apply(this, args);
  };
  
  return descriptor;
}

class TransactionService {
  @withGasEstimation
  async sendTransaction(tx) {
    return window.ethereum.request({
      method: 'eth_sendTransaction',
      params: [tx]
    });
  }

  async estimateGas(tx) {
    return window.ethereum.request({
      method: 'eth_estimateGas',
      params: [tx]
    });
  }
}

组合模式与批量交易

处理多个原子操作的组合:

class BlockchainOperation {
  execute() {}
}

class SimpleTransaction extends BlockchainOperation {
  constructor(tx) {
    super();
    this.tx = tx;
  }

  async execute() {
    return window.ethereum.request({
      method: 'eth_sendTransaction',
      params: [this.tx]
    });
  }
}

class BatchOperation extends BlockchainOperation {
  constructor() {
    super();
    this.operations = [];
  }

  add(operation) {
    this.operations.push(operation);
  }

  async execute() {
    const results = [];
    for (const op of this.operations) {
      results.push(await op.execute());
    }
    return results;
  }
}

// 使用示例
const batch = new BatchOperation();
batch.add(new SimpleTransaction({ from: '0x...', to: '0x...', value: '0x1' }));
batch.add(new SimpleTransaction({ from: '0x...', to: '0x...', value: '0x2' }));
await batch.execute();

适配器模式与跨链兼容

统一不同区块链的API接口:

class UniversalBlockchainAdapter {
  constructor(provider) {
    this.provider = provider;
  }

  async getBalance(address) {
    if (this.provider.eth) {
      // 以太坊风格
      return this.provider.eth.getBalance(address);
    } else if (this.provider.getBalance) {
      // Solana风格
      return this.provider.getBalance(address);
    }
    throw new Error('Unsupported provider');
  }
}

// 使用示例
const ethAdapter = new UniversalBlockchainAdapter(web3);
const solAdapter = new UniversalBlockchainAdapter(solanaConnection);

const ethBalance = await ethAdapter.getBalance('0x...');
const solBalance = await solAdapter.getBalance('SolanaAddress...');

单例模式与全局Web3实例

确保Web3实例全局唯一:

class Web3Singleton {
  static instance = null;

  constructor() {
    if (!Web3Singleton.instance) {
      this.web3 = new Web3(window.ethereum);
      Web3Singleton.instance = this;
    }
    return Web3Singleton.instance;
  }

  static getInstance() {
    if (!Web3Singleton.instance) {
      Web3Singleton.instance = new Web3Singleton();
    }
    return Web3Singleton.instance;
  }
}

// 使用示例
const web3Instance1 = Web3Singleton.getInstance();
const web3Instance2 = Web3Singleton.getInstance();
console.log(web3Instance1 === web3Instance2); // true

命令模式与交易队列

处理交易排队和重试逻辑:

class TransactionCommand {
  constructor(execute, undo, value) {
    this.execute = execute;
    this.undo = undo;
    this.value = value;
  }
}

class TransactionQueue {
  constructor() {
    this.history = [];
    this.queue = [];
  }

  addToQueue(command) {
    this.queue.push(command);
  }

  async processQueue() {
    while (this.queue.length > 0) {
      const command = this.queue.shift();
      try {
        await command.execute(command.value);
        this.history.push(command);
      } catch (error) {
        console.error('Execution failed, attempting undo...');
        await command.undo(command.value);
      }
    }
  }
}

// 使用示例
const queue = new TransactionQueue();

const sendTxCommand = new TransactionCommand(
  (tx) => window.ethereum.request({
    method: 'eth_sendTransaction',
    params: [tx]
  }),
  (tx) => console.log(`Reverting tx: ${tx}`)
);

queue.addToQueue(sendTxCommand);
queue.processQueue();

中介者模式与跨组件通信

协调钱包连接、网络切换等全局状态:

class BlockchainMediator {
  constructor() {
    this.components = {};
  }

  register(component) {
    this.components[component.name] = component;
    component.setMediator(this);
  }

  notify(sender, event, data) {
    switch (event) {
      case 'networkChanged':
        this.handleNetworkChange(sender, data);
        break;
      case 'accountChanged':
        this.handleAccountChange(sender, data);
        break;
    }
  }

  handleNetworkChange(sender, chainId) {
    Object.values(this.components).forEach(component => {
      if (component !== sender) {
        component.networkUpdated(chainId);
      }
    });
  }
}

class WalletComponent {
  constructor() {
    this.name = 'wallet';
    this.mediator = null;
  }

  setMediator(mediator) {
    this.mediator = mediator;
  }

  onNetworkChange(chainId) {
    this.mediator.notify(this, 'networkChanged', chainId);
  }

  networkUpdated(chainId) {
    console.log(`Wallet received network update: ${chainId}`);
  }
}

访问者模式与区块链数据分析

处理不同区块链数据的解析:

class BlockchainDataVisitor {
  visitTransaction(tx) {}
  visitBlock(block) {}
}

class GasFeeAnalyzer extends BlockchainDataVisitor {
  visitTransaction(tx) {
    return {
      gasUsed: tx.gasUsed,
      gasPrice: tx.gasPrice,
      fee: tx.gasUsed * tx.gasPrice
    };
  }
}

class BlockchainData {
  accept(visitor) {}
}

class TransactionData extends BlockchainData {
  constructor(tx) {
    super();
    this.tx = tx;
  }

  accept(visitor) {
    return visitor.visitTransaction(this.tx);
  }
}

// 使用示例
const tx = { gasUsed: 21000, gasPrice: 20000000000 };
const txData = new TransactionData(tx);
const analyzer = new GasFeeAnalyzer();
const result = txData.accept(analyzer);
console.log(`Transaction fee: ${result.fee} wei`);

享元模式与ABI缓存

优化智能合约ABI的存储:

class ABIFlyweightFactory {
  constructor() {
    this.abis = {};
  }

  getABI(contractName) {
    if (!this.abis[contractName]) {
      this.abis[contractName] = this.loadABI(contractName);
    }
    return this.abis[contractName];
  }

  loadABI(contractName) {
    // 实际项目中从文件系统或网络加载
    const abis = {
      ERC20: [...],
      Uniswap: [...]
    };
    return abis[contractName];
  }
}

// 使用示例
const factory = new ABIFlyweightFactory();
const erc20ABI = factory.getABI('ERC20');
const uniswapABI = factory.getABI('Uniswap');

责任链模式与交易验证

构建交易验证管道:

class ValidationHandler {
  constructor() {
    this.nextHandler = null;
  }

  setNext(handler) {
    this.nextHandler = handler;
    return handler;
  }

  handle(tx) {
    if (this.nextHandler) {
      return this.nextHandler.handle(tx);
    }
    return true;
  }
}

class BalanceCheckHandler extends ValidationHandler {
  handle(tx) {
    if (tx.value > getBalance(tx.from)) {
      throw new Error('Insufficient balance');
    }
    return super.handle(tx);
  }
}

class GasCheckHandler extends ValidationHandler {
  handle(tx) {
    if (tx.gas < 21000) {
      throw new Error('Gas too low');
    }
    return super.handle(tx);
  }
}

// 使用示例
const validator = new BalanceCheckHandler();
validator.setNext(new GasCheckHandler());

try {
  validator.handle({
    from: '0x...',
    value: 100,
    gas: 20000
  });
} catch (error) {
  console.error(error.message);
}

模板方法模式与交易流程

定义标准化的交易处理流程:

abstract class TransactionTemplate {
  async executeTransaction() {
    this.validate();
    const nonce = await this.getNonce();
    const tx = this.prepareTransaction(nonce);
    const signedTx = await this.signTransaction(tx);
    return this.sendTransaction(signedTx);
  }

  abstract validate();
  abstract getNonce();
  abstract prepareTransaction(nonce);
  abstract signTransaction(tx);
  abstract sendTransaction(signedTx);
}

class ERC20Transfer extends TransactionTemplate {
  validate() {
    if (!this.recipient) throw new Error('Recipient required');
  }

  async getNonce() {
    return web3.eth.getTransactionCount(this.sender);
  }

  prepareTransaction(nonce) {
    return {
      from: this.sender,
      to: this.tokenAddress,
      data: this.encodeTransfer(),
      nonce,
      gas: 50000
    };
  }
}

桥接模式与多钱包支持

分离抽象和实现以支持不同钱包:

class WalletProvider {
  connect() {}
  signTransaction() {}
}

class MetaMaskProvider extends WalletProvider {
  connect() {
    return window.ethereum.request({ method: 'eth_requestAccounts' });
  }
}

class WalletConnectProvider extends WalletProvider {
  connect() {
    // WalletConnect特定的实现
  }
}

class WalletService {
  constructor(provider) {
    this.provider = provider;
  }

  async connect() {
    return this.provider.connect();
  }

  async sign(tx) {
    return this.provider.signTransaction(tx);
  }
}

// 使用示例
const mmService = new WalletService(new MetaMaskProvider());
const wcService = new WalletService(new WalletConnectProvider());

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步