Skip to content
IRC-Coding IRC-Coding
Web3 Blockchain Entwicklung Smart Contracts DApps DeFi Ethereum Solidity

Web3 Blockchain Entwicklung Grundlagen: Smart Contracts, DApps & DeFi

Web3 Blockchain Entwicklung Grundlagen mit Smart Contracts, DApps und DeFi. Ethereum, Solidity, Web3.js, Decentralized Finance mit praktischen Beispielen.

S

schutzgeist

2 min read

Web3 Blockchain Entwicklung Grundlagen: Smart Contracts, DApps & DeFi

Dieser Beitrag ist eine umfassende Einführung in die Web3 Blockchain Entwicklung Grundlagen – inklusive Smart Contracts, DApps und DeFi mit praktischen Beispielen.

In a Nutshell

Web3 ist die nächste Generation des Internets, die auf Blockchain-Technologie basiert und dezentrale Anwendungen (DApps) ermöglicht, die ohne zentrale Instanzen auskommen.

Kompakte Fachbeschreibung

Web3 ist ein dezentrales Internet-Protokoll, das auf Blockchain-Technologie aufbaut und Benutzern die Kontrolle über ihre Daten und digitale Identitäten gibt.

Kernkomponenten:

Blockchain Grundlagen

  • Distributed Ledger: Dezentrale Datenhaltung
  • Consensus Mechanisms: Proof of Work, Proof of Stake
  • Cryptography: Hash-Funktionen, Digitale Signaturen
  • Smart Contracts: Selbstausführende Verträge
  • Gas Fees: Transaktionskosten

Ethereum Ecosystem

  • EVM: Ethereum Virtual Machine
  • Solidity: Smart Contract Programmiersprache
  • Web3.js: JavaScript Bibliothek für Web3
  • Hardhat: Entwicklungsumgebung
  • OpenZeppelin: Sichere Smart Contract Bibliotheken

Decentralized Finance (DeFi)

  • DEX: Decentralized Exchanges
  • Lending: Dezentrale Kreditplattformen
  • Yield Farming: Liquiditätsbereitstellung
  • Staking: Token-Validierung
  • Governance: Dezentrale Entscheidungsfindung

Prüfungsrelevante Stichpunkte

  • Web3: Dezentrales Internet basierend auf Blockchain
  • Blockchain: Dezentrale Datenbank mit kryptographischer Sicherheit
  • Smart Contracts: Selbstausführende Verträge auf der Blockchain
  • DApps: Dezentrale Anwendungen ohne zentrale Instanz
  • DeFi: Dezentrale Finanzdienstleistungen
  • Ethereum: Leading Smart Contract Plattform
  • Solidity: Programmiersprache für Smart Contracts
  • Gas: Transaktionskosten auf der Blockchain
  • IHK-relevant: Moderne Blockchain-Entwicklung und -Architektur

Kernkomponenten

  1. Blockchain Technology: Distributed Ledger, Konsensmechanismen
  2. Smart Contracts: Selbstausführende Verträge mit Business Logic
  3. DApps: Dezentrale Frontend-Anwendungen
  4. DeFi Protocols: Finanzdienstleistungen auf der Blockchain
  5. Wallet Integration: MetaMask, WalletConnect
  6. Web3 Libraries: Web3.js, Ethers.js
  7. Development Tools: Hardhat, Truffle, Remix
  8. Security: Audits, Best Practices, Vulnerability Scanning

Praxisbeispiele

1. Smart Contract mit Solidity

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

/**
 * @title DeFiToken
 * @dev ERC20 Token mit erweiterten Funktionen für DeFi-Anwendungen
 * @author Web3 Developer
 */
