← Öğrenmeye Dön

Akıllı Sözleşme Geliştirme

Üretim kalitesinde DeFi akıllı sözleşmeleri geliştirmeye yönelik pratik bir rehber. Modern Solidity kalıplarını, gaz optimizasyonunu, güvenlik en iyi uygulamalarını ve eksiksiz modern frontend Web3 yığınını kapsar.

Modern Solidity En İyi Uygulamaları

Solidity 0.8.24+, bugün herhangi bir yeni DeFi projesi için temel sürümdür. Yerleşik taşma koruması, gaz verimliliği için özel hatalar ve olgun araçlar (Foundry ve Hardhat 3), geliştirici deneyimini iki yıl öncesine göre bile önemli ölçüde iyileştirir.

İyi yapılandırılmış bir sözleşme, savaşta denenmiş OpenZeppelin tabanlarından miras alır: reentrancy koruması için ReentrancyGuard, rol yönetimi için Ownable veya AccessControl ve acil durum devre kesme için Pausable. Her dış fonksiyon girdileri doğrulamalı, zincir dışı indeksleme için olaylar yaymalı ve checks-effects-interactions kalıbını izlemelidir.

Sözleşme yapısı şablonu
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";

contract DeFiProtocol is ReentrancyGuard, Ownable, Pausable {
    mapping(address => uint256) public userDeposits;
    uint256 public totalDeposits;

    // Özel hatalar — gaz açısından verimli (yalnızca 4 baytlık seçici)
    error InsufficientBalance();
    error InvalidAmount();
    error TransferFailed();

    event Deposit(address indexed user, uint256 amount, uint256 timestamp);
    event Withdrawal(address indexed user, uint256 amount, uint256 rewards);

    // OZ v5: the initial owner is a constructor argument
    constructor() Ownable(msg.sender) {}

    function deposit(uint256 amount) external nonReentrant whenNotPaused {
        if (amount == 0) revert InvalidAmount();
        // ... checks-effects-interactions
    }
}

Gaz Optimizasyon Teknikleri

Gaz maliyetleri kullanıcı deneyimini doğrudan etkiler. Her optimizasyon, özellikle Ethereum ana ağında protokolünüzü daha erişilebilir hale getirir. En yüksek etkiye sahip üç teknik özel hatalar, struct paketleme ve güvenli olduğunda unchecked matematiktir.

Özel hatalar require dizelerinin yerini alır ve önemli ölçüde gaz tasarrufu sağlar — tam ABI kodlu bir dize yerine 4 baytlık bir seçici. Struct paketleme, küçük türlere slot israf etmek yerine birden fazla değeri tek bir 32 baytlık depolama slotuna sığdırır. Unchecked bloklar, girdiler zaten doğrulandığında taşma kontrollerini atlar.

Gaz optimizasyon örnekleri
// Özel hatalar vs require dizeleri
// Kötü:  require(amount > 0, "Amount must be greater than zero");
// İyi:   if (amount == 0) revert InvalidAmount();

// Struct paketleme — 3 yerine 2 slot
struct UserInfo {
    uint128 amount;      // 16 bayt ─┐
    uint128 rewardDebt;  // 16 bayt ─┘ slot 1
    bool isActive;       // 1 bayt  ──── slot 2
}

// Taşma imkansız olduğunda unchecked matematik
function calculateReward(uint256 principal, uint256 rate)
    internal pure returns (uint256)
{
    unchecked {
        return principal * rate / 10000;
    }
}

Güvenlik Kalıpları

Güvenlik DeFi'de pazarlık konusu değildir. Tek bir güvenlik açığı milyonları boşaltabilir. Checks-effects-interactions kalıbı ve OpenZeppelin ReentrancyGuard, reentrancy'ye karşı ilk savunma hattıdır. Rol tabanlı izinlerle erişim kontrolü (AccessControl) yetkisiz durum değişikliklerini önler.

Oracle entegrasyonu özel dikkat gerektirir. Her zaman fiyat tazeliğini (bayatlık eşiği) kontrol edin, fiyatın pozitif olduğunu doğrulayın ve oracle arızaları için yedek mantık uygulayın. Chainlink latestRoundData etrafındaki try/catch kalıbı, protokolünüzün tamamen geri dönmek yerine zarif bir şekilde bozulmasını sağlar.

