İçeriği Atla

Kendimize ait bağımsız bir blockchain ağı ve cripto coin örneği

Kendimize ait bağımsız bir blockchain ağı ve cripto coin örneği

Bağımsız Blockchain Ağı Kurulumu

Bağımsız bir coin geliştirmek için yeni bir blockchain ağı oluşturacağız. Bunun için aşağıdaki adımları kullanacağız:

Kullanılacak Teknolojiler:

  • C++: Performans ve güvenlik için.
  • P2P Ağ Protokolü: Blockchain'in dağıtık çalışması için.
  • LevelDB veya RocksDB: Veri saklama çözümü olarak.
  • RPC Sunucusu: Cüzdan ve node bağlantısı için.

Genesis Block ve Konsensüs Mekanizması

Bir blockchain’in başlangıç noktası olan Genesis Block'u ve madencilik için bir Proof of Work (PoW) mekanizması kuracağız. PoW algoritmasını özelleştireceğiz.

Kullanılacak Hash Algoritmaları:

  1. SHA-256: Bitcoin’de kullanılan en güvenilir hash algoritmasıdır.
  2. Blake2b: Yüksek performanslı ve güvenli bir hash algoritması.
  3. Keccak (SHA-3): Ethereum’un temel algoritmasıdır.

Bu üç algoritmanın çıktısını birbirine zincirleyerek daha güçlü ve benzersiz bir hash fonksiyonu oluşturacağız.

Örnek main.cpp Kodu (Bağımsız Blockchain için)

#include <iostream>
#include <string>
#include <openssl/sha.h>
#include <leveldb/db.h>


// Genesis block
struct Block {
    std::string prevHash;
    std::string data;
    std::string hash;
};


// SHA-256 + Blake2b + Keccak kombinasyonu
std::string hashFunction(const std::string& input) {
    unsigned char sha256[SHA256_DIGEST_LENGTH];
    SHA256(reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), sha256);


    // Blake2b
    unsigned char blake2b[64];
    BLAKE2b(blake2b, sha256, nullptr, 64, nullptr, 0);


    // Keccak
    unsigned char keccak[64];
    Keccak(keccak, 64, blake2b, 64);


    std::string finalHash(reinterpret_cast<char*>(keccak), 64);
    return finalHash;
}


// Genesis block creation
Block createGenesisBlock() {
    Block genesis;
    genesis.prevHash = "0";
    genesis.data = "Initial Block";
    genesis.hash = hashFunction(genesis.data);
    return genesis;
}


int main() {
    Block genesis = createGenesisBlock();
    std::cout << "Genesis Block Hash: " << genesis.hash << std::endl;
    return 0;
}

Akıllı Sözleşme ve Güvenlik Önlemleri

Akıllı sözleşmeyi Solidity ile yazacağız ve aşağıdaki güvenlik önlemlerini uygulayacağız:

  1. Reentrancy Koruması: Fonksiyonlar arasında çağrı döngüsü oluşmasını önleyeceğiz.
  2. Overflow ve Underflow Koruması: Solidity’nin SafeMath kütüphanesi ile veya Solidity ^0.8.x kullanarak.
  3. Access Control: Yalnızca yetkili kişilerin belirli işlevlere erişimini sağlayacağız.

Örnek ERC-20 Akıllı Sözleşme Kodu (Güvenlik Önlemleri ile)

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


import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";


contract CustomCoin is Ownable {
    using SafeMath for uint256;


    string public name = "CustomCoin";
    string public symbol = "CCN";
    uint8 public decimals = 18;
    uint256 public totalSupply;


    mapping(address => uint256) private balances;
    mapping(address => mapping(address => uint256)) private allowances;


    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);


    constructor(uint256 initialSupply) {
        totalSupply = initialSupply;
        balances[msg.sender] = initialSupply;
    }


    function balanceOf(address account) public view returns (uint256) {
        return balances[account];
    }


    function transfer(address to, uint256 amount) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(balances[msg.sender] >= amount, "Insufficient balance");


        balances[msg.sender] = balances[msg.sender].sub(amount);
        balances[to] = balances[to].add(amount);


        emit Transfer(msg.sender, to, amount);
        return true;
    }


    function approve(address spender, uint256 amount) public returns (bool) {
        require(spender != address(0), "Invalid address");
        allowances[msg.sender][spender] = amount;


        emit Approval(msg.sender, spender, amount);
        return true;
    }


    function transferFrom(address from, address to, uint256 amount) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(balances[from] >= amount, "Insufficient balance");
        require(allowances[from][msg.sender] >= amount, "Allowance exceeded");


        balances[from] = balances[from].sub(amount);
        balances[to] = balances[to].add(amount);
        allowances[from][msg.sender] = allowances[from][msg.sender].sub(amount);


        emit Transfer(from, to, amount);
        return true;
    }
}