contract DeFiToken is ERC20, ERC20Burnable, ReentrancyGuard, Ownable {
    using SafeMath for uint256;
    
    // Events
    event TokensMinted(address indexed to, uint256 amount);
    event TokensBurned(address indexed from, uint256 amount);
    event LiquidityAdded(address indexed provider, uint256 tokenAmount, uint256 ethAmount);
    event LiquidityRemoved(address indexed provider, uint256 tokenAmount, uint256 ethAmount);
    event RewardClaimed(address indexed claimant, uint256 rewardAmount);
    
    // State variables
    uint256 public constant MAX_SUPPLY = 1000000000 * 10**18; // 1 Billion tokens
    uint256 public constant INITIAL_SUPPLY = 100000000 * 10**18; // 100 Million tokens
    uint256 public constant REWARD_RATE = 1 * 10**16; // 0.01 tokens per block
    
    uint256 public totalLiquidity;
    uint256 public totalRewardsDistributed;
    uint256 public lastRewardBlock;
    uint256 public rewardPerTokenStored;
    
    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards;
    mapping(address => uint256) public liquidityProvided;
    mapping(address => uint256) public depositTimestamp;
    
    // Arrays für Staking-Pools
    struct Pool {
        uint256 totalStaked;
        uint256 rewardRate;
        uint256 lockPeriod;
        uint256 apr;
        bool active;
    }
    
    mapping(uint256 => Pool) public pools;
    mapping(address => mapping(uint256 => uint256)) public userStakes;
    mapping(address => mapping(uint256 => uint256)) public userStakeTimestamp;
    
    uint256 public poolCount;
    
    // Governance
    struct Proposal {
        uint256 id;
        address proposer;
        string description;
        uint256 voteCount;
        uint256 quorum;
        uint256 deadline;
        bool executed;
        mapping(address => bool) hasVoted;
    }
    
    mapping(uint256 => Proposal) public proposals;
    uint256 public proposalCount;
    mapping(address => uint256) public votingPower;
    
    // Modifiers
    modifier validAddress(address _addr) {
        require(_addr != address(0), "Invalid address");
        _;
    }
    
    modifier sufficientBalance(address _account, uint256 _amount) {
        require(balanceOf(_account) >= _amount, "Insufficient balance");
        _;
    }
    
    modifier sufficientLiquidity(uint256 _amount) {
        require(address(this).balance >= _amount, "Insufficient ETH liquidity");
        _;
    }
    
    modifier onlyWhenPaused() {
        require(!paused(), "Contract is paused");
        _;
    }
    
    // Constructor
    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _initialMint
    ) ERC20(_name, _symbol) {
        require(_initialMint <= INITIAL_SUPPLY, "Initial mint exceeds limit");
        
        _mint(msg.sender, _initialMint);
        lastRewardBlock = block.number;
        
        // Erstelle initialen Staking-Pool
        _createPool(100, 30 days, 10); // 100% APR, 30 Tage Lock
    }
    
    /**
     * @dev Mint neue Tokens (nur Owner)
     */
    function mint(address _to, uint256 _amount) 
        external 
        onlyOwner 
        validAddress(_to)
        returns (bool) 
    {
        require(totalSupply() + _amount <= MAX_SUPPLY, "Exceeds max supply");
        
        _mint(_to, _amount);
        emit TokensMinted(_to, _amount);
        return true;
    }
    
    /**
     * @dev Füge Liquidität zum Pool hinzu
     */
    function addLiquidity(uint256 _tokenAmount) 
        external 
        payable 
        nonReentrant 
        sufficientBalance(msg.sender, _tokenAmount)
        returns (uint256 liquidityTokens)
    {
        require(_tokenAmount > 0 && msg.value > 0, "Invalid amounts");
        
        // Berechne Liquidität-Tokens
        uint256 ethReserve = address(this).balance - msg.value;
        uint256 tokenReserve = totalSupply() - _tokenAmount;
        
        if (ethReserve == 0 || tokenReserve == 0) {
            liquidityTokens = _tokenAmount;
        } else {
            liquidityTokens = min(
                (msg.value * tokenReserve) / ethReserve,
                _tokenAmount
            );
        }
        
        require(liquidityTokens > 0, "Insufficient liquidity minted");
        
        // Transferiere Tokens und ETH
        _transfer(msg.sender, address(this), _tokenAmount);
        
        // Update Benutzer-Liquidität
        liquidityProvided[msg.sender] += liquidityTokens;
        depositTimestamp[msg.sender] = block.timestamp;
        
        // Update totale Liquidität
        totalLiquidity += liquidityTokens;
        
        // Update Rewards
        _updateReward(msg.sender);
        
        emit LiquidityAdded(msg.sender, _tokenAmount, msg.value);
        
        return liquidityTokens;
    }
    
    /**
     * @dev Entferne Liquidität aus dem Pool
     */
    function removeLiquidity(uint256 _liquidityAmount) 
        external 
        nonReentrant 
        returns (uint256 ethAmount, uint256 tokenAmount)
    {
        require(_liquidityAmount > 0, "Invalid amount");
        require(liquidityProvided[msg.sender] >= _liquidityAmount, "Insufficient liquidity");
        
        // Berechne Anteile
        uint256 totalLiquidityTokens = totalLiquidity;
        uint256 ethReserve = address(this).balance;
        uint256 tokenReserve = balanceOf(address(this));
        
        ethAmount = (ethReserve * _liquidityAmount) / totalLiquidityTokens;
        tokenAmount = (tokenReserve * _liquidityAmount) / totalLiquidityTokens;
        
        require(ethAmount > 0 && tokenAmount > 0, "Insufficient withdraw amount");
        
        // Update Benutzer-Liquidität
        liquidityProvided[msg.sender] -= _liquidityAmount;
        totalLiquidity -= _liquidityAmount;
        
        // Update Rewards
        _updateReward(msg.sender);
        _claimRewards(msg.sender);
        
        // Transferiere ETH und Tokens
        payable(msg.sender).transfer(ethAmount);
        _transfer(address(this), msg.sender, tokenAmount);
        
        emit LiquidityRemoved(msg.sender, tokenAmount, ethAmount);
        
        return (ethAmount, tokenAmount);
    }
    
    /**
     * @dev Erstelle neuen Staking-Pool
     */
    function createPool(uint256 _apr, uint256 _lockPeriod) external onlyOwner {
        _createPool(_apr, _lockPeriod, 0);
    }
    
    function _createPool(uint256 _apr, uint256 _lockPeriod, uint256 _rewardRate) internal {
        pools[poolCount] = Pool({
            totalStaked: 0,
            rewardRate: _rewardRate > 0 ? _rewardRate : REWARD_RATE,
            lockPeriod: _lockPeriod,
            apr: _apr,
            active: true
        });
        
        poolCount++;
    }
    
    /**
     * @dev Stake Tokens in Pool
     */
    function stake(uint256 _poolId, uint256 _amount) 
        external 
        nonReentrant 
        sufficientBalance(msg.sender, _amount)
        returns (bool)
    {
        require(_poolId < poolCount, "Invalid pool");
        require(pools[_poolId].active, "Pool not active");
        require(_amount > 0, "Invalid amount");
        
        // Update Rewards vor dem Stake
        _updatePoolRewards(_poolId);
        _updateUserPoolRewards(_poolId, msg.sender);
        
        // Transferiere Tokens zum Contract
        _transfer(msg.sender, address(this), _amount);
        
        // Update Staking
        userStakes[msg.sender][_poolId] += _amount;
        userStakeTimestamp[msg.sender][_poolId] = block.timestamp;
        pools[_poolId].totalStaked += _amount;
        
        // Update Voting Power
        votingPower[msg.sender] += _amount;
        
        return true;
    }
    
    /**
     * @dev Unstake Tokens aus Pool
     */
    function unstake(uint256 _poolId, uint256 _amount) 
        external 
        nonReentrant 
        returns (bool)
    {
        require(_poolId < poolCount, "Invalid pool");
        require(userStakes[msg.sender][_poolId] >= _amount, "Insufficient stake");
        
        Pool storage pool = pools[_poolId];
        
        // Check Lock Period
        uint256 stakeTime = userStakeTimestamp[msg.sender][_poolId];
        require(
            block.timestamp >= stakeTime + pool.lockPeriod,
            "Tokens still locked"
        );
        
        // Update Rewards vor dem Unstake
        _updatePoolRewards(_poolId);
        _updateUserPoolRewards(_poolId, msg.sender);
        
        // Update Staking
        userStakes[msg.sender][_poolId] -= _amount;
        pool.totalStaked -= _amount;
        
        // Update Voting Power
        votingPower[msg.sender] -= _amount;
        
        // Transferiere Tokens zurück
        _transfer(address(this), msg.sender, _amount);
        
        return true;
    }
    
    /**
     * @dev Claim Rewards aus Pool
     */
    function claimRewards(uint256 _poolId) external nonReentrant returns (uint256) {
        require(_poolId < poolCount, "Invalid pool");
        require(userStakes[msg.sender][_poolId] > 0, "No stake in pool");
        
        // Update Rewards
        _updatePoolRewards(_poolId);
        _updateUserPoolRewards(_poolId, msg.sender);
        
        uint256 reward = rewards[msg.sender];
        require(reward > 0, "No rewards to claim");
        
        // Reset rewards
        rewards[msg.sender] = 0;
        
        // Mint neue Tokens als Reward
        _mint(msg.sender, reward);
        
        emit RewardClaimed(msg.sender, reward);
        
        return reward;
    }
    
    /**
     * @dev Erstelle Governance Proposal
     */
    function createProposal(string memory _description, uint256 _quorum) 
        external 
        returns (uint256)
    {
        require(votingPower[msg.sender] >= 1000 * 10**18, "Insufficient voting power");
        require(bytes(_description).length > 0, "Empty description");
        
        Proposal storage proposal = proposals[proposalCount];
        proposal.id = proposalCount;
        proposal.proposer = msg.sender;
        proposal.description = _description;
        proposal.voteCount = 0;
        proposal.quorum = _quorum;
        proposal.deadline = block.timestamp + 7 days;
        proposal.executed = false;
        
        proposalCount++;
        
        return proposalCount - 1;
    }
    
    /**
     * @dev Vote für Proposal
     */
    function vote(uint256 _proposalId) external {
        require(_proposalId < proposalCount, "Invalid proposal");
        require(block.timestamp <= proposals[_proposalId].deadline, "Voting ended");
        require(!proposals[_proposalId].hasVoted[msg.sender], "Already voted");
        require(votingPower[msg.sender] > 0, "No voting power");
        
        proposals[_proposalId].hasVoted[msg.sender] = true;
        proposals[_proposalId].voteCount += votingPower[msg.sender];
    }
    
    /**
     * @dev Execute Proposal
     */
    function executeProposal(uint256 _proposalId) external onlyOwner {
        require(_proposalId < proposalCount, "Invalid proposal");
        require(block.timestamp > proposals[_proposalId].deadline, "Voting not ended");
        require(!proposals[_proposalId].executed, "Already executed");
        require(
            proposals[_proposalId].voteCount >= proposals[_proposalId].quorum,
            "Quorum not reached"
        );
        
        proposals[_proposalId].executed = true;
    }
    
    /**
     * @dev Update Reward Funktionen
     */
    function _updateReward(address _account) internal {
        if (_account == address(0)) return;
        
        rewardPerTokenStored = rewardPerToken();
        lastRewardBlock = block.number;
        
        rewards[_account] = earned(_account);
        userRewardPerTokenPaid[_account] = rewardPerTokenStored;
    }
    
    function _updatePoolRewards(uint256 _poolId) internal {
        // Implementiere Pool-spezifische Reward Logic
        // Dies ist eine vereinfachte Version
    }
    
    function _updateUserPoolRewards(uint256 _poolId, address _account) internal {
        // Implementiere User-spezifische Pool Rewards
    }
    
    /**
     * @dev Helper Funktionen
     */
    function rewardPerToken() public view returns (uint256) {
        if (totalLiquidity == 0) {
            return rewardPerTokenStored;
        }
        
        return rewardPerTokenStored.add(
            ((block.number.sub(lastRewardBlock)).mul(REWARD_RATE)).mul(1e18).div(totalLiquidity)
        );
    }
    
    function earned(address _account) public view returns (uint256) {
        return liquidityProvided[_account]
            .mul(rewardPerToken().sub(userRewardPerTokenPaid[_account]))
            .div(1e18)
            .add(rewards[_account]);
    }
    
    function getPoolInfo(uint256 _poolId) 
        external 
        view 
        returns (
            uint256 totalStaked,
            uint256 rewardRate,
            uint256 lockPeriod,
            uint256 apr,
            bool active
        ) 
    {
        require(_poolId < poolCount, "Invalid pool");
        Pool storage pool = pools[_poolId];
        return (pool.totalStaked, pool.rewardRate, pool.lockPeriod, pool.apr, pool.active);
    }
    
    function getUserStake(uint256 _poolId, address _user) 
        external 
        view 
        returns (uint256 amount, uint256 timestamp) 
    {
        require(_poolId < poolCount, "Invalid pool");
        return (userStakes[_user][_poolId], userStakeTimestamp[_user][_poolId]);
    }
    
    function getProposalInfo(uint256 _proposalId) 
        external 
        view 
        returns (
            address proposer,
            string memory description,
            uint256 voteCount,
            uint256 quorum,
            uint256 deadline,
            bool executed,
            bool hasVoted
        ) 
    {
        require(_proposalId < proposalCount, "Invalid proposal");
        Proposal storage proposal = proposals[_proposalId];
        return (
            proposal.proposer,
            proposal.description,
            proposal.voteCount,
            proposal.quorum,
            proposal.deadline,
            proposal.executed,
            proposal.hasVoted[msg.sender]
        );
    }
    
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
    
    /**
     * @dev Emergency Funktionen
     */
    function emergencyPause() external onlyOwner {
        _pause();
    }
    
    function emergencyUnpause() external onlyOwner {
        _unpause();
    }
    
    function emergencyWithdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
    
    /**
     * @dev Fallback für ETH Transfers
     */
    receive() external payable {
        // Akzeptiere ETH für Liquidität
    }
    
    fallback() external payable {
        // Akzeptiere ETH für Liquidität
    }
}

