大数跨境

第4章 进入以太坊世界

第4章 进入以太坊世界 数组智控产业发展科技院
2023-05-18
2
导读:文章来源《DAPP应用开发》在开始进行以太坊智能合约或去中心化应用(DApp)开发之前,我们先对以太坊的核心

文章来源《DAPP应用开发》

在开始进行以太坊智能合约或去中心化应用(DApp)开发之前,我们先对以太坊的核心概念做一些介绍,帮助大家了解以太坊的工作原理。

4.1 以太坊概述

以太坊(Ethereum)是一个建立在区块链技术之上的去中心化应用平台。

它允许任何人在平台上建立和使用通过区块链技术运行的去中心化应用(DApp)。

去中心化应用(DApp)和我们现在互联网客户端/服务端架构(C/S架构)的应用不同,应用的后端是一个有N个节点计算机(矿机)组成的网络,如图4-1所示。

我们在平时使用的应用程序中看到的内容通常是由后端的服务器提供,请求也是发送到后端的服务器处理。

而在去中心化应用中,与客户端连接的节点不能够单独处理来自用户的请求(这个请求通常称之为“交易”),而是要把用户的请求广播到整个网络,待整个网络达成共识之后,整个请求才算处理完成。

去中心化应用中一个很重要的部分就是智能合约,智能合约就是刚才描述的场景中,处理用户情求的程序。


图4-1 DApp架构

4.2 智能合约

到底什么是智能合约呢?

那就是以太坊上运行的程序,和其他程序一样,它也是由代码和数据组成的。

智能合约中的数据也称为“状态”,因为整个区块链就是由所有数据确定的一个状态机。

智能合约的英文是smart contract,和人工智能(AI:Artificial Intelligence)所说的智能没有关系,智能合约的概念最早由尼克·萨博提出,就是将法律条文写成可执行代码,让法律条文的执行中立化,这和区块链上的程序可以不被篡改地执行在理念上不谋而合,因此区块链引入了智能合约这个概念。

以太坊智能合约是“图灵完备”的,因此理论上我们可以用它来编写能做任何事情的程序。

智能合约现在的主要编程语言是Solidity和Vyper,Solidity更为成熟一些,本书中的智能合约代码都是用Solidity编写,通常合约文件的扩展名是.sol。

下面就是一个简单的计数器合约。

这段代码有一个类型为uint(无符号整数)名为“counter”的变量。

counter变量的内容(值)就是该合约的状态。

每当我们调用count()函数时,此智能合约的区块链状态将增加1,这个状态是对任何人都可见的。

图4-2很好地表示了智能合约的内容。

图4-2 智能合约包含的内容

从本书第5章开始,我们会进一步介绍智能合约开发。

4.3 账户

智能合约在以太坊网络中表现为一种特殊账户:合约账户。

账户在以太坊中是非常重要的概念,开发过程中离不开它,以太坊中有两类账户:

(1)外部用户账户(EOAs)——该类账户被公钥——私钥对控制(由人控制)。

(2)合约账户——该类账户被存储在账户中的代码控制。

外部用户账户和合约账户,都用同样的地址形式表示,地址形式为:0xea674fdde714fd979de3edf0f56aa9716b898ec8,是一个20字节的16进制数。

本书中,账户(或账号)和地址两个概念没有区别,有时地址也会指代账户

外部用户账户的地址是由私钥推导出来的(在本书第10章会作进一步介绍),合约账户的地址则由创建者的地址和nonce计算得到,这里就不深入介绍,有兴趣的读者可以延伸阅读《以太坊合约地址是怎么计算出来的?》这篇文章。

外部用户账户和合约账户都可以有余额;

合约账户使用代码管理所拥有的资金,外部用户账户则是用私钥签名来花费资金;

合约账户存储了代码,外部用户账户则没有。

它们还有一个不能忽视的区别:只有外部用户账户可以发起交易(主动行为),合约账户只能被动地响应动作。

账户状态

账户状态有4个基本组成部分,不论账户类型是什么,都存在这4个组成部分。

·nonce:如果账户是外部用户账户,nonce代表从此账户地址发送的交易序号。

如果账户是合约账户,nonce代表此账户创建的合约序号

提示:以太坊中有两种nonce,一种是账号nonce——表示一个账号的交易数量;一种是工作量证明nonce——一个用于计算满足工作量证明的随机数。

·balance:此地址拥有以太币余额数量。

单位是Wei,1 ether=1018 wei,当向地址发送带有以太币的交易时,balance会随之改变。

