Skip to content
This repository has been archived by the owner on Oct 28, 2022. It is now read-only.

Add TyzenKit #609

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
34 changes: 34 additions & 0 deletions TyzenKit.swift.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Pod::Spec.new do |s|
s.name = 'TyzenKit.swift'
s.module_name = 'TyzenKit'
s.version = '1.0'
s.summary = 'Tyzen library for Swift.'

s.description = <<-DESC
TyzenKit implements Tyzen protocol in Swift.
DESC

s.homepage = 'https://github.com/horizontalsystems/bitcoin-kit-ios'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Horizontal Systems' => 'hsdao@protonmail.ch' }
s.source = { git: 'https://github.com/horizontalsystems/bitcoin-kit-ios.git', tag: "tyzen-#{s.version}" }
s.social_media_url = 'http://horizontalsystems.io/'

s.ios.deployment_target = '13.0'
s.swift_version = '5'

s.source_files = 'TyzenKit/Classes/**/*'
s.resource_bundle = { 'TyzenKit' => 'TyzenKit/Assets/Checkpoints/*' }

s.requires_arc = true

s.dependency 'BitcoinCore.swift', '~> 0.18'
s.dependency 'OpenSslKit.swift', '~> 1.0'
s.dependency 'Secp256k1Kit.swift', '~> 1.0'
s.dependency 'HdWalletKit.swift', '~> 1.5'

s.dependency 'ObjectMapper', '~> 4.0'
s.dependency 'RxSwift', '~> 5.0'
s.dependency 'BigInt', '~> 5.0'
s.dependency 'GRDB.swift', '~> 5.0'
end
1 change: 1 addition & 0 deletions TyzenKit/Assets/Checkpoints/MainNet-bip44.checkpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
000000fd190d1f1f7685c1873e51cd8f1a543d9f7af17a7fe9a6fa90321b80f8
1 change: 1 addition & 0 deletions TyzenKit/Assets/Checkpoints/MainNet-last.checkpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
000000fd190d1f1f7685c1873e51cd8f1a543d9f7af17a7fe9a6fa90321b80f8
1 change: 1 addition & 0 deletions TyzenKit/Assets/Checkpoints/TestNet-bip44.checkpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
da67b050263323f14b35e9793ff9991366ef8e92fe5f83fb7e2781f9a3fd953b
1 change: 1 addition & 0 deletions TyzenKit/Assets/Checkpoints/TestNet-last.checkpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
da67b050263323f14b35e9793ff9991366ef8e92fe5f83fb7e2781f9a3fd953b
34 changes: 34 additions & 0 deletions TyzenKit/Classes/Core/Kit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Pod::Spec.new do |s|
s.name = 'TyzenKit.swift'
s.module_name = 'TyzenKit'
s.version = '1.0'
s.summary = 'Tyzen library for Swift.'

s.description = <<-DESC
TyzenKit implements Tyzen protocol in Swift.
DESC

s.homepage = 'https://github.com/horizontalsystems/bitcoin-kit-ios'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Horizontal Systems' => 'hsdao@protonmail.ch' }
s.source = { git: 'https://github.com/horizontalsystems/bitcoin-kit-ios.git', tag: "Tyzen-#{s.version}" }
s.social_media_url = 'http://horizontalsystems.io/'

s.ios.deployment_target = '13.0'
s.swift_version = '5'

s.source_files = 'TyzenKit/Classes/**/*'
s.resource_bundle = { 'TyzenKit' => 'TyzenKit/Assets/Checkpoints/*' }

s.requires_arc = true

s.dependency 'BitcoinCore.swift', '~> 0.18'
s.dependency 'OpenSslKit.swift', '~> 1.0'
s.dependency 'Secp256k1Kit.swift', '~> 1.0'
s.dependency 'HdWalletKit.swift', '~> 1.5'

s.dependency 'ObjectMapper', '~> 4.0'
s.dependency 'RxSwift', '~> 5.0'
s.dependency 'BigInt', '~> 5.0'
s.dependency 'GRDB.swift', '~> 5.0'
end
52 changes: 52 additions & 0 deletions TyzenKit/Classes/Core/LegacyDifficultyAdjustmentValidator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import BigInt
import BitcoinCore