2. DApp Frontend mit React und Web3.js

// src/components/Web3Provider.jsx
import React, { createContext, useContext, useEffect, useState } from 'react';
import Web3 from 'web3';
import { Contract } from 'web3-eth-contract';
import DeFiTokenABI from '../contracts/DeFiToken.json';

const Web3Context = createContext();

export const useWeb3 = () => {
  const context = useContext(Web3Context);
  if (!context) {
    throw new Error('useWeb3 must be used within a Web3Provider');
  }
  return context;
};

const Web3Provider = ({ children }) => {
  const [web3, setWeb3] = useState(null);
  const [account, setAccount] = useState(null);
  const [contract, setContract] = useState(null);
  const [networkId, setNetworkId] = useState(null);
  const [balance, setBalance] = useState('0');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const CONTRACT_ADDRESS = process.env.REACT_APP_CONTRACT_ADDRESS;
  const SUPPORTED_NETWORKS = {
    1: 'Ethereum Mainnet',
    3: 'Ropsten Testnet',
    4: 'Rinkeby Testnet',
    5: 'Goerli Testnet',
    42: 'Kovan Testnet',
    137: 'Polygon Mainnet',
    80001: 'Polygon Mumbai'
  };

  // Initialize Web3
  useEffect(() => {
    const initWeb3 = async () => {
      try {
        // Check if MetaMask is installed
        if (typeof window.ethereum !== 'undefined') {
          const web3Instance = new Web3(window.ethereum);
          setWeb3(web3Instance);

          // Request account access
          const accounts = await window.ethereum.request({
            method: 'eth_requestAccounts'
          });

          if (accounts.length > 0) {
            setAccount(accounts[0]);
            await setupContract(web3Instance);
            await getNetworkInfo(web3Instance);
            await updateBalance(web3Instance, accounts[0]);
          }

          // Setup event listeners
          setupEventListeners(web3Instance);
        } else {
          setError('MetaMask is not installed. Please install MetaMask to use this DApp.');
        }
      } catch (error) {
        console.error('Web3 initialization error:', error);
        setError('Failed to initialize Web3. Please check your wallet connection.');
      } finally {
        setLoading(false);
      }
    };

    initWeb3();
  }, []);

  const setupEventListeners = (web3Instance) => {
    // Account change
    window.ethereum.on('accountsChanged', (accounts) => {
      if (accounts.length === 0) {
        setAccount(null);
        setBalance('0');
      } else {
        setAccount(accounts[0]);
        updateBalance(web3Instance, accounts[0]);
      }
    });

    // Network change
    window.ethereum.on('chainChanged', () => {
      window.location.reload();
    });

    // Connect/Disconnect
    window.ethereum.on('connect', (connectInfo) => {
      console.log('Connected to blockchain:', connectInfo);
    });

    window.ethereum.on('disconnect', (error) => {
      console.error('Disconnected from blockchain:', error);
      setAccount(null);
      setBalance('0');
    });
  };

  const setupContract = async (web3Instance) => {
    try {
      const contractInstance = new web3Instance.eth.Contract(
        DeFiTokenABI.abi,
        CONTRACT_ADDRESS
      );
      setContract(contractInstance);
    } catch (error) {
      console.error('Contract setup error:', error);
      setError('Failed to setup smart contract.');
    }
  };

  const getNetworkInfo = async (web3Instance) => {
    try {
      const networkId = await web3Instance.eth.net.getId();
      setNetworkId(networkId);

      if (!SUPPORTED_NETWORKS[networkId]) {
        setError(`Unsupported network. Please switch to a supported network.`);
      }
    } catch (error) {
      console.error('Network info error:', error);
    }
  };

  const updateBalance = async (web3Instance, accountAddress) => {
    try {
      const balanceWei = await web3Instance.eth.getBalance(accountAddress);
      const balanceEth = web3Instance.utils.fromWei(balanceWei, 'ether');
      setBalance(balanceEth);
    } catch (error) {
      console.error('Balance update error:', error);
    }
  };

  const connectWallet = async () => {
    try {
      if (typeof window.ethereum !== 'undefined') {
        const accounts = await window.ethereum.request({
          method: 'eth_requestAccounts'
        });

        if (accounts.length > 0) {
          setAccount(accounts[0]);
          await updateBalance(web3, accounts[0]);
        }
      }
    } catch (error) {
      console.error('Wallet connection error:', error);
      setError('Failed to connect wallet.');
    }
  };

  const disconnectWallet = () => {
    setAccount(null);
    setBalance('0');
  };

  const switchNetwork = async (networkId) => {
    try {
      await window.ethereum.request({
        method: 'wallet_switchEthereumChain',
        params: [{ chainId: `0x${networkId.toString(16)}` }]
      });
    } catch (error) {
      console.error('Network switch error:', error);
      setError('Failed to switch network.');
    }
  };

  const value = {
    web3,
    account,
    contract,
    networkId,
    balance,
    loading,
    error,
    supportedNetworks: SUPPORTED_NETWORKS,
    connectWallet,
    disconnectWallet,
    switchNetwork,
    refreshBalance: () => updateBalance(web3, account)
  };

  return (
    <Web3Context.Provider value={value}>
      {children}
    </Web3Context.Provider>
  );
};

export default Web3Provider;

