2.2 以太坊

imtoken钱包 官方网站 2023-01-27 05:16:45

2.2.1 什么是以太坊

以太坊的整体系统架构如图 2-14 所示。

image.png

图2-14 以太坊整体架构

自2008年比特币出现以来,数字货币的存在逐渐被一些人所接受。 人们也在积极思考和开发基于比特币的商业应用。 然而,随着应用的扩展,人们发现比特币的设计只适用于虚拟货币场景。 由于非图灵完备性的存在,缺乏保存状态的账户概念,以及PoW挖矿机制带来的资源浪费和效率问题,在很多区块链应用场景中并不适用。 人们需要一个新的基于区块链的、具有图灵完备性、高效共识机制、支持更多应用场景的智能合约开发平台。 以太坊就是在这种情况下应运而生的。

以太坊的目的是整合和改进脚本、山寨币和链上元协议等概念,使开发人员能够创建基于任意共识、可扩展、标准化、图灵完备、易于开发和协作的应用程序。

以太坊是一个通用的全球区块链,可以管理金融和非金融类型应用程序的状态。 以太坊的新颖之处在于它神奇的计算机网络,它支持一种新型的软件应用程序,真正去中心化的应用程序。 将信任逻辑嵌入到小程序中,并在区块链上运行。 与比特币相比,以太坊建立了全新的密码学技术基础框架,在其上更易于开发应用,对轻客户端友好,同时让应用共享可生存的经济环境和可靠的区块链安全。 以太坊在全球范围内激发了商业和社会创新,为前所未有的去中心化应用打开了大门。 从长远来看,它带来的变化将影响全球经济和控制结构。

以太坊是一种平台和编程语言,包括数字货币以太币(Ether),以及用于构建和分发分布式应用程序的以太脚本(EtherScript)。

以太坊和众所周知的数字货币比特币有很多相似之处。 两者都是不可伪造的数字货币,并且都以去中心化的方式运作,以确保货币供应不受单一方控制。 以太坊的另一半重要特性是提供完整的编程语言环境,有时称为以太脚本。 我们都知道编程语言是人类用来控制计算机工作的。 因此,用任何编程语言编写的指令对计算机来说都是准确无误的。 也就是说,计算机如何执行一段代码是没有歧义的。 在同样的条件下,一段代码总会按照既定的步骤执行。 这个特点正是人类现行的法律和契约所缺失的。 因此,有了以太坊脚本,我们就可以毫无歧义地制定合约。

从底层来看,以太坊是一个多层的、基于密码学的开源技术协议。 它的不同功能模块在设计上完全集成,作为一个整体,它是一个创建和部署去中心化应用程序的综合平台。 尽管以太坊看起来像是多个相互关联的开源项目的混合体,但它的发展一直受到一个明确目标的引导,以便各种组件可以协同组装在一起。

同时,以太坊也是区块链和智能合约的完美结合。 它是智能合约的完整解决方案。 它被设计成一个通用的去中心化平台,拥有一整套可以扩展其功能的工具。 在P2P网络、加密、HttpClient等技术的支持下,实现了类似于比特币的区块链。 它通过工作量证明机制达成共识,由矿工挖矿,通过制定新的网络协议实现区块链的同步等操作。 与比特币不同的是,以太坊上可以任意编写智能合约,通过智能合约实现强大的功能,实现去中心化应用的开发。 部署在以太坊上的智能合约运行在以太坊专用的虚拟机上,通过以太坊虚拟机和RPC接口与底层区块链进行交互。

2.2.2 以太坊技术

一、以太坊的核心概念

(1) 以太坊虚拟机

以太坊虚拟机 (EVM) 是以太坊中智能合约的运行时环境。 这是以太坊项目的又一重大创新。 有人说 EVM 是“在区块链之上”,而实际上它是由许多互连的计算机组成的。 任何人都可以上传程序并让这些程序自动执行,同时确保每个程序的当前和所有先前状态始终公开可见。 这些程序在区块链上运行,并严格按照 EVM 定义的方式继续执行。 因此任何人都可以为所有权、交易格式和状态转换功能创建业务逻辑。

(2) 账户

以太坊中有两种类型的账户,它们共享相同的地址空间。 外部账户,由公私密钥对控制。 合约账户,此类账户由账户中存储的代码控制。 外部账户地址由公钥确定,合约账户地址由合约创建者的地址和合约创建时该地址发送的交易数量计算得出。 两种账户的唯一区别是外部账户没有代码,人们可以通过创建和签署交易从外部账户发送消息。 每当合约账户收到一条消息时,合约内部的代码就会被激活,允许它读取、写入内部存储、发送其他消息以及创建合约。

