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
2
3
4
K = k * G

其中k是私钥, G是称为生成的常数点, K是生成的公钥.并且*是特殊的椭圆曲线乘法运算符.
简而言之:椭圆曲线上的算术不同于"常规"整数算术.G可以乘以整数k产生另一个K,但是不存在除法将公钥K除以点G计算私钥k. 这是供药密码学和加密货币中描述的单向数学函数.

椭圆曲线乘法是一种被密码学家称为”单向”函数的函数:在一个方向(乘法)很容易实现,而在相反方向(除法)是不可能实现的.私钥的所有者可以轻松创建公钥,然后与全世界共享,因为没有人可以从公钥计算出私钥。这种数学技巧称为不可伪造的安全数学签名的基础。证明以太坊资金的所有权和合约的控制权.

  • 椭圆曲线密码学

    椭圆曲线密码学是一种基于离散对数问题的非对称或公钥密码学,由椭圆曲线上的点的乘法表示.

以太坊使用与比特币完全相同的椭圆曲线,称为secp256k1,这使得重用比特币中许多椭圆曲线库和工具

simple elliptic curve

  • 加密哈希函数

    哈希函数是任何可用于将任意大小的数据映射到固定大小的数据的函数. 加密哈希函数是一种单向哈希函数,它将任意大小的数据映射到固定大小的位串,单向性质意味着如果只知道输出哈希,则在计算上无法重新创建输入数据.哈希函数是”多对一”函数,查找散列到相同输出的两组输入数据称为查找散裂冲突.

加密哈希函数的主要属性:

  • 确定性(Determinism):

    给定输入消息总是产生相同的哈希输出

  • 可验证性(Verifiability)

    计算消息的哈希值是高效的

  • 非相关性

    对消息的一个小更改应该会极大地改变散列输出,

  • 以太坊的加密哈希函数: keccak-256

    以太坊使用Keccak-256,尽管他在代码中通常称为SHA-3.

  • 以太坊地址

以太坊地址使用Keccak-256单向哈希函数从公钥或合约生成的唯一标识符

1
2
3
4
5
6
7
8
9
10
11
私钥k:
k = f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315

公钥K(x和y坐标连接并显示为十六进制)
K = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e...

使用Keccak-256计算公钥的哈希值
Keccak256(K) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9

保留最后20个字节,作为我们以太坊地址:
001d3f1ef827552ae1114027bd3ecf1f086ba0f9

钱包

钱包这个词用来描述以太坊中的一些不同的东西

从较高层面来说,钱包是一种软件应用程序,充当以太坊的主要用户界面。钱包控制对用户资金的访问,管理密钥和地址,跟踪余额以及创建和签署交易.

更狭义地说,从程序员的角度来看,钱包一词是指用于存储和管理用户密钥的系统.每个钱包都有一个密钥管理组件。

钱包技术

关于以太坊的一个常见误解是从以太坊钱包包含以太坊或代币,事实上,严格来说,钱包只保存钥匙,以太币或其他代币记录在以太坊区块链上.用户通过使用钱包中的密钥签署交易来控制网络上的代币.从某种意义上来说,以太坊钱包就是一个钥匙串

以太坊钱包包含密钥,而不是以太币或代币,钱包就像包含私钥和公钥对的钥匙串,用户使用私钥签署交易,从而证明它们拥有以太币。以太币存储在区块链上.

钱包主要由两种类型,根据它们包含的密钥是否相互关联区分:

  • 非确定性钱包

    其中每个密钥都是根据不同的随机数独立生成,密钥彼此不相关,这种类型的钱包称为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
简单来说,并发是指多个独立系统同时进行计算,这些可以在同一个程序中(多线程)、在同一个CPU上(多处理器)或在不同的计算机上(分布式系统).以太坊是一个允许并发操作(节点、客户端、DApp)但通过共识强制执行单例状态的系统.
  • Gas价格 GasPrice

    发起者愿意支付的Gas价格(以wei为单位)

