区块链以太坊学习一:基础概念

参考资料

《精通以太坊》( Mastering Ethereum ) https://github.com/ethereumbook/ethereumbook 

《以太坊白皮书》 ( A Next-Generation Smart Contract and Decentralized Application Platform ) https://github.com/ethereum/wiki/wiki/White-Paper 

《以太坊黄皮书》(《以太坊:一种安全去中心化的通用交易账本 拜占庭 版本》) 

以太坊官方文档 ( Ethereum Homestead Documentation ) http://www.ethdocs.org/en/latest/index.html 

Solidity官方文档 https://solidity.readthedocs.io/en/latest/

 

工具

• MetaMask - 浏览器插件钱包

• Remix - 基于浏览器的 Solidity 在线编辑器

• Geth -以太坊客户端(go语言)

• web3.js – 以太坊 javascipt API库

• Ganache – 以太坊客户端(测试环境私链)

• Truffle – 以太坊开发框架

 

以太坊特点

• 以太坊是“世界计算机”,这代表它是一个开源的、全球分布的计算 基础设施

• 执行称为智能合约(smart contract)的程序

• 使用区块链来同步和存储系统状态以及名为以太币(ether)的加密 货币,以计量和约束执行资源成本

• 本质是一个基于交易的状态机(transaction-based state machine)

• 以太坊平台使开发人员能够构建具有内置经济功能的强大去中心化应 用程序(DApp);在持续自我正常运行的同时,它还减少或消除了 审查,第三方界面和交易对手风险

以太坊的组成部分

• P2P网络 以太坊在以太坊主网络上运行,该网络可在TCP端口30303上寻址,并运行一个名为 ÐΞVp2p的协议。

• 交易(Transaction) 以太坊交易是网络消息,其中包括发送者(sender),接收者(receiver),值(value) 和数据的有效载荷(payload)。

• 以太坊虚拟机(EVM) 以太坊状态转换由以太坊虚拟机(EVM)处理,这是一个执行字节码(机器语言指令)的 基于堆栈的虚拟机。

• 数据库(Blockchain) 以太坊的区块链作为数据库(通常是 Google 的 LevelDB)本地存储在每个节点上,包含 序列化后的交易和系统状态。

• 客户端 以太坊有几种可互操作的客户端软件实现,其中最突出的是 Go-Ethereum(Geth)和Parity

 

以太坊中的重要概念

• 账户(Account) 包含地址,余额和随机数,以及可选的存储和代码的对象。

  • 普通账户(EOA),存储和代码均为空

  • 合约账户(Contract),包含存储和代码

• 地址(Address)

  一般来说,这代表一个EOA或合约,它可以在区块链上接收或发送交易。 更具体地说,它是ECDSA 公钥的 keccak 散列的最右边的160位。

• 交易(Transaction)

   • 可以发送以太币和信息

  • 向合约发送的交易可以调用合约代码,并以信息数据为函数参数

  • 向空用户发送信息,可以自动生成以信息为代码块的合约账户

• gas

  以太坊用于执行智能合约的虚拟燃料。以太坊虚拟机使用核算机制来衡量 gas的消耗量并限制计算资源的消耗。

以太坊的货币

以太坊的货币单位称为以太(ether),也可以表示为ETH或符号Ξ。 以太币的发行规则:

• 挖矿前(Pre-mine,Genesis) 2014年7月/8月间,为众筹大约发行了7200万以太币。这些币有的时候被称之为“矿 前”。众筹阶段之后,以太币每年的产量基本稳定,被限制不超过7200万的25%

• 挖矿产出(Mining)

——区块奖励(block reward) 每产生一个新区块就会有一笔固定的奖励给矿工,初始是5个以太币,现在是3个。

——叔块奖励(uncle reward)有些区块被挖得稍晚一些,因此不能作为主区块链的组成部分。比特币称这类区块为 “孤块”,并且完全舍弃它们。但是,以太币称它们为“叔块”(uncles),并且在 之后的区块中,可以引用它们。如果叔块在之后的区块链中作为叔块被引用,每个叔 块会为挖矿者产出区块奖励的7/8。这被称之为叔块奖励。

——叔块引用奖励(uncle referencing reward)矿工每引用一个叔块,可以得到区块奖励的1/32作为奖励(最多引用两个叔块)

 

以太坊区块收入

• 普通区块收入

  — 固定奖励(挖矿奖励),每个普通区块都有 — 区块内包含的所有程序的 gas 花费的总和 — 如果普通区块引用了叔块,每引用一个叔块可以得到固定奖励的 1/32