以太坊中的一个账户由4部分组成:①一个随机数,一个计数器,用来确定每笔交易只能处理一次; ②账户当前以太币余额; ③账户的合约代码(如有); ④账户的存储空间(默认为空)。

(3) 讯息

以太坊消息传递与比特币交易有些相似,但两者之间有 3 个重要区别。

1)以太坊消息可以由外部实体或合约创建,而比特币交易只能在外部创建。

2) 以太坊消息可以选择性地包含数据。

3)如果以太坊消息的接收者是合约账户,可以选择响应,也就是说以太坊消息也包含了函数的概念。

(4) 交易

以太坊中的“交易”是指存储从外部账户发送的消息的签名数据包。 交易包含消息的接收者、确认发送者的签名、以太币账户余额、要发送的数据以及两个称为 STARTGAS 和 GASPRICE 的值。 为了防止代码中的指数爆炸和无限循环,每个交易都需要限制执行代码所需的计算步骤数。 STARTGAS是通过需要支付的燃料来限制计算步数,GASPRICE是每一步计算需要支付给矿工的燃料价格。

(5) 煤气

以太坊上的每笔交易都会收取一定数量的 Gas。 设置Gas的目的是为了限制交易执行所需的工作量,并为交易的执行付出代价。 当EVM执行一笔交易时,Gas会按照一定的规则逐渐消耗。 Gas价格由交易创建者设定,发送账户需要预付交易费=GASPRICE*Gas量。 如果执行后还有Gas剩余,则将Gas返还给发送账户。 无论在哪里执行,一旦Gas耗尽,都会触发out-of-gas异常。 同时,将回滚当前调用框架所做的所有状态修改。

(6) 存储、主存和栈

每个账户都有一个永久存储区,称为storage,以key-value的形式存在,key和value的长度都是256位。 在合约中,无法遍历账户的存储。 与主存和栈相比,storage的读操作开销比较大,storage的修改代价更大。 合约只能读写自己的存储。

第二个内存区域称为主内存。 每次调用消息时,合约执行都会有一个新的清除主内存。 主存可以按字节寻址,但读写的最小单位是32字节。 操作主存的开销随着主存的增长而变大。

EVM 不是基于寄存器的,而是基于堆栈的虚拟机。 因此,所有计算都在称为堆栈的区域内执行。 堆栈最多有 1024 个元素,每个元素有 256 位。 对栈的访问仅限于栈顶,允许将栈顶的 16 个元素之一复制到栈顶,或者交换栈顶的 16 个元素之一。 所有其他操作只能取最顶层的一个或几个元素并将结果压入栈顶。 当然,你可以把栈中的元素放入存储器或主存中。 但是不可能只访问栈中指定深度的元素。 在此之前,必须从堆栈中删除指定深度以上的所有元素。

(7) 指令集

EVM 的指令集故意保持在最低限度,以避免可能导致共识问题的错误。 所有指令都对256位的基本数据单元进行操作,具有常用的算术、位、逻辑和比较运算,还可以进行条件跳转和无条件跳转。 此外,合约可以访问当前区块的相关属性,例如它的编号和时间戳。

(8) 消息调用

合约可以通过消息调用调用其他合约,或者发送以太币给非合约账户。 消息调用与交易非常相似,它们都有源、目的地、数据有效负载、以太币、gas 和返回数据。 实际上,每笔交易都可以看作是一次顶层的消息调用,进而产生更多的消息调用。

合约可以决定剩余 Gas 的分配。 比如内部消息调用使用了多少Gas,或者预留了多少Gas。 如果在内部消息调用过程中发生了 out-of-gas 异常或其他异常,将通知合约并将错误代码压入堆栈。 这种情况只是内部消息调用的gas耗尽。 在solidity中,这种情况下发起调用的合约默认会触发一个人为的异常,这个异常会打印出调用栈。

如前所述,被调用合约(以及调用合约)将拥有新的主内存并可以访问调用有效负载。 呼叫有效载荷存储在称为呼叫数据的单独区域中。 调用执行后,返回的数据会存放在调用者预先分配的一块内存中。 调用层数限制为1024。所以对于更复杂的操作,我们应该使用循环而不是递归。

(9) 代码调用和库

