BitcoinSPV 0.8

BitcoinSPV 0.8

测试已测试
Lang语言 Obj-CObjective C
许可证 GPL-3.0
发布最新版本2018年10月

Davide De Rosa维护。



 
依赖项
OpenSSL-Apple~> 1.1.0i
CocoaLumberjack~> 1.9.2
CocoaAsyncSocket~> 7.3.5
AutoCoding~> 2.2.1
 

  • 作者
  • Davide De Rosa

BitcoinSPV

BitcoinSPV是一个用Objective-C编写的本机比特币SPV(简单支付验证)客户端库,适用于iOS。它方便地支持Bloom过滤器(BIP37)和分层确定性钱包(BIP32)。

BitcoinSPV仍然是实验性的,您现在绝对不希望在生产环境中使用它

结构

该库功能全面,具有高度的粒度来隔离比特币协议的细微部分。许多原子类以 tiny 的步骤组成整个系统,同时将用户从不需要关注的领域解耦,因为文件之间的依赖性保持在最低。

按区域分组

  • 全局

    • 比特币生态系统的常量值。
    • 与比特币无关的特定库设置。
    • 在由库返回的 NSError 对象中找到域和代码。
    • 有用的宏,用于频繁操作。
  • 参数

    • 在这里您可以找到特定于网络的小魔数和参数。
  • 核心

    • 通用二进制数据(序列化/反序列化)(WSBuffer)。
    • 用于所有交易和区块ID、地址、校验和等的哈希(WSHash256WSHash160)。
    • ECDSA密钥包装器,能够导入WIF私钥(WSKeyWSPublicKey)。
    • 脚本,是比特币交易系统的关键部分(WSScript)。
    • 事务家族类可以帮助您解码二进制交易或从输入、输出和密钥构建/签名您的个人交易(WSTransaction)。
    • 地址只是以更简短的方式可视化交易脚本,支持所有标准形式(P2PK,P2PKH,P2SH)(WSAddress)。
    • 对BIP32 HD钱包的大量实现(WSHDKeyring)。
  • 区块链

  • 协议

    • 几乎在这里定义了所有协议消息,每条消息一个类。
    • BIP37定义的布隆过滤器(WSBloomFilter)。
  • 网络

  • 钱包

    • 通用钱包表示。
    • 完全符合BIP32的HD钱包(WSHDWallet)。
  • 货币

    • 帮助进行货币转换的类(WSCurrency)。
    • 比特币货币变体(比特币、毫比特、聪)(《WSBitcoinCurrency》)。
  • Web

    • 借助第三方网络服务完成的有用操作。
    • 提供方的探索类(《WSWebExplorer》)。
    • 股票类和统一价格监控(《WSWebTicker》,《WSWebTickerMonitor》)。
    • 清扫外部私钥(例如,纸钱包),无论是纯文本还是密码加密(BIP38)。
  • BIPS

    • BIP21:“bitcoin:” URL的解析和构建。
    • BIP32:分层确定性钱包。
    • BIP37:快速区块链同步的布隆过滤器。
    • BIP38:密码保护的私钥。
    • BIP39:确定性密钥的助记词。
    • BIP44:确定性钱包的多账户分层。

安装

BitcoinSPV依赖于四个知名的库

由于出色的CocoaPods实用工具,设置很简单。我通常在iOS 7上测试软件,但所有内容都应该在6.x版本上运行良好。

Podfile

添加以下行

pod 'BitcoinSPV', '~> 0.7.1'

并在终端上运行

$ pod install

请注意,CocoaPods的一些最新版本可能会破坏静态链接,除非您从Pods/Pods.*.xcconfig配置文件中删除以下行。

OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)

导入

所有导入均为公开,但是您通常需要的导入是#import "BitcoinSPV.h"

测试

BitcoinSPVTests目标附带一些自动化测试。它们并不完全测试所有库功能(特别是网络区域),但它们确实是为了成功所需。单次失败保证某些内容已损坏。