• 叔块收入

  叔块收入只有一项,就是叔块奖励,计算公式为: 叔块奖励 = ( 叔块高度 + 8 – 引用叔块的区块高度 ) * 普通区块奖励 / 8

 

去中心化应用

• 基于以太坊可以创建智能合约(Smart Contract)来构建 去中心化应用(Decentralized Application,简称为 DApp)

• 以太坊的构想是成为 DApps 编程开发的平台

• DApp至少由以下组成:

  —— 区块链上的智能合约

  —— Web前端用户界面

 

代币(Token)

• 代币(token)也称作通证,本意为“令牌”,代表有所有权的资产、 货币、权限等在区块链上的抽象

• 可替代性通证(fungible token):指的是基于区块链技术发行的, 互相可以替代的,可以接近无限拆分的token

• 非同质通证(non-fungible token): 指的是基于区块链技术发行的, 唯一的,不可替代的,大多数情况下不可拆分的token,如加密猫 (CryptoKitties)

 

名词解释

• EIP: Ethereum Improvement Proposals,以太坊改进建议

• ERC:Ethereum Request for Comments的缩写,以太坊征求意见。 一些EIP被标记为ERC,表示试图定义以太坊使用的特定标准的提议

• EOA:External Owned Account,外部账户。由以太坊网络的人类用 户创建的账户

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

• HD钱包:使用分层确定性(HD protocol)密钥创建和转账协议 (BIP32)的钱包。

• Keccak256:以太坊中使用的密码哈希函数。Keccak256 被标准化 为SHA-3

• Nonce:在密码学中,术语nonce用于指代只能使用一次的值。以太 坊使用两种类型的随机数,账户随机数和POW随机数

 

以太币单位

以太坊的货币单位称为以太,也称为ETH或符号Ξ

• ether被细分为更小的单位,直到可能的最小单位,称为wei; 1 ether = 10^18 wei

• 以太的值总是在以太坊内部表示为以wei表示的无符号整数 值。

• 以太的各种单位都有一个使用国际单位制(SI)的科学名 称,和一个口语名称。

 

 

以太坊钱包

 以太坊钱包是我们进入以太坊系统的门户。它包含了私钥,可以代表我 们创建和广播交易。

• MetaMask:一个浏览器扩展钱包,可在浏览器中运行。

• Jaxx:一款多平台、多币种的钱包,可在各种操作系统上运行,包括 Android,iOS,Windows,Mac和Linux。

• MyEtherWallet(MEW):一个基于web的钱包,可以在任何浏览器中运行。

• Emerald Wallet:旨在与 ETC 配合使用,但与其他基于以太坊的区块链兼容。

 

私钥、公钥和地址

• 私钥(Private Key) 以太坊私钥事实上只是一个256位的随机数,用于发送以太的交易 中创建签名来证明自己对资金的所有权。

• 公钥(Public Key) 公钥是由私钥通过椭圆曲线加密secp256k1算法单向生成的512位 (64字节)数。

• 地址(Address) 地址是由公钥的 Keccak-256 单向哈希,取最后20个字节(160位) 派生出来的标识符。

keystore文件就是加密存储的私钥。所以当系统提示你选择密码时:将其 设置为强密码,备份并不要共享。如果你没有密码管理器,请将其写下来 并将其存放在带锁的抽屉或保险箱中。要访问账户,你必须同时有 keystore文件和密码。 • 助记词可以导出私钥,所以可以认为助记词就是私钥。请使用笔和纸进行 物理备份。不要把这个任务留给“以后”,你会忘记。

 

以太坊客户端

• 以太坊客户端是一个软件应用程序,它实现以太坊规范并通过p2p 网络与其他以太坊客户端进行通信。如果不同的以太坊客户端符合 参考规范和标准化通信协议,则可以进行相互操作。

• 以太坊是一个开源项目,由“黄皮书”正式规范定义。除了各种以 太坊改进提案之外,此正式规范还定义了以太坊客户端的标准行为。

• 因为以太坊有明确的正式规范,以太网客户端有了许多独立开发的 软件实现,它们之间又可以彼此交互。

 

以太坊的多种客户端

go-ethereum ( Go ) 官方推荐,开发使用最多 地址:https://github.com/ethereum/go-ethereum

• parity ( Rust ) 最轻便客户端,在历次以太坊网络攻击中表现卓越 地址:https://github.com/ethcore/parity/releases

• cpp-ethereum (C++) 地址:https://github.com/ethereum/cpp-ethereum

• pyethapp (python) 地址:https://github.com/heikoheiko/pyethapp

