以太坊是 “下一代智能合约和去中心化应用平台” (参考这里)
以太坊是一个内置图灵完备编程语言的区块链, 允许任何人编写智能合约和去中心化应用程序,他们可以在其中为所有权、交易格式和状态转换功能创建自己的任意规则. (参考这里)
以太坊是一个开源的、全球去中心化的计算基础设施,它执行称为智能合约的程序. 它使用区块链来同步和存储系统的状态变化,以及一种称为以太币的加密货币来计量和限制执行资源成本. 它通常被描述为“世界计算机”。(参考这里)
以太坊平台使开发人员能够构建具有内置经济功能的强大去中心化应用程序。在提供高可用性、可审计性、透明性和中立性的同时,它还减少或消除了审查制度并降低了某些交易对手风险。(参考这里)
以太坊的主要目的不是成为数字货币支付网络。虽然数字货币以太币对于以太坊的运作来说既是不可或缺的,也是必不可少的, 以太币旨在作为一种实用货币来支付使用以太坊平台作为世界计算机的费用。(参考这里)
与脚本语言非常有限的比特币不同,以太坊被设计成一个通用的可编程区块链,它运行一个能够执行任意和无限复杂代码的虚拟机。比特币的脚本语言有意限制为对花费条件进行简单的真假评估, 而以太坊的语言是图灵完备的,这意味着以太坊可以直接充当通用计算机。(参考这里)
原始区块链,即比特币的区块链,跟踪比特币单位的状态及其所有权。你可以将比特币视为分布式共识状态机,其中交易会导致全局状态转换,从而改变货币的所有权。状态转换受到共识规则的约束,允许所有参与者(最终)在挖掘多个区块后收敛于系统的共同(共识)状态。以太坊也是一个分布式状态机。但不是只跟踪货币所有权的状态,以太坊跟踪通用数据存储的状态转换,即可以保存任何可表示为键值元组的数据的存储 (参考这里)
以太坊的核心组件 (参考这里):
P2P 网络:以太坊运行在以太坊主网上,可在 TCP 端口 30303 上寻址, 并且运行着一个称作“DΞVp2p”(译者注:其实就是DEVp2p)的连接协议.
交易:以太坊交易是网络消息,包括(除其他外)发送者、接收者、价值和数据负载。
状态机:以太坊状态转换由以太坊虚拟机 (EVM) 处理,EVM 是一种基于堆栈的虚拟机,可执行字节码(机器语言指令)。EVM 程序,称为“智能合约”,是用高级语言(例如 Solidity 或 Vyper)编写的,并编译为字节码以在 EVM 上执行。
数据结构:以太坊的状态作为数据库(通常是谷歌的 LevelDB)本地存储在每个节点上,其中包含称为 Merkle Patricia Tree 的序列化哈希数据结构中的交易和系统状态。
以太坊的核心组件(持续更新中):
共识算法:以太坊之前使用比特币的共识模型 Nakamoto Consensus,通过工作量证明 (PoW) 对重要性进行加权以确定最长的链,现在以太坊已经切换到权益证明 (PoS) 算法。
经济安全性:以太坊目前使用称为 Ethash 的 PoW 算法,但在以太坊 2.0 中正在过渡到 PoS 算法。
客户端:以太坊有多个可互操作的客户端软件实现,其中最突出的是 Go-Ethereum (Geth) 和 OpenEthereum。其他的是 Erigon、Nethermind 和 Turbo-geth。OpenEthereum 正在被弃用以过渡到 Erigon,即以前的 Turbo-geth。(参考这里)
以太坊能够在称为以太坊虚拟机的状态机中执行存储的程序,同时在内存中读取和写入数据,使其成为图灵完备的系统。图灵完备系统面临停机问题的挑战,即给定一个任意程序及其输入,无法确定程序是否最终会停止运行。所以以太坊无法预测智能合约是否会终止,或者它会运行多长时间。因此,为了限制智能合约使用的资源,以太坊引入了一种称为燃料(gas)的计量机制。(参考这里)
当 EVM 执行智能合约时,它会仔细考虑每条指令(计算、数据访问等)。每条指令都有一个预先确定的成本,以 gas 为单位。当交易触发智能合约的执行时,它必须包含一定数量的燃料,以设置运行智能合约可以消耗的上限。如果计算消耗的gas量超过交易中可用的gas量,则 EVM 将终止执行。Gas 是以太坊用来允许图灵完备计算同时限制任何程序可以消耗的资源的机制。(参考这里)
以太需要与交易一起发送,并且需要明确指定用于购买燃料,以及可接受的燃料价格。就像加油站一样,汽油的价格不是固定的。购买燃料是为了交易,执行计算,并将任何未使用的燃料退还给交易的发送者。(参考这里)
去中心化应用程序,缩写为 DApp,是一种构建在开放、去中心化、点对点基础设施服务之上的网络应用程序,通常将智能合约与web界面相结合。
DApps 代表了从应用程序集中拥有和管理的“Web 2.0”到“Web 3.0”的过渡,在“Web 3.0”中,应用程序构建在用于计算(即区块链)、存储和消息传递的去中心化对等协议上。
以太坊区块链代表 Web 3.0 的去中心化计算部分。Swarm 代表去中心化存储,而 Whisper(现在的 Waku)代表去中心化消息传递协议。
去中心化可以被认为是三种类型 (参考这里):
架构去中心化
去中心化
逻辑去中心化
以太坊的货币单位称为以太币或“ETH”。以太被细分为更小的单位,最小的单位被命名为wei。10的3次方 wei 是 1 Babbage, 10的6次方 wei 是 1 Lovelace, 10的9次方 wei 是 1 Shannon 和 10的18次方 wei 是 1 Ether.
以太坊使用公钥加密来创建公私密钥对(被认为是“一对”,因为公钥是从私钥派生的) 不用于加密但用于数字签名.
以太坊使用椭圆曲线数字签名算法 (ECDSA) 进行基于椭圆曲线密码学 (ECC) 的数字签名(SECP-256k1 曲线), 一种基于有限域上椭圆曲线代数结构的公钥密码学方法。(参考这里)
以太坊私钥是一个 256 位的随机数,它唯一地确定一个单一的以太坊地址,也称为账户。
以太坊公钥是使用椭圆曲线乘法从私钥计算出的椭圆曲线上的一个点。不能从公钥计算出私钥。
以太坊状态由称为“账户”的对象组成,每个账户都有一个 20 字节的地址,状态转换是账户之间价值和信息的直接转移。(参考这里)
以太坊账户包含四个字段:
nonce,用于确保每笔交易只能处理一次的计数器
账户当前的以太币余额
账户的合约代码(如果存在)
账户的存储空间(默认为空)
以太坊有两种不同类型的账户:
由私钥控制的外部拥有账户 (EOA)
合约代码控制的合约账户
EOA 对以太币的所有权是通过私钥、以太坊地址和数字签名建立的。任何拥有私钥的人都可以控制相应的 EOA 账户及其持有的任何以太币。
EOA 没有代码,可以通过创建和签署交易从 EOA 发送消息。
一个合约账户有代码和相关的存储,每次它收到一条消息,它的代码就会激活,允许它读取和写入内部存储并依次发送其他消息或创建合约。
智能合约可以被认为是存在于以太坊执行环境中的“自治代理”, 当被消息或者交易触发时总是会执行特定代码片段,并直接控制他们自己的以太币余额和他们自己的键值存储以跟踪持久变量.
以太坊使用 Keccak-256 作为其加密哈希函数。Keccak-256 是 NIST 举办的 SHA-3 竞赛的获胜候选者,但与最终采用的 SHA-3 标准不同。(参考这里)
EOA 账户的以太坊地址是 EOA 密钥对公钥的 Keccak-256 散列的最后 20 个字节(最低有效字节)。
交易是由外部拥有的帐户 (EOA) 发起的签名消息, 由以太坊网络传输,并记录在以太坊区块链上。只有交易才能触发状态的改变。以太坊是一个基于交易的状态机。(参考这里)
一个交易有如下属性:
原子的(Atomic): 它是全有或全无,即不能被其他交易分割或中断
顺序的(Serial): 交易按顺序依次处理,不与其他交易重叠
包含与否(Inclusion): 不能保证交易被包含(打包),并且取决于网络拥塞和 gasPrice 等因素。矿工决定打包与否。
排序: 交易顺序无法保证,取决于网络拥塞和 gasPrice 等因素。矿工决定顺序。
交易是包含以下组件的序列化二进制消息 (参考这里):
nonce: 由原始 EOA 发布的序列号,用于防止消息重播
gasPrice: 发起人愿意为每单位燃料支付的以太币数量(以 wei 为单位)
gasLimit: 发起人愿意为此交易支付的最大gas量
recipient: 目标以太坊地址
value: 发送到目的地的以太币数量(以 wei 为单位)
data: 可变长度二进制数据有效载荷
v,r,s: 原始 EOA 的 ECDSA 数字签名的三个组成部分
Nonce: 标量值等于从 EOA 账户发送的交易数量,或者在合约账户的情况下,它是帐户创建合约的数量。(参考这里)
Gas price: 交易发起者愿意为换取 gas 支付的价格。价格以单位燃料 wei 为单位。gas 价格越高,交易在区块链上得到确认的速度就越快。建议的 gas 价格取决于交易时对区块空间的需求。
Gas limit: 交易发起者为完成交易愿意支付的最大gas单位数
Recipient: 交易接收者的 20 字节以太坊地址,可以是 EOA 或合约账户。
以太坊协议不验证交易中的接收人地址。可以将交易发送到没有对应私钥或合约的地址。验证应该在用户界面级别完成。
请注意,交易中没有发送者地址,因为 EOA 的公钥可以从 ECDSA 签名的 v,r,s 组件派生,交易发起人的地址可以从这个公钥中导出。
Value: 发送给交易接收者的以太币价值。如果收件人是 EOA,则该帐户的余额将增加此值。如果收件人是合约地址,则结果取决于作为此交易的一部分发送的任何数据。如果没有数据,则调用接收者合约的接收(receive)或回退(fallback)函数(如果它们存在)。根据这些功能的实现,以太值会添加到合约账户的余额中,或者发生异常则该以太币保留在发起人的帐户中。
Data: 发送到合约账户的信息,(通常)表示要调用的合约函数和该函数的参数。
v,r,s: r 和 s 是交易发起方使用私钥生成的 ECDSA 签名的两部分。v 是恢复标识符,计算为 27 或 28 之一, 或者作为链 ID(以太坊主网 chainID 为 1)加倍加 35 或 36。(参考这里)
数字签名在以太坊中有三个用途: 1) 证明私钥的所有者,即以太坊帐户的所有者,已授权以太币的支出或合约的执行 2) 保证不可否认性: 授权证明是不可否认的 3) 证明交易数据在交易签署后没有被也不能被任何人修改。
合约创建交易被发送到一个特殊的目标地址,称为零地址,即 0x0。合约创建交易包含一个数据有效负载,其中包含用于创建合约的已编译字节码。value字段中的可选以太币金额将创建具有初始余额的新合约。
交易 与 消息:
交易由EOA生成,其中外部参与者发送签名的数据包,该数据包可以是: 1) 给另一个EOA 发送价值, 或者是 2) 调用一个合约账户,在此账户执行合约代码。
消息要么是 : 1) 由交易触发指向另一个EOA或合约账户 要么 2) 在EVM内部合约触发,当执行CALL系列字节码并触发或价值转移时触发。
交易被分组到块中。区块链包含一系列这样的块,这些块被链接在一起。
区块: 包含一批交易,并包含链的前一个区块哈希值。这将块链接在一起(在一条链中),因为哈希是从块数据中加密导出的。这可以防止欺诈,因为历史上任何区块的一次更改都会使所有后续区块无效,因为所有后续哈希值都会发生变化,并且运行区块链的每个人都会注意到。为了保留交易历史,块是严格排序的(每个创建的新块都包含对其父块的引用), 区块内的交易也是严格有序的。(参考这里)
以太坊节点/客户端: 节点是实现以太坊规范并通过点对点网络与其他以太坊节点通信的软件应用程序。客户端是以太坊节点的具体实现。以太坊升级到 POS 后, 节点需要两个客户端:执行层客户端和共识称客户端。最常见的执行层客户端实现是 Geth 和 Nethermind。最常见的共识层客户端实现是 Prysm 和 Lighthouse。以太坊交易被发送到以太坊节点以在点对点网络中广播。(参考这里)
矿工、验证者: 是运行以太坊节点的实体,它们验证和执行这些交易并将它们组合成块。验证者提案区块或见证区块,若提案区块被接受将获得区块奖励。矿工还获得费用,这是区块中包含的所有交易在gas上花费的以太币。
区块gas limit 是指区块内所有交易消耗的gas总量上限。因此,就交易数量而言,区块的大小并不是固定的,因为不同的交易会消耗不同数量的gas。参考这里 。
区块需要时间通过网络传播。
共识: 以太坊上下文中的去中心化共识是指确定哪个验证者可以提案区块。
状态是地址和帐户状态之间的映射,以修改后的 Merkle Patricia 树或特里树的形式实现。Merkle 树或 trie 是一种二叉树,由一组具有以下特征的节点组成:
树底部的叶节点包含基础数据
中间节点,其中每个节点都是其两个子节点的哈希值
单个根节点由其代表树顶部的两个子节点的哈希值形成
以太坊的工作量证明算法称为“Ethash” , 现在已经不再使用。
区块包含区块头、交易和 ommers 的区块头。区块头包含 (参考这里), 部分字段在 POS 升级后,修改了使用用途。
parentHash: 整个父区块头的 Keccak 256 位哈希
ommersHash: 此块的 ommers 列表部分的 Keccak 256 位哈希
beneficiary: 160 位地址,该区块成功挖矿所收取的所有费用将转移到该地址
stateRoot: 状态树根节点的 Keccak 256 位散列,在执行所有交易并应用终结后
transactionsRoot: 块的交易列表部分中的每个交易填充的 trie 结构的根节点的 Keccak 256 位哈希
receiptsRoot: trie 结构根节点的 Keccak 256 位散列,其中填充了区块交易列表部分中每笔交易的收据
logsBloom: Bloom filter 由交易列表中每笔交易的每个日志条目中包含的可索引信息(记录器地址和日志主题)组成
difficulty: 与该块的难度级别相对应的标量值。这可以根据前一个块的难度级别和时间戳计算得出
number: 一个标量值等于祖先块的数量。创世块的编号为零
gasLimit: 一个标量值等于当前每个区块的gas消耗限制
gasUsed: 一个标量值,等于该区块中交易中使用的总gas量
timestamp: 标量值等于 Unix 的 time() 在此块开始时的合理输出
extraData: 包含与此块相关的数据的任意字节数组。这必须是 32 字节或更少
mixHash: 一个 256 位哈希值,与随机数结合,证明已对该块进行了足够量的计算
nonce: 一个 64 位值,与mixHash结合,证明已对该块执行了足够的计算量
stateRoot, transactionsRoot and receiptsRoot 是修改后的 Merkle-Patricia 树的根节点的 256 位哈希值。stateRoot 的叶子是所有以太坊地址-账户对的键值对, 其中每个相应的帐户包括:
nonce: 标量值等于从该地址发送的交易数量,或者对于具有关联代码的账户,该账户创建的合约数量
balance: 一个标量值,等于该地址拥有的 Wei 数量
storageRoot: 修改后的 Merkle-Patricia 树根节点的 256 位hash,对帐户的存储内容进行编码(256 位整数值之间的映射),作为从 256 位整数键的 Keccak 256 位散列到 RLP 编码的 256 位整数值的映射,编码到 trie 中。
codeHash: 该账户EVM代码的hash—如果此地址收到消息调用,将会执行的代码;它是不可变的,因此与所有其他字段不同,它在构建后无法更改。
交易收据是四项的元组,包括:
交易发生后立即在包含交易收据的区块中使用的累计gas
通过执行交易创建的一组日志
由这些日志中的信息组成的布隆过滤器
交易的状态码
gas退回和受益人: 交易中任何未使用的 gas(gas Limit 减去交易使用的 gas)将以相同的 gas Price 退还给发送者的账户。交易消耗的gas的以太币记入受益人(在区块标头中指定),该地址通常由验证者指定,这是支付给矿工的交易“小费”。
EVM 是一个准图灵完备机,其中”准“是因为计算本质上受参数、gas 限制的事实,限制了完成的计算总量。EVM 是智能合约的运行时环境。
以太坊合约中的代码是用一种低级的、基于堆栈的字节码语言编写的,称为“以太坊虚拟机代码”或“EVM 代码”。该代码由一系列字节(因此称为字节码)组成,其中每个字节代表一个操作。
EVM 是一个简单的基于堆栈的架构,由堆栈、易失性内存、字长为 256 位的非易失性存储(被选择以促进 Keccak256 哈希方案和椭圆曲线计算)和 Calldata 组成。
堆栈由 1024 个 256 位元素组成。EVM 指令可以操作栈顶的 16 个元素。大多数 EVM 指令使用堆栈(基于堆栈的体系结构)进行操作,并且还有特定于堆栈的操作,例如PUSH、POP、SWAP、DUP 等。
内存是一个线性字节数组,可在字节级别寻址,并且是易失性的。所有位置最初都明确定义为零。这是通过 MLOAD、MSTORE 和 MSTORE8 指令访问的。
存储是一个 256 位到 256 位的键值存储。与易失性内存不同,存储是非易失性的,并且作为系统状态的一部分进行维护。所有位置最初都明确定义为零。这是通过 SLOAD/SSTORE 指令访问的。
Calldata 是一个只读的字节可寻址空间,其中保存了交易或调用的数据参数。这是通过 CALLDATASIZE/CALLDATALOAD/CALLDATACOPY 指令访问的。
EVM 不遵循标准的冯诺依曼架构。它不是将程序代码存储在通常可访问的内存或存储器中,而是单独存储在只能通过专用指令访问的虚拟 ROM 中。
EVM 使用大端排序,其中一个字的最高有效字节存储在最小的内存地址中,最低有效字节存储在最大的内存地址中
EVM指令集可分为11类:
停止和算术运算
比较和按位逻辑运算
SHA3
环境信息
区块信息
堆栈、内存、存储和流操作
push操作
复制操作
交互操作
日志操作
系统操作
停止和算术运算(依次为:操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x00 STOP 0 0 停止执行
0x01 ADD 2 1 加法运算
0x02 MUL 2 1 乘法运算
0x03 SUB 2 1 减法运算
0x04 DIV 2 1 整数除法运算
0x05 SDIV 2 1 有符号整数除法运算(截断)
0x06 MOD 2 1 取余运算
0x07 SMOD 2 1 有符号模余运算
0x08 ADDMOD 3 1 模加法运算
0x09 MULMOD 3 1 模乘运算
0x0a EXP 2 1 指数运算
0x0b SIGNEXTEND 2 1 扩展二进制补码有符号整数的长度
比较和按位逻辑运算(依次为:操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x10 LT 2 1 小于比较
0x11 GT 2 1 大于比较
0x12 SLT 2 1 有符号小于比较
0x13 SGT 2 1 有符号大于比较
0x14 EQ 2 1 相等比较
0x15 ISZERO 1 1 简单非操作符
0x16 AND 2 1 按位与操作符
0x17 OR 2 1 按位或操作符
0x18 XOR 2 1 按位异或操作符
0x19 NOT 1 1 按位非操作符
0x1a BYTE 2 1 从一个字中获取一个字节
0x1b SHL 2 1 左移操作符
0x1c SHR 2 1 逻辑右移操作符
0x1d SAR 2 1 算数(有符号的)右移操作符
SHA3 (依次为:操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x20 SHA3 2 1 计算 Keccak-256 hash
环境信息 (依次为:操作码、助记符、栈元素被移除、栈元素被放置、描述):
0x30 ADDRESS 0 1 获取当前执行账户地址
0x31 BALANCE 1 1 获取给定账户余额
0x32 ORIGIN 0 1 获取执行源地址
0x33 CALLER 0 1 获取调用者地址
0x34 CALLVALUE 0 1 通过负责本次执行的指令/交易获得存入的价值
0x35 CALLDATALOAD 1 1 获取当前环境的输入数据
0x36 CALLDATASIZE 0 1 获取当前环境下输入数据的大小
0x37 CALLDATACOPY 3 0 将当前环境中的输入数据复制到内存中
0x38 CODESIZE 0 1 获取在当前环境中运行的代码大小
0x39 CODECOPY 3 0 拷贝当前环境运行的代码到内存
0x3a GASPRICE 0 1 获取当前环境中的gas价格
0x3b EXTCODESIZE 1 1 获取帐户代码的大小
0x3c EXTCODECOPY 4 0 将帐户代码复制到内存
0x3d RETURNDATASIZE 0 1 从当前环境中获取上一次调用的输出数据大小
0x3e RETURNDATACOPY 3 0 将上一次调用的输出数据复制到内存
0x3f EXTCODEHASH 1 1 获取帐户代码的哈希值
区块信息 (依次为:操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x40 BLOCKHASH 1 1 获取 256 个最近完整块之一的哈希值
0x41 COINBASE 0 1 获取区块的受益人地址
0x42 TIMESTAMP 0 1 获取区块的时间戳
0x43 NUMBER 0 1 获取块的编号
0x44 DIFFICULTY 0 1 获取区块的难度
0x45 GASLIMIT 0 1 获取区块的 gas limit
堆栈、内存、存储和流操作 (依次为:操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x50 POP 1 0 从堆栈中移除元素
0x51 MLOAD 1 1 从内存中加载一个字
0x52 MSTORE 2 0 保存字到内存中
0x53 MSTORE8 2 0 将字节保存到内存
0x54 SLOAD 1 1 从存储中加载字
0x55 SSTORE 2 0 保存字到存储器
0x56 JUMP 1 0 改变程序计数器
0x57 JUMPI 2 0有条件地改变程序计数器
0x58 PC 0 1 获取与该指令对应的递增之前的程序计数器的值
0x59 MSIZE 0 1 获取活动内存的大小(以字节为单位)
0x5a GAS 0 1 获取可用gas的数量,包括本条指令花费对应的减少
0x5b JUMPDEST 0 0 标记有效的跳转目的地。此操作在执行期间对机器状态没有影响。
Push 操作 (操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x60 PUSH1 0 1 将 1 字节元素目放入堆栈
0x61 PUSH2 0 1 将 2 字节的元素放入堆栈
PUSH3, PUSH4, PUSH5…PUSH31 相应地将 3, 4, 5..31 字节元素目放入堆栈
0x7f PUSH32 0 1 Place 32-byte (full word) item on stack
Duplication Operations (操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x80 DUP1 1 2 复制第一个堆栈元素
DUP2, DUP3..DUP15 复制 2nd, 3rd..15th 相应堆栈元素
0x8f DUP16 16 17 Duplicate 16th stack item
交互操作 (操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0x90 SWAP1 2 2 交换第一和第二个栈元素
0x91 SWAP2 3 3 交换第一和第三个栈元素
SWAP3, SWAP4..SWAP15 交互 1st and 4th..15th 个相应栈元素
0x9f SWAP16 17 17 Exchange 1st and 17th stack items
日志操作 (操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0xa0 LOG0 2 0 附加没有主题的日志记录
0xa1 LOG1 3 0 附加一个主题的日志记录
0xa2 LOG2 4 0 附加两个主题的日志记录
0xa3 LOG3 5 0 附加三个主题的日志记录
0xa4 LOG4 6 0 附加四个主题的日志记录
系统操作 (操作码、助记符、栈元素被移除个数、栈元素被放置个数、描述):
0xf0 CREATE 3 1 使用关联代码创建一个新帐户
0xf1 CALL 7 1 对账户进行消息调用
0xf2 CALLCODE 7 1 使用另一个可选账户的代码对账户进行消息调用
0xf3 RETURN 2 0 停止执行返回输出数据
0xf4 DELEGATECALL 6 1 使用另一个可选账户的代码对账户进行消息调用, 但是会为发送者和值保持当前值
0xf5 CREATE2 4 1 使用关联代码创建一个新帐户
0xfa STATICCALL 6 1 静态地对账户进行消息调用
0xfd REVERT 2 0 停止执行,回退状态变化,但返回数据和保持gas不变
0xfe INVALID ? ? 指定无效指令
0xff SELFDESTRUCT 1 0 停止执行并注册帐户以供以后删除
不同指令的 Gas 成本根据它们在客户端上的计算存储负载而不同。例子是:
STOP, INVALID and REVERT 是 0 gas
大多数算术、逻辑和堆栈操作都是 3-5 gas
CALL*, BALANCE and EXT* 是 2600 gas
MLOAD/MSTORE/MSTORE8 是 3 gas
SLOAD 是 2100 gas ,从0到非0设置存储槽,SSTORE 指令花费20,000 gas,反过来则需要5,000 gas;
CREATE 是 32000 gas ,SELFDESTRUCT 是 5000 gas
交易会在不同的异常情况下回退,例如 gas 耗尽、指令无效等。在这种情况下,到目前为止所做的所有状态更改都将被丢弃,帐户的原始状态将回退为该交易执行之前的状态。
To 地址是合约地址的交易在交易的data字段中包含合约的函数和所需的参数。他们是根据应用程序二进制接口 (ABI) 编码的。
合约应用程序二进制接口 (ABI): 是与以太坊生态系统中的合约进行交互的标准方式,无论是从区块链外部还是用于合约到合约的交互。
合约的接口函数是强类型的,在编译时已知并且是静态的。
合约将在编译时拥有它们调用的任何合约的接口定义。
函数选择器:函数调用的 Calldata 的前四个字节指定要调用的函数。
它是函数签名的 Keccak-256 哈希的前(左侧,大端高阶)四个字节。
签名被定义为没有数据位置说明符的基本原型的规范表达式,即带有参数类型括号列表的函数名称。参数类型由单个逗号分隔,没有空格。
函数参数:编码的参数从第五个字节开始,紧跟函数选择器。
区块浏览器:是允许任何人查看区块、交易、账户、合约交互等实时数据的门户。一个流行的以太坊区块浏览器是 etherscan.io.
Mainnet:“Main Network”的缩写,这是主要的公共以太坊区块链。还有其他以太坊“测试网”,协议或智能合约开发人员可以在其中测试他们的协议升级或合约。主网使用真实的ETH,而测试网使用可以从水龙头获得的测试ETH。这里有流行的测试网。
以太坊改进提案 (EIP) 描述了以太坊平台的标准,包括核心协议规范、客户端 API 和合约标准。Standards Track EIP 分为多种类型:(参考这里)
核心:需要共识分叉的改进以及不一定是共识关键但可能与“核心开发”讨论相关的更改
网络:包括围绕 devp2p 和 Light Ethereum Subprotocol 的改进,以及对 whisper 和 swarm 网络协议规范的改进建议
接口:包括围绕客户端 API/RPC 规范和标准的改进,以及某些语言级别的标准,如方法名称和合同 ABI。“interface”标签与 interfaces repo 一致,在将 EIP 提交到 EIPs 存储库之前,讨论应该主要发生在该存储库中
ERC: 应用层标准和约定,包括代币标准 (ERC-20)、名称注册、URI 方案、库包格式和钱包格式等合约标准
Meta: 描述围绕以太坊的流程或提议对流程(或事件)进行更改
信息性:描述以太坊设计问题,或向以太坊社区提供一般指南或信息,但不提出新功能
TheMerge:是指以太坊合并升级,将使以太坊更具可扩展性、更安全和更可持续 (参考这里)
不可变代码:一旦部署了合约的代码,它就变得不可变(下面提到的例外情况)。依赖于能够修复错误并向已部署代码添加新功能的标准软件开发实践不适用于此处。这对智能合约开发来说是一个重大的安全挑战。有以下三种例外情况:
修改后的合约可以部署在新地址(并复制旧状态),但应通知所有交互实体能够在新地址与更新后的合约进行交互。这通常被认为是不切实际的。
修改后的合约可以部署为代理模式中的新实现,其中代理在更新后指向修改后的合约。这是更新添加功能最常用的方法。
CREATE2 操作码允许使用 init_code 在原地址更新
Web3: 是一个无需许可、最小化信任和抗审查的网络,用于传输价值和信息。
实现 Web3 的流行方法是在计算、通信、存储都是去中心化的网络基础上构建它。
在以太坊生态系统中,这分别是以太坊区块链、Waku(之前的 Whisper)和 Swarm 的组合。
隐私和匿名是 Web3 的重要激励因素。
Web2 的大部分基础安全设计原则和开发实践仍然适用于 Web3。但 Web3 安全性确实是许多领域的范式转变。
语言:Web2 编程语言,如 JavaScript、Go、Rust 和 Nim,在 Web3 中被广泛使用。但是智能合约的整个领域是全新的,并且特定于 Web3。Solidity 等语言是专门为 Web3 创建的。
链上 vs 链下:智能合约是“链上”Web3 组件,它们与 Web2 软件非常相似的“链下”组件交互。因此,Web3 和 Web2 在安全方面的主要差异主要归结为智能合约安全性与 Web2 软件的安全考虑。
开源和透明:鉴于对信任最小化的强调,Web3 软件,尤其是智能合约,期待默认情况下是开源的。
部署的字节码也应该经过源代码验证(在 Etherscan 等服务上)。隐匿专有代码不是 Web3 精神的一部分。
与智能合约的所有交互都作为交易记录在区块链上。这包括交易的发送者、数据和结果。对交易和状态转换的整个历史具有完整的可见性,类似于从一开始就拥有一个可公开访问的系统审计日志。
此外,仍在“进行中”且尚未在区块链上得到确认的交易在待处理交易队列(即内存池)中也是公开可见的,并可能引发抢跑交易攻击。
不可停和不可变:Web3 应用程序,通常被称为去中心化应用程序(DApps),预计将是不可暂停和不可变的,因为它们运行在去中心化的区块链网络上。
不应该有任何一个实体可以单方面决定停止正在运行的 DApp 或对其进行更改。除非网络大多数另有决定,否则区块链上的交易和数据保证是不可变的。
通常,(用户)期望智能合约没有部署者可控制的终止开关。它们也不能被任意升级。这两者都源于 Web3 的信任最小化目标,即不需要信任潜在的恶意 DApp 开发人员。然而,这使得修复已部署代码中的安全漏洞和响应漏洞利用变得非常具有挑战性。
假名团队和 DAO:也许受比特币中本聪的启发,Web3 中的一些项目团队有一种趋势是使用假名,并且只知道他们的在线昵称。
考虑到该领域的监管不确定性,这样做的一个原因可能是为了避免将来产生任何潜在的法律影响。这也使得与任何社会声誉相关联变得更加困难,因为它与产品或其开发背后的流程的感知安全可信度有关。这也使得追究任何人的法律社会责任或责任变得棘手。
“相信软件而不是湿件”(即人)是这里的口头禅。虽然这可能是一个极端的观点,但围绕影响安全态势的项目的推出和治理仍然存在社会过程。
为了尽量减少少数特权人士在项目生命周期中的作用和影响, 由持有代币的社区成员进行治理的趋势越来越明显 — 假名代币持有区块链地址的去中心化自治组织 (DAO) 对项目资金支出和协议变更做出基于投票的决策。虽然这减少了湿件(人为)故障的集中点,但它可能会减慢对安全关键方面的决策,甚至可能导致项目分叉。
新架构、语言和工具链: 以太坊有一个新的虚拟机 (EVM) 架构,它是一个基于堆栈的机器,具有 256 位字和相关的gas语义。
Solidity 语言在没有太多真正竞争的情况下继续主导智能合约。
相关的工具链,包括开发环境(例如 Truffle、Brownie、Hardhat、Foundry)、库(例如 OpenZeppelin)、安全工具(例如 Slither、MythX、Securify)和 钱包(例如 Metamask)正在成熟,但仍在很大的成长空间。
拜占庭威胁模型: Web3 威胁模型基于处理任意恶意行为的拜占庭故障,并受制于机制设计。
鉴于缺乏值得信赖的中介机构, 默认情况下,每个人和所有事物都是不受信任的。该模型的参与者包括开发人员、矿工验证者、基础设施提供商和用户,他们都可能成为潜在的对手。
这是一个与 Web2 的威胁模型根本不同的威胁模型,在 Web2 中存在受信任的内部人员的一般概念,这些内部人员具有对资源资产的授权访问权限,这些资源资产必须受到保护以免受不受信任的外部人员(和恶意内部人员)的侵害。Web3 是最终的零信任场景。
密钥和Token: 虽然“crypto”对于一些非技术观察者来说对应着加密货币,但它实际上指的是密码学,这是 Web3 的基本基石。尽管我们在 Web2 世界中不知不觉地使用了密码学,但 Web3 正在将其推向大众。加密密钥是 Web3 世界的一级成员。
不像 Web2 有可信中介的存在,他们可以通过其他方式重置密码或从其中心化数据库中恢复帐户资产,Web3 在意识形态上将管理密钥(及其控制的资产)的责任推给了终端钱包用户。私钥(或种子短语)的丢失是不可逆转的,许多资产已因此类事件而丢失。
针对金融资产的 Web2 安全漏洞(即不包括用于 DDoS 的勒索软件和僵尸网络)通常涉及窃取金融或个人数据,然后在暗网上出售这些数据并用于获取金钱利益。由于(在中心化中介机构)实施了各种检查和措施(包括技术和监管)以减少此类网络安全事件并防止异常资产转移,因此这变得越来越困难。当这种未经授权的资产转移确实发生时,所涉及的中介机构甚至可能会合作扭转此类交易并进行补偿。
Web3 中资产的概念非常不同。加密资产是无边界的数字代币,其会计分类账由区块链上的共识管理,所有权由对相应加密密钥的访问决定。如果有人可以访问您控制加密资产的私钥,他们可以将这些资产转移到由他们的密钥控制的区块链地址。在一个完全去中心化的世界中,不应该存在可以扭转这种损失的中介(例如中心化交易所) — 交易是不可变的,因此预防性安全措施在 Web3 空间中变得更加重要。
设计的可组合性: 无需许可的创新和抗审查是 Web3 的核心目标。
有许多关于 Web2 公司的故事,这些公司最初吸引开发人员在他们的平台上进行构建,但后来当他们被视为竞争威胁时将他们拒之门外。
Web3 应用程序,尤其是智能合约,在设计上是开放的,最终用户和其他智能合约都可以在未经许可的情况下访问。
这种可组合性适用于可以叠加在其他应用程序之上的应用程序,例如乐高积木,如果一切顺利并且新的乐高玩具可靠地构建在其他应用程序之上,那就太棒了。然而,这种不受约束的可组合性引入了意想不到的跨系统依赖性,可能会触发跨组件的无效假设(考虑到不同约束由不同团队构建)并暴露之前未考虑的攻击面或模式。
如果不深入了解所有交互组件、约束和配置,这使得描述 Web3 漏洞和运用场景变得非常具有挑战性。
压缩时间尺度: Web3 领域的创新以惊人的速度发展。透明开发和设计可组合性方面是加速无许可和无边界参与的强大催化剂,互联网原生加密经济代币进一步激励了这种参与——一场完美风暴。
这将创新时间尺度缩短了几个数量级,新的实验浪潮在数周或数月内发生,而不是在 Web2 的围墙花园内通常需要数年时间。似乎这里唯一的护城河是执行速度。
这种压缩的时间尺度对设计、开发和部署期间的安全考虑产生了切实的影响。若偷工减料,走捷径,让一个未经充分测试的系统上线,那它持有价值数百万美元的代币,可能非常容易受到攻击。
生产中测试:压缩时间尺度、不受限制的可组合性的组合,拜占庭威胁模型和复制完整状态的挑战,以预测使用快速发展的实验软件工具构建的交互组件的故障模式,以多种方式迫使现实测试仅在生产环境中进行,即在“主网上”。这意味着复杂的技术和加密经济漏洞可能只有在生产部署时才能被发现。
审计作为银弹(silver bullet): Web2 产品的安全软件开发生命周期 (SSDLC) 流程已经发展了几十年,预计它们将满足内部验证组合的一些最低要求,外部评估(例如产品流程审计、渗透测试)和认证取决于所管理资产的价值, 预期风险、威胁模型和产品的市场领域(例如,金融部门有更严格的合规要求)。
Web3 项目似乎越来越依赖外部审计作为安全授权的标志。这通常是因为缺乏足够的内部安全专业知识。虽然这种方法的似乎错误地说服了投机者,由于以下几个原因,依赖外部审计是站不住脚的:
目前的审计非常昂贵,因为对具有分析复杂项目的经验和声誉的顶级审计团队的需求远远大于供应
审计通常在项目开发结束时,即生产发布之前委托进行一次
出于商业或协调上的原因,项目升级未经审计
(来自项目团队和用户的)期望是审计是解决所有漏洞的灵丹妙药,并且项目在短期审计(通常为几周)后“没有错误”
参考:
https://ethereum.org/en/whitepaper/
https://ethereum.github.io/yellowpaper/paper.pdf
https://github.com/ethereumbook/ethereumbook
https://ethereum.org/en/developers/docs/
https://ethereum.org/en/glossary/
https://docs.soliditylang.org/
https://preethikasireddy.medium.com/how-does-ethereum-work-anyway-22d1df506369
https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf
登链社区
个人专栏
阅读更多
金色早8点
Odaily星球日报
金色财经
Block unicorn
DAOrayaki
曼昆区块链法律
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。