比特币核心概念及算法
链客,专为开发者而生,有问必答!
此文章来自区块链技术社区,未经允许拒绝转载。
bitcoin项目地址位于github仓库,当前各种“币”,基本都是从抄写bitcoin代码开始起步的。想要深度研究,从看源码开始不可避免。
P2P:电骡、迅雷、BT,在中国网络影视的发展让大家对P2P很熟悉,可能已经没有人记得比特币实际上是第一批P2P的实践者。所有交易记录在全网通过P2P的方式广播,每个人都保存一份完整的交易记录。所以也叫去中心化。
去中心化:bitcoin的去中心化是指的账本去中心化,每个人都拥有完整的交易记录。因此不会出现人为修改某一个账本就导致财产丢失的情况。
在这种模式下,想有效的修改以前的交易记录,就需要有工作量证明(POW)。理论上修改之前的区块必须做到51%的联网机器都认可才可能成功,而这肯定是做不到的。
实际在整个比特币系统的运行中,P2P的特点实际上还是要有服务器系统负责支持维护,这是显然的。
在比特币软件中,这个支持系统采用的是DNS Seed来获取一部分对等节点列表,使用户快速发现对等节点,这部分DNS地址被硬编码在源码中的,每个新安装的客户端需要使用这些地址来工作:
vSeeds.emplace_back(“seed.bitcoin.sipa.be”, true); // Pieter Wuille, only supports x1, x5, x9, and xd vSeeds.emplace_back(“dnsseed.bluematt.me”, true); // Matt Corallo, only supports x9 vSeeds.emplace_back(“dnsseed.bitcoin.dashjr.org”, false); // Luke Dashjr vSeeds.emplace_back(“seed.bitcoinstats.com”, true); // Christian Decker, supports x1 - xf vSeeds.emplace_back(“seed.bitcoin.jonasschnelli.ch”, true); // Jonas Schnelli, only supports x1, x5, x9, and xd vSeeds.emplace_back(“seed.btc.petertodd.org”, true); // Peter Todd, only supports x1, x5, x9, and xd
当客户端已经工作过,并且缓存了对等的网络节点地址之后,下次再次启动,就不需要访问这个地址了。每个客户端等于自带了路由,这个时候就是真正的去中心化了。
DNS系统采用UDP方式工作,速度更快,也不容易受到DDOS攻击。
去中心化的商业理念曾经非常火爆,也被认为是比特币的重点创新之处,不过最近业界基本已经认为“去中心化”是个伪命题。因为所有提出去中心化的公司,实际都是为了以此为武器,打破大公司或者行业垄断企业的独占优势。且不说是否能够成功,即便成功的话,新公司仍然是希望自己可以独占和垄断。所以大家实际想要的不是去中心化,而是自己可以控制、别人不能控制的优势。
工作量证明:工作量证明(Proof Of Work,简称POW)。因为记账的过程是分布式的,每个人都可能发生,这个过程的监督非常困难。工作量证明等于是只监督结果,你必须付出足够的工作量(有效挖矿),才能证明你的记账工作是有效的。这个工作量的定义是由挖矿的难度决定的,参见后面挖矿。
共识机制:区块链系统使用上面所述的工作量证明来解决节点可信的问题(共识问题在计算机算法中有一个典型的模型叫拜占庭将军问题,通常分布式数据库中都会存在这种问题)。
区块链:区块链是老概念,软件专业的算法课程,基本上头几节课就会涉及到链表的概念。区块链就是链表,除了第一个“创世纪”节点,每一个节点都有一个指针指向前一个节点。单向链表的特征使得肯定会出现多个节点指向同一个节点的情况,这一般是由于同时出现两个挖矿成功,这种情况就是分叉,无限制的发展就成为了树。比特币系统的设计是不允许这种情况的,每次都会在链表中选择最长的一条链表进行下一个节点的链接,而最终短的分支会被抛弃。比特币的设计中,一个区块之后又链接了5个另外的区块(共6个区块),就可以确认本区块的交易是安全的了。一个示意性的区块链节点结构图示如下:
区块链是把一个基本数据结构模型应用于去中心化记账算法的成功范例。优点是这种创新必将对今后的金融系统设计造成深刻影响,缺点则是至今似乎尚未发现这种区块链结构在其它领域的优势应用或者优选方案。
挖矿:区块链中每一个节点都是用来记账的。为了防止节点被伪造,节点的生成有严格、耗时的要求,只有找到一个新的节点符合这些要求,这个节点才能把最近发生的交易记录进去并链接到区块链主链之上。寻找一个新的记账节点的过程就是挖矿。
挖矿算法:如果用python来表述一下挖矿算法,源码大致是这样的:
import hashlib, struct ver = 1 prev_block = “000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f” mrkl_root = “0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098” time = 1231469665 bits = 486604799 nonce = 2573394689 hex_str = struct.pack("<L", ver) + prev_block.decode(‘hex’)[::-1] +\ mrkl_root.decode(‘hex’)[::-1] + struct.pack("<LLL", time, bits, nonce) hash_str = hashlib.sha256(hashlib.sha256(hex_str).digest()).digest() # bitcoin矿机就是使用显卡或者FPGA实现sha256算法,通过暴力循环找到一个合适的nonce … block_hash = hash_str[::-1].encode(‘hex_codec’) #以下是伪代码 if meetReqirements(block_hash): newBlock=bookkeeping(block_hash) block_hash(newBlock)
挖矿的核心是进行两次的sha256运算,并且要求结果符合当前比特币要求的难度值,难度值表示两次sha256计算的结果,前面有符合难度值的0。意思是,假设计算结果是"000000xx…xxxxxx",前面0的个数,必须符合难度的要求,而且这个难度值在比特币系统中是不断增加的,也就是说挖矿难度越来越大。
参考上面的链表图,开头定义的几个常量都是节点的基本资料,不可改变,可变的只有nonce。而sha256 hash算法的特点,使得最终结果只能暴力循环所有的nonce可能值,才可能得到最终结果,至今尚无投机取巧的办法。
这个设计是为了区块链的生成没有那么容易,从而伪造区块链就成了拼计算能力的行为,而挖矿如此流行,计算能力想超过全球挖矿计算能力的半数已经是一件不可能的事情。从而在技术上杜绝了“账本伪造”这种可能性。这也成为“工作量证明(Proof-of-Work)”的共识达成机制的核心。
矿池:因为挖矿的难度越来越高,今天一个人使用自己的电脑挖矿成功的事情已经极难成功,因此出现了在辅助网站及辅助程序的帮助下,把大家零散的计算能力汇聚起来,一起进行挖矿,收益大家分享的方式,这就是矿池。矿池的主要算法是把上述的一个nonce值分段,每人穷举其中一小段,从而并行起来提高找到正确nonce值的概率。实际上今天矿池这种概念已经很成功的应用在了不少领域,诸如分布式计算、众筹等。
UTXO:一种记账方法,每个交易的记录,仅记录最终最近的交易及“UTXO”也就是未花费输出(Unspent Transaction Output),最重点,每一个交易中都包含这笔钱是谁转给你的。而链表中上一个交易也是,因此实际上每一笔钱都是可以完整追溯的。这种方式的特点是:1.得到余额需要去遍历区块链,而不是某一个节点。2.显然能大大缩小节点的数据尺寸。这对分布式每个人都保存一份账本的情况下,可以大大的降低空间需求。
矿机:上面的挖矿源码可以看出,主要的计算就是两次的sha256,想提高速度,除了用CPU,GPU更适合用作这种单纯的数学运算。因此出现了专门为挖矿设计的计算机,比如同时支持多块显卡,从而大大加快速度。这种电脑除了挖矿,在其它应用中意义并不大,所以叫“矿机”。GPU计算之后,又出现过FPGA矿机及ASIC矿机,不过看起来产量并不是很大。也可能是因为一旦挖矿失败,普通设备还可以拆开卖显卡,而这种纯粹的专业机就不好办了。
创世块:也就是创世纪区块,链表中第一个区块,相当于链表的头。这个也是硬编码在源代码中的,这个区块及其挖矿收入属于作者中本聪。来看看本尊:
curl https://blockchain.info/rawblock/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f { “hash”:“000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f”, “ver”:1, “prev_block”:“0000000000000000000000000000000000000000000000000000000000000000”, “mrkl_root”:“4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”, “time”:1231006505, “bits”:486604799, “fee”:0, “nonce”:2083236893, “n_tx”:1, “size”:285, “block_index”:14849, “main_chain”:true, “height”:0, “tx”:[ { “lock_time”:0, “ver”:1, “size”:204, “inputs”:[ { “sequence”:4294967295, “witness”:"", “script”:“04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73” } ], “weight”:816, “time”:1231006505, “tx_index”:14849, “vin_sz”:1, “hash”:“4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”, “vout_sz”:1, “relayed_by”:“0.0.0.0”, “out”:[ { “addr_tag_link”:“https://en.bitcoin.it/wiki/Genesis_block”, “addr_tag”:“Genesis of Bitcoin”, “spent”:false, “tx_index”:14849, “type”:0, “addr”:“1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa”, “value”:5000000000, “n”:0, “script”:“4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac” } ] }] }
请注意prev_block之中的一串“0”和height中的“0”,这证明这是链表的root。
创世块有个有趣的“副作用”,因为比特币“账本”的不可篡改性,其内容的唯一确定性是无可质疑的,而且人人可以验证。
因此只要有人用创世块地址的私钥签名一份声明,那就可以肯定是中本聪本人的声明,或者本人泄露了私钥。
如果说秘钥是比特币世界的印章的话,创世块地址对应的秘钥就是传国玉玺。中本聪的比特币地址就是addr中的:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。
创世纪区块可以看源码文件:src/chainparams.cpp,其中的:
assert(consensus.hashGenesisBlock == uint256S(“0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f”));
Merkle Tree:默克尔树,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树。Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值,在区块链中代表用于记账的账本内容。非叶节点是其对应子节点串联字符串的hash。hash算法也就是摘要算法,用于保证主体内容的一点点改变都导致hash内容的改变,逐级的树状结构,保证下一级的数据不被篡改。这里使用默克尔树而不是整个数据块做一个hash值,起源其实是p2p软件,用于在整个账本下载的时候,如果发生错误,不需要全部下载,而是逐级回溯hash值,下载出错的一小块数据就可以。
电子签名:比特币也是最早实践电子签名的应用之一。
电子签名分成私钥、公钥两部分,有私钥的话,可以经过计算得到公钥,反之则不可。工作时,私钥自己持有,自己负责保密,公钥发布在网络,所有人都可以看到。
所有的交易数据,都由交易者的私钥签名,其它人则可以使用公布的公钥对签名进行验证。对交易数据的修改会导致签名失效,这个才是比特币系统对资产最大的保证。
比特币电子签名使用ecdsa算法,这个算法有一个小缺陷,就是如果交易记录中仅仅修改了一个字节,仍然会验证通过。
当然这个修改无法做到修改交易金额,但可能造成后续的哈希计算得到完全不同的ID值。在攻击方网络足够快、广播能力足够强的话,可能在小范围内造成的伪造出现。
历史上曾经发生过利用这个方式伪造交易失败并向交易商索赔成功的事情,但是究其原因不算比特币系统设计问题,如果交易商严格遵循交易原则,只接受程序结果,不人为干预,是可以避免损失的。
比特币源码:src/secp256k1/src/secp256k1.c这里主要处理签名相关的东西。
电子签名机制今天已经无孔不入的遍布互联网各个环节,包括https网站、email、电子交易、网络银行,现在的问题已经不是要不要用电子签名,而是努力把每个由公网经过的环节都尽可能的签名化才是现在的趋势。
智能合约:比特币系统中的整个过程的商业逻辑就算做智能合约,与他人完成交易就相当于双方共同签订一份合约,随后利用区块链记账、交易广播、工作量证明等手段保障合约正确执行并不被篡改、攻击。这个描述比较抽象化,可能涉及了多个方面。以我个人认为,“智能合约”的理念才是比特币系统中最可贵的概念。
交易确认:交易确认分成两个部分,一个是区块生成后的确认,一个是一笔比特币交易完成后的确认,两者都设定了交易确认时间(当前是10分钟)。主要原因都是P2P的广播是需要时间的,在这个广播被尽可能多的人收到之前就确认交易,前者会造成区块链的冲突而出现分支,未能及时矫正的分支甚至会成为树从而造成区块链崩溃。后者未能广播之前就确认会出现伪造的可能,而广播被更多人收到之后,伪造就需要工作量证明,也就不可能达到了。但通常认为,达到不可逆转的6个区块链的标准,6*10实际是1小时的时间,才能真正确定一笔交易安全。
相关文章:

