👦小明同学问我:
区块链是什么?
分布式、去中心化
(搞笑的说就是一群人觉得在一个系统中,权利资源控制权应该分散在多个独立参与者中也就是民主透明基于共识算法,而非单一实体,但现在的web3看起来也并不是这样,比如持有大量币的决定权xxx之类的)全球记账本
,而看起来对于这个记账本和传统web2世界的区别就是交易成本低、基于算法自动验证、透明、freedom
。点-线-链
的结构去帮助大家先构建大局观
,那么我们需要大致看一下接下来要讲的概念节点(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):用发送方私钥对交易进行签名,确认交易来源的真实性。
💻区块
-
区块编号(Block Number):用于标识区块在链中的位置; -
区块哈希(Block Hash):通过区块内容计算出的唯一标识符; -
区块头(Block Header):包含时间戳、上一个区块的哈希(Parent Hash)、挖矿难度(Difficulty)、Nonce等信息; -
交易列表:一组已经处理并确认的交易; -
区块创建者(Miner/Validator):成功创建该区块的节点。
🔗链
区块链之我是谁?
身份验证
是一个至关重要的环节,确保去中心化网络
的安全性和可信度。身份验证涉及众多关键概念,包括公私钥加密、签名、公开签名(Public Signing)以及钱包和热钱包
等。下面我们来深入了解这些概念以及它们在身份验证中的作用。🔑公钥与私钥
椭圆曲线加密算法(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)一般涉及四个步骤:发送方通过私钥加密
操作数据;发送加密后的数据和发送方的公钥;接收方使用发送方的公钥对数据进行解密;签名信息被验证
并接受。传输安全,防篡改,防抵赖
以及保证了用户的身份真实性
。👛钱包
余额、发送交易和接收数字资产
。钱包可以是硬件钱包(如Ledger Nano)、软件钱包(如MetaMask)等。钱包中的主要安全要素是私钥,因此用户在使用钱包时需格外注意私钥的保存和保护。🔥热钱包
从身份验证(Auth)到交易(Transaction)实战
引言
web3.js
库作为示例。🆔身份验证(Auth)
👛创建钱包和密钥
web3.js
库可以用于创建以太坊钱包及对应的公私钥。以下是创建钱包实例的示例代码:
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);
✏️签名和验证
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');
}
});
});
eth.personal.sign()
函数进行签名。该方法接收三个参数:消息的哈希值、用户地址和回调函数。回调函数将处理签名后的数据。eth.personal.ecRecover()
来恢复签名和发送者地址。该方法需要传入消息的哈希值、签名和回调函数。回调函数将处理恢复过程中返回的地址,用于和已知的用户地址进行对比。若这两个地址一致,则说明身份验证成功;否则,则意味着身份验证失败或签名被篡改。💻登录
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)
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()
函数将已签名的交易广播到以太坊网络。总结:
Web3
及其在去中心化网络
中实现身份验证
和交易处理
的方法。首先,讲解了如何在以太坊公链
(其他公链以此类推)上选择和配置 RPC
提供程序,以便对身份进行验证和处理交易
。然后,详解了 Web3 如何通过非对称加密进行身份验证,以及进行交易处理的关键步骤,包括创建、签名、广播和确认交易。原文始发于微信公众号(Web3 Frontend):Web3从入门到实战