• ethereumjs-lib ( javascript ) 地址:https://github.com/ethereumjs/ethereumjs-lib

• EthereumJ / Harmony ( Java ) 地址:https://github.com/ethereum/ethereumj

 

以太坊全节点

全节点是整个主链的一个副本,存储并维护链上的所有数据,并随 时验证新区块的合法性。

• 区块链的健康和扩展弹性,取决于具有许多独立操作和地理上分散 的全节点。每个全节点都可以帮助其他新节点获取区块数据,并提 供所有交易和合约的独立验证。

• 运行全节点将耗费巨大的成本,包括硬件资源和带宽。

• 以太坊开发不需要在实时网络(主网)上运行的全节点。我们可以 使用测试网络的节点来代替,也可以用本地私链,或者使用服务商 提供的基于云的以太坊客户端;这些几乎都可以执行所有操作。

远程客户端和轻节点

• 远程客户端 不存储区块链的本地副本或验证块和交易。这些客户端一般只提 供钱包的功能,可以创建和广播交易。远程客户端可用于连接到 现有网络,MetaMask 就是一个这样的客户端。

• 轻节点 不保存链上的区块历史数据,只保存区块链当前的状态。轻节点 可以对块和交易进行验证。

 

以太坊账户

• 以太坊的“状态”,就是系统中所有帐户的列表

• 每个账户都包括了一个余额(balance),和以太坊特殊定义的数据 (代码和内部存储)

• 如果发送帐户有足够的余额来支付,则交易有效;在这种情况下发送 帐户先扣款,而收款帐户将记入这笔收入

• 如果接收帐户有相关代码,则代码会自动运行,并且它的内部存储也 可能被更改,或者代码还可能向其他帐户发送额外的消息,这就会导 致进一步的借贷资金关系

 

 

 以太坊账户类型

外部账户 (Externally owned account, EOA )

  • 有对应的以太币余额

  • 可发送交易(转币或触发合约代码)

  • 由用户私钥控制 • 没有关联代码

• 合约账户 (Contract accounts)

   • 有对应的以太币余额

  • 有关联代码 • 由代码控制

  • 可通过交易或来自其它合约的调用消息来触发代 码执行

  • 执行代码时可以操作自己的存储空间,也可以调 用其它合约 

 

 

 

以太坊交易(Transaction)

签名的数据包,由EOA发送到另一个账户

• 消息的接收方地址

• 发送方签名

• 金额(VALUE)

• 数据(DATA,可选)

• START GAS

• GAS PRICE

 

交易的本质

交易是由外部拥有的账户发起的签名消息,由以太坊网络传输,并被 序列化后记录在以太坊区块链上。

• 交易是唯一可以触发状态更改或导致合约在EVM中执行的事物。

• 以太坊是一个全局单例状态机,交易是唯一可以改变其状态的东西。

• 合约不是自己运行的,以太坊也不会“在后台”运行。以太坊上的一 切变化都始于交易。

交易数据结构

交易是包含以下数据的序列化二进制消息:

• nonce:由发起人EOA发出的序列号,用于防止交易消息重播。

• gas price:交易发起人愿意支付的gas单价(wei)。

• start gas:交易发起人愿意支付的最大gas量。

• to:目的以太坊地址。 • value:要发送到目的地的以太数量。

• data:可变长度二进制数据负载(payload)。

• v,r,s:发起人EOA的ECDSA签名的三个组成部分。

• 交易消息的结构使用递归长度前缀(RLP)编码方案进行序列化,该方案 专为在以太坊中准确和字节完美的数据序列化而创建。

 

消息(Message)

-- 合约可以向其它合约发送“消息”

-- 消息是不会被序列化的虚拟对象,只存在于以太坊执行环境 (EVM)中 -- 可以看作函数调用

• 消息发送方

• 消息接收方

• 金额(VALUE)

• 数据(DATA,可选)

• START GAS

合约(Contract)

• 可以读/写自己的内部存储(32字节key-value的 数据库)

• 可向其他合约发送消息,依次触发执行

• 一旦合约运行结束,并且由它发送的消息触发的 所有子执行(sub-execution)结束,EVM就会中 止运行,直到下次交易被唤醒

 

以太坊虚拟机(EVM)

以太坊虚拟机 EVM 是智能合约的运行环境

• 作为区块验证协议的一部分,参与网络的每个节点都会运行 EVM。他们会检查正在验证的块中列出的交易,并运行由 EVM中的交易触发的代码

