天天看點

區塊鍊/以太坊/讀書筆記/精通以太坊思維導圖

第一章~第三章

學習筆記 思維導圖

區塊鍊/以太坊/讀書筆記/精通以太坊思維導圖

附:文本結構

精通以太坊-基礎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
				懲罰基于質押的以太币,是内生于區塊鍊的
		工作量證明的通俗表述就是“挖礦”
		目的
			“挖坑”的真實目的是保護區塊鍊的安全,同時保證對系統的控制權是去中心化的
		手段
			把新鑄造的貨币作為獎勵是激勵人們為系統安全做貢獻的措施
			如果不遵循共識規則來得到區塊獎勵,那麼他們已經在挖礦上花費的電力就有可能血本無歸
		原理和假設
			誰能更改曆史資料,如何更改呢?
				不可更改性
			誰能确定未來的上鍊資料,又如何确認呢?
				确定性
			确認資料的時候,要耗費些什麼呢?
			确認資料的權力有多去中心化?
			如果某些資料發生了變化,誰會察覺?它們用什麼方式察覺?
		争議
			沒有完美的共識算法
           

繼續閱讀