Node ve P2P Ağ Protokolü

Bu kısım, blockchain'inizin node'larının birbirleriyle iletişim kurmasını sağlar.

Kullanılacak Teknolojiler:

  • Python: Node oluşturmak ve cüzdan ile iletişim kurmak için.
  • Flask: API hizmeti sağlamak için.
  • WebSocket: Gerçek zamanlı P2P iletişimi sağlamak için.

Node.py (Blockchain Node)

import hashlib
import json
from time import time
from flask import Flask, jsonify, request
from uuid import uuid4
from urllib.parse import urlparse


class Blockchain:
    def __init__(self):
        self.chain = []
        self.transactions = []
        self.nodes = set()


        # Genesis block
        self.new_block(previous_hash='1', proof=100)


    def register_node(self, address):
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)


    def new_block(self, proof, previous_hash=None):
        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'transactions': self.transactions,
            'proof': proof,
            'previous_hash': previous_hash or self.hash(self.chain[-1]),
        }
        self.transactions = []
        self.chain.append(block)
        return block


    def new_transaction(self, sender, recipient, amount):
        self.transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })
        return self.last_block['index'] + 1


    @staticmethod
    def hash(block):
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()


    @property
    def last_block(self):
        return self.chain[-1]


app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', '')


blockchain = Blockchain()


@app.route('/mine', methods=['GET'])
def mine():
    last_block = blockchain.last_block
    proof = proof_of_work(last_block)


    blockchain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )


    block = blockchain.new_block(proof)
    response = {
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    }
    return jsonify(response), 200


@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    values = request.get_json()
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return 'Missing values', 400


    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    response = {'message': f'Transaction will be added to Block {index}'}
    return jsonify(response), 201


@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain),
    }
    return jsonify(response), 200


def proof_of_work(last_block):
    last_proof = last_block['proof']
    last_hash = blockchain.hash(last_block)
    proof = 0
    while not valid_proof(last_proof, proof, last_hash):
        proof += 1
    return proof


def valid_proof(last_proof, proof, last_hash):
    guess = f'{last_proof}{proof}{last_hash}'.encode()
    guess_hash = hashlib.sha256(guess).hexdigest()
    return guess_hash[:4] == "0000"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Wallet.py (Cüzdan Uygulaması)

Bu cüzdan uygulaması, kullanıcıların adresler oluşturmasını ve blockchain ağına bağlanmasını sağlar.

import hashlib
import json
import requests
from ecdsa import SigningKey, SECP256k1


class Wallet:
    def __init__(self):
        self.private_key = SigningKey.generate(curve=SECP256k1)
        self.public_key = self.private_key.get_verifying_key()


    def get_address(self):
        return hashlib.sha256(self.public_key.to_string()).hexdigest()


    def sign_transaction(self, transaction):
        transaction_json = json.dumps(transaction, sort_keys=True).encode()
        signature = self.private_key.sign(transaction_json)
        return signature


    def send_transaction(self, node_address, recipient, amount):
        transaction = {
            'sender': self.get_address(),
            'recipient': recipient,
            'amount': amount,
        }
        signature = self.sign_transaction(transaction)


        response = requests.post(f'{node_address}/transactions/new', json={
            'transaction': transaction,
            'signature': signature.hex(),
        })


        return response.json()


# Kullanıcı adresi oluşturma
wallet = Wallet()
print("Your Wallet Address:", wallet.get_address())

Access Control ve Güvenlik Önlemleri

  1. Reentrancy Protection:
  • Flask API üzerinde cüzdan işlemleri tekil olarak işlenir, dolayısıyla döngüsel çağrı yapılamaz.
  1. Transaction Signature Verification:
  • Cüzdan tarafından yapılan her işlem, imza doğrulaması ile kontrol edilir.
  1. Secure Node Communication:
  • WebSocket kullanarak node'lar arasında gerçek zamanlı ve güvenli veri aktarımı sağlanır.


