0%

基本概念

区块 节点 区块链

区块

区块(Block)是区块链中的基本单位,它是包含了一定数量的交易数据的数据块。每个区块都包含了前一个区块的区块哈希(Block Hash),这样就形成了一个链式的连接。

结构

  1. 区块头(Block Header):区块头是区块的元数据,包含了与区块相关的重要信息,通常包括以下内容:
    • 版本号(Version Number):用于标识区块的版本。
    • 前一个区块的哈希(Previous Block Hash):该字段为前一个区块的区块哈希(Block Hash),即由区块头和交易数据一起计算得出的整个区块的哈希值。以此类推,当前区块的区块哈希记录在下一个区块的头部,从而形成区块链的链式结构。
    • 默克尔克尔根(Merkle Root):交易数据的哈希根,通过对所有交易进行哈希计算得到,用于有效验证交易数据的完整性。
    • 时间戳(Timestamp):记录区块被创建的时间,通常是Unix时间戳格式。
    • 难度目标(Difficulty Target):一个指示挖矿难度的数值,挖矿者需要寻找一个Nonce值,使得整个区块的哈希值满足这个难度目标。
    • 随机数(Nonce):用于寻找满足难度目标的解的随机值。
  2. 交易数据(Transactions Data):区块包含了一组交易数据,这些交易可能是数字货币的转账、智能合约的执行、代币交换等。交易数据包括交易的发送者、接收者、金额、时间戳等信息。

Merkle Tree

梅克尔树是一种二叉树的数据结构,它通过将一组数据分割为两两相邻的块,并对每个块进行哈希运算,逐层构建出一颗二叉树。最终,所有块的哈希值都汇聚到了树的根节点,这个根节点就被称为梅克尔根。

如果交易数据发生了任何改变,包括交易顺序的改变,那么梅克尔根也会发生变化,因为每个块的哈希值是基于交易数据计算的。因此,只需比较梅克尔根是否相等,就可以验证交易数据的完整性。

节点 矿工

节点

节点(Node)是区块链网络中的参与者,它可以是任何连接到网络的设备,如个人计算机、服务器或移动设备。节点的职能如下:

  1. 交易传播和广播:节点负责将新的交易广播到整个网络,以便其他节点能够了解到这些交易。
  2. 交易验证:节点验证从其他节点收到的交易,检查交易的合法性、数字签名和余额等。
  3. 区块传播和同步:节点负责传播新的区块到整个网络,以保持所有节点的区块链数据同步。
  4. 共识机制参与:在 PoW 中,节点通过解决数学难题来创建新的区块,而在 PoS 中,节点可能会被选为验证者,负责验证交易并打包区块。
  5. 提供网络安全性:更多的节点参与网络,可以提高网络的去中心化程度和安全性,使其对攻击更具抵抗力。
  6. 提供 API 和服务:一些节点可能提供 API 接口,供开发者查询区块链数据、调用智能合约等。

矿工

矿工是一种特殊的节点,主要职责是参与区块的创建和添加到区块链中。矿工通常是节点中的一小部分,他们在网络中执行更加计算密集的工作,比如在 PoW 共识机制中解决难题。矿工的职能如下:

  1. 交易打包: 矿工将未确认的交易打包成区块,然后尝试解决一个数学难题以获得新区块的权利。
  2. 计算工作量证明(PoW): 在 PoW 中,矿工需要通过计算找到一个满足难题要求的散列值,以便创建新的区块。
  3. 共识机制的维护: 矿工的参与确保了区块链网络的去中心化、安全性和一致性。
  4. 获得奖励: 矿工完成区块后,可以获得一定数量的加密货币奖励(如比特币、以太币)。

区块链

区块链(Blockchain)是由一系列链接在一起的区块构成的分布式账本。每个区块都包含了前一个区块的哈希值,形成了一个不断增长的链式结构。区块链的核心特性包括去中心化、透明性、不可篡改性和安全性。区块链技术的设计使得在没有中心控制机构的情况下,参与者可以达成共识并维护一个共享的账本。

比特币

比特币(Bitcoin)是区块链技术的第一个应用,它是一种去中心化的数字货币。比特币的区块链用于记录比特币交易,确保交易的安全性和完整性,同时也通过工作量证明(Proof of Work,PoW)共识机制维护整个网络的安全性。

以太坊

以太坊(Ethereum)是一个更加通用的区块链平台,它不仅支持数字货币交易,还引入了智能合约和去中心化应用的概念。以太坊的区块链不仅用于记录以太币交易,还可以执行智能合约代码,这使得开发者可以在以太坊上构建各种分布式应用和资产。

共识机制

共识机制(Consensus Mechanism)是区块链技术中用于解决分布式网络中不同节点之间达成一致的问题的一种算法或规则体系。在没有中央权威机构的情况下,共识机制确保了区块链网络的安全性、一致性和可靠性。不同的共识机制适用于不同的区块链项目和应用场景。

工作量证明(Proof of Work,PoW)

工作量证明是比特币等早期区块链项目采用的共识机制,其基本原理是通过解决复杂的数学难题来创建新的区块,并将其添加到区块链上。

  1. 创建新区块:矿工(也称为节点)竞争解决一个数学难题,这个难题需要进行大量的计算才能找到答案。第一个找到答案的矿工可以创建新的区块。
  2. 难度设置:区块链协议会根据全网的计算能力和时间来动态地调整难题的难度,以保持区块的平均产生时间稳定在一定值(如比特币的约10分钟)。
  3. 验证和奖励:其他节点可以轻松验证矿工找到的答案是否正确,因此只需要很少的时间来确认新区块的有效性。矿工获得创建新区块的权利以及一定数量的比特币作为奖励。
  4. 网络安全:PoW机制通过要求大量计算来创建新区块,保护了区块链网络免受攻击,因为攻击者需要控制大部分计算能力才能改变区块链的历史记录。