一些测试将在iPhone模拟器的全局Library/Caches中写入文件。您可以在BitcoinSPVTests子目录下找到它们。

基本用法

熟悉bitcoinj的开发者可能会记得以下代码片段中的某些类名。

创建新钱包

#import "BitcoinSPV.h"

- (void)createWallet
{
    WSParameters *parameters = WSParametersForNetworkType(WSNetworkTypeTestnet3);

    WSSeed *seed = [[WSSeedGenerator sharedInstance] generateRandomSeed];

    // now's the time to backup the seed somewhere, show it to the user etc.

    id<WSBlockStore> store = [[WSMemoryBlockStore alloc] initWithParameters:parameters];
    WSHDWallet *wallet = [[WSHDWallet alloc] initWithParameters:parameters seed:seed];
    WSBlockChainDownloader *downloader = [[WSBlockChainDownloader alloc] initWithStore:store wallet:wallet];
    
    WSPeerGroup *peerGroup = [[WSPeerGroup alloc] initWithParameters:parameters];
    [peerGroup startConnections];
    [peerGroup startDownloadWithDownloader:downloader];

    // strongly retain peer group
    self.peerGroup = peerGroup;
}

恢复现有钱包

#import "BitcoinSPV.h"

- (void)restoreWallet
{
    WSParameters *parameters = WSParametersForNetworkType(WSNetworkTypeTestnet3);

    WSSeed *seed = WSSeedMakeFromISODate(@"enter your bip39 mnemonic seed phrase", @"2014-02-28");

    id<WSBlockStore> store = [[WSMemoryBlockStore alloc] initWithParameters:parameters];
    WSHDWallet *wallet = [[WSHDWallet alloc] initWithParameters:parameters seed:seed];
    WSBlockChainDownloader *downloader = [[WSBlockChainDownloader alloc] initWithStore:store wallet:wallet];
    
    WSPeerGroup *peerGroup = [[WSPeerGroup alloc] initWithParameters:parameters];
    [peerGroup startConnections];
    [peerGroup startDownloadWithDownloader:downloader];

    // strongly retain peer group
    self.peerGroup = peerGroup;
}

概述

网络参数

比特币节点可以运行在三个网络之上

  • 主网络:这是真实世界的网络,其中的币具有真实价值。
  • 测试网络3(Testnet3):测试币非常难以挖掘,但价值微乎其微。存在在线 水龙头(faucets) 以获取测试币。
  • 回归测试网络(Regtest):在regtest网络上挖掘时间微不足道,因此非常适合测试手动构建的区块链。

大多数初始化器依赖于网络参数,您可以使用以下代码获取参考

// networkType must be one of: WSNetworkTypeMain, WSNetworkTypeTestnet3, WSNetworkTypeRegtest

WSParameters *networkParameters = WSParametersForNetworkType(WSNetworkTypeTestnet3);
...

警告:在主网络上运行可能会花费您真实金钱,确保您知道自己在做什么!

助记词

BIP39 提供了关于如何将人类可读短语(助记词)生成用于HD钱包的二进制种子的特殊提示。BitcoinSPV在 WSSeedGenerator 类中实现了BIP39规范,可用于

  • 生成随机助记词。
  • 将助记词转换为二进制数据。
  • 将二进制数据转换为助记词。
  • 从助记词派生关键数据。

然而,在BitcoinSPV中,助记词通常封装在包含助记词首次创建时间的 WSSeed 对象中。通过指定这样的时间(称为“快速追赶时间”),可以显著加快链同步速度,因为首次找到的区块不会包含对我们的钱包相关的交易,可以安全地跳过。

分层确定性钱包

分层确定性钱包在 BIP32 中进行了描述。在BitcoinSPV中,它们是WSHDWallet 类的实例,并从具有可选间隙限制的 WSSeed 对象构建而成(默认为10)。另外,还内部预生成了额外的预览地址集,以防止每次新事务消耗一个新地址时重新加载Bloom过滤器。

