# Ethereum TL;DR ###### tags: `Study` `Blockchain` :::danger 本區討論僅作為本人吸收後的摘要,故只會有大略描述,詳細內容仍得看藍色連結。 ::: --- ## 查詢關鍵字 `MerkleTree` `RLP` `Ethash` `Smart Contract` ## 相關討論 :::success * [x] [Ethereum Light Client](https://blog.ethereum.org/2015/01/10/light-clients-proof-stake/) * [x] [Ethereum Light Client Protocol](https://github.com/ethereum/wiki/wiki/Light-client-protocol) * [x] [Brief of Light Node](https://www.parity.io/what-is-a-light-client/) * [x] [Ethereum Sharding](https://medium.com/@icebearhww/ethereum-sharding-and-finality-65248951f649) * [x] [Web3.js Sign Trasaction](https://web3j.readthedocs.io/en/latest/transactions.html#transaction-signing-via-an-ethereum-client) * [ ] [Casper 101](https://medium.com/@jonchoi/ethereum-casper-101-7a851a4f1eb0) ::: ## 什麼是 Sparse Merkle Tree ? * [稀疏默克爾樹 HackMD](https://hackmd.io/@ofAlpaca/sparseMT) ## Ethereum State Trie 介紹 :::info * https://medium.com/cybermiles/diving-into-ethereums-world-state-c893102030ed * https://hackernoon.com/getting-deep-into-ethereum-how-data-is-stored-in-ethereum-e3f669d96033 ::: * **Merkle Paricia Trie** 是乙太坊 Account 的樹狀結構,每個 Account 都包含了 160-bits 的 address 以及其 value ,包含 : * `nonce` : 此帳號送出交易數量 * `balance` : 帳號餘額 * `storageRoot` : 帳號的儲存空間,給智能合約使用 * `codeHash` : 智能合約的雜奏值 * Account address 則會是 State Trie 的 node :  ## Ethereum Account nonce 可以防止 Replay Attack ? :::info * https://ethereum.stackexchange.com/questions/27432/what-is-nonce-in-ethereum-how-does-it-prevent-double-spending * https://github.com/ethereum/wiki/wiki/Glossary ::: * 為了避免同樣被簽章過的交易被反覆送出,所以需要 nonce 來阻止重送。 * 由某 Account 送出的 transaction 上的 nonce 會和 Account 本身的 nonce 相同,以避免同交易被送數次。 * Transaction nonce 必須是遞增的,在還沒送出 nonce 為 0 和 1 的交易前, nonce 為 2 的交易不會被接受。 * Account nonce 也==可以阻止雙花攻擊==,例如 A 送出交易給 B , B 確認後完成買賣, A 又趁機送出另一筆有較高 gas price 的交易給自己,一般來說,後者會先被上鏈,造成雙花攻擊。 * 當交易有了 nonce ,那麼當 A 發送第二筆交易時,該交易會先等前一筆交易被上鏈後才會上鏈,從而阻止了雙花。 ## Block Gas Limit 與 Transaction Gas Limit 的關係 ? :::info * https://ethereum.stackexchange.com/questions/7359/are-gas-limit-in-transaction-and-block-gas-limit-different * https://hudsonjameson.com/2017-06-27-accounts-transactions-gas-ethereum/ * https://ethereum.stackexchange.com/questions/1106/is-there-a-limit-for-transaction-size ::: * 在[乙太坊黃皮書](https://ethereum.github.io/yellowpaper/paper.pdf)中可以看到 : > The sum of the transaction’s gas limit, $Tg$, and the gas utilised in this block prior, given by $l(BR)u$, must be no greater than the block’s gasLimit, $BH1$. > [name=Ethereum Yellow Paper 6.1.58] * 也就是說,全 block 內的 transaction gasLimit 總和不得超過 block gasLimit 。 * **Block gasLimit** 與 **Transaction gasLimit** 最根本的差別在於前者是由礦工共同決定大小,而後者是發送者自行決定的。 * **gas price** 也是由發送者決定的。 * 礦工能依據上個區塊的 gasLimit 來調整下個區塊的 gasLimit 大小,但只能調整上個區塊 gasLimit 的 1/1024 的比例 ([Mastering Ethereum](https://github.com/ChenPoWei/ethereumbook_zh/blob/master/第十三章.asciidoc#誰來決定區塊gas限制是多少))。 * 礦工可以投票決定 block gasLimit 的大小,例如在全網交易過多時(可能是[DDoS](https://blog.ethereum.org/2016/09/22/transaction-spam-attack-next-steps/)),礦工可以自行降低 gasLimit ,來讓本身處理交易量下降以避免被癱瘓。 ## What's RLP encoding ? :::info * https://github.com/ethereum/wiki/wiki/RLP * http://kimiwublog.blogspot.com/2018/06/ethereum-raw-transaction.html ::: * ==RLP (Recursive-Length Prefix Encoding)== 是 Ethereum 所支援的一種編碼方法。 * 可以將 array structure 的內容編碼程 binary data 。 * 也使用於 Ethereum account 的內容,例如 : `nonce`,`balance`,`storageRoot`,`codeHash` 。 * 以下為基本的編碼方式, wiki 有更詳細的 : * 編碼字元範圍是在 `0x00~0x7f` (也就是不超過 1 byte 的範圍下) ,則其字元本身直接是編碼後的字元。 * `10` 的編碼 --> `0x0a` * 編碼字元範圍是在 `0x80~0xb7` (長度為 0~55 bytes ) ,則其編碼為 `0x80 + [Bytes 長度]` ,其後再接上 String 本身。 * `dog` 的編碼 --> `0x83 + 'dog'` * 編碼字元範圍是在 `0xb8~0xbf` (長度超過 55 bytes) ,則是將 `0xb7` 加上字串長度的的 byte 的長度,再加上字串長度,再加上 String 本身。 * 長度為 1024 bytes 的字串的編碼 --> `0xb9 + 0x04 + 0x00 + string` ## Ethereum 硬分岔 (Hard Fork) 歷史 :::info * https://www.skalex.io/ethereum-constantinople/ * https://medium.com/mycrypto/ethereum-constantinople-everything-you-need-to-know-a47f3a16f3d2 :::  ## Smart Contract 的 Tranasction v.s. Internal Transaction :::info * https://ethereum.stackexchange.com/questions/6429/normal-transactions-vs-internal-transactions-in-etherscan * https://ethereum.stackexchange.com/questions/27441/is-transfer-a-transaction-or-a-call-message :::  * 從 Externally Owned Account (EOA) 發起的交易都為一般 Transaction ,這些交易是被簽章後,再紀錄到區塊鏈上。 * 可以是從 EOA 到 EOA ,或是 EOA 到 Contract Account 。 * Internal Transaction 又稱為 **internal-message-call** ,這些交易並不算是真正的交易,都是由 Contract Account 發起。 * 這些 Internal Transaction 不會記錄到區塊鏈上。 * 智能合約不會對這些交易做簽章。 * 在 [Etherscan](https://etherscan.io/txsInternal) 上可以看到 Internal Transaction 是因為 Etherscan 有額外去記載,區塊鏈本身並沒有紀錄。 * 問題是如果合約無法自行發出交易,那參與者每次都要自己呼叫合約才可以和他互動嗎 ? * 可以透過 Dapp 的前端網頁來負責呼叫合約。 ### 使用 [Dice2Win](https://dice2.win/) Dapp 說明執行過程 * 此 DAPP 簡單來說是個賭博遊戲,玩家壓注 Ether 至 Jackpot 後再等新的區塊 hash 來做為隨機數抽籤決定贏家。 * 下圖是玩家 (`0x8f1f...`) 壓注 0.05 Ether 至 Dice2Win 合約 (`0xd1ce...`),這裡都算是一般交易。  * 下圖是當結果出爐, Dice2Win 的前端帳號 (`0x0000...`) 呼叫合約 (`0xd1ce...`) ,合約根據程式將獎金 ( 1 wei ) 轉給贏家帳號 (`0x8f15...`),從前端帳號到合約的交易為 Transaction 。  * 因為從合約至贏家帳號的交易為合約本身產生的,股為 Internal Transaction 。  ## Contract Account 怎麼來的 ? :::info * https://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed/761#761 ::: * Contract account 是透過發布者 (sender) 的 address 和其 nonce 一起做 RLP 編碼後再做 keccak-256 雜湊取前 20 bytes 所得來的。 * ==合約位址與內容無關==,因此把同一份合約放到不同的 testnet 上也會有不同的合約位址。 ## 傳送至 Smart Contract 的交易 data field 構造 :::info * https://programtheblockchain.com/posts/2018/07/25/anatomy-of-transaction-data/ * https://programtheblockchain.com/posts/2017/12/29/how-ethereum-transactions-work/ ::: * 送給合約的交易中的 `data` 欄位可以拆分為 `function selector` 和 `arguments` 。 * `function selector` 用於選擇合約中的函式,例如 `transfer(address)` 的函式被 **Keccak-256 (SHA-3)** 雜湊後為 `0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b` ,而 `0xa9059cbb` 就成了其 `function selector` 。 (省略 return 和 parameter name) * 剩下的 `arguments` 部分則以每 32-bytes 為單位連接在 `function selector` 後面。 * 要送給合約的內容 `transfer(0x123456789a1234567989a123456789a123456789a)` 就會被編碼為 `0xa9059cbb000000000000123456789a123456789a123456789a123456798a` 。 ## Ethash 運作原理 :::info * https://www.vijaypradeep.com/blog/2017-04-28-ethereums-memory-hardness-explained/ ::: * **Ethash** 是使用==對記憶體存取的限制==來防止礦機的。 * 和一般的 PoW 一樣,都是要透過調整 nonce 來找到小於等於 Target 的雜湊值。 * **Ethash** 步驟如下 : 1. 先透過一個 `seed` 在記憶體內產生一組偽隨機的 DAG dataset,其大小約為 2GB ,會隨區塊鏈成長而變大。 2. 將最後區塊的 hash 與目前的nonce 做 SHA-3 的雜湊,得到一個 128 Bytes 的 `Mix 0` 。 3. 將 `Mix 0` 與 DAG 中相對應的 128 Bytes 的 Page 取出做計算。 4. 兩者計算後會產生 `Mix 1` ,重複第 2、3 步驟,直到 `Mix 64` 出現。 5. 將 `Mix 64` 再產生一個較短 32 Bytes 的 `Mix Digest` 。 6. 把 `Mix Digest` 與 Target 做比較,如果小於等於 Target ,則代表目前 nonce 就是解答;否則選擇另一個 nonce 再重頭計算。  ## Fraud Proof & Data availability :::info * https://hackernoon.com/fraud-proofs-secure-on-chain-scalability-f96779574df * https://medium.com/taipei-ethereum-meetup/fraud-and-data-availability-proofs-aa333688afc6 * [Original paper](https://arxiv.org/abs/1809.09044) ::: * **Fraud Proof** : light node 在接收到新的區塊後,如果在一定時間內沒有收到其他人的 fraud proof ,則會直接認定該區塊為合法。 * Light node 會去對數個 full node 做請求來確認收到的新 block 是正確的。 * **Validaion Proof** : light node 需要收集所需的交易資訊來重組回 root hash ,較費資源但更安全。 * **Data availability problem** 是指說如果挖出區塊的礦工只提供 header 而非 data ,那將無法確認該區塊是錯誤的。 * 就算有 99% 的 block data 是 available 的,但只要有 1% 是 unavailable 的,那就不能證明他是錯的。 * Vitalik 使用糾刪碼 (Erasure Code) 來解決這問題,使用 Reed-Solomon codes ,可以透過 M-out-of-N 個區段重組回原本的 data ,進而避免資料遺失或是蓄意不給的問題。 ## Sharding vs Plasma :::info * https://vitalik.ca/general/2019/06/12/plasma_vs_sharding.html ::: * Sharding 與 Plasma 兩者都是透過一條 "Parent chain" 與數條的 "Child chains" 來提升整體系統的擴展性 (Scalability) 。 * 同樣都是透過週期性的把子鏈的 hash 上傳至父鏈的方式來驗證。 * 兩者皆為由 Vitalik 提出的以太坊擴容方案。 * Sharding 與 Plasma 最大的差異在於前者具有 ==緊耦合(Tight coupling)== 的特性。 * **緊耦合**指的是子鏈與父鏈緊緊相關聯,雙方的驗證過程是不可分開的,換句話說,如果父鏈區塊包含了不合法的子鏈區塊,則其父鏈區塊也會跟著被視為不合法。 * Plamsa 則是父鏈與子鏈可以分開,子鏈若發生意外,並不會影響父鏈;對父鏈而言,子鏈的週期性 hash 驗證只不過是資料而已。 | Type | Property | | -------- | -------- | | Sharding | Try really hard to ensure total validity/availability of every part of the system| |Plasma | Accept local faults but try to limit their consequences| ## Ethereum State Tree Pruning :::info * https://blog.ethereum.org/2015/06/26/state-tree-pruning/ ::: * Vitalik 有提出區塊鏈資料修剪 (State Tree Pruning) 的方式,主要是針對 Account-based 的區塊鏈系統,也就是 Ethereum 。 * 以太坊的區塊頭會存有三棵樹的 Root Hash ,分別是 StateRoot、TransactionRoot、ReceiptsRoot。而 Pruning 主要是縮減 StateRoot 底下的節點。 * 世界狀態樹 (World State Tree) 為了避免每個區塊都存放一整顆狀態樹,所以只有新增或修改後的節點會記載在新的區塊,其餘尚未被動到的節點則會參照前一個區塊,結果如下圖。 (***註:此處節點指的是「樹」結構裡的節點,並非網路上的 peers***) * 當 Account 175 底下的資料 27 被修改為 45 後,新的區塊會產生新的節點存放 45 這筆資料,但是其他未被動到的子樹則會透過參照接回去。  * 一旦舊區塊裡狀態樹上的節點沒有被其他人所參照時,就會被列入 Death Row ,當 Death Row 存放 N 個區塊後, Death Row 就會被刪除,以節省區塊鏈的儲存成本。 * 見下圖,假如 Block 175223 要被 pruning ,則會刪除那些已經沒有被參照到的節點,並保留那些還有被參照到的子數。  ## 什麼是 Ethereum Raiden Network ? :::info * https://medium.com/taipei-ethereum-meetup/raiden-network-ethereum-區塊鏈支付通道-c44cea954e9b * https://medium.com/raiden-network/the-raiden-network-token-model-9b6ef8d0b64 ::: * 雷電網路 (Raiden Network) 是以太坊的一種鏈下 (Off-chain) 擴容方案,主要目的為增加交易速度、降低費用、提升隱私,可以使整體網路的吞吐量增加,便免網路壅塞。 * 其運作原理是使用**智能合約** (ERC-20 token) 來做為交易雙方的橋樑,事先雙方儲值 token 至合約,開啟 Channel 後來處理雙方批次的交易,當關閉 Channel 時,可以上傳雙方最後餘額來確認最後結果。 * 虛線下方為 Raiden Network 的鏈下交易過程。 * 當批次交易結束時,會把最後餘額的交易結果上傳回以太坊。  * 維護 Raiden Network 的是其專屬的節點,並非以太坊上的礦工。 * Raiden Network Node 也有分 full node 與 light node。 * Full node 需要同時運行 Raiden Network Node 與 Ethereum Node,為了能把最後結果送上以太坊區塊鏈。 * Light node 則是會向 full node 發送交易,但也會被 full node 要求手續費。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up