【php增删改查实例】第十七节 - 用户登录(1)
新建一个login文件,里面存放的就是用户登录的模块。 <html><head><meta charset"utf-8"><style type"text/css"></style><script type"text/javascript"></script></head><body&…

mysqlselectdb php_PHP MySQL Select(数据库查询)
SELECT 语句用于从数据库中选取数据。语法SELECT column_name(s) FROM table_name注释:SQL 语句对大小写不敏感。SELECT 与 select 等效。column_name(s)表示查询字段,可以是一个或多个,* 表示查询所有字段,table_name指数据表的名…

比特币和加密货币入门
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 比特币与加密货币 现在人们对加密货币空间产生巨大的兴趣的同时也同样也存在这疑惑与不解。比特币,加密货币,区块链&#…

有关RDS上只读实例延时分析-同适用于自建MySQL主从延时分析判断
个人不是很喜欢在技术上跟人互喷,尤其是不在同一个岗位上的人。一方面本人的性格如此,另一方面,我自身的口水也确实是不行,人生经历了第一次的双11洗礼,在大促的环境下,总算知道了有些东西是否应该规避&…

后盾网php多少钱_复合排水网价格多少钱
官方电话:【15266936188,0534-2138689】我公司专业生产防渗膜、土工膜、复合土工膜、土工布、隧道防水板、GCL钠基膨润土防水毯、聚酯长丝土工布等土工合成材料,价格合理、提供施工服务。一般情况下它不单独使用,因此在拉伸的过程中通常与成品…

