## 以太坊的賬戶設計
以太坊的賬戶設計,替代了UTXO這一區塊鏈中最為關鍵的對象設計(或者說放棄了UTXO設計),轉而采用一種更簡單的方法:狀態存儲一個賬戶列表,每個賬戶都有余額,以及以太坊特定的數據(代碼和內部存儲),如果發送賬戶有足夠的余額,則交易有效余額來支付它,在這種情況下,發送賬戶被借記,接收賬戶被記入價值。 如果接收帳戶有代碼,則代碼會運行,并且內部存儲也可能會更改,或者代碼甚至可能會向其他帳戶創建額外的消息,從而導致進一步的借記和貸記。
### 以太坊賬戶分類
* 在以太坊中,有兩種類型的賬戶:外部賬戶(EOA,也稱為基本賬戶)和合約賬戶。
* EOA 賬戶可以使用它相互發送以太幣并部署智能合約
* 合約賬戶是部署智能合約時創建的賬戶。
* 每個智能合約都有自己的以太坊賬戶
* 帳戶狀態包含有關以太坊帳戶的信息。 例如,它存儲一個賬戶有多少以太幣以及該賬戶發送的交易數量。 每個帳戶都有一個帳戶狀態。
如果 一下結構中,codeHash 為空,則說明該賬戶是一個簡單的外部賬戶,只存在 nonce 和 balance。
以太坊賬戶包含以下信息:
1. **nonce**
以太坊所有的交易都是基于 account ,不同于基于 utxo 的比特幣,因此需要對每次交易都按順序記錄,nonce值就是這個順序,nonce 是交易原始地址的屬性。它不存儲在以太坊區塊鏈上,而是通過計算從一個地址發送的交易數量來計。
從該地址發送的交易數量(如果當前是 EOA 賬戶)或該賬戶產生的合約創建操作每發起一筆交易,nonce就會加1。對于發起的解釋:
1.外部賬戶(EOA)每發送一筆交易;
2.合約賬戶(Contract Wallet) 每創建一個合約
而轉入交易、合約調用其他合約等屬于內部調用,因此 nonce 值不變。
nonce可以記錄交易順序,同時防止重放攻擊(因為任何人都可以看到這筆交易,然后復制粘貼,重復提交給以太坊的網絡,耗盡你的余額,也就是所謂的重放攻擊)、加速(基于 nonce 的特性,自增和唯一性,使用相同的 nonce 重新發起交易即可實現加速)或取消交易。
**2. balance**
該賬戶擁有的以太幣數量 (單位是 Wei) 。
**3. storageRoot**
storage trie的根節點的hash值,標示合約存儲結構的 MPT 樹根節點 hash 值。僅僅智能合約賬戶不為空。
**4. codeHash**
僅在合約賬戶上該屬性有效,標示合約代碼對應的 Hash 值。
對于合約賬戶,這是存儲 EVM 代碼哈希的賬戶。 對于 EOA 帳戶(基本賬戶),請將此留空。 帳戶狀態中一個不容忽視的細節是,包括上述在內的所有對象都是可變的(codeHash 除外)。 例如,當一個賬戶向其他賬戶發送以太幣時,除了隨機數增加外,該賬戶的余額也會相應變化。 如果部署了易受攻擊的智能合約,codeHash 的不變性使得無法修復和更新該合約。 相應地,只能部署新合約(易受攻擊的版本將始終存在于區塊鏈上)。 這就是為什么有必要使用 Truffle 進行智能合約開發和部署,并在使用 Solidity 編程時遵循最佳實踐(確保智能合約的健壯性)。

