深入分析 Bitcoin 的原理和技术实现

标签: 分析 bitcoin 原理 | 发表时间:2011-06-01 03:09 | 作者:(author unknown) iFunbox
出处:http://www.feedzshare.com/s/t/1

来自: Hippo notes - FeedzShare  
发布时间:2011年05月31日,  已有 9 人推荐


    Bitcoin 是一种虚拟电子货币,上周我写过一篇介绍性质的文章《通俗易懂讲解什么是 Bitcoin 虚拟货币》(http://ivarptr.blogspot.com/2011/05/bitcoin.html),当时主要参考了官方和民间的介绍材料,并没有深入了解 Bitcoin 的技术细节。这篇文章会进一步分析Bitcoin的原理和技术实现方法和细节,其中原理部分主要参考了 Bitcoin 的创始者Satoshi Nakamoto的论文 《Bitcoin: A Peer-to-Peer Electronic Cash System》,Bitcoin 的Wiki,而技术分析部分主要由实践以及阅读源代码 所得。由于 Bitcoin 涉及的技术领域比较多,很多地方我还没法理解或没完全理解,所以如果发现这篇文章的错误,请反馈到这篇文章的原始出处(http://ivarptr.blogspot.com/),(转载此文请保留原始链接)。我会及时补充及更正。@ivarptr
    要了解 Bitcoin 的技术原理,最好的方法是从 Bitcoin 应用程序开始(从这里可以下载),运行之后会看到如图1所示的窗口:


图1:Bitcoin 程序窗口

    窗口上侧的是你的“收款地址”(下面称为Bitcoin地址),这个地址是你第一次运行 Bitcoin 程序时自动创建的,你可以点击“New”按钮重新创建一个或者多个地址,其他人向你的任何一个地址发送Bitcoin币(以下简称 BTC)你都能接收到。Bitcoin地址实质上是一对公私钥(参考 ECDSA)当中的公钥,转帐交易时使用公钥加密信息,只有持有相应私钥的人才能解密,这样就能完成一笔交易了。所以在 Bitcoin 网络中你并不需要在某个网站注册会员帐号,只要产生一对公私钥匙(产生成本是零)就可以跟他人交易了。
    窗口中间的是“交易记录”,显示所有汇入和汇出记录,包括交易被多少人“见证”(后面会讲到)、时间、汇出或接收地址、金额等。第一次运行 Bitcoin 程序时这个列表是空白的。
    窗口最底部的是Bitcoin程序此时跟多少人连接(connection)、下载了多少个数据块(block),以及交易记录的数量。

Bitcoin 程序实际上是一个P2P程序

    成千上万个人运行 Bitcoin 程序并且通过互联网相连,就形成了一个庞大的“Bitcoin网络”。Bitcoin网络不存在服务器、中心节点、管理员,所有运行 Bitcoin 的节点的都平等的,所以跟 eMule、BT类似,Bitcoin也是一个P2P程序。Bitcoin 网络组成如图2所示(画得比较粗糙,见谅):


图2:Bitcoin 网络的组成示意图

    图2当中绿色的表示Bitcoin应用程序,有些网站比如矿场(Mining Pool)和Bitcoin交易网站,其实内部也是运行着Bitcoin应用程序(可能是网站自己开发的程序,并不一定是官方所提供的那个,不过他们遵守共同的通信协议),网站只是在外围增加一些业务逻辑和界面让访客通过网页的形式访问。
    跟eMule和BT不同的是,所有运行Bitcoin 程序的节点只会共享一个内容相同的“文件”(这个说法不严谨,不过好理解一些),这个文件会被分割成许多个小块(称为数据块,下面简称为 block),数据块会不断增长,大概每10分钟增加一个数据块,目前 Bitcoin 网络上这个大家所共享的“文件”大概由12万个数据块组成。只有当你的 Bitcoin 程序下载完所有这些数据块才进入正常的工作状态,所以首次运行 Bitcoin 你需要等待一段时间。

Bitcoin 共享的数据储存在哪里?

    Bitcoin 共享的数据位于文件夹:

  • ~/.bitcoin/ (Linux)
  • ~/Library/Application Support/Bitcoin/ (MacOSX)
  • C:\Documents and Settings\YourUserName\Application data\Bitcoin\ (Windows XP)
  • C:\Users\YourUserName\Appdata\Roaming\Bitcoin\ (Windows vista / Windows 7)


    进入这个文件夹会看到如下图所以的文件列表:

图3:Bitcoin的数据文件夹

主要文件的作用:

  • bitcoin.conf 这是应用程序配置文件,如果没有这个文件则表示程序是用默认设置,一个典型的 bitcoin.conf 文件内容参考这里:https://en.bitcoin.it/wiki/Running_Bitcoin ;
  • blkxxxx.dat 和blkindex.dat,储存所有block的数据库文件,前者是数据内容,后者是数据索引;
  • __db.xxx,数据库 Berkeley DB所使用到的文件;
  • database,数据库的日志文件;
  • wallet.dat,你的“钱包”文件。


    对用户来说wallet.dat 最为重要的文件,里面存储着你所有的Bitcoin地址,所以这个文件相当于你的银行存折。假如这个文件丢失了或者损坏了,你的所有BTC也会随之消失,并且没法恢复。同样道理,假如这个文件被其他人所获得,那么你的所有 BTC 就归那个人所有,因为 wallet.dat 是没有密码保护的。所以及时安全地备份这个文件是有必要的。
    目前Bitcoin 应用程序对wallet的实现还略显粗糙,缺少导出(备份)、导入(还原)、合并等功能。
    现在网络上有一些托管Bitcoin账号的网站,它也可以为你生成Bitcoin地址,可以在里面进行汇入、汇出等操作,使得用户可以完全脱离Bitcoin程序,这样就不必担心wallet.dat文件丢失或者被盗了,不过前提是你是否完全信任那些网站。


Bitcoin 是怎样实现互联的?

    由于Bitcoin网络不存在服务器或者中心节点,所以所有block都是从其他人所运行的Bitcoin程序处(下面称为节点)下载的,同时你已经下载的block也会共享给其他还没下载的节点。那么 Bitcoin是如何发现网络上其他节点的呢?
    运行 Bitcoin 时它会首先连接一个指定的IRC(一种古老的网络聊天服务)服务器(irc.lfnet.org),然后加入 “#bitcoin”聊天频道并声明自己的IP地址,当 Bitcoin 程序查询当前聊天频道的用户时,就能获取网络上其他节点的IP地址了,然后bitcoin会自动连接一定数量的节点,可见IRC在Bitcoin网络中充当着媒介角色。假如IRC服务器当掉,那么第一次运行Bitcoin 程序时程序会调出内置的一批IP地址(称为“种子节点”)然后试图连接这些节点。Bitcoin 连接到某个节点之后还能通过那个节点获取更多其他节点,即所有节点同时也充当媒介角色,这样一个P2P网络就形成了。
    Bitcoin 程序所有的功能都依赖于 Bitcoin P2P网络,有时运行 Bitcoin 程序会发现连接数(见图1窗口中底部的 connections)是“0”(正常情况下应该有50~200个连接),这有可能是因为你的网络受到限制而导致的,这种情况下 Bitcoin 是没法正常工作的。下面讲解如何解决网络问题:
1、检查网络防火墙或者路由器的端口打开状态:连接 IRC 服务器需要打开 tcp 6667传出端口,连接其他 节点需要打开 tcp 8333 传出端口,其他节点连接你需要打开 tcp 8333 传入端口。所以在防火墙或路由上一共需要增加3条规则:

  • tcp 6667 传出
  • tcp 8333 传入
  • tcp 8333传出

2、检查 IRC 服务器的ip地址解析状态,有时国外的域名会受到DNS污染,irc.lfnet.org 服务器的ip地址是:

  • 173.246.103.92
  • 193.107.204.22
  • 193.107.204.81
  • 92.243.23.21

    把它们添加到 /etc/hosts 文件即可。
3、增加几个 Bitcoin 固定节点
    Bitcoin网络上有一些相对固定的节点(比如一些交易网站和矿场网站服务器),在这里可以找到一份列表:https://en.bitcoin.it/wiki/Fallback_Nodes ,挑选几个并把他们添加到 bitcoin.conf 配置文件(文件的位置见图3)可以增加连接的成功几率,添加之后的配置文件如图4当中的addnode部分所示:


图4:添加几个固定的Bitcoin节点到配置文件

    从这里可以看到 Bitcoin 网络并不是宣称中的“不可屏蔽”,相对其他P2P技术来说Bitcoin的并没有多大创新,某些地区或国家只需把IRC和种子节点干扰或者屏蔽一下就让普通人无法使用Bitcoin了。

说说Block吧
    Bitcoin 所共享的数据就是一大堆 block,那么一个 block 里装有什么内容呢?见图5:


图5:一个Block的内容,以及Block链

    一个block的主要内容是“最近的交易列表”和“上一个block的hash值”。交易列表记录着产生当前block这段时间内整个Bitcoin网络的所有交易记录,包括汇出地址、汇入地址、金额等。“上一个block的hash值”用于定位上一个block,有这个数据之后所有block就可以按顺序地形成一条链。一条完整的链记录着Bitcoin网络从诞生一刻开始直到未来所有的交易记录,这些记录会共享到每一个运行Bitcoin的节点。这里有个网站可以浏览每一个block和每一笔交易的具体内容:http://blockexplorer.com/ 。(题外话:在这个链当中的第一个block是比较特殊的,它是创始人Satoshi Nakamoto人为创造的,所以称为 Genesis Block)。
    假如Bitcoin得到广泛应用,每个block中的交易列表会相当庞大,那么每个运行Bitcoin的节点会耗费大量的储存空间,到时可能更多人不再运行Bitcoin应用程序转而使用在线的Bitcoin银行网站。分析到这里不禁会想到:假设Bitcoin整个网络只剩下100万个节点,某个组织自己搭建一个200万个节点的“黑网络”,然后更改其中的数学公式,再连接到外面正常的Bitcoin网络,这样Bitcoin系统是不是会受到破坏呢?
    每个block都会被计算出一个hash值(使用SHA256算法 ),以提供下一个block链接使用,而计算这个hash值的过程就是“挖金矿(mining)”过程,第一个计算出hash值的人就能获得50BTC的奖励(以后每21万个blocks奖金减半)。一般来说,现在的计算机要计算一个hash值已经非常快,所以为了竞争,Bitcoin对hash过程提出了一个要求:原始数据中留一个空缺让你填写任意内容,使得计算出的hash值前面有指定个数的数字“0”,问题可以用如下的式子理解:
sha256(“hello” + N)= “000000xxxxxxx”,其中N是让你填写的任意内容,xxxx的内容不限。
这就是专门用来为难CPU的HashCash算法,目前已知的解决方法只能将N从0开始一直递增到9999999.....逐个尝试看看计算出来的hash值的前面是否恰好有若干个0。使用这种方法除了可以让计算机耗费大量时间来计算hash值之外,还能通过增加或减少前导0的数目来调节难度,比如要计算出前面有4个0的平均时间为1小时,那么要计算5个0的平均时间可能会多10多倍。现在Bitcoin的计算难度正以指数形式不断增加(见统计图 http://bitcoin.sipa.be/ ),所以已经不能单独个人挖矿了,只能通过矿场(mining pool)来挖取BTC。

讲到Mining Pool
    Mining pool是用来集中散户力量共同挖矿,然后按工作量来分摊劳动所得的一种网站(比如 http://deepbit.net/ ),挖矿程序(Miner,比较常见的有 GUIMiner  和 DiabloMiner ,都是GPU挖矿程序)通过JSON-RPC 协议 向矿场请求工作,矿场会把一个挖矿任务分割成许多份小工作,然后分派给 miner,
miner 计算完之后向矿场提交劳动结果,这样就完成Pooled mining过程了。具体过程如下:
    miner 调用矿场的 getwork(null)方法,获取一个工作任务,传输内容大致如下:
请求 --> {"method":"getwork",
"id":"1",
"params":null}
返回 <-- {"error":null,
"id":"1",
"result":
{"midstate":"bbdb4f3078cc......",
"data":"00000001106e6da2fdf......",
"hash1":"000000000000000000......",
"target":"fffffffffffff......"}}
Miner根据midstate,data,hash1,target再加上一个自己的递增的数字计算出符合要求的hash值,有结果之后再次调用矿场的getwork(data)方法以提交。具体的算法请参阅Bitcoin或者miner的源代码。矿场可能会因为这种工作方式而遭受类似DDos的攻击,假如有人写个恶意的miner不断获取工作而不真正干活,矿场有可能会减产。
    矿场的服务端口通常是tcp 8332,要参加矿场工作你需要确认你的网络防火墙或者路由器打开了 tcp 8332端口的传出规则。
   
结论
    Bitcoin比较吸引人的地方在于其游戏规则,不过通过仔细分析部分技术实现来看,发现仍有有待完善的地方。至于更多原理和技术细节,比如Bitcoin的 P2P协议、Bitcoin 的API,以后我会看是否需要或者是否有空再写。
    最后,假如你觉得这篇文章对你有用,在 twitter RT一下吧 :)。

相关 [分析 bitcoin 原理] 推荐:

深入分析 Bitcoin 的原理和技术实现

- iFunbox - FeedzShare 1天最热
来自: Hippo notes - FeedzShare  . 发布时间:2011年05月31日,  已有 9 人推荐.     Bitcoin 是一种虚拟电子货币,上周我写过一篇介绍性质的文章《通俗易懂讲解什么是 Bitcoin 虚拟货币》(http://ivarptr.blogspot.com/2011/05/bitcoin.html),当时主要参考了官方和民间的介绍材料,并没有深入了解 Bitcoin 的技术细节.

Bitcoin 的基本原理

- 靛海幽蓝 - 云风的 BLOG
昨天读到了 Bitcoin 的中文介绍,觉得非常有意思. 不过上面这篇文章解释的非常不靠谱,我花了一晚上去Bitcoin的官方网站 仔细研究了一下,总算理解了其原理. 感觉非常有启发,尤其是对虚拟货币的流通和发行有许多借鉴意义. 货币就是商品(包括服务)交换的媒介. 现在我们通行的货币是由有信誉的银行发行的,基本上是由其信誉来担保的.

Bitcoin虚拟货币原理

- Blacat - 月光博客
  Bitcoin 是最近热议的话题,不过中文资料非常少,这篇文章不会评论 Bitcoin 的意义和利弊,只希望以尽简单的方式介绍什么是 Bitcoin,让更多人了解到这个有趣且了不起的创意. 同时笔者不断修正或补充内容,尽量做到当有人问到“什么是Bitcoin”时,只需把这篇文章的网址发给他就可以了.

bitcoin的技术原理

- Yunchao - 张志强的网络日志
博客 » IT技术 » bitcoin ». 最近bitcoin很火,我也是最先从云风那里了解到的,后来发现李笑来&霍炬对其都有涉及. 不过他们对其具体技术原理的描述还是不够细致,所以我自己把bitcoin wiki又重新看了一遍. 看完之后,疑惑挺多,我对这个体系远没有前面三位这么乐观. 诚然,它会成为"Geeks "手中的玩物甚至灰色交易的工具,但要说的达到“一出天下反”的程度,那还需要解决一些技术和金融方面的问题.

对BITCOIN的几点想法

- wuwu - 郭凯经济笔记
有人问我对BITCOIN有什么看法,我还没时间仔细想这个东西,但是粗略的了解了一下之后,有以下初步的想法,总结起来就是:神奇的技术,但优点可能被夸大,缺点可能很致命. 技术的部分我就不评价了,不懂更没资格评价. BITCOIN的优点中最被强调的就是:这是一个不需要中央银行的P2P的货币体系,因此不会有滥发钞票的风险.

BitCoin for Ubuntu 11.04 客户端

- Riku - Wow! Ubuntu
BitCoin 最近很热,大量的媒体、Blog ,甚至叽喳上都在谈论此物. 那么 BitCoin 到底为何物. [以下引用自 ivarptr 的文章,详情请看“通俗易懂讲解什么是 Bitcoin 虚拟货币”一文]. Bitcoin (为了便于书写和理解,下面如果是表示 “Bitcoin币”意思的地方我称呼其为“贝壳币”,取粤语相近的音译)是一种网络虚拟货币,跟腾讯公司的Q币类似,你可以使用贝壳币购买一些虚拟的物品,比如网络游戏当中的衣服、帽子、装备等,只要有人接受,你也可以使用贝壳币购买现实生活当中的物品.

Bitcoin被用于毒品交易

- Albert - Solidot
半岛电视台报导,最近颇受关注的P2P虚拟货币bitcoin被拍卖网站用于交易可卡因,大麻和其它毒品. 两位美国参议员要求联邦当局打击接受虚拟货币的在线毒品市场. 匿名的网上社区Dark Web交易海洛因,可卡因和甲基苯丙胺等毒品,它已经秘密运行了几个月. 两位参议员要求美国司法部和毒品管制局关闭和调查该网站.

NumericField&NumericRangeQuery原理分析

- - 搜索引擎技术博客
NumericField和NumericRangeQuery是Lucene. 针对数值型区间查询的优化方案. 和NumbericRanageQuery. 的实现原理之前,对于Lucene范围查询的实现和概念可以参考博文《TermRangeQuery源码解析》一文.       从Lucene 2.9 开始,提供对数字范围的支持,然而欲使用此查询,必须使用NumericField 添加域,使用Lucene原生API:.

[原]CAS原理分析

- -
1、悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作. 悲观锁的实现,往往依靠底层提供的锁机制;悲观锁会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 2、乐观锁:假设不会发生并发冲突,每次不加锁而是假设没有冲突而去完成某项操作,只在提交操作时检查是否违反数据完整性. 如果因为冲突失败就重试,直到成功为止.