Go实现简单的区块链和数字签名流程

区块链的工作原理结合了多种技术,每种技术在链条的不同环节中发挥作用:

1. 非对称加密(椭圆曲线加密)

     用于生成钱包地址和数字签名,保证交易的安全性和不可抵赖性。

          • 椭圆曲线算法(ECDSA)生成公私钥对,签署交易。

2. 哈希算法(Hash Function)

     用于将任意长度的数据映射为固定长度的散列值(如 SHA256),确保数据完整性,并实现工作量证明(PoW)。

3. P2P 网络(Peer-to-Peer Network)

     区块链通过 P2P 网络传播和同步数据,节点之间相互连接,不依赖中心服务器。

4. 分布式系统与共识机制

     通过共识机制(如 PoW、PoS)确保所有节点对数据的一致性达成共识,防止双花攻击。

使用 Go 实现集成了非对称加密、哈希算法、P2P 网络和共识机制(PoW)的简单区块链系统。

package main

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/sha256"
    "encoding/hex"
    "fmt"
    "math/big"
    "strings"
    "time"
)

// Block 表示区块链中的单个区块
type Block struct {
    Timestamp    int64  // 区块生成的时间戳
    PreviousHash string // 前一个区块的哈希值
    Hash         string // 当前区块的哈希值
    Data         string // 区块中存储的数据
    Nonce        int    // PoW 的随机数,用于找到符合难度的哈希
}

// 计算区块的哈希值
func (b *Block) calculateHash() string {
    data := fmt.Sprintf("%d%s%s%d", b.Timestamp, b.PreviousHash, b.Data, b.Nonce)
    hash := sha256.Sum256([]byte(data))
    return hex.EncodeToString(hash[:])
}

// 工作量证明 (Proof of Work, PoW) 挖矿
func (b *Block) mineBlock(difficulty int) {
    target := strings.Repeat("0", difficulty)
    for !strings.HasPrefix(b.Hash, target) {
        b.Nonce++
        b.Hash = b.calculateHash()
    }
    fmt.Printf("Block mined: %s\n", b.Hash)
}

// 创建新的区块
func newBlock(data string, previousHash string) *Block {
    block := &Block{time.Now().Unix(), previousHash, "", data, 0}
    block.mineBlock(4) // 设置难度为4
    return block
}

// Blockchain 表示区块链
type Blockchain struct {
    blocks []*Block
}

// 向区块链添加区块
func (bc *Blockchain) addBlock(data string) {
    prevBlock := bc.blocks[len(bc.blocks)-1]
    newBlk := newBlock(data, prevBlock.Hash)
    bc.blocks = append(bc.blocks, newBlk)
}

// 创建创世区块
func createGenesisBlock() *Block {
    return newBlock("Genesis Block", "0")
}

// 初始化区块链
func newBlockchain() *Blockchain {
    return &Blockchain{[]*Block{createGenesisBlock()}}
}

// 生成ECDSA公私钥对
func generateKeys() (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
    privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    return privateKey, &privateKey.PublicKey
}

// 使用私钥对消息签名
func signMessage(privateKey *ecdsa.PrivateKey, message string) ([]byte, []byte) {
    hash := sha256.Sum256([]byte(message))
    r, s, _ := ecdsa.Sign(rand.Reader, privateKey, hash[:])
    return r.Bytes(), s.Bytes()
}

// 验证签名
func verifySignature(publicKey *ecdsa.PublicKey, message string, rBytes, sBytes []byte) bool {
    hash := sha256.Sum256([]byte(message))
    var r, s big.Int
    r.SetBytes(rBytes)
    s.SetBytes(sBytes)
    return ecdsa.Verify(publicKey, hash[:], &r, &s)
}

func main() {
    // 1. 初始化区块链
    blockchain := newBlockchain()

    // 2. 生成公私钥对
    privateKey, publicKey := generateKeys()

    // 3. 签名交易
    message := "Transaction: Alice -> Bob 10 BTC"
    r, s := signMessage(privateKey, message)

    // 4. 验证签名,只有验证通过后才添加到区块链中
    if verifySignature(publicKey, message, r, s) {
        fmt.Println("Signature verified. Adding transaction to the blockchain...")
        signedMessage := fmt.Sprintf("%s\nSignature (r): %x\nSignature (s): %x", message, r, s)
        blockchain.addBlock(signedMessage) // 添加已验证的交易到区块链中
    } else {
        fmt.Println("Invalid signature. Transaction rejected.")
    }

    // 5. 打印区块链信息
    for i, block := range blockchain.blocks {
        fmt.Printf("Block %d:\n", i)
        fmt.Printf("\tTimestamp: %d\n", block.Timestamp)
        fmt.Printf("\tPrevious Hash: %s\n", block.PreviousHash)
        fmt.Printf("\tHash: %s\n", block.Hash)
        fmt.Printf("\tData: %s\n", block.Data)
    }
}

代码解读:

区块链部分:

     • 创建区块 (newBlock) 并通过工作量证明(PoW)机制挖矿。

     • 将新块添加到区块链 (addBlock)。

     • 创世区块是区块链的起点。

• 加密签名部分:

     • 使用椭圆曲线加密 (ECDSA) 生成公私钥。

     • 使用私钥签名消息,公钥验证签名。

运行结果:

     • 区块链会生成两个新块,并输出每个区块的详细信息。

• 最后验证签名是否有效,输出签名验证结果。