1
Gas不是以太币--它是一种独立的虚拟货币。与以太币有自己的汇率,以太币使用Gas来控制交易可以使用的资源量.交易中gasPrice字段允许交易发起者设置它们愿意为交换Gas而支付的价格,价格以每Gas单位wei来衡量. GasPrice可以设置的最小值为0,这意味着免费交易,在区块空间需求较低的时期,此类交易很可能会被开采.

可接受的最低GasPrice为零,这意味着钱包可以产生完全免费的交易,根据容量的不同,这些可能永远不会被确认,但协议中没有任何内容禁止自由交易

  • Gas Limit

    交易发起者愿意为此次交易支付的最大Gas

对于简单支付,将以太币从一个EOA转移到另一个EOA的交易,所需要的Gas量固定为21000 Gas单位,要计算需要话费多少以太币,请将21,000乘以你愿意支付的GasPrice

  • 交易接收者

    目标以太坊地址

1
2
3
交易的接收者在to字段中指定,包含一个20字节的以太坊地址,地址可以是EOA或合约地址.

以太坊没有进一步验证该字段,任何20字节值都被视为有效,您可以发送到没有响应私钥或合约的地址,从而"燃烧"以太币,使其永远无法使用。
  • 交易金额

    发送到接收者的以太币数量

1
2
3
交易的主要“有效负载”包含在两个字段中: 值和数据.交易可以同时具有价值和数据、只有价值、只有数据、或者即没有价值也没有数据.

只有价值的交易叫支付;仅包含数据的事务是调用;既有价值又有数据的交易即是支付也是调用;即没有价值也没有数据的交易--只是浪费Gas
  • 数据

    可变长度二进制数据有效payload

发送到ABI兼容合约的数据负载是以十六进制序列化编码:

1
2
3
4
5
* 功能选择器:
函数原型的Keccak-256哈希值的前4个字节,这允许合约明确地识别您希望调用那个函数;

* 函数参数:
函数参数根据ABI规范中定义的各种基本类型的规范进行编码

特殊交易: 合约创建

1
合约创建被发送到一个称为零地址的特殊目标地址: 合约注册交易中的to字段包含地址0x0,该地址即不代表EOA,也不代表合约,它永远不能花费以太币或发起交易。仅用作目的地址
  • v,r,s

    原始EOA的ECDSA数字签名的三个组成部分

交易消息的结构使用递归长度前缀(RLP)编码方案进行序列化,该方案是专门为以太坊中简单、字节完美的数据序列化而创建的。以太坊中的所有数字都编码为大端整数,长度为8位的倍数.

数字签名

椭圆曲线数字签名算法 ECDSA

数字签名在以太坊中具有三个用途,首先,签名证明私钥的所有者(即以太坊账户的所有者)已授权花费以太币或执行合同,其次,它保证不可否认性,第三,签名证明交易数据在交易签名后无法被任何人修改.

  • 创建数字签名
1
2
3
4
5
6
7
8
9
10
11
在以太坊中ECDSA实现中,被签名的"消息"就是交易,或者更准确地说,是交易中RLP编码数据的Keccak-256哈希值,签名密钥是EOA的私钥
Sig = Fsig(Fkeccak256(m),k)

k: 签名私钥
m: RLP币安吗的交易
Fkeccak256: 是Keccak-256哈希函数
Fsig: 签名算法
Sig: 是生成的签名

函数Fsig生成两个值组成的签名Sig,
Sig = (r, s)
  • 验证签名
1
验证签名需要签名(r,s),序列化交易以及用于创建签名的私钥对应的公钥.本质上,签名验证意味着“只有生成该公钥的私钥的所有者才能在该交易上生成该签名”
  • Fsig签名算法

交易传播

多重签名(Multisig)交易

多重签名交易作为智能合约实现的能力证明了以太坊的灵活性,然而,它是一把双刃剑,因为额外的灵活性可能会导致漏洞

智能合约和Solidity语言

外部账户(EOA)是没有任何关联代码或数据存储的简单账户,而合约账户既有关联代码又有数据存储

什么是智能合约?

