mastering-ethereum
第二章 - 以太坊基础知识
以太坊钱包
表示抱住管理以太坊账户的软件应用程序
MetaMask
MetaMask是一个在浏览器中运行的浏览器扩展钱包,易于使用且方便测试,MetaMask是一个基于网络的钱包. 是一个多功能的基于浏览器的钱包、RPC客户端和基本合约浏览器.MetaMask将web3实例注入浏览器JavaScript上下文中,充当链接到各种以太坊区块链的RPC客户端Jaxx
Jaxx是一款多平台、多货币钱包,可在多种操作系统上运行,Jaxx是移动钱包或桌面钱包MEW
MyEtherWallet是一个基于网络的钱包,可以在任何浏览器中运行。
EVM
EVM是一个全局单例,这意味着他的运行就像一台全局单实例计算机一样,在任何地方运行,在以太坊网络上的每个节点都运行EVM的本地副本来验证合约执行,而以太坊区块链则记录这台世界计算机在处理交易和智能合约时的状态变化。
EOA(Externally Owned Accounts) && Contarct Account
EOA称为外部拥有账户,外部拥有的账户是指哪些拥有私钥的账户,合约账户,合约账户有智能合约代码。合约账户有地址,合约也可以发送和接收以太币.当交易的目的地时合约地址时,它会导致该合约在EVM中运行,并使用交易和交易数据作为其输入.由于合约地址没有私钥,因此无法发起交易。
第三章 - 以太坊客户端
目前,以太坊协议有六种主要实现,用六种不同的语言编写:
名称 | 编写语言 |
---|---|
Parity | Rust |
Geth | Go |
cpp-ethereum | C++ |
pyethereum | Python |
Mantis | Scala |
Harmony | Java |
全节点的优点和缺点
JSON-RPC接口
以太坊客户端提供应用程序编程接口和一组远程过程调用(RPC)命令,这些命令被编程为JavaScript对象表示法(JSON). JSON-RPC API是一个接口,允许我们编写使用以太坊客户端作为以太坊网络和区块链网关的程序.
第四章 - 密码学
- 密钥和地址
以太坊有两种不同类型的账户: 外部账户(EOA)和合约. EOA对以太坊的所有权是通过数字私钥、以太坊地址和数字签名建立的,私钥是所有用户与以太坊交互的核心,事实上,账户地址直接源自私钥:私钥唯一确定单个以太坊地址,也称为账户.
私钥
不以任何方式直接在以太坊系统中使用;它们永远不会在以太坊上传输或存储。只有账户地址和数字签名会被传输和存储在以太坊系统上.资金的访问
公钥密码学和加密货币
公钥密码学(也称为“非对称密码学”),公钥加密使用唯一的密钥来保护信息,这些密钥基于具有特殊属性的数学函数,计算它们很容易,但是计算它们的逆却很难.
素因数分解
: 将两个大素数相乘计算出结果很简单,但是给定两个大素数的乘积,找到两个素数是非常困难的
有关密码学和现代密码学中使用的数学函数有一下几种:
在以太坊中,我们使用公钥加密技术(也称为非对称加密技术)来创建本章讨论的公私密钥对,它们被视为“对”,因为公钥是从私钥派生,它们共同代表一个以太坊账户
2^256 – 以太坊私钥空间的大小是一个很大的数字,十进制10^77,
私钥
私钥知识一个随机选择的数字,私钥的所有权和控制权是用户控制与响应以太坊地址相关的所有资金以及访问授权地址的合约的根源
公钥
以太坊公钥是椭圆曲线上的一个点,意味着他是满足椭圆曲线方程的一组x和y坐标.简单来说,以太坊公钥是两个数字连接在一起,这些数字是通过只能单向计算从私钥生成的。
1 |
|
椭圆曲线乘法是一种被密码学家称为”单向”函数的函数:在一个方向(乘法)很容易实现,而在相反方向(除法)是不可能实现的.私钥的所有者可以轻松创建公钥,然后与全世界共享,因为没有人可以从公钥计算出私钥。这种数学技巧称为不可伪造的安全数学签名的基础。证明以太坊资金的所有权和合约的控制权.
- 椭圆曲线密码学
椭圆曲线密码学是一种基于离散对数问题的非对称或公钥密码学,由椭圆曲线上的点的乘法表示.
以太坊使用与比特币完全相同的椭圆曲线,称为secp256k1,这使得重用比特币中许多椭圆曲线库和工具
- 加密哈希函数
哈希函数
是任何可用于将任意大小的数据映射到固定大小的数据的函数.加密哈希函数
是一种单向哈希函数,它将任意大小的数据映射到固定大小的位串,单向
性质意味着如果只知道输出哈希,则在计算上无法重新创建输入数据.哈希函数
是”多对一”函数,查找散列到相同输出的两组输入数据称为查找散裂冲突.
加密哈希函数的主要属性:
确定性(Determinism):
给定输入消息总是产生相同的哈希输出
可验证性(Verifiability)
计算消息的哈希值是高效的
非相关性
对消息的一个小更改应该会极大地改变散列输出,
以太坊的加密哈希函数: keccak-256
以太坊使用Keccak-256,尽管他在代码中通常称为SHA-3.
以太坊地址
以太坊地址使用Keccak-256单向哈希函数从公钥或合约生成的唯一标识符
1 |
|
钱包
钱包
这个词用来描述以太坊中的一些不同的东西
从较高层面来说,钱包是一种软件应用程序,充当以太坊的主要用户界面。钱包控制对用户资金的访问,管理密钥和地址,跟踪余额以及创建和签署交易.
更狭义地说,从程序员的角度来看,钱包
一词是指用于存储和管理用户密钥的系统.每个钱包都有一个密钥管理组件。
钱包技术
关于以太坊的一个常见误解是从以太坊钱包包含以太坊或代币,事实上,严格来说,钱包只保存钥匙,以太币或其他代币记录在以太坊区块链上.用户通过使用钱包中的密钥签署交易来控制网络上的代币.从某种意义上来说,以太坊钱包就是一个钥匙串
以太坊钱包包含密钥,而不是以太币或代币,钱包就像包含私钥和公钥对的钥匙串,用户使用私钥签署交易,从而证明它们拥有以太币。以太币存储在区块链上.
钱包主要由两种类型,根据它们包含的密钥是否相互关联区分:
非确定性钱包
其中每个密钥都是根据不同的随机数独立生成,密钥彼此不相关,这种类型的钱包称为
JBOK
钱包, “Just a Bunch of Keys”确定性钱包
所有密钥都源自单个主密钥(种子),此类钱包中的所有密钥都是相互关联.为了确定性钱包更安全防止数据丢失事故,种子通常被编码为单词列表(英文或其他语言)。这些被称为钱包的助记词.
确定性(种子)钱包
- 分层确定性钱包(BIP-32/BIP-44)
目前最先进的确定性钱包是比特币BIP-32标准定义的分层确定性(HD)钱包. HD钱包包含以树结构派生的密钥,使得父密钥可以派生一系列子密钥
- 种子和助记符代码(BIP-39)
使用一系列单词,当以正确的顺序组合在一起时,可以唯一地重新创建私钥.称为助记符. 使用恢复单词列表对HD钱包的种子进行编码,可以最简单地安全导出、转录、记录在纸上、无错误读取以及将私钥集倒入到另一个钱包中.
以下详细研究其中每一项技术:
- 助记码(BIP-39)
助记词列表使得用户更容易备份钱包,因此它们易于阅读和正确转移.
助记词经常和”brainwallets”混淆,它们不一样,主要区别在于,脑钱包由用户选择的单词组成,而助记词是由钱包随机创建并呈现给用户的,这一重要的区别使得助记词更加安全,因为人类的随机性来源非常差,也许更重要的是,使用”脑钱包”这个词意味着必须记住这些词.
交易
交易是由外部账户发起,由以太坊网络传输并记录在以太坊区块链上的签名消息.交易是唯一可以触发状态变化或导致合约在EVM中执行的事物.
交易的结构
交易是包含以下数据的序列化二进制消息:
- 随机数
由外部账户发出的序列号,用于防止消息重放
nonce: 一个标量值,等于从该地址发送的交易数量,或者在具有关联合约的账户的情况下,等于该账户创建的合约数量
严格来说,nonce是源地址的一个属性;也就是说,它仅在发送地址的上下文中有意义,但是,随机数并未明确存储为区块链上账户状态的一部分。相反,它是通过计算发送地址已确任交易的数量来动态计算的.
1 |
|
随机数之间的差距、重复随机数和确认
1 |
|
并发行、交易发起和随机数
1 |
|
- Gas价格 GasPrice
发起者愿意支付的Gas价格(以wei为单位)
1 |
|
可接受的最低GasPrice为零,这意味着钱包可以产生完全免费的交易,根据容量的不同,这些可能永远不会被确认,但协议中没有任何内容禁止自由交易
- Gas Limit
交易发起者愿意为此次交易支付的最大Gas
对于简单支付,将以太币从一个EOA转移到另一个EOA的交易,所需要的Gas量固定为21000 Gas单位,要计算需要话费多少以太币,请将21,000乘以你愿意支付的GasPrice
- 交易接收者
目标以太坊地址
1 |
|
- 交易金额
发送到接收者的以太币数量
1 |
|
- 数据
可变长度二进制数据有效payload
发送到ABI兼容合约的数据负载是以十六进制序列化编码:
1 |
|
特殊交易: 合约创建
1 |
|
- v,r,s
原始EOA的ECDSA数字签名的三个组成部分
交易消息的结构使用递归长度前缀(RLP)编码方案进行序列化,该方案是专门为以太坊中简单、字节完美的数据序列化而创建的。以太坊中的所有数字都编码为大端整数,长度为8位的倍数.
数字签名
椭圆曲线数字签名算法 ECDSA
数字签名在以太坊中具有三个用途,首先,签名证明私钥的所有者(即以太坊账户的所有者)已授权花费以太币或执行合同,其次,它保证不可否认性,第三,签名证明交易数据在交易签名后无法被任何人修改.
- 创建数字签名
1 |
|
- 验证签名
1 |
|
- Fsig签名算法
交易传播
多重签名(Multisig)交易
多重签名交易作为智能合约实现的能力证明了以太坊的灵活性,然而,它是一把双刃剑,因为额外的灵活性可能会导致漏洞
智能合约和Solidity语言
外部账户(EOA)是没有任何关联代码或数据存储的简单账户,而合约账户既有关联代码又有数据存储
什么是智能合约?
“智能合约”指代在作为以太坊网络协议一部分的以太坊虚拟机环境中确定性运行的不可变计算机程序
程序
智能合约只是计算机程序可不变性
一旦部署,智能合约的代码就无法更改,与传统软件不同,修改智能合约的唯一方法是部署新实例确定性
智能合约的执行结果对于每个运行它的人来说都是相同的EVM上下文
智能合约在非常有限的执行环境下运行,它们可以访问自己的状态、调用它们的交易的上下文以及有关最新区块的信息去中心化世界计算机
EVM作为每个以太坊节点上的本地实例运行,但由于EVM的所有实例都在相同的初始状态下运行并产生相同的最终状态
智能合约的生命周期?
1 |
|
以太坊高级语言
1 |
|
目前支持的智能合约高级编程语言包括以下:
LLL
一种函数式(声明式)编程语言,具有类似Lisp的语法,它是以太坊智能合约的第一种高级语言
Serpent:
一种过程式(命令式)编程语言, 其语法类似Python.
Solidity
一种过程式(命令式)编程语言,其语法类似于JavaScript、C++或Java.
Vyper
一种类似于Serpent的开发语言,同样类似Python语法,旨在比Serpent更接近纯函数式的类似Python的语言,并不是要取代Serpent.
Bamboo
一种新开发的语言,受Erlang的影响,具有明确的状态转换并且没有循环流
使用Solidity构建智能合约
solc
Solifity编译器solc,将Solidity语言编写的程序转换为EVM字节码
以太坊合约ABI
ABI定义了如何在机器代码中访问数据结构和函数,合约的ABI被指定为函数描述和事件的JSON数组,函数描述是一个包含字段type、name、inputs、outputs、constant的JSON对象payable.
1 |
|
智能合约安全
安全最佳实践
防御性编程是一种特别适合智能合约的编程风格
- 极简主义
复杂性是安全的敌人,代码越简单,所做的事情越少.出现错误或不可预见的影响的可能性就越低
- 代码复用
尽量不要重新发明轮子,如果已经存在可以满足大部分需要的库或合约,请重用,在自己的代码中,遵循DRY原则,不要重复自己
代码质量
可读性/可审计性
代码应该清晰易于理解测试覆盖率
智能合约在公共执行环境中运行,任何人都可以使用它们想要的任何输入来执行它们.你不应该假设输入格式良好,界限正确或具有良性目的
安全风险和反模式
可重入性
外部恶意合约调用易受攻击的合约上的函数,并且代码执行路径”重新进入”它.预防技术
1 |
|
现实世界的例子: DAO
DAO(去中心化自治组织)攻击是以太坊早起开发中发生的主要黑客攻击之一,可重入性在攻击中发挥了重要作用,最终导致了创建以太坊经典(ETC)的硬分叉.
算术溢出
以太坊虚拟机为整数指定了固定大小的数据类型,意味着整型变量智能表示一定范围的数字
1 |
|
1 |
|
令牌 token
令牌如何使用
令牌最明显的用途是作为数字私人货币
货币
令牌可以作为货币的一种形式,其价值通过私人交易确定
资源
令牌可以代表在共享经济或资源共享环境中赚取或产生的资源
资产
令牌可以额代表内在或外在,有形或无形资产的所有权
使用权
令牌可以代表访问权限并授予对数字或物理资产的访问权限
公平
令牌可以代表数字组织或法人实体中的股东权益
表决
令牌可以代表数字或法律系统中的投票权
收藏品
令牌可以代表数字收藏品
身份
令牌可以代表数字身份或合法身份
签证
令牌可以代表某个权威机构或去中心化声誉系统
公共事业
令牌可用于访问或支付服务费用
1 |
|
基于区块链的令牌最重要的影响是能够将外部资产转换为内部资产,从而消除交易对手风险。
以太坊上的令牌
1 |
|
ERC20令牌标准
ERC20标准为实现令牌代币的合约定义了一个通用接口,以便可以以相同的方式访问和使用任何兼容的代币,该接口由许多必须存在于标准的每个实现中的函数以及开发人员可以添加的一些可选函数和属性组成
1 |
|
预言机 - Oracles
预言机,它是可以为以太坊智能合约提供外部数据源的系统,在区块链的背景下,语言机是一个可以挥发以太坊外部问题的系统.理想情况下,语言机是去信任的系统,意味着它们不需要被信任,因为它们按照去中心化原则运行
为什么需要预言机
以太坊平台的一个关键组件是以太坊虚拟机,它能够在去中心化网络中的任何节点上执行程序并更新以太坊状态(受共识规则约束). 为了保持共识,EVM的执行必须是完全确定性的,并且仅基于以太坊状态和签名交易的共享上下文。者两个特别重要的后果: 第一个是EVM和智能合约无法使用内在的随机性来源,第二是外部数据只能作为交易的数据负载引入.
预言机用例
理想情况下,预言机提供一种无需信任(或至少无需信任)的方式来获取外部信息.因此,预言机可以被认为是一种弥合链下世界和智能合约之间差距的机制.
预言机设计模式
根据定义,所有预言机都提供一些关键功能
1 |
|
设置预言机的三种主要方式分为:
1 |
|
数据认证
数据身份验证的两种常见方法是真实性证明
和可信执行环境(TEE)
.
真实性证明
真实性证明是数据未被篡改的加密保护.基于各种证明技术,它们有效地将信任从数据载体转移到证明者.通过验证链上的真实性证明,正能合约能够在对其进行操作之前验证数据的完整性.
TEE 可信执行环境
计算预言机
预言机也可以用于执行任意计算,计算预言机不仅仅是转发查询结果,还可以用于对一组输入执行计算,并返回可能无法在链上计算的计算结果
去中心化预言机
去中心化应用程序 (DApp)
Web3: 使用智能合约和P2P技术的去中心化网络.
什么是DApp?
DApp是一种大部分或完全去中心化的应用程序.
创建DApp由许多典型中心化架构无法提供的优势:
弹性:
由于业务逻辑由智能合约控制,因此DApp后端将完全在区块链平台上分布和管理.透明度:
DApp的链上性质允许每个人检查代码并更加确定其功能, 与DApp的任何交互都将永久存储在区块链中抵制审查制度:
只要用户有权访问以太坊节点,用户就始终能够与DApp进行交互,而不会收到任何集中控制的干扰后端(智能合约)
在DApp中,智能合约用于存储应用程序的业务逻辑和相关状态.智能合约架构设计的一个主要考虑因素是智能合约一旦部署就无法更改代码,智能合约架构设计的第二个主要考虑因素是DApp的大小.前端 (网页用户界面)
DApp的客户端界面可以使用标准的Web技术(HTML,CSS,JavaScript),前端通常通过web3.js JavaScript库链接到以太坊,该库与前端资源捆绑在一起,并通过Web服务向浏览器提供服务.数据存储
智能合约不适合存储或处理大量数据,大多数DApp使用链下数据存储服务,这意味着它们将以以太坊链上的大量数据存储在数据存储平台. 去中心化P2P存储非常适合存储和分发大型静态资产.
1 |
|
- 去中心化消息通信协议
1
任何应用程序的主要组成部分进程间通信,DApp最著名的P2P消息传递协议是Whisper. 它是以太坊基金会Go-Ethereum工具套件的一部分.
第十三章 以太坊虚拟机
以太坊协议和操作的核心是以太坊虚拟机, 简称EVM
什么是EVM?
EVM是以太坊的一部分,负责处理智能合约的部署和执行. EVM具有基于堆栈的架构,将所有内存值存储在堆栈上,他的字大小为256位(主要为了方便哈希和椭圆曲线操作),并且具有多个可寻址数据组件.
EVM没有调度功能,所以以太坊世界计算机是单线程的
EVM指令集(字节码操作)
EVM指令集提供您可以期望的大部分操作,除了典型的字节码操作之外,EVM还可以访问账户信息和区块信息
- 算术运算
1
2
3
4ADD // 弹出栈顶两项并相加
MUL // 弹出栈顶的两项相乘
SUB // 减去栈顶两项
DIV // 整数除法
以太坊状态
EVM的工作是通过计算智能合约代码执行的有效状态转换来更新以太坊状态,当交易导致智能合约代码执行时,EVM会被实例化,其中包含与当前正在创建的区块和正在处理的特定交易相关的所有所需信息.
将Solidity编译为EVM字节码
要获取部署字节码:
1 |
|
要获得运行时字节码
1 |
|
运行时字节码是部署字节码的子集