ether和wei是以太坊中以太币的两种面额单位,就像人民币的元和分,除此之外,还有一个常用的面额单位Gwei,用来给gas定价,1 Gwei = 109 wei。

·storageRoot:Merkle Patricia树的根节点哈希值。

Merkle树会将此账户存储内容的哈希值进行编码,默认是空值。

·codeHash:此账户代码的哈希值。

对于合约账户,就是合约代码被哈希计算后的哈希值作为codeHash保存。

对于外部用户账户,codeHash是一个空字符串的哈希值。

以太坊的全局共享状态是由所有账户状态组成,它由账户地址和账户状态组成的映射存储在区块的状态树中,如图4-3所示。

图4-3 以太坊全局状态

4.4 以太币的单位

以太币是一种货币,不同单位的货币就像法定货币中不同的面额,对于用户来讲,最常用的是ether,1个ether就是我们常说的一个以太币(通常也简称为以太),对于开发者来说可能最常用的是wei,它是以太币的最小单位,其他的单位包括finney、szabo以及gwei。

它们的换算关系是:

·1 ether == 10^3 finney

·1 ether == 10^6 szabo

·1 ether == 10^18 wei

·1 gwei == 10^9 wei

以太币的单位其实很有意思,以太坊社区为了纪念密码学家的贡献,使用密码学家的名字作为货币单位,就像很多国家的货币会印上对国家有卓越贡献的伟人头像一样。

wei名字来自于Wei Dai(戴伟),密码学家,发表了B-money。


finney来自于Hal Finney(哈尔·芬尼),密码学家,提出了工作量证明机制(PoW)。


szabo来自于Nick Szabo(尼克·萨博),密码学家,智能合约的提出者。

4.5 以太坊虚拟机(EVM)

以太坊虚拟机(Ethereum Virtual Machine),简称EVM,用来执行以太坊上的交易,提供智能合约的运行环境。

熟悉Java的同学,可以把EVM当作JVM来理解,EVM同样是一个程序运行的容器。

以太坊虚拟机是一个被沙箱封装起来、完全隔离的运行环境。

而以太坊虚拟机本身运行在以太坊节点客户端上,各层关系如图4-4所示。

图4-4 EVM位置

gas

前面提到,在EVM上运行的智能合约是“图灵完备”的,理论上可以编写能做任何事情的程序。

既然如此,恶意的执行者就可以通过执行一个包含无限循环的交易轻易地让网络瘫痪。

以太坊通过每笔交易收取一定的费用来保护网络不受蓄意攻击,这一套收费的机制称为gas机制。

gas是衡量一个操作或一组操作需要执行多少“工作量”的单位。

例如,计算一个Keccak256加密哈希函数,每次计算哈希时需要30个gas,再加上每256位被哈希的数据要花费6个gas。

EVM上执行的每个操作都会消耗一定数量的gas,而需要更多计算资源的操作也会消耗更多的gas,以太坊黄皮书中定义了每一步操作需要的gas。

如果gas仅仅是一个“工作量”单位,那怎么支付费用呢?

还有另一个概念——gas价格。

其实每笔交易都要指定预备的gas及愿意为单位gas支付的gas价格(gas price),这是两者的结合,gas * gas价格=交易预算。

gas价格是用以太币(ether)来表示,没有任何实际的gas代币(Token)。

也就是说,你不能拥有1 000个gas。

之所以称为预算,是因为如果交易完成还有gas剩余,这些gas对应的费用将被返还给发送者账户。

我们也可以认为gas是以太坊虚拟机的运行燃料,它在每执行一步的时候消耗一定的gas,如果给定的gas不够,无论执行到什么位置,一旦gas被耗尽(比如降为负值),将会触发一个out-of-gas异常,当前交易所作的所有状态修改都将被还原。

4.6 以太坊客户端

以太坊客户端是以太坊网络中的节点程序,这个节点程序可以完成如创建账号、发起交易、部署合约、执行合约、挖掘区块等工作。

很多编程语言都参考以太坊协议开发出以太坊客户端,常用的为Geth和OpenEthereum。

Geth是以太坊官方社区开发的客户端,基于Go语言开发。OpenEthereum是Rust语言实现的客户端。

使用Geth的开发者更多,接下来介绍Geth的使用方法。

Geth提供了一个交互式命令控制台,我们可以在控制台中和以太坊网络进行交互。

4.7 以太坊钱包

除了geth这样的相对“重”的以太坊客户端,还有一种是比较“轻”的客户端:钱包。

