以太坊_以太坊导以太坊导 - CSDN
以太坊 订阅
以太坊(英文Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(Ethereum Virtual Machine)来处理点对点合约。以太坊的概念首次在2013至2014年间由程序员Vitalik Buterin受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹开始得以发展。截至2018年2月,以太币是市值第二高的加密货币,仅次于比特币。 展开全文
以太坊(英文Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(Ethereum Virtual Machine)来处理点对点合约。以太坊的概念首次在2013至2014年间由程序员Vitalik Buterin受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹开始得以发展。截至2018年2月,以太币是市值第二高的加密货币,仅次于比特币。
信息
创始人
杰弗里•维尔克
外文名
Ethereum
中文名
以太坊
属    性
平台
以太坊产生背景
比特币开创了去中心化密码货币的先河,五年多的时间充分 检验了区块链技术的可行性和安全性。比特币的区块链事实上是一套分布式的数据库,如果再在其中加进一个符号——比特币,并规定一套协议使得这个符号可以在数据库上安全地转移,并且无需信任第三方,这些特征的组合完美地构造了一个货币传输体系——比特币网络。然而比特币并不完美,其中协议的扩展性是一项不足,例如比特币网络里只有一种符号——比特币,用户无法自定义另外的符号,这些符号可以是代表公司的股票,或者是债务凭证等,这就损失了一些功能。另外,比特币协议里使用了一套基于堆栈的脚本语言,这语言虽然具有一定灵活性,使得像多重签名这样的功能得以实现,然而却不足以构建更高级的应用,例如去中心化交易所等。以太坊从设计上就是为了解决比特币扩展性不足的问题。
收起全文
  • 通过这个课程的学习,我们可以了解以太坊发展的轨迹,学会洞察智能合约的漏洞,学会如何发币以及具备一定的智能合约开发技能,让学习者在区块链的大潮中立于不败之地。 本科主要介绍5个智能合约项目,包括1.奖金...
  • 孟岩老师从比特币入手,深入分析区块链的基本原理和知识,在此基础上拨云见日地带领学员入门以太坊,让学员迅速掌握发币、转账、挖矿的基本步骤和技能。
  • 以太坊开发入门

    2019-12-30 15:53:44
    本课程是一个系列基础教程,目标是带领读者上手实战,课程以以太坊为核心,带领到家从具体的以太坊节点部署、真实环境同步及问题、 以太坊节点json-rpc接口调用等,以及这个过程中的经验分享。
  • 以太坊:源码解读

    2018-12-26 10:02:09
    源码解读是深入了解一个产品最好的方式,通过以太坊源码可以理解以太坊的基本设计思想,智能合约的实现过程; 本教程由浅入深为你讲述以太坊区块链的实现过程,如何实现交易,如何实现EVM等关键技术
  • 【课程简介】本套以太坊课程,对以太坊基础理论知识和架构做了系统的梳理和深入的阐述,并对solidity和DApp的开发做了系统讲解,另外还对以太坊白皮书、黄皮书做了介绍;为有志于学习区块链技术、了解以太坊底层架构...
  • 以太坊简介

    2020-07-21 09:56:46
    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球已有200多个以太坊应用诞生。以太坊是一个平台和一种编程语言,使开发人员...
  • 1. 以太坊的介绍 以太坊是一个开放的区块链平台,允许任何人在平台中建立和使用通过区块链技术运行的去中心化应用,同比特币一样,以太坊由全球范围的很多人共同创建,不受任何个人控制。 2. 下一代区块链 ...

    本文个人博客地址:http://www.huweihuang.com/article/ethereum/ethereum-introduction/

    1. 以太坊的介绍

    以太坊是一个开放的区块链平台,允许任何人在平台中建立和使用通过区块链技术运行的去中心化应用,同比特币一样,以太坊由全球范围的很多人共同创建,不受任何个人控制。

    2. 下一代区块链

    区块链技术是比特币的底层技术。在比特币中,分布式数据库被设想为一个账户余额表(总账),交易通过比特币的转移来实现个体之间无需信任基础的金融活动。以太坊试图实现一个总体上完全无需信任基础的智能合约平台。

    3. 以太坊虚拟机

    以太坊是可编程的区块链,不会给用户一系列预先设置好的操作,允许用户自定义复杂的操作。以太坊狭义上是指一系列定义去中心化应用平台的协议,核心是以太坊虚拟机(EVM),其可以执行任意复杂算法的编码。以太坊是图灵完备的。

    以太坊也有一个点对点的网络协议,以太坊区块链数据库由各网络节点来维护和更新,每个节点运行以太坊虚拟机并执行相同的指令,保证区块链的一致性。

    4. 以太坊工作原理

    比特币可以看作是关于交易的列表,而以太坊的基础单元是账户。以太坊跟踪每个账户的状态,以太坊上所有状态转换都是账户之间价值和信息的转换。

    账户分为两类:

    • 外部账户(EOA):由私人密钥控制
    • 合约账户:由合约代码控制,只能由外部账户“激活”。

    智能合约:指合约账户中的编码,即交易被发送给该账户时所运行的程序。用户可以通过在区块链中部署编码来创建新的合约。

    只有当外部账户发出指令时,合约账户才会执行相应的操作,是为了保证正确执行所有操作。

    和比特币一样,以太坊用户需要向网络支付少量的交易费用,通过以太币的形式支付。这样避免受到类似DDos的攻击。

    交易费用由节点收集,节点使网络生效。“矿工”就是以太坊网络中收集、传播、确认和执行交易的节点。矿工将交易打包,打包的数据成为区块,打包的过程就是将以太坊中账户的状态更新的过程。矿工们相互竞争挖矿,成功挖矿的可以得到以太币的奖励。

    参考:

    展开全文
  • 作为公有区块链平台,以太坊将比特币针对数字货币交易的功能进一步进行拓展,面向更为复杂和灵活的应用场景,支持了智能合约(Smart Contract)这一重要特性。 从此,区块链技术的应用场景,从单一基于 UTXO 的数字...

     

     

     

    君子和而不同。

    在区块链领域,以太坊项目同样是十分出名的开源项目。作为公有区块链平台,以太坊将比特币针对数字货币交易的功能进一步进行拓展,面向更为复杂和灵活的应用场景,支持了智能合约(Smart Contract)这一重要特性。

    从此,区块链技术的应用场景,从单一基于 UTXO 的数字货币交易,延伸到图灵完备的通用计算领域。用户不再受限于仅能使用比特币脚本所支持的简单逻辑,而是可以自行设计任意复杂的合约逻辑。这就为构建各种多样化的上层应用开启了大门,可谓意义重大。

    本章将参照比特币项目来介绍以太坊项目的核心概念和改进设计,以及如何安装客户端和使用智能合约等内容。

    以太坊项目简介

    以太坊项目

    图 1.10.1.1 - 以太坊项目

    以太坊(Ethereum)项目的最初目标,是打造一个运行智能合约的平台(Platform for Smart Contract)。该平台支持图灵完备的应用,按照智能合约的约定逻辑自动执行,理想情况下将不存在故障停机、审查、欺诈,以及第三方干预等问题。

    以太坊平台目前支持 Golang、C++、Python 等多种语言实现的客户端。由于核心实现上基于比特币网络的核心思想进行了拓展,因此在很多设计特性上都与比特币网络十分类似。

    基于以太坊项目,以太坊团队目前运营了一条公开的区块链平台——以太坊网络。智能合约开发者使用官方提供的工具和以太坊专用应用开发语言 Solidity,可以很容易开发出运行在以太坊网络上的“去中心化”应用(Decentralized Application,DApp)。这些应用将运行在以太坊的虚拟机(Ethereum Virtual Machine,EVM)里。用户通过以太币(Ether)来购买燃料(Gas),维持所部署应用的运行。

    以太坊项目的官网网站为 ethereum.org,代码托管在 github.com/ethereum

    以太坊项目简史

    相对比特币网络自 2009 年上线的历史,以太坊项目要年轻的多。

    2013 年底,比特币开发团队中有一些开发者开始探讨将比特币网络中的核心技术,主要是区块链技术,拓展到更多应用场景的可能性。以太坊的早期发明者 Vitalik Buterin 提出应该能运行任意形式(图灵完备)的应用程序,而不仅仅是比特币中受限制的简单脚本。该设计思想并未得到比特币社区的支持,后来作为以太坊白皮书发布。

    2014 年 2 月,更多开发者(包括 Gavin Wood、Jeffrey Wilcke 等)加入以太坊项目,并计划在社区开始以众筹形式募集资金,以开发一个运行智能合约的信任平台。

    2014 年 7 月,以太币预售,经过 42 天,总共筹集到价值超过 1800 万美金的比特币。随后在瑞士成立以太坊基金会,负责对募集到的资金进行管理和运营;并组建研发团队以开源社区形式进行平台开发。

    2015 年 7 月底,以太坊第一阶段 Frontier 正式发布,标志着以太坊区块链网络的正式上线。这一阶段采用类似比特币网络的 PoW 共识机制,参与节点以矿工挖矿形式维护网络;支持上传智能合约。Frontier 版本实现了计划的基本功能,在运行中测试出了一些安全上的漏洞。这一阶段使用者以开发者居多。

    2016 年 3 月,第二阶段 Homestead 开始运行(区块数 1150000),主要改善了安全性,同时开始提供图形界面的客户端,提升了易用性,更多用户加入进来。

    2016 年 6 月,DAO 基于以太坊平台进行众筹,受到漏洞攻击,造成价值超过 5000 万美金的以太币被冻结。社区最后通过硬分叉(Hard Fork)进行解决。

    2017 年 3 月,以太坊成立以太坊企业级联盟(Enterprise Ethereum Alliance,EEA),联盟成员主要来自摩根大通,微软,芝加哥大学和部分创业企业等。

    2017 年 11 月,再次暴露多签名钱包漏洞,造成价值 2.8 亿美元的以太币被冻结。

    目前,以太坊网络支持了接近比特币网络的交易量,成为广受关注的公有链项目。

    后续按照计划将发布第三阶段 Metropolis 和第四阶段 Serenity,主要特性包括支持 PoS 股权证明的共识机制,以降低原先 PoW 机制造成的能耗浪费;以及图形界面的钱包,以提升易用性。

    包括 DAO 在内,以太坊网络已经经历了数次大的硬分叉,注意每次硬分叉后的版本对之前版本并不兼容。

    主要特点

    以太坊区块链底层也是一个类似比特币网络的 P2P 网络平台,智能合约运行在网络中的以太坊虚拟机里。网络自身是公开可接入的,任何人都可以接入并参与网络中数据的维护,提供运行以太坊虚拟机的资源。

    跟比特币项目相比,以太坊区块链的技术特点主要包括:

    • 支持图灵完备的智能合约,设计了编程语言 Solidity 和虚拟机 EVM;
    • 选用了内存需求较高的哈希函数,避免出现强算力矿机、矿池攻击;
    • 叔块(Uncle Block)激励机制,降低矿池的优势,并减少区块产生间隔(10 分钟降低到 15 秒左右);
    • 采用账户系统和世界状态,而不是 UTXO,容易支持更复杂的逻辑;
    • 通过 Gas 限制代码执行指令数,避免循环执行攻击;
    • 支持 PoW 共识算法,并计划支持效率更高的 PoS 算法。

    此外,开发团队还计划通过分片(Sharding)方式来解决网络可扩展性问题。

    这些技术特点,解决了比特币网络在运行中被人诟病的一些问题,让以太坊网络具备了更大的应用潜力。

    核心概念

    基于比特币网络的核心思想,以太坊项目提出了许多创新的技术概念,包括智能合约、基于账户的交易、以太币和燃料等。

    智能合约

    智能合约(Smart Contract)是以太坊中最为重要的一个概念,即以计算机程序的方式来缔结和运行各种合约。最早在上世纪 90 年代,Nick Szabo 等人就提出过类似的概念,但一直依赖因为缺乏可靠执行智能合约的环境,而被作为一种理论设计。区块链技术的出现,恰好补充了这一缺陷。

    以太坊支持通过图灵完备的高级语言(包括 Solidity、Serpent、Viper)等来开发智能合约。智能合约作为运行在以太坊虚拟机(Ethereum Virual Machine,EVM)中的应用,可以接受来自外部的交易请求和事件,通过触发运行提前编写好的代码逻辑,进一步生成新的交易和事件,可以进一步调用其它智能合约。

    智能合约的执行结果可能对以太坊网络上的账本状态进行更新。这些修改由于经过了以太坊网络中的共识,一旦确认后无法被伪造和篡改。

    账户

    在之前章节中,笔者介绍过比特币在设计中并没有账户(Account)的概念,而是采用了 UTXO 模型记录整个系统的状态。任何人都可以通过交易历史来推算出用户的余额信息。而以太坊则采用了不同的做法,直接用账户来记录系统状态。每个账户存储余额信息、智能合约代码和内部数据存储等。以太坊支持在不同的账户之间转移数据,以实现更为复杂的逻辑。

    具体来看,以太坊账户分为两种类型:合约账户(Contracts Accounts)和外部账户(Externally Owned Accounts,或 EOA)。

    • 合约账户:存储执行的智能合约代码,只能被外部账户来调用激活;
    • 外部账户:以太币拥有者账户,对应到某公钥。账户包括 nonce、balance、storageRoot、codeHash 等字段,由个人来控制。

    当合约账户被调用时,存储其中的智能合约会在矿工处的虚拟机中自动执行,并消耗一定的燃料。燃料通过外部账户中的以太币进行购买。

    交易

    交易(Transaction),在以太坊中是指从一个账户到另一个账户的消息数据。消息数据可以是以太币或者合约执行参数。

    以太坊采用交易作为执行操作的最小单位。每个交易包括如下字段:

    • to:目标账户地址。
    • value:可以指定转移的以太币数量。
    • nonce:交易相关的字串,用于防止交易被重放。
    • gasPrice:执行交易需要消耗的 Gas 价格。
    • gasLimit:交易消耗的最大 Gas 值。
    • data: 交易附带字节码信息,可用于创建/调用智能合约。
    • signature:签名信息。

    类似比特币网络,在发送交易时,用户需要缴纳一定的交易费用,通过以太币方式进行支付和消耗。目前,以太坊网络可以支持超过比特币网络的交易速率(可以达到每秒几十笔)。

    以太币

    以太币(Ether)是以太坊网络中的货币。

    以太币主要用于购买燃料,支付给矿工,以维护以太坊网络运行智能合约的费用。以太币最小单位是 wei,一个以太币等于 10^18 个 wei。

    以太币同样可以通过挖矿来生成,成功生成新区块的以太坊矿工可以获得 3 个以太币的奖励,以及包含在区块内交易的燃料费用。用户也可以通过交易市场来直接购买以太币。

    目前每年大约可以通过挖矿生成超过一千万个以太币,单个以太币的市场价格目前超过 300 美金。

    燃料

    燃料(Gas),控制某次交易执行指令的上限。每执行一条合约指令会消耗固定的燃料。当某个交易还未执行结束,而燃料消耗完时,合约执行终止并回滚状态。

    Gas 可以跟以太币进行兑换。需要注意的是,以太币的价格是波动的,但运行某段智能合约的燃料费用可以是固定的,通过设定 Gas 价格等进行调节。

    主要设计

    以太坊项目的基本设计与比特币网络类似。为了支持更复杂的智能合约,以太坊在不少地方进行了改进,包括交易模型、共识、对攻击的防护和可扩展性等。

    智能合约相关设计

    运行环境

    以太坊采用以太坊虚拟机作为智能合约的运行环境。以太坊虚拟机是一个隔离的轻量级虚拟机环境,运行在其中的智能合约代码无法访问本地网络、文件系统或其它进程。

    对同一个智能合约来说,往往需要在多个以太坊虚拟机中同时运行多份,以确保整个区块链数据的一致性和高度的容错性。另一方面,这也限制了整个网络的容量。

    开发语言

    以太坊为编写智能合约设计了图灵完备的高级编程语言,降低了智能合约开发的难度。

    目前 Solidity 是最常用的以太坊合约编写语言之一。

    智能合约编写完毕后,用编译器编译为以太坊虚拟机专用的二进制格式(EVM bytecode),由客户端上传到区块链当中,之后在矿工的以太坊虚拟机中执行。

    交易模型

    出于智能合约的便利考虑,以太坊采用了账户的模型,状态可以实时的保存到账户里,而无需像比特币的 UXTO 模型那样去回溯整个历史。

    UXTO 模型和账户模型的对比如下。

    特性 UXTO 模型 账户模型
    状态查询和变更 需要回溯历史 直接访问
    存储空间 较大 较小
    易用性 较难处理 易于理解和编程
    安全性 较好 需要处理好重放攻击等情况
    可追溯性 支持历史 不支持追溯历史

    共识

    以太坊目前采用了基于成熟的 PoW 共识的变种算法 Ethash 协议作为共识机制。

    为了防止 ASIC 矿机矿池的算力攻击,跟原始 PoW 的计算密集型 Hash 运算不同,Ethash 在执行时候需要消耗大量内存,反而跟计算效率关系不大。这意味着很难制造出专门针对 Ethash 的芯片,反而是通用机器可能更加有效。

    虽然,Ethash 相对原始的 PoW 进行了改进,但仍然需要进行大量无效的运算,这也为人们所诟病。

    社区已经有计划在未来采用更高效的 Proof-of-Stake(PoS)作为共识机制。相对 PoW 机制来讲,PoS 机制无需消耗大量无用的 Hash 计算,但其共识过程的复杂度要更高一些,还有待进一步的检验。

    降低攻击

    以太坊网络中的交易更加多样化,也就更容易受到攻击。

    以太坊网络在降低攻击方面的核心设计思想,仍然是通过经济激励机制防止少数人作恶:

    • 所有交易都要提供交易费用,避免 DDoS 攻击;
    • 程序运行指令数通过 Gas 来限制,所消耗的费用超过设定上限时就会被取消,避免出现恶意合约。

    这就确保了攻击者试图消耗网络中虚拟机的计算资源时,需要付出经济代价(支付大量的以太币);同时难以通过构造恶意的循环或不稳定合约代码来对网络造成破坏。

    提高扩展性

    可扩展性是以太坊网络承接更多业务量的最大制约。

    以太坊项目未来希望通过分片(sharding)机制来提高整个网络的扩展性。

    分片是一组维护和执行同一批智能合约的节点组成的子网络,是整个网络的子集。

    支持分片功能之前,以太坊整个网络中的每个节点都需要处理所有的智能合约,这就造成了网络的最大处理能力会受限于单个节点的处理能力。

    分片后,同一片内的合约处理是同步的,彼此达成共识,不同分片之间则可以是异步的,可以提高网络整体的可扩展性。

    相关工具

    客户端和开发库

    以太坊客户端可用于接入以太坊网络,进行账户管理、交易、挖矿、智能合约等各方面操作。

    以太坊社区现在提供了多种语言实现的客户端和开发库,支持标准的 JSON-RPC 协议。用户可根据自己熟悉的开发语言进行选择。

    Geth

    上述实现中,go-ethereum 的独立客户端 Geth 是最常用的以太坊客户端之一。

    用户可通过安装 Geth 来接入以太坊网络并成为一个完整节点。Geth 也可作为一个 HTTP-RPC 服务器,对外暴露 JSON-RPC 接口,供用户与以太坊网络交互。

    Geth 的使用需要基本的命令行基础,其功能相对完整,源码托管于 github.com/ethereum/go-ethereum。

    以太坊钱包

    对于只需进行账户管理、以太坊转账、DApp 使用等基本操作的用户,则可选择直观易用的钱包客户端。

    Mist 是官方提供的一套包含图形界面的钱包客户端,除了可用于进行交易,也支持直接编写和部署智能合约。

    Mist 浏览器

    图 1.10.4.1 - Mist 浏览器

    所编写的代码编译发布后,可以部署到区块链上。使用者可通过发送调用相应合约方法的交易,来执行智能合约。

    IDE

    对于开发者,以太坊社区涌现出许多服务于编写智能合约和 DApp 的 IDE,例如:

    • Truffle:一个功能丰富的以太坊应用开发环境。
    • Embark:一个 DApp 开发框架,支持集成以太坊、IPFS 等。
    • Remix:一个用于编写 Solidity 的 IDE,内置调试器和测试环境。

    网站资源

    已有一些网站提供对以太坊网络的数据、运行在以太坊上的 DApp 等信息进行查看,例如:

    • ethstats.net:实时查看网络的信息,如区块、价格、交易数等。
    • ethernodes.org:显示整个网络的历史统计信息,如客户端的分布情况等。
    • dapps.ethercasts.com:查看运行在以太坊上的 DApp 的信息,包括简介、所处阶段和状态等。

    以太坊网络上的 Dapp 信息

    图 1.10.4.2 - 以太坊网络上的 Dapp 信息

    安装客户端

    本节将介绍如何安装 Geth,即 Go 语言实现的以太坊客户端。这里以 Ubuntu 16.04 操作系统为例,介绍从 PPA 仓库和从源码编译这两种方式来进行安装。

    从 PPA 直接安装

    首先安装必要的工具包。

    $ apt-get install software-properties-common
    

    之后用以下命令添加以太坊的源。

    $ add-apt-repository -y ppa:ethereum/ethereum
    $ apt-get update
    

    最后安装 go-ethereum。

    $ apt-get install ethereum
    

    安装成功后,则可以开始使用命令行客户端 Geth。可用 geth --help 查看各命令和选项,例如,用以下命令可查看 Geth 版本为 1.6.1-stable。

    $ geth version
    
    Geth
    Version: 1.6.1-stable
    Git Commit: 021c3c281629baf2eae967dc2f0a7532ddfdc1fb
    Architecture: amd64
    Protocol Versions: [63 62]
    Network Id: 1
    Go Version: go1.8.1
    Operating System: linux
    GOPATH=
    GOROOT=/usr/lib/go-1.8
    

    从源码编译

    也可以选择从源码进行编译安装。

    安装 Go 语言环境

    Go 语言环境可以自行访问 golang.org 网站下载二进制压缩包安装。注意不推荐通过包管理器安装版本,往往比较旧。

    如下载 Go 1.8 版本,可以采用如下命令。

    $ curl -O https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
    

    下载完成后,解压目录,并移动到合适的位置(推荐为 /usr/local 下)。

    $ tar -xvf go1.8.linux-amd64.tar.gz
    $ sudo mv go /usr/local
    

    安装完成后记得配置 GOPATH 环境变量。

    $ export GOPATH=YOUR_LOCAL_GO_PATH/Go
    $ export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
    

    此时,可以通过 go version 命令验证安装 是否成功。

    $ go version
    
    go version go1.8 linux/amd64
    

    下载和编译 Geth

    用以下命令安装 C 的编译器。

    $ apt-get install -y build-essential
    

    下载选定的 go-ethereum 源码版本,如最新的社区版本:

    $ git clone https://github.com/ethereum/go-ethereum
    

    编译安装 Geth。

    $ cd go-ethereum
    $ make geth
    

    安装成功后,可用 build/bin/geth --help 查看各命令和选项。例如,用以下命令可查看 Geth 版本为 1.6.3-unstable。

     

    $ build/bin/geth version
    Geth
    Version: 1.6.3-unstable
    Git Commit: 067dc2cbf5121541aea8c6089ac42ce07582ead1
    Architecture: amd64
    Protocol Versions: [63 62]
    Network Id: 1
    Go Version: go1.8
    Operating System: linux
    GOPATH=/usr/local/gopath/
    GOROOT=/usr/local/go

    使用智能合约

    以太坊社区有不少提供智能合约编写、编译、发布、调用等功能的工具,用户和开发者可以根据需求或开发环境自行选择。

    本节将向开发者介绍使用 Geth 客户端搭建测试用的本地区块链,以及如何在链上部署和调用智能合约。

    搭建测试用区块链

    由于在以太坊公链上测试智能合约需要消耗以太币,所以对于开发者开发测试场景,可以选择本地自行搭建一条测试链。开发好的智能合约可以很容易的切换接口部署到公有链上。注意测试链不同于以太坊公链,需要给出一些非默认的手动配置。

    配置初始状态

    首先配置私有区块链网络的初始状态。新建文件 genesis.json,内容如下。

    {
      "config": {
            "chainId": 22,
            "homesteadBlock": 0,
            "eip155Block": 0,
            "eip158Block": 0
      },
      "alloc"      : {},
      "coinbase"   : "0x0000000000000000000000000000000000000000",
      "difficulty" : "0x400",
      "extraData"  : "",
      "gasLimit"   : "0x2fefd8",
      "nonce"      : "0x0000000000000038",
      "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
      "timestamp"  : "0x00"
    }
    

    其中,chainId 指定了独立的区块链网络 ID,不同 ID 网络的节点无法互相连接。配置文件还对当前挖矿难度 difficulty、区块 Gas 消耗限制 gasLimit 等参数进行了设置。

    启动区块链

    用以下命令初始化区块链,生成创世区块和初始状态。

    $ geth --datadir /path/to/datadir init /path/to/genesis.json
    

    其中,--datadir 指定区块链数据的存储位置,可自行选择一个目录地址。

    接下来用以下命令启动节点,并进入 Geth 命令行界面。

    $ geth --identity "TestNode" --rpc --rpcport "8545" --datadir /path/to/datadir --port "30303" --nodiscover console
    

    各选项的含义如下。

    • --identity:指定节点 ID;
    • --rpc: 表示开启 HTTP-RPC 服务;
    • --rpcport: 指定 HTTP-RPC 服务监听端口号(默认为 8545);
    • --datadir: 指定区块链数据的存储位置;
    • --port: 指定和其他节点连接所用的端口号(默认为 30303);
    • --nodiscover: 关闭节点发现机制,防止加入有同样初始配置的陌生节点;

    创建账号

    用上述 geth console 命令进入的命令行界面采用 JavaScript 语法。可以用以下命令新建一个账号。

    > personal.newAccount()
    
    Passphrase:
    Repeat passphrase:
    "0x1b6eaa5c016af9a3d7549c8679966311183f129e"
    

    输入两遍密码后,会显示生成的账号,如"0x1b6eaa5c016af9a3d7549c8679966311183f129e"。可以用以下命令查看该账号余额。

    > myAddress = "0x1b6eaa5c016af9a3d7549c8679966311183f129e"
    > eth.getBalance(myAddress)
    0
    

    看到该账号当前余额为 0。可用 miner.start() 命令进行挖矿,由于初始难度设置的较小,所以很容易就可挖出一些余额。miner.stop() 命令可以停止挖矿。

    创建和编译智能合约

    以 Solidity 编写的智能合约为例。为了将合约代码编译为 EVM 二进制,需要安装 Solidity 编译器 solc。

    $ apt-get install solc
    

    新建一个 Solidity 智能合约文件,命名为 testContract.sol,内容如下。该合约包含一个方法 multiply,作用是将输入的整数乘以 7 后输出。

    pragma solidity ^0.4.0;
    contract testContract {
      function multiply(uint a) returns(uint d) {
        d = a * 7;
      }
    }
    

    用 solc 获得合约编译后的 EVM 二进制码。

    $ solc --bin testContract.sol
    
    ======= testContract.sol:testContract =======
    Binary:
    6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a72305820748467daab52f2f1a63180df2c4926f3431a2aa82dcdfbcbde5e7d036742a94b0029
    

    再用 solc 获得合约的 JSON ABI(Application Binary Interface),其中指定了合约接口,包括可调用的合约方法、变量、事件等。

    $ solc --abi testContract.sol
    
    ======= testContract.sol:testContract =======
    Contract JSON ABI
    [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"type":"function"}]
    

    下面回到 Geth 的 JavaScript 环境命令行界面,用变量记录上述两个值。注意在 code 前加上 0x 前缀。

    > code = "0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a72305820748467daab52f2f1a63180df2c4926f3431a2aa82dcdfbcbde5e7d036742a94b0029"
    > abi = [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"type":"function"}]
    

    部署智能合约

    在 Geth 的 JavaScript 环境命令行界面,首先用以下命令解锁自己的账户,否则无法发送交易。

    > personal.unlockAccount(myAddress)
    
    Unlock account 0x1b6eaa5c016af9a3d7549c8679966311183f129e
    Passphrase:
    true
    

    接下来发送部署合约的交易。

    > myContract = eth.contract(abi)
    > contract = myContract.new({from:myAddress,data:code,gas:1000000})
    

    如果此时没有在挖矿,用 txpool.status 命令可看到本地交易池中有一个待确认的交易。可用以下命令查看当前待确认的交易。

    > eth.getBlock("pending",true).transactions
    
    [{
        blockHash: "0xbf0619ca48d9e3cc27cd0ab0b433a49a2b1bed90ab57c0357071b033aca1f2cf",
        blockNumber: 17,
        from: "0x1b6eaa5c016af9a3d7549c8679966311183f129e",
        gas: 90000,
        gasPrice: 20000000000,
        hash: "0xa019c2e5367b3ad2bbfa427b046ab65c81ce2590672a512cc973b84610eee53e",
        input: "0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a72305820748467daab52f2f1a63180df2c4926f3431a2aa82dcdfbcbde5e7d036742a94b0029",
        nonce: 1,
        r: "0xbcb2ba94f45dfb900a0533be3c2c603c2b358774e5fe89f3344031b202995a41",
        s: "0x5f55fb1f76aa11953e12746bc2d19fbea6aeb1b9f9f1c53a2eefab7058515d99",
        to: null,
        transactionIndex: 0,
        v: "0x4f",
        value: 0
    }]
    

    可以用 miner.start() 命令挖矿,一段时间后,交易会被确认,即随新区块进入区块链。

    调用智能合约

    用以下命令可以发送交易,其中 sendTransaction 方法的前几个参数与合约中 multiply 方法的输入参数对应。这种方式,交易会通过挖矿记录到区块链中,如果涉及状态改变也会获得全网共识。

    > contract.multiply.sendTransaction(10, {from:myAddress})
    

    如果只是想本地运行该方法查看返回结果,可采用如下方式获取结果。

    > contract.multiply.call(10)
    70

    智能合约案例:投票

    本节将介绍一个用 Solidity 语言编写的智能合约案例。代码来源于 Solidity 官方文档 中的示例。

    该智能合约实现了一个自动化的、透明的投票应用。投票发起人可以发起投票,将投票权赋予投票人;投票人可以自己投票,或将自己的票委托给其他投票人;任何人都可以公开查询投票的结果。

    智能合约代码

    实现上述功能的合约代码如下所示,并不复杂,语法跟 JavaScript 十分类似。

    pragma solidity ^0.4.11;
    
    contract Ballot {
        struct Voter {
            uint weight;
            bool voted;
            address delegate;
            uint vote;
        }
    
        struct Proposal {
            bytes32 name;
            uint voteCount;
        }
    
        address public chairperson;
        mapping(address => Voter) public voters;
        Proposal[] public proposals;
    
        // Create a new ballot to choose one of `proposalNames`
        function Ballot(bytes32[] proposalNames) {
            chairperson = msg.sender;
            voters[chairperson].weight = 1;
    
            for (uint i = 0; i < proposalNames.length; i++) {
                proposals.push(Proposal({
                    name: proposalNames[i],
                    voteCount: 0
                }));
            }
        }
    
        // Give `voter` the right to vote on this ballot.
        // May only be called by `chairperson`.
        function giveRightToVote(address voter) {
            require((msg.sender == chairperson) && !voters[voter].voted);
            voters[voter].weight = 1;
        }
    
        // Delegate your vote to the voter `to`.
        function delegate(address to) {
            Voter sender = voters[msg.sender];
            require(!sender.voted);
            require(to != msg.sender);
    
            while (voters[to].delegate != address(0)) {
                to = voters[to].delegate;
    
                // We found a loop in the delegation, not allowed.
                require(to != msg.sender);
            }
    
            sender.voted = true;
            sender.delegate = to;
            Voter delegate = voters[to];
            if (delegate.voted) {
                proposals[delegate.vote].voteCount += sender.weight;
            } else {
                delegate.weight += sender.weight;
            }
        }
    
        // Give your vote (including votes delegated to you)
        // to proposal `proposals[proposal].name`.
        function vote(uint proposal) {
            Voter sender = voters[msg.sender];
            require(!sender.voted);
            sender.voted = true;
            sender.vote = proposal;
    
            proposals[proposal].voteCount += sender.weight;
        }
    
        // @dev Computes the winning proposal taking all
        // previous votes into account.
        function winningProposal() constant
                returns (uint winningProposal)
        {
            uint winningVoteCount = 0;
            for (uint p = 0; p < proposals.length; p++) {
                if (proposals[p].voteCount > winningVoteCount) {
                    winningVoteCount = proposals[p].voteCount;
                    winningProposal = p;
                }
            }
        }
    
        // Calls winningProposal() function to get the index
        // of the winner contained in the proposals array and then
        // returns the name of the winner
        function winnerName() constant
                returns (bytes32 winnerName)
        {
            winnerName = proposals[winningProposal()].name;
        }
    }
    

    代码解析

    指定版本

    在第一行,pragma 关键字指定了和该合约兼容的编译器版本。

    pragma solidity ^0.4.11;
    

    该合约指定,不兼容比 0.4.11 更旧的编译器版本,且 ^ 符号表示也不兼容从 0.5.0 起的新编译器版本。即兼容版本范围是 0.4.11 <= version < 0.5.0。该语法与 npm 的版本描述语法一致。

    结构体类型

    Solidity 中的合约(contract)类似面向对象编程语言中的类。每个合约可以包含状态变量、函数、事件、结构体类型和枚举类型等。一个合约也可以继承另一个合约。

    在本例命名为 Ballot 的合约中,声明了 2 个结构体类型:Voter 和 Proposal

    • struct Voter:投票人,其属性包括 uint weight(该投票人的权重)、bool voted(是否已投票)、address delegate(如果该投票人将投票委托给他人,则记录受委托人的账户地址)和 uint vote(投票做出的选择,即相应提案的索引号)。
    • struct Proposal:提案,其属性包括 bytes32 name(名称)和 uint voteCount(已获得的票数)。

    需要注意,address 类型记录了一个以太坊账户的地址。address 可看作一个数值类型,但也包括一些与以太币相关的方法,如查询余额 <address>.balance、向该地址转账 <address>.transfer(uint256 amount) 等。

    状态变量

    合约中的状态变量会长期保存在区块链中。通过调用合约中的函数,这些状态变量可以被读取和改写。

    本例中定义了 3 个状态变量:chairpersonvotersproposals

    • address public chairperson:投票发起人,类型为 address
    • mapping(address => Voter) public voters:所有投票人,类型为 address 到 Voter 的映射。
    • Proposal[] public proposals:所有提案,类型为动态大小的 Proposal 数组。

    3 个状态变量都使用了 public 关键字,使得变量可以被外部访问(即通过消息调用)。事实上,编译器会自动为 public 的变量创建同名的 getter 函数,供外部直接读取。

    状态变量还可设置为 internal 或 privateinternal 的状态变量只能被该合约和继承该合约的子合约访问,private 的状态变量只能被该合约访问。状态变量默认为 internal

    将上述关键状态信息设置为 public 能够增加投票的公平性和透明性。

    函数

    合约中的函数用于处理业务逻辑。函数的可见性默认为 public,即可以从内部或外部调用,是合约的对外接口。函数可见性也可设置为 externalinternal 和 private

    本例实现了 6 个 public 函数,可看作 6 个对外接口,功能分别如下。

    创建投票

    函数 function Ballot(bytes32[] proposalNames) 用于创建一个新的投票。

    所有提案的名称通过参数 bytes32[] proposalNames 传入,逐个记录到状态变量 proposals 中。同时用 msg.sender 获取当前调用消息的发送者的地址,记录为投票发起人 chairperson,该发起人投票权重设为 1。

    赋予投票权

    函数 function giveRightToVote(address voter) 实现给投票人赋予投票权。

    该函数给 address voter 赋予投票权,即将 voter 的投票权重设为 1,存入 voters 状态变量。

    这个函数只有投票发起人 chairperson 可以调用。这里用到了 require((msg.sender == chairperson) && !voters[voter].voted) 函数。如果 require 中表达式结果为 false,这次调用会中止,且回滚所有状态和以太币余额的改变到调用前。但已消耗的 Gas 不会返还。

    委托投票权

    函数 function delegate(address to) 把投票委托给其他投票人。

    其中,用 voters[msg.sender] 获取委托人,即此次调用的发起人。用 require 确保发起人没有投过票,且不是委托给自己。由于被委托人也可能已将投票委托出去,所以接下来,用 while 循环查找最终的投票代表。找到后,如果投票代表已投票,则将委托人的权重加到所投的提案上;如果投票代表还未投票,则将委托人的权重加到代表的权重上。

    该函数使用了 while 循环,这里合约编写者需要十分谨慎,防止调用者消耗过多 Gas,甚至出现死循环。

    进行投票

    函数 function vote(uint proposal) 实现投票过程。

    其中,用 voters[msg.sender] 获取投票人,即此次调用的发起人。接下来检查是否是重复投票,如果不是,进行投票后相关状态变量的更新。

    查询获胜提案

    函数 function winningProposal() constant returns (uint winningProposal) 将返回获胜提案的索引号。

    这里,returns (uint winningProposal) 指定了函数的返回值类型,constant 表示该函数不会改变合约状态变量的值。

    函数通过遍历所有提案进行记票,得到获胜提案。

    查询获胜者名称

    函数 function winnerName() constant returns (bytes32 winnerName) 实现返回获胜者的名称。

    这里采用内部调用 winningProposal() 函数的方式获得获胜提案。如果需要采用外部调用,则需要写为 this.winningProposal()

    本章小结

    以太坊项目将区块链技术在数字货币的基础上进行了延伸,提出打造更为通用的智能合约平台的宏大构想,并基于开源技术构建了以太坊为核心的开源生态系统。

    本章内容介绍了以太坊的相关知识,包括核心概念、设计、工具,以及客户端的安装、智能合约的使用和编写等。

    比照比特币项目,读者通过学习可以掌握以太坊的相关改进设计,并学习智能合约的编写。实际上,智能合约并不是一个新兴概念,但区块链技术的出现为智能合约的“代码即律法”提供提供了信任基础和实施架构。通过引入智能合约,区块链技术释放了支持更多应用领域的巨大潜力。

     

     

    展开全文
  • 一、区块链入门介绍 ... 区块链技术:是一个去中心化的数据库,是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。 狭义的说,区块链是按照时间顺序将数据区块以顺序相连的方式组合成的...

    一、区块链入门介绍

    阮一峰写的挺好的:   http://www.ruanyifeng.com/blog/2017/12/blockchain-tutorial.html

    区块链技术:是一个去中心化的数据库,是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。

    狭义的说,区块链是按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改、不开伪造的分布式账本。

    广义来说,区块链技术是利用块链式数据结构来验证与存储数据、利用分布式节点共识算法来生产和更新数据、利用密码学方式保证数据传输和访问的安全、利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式。

    技术特征:

    • 块链式数据结构:每个区块打包记录一段时间内发生的交易是对当前账本的一次共识,并且记录上一个区块的hash值进行关联。
    • 分布式共识算法:技术上杜绝非法篡改数据的可能性
    • 密码学方式:交易信息公开,账户信息加密

    功能特征:

    • 多中心:多机构监督实时对账,提高数据安全性
    • 自动化:智能合约(可以自动化执行一些预先定义好的规则和条款的计算机程序)
    • 可信任:数据不可篡改且可溯源

    基本概念:

    • Transaction交易:导致区块状态变化的操作,一次交易对应唯一的hash值
    • block区块:打包记录一段时间内的交易和状态结果,是对当前账本的一次共识
    • chain链:区块按照时间顺序串联,每个区块记录上一个区块的hash值关联,是整个状态改变的日志

    分类:

    • 许可链:公有链
    • 非许可链:联盟链、私有链

    演化:

    • 1.0 数字货币
    • 2.0 智能合约:以太坊,可以构建智能合约构建DAPP去中心化应用
    • 3.0 超越货币、经济和市场

    分层架构:

    • 数据层:
      • 区块结构:区块头+区块体,可以用区块头hash值和区块高度(不唯一)识别区块
      • merkle树:每个叶子为交易两次SHA256后的hash值,是平衡二叉树,根为所有交易数据的标志
      • 非对称加密与数字签名
      • 时间戳
      • hash函数
    • 网络层
      • P2P网络:全节点(存储所有完整数据,实时参与校验和更新主链),轻节点(记录部分信息,利用建议支付验证SPV方式向相邻节点请求验证)
      • 传输机制:新区块生成后广播全网以验证
      • 验证机制:按照预定义的标准验证
    • 共识层
      • 在分布式系统中达成共识
      • 区块链用的工作量证明Proof of Work机制:消耗资源、达成共识周期长
      • 股权证明机制PoS:
      • 股份授权证明机制DPoS:多中心化
      • 实用拜占庭容错算法PBFT:实用
    • 激励层 经济因素
      • 发行机制
      • 分配机制
    • 合约层
      • 建立在区块链底层(虚拟机)上的商业逻辑和算法
      • 构建内置由图灵完备编程语言的公有区块链  图灵完备:一切可计算的问题可以通过计算解决
    • 应用层

    另一种分层方式如下图所示:

    交易流程如下图:

    应用广泛,如下图所示:

     

    二、以太坊简介

    以太坊就是区块链技术+智能合约。

    以太坊和区块链技术一样,有Transation,Block,账户与账户之间的关系需要用Transation来执行,任何Transation都需要有通过block来产生。

    以太坊和比特币技术的不同:
    A.是吸纳了基于solidity语言的智能合约,并将智能合约看做一种特殊的账户,从而使得在智能合约上也可以实现具体的方法。
    B.实现了智能合约能落地执行的EVM(以太坊虚拟机),通过以太坊虚拟机,从而将solidity这样的类JS的代码变成了可以在区块链是执行的加密代码。
    C.不同于比特币技术,在以太坊的transation都需要gas,一份合约或者一次交易的gas是固定的(取决于代码大小和复杂程度),而gas的价格则有以太坊中的oracle来决定。
    D.以太坊同时还构建了较完整的,开源的生态系统,不仅有底层的geth,编程的solidity,合约在线浏览器browser-solidity,合约钱包Mist/wallet,以太坊的前端开发框架Truffle,各种各样的开源DApp。

        原文地址: Ethereum for web developers

        关于以太坊有很多的资源(文章、视频、官方文档),让人眼花缭乱。但是,其中许多都过时了,这是可以理解的,因为这个以太坊平台仍在迅速发展。我花了一些时间来拼凑出一个完整的画面: 什么是以太坊、它是怎么运行的。在Meetup和其他在线社区的开发者说,这感觉就像大家都想拥抱这项新技术但是遇到相同的困难。本文从Web开发者的角度来解释以太坊.

        如果你是一个web开发者, 那应该很清楚web应用其实是客户端-服务器的架构.

        你一般将你的Web应用托管在服务器上、像亚马逊云AWS、Heroku或VPS。所有客户端都与这一个中心应用程序交互。客户端可以是浏览器,或者其他与服务器交互的程序。当客户端向服务器发出请求时,服务器会执行相应处理,与数据库或缓存进行交互,读/写/更新数据库, 并为客户端服务。

        这种架构大部分时间都运行得很好。然而,对于某些应用,如果数据库能够被公开,每个人都安全地访问,将是非常有益的,不需要靠这个webapp访问数据。

        例如,让我们看看eBay。如果你是一个赢得了数百次好评的电商,或者出于某种原因,eBay暂停你的账户。那会很糟糕。如果可以让你的电商数据(接受的好评和评级)完全转移到另一个平台(比如淘宝)那是非常好的(但是目前是不可能的)。eBay提供的服务是买家和卖家之间信任的第三方。但是,他们也会在每次销售时收取佣金。如果有一种方法可以完全消除eBay在买卖双方之间的交易,这样你就可以节省佣金,而且你还可以访问自己所有的电商数据?这是去中心化应用程序进入我的画面的地方。以太坊它使Dapps(去中心化应用)很容易实现。

    这是以太坊DAPP架构图:

        如果您注意到,每个客户端(浏览器)都与应用程序自身的实例进行通信。没有一个中心服务器让所有客户端去连接。这意味着,每一个想与DAPP(去中心化应用程序)交互的人,将需要在他们的电脑或者手机上运行一个完整的副本。也就是说在使用一个应用程序之前,您必须下载整个区块链然后才开始使用该应用程序。这听起来可能有点荒谬,但它的好处是不依赖于一个单一的中央服务器(说不准哪天服务器就不见了)。

    在现实中,你不需要花费你很多的硬盘和内存下载整个blockchain。有几个方法优化保持应用去中心化斌并且使交互方便快捷。

    讲到这里,那个就是区块链是什么呢?它包含:

            数据库:以太坊网络中每几个交易就会被记录在一个块中,块与块间有链接关系。这一些列持有交易数据的块组成了区块链。如果我们回到eBay的例子,买家和卖家之间的所有交易,无论是销售、退款或纠纷都会被记录在区块链上,每个人都可以看到。以太坊使用工作量证明算法(新版本已经不是工作量证明算法)来确保所有节点的数据一致性,确保没有无效的数据被记录.

            代码:数据库方面只存储数据。但在所有的逻辑(买、卖、退款等)在哪里呢?在以太坊平台上,你用Solidity写的应用程序代码称为合约。然后使用Solidity的编译器来编译它生成字节码然后将该字节码部署到区块链上。Solidity是迄今为止最流行的智能合约开发语言,少有替代者。

            所以基本上,区块链存储您的数据、代码,并且在以太坊虚拟机(EVM)中运行你的代码。
            构建基于Web的dapps,以太坊有一个方便的JavaScript库可以连接到区块链节点上,称为web3.js。所以只需在你数据的框架中如 reactjs,AngularJS导入这个库然后开始构建。

            另一个重要的特点是平台的金融能力。在你开始使用DAPP时,内部会给你分配一个账户,事实上,你在短时间内分配很多账户都没问题。这些银行账户被称为钱包,用来存贮数字资产和交易。

    转载自:https://blog.csdn.net/yzj050322/article/details/79745996

    三、以太坊基础

    图灵完备的基础:以太坊虚拟机EVM,类似于JVM

    基本概念:

    • 节点:进行区块链读写
    • 矿工:通过hash运算产生工作量的网络节点
    • 挖矿:发行以太币的途径
    • 账户:可以发送交易
      • 外部账户:公私钥对控制,地址由公钥决定
      • 合约账户:部署合约时确定,存储了代码,在收到合法交易后会执行合约代码
    • Gas:限制执行交易所需的工作量,为执行交易支付费用
    • EVM:智能合约的运行环境,是一个沙盒,不能进行网络、文件或者执行其他进程
    • 智能合约:代码和数据的集合,存于以太坊区块链的指定地址
    • 交易:交易是通过状态转移来标记的,状态由被称为账户的对象和两个账户之间的转移价值和信息状态转换构成

    外部账户和合约账户在以太坊下用同一数据结构表示,如下图所示。其包含Balance、Nonce、CodeHash 和StorageRoot 四个属性,Balance是账户中的以太币余额;Nonce 是对账户发送过的交易的计数,用于防范重放攻击;当账户被应用于智能合约时,CodeHash 为合约代码的哈希值,StorageRoot 是合约状态数据的Merkle Patricia 树根。

    以太坊的交易包含To、Value、Nonce、gasPrice、gasLimit、Data 及Signature交易签名七个属性。To 是接收者的账户地址,Value 是转账的以太币金额,Nonce是发送者对本次交易的计数,gasPrice 是交易时Gas的以太币单价,gasLimit 是执行该交易所允许消耗的最大Gas 数额,Data 是调用智能合约时的消息数据,交易签名是发送者对交易的ECDSA 签名。

    以太坊核心原理:

    • 共识机制
    • EVM
      • 编译合约模块:对底层Solc编译器进行封装,提供RPC接口给外部服务,编译智能合约
      • ledger模块:对账户系统更新和修改
      • EVM执行模块:解析和执行合约代码
    • 数据存储:Merkle Patricia tree
    • 加密算法:hash算法SHA256,ECC进行数字签名

    以太坊现存问题:

    • 共识效率低下
    • 隐私保护缺乏
    • 大规模存储困难
    • 信息难以监管
    展开全文
  • 以太坊基础概念详解

    2018-06-03 15:12:03
    以太坊的解剖按从整体到局部的思路进行:1、以太坊以太坊可以用几句话道出其本质:以太坊是一个基于交易的状态机。全球就这一台单机(但分布存在),【系统状态】不停的改变。系统状态是一个术语,即后面讲...

    本文不讲区块链,也就意味着你有一些区块链的基本认知。
    主要讲解以太坊中的一些基本元素,如:区块、账户、状态、交易、费用等。因这些概念之间相互紧密联系,虽描述的时候尽量分出层级,但提醒看官看得时候可以前后翻阅。

    对以太坊的解剖按从整体到局部的思路进行:

    1、以太坊

    以太坊可以用几句话道出其本质:

    以太坊是一个基于交易的状态机。

    全球就这一台单机(但分布存在),【系统状态】不停的改变。系统状态是一个术语,即后面讲到的world state。

    这台单机主要由区块链组成,区块链上保存着状态和交易。

    当我们与以太坊交互时,其实就是在执行交易、改变系统状态。

    用一个简洁优美的公式表示就是:

    σ′ =Υ(σ,T)

    Υ是状态转换函数,T是交易,σ是状态,σ′转换后的状态。

    借用一张图吧


    从创世区块开始,无尽的交易不断的刷新着系统当前状态,每产生一个区块就对当前状态做一次快照(patricia trie根)存入区块头中。

    patricia trie是merkle tree的变体,请自行了解merkle tree。

    2、区块结构

    再看一个公式

    B≡ (BH,BT,BU)

    意思是区块恒等于(区块头,交易列表,叔块)

    所以,区块是由三大部分组成:
    区块头,叔块,交易列表。请看图:

    1)区块头由15个字段组成。
    2)叔块其实就是孤块,因以太坊出块速度很快平均十几秒就会打包生成一个块,所以矿工挖矿的竞争性很高,可能同时产出几个都合法的区块,以太坊为了一些安全性起见,允许竞争块也挂在到主链上,同时给与挖出这些孤块的矿工们少许奖励增加工作的公平性。这些孤块最多允许6个高度,这也是6个区块确认主链说法的来源。
    3)交易列表,存储的是本区块中所有的交易内容。

    图中的公式后面说。

    看一下一个实际的区块信息:

    "blocks" : [
                {
                    "blockHeader" : {
                        "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                        "coinbase" : "0x3535353535353535353535353535353535353535",
                        "difficulty" : "0x020000",
                        "extraData" : "",
                        "gasLimit" : "0x05f5e100",
                        "gasUsed" : "0x014fa1",
                        "hash" : "0x39f4659b079e257df8fd7e699528531e97a6b8a442ca0d11200c4a2f7433c483",
                        "mixHash" : "0x7379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969",
                        "nonce" : "0x8e08d7aabeee8773",
                        "number" : "0x01",
                        "parentHash" : "0xadbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3",
                        "receiptTrie" : "0xb21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316b",
                        "stateRoot" : "0xde4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7",
                        "timestamp" : "0x03e8",
                        "transactionsTrie" : "0x56445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769d",
                        "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
                    },
                    "rlp" : "0xf90308f901f9a0adbef3bf0b3b7b14f6e7b1a45d240ecc863543a279a86c23f60170e8e7a6bcc3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347943535353535353535353535353535353535353535a0de4ce9b5b2f88ab1680962c64281224b1743bdf94bd6a9e390ea779ff616c1f7a056445ba866f3e41851154fb8700dcec8556a178f1833021e030b8a47b494769da0b21660268480338c0cd0613358315359b619bd527d5850949c4863cddaec316bb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018405f5e10083014fa18203e880a07379f33af4ae2db7e293f808a165135d0b1a99572cc96fb9f7d17ef64a751969888e08d7aabeee8773f90108f90105460183030d4094c305c901078781c232a2a521c2af7980f8385ee980b8a430c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000001ba021a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44a075af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14c0",
                    "transactions" : [
                        {
                            "data" : "0x30c8d1da000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
                            "gasLimit" : "0x030d40",
                            "gasPrice" : "0x01",
                            "nonce" : "0x46",
                            "r" : "0x21a28cc82b40931239f8653ffa5300e1a506c0ef7fb79a663772cafe6558ab44",
                            "s" : "0x75af23441f7f176a2770af41142c77b671391209b15d59144e7a1332179b5e14",
                            "to" : "0xc305c901078781c232a2a521c2af7980f8385ee9",
                            "v" : "0x1b",
                            "value" : "0x00"
                        }
                    ],
                    "uncleHeaders" : [
                    ]
                }
            ]

    3、区块头

    区块头包含15个字段,介绍如下:

    type Header struct {
            ParentHash  common.Hash    //Hp,上一区块全部内容的hash,区块因它而成链!
            UncleHash   common.Hash    //Ho,本区块的ommers(所有叔块)列表的hash
            Coinbase    common.Address //Hc,成功挖出本区块的矿工地址,用于接收矿工费
            Root        common.Hash    //Hr,本区块所有交易的状态tree的根hash
            TxHash      common.Hash    //Ht,本区块所有交易tree的根hash
            ReceiptHash common.Hash    //He,本区块所有交易的收据的tree的根hash
            Bloom       Bloom          //Hb,交易收据日志组成的Bloom过滤器 
            Difficulty  *big.Int       //Hd,本区块难度级别
            Number      *big.Int       //Hi,区块序号,从创世块0递增
            GasLimit    uint64         //Hl,每个区块当前的gas limit
            GasUsed     uint64         //Hg,本区块交易消耗的总gas
            Time        *big.Int       //Hs,本区块创建时的Unix时间戳
            Extra       []byte         //Hx,区块附加数据,<=32字节
            MixDigest   common.Hash    //Hm,256位的hash,与nonce组合证明出块执行了足够的计算
            Nonce       BlockNonce     //Hn,64位的hash,与MixDigest组合证明出块执行了足够的计算
    }

    首先,ParentHash是上一个区块全部内容的hash值,下一个区块总是包含上一个区块全部内容的hash值,这就使得区块成链。

    再次,有三个特别的字段保存的是patricia trie的根,Root(状态hash)、TxHash(交易列表hash)、ReceiptHash(收据列表hash)。这个Root就是系统状态hash。系统状态就是以太坊整个网络中所有账户的状态,就是world state,它是一个merkle patricia trie结构。这个树(包括所有patricia trie)并不存在于链上,而存在于节点的levelDB中。只有它的根hash存在于区块头Root中,每一个区块头里的Root都是区块被挖出确认时的快照,而world state指现在所有账户的状态。


    world state是跨块存在的,另外两棵树只存储本区块的交易和收据。

    4、world state

    再说一下world state:
    world state是一颗全局状态树,在以太坊里只有一个,它被持续地更新。
    这棵树包含了以太坊网络里每一个账户的key/value映射。
    所以它表示的是整个以太坊系统所有账户当前的状态。

    其折叠函数是:

    LS(σ) ≡ {p(a) : σ[a]≠ ∅}

    意味着非空p(a)的集合,p(a)就是patrcia 叶子节点的内容:

    p(a) ≡ (KEC(a), RLP((σ[a]n, σ[a]b, σ[a]s, σ[a]c)))

    这表示一个叶子节点是一个key/value映射,key是KEC(a)即160位的账户地址的哈希(Keccak-256算法),value是账户(nonce、balance、storageRoot、codeHash)的RLP格式序列化字节。

    5、账户

    以太坊中有两种账户
    1、外部拥有账户(EOA),一般指自然人拥有的账户。
    2、合约账户(CA),为智能合约分配的账户。

    看一下账户的源码定义:

    type Account struct {
        Nonce    uint64      // σ[a]n ,若为EOA是发送的交易序号,如为CA是合约创建的序号。
        Balance  *big.Int    // σ[a]b ,这个地址的余额。
         //merkle root of the storage trie
        Root     common.Hash // σ[a]s ,账户自身内容RPL编码组成的Merkle Trie的根哈希
        CodeHash []byte      // σ[a]c ,账户绑定的EVM Code,账户一经创建不可修改。
    }
    • EOA特征
      codeHash为空
      storageRoot为空
      通过私钥控制
      发起交易(转移以太币或触发合约代码)
    • CA特征
      不能发起交易,可以被触发执行合约代码(通过EOA发起的交易或者从其他CA接收的消息调用激活)

    怎么判断一个账户是空账户?

    EMPTY(σ,a)≡ σ[a]c =KEC(()) ∧ σ[a]n =0 ∧ σ[a]b =0

    从公式看,一个账户的Root为空且nonce为0且余额为0,则说明这是一个空账户。

    6、交易

    再回顾一个公式

    σ′ =Υ(σ,T)

    以太坊是一个基于交易的状态机。
    任意两个账户之间的交易都会引起world state的改变。 
    两个相邻区块之间的状态差别很小,patricia trie这种数据结构能高效的处理整个系统账户变化的部分。

    交易基本定义:【从外部拥有账户】发送的加密签名序列化指令。换句话说交易必须是从EOA发起的才能叫交易,CA之间的通信叫消息也有叫内部交易的,现在是有区别,以后这个区别会不会模糊化不知道。

    交易类型有两种:
    1、消息调用(Td
    2、合约创建(Ti


    从EOA到EOA的交易仅是转账。
    EOA到CA可以激活各种操作。

    看交易的源码定义:

    type txdata struct {
        AccountNonce uint64          //Tn
        Price        *big.Int        //Tp
        GasLimit     uint64          //Tg
        Recipient    *common.Address //Tt
        Amount       *big.Int        //Tv
        Payload      []byte          //Td || Ti 
        V *big.Int
        R *big.Int
        S *big.Int
        // This is only used when marshaling to JSON.
        Hash *common.Hash
    }

    Tn必须等于发起交易的账户的nonce(翻阅前面说法可知,账户nonce是该账户发起的第几笔交易的序号,如果是创建合约则代表第几次创建合约的序号)
    Tp是这笔交易消耗的gas单价
    Tg是你愿意为这笔交易最多可以支付的上限
    Tt是接收账户的地址,如果为空说明接受账户是一个CA,否则是EOA
    Tv是到接收者的额度
    Td或Ti,如果交易类型是消息调用则Palload写为Td,表示输入数据,例如消息的参数,假设有一个注册域名的合约服务,则Td就是该服务需要的参数如IP等。如果交易类型是创建合约,则Payload写为Ti,表示一段代码,这段代码用于创建合约账户,这段初始化代码只会被执行一次就丢弃掉,第二次执行的是创建完的合约代码体。

    交易的公式:

    可以看到当接收账户不同时,区别仅仅是Td和Ti的区别。

    另外,一个区块里交易的顺序由装配这个区块的矿工决定。

    7、费用

    以太坊网络里任何计算都要支付gas(燃料),
    思考为什么不直接用eth做费用?
    答案是用两个概念gas和eth区别价值和价格,gas是一种固定衡量的价值,而eth是市场上快速变化的价格,很多EVM(以太坊虚拟机)的操作指令都需要消耗固定的费用就用gas来计价,gas的最小单位是wei,1eth = 1018wei = 109gwei。所以eth和gas之间是有汇率的。

    GasPrice:燃料单价
    GasLimit:愿意支付的燃料上限

    GasLimit × GasPrice = 愿意支付的最大费用
    10000 × 100gwei = 1015wei = 0.001eth


    这图要说明的是:
    一笔交易中,你设置的最大费用如果没有消耗完,多出的会返回给你。如果最大费用不够计算的花费,那么交易会终止、已改变的状态会回滚、但是钱被消耗不会退回了。这些已消耗的费用都奖励给矿工了。

    计算都是有费用的,初次之外还有一些东西需要缴费:

    费用的三种不同构成:
    1)计算操作的固定费用
    2)交易(合约创建或消息调用)费用
    3)存储(内存、存储账户合约数据)费用

    着重说一下存储费用:
    存储收费是因为假如你的合约使得状态数据库存储增大,所有节点都会增加存储。
    以太币是鼓励尽量保持少量存储的。
    但是如果有操作是清除一个存储条目,这个操作的费用不但会被免除,而且由于释放空间还会获得退款。

    总结

    以上就是以太坊里的一些基础元素,没有讲到复杂的交易执行、EVM等,后续再写。

    展开全文
  • 一、区块链 1. 分布式去中心化 比特币设计的初衷就是要避免依赖中心化的机构,没有发行机构,也不可能操纵发行数量。既然没有中心化的信用机构,在电子货币运行的过程中,也势必需要一种机制来认可运行在区块链...
  • 以太坊怎么购买,如何在交易平台上购买以太坊  近两年火遍全球的以太坊、比特币等虚拟货币,在2019年依然备受投资者的关注,尤其虚拟币合约交易的出现,为这个市场带来了新的活力,也为投资者提供了更安全简单的...
  • 以太坊交易教程

    2018-09-26 16:56:45
    最近很多人都在问我挖出来的以太坊如何交易,我在这里系统的给大家进行介绍。 目前以太坊等虚拟货币有两种交易方式,我具体的讲述一下。 一、场外交易  场外交易就是个人与个人之间的交易,有一些网站提供了这样...
  • 以太坊2019走势,2019年以太坊能涨到多少  最近的一项调查显示,150所大学捐赠基金中有94%在与加密相关的项目中有过某种接触。另一个有趣的观察结果是,49%的受访者表示,总体而言,捐赠基金对加密投资的分配...
  • 新版本的挖矿软件进行了升级,算力有一定的提升,首先放上下载链接 百度云|算力提升版下载地址 下面是简单易懂的教程。 一、申请钱包 登录imtoken官方下载ETH钱包app 点击打开链接 按照流程进行注册就可以......
  • 乌班图(Ubuntu)等linux环境下以太坊(ETH)怎么挖矿,如何在linux在挖以太币,有没有最新的linux以太坊挖矿软件?小编发现网上的window以太坊挖矿教程很多,但是linux下的教程和软件几乎没有,只能查到三年前的,...
  • 以太坊(ETH)作为最火的区块链货币之一,具有很高的升值空间,而且以太坊挖矿条件简单,只要一张2G以上的显卡即可开始挖矿,一张1060每日就能有10多元的收益,这篇教程简单易懂很适合不太懂的小白上手。 一、申请...
  • 什么是以太坊API?区块链开发人员在开发以太坊应用时,除了使用自己搭建的节点,也可以利用第三方提供的以太坊api。Tokenview提供的以太坊API获取以太坊区块信息,进行广播交易,查询地址和交易详情。虽然以太坊节点...
  • 以太坊(ETH)挖矿教程

    2019-12-30 10:25:57
    挖矿教程第三弹——以太坊挖矿教程 小白必看:什么是挖矿,挖矿的原理是什么,请看下方链接视频《什么是挖矿》 https://www.bilibili.com/video/av73767941/ 首先,请确保你的显存大于3GB,等于3GB也不行。因为...
  • 通过本文所述方法和项目中的脚本,我们可以快速的搭建好自己的私有链进行区块链开发测试,本文基于以太坊技术进行搭建,分两个部分,一个是Ubuntu下搭建方法,另一个是Windwos下搭建方法,关于以太坊相关的基础知识...
1 2 3 4 5 ... 20
收藏数 42,771
精华内容 17,108
关键字:

以太坊