✨ Enhance blockchain
This commit is contained in:
116
SwiftChainCore/Models/Block.swift
Normal file
116
SwiftChainCore/Models/Block.swift
Normal file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user