找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

262

积分

0

好友

32

主题
发表于 昨天 02:24 | 查看: 2| 回复: 0

在上一篇文章中,我们成功实现了一个可以跑起来的迷你区块链,掌握了区块、链结构和简单的挖矿逻辑。但是,一个真正的区块链不仅仅是区块堆起来就行,还需要处理交易(tx),保证数据不可篡改,并让节点能够安全达成共识

本篇文章,我们将深入交易设计、区块验证与链安全,手把手用 Go 实现更完整的区块链核心功能。

一、交易(Transaction)设计

在真实的区块链中,交易是区块的核心内容,每一个区块都是交易的集合。

1️⃣ 交易结构

我们可以用 Go 定义一个简单的交易结构:

type Transaction struct {
    ID     []byte
    From   string
    To     string
    Amount float64
}
  • ID:交易哈希,用于唯一标识
  • From/To:转账双方
  • Amount:交易金额

💡 提示:在真实区块链中,交易还需要签名验证、防重放攻击等,这里先简化为演示逻辑。

2️⃣ 生成交易哈希

func HashTransaction(tx Transaction) []byte {
    data := tx.From + "|" + tx.To + "|" + strconv.Itoa(tx.Amount)
    h := sha256.Sum256([]byte(data))
    return h[:]
}

每笔交易通过哈希保证唯一性和完整性,一旦交易被篡改,哈希就会变化。

3️⃣ 交易签名(示例)

func (tx *Transaction) Sign(privKey *ecdsa.PrivateKey) error {
    tx.ID = tx.Hash()
    r, s, err := ecdsa.Sign(rand.Reader, privKey, tx.ID)
    if err != nil {
        return err
    }
    tx.Signature = append(r.Bytes(), s.Bytes()...)
    return nil
}
  • Signature 是发送方私钥生成的签名
  • 节点验证时可以用公钥确认交易合法性

二、交易池(Mempool)

在区块生成前,交易需要存放在交易池中等待打包:

type TxPool struct {
    Transactions []*Transaction
}

func (pool *TxPool) AddTransaction(tx *Transaction) {
    pool.Transactions = append(pool.Transactions, tx)
}
  • 挖矿节点从交易池中挑选交易打包到新区块
  • 可以根据交易手续费、优先级进行排序

🔹 交易池让区块链系统可以异步处理交易,提高效率。

三、区块的交易列表与验证

1️⃣ 区块结构

在上篇文章中,我们的区块只有数据字段,这里增加交易列表:

// Block 区块结构体,代表区块链中的一个区块
type Block struct {
    Index        int      `json:"index"`        // 区块索引(高度)
    Timestamp    int64    `json:"timestamp"`    // 区块生成时间戳
    Transactions []string `json:"transactions"` // 包含的交易ID列表
    PrevHash     string   `json:"prev_hash"`    // 前一个区块的哈希值
    Nonce        int64    `json:"nonce"`        // 工作量证明的随机数
    Hash         string   `json:"hash"`         // 当前区块的哈希值
}

2️⃣ 新增区块时验证交易

新增区块时,需要保证每笔交易有效,例如发送方有足够余额、交易未被篡改。

// VerifyTransaction 验证交易签名的有效性
func VerifyTransaction(tx Transaction) bool {
    pubBytes, err := hex.DecodeString(tx.From)
    if err != nil {
        return false
    }
    x, y := elliptic.Unmarshal(elliptic.P256(), pubBytes)
    if x == nil {
        return false
    }
    pub := ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
    sigBytes, err := hex.DecodeString(tx.Signature)
    if err != nil {
        return false
    }
    h := HashTransaction(tx)
    return ecdsa.VerifyASN1(&pub, h, sigBytes)
}

✅ 提示:这是最基础的验证逻辑,真实链还需要更复杂的数字签名和状态验证。

四、区块链共识机制简述

在去中心化环境中,多个节点可能同时出块,必须有规则确定哪条链才是有效链,这是网络与系统中分布式一致性的经典问题。

  • 工作量证明(PoW):上篇已实现基础挖矿逻辑。
  • 最长链原则:节点总是认同最长的有效链。
// AddBlock 向区块链中添加新区块
func AddBlock(b Block) bool {
    chainMutex.Lock()
    defer chainMutex.Unlock()
    last := blockchain[len(blockchain)-1]

    // 验证区块的前哈希是否正确
    if b.PrevHash != last.Hash {
        return false
    }
    // 验证区块哈希值是否正确
    if CalculateHash(b) != b.Hash {
        return false
    }
    // 验证工作量证明是否有效
    if !strings.HasPrefix(b.Hash, strings.Repeat("0", difficulty)) {
        return false
    }
    blockchain = append(blockchain, b)
    return true
}

当节点接收到新区块时,只要验证交易合法并满足 PoW 条件,就可以加入链中。

五、挖矿与区块奖励

矿工在验证并打包交易后,生成新区块,并获得奖励(挖矿收益):

// CoinbaseTx 创建一个Coinbase交易(挖矿奖励)
// coinbaseData: 区块中包含的额外数据(如矿工信息)
// to: 接收奖励的地址
// amount: 奖励金额
func CoinbaseTx(coinbaseData, to string, amount int) UTXOTx {
    // Coinbase交易没有输入,使用特殊标记
    inputs := []TxInput{
        {
            Txid:      "0", // 特殊标记表示coinbase交易
            Vout:      -1,  // 特殊值
            Signature: coinbaseData,
            PubKey:    "coinbase", // 标记为coinbase
        },
    }
    // 创建输出给矿工的奖励
    outputs := []TxOutput{
        {
            Address: to,
            Amount:  amount,
        },
    }
    return UTXOTx{Inputs: inputs, Outputs: outputs}
}
  • 挖矿奖励通过特殊交易(coinbase)发放
  • 提高节点参与动力

六、简单余额查询示例

结合交易结构,我们可以快速实现账户余额查询:

func (bc *Blockchain) GetBalance(address string) float64 {
    var balance float64
    for _, block := range bc.Blocks {
        for _, tx := range block.Transactions {
            if tx.From == address {
                balance -= tx.Amount
            }
            if tx.To == address {
                balance += tx.Amount
            }
        }
    }
    return balance
}

🔹 这个方法展示了交易在链上的价值流向,也为钱包功能奠定基础。

七、实践总结

通过本篇,我们完成了:

  • 交易结构、哈希与签名的基础设计
  • 交易池(Mempool)的简单管理
  • 区块验证与 PoW 共识机制的集成
  • 挖矿奖励与账户余额的初步计算

这样,我们的迷你区块链不仅能存储数据,还能处理简单的交易逻辑,朝着一个功能更完整的区块链系统又迈进了一步。

您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-3 13:46 , Processed in 0.083686 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表