区块链/以太坊/读书笔记/精通以太坊思维导图

第一章~第三章

学习笔记 思维导图

在这里插入图片描述

附:文本结构

精通以太坊-基础1~3章
	概念
		基于区块链技术打造的平台
		智能合约
			以太坊计算基础框架上执行的程序
		DApp
			狭义
				基于智能合约开发的用户界面
					至少包含一个智能合约
			广义
				开放的去中心化的网络应用
		以太币
			以太坊官方货币
			由挖矿成功得以产生
				成功打包区块的奖励
			可购买gas
			运行智能合约需消耗gas
		特点
			任何人都可以在平台上发布dapp,区块链应用
			开放的
			去中心化
			无政府状态
		gas
			可看作是支持智能合约运行的能量
			可通过以太币购买
			gasPrice
				愿意为运行智能合约支付的gas数
			gasLimit
				为智能合约运行消耗配置上限
				理论上可以配置为无穷大,以支持智能合约的永久运行
			用于支付交易手续费,交易失败不退还
		钱包
			钱包软件的选择
				可通过发起交易转移到别的钱包软件
				也可通过私钥迁移
			不同种类的钱包
				移动钱包
					Jaxx
				桌面钱包
					Jaxx
					Emerald Wallet
				基于浏览器的钱包
					MetaMask
					MyEtherWallet(MEW)
		以太坊客户端
			本质
				一种软件应用程序,实现了以太坊协议规范,并通过点对点网络与其他以太坊客户端通信
			作用
				同步
				JSON-RPC接口
				远程调用以太坊客户端
					分类
						移动钱包
							只提供最基本的钱包功能
						其他
							功能完备的DApp浏览器
					共同点
						这些客户端提供的功能都是全功能客户端的子集
						而且不会在本地同步以太坊区块链数据,只会连接到别的地方运行的全功能节点,例如你自己不熟的本地设备或者Web服务器上的全功能节点,或者第三方部署在服务器上的全功能节点
					功能
						管理钱包中的私钥和以太坊地址
						创建、签名并广播交易
						通过交易内数据载荷的方式与智能合约交互
						浏览并使用DApp
						提供外部服务的链接,例如区块浏览器
						转换以太币的单位,从外部获取兑换的汇率
						向浏览器注入一个web3实例(供页面上的JavaScript与客户端交互)
						使用其他客户端提供或注入浏览器的web3实例
						访问本地或远程以太坊节点的RPC服务
		全功能节点
			好处
				为以太坊的可扩展性和防审查机制提供更强的支持
				可信地验证所有交易
				可以跟主网上所有的合约进行交互,不需要任何中间角色
				可以在需要时,离线查询(只读形式)区块链的状态,如账户、合约等
			弊端
				需要显著并且不断增长的硬件资源和带宽资源
				需要数小时甚至数天才能完成区块链数据的同步
					逐一从创世区块开始下载并验证每一个区块和其中的每一笔交易
					有一部分被Dos攻击期间的区块验证极其缓慢,因此可跳过这些问题区块的完整验证操作,直到同步到区块链最新区块,才恢复完整验证
						Geth启用参数是--fast
						Parity默认开启
				必须持续的维护、升级、保持节点在线才能保证区块链数据的同步
		公共测试网络
			好处
				测试网络节点只需要同步和保存更少的区块链数据
				测试网络节点的区块数据同步只需要数小时就能完成
				测试网络上不需要真实以太币和gas,可通过多个渠道免费获得测试以太币
				测试网络是一个包含众多其他用户和合约的正在实际运行的公共区块链
			弊端
				测试网络上没有真实以太币,黑客对没有价值的环境不感兴趣,也就无法在测试网络上检测安全性
				交易手续费等在测试网络上往往会被忽略,毕竟gas免费
				测试完不会出现主网上有时会纵欲的拥堵情形
		本地区块链模拟器
			好处
				不需要同步区块链数据,几乎不占用硬盘空间
				开发者自己完成第一个区块的挖矿
				不需要设法获取测试以太币,开发者在挖矿时可以给自己奖励以太币并用于测试
				没有其他用户
				没有其他合约
			弊端
				没有交易打包空间和顺序的竞争
				只有你一个人挖矿,没法测试在公链上与挖矿有关的一些场景
				没有其他合约,意味着你必须部署测试所需要的所有依赖合约和各种合约库
				无法重建一些公链上的合约并使用它们在公链上的地址进行特殊的测试,例如DAO合约
	2020-06-16
		总市值
			比特币是以太币7倍
		单币价
			比特币是以太币41倍
		区块链数据库总大小
			同样都约为330GB
	生态
		节点客户端模式
			测试网
				用途
					用于开发测试
					虽然和主网分离,但建议使用另外的账户
						避免误操作导致主网财产损失
				分类
					公共测试网
						在“水龙头”提供的无价值的以太币上运行
						尽可能的模拟了主网环境
					本地测试网
						本机或小型私有集群环境
			主网
				真实网络
				可参与挖矿
				使用真实以太币
				消耗真实gas
		各语言版本的客户端
			Go
				go-ethereum
					geth
			Rust
				openethereum
					parity
						以太坊客户端软件中最著名的可互操作实现之一
			Java
				pegasys
				Harmony
			C#
				Nethermind
			Scala
				Mantis
			Python
				pyethereum
			C++
				cpp-ethereum
		ethnode
			本地节点的零配置运行工具
			支持Parity(openethereum) 和 Geth
		前后端API
			都是以太坊平台接口?
		DApp经典架构
			编写智能合约,发布到主网
			Import对应的前后端API包,编写程序,与以太坊用户或智能合约进行交互、交易等
		其他组成
			智能合约编程语言
				Solidity
					开发智能合约通常使用的语言
				Vyper
					基于python语言
					致力于提高安全性
			API库
				前端JS API
					Web3.js
						以太坊 JavaScript API
					Ethers.js
						JavaScript 和 TypeScript 中完整的以太坊钱包实现和实用工具
					light.js
						针对轻客户端优化的高级响应式 JS 库
				后端API
					Infura
						以太坊 API 即服务
					Cloudflare
						以太坊网关
					Nodesmith
						JSON-RPC API 访问以太坊主网和测试网
					Chainstack
						共享及专用的以太坊节点即服务
			开发者工具、框架
				web3.j
					以太坊的 Java/Android/Kotlin/Scala 集成库
				Truffle
					开发环境、测试框架、部署通道及其他工具
				Waffle
					高级智能合约开发和测试的框架 (基于 ethers.js)
				One Click Dapp
					直接从 ABI 生成一个前端进行快速开发和测试
				Ethereum Grid
					用于下载、配置和运行以太坊客户端及以太坊工具的桌面应用程序
			IDE
				Client IDE
					官方支持的VSCode
				WEB IDE
					Ethereum Studio
					Remix
					EthFiddle
		经典DApp架构
			智能合约
			框架+API
		最佳实践
			智能合约
				自动执行的程序
				可以做什么?
					比如绝对中立的专家
					比如版权认证
					比如游戏
						土地购买游戏
							土地拥有者可盈利或亏损
							开发者收取交易金额的比例佣金
						养猫游戏

