以太坊学习笔记

以太坊学习笔记

0. 术语

外部拥有账户 EOA

Externally Owned Account,外部拥有账户,由以太坊的真人用户创建的账户。账户的一种,另一种是合约账户。

地址 Address

代表一个账户,是 ECDSA 公钥的 Keccak 散列的最右边的160位,表现为16进制的40个字符长度,在前面加上0x字符。

比特币改进提议 BIP

Bitcoin Improvement Proposals,由比特币社区成员提交。

区块 Block

区块是关于所包含的交易的所需信息(区块头)的集合,以及称为ommer的一组其他区块头。它被矿工添加到以太坊网络中。

区块链 Blockchain

由 工作证明系统 验证的一系列区块,每个区块都连接到它的前任,一直到创世区块。这与比特币协议不同,它没有块大小限制。

共识 Consensus

网络上的大量大多数节点,在其本地验证的最佳区块链中都有相同的区块的情况。

共识规则 Consensus rules

完整节点为了与其他节点保持一致,遵循的区块验证规则。

合约账户 Contract account

包含代码的账户,每当它从另一个账户(EOA 或合约)收到交易时将执行。

合约创建交易 Contract creation transaction

一个特殊的交易,以“零地址”作为收件人,用于注册合约并将其记录在以太坊区块链中。

去中心化自治组织 DAO

Decentralised Autonomous Organization,没有层级管理的公司和其他组织。

也可能是指2016年4月30日发布的名为The DAO的合约。

去中心化应用 DApp

Decentralised Application,Web 应用程序,至少包括智能合约和 web 用户界面,许多 DApp 也包括去中心化存储和/或消息协议和平台。

契约 Deed

不可替代的标记标准,证明了所有权并且不可互换。但目前还未在任何管辖区都被认可为合法文件。

难度 Difficulty

网络范围的设置,控制产生工作量证明需要多少计算。

数字签名 Digital signature

用户可以使用私钥生成称为“签名”的短字符串数据,使其他人可以验证该文件由该特定私钥的所有者“签名”,以及该文件在签署后未被更改。

椭圆曲线数字签名算法 ECDSA

Elliptic Curve Digital Signature Algorithm,用来确保资金只能由合法所有者使用。

以太坊改进建议 EIP

Ethereum Improvement Proposals,描述以太坊平台的建议标准。

以太坊名称服务 ENS

Ethereum Name Service。

以太坊注释请求 ERC

Ethereum Request for Comments,一些 EIP 被标记为 ERC,表示试图定义以太坊使用的特定标准的建议。

Ethash

以太坊1.0的工作量证明算法。

以太 Ether

以太坊系统中使用的本地货币,符号是 ΞXi

事件 Event

允许EVM日志工具的使用,后者可以用来在DApp的用户界面中调用JavaScript回调来监听Event。

以太坊虚拟机 EVM

Ethereum Virtual Machine,在以太坊中,执行模型指定了系统状态如何发生改变。 这是通过虚拟状态机的正式模型指定的。

Ganache

私有以太坊区块链,可以在上面进行测试,执行命令,在控制区块链如何运作时检查状态。

燃气 Gas

以太坊用于执行智能合约的虚拟燃料。EVM使用会计机制来衡量天然气的消耗量并限制计算资源的消耗。燃气是执行智能合约的每条指令产生的计算单位。燃气与以太加密货币挂钩。

燃气限制 Gas limit

区块有一个名为燃气限制的区域。它定义了整个区块中所有交易允许消耗的最大燃气量。

创世区块 Genesis block

区块链中的第一个块,用来初始化特定的网络和加密数字货币。

硬分叉 Hard fork

区块链中的一种永久性分歧,通常发生在非升级节点无法验证升级节点创建的遵循新共识规则的区块时。

分层确定钱包 HD wallet

使用分层确定密钥生成和传输协议的钱包。

分层确定钱包种子 HD wallet seed

HD钱包种子或根种子是一个可能很短的值,用作生成HD钱包的主私钥和主链码的种子。钱包种子可以用助记词表示。

互换客户端地址协议 ICAP

Inter exchange Client Address Protocol,以太坊地址编码,与国际银行帐号(IBAN)编码部分兼容。ICAP总是以XE开始。目的是引入一个新的IBAN国家代码。X表示”extended”,E表示以太坊。