• EVM不仅是沙盒封装的,而且是完全隔离的,也就是说在 EVM 中运行的代码是无法访问网络、文件系统和其他进程的, 甚至智能合约之间的访问也是受限的

• 合约以字节码的格式(EVM bytecode)存在于区块链上

• 合约通常以高级语言(solidity)编写,通过EVM编译器编译 为字节码,最终通过客户端上载部署到区块链网络中

EVM和账户

• 以太坊中有两类账户: 外部账户 和 合约账户,它们共用 EVM中同一个地址空间

• 无论帐户是否存储代码,这两类账户对 EVM 来说处理方 式是完全一样的

• 每个账户在EVM中都有一个键值对形式的持久化存储。其 中 key 和 value 的长度都是256位,称之为 存储空间 (storage)

EVM和交易

• 交易可以看作是从一个帐户发送到另一个帐户的消息,它 可以包含二进制数据(payload)和以太币

• 如果目标账户含有代码,此代码会在EVM中执行,并以 payload 作为入参,这就是合约的调用

• 如果目标账户是零账户(账户地址为 0 ),此交易就将创建 一个 新合约 ,这个用来创建合约的交易的 payload 会被 转换为 EVM 字节码并执行,执行的输出作为合约代码永 久存储

EVM和gas

• 合约被交易触发调用时,指令会在全网的每个节点上执行:这需要消 耗算力成本;每一个指令的执行都有特定的消耗,gas 就用来量化表 示这个成本消耗

• 一经创建,每笔交易都按照一定数量的 gas 预付一笔费用,目的是限 制执行交易所需要的工作量和为交易支付手续费

• EVM 执行交易时,gas 将按特定规则逐渐耗尽

• gas price 是交易发送者设置的一个值,作为发送者预付手续费的单 价。如果交易执行后还有剩余, gas 会原路返还

• 无论执行到什么位置,一旦 gas 被耗尽(比如降为负值),将会触发 一个 out-of-gas 异常。当前调用帧(call frame)所做的所有状态修改 都将被回滚

EVM数据存储

Storage • 每个账户都有一块持久化的存储空间,称为 storage,这是一个将256位字映射到256位字的 key-value 存储区,可以理解为合约的数据库 • 永久储存在区块链中,由于会永久保存合约状态变量,所以读写的 gas 开销也最大

Memory(内存) • 每一次消息调用,合约会临时获取一块干净的内存空间 • 生命周期仅为整个方法执行期间,函数调用后回收,因为仅保存临时变量,故读写 gas 开销较 小

Stack(栈) • EVM 不是基于寄存器的,而是基于栈的,因此所有的计算都在一个被称为栈(stack)的区域 执行 • 存放部分局部值类型变量,几乎免费使用的内存,但有数量限

消息调用( Message Calls )

• 合约可以通过消息调用的方式来调用其它合约或者发送以 太币到非合约账户

• 合约可以决定在其内部的消息调用中,对于剩余的 gas , 应发送和保留多少

• 如果在内部消息调用时发生了 out-of-gas 异常(或其他任 何异常),这将由一个被压入栈顶的错误值所指明;此时 只有与该内部消息调用一起发送的 gas 会被消耗掉

委托调用(Delegatecall)

• 一种特殊类型的消息调用

• 目标地址的代码将在发起调用的合约的上下文中执行,并 且 msg.sender 和 msg.value 不变

• 可以由此实现“库”(library):可复用的代码库可以放 在一个合约的存储上,通过委托调用引入相应代码

合约的创建和自毁

• 通过一个特殊的消息调用 create calls,合约可以创建其 他合约(不是简单的调用零地址)

• 合约代码从区块链上移除的唯一方式是合约在合约地址上 的执行自毁操作 selfdestruct ;合约账户上剩余的以太币 会发送给指定的目标,然后其存储和代码从状态中被移除

 

智能合约概述

Solidity中合约

• 一组代码(合约的函数 )和数据(合约的状态 ),它们位 于以太坊区块链的一个特定地址上

• 代码行 uint storedData; 声明一个类型为 uint (256位无符 号整数)的状态变量,叫做 storedData

• 函数 set 和 get 可以用来变更或取出变量的值

合约结构

• 状态变量(State Variables) 作为合约状态的一部分,值会永久保存在存储空间内。

• 函数(Functions) 合约中可执行的代码块。

• 函数修饰器(Function Modifiers) 用在函数声明中,用来补充修饰函数的语义。

• 事件(Events) 非常方便的 EVM 日志工具接口。

posted @ 2022-09-14 11:42  caolingyi  阅读(435)  评论(0编辑  收藏  举报