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

18 KiB
Raw Blame History

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. 区块链核心原理

区块结构

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. 添加区块到链上

代码示例

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. 作恶会被罚没质押的代币

代码示例

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. 表现不好会被投票出局

示例

// 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示例以太坊智能合约
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 银行联盟、供应链 企业内部

公链代码示例

// 任何人都可以加入网络
func (n *PublicNetwork) Join() {
    // 下载区块链数据
    // 开始挖矿/验证
    // 无需许可
}

联盟链代码示例

// 只有授权成员可以加入
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

代码示例

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

问题:区块链无法访问外部数据

智能合约无法直接访问:
- 股票价格
- 天气数据
- 体育比赛结果
- 法币汇率

解决方案:预言机

// 使用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同质化代币

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非同质化代币

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多代币标准

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示例

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

代码实现

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示例

// 证明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治理
  • 监管趋势