Keccak256

以太坊使用的加密哈希方法,不同于标准的 NIST-SHA3。

密钥推导方法 KDF

Key Derivation Function,也称为密码扩展算法,它被keystore格式使用,以防止对密码加密的暴力破解。

Keystore 文件

JSON 编码的文件,包含一个(随机生成的)私钥,被一个密码加密,以提供额外的安全性。

库 Library

以太坊中的库,是特殊类型的合约,没有用于支付的方法,没有后备方法,没有数据存储。所以它不能接收或存储以太,或存储数据。库用作之前部署的代码,其他合约可以调用只读计算。

轻量级客户端 Lightweight client

是一个以太坊客户端,它不存储区块链的本地副本,也不验证块和事务。它提供了钱包的功能,可以创建和广播交易。

消息 Message

内部交易,从未被序列化,只在EVM中发送。

矿工 Miner

通过重复哈希计算,为新的区块寻找有效的工作量证明的网络节点。

网络 Network

将交易和区块传播到每个以太坊节点的对等网络。

节点 Node

参与到对等网络的软件客户端。

Ommer

祖父节点的子节点,但它本身并不是父节点。当矿工找到一个有效的区块时,另一个矿工可能已经发布了一个竞争的区块,并添加到区块链顶部。以太坊中的孤儿区块可以被新的区块作为ommers包含,并获得部分奖励。

权益证明 PoS

Proof-of-Stake,加密货币区块链协议旨在实现分布式共识的一种方法。权益证明要求用户证明一定数量的加密货币的所有权,以便能够参与交易验证。

工作量证明 PoW

Proof-of-Work,一份需要大量计算才能找到的数据(证明)。在以太坊,矿工必须找到符合网络难度目标的 Ethash 算法的数字解决方案。

收据 Receipt

以太坊客户端返回的数据,表示特定交易的结果,包括交易的哈希值、区块编号、使用的燃气量,以及在部署智能合约时的合约地址。

重入攻击 Re-entrancy Attack

当攻击者合约(Attacker contracts)调用受害者合约(Victim contracts)的方法时,可以重复这种攻击。称为victim.withdraw(),在对该合约函数的原始调用完成之前,再次调用victim.withdraw()方法,持续递归调用它自己。 递归调用可以通过攻击者合约的后备方法实现。 攻击者必须执行的唯一技巧是在用完燃气之前中断递归调用,并避免盗用的以太被还原。

REVERT指令

REVERT指令提供了一种停止执行和恢复状态更改的方式,不消耗所有提供的燃气并且能够返回原因。

奖励 Reward

ETH的数量,包含在每个新区块中的金额作为网络对找到工作证明解决方案的矿工的奖励。

递归长度前缀 RLP

Recursive Length Prefix,一种编码标准,用来编码和序列化任意复杂度和长度的对象/数据结构。

SELFDESTRUCT 操作码

只要整个网络存在,智能合约就会存在并可执行。如果它们被编程为自毁的或使用委托调用(delegatecall)或调用代码(calicoed)执行该操作,它们将从区块链中消失。 一旦执行自毁操作,存储在合约地址处的剩余Ether将被发送到另一个地址,并将存储和代码从状态中移除。 尽管这是预期的行为,但自毁合约的修剪可能或不会被以太坊客户实施。

智能合约 Smart Contract

在以太坊的计算框架上执行的程序。

交易 Transaction

由原始帐户签署的提交到以太坊区块链的数据,并以特定地址为目标。交易包含元数据,例如交易的燃气限额。

钱包 Wallet

拥有你的所有密钥的软件。作为访问和控制以太坊账户并与智能合约交互的界面。不存储实际的硬币或代币。

Wei

以太的最小单位。$10^{18}\ \rm wei = 1\ \rm ether$ .

零地址 Zero address

特殊的以太坊地址,全部是由 0 组成(即 0x0000000000000000000000000000000000000000),被指定为创建一个智能合约所发起的交易的目标地址(即 to 参数的值)。

1. 以太坊概念

1.1 以太坊基本概念及历史

从计算机科学的角度来说,以太坊是一种确定性但实际上无界的状态机,它有两个基本功能,第一个是全局可访问的单例状态,第二个是对状态进行更改的虚拟机。