以太坊中存在一种特殊类型的消息调用,称为调用代码。 它与消息调用几乎完全相同,只是从目标地址加载的代码将在调用合约的上下文中运行。 这意味着合约可以在运行时从另一个地址动态加载代码。 存储、当前地址和余额都指向调用合约,只有代码是从被调用地址中获取的。 这允许 Solidity 实现“库”。 可复用的库代码可以应用于合约的存储,可以用来实现复杂的数据结构,让智能合约更加强大。

2. 以太坊的状态转移

以太坊的状态转换是指以太坊在一笔交易(TX)发生时,从一个正确的状态(S)到下一个正确的状态(S')的转换过程,如图2-15所示。 对于交易来说,为了防止代码的指数级爆炸和死循环,每个交易都需要限制执行代码导致的计算步数。 STARTGAS是limit,GASPRICE是矿工每一步计算需要支付的手续费价格。

image.png

图 2-15 以太坊状态转换

以太坊的状态转移函数为APPLY (S, TX) -> S',可以定义如下:

1) 检查交易格式是否正确,签名是否有效,以及随机数是否与发送方账户的随机数匹配。 如果不是,则返回错误。

2)计算交易手续费fee = STARTGAS * GASPRICE,由签名确定发送方地址。 从发送者的账户中减去交易费用并增加发送者的随机数。 如果账户余额不足,则返回错误。

3) 设置初始值Gas=STARTGAS,根据交易的字节数减去一定量的gas值。

4) 将价值从发送者的账户转移到接收者的账户。 如果接收帐户尚不存在,请创建它。 如果收款账户是合约,则运行合约的代码,直到代码运行结束或者gas耗尽。

5)如果由于发送方账户手续费不足或代码执行燃料耗尽导致价值转移失败,将恢复原状14年以太坊官方众筹说明,但仍需支付交易手续费,交易手续费将添加到矿工的账户。

6) 如果代码执行成功,剩余的gas将全部返还给发送者,消耗的gas将作为交易费用发送给矿工。

例如,假设一个合约有如下代码:

if !contract.storage[msg.data[0]]:contract.storage[msg.data[0]] = msg.data[1]

应该注意的是,实际上合约代码是用底层的以太坊虚拟机 (EVM) 代码编写的。 上面的合约是用我们的高级语言Serpent写的,可以编译成EVM代码。 假设一开始合约内存为空,发送了一笔价值为10 Ether,燃料为2000,燃料价格为0.001 Ether,两个数据字段值为[2,'CHARLIE']的交易后,流程状态转换函数如下:

1) 检查交易是否有效且格式正确。

2) 检查交易发送方是否至少有2000×0.001=2 ETH。 如果是这样,从发送者的账户中减去 2 个以太币。

3)初始设置Gas=2000,假设交易长度为170字节,每字节费用为514年以太坊官方众筹说明,减去850,所以还剩1150。

4) 从发送者账户中减去10 ETH,向合约账户中添加10 ETH。

5) 运行代码。 在这个合约中,运行代码很简单:它检查合约内存索引 2 是否被使用,注意到它没有被使用,并将它的值设置为 CHARLIE。 假设这样消耗了187单位的燃料,那么剩余的燃料就是1150-187=963。

6) 向发送者账户添加963×0.001=0.963 ETH,返回最终状态。

如果没有合约接收交易,那么所有交易手续费等于GASPRICE×交易字节长度,交易数据与交易手续费无关。 此外,需要注意的是,由合约发起的消息可以为它们生成的计算分配一个气体限制,如果子计算耗尽气体,它只会恢复到发送消息时的状态。 因此,就像交易一样,合约也可以通过对它们生成的子计算设置严格限制来保护它们的计算资源。

3. 以太坊客户端

为了测试各种语言对以太坊的支持,让更多人参与到以太坊的开发和使用中,目前有四种语言编写的四种以太坊客户端。 它们分别是用Go语言实现的客户端Geth,用C++实现的客户端Eth,用Python语言实现的客户端Pyethapp,用Java实现的客户端EthereumJ。 其中,Go语言版本是一直维护推荐的以太坊官方客户端。

以太坊包括一个专用的客户端浏览器,使用户能够运行各种去中心化应用程序 (DApp) 并发布智能合约。 该浏览器名为Mist,易于使用,降低了用户的进入门槛,让DApps和智能合约被大量用户使用。 这就像浏览器之于互联网或 iTunes 之于数字内容下载。 Mist 由特殊安全层、密钥管理、去中心化账户管理和区块链相关组件组成。 这一切使得 Mist 成为普通用户运行或管理区块链去中心化应用程序不可或缺的工具,普通用户无需了解技术方面的知识。