第四章~第六章

学习笔记 思维导图
在这里插入图片描述

附:文本结构

精通以太坊-4~6章
	密码学
		概念知识
			密码学是以太坊的技术基石
			以太坊协议本身没有任何加密信息
				所有通信和交易数据都不是加密的
				因此所有人都可以读取到交易数据等
				每个人都可以验证状态更新的正确性并达成共识
			只有账户地址和数字签名可以在链上传输和存储
			资金的访问和控制权是通过数字签名实现的
			第4章主要是介绍以密钥和地址的形式来控制资金所有权的公钥密码学(PKC)
			两类账户可以操作以太币
				外部账户
					对以太币的所有权是通过私钥、以太坊地址、数字签名建立起来的
				合约账户
					没有私钥来控制所有权
		随机数生成器生成私钥
			使用密码学安全的伪随机数生成器
				并使用熵源充足的随机源做种子
				如CSPRNG
			不要使用“简易”随机数生成器
				因为这种假随机更容易重复
		椭圆曲线加密算法(ECC)
			加法
				Y坐标不同时,A+B=AB连线与曲线的交点P‘,再取交点P‘关于X轴的对称点P
			二倍运算
				A和A为同一点时,A+A=2A,即二倍运算,由切线得出交点P‘,再得到P
			正负取反
				即取该点的X轴对称点
					P=-P
			无穷远点
				互为正反点时,由于没有交点,故称P+(-P)=无穷远点
			ECC比起RSA更快更安全
				RSA基于因数分解难度大
			公钥的计算公式
				公钥K=私钥k*生成点G
					G+G+G+...+G
						G+G=G2
							第一次加法
						G2+G=G3
							第二次加法
						G3+G=G4
							第三次加法
						......
							K=k*G是可以计算得出的
								累加法是最笨最慢的方法
								还有很多更快更先进的方法
									
							已知K、G,求k是几乎不可能的
								每次加法都是基于新的点,k是256位,10^77次方的可能性,快赶上人类已知的原子个数10^80次方了。
							已知一百亿次加法,那就做一百亿次加法,就能得到K
								反过来,不知道是一百亿次,那就得从1次开始尝试推导出k1,用k1试试能不能开锁,不能再尝试第2次加法,直到尝试到一百亿次加法,才能发现开锁成功了,即使一亿秒能完成这么多次尝试,也需要将近三年时间。更何况k远大于一百亿。
			以上特性决定了私钥不可被破解
				接下来,我们需要保证公钥加密的内容只能通过私钥解密,公钥也不能解密
		哈希函数
			概念
				将任意长度数据映射成固定长度数据的数学函数
			是多对一的函数
				可能存在多种输入,得到同一个输入
					这个问题被称为哈希碰撞问题
					哈希碰撞情形越少代表哈希函数性能越好
			特性
				确定性
					同样的输入总会产生同样的哈希值
				可验证性
					计算非常高效(线性计算性能)
				无关联性
					输入消息的微小变化将输出巨大变化哈希值
				不可逆性
					反向计算得出原始信息是不现实的
				碰撞保护性
					???
					防止碰撞的方法
						拉链法
							完全避免碰撞,但实现较复杂
						多哈希法
							依然存在碰撞
						开放地址法
						建域法
			应用
				数据指纹
				数据一致性,错误侦测
				工作量证明
				身份认证
				伪随机数生成器
				消息承诺
				唯一标识符
			基本思路
				对每一个字符计算得出一个散列值并汇总,且每个字符都对后面的字符产生影响
				位数不够的需填充补齐
			以太坊使用的哈希函数
				Keccak-256
		以太坊地址格式
			ICAP协议
				互换客户端地址协议
					一种与国际银行账号(IBAN)编码部分兼容的以太坊地址编码形式
					ICAP是一个去中心化实现
					IBAN是一个中心化,收到高度监管的服务
				ICAP地址可用于编码以太坊地址
				也可用于编码注册再以太坊域名注册服务之下的通用名称
			EIP-55
				十六进制编码地址的大写校验
				能很快速地校验出地址是否拼写错误
	钱包
		概念
			一个用户界面
				控制对以太币的访问、管理私钥和地址、跟踪账户余额、创建并签名交易
			存储和管理用户密钥的系统
				对开发者来说
		私钥保存形式
			JSON格式的keystore文件
			钱包类型
				非确定性(随机钱包)
					这个文件并使用额外的密码进行加密
					额外的密码进行262144轮的哈希计算后,再用于加密,进一步大大提高了破解难度
				确定性(种子密钥)钱包
				层次式确定性钱包
					从单一种子中衍生出多个密钥
				种子密钥和助记词
			最佳实践
				不同钱包类型实现的各种标准
				说白了就是生成密钥和保存密钥的方案
	交易
		概念
			交易由外部账户发出的经过签名的消息,通过以太坊的网络传播,由矿工记录在区块链上
				交易是唯一能够出发区块链状态改变,或出发EVM上的合约执行的东西
			以太坊是一个全局的单体状态机,交易是唯一能让这台状态机向前推进并改变状态的东西
				合约不会自动运行
				以太坊也不会在“后台”运行
				所有这一切,都是由交易触发的
		交易的结构
			交易在以太坊网络上打包和传输的基本结构
				交易是一串打包在一起的二进制数据,包括以下内容
					nonce
						一个序列编号
						由构建这个交易的外部账户提供
						用于防止交易的重放攻击
					gas price
						交易发起方愿意支付的gas
					gas limit
						交易发起方愿意为这个交易支付的gas上限
					recipient
						目标以太坊地址
					value
						发送给目标地址的以太币数量
					data
						附在交易中的可变长度的数据
					v,r,s
						由构建交易的外部账户提供
						椭圆曲线签名的三个组成部分
						可推算出公钥
							进而推算出发起方的地址
						目的是节省区块链数据空间
		交易的随机数
			一个数值
				等于这个地址发出的交易数量
				当这个地址与合约关联时,是这个地址所创建的合约数量
			只在发送地址的上下文中才有意义
				不会作为账户状态的一部分显式的保存在区块链上
				通过计算发送方地址已经确认的交易数量而动态计算的
			重要作用
				交易创建顺序中的可用性特征
					如果没有随机数
						节点会以任意顺序接收交易
						没有任何方法能保证某个节点在另外一个节点之前接收到某笔交易
					一个例子
						当你有10ether时,先发起6ether交易,再发起8ether交易时
							在没有随机数的情况下,接收与否完全时随机的
							如果包含了随机数,假设6e的交易随机数是3,8e的交易随机数时4,那么即使8e先被接收到,也会先处理0到3的交易
								如果nonce跳跃提交,那该交易不会进入区块链,而是保存在待确认交易内存池中,只有在缺失的部分都补齐后,才会写入区块链,并按顺序被处理
				交易重复保护的重要特征
					如果没有随机数,一笔交易可以被攻击者不断复制重放,造成你的损失
					而有了随机数,一笔交易被复制多次也只会被完成一次
			nonce是从0开始计数的
			getTransactionCount
				当有待确认交易时,无法获取到正确的nonce
			parity_nextNonce
				Parity支持的更加准确的获取nonce值的方法
			并发情况下的随机数
				策略一:一台计算机分配nonce,其他计算机先到先得
					问题1:这台计算机可能会单点故障,导致其他计算机拿不到nonce
					问题2:其他计算机只要有1台单点故障,就会导致这台处理的nonce后面的nonce交易被堵住
				策略二:其他计算机发起交易,不带nonce和签名,集中到一台计算机后分配nonce和签名
					问题1:这台分配nonce的计算机单点故障即无法处理任何交易
					缓解问题2:其他计算机个别出故障时,互相不影响
				策略三:不得不抛弃并发
					1:单进程处理所有交易
					2:间歇性重新计算余额
		交易的gas
			以太坊的燃料
			跟以太币存在汇率关系
			控制交易对资源的使用
			独立于以太币,以太币价格大幅度波动情况下也能保护系统的灵活性
				对于各种消耗gas的资源,gas能够管理它们之间重要而敏感的汇率关系
			案例:将以太币从一个账户转账到另一个账户
				所需要的gas数量是固定的21000单位个的gas
				gasPrice
					gasPrice允许交易的发起方设定针对gas的汇率
					计量单位是wei/gas
						如本书中的实例,钱包软件把gasPrice设定为3(gwei)
					gasPrice越高,交易被确认的速度也越快
						对ETH汇率越高,同等数量的gas(21000)对应支付的ETH也就越高
					gasPrice可以为0,在区块有多余空间时也会被矿工打包提交到区块链之上
						有可能永远不被确认,但区块链上存在这种交易已成功处理
				gas*gasPrice=21000*3(gwei)= 63000(gwei)=63000/10亿(ETH)
					10亿(gwei)= 1ETH
			gasLimit
				是发起方愿意支付的最大gas数量
					如果交易目标地址是一个合约,那么需要的gas数量是可以估计,但很难精确算出
						合约可以根据不同初始条件,选择不同的执行路径,这样就会导致不同的gas开销
						因此你需要提供一个足够执行完成的gas数量,最终按实际消耗扣除费用
					发出交易时,验证交易的第一步时确保发起交易的账户中有足够的以太币来支付对应的gas费用(gasPrice*gas)
						但是不会从账户中直接扣除gas
						而是直到交易执行结束后才会扣除
						你只会被扣除交易执行所实际发生的gas
						但是账户中必须有高于你在交易中指定的最高gas费用对应的以太币,这个交易才能被通过验证
		交易的接收方
			to字段指定
				20字节的地址
					外部账户地址
					合约地址
				不会验证地址,只要20字节的值都会被认为是正确的
				如果向一个没有对应私钥的地址发送以太币,相当于是销毁以太币
				接收方地址的验证工作需要在用户应用这一层完成
					十六进制编码地址的大写校验
				由于以太币的数量是有限的,合理销毁以太币能有效地将价值传到所有以太币持有者手上(按持有以太币的比例)
		交易中的以太币和数据
			核心
				value
				data
					函数选择器
						被调用函数原型的哈希值的前4个字节
							可准确无误地识别被调函数
					函数参数
						函数的参数
							追加到函数选择器后,填满32字节
					Data组成实例
						2e1a7d4d000000000000000000000000000000000000000000000000002386f26fc10000
							函数
								2e1a7d4d
									web3.sha3(”withdraw(uint256)”)
							参数
								2386f26fc10000
									0.01ether
			交易类型
				同时包含value和data
				只有value
					转账
				只有data
					调用合约
				没有value也没有data
					什么也不发生
			目标地址
				外部账户
					存在此账户就增加余额
					不存在就创建这个地址并初始化余额为此value
					通常对外部账户发起的交易中的data字段内容没有意义,以太坊协议没有对此作出规。只有少部分特定的钱包软件(接受者)会对此解读
				合约
					data字段指定要调用的函数
					如果data为空,则调用回退函数
						回退函数如果是可支付的,那么根据函数的代码来决定下一步动作
						如果没有回退函数,则增加合约的余额
		合约创建
			特殊交易
				to:0x0
					目标地址为零地址
					仅用来合约注册,但也可能误操作而销毁以太币
				data为编译后的合约字节码,value字段包含以太币可为合约设置起始余额(这是可选的)
		数字签名
			椭圆曲线数字签名算法
				ECDSA
			三个作用
				证明签名方是私钥的持有人
					授权以太坊转账或合约的执行
						身份认证
				证明这个授权是不可否认的
					发送方不能否认
				确保交易数据在经过签名之后没有也不能被任何人修改
					完整性
			工作原理
				创建签名
					使用私钥签名
				验证签名
					任何人使用消息和公钥验证签名
			具体算法
				略
		签名的前缀和公钥恢复
			公钥恢复
				获得公钥之后,很容易计算出发起方的以太坊地址
			v字段
				偶数
					R是正确的值
				奇数
					R‘是临时公钥
		离线签名
			签名和广播分开处理
				离线签名,保证私钥的安全
				广播是需要连接到互联网上
			签名和广播的机器分开两台机器处理,并且保证签名的机器是未联机的
				USB离线传输签名
				离线签名生成QR码,扫码传输
		交易的传播
			平均每个节点维护了至少13个跟它直接相连的其他节点,称为邻居
				每个邻居节点都会在收到交易数据包后立刻进行验证
				如果它们确认交易数据包合法,这些节点就会保留一份交易副本,然后把交易数据包广播给与它们相连的邻居(除去消息来源的那个上游节点)
					因此,交易就像水中的波纹一样,在整个网络中迅速传播开,直到所有节点都收到了一份交易的副本
				节点可对所广播的消息进行过滤,但默认情况下,会广播收到的所有验证消息
				在短短几秒内衣他以太坊交易就能到达全球范围内的所有以太坊节点
				从单个节点的角度而言,它无从知晓这个消息的来源
					因此攻击者必须控制网络中的大部分节点
		记录在区块链上
			合理验证过的交易最终会被包含在一个区块中,并且记录在以太坊的区块链上
				记录到区块链之后,交易就会更改以太坊网络的单体,修改账户余额,或者调用改变内部状态的合约
			到此就是一笔交易的全过程
				创建
				签名
				写入区块链
		多签名交易
			创建多重账户
			该账户只有在多方共同签名的情况下才能花费其中的资金
				利用“钱包合约”编程
				将以太币转移到多重签名合约
				安全性由这个多重签名合约的代码决定
			比特币有多重签名系统,以太坊则依赖另外的合约实现