从更实际的角度来说,以太坊是一个开源的、全球的去中心化计算架构,执行被称为 智能合约 的程序。它使用区块链来从同步和存储系统状态,并使用称为 ether 的加密货币来计量和约束执行资源成本。

以太坊与其他开放区块链共享许多通用元素:连接参与者的对等网络,用于状态同步(工作证明)的共识算法,数字货币(以太)和全局账本(区块链)。

开源、公开的区块链通常包括以下组件:

  • 一个连接参与者,传播交易和包含已验证交易的区块的点对点网络,基于标准的gossip协议。
  • 状态机中实现的一系列共识规则。
  • 消息,以交易的形式表示,代表状态转移。
  • 根据共识规则处理交易的状态机。
  • 分布式数据库,区块链,记录所有状态转移的日志。
  • 共识算法,通过强制参与者竞争并使用共识规则约束他们,来分散区块链的控制权。

相比于比特币,以太坊中的开发文化的重点是速度和创新,即使会破坏兼容性。因此以太坊开发人员面临的一个重大挑战是将代码部署到不可变账本与仍在快速发展的开发平台之间的内在矛盾。

以太坊的主要目的不是数字货币支付网络,但数字货币ether对于以太坊的运作来说仍是必要的。

与具有非常有限的脚本语言的比特币不同,以太坊被设计成一个通用可编程区块链,能够执行任意和无限复杂的代码。以太坊的语言是图灵完备的,这意味着它相当于一台通用计算机。

以太坊的发展计划分四个阶段进行,每个新阶段都会发生重大变化。每个阶段都可能包含不向后子版本,称为“硬分叉”。四个主要的发展阶段为:

  • 前沿(Frontier)
    • 冰河时代(Ice Age)
  • 家园(Homestead)
    • DAO
    • 蜜桔前哨(Tangerine Whistle)
    • 假龙(Spurious Dragon)
  • 大都会(Metropolis)
    • 拜占庭(Byzantium)
    • 君士坦丁堡(Constantinople)(当前阶段)
  • 宁静(Serenity)

原始区块链(比特币的区块链)追踪比特币单位的状态及其所有权。可以将比特币视为分布式共识状态机,其中交易引起全局的状态转移,从而更改比特币的所有权。状态转移受共识规则的制约,允许所有参与者开采数个区块后在系统的共同共识状态上汇合。

以太坊也是一个分布式状态机。除了货币所有权的状态,以太坊还可以追踪通用数据存储的状态转换,通常为键值对。以太坊有自己的memory用来存储代码和数据,使用区块链来跟踪这些内存随着时间的变化。可以将代码加载到其状态机中并运行该代码,并将结果状态更改存储在其区块链中。以太坊状态的变化受共识规则的支配,并且状态通过共享账本全球分布。

1.2 以太坊的组件

P2P Network

以太坊在以太坊主网上运行,可以通过TCP端口30303访问,运行称作ÐΞVp2p的协议。

Consensus rules

以太坊的共识规则,在参考规范,即黄皮书中定义。

Transactions

Ethereum交易,一种网络消息,包括发送者,接收者,值和数据负载等。

State Machine

以太坊的状态转移由EVM处理,执行被称为“智能合约”的程序。

Blockchain

以太坊的区块链作为database存储在每个节点上(通常使用LevelDB),包含交易和系统状态。

Consensus Algorithm

以太坊目前使用名为Ethash的工作量证明算法,将逐步过渡到称为Casper的权益证明系统。

1.3 以太坊与图灵完备性

以太坊是一台通用图灵机,可以计算任何图灵机可以计算的算法。

图灵完备系统可以在“无限循环”中运行。以太坊在没有实际运行时,无法预测智能合约是否会终止,或者运行多久。为了应对这一问题,以太坊引入了称为燃气(gas)的计量机制。EVM在执行智能合约时,会仔细考虑每条指令的成本。每条指令都有一个以燃气为单位的预定成本。当交易触发智能合约的执行时,它必须包含一定量的燃气,用以设定运行智能合约可消耗的计算上限。如果计算所消耗的燃气量超过交易中可用的然气量,则EVM将终止该合约的执行。

1.4 去中心化应用

web3.js库中包含名为Swarm的P2P存储网络接口和名为Whisper的P2P消息传递服务。通过包含这些组件,可以构建DApp。