值得注意的是,种子助记词是极其敏感的信息——技术上门户可以持有您所有的硬币——因此,它不会通过 [WSWallet saveToPath:] 方法序列化:这意味着您必须将其存储在其他地方,例如密钥链中。助记词将对于以后使用 [WSHDWallet loadFromPath:parameters:seed:] 方法恢复序列化的钱包至关重要。

块存储

实现 WSBlockStore 协议的类负责序列化区块链。目前有一个实现:《WSMemoryBlockStore》。名称本身就非常通俗易懂。

对等组

WSPeerGroup 类包含连接到比特币网络的全部逻辑,是主要的事件通知源。一个组可以同时连接到多个节点,强制限制连接节点的数量并将区块链下载到块存储中。与钱包一起构建时,也会将相关区块和交易转发给钱包。钱包反过来将它们注册并内部更新其历史记录、未使用输出(UTXOs)、确认信息等。

最后但同样重要的是,与网络的关键交互显然是如何发布交易。不出所料,这是通过 publishTransaction: 方法完成的。

洞察力

字节序

比特币结构通常是小端字节序,一个例子后果是交易和区块哈希在十六进制编辑器中的“反转”与我们看到的像 Blockchain.info 这样的网络区块链探索器相比。尽管如此,还是有一些例外,因为网络地址保留了标准的大端字节序。是的,这一切都使得二进制编码非常容易出错。

这就是为什么 BitcoinSPV 将编码内部封装在 WSBufferWSMutableBuffer 类中。使用缓冲区类,你可以安全地读取/写入任意字节或基本结构,如哈希、网络地址、库存等,而不必担心协议字节序。

不变性

BitcoinSPV依赖Grand Central Dispatch,这意味着大部分代码都将在多个队列上运行以实现最佳性能。为了限制整体复杂性,我尽量将可变对象的的使用降到最低。不可变方法大大简化了关键部分,并免费保证了序列化数据的一致性。没有Core Data实体是可变的,区块链相关结构通常也不是。想想看,修改一个已接受的区块甚至违背了协议的初衷。

安全

敏感数据永远不会自动序列化,这样客户端就能通过其他更安全的方式保存它们。例如,HD钱包的交易和地址可以安全地写入文件,而秘密助记符则值得更多注意。您可以将它加密保存在密钥链中,也可以从服务提供商处获取并加解密,甚至可以决定完全不离保存。实际上,在保存助记符安全性方面拥有完全的自由。

已知问题

BitcoinSPV仍然是一个正在进行的项目,最终将经历巨大的修改。还剩下一些基本事物要做,按优先级排序:

  • 构建多重签名交易(支持不完整)。
  • 实现如BIP70/BIP71/BIP72/BIP73所描述的支付协议。
  • 通过跟踪对等信心提高SPV安全性。
  • 支持带静态密钥的基本钱包。
  • 处理Core Data版本

许可

BitcoinSPV遵循GPLv3许可发布。

基本上,那些希望将比特币SPV用于其软件中的人们被迫发布他们的源代码,因为其整个目的在于尽可能使与比特币相关的软件保持透明,以增加信任和社区贡献。

只要遵循这个经验法则,就没有更多的义务,仍然会在致谢中注明会让人感到高兴。

致谢

  • bitcoinj - 最受欢迎的Java比特币库。
  • breadwallet - 针对iOS的开源比特币钱包。
  • bip32.org - 用于JavaScript的确定性钱包。

免责声明

开发者不对因比特币SPV的正常使用或错误造成的金钱损失或任何损害承担责任。自行承担责任。

联系方式

Twitter: @keeshux

网站: davidederosa.com

捐款

BitcoinSPV是免费软件,捐款非常受欢迎。

比特币地址:16w2AWamiH2SS68NYSMDcrbh5MnZ1c5eju