从用户体验的角度来看,您可以在 Mist 中使用 DApp,就像通过常规浏览器与网站交互一样。 例如,一个纯 DApp(如预测市场 Augur)可以运行在 Ethereum Mist 浏览器中。 当然,这些服务也可以通过传统的浏览器以更传统的Web 2.0方式实现。

2.2.3 以太坊智能合约

1. 智能合约

智能合约是 Nick Szabo 提出的一个想法,几乎与互联网同龄。 然而,由于缺乏可信的执行环境,智能合约并未应用于实际行业。 自比特币诞生以来,人们就意识到比特币的底层技术区块链可以为智能合约提供可信的执行环境。 以太坊首先实现了区块链和智能合约的完全融合。

以太坊是一种内置图灵完备 [1] 编程语言的区块链。 通过建立一个抽象的基础层,任何人都可以创建合约和去中心化应用程序,并设置他们自由定义的所有权规则、交易模式和状态转换功能。 搭建一个token的主框架只需两行代码即可实现,其他协议如货币、信誉系统等不到20行代码即可实现。 智能合约就像一个加密的盒子,里面装着价值,只有在以太坊平台上满足一定的条件才能打开,而且因为图灵完备、价值感知、区块链感知)和记录多种状态,比智能合约强大得多比特币脚本可以提供。

2.开发语言

以太坊的软件开发语言是其最大的特点之一,因为对区块链进行编程是其主要目标。 以太坊有 4 种专用语言:Serpent(受 Python 启发)、Solidity(受 JavaScript 启发)、Mutan(受 Go 启发)和 LLL(受 Lisp 启发),所有语言都是为面向合约的编程而设计的。

作为以太坊的高级编程语言,Serpent 的设计与 Python 非常相似。 它被设计得尽可能简洁明了,结合了低级语言的效率优势和编程风格的易用性。

Solidity 是以太坊的首选语言。 它内置了 Serpent 的所有功能,但语法类似于 JavaScript。 Solidity充分利用了数百万程序员已经掌握JavaScript的优势,降低了学习门槛,易于掌握和使用。

以太坊区块链的另一个关键特性是它的“图灵完备性”,这保证了以太坊可以解决所有的计算问题。 更准确地说,它是“半”图灵完备的,因为通过对计算量设置上限,它避免了完全图灵完备语言的不间断问题。 另外,由于以太坊的语言是专门为区块链设计的,它有账户的概念,这使得它在交易的可视化和账户状态的查询上提供了实时性。 这是一个受欢迎的功能,但对比特币来说是一个挑战。 在比特币上,由于只有UTXO,没有账户概念,我们需要导入区块链数据库,分析所有交易,查询交易,才能提取出某个用户在区块链上的交易状态。 通过以太坊,我们可以根据实时区块链上的一个地址,实时查看当前账户状态和交易状态。

3.代码执行

以太坊合约的代码是用一种基于堆栈的低级字节码语言编写的,称为“以太坊虚拟机代码”或“EVM 代码”。 该代码由一系列字节组成,每个字节代表一个操作。 一般来说,代码执行是一个无限循环,程序计数器每加一(初始值为零)就执行一次操作,直到代码执行完或遇到错误、STOP或RETURN指令。 操作可以访问 3 种类型的存储空间:

1)栈,一种后进先出的数据存储方式,出栈的基本单位是32字节。

2)内存,可无限扩展的字节队列。

3)合约长期存储,key/value存储,key和value都是32字节大小。 与计算完成时重置的堆栈和内存不同,存储内容会保留很长时间。

代码可以像区块头数据一样访问已发送和已接收消息中的值、数据,并且代码还可以返回数据的字节队列作为输出。 EVM 代码的正式执行模型非常简单。 以太坊虚拟机在运行时,其完整的计算状态可以通过元组(block_state、transaction、message、code、memory、stack、pc、gas)来定义,其中block_state是包括所有账户余额和存储在内的全局状态。 每条指令如何影响元组是通过在每轮执行中调出代码的 pc(程序计数器)字节来定义的。 例如,ADD 从堆栈中弹出两个元素并压入它们的总和,减少 Gas 并将 1 加到 pc; stack 弹出最前面的两个元素,插入第一个元素定义的第二个元素 合约的存储位置,同时最多减少 200 的 Gas 值,同时给 pc 加 1。 虽然有很多方法可以通过即时编译来优化以太坊,但可以用几百行代码来实现以太坊的基本实现。

