丰富的线上&线下活动,深入探索云世界
做任务,得社区积分和周边
最真实的开发者用云体验
让每位学生受益于普惠算力
让创作激发创新
资深技术专家手把手带教
遇见技术追梦人
技术交流,直击现场
海量开发者使用工具、手册,免费下载
极速、全面、稳定、安全的开源镜像
开发手册、白皮书、案例集等实战精华
为开发者定制的Chrome浏览器插件
邢有涛
菜根科技技术总监
简单来说,区块链是比特币的底层技术。谈到区块链,就不得不先说一下比特币。对于“比特币(Bitcoin)”这个词,有三层含义。首先,比特币特指一种加密数字货币,是最早也是目前规模最大的加密数字货币。其次,比特币协议可以被看成一种基于区块链的“价值传输协议”,该协议可以用来描述数字资产是如何在区块链上转移的。最后,比特币系统指底层的共有区块链技术平台,包含去中心化的公开总帐、比特币钱包等软件和系统。
比特币(Bitcoin)是一种全球通用的加密电子货币(Crypto-Currency),完全交由用户们自治的交易工具。比特币的概念由中本聪(SatoshiNakamoto)在2008年11月发表的论文《Bitcoin:APeer-to-PeerElectronicCashSystem》中首次提出。与数字货币不同,比特币完全是去中心化的,不依靠特定机构来发行,而是依据特定算法,通过大量的计算产生。比特币系统使用整个P2P网络中众多节点构成的分布式数据库对所有的事务进行确认并记录,并使用密码学的设计来确保货币流通各个环节安全性。
尽管比特币P2P网络中的各个节点相互对等,但是根据所提供的功能不同,各节点可能具有不同的分工。每个比特币节点都是路由、区块链数据库、挖矿、钱包服务的功能集合。一个全节点(FullNode)包括钱包、完整区块链、矿工、网络路由节点四个功能。
现在我们重新回到区块链的话题上来。
链上的每个区块都可以用来记录货币、股权、债券、数字签名、数字合约,或其它任何数字化内容。在全球网络下,由无数独立的计算机来维护、更新和核查,确保记账结果的公平、公正和公开透明,而无需任何中心化机构的审核和维护。
我们仍然以比特币为例,说明区块链形成过程:
比特币区块链主要使用PoW来实现共识。通过使用单向函数挖掘,使得矿工在得到正确的计算结果前,必须经过公开算法的计算,而结果的验证速度非常快。通过验证这个结果,其他矿工就可以确认是执行了一定量的计算工作才得出的。
PoW的优点是:完全去中心化,节点自由进出。
DPoS类似于董事会投票,它的原理是让每一个持有比特股的人进行投票,由此产生101位代表可以将其理解为101个超级节点或者矿池,而超级节点彼此的权利是完全相等的。DPoS有点像是美国的议会制度,如果代表不能履行他们的职责(无法生成区块),即被除名,网络会选出新的超级节点来取代他们。
DPoS可以大幅缩小参与验证和记账节点的数量,可以达到秒级的共识验证。
中本聪巧妙地将以下几个成熟的技术和理论组合的一起,并以此为基础构建区块链技术:
如果同时具有上述四点要素,可以认为这是一种公共区块链技术,简称公有链。如果只具有前三点要素,将其称为私有区块链技术,简称私有链。而联盟链则介于两者之间,可视为联盟成员内的一种私有链。这里主要介绍公有链和私有链。
公有链是指全世界任何人都可读取的、任何人都能发送事务且能获得有效确认的、任何人都能参与共识过程的区块链。共识过程决定哪个区块可被添加到区块链中和明确当前状态。作为中心化或者准中心化信任的替代物,公有链的安全由加密数字经济维护。加密数字经济采取工作量证明机制或权益证明机制等方式,将经济奖励和加密数字验证结合了起来,并遵循着一般原则:每个人从中可获得的经济奖励,与对共识过程作出的贡献成正比。这些区块链通常被认为是完全去中心化的。
私有链相比于公有链的优点:
私有链的缺点:
公有链的优点:
因此使用公有链,还是私有链,完全根据需求而定。
区块链1.0:可编程的数字货币
比特币的发明人SatoshiNakamoto在其2008.11年发表的论文《BitCoin:APeer-to-PeerElectronicCashSystem》中指出:“区块链是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方案。”
区块链1.0的主要应用领域为“加密数字货币”,包括货币的发行机制、分配机制、币值调节机制等。
比特币可视为区块链的首个在金融支付领域中的应用。比特币所产生和使用的区块链,是最早也是目前应用最广泛的公有区块链。
区块链2.0:可编程的智能合约
在2015年10月召开的“2015首届全球区块链峰会”上,以太坊的创始人VitalikButerin发表了题为《Visions,Part1:TheValueofBlockchainTechnology》主题演讲,并重新定义了区块链:“一个区块链就是一个任何人都可以上传程序并使其自己执行的神奇电脑,每个程序的当前和所有过去状态都是公共可见的,强大的密码经济学保证程序能够按照该区块链协议所定义的方式持续执行。”
区块链成为一种“信任的机器”,通过自我限制和安全加密,确保机器能安全可信地自动执行预设的逻辑。
区块链2.0的主要应用领域为智能合约。智能合约能够令各方自动执行操作,结果由软件验证,而非人类扮演中介。
典型应用:
区块链3.0:可编程的社会治理
区块链3.0目前没有严格的定义,总的来说有两大类应用:
区块链3.0的主要应用领域为社会治理:
Ethereum以太坊是运行在区块链技术上的开放平台,使开发人员能够建立和发布下一代分布式应用DApp。
Ethereum可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易、众筹、公司管理、合约、知识产权、硬件集成的智能资产。
区块链2.0重要的是智能合约、智能资产,而智能合约领域最有影响力的开发平台就是以太坊。
自行车的所有者会将一个Slock(智能锁)安装到他们的自行车上,并且在以太坊区块链上给自行车注册一个智能合约(一段程序代码)。接下来,任何人都可以向该智能合约发起一个发送一定数量数字货币的请求,合约在接到这个请求之后,会自动将这笔数字货币转发给自行车的所有者,这样发送者可以获得2个小时的使用权。
挖矿这个词源于对加密货币与黄金的类比。黄金或贵金属很稀有,电子代币也是,增加总量的唯一方法就是挖矿;同时,挖矿也是通过在区块链中创建、验证、发行和传播区块的方法来保护网络的。
挖以太币=保护网络=验证计算
以太坊,与所有的区块链技术一样,使用激励驱动的安全模式。共识基于选择具有最高总难度的区块。矿工创建区块,其他人检测有效性。
以太坊区块链上的所有行为都是由外部账户通过transaction触发的。每当合约账户接收到transaction,就按照输入参数的指示执行。合约代码是由参与到网络的每个节点上的以太坊虚拟机执行。
所有以太币余额和价值都以wei为单位:1ether=1e18wei
transaction在以太坊里指被签名的数据包,数据包存储着从外部账户发送到区块链上另一账户的消息。
transaction包括:
合约可以发送消息给其他的合约。消息是虚拟对象,不能被序列化,只能存在于以太坊的执行环境下。可以被想象成函数调用。
消息包括:
本质上,消息就像transaction,只不过消息是由合约而不是由外在因素创造的。
当消息或transaction触发合约执行时,每个指令在每个网络节点都被执行。这是需要代价的:每个执行的操作都有特定的成本,以一定量的gas单元表现。
Gas是transaction发送方需要为每个以太坊区块链上发生的操作所支付的执行费用。Gas名字的灵感来自一个观点:这笔费用就像加密燃料,驱使智能合约的运行。Gas从执行代码的矿工处购买以太币。
Gas和以太币被故意分开,因为Gas单位与自然成本的运算类似,而以太币的价格是根据市场而波动的。
Gas价格实际上由矿工决定,矿工可以拒绝以低于最低限度的gas价格进行transaction。
以太坊客户端会自用使用以太币购买gas,数量是指定的transaction最大支出。
在每个合约执行或每个transaction的运算步骤,以太坊协议都要收费,以防止以太坊网络上发生蓄意攻击或滥用。
每个transaction都必须包含gas限额和愿意支付的gas花费。如果transaction产生的、用于运算步骤的gas总量,包括原始消息和可能引发的子消息,少于或等于gas限额,那么transaction就会进行;如果总量超过限额,那么所有变化都会复原,但是transaction仍然有效,矿工可以收集花费,多余的gas会以以太币的形式偿还给发送方。
估算transaction成本:
transaction花费的以太币总量基于两个因素:
总成本=gasUsed*gasPrice
gasUsed
以太坊虚拟机上的每个操作都会被指派消费的gas数量。gasUsed是所有执行的操作所需的gas总额。有个电子表格可以看到背后的一些统计。
gasPrice
用户建构并签署transaction,每个用户可以说明自己想要的gasPrice,可以是零。然而Frontier发布的以太坊客户端默认gasPrice是0.05e12wei。由于矿工会使收入最优化,如果大部分transaction都以0.05e12wei的gasPrice提交,就很难说服矿工接受价格更低或为0的transaction。
示例transaction成本
我们来做一个只添加2个数字的合约。EVMOPCODEADD消费3gas。
大概的成本,以默认gas价格计算(2016年1月)是:
3*0.05e12=1.5e11wei
这是个简化的计算,忽略了一些成本。
EVM:在底层,以太坊基于区块链技术,实现了数据的去中心化、分布式存储和信息交换的信任问题。同时,以太坊实现了一个叫EthereumVirtualMachine(EVM)的运行时环境,类似JVM,它的主要工作是执行智能合约(该概念下面会介绍)的位元组码。
接口:
1.JavascriptConsole:以太坊客户端会启动一个相互的console,提供javascript运行环境,可以使用javascriptAPI与节点交互。
2.JSON-RPCserver:节点可以启动json-rpc服务器,从而暴露JSON-RPCAPI
3.命令行:geth
结合以上概念,归纳Ethereum工作流程:
以太坊的基础单元是账户,跟踪每个账户的状态,所有以太坊区块链上的状态转换都是账户之间价值和信息的转移。
外有账户是由人类用户掌控,因为人类用户能够控制私钥,进而控制外有账户。而合约账户则是由内部代码管控。智能合约指的是合约账户中的代码:事务被发送给该账户时所运行的程序。用户可以通过在区块链中部署代码来创建新的合约。
只有外有账户发出事务时,合约账户才会执行相应的操作,合约账户不可能自发地执行。因为以太坊要求节点能够与运算结果保持一致,这就要求保证严格确定执行。
以太坊用户必须向网络支付少量事务费用。这可以使以太坊区块链免受无关紧要或恶意的运算任务干扰,比如分布式拒绝服务(DDoS)攻击或无限循环。事务的发送者必须在激活的合约账户的每一步付款,包括运算和数据存储。费用通过以太坊Gas结算,以太币的形式支付。
事务费用由节点收集,矿工是以太坊网络中收集、传播、确认和执行事务的节点。矿工们将事务分组:以太坊区块链中账户状态的更新被分成的组存储在区块中(Block),矿工们会互相竞争,以使各自的区块(Block)可以添加到区块链的下一个节点上。矿工们每挖到一个成功的区块就会得到以太币奖励,这就为矿工带来了经济激励,促使矿工为以太坊网络贡献硬件和电力。
矿工们通过解决复杂数学问题的任务以便成功地挖到区块(Block)。这被称为工作量证明(PoW)。一个运算问题,如果在算法上解决,比验证解决方法需要更多数量级的资源,那么它就是工作证明的最好选择。为防止比特币网络中已经发生的专用硬件(例如特定用途集成电路)造成的中心化现象,以太坊选择了难以存储的运算问题。这就使以太坊的工作量证明具有抗特定用途集成电路性,和比特币这种由专门硬件控制挖矿的区块链相比,能够带来更加去中心化的安全分布。
为了搭建本地测试网络,需要完成三件工作:
以下就分别开始介绍。
Ethereum客户端类似于Java虚拟机,按照黄皮书执行;项目早期,在不同的操作系统中就有多个可以彼此协作的客户端实现:go-ethereum、cpp-ethereum、pyethapp、ruby-ethereum等等。
进入Homestead阶段后,Go客户端(geth)占据了主导地位,因此我们也采用go-ethereum完成测试网络的搭建。
1.首先在选择的目录下clone客户端代码go-ethereum
2.构建geth前需要安装额外库:
mac系统:
ubuntu系统:
3.最后,就可以使用以下命令编译geth了:
编译成功生成build/bin/geth
现在进入构建solidity编译器(源码安装)的流程:
1.首先在选择的目录下clonesolidity的编译器代码
2.安装依赖
3.最后,就可以使用以下命令编译solc了
geth和solc编译完成后,重新回到go-ethereum代码根目录
1.创建初始区块:
初始区块是区块链的起始:第一个区块,区块0,唯一没有指向前面区块的一个区块。除非与其他节点具有相同的初始区块,协议确保了这些节点不会和该区块链一致。这样就可以创建任意的私有测试网络区块链。
2.启动geth:
下面介绍上述命令中的主要参数:
1.--nodiscover:使用这个命令可以确保你的节点不会被非手动添加你的人发现。否则,你的节点可能被陌生人的区块链无意添加,如果他和你有相同的初始文件和网络ID。
2.--rpc:可以激活你节点上的RPC接口。它在geth中通常被默认激活。
3.--rpcapi:这个命令可以决定允许什么API通过RPC进入。在默认情况下,geth可以在RPC激活web3界面。
4.--rpcport:改变RPC上的开放端口。
5.--rpccorsdomain“*”:可以指示什么URL能连接到你的节点来执行RPC定制端任务。
6.--datadir“test/chain”:私有链数据所储存在的数据目录
7.--identity:为节点设置一个身份,使之更容易在端点列表中被辨认出来。
8.--solc:制定solc编译器
编写智能合约的高级语言有:solidity、serpent、LLL、Mutan。
我们以multiply为例开始第一个Solidity的智能合约。
合约代码如下:
contracttest{
functionmultiply(uinta)returns(uintd){
returna*7;
}
首先将合约test赋值变量source,然后使用solidity编译器进行编译,将返回结果赋值给contract。
下面简要描述一下contract的字段:
确保有解锁的账户和资金,部署完成后,在区块链上就会创建一个合约。这一步骤是需要支付执行的。一旦transaction成功进入区块,账户余额会根据以太坊虚拟机的gas规则被扣减。
与合约交互典型做法是使用eth.contract()功能的抽象层,它会返回javascript对象。描述合约可用功能的标准方法是ABI定义。
当sendTransaction被调用时,功能调用通过发送transaction来执行。需要花费以太币发送,记录会永久记录在区块链上。这种方式返回的是transaction散列。
当call被调用时,功能在以太坊虚拟机本地执行。用这种方式进行的调用不会记录在区块链上,因此不会改变合约内部状态。这种调用方式被称为恒定功能调用,不花费以太币。
最后,有兴趣的朋友,也可以尝试testrpc和truffle,更加方便。
Q1:一次交易都要在以太坊的所有节点的EVM上执行一遍吗?
A1:是的。区块链其实是比较昂贵的,它的目的不是为了提升效率。在EthereumHomestead里是这样描述的:Eachandeveryfullnodeinthenetworkdoesthesamecalculationsandstoresthesamevalues.ClearlyEthereumisnotaboutoptimisingefficiencyofcomputation.Itsparallelprocessingisredundantlyparallel.
Q2:哪些公司用以太坊做开发基础?
A2:国内的金丘股份,万向区块链实验室,众安保险,蚂蚁金服。
Q3:智能合约的代码量最大是1M吗?也就是一个区块的大小?
A3:1M是比特币的区块限制。
Q4:以太坊同步一次要多久?
A4:比特币区块链的大小约为84.9GB,现在以太坊的区块链还比较小,第一次同步的时候,持续的十个小时左右,于网络速率有关。
Q5:如果由于网络中断,导致出现两条链,当网络恢复后,如何合并这两条链?
A5:不会合并的。最终还是拼的算力。
(接上一问)
Q6:这样不是会导致很多分叉吗?
Q7:如果智能合约太大,无法在一个区块中写入,以太坊如何操作?
A7:因为合约之间可以通过消息调用,所以可以把代码拆开,分别deploy。当然前提是真得有这么大的合约。