theme: juejin highlight: a11y-light
账户
在以太坊中,有两种类型的账户:外部拥有账户(Externally Owned Accounts, EOAs)和合约账户(Contract Accounts)。尽管这两种账户在功能上有所不同,但在以太坊虚拟机(EVM)层面,它们都遵循相同的数据结构。下面解释一下每个账户的特点及其在EVM中的表示:
外部拥有账户(EOA)
-
定义:由私钥直接控制,没有关联的代码。用户通过私钥进行签名,从而发起交易。
-
特点:
- 不包含代码(
codeHash
字段为空)。 - 可以发送交易(如转账、创建智能合约)。
- 不包含代码(
合约账户
-
定义:由智能合约代码控制,该代码在合约部署时创建。
-
特点:
- 包含关联的EVM代码(
codeHash
包含代码的哈希)。 - 不能自行发起交易,但可以在接收到交易时执行代码。
- 交易只能从外部账户发出,合约只能被动的执行 (账户交互)
- 合约之间的交互通常成为消息,所有的手续费gas只能由外部账户支付。
- 包含关联的EVM代码(
EVM中的账户表示
无论是EOA还是合约账户,在EVM中它们都拥有以下属性:
- Nonce:对于EOA,nonce是该账户发送的交易数量。对于合约账户,它是该账户创建的合约数量。
- Balance:账户的以太币余额。
- StorageRoot:账户存储的Merkle Patricia树的根节点,该树存储了账户的所有状态信息。
- CodeHash:账户代码的哈希。对于EOA,这个值是固定的,因为EOA没有关联代码。对于合约账户,这个哈希代表合约代码。
账户的等效性
在EVM层面,EOA和合约账户在结构上是等效的,意味着它们都使用相同的数据结构。但它们的行为和用途存在明显区别。这种设计允许EVM以统一的方式处理不同类型的账户,同时支持多样化的交互和合约功能。
总结
尽管EOA和合约账户在功能上有所区别,但在EVM层面,它们都遵循相同的数据结构,包括nonce、balance、storageRoot和codeHash。这种设计使得EVM可以在处理账户时保持一致性和灵活性,同时支持以太坊丰富的功能和智能合约系统。
交易
交易的原子性
EVM 是由交易驱动,而每一个交易的执行只会有两种情况,要么成功要么失败。交易执行一旦失败就会回滚,所引起的状态改变就会抹掉,回到交易之前的状态,就像没有执行过这个交易一样,区块链的状态也就不会被改变。这就是交易的原子性。
这也就代表了,你所写的智能合约的函数包含多个操作时,如果其中任何一个操作失败,整个函数将被回滚,所有操作都将被取消,以保持数据的一致性。这确保了交易的原子性,即要么所有操作都成功,要么所有操作都不执行。
以太坊的三种交易
在以太坊网络中,根据交易的目的和类型,主要有以下几种交易类型:
1. 普通交易(向外部账户发送以太币)
普通交易是最基本的交易类型,通常用于将以太币(ETH)从一个账户转移到另一个账户。它的结构大致如下:
{
to: "0xRecipientAddress...", // 接收者的以太坊地址
value: "0.002", // 转移的以太币数量,单位是ETH
data: "0xOptionalMessage" // 可选,附加数据,通常是十六进制编码的消息
}
在这种交易中,data
字段通常不是必需的,除非你想发送一些附加信息。
使用ethers 附加消息
使用Ethers.js附加消息到交易
首先,你需要创建一个Ethers.js实例,设置提供者和签名者(通常是你的以太坊钱包),然后构建并发送交易。
-
初始化Ethers.js:
const { ethers } = require('ethers'); // 连接到以太坊节点,这里使用的是Ethers默认提供者(例如,Infura) const provider = ethers.getDefaultProvider('ropsten'); // 你的钱包私钥 const privateKey = 'your-private-key'; // 创建一个钱包实例 const wallet = new ethers.Wallet(privateKey, provider);
ethers.getDefaultProvider()
:这是 Ethers.js 提供的一个方法,用来获取一个默认的提供者实例。这个方法自动配置提供者,并连接到一个公共的以太坊节点或服务。
'ropsten'
:这是一个字符串参数,指定要连接到的以太坊网络。在这个例子中,使用的是 Ropsten 测试网络。Ropsten 是以太坊的一个公共测试网络,允许开发者测试他们的应用程序和智能合约而不需要消耗真实的以太币。除了 Ropsten,Ethers.js 也支持其他几个公共网络,例如主网络('homestead'),以及 Rinkeby 和 Kovan 测试网络。
如果在前端使用Metamaskconst signer = provider.getSigner();
不再使用私钥来创建一个wallet来签名 ,而是获取签名器来签名
2. 编码消息:
Ethers.js内置了将字符串转换为十六进制的功能。
```
const message = "Hello, Ethereum!";
const hexMessage = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message));
console.log(hexMessage); // 输出将是十六进制表示的消息
```
-
构建交易对象:
const transaction = { to: "0xReceiverAddress...", // 收款人地址 value: ethers.utils.parseEther("0.1"), // 转账金额 data: hexMessage, // 附加的十六进制消息 // 可选地,你可以设置 gasLimit, gasPrice 等 };
-
发送交易:
wallet.sendTransaction(transaction) .then((tx) => { console.log(tx); // 等待交易确认 return tx.wait(); }) .then((receipt) => { console.log('Transaction confirmed:', receipt); }) .catch((error) => { console.error('Error sending transaction:', error); });
2. 创建合约
创建合约的交易用于在以太坊区块链上部署新的智能合约。此类交易的结构没有to
字段,因为合约尚未部署,因此没有地址。它的结构如下:
{
from: "0xYourAddress...", // 发送者的以太坊地址
value: "0", // 可选,发送到合约的以太币数量
data: "0xContractBytecode" // 智能合约的编译后的字节码
}
在这种交易中,data
字段包含了智能合约的编译字节码,这是部署合约所必需的。
3. 调用合约
调用合约的交易用于执行智能合约中定义的函数。这种交易的to
字段指向要调用的合约的地址,而data
字段包含了函数调用的信息,通常包括函数的签名和参数。结构如下:
{
to: "0xContractAddress...", // 被调用合约的以太坊地址
value: "0", // 可选,发送到合约的以太币数量
data: "0xFunctionSignatureAndParameters" // 函数调用的数据
}
在这个例子中,data
字段是一个编码后的字符串,它表示要调用的合约函数及其参数。
总结
- 普通交易:用于直接向另一个账户发送以太币,可选附加消息。
- 创建合约:用于部署新的智能合约,包含合约的编译字节码。
- 调用合约:用于执行合约中的特定函数,需要指定合约地址和包含函数及其参数的数据。
EVM
EVM 即以太坊虚拟机,是以太坊网络上的运行环境,用于执行智能合约代码。它是一个完全隔离的环境,意味着在EVM中运行的代码不能直接访问网络、文件系统或其他外部系统。这种设计出于安全考虑,确保了智能合约的执行不会受到外部环境的不确定性和潜在恶意影响。
EVM的封闭性
- 确定性:EVM设计为封闭环境以确保其操作是确定性的。这意味着给定相同的输入和初始状态,智能合约的执行将总是产生相同的结果。这是区块链共识机制正常工作的关键要求。
- 安全性:通过限制对外部环境的访问,EVM降低了智能合约被攻击的风险,因为合约不能被外部系统直接影响或操控。
- 隔离性:合约间的隔离性确保了一个合约的行为不会直接影响到其他合约或主机系统,这有助于减少系统级的风险。
访问外部环境:预言机(Oracles)
虽然EVM本身不能直接访问外部系统,但智能合约可以通过“预言机”与外部世界交互。预言机是一种第三方服务,它们作为链外(off-chain)数据与链内(on-chain)智能合约之间的桥梁。以下是如何使用预言机的基本概念:
- 获取外部数据:预言机从外部数据源(如APIs、数据提供商等)获取信息。
- 提供数据给合约:预言机将这些信息传送到智能合约。这通常是通过发布交易来实现的,交易包含所需的数据,并由智能合约接收处理。
- 应用场景:例如,一个需要实时汇率的去中心化金融(DeFi)应用可以使用预言机来获取最新的货币汇率。
流行的预言机平台
- Chainlink:一个广泛使用的去中心化预言机网络,可为智能合约提供高质量、可靠的外部数据。
- Band Protocol:另一种预言机解决方案,提供快速、可扩展的数据查询功能。
总结
EVM的封闭性是其设计的一个关键特性,它确保了智能合约的确定性、安全性和隔离性。虽然这意味着智能合约不能直接访问外部系统,但通过使用预言机,合约可以安全地接收来自外部世界的数据,从而扩展其功能和应用场景。预言机在连接区块链与现实世界数据方面扮演着至关重要的角色。
以太坊客户端
以太坊客户端是一个软件应用,用于与以太坊网络进行交互。这些客户端实现了以太坊的协议规范,允许用户发送交易、创建智能合约、同步区块链数据,以及执行其他与网络相关的操作。以太坊客户端分为两大类:全节点客户端和轻节点客户端。
客户端
- 客户端通常指的是一款软件,它实现了区块链网络的协议规则。
- 这款软件可以是一个应用程序,比如Geth、Parity(现为OpenEthereum)或Besu,这些都是以太坊网络的不同客户端。
- 客户端定义了如何验证交易和区块,如何传播信息,以及如何与整个网络交互。
节点
- 当你在某个设备上运行客户端软件时,这个设备成为了一个节点。
- 节点指的是网络中的一个活跃成员,它参与网络的维护,包括验证交易、维护区块链数据等。
- 节点可以是全节点,存储整个区块链的历史记录;也可以是轻节点,只下载部分数据。
全节点客户端
全节点客户端下载并维护整个以太坊区块链的副本。它们验证所有区块和交易,确保网络的安全和数据的一致性。使用全节点客户端,你可以完全独立地参与以太坊网络,不需要依赖任何外部服务。主要的全节点客户端包括:
- Geth (Go-Ethereum) :使用Go语言编写,是最流行的以太坊客户端之一。
- OpenEthereum (原Parity Ethereum) :使用Rust语言编写,以高性能和高可靠性而闻名。
- Nethermind:使用.NET Core编写,是一个高性能的以太坊客户端。
- Besu:由Hyperledger开发,是一个企业级的以太坊客户端。
轻节点客户端
轻节点客户端不需要下载整个区块链,而是仅下载区块头以验证交易的真实性。它们适用于资源有限的环境(如个人电脑或移动设备),并依赖于全节点为其提供数据。轻节点客户端示例包括:
- Geth (Light Client Mode) :Geth也支持轻节点模式。
- MetaMask:一个浏览器插件,允许用户轻松访问以太坊网络,同时提供钱包功能。
在区块链和以太坊的语境中,客户端和节点经常可以互换使用,但它们在某些方面有细微的区别。
总结
- 当我们谈论“客户端”时,通常指的是实现区块链协议的软件。
- 而“节点”则是运行这个软件的实际计算机或设备,它作为网络中的一个活跃参与者。
- 所以,可以说客户端是软件,节点是这个软件运行时创建的实体。当一个客户端在设备上运行时,这个设备就成为了网络的一个节点。
- 通过节点交互以太坊
- 节点服务商 quicknode infura aclchemy
GAS
GAS相关知识
在以太坊网络中,"Gas" 是一个核心概念,涉及到交易和智能合约执行的几个重要方面。以下是有关 Gas 的简要总结:
什么是 Gas?
- 度量单位:Gas 是以太坊网络中用来度量执行操作的计算工作量的单位。
- 交易成本:每个操作,如交易发送或智能合约执行,都需要一定量的计算资源。Gas 是这些资源的抽象表示。
Gas 价格
- 用户设置:当用户发起交易时,他们会设置一个“Gas 价格”,这是他们愿意为每单位 Gas 支付的以太币数量。
- 市场决定:Gas 价格由市场决定,根据网络拥堵程度变化。
Gas 限制
- 交易上限:每笔交易都有一个 Gas 限制,这是用户愿意为该交易支付的最大 Gas 数量。
- 防止资源浪费:Gas 限制有助于防止恶意合约消耗过多资源。
Gas 费用
- 总成本:交易的总成本是 Gas 使用量与 Gas 价格的乘积。
- 支付矿工:这笔费用支付给挖掘该交易的矿工,作为提供计算资源的报酬。
Gas 和智能合约
- 计算成本:智能合约操作的成本以 Gas 衡量,每种操作(如加法、数据存储)都有固定的 Gas 成本。
- 优化重要:智能合约的效率对 Gas 成本有直接影响,因此优化合约代码以减少 Gas 使用是重要的。
Gas 和以太坊升级
- EIPs:以太坊改进提案(EIPs)经常调整 Gas 成本,以反映网络的变化和技术进步。
- 伦敦升级和EIP-1559:最近的伦敦升级引入了EIP-1559,改变了 Gas 费用的结构,引入了基础费用和优先费用的概念。
为什么 Gas 重要?
- 网络安全:Gas 系统帮助防止DDoS攻击,因为任何需要大量计算的行为都是昂贵的。
- 资源分配:通过使操作有成本,Gas 机制确保了网络资源(计算、存储)的合理分配。
总结
Gas 是以太坊网络中的一个关键概念,涉及交易成本、资源使用和网络安全。理解 Gas 的工作原理对于任何使用以太坊网络的人来说都是重要的,无论是普通用户还是开发者。
GAS作用
在以太坊网络中,Gas 扮演着非常关键的角色,其主要作用包括:
1. 度量计算工作量
- 计算资源的度量:Gas 用于量化执行交易或智能合约所需的计算工作量。每种操作(比如转账、存储数据、执行算法)都有与之对应的固定 Gas 成本。
2. 防止网络滥用
- DDoS防御:通过为计算资源设置费用,Gas 有助于防止恶意用户发起资源消耗型攻击(如DDoS)。这是因为大量计算工作或无限循环会产生高昂的费用。
3. 交易费用
- 激励机制:Gas 费用支付给矿工,以激励他们验证和处理交易,确保网络的维护和安全。
4. 网络资源管理
- 控制资源使用:通过限制交易可以使用的最大 Gas 数量(Gas Limit),以太坊确保单个交易不会占用过多网络资源。
5. 用户成本控制
- 控制费用风险:用户通过设置 Gas Price(Gas 价格)和 Gas Limit(Gas 限制),可以控制他们愿意为交易支付的最大费用,防止意外高额费用。
6. 促进经济效率
- 市场定价:Gas 价格由市场决定,反映了网络拥堵程度和用户对快速处理的需求。这促进了资源的有效分配。
7. 透明度
- 预测交易成本:用户在发起交易前可以估计其成本,这增加了操作的透明度。
总结
总的来说,Gas 在以太坊中是一个至关重要的概念,它不仅作为计算资源的度量和网络资源管理的工具,而且还是防止网络滥用、控制用户成本、激励网络维护和保持经济效率的关键因素。理解 Gas 的作用对于任何在以太坊上进行操作的人来说都是必要的。
问题
合约中是否有定时任务?
无:需要外部配置,或者使用预言机服务 kepper
EIP1559
"EIP-1559",这是一个重要的以太坊改进提案,于2021年8月在伦敦升级中实施。EIP-1559对以太坊的交易费用模型进行了重大改革,旨在改善费用市场的可预测性和用户体验。
EIP-1559带来的主要变化
-
基础费用(Base Fee) :
- 自动调整:EIP-1559引入了一个网络自动调整的基础费用机制,用于每个区块的交易费用。这个费用基于网络的拥堵程度自动上下浮动。
- 燃烧机制:交易中支付的基础费用不再支付给矿工,而是被"燃烧"(即从总供应量中移除),这有助于减缓以太币的通货膨胀。
-
优先费用(Priority Fee) :
- 用户可以通过支付优先费用(又称"小费"或"提示")来激励矿工优先处理他们的交易。这类似于之前的Gas价格拍卖模式,但现在是在基础费用之上。
-
更可预测的交易费用:
- 基础费用的自动调整使得交易费用更加可预测,用户不再需要通过复杂的拍卖机制来估算合适的Gas价格。
-
区块大小的弹性调整:
- EIP-1559还引入了区块大小的动态调整机制,使得区块大小在一定范围内根据网络需求变化。这有助于网络在高需求时期更有效地处理交易。
EIP-1559实施前后的区别
- 实施前:交易费用完全由市场决定,用户必须通过出价来竞争区块空间,这导致了费用的不可预测性和潜在的过度支付。
- 实施后:通过基础费用和优先费用的结合,用户更容易理解和估算交易费用。基础费用的燃烧还为以太坊经济模型带来了长期的可持续性。
总结
EIP-1559是以太坊网络中一个重要的里程碑,它通过重新设计交易费用机制,提高了费用的可预测性,减少了用户的交易费用不确定性,并通过燃烧机制减少了以太币的通货膨胀。这些变化对于用户、开发者和整个以太坊网络都产生了深远的影响。
补充EIP-1559实施之前,矿工作恶
在EIP-1559实施之前,以太坊网络中确实存在矿工作恶的潜在问题,尽管这并不是普遍现象。以下是一些可能的不良行为:
1. Gas Price Bidding Wars
- 在旧的费用模型中,用户通过竞价(提高Gas价格)来确保他们的交易被快速处理。这有时会导致Gas价格的战争,尤其是在网络拥堵时。
- 矿工可以优先选择Gas价格高的交易来最大化收益,这可能导致网络费用飙升。
2. 交易排队
- 矿工可以根据Gas价格对交易进行排队处理,而低Gas价格的交易可能会长时间等待处理或甚至被忽略。
3. 潜在的拥堵利用
- 理论上,矿工可以通过创建或促进网络拥堵来提高交易费用,从而增加自己的收益。他们可以发送大量的交易来人为地增加网络负载,提高Gas价格,然后从处理高Gas价格交易中获益。
4. 矿工可提取价值 (MEV)
- 矿工可提取价值(MEV)是指矿工通过在区块中选择、排列或操纵交易来获得额外收益的行为。这可能包括交易前沿(front-running)或交易夹击(back-running)等策略。
EIP-1559带来的改变
- 基础费用和燃烧:通过燃烧基础费用,减少了矿工通过操纵网络状态来提高费用的动机。
- 更可预测的费用模型:减少了竞价战,用户不再需要为了加快交易速度而过度支付。
- 区块大小的动态调整:增加了网络处理高需求的能力,减少了因拥堵导致的费用上升。
总结
尽管在EIP-1559之前,大多数矿工按照规则操作,但存在的潜在问题和可利用空间促使了对费用机制的改革。EIP-1559的实施旨在解决这些问题,提供更公平、更透明、更可预测的费用系统。
以太坊更新升级EIP&&ERC与 提案兼容问题
以太坊网络的更新和升级通常是通过改进提案(Ethereum Improvement Proposals, 简称 EIPs)的形式来实施的。这些提案描述了对以太坊网络的潜在改进,包括新功能、协议更改和标准建议。兼容性是实施这些更新时的一个重要考虑因素。
以太坊更新升级流程
- 提案阶段:社区成员(如开发者、研究人员)提交EIP。
- 讨论与审核:EIP在社区中进行讨论和审查,以评估其可行性、安全性和对网络的影响。
- 接受与测试:通过审核的EIP可能被包含在下一个网络升级(又称作“硬分叉”)中。在此之前,会在测试网络上进行广泛测试。
- 网络升级:经过充分测试后,EIP将在全球以太坊网络上实施。
兼容性考虑
- 向后兼容(Soft Fork) :这种升级通常向下兼容,意味着旧节点仍然可以识别并验证新规则下的区块。这类更新不会导致网络分叉。
- 不向后兼容(Hard Fork) :这类升级引入了与旧规则不兼容的变化。所有节点都需要升级才能继续验证区块。不升级的节点会被分割到旧版本的网络上。
- 共识机制:以太坊基于共识机制进行升级。网络的多数参与者(包括矿工和节点运营者)需要同意这些变化并升级他们的软件。
- 平滑过渡:对于重大更新,如EIP-1559,以太坊社区会采取措施确保过渡平稳,包括广泛的沟通、测试和准备工作。
- 分叉风险:对于重大的不兼容升级,存在网络分叉的风险,尤其是当社区对某一提案的接受程度分歧较大时。
- 智能合约和DApp开发者:开发者需要密切关注以太坊的更新,确保他们的智能合约和去中心化应用(DApps)与新的网络规则兼容。
总结
以太坊的更新和升级是基于社区共识和提案制度进行的。这些升级旨在改进网络的性能、安全性和功能。确保新旧系统的兼容性是升级过程中的一个关键挑战,需要社区成员的积极参与和合作来克服。向后兼容性和不兼容性升级都有其特定的场景和影响,因此需要慎重考虑和准备。
EIP && ERC
EIP(以太坊改进提案)和ERC(以太坊请求评论)都是以太坊社区用于提出和讨论新特性和标准的机制。尽管它们有相似之处,但它们各自关注的领域有所不同。
EIP(以太坊改进提案)
-
定义:EIPs是针对以太坊平台的改进提案,涵盖了技术规范和协议修改。
-
内容范围:
- 包括对以太坊协议本身的改进,如共识机制的变化、网络协议的调整、Gas价格的修改等。
- 也包括对以太坊虚拟机和智能合约编程的改进。
-
例子:
- EIP-1559:重新设计了交易费用模型。
- EIP-721:为非同质化代币(NFT)的标准化提出了规范。
ERC(以太坊请求评论)
-
定义:ERCs是一种特殊类型的EIP,专注于以太坊应用层和标准的制定。
-
内容范围:
- 主要关注的是智能合约层面的标准,如代币标准、智能合约接口等。
- ERCs为开发者提供了开发去中心化应用的通用标准和规范。
-
例子:
- ERC-20:为以太坊上的代币创造了一个标准化接口,是最著名的代币标准。
- ERC-721:为非同质化代币(NFT)定义了标准。
关键区别
- 焦点不同:EIPs更多关注以太坊网络和协议层面的改进,而ERCs则关注应用层面的标准和协议。
- 应用范围:EIPs的影响通常更加广泛,可能影响整个以太坊网络,而ERCs主要影响特定类型的智能合约和DApps开发。
总结
EIP和ERC都是以太坊社区用来提出和讨论新的想法和标准的机制。EIP涵盖了广泛的技术改进,包括网络协议和以太坊虚拟机,而ERC专注于应用层面的标准,如代币和智能合约的接口。两者都对以太坊的发展和生态系统的繁荣起着至关重要的作用。