Educational Codeforces Round 45 (Rated for Div. 2) D Graph And Its Complement(图的构造)
题意:构造一个图,使这个图的连通分量有a个,其补图的连通分量有b个,输出邻接矩阵 可以推出当min(a,b)!1时输出no ab1且n2或者n3时也为no 其余只要把一个连通分量里的x个点用x-1条边串起来就好了 哎,最后想到n3也为no,可惜了.. #include <bits/stdc.h> #define ll long…

一文读懂公有链、私有链、联盟链
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 区块链中公有链、私有链、联盟链都是区块链技术的一个细分,而技术仅仅是一种工具,怎么在不同的场景应用好不同的工具才是技…

近20个绚丽实用的jQuery/CSS3侧边栏菜单(转载)
http://developer.51cto.com/art/201510/493530.htm 近20个绚丽实用的jQuery/CSS3侧边栏菜单 jQuery作为一款主流的JavaScript前端开发框架,深受广告开发者的亲睐,同时jQuery有着不计其数的插件,特别是菜单插件更为丰 富,本文将要…

OpenJDK 编译-Linux环境
说明:笔者是在Ubuntu 16.04虚拟机中编译 OpenJDK 8 源码下载 http://download.java.net/openjdk/jdk8/ 推荐直接下载openjdk-8-src-b132-03_mar_2014.zip 环境准备: 安装bootstrap JDK,笔者安装的jdk7; 在环境变量PATH中添加jdk的…

