Files
interview/questions/14-Web3与区块链/Web3基础知识.md

901 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Web3基础知识
## 问题
1. 什么是Web3Web1、Web2、Web3的区别是什么
2. 区块链的核心原理是什么?区块结构是怎样的?
3. 什么是共识机制PoW、PoS、DPoS的区别
4. 什么是智能合约?它有什么特点?
5. 公链、私链、联盟链的区别?
6. 什么是Gas费为什么需要Gas费
7. 什么是预言机Oracle它解决了什么问题
8. 什么是代币标准ERC-20、ERC-721、ERC-1155的区别
9. 什么是哈希函数?它在区块链中的作用?
10. 什么是默克尔树Merkle Tree它有什么作用
---
## 标准答案
### 1. Web1、Web2、Web3的区别
#### **Web11990-2005只读时代**
```
特点:
- 静态网页
- 用户只能阅读内容
- 单向信息传递
- 门户网站主导
代表新浪、搜狐、Yahoo
```
#### **Web22005-至今):读写时代**
```
特点:
- 动态网页、交互式
- 用户可以创建内容
- 平台主导、中心化
- 数据存储在中心化服务器
代表Facebook、Twitter、抖音
问题:
- 数据归平台所有
- 平台可以删除账号
- 隐私泄露
- 平台垄断
```
#### **Web3未来读写拥有时代**
```
特点:
- 去中心化
- 用户拥有数据所有权
- 基于区块链
- 代币经济激励
- 智能合约自动执行
代表Uniswap、OpenSea、ENS
优势:
- 数据归用户所有
- 抗审查
- 透明可信
- 价值回归用户
```
---
### 2. 区块链核心原理
#### **区块结构**
```go
type Block struct {
Header *BlockHeader
Data []byte // 交易数据
}
type BlockHeader struct {
Version uint32 // 版本号
PrevBlockHash []byte // 前一个区块的哈希
MerkleRoot []byte // 默克尔树根
Timestamp uint32 // 时间戳
Bits uint32 // 难度目标
Nonce uint32 // 随机数(挖矿时调整)
}
```
#### **链式结构**
```
Genesis Block (区块0)
↓ (PrevBlockHash)
Block 1
↓ (PrevBlockHash)
Block 2
↓ (PrevBlockHash)
Block 3
...
```
**关键特性**
- **不可篡改**:修改任意区块,后续所有区块的哈希都会变化
- **透明性**:所有交易公开可查
- **去中心化**:没有单一控制方
#### **交易流程**
```
1. 用户发起交易(转账、调用合约)
2. 交易广播到网络
3. 矿工/验证者打包交易到区块
4. 达成共识PoW/PoS
5. 区块添加到链上
6. 交易确认
```
---
### 3. 共识机制
#### **PoWProof of Work- 工作量证明**
**代表**比特币、以太坊1.0
**原理**
```
1. 矿工收集交易
2. 计算哈希值不断调整Nonce
3. 第一个找到符合难度要求的哈希的矿工获得记账权
4. 其他节点验证
5. 添加区块到链上
```
**代码示例**
```go
func (pow *ProofOfWork) Run() (int, []byte) {
var hashInt big.Int
var hash [32]byte
nonce := 0
for nonce < maxNonce {
data := pow.prepareData(nonce)
hash = sha256.Sum256(data)
hashInt.SetBytes(hash[:])
if hashInt.Cmp(pow.target) == -1 {
break // 找到有效哈希
} else {
nonce++
}
}
return nonce, hash[:]
}
```
**优点**
- 安全性高51%攻击成本极高)
- 去中心化程度高
**缺点**
- 能源消耗大
- TPS低比特币7 TPS
- 确认时间长
---
#### **PoSProof of Stake- 权益证明**
**代表**以太坊2.0、Cardano、Polkadot
**原理**
```
1. 验证者质押代币
2. 根据质押数量和时长选择验证者
3. 验证者创建区块
4. 获得奖励
5. 作恶会被罚没质押的代币
```
**代码示例**
```go
type Validator struct {
Address string
Stake uint64 // 质押数量
Uptime float64 // 在线时长
Reputation uint64 // 信誉分数
}
func SelectValidator(validators []Validator) *Validator {
// 根据质押数量加权随机选择
totalStake := uint64(0)
for _, v := range validators {
totalStake += v.Stake
}
randNum := rand.Uint64() % totalStake
cumulative := uint64(0)
for _, v := range validators {
cumulative += v.Stake
if randNum < cumulative {
return &v
}
}
return nil
}
```
**优点**
- 能源消耗低比PoW节能99%
- 更高的TPS
- 更快确认时间
**缺点**
- 富者愈富(大户更容易被选中)
- 可能导致中心化
---
#### **DPoSDelegated Proof of Stake- 委托权益证明**
**代表**EOS、TRON、BTS
**原理**
```
1. 代币持有者投票选举超级节点
2. 超级节点轮流记账
3. 超级节点获得奖励
4. 表现不好会被投票出局
```
**示例**
```go
// EOS21个超级节点
func (bp *BlockProducer) Schedule(blocks []*Block) {
// 每个超级节点轮流出块
// 每3秒一个区块
// 21个节点轮一圈 = 63秒
for i, block := range blocks {
producer := bp.producers[i % 21]
producer.ProduceBlock(block)
}
}
```
**优点**
- TPS极高EOS可达4000+ TPS
- 确认快
- 能耗低
**缺点**
- 中心化程度高只有21个节点
- 可能被大户控制
---
### 4. 智能合约
#### **定义**
智能合约是运行在区块链上的自动执行程序,当满足预设条件时自动执行。
#### **特点**
```solidity
// Solidity示例以太坊智能合约
pragma solidity ^0.8.0;
contract SimpleVault {
mapping(address => uint256) public balances;
// 存款
function deposit() public payable {
balances[msg.sender] += msg.value;
}
// 取款
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
// 自动转账,无需人工干预
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
}
```
**特点**
1. **自动执行**:条件满足自动运行
2. **不可篡改**:部署后无法修改
3. **透明可信**:代码公开可查
4. **去信任化**:不需要第三方中介
#### **应用场景**
```
- DeFi去中心化金融
- NFT数字资产
- DAO去中心化组织
- 供应链溯源
- 保险理赔
```
---
### 5. 公链、私链、联盟链
| 特性 | 公链 | 联盟链 | 私链 |
|------|------|--------|------|
| **访问权限** | 任何人 | 授权成员 | 单个组织 |
| **去中心化** | 高 | 中 | 低 |
| **性能** | 低 | 中 | 高 |
| **代表** | Bitcoin、Ethereum | Hyperledger Fabric | 企业内部链 |
| **应用场景** | 加密货币、DeFi | 银行联盟、供应链 | 企业内部 |
**公链代码示例**
```go
// 任何人都可以加入网络
func (n *PublicNetwork) Join() {
// 下载区块链数据
// 开始挖矿/验证
// 无需许可
}
```
**联盟链代码示例**
```go
// 只有授权成员可以加入
func (n *ConsortiumNetwork) Join(nodeID string, cert *Certificate) error {
// 验证证书
if !n.verifyCertificate(cert) {
return errors.New("unauthorized")
}
// 添加到联盟
n.members = append(n.members, nodeID)
return nil
}
```
---
### 6. Gas费
#### **为什么需要Gas费**
```
1. 防止DDoS攻击
- 如果交易免费,攻击者可以发送大量垃圾交易
- Gas费让攻击成本极高
2. 激励矿工/验证者
- 矿工打包交易需要消耗资源
- Gas费作为报酬
3. 优先级机制
- Gas费越高越快被打包
```
#### **Gas费计算**
```
交易费用 = Gas Used × Gas Price
例如:
- 转账消耗21,000 Gas
- Gas Price20 Gwei
- 总费用 = 21,000 × 20 Gwei = 0.00042 ETH
```
**代码示例**
```go
type Transaction struct {
To *common.Address
Value *big.Int
GasLimit uint64 // 最大Gas消耗
GasPrice *big.Int // Gas价格
Data []byte
}
func (tx *Transaction) Cost() *big.Int {
// 总成本 = 转账金额 + Gas费用
gasFee := new(big.Int).Mul(
new(big.Int).SetUint64(tx.GasLimit),
tx.GasPrice,
)
return new(big.Int).Add(tx.Value, gasFee)
}
```
#### **EIP-1559伦敦升级**
```
旧模式:
- 用户设置Gas Price
- 全部给矿工
新模式EIP-1559
- Base Fee网络自动计算销毁
- Priority Fee给矿工的小费
- 总费用 = Base Fee + Priority Fee
```
---
### 7. 预言机Oracle
#### **问题:区块链无法访问外部数据**
```
智能合约无法直接访问:
- 股票价格
- 天气数据
- 体育比赛结果
- 法币汇率
```
#### **解决方案:预言机**
```solidity
// 使用Chainlink预言机
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract PriceConsumer {
AggregatorV3Interface internal priceFeed;
constructor() {
// ETH/USD 价格预言机
priceFeed = AggregatorV3Interface(
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
);
}
function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}
}
```
#### **预言机的工作流程**
```
1. 智能合约请求数据
2. 预言机监听事件
3. 预言机从外部API获取数据
4. 预言机将数据提交到链上
5. 智能合约使用数据
```
#### **去中心化预言机**
```
Chainlink
- 多个节点提供数据
- 聚合结果
- 防止单点故障
- 惩罚作恶节点
```
---
### 8. 代币标准
#### **ERC-20同质化代币**
```solidity
pragma solidity ^0.8.0;
contract MyToken {
string public name = "My Token";
string public symbol = "MTK";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(uint256 _initialSupply) {
totalSupply = _initialSupply * 10 ** uint256(decimals);
balanceOf[msg.sender] = totalSupply;
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
}
```
**应用**
- USDT、USDC稳定币
- UNI、AAVE治理代币
---
#### **ERC-721NFT非同质化代币**
```solidity
pragma solidity ^0.8.0;
contract MyNFT {
string public name = "My NFT";
string public symbol = "MNFT";
mapping(uint256 => address) public ownerOf;
mapping(address => uint256) public balanceOf;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
function mint(address _to, uint256 _tokenId) public {
require(ownerOf[_tokenId] == address(0), "Token already exists");
ownerOf[_tokenId] = _to;
balanceOf[_to]++;
emit Transfer(address(0), _to, _tokenId);
}
function transferFrom(address _from, address _to, uint256 _tokenId) public {
require(ownerOf[_tokenId] == _from, "Not owner");
ownerOf[_tokenId] = _to;
balanceOf[_from]--;
balanceOf[_to]++;
emit Transfer(_from, _to, _tokenId);
}
}
```
**应用**
- CryptoKitties加密猫
- Bored Ape Yacht Club
- OpenSeaNFT市场
---
#### **ERC-1155多代币标准**
```solidity
pragma solidity ^0.8.0;
contract MultiToken {
// 同时支持FT和NFT
mapping(uint256 => mapping(address => uint256)) public balanceOf;
function safeTransferFrom(
address _from,
address _to,
uint256 _id,
uint256 _amount,
bytes memory _data
) public {
require(balanceOf[_id][_from] >= _amount, "Insufficient balance");
balanceOf[_id][_from] -= _amount;
balanceOf[_id][_to] += _amount;
}
// 批量转账
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] memory _ids,
uint256[] memory _amounts,
bytes memory _data
) public {
for (uint256 i = 0; i < _ids.length; i++) {
balanceOf[_ids[i]][_from] -= _amounts[i];
balanceOf[_ids[i]][_to] += _amounts[i];
}
}
}
```
**优势**
- 一次交易可转账多种代币
- 节省Gas费
- 游戏道具有些是FT有些是NFT
---
### 9. 哈希函数
#### **特性**
```
1. 确定性:相同输入总是产生相同输出
2. 快速计算:易于验证
3. 不可逆:无法从哈希值反推输入
4. 雪崩效应:输入微小变化,输出完全不同
5. 抗碰撞:很难找到两个不同输入产生相同输出
```
#### **SHA-256示例**
```go
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
data := "Hello, Blockchain!"
hash := sha256.Sum256([]byte(data))
fmt.Printf("原始数据: %s\n", data)
fmt.Printf("哈希值: %s\n", hex.EncodeToString(hash[:]))
// 修改一个字符
data2 := "Hello, Blockchain?"
hash2 := sha256.Sum256([]byte(data2))
fmt.Printf("\n修改后数据: %s\n", data2)
fmt.Printf("哈希值: %s\n", hex.EncodeToString(hash2[:]))
}
// 输出:
// 原始数据: Hello, Blockchain!
// 哈希值: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146
//
// 修改后数据: Hello, Blockchain?
// 哈希值: 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d906
```
#### **在区块链中的应用**
```
1. 区块哈希
- 标识区块
- 链式结构
2. 交易哈希
- 标识交易
- 防篡改
3. 默克尔树根
- 快速验证交易
- 轻节点验证
4. 地址生成
- 公钥 → 哈希 → 地址
5. 挖矿
- 寻找符合难度要求的哈希
```
---
### 10. 默克尔树Merkle Tree
#### **结构**
```
Merkle Root
/ \
Hash01 Hash23
/ \ / \
Hash0 Hash1 Hash2 Hash3
| | | |
Tx0 Tx1 Tx2 Tx3
```
#### **代码实现**
```go
type MerkleTree struct {
RootNode *MerkleNode
}
type MerkleNode struct {
Left *MerkleNode
Right *MerkleNode
Data []byte
}
func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode {
node := &MerkleNode{}
if left == nil && right == nil {
// 叶子节点
hash := sha256.Sum256(data)
node.Data = hash[:]
} else {
// 非叶子节点
prevHash := append(left.Data, right.Data...)
hash := sha256.Sum256(prevHash)
node.Data = hash[:]
}
node.Left = left
node.Right = right
return node
}
func NewMerkleTree(data [][]byte) *MerkleTree {
var nodes []MerkleNode
// 创建叶子节点
for _, datum := range data {
node := NewMerkleNode(nil, nil, datum)
nodes = append(nodes, *node)
}
// 构建树
for len(nodes) > 1 {
var newLevel []MerkleNode
for i := 0; i < len(nodes); i += 2 {
left := &nodes[i]
right := &nodes[i+1]
parent := NewMerkleNode(left, right, nil)
newLevel = append(newLevel, *parent)
}
nodes = newLevel
}
return &MerkleTree{RootNode: &nodes[0]}
}
```
#### **作用**
```
1. 快速验证交易
- 只需要 log(n) 个哈希值
- 不需要下载整个区块
2. 轻节点SPV
- 只存储区块头包含Merkle Root
- 通过Merkle Proof验证交易
3. 防篡改
- 任何一个交易被修改
- Merkle Root都会变化
```
#### **Merkle Proof示例**
```go
// 证明Tx2在区块中
func VerifyMerkleProof(tx []byte, proof [][]byte, root []byte) bool {
hash := sha256.Sum256(tx)
current := hash[:]
for _, p := range proof {
if isLeftNode {
combined := append(current, p...)
hash := sha256.Sum256(combined)
current = hash[:]
} else {
combined := append(p, current...)
hash := sha256.Sum256(combined)
current = hash[:]
}
}
return bytes.Equal(current, root)
}
```
---
## 结合简历的面试题
### 1. 从Web2到Web3的迁移经验
**面试官会问**
> "你在字节跳动做过高并发系统50k+ QPS这些经验如何应用到Web3"
**参考回答**
```
Web2经验
- 50k+ QPS消费券系统
- 双机房容灾
- 监控告警
Web3应用
1. 高并发经验
- 交易所撮合引擎
- NFT抢购Gas优化
- 预言机高频更新
2. 容灾经验
- 跨链桥多节点验证
- 智能合约多签钱包
- DEX多流动性池
3. 监控经验
- 链上数据监控
- 交易池监控
- 智能合约事件监听
```
### 2. Golang在区块链中的应用
**面试官会问**
> "你精通Golang在区块链领域Golang有哪些应用"
**参考回答**
```
1. 公链开发
- Geth以太坊客户端
- Cosmos SDK
- Polkadot Substrate
2. 基础设施
- 区块浏览器
- 预言机节点
- 跨链桥
3. 性能优势
- 并发处理交易
- 高性能RPC节点
- 链下计算
示例:
- 使用Goroutine并发处理交易验证
- 使用Channel做交易池管理
- 使用Go的高性能网络库做P2P通信
```
### 3. 分布式系统与区块链
**面试官会问**
> "你有分布式系统经验,区块链的共识机制和传统分布式系统有什么区别?"
**参考回答**
```
传统分布式系统如Raft、Paxos
- 节点身份已知
- 需要容许节点故障
- 强一致性
- 性能高
区块链PoW/PoS
- 节点身份未知(无许可)
- 需要容许恶意节点(拜占庭容错)
- 最终一致性
- 性能低
关键差异:
1. 信任模型
- 传统:信任节点
- 区块链:不信任任何节点
2. 激励机制
- 传统:无
- 区块链:代币激励
3. 数据不可篡改
- 传统:可以修改
- 区块链:不可篡改
```
---
## Web3面试加分项
### 1. 实际经验
- 有智能合约开发经验Solidity、Rust
- 参与过DeFi项目
- 熟悉Web3工具Hardhat、Foundry、Ethers.js
- 了解主流公链Ethereum、Solana、BSC
### 2. 技术深度
- 理解EVM原理
- 了解零知识证明
- 熟悉跨链技术
- 了解Layer2扩容方案
### 3. 安全意识
- 智能合约安全审计
- 常见攻击手法(重入攻击、闪电贷攻击)
- 防御措施
### 4. 行业理解
- DeFi协议Uniswap、Aave、Compound
- NFT生态
- DAO治理
- 监管趋势