“智能合约”指代在作为以太坊网络协议一部分的以太坊虚拟机环境中确定性运行的不可变计算机程序

  • 程序
    智能合约只是计算机程序

  • 可不变性
    一旦部署,智能合约的代码就无法更改,与传统软件不同,修改智能合约的唯一方法是部署新实例

  • 确定性
    智能合约的执行结果对于每个运行它的人来说都是相同的

  • EVM上下文
    智能合约在非常有限的执行环境下运行,它们可以访问自己的状态、调用它们的交易的上下文以及有关最新区块的信息

  • 去中心化世界计算机
    EVM作为每个以太坊节点上的本地实例运行,但由于EVM的所有实例都在相同的初始状态下运行并产生相同的最终状态

智能合约的生命周期?

1
2
3
4
5
智能合约只有在交易调用时才会运行,以太坊中的所有智能合约最总都是由EOA发起的交易而执行的,一个合约可以额调用另一个合约,另一个合约又可以调用另一个合约,以此类推,但此类执行链中的第一个合约将始终由EOA中的事务调用. 智能合约在任何意义上都不是并行执行的,以太坊世界计算机可以被认为是一个单线程机器.

交易是原子的,无论它们调用了多少个合约,或者这些合约在调用时会做什么,交易会完整执行,只有在所有执行成功终止时才会被记全局状态(合约、账户)的任何变化。成功终止意味着程序执行没有错误并到达执行结束,如果执行由于错误而失败,则其所有影响(状态更改)都会"回滚",就好像事务从未运行过一样.失败的交易仍然被记录为已尝试,并且执行时花费在Gas上的以太币将从原始账户中扣除,但它对合约或账户状态没有其他影响.

合约代码无法更改,但是可以“删除”合约,从其地址中删除代码以及内部状态(存储),留下空白账户. `SELFDESTRUCT` EVM操作吗,该操作花费"负Gas",从而激励通过删除存储状态来释放网络客户端资源. 这种方式删除合约并不会删除合约的交易历史,因为区块链本身是不可变的. 还需注意,只有合约作者将智能合约编程为具有该功能,自毁程序才可用,如果合约的代码没有SELFDRSTYUCT操作码,或者无法访问,则无法删除智能合约.

以太坊高级语言

1
EVM是一种虚拟机,运行一种称为EVM字节码的特殊形式的代码.编程语言可以分为两大类编程范式:声明式和命令式,也分别称为函数式和过程式。声明式编程中我们编写表达程序逻辑的函数,但不表达其流程。命令式编程是程序员编写一组结合程序逻辑和流程的过程。

目前支持的智能合约高级编程语言包括以下:

  • 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
2
3
4
5
6
7
ethereumbook/code/Solidity on  feat/learn [!+]
➜ solc --abi Faucet.sol

