// // Block.swift // Blockchain // // Created by Victor BODINAUD on 27/02/2020. // Copyright © 2020 Victor BODINAUD. All rights reserved. // internal import CryptoSwift import Foundation public class Block: Codable { var hash: String var transactions: [Transaction] var previousHash: String var index: Int var nonce: Int var timestamp: Int var difficulty: Int var miner: String? enum CodingKeys: String, CodingKey { case hash, transactions, previousHash, index, nonce, timestamp, difficulty, miner } init(hash: String = "", transactions: [Transaction] = [], previousHash: String = "", index: Int = 0, nonce: Int = 0, timestamp: Int = 0, difficulty: Int = 4) { self.hash = hash self.transactions = transactions self.previousHash = previousHash self.index = index self.nonce = nonce self.timestamp = timestamp self.difficulty = difficulty } func mineBlock() -> Double { let startTime = Date() let target = String(repeating: "0", count: difficulty) print("Mining block \(index) with difficulty \(difficulty)...") repeat { nonce += 1 hash = generateHash() } while !hash.hasPrefix(target) let timeElapsed = Date().timeIntervalSince(startTime) print("Block mined! Nonce: \(nonce), Hash: \(hash)") return timeElapsed } func isValid() -> Bool { // Vérification de base du hash let target = String(repeating: "0", count: difficulty) if hash != generateHash() || !hash.hasPrefix(target) { print("Block \(index): Invalid hash") return false } // Vérifier l'index if index < 0 { print("Block: Invalid index") return false } // Vérifier le timestamp let currentTime = Int(Date().timeIntervalSince1970) if timestamp > currentTime + 7200 || timestamp < 1701388800 { // 2h dans le futur max print("Block: Invalid timestamp") return false } // Vérifier les transactions for transaction in transactions { if !transaction.isValid() { print("Block: Invalid transaction found") return false } // Vérifier qu'il n'y a qu'une seule récompense de minage if transaction.type == "MINING_REWARD" { if transactions.filter({ $0.type == "MINING_REWARD" }).count > 1 { print("Block: Multiple mining rewards found") return false } } } return true } func generateHash() -> String { let txData = transactions.map { "\($0.sender)\($0.receiver)\($0.amount)\($0.type)" }.joined() return "\(previousHash)\(txData)\(String(timestamp))\(String(index))\(String(nonce))".sha256() } } // Structure pour suivre la progression du mining struct MiningProgress { let hashesChecked: Int let hashRate: Double let elapsedTime: TimeInterval let estimatedTimeRemaining: TimeInterval? } // Erreurs possibles pendant le mining enum MiningError: Error { case cancelled case failed(String) }