第七章~第九章

智能合约 安全 风险 漏洞 Solidity Vyper

学习笔记 思维导图
在这里插入图片描述

附:文本结构

精通以太坊-7~9章
	智能合约
		以太坊的智能合约既不智能,也没有法律上的合约效力
		以太坊的智能合约是那些不可改变的计算机程序
			以确定性方式运行在以太坊的虚拟机上的程序
			以太坊去中心化世界计算机
		定义
			计算机程序
				智能合约就是计算机程序,这里的合约没有任何法律上相关的含义
			不可改变
				一旦部署,智能合约的代码就不能被改变
				更改智能合约的唯一办法就是部署一个新的实例
			确定性的
				智能合约执行结果对于每一个运行或调用它的人来说都是一样的
			以太坊虚拟机上下文
				智能合约运行在一个非常有限的执行环境中。
				它们可以访问自己的状态,调用合约交易的上下文信息,以及有关最近区块的信息
			去中心化的世界计算机
				EVM作为每一个以太坊节点的本地实例运行,但是因为所有EVM都是运行在相同的初始状态,并且输出完全相同的最终状态,所以整个系统就像是一台世界计算机
		生命周期
			通过发起目标地址为0x0的交易部署合约
			合约的创建者不会再协议层获得相对其他用户而言的任何特权
				但可以把自己的特权写入合约内部
			合约账户没有私钥,智能合约的主人不是创建者,而是它自己
			合约只有在被交易调用时才会执行
				合约可以调用另一个合约,然后一层层地在合约之间不断调用
				但这个执行链条中的第一个合约的执行,一定是由外部账户所创建的交易触发的
			合约直到交易触发执行前,都处于等待调用的状态,而永远不会“自动执行”或者“在后台运行”
			任何情况下智能合约的“并发执行”都是没有意义的
				以太坊世界计算机可以被认为是一台单线程的计算机
			交易原子化
				无论调用多少合约,多少次操作,如果错误会回滚
				失败的交易仍然会被作为一次失败的尝试而记录在案
					所花费的gas依然会被扣除
			合约实例删除
				执行名为SELFDESTRUCT的EVM字节码
				需要合约的开发者在代码中编写了对应的删除功能,SELFDESTRUCT字节码才会起作用
					否则该合约实例无法删除
					可控制仅能由创建者删除
				删除合约实例,不会执行任何代码
				删除操作会产生负的gas消耗,也就是系统会提供gas退款
					用于激励人们通过删除存储状态的方式释放资源
				删除合约并不会清楚这个合约之前交易的历史记录
		注意事项
			gas消耗
				开发智能合约时必须认真对待gas相关问题,gas用于限定衣他交易运行所耗费的最大计算量。
				耗尽gas将会
					抛出“out of gas”异常
					状态被恢复到执行开始之前
					所有在这次执行过程中的gas开销都会被作为交易费用
				有一些需要遵循的最佳实践,尽可能把合约调用的gas消耗最小化
			避免动态尺寸的数组
				遍历数组的每一个元素进行查找或操作,都有触发高额gas消耗的风险
				因此要避免使用动态尺寸的数组
			避免调用其他合约
				特别是gas消耗未知的合约
				没有经过测试和广泛使用的库合约
			估计gas开销
				gasEstimate可用于估计调用开销
		合约的常见漏洞
			可自毁合约
				任何地址都可杀死
			贪婪合约
				达到某个执行状态,就无法释放以太币
			慷慨合约
				把以太币转给任意地址
		读取数据
			智能合约可以将数据写进两个地方
				全局状态
					状态变量存储在以太坊全局状态树中
					只能存储、读取、修改与自身地址相关的数据
					不能读写其他智能合约的数据
				日志
					通过日志事件,将数据写入以太坊区块链数据中
					智能合约无法对所创建的链上日志进行读操作
					但日志数据可悲轻客户端发现和读取
					可获得指定交易收据的日志数据
	Vyper与Solidity
		抛弃修饰符
			提高代码可审计性和可读性
				可通过明确的代码代替
		抛弃继承
			继承关系需要在多个文件之间跳转会提高阅读难度
		抛弃内联汇编
			内联汇编可读性差
		抛弃函数重载
			不允许同名函数
			避免混淆
		变量类型转换
			使用convert函数
			更安全
		显式地处理前置和后置条件和状态变化
			虽然会产生冗余代码,但提高可读性和安全性
			Vyper中编写时应遵循三点
				条件
					以太坊状态变量的当前状态和条件是什么?
				影响
					智能合约在执行时对状态变量的条件的影响
						什么会受影响
						什么不会受影响
						这些影响是否与智能合约的意图一致
				交互
					有逻辑地逐步执行代码,并考虑代码执行后所有可能的永久结果、后果、场景
		总结
			Vyper
				功能强大
				面向合约编程
				偏向正确性,牺牲灵活性
				更安全
	智能合约安全
		安全最佳实践
			最小化/简单化
			代码重用
			代码质量
				因为你处在航天工程那样或其他类似的零容错的工程领域之中
			可读性和可审计性
				智能合约是公开的,任何人都可以获得其字节码并进行反向工程
				因此智能合约很契合在开源社区协作开发
			测试覆盖率
				尽可能测试所有情况
		安全风险
			重入
				漏洞
					外部的恶意合约通过函数调用来重新进入合约代码执行过程
				防范技术
					尽可能使用内置的transfer函数向外部合约发送以太币
					所有对状态变量的修改都在向其他合约发送以太币之前来执行
					引入互斥锁,增加一个状态变量来在代码执行中锁定合约,避免重入的调用
			算数溢出
				漏洞
					比如unit8范围是[0,255],用来保存256时就溢出变为了0
						257变为1,以此类推
						因此可能被攻击者利用来伪造数值
					也要注意加减乘等等的溢出
						上溢
						下溢
					除法不会导致溢出
						除以0时会抛出异常
				防范技术
					使用或构建安全的算数运算的库合约来代替标准的算数操作
						如使用OpenZeppelin的SafeMath.sol
			意外的以太币
				漏洞
					攻击者向合约发送以太币,导致合约的初始数值非零,产生一些负面影响
						不是所有攻击,攻击者都是为了盈利,也可能是为了纯粹的破坏,就算自己付出了些许代价
				防范技术
					避免依赖合约余额的具体数值(this.balance),因为它可以被人为地操纵
					自定义变量在payable函数记录数额变动
			DELEGATECALL
				运行在调用合约的上下文
				CALL则是运行在目标合约的上下文
				漏洞
					可能导致非预期的代码执行结果
				防范技术
					使用DELEGATECALL要非常仔细地注意库合约和主调用合约的可能的调用上下文
					并尽可能构建无状态的库合约
			默认的可见性
				漏洞
					函数默认可见性是public
					因此如果函数不指定可见性,函数就是可以被外部用户调用的
				防范技术
					对合约中的所有函数明确指定可见性
			无序错觉
				漏洞
					区块链是一个确定性的系统
					随机数都是伪随机数
					不能通过时钟来产生随机数
					如果使用未来的区块哈希值判定赌局,矿工可以不发布不利于自己的区块,而是重新打包区块直到得到有利的新的区块哈希值再发布
					如果使用过去的变量更加灾难,因为这些对所有人都是透明的,也就更容易被攻击者知晓
					区块变量不能作为无序性的来源,因为可以被矿工们操纵
				防范技术
					无序性(随机性)必须来自区块链外部
					比如使用RandDAO
					比如每个参与者提供一个seed,再一起进行hash公示
			外部合约引用
				漏洞
					在部署时更改外部合约引用,从而运行攻击者自己的代码
				防范技术
					使用new创建引用的合约,这样以来部署的用户也无法在不更改代码的情况下替换改引用合约
						代码发生变化,合约字节码就发生变化,合作用户就能发现代码被篡改过
					对外部合约地址进行硬编码
						将外部合约地址设定为public,用户就可以轻松检查合约所引用的外部合约
			短地址/参数攻击
				漏洞
					攻击者故意传一个位数少了的地址参数,让没有检查正确性的合约使用0自动补齐,进而产生不良影响
				防范技术
					所有外部应用在把输入参数发送到区块链之前都应该对它们进行校验,包括参数的顺序等都同样扮演着重要角色
			未检查的调用返回值
				漏洞
					Call喝send函数会返回一个布尔值来指明调用是否成功,因此如果外部调用失败,执行了这些函数的那个交易不会revert回滚
				防范技术
					调用call喝send函数后检查布尔值,以分别处理成功以及失败的场景
			竞争条件/预先交易
				漏洞
					攻击者监视交易池中的交易,如果交易中包含了对某个问题的答案,那么攻击者可以去修改或者撤销解决者的权限,或者把合约修改为对解决者不利的状态
					然后,攻击者从解决者的交易中获取数据,并用更高的gasPrice创建他们自己的交易,这样他们的交易就会优先于原始交易被打包到区块中
					直白点:攻击者作弊偷了答案,并用更高的gasPrice让自己优先交卷
						交易打包按gasPrice排序
					两类攻击
						用户修改其交易的gasPrice
						矿工自己按照自己的意愿随意对区块内的交易进行排序
							仅在自己找到区块的工作量证明时才能发起攻击
				防范技术
					将gasPrice设置为上限,避免第一类攻击
					提示-揭示策略
						发送带有隐秘信息的交易(通常是一个哈希值)
						当交易被包含到区块后再发送一个交易揭示先前发送的数据
						如ENS智能合约允许用户先提交它们希望话费的以太币数量,同时附带任意数量的以太币,然后在揭示阶段,用户可以获得以太币返还
							?
					水底发送策略
			拒绝服务
				漏洞
					基于可被外部操纵的映射或数组的循环
						Distribute向多个账户分发代币时,攻击者创建过多的账户,使该合约的gas消耗超过gasLimit
					主人的操作
						必须经过拥有特权的主任来进行某些操作才能进入下一步状态
						如果主人丢失了私钥,这个合约就进行不了下一步了
					基于外部调用来修改状态
						比如创建一个不接受转账的合约
						而新的状态需要先将以太币被全部取走才能进入下一步
				防范技术
					第一个例子,合约不应该基于一个可以被外部用户人为操作的数据结构来执行循环
						这里推荐使用取回模式
						只能让取款人单独地调用withdraw函数来取回他们各自的代币
					第二、三个例子
						可以使用时间解锁机制
							保证意外发生,也可在到期时自动进行下一步
			区块时间戳操纵
				漏洞
					矿工是可以操纵时间戳的
				防范技术
					时间戳不应该被用来作为无序数据或生成随机数
					或者说不能用来作为重要的状态变动
			小心使用构造函数
				漏洞
					如果合约名称被改动后,构造函数忘记修改,就会变成普通的可被调用的public函数,从而引发攻击
				防范技术
					0.4.22版本的solidity编译器引入了constructor关键字来制定构造函数,因此此漏洞已经不存在了
			未初始化的存储指针
				漏洞
					EVM是用存储或内存来保存数据的,不适当的变量初始化可能会产生有漏洞的合约
				防范技术
					注意为初始化的存储变量警告
					在处理复杂数据类型时严格使用memory或storage标识符
						努力让行为符合预期
			浮点数和精度
				漏洞
					旧版solidity没有浮点型,需要特殊处理
				防范技术
					有时候先乘后除精度会更高
			Tx.Origin验证
				Solidity中的一个全局变量,它会回溯整个调用栈并返回最初发起这个调用或交易的账户地址
				漏洞
					如果受害者的合约A是通过tx.origin==owner来授权提取余额的
					那攻击者可以编写攻击合约B,诱导受害者调用合约B(如在将合约B伪造成外部账户在社交活动中钓鱼),而实际上合约B调用了合约A,从而将合约A中的余额转入攻击者账户上
				防范技术
					智能合约不应该使用tx.origin来进行验证授权
					Tx.origin的合理用法如:可以用来拒绝外部合约调用当前合约
	合约程序库
		OpenZeppelin系列
		ZeppelinOS
		ethpm
	注意
		公共网络上合约的代码并不是默认公开可见的
		不要重复发明加密算法(不要重复造轮子)

