## 以太坊的账户设计
以太坊的账户设计,替代了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 编程时遵循最佳实践(确保智能合约的健壮性)。
![](https://img.kancloud.cn/ac/a3/aca3cd6370ab81cf976e3bf09927fc01_2402x658.png)
### 以太坊账户的数据存储规则
以太坊用 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 字节的映射形式存储在账户存储树中。
![](https://img.kancloud.cn/d9/15/d915d18813785a490fb55e32a7a8b71c_1217x549.png)
- 重要更新说明
- 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管理工具