linux 故障注入_阿里巴巴开源故障注入工具_chaosblade
chaosblade是阿里巴巴最近开源的一款故障注入的工具,因为我最近在做公司的虚拟化平台的可靠性测试工具,无意中发现这个工具,个人感觉比较有用,用起来也比较简单,所以拿出来分享一下,期望对大家的工作和学习…

带你了解“比特币黄金”和SegWit2x分叉
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 10月25日,比特币黄金从比特币中分离出来创造出一个基于ASIC挖矿的数字货币。几周之后,比特币公司中一个重要的集团想要根据…

HTML5-用canvas画布rotate字体旋转(中国象棋棋谱)。
一开始我们老师安排我做这个作业,在这个作业我遇到了一个很重大的问题就是,文字旋转这么旋转,我查了很多资料。 1发现绘画正方形,使他正方形中心原点旋转非常容易理解。(我相信这个很多人看一下都会懂,) 1.…

jQuery的deferred对象详解
阮一峰大神的关于jQuery的deferred对象详解 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html 转载于:https://www.cnblogs.com/qiufang/p/8886412.html

unity3d 切换网络_Unity3d新网络请求方式UnityWebRequest详解
Unity将要逐步放弃www网络请求api,新的api请求方式来临:UnityWebRequestThe,也正是本篇文章要给大家介绍的重点,那就是UnityWebRequestThe的使用详解。旧的 www :https://docs.unity3d.com/ScriptReference/WWW.html新…

