代码
调试技术
数据库
- 《Getting started with impala》
- 《mysql 必知必会》
- 《mysql 性能调优与架构实践》
- 《Mysql 技术内幕 InnoDB 存储引擎》
- 《Redis 实战》
- 《Redis 深度历险核心原理和应用实践》
- 《redis设计与实现》
- 《七周七数据库》
- 《深入浅出mysql》
- 《高性能mysql第三版》
- 《MySQL是怎样运行的》
前端
GOLANG
- 《1 The Go Programming Language》
- 《2 The Go Programming Language》
- 《3 The Go Programming Language》
- 《Build Web Application With Golang》
- 《Go101》
- 《Network Programming with go》
- 《Building Microservices With Go》
- 《Building Restful Web Services with Go》
- 《Concurrency In Go》
- 《Go In Action(Go 实战)》
- 《Go学习笔记语言详解》
- 《Go学习笔记源码剖析》
- 《Go语言编程》
JAVA
网络
心理学
PYTHON
创业
UNIX/LINUX
分布式
系统设计
搜索引擎
开发工具
- 《Practical Vim》
- 《Vim8文本处理实战》
- 《Learn vim scrpt the hard way》
- 《Pro Git》
- 《Mastering Vim》
- 《Mastering Vim Quickly》
思维
源码
网站架构微服务
- 《微服务架构设计模式》
- 《从0开始学架构》
- 《web scalavility for startup engineers》
- 《designdatainstensive_application》
- 《designdatainstensive_application2》
- 《clean_architecture》
- 《微服务实战》
- 《微服务设计》
软件工程/项目管理
运维
金融理财
写作
互联网
区块链
技术演讲网课
- 《哔哩哔哩的go微服务实战》
- 《go业务基础库之Error&Context》
- 《Go同步和并发设计模式》
- 《300分钟吃透分布式缓存》
- 《DDD实战课》
- 《分布式技术原理与实战45讲》
- 《架构设计面试精讲》
- 《高并发系统设计40问》
- 《java并发编程78讲》
- 《中间件核心技术与实战讲》
职场
《区块链技术指南》
区块链思想的诞生与概念
从数字货币说起
双重支付攻击:持有人可以试图将同一份电子货币发给多个人。 当前银行中电子化货币假定存在一个安全可靠的第三方机构来实现,这个机构利用信用作为抵押,来完成交易。
去中心化场景下存在几个难题: - 货币的防伪 - 货币交易 - 避免双重支付
数字货币的几代演进: - 1983年 ecash,依赖中心化的中介机构,最终失败 - 1997, Hashcash. 首次提出工作量证明(Proof of Work, PoW)机制获取额度,该技术后来被后续数字货币技术采用 - 1998, B-money. 将POW 引入数字货币生成,同时是首个面向去中心化的设计,但是未能提出具体实现 - 比特币,PoW 与共识机制结合在一起
目前数字货币两种模式:paypal跟已有系统合作,成为代理;一种是比特币这样的完全丢弃已有体系的分布式技术
什么是比特币: 2008年10月31,化名为中本聪提出了比特币设计白皮书,并在2009年公开了最初的代码实现,第一个比特币是2009年 1月31日 18:15:05 生成。作为一种概念金融货币,比特币主要是希望解决已有金融货币系统的几个问题: - 被掌握在发型机构手中 - 自身价值无法保证 - 无法匿名交易
比特币到区块链: 实现去中心化记账本系统的一种极具潜力的可行技术。 区块链属于一种去中心化的记录技术,参与到系统上的节点,可能不属于同一组织彼此无需信任,区块链数据由所有节点共同维护, 每个节点都能复制获取一份完整记录的拷贝。和传统的记账技术相比其特点包括: - 维护一条不断增长的链,只能添加记录,发生过的记录都不可篡改 - 去中心化(多中心化) - 通过密码学机制确保交易无法抵赖和破坏,并尽量保护用户信息和记录的隐私性
区块链基本原理: - 交易(Transaction): 一次操作,导致账本状态的一次改变,如添加一条记录 - 区块(Block): 记录一段时间内发生的交易和状态结果,是对当前账本状态的一次共识 - 链(Chain): 由一个个区块按照发生顺序串联而成,是整个状态变化的日志记录
以比特币看如何使用区块链技术: 客户端发起一项交易后,会广播到网络中等待确认。网络中的节点会讲一些等待确认的交易记录打包在一起(还要包括此前区块的哈希值等信息), 组成一个候选区块。然后试图找打一个 nonce 串放到区块里,使得候选区块的hash值结果满足一定条件(比如小于某个值)。 一旦算出来这个区块在格式上就合法了,就可以进行全网广播。大家拿到提案区块,进行验证,发现确实符合约定条件了,就承认这个区块是一个 合法的新区块,被添加到链上。 比特币的这种基于算力的共识机制被称为Proof of Work(PoW)。目前要让hash结果满足一定的条件并无已知的启发式算法,只能暴力尝试。 尝试次数越多算出来的概率越大。通过调节对hash结果的限制,比特币网络控制月10分钟平均算出一个合法区块。 算出来的节点将得到区块中所有交易的管理费和协议固定发放的奖励费(每4年减半),也俗称挖矿。
区块链分类,根据参与者不同,可以分为: - 公开链:任何人都可以参与使用和维护,比如比特币 - 私有链:集中管理者进行限制,内部少数人可以使用,信息不公开 - 联盟链:若干组织一起合作维护一条区块链
区块链技术的价值、挑战与展望
价值
技术上说区块链一般被认为具有: - 分布式容错 - 不可篡改 - 隐私保护
随之带来的业务特性包括: - 可信任性 - 降低成本 - 增强安全
关键技术和挑战
- 密码学技术
- 分布式共识:核心在于如何解决某个变更在网络中是一致的,是被大家都承认的。经典的拜占庭算法等,可以解决确定性问题
- 处理性能。提高交易吞吐量,降低交易确认延迟
- 扩展性:网络节点数过多可能会因为一致性达成过车概念延迟降低整个网络的性能
- 系统安全。立法监管;软件漏洞
- 数据库和存储系统。
- 可集成性。如何与现有系统共存
- 其他:运营问题
典型应用场景
区块链在不引入第三方中介机构的前提下,可以提供去中心化、不可篡改、安全可靠等特性保证。所有直接或间接依赖于第三方担保信任机构的活动, 均可从区块链技术中获益。
金融服务。降低交易成本,减少跨组织交易风险等
交易本质上交换的是价值的所属权。 银行金融管理;支付服务;证券交易
征信和权属管理
- 征信管理:区块链天然无法篡改、不可抵赖的特性
- 权属管理:产权、版权等所有权的管理和追踪
资源共享: airbnb,降低管理成本
问题主要包括:成本高、用户身份评分难、共享服务管理难 短租共享;社区能源共享; 电商平台;大数据共享
投资管理:降低管理成本和管控风险
跨境交易;一带一路;众筹投资
物联网与供应链
物流供应链;公共网络服务
分布式系统
一致性问题
分布式系统中一致性(Consistency)指对于系统中多个服务节点,给定一系列操作,在协议(往往通过某种共识算法)保障下,试图使得 他们对处理结果达成某种程度的一致。一致性不代表结果正确与否,而是系统对外呈现的状态是否一致。 将可能引发不一致的并行操作进行串行化,就是现代计算机系统里处理分布式一致性问题的基础思路和唯一秘诀。 规范的说,理想的分布式系统一致性应该满足: - 可终止性(Termination):一致的结果在有限时间内能完成; - 共识性(Consensus):不同节点最终完成决策的结果应该相同; - 合法性(Validity):决策的结果必须是其它进程提出的提案。
强一致性主要包括两类: - 顺序一致性:保证所有进程看到的 全局执行顺序(total order)一致,并且每个进程看自身的执行(local order)跟实际发生顺序一致 - 线性一致性: 顺序一致性前提下加强了进程间的操作排序,形成唯一的全局顺序(系统等价于是顺序执行,所有进程看到的所有操作的序列顺序都一致,并且跟实际发生顺序一致),是很强的原子性保证。但是比较难实现,目前基本上要么依赖于全局的时钟或锁,要么通过一些复杂算法实现,性能往往不高。
弱一致性:最终一致性
共识算法
共识算法解决的是对某个提案(Proposal),大家达成一致意见的过程。提案的含义在分布式系统中十分宽泛,如多个事件发生的顺序、某个键对应的值、谁是领导……等等,可以认为任何需要达成一致的信息都是一个提案。 一般地,把故障(不响应)的情况称为“非拜占庭错误”,恶意响应的情况称为“拜占庭错误”(对应节点为拜占庭节点)。 常见算法:针对非拜占庭错误的情况,一般包括 Paxos、Raft 及其变种。 对于要能容忍拜占庭错误的情况,一般包括 PBFT 系列、PoW 系列算法等。从概率角度,PBFT 系列算法是确定的,一旦达成共识就不可逆转;而 PoW 系列算法则是不确定的,随着时间推移,被推翻的概率越来越小。
FLP 不可能性原理
即便在网络通信可靠情况下,一个可扩展的分布式系统的共识问题的下限是无解。 这个结论,被称为 FLP 不可能性 原理,可以看做分布式领域的“测不准原理”: FLP 不可能原理:在网络可靠,存在节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法。
但是工程上,付出 一些代价,把它变成可能。回答这个问题的是另一个很出名的原理:CAP原理
CAP 原理
分布式计算系统不可能同时确保一致性(Consistency)、可用性(Availablity)和分区容忍性(Partition),设计中往往需要弱化对某个特性的保证。
- 一致性(Consistency):任何操作应该都是原子的,发生在后面的事件能看到前面事件发生导致的结果,注意这里指的是强一致性;
- 可用性(Availablity):在有限时间内,任何非失败节点都能应答请求;
- 分区容忍性(Partition):网络可能发生分区,即节点之间的通信不可保障。
比较直观地理解,当网络可能出现分区时候,系统是无法同时保证一致性和可用性的。要么,节点收到请求后因为没有得到其他人的确认就不应答,要么节点只能应答非一致的结果。 好在大部分时候网络被认为是可靠的,因此系统可以提供一致可靠的服务;当网络不可靠时,系统要么牺牲掉一致性(大部分时候都是如此),要么牺牲掉可用性。
弱化一致性:对结果一致性不敏感的应用,可以允许在新版本上线后过一段时间才更新成功,期间不保证一致性。 例如网站静态页面内容、实时性较弱的查询类数据库等,CouchDB、Cassandra 等为此设计。 弱化可用性:对结果一致性很敏感的应用,例如银行取款机,当系统故障时候会拒绝服务。MongoDB、Redis 等为此设计。 Paxos、Raft 等算法,主要处理这种情况。 弱化分区容忍性: 现实中,网络分区出现概率减小,但较难避免。某些关系型数据库、ZooKeeper 即为此设计。
ACID 原则
即 Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性)。
ACID 原则描述了对分布式数据库的一致性需求,同时付出了可用性的代价。
- Atomicity:每次操作是原子的,要么成功,要么不执行;
- Consistency:数据库的状态是一致的,无中间状态;
- Isolation:各种操作彼此互相不影响;
- Durability:状态的改变是持久的,不会失效。
一个与之相对的原则是 BASE(Basic Availiability,Soft state,Eventually Consistency),牺牲掉对一致性的约束(最终一致性),来换取一定的可用性。
Paxos 与 Raft
Paxos 问题是指分布式的系统中存在故障(fault),但不存在恶意(corrupt)节点场景(即可能消息丢失或重复,但无错误消息)下的共识达成(Consensus)问题。因为最早是 Leslie Lamport 用 Paxon 岛的故事模型来进行描述而命名。
Paxos
Paxos 是第一个被证明的共识算法,其原理基于 两阶段提交 并进行扩展。
作为现在共识算法设计的鼻祖,以最初论文的难懂(算法本身并不复杂)出名。算法中将节点分为三种类型:
- proposer:提出一个提案,等待大家批准为结案。往往是客户端担任该角色;
- acceptor:负责对提案进行投票。往往是服务端担任该角色;
- learner:被告知结案结果,并与之统一,不参与投票过程。可能
并且,算法需要满足 safety 和 liveness 两方面的约束要求(实际上这两个基础属性是大部分分布式算法都该考虑的):
- safety:保证决议结果是对的,无歧义的,不会出现错误情况。 决议(value)只有在被 proposers 提出的 proposal 才能被最终批准; 在一次执行实例中,只批准(chosen)一个最终决议,意味着多数接受(accept)的结果能成为决议;
- liveness:保证决议过程能在有限时间内完成。 决议总会产生,并且 learners 能获得被批准(chosen)的决议。
Paxos 能保证在超过的正常节点存在时,系统能达成共识。
单个提案者+多接收者
如果系统中限定只有某个特定节点是提案者,那么一致性肯定能达成(只有一个方案,要么达成,要么失败)。提案者只要收到了来自多数接收者的投票,即可认为通过,因为系统中不存在其他的提案。 但一旦提案者故障,则系统无法工作。
多个提案者+单个接收者
限定某个节点作为接收者。这种情况下,共识也很容易达成,接收者收到多个提案,选第一个提案作为决议,拒绝掉后续的提案即可。 缺陷也是容易发生单点故障,包括接收者故障或首个提案者节点故障。 以上两种情形其实类似主从模式,虽然不那么可靠,但因为原理简单而被广泛采用。 当提案者和接收者都推广到多个的情形,会出现一些挑战。
多个提案者+多个接收者
既然限定单提案者或单接收者都会出现故障,那么就得允许出现多个提案者和多个接收者。问题一下子变得复杂了。 一种情况是同一时间片段(如一个提案周期)内只有一个提案者,这时可以退化到单提案者的情形。需要设计一种机制来保障提案者的正确产生,例如按照时间、序列、或者大家猜拳(出一个数字来比较)之类。考虑到分布式系统要处理的工作量很大,这个过程要尽量高效,满足这一条件的机制非常难设计。 另一种情况是允许同一时间片段内可以出现多个提案者。那同一个节点可能收到多份提案,怎么对他们进行区分呢?这个时候采用只接受第一个提案而拒绝后续提案的方法也不适用。很自然的,提案需要带上不同的序号。节点需要根据提案序号来判断接受哪个。比如接受其中序号较大(往往意味着是接受新提出的,因为旧提案者故障概率更大)的提案。
如何为提案分配序号呢?一种可能方案是每个节点的提案数字区间彼此隔离开,互相不冲突。为了满足递增的需求可以配合用时间戳作为前缀字段。 此外,提案者即便收到了多数接收者的投票,也不敢说就一定通过。因为在此过程中系统可能还有其它的提案。
两阶段提交
Paxos 里面对这两个阶段分别命名为准备(prepare)和提交(commit)。准备阶段解决大家对哪个提案进行投票的问题,提交阶段解决确认最终值的问题。
准备阶段:
提案者发送自己计划提交的提案的编号到多个接受者,试探是否可以锁定多数接受者的支持。 接受者时刻保留收到过提案的最大编号和接受的最大提案。如果收到的提案号比目前保留的最大提案号还大,则返回自己已接受的提案值(如果还未接受过任何提案,则为空)给提案者,更新当前最大提案号,并说明不再接受小于最大提案号的提案。
提交阶段:
提案者如果收到大多数的回复(表示大部分人听到它的请求),则可准备发出带有刚才提案号的接受消息。如果收到的回复中不带有新的提案,说明锁定成功,则使用自己的提案内容;如果返回中有提案内容,则替换提案值为返回中编号最大的提案值。如果没收到足够多的回复,则需要再次发出请求。 接受者收到接受消息后,如果发现提案号不小于已接受的最大提案号,则接受该提案,并更新接受的最大提案。
一旦多数接受了共同的提案值,则形成决议,成为
Raft
Raft 是 Paxos 算法的一种简化实现。 包括三种角色:leader、candidate 和 follower,其基本过程为:
- Leader 选举:每个 candidate 随机经过一定时间都会提出选举方案,最近阶段中得票最多者被选为 leader;
- 同步 log:leader 会找到系统中 log 最新的记录,并强制所有的 follower 来刷新到这个记录;( 此处 log 并非是指日志消息,而是各种事件的发生记录。)
拜占庭问题与算法
拜占庭问题
拜占庭问题更为广泛,讨论的是允许存在少数节点作恶(消息可能被伪造)场景下的一致性 达成问题。拜占庭算法讨论的是最坏情况下的保障。
拜占庭将军(Byzantine Generals Problem)问题,是 Leslie Lamport 1982 年提出用来解释一致性问题的一个虚构模型。拜占庭是古代东罗马帝国的首都,由于地域宽广,守卫边境的多个将军(系统中的多个节点)需要通过信使来传递消息,达成某些一致的决定。但由于将军中可能存在叛徒(系统中节点出错),这些叛徒将努力向不同的将军发送不同的消息,试图会干扰一致性的达成。 拜占庭问题即为在此情况下,如何让忠诚的将军们能达成行动的一致。
对于拜占庭问题来说,假如节点总数为 N,叛变将军数为 F,则当 N >= 3F+1 时,问题才有解,即 Byzantine Fault Tolerant (BFT) 算法。
Byzantine Fault Tolerant 算法
面向拜占庭问题的容错算法,解决的是网络通信可靠,但节点可能故障情况下的一致性达成。 最早由 Castro 和 Liskov 在 1999 年提出的 Practical Byzantine Fault Tolerant(PBFT)是第一个得到广泛应用的 BFT 算法。只要系统中有 的节点是正常工作的,则可以保证一致性。 PBFT 算法包括三个阶段来达成共识:Pre-Prepare、Prepare 和 Commit。
新的解决思路
拜占庭问题之所以难解,在于任何时候系统中都可能存在多个提案(因为提案成本很低),并且要完成最终的一致性确认过程十分困难,容易受干扰。但是一旦确认,即为最终确认。 比特币的区块链网络在设计时提出了创新的 PoW(Proof of Work)工作量证明算法思路。一个是限制一段时间内整个网络中出现提案的个数(增加提案成本),另外一个是放宽对最终一致性确认的需求,约定好大家都确认并沿着已知最长的链进行拓宽。系统的最终确认是概率意义上的存在。这样,即便有人试图恶意破坏,也会付出很大的经济代价(付出超过系统一半的算力)。 后来的各种 PoX 系列算法,也都是沿着这个思路进行改进,采用经济上的惩罚来制约破坏者。
可靠性指标
一般来说,单点的服务器系统至少应能满足两个九;普通企业信息系统三个九就肯定足够了(大家可以统计下自己企业内因系统维护每年要停多少时间),系统能达到四个九已经是业界领先水平了(参考 AWS)。电信级的应用一般号称能达到五个九,这已经很厉害了,一年里面最多允许五分钟的服务停用。六个九和以上的系统,就更加少见了,要实现往往意味着极高的代价。 那么,该如何提升可靠性呢?有两个思路:一是让系统中的单点变得更可靠;二是消灭单点。
密码学技术
Hash 算法
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。 例如计算一段话“hello blockchain world, this is yeasy@github”的 MD5 hash 值为 89242549883a2ef85dc81b90fb606046。 hash 值在应用中又被称为指纹(fingerprint)、摘要(digest)。 注:MD5 是一个经典的 hash 算法,其和 SHA-1 算法都已被 证明 安全性不足应用于商业场景。
一个优秀的 hash 算法,将能实现:
- 正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
- 逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
- 输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。 也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。
加解密算法
算法类型 | 特点 | 优势 | 缺陷 | 代表算法 |
---|---|---|---|---|
对称加密 | 加解密密钥相同或可推算 | 计算效率高,加密强度高 | 需提前共享密钥;易泄露 | DES、3DES、AES、IDEA |
非对称加密 | 加解密密钥不相关 | 无需提前共享密钥 | 计算效率低,仍存在中间人攻击可能 | RSA、ElGamal、椭圆曲线系列算法 |
对称加密
顾名思义,加解密的密钥是相同的。 优点是加解密效率高(速度快,空间占用小),加密强度高。 缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。 对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。 代表算法包括 DES、3DES、AES、IDEA 等。
非对称加密
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。 顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。 公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。 优点是公私钥分开,不安全通道也可使用。 缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。 非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。 代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
一般适用于签名场景或密钥协商,不适于大量数据的加解密。 RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
混合加密机制
即先用计算复杂度高的非对称加密协商一个临时的对称加密密钥(会话密钥,一般相对内容来说要短的多),然后双方再通过对称加密对传递的大量数据进行加解密处理。 典型的场景是现在大家常用的 HTTPS 机制。HTTPS 实际上是利用了 Transport Layer Security/Secure Socket Layer(TLS/SSL)来实现可靠的传输。TLS 为 SSL 的升级版本,目前广泛应用的为 TLS 1.0,对应到 SSL 3.1 版本。
建立安全连接的具体步骤如下: - 客户端浏览器发送信息到服务器,包括随机数 R1,支持的加密算法类型、协议版本、压缩算法等。注意该过程为明文。 - 服务端返回信息,包括随机数 R2、选定加密算法类型、协议版本,以及服务器证书。注意该过程为明文。 - 浏览器检查带有该网站公钥的证书。该证书需要由第三方 CA 来签发,浏览器和操作系统会预置权威 CA 的根证书。如果证书被篡改作假(中间人攻击),很容易通过 CA 的证书验证出来。 - 如果证书没问题,则用证书中公钥加密随机数 R3,发送给服务器。此时,只有客户端和服务器都拥有 R1、R2 和 R3 信息,基于 R1、R2 和 R3,生成对称的会话密钥(如 AES 算法)。后续通信都通过对称加密进行保护。
数字签名
类似在纸质合同上签名确认合同内容,数字签名用于证实某数字内容的完整性(integrity)和来源(或不可抵赖,non-repudiation)。 一个典型的场景是,A 要发给 B 一个文件(一份信息),B 如何获知所得到的文件即为 A 发出的原始版本?A 先对文件进行摘要,然后用自己的私钥进行加密,将文件和加密串都发给 B。B 收到后文件和加密串,用 A 的公钥来解密加密串,得到原始的数字摘要,跟对文件进行摘要后的结果进行比对。如果一致,说明该文件确实是 A 发过来的,并且文件内容没有被修改过。
HMAC
全称是 Hash-based Message Authentication Code,即“基于 Hash 的消息认证码”。基本过程为对某个消息,利用提前共享的对称密钥和 Hash 算法进行加密处理,得到 HMAC 值。该 HMAC 值提供方可以证明自己拥有共享的对称密钥,并且消息自身可以利用 HMAC 确保未经篡改。
HMAC(K, H, Message)
其中,K 为提前共享的对称密钥,H 为提前商定的 Hash 算法(一般为公认的经典算法),Message 为要处理的消息内容。如果不知道 K 和 H,则无法根据 Message 得到准确的 HMAC 值。
盲签名
1983 年由 David Chaum 提出。签名者在无法看到原始内容的前提下对信息进行签名。
盲签名主要是为了实现防止追踪(unlinkability),签名者无法将签名内容和结果进行对应。典型的实现包括 RSA 盲签名)。
多重签名
n 个持有人中,收集到至少 m 个()的签名,即认为合法,这种签名被称为多重签名。 其中,n 是提供的公钥个数,m 是需要匹配公钥的最少的签名个数。
群签名
1991 年由 Chaum 和 van Heyst 提出。群签名属于群体密码学的一个课题。 群签名有如下几个特点:只有群中成员能够代表群体签名(群特性);接收者可以用公钥验证群签名(验证简单性);接收者不能知道由群体中哪个成员所签(无条件匿名保护);发生争议时,群体中的成员或可信赖机构可以识别签名者(可追查性)。
环签名
环签名由 Rivest,shamir 和 Tauman 三位密码学家在 2001 年首次提出。环签名属于一种简化的群签名。
数字证书
数字证书用来证明某个公钥是谁的,并且内容是正确的。 对于非对称加密算法和数字签名来说,很重要的一点就是公钥的分发。一旦公钥被人替换(典型的如中间人攻击),则整个安全体系将被破坏掉。
怎么确保一个公钥确实是某个人的原始公钥? 这就需要数字证书机制。 顾名思义,数字证书就是像一个证书一样,证明信息和合法性。由证书认证机构(Certification Authority,CA)来签发,权威的 CA 包括 verisign 等。
更进一步地,怎么证明 CA 的签名合法不合法呢? 类似的,CA 的数字签名合法不合法也是通过 CA 的证书来证明的。主流操作系统和浏览器里面会提前预置一些 CA 的证书(承认这些是合法的证书),然后所有基于他们认证的签名都会自然被认为合法。
PKI 体系
在非对称加密中,公钥则可以通过证书机制来进行保护,如何管理和分发证书则可以通过 PKI(Public Key Infrastructure)来保障。 顾名思义,PKI 体系在现代密码学应用领域处于十分基础的地位,解决了十分核心的证书管理问题。 PKI 并不代表某个特定的密码学技术和流程,PKI 是建立在公私钥基础上实现安全可靠传递消息和身份确认的一个通用框架。实现了 PKI 的平台可以安全可靠地管理网络中用户的密钥和证书,包括多个实现和变种,知名的有 RSA 公司的 PKCS(Public Key Cryptography Standards)标准和 X.509 规范等。
一般情况下,PKI 至少包括如下组件: - CA(Certification Authority):负责证书的颁发和作废,接收来自 RA 的请求,是最核心的部分; - RA(Registration Authority):对用户身份进行验证,校验数据合法性,负责登记,审核过了就发给 CA; 证书数据库:存放证书,一般采用 LDAP 目录服务,标准格式采用 X.500 系列。 - CA 是最核心的组件,主要完成对证书的管理。
常见的流程为,用户通过 RA 登记申请证书,CA 完成证书的制造,颁发给用户。用户需要撤销证书则向 CA 发出申请。
Merkle 树
默克尔树(又叫哈希树)是一种二叉树,由一个根节点、一组中间节点和一组叶节点组成。最下面的叶节点包含存储数据或其哈希值,每个中间节点是它的两个孩子节点内容的哈希值,根节点也是由它的两个子节点内容的哈希值组成。 进一步的,默克尔树可以推广到多叉树的情形。 默克尔树的特点是,底层数据的任何变动,都会传递到其父亲节点,一直到树根。
默克尔树的典型应用场景包括:
- 快速比较大量数据:当两个默克尔树根相同时,则意味着所代表的数据必然相同。
- 快速定位修改:例如上例中,如果 D1 中数据被修改,会影响到 N1,N4 和 Root。因此,沿着 Root --> N4 --> N1,可以快速定位到发生改变的 D1;
- 零知识证明:例如如何证明某个数据(D0……D3)中包括给定内容 D0,很简单,构造一个默克尔树,公布 N0,N1,N4,Root,D0 拥有者可以很容易检测 D0 存在,但不知道其它内容。
同态加密
同态加密(Homomorphic Encryption)是一种特殊的加密方法,允许对密文进行处理得到仍然是加密的结果,即对密文直接进行处理,跟对明文进行处理再加密,得到的结果相同。从代数的角度讲,即同态性。
其他问题
零知识证明(zero knowledge validation)
证明者在不向验证者提供任何有用的信息的前提下,使验证者相信某个论断是正确的。
例如,A 向 B 证明自己有一个物品,但 B 无法拿到这个物品,无法用 A 的证明去向别人证明自己也拥有这个物品。
比特币项目-思想诞生的摇篮
原理和设计
比特币网络是一个分布式的点对点网络,网络中的矿工通过“挖矿”来完成对交易记录的记账过程,维护网络的正常运行。
比特币通过区块链网络提供一个公共可见的记账本,用来记录发生过的交易的历史信息。 每次发生交易,用户需要将新交易记录写到比特币区块链网络中,等网络确认后即可认为交易完成。每个交易包括一些输入和一些输出,未经使用的交易的输出( Unspent Transaction Outputs,UTXO)可以被新的交易引用作为合法的输入。 一笔合法的交易,即引用某些已存在交易的 UTXO,作为交易的输入,并生成新的输出的过程。 在交易过程中,转账方需要通过签名脚本来证明自己是 UTXO 的合法使用者,并且指定输出脚本来限制未来对本交易的使用者(为收款方)。对每笔交易,转账方需要进行签名确认。并且,对每一笔交易来说,总输入不能小于总输出。
概念:
- 账户/地址: 比特币账户采用了非对称的加密算法,用户自己保留私钥,对他发出的交易进行签名确认,并公开公钥。 比特币的账户地址其实就是用户公钥经过一系列 hash(HASH160,或先进行 SHA256,然后进行 RIPEMD160)及编码运算后生成的 160 位(20 字节)的字符串。
交易
- 付款人地址:合法的地址,公钥经过 SHA256 和 RIPEMD160 两次 hash,得到 160 位 hash 串;
- 付款人对交易的签字确认:确保交易内容不被篡改;
- 付款人资金的来源交易 ID:从哪个交易的输出作为本次交易的输入;
- 交易的金额:多少钱,跟输入的差额为交易的服务费;
- 收款人地址:合法的地址;
- 收款人的公钥:收款人的公钥;
- 时间戳:交易何时能生效。
网络中节点收到交易信息后,将进行如下检查:
- 交易是否已经处理过; - 交易是否合法。包括地址是否合法、发起交易者是输入地址的合法拥有者、是否是 UTXO; - 交易的输入之和是否大于输出之和。 - 检查都通过,则将交易标记为合法的未确认交易,并在网络内进行广播。
- 脚本 脚本(Script) 是保障交易完成(主要用于检验交易是否合法)的核心机制,当所依附的交易发生时被触发。通过脚本机制而非写死交易过程,比特币网络实现了一定的可扩展性。比特币脚本语言是一种非图灵完备的语言,类似 Forth 语言。 一般每个交易都会包括两个脚本:输出脚本(scriptPubKey)和认领脚本(scriptSig)。 输出脚本一般由付款方对交易设置锁定,用来对能动用这笔交易输出(例如,要花费交易的输出)的对象(收款方)进行权限控制,例如限制必须是某个公钥的拥有者才能花费这笔交易。 认领脚本则用来证明自己可以满足交易输出脚本的锁定条件,即对某个交易的输出(比特币)的拥有权。
区块 一个区块将主要包括如下内容:
- 4 字节的区块大小信息;
- 80 字节的区块头信息:
- 版本号:4 字节;
- 上一个区块头的 SHA256 hash 值:链接到一个合法的块上,32 字节;
- 包含的所有验证过的交易的 Merkle 树根的哈希值,32 字节;
- 时间戳:4 字节;
- 难度指标:4 字节;
- Nonce:4 字节,PoW 问题的答案;
- 交易个数计数器:1~9 字节;
所有交易的具体内容,可变长。
设计理念
如何避免作恶: 比特币网络需要所有试图参与者(矿工)都首先要付出挖矿的代价,进行算力消耗,越想拿到新区块的决定权,意味着抵押的算力越多。一旦失败,这些算力都会被没收掉,成为沉没成本。当网络中存在众多参与者时,个体试图拿到新区块决定权要付出的算力成本是巨大的,意味着进行一次作恶付出的代价已经超过可能带来的好处。 负反馈调节: 比特币网络中矿工越多,系统就越稳定,比特币价值就越高,但挖到矿的概率会降低。 反之,网络中矿工减少,会让系统更容易导致被攻击,比特币价值越低,但挖到矿的概率会提高。
共识机制
首先是不实现最终共识,理论上现有达成的任何结果都可能被推翻,只是被推翻的可能性随着时间而指数级的下降,要付出的代价迅速上升。 此外,达成共识的时间比较长,而且是按照块来进行阶段性的确认(快照),提高网络可用性。 此外,通过进行 PoW 限制合法提案的个数,提高网络的稳定性。
挖矿
了解比特币,最应该知道的一个概念就是“挖矿”,挖矿是参与维护比特币网络的节点,通过协助生成新区块来获取一定量新增的比特币。
当用户发布交易后,需要有人将交易进行确认,写到区块链中,形成新的区块。在一个互相不信任的系统中,该由谁来完成这件事情呢?比特币网络采用了“挖矿”的方式来解决这个问题。
目前,每 10 分钟左右生成一个不超过 1 MB 大小的区块(记录了这 10 分钟内发生的验证过的交易内容),串联到最长的链尾部,每个区块的成功提交者可以得到系统 12.5 个比特币的奖励(一定区块数后才能使用),以及用户附加到交易上的支付服务费用。
注:每个区块的奖励一开始是 50 个比特币,每隔 21 万个区块自动减半,即 4 年时间,最终比特币总量稳定在 2100 万个。因此,比特币是一种通缩的货币。
挖矿的具体过程为:参与者根据上一个区块的 hash 值,10 分钟内的验证过的交易内容,再加上自己猜测的一个随机数 X,让新区块的 hash 值小于比特币网络中给定的一个数。这个数越小,计算出来就越难。系统每隔两周(即经过 2016 个区块)会根据上一周期的挖矿时间来调整挖矿难度(通过调整限制数的大小),来调节生成区块的时间稳定在 10 分钟左右。为了避免震荡,每次调整的最大幅度为 4 倍。 为了挖到矿,参与处理区块的用户端往往需要付出大量的时间和计算力。算力一般以每秒进行多少次 hash 计算为单位,记为 h/s。
工具
客户端
客户端分为三种:完整客户端、轻量级客户端和在线客户端。
- 完整客户端:存储所有的交易历史记录,功能完备;
- 轻量级客户端:不保存交易副本,交易需要向别人查询;
在线客户端:通过网页模式来浏览第三方服务器提供的服务。
钱包
矿机
专门为“挖矿”设计的硬件,包括基于 GPU 和 ASIC 的芯片。
脚本
比特币交易支持一种比较简单的脚本语言(类 Forth 的栈脚本语言),可以写入 UTXO。交易发生时,输入的解锁脚本和输出的锁定脚本进行执行,检验交易合法性。 比特币脚本并不支持循环等复杂的流控制,因此它是非图灵完备的。
共识机制
比特币网络是公开的,因此共识协议的稳定性和防攻击性十分关键。 比特币区块链采用了 Proof of Work(PoW)的机制来实现共识,该机制于 1998 年在 B-money 设计中提出。 目前,Proof of 系列中比较出名的一致性协议包括 PoW 和 PoS,都是通过经济惩罚来限制恶意参与。
PoW
工作量证明,Proof of Work,通过计算来猜测一个数值(nonce),得以解决规定的 hash 问题(来源于 hashcash)。保证在一段时间内,系统中只能出现少数合法提案。 同时,这些少量的合法提案会在网络中进行广播,收到的用户进行验证后会基于它认为的最长链上继续难题的计算。因此,系统中可能出现链的分叉(Fork),但最终会有一条链成为最长的链。 hash 问题具有不可逆的特点,因此,目前除了暴力计算外,还没有有效的算法进行解决。反之,如果获得符合要求的 nonce,则说明在概率上是付出了对应的算力。谁的算力多,谁最先解决问题的概率就越大。当掌握超过全网一半算力时,从概率上就能控制网络中链的走向。这也是所谓 51% 攻击 的由来。
PoS
权益证明,Proof of Stake,2013 年被提出,最早在 Peercoin 系统中被实现,类似现实生活中的股东机制,拥有股份越多的人越容易获取记账权。
典型的过程是通过保证金(代币、资产、名声等具备价值属性的物品即可)来对赌一个合法的块成为新的区块,收益为抵押资本的利息和交易服务费。提供证明的保证金(例如通过转账货币记录)越多,则获得记账权的概率就越大。合法记账者可以获得收益。
闪电网络
比特币的交易网络最为人诟病的一点便是交易性能:全网每秒 7 笔的交易速度,远低于传统的金融交易系统;同时,等待 6 个块的可信确认导致约 1 个小时的最终确认时间。
闪电网络的主要思路十分简单 -- 将大量交易放到比特币区块链之外进行。该设计最早是 2015 年 2 月在论文《The Bitcoin Lightning Network: Scalable Off-Chain Instant Payments》中提出。
比特币的区块链机制自身提供了很好的可信保障,但是很慢;另一方面考虑,对于大量的小额交易来说,是否真实需要这么高的可信性?闪电网络通过智能合约来完善链下的交易渠道。 核心的概念主要有两个:RSMC(Recoverable Sequence Maturity Contract)和 HTLC(Hashed Timelock Contract)。前者解决了链下交易的确认问题,后者解决了支付通道的问题。
RSMC
Recoverable Sequence Maturity Contract,中文可以翻译为“可撤销的顺序成熟度合同”。这个词很绕,其实主要原理很简单,就是类似准备金机制。
我们先假定交易双方之间存在一个“微支付通道”(资金池)。双方都预存一部分资金到“微支付通道”里,之后每次交易,就对交易后的资金分配方案共同进行确认,同时签字作废旧的版本。当需要提现时,将最终 交易结果写到区块链网络中,被最终确认。可以看到,只有在提现时候才需要通过区块链。 任何一个版本的方案都需要经过双方的签名认证才合法。任何一方在任何时候都可以提出提现,提现需要提供一个双方都签名过的资金分配方案(意味着肯定是某次交易后的结果)。在一定时间内,如果另外一方提出证明表明这个方案其实之前被作废了(非最新的交易结果),则资金罚没给质疑成功方。这就确保了没人会拿一个旧的交易结果来提现。 另外,即使双方都确认了某次提现,首先提出提现一方的资金到账时间要晚于对方,这就鼓励大家尽量都在链外完成交易。
HTLC
微支付通道是通过 Hashed Timelock Contract 来实现的,中文意思是“哈希的带时钟的合约”。这个其实就是限时转账。理解起来其实也很简单,通过智能合约,双方约定转账方先冻结一笔钱,并提供一个哈希值,如果在一定时间内有人能提出一个字符串,使得它哈希后的值跟已知值匹配(实际上意味着转账方授权了接收方来提现),则这笔钱转给接收方。
不太恰当的例子,约定一定时间内,有人知道了某个暗语(可以生成匹配的哈希值),就可以拿到这个指定的资金。
推广一步,甲想转账给丙,丙先发给甲一个哈希值。甲可以先跟乙签订一个合同,如果你在一定时间内能告诉我一个暗语,我就给你多少钱。乙于是跑去跟丙签订一个合同,如果你告诉我那个暗语,我就给你多少 钱。丙于是告诉乙暗语,拿到乙的钱,乙又从甲拿到钱。最终达到结果是甲转账给丙。这样甲和丙之间似乎构成了一条完整的虚拟的“支付通道”。
HTLC 的机制可以扩展到多个人,大家可以想象一下,想象出来了就理解了闪电网络。
闪电网络
RSMC 保障了两个人之间的直接交易可以在链下完成,HTLC 保障了任意两个人之间的转账都可以通过一条“支付”通道来完成。整合这两种机制,就可以实现任意两个人之间的交易都可以在链下完成了。
在整个交易中,智能合约起到了中介的重要角色,而区块链则确保最终的交易结果被确认。
侧链
允许资产在比特币区块链和其它链之间互转。降低核心的区块链上发生交易的次数。
也来自比特币社区,2013 年 12 月提出,2014 年 4 月成立项目。 通过简单地复用现有比特币的方式,实现比特币和其他帐簿资产在多个区块链间的转移。 Blockstream 基于侧链技术探索更多功能,已发布商业化应用 Liquid,并与普华永道进行相关合作。
Ethereum - 以太坊项目
以太坊项目进一步扩展了区块链网络的能力,从交易延伸为智能合约(Smart Contract)。
其官网首页为 ethereum.org。
简介:
- 单独为智能合约指定编程语言 Solidity;
- 使用了内存需求较高的哈希函数:避免出现算力矿机;
- uncle 块激励机制:降低矿池的优势,减少区块产生间隔为 15 秒;
- 难度调整算法:一定的自动反馈机制;
- gas 限制调整算法:限制代码执行指令数,避免循环攻击;
- 记录当前状态的哈希树的根哈希值到区块:某些情形下实现轻量级客户端;
- 为执行智能合约而设计的简化的虚拟机 EVM。
安装
Go
curl -O https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.5.1.linux-amd64.tar.gz
mkdir -p ~/go; echo "export GOPATH=$HOME/go" >> ~/.bashrc
echo "export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc<Paste>
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum
相关工具
客户端
官方提供钱包客户端 Mist,支持进行交易,同时支持直接编写和部署智能合约。
所编写的代码编译发布后,可以部署到区块链上。使用者可通过发送调用相应合约方法的交易,由矿工的以太坊虚拟机(EVM)在区块链上执行。
以太坊现在有多种语言实现的客户端,包括:
- ethereumjs-lib:javascript 语言实现;
- Ethereum(J):Java 语言实现;
- ethereumH:Haskell 语言实现;
- go-ethereum:go 语言实现;
- Parity:Rust 语言实现;
- pyethapp:python 语言实现;
- ruby-ethereum:Ruby 语言实现;
IDE
网站资源
已有一些网站提供对以太坊网络的数据查看,包括 EthStats.net、EtherNodes.com 等。
协议设计
核心概念
- EVM:以太坊虚拟机,轻量级虚拟机环境,是以太坊中智能合约的运行环境。
- Account:账户,分两类:合约账户存储执行的合约代码;外部账户为以太币拥有者账户,对应到某公钥。
- Transaction:交易,从一个账户到另一个账户的消息,包括以太币或者合约执行参数。
- Gas:燃料,每执行一条合约指令会消耗一定的燃料,当某个交易还未执行结束,而燃料消耗完时,合约执行终止并回滚状态。
一致性
目前采用了 PoW 作为一致达成保证,未来可能迁移到 PoS 上。
降低攻击
设计核心思想是通过经济激励机制防止少数人作恶:
- 所有交易都要提供交易费用,避免 DDoS 攻击;
- 程序运行指令数通过 gas 来限制,所消耗的费用超过设定上限时会被取消,避免恶意合约。
提高扩展性
以太坊未来希望通过分片机制可以提高整个网络的扩展性。分片之前整个网络的处理取决于单个节点的处理。 分片后,只有同一片内的处理是同步的、一致的,不同分片之间则可以是异步的。
智能合约设计
- 第一步 生成智能合约代码对象
- 第二步 编译合约代码
- 第三步 设置希望返回的字符串
- 第四步 部署合约
- 第五步 挖矿
- 第六步 停止挖矿(可选)
- 第七步 部署在其他节点上
- 第八步 部署在其他节点上
- 第九步 自毁程序
Hyperledger - 超级账本项目
Hyperledger 项目是首个面向企业的开放区块链技术的重要探索。在 Linux 基金会的支持下,吸引了包括 IBM、Intel、摩根等在内的众多科技和金融巨头的参与。
简介
该项目的出现,实际上宣布区块链技术已经不再是仅面向“社会实验”性质的应用场景,它已经正式被主流机构和企业市场认可;同时,Hyperledger 首次提出和实现的完备权限管理、创新的一致性算法和可拔插、可扩展的框架,对于区块链相关技术和产业的发展都将产生深远的影响。
主要项目
https://github.com/hyperledger/
目前主要包括三大账本平台项目和若干其它项目。 - Fabric:包括 Fabric、Fabric CA、Fabric SDK(包括 Node.Js、Python 和 Java 等语言)和 fabric-api、fabric-sdk-node、fabric-sdk-py 等,目标是区块链的基础核心平台,支持 pbft 等新的 consensus 机制,支持权限管理,最早由 IBM 和 DAH 发起; - SawToothLake:包括 arcade、core、dev-tools、validator、mktplace 等。是 Intel 主要发起和贡献的区块链平台,支持全新的基于硬件芯片的共识机制 Proof of Elapsed Time(PoET)。 - Iroha:账本平台项目,基于 C++ 实现,带有不少面向 Web 和
项目原则
项目约定共同遵守的 基本原则 为:
重视模块化设计,包括交易、合同、一致性、身份、存储等技术场景; 代码可读性,保障新功能和模块都可以很容易添加和扩展; 演化路线,随着需求的深入和更多的应用场景,不断增加和演化新的项目。 如果你对 Hyperledger 的源码实现感兴趣,可以参考 Hyperledger 源码分析之 Fabric。
开发和提交代码
小结
Hyperledger 是 Linux 基金会支持的分布式账本平台,这是开源界试图构建一套标准化分布式账本平台的重要尝试。 类似的项目还包括 以太坊平台、R3 CEV 牵头的 Corda 项目、微软的 bletchley 项目 等。
Fabric 部署与管理
本章讲了如何部署 Fabric 和交互
区块链应用开发
给出了几个示例: - 信息公证 - 交易资产 - 数字货币发行与管理:中央银行、商业银行、企业 - 学历认证 - 社区能源共享
Fabric 架构与设计
架构设计
包括三大组件:区块链服务(Blockchain)、链码服务(Chaincode)、成员权限管理(Membership)。 术语、区块链服务、交易、区块、链码服务、接口和操作、容器、gRPC消息、成员权限管理
消息协议
消息分为四大类:Discovery(探测)、Transaction(交易)、Synchronization(同步)、Consensus(一致性)。
区块链服务平台设计
区块链平台作为分布式基础设施,其部署和维护过程需要多方面的技能,这对很多应用开发者来说都是不小的挑战。为了解决这些问题,区块链即服务(Blockchain as a Service, BaaS)平台应运而生。BaaS 可以利用云服务基础设施的部署和管理优势,为开发者提供创建、使用,甚至安全监控区块链平台的快捷服务。目前,业界已有一些区块链前沿技术团队率先开发并上线了区块链服务平台。
IBM Bluemix 云区块链服务
Bluemix 是 IBM 推出的开放的 PaaS 云平台,包含大量平台和软件服务,旨在帮助开发者实现一站式地应用开发与部署管理。 2016 年,Bluemix 面向开发者推出了基于超级账本 Fabric 的区块链服务,供全球的区块链爱好者使用。用户可以通过访问 https://console.ng.bluemix.net/catalog/services/blockchain 使用该服务。
微软 Azure 云区块链服务
Azure 是微软推出的云计算平台,向用户提供开放的 IaaS 和 PaaS 服务。
Azure 陆续在其应用市场中提供了若干个与区块链相关的服务,分别面向多种不同的区块链底层平台,其中包括以太坊和超级账本 Fabric。
可以在应用市场(https://azuremarketplace.microsoft.com/en-us/marketplace/apps)中搜索 “blockchain” 关键字查看这些服务,如下图所示。
使用超级账本 Cello 搭建区块链服务
超级账本的 Cello 项目为本地搭建区块链服务管理平台提供了开源的解决方案,可以实现在多种类型的物理资源上实现区块链网络的生命周期管理。
性能与评测
过早优化,往往引来各种麻烦。 一项技术究竟能否实用,有两项基本指标十分关键:一是功能的完备;一是性能的达标。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论