// src/components/TokenDashboard.jsx
import React, { useState, useEffect } from 'react';
import { useWeb3 } from './Web3Provider';
import { Card, CardHeader, CardContent, CardActions } from './UI/Card';
import Button from './UI/Button';
import Input from './UI/Input';
import Alert from './UI/Alert';
import LoadingSpinner from './UI/LoadingSpinner';

const TokenDashboard = () => {
  const { web3, account, contract, balance, refreshBalance } = useWeb3();
  const [tokenBalance, setTokenBalance] = useState('0');
  const [totalSupply, setTotalSupply] = useState('0');
  const [stakingData, setStakingData] = useState([]);
  const [liquidityData, setLiquidityData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [success, setSuccess] = useState(null);

  // Form states
  const [stakeAmount, setStakeAmount] = useState('');
  const [liquidityTokenAmount, setLiquidityTokenAmount] = useState('');
  const [liquidityEthAmount, setLiquidityEthAmount] = useState('');

  // Load token data
  useEffect(() => {
    if (contract && account) {
      loadTokenData();
    }
  }, [contract, account]);

  const loadTokenData = async () => {
    try {
      setLoading(true);
      setError(null);

      const [
        tokenBalanceWei,
        totalSupplyWei,
        poolCount,
        userLiquidity,
        userRewards
      ] = await Promise.all([
        contract.methods.balanceOf(account).call(),
        contract.methods.totalSupply().call(),
        contract.methods.poolCount().call(),
        contract.methods.liquidityProvided(account).call(),
        contract.methods.earned(account).call()
      ]);

      setTokenBalance(web3.utils.fromWei(tokenBalanceWei, 'ether'));
      setTotalSupply(web3.utils.fromWei(totalSupplyWei, 'ether'));
      setLiquidityData({
        provided: web3.utils.fromWei(userLiquidity, 'ether'),
        rewards: web3.utils.fromWei(userRewards, 'ether')
      });

      // Load staking data
      const pools = [];
      for (let i = 0; i < poolCount; i++) {
        const [poolInfo, userStake] = await Promise.all([
          contract.methods.getPoolInfo(i).call(),
          contract.methods.getUserStake(i, account).call()
        ]);

        pools.push({
          id: i,
          ...poolInfo,
          userStake: {
            amount: web3.utils.fromWei(userStake.amount, 'ether'),
            timestamp: userStake.timestamp
          }
        });
      }
      setStakingData(pools);

    } catch (error) {
      console.error('Token data load error:', error);
      setError('Failed to load token data.');
    } finally {
      setLoading(false);
    }
  };

  const handleStake = async (poolId, amount) => {
    try {
      setLoading(true);
      setError(null);

      const amountWei = web3.utils.toWei(amount, 'ether');
      
      const tx = await contract.methods.stake(poolId, amountWei).send({
        from: account,
        gas: '300000'
      });

      setSuccess(`Successfully staked ${amount} tokens! Transaction: ${tx.transactionHash}`);
      setStakeAmount('');
      await loadTokenData();
      await refreshBalance();

    } catch (error) {
      console.error('Stake error:', error);
      setError('Failed to stake tokens.');
    } finally {
      setLoading(false);
    }
  };

  const handleUnstake = async (poolId, amount) => {
    try {
      setLoading(true);
      setError(null);

      const amountWei = web3.utils.toWei(amount, 'ether');
      
      const tx = await contract.methods.unstake(poolId, amountWei).send({
        from: account,
        gas: '300000'
      });

      setSuccess(`Successfully unstaked ${amount} tokens! Transaction: ${tx.transactionHash}`);
      await loadTokenData();
      await refreshBalance();

    } catch (error) {
      console.error('Unstake error:', error);
      setError('Failed to unstake tokens.');
    } finally {
      setLoading(false);
    }
  };

  const handleClaimRewards = async (poolId) => {
    try {
      setLoading(true);
      setError(null);

      const tx = await contract.methods.claimRewards(poolId).send({
        from: account,
        gas: '200000'
      });

      const rewards = await contract.methods.claimRewards(poolId).call({ from: account });
      setSuccess(`Successfully claimed ${web3.utils.fromWei(rewards, 'ether')} tokens!`);
      await loadTokenData();

    } catch (error) {
      console.error('Claim rewards error:', error);
      setError('Failed to claim rewards.');
    } finally {
      setLoading(false);
    }
  };

  const handleAddLiquidity = async () => {
    try {
      setLoading(true);
      setError(null);

      const tokenAmountWei = web3.utils.toWei(liquidityTokenAmount, 'ether');
      const ethAmountWei = web3.utils.toWei(liquidityEthAmount, 'ether');

      // Approve token transfer
      await contract.methods.approve(CONTRACT_ADDRESS, tokenAmountWei).send({
        from: account,
        gas: '100000'
      });

      // Add liquidity
      const tx = await contract.methods.addLiquidity(tokenAmountWei).send({
        from: account,
        value: ethAmountWei,
        gas: '300000'
      });

      setSuccess(`Successfully added liquidity! Transaction: ${tx.transactionHash}`);
      setLiquidityTokenAmount('');
      setLiquidityEthAmount('');
      await loadTokenData();
      await refreshBalance();

    } catch (error) {
      console.error('Add liquidity error:', error);
      setError('Failed to add liquidity.');
    } finally {
      setLoading(false);
    }
  };

  const handleRemoveLiquidity = async (amount) => {
    try {
      setLoading(true);
      setError(null);

      const amountWei = web3.utils.toWei(amount, 'ether');

      const tx = await contract.methods.removeLiquidity(amountWei).send({
        from: account,
        gas: '300000'
      });

      setSuccess(`Successfully removed liquidity! Transaction: ${tx.transactionHash}`);
      await loadTokenData();
      await refreshBalance();

    } catch (error) {
      console.error('Remove liquidity error:', error);
      setError('Failed to remove liquidity.');
    } finally {
      setLoading(false);
    }
  };

  if (loading && !tokenBalance) {
    return <LoadingSpinner />;
  }

  return (
    <div className="token-dashboard">
      <div className="dashboard-header">
        <h1>DeFi Token Dashboard</h1>
        <div className="account-info">
          <p><strong>Account:</strong> {account}</p>
          <p><strong>ETH Balance:</strong> {balance} ETH</p>
          <p><strong>Token Balance:</strong> {tokenBalance} DEFI</p>
        </div>
      </div>

      {error && <Alert type="error" message={error} />}
      {success && <Alert type="success" message={success} />}

      {/* Token Info */}
      <Card className="token-info-card">
        <CardHeader>
          <h2>Token Information</h2>
        </CardHeader>
        <CardContent>
          <div className="info-grid">
            <div className="info-item">
              <label>Total Supply</label>
              <span>{totalSupply} DEFI</span>
            </div>
            <div className="info-item">
              <label>Your Balance</label>
              <span>{tokenBalance} DEFI</span>
            </div>
            <div className="info-item">
              <label>Liquidity Provided</label>
              <span>{liquidityData?.provided || '0'} DEFI</span>
            </div>
            <div className="info-item">
              <label>Pending Rewards</label>
              <span>{liquidityData?.rewards || '0'} DEFI</span>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Staking Pools */}
      <Card className="staking-card">
        <CardHeader>
          <h2>Staking Pools</h2>
        </CardHeader>
        <CardContent>
          {stakingData.map((pool) => (
            <div key={pool.id} className="staking-pool">
              <div className="pool-header">
                <h3>Pool #{pool.id + 1}</h3>
                <span className={`pool-status ${pool.active ? 'active' : 'inactive'}`}>
                  {pool.active ? 'Active' : 'Inactive'}
                </span>
              </div>
              
              <div className="pool-info">
                <div className="pool-stat">
                  <label>APR</label>
                  <span>{pool.apr}%</span>
                </div>
                <div className="pool-stat">
                  <label>Lock Period</label>
                  <span>{pool.lockPeriod / 86400} days</span>
                </div>
                <div className="pool-stat">
                  <label>Total Staked</label>
                  <span>{web3.utils.fromWei(pool.totalStaked, 'ether')} DEFI</span>
                </div>
                <div className="pool-stat">
                  <label>Your Stake</label>
                  <span>{pool.userStake.amount} DEFI</span>
                </div>
              </div>

              <div className="pool-actions">
                {pool.active && (
                  <>
                    <div className="stake-form">
                      <Input
                        type="number"
                        placeholder="Amount to stake"
                        value={stakeAmount}
                        onChange={(e) => setStakeAmount(e.target.value)}
                        min="0"
                        step="0.01"
                      />
                      <Button
                        onClick={() => handleStake(pool.id, stakeAmount)}
                        disabled={!stakeAmount || parseFloat(stakeAmount) <= 0}
                      >
                        Stake
                      </Button>
                    </div>

                    {pool.userStake.amount > '0' && (
                      <>
                        <Button
                          variant="secondary"
                          onClick={() => handleUnstake(pool.id, pool.userStake.amount)}
                        >
                          Unstake All
                        </Button>
                        <Button
                          variant="outline"
                          onClick={() => handleClaimRewards(pool.id)}
                        >
                          Claim Rewards
                        </Button>
                      </>
                    )}
                  </>
                )}
              </div>
            </div>
          ))}
        </CardContent>
      </Card>

      {/* Liquidity Management */}
      <Card className="liquidity-card">
        <CardHeader>
          <h2>Liquidity Management</h2>
        </CardHeader>
        <CardContent>
          <div className="liquidity-form">
            <h3>Add Liquidity</h3>
            <div className="form-row">
              <Input
                type="number"
                placeholder="Token amount"
                value={liquidityTokenAmount}
                onChange={(e) => setLiquidityTokenAmount(e.target.value)}
                min="0"
                step="0.01"
              />
              <Input
                type="number"
                placeholder="ETH amount"
                value={liquidityEthAmount}
                onChange={(e) => setLiquidityEthAmount(e.target.value)}
                min="0"
                step="0.01"
              />
            </div>
            <Button
              onClick={handleAddLiquidity}
              disabled={!liquidityTokenAmount || !liquidityEthAmount || loading}
            >
              Add Liquidity
            </Button>
          </div>

          {liquidityData?.provided > '0' && (
            <div className="remove-liquidity">
              <h3>Remove Liquidity</h3>
              <div className="form-row">
                <Input
                  type="number"
                  placeholder="Amount to remove"
                  min="0"
                  max={liquidityData.provided}
                  step="0.01"
                />
                <Button
                  variant="danger"
                  onClick={() => handleRemoveLiquidity(liquidityData.provided)}
                >
                  Remove All
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
};

export default TokenDashboard;

// src/components/GovernancePanel.jsx
import React, { useState, useEffect } from 'react';
import { useWeb3 } from './Web3Provider';
import { Card, CardHeader, CardContent, CardActions } from './UI/Card';
import Button from './UI/Button';
import Input from './UI/Input';
import Alert from './UI/Alert';

const GovernancePanel = () => {
  const { web3, account, contract } = useWeb3();
  const [proposals, setProposals] = useState([]);
  const [votingPower, setVotingPower] = useState('0');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [success, setSuccess] = useState(null);

  // Form states
  const [proposalDescription, setProposalDescription] = useState('');
  const [proposalQuorum, setProposalQuorum] = useState('');

  useEffect(() => {
    if (contract && account) {
      loadGovernanceData();
    }
  }, [contract, account]);

  const loadGovernanceData = async () => {
    try {
      setLoading(true);
      setError(null);

      const [proposalCount, userVotingPower] = await Promise.all([
        contract.methods.proposalCount().call(),
        contract.methods.votingPower(account).call()
      ]);

      setVotingPower(web3.utils.fromWei(userVotingPower, 'ether'));

      // Load proposals
      const proposalList = [];
      for (let i = 0; i < proposalCount; i++) {
        const proposalInfo = await contract.methods.getProposalInfo(i).call();
        proposalList.push({
          id: i,
          proposer: proposalInfo[0],
          description: proposalInfo[1],
          voteCount: web3.utils.fromWei(proposalInfo[2], 'ether'),
          quorum: web3.utils.fromWei(proposalInfo[3], 'ether'),
          deadline: new Date(proposalInfo[4] * 1000),
          executed: proposalInfo[5],
          hasVoted: proposalInfo[6]
        });
      }

      setProposals(proposalList.reverse()); // Newest first

    } catch (error) {
      console.error('Governance data load error:', error);
      setError('Failed to load governance data.');
    } finally {
      setLoading(false);
    }
  };

  const handleCreateProposal = async () => {
    try {
      setLoading(true);
      setError(null);

      const quorumWei = web3.utils.toWei(proposalQuorum, 'ether');

      const tx = await contract.methods.createProposal(
        proposalDescription,
        quorumWei
      ).send({
        from: account,
        gas: '200000'
      });

      setSuccess(`Proposal created successfully! Transaction: ${tx.transactionHash}`);
      setProposalDescription('');
      setProposalQuorum('');
      await loadGovernanceData();

    } catch (error) {
      console.error('Create proposal error:', error);
      setError('Failed to create proposal.');
    } finally {
      setLoading(false);
    }
  };

  const handleVote = async (proposalId) => {
    try {
      setLoading(true);
      setError(null);

      const tx = await contract.methods.vote(proposalId).send({
        from: account,
        gas: '100000'
      });

      setSuccess(`Vote cast successfully! Transaction: ${tx.transactionHash}`);
      await loadGovernanceData();

    } catch (error) {
      console.error('Vote error:', error);
      setError('Failed to cast vote.');
    } finally {
      setLoading(false);
    }
  };

  const handleExecuteProposal = async (proposalId) => {
    try {
      setLoading(true);
      setError(null);

      const tx = await contract.methods.executeProposal(proposalId).send({
        from: account,
        gas: '100000'
      });

      setSuccess(`Proposal executed successfully! Transaction: ${tx.transactionHash}`);
      await loadGovernanceData();

    } catch (error) {
      console.error('Execute proposal error:', error);
      setError('Failed to execute proposal.');
    } finally {
      setLoading(false);
    }
  };

  const canVote = (proposal) => {
    return !proposal.hasVoted && 
           votingPower > '0' && 
           new Date() < proposal.deadline && 
           !proposal.executed;
  };

  const canExecute = (proposal) => {
    return !proposal.executed && 
           new Date() > proposal.deadline && 
           proposal.voteCount >= proposal.quorum;
  };

  return (
    <div className="governance-panel">
      <div className="governance-header">
        <h1>Governance</h1>
        <div className="voting-info">
          <p><strong>Your Voting Power:</strong> {votingPower} DEFI</p>
        </div>
      </div>

      {error && <Alert type="error" message={error} />}
      {success && <Alert type="success" message={success} />}

      {/* Create Proposal */}
      <Card className="create-proposal-card">
        <CardHeader>
          <h2>Create Proposal</h2>
        </CardHeader>
        <CardContent>
          <div className="proposal-form">
            <div className="form-group">
              <label>Proposal Description</label>
              <textarea
                value={proposalDescription}
                onChange={(e) => setProposalDescription(e.target.value)}
                placeholder="Describe your proposal..."
                rows={4}
              />
            </div>
            <div className="form-group">
              <label>Quorum (tokens required)</label>
              <Input
                type="number"
                value={proposalQuorum}
                onChange={(e) => setProposalQuorum(e.target.value)}
                placeholder="1000000"
                min="0"
                step="0.01"
              />
            </div>
          </div>
        </CardContent>
        <CardActions>
          <Button
            onClick={handleCreateProposal}
            disabled={!proposalDescription || !proposalQuorum || votingPower < '1000'}
          >
            Create Proposal
          </Button>
        </CardActions>
      </Card>

      {/* Proposals List */}
      <Card className="proposals-card">
        <CardHeader>
          <h2>Proposals</h2>
        </CardHeader>
        <CardContent>
          {proposals.length === 0 ? (
            <p>No proposals yet.</p>
          ) : (
            <div className="proposals-list">
              {proposals.map((proposal) => (
                <div key={proposal.id} className="proposal-item">
                  <div className="proposal-header">
                    <h3>Proposal #{proposal.id + 1}</h3>
                    <div className="proposal-status">
                      {proposal.executed ? (
                        <span className="status-executed">Executed</span>
                      ) : new Date() > proposal.deadline ? (
                        <span className="status-expired">Expired</span>
                      ) : (
                        <span className="status-active">Active</span>
                      )}
                    </div>
                  </div>

                  <div className="proposal-content">
                    <p className="proposal-description">{proposal.description}</p>
                    
                    <div className="proposal-meta">
                      <div className="meta-item">
                        <label>Proposer:</label>
                        <span>{proposal.proposer}</span>
                      </div>
                      <div className="meta-item">
                        <label>Deadline:</label>
                        <span>{proposal.deadline.toLocaleDateString()}</span>
                      </div>
                      <div className="meta-item">
                        <label>Vote Count:</label>
                        <span>{proposal.voteCount} / {proposal.quorum}</span>
                      </div>
                    </div>

                    <div className="vote-progress">
                      <div className="progress-bar">
                        <div 
                          className="progress-fill"
                          style={{
                            width: `${Math.min((parseFloat(proposal.voteCount) / parseFloat(proposal.quorum)) * 100, 100)}%`
                          }}
                        />
                      </div>
                      <span className="progress-text">
                        {Math.round((parseFloat(proposal.voteCount) / parseFloat(proposal.quorum)) * 100)}%
                      </span>
                    </div>
                  </div>

                  <div className="proposal-actions">
                    {canVote(proposal) && (
                      <Button onClick={() => handleVote(proposal.id)}>
                        Vote
                      </Button>
                    )}
                    
                    {canExecute(proposal) && (
                      <Button variant="success" onClick={() => handleExecuteProposal(proposal.id)}>
                        Execute
                      </Button>
                    )}

                    {proposal.hasVoted && (
                      <span className="voted-indicator">✓ Voted</span>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
};

export default GovernancePanel;

// src/App.jsx
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Web3Provider from './components/Web3Provider';
import TokenDashboard from './components/TokenDashboard';
import GovernancePanel from './components/GovernancePanel';
import Navbar from './components/Navbar';
import './App.css';

function App() {
  return (
    <Web3Provider>
      <Router>
        <div className="App">
          <Navbar />
          <main className="main-content">
            <Routes>
              <Route path="/" element={<TokenDashboard />} />
              <Route path="/governance" element={<GovernancePanel />} />
            </Routes>
          </main>
        </div>
      </Router>
    </Web3Provider>
  );
}

export default App;

3. DeFi Protocol mit Python und Web3.py

# defi_protocol.py
import json
import time
from web3 import Web3
from web3.contract import Contract
from web3.middleware import geth_poa_middleware
from eth_account import Account
from eth_utils import to_checksum_address
from decimal import Decimal
import logging

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class DeFiProtocol:
    """
    DeFi Protocol implementation for automated trading and liquidity management
    """
    
    def __init__(self, provider_url, private_key=None):
        """
        Initialize DeFi Protocol
        
        Args:
            provider_url: Web3 provider URL
            private_key: Private key for transactions (optional)
        """
        self.w3 = Web3(Web3.HTTPProvider(provider_url))
        
        # Inject POA middleware for testnets
        if self.w3.eth.chain_id in [3, 4, 5, 42, 80001]:
            self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
        
        self.account = None
        if private_key:
            self.account = Account.from_key(private_key)
            self.w3.eth.default_account = self.account.address
        
        # Contract addresses and ABIs
        self.contracts = {}
        self.load_contracts()
        
        # Gas settings
        self.gas_price = self.w3.eth.gas_price
        self.gas_limit = 300000
        
    def load_contracts(self):
        """Load contract ABIs and addresses"""
        # Example contract ABIs (would normally load from files)
        erc20_abi = [
            {
                "constant": True,
                "inputs": [{"name": "_owner", "type": "address"}],
                "name": "balanceOf",
                "outputs": [{"name": "balance", "type": "uint256"}],
                "type": "function"
            },
            {
                "constant": False,
                "inputs": [
                    {"name": "_to", "type": "address"},
                    {"name": "_value", "type": "uint256"}
                ],
                "name": "transfer",
                "outputs": [{"name": "", "type": "bool"}],
                "type": "function"
            },
            {
                "constant": False,
                "inputs": [
                    {"name": "_spender", "type": "address"},
                    {"name": "_value", "type": "uint256"}
                ],
                "name": "approve",
                "outputs": [{"name": "", "type": "bool"}],
                "type": "function"
            }
        ]
        
        uniswap_router_abi = [
            {
                "constant": False,
                "inputs": [
                    {"name": "amountOutMin", "type": "uint256"},
                    {"name": "path", "type": "address[]"},
                    {"name": "to", "type": "address"},
                    {"name": "deadline", "type": "uint256"}
                ],
                "name": "swapExactETHForTokens",
                "outputs": [{"name": "amounts", "type": "uint256[]"}],
                "type": "function"
            },
            {
                "constant": False,
                "inputs": [
                    {"name": "amountIn", "type": "uint256"},
                    {"name": "amountOutMin", "type": "uint256"},
                    {"name": "path", "type": "address[]"},
                    {"name": "to", "type": "address"},
                    {"name": "deadline", "type": "uint256"}
                ],
                "name": "swapExactTokensForTokens",
                "outputs": [{"name": "amounts", "type": "uint256[]"}],
                "type": "function"
            },
            {
                "constant": True,
                "inputs": [
                    {"name": "amountIn", "type": "uint256"},
                    {"name": "reserveIn", "type": "uint256"},
                    {"name": "reserveOut", "type": "uint256"}
                ],
                "name": "getAmountOut",
                "outputs": [{"name": "amountOut", "type": "uint256"}],
                "type": "function"
            }
        ]
        
        # Contract addresses (example for Ethereum Mainnet)
        self.contract_addresses = {
            'WETH': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
            'USDC': '0xA0b86a33E6441E7C1A785D1A97b7327c2c0c0c0c',
            'DAI': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
            'UNISWAP_ROUTER': '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
            'UNISWAP_FACTORY': '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'
        }
        
        # Initialize contracts
        for name, address in self.contract_addresses.items():
            if name in ['WETH', 'USDC', 'DAI']:
                self.contracts[name] = self.w3.eth.contract(
                    address=address,
                    abi=erc20_abi
                )
            elif name == 'UNISWAP_ROUTER':
                self.contracts[name] = self.w3.eth.contract(
                    address=address,
                    abi=uniswap_router_abi
                )
    
    def get_balance(self, token_symbol, address=None):
        """
        Get token balance for address
        
        Args:
            token_symbol: Token symbol (e.g., 'ETH', 'USDC', 'DAI')
            address: Address to check (default: current account)
        
        Returns:
            Token balance as Decimal
        """
        if address is None:
            if not self.account:
                raise ValueError("No account specified")
            address = self.account.address
        
        if token_symbol == 'ETH':
            balance_wei = self.w3.eth.get_balance(address)
            return Decimal(balance_wei) / Decimal(10**18)
        
        if token_symbol not in self.contracts:
            raise ValueError(f"Unknown token: {token_symbol}")
        
        contract = self.contracts[token_symbol]
        balance_wei = contract.functions.balanceOf(address).call()
        decimals = self.get_token_decimals(token_symbol)
        
        return Decimal(balance_wei) / Decimal(10**decimals)
    
    def get_token_decimals(self, token_symbol):
        """Get token decimals"""
        decimals_map = {
            'WETH': 18,
            'USDC': 6,
            'DAI': 18
        }
        return decimals_map.get(token_symbol, 18)
    
    def approve_token(self, token_symbol, spender_address, amount):
        """
        Approve token spending
        
        Args:
            token_symbol: Token symbol to approve
            spender_address: Address to approve for
            amount: Amount to approve (in human-readable format)
        
        Returns:
            Transaction hash
        """
        if not self.account:
            raise ValueError("No account configured")
        
        if token_symbol not in self.contracts:
            raise ValueError(f"Unknown token: {token_symbol}")
        
        contract = self.contracts[token_symbol]
        decimals = self.get_token_decimals(token_symbol)
        amount_wei = int(Decimal(amount) * Decimal(10**decimals))
        
        # Build transaction
        transaction = contract.functions.approve(
            spender_address,
            amount_wei
        ).build_transaction({
            'from': self.account.address,
            'gas': self.gas_limit,
            'gasPrice': self.gas_price,
            'nonce': self.w3.eth.get_transaction_count(self.account.address)
        })
        
        # Sign and send transaction
        signed_txn = self.w3.eth.account.sign_transaction(transaction, self.account.key)
        tx_hash = self.w3.eth.send_raw_transaction(signed_txn.rawTransaction)
        
        # Wait for confirmation
        receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
        
        if receipt.status == 1:
            logger.info(f"Token approved: {tx_hash.hex()}")
            return tx_hash.hex()
        else:
            raise Exception("Transaction failed")
    
    def swap_eth_for_tokens(self, eth_amount, token_symbol, slippage_percent=1):
        """
        Swap ETH for tokens on Uniswap
        
        Args:
            eth_amount: Amount of ETH to swap
            token_symbol: Target token symbol
            slippage_percent: Maximum slippage percentage
        
        Returns:
            Transaction hash
        """
        if not self.account:
            raise ValueError("No account configured")
        
        if token_symbol not in self.contract_addresses:
            raise ValueError(f"Unknown token: {token_symbol}")
        
        router = self.contracts['UNISWAP_ROUTER']
        token_address = self.contract_addresses[token_symbol]
        
        # Calculate minimum amount out with slippage
        amount_out = self.get_swap_amount_out(eth_amount, 'ETH', token_symbol)
        min_amount_out = int(amount_out * (1 - slippage_percent / 100))
        
        # Build transaction
        eth_amount_wei = int(Decimal(eth_amount) * Decimal(10**18))
        deadline = int(time.time()) + 300  # 5 minutes
        
        transaction = router.functions.swapExactETHForTokens(
            min_amount_out,
            [self.contract_addresses['WETH'], token_address],
            self.account.address,
            deadline
        ).build_transaction({
            'from': self.account.address,
            'value': eth_amount_wei,
            'gas': self.gas_limit,
            'gasPrice': self.gas_price,
            'nonce': self.w3.eth.get_transaction_count(self.account.address)
        })
        
        # Sign and send transaction
        signed_txn = self.w3.eth.account.sign_transaction(transaction, self.account.key)
        tx_hash = self.w3.eth.send_raw_transaction(signed_txn.rawTransaction)
        
        # Wait for confirmation
        receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
        
        if receipt.status == 1:
            logger.info(f"ETH swapped for {token_symbol}: {tx_hash.hex()}")
            return tx_hash.hex()
        else:
            raise Exception("Transaction failed")
    
    def swap_tokens_for_eth(self, token_symbol, token_amount, slippage_percent=1):
        """
        Swap tokens for ETH on Uniswap
        
        Args:
            token_symbol: Token symbol to swap
            token_amount: Amount of tokens to swap
            slippage_percent: Maximum slippage percentage
        
        Returns:
            Transaction hash
        """
        if not self.account:
            raise ValueError("No account configured")
        
        if token_symbol not in self.contract_addresses:
            raise ValueError(f"Unknown token: {token_symbol}")
        
        router = self.contracts['UNISWAP_ROUTER']
        token_address = self.contract_addresses[token_symbol]
        
        # Approve token spending
        self.approve_token(token_symbol, self.contract_addresses['UNISWAP_ROUTER'], token_amount)
        
        # Calculate minimum amount out with slippage
        amount_out = self.get_swap_amount_out(token_amount, token_symbol, 'ETH')
        min_amount_out = int(amount_out * (1 - slippage_percent / 100))
        
        # Build transaction
        decimals = self.get_token_decimals(token_symbol)
        token_amount_wei = int(Decimal(token_amount) * Decimal(10**decimals))
        deadline = int(time.time()) + 300  # 5 minutes
        
        transaction = router.functions.swapExactTokensForTokens(
            token_amount_wei,
            min_amount_out,
            [token_address, self.contract_addresses['WETH']],
            self.account.address,
            deadline
        ).build_transaction({
            'from': self.account.address,
            'gas': self.gas_limit,
            'gasPrice': self.gas_price,
            'nonce': self.w3.eth.get_transaction_count(self.account.address)
        })
        
        # Sign and send transaction
        signed_txn = self.w3.eth.account.sign_transaction(transaction, self.account.key)
        tx_hash = self.w3.eth.send_raw_transaction(signed_txn.rawTransaction)
        
        # Wait for confirmation
        receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
        
        if receipt.status == 1:
            logger.info(f"{token_symbol} swapped for ETH: {tx_hash.hex()}")
            return tx_hash.hex()
        else:
            raise Exception("Transaction failed")
    
    def get_swap_amount_out(self, amount_in, token_in, token_out):
        """
        Calculate amount out for swap (simplified)
        
        Args:
            amount_in: Amount to swap
            token_in: Input token symbol
            token_out: Output token symbol
        
        Returns:
            Expected amount out
        """
        # This is a simplified calculation
        # In production, you would query the actual pool reserves
        
        # Example exchange rates (would be fetched from DEX)
        exchange_rates = {
            ('ETH', 'USDC'): 2000,  # 1 ETH = 2000 USDC
            ('ETH', 'DAI'): 2000,    # 1 ETH = 2000 DAI
            ('USDC', 'ETH'): 0.0005, # 1 USDC = 0.0005 ETH
            ('DAI', 'ETH'): 0.0005,  # 1 DAI = 0.0005 ETH
        }
        
        rate = exchange_rates.get((token_in, token_out))
        if rate is None:
            raise ValueError(f"No exchange rate for {token_in} -> {token_out}")
        
        return Decimal(amount_in) * Decimal(rate)
    
    def add_liquidity(self, token_symbol, token_amount, eth_amount):
        """
        Add liquidity to Uniswap pool
        
        Args:
            token_symbol: Token symbol to add
            token_amount: Amount of tokens to add
            eth_amount: Amount of ETH to add
        
        Returns:
            Transaction hash
        """
        if not self.account:
            raise ValueError("No account configured")
        
        # This would implement actual Uniswap liquidity addition
        # For now, it's a placeholder
        logger.info(f"Adding liquidity: {token_amount} {token_symbol} + {eth_amount} ETH")
        
        # In production, you would:
        # 1. Approve token spending
        # 2. Call Uniswap router's addLiquidityETH function
        # 3. Handle transaction and receipt
        
        return "0xplaceholder"
    
    def remove_liquidity(self, token_symbol, liquidity_amount):
        """
        Remove liquidity from Uniswap pool
        
        Args:
            token_symbol: Token symbol of the pool
            liquidity_amount: Amount of liquidity tokens to remove
        
        Returns:
            Transaction hash
        """
        if not self.account:
            raise ValueError("No account configured")
        
        # This would implement actual Uniswap liquidity removal
        logger.info(f"Removing liquidity: {liquidity_amount} from {token_symbol} pool")
        
        # In production, you would:
        # 1. Call Uniswap router's removeLiquidityETH function
        # 2. Handle transaction and receipt
        
        return "0xplaceholder"
    
    def get_portfolio_value(self, address=None):
        """
        Calculate total portfolio value in USD
        
        Args:
            address: Address to calculate for (default: current account)
        
        Returns:
            Portfolio value in USD
        """
        if address is None:
            if not self.account:
                raise ValueError("No account specified")
            address = self.account.address
        
        # Get balances
        eth_balance = self.get_balance('ETH', address)
        usdc_balance = self.get_balance('USDC', address)
        dai_balance = self.get_balance('DAI', address)
        
        # Calculate USD value (simplified)
        # In production, you would fetch real prices from oracles
        eth_price_usd = 2000  # Example price
        dai_price_usd = 1.0    # DAI is pegged to USD
        
        portfolio_value = (
            eth_balance * eth_price_usd +
            usdc_balance +
            dai_balance * dai_price_usd
        )
        
        return {
            'total_value_usd': portfolio_value,
            'breakdown': {
                'ETH': {'amount': eth_balance, 'value_usd': eth_balance * eth_price_usd},
                'USDC': {'amount': usdc_balance, 'value_usd': usdc_balance},
                'DAI': {'amount': dai_balance, 'value_usd': dai_balance * dai_price_usd}
            }
        }
    
    def monitor_gas_prices(self):
        """
        Monitor current gas prices
        
        Returns:
            Current gas price in Gwei
        """
        gas_price_wei = self.w3.eth.gas_price
        gas_price_gwei = gas_price_wei / 10**9
        
        return {
            'gas_price_wei': gas_price_wei,
            'gas_price_gwei': gas_price_gwei,
            'estimated_eth_cost': gas_price_wei * self.gas_limit / 10**18
        }
    
    def execute_arbitrage(self, token_symbol, min_profit_percent=1):
        """
        Execute arbitrage opportunity (simplified)
        
        Args:
            token_symbol: Token to arbitrage
            min_profit_percent: Minimum profit percentage required
        
        Returns:
            Transaction hash if arbitrage executed
        """
        # This is a simplified arbitrage implementation
        # In production, you would:
        # 1. Monitor prices across multiple DEXs
        # 2. Calculate profit opportunities
        # 3. Execute trades when profitable
        
        logger.info(f"Checking arbitrage opportunities for {token_symbol}")
        
        # Example: Check price difference between two DEXs
        # This is placeholder logic
        price_dex1 = self.get_swap_amount_out(1, 'ETH', token_symbol)
        price_dex2 = self.get_swap_amount_out(1, 'ETH', token_symbol) * 1.02  # 2% difference
        
        profit_percent = ((price_dex2 - price_dex1) / price_dex1) * 100
        
        if profit_percent >= min_profit_percent:
            logger.info(f"Arbitrage opportunity found: {profit_percent:.2f}% profit")
            # Execute arbitrage trades
            return "0xarbitrage_placeholder"
        
        return None

# Usage example
def main():
    """Example usage of DeFi Protocol"""
    
    # Initialize protocol
    provider_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
    private_key = "YOUR_PRIVATE_KEY"  # Be careful with private keys!
    
    protocol = DeFiProtocol(provider_url, private_key)
    
    # Get portfolio value
    portfolio = protocol.get_portfolio_value()
    print(f"Portfolio Value: ${portfolio['total_value_usd']:.2f}")
    
    # Check gas prices
    gas_info = protocol.monitor_gas_prices()
    print(f"Gas Price: {gas_info['gas_price_gwei']:.2f} Gwei")
    
    # Swap ETH for USDC
    try:
        tx_hash = protocol.swap_eth_for_tokens(0.1, 'USDC', slippage_percent=1)
        print(f"Swap transaction: {tx_hash}")
    except Exception as e:
        print(f"Swap failed: {e}")
    
    # Check for arbitrage opportunities
    arbitrage_tx = protocol.execute_arbitrage('USDC', min_profit_percent=1)
    if arbitrage_tx:
        print(f"Arbitrage executed: {arbitrage_tx}")

if __name__ == "__main__":
    main()

Web3 Architektur

DeFi Ecosystem

graph TD
    A[User] --> B[Wallet]
    B --> C[DApp Frontend]
    C --> D[Web3.js/Ethers.js]
    D --> E[Smart Contracts]
    
    E --> F[DeFi Protocols]
    F --> G[DEX]
    F --> H[Lending]
    F --> I[Yield Farming]
    F --> J[Liquidity Pools]
    
    E --> K[Blockchain]
    K --> L[Ethereum]
    K --> M[Polygon]
    K --> N[BSC]
    
    O[Oracles] --> E
    P[Chainlink] --> O
    Q[Band Protocol] --> O
    
    R[Governance] --> E
    S[DAO] --> R
    T[Token Holders] --> R

Smart Contract Security

Common Vulnerabilities

VulnerabilityBeschreibungSchutzmaßnahme
ReentrancyRecursive calls before state updateReentrancyGuard, Checks-Effects-Interactions
Integer OverflowArithmetic overflow/underflowSafeMath, Solidity 0.8+
Access ControlUnauthorized function callsModifiers, Role-based access
Front-RunningTransaction order manipulationCommit-reveal schemes
Oracle ManipulationPrice feed manipulationDecentralized oracles

DeFi Protocols Vergleich

Leading DeFi Categories

KategorieProtokolleFunktionTVL (Billion $)
DEXUniswap, SushiSwapToken Swaps25+
LendingAave, CompoundKredite20+
YieldYearn, HarvestYield Optimization10+
DerivativesSynthetix, PerpetualDerivatives5+
OracleChainlink, BandPrice Feeds15+

Vorteile und Nachteile

Vorteile von Web3/DeFi

  • Dezentralisierung: Keine zentrale Instanz erforderlich
  • Transparenz: Alle Transaktionen sind öffentlich sichtbar
  • Permissionless: Jeder kann teilnehmen ohne Genehmigung
  • Programmierbarkeit: Smart Contracts ermöglichen komplexe Logik
  • Composability: Protokolle können kombiniert werden

Nachteile

  • Skalierbarkeit: Begrenzte Transaktionsdurchsatz
  • Gas Fees: Hohe Transaktionskosten bei Netzwerklast
  • User Experience: Komplexe Wallet-Integration
  • Security Risks: Smart Contract Vulnerabilities
  • Regulatory Uncertainty: Ungewisse regulatorische Lage

Häufige Prüfungsfragen

  1. Was ist der Unterschied zwischen Web2 und Web3? Web2 ist zentralisiert mit Servern, Web3 ist dezentralisiert mit Blockchain und Smart Contracts.

  2. Erklären Sie Smart Contracts! Smart Contracts sind selbstausführende Verträge auf der Blockchain, die Business Logic ohne Zwischenhändler ausführen.

  3. Wann verwendet man DeFi Protokolle? DeFi Protokolle werden für dezentrale Finanzdienstleistungen wie Trading, Lending und Yield Farming verwendet.

  4. Was sind die Hauptvorteile von Blockchain? Dezentralisierung, Transparenz, Unveränderlichkeit und Sicherheit durch Kryptographie.

Wichtigste Quellen

  1. https://ethereum.org/
  2. https://docs.soliditylang.org/
  3. https://uniswap.org/
  4. https://aave.com/
Zurück zum Blog
Share:

Ähnliche Beiträge