### 以太坊賬戶的數據存儲規則
以太坊用 NoSQL 數據庫以 Key-Value 的形式存儲所有的數據。針對賬戶數據結構,需要存儲的數據主要包含智能合約的 Storage 和基本的賬戶信息。對應的存儲規則如下:
1. 針對智能合約 Storage,將數據按照編碼規則映射成 MPT,然后將 MPT 的所有節點的 Key 和 Value 構建一個 RLP List 編碼作為數據庫存儲的 Value 值,將該 Value 值進行 Sha3 計算 hash 值作為數據庫存儲的 Key 值進行存儲。
2. 針對基本賬戶信息,將其對應智能合約 Storage 的 MPT Root Hash 保存于賬戶的 StorageRoot 屬性,然后將系統中的所有 Account 構建一個 MPT。按照和 Storage 的數據庫存儲方式將 MPT 的所有節點進行存儲。
帳戶狀態存儲有關帳戶的信息,例如帳戶有多少以及從該帳戶發送了多少交易。 它有四個字段:nonce、balance、storageRoot 和 codeHash。 **以太坊賬戶狀態信息是世界狀態樹中的葉節點**。
### (智能合約)賬戶存儲樹
Account Storage Trie 是存儲與帳戶關聯的數據的位置。
帳戶存儲樹的根哈希由帳戶狀態存儲。 **每個智能合約帳戶都有一個帳戶存儲樹。**
賬戶存儲樹是保存與智能合約賬戶相關的數據的結構:也就是說賬戶存儲樹僅適用于合約賬戶。在EOA中,storageRoot為空,codeHash為空字符串的哈希值。 所有智能合約數據都以 32 字節的映射形式存儲在賬戶存儲樹中。

- 重要更新說明
- linechain發布
- linechain新版設計
- 引言一
- 引言二
- 引言三
- vs-code設置及開發環境設置
- BoltDB數據庫應用
- 關于Go語言、VS-code的一些Tips
- 區塊鏈的架構
- 網絡通信與區塊鏈
- 單元測試
- 比特幣腳本語言
- 關于區塊鏈的一些概念
- 區塊鏈組件
- 區塊鏈第一版:基本原型
- 區塊鏈第二版:增加工作量證明
- 區塊鏈第三版:持久化
- 區塊鏈第四版:交易
- 區塊鏈第五版:實現錢包
- 區塊鏈第六版:實現UTXO集
- 區塊鏈第七版:網絡
- 階段小結
- 區塊鏈第八版:P2P
- P2P網絡架構
- 區塊鏈網絡層
- P2P區塊鏈最簡體驗
- libp2p建立P2P網絡的關鍵概念
- 區塊鏈結構層設計與實現
- 用戶交互層設計與實現
- 網絡層設計與實現
- 建立節點發現機制
- 向區塊鏈網絡請求區塊信息
- 向區塊鏈網絡發布消息
- 運行區塊鏈
- LineChain
- 系統運行流程
- Multihash
- 區塊鏈網絡的節點發現機制深入探討
- DHT
- Bootstrap
- 連接到所有引導節點
- Advertise
- 搜索其它peers
- 連接到搜到的其它peers
- 區塊鏈網絡的消息訂發布-訂閱機制深入探討
- LineChain:適用于智能合約編程的腳本語言支持
- LineChain:解決分叉問題
- LineChain:多重簽名
- libp2p升級到v0.22版本
- 以太坊基礎
- 重溫以太坊的樹結構
- 世界狀態樹
- (智能合約)賬戶存儲樹
- 交易樹
- 交易收據樹
- 小結
- 以太坊的存儲結構
- 以太坊狀態數據庫
- MPT
- 以太坊POW共識算法
- 智能合約存儲
- Polygon Edge
- block結構
- transaction數據結構
- 數據結構小結
- 關于本區塊鏈的一些說明
- UML工具-PlantUML
- libp2p介紹
- JSON-RPC
- docker制作:啟動多個應用系統
- Dockerfile
- docker-entrypoint.sh
- supervisord.conf
- docker run
- nginx.conf
- docker基礎操作整理
- jupyter計算交互環境
- git技巧一
- git技巧二
- 使用github項目的最佳實踐
- windows下package管理工具