[1] 图灵完备性请参考3.3节。

2.2.4 以太坊去中心化应用

1. 什么是 DApp

DApp 由智能合约和客户端代码组成。 智能合约就像加密的价值盒子。 它只有在满足某些条件时才会打开,它封装了一些逻辑、规则、处理步骤或双方之间的协议。

从架构的角度来看,DApp 与传统的 Web 应用程序非常相似。 主要区别在于,在传统的 Web 应用程序中,客户端具有由用户在其浏览器中执行的 JavaScript 代码; 服务器端代码由主机运行。 但在DApp中,其智能逻辑运行在区块链上,客户端代码运行在专门的浏览器Mist中。

2.应用实例

正如苹果电脑的 App Store 为许多公司和个人提供了极好的商业机会一样,在以太坊等平台上也会有像“愤怒的小鸟”这样的成功例子。 对于以IT为主的创业公司和个人来说,这是一个广阔的空间。 这里有几个例子可以看出这个领域正在培育的项目。

Augur ( ),一个去中心化的预测系统正在开发中。 Augur 在英语中是“预测者”的意思。 用户可以在此应用上对各种事件进行投注和投注,例如希拉里克林顿是否会赢得2016年美国大选; 2016年中国GDP增速是否会超过7%; 2020年之前上证指数会不会突破10000点等等。 对于参与者来说,如果预测正确,将获得经济奖励; 对于整个社会来说,Augur 成为了一个群体智慧的收集器,其上的投注信息反映了人们对未来某一事件的预期。 可能性的最佳估计。 当你打开搜索引擎,输入“Will ××× win the 2020 US election”,你可能会发现这样的结果:“Augur:这件事发生的概率是46.6%”。

Maker(),一个正在开发中的金融去中心化自治组织。 Maker 是一个去中心化自治组织(DAO),它维护着一系列用于金融服务的合约软件(智能合约),其中之一就是 The Dai Credit System。 借贷系统是一种通过抵押方式进行借款的应用。 当用户在区块链上拥有大量资产时,一个必然的需求就是通过抵押贷款的方式获取资金,而不是出售资产,类似于住房抵押贷款。

WeiFund,一个正在开发中的去中心化众筹平台。 本众筹平台的优势在于资金不需要第三方托管,而是由程序托管,因此可以保证100%的资金安全。 如果众筹项目的资金在限定时间内超过预定目标,则该计划将资金发送给企业家; 如果没有达到目标,资金将退还给众筹参与者。

Boardroom,一个正在开发中的 DAO 管理平台。 去中心化自治组织和传统公司一样,也可以有股份的概念,通常是DAO代币,这些代币可以有投票权。 结合前面例子中的 WeiFund,会发生一些有趣的事情:如果众筹目标达成,WeiFund 可以将资金发送到 Boardroom,并将众筹项目的参与者组成一个 DAO。 这样一来,这些参与者就可以通过投票来控制资金的具体使用,而不是简单地将资金一次性分配给创业者,从而极大地避免了创业者的道德风险。

Ujo Music,音乐版权管理平台,测试版。 Ujo Music作为一个音乐版权管理平台,可以直接在歌曲创作者和消费者之间建立直接连接,从而省去了中间商。 此外,歌手甚至可以通过IPO的方式在微基金上架他们的作品。 这样一来,持有歌手代币的投资人将获得歌手未来歌曲销售收入的分成。 他们是这位歌手天生的铁杆粉丝。 帮助歌手宣传自己的音乐,不仅是出于经济上的动机,更是出于情感上的支持。 试想一下,在周杰伦名不见经传的情况下,粉丝们拿着周杰伦的代币会有多自豪。 同时,代币也是歌手与粉丝群体互动的媒介。 例如,歌手可以让持有代币的粉丝优先购买演唱会门票。 这样一来,粉丝经济就会更加繁荣。

Decentralized Autonomous Insured Bond,简称 Dai 或 Dai Bond,是一种可转让、等价、可互换的“加密债券”。 在信用系统中流通,用户无需事先认证。 有风险。 贷款的发行人(借款人)将以以太坊区块链上的以太等数字加密资产作为抵押品发行贷款,然后将这些贷款在市场上出售给贷款持有人,以换取流动性资产。 贷款持有人之所以是为了赚取收入,或者是将贷款作为一种具有稳定价值的加密货币来使用。