以太坊核心概念
在开始以太坊智能合约和去中心化应用(DApp)开发之前,首先需要对以太坊的核心概念有一定的了解。本章将介绍以太坊的核心概念,以更好地理解以太坊的工作原理。
1. 以太坊简介及web3技术架构
以太坊(Ethereum)是一个建立在区块链技术之上的去中心化应用平台。它允许任何人在其平台上创建和使用通过区块链技术运行的去中心化应用(DApp)。
传统的互联网客户端/服务端架构(C/S架构)通常如下所示:
而去中心化应用(DApp)则有所不同,其后端由一组多个节点计算机(矿工)组成的网络支持,如下图所示:
通常情况下,我们使用的应用程序的内容由后端服务器提供,并将请求发送到后端服务器进行处理。例如,支付宝、京东等应用程序中的所有数据都由公司拥有。
然而,在去中心化应用中,前端用户通过自己的钱包管理自己的数据,而后端核心逻辑则通过智能合约在区块链上运行,实现了去中心化的信任机制。DApp与客户端连接的节点只是网络中的一部分,它不会单独处理来自用户的请求(通常称为“交易”),而是需要将用户的请求广播到整个网络。在整个网络达成共识后,该请求才被视为已经处理完成。
2.智能合约
智能合约是以太坊上运行的程序。就像其他计算机程序一样,它由代码和数据组成。智能合约中的数据通常被称为“状态”,因为整个区块链可以看作是所有数据状态的一个确定的记录。
提示:
请不要被智能合约名称中的“智能”一词所误导,它与人工智能(AI:Artificial Intelligence)无关。智能合约的概念最早由尼克·萨博提出,实质上是将法律条款编写成可执行代码,从而使法律执行变得分散化。这与区块链上的程序无法篡改地执行的理念相契合,因此智能合约成为了区块链的重要概念。
以太坊的智能合约是“图灵完备”的,这意味着理论上我们可以使用它来编写执行任何任务的程序。目前,智能合约的两个主要编程语言是Solidity和Vyper,其中Solidity更为成熟。在本教程中,我们将使用Solidity编写智能合约代码,合约文件的扩展名通常是.sol
。
以下是一个简单的计数器合约示例:
pragma solidity ^0.8.0;
contract Counter {
uint counter;
constructor() {
counter = 0;
}
function count() public {
counter = counter + 1;
}
}
这段代码有一个类型为uint
(无符号整数)名为counter
的变量。counter
变量的内容(值)就是该合约的状态。每当我们调用count()
函数时,此智能合约的区块链状态将增加1
。
在后面的教程中,我们会进一步介绍智能合约开发,在合约的代码组成一节,会进一步介绍合约代码的构成。
3.账户
当我们将counter
合约部署到链上之后,它会用一个地址来表示(称为合约地址),这是一个以太坊网络中的一种帐户:合约账户
。
账户在以太坊中是非常重要的概念,任何事情都离不开它。以太坊中有两类账户:
(1)外部用户账户(EOAs)——该类账户由公钥-私钥对控制(由人控制)。
(2)合约账户(CA:Contract Account)——该类账户由存储在账户中的代码控制。
外部用户账户和合约账户,它们都使用相同的地址格式来表示,在EVM层面是一样的,地址格式为:0xea674fdde714fd979de3edf0f56aa9716b898ec8,是一个20字节的16进制数。
外部用户账户的地址是由私钥生成的,而合约账户的地址是由创建者的地址和nonce计算得出的,详细信息可参考《以太坊合约地址是如何计算的?》 。
它们之间还有一个不可忽视的区别:只有外部用户账户可以发起交易(主动行为),而合约账户只能被动地响应操作,并且所有的手续费(Gas)必须由外部账户支付。
绿色箭头表示发起交易,灰色箭头表示消息调用
4.账户状态
无论账户类型如何,账户状态都由4个基本组成部分组成:
nonce :如果账户是一个外部用户账户,nonce代表从此账户地址发送的交易序号。如果账户是一个合约账户,nonce代表此账户创建的合约序号。
提示:以太坊中有两种nonce , 一种是账号nonce——表示一个账号的交易数量;一种是工作量证明nonce——一个用于计算满足工作量证明的随机数。
balance:此地址拥有的以太币余额数量。单位是
Wei
,1 ether
=10^18 wei
。当向地址发送带有以太币的交易时,balance会随之改变。外部用户账户和合约账户都可以有余额;合约账户使用代码管理所拥有的资金,外部用户账户则是使用私钥签名来花费资金;合约账户存储了代码,外部用户账户则没有。storageRoot:Merkle Patricia树的根节点哈希值。Merkle树会将此账户存储内容的哈希值进行编码,默认是空值。
codeHash:此账户代码的哈希值。对于合约账户,它是合约代码被哈希计算之后的结果作为codeHash保存。对于外部用户账户,codeHash 是一个空字符串的哈希值。
下面通过一个合约账户的可视化示例来总结上述内容:
以太坊的全局共享状态由所有账户状态组成,这些状态以账户地址和账户状态之间的映射形式存储在区块的状态树中,如下图所示:
上述内容总结如下:
5.以太币
以太币是一种货币,不同单位的货币就像法币中的不同面额,对于用户来说,最常用的单位是ether,1个ether通常也简称为以太。而对于开发者来说,可能更常使用wei,它是以太币的最小单位,其他单位包括finney和szabo,此外,wei还有几个衍生单位,包括Kwei、Mwei和Gwei。它们之间的换算关系如下:
1 ether = 10^3 finney(即1000 finney)
1 ether = 10^6 szabo
1 ether = 10^18 wei
1 Gwei = 10^9 wei
1 Mwei = 10^6 wei
以太币的单位命名方式非常有趣,以太坊社区为了纪念密码学家的贡献,使用了密码学家的名字作为货币单位,类似于许多国家的货币上印有国家的杰出人物头像一样。
- wei的名称来源于Wei Dai(戴伟),他是一位密码学家,提出了B-money。
- finney的名称来自于Hal Finney(哈尔·芬尼),他是一位密码学家,提出了工作量证明机制(PoW)。
- szabo的名称来自于Nick Szabo(尼克·萨博),他是一位密码学家,智能合约的概念提出者。
6.以太坊虚拟机(EVM)
EVM(以太坊虚拟机)是一种虚拟计算机,用于执行以太坊区块链上的智能合约和去中心化应用程序。EVM是以太坊的核心组件之一,它负责处理和执行智能合约的代码。
EVM的工作原理与传统的计算机虚拟机类似,但它是专门为区块链和智能合约而设计的。智能合约是以太坊上的自动化合同,其代码在EVM上运行,并且可以执行各种任务,例如转移加密货币资金、管理数字资产、实施投票机制等。
EVM执行智能合约时,会将智能合约的字节码加载到内存中,然后按照预定的规则执行该字节码。EVM提供了一种安全的执行环境,以确保合约的正确执行,同时还实施了燃气(Gas)的概念,以防止恶意代码无限循环或耗尽计算资源。
7.以太坊客户端
以太坊客户端是连接到以太坊网络的节点程序,其中以太坊虚拟机(EVM)是客户端的重要组成部分。通过运行节点程序,您可以成为以太坊网络中的一个节点,参与区块链网络的操作和维护。
以太坊网络分为两个主要层次:
执行层(Execution Layer):执行层负责处理交易的执行,这包括智能合约的部署和执行。执行层客户端包括 Geth(Go语言实现)、Nethermind(C#实现)和 Erigon(Go语言实现)。这些客户端用于处理以太坊网络上的智能合约操作和交易执行。
共识层(Consensus Layer):共识层负责处理共识算法,即出块和确认交易。共识层客户端包括 Prysm(Go语言实现)和 Lighthouse(Rust实现)。这些客户端用于参与共识过程,确保区块链网络的一致性和安全性。
以太坊节点程序可以执行多种任务,包括创建账户、发起交易、部署智能合约、执行智能合约、挖矿出块等。常见的以太坊客户端包括 Geth 和 Parity。Geth 是以太坊官方社区开发的客户端,使用 Go 语言编写。Parity 也是一种以太坊客户端,使用 Rust 语言编写。开发者通常使用 Geth,因为它是官方维护的客户端,并且提供了广泛的文档和支持。
以太坊虚拟机(EVM)是以太坊节点客户端的核心组件,它执行智能合约的代码,并处理交易。EVM与节点客户端紧密结合,使得以太坊网络能够运行智能合约并处理交易。它是以太坊的计算引擎,负责执行智能合约代码并维护全网的状态。
所有用户都通过节点与区块链网络进行交互,一般用户无需设置节点,因为运行节点需要大量资源。目前,有许多专业的节点服务提供商,例如 Infura 和 Alchemy,它们提供了便捷的方式来连接到区块链网络。
8.钱包
钱包是管理账户的重要工具,用户可以使用钱包创建账户、进行交易签名,并在需要时连接到区块链节点来执行交易。需要注意的是,钱包本身并不存储用户的资产,而是管理访问这些资产的密钥和签名功能。
常见的移动端钱包包括 ImToken、Trust Wallet 等,它们适用于一般用户,提供了便捷的方式来管理加密资产。
MetaMask 是一个浏览器插件,支持多种主流浏览器,如 Chrome、Firefox 和 Opera。它不仅可以用于管理账户,还可以用于部署和执行智能合约。开发者通常使用 MetaMask 与 Remix IDE 等工具结合使用,以便更轻松地开发和测试智能合约。
您可以在 MetaMask 官方网站 上找到相应的插件,并按照指南进行安装。安装完成后,您可以导入现有账户或创建新账户,并在 MetaMask 的界面中查看账户信息,如您所示的截图所示。这将为您提供一个方便的方式来管理您的以太坊账户和进行区块链操作。
9.Gas机制
在以太坊上,智能合约的“图灵完备性”允许编写执行各种任务的程序。然而,为了防止恶意行为,以太坊引入了Gas机制,它是一种衡量执行操作所需工作量的单位。
Gas价格(Gas price)是Gas机制中的一个关键概念。每笔交易需要指定Gas预算(Gas limit)和愿意支付的Gas价格。Gas预算乘以Gas价格等于交易费用。如果Gas预算不足以覆盖实际Gas消耗,交易将失败,状态更改会被回滚。
另一个要注意的是,如果交易执行结束后还有剩余Gas,剩余Gas会退还给发起交易的账户。这使得Gas机制更加灵活,用户可以根据需求调整Gas价格和Gas预算。
Gas机制是以太坊的重要特性,它确保了网络的稳定性和安全性,同时也为矿工提供了适当的激励来执行交易和合约。
10.以太坊交易
以太坊交易可以分为以下三种类型:
普通交易:用于向其他地址转移以太币。
创建合约:用于在区块链上创建智能合约。这种交易类型的
to
字段为空,data
字段包含智能合约的字节码。调用合约函数:用于调用已部署的智能合约的函数。这种交易类型的
to
字段包含目标合约地址,data
字段包含函数名称和参数。
虽然实际交易包含更多细节,但以上是交易的核心概念。接下来,让我们看一些具体的交易示例,特别是通过data
字段来理解合约调用。
普通交易示例:
{
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85",
"value": 0.0005,
"data": "0x" // 可以包含消息或留言
}
这是一个非常简单的普通交易,它将一定数量的以太币转移到指定地址,如果愿意,还可以在交易中包含一条消息。
创建智能合约示例:
{
"to": "",
"value": 0.0,
"data": "0x6060604052341561000c57xlb60405160c0806……………"
}
在创建智能合约的交易中,TO字段留空表示创建智能合约,而DATA字段包含了智能合约的字节码。
调用智能合约函数示例:
{
"to": "0x687422eEA2cB73B5d3e242bA5456b782919AFc85", // 合约地址
"value": 0.0,
"data": "0x06661abd"
}
调用智能合约函数的信息封装在DATA字段中,将此交易信息发送到要要调用的智能合约的地址。假设我们要调用前面的count()
函数,传递的是 count()
函数的选择器。