权益证明(Proof of Stake,PoS)

权益证明是一种更节能且环保的共识机制,通过节点持有的数字资产数量来决定谁有权创建新区块。

  1. 验证者选择:在PoS中,验证者(也称为节点)被选择来创建新区块的几率与他们持有的代币数量成比例。持有更多代币的节点有更大的机会获得创建区块的权利。
  2. 抵押资产:验证者需要将一定数量的代币作为抵押品,证明他们对网络的利益和责任。这些抵押品可以被取走或处罚,如果节点违反了规则。
  3. 创建新区块:被选择的验证者将基于一定的算法和轮次创建新区块。其他节点可以轻松验证这个区块的有效性。
  4. 奖励和交易费用:验证者获得创建新区块的权利以及交易费用作为奖励。他们的收入与他们抵押的代币数量成比例。
  5. 环保特性:PoS机制不需要大量的计算能力,因此能源消耗较低,相对环保。

智能合约

智能合约(Smart Contract)是一种在区块链技术中实现的自动化合约,它是一段自执行的计算机代码,用于管理、验证和执行合同条款和交易。智能合约被用在参与者之间建立可信的联系而不需要可信第三方的存在。比特币因为缺乏图灵完备性以及低扩展性对智能合约有很多限制,与比特币相比,以太坊则更加适合智能合约的存在。

功能特点

  1. 自动化执行:智能合约能够根据预定的条件自动执行合同条款和操作,无需中介或第三方的干预。这消除了人为错误和延迟,提高了执行效率。
  2. 可编程性:智能合约是可编程的,开发者可以使用支持的编程语言编写和定制合约,以满足特定的业务需求。
  3. 不可篡改性:一旦智能合约部署在区块链上,其代码和状态将被永久记录,并且不可更改。这确保了合约的可信度和安全性。
  4. 条件触发:智能合约可以根据特定的条件自动触发操作和交易。例如,当某个事件发生时,合约可以自动执行相关的操作,如支付、转账等。
  5. 透明性:区块链上的智能合约是公开可查看的,所有参与者都可以验证合约的执行过程和结果,增强了透明度和信任。
  6. 降低中介成本:智能合约消除了传统中介机构的需求,减少了交易和合同的处理成本。
  7. 时间戳和证明:智能合约的执行和结果都会被区块链网络的时间戳和数字签名记录下来,提供了对交易和操作的不可否认的证明。

编写合约

以太坊的智能合约就是一段由EVM虚拟机执行的字节码,直接编写字节码非常困难,通常都是由编译器负责把高级语言编译为字节码。以太坊智能合约主要使用Solidity编写,其语法类似于JavaScript

合约可以包括状态变量、函数、事件等。以下是一个简单的投票合约示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// SPDX-License-Identifier: GPL-3.0

pragma solidity =0.8.7;
// 指定编译器版本为0.8.7

contract Vote {
// 关键字contract声明一个合约

event Voted(address indexed voter, uint8 proposal);
// 定义一个Voted事件,在写方法中触发

mapping(address => bool) public voted;
// 将地址映射到一个布尔值,记录已投票的地址

uint256 public endTime;
// 记录投票终止时间

uint256 public proposalA;
uint256 public proposalB;
uint256 public proposalC;
// 记录得票数量

constructor(uint256 _endTime) {
// 构造函数仅在合约部署时执行一次
endTime = _endTime;
}

function vote(uint8 _proposal) public {
// 没有view修饰的函数是写入函数,它会修改成员变量,即改变了合约的状态

require(block.timestamp < endTime, "Vote expired.");
require(_proposal >= 1 && _proposal <= 3, "Invalid proposal.");
require(!voted[msg.sender], "Cannot vote again.");
voted[msg.sender] = true;
if (_proposal == 1) {
proposalA ++;
}
else if (_proposal == 2) {
proposalB ++;
}
else if (_proposal == 3) {
proposalC ++;
}

emit Voted(msg.sender, _proposal);
// 当调用vote()写方法时,通过emit关键字,会触发Voted事件
}

function votes() public view returns (uint256) {
// 以view修饰的函数是只读函数,它不会修改成员变量,即不会改变合约的状态
return proposalA + proposalB + proposalC;
}
}

部署合约

当一个合约编写完成并成功编译后,我们就可以把它部署到以太坊上。部署合约也是一个交易,需要一个外部账户(普通用户用私钥控制的账户)并花费一定的Gas(交易的手续费)。合约部署后将自动获得一个地址,通过该地址即可访问合约。

contract Vote {...}看作一个类,部署就相当于一个实例化。如果部署两次,将得到两个不同的地址,相当于实例化两次,两个部署后的合约对应的成员变量是完全独立的,互不影响。

构造函数在部署合约时就会立刻执行,且仅执行一次。合约部署后就无法调用构造函数。

调用合约

部署完成后,可以使用以太坊地址或合约地址与智能合约进行交互。

调用合约的只读函数无需签名,也无需Gas,任何时候均可调用;

调用合约的写入函数需要签名发送的交易,并消耗一定的Gas。只有等交易被矿工打包到区块中,并且该区块被添加到区块链上,写入才算成功。