普通用户用得较多的钱包是imToken等,而开发者常用的钱包是MetaMask,它是一个浏览器插件(支持Chrome、Firefox、Opera等浏览器),它可以和Remix配合使用,用来部署和执行智能合约。

MetaMask可以在一家网站(https://metamask.io)找到对应的插件来安装,安装完成经过账号导入或创建之后,可以看到MetaMask的界面,如图4-5所示。

右上角可以切换不同的网络,如图4-6所示。

图4-6 MetaMask网络选择

4.8 以太坊交易

我们知道,比特币交易非常简单,它只做一件事,就是进行货币的转移。

可以归纳为TO(谁收钱),FROM(谁汇款)和AMOUNT(多少钱)。

以太坊与之很大的不同在于其交易还有DATA字段。DATA字段支持以下三种类型的交易。

1价值传递(和比特币相同)

·〇 TO:收款地址

·〇 DATA:留空或留言信息

·〇 FROM:谁发出

·〇 AMOUNT:发送多少

2.创建合约

·〇 TO:留空(这就是触发创建智能合约的原因)

·〇 DATA:包含编译为字节码的智能合约代码

·〇 FROM:谁创建

·〇 AMOUNT:可以是0或任何数量的以太币,它是我们想要给合约的存款

3.调用合约函数

·〇 TO:目标合约账户地址

·〇 DATA:包含函数名称和参数——标识如何调用智能合约函数

·〇 FROM:谁调用

·〇 AMOUNT:可以是0或任意数量的以太币,例如可以支付给合约的服务费用虽然实际交易有更多复杂的细节,但核心概念就是这些。

4.8.1 价值传递

非常简单,就是转移一定数量的以太币到某个地址,如果我们愿意也可以向交易添加消息。

4.8.2 创建智能合约

如上所述,TO为空表示创建智能合约,DATA包含编译为字节码的智能合约代码。

4.8.3 调用合约方法

4.9 以太坊网络

4.9.1 主网网络(Mainnet)

以太坊主网网络,或直接称为以太坊网络,是真正产生价值的全球网络,是矿工挖矿的网络。

可以通过https://ethstats.net查询到以太坊网络实时数据,如当前的区块、挖矿难度、gas价格和gas花费等信息。

在区块浏览器(https://cn.etherscan.com/)可以查询到部署在主网的智能合约、相关交易信息等。

4.9.2 测试网络(Testnet)

在主网,任何合约的执行都会消耗真实的以太币,不适合开发、调试和测试。

因此以太坊专门提供了测试网络,在测试网络中可以很容易地获得免费的以太币。

测试网络同样是一个全球网络。目前以太坊公开的测试网络包括:

(1)Morden(已退役)。

(2)Ropsten(https://ropsten.etherscan.io/)——Ropsten使用的共识机制为PoW,挖矿难度很低,普通笔记本电脑的CPU(中央处理器)也可以支持挖出区块。

(3)Rinkeby(https://rinkeby.etherscan.io)——Rinkeby使用了权威证明(Proof-of-Authority)的共识机制,简称PoA。

(4)Kovan(https://kovan.etherscan.io/)——Kovan也使用了PoA,目前Kovan网络仅被Parity钱包支持。

(5)Goerli为升级到以太坊2.0而准备的测试网。

不过使用测试网络依然有一个缺点,那就是需要花较长时间初始化节点,在实际使用中,测试网络更适合担当如灰度发布(正式上线之前用于验证功能的发布)的角色。

4.9.3 私有网络、开发者模式

我们还可以创建自己的私有网络,通常也称为私有链,进行开发、调试、测试。

通过上面提到的Geth可以很容易地创建一个属于自己的测试网络(私有网络),在自己的测试网络中,以太币很容易挖到,也省去了同步网络的耗时。

例如,公司里多个团队共享一个网络用来测试。

当然,我们也可以直接使用Geth提供的开发者模式(这也是一种私有链)。

在开发者网络模式下,它会自动分配一些有大量余额的开发者账户给我们使用。

4.9.4 模拟区块链网络

另一个创建测试网络的方法是使用Ganache,Ganache在本地使用内存模拟的以太坊环境,对于开发调试来说,更加方便快捷。

而且Ganache可以在启动时帮我们创建10个存有100个以太币的测试账户,Ganache是一个桌面App,可以在这个地址下载:

https://www.trufflesuite.com/ganache,其界面如图4-7所示。

图4-7 Ganache运行截图

注意一点,由于Ganache默认的数据是在内存中,因此每当Ganache重新启动后,所有的区块数据会消失。

进行合约开发时,可以在Ganache中测试通过后,再部署到Geth节点中。

4.10 以太坊历史回顾

本章的最后一节,来回顾一下以太坊的发展历史,我们现在看到的以太坊是经过一次次的分叉升级发展而来。以太坊的发展大概有以下几个阶段,每个阶段都命名了一个代号。

4.10.1 奥林匹克(Olympic)

以太坊区块链在2015年5月开始向用户(主要是开发者)开放使用。

版本称为“奥林匹克”,这是一个测试版本。

主要供开发人员提前探索以太坊区块链开放以后的运作方式,比如测试交易活动、虚拟机使用、挖矿方式和惩罚机制,同时尝试使网络过载,并对网络状态进行极限测试,了解协议如何处理流量巨大的情况。

4.10.2 边疆(Frontier)

经过几个月对奥林匹克的压力测试,以太坊在2015年7月30日发布官方公共主网,第一个以太坊创世区块产生。

边疆依旧是一个很初级的版本,交易都是通过命令行来完成。

不过,边疆版本已经具备以太坊的一系列关键特征:

(1)区块奖励:当矿工成功挖出一个新区块并确认后,矿工仅得到5个以太币的奖励。

(2)Gas机制:通过gas来限制交易和智能合约的工作量。

(3)引入了合约。

4.10.3 家园(Homestead)

家园是以太坊网络的首次硬分叉升级计划,在2016年3月14日发生在第1 150 000个区块上。家园版本为以太坊带来的主要更新有:

(1)完善了以太坊编程语言Solidity;

(2)上线Mist钱包,使用户能够通过UI界面持有或交易ETH,编写或部署智能合约。

家园升级是第一个通过以太坊改进提案(EIP)实施的分叉升级。

EIP(Ethereum Improvement Proposal)即以太坊改进提案,是以太坊去中心化治理的一部分,所有人都可以提出治理的改进方案,当社区讨论通过后,就会囊括在网络升级版本中。

家园升级主要包括三个EIP提案:EIP2、EIP7、EIP8。这些提案具体包含的内容可以通过EIP文档查看:https://eips.ethereum.org/。

作者翻译一些EIP文档,英文不好的同学可前往https://learnblockchain.cn/docs/eips/阅读。

4.10.4 DAO分叉

这是一个计划外的分叉,并非为了功能升级,而是以太坊社区为了对黑客攻击防止损失,而采取的硬分叉回滚了黑客的交易。

事情是这样的:2016年,去中心化自治组织“The DAO”通过发售DAO代币募集了1.5亿美元的资金,作为DAO代币持有人可以投票及审查投资项目,并获得一定比例的项目收益,所有的资金均由智能合约管理。

然后在2016年6月,the DAO合约遭到黑客攻击,黑客可以利用漏洞源源不断地从合约中盗取以太币。

最终在以太坊社区投票后实行了硬分叉(在1 920 000块高度时发生),将资金返还到原钱包并修复漏洞。

不过这次硬分叉仍旧引来很大的争议,以太坊社区的一些成员认为这种硬分叉方式违背了“Code Is Law”原则,他们选择继续在原链上进行挖矿和交易。

未返还被盗资金的原链则演变成以太坊经典(即ETC)。

The DAO事件的分析,可以阅读上海对外经贸大学区块链研究中心主任乐扣老师的文章:https://learnblockchain.cn/article/644。

4.10.5 拜占庭(Byzantium)

拜占庭(Byzantium)和君士坦丁堡(Constantinople)是以太坊称为“大都会”(Metropolis)升级的两个阶段。

拜占庭在2017年10月第4 370 000个区块上激活,拜占庭分叉更新有:

增加“REVERT”操作符、增加一些加密方法、调整难度计算、推迟难度炸弹、调整区块奖励(5个减为3个)。

“难度炸弹”(Difficulty Bomb)是这样一种机制:


一旦被激活,将增加挖掘新区块所耗费的成本(即“难度”),直到难度系数变为不可能或者没有新区块等待挖掘。


这在以太坊中称为进入冰河时代,“难度炸弹”机制在2015年9月就被引入以太坊网络。


它的目的是促使以太坊最终从工作量证明(PoW)转向权益证明(PoS)。


因为从理论上来说,未来在PoS机制下,矿工仍然可以选择在旧的PoW链上作业,而这种行为将导致社区分裂,从而形成两条独立的链。


为了预防这种情况的发生,通过“难度炸弹”增加难度,将最终淘汰PoW挖矿,促使网络完全过渡到PoS机制。

这次分叉包括9个EIP:EIP100、EIP658、EIP649、EIP140、EIP196、EIP197、EIP198、EIP211、EIP214 ,详细的变更可以参考这个链接:https://github.com/ethereum/wiki/wiki/Byzantium-Hard-Fork-changes。

4.10.6 君士坦丁堡(Constantinople)

“大都会”升级的第二阶段被称作“君士坦丁堡”,原计划于2019年1月中旬在第7 080 000个区块上执行。

不过由于潜在的安全问题,以太坊核心开发者和社区其他成员投票决定推迟升级,直到该安全漏洞得以修复。

最终在2019年2月28日区块高度7 280 000上得到执行。其中主要的EIPs包括:

EIP145——增加按位移动指令;

EIP1052——允许智能合约只需通过检查另一个智能合约的哈希值来验证彼此;

EIP1014——添加了新的创建合约的指令CREATE2;

EIP1234——区块奖励从每块3 ETH减少到2 ETH,难度炸弹推迟12个月。

4.10.7 伊斯坦布尔(Istanbul)

伊斯坦布尔是在9 069 000在块高执行的,执行时间是在2019年12月8日,伊斯坦布尔分叉有以下几个重要改进:

(1)降低calldata(是一个存储数据的位置,将在第6章介绍)参数的gas消耗(EIP2028);

(2)降低alt_bn128(椭圆曲线)预编译函数的gas消耗(EIP1108);

(3)增加了chainid操作码,让智能合约可以识别自己在主链还是分叉链或二层网络扩容链上(EIP-1344);

(4)添加BLAKE2预编译函数,让以太坊可以和专注隐私功能的Zcash链交互,提高以太坊的隐私能力。

其中,前三点对以太坊的二层网络扩容方案是重大利好,因为很多二层网络方案会把很多交易打包在一起传递给(通过calldata参数)智能合约验证(通过alt_bn128函数验证)。

伊斯坦布尔分叉另外还有两个重新调整gas费用的改进:EIP-1884(链接:

https://learnblockchain.cn/docs/eips/eip-1884.html)及EIP-2200(链接:https://learnblockchain.cn/docs/eips/eip-2200.html)。

这里不详细介绍,读者有兴趣可以通过链接阅读。

4.10.8 以太坊2.0

以太坊2.0将是以太坊非常重大的改进(以此对应当前的以太坊有时被称为以太坊1.x),以太坊2.0将从现在的工作量证明(PoW)共识完全转换到权益证明(PoS)共识,同时还会引入分片(sharding)概念,让以太坊的网络能力可以提高到每秒处理数千至上万笔交易,以及技术引入新的虚拟机eWASM(Ethereum-flavored Web Assembly)执行合约,让编写智能合约有更多的选择,由于以太坊2.0是一个庞大的项目,以太坊社区计划分为3个阶段来完成:

(1)第0阶段:建立信标链(Beacon Chain)。

信标链主要用来完成从POW到PoS共识机制的转变,信标链通过质押32个ETH成为验证人来参与出块(而不再是使用算力参与挖矿)恶意出块的验证人会通过扣除质押金的方式进行处罚。同时信标链将成为之后分片链协调者和管理者。

本书写作时(2020年6月)信标链测试网络已经启动。

(2)第1阶段:分片。

这个阶段将启动64条分片链同时进行交易、存储和信息处理,当前的以太坊1.x会作为其中的一条分片链,信标链将对分片链的执行情况进行监督。

分片是以太坊扩容的关键。

(3)第2阶段:引入状态机制/执行机制,例如eWASM。

这个阶段会带来哪些内容,还有很多不确定性。

在朝以太坊2.0发展的同时,以太坊1.x同样会持续得到完善。

       

【声明】内容源于网络
0
0
数组智控产业发展科技院
以AI技术为底层能力,聚焦智慧园区、城市公共安全、数智警务、健康医疗、能源电力、科研实验及平安校园等领域,提供从感知到决策的全流程软硬件一体化的国产装备智能体产品解决方案。
内容 986
粉丝 0
数组智控产业发展科技院 以AI技术为底层能力,聚焦智慧园区、城市公共安全、数智警务、健康医疗、能源电力、科研实验及平安校园等领域,提供从感知到决策的全流程软硬件一体化的国产装备智能体产品解决方案。
总阅读2.8k
粉丝0
内容986