web3区块链-ETH以太坊
一. 以太坊概述
以太坊(Ethereum)作为区块链技术的代表性项目之一,自2015年发布以来,迅速成为全球区块链行业的核心基础设施。相比比特币,以太坊不仅支持点对点的价值转移,还引入了智能合约,使其能够承载更加丰富的去中心化应用(DApps)。本文将从以太坊的基本概念、核心原理、技术架构、工作机制及其应用场景等方面展开全面探讨,帮助读者深入理解以太坊的技术优势和实际价值。
一、以太坊的概念
1.1 以太坊是什么?
以太坊是一个开源的区块链平台,旨在为开发者提供去中心化应用开发的环境。与比特币不同,除了提供点对点的加密货币交易功能外,以太坊还内置了一种编程语言(Solidity),可以用于编写智能合约,从而实现自动化的业务逻辑执行。
1.2 以太坊的核心目标
- 去中心化:提供一个无需第三方中介的交易和应用平台。
- 不可篡改:确保数据一旦上链无法被篡改。
- 高效透明:通过智能合约自动执行业务逻辑,减少人为干预,提高效率。
- 支持DApp开发:为开发者提供工具和环境,构建各类去中心化应用。
1.3 以太坊的基础组件
- 以太币(Ether,ETH):以太坊网络的原生加密货币,用于支付交易手续费和智能合约的执行成本。
- 智能合约:一段存储在以太坊区块链上的代码,可以自动执行特定条件下的预设逻辑。
- 虚拟机(EVM):以太坊虚拟机是智能合约运行的核心环境,为开发者提供了一个沙箱式的代码执行环境。
二、以太坊的技术原理
对比比特币的 “UTXO” 余额模型,以太坊使用“账户”余额模型。 以太坊丰富了账户内容,除余额外还能自定义存放任意多数据。 并利用账户数据的可维护性,构建智能合约账户。
实际上以太坊是为了实现智能合约而提炼的账户模型。 以账户为单位,安全隔离数据。 账户间信息相互独立,互不干扰。 再配合以太坊虚拟机,让智能合约沙盒运行。
以太坊作为智能合约操作平台,将账户划分为两类:外部账户(EOAs)和合约账户(contract account)。
2.1 账户模型
以太坊采用账户模型,而比特币采用UTXO模型。以太坊的账户模型包含两种类型:
外部账户(Externally Owned Account, EOA):
类似于BTC系统中公私钥对
是由我们通过私钥创建的账户。 是真实世界的金融账户的映射,拥有该账户私钥的任何人都可以控制该账户。 如同银行卡,到ATM机取款时只需要密码输入正确即可交易。 这也是人类与以太坊账本沟通的唯一媒介,因为以太坊中的交易需要签名, 而只能使用拥有私有外部账户签名。
合约账户特点总结:
- 拥有以太余额。
- 能发送交易,包括转账和执行合约代码。
- 被私钥控制。
- 没有相关的可执行代码。
合约账户(Contract Account, CA):
合约账户则是含有合约代码的账户。 被外部账户或者合约创建,合约在创建时被自动分配到一个账户地址, 用于存储合约代码以及合约部署或执行过程中产生的存储数据。 合约账户地址是通过SHA3哈希算法产生,而非私钥。 因无私钥,因此无人可以拿合约账户当做外部账户使用。 只能通过外部账户来驱动合约执行合约代码。
不是通过公私钥对控制。(不能主动发起交易,以太坊规定所有的交易只能有外部账户才能发起,一个合约账户在接收到外部账户调用后才能发起交易或调用其他合约账户)其除了balance和nonce之外还有code(代码)、storage(相关状态-存储)。
合约账户特点总结:
- 拥有以太余额。
- 有相关的可执行代码(合约代码)。
- 合约代码能够被交易或者其他合约消息调用。
- 合约代码被执行时可再调用其他合约代码。
- 合约代码被执行时可执行复杂运算,可永久地改变合约内部的数据存储。
差异对比
综上,下面表格列出两类账户差异,合约账户更优于外部账户。 但外部账户是人们和以太坊沟通的唯一媒介,和合约账户相辅相成。
比较项 | 外部账户 | 合约账户 |
---|---|---|
私钥 private Key | 有 | 无 |
余额 balance | 有 | 有 |
代码 code | 无 | 有 |
多重签名 | 无 | 有 |
控制方式 | 私钥控制 | 通过外部账户执行合约 |
上面有列出多重签名,是因为以太坊外部账户只由一个独立私钥创建,无法进行多签。 但合约具有可编程性,可编写符合多重签名的逻辑,实现一个支持多签的账户。
如何调用一个合约账户?
创建合约账户的时候会返回一个地址,知道这个合约的地址就可以对其调用。调用过程中,代码不变但状态会发生改变。
为什么要做以太坊,更换为基于账户的模型而不是沿袭BTC系统?
比特币中支持每次更换账户,但以太坊是为了支持智能合约,而合约签订双方是需要明确且较少变化的。尤其是对于合约账户来说,需要保持账户的稳定状态。
二、帐户创建
2.1 外部账户创建
当你想要创建一个帐户时,大多数库将生成一个随机的私钥。
私钥由 64 个十六进制字符组成,可以用密码加密保存。
例如:
fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036415f
使用椭圆曲线数字签名算法从私钥生成公钥。 通过获取公钥 Keccak-256 哈希的最后 20 个字节并校验码前面添加 0x,可以为帐户获取公共地址。
// PubkeyToAddress 公钥转地址方法
func (p *PublicKey) ToAddress() Address {
pubBytes := p.FromECDSAPub()
i := sha3.Keccak256(pubBytes[1:])[12:]
return BytesToAddress(i)
}
地址具体生成细节可参考: 以太坊地址生成
下面是使用 GETH 的 personal_newAccount 在控制台中创建一个帐户的例子
> personal.newAccount()
Passphrase: 输入账户密码
Repeat passphrase: 再次输入账户密码
"0x0dd26b4f63f9362314b708816a6aa18a04442679" 得到账户地址> personal.newAccount(123456)
"0x5942bd5c577b569e27dd789b50b7d8824fe399ea"
geth指令详情可查看geth文档
2.2 合约账户创建
下面是合约地址生成算法:Keccak256(rlp([sender,nonce])[12:]
// https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go
func CreateAddress(b common.Address, nonce uint64) common.Address {
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
return common.BytesToAddress(Keccak256(data)[12:])
}
因为合约由其他账户创建,因此将创建者地址和该交易的随机数进行哈希后截取部分生成。
特别需要注意的是,在EIP1014中提出的另一种生成合约地址的算法。 其目的是为状态通道提供便利,通过确定内容输出稳定的合约地址。 在部署合约前就可以知道确切的合约地址。下面是算法方法:
keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]。
// https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}
三、账户数据结构
3.1 账户状态
账户的状态(Acccount State)描述了一个账户当前的情况。以太坊公链时时刻刻跟踪并维护着每一个账户的状态。 一个账户在初次接收或者发出交易后,都会形成初始状态。随着时间的推移,每次针对该账户的交易将不断修改其状态。
注:总结而言,每一个账户在数据结构上具有两个元素:一个公开地址,一个与该地址关联的状态。
在程序逻辑上两类账户的数据结构一致,包含四大元素:
- nonce:已执行交易总数,用来标示该账户发出的交易数量;
- balance:持币数量,记录用户的以太币余额;
- storageRoot hash:存储区的哈希值,指向智能合约账户的存储数据区;
- code hash:代码区的哈希值,指向智能合约账户存储的智能合约代码。
//github.com/ethereum/go-ethereum/core/types/account.gotype Account struct {
Nonce uint64
Balance *big.Int
Root common.Hash
CodeHash []byte
}
以太坊数据以账户为单位组织,账户数据的变更引起账户状态变化。 从而引起以太坊状态变化。
以太坊状态数据:
基于状态机模型,以太坊网络已变成一个依靠矿工维护的去中心化的大型状态机。在任意时刻,只会处于一个状态中,全世界唯一的状态。我们把这个状态机,称之为以太坊世界状态,代表着以太坊网络的全局状态。
世界状态(state)
由无数的账户信息组成,每个账户均存在一个唯一的账户信息。账户信息中存储着账户余额、Nonce、合约哈希、账户状态等内容,每个账户信息通过账户地址影射。 从创世状态开始,随着将交易作为输入信息,在预设协议标准(条件)下将世界态推进到下一个新的状态中。
世界状态中存储了哪些内容:
首先,以太坊中有两种级别的状态,一个是顶级的世界状态,另一个是账户级的账户状态。账户状态中存储账户信息:
- nonce: 这个值等于由此账户发出的交易数量,或者由这个账户所创建的合约数量(当这个账户有关联代码时)。
- balance: 表示这个账户账户余额。
- storageRoot: 表示保存了账户存储内容的 MPT 树的根节点的哈希值。
- codeHash: 表示账户的 EVM 代码哈希值,当这个地址接收到一个消息调用时,这些代码会被执行; 它和其它字段不同,创建后不可更改。如果 codeHash 为空,则说明该账户是一个简单的外部账户,只存在 nonce 和 balance。
在程序逻辑上两类账户的数据结构一致:
//github.com/ethereum/go-ethereum/core/types/account.gotype Account struct {
Nonce uint64
Balance *big.Int
Root common.Hash
CodeHash []byte
}
但在数据存储上稍有不同, 因为外部账户无内部存储数据和合约代码,因此外部账户数据中 StateRootHash 和 CodeHash 是一个空默认值。 一旦属于空默认值,则不会存储对应物理数据库中。 在程序逻辑上,存在code则为合约账户。 即 CodeHash 为空值时,账户是一个外部账户,否则是合约账户。
关于nonce,解决重放攻击,重放攻击解释:
A向B转账,过一段时间,B将A的交易重新广播一次,从而导致A账户被扣钱两次。假设A给B转钱,双花攻击(double spending attack)是A不诚实,重放攻击(replay attack)是B不诚实。
为了防范重放攻击,给账户交易添加计数器记录该账户有史以来发布过多少次交易,转账时候将转账次数计入交易的内容中。
如果此时如果B重放了这个交易,那么当前A的nonce至少是大于等于21,那么显然与下一笔合法交易要比当前nonce+1不再满足了!!
系统中全节点维护账户余额和该计数器的交易数,从而防止本地篡改余额或进行重放攻击。
3.2 账户状态结构
四. 以太坊的状态树
4.1 账户状态的数据结构
以太坊采用基于账户的模式,系统中显式记录每个账户的余额。我们要完成的是从账户地址到账户状态的映射,addr-->state。
在以太坊中,账户地址为160位,表示为40个16进制数;状态包含了余额(balance)、交易次数(nonce),合约账户中还包含了code(代码)、存储(stroge)。
需要记住的是,在BTC和以太坊中,交易保存在区块内部,一个区块可以包含多个交易。通过区块构成区块链,而非交易。
直观地来看,其本质上为Key-value键值对,直接可以查询每个账户的状态,所以直观想法便用哈希表实现。若不考虑哈希碰撞,查询直接为常数级别的查询效率。但采用哈希表,难以提供Merkle proof。
例如:跟一个人签合同,希望他证明他的账户余额有多少钱
- 一种方法是像BTC中,将哈希表的内容组织为Merkle Tree
- 将哈希表的元素组织成一个Merkle Tree,算出根哈希值,并保存在blockheader中,只要保证根哈希值不变就能保证内容不变。
- 但当新区块发布,哈希表内容会改变,再次将其组织为新的Merkle Tree,如果这样,每当产生新区块(ETH中新区块产生时间为10s左右),都要重新组织Merkle Tree,很明显这是不现实的,代价太大。
- 而在区块链中没有这个缺点,因为比特币系统中没有账户概念,交易由区块管理,每个Merkle Tree包含着一个区块的所有交易,每一个区块对应一个Merkle Tree,一旦发布就不会再改了,所以Merkle Tree不是无限增大的。而ETH中,将账户信息组织成Merkle Tree,很明显其会越来越庞大。
- 第二种方法是不要哈希表了,直接使用Merkle Tree组织账户信息,每次修改只需要修改其中一部分即可
- 实际中,Merkle Tree并未提供一个高效的查找和更新的方案。
- 此外,将所有账户构建为一个大的Merkle Tree,为了保证所有节点的一致性和查找速度,必须进行排序,如果不排序,得到的Merkle Tree可能不一样。
- 为什么区块链没有这个缺点。在区块链中每个人组织的块里的交易顺序是不一样的,但是有决定权的只有有记账权的那个人,所以顺序一不一样无所谓。
- 第三种方法,经过排序,使用Sorted Merkle Tree可以吗?
- 新增账户,由于其地址随机,插入Merkle Tree时候很大可能在Tree中间,发现其必须进行重构,所以Sorted Merkle Tree插入、删除(实际上可以不删除)的代价太大。
- 而且其实创建账户没必要让别人知道,只有状态改变才需要让别人知道
既然哈希表和 Merkle Tree都不可以,实际中以太坊采取的数据结构:MPT(Merkle Patricia trie)
4.2 trie(字典树、前缀树)
先了解一个简单的数据结构trie
如下为一个通过5个单词组成的trie数据结构(只画出key,未画出value)
特点:
- trie中每个节点的分支数目取决于Key值中每个元素的取值范围(图中最多26个英文字母分叉+一个结束标志位)。以太坊中分支数目是17(16进制加一个结束标志位)
- trie查找效率取决于key的长度。实际应用中(以太坊地址长度为40)
- 理论上哈希会出现碰撞,而trie上面不会发生碰撞。
- 给定输入,无论如何顺序插入,构造的trie都是一样的。
- 更新操作局部性较好
缺点:
- trie的存储浪费。很多节点只存储一个key,但其“儿子”只有一个,过于浪费。因此,为了解决这一问题,我们引入Patricia tree/trie
4.3 Patricia tree/trie
Patricia trie就是进行了路径压缩的trie。
压缩后好处是树的高度缩短,这样访问内存的次数大大减少,效率变高。
需要注意的是,如果新插入单词,原本压缩的路径可能需要扩展开来。那么,需要考虑什么情况下路径压缩效果较好?树中插入的键值分布较为稀疏的情况下,可见路径压缩效果较好。
在以太坊系统中,160位的地址存在2^160 种,该数实际上已经非常大了,和账户数目相比,可以认为地址这一键值非常稀疏。
因此,我们可以在以太坊账户管理种使用Patricia tree这一数据结构。
但实际上,在以太坊种使用的并非简单的PT(Patricia tree),而是MPT(Merkle Patricia tree)。
4.4 Merkle Tree (克尔树)和 Binary Tree(二叉树)
区块链和链表的区别在于区块链使用哈希指针,链表使用普通指针。同样,Merkle Tree 相比 Binary Tree,也是普通指针换成了哈希指针。
所以,以太坊系统中可如此,将所有账户状态组织为一个Patricia tree,用路径压缩提高效率,将普通指针换成了哈希指针,就可以计算出一个根哈希值,这个根哈希值存储于block header中。
根哈希值的作用:
- 第一:防止篡改,只要根哈希值不变,所有账户的状态也不变。
- 第二:提供Merkle Proof,可以证明账户余额,轻节点进行验证
- 第三,证明某个发生了交易的账户是否存在,也就是证明某个键值是否存在。
4.5 MPT(Modified Patricia tree)
以太坊中针对原生版的MPT(Merkle Patricia tree)进行了修改,我们称其为MPT(Modified Patricia tree)
下图为以太坊中使用的MPT结构示意图。右上角表示四个账户(为了直观,账户地址显示较短)和其状态(只显示账户余额)。
树中的节点分为三种,第一个是Extension Node,当发生了路径压缩就会有;第二个节点是Leaf Node,表示叶子节点,是最后的;第三个是Branch Node,表示分支节点。还有一个根节点,取哈希得到根哈希值,写入块头。
需要注意这里的指针都是哈希指针,普通指针里面存的是下一个节点的地址,而这里的哈希指针存的是下面节点的哈希值。
每次发布新区块,状态树中部分节点状态会改变,但改变并非在原地修改,而是新建一些分支,原本状态是保留的。
如下图中,仅仅有新发生改变的节点才需要修改,其他未修改节点直接指向前一个区块中的对应节点。
所以,系统中全节点并非维护一棵MPT,而是每次发布新区块都要新建MPT,只不过大部分节点共享,只有少数发生变化的节点是要新建分支的。
为什么要保存原本状态?为何不直接修改?
为了便于回滚。如下1中产生分叉,而后上面节点胜出,变为2中状态。那么,下面节点中状态的修改便需要进行回滚。
以太坊中有智能合约,理论上能实现很复杂的功能,如果不保存历史状态,智能合约执行完后,想推算出以前的状态是不可能的,因此,需要维护这些历史记录。
4.6 以太坊中代码的数据结构
block header 中的数据结构
arentHash是前一区块块头的哈希值。Coinbase挖出区块的矿工的地址。
三棵树:状态数、交易树、收据树
Difficulty也需要根据需要修改
Nouce挖矿中需要猜的随机数
区块结构
区块在网上真正发布时的信息
状态树中保存Key-value对,key就是地址,而value状态通过RLP (Recursive Length Prefix,一种进行序列化的方法,特点是很简单) 编码序列号之后再进行存储。
五.交易树和状态树
每次发布区块,区块中的交易会组织成一棵交易树,也是一棵Merkle tree与比特币类似
每个交易执行完之后会产生一个收据,记录交易的相关信息,交易树和收据树的结点是一一对应的。
由于以太坊智能合约执行较为复杂,通过增加收据树,便于快速查询执行结果。
数据结构
交易树和收据树都是MPT,而BTC中都采用普通的MT,MPT的好处是支持查找操作,通过键值沿着树进行查找即可。对于状态树,查找键值为账户地址;对于交易树和收据树,查找键值为交易在发布的区块中的序号,序号由发布区块的结点决定。
交易树和收据树只把当前发布区块的交易组织起来,而状态树是把系统中所有账户的状态包含进去,无论这些账户是否与当前区块中交易有关系。多个区块状态树共享节点,只会为更改了状态的结点新建一个分支,而交易树和收据树依照区块独立。
交易树和收据树的作用
- 提供Merkle proof
- 更加复杂的查找操作(例如:查找过去十天与某个智能合约有关的交易;过去十天的众筹事件等)
Bloom filter
支持较为高效地查找某个元素是否在某个比较大的集合中
最笨:元素遍历,复杂度为O(n),且轻节点没有存储交易列表不能使用
Bloom filter的思想:给一个大的集合,计算出一个非常紧凑的“摘要”
例:如下图,给定一个数据集,其中含有元素a、b、c,通过一个哈希函数H()对其进行计算,将其映射到一个初始全为0的向量的某个位置,将该位置置为1。将所有元素处理完,就可以得到一个向量,则称该向量为原集合的“摘要”。可见该“摘要”比原集合是要小很多的。
假定想要查询一个元素d是否在集合中,假设H(d)映射到向量中的位置处值为0,说明d一定不在集合中;假设H(d)映射到向量中的位置处为1,有可能集合中确实有d,也有可能因为哈希碰撞产生误报。
Bloom filter特点:有可能出现误报,但不会出现漏报。
Bloom filter变种:采用一组哈希函数进行向量映射,有效避免哈希碰撞
Bloom filter不支持删除操作,有产生碰撞的可能
ETH中的Bloom filter
每个交易完成后会产生一个收据,收据中会包含一个Bloom filter,记录这个交易的类型、地址等其他信息,在发布的区块的block header中也包含一个总的Bloom filter,其为该区块中所有交易的Bloom filter的一个并集。
要查找过去十天发生的与智能合约相关的所有交易
查找时候先查找哪个块头中的Bloom filter有要查找的交易类型,如果块头中没有,则这个区块就不是我们要找的,如果块头有的话,我们继续查找这个区块所包含的交易的收据树中的Bloom filter,如果存在,再查看交易进行确认;如果不存在,则说明发生了“碰撞”。
好处:通过Bloom filter这样一个结构,快速大量过滤掉大量无关区块,从而提高了查找效率。
补充
以太坊的运行过程,可以视为交易驱动的状态机,状态机的状态是状态树的内容,交易是每次发布的区块所包含的交易,通过执行当前区块中包含的交易,驱动系统从当前状态转移到下一状态。BTC我们也可以视为交易驱动的状态机,其状态为UTXO。问题1:A转账到B,有没有可能收款账户不包含再状态树中?
可能。因为以太坊中账户可以节点自己产生,不需要通知其他人,只有在产生交易时才会被系统知道,此时在状态树中会新插入一个结点。
问题2:可否将每个区块中状态树更改为只包含和区块中交易相关的账户状态?(大幅削减状态树大小,且和交易树、收据树保持一致)
不能。首先,这样设计要查找账户状态很不方便,因为不存在某个区块包含所有状态,在转账的时候因为要查找相关账户的状态信息,需要从区块依次往前查找这个账户的信息,如果这个账户很久没有参与交易的话会需要往前查找很多区块,其次,如果要向一个新创建账户转账,因为需要知道收款账户的状态,才能给其添加金额,但由于其是新创建的账户,所以需要一直找到创世纪块发现根本不存在这个账户,才能知道该账户为新建账户,系统中并未存储。
代码中的具体数据结构
创建交易树和收据树
求根哈希值
Trie的数据结构
Receipt的数据结构
区块头的数据结构
生成Bloom filter
查询Bloom filter中是否包含topic
六.权益证明
概念
PoS(Proof-of-Stake,权益证明) 是一种用于区块链网络的共识算法,它作为 Proof-of-Work(PoW,工作量证明) 的替代方案而出现,目的在于提升能源效率与安全性。在 PoS 中,节点的记账权(即产生新区块的权利)并不是通过计算能力竞争获得的,而是根据其在网络中持有的代币数量及质押时间来分配。
基本原理
质押(Staking):
- 用户将自己持有的代币锁定(质押)在网络中作为保证金。
- 质押越多,获得验证资格和奖励的机会就越大。
选出区块提议者(Proposer):
- 系统根据质押比例、随机性等因素选出一名节点来“提议”新区块。
验证与投票:
- 其他持币人或验证节点对新区块进行投票,达成共识。
- 一旦多数验证者同意,新区块即被添加到区块链上。
奖励与惩罚:
- 成功打包新区块的验证者会获得区块奖励。
- 恶意节点(如双重签名)将被罚没质押,称为“slashing”。
优点
优点 | 描述 |
节能环保 | 不需要大量计算资源,能耗远低于 PoW |
成本门槛低 | 不需购买昂贵的挖矿设备,只需质押代币 |
更快确认 | 出块速度较快,交易确认时间更短 |
经济安全性 | 惩罚机制让作恶成本高昂,激励诚实行为 |
缺点
缺点 | 描述 |
富者更富效应 | 拥有大量代币者更容易当选,进一步获得奖励 |
长程攻击风险 | 恶意节点可在过去历史上“重建链” |
Nothing-at-Stake | 验证者可能在多个分叉上签名,不承担太多风险 |
中心化风险 | 质押池或大型验证节点可能垄断权力 |
以太坊正式从工作量证明(PoW) 转向权益证明(PoS) 的时间是 2022年9月15日,这一重大升级被称为 “合并”(The Merge)。以下是关键细节:
⏰ 1. 具体时间点
-
2022年9月15日世界标准时间(UTC)06:42:42,以太坊主网达到预设的终端总难度(TTD)58,750,000,000T,触发了合并过程。
-
合并后,以太坊的原PoW主网与PoS信标链(Beacon Chain)完全整合,区块生成和验证正式由矿工移交至验证者(Validators)。
💡 2. 合并的意义与核心变化
-
能源消耗降低99.95%:PoS机制无需矿工进行算力竞争,大幅减少电力需求。
-
ETH发行量减少90%:合并后每日ETH发行量从约13,000枚降至约1,600枚,通缩压力增强。
-
安全性提升:攻击成本显著增加,需控制全网2/3质押的ETH才可能篡改最终确定的交易。
🔧 3. 合并的背景与延迟
-
以太坊PoS升级计划最早可追溯至2020年(信标链上线),但主网合并多次推迟。原定2022年6月的日期因测试未完成延至9月。
-
关键测试包括影子分叉(模拟主网合并)和Bellatrix升级(9月6日激活共识层准备),最终确保合并平稳进行。
⚙️ 4. 后续影响
-
矿工退出:PoW挖矿被淘汰,部分矿工转向以太坊经典(ETC)或支持分叉链ETHW56。
-
生态升级基础:合并为以太坊后续扩容方案(如分片技术Danksharding)奠定基础,提升交易处理能力
七.以太坊智能合约
以太坊中的智能合约(Smart Contract) 是一种运行在区块链上的自动化程序,由代码定义并强制执行合约条款。它彻底改变了传统合约依赖第三方中介的模式,实现了“代码即法律”的理念。以下是其核心要点详解:
一、本质与核心特征
-
自执行代码
当预设条件(如时间、交易触发)满足时,智能合约自动执行操作(如转账、数据更新),无需人工干预。 -
去中心化与不可篡改
部署后存储在以太坊区块链上,由全网节点共同验证执行,无法被修改或停止(除非预设自毁机制)。 -
透明公开
代码和交易记录对所有用户可见,确保可审计性。 -
成本驱动(Gas 机制)
每次执行需消耗 Gas(以 ETH 支付),用于补偿节点计算资源消耗,防止垃圾代码攻击。
二、技术实现原理
组件 | 作用 |
---|---|
以太坊虚拟机 (EVM) | 智能合约的运行环境,确保代码在所有节点执行结果一致。 |
Solidity 语言 | 以太坊主流开发语言(类 JavaScript),用于编写合约逻辑。 |
合约地址 | 合约部署后生成唯一地址(类似银行账户),用户通过地址调用合约功能。 |
状态存储 | 合约可读写区块链上的永久存储空间(Storage),或临时内存(Memory)。 |
✅ 示例流程:
用户 A 调用“支付合约” → 合约验证 A 是否转账 1 ETH → 自动向用户 B 转账 1 ETH → 交易记录上链。
三、核心应用场景
领域 | 典型案例 |
---|---|
DeFi | 去中心化交易所(Uniswap)、借贷协议(Aave)、稳定币(DAI)。 |
NFT | 生成(ERC-721)、交易(OpenSea)、版权管理合约。 |
DAO | 基于投票合约管理组织资金与规则(如 ConstitutionDAO)。 |
供应链 | 追踪商品流转(如 IBM Food Trust)。 |
游戏 | 游戏资产确权(Axie Infinity)、自动分发奖励。 |
四、优势与挑战
优势 | 挑战 |
---|---|
去信任化:无需依赖中介 | 代码漏洞风险:一旦部署无法修复(如 2016 The DAO 被黑损失 6000 万美元) |
降低成本:减少人工审核 | 法律灰色地带:代码是否具备法律效力仍存争议 |
高效透明:执行过程可追溯 | Gas 费用波动:网络拥堵时执行成本剧增 |
创新潜力:支撑 Web3 生态 | 复杂性:开发需精通密码学与区块链安全 |
五、与传统合约的对比
特性 | 智能合约 | 传统合约 |
---|---|---|
执行方式 | 自动触发,无人工干预 | 依赖法院/仲裁机构强制执行 |
信任基础 | 代码与数学原理 | 法律体系与第三方权威 |
修改权限 | 不可篡改(除非预设升级逻辑) | 双方协商后可修订 |
透明度 | 链上完全公开 | 通常保密 |
成本结构 | 一次性部署 Gas + 调用费用 | 律师费、公证费、时间成本 |
六、安全须知
-
审计必选
部署前需经专业公司(如 CertiK, OpenZeppelin)审计代码,避免重入攻击、整数溢出等漏洞。 -
权限控制
关键函数应设置权限(如onlyOwner
),防止未授权调用。 -
紧急开关
高风险合约需设计暂停机制(Circuit Breaker),应对突发风险。
总结
以太坊的智能合约是区块链技术的革命性应用,通过代码自动化执行协议,构建了去中心化金融、NFT、DAO 等万亿级生态。尽管面临安全与法律挑战,其“无需信任”的核心逻辑正重塑商业协作范式。
下一阶段演进:随着以太坊扩容(如 Layer2)和零知识证明(ZK-SNARKs)的发展,智能合约将向更高效率、更强隐私性进化。
八.TheDAO
TheDAO(Decentralized Autonomous Organization,去中心化自治组织)是以太坊历史上具有里程碑意义但最终失败的项目,它既是区块链治理的早期实验,也是引发以太坊硬分叉的关键事件。以下是综合梳理:
⚙️ 1. 基本定义与核心机制
-
去中心化自治组织:TheDAO旨在通过智能合约实现完全代码驱动的组织管理,无需传统公司结构。参与者通过购买DAO代币(以ETH兑换)获得投票权,共同决策资金使用(如投资项目)。
-
技术基础:基于以太坊智能合约,规则透明且自动执行,目标是成为“去中心化的风险投资基金”。
📅 2. 历史背景与规模
-
众筹纪录:2016年4月启动,28天内筹集1200万ETH(占当时以太坊流通量的14%),价值约1.5亿美元,参与超1.1万人,成为史上最大众筹项目。
-
理想愿景:由区块链公司Slock.it发起,试图颠覆传统风投模式,实现“集体民主投资”。
⚠️ 3. 黑客攻击事件(2016年6月17日)
-
漏洞利用:黑客利用智能合约中
splitDAO
函数的递归调用漏洞,在未更新账户余额前重复提取资金,并结合“资产转移规避销毁”的漏洞,盗取360万ETH(时值约5000万美元)。 -
安全预警失效:早在攻击前,以太坊开发者Vlad Zamfir等人多次警告合约风险,但未被重视。
⚖️ 4. 社区应对与硬分叉
-
紧急措施:
-
软分叉尝试:提议冻结TheDAO相关交易,但因漏洞导致网络可能被DoS攻击而失败。
-
白帽行动:黑客组织“罗宾汉”复制攻击手法转移剩余资金至安全地址。
-
-
硬分叉争议:
-
支持派(87%投票通过):认为需挽回用户损失,避免系统性信任危机。
-
反对派:主张“代码即法律”,坚持区块链不可篡改性,反对人为干预
-
-
分叉执行(2016年7月20日):
-
以太坊在第192万个区块执行硬分叉,将被盗资金强制退回新合约,允许投资者赎回ETH。
-
分裂结果:反对者维护原链,形成以太坊经典(ETC),黑客所盗资金在该链仍有效。
-
💎 5. 影响与遗产
-
技术反思:
-
暴露智能合约安全风险,推动形式化验证、审计工具发展(如OpenZeppelin)。
-
促成Solidity语言改进与安全最佳实践(如“检查-生效-交互”模式防重入攻击)。
-
-
治理启示:
-
挑战“完全去中心化”理想,揭示紧急情况下社区决策与链上干预的必要性。
-
DAO概念重生:2020年后涌现宪法DAO、LinksDAO等项目,聚焦明确目标与安全设计,脱离TheDAO阴影。
-
-
市场影响:
-
短期导致ETH价格暴跌30%,但长期助推以太坊生态成熟。
-
ETC作为“原则捍卫者”延续运行,但市值远低于ETH。
-
💎 总结
TheDAO是以太坊早期一场乌托邦式的社会实验,它因安全漏洞崩塌,却深刻重塑了区块链的发展轨迹:技术上催生了智能合约安全范式,治理上揭示了代码与人性规则的冲突平衡,生态上间接孕育了今日DAO经济的百花齐放。其兴衰警示后人:去中心化愿景需扎根于稳健的工程与包容的治理。
九.美链
以太坊美链(Beauty Chain,简称BEC)是2018年基于以太坊发行的代币项目,旨在构建去中心化的“美丽产业生态链”,但因安全漏洞事件引发巨大争议并最终失败。以下是其核心要点解析:
⚙️ 一、项目定位与技术基础
-
生态愿景
美链试图整合美容产业上下游资源(内容生产者、商家、用户等),通过区块链技术激励生态贡献,例如用户分享美容内容或数据可获得BEC代币奖励。 -
技术实现
-
作为ERC-20代币,运行于以太坊虚拟机(EVM),无独立区块链。
-
代币转账、发行均通过智能合约函数调用完成,账户余额存储在以太坊状态树的存储节点中。
-
💥 二、安全漏洞事件(2018年4月)
-
漏洞触发点
关键函数batchTransfer
用于批量转账,但未使用安全数学库(如SafeMath),导致整数溢出漏洞:solidity
uint256 amount = uint256(cnt) * _value; // 若_value极大,乘法溢出使amount归零
-
攻击者构造参数使
amount
溢出为0,仅扣除调用者极少代币,却向接收地址转入巨额BEC(例:单笔转出天文数字代币)。
-
-
攻击结果
-
大量BEC被凭空增发,代币价格24小时内暴跌近100%,市值从近50亿美元几近归零。
-
交易所紧急暂停提币并回滚交易,避免黑客套现。
-
🧾 三、代币经济与争议
关键问题 | 详情 |
---|---|
代币分配高度集中 | 70亿总量中,前4个地址持有99.93%,普通用户持币量微乎其微。 |
无公募/私募环节 | 代币直接由团队控制,市场流通代币来源不明,疑似团队操纵。 |
与美图公司的模糊关系 | 代币名“BEC”与美图旗下钱包“Bec”同名,蔡文胜(美图董事长)投资了首发交易所OKEx,但美图官方声明“仅为海外推广合作”。 |
⚠️ 四、安全事件的行业教训
-
代码审计必要性
漏洞源于未采用SafeMath的乘法校验(加/减函数已使用),暴露开发者对溢出风险的忽视。 -
溢出防护实践
SafeMath库通过assert(c / a == b)
检测乘法溢出,成为此后智能合约开发的标准实践。 -
中心化操控风险
代币高度集中+无透明分配机制,削弱了去中心化主张,凸显代币经济模型设计缺陷。
💎 五、事件后续与影响
-
市场信任崩塌:BEC事件与The DAO攻击并列,成为以太坊智能合约安全的经典反面案例。
-
监管警示:加速交易所对代币审计的要求,推动ERC-20项目强化安全实践(如强制第三方审计)。
-
项目结局:美链生态未落地,代币归零后团队消失,成为“空气币”典型。
总结
美链(BEC)是以太坊ERC-20代币早期泡沫化的缩影:其技术漏洞暴露了智能合约开发的安全性短板,代币集中化揭示了项目方操控风险,而与美图的暧昧关联则反映市场炒作乱象。尽管其“美丽生态”愿景具创新性,但安全与管理失控终致失败,为行业留下深刻风控启示:代码审计非选项而是必需,代币分配透明是信任根基。