Yedekli oracle entegrasyonu
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract PriceAwareProtocol {
    AggregatorV3Interface internal priceFeed;
    uint256 public constant STALENESS_THRESHOLD = 3600; // 1 saat
    uint256 public fallbackPrice;

    function getPrice() public view returns (uint256) {
        try priceFeed.latestRoundData() returns (
            uint80, int256 price, uint256, uint256 updatedAt, uint80
        ) {
            if (block.timestamp - updatedAt > STALENESS_THRESHOLD)
                return fallbackPrice;
            if (price <= 0) return fallbackPrice;
            return uint256(price);
        } catch {
            return fallbackPrice;
        }
    }
}

DeFi Kalıpları: Likidite Havuzları

Sabit çarpım AMM'si (x * y = k), merkeziyetsiz borsaların temelidir. Bir likidite havuzu iki token tutar ve bunları oranlarına göre fiyatlandırır. Likidite eklemek, katkıda bulunulan paya orantılı LP token basar; takas, çıktıyı değişmez üzerinden hesaplamadan önce bir ücret (genellikle %0,3) uygular.

Aşağıdaki uygulama temel mekaniği gösterir. Üretimde kayma koruması (minimum çıktı miktarları), TWAP oracle'ları, yoğunlaştırılmış likidite aralıkları ve flash-loan'a dirençli fiyatlandırma eklerdiniz.

Basitleştirilmiş AMM takası
function swap(uint256 amountIn, bool aToB) external returns (uint256 amountOut) {
    require(amountIn > 0, "Invalid input amount");

    uint256 reserveIn  = aToB ? reserveA : reserveB;
    uint256 reserveOut = aToB ? reserveB : reserveA;

    // %0,3 ücret uygula
    uint256 amountInWithFee = amountIn * 997;
    amountOut = (amountInWithFee * reserveOut)
              / (reserveIn * 1000 + amountInWithFee);

    require(amountOut > 0, "Insufficient output amount");
    // ... token transfer et, rezervleri güncelle, Swap olayı yay
}

DeFi Kalıpları: Yield Farming

Yield farming, ödül tokenlarını zaman içinde stake edenlere dağıtır. Standart kalıp, küresel bir rewardPerToken biriktiricisini ve her kullanıcının ödenmiş-kadar anlık görüntüsünü izler. Her stake, çekme veya talep işleminde, kullanıcının bakiyesi mevcut ve son görülen biriktirici arasındaki farkla çarpılarak ödüller hesaplanır.

Bu yaklaşım depolama açısından verimlidir (iki eşleme artı birkaç skaler) ve gaz açısından verimlidir (stake eden sayısından bağımsız olarak kullanıcı etkileşimi başına O(1)).

Ödül biriktirici kalıbı
modifier updateReward(address account) {
    rewardPerTokenStored = rewardPerToken();
    lastUpdateTime = block.timestamp;
    if (account != address(0)) {
        rewards[account] = earned(account);
        userRewardPerTokenPaid[account] = rewardPerTokenStored;
    }
    _;
}

function earned(address account) public view returns (uint256) {
    return (balances[account] *
        (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18
        + rewards[account];
}

Frontend Web3 Yığını

Modern DeFi frontend yığını, cüzdan bağlantıları için React 19+, Next.js 15+, wagmi 2.x, viem 2.x ve RainbowKit 2.x etrafında toplanır. TanStack Query, zincir üstü verilerin önbelleğe alınmasını ve yeniden getirilmesini yönetir. Bu kombinasyon, tür güvenli sözleşme okuma ve yazma işlemleri, otomatik zincir değiştirme ve hazır gelen cilalı bir wallet-connect deneyimi sunar.

Projenizi yeniden kullanılabilir UI bileşenleri, Web3'e özgü bileşenler (cüzdan bağlantısı, zincir seçici) ve DeFi protokol bileşenleri (yatırım formları, havuz görünümleri) için ayrı dizinlerle yapılandırın. useContractRead ve useContractWrite gibi özel hook'lar, sözleşme etkileşimlerini temiz bir API arkasında soyutlarken, bir TransactionModal bileşeni kullanıcılara net ilerleme geri bildirimi verir.

wagmi + RainbowKit kurulumu
// lib/wagmi.ts
import { getDefaultConfig } from '@rainbow-me/rainbowkit';
import { mainnet, polygon, arbitrum, base } from 'wagmi/chains';

export const config = getDefaultConfig({
  appName: 'CryptaCore DeFi',
  projectId: 'YOUR_WALLETCONNECT_PROJECT_ID',
  chains: [mainnet, polygon, arbitrum, base],
  ssr: true,
});
TipHer zaman önce bir test ağına dağıtın. Foundry'nin forge script'i ve Hardhat'ın dağıtım çerçevesi, doğrulamayla birlikte çok zincirli dağıtımları destekler. Herhangi bir üretim dağıtımından önce tam test paketinizi bir ana ağ çatalına karşı çalıştırın.