需求背景
就有个朋友说她想搞个前端Web3社区,我觉得这事大不可为,毕竟Web3跟前端确实没太大关系,然后她说先试试嘛,然后就帮忙写篇文章呗。
1、区块链是什么?
区块链的本质就是一个分布式、去中心化
(搞笑的说就是一群人觉得在一个系统中,权利资源控制权应该分散在多个独立参与者中也就是民主透明基于共识算法,而非单一实体,但现在的web3看起来也并不是这样,比如持有大量币的决定权xxx之类的)全球记账本
,而看起来对于这个记账本和传统web2世界的区别就是交易成本低、基于算法自动验证、透明、freedom
。
在Web3中有许多的概念和名词,为了大家去帮助理解这篇文章,我会以点-线-链
的结构去帮助大家先构建大局观
,那么我们需要大致看一下接下来要讲的概念节点(Node)
、交易结构(Transaction Structure)
、区块(Block)
、链(Chain)
之间的关系。
节点
之间协同运作以完成交易验证、区块生成等任务,维护整个网络的稳定运行
。节点
生成并验证交易
,根据交易结构组织和存储
交易数据。- 生成的
交易
被打包到新的区块
中,并通过挖矿
或权益证明
等共识机制
将区块添加到链上。 - 链是由一系列按顺序连接的区块组成的
数据结构
。每个区块都包含前一个区块的哈希,通过这种方式将它们连接在一起,形成一个链式结构
。这个链式结构
能够快速地检测篡改和恶意行为,维护整个网络的安全。
Node:
那么首先是Node
,节点是构成去中心化网络基础
的关键组件
。在Web3
(去中心化网络)概念中,节点是独立的服务器
或计算设备
,共同组成并维护整个网络。这些节点通过互联网相互连接,执行并验证网络中的操作和交易。每个节点维护网络
的一个副本,这使整个系统具有高度的安全性
和抗攻击能力
。
总的来说,在Web3
环境中,各种类型的节点
共同维护去中心化网络的安全和稳定运行,这些节点之间互相协作,实现了数据的传输、验证和共享。节点的多样性使得网络能够抵抗各种类型的攻击和故障,提升了整个网络的生态健康和可持续性,那么我们接下来可以看一看一般拥有哪些节点。
全节点(Full Node)
全节点
是存储整个区块链数据的节点,包括所有已完成的交易和区块历史。全节点会验证所有交易和区块,确保网络中的数据和交易遵循协议规则
。这使得全节点
成为网络中安全和信任的基石。不过,运行全节点需要大量的存储和计算资源,因此不是所有参与者都可以或愿意承担这一角色。
轻节点(Light Node)
与全节点相反,轻节点不存储整个区块链数据。轻节点只会存储与其自身相关的交易
和部分链的元数据
(如块头)。轻节点依赖全节点进行交易验证和区块确认等功能。轻节点在网络中提供了一种更轻量级的参与方式,降低了参与者的门槛,但需要信任全节点提供的数据的正确性。
验证节点(Validator Node)
在某些共识算法
(如权益证明算法,Proof of Stake,PoS)中,验证节点
将具有创建新区块和验证交易的权利。这些验证节点通常需要持有一定数量的网络代币并锁定(抵押)作为押金。验证节点的角色主要是保证网络的有效性和安全性,参与网络治理,并根据贡献赚取奖励。
挖矿节点(Mining Node)
在工作量证明(Proof of Work,PoW)系统
中,挖矿节点负责解决复杂数学问题
(简称浪费资源)以生成新区块并添加到区块链。挖矿节点的贡献与其计算能力相关。成功创建新区块的节点会获得一定数量的网络代币作为奖励。挖矿节点的存在保证了网络的去中心化和安全性
。
交易结构
交易结构是网络中对交易数据进行编码和组织的方式。一个典型的交易结构包括以下信息:
- 发送方地址:从哪个账户发出的交易;
- 接收方地址:交易的目标账户;
- 数量(Value):交易中涉及的资产数量;
- Gas Price:用于支付交易处理费用的价格;
- Nonce:防止交易重放攻击的计数器;
- 交易数据(Data):附加在交易上的数据,如智能合约中的函数调用及参数;
- 签名(Signature):用发送方私钥对交易进行签名,确认交易来源的真实性。
区块
区块是Web3网络中的核心数据结构,包含了一组理解成一个特定时间段内进行的交易。区块中主要包含以下信息:
- 区块编号(Block Number):用于标识区块在链中的位置;
- 区块哈希(Block Hash):通过区块内容计算出的唯一标识符;
- 区块头(Block Header):包含时间戳、上一个区块的哈希(Parent Hash)、挖矿难度(Difficulty)、Nonce等信息;
- 交易列表:一组已经处理并确认的交易;
- 区块创建者(Miner/Validator):成功创建该区块的节点。
链
多笔交易打包在一起后就形成了一个区块,这样的区块们首尾相连成为一条"链",也就是所谓的区块链。
2、区块链之我是谁?
Web3体系中,身份验证
是一个至关重要的环节,确保去中心化网络
的安全性和可信度。身份验证涉及众多关键概念,包括公私钥加密、签名、公开签名(Public Signing)以及钱包和热钱包
等。下面我们来深入了解这些概念以及它们在身份验证中的作用。
公钥与私钥
公钥和私钥是非对称加密的基石。在Web3体系中,公钥和私钥是一对密钥,可以实现信息加密和解密的功能。公钥是用户公开给其他人用于加密信息的密钥,而私钥是用户自己拥有并妥善保管的密钥,用于解密信息,他们共同组成了你的身份信息。而公钥私钥的加密和签名是通过椭圆曲线加密算法。
椭圆曲线加密算法(Ellipse Curve Cryptography,ECC),ECC有两个重要组成部分:
- 私钥 在Web3中,私钥是一个随机选择的大整数。一般来说,私钥长度为256比特,从硬件随机数发生器或密码学安全的伪随机数发生器中选取。
- 公钥 使用椭圆曲线密码学(ECC)中的数学运算计算公钥。
- 计算 基于数学的特性,公私钥一一对应,由私钥→可以计算出公钥,但是公钥却无法反推私钥。由于私钥严格保密,因此公钥可作为私钥拥有者的一个标识。 使用ECC进行加密时:对于明文可分别用私钥/公钥进行加密,加密后的密文需要对应的通过公钥/私钥才能解开。例如: 1)ECC("hello",私钥) = 密文a 仅能公钥将密文a还原成"hello"。这适用于验证发件人是本人的场景。(数字签名) 1)ECC("hello",公钥) = 密文b; 仅能私钥将密文b还原成"hello"。这适用于确保接收方是本人的场景。
签名(Sign)
签名指的是利用私钥
对一段数据进行加密的过程。当Web3中的用户需要在去中心化应用
中进行某项操作时,用户需要对这个操作的数据
进行签名。签名过程中,私钥被用来对用户生成的操作数据进行加密,以确保数据来源的真实性。签名后的数据可以被其他用户(接收方)通过发送方的公钥
进行验证和解密。
公开签名(Public Signing)
公开签名是指在公钥加密体系中使用签名操作的过程。它的主要应用场景包括数字签名、数字证书
等。公开签名(Public Signing)一般涉及四个步骤:发送方通过私钥加密
操作数据;发送加密后的数据和发送方的公钥;接收方使用发送方的公钥对数据进行解密;签名信息被验证
并接受。
公开签名机制确保了数据的完整性和传输安全,防篡改,防抵赖
以及保证了用户的身份真实性
。
钱包
钱包是用户在Web3环境中存储、管理数字资产与密钥的应用程序。通过钱包,用户可以看到他们的余额、发送交易和接收数字资产
。钱包可以是硬件钱包(如Ledger Nano)、软件钱包(如MetaMask)等。钱包中的主要安全要素是私钥,因此用户在使用钱包时需格外注意私钥的保存和保护。
热钱包
热钱包是指始终与互联网连接的数字货币钱包,可以方便的完成交易操作,适合日常的小额交易。由于热钱包始终在线,可能存在安全隐患,因此用户一般将大额资产存放在更为安全的冷钱包中。热钱包通常包括网页钱包(如MyEtherWallet)、桌面钱包(如Electrum)以及手机钱包(如Trust Wallet)等。
综上所述,公私钥加密和签名机制为Web3提供了一种强大的身份验证手段,确保去中心化网络的安全和可信度。而钱包和热钱包等工具则为用户在Web3体系中提供了便捷的资产管理手段。
3、从身份验证(Auth)到交易(Transaction)实战
引言
在去中心化网络和基于区块链的应用中,开发者和用户需要确保身份验证和交易的安全性。本文将通过并结合Web3及相关技术,探讨如何基于以太坊实现身份验证、登录和交易过程。涉及的实战操作将包括用户身份验证、签名、交易的发起、签名和广播等。同时,我们将分析其中的原理,并使用web3.js
库作为示例。
身份验证(Auth)
在Web3世界中,身份验证是通过公私钥对应用用户进行识别和授权的过程。用户拥有唯一的私钥,通过椭圆曲线算法生成对应的公钥和地址(如以太坊地址)。私钥仅限用户自己持有,不应泄露给他人。在进行身份验证时,用户使用自己的私钥对特定消息进行签名,验证方通过验证签名和公钥(或地址)来确保身份的真实性。
创建钱包和密钥
在Web3中,web3.js
库可以用于创建以太坊钱包及对应的公私钥。以下是创建钱包实例的示例代码:
javascript
const Web3 = require('web3');
// 这里为RPC节点
const web3 = new Web3('your_rpc_provider');
// 以eth为例
const account = web3.eth.accounts.create();
console.log('Address: ', account.address);
console.log('Private Key: ', account.privateKey);
此代码将生成一个以太坊钱包实例,其中包括一个地址和与该地址关联的私钥。
签名和验证
用户进行身份验证时,需要提供用私钥签名的消息。验证方可以通过恢复签名来确定签名者的地址。以下是实现签名和验证过程的示例代码:
javascript
const msg = 'Hello Web3 Authentication';
const msgHash = web3.utils.sha3(msg);
web3.eth.personal.sign(msgHash, account.address, (error, signature) => {
if (error) {
console.error('Sign error:', error);
return;
}
web3.eth.personal.ecRecover(msgHash, signature, (error, recoveredAddress) => {
if (error) {
console.error('Recover error:', error);
return;
}
if (recoveredAddress === account.address) {
console.log('Authentication successful');
} else {
console.log('Authentication failed');
}
});
});
在上述代码中,用户首先签名一个消息(如:"Hello Web3 Authentication"),然后使用eth.personal.sign()
函数进行签名。该方法接收三个参数:消息的哈希值、用户地址和回调函数。回调函数将处理签名后的数据。
验证方接收到签名后,通过调用eth.personal.ecRecover()
来恢复签名和发送者地址。该方法需要传入消息的哈希值、签名和回调函数。回调函数将处理恢复过程中返回的地址,用于和已知的用户地址进行对比。若这两个地址一致,则说明身份验证成功;否则,则意味着身份验证失败或签名被篡改。
登录
在传统的中心化应用中,用户的登录是通过用户名和密码实现的。然而在去中心化和基于区块链的应用场景下,这种方法将引入中心化服务器作为信任中介,不符合去中心化的要求。因此,在Web3世界中,登录也需要使用前述(身份验证)部分所介绍的签名和验证方法。
用户首先在客户端使用私钥对一个随机生成的、包含时间戳和随机数的消息进行签名。然后将签名后的数据发送给应用后端,后端验证签名并将验证结果作为身份验证的依据。之后,应用后端可向客户端下发一个安全的、有时限的访问令牌(如JWT),以便应用客户端在后续的请求中使用。
python
async def loginwithsign(signUp: LoginWithSignModel, user_service: UserService = Depends()):
address = signUp.address
message = signUp.msg
signature = signUp.sig
flag = verify_signature(address, message, signature)
if flag:
user = await user_service.get_user_by_address(address)
if user is None:
user = await user_service.create_user_with_sign(signUp)
if user is None:
raise HTTPException(status_code=401, detail="Bad sign")
else:
logging.info("create user with sign success")
access_token = await user_service.create_access_token(user.id)
else:
access_token = await user_service.create_access_token(user.id)
data = {
"token":access_token,
"uid":user.id,
"username":user.username,
'avatar':user.get_avatar(),
"inviteCode":user.invite_code,
"inviteLink":user.get_invite_link(),
"jwtToken":access_token,
"pid":user.pid,
"verified":user.verified,
}
return success_return(data)
else:
raise HTTPException(status_code=401, detail="Bad Signature")
这样就实现了一种基于非对称加密和公钥体系的登录过程,确保了身份验证的安全性,同时避免了传统的用户名和密码方式所带来的安全隐患。
交易(Transaction)
在去中心化的网络中,交易(Transaction)是从一方发送资产或数据到另一方的过程。例如,在以太坊中,交易可以是发送以太币(ETH)或在智能合约中调用方法。交易需要发起方使用私钥对其内容进行签名,以确保交易不被篡改和伪造。验证方(如以太坊网络节点)将验证交易的签名,并将交易及其结果记录在区块链上。
以下是在以太坊网络上发起交易的简单示例代码:
javascript
const rawTx = {
from: account.address,
to: 'address_of_recipient', // 请替换成实际的接收方地址
value: web3.utils.toWei('1', 'ether'), // 发送的金额
gas: 21000,
gasPrice: web3.utils.toWei('10', 'gwei'),
};
web3.eth.accounts.signTransaction(rawTx, account.privateKey, (error, signedTx) => {
if (error) {
console.error('Transaction signing error:', error);
return;
}
web3.eth
.sendSignedTransaction(signedTx.rawTransaction)
.on('transactionHash', (hash) => {
console.log('Transaction Hash: ', hash);
})
.on('receipt', (receipt) => {
console.log('Receipt:', receipt);
})
.on('error', (error) => {
console.error('Transaction sending error:', error);
});
});
在上述代码中,我们首先创建一个未签名的交易对象rawTx
,其中包含了交易的发起方地址、接收方地址、交易金额(ETH)和所需的Gas等相关信息。
接着,我们使用发起方的私钥对这个未签名交易进行签名,调用eth.accounts.signTransaction()
函数。签名后,我们使用eth.sendSignedTransaction()
函数将已签名的交易广播到以太坊网络。
可以在交易发送过程中添加多个事件监听,以获取交易哈希值、交易收据、发送状态和其他信息。最终,交易将被打包进以太坊区块链,相关状态将更新或记录。
4、总结:
本文详细探讨了 Web3
及其在去中心化网络
中实现身份验证
和交易处理
的方法。首先,讲解了如何在以太坊公链
(其他公链以此类推)上选择和配置 RPC
提供程序,以便对身份进行验证和处理交易
。然后,详解了 Web3 如何通过非对称加密进行身份验证,以及进行交易处理的关键步骤,包括创建、签名、广播和确认交易。