2. 以太坊基础

2.1 概述

加密货币功能是服务于以太坊作为世界计算机的功能。以太旨在用于支付运行的智能合约。

EVM是一个全球性的单实例计算机。以太坊网络上的每个节点运行EVM的本地副本以验证合约执行,而以太坊区块链记录此世界计算机在处理交易和智能合约时变化的状态。

外部所有账户是那些拥有私人密钥的账户,它控制对资金或合约的访问。合约账户由以太坊区块链记录,由EVM执行的软件程序的逻辑所拥有和控制。区别在于人们通过EOA做出决定,而软件通过合约做出决定。

当交易目的地是合约地址时,它会导致该合约在EVM中运行,并将交易作为其输入。除了ether之外,交易还可以包含数据,用于指示合约中要运行的特定方法以及传递给该方法的参数。通过这种方式,合约可以产生调用其他合约的交易,从而建立复杂的执行路径。

2.2 合约代码示例

Solidity是智能合约编程的主要高级语言。

一个简单的合约:

1
2
3
4
5
6
7
8
9
10
11
contract Faucet {
// Give out ether to anyone who asks
function withdraw(uint withdraw_amount) public {
// Limit withdrawal amount。单位为wei
require(withdraw_amount <= 100000000000000000);
// Send the amount to the address that requested it
msg.sender.transfer(withdraw_amount);
}
// Accept any incoming amount
function () public payable {}
}

uint:无符号整数;

require:如果不满足则停止执行并显示异常;

msg:所有合约可以访问的输入对象之一,代表触发执行此合约的交易;

msg.sender:触发此合约执行的交易的 sender,也即调用此函数的账户。

function () public payable {}:默认函数,如果合约的交易没有命中任何已声明的其他函数,则会触发此函数。

2.3 编译Solidity合约

使用一个被称为Remix的在线IDE:https://remix.ethereum.org/

2.4 在区块链上创建合约

使用Ropsten测试网来测试合约。在区块链上注册合约需要向零地址发起一个特殊交易。

首先安装MetaMask浏览器插件:MetaMask - Chrome 网上应用店 (google.com)

随后导入或者创建钱包:

3. 以太坊客户端

以太坊客户端是实现以太坊规范并通过对等网络与其他以太坊客户端进行通信的程序,它可以由不同的编程语言实现。

3.1 以太坊网络

存在着各种基于以太坊的网络,这些网络很大程度上符合以太坊“黄皮书”中定义的规范,但它们可能或不能互相操作。较为出名的以太坊网络有:Ethereum、Ethereum Classic、Ella、Expanse、Ubiq、Musicoin等。较为出名的以太坊客户端有:Geth(Go)、parity(Rust)、cpp-ethereum(C++)、pyethereum(Python)、mantis(Scala)、harmony(Java)。

3.2 完整节点

每个完整节点都可以帮助其他新节点获取块数据以引导其操作,并为运营商提供对所有交易和合约的权威和独立验证。但是,运行完整的节点会导致硬件资源和带宽的巨大成本。

轻量级客户端不会存储区块链的本地副本或验证块和交易;但提供钱包的功能,并可以创建和广播交易;同时还提供API功能(如web3js API)。轻量级客户端通常不验证区块头或交易,它们完全信任由第三方运营的完整客户端并通过RPC访问区块链。

3.2.1 完整节点优缺点

优点:

  • 可以权威性验证所有交易
  • 无需中介即可与公共区块链上的任何合约进行交互
  • 可以离线查询区块链状态
  • 无需中介即可将自己的合约部署到公共区块链中

缺点:

  • 需要大量且不断增长的硬件和带宽资源
  • 需要较长时间完成初始同步

3.2.2 公共测试网优缺点

优点:

  • 测试网需要同步的数据量极少
  • 交易所需的测试ether可以免费获得

缺点:

  • 测试网gas免费,而主网需要考虑gas费用
  • 测试网不会像主网那样经历网络拥塞

3.2.3 本地实例(TestRPC)

TestRPC节点可以创建一个本地私有区块链实例,无需其他参与者即可与之交互。

但这也意味着它没有交易的空间、无法测试公链上采矿的不可预测性、必须自己部署依赖与合约以及不能创建公共合约。

3.3 运行以太坊客户端