class LegacyDifficultyAdjustmentValidator: IBlockChainedValidator {
private let heightInterval: Int
private let targetTimespan: Int
private let maxTargetBits: Int

let difficultyEncoder: IDifficultyEncoder
let blockValidatorHelper: IBlockValidatorHelper

init(encoder: IDifficultyEncoder, blockValidatorHelper: IBlockValidatorHelper, heightInterval: Int, targetTimespan: Int, maxTargetBits: Int) {
difficultyEncoder = encoder
self.blockValidatorHelper = blockValidatorHelper

self.heightInterval = heightInterval
self.targetTimespan = targetTimespan
self.maxTargetBits = maxTargetBits
}

func validate(block: Block, previousBlock: Block) throws {
guard let beforeFirstBlock = blockValidatorHelper.previous(for: previousBlock, count: heightInterval) else {
throw BitcoinCoreErrors.BlockValidation.noPreviousBlock
}

var timespan = previousBlock.timestamp - beforeFirstBlock.timestamp
if (timespan < targetTimespan / 4) {
timespan = targetTimespan / 4
} else if (timespan > targetTimespan * 4) {
timespan = targetTimespan * 4
}

var bigIntDifficulty = difficultyEncoder.decodeCompact(bits: previousBlock.bits)
bigIntDifficulty *= BigInt(timespan)
bigIntDifficulty /= BigInt(targetTimespan)
var newDifficulty = difficultyEncoder.encodeCompact(from: bigIntDifficulty)

// Difficulty hit proof of work limit: newTarget
if newDifficulty > maxTargetBits {
newDifficulty = maxTargetBits
}

guard newDifficulty == block.bits else {
throw BitcoinCoreErrors.BlockValidation.notDifficultyTransitionEqualBits
}
}

func isBlockValidatable(block: Block, previousBlock: Block) -> Bool {
block.height % heightInterval == 0
}

}
36 changes: 36 additions & 0 deletions TyzenKit/Classes/Core/ProofOfWorkValidator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation
import BitcoinCore
import BigInt

class ProofOfWorkValidator: IBlockValidator {
private let hasher: IHasher
private let difficultyEncoder: IDifficultyEncoder

init(hasher: IHasher, difficultyEncoder: IDifficultyEncoder) {
self.hasher = hasher
self.difficultyEncoder = difficultyEncoder
}

private func serializeHeader(block: Block) -> Data {
var data = Data()

data.append(Data(from: UInt32(block.version)))
data += block.previousBlockHash
data += block.merkleRoot
data.append(Data(from: UInt32(block.timestamp)))
data.append(Data(from: UInt32(block.bits)))
data.append(Data(from: UInt32(block.nonce)))

return data
}

func validate(block: Block, previousBlock: Block) throws {
let header = serializeHeader(block: block)
let hash = hasher.hash(data: header)

guard (difficultyEncoder.compactFrom(hash: hash) < block.bits) else {
throw BitcoinCoreErrors.BlockValidation.invalidProofOfWork
}
}

}
12 changes: 12 additions & 0 deletions TyzenKit/Classes/Core/ScryptHasher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import OpenSslKit
import BitcoinCore

class ScryptHasher: IHasher {

init() {}

func hash(data: Data) -> Data {
OpenSslKit.Kit.scrypt(pass: data)
}

}
35 changes: 35 additions & 0 deletions TyzenKit/Classes/Network/MainNet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import BitcoinCore

public class MainNet: INetwork {
public let bundleName = "TyzenKit"

public let pubKeyHash: UInt8 = 0x42
public let privateKey: UInt8 = 0xb0
public let scriptHash: UInt8 = 0x80
public let bech32PrefixPattern: String = "tzn"
public let xPubKey: UInt32 = 0x03b47334
public let xPrivKey: UInt32 = 0x03b473b9
public let magic: UInt32 = 0xfbc0b6db
public let port = 2332
public let coinType: UInt32 = 2
public let sigHash: SigHashType = .bitcoinAll
public var syncableFromApi: Bool = true

public let dnsSeeds = [
"node1.tyzen.io",
"node2.tyzen.io",
"node3.tyzen.io",
"node4.tyzen.io",
"node5.tyzen.io",
"node6.tyzen.io",
"node7.tyzen.io",
"node8.tyzen.io",
"node9.tyzen.io",
"node10.tyzen.io"
]

public let dustRelayTxFee = 3000

public init() {}

}
25 changes: 25 additions & 0 deletions TyzenKit/Classes/Network/TestNet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import BitcoinCore

class TestNet: INetwork {
let bundleName = "TyzenKit"

let pubKeyHash: UInt8 = 0x42
let privateKey: UInt8 = 0xb0
let scriptHash: UInt8 = 0x80
let bech32PrefixPattern: String = "ttzn"
let xPubKey: UInt32 = 0x03ba2f80
let xPrivKey: UInt32 = 0x03ba3005
let magic: UInt32 = 0xfdd2c8f1
let port = 20595
let coinType: UInt32 = 1
let sigHash: SigHashType = .bitcoinAll
var syncableFromApi: Bool = false

let dnsSeeds = [
"testnet1.tyzen.io",
"testnet2.tyzen.io",
"testnet3.tyzen.io",
]

let dustRelayTxFee = 3000 // https://github.com/bitcoin/bitcoin/blob/c536dfbcb00fb15963bf5d507b7017c241718bf6/src/policy/policy.h#L50
}