Blockchain Grundlagen: Kryptographie, Dezentrale Netzwerke, Smart Contracts & Kryptowährungen
Dieser Beitrag ist eine umfassende Einführung in die Blockchain Grundlagen – inklusive Kryptographie, dezentralen Netzwerken, Smart Contracts und Kryptowährungen mit praktischen Beispielen.
In a Nutshell
Blockchain ist eine dezentrale, unveränderliche Datenbanktechnologie, die durch kryptographische Verfahren die Integrität und Sicherheit von Transaktionen in verteilten Netzwerken gewährleistet.
Kompakte Fachbeschreibung
Blockchain ist eine verteilte Ledger-Technologie, die Daten in Blöcken organisiert und durch kryptographische Hash-Funktionen miteinander verkettet, um eine unveränderliche Kette von Transaktionen zu erstellen.
Kernkomponenten:
Kryptographische Grundlagen
- Hash-Funktionen: SHA-256, Keccak-256 für Integrität
- Digitale Signaturen: ECDSA, Ed25519 für Authentizität
- Public-Key-Infrastruktur: Asymmetrische Verschlüsselung
- Merkle Trees: Effiziente Datenverifikation
Dezentrale Netzwerke
- Peer-to-Peer: Direkte Kommunikation ohne Zentralinstanz
- Konsens-Algorithmen: Proof of Work, Proof of Stake
- Distributed Ledger: Replizierte Datenhaltung
- Network Topology: Mesh-Netzwerke
Smart Contracts
- Automatisierte Verträge: Selbstausführende Vertragslogik
- Ethereum Virtual Machine: Ausführungsumgebung
- Solidity: Programmiersprache für Smart Contracts
- Gas Fees: Transaktionskostenberechnung
Kryptowährungen
- Bitcoin: Erste dezentrale Kryptowährung
- Ethereum: Plattform für Smart Contracts
- Altcoins: Alternative Kryptowährungen
- Stablecoins: Preisstabile Token
Prüfungsrelevante Stichpunkte
- Blockchain: Dezentrale, unveränderliche Datenbanktechnologie
- Kryptographie: Hash-Funktionen, digitale Signaturen, Public-Key
- Dezentrale Netzwerke: P2P, Konsens-Algorithmen, Distributed Ledger
- Smart Contracts: Selbstausführende Verträge, EVM, Solidity
- Kryptowährungen: Bitcoin, Ethereum, Altcoins, Stablecoins
- Mining: Proof of Work, Block-Rewards, Difficulty Adjustment
- Wallets: Private Keys, Public Keys, Address Generation
- Konsens: Byzantine Fault Tolerance, Network Consensus
- IHK-relevant: Moderne dezentrale Technologien und Kryptographie
Kernkomponenten
- Distributed Ledger: Dezentrale Datenhaltung
- Kryptographie: Sicherheitsgrundlagen
- Konsens-Algorithmen: Einigung im Netzwerk
- Smart Contracts: Automatisierte Verträge
- Mining/Validierung: Block-Erstellung
- Wallets: Schlüsselverwaltung
- Transaktionen: Datenübertragung
- Network Layer: Kommunikationsprotokolle
Praxisbeispiele
1. Blockchain Implementation mit JavaScript
// Block structure
class Block {
constructor(index, timestamp, data, previousHash = '') {
this.index = index;
this.timestamp = timestamp;
this.data = data;
this.previousHash = previousHash;
this.hash = this.calculateHash();
this.nonce = 0;
}
calculateHash() {
return SHA256(
this.index +
this.previousHash +
this.timestamp +
JSON.stringify(this.data) +
this.nonce
).toString();
}
mineBlock(difficulty) {
const target = Array(difficulty + 1).join("0");
while (this.hash.substring(0, difficulty) !== target) {
this.nonce++;
this.hash = this.calculateHash();
}
console.log(`Block mined: ${this.hash}`);
}
}
// Blockchain structure
class Blockchain {
constructor() {
this.chain = [this.createGenesisBlock()];
this.difficulty = 2;
this.pendingTransactions = [];
this.miningReward = 100;
}
createGenesisBlock() {
return new Block(0, Date.now(), "Genesis Block", "0");
}
getLatestBlock() {
return this.chain[this.chain.length - 1];
}
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.mineBlock(this.difficulty);
this.chain.push(newBlock);
}
isChainValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
createTransaction(transaction) {
this.pendingTransactions.push(transaction);
}
minePendingTransactions(miningRewardAddress) {
const rewardTx = {
from: null,
to: miningRewardAddress,
amount: this.miningReward
};
const block = new Block(
this.chain.length,
Date.now(),
this.pendingTransactions,
this.getLatestBlock().hash
);
block.mineBlock(this.difficulty);
console.log('Block successfully mined!');
this.chain.push(block);
this.pendingTransactions = [rewardTx];
}
getBalance(address) {
let balance = 0;
for (const block of this.chain) {
for (const trans of block.data) {
if (trans.from === address) {
balance -= trans.amount;
}
if (trans.to === address) {
balance += trans.amount;
}
}
}
return balance;
}
}
// SHA256 implementation
function SHA256(msg) {
// Convert string to bytes
const msgBuffer = new TextEncoder().encode(msg);
// Hash the message
return crypto.subtle.digest('SHA-256', msgBuffer);
}
// Transaction structure
class Transaction {
constructor(fromAddress, toAddress, amount) {
this.fromAddress = fromAddress;
this.toAddress = toAddress;
this.amount = amount;
this.timestamp = Date.now();
}
calculateHash() {
return SHA256(this.fromAddress + this.toAddress + this.amount + this.timestamp);
}
signTransaction(signingKey) {
if (signingKey.getPublic('hex') !== this.fromAddress) {
throw new Error('You cannot sign transactions for other wallets!');
}
const hashTx = this.calculateHash();
const sig = signingKey.sign(hashTx, 'base64');
this.signature = sig;
}
isValid() {
if (this.fromAddress === null) return true;
if (!this.signature || this.signature.length === 0) {
throw new Error('No signature in this transaction');
}
const publicKey = ec.keyFromPublic(this.fromAddress, 'hex');
const hashTx = this.calculateHash();
return publicKey.verify(hashTx, this.signature);
}
}
// Wallet implementation
class Wallet {
constructor() {
const keyPair = ec.genKeyPair();
this.privateKey = keyPair.getPrivate('hex');
this.publicKey = keyPair.getPublic('hex');
}
getPublicKey() {
return this.publicKey;
}
getPrivateKey() {
return this.privateKey;
}
getAddress() {
const hash = SHA256(this.publicKey);
return hash.toString().substring(0, 40);
}
sign(data) {
const key = ec.keyFromPrivate(this.privateKey, 'hex');
const hash = SHA256(data);
return key.sign(hash);
}
verify(data, signature) {
const key = ec.keyFromPublic(this.publicKey, 'hex');
const hash = SHA256(data);
return key.verify(hash, signature);
}
}
// Usage example
const myCoin = new Blockchain();
const walletA = new Wallet();
const walletB = new Wallet();
console.log('Starting the miner...');
myCoin.minePendingTransactions(walletA.getAddress());
console.log(`Balance of walletA is ${myCoin.getBalance(walletA.getAddress())}`);
// Create transactions
const tx1 = new Transaction(walletA.getAddress(), walletB.getAddress(), 100);
tx1.signTransaction(walletA);
myCoin.createTransaction(tx1);
console.log('Starting the miner again...');
myCoin.minePendingTransactions(walletA.getAddress());
console.log(`Balance of walletA is ${myCoin.getBalance(walletA.getAddress())}`);
console.log(`Balance of walletB is ${myCoin.getBalance(walletB.getAddress())}`);
// Verify chain integrity
console.log(`Is chain valid? ${myCoin.isChainValid()}`);
2. Smart Contract mit Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Simple Token Contract
contract SimpleToken {
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(string memory _name, string memory _symbol, uint256 _totalSupply) {
name = _name;
symbol = _symbol;
decimals = 18;
totalSupply = _totalSupply * 10**decimals;
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(_to != address(0), "Invalid address");
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
require(balanceOf[_to] + _value >= balanceOf[_to], "Overflow check");
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_to != address(0), "Invalid address");
require(balanceOf[_from] >= _value, "Insufficient balance");
require(allowance[_from][msg.sender] >= _value, "Insufficient allowance");
require(balanceOf[_to] + _value >= balanceOf[_to], "Overflow check");
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
function mint(address _to, uint256 _value) public returns (bool success) {
require(_to != address(0), "Invalid address");
require(totalSupply + _value >= totalSupply, "Overflow check");
totalSupply += _value;
balanceOf[_to] += _value;
emit Transfer(address(0), _to, _value);
return true;
}
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
require(totalSupply >= _value, "Total supply check");
balanceOf[msg.sender] -= _value;
totalSupply -= _value;
emit Transfer(msg.sender, address(0), _value);
return true;
}
}
// Voting Contract
contract Voting {
struct Candidate {
string name;
uint256 voteCount;
}
struct Voter {
bool hasVoted;
uint256 votedCandidateId;
uint256 weight;
}
address public owner;
string public electionName;
uint256 public votingDeadline;
bool public electionEnded;
mapping(address => Voter) public voters;
Candidate[] public candidates;
event VoteCast(address voter, uint256 candidateId);
event ElectionEnded(string electionName);
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
modifier votingOpen() {
require(!electionEnded, "Election has ended");
require(block.timestamp < votingDeadline, "Voting deadline passed");
_;
}
constructor(string memory _electionName, uint256 _votingDuration) {
owner = msg.sender;
electionName = _electionName;
votingDeadline = block.timestamp + _votingDuration;
electionEnded = false;
}
function addCandidate(string memory _name) public onlyOwner {
candidates.push(Candidate({
name: _name,
voteCount: 0
}));
}
function giveRightToVote(address _voter) public onlyOwner {
voters[_voter].weight = 1;
}
function vote(uint256 _candidateId) public votingOpen {
require(voters[msg.sender].weight > 0, "No voting rights");
require(!voters[msg.sender].hasVoted, "Already voted");
require(_candidateId < candidates.length, "Invalid candidate");
voters[msg.sender].hasVoted = true;
voters[msg.sender].votedCandidateId = _candidateId;
candidates[_candidateId].voteCount += voters[msg.sender].weight;
emit VoteCast(msg.sender, _candidateId);
}
function endElection() public onlyOwner {
require(!electionEnded, "Election already ended");
electionEnded = true;
emit ElectionEnded(electionName);
}
function getWinner() public view returns (string memory winnerName, uint256 winnerVotes) {
require(electionEnded, "Election not ended yet");
uint256 maxVotes = 0;
uint256 winnerIndex = 0;
for (uint256 i = 0; i < candidates.length; i++) {
if (candidates[i].voteCount > maxVotes) {
maxVotes = candidates[i].voteCount;
winnerIndex = i;
}
}
return (candidates[winnerIndex].name, maxVotes);
}
function getCandidateCount() public view returns (uint256) {
return candidates.length;
}
function getCandidate(uint256 _index) public view returns (string memory, uint256) {
require(_index < candidates.length, "Invalid candidate index");
return (candidates[_index].name, candidates[_index].voteCount);
}
}
// Escrow Contract
contract Escrow {
enum State { AWAITING_PAYMENT, AWAITING_DELIVERY, COMPLETED, REFUNDED }
address public buyer;
address public seller;
address public arbiter;
uint256 public amount;
uint256 public fee;
State public currentState;
modifier inState(State _state) {
require(currentState == _state, "Invalid state for this operation");
_;
}
modifier onlyBuyer() {
require(msg.sender == buyer, "Only buyer can call this function");
_;
}
modifier onlySeller() {
require(msg.sender == seller, "Only seller can call this function");
_;
}
modifier onlyArbiter() {
require(msg.sender == arbiter, "Only arbiter can call this function");
_;
}
event PaymentReceived(address from, uint256 amount);
event DeliveryConfirmed();
escrowCompleted(uint256 amount);
escrowRefunded(uint256 amount);
constructor(address _seller, address _arbiter, uint256 _fee) {
buyer = msg.sender;
seller = _seller;
arbiter = _arbiter;
fee = _fee;
currentState = State.AWAITING_PAYMENT;
}
function deposit() public payable onlyBuyer inState(State.AWAITING_PAYMENT) {
require(msg.value == amount, "Incorrect amount");
currentState = State.AWAITING_DELIVERY;
emit PaymentReceived(msg.sender, msg.value);
}
function confirmDelivery() public onlyBuyer inState(State.AWAITING_DELIVERY) {
currentState = State.COMPLETED;
uint256 sellerAmount = amount - fee;
payable(seller).transfer(sellerAmount);
payable(arbiter).transfer(fee);
emit DeliveryConfirmed();
emit escrowCompleted(amount);
}
function refundBuyer() public onlyArbiter inState(State.AWAITING_DELIVERY) {
currentState = State.REFUNDED;
payable(buyer).transfer(amount);
emit escrowRefunded(amount);
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
function getState() public view returns (string memory) {
if (currentState == State.AWAITING_PAYMENT) return "AWAITING_PAYMENT";
if (currentState == State.AWAITING_DELIVERY) return "AWAITING_DELIVERY";
if (currentState == State.COMPLETED) return "COMPLETED";
if (currentState == State.REFUNDED) return "REFUNDED";
return "UNKNOWN";
}
}
// Decentralized Autonomous Organization (DAO)
contract DAO {
struct Proposal {
string description;
uint256 amount;
address recipient;
uint256 votesFor;
uint256 votesAgainst;
uint256 deadline;
bool executed;
mapping(address => bool) hasVoted;
}
address public owner;
uint256 public votingPeriod;
uint256 public quorum;
mapping(uint256 => Proposal) public proposals;
mapping(address => uint256) public shares;
uint256 public totalShares;
uint256 public proposalCount;
event ProposalCreated(uint256 proposalId, string description, uint256 amount);
event VoteCast(address voter, uint256 proposalId, bool inFavor);
event ProposalExecuted(uint256 proposalId);
modifier onlyShareholder() {
require(shares[msg.sender] > 0, "Only shareholders can vote");
_;
}
constructor(uint256 _votingPeriod, uint256 _quorum) {
owner = msg.sender;
votingPeriod = _votingPeriod;
quorum = _quorum;
}
function addShareholder(address _shareholder, uint256 _shares) public {
require(msg.sender == owner, "Only owner can add shareholders");
require(_shares > 0, "Shares must be greater than 0");
if (shares[_shareholder] == 0) {
totalShares += _shares;
} else {
totalShares += _shares - shares[_shareholder];
}
shares[_shareholder] = _shares;
}
function createProposal(string memory _description, uint256 _amount, address _recipient) public onlyShareholder {
proposalCount++;
proposals[proposalCount] = Proposal({
description: _description,
amount: _amount,
recipient: _recipient,
votesFor: 0,
votesAgainst: 0,
deadline: block.timestamp + votingPeriod,
executed: false
});
emit ProposalCreated(proposalCount, _description, _amount);
}
function vote(uint256 _proposalId, bool _inFavor) public onlyShareholder {
Proposal storage proposal = proposals[_proposalId];
require(block.timestamp < proposal.deadline, "Voting period ended");
require(!proposal.hasVoted[msg.sender], "Already voted");
require(!proposal.executed, "Proposal already executed");
proposal.hasVoted[msg.sender] = true;
if (_inFavor) {
proposal.votesFor += shares[msg.sender];
} else {
proposal.votesAgainst += shares[msg.sender];
}
emit VoteCast(msg.sender, _proposalId, _inFavor);
}
function executeProposal(uint256 _proposalId) public {
Proposal storage proposal = proposals[_proposalId];
require(block.timestamp >= proposal.deadline, "Voting period not ended");
require(!proposal.executed, "Proposal already executed");
uint256 totalVotes = proposal.votesFor + proposal.votesAgainst;
require(totalVotes >= quorum, "Quorum not reached");
require(proposal.votesFor > proposal.votesAgainst, "Proposal not approved");
proposal.executed = true;
if (address(this).balance >= proposal.amount) {
payable(proposal.recipient).transfer(proposal.amount);
}
emit ProposalExecuted(_proposalId);
}
function deposit() public payable {
// Allow anyone to deposit funds to the DAO
}
function getProposal(uint256 _proposalId) public view returns (
string memory description,
uint256 amount,
address recipient,
uint256 votesFor,
uint256 votesAgainst,
uint256 deadline,
bool executed
) {
Proposal storage proposal = proposals[_proposalId];
return (
proposal.description,
proposal.amount,
proposal.recipient,
proposal.votesFor,
proposal.votesAgainst,
proposal.deadline,
proposal.executed
);
}
function hasVoted(uint256 _proposalId, address _voter) public view returns (bool) {
return proposals[_proposalId].hasVoted[_voter];
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
3. Python Blockchain mit Mining
import hashlib
import json
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
from urllib.parse import urlparse
import requests
class Blockchain:
def __init__(self):
self.chain = []
self.current_transactions = []
self.nodes = set()
# Create the genesis block
self.new_block(previous_hash='1', proof=100)
def new_block(self, proof, previous_hash=None):
"""
Create a new Block in the Blockchain
:param proof: The proof given by the Proof of Work algorithm
:param previous_hash: Hash of previous Block
:return: New Block
"""
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.current_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
# Reset the current list of transactions
self.current_transactions = []
self.chain.append(block)
return block
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: Address of the Sender
:param recipient: Address of the Recipient
:param amount: Amount
:return: The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
@property
def last_block(self):
return self.chain[-1]
@staticmethod
def hash(block):
"""
Creates a SHA-256 hash of a Block
:param block: Block
:return: hash
"""
# We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
def proof_of_work(self, last_proof):
"""
Simple Proof of Work Algorithm:
- Find a number 'p' such that hash(pp') contains leading 4 zeroes
- Where p is the previous Proof, and p' is the new Proof
:param last_proof: Previous Proof
:return: proof
"""
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
@staticmethod
def valid_proof(last_proof, proof):
"""
Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
:param last_proof: Previous Proof
:param proof: Current Proof
:return: True if correct, False if not.
"""
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
def register_node(self, address):
"""
Add a new node to the list of nodes
:param address: Address of node. Eg. 'http://192.168.0.1:5000'
:return: None
"""
parsed_url = urlparse(address)
if parsed_url.netloc:
self.nodes.add(parsed_url.netloc)
elif parsed_url.path:
# Accepts an URL without scheme like '192.168.0.1:5000'.
self.nodes.add(parsed_url.path)
else:
raise ValueError('Invalid URL')
def valid_chain(self, chain):
"""
Determine if a given blockchain is valid
:param chain: A blockchain
:return: True if valid, False if not
"""
last_block = chain[0]
current_index = 1
while current_index < len(chain):
block = chain[current_index]
print(f'{last_block}')
print(f'{block}')
print("\n-----------\n")
# Check that the hash of the block is correct
if block['previous_hash'] != self.hash(last_block):
return False
# Check that the Proof of Work is correct
if not self.valid_proof(last_block['proof'], block['proof']):
return False
last_block = block
current_index += 1
return True
def resolve_conflicts(self):
"""
This is our Consensus Algorithm, it resolves conflicts
by replacing our chain with the longest one in the network.
:return: True if our chain was replaced, False if not
"""
neighbours = self.nodes
new_chain = None
# We're only looking for chains longer than ours
max_length = len(self.chain)
# Grab and verify the chains from all the nodes in our network
for node in neighbours:
response = requests.get(f'http://{node}/chain')
if response.status_code == 200:
length = response.json()['length']
chain = response.json()['chain']
# Check if the length is longer and the chain is valid
if length > max_length and self.valid_chain(chain):
max_length = length
new_chain = chain
# Replace our chain if we discovered a new, valid chain longer than ours
if new_chain:
self.chain = new_chain
return True
return False
# Flask application
app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', '')
# Instantiate the Blockchain
blockchain = Blockchain()
@app.route('/mine', methods=['GET'])
def mine():
# We run the proof of work algorithm to get the next proof...
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
# We must receive a reward for finding the proof.
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
# Forge the new Block by adding it to the chain
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
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()
# Check that the required fields are in the POST'ed data
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return "Missing values", 400
# Create a new Transaction
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
@app.route('/nodes/register', methods=['POST'])
def register_nodes():
values = request.get_json()
nodes = values.get('nodes')
if nodes is None:
return "Error: Please supply a valid list of nodes", 400
for node in nodes:
blockchain.register_node(node)
response = {
'message': 'New nodes have been added',
'total_nodes': list(blockchain.nodes),
}
return jsonify(response), 201
@app.route('/nodes/resolve', methods=['GET'])
def consensus():
replaced = blockchain.resolve_conflicts()
if replaced:
response = {
'message': 'Our chain was replaced',
'new_chain': blockchain.chain
}
else:
response = {
'message': 'Our chain is authoritative',
'chain': blockchain.chain
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
# Cryptographic utilities
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
class CryptoUtils:
@staticmethod
def generate_key_pair():
"""Generate RSA key pair for digital signatures"""
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
return private_key, public_key
@staticmethod
def sign_message(private_key, message):
"""Sign a message with private key"""
signature = private_key.sign(
message.encode('utf-8'),
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return base64.b64encode(signature).decode('utf-8')
@staticmethod
def verify_signature(public_key, message, signature):
"""Verify a signature with public key"""
try:
public_key.verify(
base64.b64decode(signature),
message.encode('utf-8'),
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return True
except:
return False
@staticmethod
def serialize_public_key(public_key):
"""Serialize public key to PEM format"""
return public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
).decode('utf-8')
@staticmethod
def deserialize_public_key(pem_data):
"""Deserialize public key from PEM format"""
return serialization.load_pem_public_key(
pem_data.encode('utf-8'),
backend=default_backend()
)
# Wallet implementation
class Wallet:
def __init__(self):
self.private_key, self.public_key = CryptoUtils.generate_key_pair()
self.address = self.generate_address()
def generate_address(self):
"""Generate wallet address from public key"""
public_key_pem = CryptoUtils.serialize_public_key(self.public_key)
address = hashlib.sha256(public_key_pem.encode('utf-8')).hexdigest()
return address[:40] # Use first 40 characters as address
def sign_transaction(self, transaction_data):
"""Sign transaction data"""
transaction_string = json.dumps(transaction_data, sort_keys=True)
return CryptoUtils.sign_message(self.private_key, transaction_string)
def get_address(self):
"""Get wallet address"""
return self.address
def get_public_key(self):
"""Get public key in PEM format"""
return CryptoUtils.serialize_public_key(self.public_key)
# Usage example
if __name__ == "__main__":
# Create wallets
alice_wallet = Wallet()
bob_wallet = Wallet()
print(f"Alice's address: {alice_wallet.get_address()}")
print(f"Bob's address: {bob_wallet.get_address()}")
# Create transaction
transaction = {
'sender': alice_wallet.get_address(),
'recipient': bob_wallet.get_address(),
'amount': 10,
'timestamp': time()
}
# Sign transaction
signature = alice_wallet.sign_transaction(transaction)
print(f"Transaction signature: {signature}")
# Verify signature
alice_public_key = CryptoUtils.deserialize_public_key(alice_wallet.get_public_key())
transaction_string = json.dumps(transaction, sort_keys=True)
is_valid = CryptoUtils.verify_signature(alice_public_key, transaction_string, signature)
print(f"Signature valid: {is_valid}")
Blockchain Architektur
Schichtenmodell
graph TD
A[Application Layer] --> B[Smart Contracts]
B --> C[Virtual Machine]
C --> D[Consensus Layer]
D --> E[Network Layer]
E --> F[Data Layer]
A1[DApps] --> A
A2[Wallets] --> A
A3[Exchanges] --> A
B1[Ethereum] --> B
B2[Solidity] --> B
B3[Gas Fees] --> B
C1[EVM] --> C
C2[WASM] --> C
C3[Bytecode] --> C
D1[PoW] --> D
D2[PoS] --> D
D3[DPoS] --> D
E1[P2P] --> E
E2[Gossip] --> E
E3[RPC] --> E
F1[Blocks] --> F
F2[Merkle Trees] --> F
F3[Hash Chains] --> F
Konsens-Algorithmen
Proof of Work (PoW)
| Eigenschaft | Beschreibung | Energieverbrauch |
|---|---|---|
| Sicherheit | Hoch durch kryptographische Beweise | Sehr Hoch |
| Zentralisierung | Tendenz zur Zentralisierung | Hoch |
| Skalierbarkeit | Begrenzt durch Blockzeit | Niedrig |
| Anwendung | Bitcoin, Ethereum (früher) | Mining |
Proof of Stake (PoS)
| Eigenschaft | Beschreibung | Energieverbrauch |
|---|---|---|
| Sicherheit | Wirtschaftliche Anreize | Gering |
| Zentralisierung | Weniger zentralisiert | Mittel |
| Skalierbarkeit | Besser als PoW | Hoch |
| Anwendung | Ethereum 2.0, Cardano | Staking |
Kryptographische Grundlagen
Hash-Funktionen
# SHA-256 Implementation
import hashlib
def sha256_hash(data):
"""Calculate SHA-256 hash of data"""
return hashlib.sha256(data.encode()).hexdigest()
# Merkle Tree Implementation
class MerkleTree:
def __init__(self, transactions):
self.transactions = transactions
self.tree = self.build_tree()
def build_tree(self):
"""Build Merkle tree from transactions"""
tree = [transactions]
while len(tree[-1]) > 1:
current_level = tree[-1]
next_level = []
for i in range(0, len(current_level), 2):
if i + 1 < len(current_level):
combined = current_level[i] + current_level[i + 1]
next_level.append(sha256_hash(combined))
else:
next_level.append(current_level[i])
tree.append(next_level)
return tree
def get_root(self):
"""Get Merkle root"""
return self.tree[-1][0] if self.tree else None
def verify_proof(self, transaction_hash, proof, root):
"""Verify Merkle proof"""
current_hash = transaction_hash
for proof_element in proof:
if current_hash < proof_element:
combined = current_hash + proof_element
else:
combined = proof_element + current_hash
current_hash = sha256_hash(combined)
return current_hash == root
Digitale Signaturen
# ECDSA Implementation
from ecdsa import SigningKey, VerifyingKey, NIST256p, SECP256k1
class DigitalSignature:
def __init__(self):
self.private_key = SigningKey.generate(SECP256k1)
self.public_key = self.private_key.get_verifying_key()
def sign_message(self, message):
"""Sign message with private key"""
return self.private_key.sign(message.encode())
def verify_signature(self, message, signature):
"""Verify signature with public key"""
try:
self.public_key.verify(signature, message.encode())
return True
except:
return False
def get_public_key_hex(self):
"""Get public key in hex format"""
return self.public_key.to_string().hex()
@staticmethod
def from_public_key_hex(public_key_hex):
"""Create verifier from public key hex"""
public_key = VerifyingKey.from_string(bytes.fromhex(public_key_hex), curve=SECP256k1)
return DigitalSignature.from_public_key(public_key)
Smart Contract Entwicklung
Ethereum Virtual Machine (EVM)
| Komponente | Beschreibung | Funktion |
|---|---|---|
| Bytecode | Kompilierter Smart Contract | Ausführung |
| Gas | Transaktionskosten | Ressourcenlimit |
| Storage | Persistenter Speicher | Datenhaltung |
| Memory | Temporärer Speicher | Berechnungen |
| Stack | Ausführungsstack | Operationen |
Solidity Best Practices
// Secure contract example
pragma solidity ^0.8.0;
contract SecureContract {
// Use latest Solidity version
// Use explicit visibility specifiers
// Implement proper access control
// Handle reentrancy attacks
// Use safe math operations
address private owner;
mapping(address => uint256) private balances;
bool private locked;
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
modifier noReentrant() {
require(!locked, "No reentrancy");
locked = true;
_;
locked = false;
}
modifier safeTransfer(address to, uint256 amount) {
require(to != address(0), "Invalid address");
require(amount > 0, "Amount must be greater than 0");
require(balances[msg.sender] >= amount, "Insufficient balance");
_;
}
constructor() {
owner = msg.sender;
}
function transfer(address to, uint256 amount)
public
safeTransfer(to, amount)
noReentrant
returns (bool)
{
balances[msg.sender] -= amount;
balances[to] += amount;
return true;
}
function getBalance(address account) public view returns (uint256) {
return balances[account];
}
}
Dezentrale Anwendungen (DApps)
Web3.js Integration
// Web3.js for blockchain interaction
const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_PROJECT_ID');
// Contract ABI and address
const contractABI = [...]; // Contract ABI
const contractAddress = '0x...'; // Contract address
// Create contract instance
const contract = new web3.eth.Contract(contractABI, contractAddress);
// Get account balance
async function getBalance(address) {
const balance = await web3.eth.getBalance(address);
return web3.utils.fromWei(balance, 'ether');
}
// Send transaction
async function sendTransaction(from, to, amount, privateKey) {
const nonce = await web3.eth.getTransactionCount(from);
const gasPrice = await web3.eth.getGasPrice();
const tx = {
from: from,
to: to,
value: web3.utils.toWei(amount, 'ether'),
gas: 21000,
gasPrice: gasPrice,
nonce: nonce
};
const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
return receipt;
}
// Interact with smart contract
async function callContract(method, ...args) {
const result = await contract.methods[method](...args).call();
return result;
}
async function sendContractTransaction(method, from, privateKey, ...args) {
const nonce = await web3.eth.getTransactionCount(from);
const gasPrice = await web3.eth.getGasPrice();
const tx = contract.methods[method](...args);
const gas = await tx.estimateGas({ from: from });
const txData = {
from: from,
to: contractAddress,
gas: gas,
gasPrice: gasPrice,
nonce: nonce,
data: tx.encodeABI()
};
const signedTx = await web3.eth.accounts.signTransaction(txData, privateKey);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
return receipt;
}
Kryptowährungs-Typen
Kategorien
| Typ | Beschreibung | Beispiele | Use Cases |
|---|---|---|---|
| Payment Coins | Digitales Geld | Bitcoin, Litecoin | Zahlungen |
| Platform Coins | Smart Contract Plattformen | Ethereum, Solana | DApps |
| Privacy Coins | Anonyme Transaktionen | Monero, Zcash | Datenschutz |
| Stablecoins | Preisstabile Token | USDC, DAI | Stabilität |
| Utility Tokens | Plattform-Nutzung | BNB, LINK | Services |
| Security Tokens | Regulierte Wertpapiere | STOs | Investment |
Mining und Validierung
Mining Prozess
# Mining simulation
import hashlib
import json
import time
class Miner:
def __init__(self, blockchain):
self.blockchain = blockchain
self.mining_reward = 10
def mine_block(self, transactions):
"""Mine a new block"""
last_block = self.blockchain.get_last_block()
proof = self.proof_of_work(last_block.proof)
# Create reward transaction
reward_tx = {
'sender': '0',
'recipient': 'miner_address',
'amount': self.mining_reward
}
transactions.append(reward_tx)
# Create new block
new_block = {
'index': last_block.index + 1,
'timestamp': time.time(),
'transactions': transactions,
'proof': proof,
'previous_hash': self.hash_block(last_block)
}
# Add block to blockchain
self.blockchain.add_block(new_block)
return new_block
def proof_of_work(self, last_proof):
"""Proof of Work algorithm"""
proof = 0
difficulty = 4 # Number of leading zeros
while not self.valid_proof(last_proof, proof, difficulty):
proof += 1
return proof
@staticmethod
def valid_proof(last_proof, proof, difficulty):
"""Validate proof"""
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:difficulty] == '0' * difficulty
@staticmethod
def hash_block(block):
"""Hash a block"""
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
Wallet Management
Hierarchical Deterministic Wallets
# HD Wallet implementation
import hmac
import hashlib
from bip_utils import Bip39MnemonicValidator, Bip39SeedGenerator, Bip44, Bip44Coins, Bip44Changes
class HDWallet:
def __init__(self, mnemonic=None):
if mnemonic is None:
# Generate new mnemonic
self.mnemonic = self.generate_mnemonic()
else:
# Validate existing mnemonic
if not Bip39MnemonicValidator().Validate(mnemonic):
raise ValueError("Invalid mnemonic phrase")
self.mnemonic = mnemonic
# Generate seed from mnemonic
self.seed_bytes = Bip39SeedGenerator(self.mnemonic).Generate()
# Create master key
self.master_key = Bip44.FromSeed(self.seed_bytes, Bip44Coins.BITCOIN)
def generate_mnemonic(self, wordlist='english', strength=128):
"""Generate new mnemonic phrase"""
return Bip39MnemonicValidator().Generate(strength, wordlist)
def get_address(self, account=0, change=0, address_index=0):
"""Generate address from HD path"""
# Derive key from HD path: m/44'/0'/0'/0/0
bip44_obj = self.master_key.Purpose().Coin().Account(account).Change(change).AddressIndex(address_index)
return bip44_obj.Address()
def get_private_key(self, account=0, change=0, address_index=0):
"""Get private key from HD path"""
bip44_obj = self.master_key.Purpose().Coin().Account(account).Change(change).AddressIndex(address_index)
return bip44_obj.PrivateKey().Raw().ToHex()
def get_public_key(self, account=0, change=0, address_index=0):
"""Get public key from HD path"""
bip44_obj = self.master_key.Purpose().Coin().Account(account).Change(change).AddressIndex(address_index)
return bip44_obj.PublicKey().RawCompressed().ToHex()
def get_extended_public_key(self, account=0):
"""Get extended public key for account"""
return self.master_key.Purpose().Coin().Account(account).Public()
def get_extended_private_key(self, account=0):
"""Get extended private key for account"""
return self.master_key.Purpose().Coin().Account(account).Private()
Vorteile und Nachteile
Vorteile von Blockchain
- Dezentralisierung: Keine zentrale Kontrollinstanz
- Unveränderlichkeit: Daten können nicht nachträglich geändert werden
- Transparenz: Alle Transaktionen sind öffentlich einsehbar
- Sicherheit: Kryptographische Sicherheit
- Effizienz: Eliminierung von Intermediären
Nachteile
- Skalierbarkeit: Begrenzte Transaktionsdurchsatz
- Energieverbrauch: Hoher Energieverbrauch bei PoW
- Komplexität: Technische Komplexität
- Regulierung: Unsicherheit bei rechtlicher Behandlung
- Volatilität: Starke Preisschwankungen
Häufige Prüfungsfragen
-
Was ist der Unterschied zwischen Proof of Work und Proof of Stake? PoW verwendet rechenintensive Aufgaben zur Block-Erstellung, PoS verwendet wirtschaftliche Anreize durch Staking von Coins.
-
Erklären Sie die Funktion von Smart Contracts! Smart Contracts sind selbstausführende Verträge, die auf der Blockchain laufen und automatisch Vertragsbedingungen durch Code umsetzen.
-
Wie funktioniert kryptographische Hashing in Blockchain? Jeder Block enthält den Hash des vorherigen Blocks, was eine unveränderliche Kette erstellt. Änderungen würden alle nachfolgenden Hashes ungültig machen.
-
Was ist der Zweck von Mining? Mining sichert das Netzwerk durch Proof of Work, validiert Transaktionen und erstellt neue Blöcke mit Belohnungen.
Wichtigste Quellen
- https://bitcoin.org/
- https://ethereum.org/
- https://solidity.readthedocs.io/
- https://web3js.readthedocs.io/