======= Faucet.sol:Faucet =======
Contract JSON ABI
[{"inputs":[{"internalType":"uint256","name":"withdraw_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

智能合约安全

安全最佳实践

防御性编程是一种特别适合智能合约的编程风格

  • 极简主义

复杂性是安全的敌人,代码越简单,所做的事情越少.出现错误或不可预见的影响的可能性就越低

  • 代码复用

尽量不要重新发明轮子,如果已经存在可以满足大部分需要的库或合约,请重用,在自己的代码中,遵循DRY原则,不要重复自己

  • 代码质量

  • 可读性/可审计性
    代码应该清晰易于理解

  • 测试覆盖率
    智能合约在公共执行环境中运行,任何人都可以使用它们想要的任何输入来执行它们.你不应该假设输入格式良好,界限正确或具有良性目的

安全风险和反模式

  • 可重入性
    外部恶意合约调用易受攻击的合约上的函数,并且代码执行路径”重新进入”它.

  • 预防技术

1
2
3
1. 将以太币发送到外部合约时使用内置的传输函数
2. 确保更改状态变量的所有逻辑发生在以太币合约(任何外部调用)发送出去之前
3. 引入互斥锁,添加一个在代码执行期间锁定合约的状态变量
  • 现实世界的例子: DAO

    DAO(去中心化自治组织)攻击是以太坊早起开发中发生的主要黑客攻击之一,可重入性在攻击中发挥了重要作用,最终导致了创建以太坊经典(ETC)的硬分叉.

  • 算术溢出

    以太坊虚拟机为整数指定了固定大小的数据类型,意味着整型变量智能表示一定范围的数字

1
2
漏洞:
1. 当执行的操作需要固定大小的变量来存储超出变量数据类型范围的数字时,就会发生上溢/下溢
1
2
预防技术:
当前防范下溢/上溢漏洞的传统技术是使用或构建数学库来替代标准数据运算符

令牌 token

令牌如何使用

令牌最明显的用途是作为数字私人货币

  • 货币

    令牌可以作为货币的一种形式,其价值通过私人交易确定

  • 资源

    令牌可以代表在共享经济或资源共享环境中赚取或产生的资源

  • 资产

    令牌可以额代表内在或外在,有形或无形资产的所有权

  • 使用权

    令牌可以代表访问权限并授予对数字或物理资产的访问权限

  • 公平

    令牌可以代表数字组织或法人实体中的股东权益

  • 表决

    令牌可以代表数字或法律系统中的投票权

  • 收藏品

    令牌可以代表数字收藏品

  • 身份

    令牌可以代表数字身份或合法身份

  • 签证

    令牌可以代表某个权威机构或去中心化声誉系统

  • 公共事业

    令牌可用于访问或支付服务费用

1
2
令牌的可替代性:
维基百科:在经济学中,可替代性是一种商品或商品的属性,其各个单位本质是可以互换的。当我们可以用令牌的任何一个单位替换另一个单位而其价值或功能没有任何差异时,令牌时可替代的.

基于区块链的令牌最重要的影响是能够将外部资产转换为内部资产,从而消除交易对手风险。

以太坊上的令牌

1
令牌和以太币不同,因为以太坊协议对令牌一无所知,发送以太币是以以太币平台的固有行为,但发送甚至拥有令牌则不是,以太坊账户的以太币是在协议级别处理的,而以太坊账户的令牌是在合约级别处理

ERC20令牌标准

ERC20标准为实现令牌代币的合约定义了一个通用接口,以便可以以相同的方式访问和使用任何兼容的代币,该接口由许多必须存在于标准的每个实现中的函数以及开发人员可以添加的一些可选函数和属性组成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
总供应量:
返回当前存在的该令牌的总单位数,ERC20代币可以由固定或可变的供应

余额:
给定一个地址,返回该地址的代币余额

转移:
给定地址和金额,从执行转移的地址的余额中将该数量的代币转移

从转移:
给定发送者、接收者和金额,将代币从一个账户转移到另一个账户

批准:
给定收件人地址和金额,授权该地址从发出批准的账户执行多次转账,金额不超过该金额

津贴:

预言机 - Oracles

预言机,它是可以为以太坊智能合约提供外部数据源的系统,在区块链的背景下,语言机是一个可以挥发以太坊外部问题的系统.理想情况下,语言机是去信任的系统,意味着它们不需要被信任,因为它们按照去中心化原则运行

为什么需要预言机

以太坊平台的一个关键组件是以太坊虚拟机,它能够在去中心化网络中的任何节点上执行程序并更新以太坊状态(受共识规则约束). 为了保持共识,EVM的执行必须是完全确定性的,并且仅基于以太坊状态和签名交易的共享上下文。者两个特别重要的后果: 第一个是EVM和智能合约无法使用内在的随机性来源,第二是外部数据只能作为交易的数据负载引入.

预言机用例

理想情况下,预言机提供一种无需信任(或至少无需信任)的方式来获取外部信息.因此,预言机可以被认为是一种弥合链下世界和智能合约之间差距的机制.

预言机设计模式

根据定义,所有预言机都提供一些关键功能

1
2
3
1. 从链下来源收集数据
2. 使用签名消息在链上传输数据
3. 通过将数据放入智能合约的存储中来使其可用

设置预言机的三种主要方式分为:

1
2
3
4
5
6
7
1. 请求响应
请求响应类别是最复杂的,这是数据空间太大而无法存储在智能合约中
2. 发布订阅
预言机有效地为预期更改(可能定期和频繁)的数据提供广播服务,要么由链上智能合约轮询,要么由链外守护进程监视用于更新

3. 立即读取
这些预言机只提供立即所需的数据

数据认证

数据身份验证的两种常见方法是真实性证明可信执行环境(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
2
3
4
5
6
7
IPFS:
星际文件系统IPFS是一种去中心化的内容可寻址存储系统.内容可寻址意味着每段内容(文件)都经过哈希处理,并且该哈希值用于识别该文件.然后您可以通过哈希请求从任何IPFS节点检索任何文件.

IPFS旨在取代HTTP作为Web应用程序交付的首选协议,文件不是存储在单个服务器上,而是存储在IPFS上,并且可以从任何IPFS节点检索.

Swarm:
Swarm是另一种内容可寻址的P2P存储系统,类似于IPFS
  • 去中心化消息通信协议
    1
    任何应用程序的主要组成部分进程间通信,DApp最著名的P2P消息传递协议是Whisper. 它是以太坊基金会Go-Ethereum工具套件的一部分.

第十三章 以太坊虚拟机

以太坊协议和操作的核心是以太坊虚拟机, 简称EVM

什么是EVM?

EVM是以太坊的一部分,负责处理智能合约的部署和执行. EVM具有基于堆栈的架构,将所有内存值存储在堆栈上,他的字大小为256位(主要为了方便哈希和椭圆曲线操作),并且具有多个可寻址数据组件.

Ethereum EVM Architecture

EVM没有调度功能,所以以太坊世界计算机是单线程的

EVM指令集(字节码操作)

EVM指令集提供您可以期望的大部分操作,除了典型的字节码操作之外,EVM还可以访问账户信息和区块信息

  • 算术运算
    1
    2
    3
    4
    ADD // 弹出栈顶两项并相加
    MUL // 弹出栈顶的两项相乘
    SUB // 减去栈顶两项
    DIV // 整数除法

以太坊状态

EVM的工作是通过计算智能合约代码执行的有效状态转换来更新以太坊状态,当交易导致智能合约代码执行时,EVM会被实例化,其中包含与当前正在创建的区块和正在处理的特定交易相关的所有所需信息.

将Solidity编译为EVM字节码

要获取部署字节码:

1
2
3
4
5
solc --bin Faucet.sol
======= code/Solidity/Faucet.sol:Faucet =======
Binary:
608060405234801561000f575f80fd5b5061014c8061001d5f395ff3fe608060405260043610610021575f3560e01c80632e1a7d4d1461002c57610028565b3661002857005b5f80fd5b348015610037575f80fd5b50610052600480360381019061004d91906100eb565b610054565b005b67016345785d8a0000811115610068575f80fd5b5f3390508073ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f193505050501580156100af573d5f803e3d5ffd5b505050565b5f80fd5b5f819050919050565b6100ca816100b8565b81146100d4575f80fd5b50565b5f813590506100e5816100c1565b92915050565b5f60208284031215610100576100ff6100b4565b5b5f61010d848285016100d7565b9150509291505056fea26469706673582212208b36bb30653db54845c50b0b2e6c4422f5dc02e934e5809e45e3eb72b8728e4564736f6c63430008170033

要获得运行时字节码

1
2
3
4
solc --bin-runtime Faucet.sol
======= code/Solidity/Faucet.sol:Faucet =======
Binary of the runtime part:
608060405260043610610021575f3560e01c80632e1a7d4d1461002c57610028565b3661002857005b5f80fd5b348015610037575f80fd5b50610052600480360381019061004d91906100eb565b610054565b005b67016345785d8a0000811115610068575f80fd5b5f3390508073ffffffffffffffffffffffffffffffffffffffff166108fc8390811502906040515f60405180830381858888f193505050501580156100af573d5f803e3d5ffd5b505050565b5f80fd5b5f819050919050565b6100ca816100b8565b81146100d4575f80fd5b50565b5f813590506100e5816100c1565b92915050565b5f60208284031215610100576100ff6100b4565b5b5f61010d848285016100d7565b9150509291505056fea26469706673582212208b36bb30653db54845c50b0b2e6c4422f5dc02e934e5809e45e3eb72b8728e4564736f6c63430008170033

运行时字节码是部署字节码的子集

反汇编字节码

共识


mastering-ethereum
https://blog.chyidl.com/2024/01/12/mastering-ethereum/
作者
Yaqing Chyi
发布于
2024年1月12日
许可协议