Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kishikawakatsumi committed Feb 5, 2018
1 parent ae7ad48 commit 7026a80
Show file tree
Hide file tree
Showing 90 changed files with 25,911 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "Carthage/Checkouts/KeychainAccess"]
path = Examples/Wallet/Carthage/Checkouts/KeychainAccess
url = https://github.com/kishikawakatsumi/KeychainAccess.git
25 changes: 25 additions & 0 deletions BitcoinKit.podspec
@@ -0,0 +1,25 @@
Pod::Spec.new do |spec|
spec.name = 'BitcoinKit'
spec.version = '0.1.0'
spec.summary = 'Bitcoin protocol toolkit for Swift'
spec.description = <<-DESC
BitcoinKit implements Bitcoin protocol in Swift. It is an implementation of the Bitcoin SPV protocol written (almost) entirely in swift.
```
DESC
spec.homepage = 'https://github.com/kishikawakatsumi/BitcoinKit'
spec.license = { :type => 'Apache 2.0', :file => 'LICENSE' }
spec.author = { 'Kishikawa Katsumi' => 'kishikawakatsumi@mac.com' }
spec.social_media_url = 'https://twitter.com/k_katsumi'

spec.requires_arc = true
spec.source = { git: 'https://github.com/kishikawakatsumi/BitcoinKit.git', tag: "v#{spec.version}" }
spec.source_files = 'BitcoinKit/*.{h,swift}'

spec.pod_target_xcconfig = { 'SWIFT_WHOLE_MODULE_OPTIMIZATION' => 'YES',
'APPLICATION_EXTENSION_API_ONLY' => 'YES' }

spec.ios.deployment_target = '8.0'

spec.preserve_paths = './setup'
spec.prepare_command = 'sh ./setup/build_libraries.sh'
end
560 changes: 560 additions & 0 deletions BitcoinKit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions BitcoinKit.xcodeproj/xcshareddata/xcschemes/BitcoinKit.xcscheme
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "147494C6201F9A29006D1CF8"
BuildableName = "BitcoinKit.framework"
BlueprintName = "BitcoinKit"
ReferencedContainer = "container:BitcoinKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "147494CF201F9A29006D1CF8"
BuildableName = "BitcoinKitTests.xctest"
BlueprintName = "BitcoinKitTests"
ReferencedContainer = "container:BitcoinKit.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "147494C6201F9A29006D1CF8"
BuildableName = "BitcoinKit.framework"
BlueprintName = "BitcoinKit"
ReferencedContainer = "container:BitcoinKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "147494C6201F9A29006D1CF8"
BuildableName = "BitcoinKit.framework"
BlueprintName = "BitcoinKit"
ReferencedContainer = "container:BitcoinKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "147494C6201F9A29006D1CF8"
BuildableName = "BitcoinKit.framework"
BlueprintName = "BitcoinKit"
ReferencedContainer = "container:BitcoinKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
10 changes: 10 additions & 0 deletions BitcoinKit.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions BitcoinKit/Address.swift
@@ -0,0 +1,72 @@
//
// Address.swift
// BitcoinKit
//
// Created by Kishikawa Katsumi on 2018/01/31.
// Copyright © 2018 Kishikawa Katsumi. All rights reserved.
//

import Foundation

/// A Bitcoin address looks like 1MsScoe2fTJoq4ZPdQgqyhgWeoNamYPevy and is derived from an elliptic curve public key
/// plus a set of network parameters.
/// A standard address is built by taking the RIPE-MD160 hash of the public key bytes, with a version prefix and a
/// checksum suffix, then encoding it textually as base58. The version prefix is used to both denote the network for
/// which the address is valid.
public struct Address {
public typealias Base58Check = String

let network: Network

let publicKeyHash: Data
let base58: Base58Check

public init(_ publicKey: PublicKey) {
network = publicKey.network
publicKeyHash = Crypto.sha256ripemd160(publicKey.raw)
base58 = publicKey.toAddress()
}

public init(_ base58: Base58Check) throws {
self.base58 = base58

let raw = Base58.decode(base58)
let checksum = raw.suffix(4)
let pubKeyHash = raw.dropLast(4)
let checksumConfirm = Crypto.sha256sha256(pubKeyHash).prefix(4)
guard checksum == checksumConfirm else {
throw AddressError.invalid
}

let network: Network
let addressPrefix = pubKeyHash[0]
switch addressPrefix {
case Network.mainnet.pubkeyhash:
network = .mainnet
case Network.testnet.pubkeyhash:
network = .testnet
default:
throw AddressError.wrongNetwork
}
self.network = network

self.publicKeyHash = pubKeyHash.dropFirst()
}
}

extension Address : Equatable {
public static func ==(lhs: Address, rhs: Address) -> Bool {
return lhs.network == rhs.network && lhs.publicKeyHash == rhs.publicKeyHash
}
}

extension Address : CustomStringConvertible {
public var description: String {
return base58
}
}

public enum AddressError: Error {
case invalid
case wrongNetwork
}
12 changes: 12 additions & 0 deletions BitcoinKit/BitcoinKit.h
@@ -0,0 +1,12 @@
//
// BitcoinKit.h
// BitcoinKit
//
// Created by Kishikawa Katsumi on 2018/01/30.
// Copyright © 2018 Kishikawa Katsumi. All rights reserved.
//

#import <UIKit/UIKit.h>

FOUNDATION_EXPORT double BitcoinKitVersionNumber;
FOUNDATION_EXPORT const unsigned char BitcoinKitVersionString[];
43 changes: 43 additions & 0 deletions BitcoinKit/BlockChain.swift
@@ -0,0 +1,43 @@
//
// BlockChain.swift
// BitcoinKit
//
// Created by Kishikawa Katsumi on 2018/02/03.
// Copyright © 2018 Kishikawa Katsumi. All rights reserved.
//

import Foundation

public class BlockChain {
let wallet: WalletProtocol
let blockStore: BlockStore

public init(wallet: WalletProtocol, blockStore: BlockStore) {
self.wallet = wallet
self.blockStore = blockStore
}

public func addBlock(_ block: BlockMessage, hash: Data) throws {
try blockStore.addBlock(block, hash: hash)
}

public func addMerkleBlock(_ merkleBlock: MerkleBlockMessage, hash: Data) throws {
try blockStore.addMerkleBlock(merkleBlock, hash: hash)
}

public func addTransaction(_ transaction: Transaction, hash: Data) throws {
try blockStore.addTransaction(transaction, hash: hash)
}

public func calculateBlance() throws -> Int64 {
return try blockStore.calculateBlance(address: Address(wallet.address))
}

public func latestBlockHash() -> Data {
var latestBlockHash: Data?
do {
latestBlockHash = try blockStore.latestBlockHash()
} catch {}
return latestBlockHash ?? wallet.network.checkpoints.last!.hash
}
}

0 comments on commit 7026a80

Please sign in to comment.