第十章~第十四章

代币 预言机 DApp EVM 共识

学习笔记 思维导图

在这里插入图片描述

附:文本结构

精通以太坊-10~14章
	代币
		使用方式
			数字货币
				通过私下交易的方式确定它的价值
			资源
				来自一个共享经济体或资源分享环境所产出或获取的资源
			资产
				链上或链下,有形或无形的资产
			访问权限
				针对物理资产或数字资产的访问权限
			权益
				数字化组织的股东权益(例如DAO去中心化自治组织)
			投票权
				数字系统或传统组织中的投票权
			收藏品
				数字化收藏品(如CryptoPunks)或真实收藏品(如油画、邮票)
			身份
				数字化身份,或者法律意义上的身份
			证言
				针对某个事实的认证或证言
			Utility
				用于使用或支付某种服务的代币
		可替代性
			可直接兑换货币
		对手方风险
			资产的保有方就是这个额外的对手方风险
				他们是否真正持有这些资产
				他们是否认可这次基于代币形式的交易
		代币和内在性
			区块链内的资产替代区块链外的资产,可以消除对手方风险
		工具还是权益
			工具型代币
				用于支付
			权益型代币
				初创公司股权的代币
		以太坊的代币
			以太币
			自定义新代币
				基于智能合约实现
		代币标准
			ERC20代币标准
				必须函数和事件
					totalSupply
						总发行量
					balanceOf
						余额
					transfer
						转账
					transferFrom
						从其他账户转账,通常与approve一并使用
					approve
						审批
							给一个接收地址授权一次或分次转账不超过对应数量的代币
								类比企业老板授权给采购员
					allowance
						配额
							给定一个持有方和发送方地址,返回发送方还可以从持有方转走的经过审批的代币的余额
					Transfer
						转账事件
							即使转账金额为0也会触发这个事件
					Approval
						审批事件
							成功执行审批后触发的事件
				可选函数
					name
					symbol
					decimals
						位数
							返回代币可以细分的颗粒度
							如:decimals为2,那么可以在用户端显示为100的份数
							同理decimals为-2,就是0.01的份数
							为10的decimals次方
			ERC233
			ERC777
			ERC721
			可使用Truffle框架创建和发行一个属于自己的代币
			自定义代币的转账时通过代币合约内相关的状态转换进行的,使用合约作为地址,而不是接收方的地址
			自定义代币合约应该拒绝接收以太币,防止以太币被“销毁”
		代币接口标准的扩展
			持有人控制
			销毁
			铸币
			众筹
			硬顶
			可恢复性后门
			白名单
			黑名单
		代币和ICO
			今天在以太坊上提供的许多代币几乎是骗局、传销和割韭菜行为
			短期ICO泡沫
	预言机
		是什么
			在区块链的上下文中,预言机是一个可以回答以太坊外部问题的系统
			无信任的系统
			将外部事实带入合约执行
		EVM执行过程必须完全确定,后果
			EVM和智能合约没有内在的随机性来源
			外部数据只能作为交易数据载荷引入
		应用场景
			弥合链外世界与智能合约之间差距的机制
			允许智能合约基于真实世界的事件和数据来强制执行合约关系
		应用示例
			物理随机数源或熵源
				量子现象或热现象
			汇率数据
				让加密货币与法定货币精准挂钩
			与自然灾害相关的参数触发器
				地震里氏震级测量债券
			统计与准统计数据
				安全标识、国家代号、货币代号等
			时间和间隔数据
				基于精准的SI时间度量的事件触发器
			天气数据
				基于天气预报的保险费计算器
			政治事件
				预测市场的走势
			运动事件
				预测市场走势以及体育博彩相关的合约
			以太币市场价格
				gas价格预言机
		设计模式
			关键能力
				从链外的数据源收集数据
				使用签名消息在链上传输数据
				将数据放入智能合约的存储空间,使数据可用
					其他合约可以调用预言机智能合约的“检索”功能访问
					也可以直接查看预言机的存储
			设置预言机的三种主要方式
				请求与响应
					数据空间大的情况下使用
					步骤
						1、接收来自DApp的查询
						2、解析查询
						3、检查是否提供了付款和数据访问权限
						4、从链外数据源检索相关数据
						5、使用包含的数据对事务进行签名
						6、将事务广播到网络
						7、安排任何进一步必要的交易,例如通知等
				发布和订阅
					轮询,推送
						不直接向接收者发送消息
						而是将发布的消息分类到不同的类中
						订阅者能够表达对一个或多个类的兴趣并检索那些感兴趣的消息
					效率低下
						只适合低频改变
				立即读取
					存储在合约存储中
		数据认证
			真实性证明
				TLS传输层安全协议
				TLS可以掌握密钥获取数据后给数据签名,并将数据分配给三方
					服务器(预言机)
					受审单位(Oraclize)
					审计方
				依然要假设亚马逊自己不会篡改虚拟机实例
			可信执行环境
				Town Crier
					使用英特尔的SGX
					保证应用程序在安全区运行时,其状态对其他进程来说,是不可知的
					SGX通过生成应用程序确定在安全区中运行的数字签名,DApp通过验证此数字签名就可以证明
		计算性的预言机
			TrueBit
				可扩展和可验证的链外计算解决方案
			大量计算的任务不可能在区块链上执行,那将花费巨额gas
		去中心化预言机
			以上都是中心化的预言机系统,都需要以来可信的权威,如亚马逊、英特尔
			ChainLink
	去中心化应用
		英文
			Decentralized Application
			简称
				DApp
		构成
			后端软件(应用逻辑)
				智能合约
					被用来存储应用的业务逻辑(程序代码)和相关的状态信息
				主要考虑因素
					合约代码一旦部署,不可修改,只可能被彻底删除
					体量大的合约意味着花费更多的gas,因此一些应用程序会选择链外计算和外部数据源
						依赖外部意味着你的用户必须引入这些外部资源
			前端软件
				客户端界面
					通常是Web前端
						通过web3.js JavaScript库连接到以太坊,该库与前端资源捆绑在一起,并由Web服务的提供给浏览器
					目前没有创建移动端DApp的最佳实践,主要原因是缺少具有密钥管理功能的移动客户端来承担轻客户端的角色
			数据存储
				智能合约不太适合存储和处理大量数据,因此大多数DApp利用链下数据存储服务
				中心化的
					如传统的云端数据库
				去中心化的
					IPFS
						星际文件系统
						特点
							去中心化的
							内容可寻址的存储系统
								意味着内容(文件)的每一个块都被哈希处理,并且这个哈希值可以标识文件
								可以通过这个哈希值在IPFS的任何节点上将文件取回
						目标
							在Web应用程序的分发上取代HTTP协议
								文件可直接在任何IPFS节点被获取
					以太坊自由平台Swarm等
						点对点形式的
						特点
							内容可寻址
							P2P存储系统
						以太坊基金会创建的
						作为Go-Ethereum工具链的一部分
						可以运行前端程序
			消息通信
				去中心化消息通信协议
					Whisper
						以太坊基金会Go-Ethereum工具链的一部分
						可用于创建聊天室
			名词解析
				以太坊名称服务(ENS)
					一种去中心化的方式
					是一个智能合约
					也是一个基础的DApp
				例如,以太坊基金会的捐赠地址是:0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359
					在支持ENS的钱包中,它被简单地表示为:ethreum.eth
				ENS标准
					EIP-137
						规定了ENS的基本功能
					EIP-162
						描述了根.eth的拍卖系统
					EIP-181
						规定了地址的反向注册规则
		优点
			弹性
				只要区块链平台仍在运行,DApp就不会停机
			透明
				任何人都可以对代码进行检查,并审核它的功能
				任何与DApp的交互都会永久地存储在区块链上
			审查阻力
				一旦部署到区块链就不能被任何人修改
				不会受到集中式控制力量的干扰
		DApp的治理
			双刃剑
				特权账户被破坏,DApp的安全性就随之被破坏
				如果没有特权账户,一旦合约出现问题,就没有恢复的余地
			真正的DApp不应该存在能进行特权访问的特权账户
	以太坊虚拟机
		主要任务
			基于以太坊协议、根据智能合约代码的执行来计算合法的状态转换,用以更新以太坊的状态
		用来处理智能合约的部署和执行
		可以被想象成一个全球化的去中心化计算机
		“准”图灵完备的状态机
		基于栈的架构,在一个栈中保存了所有内存数值
		数据处理单位被定义为256位的“字”
		包含以下数据组件
			一个不可变的程序代码存储区ROM,加载了要执行的智能合约字节码
			一个内容可变的内存,它被严格地初始化为全0数值
			一个永久的存储,它是作为以太坊状态的一部分存在的,也会被初始化为全0
		是一个计算引擎,是“单线程”的,没有“系统接口”,没有“硬件支持”
		EVM指令集(字节码)
			算数和位运算逻辑操作
				ADD
				MUL
				MOD
				SHA3
				...
				LT
				GT
				EQ
				AND
				OR
				NOT
				...
			执行上下文查询
			栈、内存和存储访问
				POP
				MLOAD
				MSTORE
				SLOAD
				...
			处理流程操作
				STOP
					停止执行
				JUMP
					将程序计数器设置为任意数值
				JUMPI
					基于条件修改程序计数器的值
				PC
					取得程序计数器的数值
				JUMPDEST
					标记一个有效的跳转地址
			日志、跳转
				LOGx
				CREATE
					用关联代码创建一个新账户
				CALL
					向另一个账户发起消息调用,也就是运行另一个账户的代码
				RETURN
					停止执行并返回输出数据
				...
			环境操作
				处理执行环境信息的操作码
				GAS
					取得可用gas的数量
				ADDRESS
					取得当前账户的地址
				CALLER
					取得当前执行的调用者地址
				...
			区块操作
				BLOCKHASH
					取得最新的256个完整区块中某个区块的哈希
				COINBASE
					取得当前区块的区块奖励受益人地址
				TIMESTAMP
					取得当前区块的时间戳
				NUMBER
				DIFFICULTY
				GASLIMIT
		以太坊状态
			以太坊世界状态
				一个以太坊地址到账户数据的映射
				组成
					一个以太币的余额
						这个账户所持有的以wei为单位的以太币数量
					一个nonce
						EOA
							从这个账户所发出的交易的数量
							一个EOA永远不会有代码,且只有全空的存储
						合约账户
							由它所创建的合约的数量
					账户的存储
						仅供智能合约使用的永久数据存储
					账户的程序代码
						智能合约账户
			gas
				负的gas消耗
					删除一个合约会返还24000gas
					将一个非零值的存储地址设置为0,会返还15000gas
					最大gas返还数量为交易中总共消耗的gas数量的一半(向下舍入)
						避免通过返还机制牟利
				作用
					解决了停机问题
					保护以太坊免受拒绝服务攻击
	共识
		共识算法
			工作量证明PoW
				惩罚是基于外生的电力
			权益证明PoS
				以太坊计划使用的PoS算法叫Casper
				惩罚基于质押的以太币,是内生于区块链的
		工作量证明的通俗表述就是“挖矿”
		目的
			“挖坑”的真实目的是保护区块链的安全,同时保证对系统的控制权是去中心化的
		手段
			把新铸造的货币作为奖励是激励人们为系统安全做贡献的措施
			如果不遵循共识规则来得到区块奖励,那么他们已经在挖矿上花费的电力就有可能血本无归
		原理和假设
			谁能更改历史数据,如何更改呢?
				不可更改性
			谁能确定未来的上链数据,又如何确认呢?
				确定性
			确认数据的时候,要耗费些什么呢?
			确认数据的权力有多去中心化?
			如果某些数据发生了变化,谁会察觉?它们用什么方式察觉?
		争议
			没有完美的共识算法
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值