Bir blockchain explorer, kullanıcıların blockchain ağı üzerinde gerçekleşen işlemleri, blokları ve hesap bakiyelerini görmesini sağlayan bir web tabanlı uygulamadır. Bu explorer uygulaması, Node.js (Express) ve React kullanarak hem backend hem de frontend entegrasyonunu içerir.


Adım 1: Backend API (Node.js - Express)

Bu kısım, blockchain verilerini almak için bir REST API sağlar. Blockchain node'umuzla iletişim kurar ve bloklar, işlemler ve hesap bilgilerini frontend'e gönderir.

Proje Yapısı

blockchain-explorer
├── backend
│   ├── app.js
│   └── routes
│       └── explorerRoutes.js
└── frontend
    └── src
        └── components
            └── Explorer.js

Backend: app.js

Backend API için Express kullanıyoruz. Bu API, blockchain node'una bağlanarak blok verilerini alır.

const express = require('express');
const axios = require('axios');
const app = express();
const port = 3001;


// Blockchain Node URL
const NODE_URL = 'http://localhost:5000';


// Route: Get all blocks
app.get('/api/blocks', async (req, res) => {
    try {
        const response = await axios.get(`${NODE_URL}/chain`);
        res.json(response.data);
    } catch (error) {
        res.status(500).json({ error: 'Unable to fetch blocks' });
    }
});


// Route: Get a specific block by index
app.get('/api/blocks/:index', async (req, res) => {
    const { index } = req.params;
    try {
        const response = await axios.get(`${NODE_URL}/chain`);
        const block = response.data.chain.find(block => block.index == index);
        if (block) {
            res.json(block);
        } else {
            res.status(404).json({ error: 'Block not found' });
        }
    } catch (error) {
        res.status(500).json({ error: 'Unable to fetch block' });
    }
});


// Route: Get account balance
app.get('/api/balance/:address', async (req, res) => {
    const { address } = req.params;
    try {
        const response = await axios.get(`${NODE_URL}/chain`);
        let balance = 0;


        response.data.chain.forEach(block => {
            block.transactions.forEach(transaction => {
                if (transaction.recipient === address) balance += transaction.amount;
                if (transaction.sender === address) balance -= transaction.amount;
            });
        });


        res.json({ address, balance });
    } catch (error) {
        res.status(500).json({ error: 'Unable to fetch balance' });
    }
});


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

Adım 2: Frontend (React)

Frontend kısmı, API'den gelen verileri kullanıcıya gösterir. React ile blokların ve işlemlerin listesini oluşturacağız.

import React, { useEffect, useState } from 'react';
import axios from 'axios';


function Explorer() {
    const [blocks, setBlocks] = useState([]);
    const [loading, setLoading] = useState(true);


    useEffect(() => {
        async function fetchBlocks() {
            try {
                const response = await axios.get('http://localhost:3001/api/blocks');
                setBlocks(response.data.chain);
                setLoading(false);
            } catch (error) {
                console.error('Error fetching blocks:', error);
                setLoading(false);
            }
        }
        fetchBlocks();
    }, []);


    if (loading) return <p>Loading blocks...</p>;


    return (
        <div>
            <h1>Blockchain Explorer</h1>
            {blocks.map(block => (
                <div key={block.index} style={{ border: '1px solid #ccc', padding: '10px', margin: '10px 0' }}>
                    <h3>Block #{block.index}</h3>
                    <p><strong>Timestamp:</strong> {new Date(block.timestamp * 1000).toLocaleString()}</p>
                    <p><strong>Previous Hash:</strong> {block.previous_hash}</p>
                    <p><strong>Hash:</strong> {block.hash}</p>
                    <p><strong>Transactions:</strong></p>
                    <ul>
                        {block.transactions.map((tx, idx) => (
                            <li key={idx}>
                                {tx.sender} → {tx.recipient}: {tx.amount} CCN
                            </li>
                        ))}
                    </ul>
                </div>
            ))}
        </div>
    );
}


export default Explorer;



Ek Güvenlik ve Özelleştirmeler

  1. Access Control: API’ye gelen isteklerde JWT kullanarak kimlik doğrulama ekleyiniz.
  2. WebSocket Entegrasyonu: Blok zincirindeki yeni blokları ve işlemleri gerçek zamanlı olarak gösterebilirsiniz.
  3. Explorer UI Geliştirmesi: Daha profesyonel bir görünüm için UI bileşenlerini geliştirebilirsiniz.