PoW工作量证明
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 PoW是Proof of Work的缩写,即工作量证明的意思。在《拜占庭将军问题》中介绍过,比特币系统中引入了“工作量”的概念&#…

zookeeper 集群安装
一、ZooKeeper相关概念简介:ZooKeeper是一个开源的、分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服…

python queue 多进程_python中的Queue与多进程(multiprocessing)
最近接触一个项目,要在多个虚拟机中运行任务,参考别人之前项目的代码,采用了多进程来处理,于是上网查了查python中的多进程一、先说说Queue(队列对象)Queue是python中的标准库,可以直接import 引用,之前学习…

postman测试上传文件
输入url:http://127.0.0.1:8081/uploadfile 选择post方式 选择body 选择form-data,text改为file 输入key:file ,value:选择文件 send即可 转载于:https://www.cnblogs.com/shimh/p/6094410.html

区块链资产安全攻略
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 本文从钱包、密码、软件、备份、交易所、习惯几个方面给出一些指引。 钱包 每个钱包在熟练使用之前,请用小额测试。 有条件购买硬件钱…

win10安装docker并结合Idea2018.1部署springboot项目
一、准备工作 1.、工具:win10,idea2018,maven3.5,jdk8 二、win10安装docker 1、win10安装docker:http://www.runoob.com/docker/windows-docker-install.html 2、安装完毕后,点击小鲸鱼,选择set…

在桌面右键菜单,停止工作,并提示“资源管理器停止工作”等情况。
在配置文件中,找到右键管理菜单,然后删除NvCp开头的扩展项有问题,去掉就完事了。转载于:https://www.cnblogs.com/wangfengderizi/p/6094446.html

ue4cmd怎么调用_[UE4,automation]UE4批渲染cmd篇
之前做项目的过程中,有一部分工作是在UE4里制作输出小短片。由于要完成的量比较大,所以研究了一些批渲染的方法。逻辑上跟以前在maya里用batch render差不多,不过UE4这边的设置相对繁琐一点点。本文讲解了在不打开UE4软件的前提下,…

区块链将带来怎样的应用?
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 在上一篇文章中,咱们聊到了区块链技术正在与大数据、云计算、物联网以及人工智能这些技术链接,随时可能碰撞出技术创新的火…

【Spark】Spark2.x版的新特性
一、API 1. 出现新的上下文接口:SparkSession,统一了SQLContext和HiveContext,并且为SparkSession开发了新的流式调用的configuration API 2. 统一了DataFrame和DataSet。DataFrame相当于DataSet[Row],以及DataSet的增强聚合API 3…

python基础主要内容_python基础—python的介绍
编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.这是因为计算机不能直接认识并…

Web Serveice服务代理类生成及编译
一、生成代理类 对于web service服务和wcf的webservice服务,我们都可以通过一个代理类来调用。 怎么写那个代理类呢?通过一个工具生成即可!!微软为我们提供了一个wsdl.exe的Web服务描述语言工具,wsdl.exe从 WSDL 协定文…

生成器/迭代器 和 函数的递归
生成器 一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个…

CDN -- 集合
weui https://cdnjs.cloudflare.com/ajax/libs/weui/0.4.3/style/weui.min.css 百度静态资源库 http://cdn.code.baidu.com/转载于:https://www.cnblogs.com/xuange306/p/6102407.html

python清华大学出版社第三章课堂作业的答案_Python程序设计清华大学出版社董付国第3章选择与循环题库.ppt...
3.5 综合运用 例2:输出序列中的元素。 a_list[a, b, mpilgrim, z, example] for i,v in enumerate(a_list): print 列表的第, i1, 个元素是:, v 3.5 综合运用 例3:求1~100之间能被7整除,但不能同时被5整除的所有整数 。 for i in …

以太坊私链入门
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载 目录 背景软件安装与配置 2.1. Ubuntu 2.1.1. 安装 geth 2.1.2. 安装 solc 2.2. Windows 2.3. Mac OS 2.4. 编译安装创世区块 3.1. 初始化创世区块 …