{"id":789,"date":"2025-10-28T14:42:00","date_gmt":"2025-10-28T06:42:00","guid":{"rendered":"https:\/\/www.db2go.net\/?p=789"},"modified":"2025-10-29T09:26:36","modified_gmt":"2025-10-29T01:26:36","slug":"%e4%bb%8e%e6%89%8b%e5%86%99%e5%8c%ba%e5%9d%97%e9%93%bedemo%e6%9d%a5%e7%90%86%e8%a7%a3%e5%8c%ba%e5%9d%97%e9%93%be","status":"publish","type":"post","link":"https:\/\/www.db2go.net\/?p=789","title":{"rendered":"\u4ece\u624b\u5199\u533a\u5757\u94fedemo\u6765\u7406\u89e3\u533a\u5757\u94fe"},"content":{"rendered":"<p>\u4e00\u76f4\u60f3\u624b\u5199\u4e00\u6b21\u533a\u5757\u94fe\u6765\u7406\u89e3\uff0c\u7ec8\u4e8e\u8865\u5145\u4e86\u3002<br \/>\n\u9996\u5148\u4e0a\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-go line-numbers\">\/\/ \u533a\u5757\u94feDemo - Go\u8bed\u8a00\u5b9e\u73b0\n\/\/ \u672c\u7a0b\u5e8f\u6f14\u793a\u4e86\u533a\u5757\u94fe\u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5305\u62ec\uff1a\n\/\/ 1. \u533a\u5757\u7ed3\u6784\u548c\u533a\u5757\u94fe\n\/\/ 2. \u5de5\u4f5c\u91cf\u8bc1\u660e(PoW)\u7b97\u6cd5\n\/\/ 3. \u4ea4\u6613\u7cfb\u7edf\n\/\/ 4. \u9ed8\u514b\u5c14\u6811\n\/\/ 5. \u533a\u5757\u94fe\u9a8c\u8bc1\n\npackage main\n\nimport (\n    \"bytes\"         \/\/ \u7528\u4e8e\u5b57\u8282\u64cd\u4f5c\n    \"crypto\/sha256\" \/\/ SHA256\u54c8\u5e0c\u7b97\u6cd5\n    \"encoding\/gob\"  \/\/ Go\u4e8c\u8fdb\u5236\u7f16\u7801\n    \"encoding\/hex\"  \/\/ \u5341\u516d\u8fdb\u5236\u7f16\u7801\n    \"fmt\"           \/\/ \u683c\u5f0f\u5316\u8f93\u51fa\n    \"log\"           \/\/ \u65e5\u5fd7\u8bb0\u5f55\n    \"math\"          \/\/ \u6570\u5b66\u51fd\u6570\n    \"math\/big\"      \/\/ \u5927\u6574\u6570\u8fd0\u7b97\n    \"strconv\"       \/\/ \u5b57\u7b26\u4e32\u8f6c\u6362\n    \"time\"          \/\/ \u65f6\u95f4\u5904\u7406\n)\n\n\/\/ Transaction \u8868\u793a\u4e00\u4e2a\u4ea4\u6613\n\/\/ \u6bcf\u4e2a\u4ea4\u6613\u5305\u542b\u4e00\u4e2a\u552f\u4e00\u7684ID\u3001\u8f93\u5165\u5217\u8868\u548c\u8f93\u51fa\u5217\u8868\ntype Transaction struct {\n    ID   []byte     \/\/ \u4ea4\u6613\u7684\u552f\u4e00\u6807\u8bc6\u7b26\uff08\u54c8\u5e0c\u503c\uff09\n    Vin  []TXInput  \/\/ \u4ea4\u6613\u8f93\u5165\u5217\u8868\n    Vout []TXOutput \/\/ \u4ea4\u6613\u8f93\u51fa\u5217\u8868\n}\n\n\/\/ TXInput \u8868\u793a\u4ea4\u6613\u7684\u8f93\u5165\n\/\/ \u8f93\u5165\u5f15\u7528\u4e4b\u524d\u4ea4\u6613\u7684\u8f93\u51fa\uff0c\u8bc1\u660e\u4f60\u6709\u6743\u82b1\u8d39\u8fd9\u4e9b\u8d44\u91d1\ntype TXInput struct {\n    Txid      []byte \/\/ \u5f15\u7528\u7684\u4ea4\u6613ID\n    Vout      int    \/\/ \u5f15\u7528\u7684\u8f93\u51fa\u7d22\u5f15\n    ScriptSig string \/\/ \u89e3\u9501\u811a\u672c\uff08\u8fd9\u91cc\u7b80\u5316\u4e3a\u5730\u5740\uff09\n}\n\n\/\/ TXOutput \u8868\u793a\u4ea4\u6613\u7684\u8f93\u51fa\n\/\/ \u8f93\u51fa\u6307\u5b9a\u4e86\u8d44\u91d1\u7684\u63a5\u6536\u8005\u548c\u91d1\u989d\ntype TXOutput struct {\n    Value        int    \/\/ \u8f93\u51fa\u7684\u91d1\u989d\n    ScriptPubKey string \/\/ \u9501\u5b9a\u811a\u672c\uff08\u8fd9\u91cc\u7b80\u5316\u4e3a\u63a5\u6536\u8005\u5730\u5740\uff09\n}\n\n\/\/ Block \u8868\u793a\u533a\u5757\u94fe\u4e2d\u7684\u4e00\u4e2a\u533a\u5757\n\/\/ \u6bcf\u4e2a\u533a\u5757\u5305\u542b\u591a\u4e2a\u4ea4\u6613\uff0c\u5e76\u901a\u8fc7\u54c8\u5e0c\u4e0e\u524d\u4e00\u4e2a\u533a\u5757\u94fe\u63a5\ntype Block struct {\n    Timestamp     int64          \/\/ \u533a\u5757\u521b\u5efa\u65f6\u95f4\u6233\n    Transactions  []*Transaction \/\/ \u533a\u5757\u4e2d\u5305\u542b\u7684\u4ea4\u6613\u5217\u8868\n    PrevBlockHash []byte         \/\/ \u524d\u4e00\u4e2a\u533a\u5757\u7684\u54c8\u5e0c\u503c\n    Hash          []byte         \/\/ \u5f53\u524d\u533a\u5757\u7684\u54c8\u5e0c\u503c\n    Nonce         int            \/\/ \u5de5\u4f5c\u91cf\u8bc1\u660e\u7684\u968f\u673a\u6570\n}\n\n\/\/ Blockchain \u8868\u793a\u6574\u4e2a\u533a\u5757\u94fe\n\/\/ \u533a\u5757\u94fe\u662f\u4e00\u4e2a\u6309\u65f6\u95f4\u987a\u5e8f\u6392\u5217\u7684\u533a\u5757\u5217\u8868\ntype Blockchain struct {\n    blocks []*Block \/\/ \u533a\u5757\u5217\u8868\n}\n\n\/\/ NewBlock \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u533a\u5757\n\/\/ \u901a\u8fc7\u5de5\u4f5c\u91cf\u8bc1\u660e\u7b97\u6cd5\u8ba1\u7b97\u533a\u5757\u54c8\u5e0c\nfunc NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {\n    \/\/ \u521b\u5efa\u65b0\u533a\u5757\uff0c\u521d\u59cb\u54c8\u5e0c\u4e3a\u7a7a\n    block := &amp;Block{\n        Timestamp:     time.Now().Unix(), \/\/ \u5f53\u524d\u65f6\u95f4\u6233\n        Transactions:  transactions,      \/\/ \u4ea4\u6613\u5217\u8868\n        PrevBlockHash: prevBlockHash,     \/\/ \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c\n        Hash:          []byte{},          \/\/ \u5f53\u524d\u533a\u5757\u54c8\u5e0c\uff08\u5f85\u8ba1\u7b97\uff09\n        Nonce:         0,                 \/\/ \u968f\u673a\u6570\uff08\u5f85\u8ba1\u7b97\uff09\n    }\n\n    \/\/ \u521b\u5efa\u5de5\u4f5c\u91cf\u8bc1\u660e\u5bf9\u8c61\u5e76\u8fd0\u884c\u6316\u77ff\u7b97\u6cd5\n    pow := NewProofOfWork(block)\n    nonce, hash := pow.Run()\n\n    \/\/ \u8bbe\u7f6e\u8ba1\u7b97\u51fa\u7684\u54c8\u5e0c\u548c\u968f\u673a\u6570\n    block.Hash = hash[:]\n    block.Nonce = nonce\n\n    return block\n}\n\n\/\/ NewGenesisBlock \u521b\u5efa\u521b\u4e16\u533a\u5757\n\/\/ \u521b\u4e16\u533a\u5757\u662f\u533a\u5757\u94fe\u7684\u7b2c\u4e00\u4e2a\u533a\u5757\uff0c\u6ca1\u6709\u524d\u4e00\u4e2a\u533a\u5757\nfunc NewGenesisBlock(coinbase *Transaction) *Block {\n    return NewBlock([]*Transaction{coinbase}, []byte{})\n}\n\n\/\/ NewBlockchain \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u533a\u5757\u94fe\n\/\/ \u521d\u59cb\u5316\u65f6\u521b\u5efa\u5305\u542b\u521b\u4e16\u533a\u5757\u7684\u533a\u5757\u94fe\nfunc NewBlockchain() *Blockchain {\n    return &amp;Blockchain{[]*Block{NewGenesisBlock(NewCoinbaseTX(\"genesis\", \"\"))}}\n}\n\n\/\/ AddBlock \u5411\u533a\u5757\u94fe\u6dfb\u52a0\u65b0\u533a\u5757\n\/\/ \u65b0\u533a\u5757\u7684\u54c8\u5e0c\u57fa\u4e8e\u524d\u4e00\u4e2a\u533a\u5757\u7684\u54c8\u5e0c\u8ba1\u7b97\nfunc (bc *Blockchain) AddBlock(transactions []*Transaction) {\n    prevBlock := bc.blocks[len(bc.blocks)-1]           \/\/ \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u533a\u5757\n    newBlock := NewBlock(transactions, prevBlock.Hash) \/\/ \u521b\u5efa\u65b0\u533a\u5757\n    bc.blocks = append(bc.blocks, newBlock)            \/\/ \u6dfb\u52a0\u5230\u533a\u5757\u94fe\n}\n\n\/\/ HashTransactions \u8ba1\u7b97\u533a\u5757\u4e2d\u6240\u6709\u4ea4\u6613\u7684\u54c8\u5e0c\n\/\/ \u4f7f\u7528\u9ed8\u514b\u5c14\u6811\u6765\u9ad8\u6548\u5730\u8ba1\u7b97\u6240\u6709\u4ea4\u6613\u7684\u6839\u54c8\u5e0c\nfunc (b *Block) HashTransactions() []byte {\n    var txHashes [][]byte\n\n    \/\/ \u6536\u96c6\u6240\u6709\u4ea4\u6613\u7684ID\n    for _, tx := range b.Transactions {\n        txHashes = append(txHashes, tx.ID)\n    }\n\n    \/\/ \u521b\u5efa\u9ed8\u514b\u5c14\u6811\u5e76\u8fd4\u56de\u6839\u8282\u70b9\u54c8\u5e0c\n    tree := NewMerkleTree(txHashes)\n    return tree.RootNode.Data\n}\n\n\/\/ Serialize \u5e8f\u5217\u5316\u533a\u5757\n\/\/ \u5c06\u533a\u5757\u8f6c\u6362\u4e3a\u5b57\u8282\u6570\u7ec4\uff0c\u7528\u4e8e\u5b58\u50a8\u6216\u4f20\u8f93\nfunc (b *Block) Serialize() []byte {\n    var result bytes.Buffer\n    encoder := gob.NewEncoder(&amp;result)\n\n    err := encoder.Encode(b)\n    if err != nil {\n        log.Panic(err)\n    }\n\n    return result.Bytes()\n}\n\n\/\/ DeserializeBlock \u53cd\u5e8f\u5217\u5316\u533a\u5757\n\/\/ \u4ece\u5b57\u8282\u6570\u7ec4\u6062\u590d\u533a\u5757\u5bf9\u8c61\nfunc DeserializeBlock(d []byte) *Block {\n    var block Block\n\n    decoder := gob.NewDecoder(bytes.NewReader(d))\n    err := decoder.Decode(&amp;block)\n    if err != nil {\n        log.Panic(err)\n    }\n\n    return &amp;block\n}\n\n\/\/ SetID \u8bbe\u7f6e\u4ea4\u6613\u7684ID\n\/\/ \u901a\u8fc7\u5e8f\u5217\u5316\u4ea4\u6613\u5185\u5bb9\u5e76\u8ba1\u7b97SHA256\u54c8\u5e0c\u6765\u751f\u6210\u4ea4\u6613ID\nfunc (tx *Transaction) SetID() {\n    var encoded bytes.Buffer\n    var hash [32]byte\n\n    \/\/ \u5e8f\u5217\u5316\u4ea4\u6613\u5185\u5bb9\n    enc := gob.NewEncoder(&amp;encoded)\n    err := enc.Encode(tx)\n    if err != nil {\n        log.Panic(err)\n    }\n\n    \/\/ \u8ba1\u7b97SHA256\u54c8\u5e0c\n    hash = sha256.Sum256(encoded.Bytes())\n    tx.ID = hash[:]\n}\n\n\/\/ NewCoinbaseTX \u521b\u5efacoinbase\u4ea4\u6613\n\/\/ Coinbase\u4ea4\u6613\u662f\u77ff\u5de5\u5956\u52b1\u4ea4\u6613\uff0c\u6ca1\u6709\u8f93\u5165\uff0c\u53ea\u6709\u8f93\u51fa\nfunc NewCoinbaseTX(to, data string) *Transaction {\n    \/\/ \u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u6570\u636e\uff0c\u4f7f\u7528\u9ed8\u8ba4\u683c\u5f0f\n    if data == \"\" {\n        data = fmt.Sprintf(\"Reward to '%s'\", to)\n    }\n\n    \/\/ \u521b\u5efacoinbase\u4ea4\u6613\u7684\u8f93\u5165\uff08Txid\u4e3a\u7a7a\uff0cVout\u4e3a-1\u8868\u793acoinbase\uff09\n    txin := TXInput{[]byte{}, -1, data}\n    \/\/ \u521b\u5efa\u8f93\u51fa\uff08\u5956\u52b1100\u4e2a\u5e01\u7ed9\u6307\u5b9a\u5730\u5740\uff09\n    txout := TXOutput{100, to}\n\n    \/\/ \u521b\u5efa\u4ea4\u6613\u5e76\u8bbe\u7f6eID\n    tx := Transaction{nil, []TXInput{txin}, []TXOutput{txout}}\n    tx.SetID()\n\n    return &amp;tx\n}\n\n\/\/ NewTransaction \u521b\u5efa\u65b0\u4ea4\u6613\n\/\/ \u4ece\u6307\u5b9a\u5730\u5740\u5411\u76ee\u6807\u5730\u5740\u8f6c\u8d26\u6307\u5b9a\u91d1\u989d\nfunc NewTransaction(from, to string, amount int, bc *Blockchain) *Transaction {\n    var inputs []TXInput\n    var outputs []TXOutput\n\n    \/\/ \u67e5\u627e\u53d1\u9001\u8005\u7684\u53ef\u82b1\u8d39\u8f93\u51fa\n    acc, validOutputs := bc.FindSpendableOutputs(from, amount)\n\n    \/\/ \u68c0\u67e5\u4f59\u989d\u662f\u5426\u8db3\u591f\n    if acc &lt; amount {\n        log.Panic(\"ERROR: Not enough funds\")\n    }\n\n    \/\/ \u521b\u5efa\u4ea4\u6613\u8f93\u5165\n    for txid, outs := range validOutputs {\n        txID, err := hex.DecodeString(txid)\n        if err != nil {\n            log.Panic(err)\n        }\n\n        for _, out := range outs {\n            input := TXInput{txID, out, from}\n            inputs = append(inputs, input)\n        }\n    }\n\n    \/\/ \u521b\u5efa\u4ea4\u6613\u8f93\u51fa\n    outputs = append(outputs, TXOutput{amount, to})\n    \/\/ \u5982\u679c\u6709\u627e\u96f6\uff0c\u521b\u5efa\u627e\u96f6\u8f93\u51fa\n    if acc &gt; amount {\n        outputs = append(outputs, TXOutput{acc - amount, from})\n    }\n\n    \/\/ \u521b\u5efa\u4ea4\u6613\u5e76\u8bbe\u7f6eID\n    tx := Transaction{nil, inputs, outputs}\n    tx.SetID()\n\n    return &amp;tx\n}\n\n\/\/ FindSpendableOutputs \u67e5\u627e\u53ef\u82b1\u8d39\u7684\u8f93\u51fa\n\/\/ \u8fd4\u56de\u6307\u5b9a\u5730\u5740\u7684\u53ef\u7528\u4f59\u989d\u548c\u5bf9\u5e94\u7684\u672a\u82b1\u8d39\u8f93\u51fa\nfunc (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map[string][]int) {\n    unspentOutputs := make(map[string][]int)\n    unspentTXs := bc.FindUnspentTransactions(address)\n    accumulated := 0\n\n    \/\/ \u904d\u5386\u672a\u82b1\u8d39\u4ea4\u6613\uff0c\u7d2f\u79ef\u91d1\u989d\u76f4\u5230\u6ee1\u8db3\u9700\u6c42\nWork:\n    for _, tx := range unspentTXs {\n        txID := hex.EncodeToString(tx.ID)\n\n        for outIdx, out := range tx.Vout {\n            if out.CanBeUnlockedWith(address) &amp;&amp; accumulated &lt; amount {\n                accumulated += out.Value\n                unspentOutputs[txID] = append(unspentOutputs[txID], outIdx)\n\n                \/\/ \u5982\u679c\u7d2f\u79ef\u91d1\u989d\u8db3\u591f\uff0c\u505c\u6b62\u67e5\u627e\n                if accumulated &gt;= amount {\n                    break Work\n                }\n            }\n        }\n    }\n\n    return accumulated, unspentOutputs\n}\n\n\/\/ FindUnspentTransactions \u67e5\u627e\u672a\u82b1\u8d39\u7684\u4ea4\u6613\n\/\/ \u4ece\u6700\u65b0\u533a\u5757\u5f00\u59cb\u5411\u524d\u904d\u5386\uff0c\u627e\u51fa\u6307\u5b9a\u5730\u5740\u7684\u6240\u6709\u672a\u82b1\u8d39\u4ea4\u6613\nfunc (bc *Blockchain) FindUnspentTransactions(address string) []Transaction {\n    var unspentTXs []Transaction\n    spentTXOs := make(map[string][]int) \/\/ \u8bb0\u5f55\u5df2\u82b1\u8d39\u7684\u8f93\u51fa\n    bci := bc.Iterator()\n\n    \/\/ \u4ece\u6700\u65b0\u533a\u5757\u5f00\u59cb\u5411\u524d\u904d\u5386\n    for {\n        block := bci.Next()\n\n        \/\/ \u904d\u5386\u533a\u5757\u4e2d\u7684\u6bcf\u4e2a\u4ea4\u6613\n        for _, tx := range block.Transactions {\n            txID := hex.EncodeToString(tx.ID)\n\n        Outputs:\n            \/\/ \u68c0\u67e5\u4ea4\u6613\u8f93\u51fa\n            for outIdx, out := range tx.Vout {\n                \/\/ \u8df3\u8fc7\u5df2\u82b1\u8d39\u7684\u8f93\u51fa\n                if spentTXOs[txID] != nil {\n                    for _, spentOutIdx := range spentTXOs[txID] {\n                        if spentOutIdx == outIdx {\n                            continue Outputs\n                        }\n                    }\n                }\n\n                \/\/ \u5982\u679c\u8f93\u51fa\u53ef\u4ee5\u88ab\u6307\u5b9a\u5730\u5740\u89e3\u9501\uff0c\u6dfb\u52a0\u5230\u672a\u82b1\u8d39\u5217\u8868\n                if out.CanBeUnlockedWith(address) {\n                    unspentTXs = append(unspentTXs, *tx)\n                }\n            }\n\n            \/\/ \u5982\u679c\u4e0d\u662fcoinbase\u4ea4\u6613\uff0c\u8bb0\u5f55\u5df2\u82b1\u8d39\u7684\u8f93\u51fa\n            if !tx.IsCoinbase() {\n                for _, in := range tx.Vin {\n                    if in.CanUnlockOutputWith(address) {\n                        inTxID := hex.EncodeToString(in.Txid)\n                        spentTXOs[inTxID] = append(spentTXOs[inTxID], in.Vout)\n                    }\n                }\n            }\n        }\n\n        \/\/ \u5982\u679c\u5230\u8fbe\u521b\u4e16\u533a\u5757\uff0c\u505c\u6b62\u904d\u5386\n        if len(block.PrevBlockHash) == 0 {\n            break\n        }\n    }\n\n    return unspentTXs\n}\n\n\/\/ Iterator \u521b\u5efa\u533a\u5757\u94fe\u8fed\u4ee3\u5668\n\/\/ \u7528\u4e8e\u4ece\u6700\u65b0\u533a\u5757\u5f00\u59cb\u5411\u524d\u904d\u5386\u533a\u5757\u94fe\nfunc (bc *Blockchain) Iterator() *BlockchainIterator {\n    bci := &amp;BlockchainIterator{[]byte{}, len(bc.blocks) - 1, bc}\n    return bci\n}\n\n\/\/ BlockchainIterator \u533a\u5757\u94fe\u8fed\u4ee3\u5668\n\/\/ \u7528\u4e8e\u904d\u5386\u533a\u5757\u94fe\u4e2d\u7684\u533a\u5757\ntype BlockchainIterator struct {\n    currentHash []byte      \/\/ \u5f53\u524d\u533a\u5757\u54c8\u5e0c\n    current     int         \/\/ \u5f53\u524d\u533a\u5757\u7d22\u5f15\n    bc          *Blockchain \/\/ \u533a\u5757\u94fe\u5f15\u7528\n}\n\n\/\/ Next \u8fd4\u56de\u4e0b\u4e00\u4e2a\u533a\u5757\n\/\/ \u4ece\u6700\u65b0\u533a\u5757\u5f00\u59cb\u5411\u524d\u904d\u5386\nfunc (i *BlockchainIterator) Next() *Block {\n    block := i.bc.blocks[i.current]\n    i.currentHash = block.Hash\n    i.current-- \/\/ \u5411\u524d\u79fb\u52a8\n    return block\n}\n\n\/\/ CanUnlockOutputWith \u68c0\u67e5\u8f93\u5165\u662f\u5426\u53ef\u4ee5\u89e3\u9501\u8f93\u51fa\n\/\/ \u9a8c\u8bc1\u89e3\u9501\u811a\u672c\u662f\u5426\u5339\u914d\nfunc (in *TXInput) CanUnlockOutputWith(unlockingData string) bool {\n    return in.ScriptSig == unlockingData\n}\n\n\/\/ CanBeUnlockedWith \u68c0\u67e5\u8f93\u51fa\u662f\u5426\u53ef\u4ee5\u88ab\u89e3\u9501\n\/\/ \u9a8c\u8bc1\u9501\u5b9a\u811a\u672c\u662f\u5426\u5339\u914d\nfunc (out *TXOutput) CanBeUnlockedWith(unlockingData string) bool {\n    return out.ScriptPubKey == unlockingData\n}\n\n\/\/ IsCoinbase \u68c0\u67e5\u662f\u5426\u662fcoinbase\u4ea4\u6613\n\/\/ Coinbase\u4ea4\u6613\u7684\u7279\u5f81\uff1a\u53ea\u6709\u4e00\u4e2a\u8f93\u5165\uff0c\u4e14Txid\u4e3a\u7a7a\uff0cVout\u4e3a-1\nfunc (tx *Transaction) IsCoinbase() bool {\n    return len(tx.Vin) == 1 &amp;&amp; len(tx.Vin[0].Txid) == 0 &amp;&amp; tx.Vin[0].Vout == -1\n}\n\n\/\/ MerkleTree \u9ed8\u514b\u5c14\u6811\n\/\/ \u7528\u4e8e\u9ad8\u6548\u5730\u9a8c\u8bc1\u533a\u5757\u4e2d\u7684\u4ea4\u6613\ntype MerkleTree struct {\n    RootNode *MerkleNode \/\/ \u6839\u8282\u70b9\n}\n\n\/\/ MerkleNode \u9ed8\u514b\u5c14\u6811\u8282\u70b9\n\/\/ \u6bcf\u4e2a\u8282\u70b9\u5305\u542b\u5de6\u53f3\u5b50\u8282\u70b9\u548c\u6570\u636e\ntype MerkleNode struct {\n    Left  *MerkleNode \/\/ \u5de6\u5b50\u8282\u70b9\n    Right *MerkleNode \/\/ \u53f3\u5b50\u8282\u70b9\n    Data  []byte      \/\/ \u8282\u70b9\u6570\u636e\uff08\u54c8\u5e0c\u503c\uff09\n}\n\n\/\/ NewMerkleNode \u521b\u5efa\u9ed8\u514b\u5c14\u6811\u8282\u70b9\n\/\/ \u5982\u679c\u662f\u53f6\u5b50\u8282\u70b9\uff0c\u76f4\u63a5\u8ba1\u7b97\u6570\u636e\u7684\u54c8\u5e0c\n\/\/ \u5982\u679c\u662f\u5185\u90e8\u8282\u70b9\uff0c\u8ba1\u7b97\u5de6\u53f3\u5b50\u8282\u70b9\u6570\u636e\u7684\u7ec4\u5408\u54c8\u5e0c\nfunc NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode {\n    node := MerkleNode{}\n\n    if left == nil &amp;&amp; right == nil {\n        \/\/ \u53f6\u5b50\u8282\u70b9\uff1a\u76f4\u63a5\u8ba1\u7b97\u6570\u636e\u7684\u54c8\u5e0c\n        hash := sha256.Sum256(data)\n        node.Data = hash[:]\n    } else {\n        \/\/ \u5185\u90e8\u8282\u70b9\uff1a\u8ba1\u7b97\u5de6\u53f3\u5b50\u8282\u70b9\u6570\u636e\u7684\u7ec4\u5408\u54c8\u5e0c\n        prevHashes := append(left.Data, right.Data...)\n        hash := sha256.Sum256(prevHashes)\n        node.Data = hash[:]\n    }\n\n    node.Left = left\n    node.Right = right\n\n    return &amp;node\n}\n\n\/\/ NewMerkleTree \u521b\u5efa\u9ed8\u514b\u5c14\u6811\n\/\/ \u4ece\u4ea4\u6613\u54c8\u5e0c\u5217\u8868\u6784\u5efa\u5b8c\u6574\u7684\u9ed8\u514b\u5c14\u6811\nfunc NewMerkleTree(data [][]byte) *MerkleTree {\n    var nodes []MerkleNode\n\n    \/\/ \u521b\u5efa\u53f6\u5b50\u8282\u70b9\n    for _, datum := range data {\n        node := NewMerkleNode(nil, nil, datum)\n        nodes = append(nodes, *node)\n    }\n\n    \/\/ \u9010\u5c42\u6784\u5efa\u6811\uff0c\u76f4\u5230\u53ea\u5269\u4e00\u4e2a\u6839\u8282\u70b9\n    for len(nodes) &gt; 1 {\n        var level []MerkleNode\n\n        \/\/ \u6bcf\u4e24\u4e2a\u8282\u70b9\u5408\u5e76\u4e3a\u4e00\u4e2a\u7236\u8282\u70b9\n        for i := 0; i &lt; len(nodes); i += 2 {\n            if i+1 == len(nodes) {\n                \/\/ \u5982\u679c\u8282\u70b9\u6570\u4e3a\u5947\u6570\uff0c\u6700\u540e\u4e00\u4e2a\u8282\u70b9\u76f4\u63a5\u590d\u5236\n                level = append(level, nodes[i])\n                continue\n            }\n\n            node := NewMerkleNode(&amp;nodes[i], &amp;nodes[i+1], nil)\n            level = append(level, *node)\n        }\n\n        nodes = level\n    }\n\n    tree := MerkleTree{&amp;nodes[0]}\n    return &amp;tree\n}\n\n\/\/ ProofOfWork \u5de5\u4f5c\u91cf\u8bc1\u660e\n\/\/ \u7528\u4e8e\u6316\u77ff\u548c\u9a8c\u8bc1\u533a\u5757\u7684\u6709\u6548\u6027\ntype ProofOfWork struct {\n    block  *Block   \/\/ \u8981\u6316\u77ff\u7684\u533a\u5757\n    target *big.Int \/\/ \u76ee\u6807\u96be\u5ea6\uff08\u54c8\u5e0c\u503c\u5fc5\u987b\u5c0f\u4e8e\u6b64\u503c\uff09\n}\n\n\/\/ NewProofOfWork \u521b\u5efa\u5de5\u4f5c\u91cf\u8bc1\u660e\n\/\/ \u8bbe\u7f6e\u76ee\u6807\u96be\u5ea6\u4e3a24\u4f4d\uff08\u524d3\u4e2a\u5b57\u8282\u4e3a0\uff09\nfunc NewProofOfWork(b *Block) *ProofOfWork {\n    target := big.NewInt(1)\n    target.Lsh(target, uint(256-targetBits)) \/\/ \u5de6\u79fb232\u4f4d\uff0c\u76f8\u5f53\u4e8e\u524d24\u4f4d\u4e3a0\n\n    pow := &amp;ProofOfWork{b, target}\n    return pow\n}\n\n\/\/ prepareData \u51c6\u5907\u6570\u636e\n\/\/ \u5c06\u533a\u5757\u6570\u636e\u7ec4\u5408\u6210\u7528\u4e8e\u54c8\u5e0c\u8ba1\u7b97\u7684\u5b57\u8282\u6570\u7ec4\nfunc (pow *ProofOfWork) prepareData(nonce int) []byte {\n    data := bytes.Join(\n        [][]byte{\n            pow.block.PrevBlockHash,       \/\/ \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c\n            pow.block.HashTransactions(),  \/\/ \u4ea4\u6613\u54c8\u5e0c\uff08\u9ed8\u514b\u5c14\u6839\uff09\n            IntToHex(pow.block.Timestamp), \/\/ \u65f6\u95f4\u6233\n            IntToHex(int64(targetBits)),   \/\/ \u76ee\u6807\u96be\u5ea6\n            IntToHex(int64(nonce)),        \/\/ \u968f\u673a\u6570\n        },\n        []byte{},\n    )\n\n    return data\n}\n\n\/\/ Run \u8fd0\u884c\u5de5\u4f5c\u91cf\u8bc1\u660e\n\/\/ \u901a\u8fc7\u4e0d\u65ad\u8c03\u6574nonce\u503c\u6765\u5bfb\u627e\u6709\u6548\u7684\u54c8\u5e0c\nfunc (pow *ProofOfWork) Run() (int, []byte) {\n    var hashInt big.Int\n    var hash [32]byte\n    nonce := 0\n\n    fmt.Printf(\"Mining the block containing \\\"%s\\\"\\n\", pow.block.Transactions[0].Vout[0].ScriptPubKey)\n\n    \/\/ \u4e0d\u65ad\u5c1d\u8bd5\u4e0d\u540c\u7684nonce\u503c\n    for nonce &lt; maxNonce {\n        data := pow.prepareData(nonce)\n        hash = sha256.Sum256(data)\n        fmt.Printf(\"\\r%x\", hash)\n        hashInt.SetBytes(hash[:])\n\n        \/\/ \u68c0\u67e5\u54c8\u5e0c\u662f\u5426\u5c0f\u4e8e\u76ee\u6807\u503c\n        if hashInt.Cmp(pow.target) == -1 {\n            break\n        } else {\n            nonce++\n        }\n    }\n    fmt.Print(\"\\n\\n\")\n\n    return nonce, hash[:]\n}\n\n\/\/ Validate \u9a8c\u8bc1\u5de5\u4f5c\u91cf\u8bc1\u660e\n\/\/ \u9a8c\u8bc1\u533a\u5757\u7684nonce\u503c\u662f\u5426\u4ea7\u751f\u6709\u6548\u7684\u54c8\u5e0c\nfunc (pow *ProofOfWork) Validate() bool {\n    var hashInt big.Int\n\n    data := pow.prepareData(pow.block.Nonce)\n    hash := sha256.Sum256(data)\n    hashInt.SetBytes(hash[:])\n\n    isValid := hashInt.Cmp(pow.target) == -1\n    return isValid\n}\n\n\/\/ IntToHex \u5c06\u6574\u6570\u8f6c\u6362\u4e3a\u5341\u516d\u8fdb\u5236\n\/\/ \u7528\u4e8e\u5c06\u6570\u503c\u8f6c\u6362\u4e3a\u5b57\u8282\u6570\u7ec4\nfunc IntToHex(n int64) []byte {\n    return []byte(strconv.FormatInt(n, 16))\n}\n\n\/\/ \u5e38\u91cf\u5b9a\u4e49\nconst targetBits = 16          \/\/ \u76ee\u6807\u96be\u5ea6\u4f4d\u6570\uff08\u524d16\u4f4d\u5fc5\u987b\u4e3a0\uff09\nconst maxNonce = math.MaxInt64 \/\/ \u6700\u5927nonce\u503c\n\n\/\/ main \u4e3b\u51fd\u6570\n\/\/ \u6f14\u793a\u533a\u5757\u94fe\u7684\u57fa\u672c\u529f\u80fd\nfunc main() {\n    fmt.Println(\"=== \u533a\u5757\u94feDemo\u6f14\u793a ===\")\n    fmt.Println(\"\u6b63\u5728\u521b\u5efa\u533a\u5757\u94fe...\")\n\n    \/\/ \u521b\u5efa\u65b0\u7684\u533a\u5757\u94fe\uff08\u5305\u542b\u521b\u4e16\u533a\u5757\uff09\n    bc := NewBlockchain()\n\n    \/\/ \u6dfb\u52a0\u4e00\u4e9b\u7b80\u5355\u7684coinbase\u4ea4\u6613\u6765\u6f14\u793a\n    fmt.Println(\"\u6b63\u5728\u6dfb\u52a0\u533a\u5757...\")\n    bc.AddBlock([]*Transaction{NewCoinbaseTX(\"\u5f20\u4e09\", \"\u5956\u52b1\u7ed9\u5f20\u4e09\")})\n    bc.AddBlock([]*Transaction{NewCoinbaseTX(\"\u674e\u56db\", \"\u5956\u52b1\u7ed9\u674e\u56db\")})\n\n    \/\/ \u6253\u5370\u533a\u5757\u94fe\u4fe1\u606f\n    fmt.Println(\"\\n=== \u533a\u5757\u94fe\u4fe1\u606f ===\")\n    for i, block := range bc.blocks {\n        fmt.Printf(\"\u533a\u5757 %d:\\n\", i)\n        fmt.Printf(\"  \u65f6\u95f4\u6233: %d\\n\", block.Timestamp)\n        fmt.Printf(\"  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: %x\\n\", block.PrevBlockHash)\n        fmt.Printf(\"  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: %x\\n\", block.Hash)\n        fmt.Printf(\"  \u968f\u673a\u6570: %d\\n\", block.Nonce)\n        fmt.Printf(\"  \u4ea4\u6613\u6570\u91cf: %d\\n\", len(block.Transactions))\n\n        \/\/ \u6253\u5370\u4ea4\u6613\u8be6\u60c5\n        for j, tx := range block.Transactions {\n            fmt.Printf(\"    \u4ea4\u6613 %d: %x\\n\", j, tx.ID)\n            if tx.IsCoinbase() {\n                fmt.Printf(\"      \u7c7b\u578b: Coinbase\u4ea4\u6613\\n\")\n                fmt.Printf(\"      \u63a5\u6536\u8005: %s\\n\", tx.Vout[0].ScriptPubKey)\n                fmt.Printf(\"      \u91d1\u989d: %d\\n\", tx.Vout[0].Value)\n            }\n        }\n        fmt.Println()\n    }\n\n    \/\/ \u9a8c\u8bc1\u533a\u5757\u94fe\n    fmt.Println(\"=== \u9a8c\u8bc1\u533a\u5757\u94fe ===\")\n    for i, block := range bc.blocks {\n        pow := NewProofOfWork(block)\n        fmt.Printf(\"\u533a\u5757 %d \u9a8c\u8bc1\u7ed3\u679c: %t\\n\", i, pow.Validate())\n    }\n\n    \/\/ \u6f14\u793a\u9ed8\u514b\u5c14\u6811\n    fmt.Println(\"\\n=== \u9ed8\u514b\u5c14\u6811\u6f14\u793a ===\")\n    if len(bc.blocks) &gt; 0 {\n        block := bc.blocks[0]\n        txHashes := make([][]byte, len(block.Transactions))\n        for i, tx := range block.Transactions {\n            txHashes[i] = tx.ID\n        }\n        merkleTree := NewMerkleTree(txHashes)\n        fmt.Printf(\"\u9ed8\u514b\u5c14\u6839\u54c8\u5e0c: %x\\n\", merkleTree.RootNode.Data)\n    }\n\n    fmt.Println(\"\\n=== \u6f14\u793a\u5b8c\u6210 ===\")\n}\n\n<\/code><\/pre>\n<h2>\u5173\u952e\u4ee3\u7801\u5206\u6790<\/h2>\n<h3>\u00a01.\u00a0\u6838\u5fc3\u6570\u636e\u7ed3\u6784<\/h3>\n<h4>\u4ea4\u6613\u7ed3\u6784 (Transaction)<\/h4>\n<pre><code class=\"language-go line-numbers\">type Transaction struct {\n    ID   []byte     \/\/ \u4ea4\u6613\u54c8\u5e0cID\n    Vin  []TXInput  \/\/ \u4ea4\u6613\u8f93\u5165\uff08\u8d44\u91d1\u6765\u6e90\uff09\n    Vout []TXOutput \/\/ \u4ea4\u6613\u8f93\u51fa\uff08\u8d44\u91d1\u53bb\u5411\uff09\n}\n<\/code><\/pre>\n<h4>\u533a\u5757\u7ed3\u6784 (Block)<\/h4>\n<pre><code class=\"language-go line-numbers\">type Block struct {\n    Timestamp     int64          \/\/ \u65f6\u95f4\u6233\n    Transactions  []*Transaction \/\/ \u4ea4\u6613\u5217\u8868\n    PrevBlockHash []byte         \/\/ \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c\uff08\u94fe\u5f0f\u7ed3\u6784\uff09\n    Hash          []byte         \/\/ \u5f53\u524d\u533a\u5757\u54c8\u5e0c\n    Nonce         int            \/\/ \u5de5\u4f5c\u91cf\u8bc1\u660e\u968f\u673a\u6570\n}\n<\/code><\/pre>\n<h3>2. \u5173\u952e\u6d41\u7a0b<\/h3>\n<h4>\u6d41\u7a0b1: \u533a\u5757\u94fe\u521d\u59cb\u5316<\/h4>\n<pre><code class=\"language-go line-numbers\">func NewBlockchain() *Blockchain {\n    \/\/ \u521b\u5efa\u5305\u542b\u521b\u4e16\u533a\u5757\u7684\u533a\u5757\u94fe\n    return &amp;Blockchain{[]*Block{NewGenesisBlock(NewCoinbaseTX(\"genesis\", \"\"))}}\n}\n<\/code><\/pre>\n<h4>\u6d41\u7a0b2: \u521b\u5efa\u65b0\u533a\u5757<\/h4>\n<pre><code class=\"language-go line-numbers\">func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block {\n    \/\/ 1. \u521b\u5efa\u533a\u5757\u7ed3\u6784\n    block := &amp;Block{\n        Timestamp:     time.Now().Unix(),\n        Transactions:  transactions,\n        PrevBlockHash: prevBlockHash,\n        Hash:          []byte{},  \/\/ \u5f85\u8ba1\u7b97\n        Nonce:         0,         \/\/ \u5f85\u8ba1\u7b97\n    }\n\n    \/\/ 2. \u5de5\u4f5c\u91cf\u8bc1\u660e\u6316\u77ff\n    pow := NewProofOfWork(block)\n    nonce, hash := pow.Run()\n\n    \/\/ 3. \u8bbe\u7f6e\u6316\u77ff\u7ed3\u679c\n    block.Hash = hash[:]\n    block.Nonce = nonce\n\n    return block\n}\n<\/code><\/pre>\n<h4>\u6d41\u7a0b3: \u5de5\u4f5c\u91cf\u8bc1\u660e\u6316\u77ff<\/h4>\n<pre><code class=\"language-go line-numbers\">func (pow *ProofOfWork) Run() (int, []byte) {\n    var hashInt big.Int\n    var hash [32]byte\n    nonce := 0\n\n    \/\/ \u4e0d\u65ad\u5c1d\u8bd5\u4e0d\u540c\u7684nonce\u503c\n    for nonce &lt; maxNonce {\n        data := pow.prepareData(nonce)\n        hash = sha256.Sum256(data)  \/\/ \u8ba1\u7b97SHA256\u54c8\u5e0c\n        hashInt.SetBytes(hash[:])\n\n        \/\/ \u68c0\u67e5\u662f\u5426\u6ee1\u8db3\u96be\u5ea6\u8981\u6c42\uff08\u524d16\u4f4d\u4e3a0\uff09\n        if hashInt.Cmp(pow.target) == -1 {\n            break  \/\/ \u6316\u77ff\u6210\u529f\n        } else {\n            nonce++  \/\/ \u7ee7\u7eed\u5c1d\u8bd5\n        }\n    }\n\n    return nonce, hash[:]\n}\n<\/code><\/pre>\n<h4>\u6d41\u7a0b4: \u6dfb\u52a0\u533a\u5757\u5230\u94fe<\/h4>\n<pre><code class=\"language-go line-numbers\">func (bc *Blockchain) AddBlock(transactions []*Transaction) {\n    prevBlock := bc.blocks[len(bc.blocks)-1]           \/\/ \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u533a\u5757\n    newBlock := NewBlock(transactions, prevBlock.Hash) \/\/ \u521b\u5efa\u65b0\u533a\u5757\n    bc.blocks = append(bc.blocks, newBlock)            \/\/ \u6dfb\u52a0\u5230\u94fe\n}\n<\/code><\/pre>\n<h3>3. \u5173\u952e\u7b97\u6cd5<\/h3>\n<h4>\u9ed8\u514b\u5c14\u6811 (Merkle Tree)<\/h4>\n<pre><code class=\"language-go line-numbers\">func NewMerkleTree(data [][]byte) *MerkleTree {\n    var nodes []MerkleNode\n\n    \/\/ 1. \u521b\u5efa\u53f6\u5b50\u8282\u70b9\n    for _, datum := range data {\n        node := NewMerkleNode(nil, nil, datum)\n        nodes = append(nodes, *node)\n    }\n\n    \/\/ 2. \u9010\u5c42\u6784\u5efa\u6811\n    for len(nodes) &gt; 1 {\n        var level []MerkleNode\n        for i := 0; i &lt; len(nodes); i += 2 {\n            if i+1 == len(nodes) {\n                level = append(level, nodes[i])  \/\/ \u5947\u6570\u8282\u70b9\u76f4\u63a5\u590d\u5236\n                continue\n            }\n            node := NewMerkleNode(&amp;nodes[i], &amp;nodes[i+1], nil)\n            level = append(level, *node)\n        }\n        nodes = level\n    }\n\n    return &amp;MerkleTree{&amp;nodes[0]}\n}\n<\/code><\/pre>\n<h4>\u4ea4\u6613ID\u751f\u6210<\/h4>\n<pre><code class=\"language-go line-numbers\">func (tx *Transaction) SetID() {\n    var encoded bytes.Buffer\n    var hash [32]byte\n\n    \/\/ \u5e8f\u5217\u5316\u4ea4\u6613\u5185\u5bb9\n    enc := gob.NewEncoder(&amp;encoded)\n    err := enc.Encode(tx)\n    if err != nil {\n        log.Panic(err)\n    }\n\n    \/\/ \u8ba1\u7b97SHA256\u54c8\u5e0c\u4f5c\u4e3a\u4ea4\u6613ID\n    hash = sha256.Sum256(encoded.Bytes())\n    tx.ID = hash[:]\n}\n<\/code><\/pre>\n<h3>4. \u4e3b\u7a0b\u5e8f\u6d41\u7a0b<\/h3>\n<pre><code class=\"language-go line-numbers\">func main() {\n    \/\/ 1. \u521b\u5efa\u533a\u5757\u94fe\n    bc := NewBlockchain()\n\n    \/\/ 2. \u6dfb\u52a0\u4ea4\u6613\u533a\u5757\n    bc.AddBlock([]*Transaction{NewCoinbaseTX(\"\u5f20\u4e09\", \"\u5956\u52b1\u7ed9\u5f20\u4e09\")})\n    bc.AddBlock([]*Transaction{NewCoinbaseTX(\"\u674e\u56db\", \"\u5956\u52b1\u7ed9\u674e\u56db\")})\n\n    \/\/ 3. \u663e\u793a\u533a\u5757\u94fe\u4fe1\u606f\n    for i, block := range bc.blocks {\n        fmt.Printf(\"\u533a\u5757 %d:\\n\", i)\n        fmt.Printf(\"  \u54c8\u5e0c: %x\\n\", block.Hash)\n        fmt.Printf(\"  \u968f\u673a\u6570: %d\\n\", block.Nonce)\n    }\n\n    \/\/ 4. \u9a8c\u8bc1\u533a\u5757\u94fe\n    for i, block := range bc.blocks {\n        pow := NewProofOfWork(block)\n        fmt.Printf(\"\u533a\u5757 %d \u9a8c\u8bc1\u7ed3\u679c: %t\\n\", i, pow.Validate())\n    }\n}\n<\/code><\/pre>\n<h3>5. \u5173\u952e\u6280\u672f\u70b9<\/h3>\n<ol>\n<li>\u94fe\u5f0f\u7ed3\u6784: \u6bcf\u4e2a\u533a\u5757\u5305\u542b\u524d\u4e00\u4e2a\u533a\u5757\u7684\u54c8\u5e0c<\/li>\n<li>\u5de5\u4f5c\u91cf\u8bc1\u660e: \u901a\u8fc7\u8c03\u6574nonce\u627e\u5230\u6ee1\u8db3\u96be\u5ea6\u7684\u54c8\u5e0c<\/li>\n<li>\u9ed8\u514b\u5c14\u6811: \u9ad8\u6548\u9a8c\u8bc1\u533a\u5757\u4e2d\u7684\u4ea4\u6613<\/li>\n<li>SHA256\u54c8\u5e0c: \u786e\u4fdd\u6570\u636e\u5b8c\u6574\u6027<\/li>\n<li>\u5e8f\u5217\u5316: \u4f7f\u7528gob\u7f16\u7801\u5b58\u50a8\u548c\u4f20\u8f93\u6570\u636e<\/li>\n<\/ol>\n<h2>\u6267\u884c\u7ed3\u679c\u5206\u6790<\/h2>\n<pre><code class=\"line-numbers\"># go run main.go\n=== \u533a\u5757\u94feDemo\u6f14\u793a ===\n\u6b63\u5728\u521b\u5efa\u533a\u5757\u94fe...\nMining the block containing \"genesis\"\n0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93\n\n\u6b63\u5728\u6dfb\u52a0\u533a\u5757...\nMining the block containing \"\u5f20\u4e09\"\n00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6\n\nMining the block containing \"\u674e\u56db\"\n00006f757d2d31b5f98388f25c328b2813304ebd0c38f1069af8e72eea19467c\n\n\n=== \u533a\u5757\u94fe\u4fe1\u606f ===\n\u533a\u5757 0:\n  \u65f6\u95f4\u6233: 1761630912\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c:\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93\n  \u968f\u673a\u6570: 26477\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: f110075914d97d4ec56b67e3ee5c29a7ae7c5f2876d3f1a80414603f28b5c34d\n      \u7c7b\u578b: Coinbase\u4ea4\u6613\n      \u63a5\u6536\u8005: genesis\n      \u91d1\u989d: 100\n\n\u533a\u5757 1:\n  \u65f6\u95f4\u6233: 1761630917\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6\n  \u968f\u673a\u6570: 27602\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: 5ee6dcf4f2a1402d7bdb1e92004113d75331f426bb49532796cc715bdce809b9\n      \u7c7b\u578b: Coinbase\u4ea4\u6613\n      \u63a5\u6536\u8005: \u5f20\u4e09\n      \u91d1\u989d: 100\n\n\u533a\u5757 2:\n  \u65f6\u95f4\u6233: 1761630923\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00006f757d2d31b5f98388f25c328b2813304ebd0c38f1069af8e72eea19467c\n  \u968f\u673a\u6570: 6834\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: e61d4fb8f92dbcf5c775e090fee8ba7f50859bdd80d75204563e2b523a1516bd\n      \u7c7b\u578b: Coinbase\u4ea4\u6613\n      \u63a5\u6536\u8005: \u674e\u56db\n      \u91d1\u989d: 100\n\n=== \u9a8c\u8bc1\u533a\u5757\u94fe ===\n\u533a\u5757 0 \u9a8c\u8bc1\u7ed3\u679c: true\n\u533a\u5757 1 \u9a8c\u8bc1\u7ed3\u679c: true\n\u533a\u5757 2 \u9a8c\u8bc1\u7ed3\u679c: true\n\n=== \u9ed8\u514b\u5c14\u6811\u6f14\u793a ===\n\u9ed8\u514b\u5c14\u6839\u54c8\u5e0c: 2c548dd8f363a5048d3f1fe5b1afd0feefbf3a1fcf8a7c0eb32945534021c3be\n<\/code><\/pre>\n<h3>1. \u7a0b\u5e8f\u542f\u52a8\u9636\u6bb5<\/h3>\n<pre><code class=\"line-numbers\">=== \u533a\u5757\u94feDemo\u6f14\u793a ===\n\u6b63\u5728\u521b\u5efa\u533a\u5757\u94fe...\n<\/code><\/pre>\n<p>\u7a0b\u5e8f\u5f00\u59cb\u8fd0\u884c\uff0c\u521b\u5efa\u65b0\u7684\u533a\u5757\u94fe\u3002\u6b64\u65f6\u4f1a\u521b\u5efa\u521b\u4e16\u533a\u5757\uff08\u7b2c\u4e00\u4e2a\u533a\u5757\uff09<\/p>\n<h3>2. \u6316\u77ff\u8fc7\u7a0b<\/h3>\n<pre><code class=\"line-numbers\">Mining the block containing \"genesis\"\n0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93\n\nMining the block containing \"\u5f20\u4e09\"\n00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6\n\nMining the block containing \"\u674e\u56db\"\n00006f757d2d31b5f98388f25c328b2813304ebd0c38f1069af8e72eea19467c\n<\/code><\/pre>\n<p>\u6316\u77ff\u8fc7\u7a0b\u89e3\u91ca\uff1a<br \/>\n&#8211; Mining the block containing &#8220;xxx&#8221; &#8211; \u6b63\u5728\u6316\u77ff\u5305\u542b\u6307\u5b9a\u5185\u5bb9\u7684\u533a\u5757<br \/>\n&#8211; \u540e\u9762\u7684\u4e00\u4e32\u5341\u516d\u8fdb\u5236\u6570\u5b57\u662f\u6316\u77ff\u6210\u529f\u540e\u7684\u533a\u5757\u54c8\u5e0c\u503c<br \/>\n&#8211; \u6ce8\u610f\u6240\u6709\u54c8\u5e0c\u90fd\u4ee5 0000 \u5f00\u5934\uff0c\u8bf4\u660e\u6ee1\u8db3\u4e8616\u4f4d\u96be\u5ea6\u8981\u6c42<br \/>\n&#8211; \u6316\u77ff\u5c31\u662f\u4e0d\u65ad\u5c1d\u8bd5nonce\u503c\uff0c\u76f4\u5230\u627e\u5230\u6ee1\u8db3\u6761\u4ef6\u7684\u54c8\u5e0c<\/p>\n<h3>3. \u533a\u5757\u94fe\u7ed3\u6784\u4fe1\u606f<\/h3>\n<h4>\u533a\u5757 0 (\u521b\u4e16\u533a\u5757)<\/h4>\n<pre><code class=\"line-numbers\">\u533a\u5757 0:\n  \u65f6\u95f4\u6233: 1761630912                    # Unix\u65f6\u95f4\u6233\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c:                        # \u7a7a\uff08\u521b\u4e16\u533a\u5757\u6ca1\u6709\u524d\u4e00\u4e2a\u533a\u5757\uff09\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93\n  \u968f\u673a\u6570: 26477                          # \u6316\u77ff\u6210\u529f\u7684nonce\u503c\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: f110075914d97d4ec56b67e3ee5c29a7ae7c5f2876d3f1a80414603f28b5c34d\n      \u7c7b\u578b: Coinbase\u4ea4\u6613                 # \u77ff\u5de5\u5956\u52b1\u4ea4\u6613\n      \u63a5\u6536\u8005: genesis                    # \u63a5\u6536\u8005\u5730\u5740\n      \u91d1\u989d: 100                          # \u5956\u52b1\u91d1\u989d\n<\/code><\/pre>\n<h4>\u533a\u5757 1 (\u5f20\u4e09\u7684\u533a\u5757)<\/h4>\n<pre><code class=\"line-numbers\">\u533a\u5757 1:\n  \u65f6\u95f4\u6233: 1761630917                    # \u6bd4\u533a\u57570\u665a5\u79d2\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 0000967996bf72383203b5bc2d6819b0a0834b4070a1ef427ed5c0a603aaaf93  # \u533a\u57570\u7684\u54c8\u5e0c\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6\n  \u968f\u673a\u6570: 27602                          # \u4e0d\u540c\u7684nonce\u503c\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: 5ee6dcf4f2a1402d7bdb1e92004113d75331f426bb49532796cc715bdce809b9\n      \u7c7b\u578b: Coinbase\u4ea4\u6613\n      \u63a5\u6536\u8005: \u5f20\u4e09                        # \u5f20\u4e09\u83b7\u5f97\u5956\u52b1\n      \u91d1\u989d: 100\n<\/code><\/pre>\n<h4>\u533a\u5757 2 (\u674e\u56db\u7684\u533a\u5757)<\/h4>\n<pre><code class=\"line-numbers\">\u533a\u5757 2:\n  \u65f6\u95f4\u6233: 1761630923                    # \u6bd4\u533a\u57571\u665a6\u79d2\n  \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 00003b2999cf8addbb30b10ee798abed8119160eab4b72bea4d7b094895e88a6  # \u533a\u57571\u7684\u54c8\u5e0c\n  \u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00006f757d2d31b5f98388f25c328b2813304ebd0c38f1069af8e72eea19467c\n  \u968f\u673a\u6570: 6834                           # \u4e0d\u540c\u7684nonce\u503c\n  \u4ea4\u6613\u6570\u91cf: 1\n    \u4ea4\u6613 0: e61d4fb8f92dbcf5c775e090fee8ba7f50859bdd80d75204563e2b523a1516bd\n      \u7c7b\u578b: Coinbase\u4ea4\u6613\n      \u63a5\u6536\u8005: \u674e\u56db                        # \u674e\u56db\u83b7\u5f97\u5956\u52b1\n      \u91d1\u989d: 100\n<\/code><\/pre>\n<h3>4. \u533a\u5757\u94fe\u94fe\u63a5\u5173\u7cfb<\/h3>\n<pre><code class=\"line-numbers\">\u533a\u57570 \u2192 \u533a\u57571 \u2192 \u533a\u57572\n  |       |       |\n  |       |       \u2514\u2500 \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c = \u533a\u57571\u7684\u54c8\u5e0c\n  |       \u2514\u2500 \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c = \u533a\u57570\u7684\u54c8\u5e0c\n  \u2514\u2500 \u521b\u4e16\u533a\u5757\uff08\u6ca1\u6709\u524d\u4e00\u4e2a\u533a\u5757\uff09\n<\/code><\/pre>\n<h3>5. \u9a8c\u8bc1\u7ed3\u679c<\/h3>\n<pre><code class=\"line-numbers\">=== \u9a8c\u8bc1\u533a\u5757\u94fe ===\n\u533a\u5757 0 \u9a8c\u8bc1\u7ed3\u679c: true\n\u533a\u5757 1 \u9a8c\u8bc1\u7ed3\u679c: true\n\u533a\u5757 2 \u9a8c\u8bc1\u7ed3\u679c: true\n<\/code><\/pre>\n<p>\u9a8c\u8bc1\u542b\u4e49\uff1a<br \/>\n&#8211; \u6bcf\u4e2a\u533a\u5757\u7684\u54c8\u5e0c\u503c\u90fd\u6ee1\u8db3\u5de5\u4f5c\u91cf\u8bc1\u660e\u8981\u6c42<br \/>\n&#8211; \u533a\u5757\u94fe\u7684\u5b8c\u6574\u6027\u5f97\u5230\u786e\u8ba4<br \/>\n&#8211; \u6ca1\u6709\u53d1\u73b0\u7be1\u6539\u6216\u9519\u8bef<\/p>\n<h3>6. \u9ed8\u514b\u5c14\u6811\u6f14\u793a<\/h3>\n<pre><code class=\"line-numbers\">=== \u9ed8\u514b\u5c14\u6811\u6f14\u793a ===\n\u9ed8\u514b\u5c14\u6839\u54c8\u5e0c: 2c548dd8f363a5048d3f1fe5b1afd0feefbf3a1fcf8a7c0eb32945534021c3be\n<\/code><\/pre>\n<p>\u9ed8\u514b\u5c14\u6811\u4f5c\u7528\uff1a<br \/>\n&#8211; \u5c06\u533a\u5757\u4e2d\u7684\u6240\u6709\u4ea4\u6613\u7ec4\u7ec7\u6210\u6811\u72b6\u7ed3\u6784<br \/>\n&#8211; \u6839\u54c8\u5e0c\u4ee3\u8868\u6574\u4e2a\u533a\u5757\u7684\u4ea4\u6613\u6458\u8981<br \/>\n&#8211; \u7528\u4e8e\u5feb\u901f\u9a8c\u8bc1\u4ea4\u6613\u662f\u5426\u88ab\u7be1\u6539<\/p>\n<h3>7. \u5173\u952e\u89c2\u5bdf\u70b9<\/h3>\n<ol>\n<li>\u54c8\u5e0c\u94fe\u5f0f\u7ed3\u6784: \u6bcf\u4e2a\u533a\u5757\u90fd\u5305\u542b\u524d\u4e00\u4e2a\u533a\u5757\u7684\u54c8\u5e0c<\/li>\n<li>\u65f6\u95f4\u9012\u589e: \u65f6\u95f4\u6233\u4f9d\u6b21\u9012\u589e\uff0c\u4f53\u73b0\u533a\u5757\u7684\u65f6\u95f4\u987a\u5e8f<\/li>\n<li>\u6316\u77ff\u96be\u5ea6: \u6240\u6709\u54c8\u5e0c\u90fd\u4ee5 0000 \u5f00\u5934\uff0c\u6ee1\u8db316\u4f4d\u96be\u5ea6<\/li>\n<li>\u4ea4\u6613\u5b8c\u6574\u6027: \u6bcf\u4e2a\u533a\u5757\u90fd\u5305\u542b\u6709\u6548\u7684coinbase\u4ea4\u6613<\/li>\n<li>\u9a8c\u8bc1\u901a\u8fc7: \u6240\u6709\u533a\u5757\u90fd\u901a\u8fc7\u4e86\u5de5\u4f5c\u91cf\u8bc1\u660e\u9a8c\u8bc1<\/li>\n<\/ol>\n<h2>\u65f6\u5e8f\u56fe<\/h2>\n<h3>\u533a\u5757\u94feDemo\u65f6\u5e8f\u56fe<\/h3>\n<pre><code class=\"line-numbers\">\u65f6\u95f4\u8f74: \u7a0b\u5e8f\u542f\u52a8 \u2192 \u521b\u5efa\u533a\u5757\u94fe \u2192 \u6316\u77ff\u8fc7\u7a0b \u2192 \u9a8c\u8bc1\u7ed3\u679c\n\n\u53c2\u4e0e\u8005: Main\u51fd\u6570 | Blockchain | Block | ProofOfWork | Transaction\n\nMain\u51fd\u6570:\n    \u2502\n    \u251c\u2500 1. \u542f\u52a8\u7a0b\u5e8f\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u8f93\u51fa: \"=== \u533a\u5757\u94feDemo\u6f14\u793a ===\"\n    \u2502\n    \u251c\u2500 2. \u521b\u5efa\u533a\u5757\u94fe\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8c03\u7528: NewBlockchain()\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u521b\u4e16\u533a\u5757\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u521b\u5efaCoinbase\u4ea4\u6613: genesis\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8c03\u7528: NewBlock(transactions, nil)\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u533a\u5757\u57fa\u672c\u4fe1\u606f\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500 Timestamp: \u5f53\u524d\u65f6\u95f4\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500 Transactions: [coinbase]\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500 PrevBlockHash: [] (\u7a7a)\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2514\u2500 Hash: [] (\u5f85\u8ba1\u7b97)\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u5de5\u4f5c\u91cf\u8bc1\u660e: NewProofOfWork(block)\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u76ee\u6807\u96be\u5ea6: 16\u4f4d (0000...)\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u5f00\u59cb\u6316\u77ff: pow.Run()\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u251c\u2500 nonce = 0\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u251c\u2500 \u5faa\u73af: for nonce &lt; maxNonce\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u251c\u2500 \u51c6\u5907\u6570\u636e: prepareData(nonce)\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u251c\u2500 \u7ec4\u5408: PrevBlockHash + Transactions + Timestamp + TargetBits + Nonce\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b57\u8282\u6570\u7ec4\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u251c\u2500 \u8ba1\u7b97\u54c8\u5e0c: SHA256(data)\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u251c\u2500 \u68c0\u67e5\u96be\u5ea6: hash &lt; target?\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u251c\u2500 \u662f: \u6316\u77ff\u6210\u529f! \u2192 \u8fd4\u56de (nonce, hash)\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502   \u2514\u2500 \u5426: nonce++ \u2192 \u7ee7\u7eed\u5faa\u73af\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502   \u2514\u2500 \u8f93\u51fa: \u6316\u77ff\u8fc7\u7a0b\u4e2d\u7684\u54c8\u5e0c\u503c\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2502       \u2514\u2500 \u8f93\u51fa: \"Mining the block containing 'genesis'\"\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u533a\u5757\u54c8\u5e0c: block.Hash = hash\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u8bbe\u7f6e\u968f\u673a\u6570: block.Nonce = nonce\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b8c\u6574\u7684\u521b\u4e16\u533a\u5757\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u521b\u5efa\u533a\u5757\u94fe: Blockchain{blocks: [genesisBlock]}\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u8f93\u51fa: \"\u6b63\u5728\u521b\u5efa\u533a\u5757\u94fe...\"\n    \u2502\n    \u251c\u2500 3. \u6dfb\u52a0\u7b2c\u4e00\u4e2a\u533a\u5757 (\u5f20\u4e09)\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8f93\u51fa: \"\u6b63\u5728\u6dfb\u52a0\u533a\u5757...\"\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u521b\u5efaCoinbase\u4ea4\u6613: NewCoinbaseTX(\"\u5f20\u4e09\", \"\u5956\u52b1\u7ed9\u5f20\u4e09\")\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u4ea4\u6613\u8f93\u5165: TXInput{Txid: [], Vout: -1, ScriptSig: \"\u5956\u52b1\u7ed9\u5f20\u4e09\"}\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u4ea4\u6613\u8f93\u51fa: TXOutput{Value: 100, ScriptPubKey: \"\u5f20\u4e09\"}\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u4ea4\u6613: Transaction{Vin: [input], Vout: [output]}\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u8ba1\u7b97\u4ea4\u6613ID: tx.SetID()\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u5e8f\u5217\u5316\u4ea4\u6613: gob.Encode(tx)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8ba1\u7b97\u54c8\u5e0c: SHA256(serialized)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u8bbe\u7f6eID: tx.ID = hash\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b8c\u6574\u7684coinbase\u4ea4\u6613\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8c03\u7528: bc.AddBlock([coinbaseTX])\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u533a\u5757: bc.blocks[len-1]\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u65b0\u533a\u5757: NewBlock(transactions, prevBlock.Hash)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u533a\u5757\u4fe1\u606f\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 Timestamp: \u5f53\u524d\u65f6\u95f4\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 Transactions: [\u5f20\u4e09\u7684coinbase]\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 PrevBlockHash: \u521b\u4e16\u533a\u5757\u7684\u54c8\u5e0c\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 Hash: [] (\u5f85\u8ba1\u7b97)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u5de5\u4f5c\u91cf\u8bc1\u660e\u6316\u77ff\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u8f93\u51fa: \"Mining the block containing '\u5f20\u4e09'\"\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u6316\u77ff\u5faa\u73af (\u540c\u521b\u4e16\u533a\u5757)\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u8f93\u51fa: \u6316\u77ff\u8fc7\u7a0b\u4e2d\u7684\u54c8\u5e0c\u503c\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u54c8\u5e0c\u548cnonce\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b8c\u6574\u7684\u533a\u57571\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u6dfb\u52a0\u5230\u94fe: bc.blocks.append(newBlock)\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u8f93\u51fa: \u6316\u77ff\u6210\u529f\u54c8\u5e0c\n    \u2502\n    \u251c\u2500 4. \u6dfb\u52a0\u7b2c\u4e8c\u4e2a\u533a\u5757 (\u674e\u56db)\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u521b\u5efaCoinbase\u4ea4\u6613: NewCoinbaseTX(\"\u674e\u56db\", \"\u5956\u52b1\u7ed9\u674e\u56db\")\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u4ea4\u6613\u8f93\u5165\/\u8f93\u51fa\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u8ba1\u7b97\u4ea4\u6613ID\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b8c\u6574\u7684coinbase\u4ea4\u6613\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8c03\u7528: bc.AddBlock([coinbaseTX])\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u83b7\u53d6\u6700\u540e\u4e00\u4e2a\u533a\u5757: \u533a\u57571\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u65b0\u533a\u5757: NewBlock(transactions, \u533a\u57571.Hash)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8bbe\u7f6e\u533a\u5757\u4fe1\u606f\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 PrevBlockHash: \u533a\u57571\u7684\u54c8\u5e0c\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u5176\u4ed6\u4fe1\u606f...\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u5de5\u4f5c\u91cf\u8bc1\u660e\u6316\u77ff\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u8f93\u51fa: \"Mining the block containing '\u674e\u56db'\"\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u6316\u77ff\u5faa\u73af\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u8f93\u51fa: \u6316\u77ff\u8fc7\u7a0b\u4e2d\u7684\u54c8\u5e0c\u503c\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: \u5b8c\u6574\u7684\u533a\u57572\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u6dfb\u52a0\u5230\u94fe: bc.blocks.append(newBlock)\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u8f93\u51fa: \u6316\u77ff\u6210\u529f\u54c8\u5e0c\n    \u2502\n    \u251c\u2500 5. \u663e\u793a\u533a\u5757\u94fe\u4fe1\u606f\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8f93\u51fa: \"=== \u533a\u5757\u94fe\u4fe1\u606f ===\"\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u904d\u5386\u6240\u6709\u533a\u5757: for i, block := range bc.blocks\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u8f93\u51fa\u533a\u5757\u57fa\u672c\u4fe1\u606f\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u533a\u5757\u7f16\u53f7: i\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u65f6\u95f4\u6233: block.Timestamp\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: block.PrevBlockHash\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u5f53\u524d\u533a\u5757\u54c8\u5e0c: block.Hash\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u968f\u673a\u6570: block.Nonce\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u4ea4\u6613\u6570\u91cf: len(block.Transactions)\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u904d\u5386\u533a\u5757\u4e2d\u7684\u4ea4\u6613: for j, tx := range block.Transactions\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8f93\u51fa\u4ea4\u6613ID: tx.ID\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u68c0\u67e5\u4ea4\u6613\u7c7b\u578b: tx.IsCoinbase()\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u662fcoinbase: \u8f93\u51fa\u7c7b\u578b\u3001\u63a5\u6536\u8005\u3001\u91d1\u989d\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u5426: \u8f93\u51fa\u666e\u901a\u4ea4\u6613\u4fe1\u606f\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u8f93\u51fa\u7a7a\u884c\u5206\u9694\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u5b8c\u6210\u533a\u5757\u4fe1\u606f\u663e\u793a\n    \u2502\n    \u251c\u2500 6. \u9a8c\u8bc1\u533a\u5757\u94fe\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8f93\u51fa: \"=== \u9a8c\u8bc1\u533a\u5757\u94fe ===\"\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u904d\u5386\u6240\u6709\u533a\u5757: for i, block := range bc.blocks\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u5de5\u4f5c\u91cf\u8bc1\u660e: NewProofOfWork(block)\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u9a8c\u8bc1\u533a\u5757: pow.Validate()\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u51c6\u5907\u6570\u636e: prepareData(block.Nonce)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u8ba1\u7b97\u54c8\u5e0c: SHA256(data)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u68c0\u67e5\u96be\u5ea6: hash &lt; target?\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u251c\u2500 \u662f: \u8fd4\u56de true\n    \u2502   \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2502   \u2514\u2500 \u5426: \u8fd4\u56de false\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u8f93\u51fa: \"\u533a\u5757 i \u9a8c\u8bc1\u7ed3\u679c: true\/false\"\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u5b8c\u6210\u9a8c\u8bc1\n    \u2502\n    \u251c\u2500 7. \u9ed8\u514b\u5c14\u6811\u6f14\u793a\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8f93\u51fa: \"=== \u9ed8\u514b\u5c14\u6811\u6f14\u793a ===\"\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u83b7\u53d6\u7b2c\u4e00\u4e2a\u533a\u5757: bc.blocks[0]\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u6536\u96c6\u4ea4\u6613\u54c8\u5e0c: for tx := range block.Transactions\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 txHashes.append(tx.ID)\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u521b\u5efa\u9ed8\u514b\u5c14\u6811: NewMerkleTree(txHashes)\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u521b\u5efa\u53f6\u5b50\u8282\u70b9: for each txHash\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 NewMerkleNode(nil, nil, txHash)\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u251c\u2500 \u9010\u5c42\u6784\u5efa\u6811: while len(nodes) &gt; 1\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u251c\u2500 \u6bcf\u4e24\u4e2a\u8282\u70b9\u5408\u5e76: NewMerkleNode(left, right, nil)\n    \u2502   \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2502   \u2514\u2500 \u8ba1\u7b97\u7236\u8282\u70b9\u54c8\u5e0c: SHA256(left.Data + right.Data)\n    \u2502   \u2502   \u2502\n    \u2502   \u2502   \u2514\u2500 \u8fd4\u56de: MerkleTree{RootNode}\n    \u2502   \u2502\n    \u2502   \u251c\u2500 \u8f93\u51fa\u6839\u54c8\u5e0c: merkleTree.RootNode.Data\n    \u2502   \u2502\n    \u2502   \u2514\u2500 \u5b8c\u6210\u9ed8\u514b\u5c14\u6811\u6f14\u793a\n    \u2502\n    \u2514\u2500 8. \u7a0b\u5e8f\u7ed3\u675f\n        \u2502\n        \u2514\u2500 \u8f93\u51fa: \"=== \u6f14\u793a\u5b8c\u6210 ===\"\n<\/code><\/pre>\n<h3>\u6570\u636e\u6d41\u5411<\/h3>\n<pre><code class=\"line-numbers\">Main \u2192 NewBlockchain \u2192 NewGenesisBlock \u2192 NewBlock \u2192 NewProofOfWork \u2192 Run()\n  \u2502                                                                    \u2502\n  \u2502                                                                    \u25bc\n  \u2502                                                              \u6316\u77ff\u6210\u529f\n  \u2502                                                                    \u2502\n  \u2502                                                                    \u25bc\n  \u2502                                                              \u8bbe\u7f6eHash\u548cNonce\n  \u2502                                                                    \u2502\n  \u2502                                                                    \u25bc\n  \u2502                                                              \u8fd4\u56de\u5b8c\u6574\u533a\u5757\n  \u2502                                                                    \u2502\n  \u25bc                                                                    \u2502\nAddBlock \u2190\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  \u2502\n  \u25bc\n\u6dfb\u52a0\u5230\u533a\u5757\u94fe\n  \u2502\n  \u25bc\n\u7ee7\u7eed\u4e0b\u4e00\u4e2a\u533a\u5757...\n<\/code><\/pre>\n<h3>\u4e3b\u8981\u6d41\u7a0b\u65f6\u5e8f\u56fe<\/h3>\n<div class=\"mermaid mermaid-diagram no-emojify\"><script type=\"text\/javascript\">document.write(\"sequenceDiagram\\n    participant Main as Main\u51fd\u6570\\n    participant BC as Blockchain\\n    participant Block as Block\\n    participant PoW as ProofOfWork\\n    participant TX as Transaction\\n    participant Merkle as MerkleTree\\n\\n    Main-&gt;&gt;Main: \u542f\u52a8\u7a0b\u5e8f\\n    Note over Main: \u8f93\u51fa \\\"=== \u533a\u5757\u94feDemo\u6f14\u793a ===\\\"\\n\\n    Main-&gt;&gt;BC: NewBlockchain()\\n    BC-&gt;&gt;TX: NewCoinbaseTX(\\\"genesis\\\", \\\"\\\")\\n    TX-&gt;&gt;TX: \u521b\u5efacoinbase\u4ea4\u6613\\n    TX--&gt;&gt;BC: \u8fd4\u56de\u4ea4\u6613\\n\\n    BC-&gt;&gt;Block: NewGenesisBlock(coinbase)\\n    Block-&gt;&gt;PoW: NewProofOfWork(block)\\n    PoW-&gt;&gt;PoW: \u8bbe\u7f6e\u76ee\u6807\u96be\u5ea6(16\u4f4d)\\n\\n    Note over PoW: \u5f00\u59cb\u6316\u77ff\u5faa\u73af\\n    loop \u6316\u77ff\u8fc7\u7a0b\\n        PoW-&gt;&gt;PoW: prepareData(nonce)\\n        PoW-&gt;&gt;PoW: SHA256(data)\\n        PoW-&gt;&gt;PoW: \u68c0\u67e5\u96be\u5ea6 hash &lt; target?\\n        alt \u6ee1\u8db3\u96be\u5ea6\\n            PoW--&gt;&gt;Block: \u8fd4\u56de (nonce, hash)\\n        else \u4e0d\u6ee1\u8db3\\n            PoW-&gt;&gt;PoW: nonce++\\n        end\\n    end\\n\\n    Note over Main: \u8f93\u51fa \\\"Mining the block containing \\'genesis\\'\\\"\\n    Note over Main: \u8f93\u51fa\u6316\u77ff\u54c8\u5e0c\u503c\\n\\n    Block-&gt;&gt;Block: \u8bbe\u7f6eHash\u548cNonce\\n    Block--&gt;&gt;BC: \u8fd4\u56de\u521b\u4e16\u533a\u5757\\n    BC--&gt;&gt;Main: \u8fd4\u56de\u533a\u5757\u94fe\\n\\n    Main-&gt;&gt;Main: \u8f93\u51fa \\\"\u6b63\u5728\u521b\u5efa\u533a\u5757\u94fe...\\\"\\n\\n    Main-&gt;&gt;TX: NewCoinbaseTX(\\\"\u5f20\u4e09\\\", \\\"\u5956\u52b1\u7ed9\u5f20\u4e09\\\")\\n    TX-&gt;&gt;TX: \u521b\u5efa\u4ea4\u6613\u5e76\u8ba1\u7b97ID\\n    TX--&gt;&gt;Main: \u8fd4\u56de\u5f20\u4e09\u7684\u4ea4\u6613\\n\\n    Main-&gt;&gt;BC: AddBlock([\u5f20\u4e09\u4ea4\u6613])\\n    BC-&gt;&gt;Block: NewBlock(transactions, prevHash)\\n    Block-&gt;&gt;PoW: NewProofOfWork(block)\\n\\n    Note over PoW: \u5f20\u4e09\u533a\u5757\u6316\u77ff\\n    loop \u6316\u77ff\u8fc7\u7a0b\\n        PoW-&gt;&gt;PoW: prepareData(nonce)\\n        PoW-&gt;&gt;PoW: SHA256(data)\\n        PoW-&gt;&gt;PoW: \u68c0\u67e5\u96be\u5ea6\\n        alt \u6ee1\u8db3\u96be\u5ea6\\n            PoW--&gt;&gt;Block: \u8fd4\u56de (nonce, hash)\\n        else \u4e0d\u6ee1\u8db3\\n            PoW-&gt;&gt;PoW: nonce++\\n        end\\n    end\\n\\n    Note over Main: \u8f93\u51fa \\\"Mining the block containing \\'\u5f20\u4e09\\'\\\"\\n    Note over Main: \u8f93\u51fa\u6316\u77ff\u54c8\u5e0c\u503c\\n\\n    Block-&gt;&gt;Block: \u8bbe\u7f6eHash\u548cNonce\\n    Block--&gt;&gt;BC: \u8fd4\u56de\u5f20\u4e09\u533a\u5757\\n    BC-&gt;&gt;BC: \u6dfb\u52a0\u5230\u533a\u5757\u94fe\\n    BC--&gt;&gt;Main: \u5b8c\u6210\u6dfb\u52a0\\n\\n    Main-&gt;&gt;TX: NewCoinbaseTX(\\\"\u674e\u56db\\\", \\\"\u5956\u52b1\u7ed9\u674e\u56db\\\")\\n    TX-&gt;&gt;TX: \u521b\u5efa\u4ea4\u6613\u5e76\u8ba1\u7b97ID\\n    TX--&gt;&gt;Main: \u8fd4\u56de\u674e\u56db\u7684\u4ea4\u6613\\n\\n    Main-&gt;&gt;BC: AddBlock([\u674e\u56db\u4ea4\u6613])\\n    BC-&gt;&gt;Block: NewBlock(transactions, prevHash)\\n    Block-&gt;&gt;PoW: NewProofOfWork(block)\\n\\n    Note over PoW: \u674e\u56db\u533a\u5757\u6316\u77ff\\n    loop \u6316\u77ff\u8fc7\u7a0b\\n        PoW-&gt;&gt;PoW: prepareData(nonce)\\n        PoW-&gt;&gt;PoW: SHA256(data)\\n        PoW-&gt;&gt;PoW: \u68c0\u67e5\u96be\u5ea6\\n        alt \u6ee1\u8db3\u96be\u5ea6\\n            PoW--&gt;&gt;Block: \u8fd4\u56de (nonce, hash)\\n        else \u4e0d\u6ee1\u8db3\\n            PoW-&gt;&gt;PoW: nonce++\\n        end\\n    end\\n\\n    Note over Main: \u8f93\u51fa \\\"Mining the block containing \\'\u674e\u56db\\'\\\"\\n    Note over Main: \u8f93\u51fa\u6316\u77ff\u54c8\u5e0c\u503c\\n\\n    Block-&gt;&gt;Block: \u8bbe\u7f6eHash\u548cNonce\\n    Block--&gt;&gt;BC: \u8fd4\u56de\u674e\u56db\u533a\u5757\\n    BC-&gt;&gt;BC: \u6dfb\u52a0\u5230\u533a\u5757\u94fe\\n    BC--&gt;&gt;Main: \u5b8c\u6210\u6dfb\u52a0\\n\\n    Main-&gt;&gt;Main: \u8f93\u51fa \\\"=== \u533a\u5757\u94fe\u4fe1\u606f ===\\\"\\n\\n    loop \u904d\u5386\u6240\u6709\u533a\u5757\\n        Main-&gt;&gt;BC: \u83b7\u53d6\u533a\u5757\u4fe1\u606f\\n        BC--&gt;&gt;Main: \u8fd4\u56de\u533a\u5757\u6570\u636e\\n        Main-&gt;&gt;Main: \u8f93\u51fa\u533a\u5757\u8be6\u60c5\\n        Note over Main: \u65f6\u95f4\u6233\u3001\u54c8\u5e0c\u3001\u968f\u673a\u6570\u3001\u4ea4\u6613\u7b49\\n    end\\n\\n    Main-&gt;&gt;Main: \u8f93\u51fa \\\"=== \u9a8c\u8bc1\u533a\u5757\u94fe ===\\\"\\n\\n    loop \u9a8c\u8bc1\u6240\u6709\u533a\u5757\\n        Main-&gt;&gt;PoW: NewProofOfWork(block)\\n        PoW-&gt;&gt;PoW: prepareData(block.Nonce)\\n        PoW-&gt;&gt;PoW: SHA256(data)\\n        PoW-&gt;&gt;PoW: \u9a8c\u8bc1\u96be\u5ea6\\n        PoW--&gt;&gt;Main: \u8fd4\u56de\u9a8c\u8bc1\u7ed3\u679c\\n        Main-&gt;&gt;Main: \u8f93\u51fa\u9a8c\u8bc1\u7ed3\u679c\\n    end\\n\\n    Main-&gt;&gt;Main: \u8f93\u51fa \\\"=== \u9ed8\u514b\u5c14\u6811\u6f14\u793a ===\\\"\\n    Main-&gt;&gt;BC: \u83b7\u53d6\u7b2c\u4e00\u4e2a\u533a\u5757\\n    BC--&gt;&gt;Main: \u8fd4\u56de\u533a\u5757\\n    Main-&gt;&gt;Merkle: NewMerkleTree(txHashes)\\n\\n    loop \u6784\u5efa\u9ed8\u514b\u5c14\u6811\\n        Merkle-&gt;&gt;Merkle: \u521b\u5efa\u53f6\u5b50\u8282\u70b9\\n        Merkle-&gt;&gt;Merkle: \u9010\u5c42\u5408\u5e76\u8282\u70b9\\n        Merkle-&gt;&gt;Merkle: \u8ba1\u7b97\u7236\u8282\u70b9\u54c8\u5e0c\\n    end\\n\\n    Merkle--&gt;&gt;Main: \u8fd4\u56de\u9ed8\u514b\u5c14\u6811\\n    Main-&gt;&gt;Main: \u8f93\u51fa\u6839\u54c8\u5e0c\\n\\n    Main-&gt;&gt;Main: \u8f93\u51fa \\\"=== \u6f14\u793a\u5b8c\u6210 ===\\\"\\n\");<\/script><\/div>\n<h3>\u6316\u77ff\u8fc7\u7a0b\u8be6\u7ec6\u65f6\u5e8f\u56fe<\/h3>\n<div class=\"mermaid mermaid-diagram no-emojify\"><script type=\"text\/javascript\">document.write(\"sequenceDiagram\\n    participant PoW as ProofOfWork\\n    participant SHA as SHA256\\n    participant Target as Target\\n\\n    Note over PoW: \u6316\u77ff\u5f00\u59cb\\n    PoW-&gt;&gt;PoW: nonce = 0\\n\\n    loop \u6316\u77ff\u5faa\u73af (nonce &lt; maxNonce)\\n        PoW-&gt;&gt;PoW: prepareData(nonce)\\n        Note over PoW: \u7ec4\u5408\u6570\u636e:&lt;br\/&gt;PrevBlockHash + Transactions + Timestamp + TargetBits + Nonce\\n\\n        PoW-&gt;&gt;SHA: SHA256(data)\\n        SHA--&gt;&gt;PoW: \u8fd4\u56de\u54c8\u5e0c\u503c\\n\\n        PoW-&gt;&gt;Target: \u68c0\u67e5\u96be\u5ea6 (hash &lt; target?)\\n\\n        alt \u6ee1\u8db3\u96be\u5ea6\u8981\u6c42\\n            Target--&gt;&gt;PoW: true\\n            Note over PoW: \u6316\u77ff\u6210\u529f\uff01\\n            PoW--&gt;&gt;PoW: \u8fd4\u56de (nonce, hash)\\n        else \u4e0d\u6ee1\u8db3\u96be\u5ea6\\n            Target--&gt;&gt;PoW: false\\n            PoW-&gt;&gt;PoW: nonce++\\n            Note over PoW: \u7ee7\u7eed\u5c1d\u8bd5\u4e0b\u4e00\u4e2anonce\\n        end\\n    end\\n\");<\/script><\/div>\n<h3>\u533a\u5757\u94fe\u7ed3\u6784\u56fe<\/h3>\n<div class=\"mermaid mermaid-diagram no-emojify\"><script type=\"text\/javascript\">document.write(\"graph TD\\n    A[\u521b\u4e16\u533a\u5757] --&gt; B[\u5f20\u4e09\u533a\u5757]\\n    B --&gt; C[\u674e\u56db\u533a\u5757]\\n\\n    A1[\u533a\u57570: genesis] --&gt; A2[\u65f6\u95f4\u6233: 1761630912]\\n    A1 --&gt; A3[\u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: \u7a7a]\\n    A1 --&gt; A4[\u5f53\u524d\u533a\u5757\u54c8\u5e0c: 0000967996...]\\n    A1 --&gt; A5[\u968f\u673a\u6570: 26477]\\n    A1 --&gt; A6[\u4ea4\u6613: Coinbase to genesis]\\n\\n    B1[\u533a\u57571: \u5f20\u4e09] --&gt; B2[\u65f6\u95f4\u6233: 1761630917]\\n    B1 --&gt; B3[\u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 0000967996...]\\n    B1 --&gt; B4[\u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00003b2999...]\\n    B1 --&gt; B5[\u968f\u673a\u6570: 27602]\\n    B1 --&gt; B6[\u4ea4\u6613: Coinbase to \u5f20\u4e09]\\n\\n    C1[\u533a\u57572: \u674e\u56db] --&gt; C2[\u65f6\u95f4\u6233: 1761630923]\\n    C1 --&gt; C3[\u524d\u4e00\u4e2a\u533a\u5757\u54c8\u5e0c: 00003b2999...]\\n    C1 --&gt; C4[\u5f53\u524d\u533a\u5757\u54c8\u5e0c: 00006f757d...]\\n    C1 --&gt; C5[\u968f\u673a\u6570: 6834]\\n    C1 --&gt; C6[\u4ea4\u6613: Coinbase to \u674e\u56db]\\n\");<\/script><\/div>\n<h3>\u9ed8\u514b\u5c14\u6811\u7ed3\u6784\u56fe<\/h3>\n<div class=\"mermaid mermaid-diagram no-emojify\"><script type=\"text\/javascript\">document.write(\"graph TD\\n    Root[\u9ed8\u514b\u5c14\u6839\u54c8\u5e0c&lt;br\/&gt;2c548dd8f363a5048d3f1fe5b1afd0feefbf3a1fcf8a7c0eb32945534021c3be]\\n\\n    Root --&gt; Left[\u5de6\u5b50\u6811]\\n    Root --&gt; Right[\u53f3\u5b50\u6811]\\n\\n    Left --&gt; L1[\u4ea4\u66131\u54c8\u5e0c&lt;br\/&gt;f110075914d97d4ec56b67e3ee5c29a7ae7c5f2876d3f1a80414603f28b5c34d]\\n\\n    Right --&gt; R1[\u4ea4\u66132\u54c8\u5e0c&lt;br\/&gt;\u5982\u679c\u5b58\u5728\u7b2c\u4e8c\u4e2a\u4ea4\u6613]\\n\\n    Note1[\u6ce8\u610f: \u521b\u4e16\u533a\u5757\u53ea\u6709\u4e00\u4e2acoinbase\u4ea4\u6613&lt;br\/&gt;\u6240\u4ee5\u9ed8\u514b\u5c14\u6811\u7ed3\u6784\u76f8\u5bf9\u7b80\u5355]\\n\");<\/script><\/div>\n<h3>\u9a8c\u8bc1\u6d41\u7a0b\u65f6\u5e8f\u56fe<\/h3>\n<div class=\"mermaid mermaid-diagram no-emojify\"><script type=\"text\/javascript\">document.write(\"sequenceDiagram\\n    participant Main as Main\u51fd\u6570\\n    participant PoW as ProofOfWork\\n    participant Block as Block\\n\\n    Main-&gt;&gt;Main: \u5f00\u59cb\u9a8c\u8bc1\u533a\u5757\u94fe\\n\\n    loop \u9a8c\u8bc1\u6bcf\u4e2a\u533a\u5757\\n        Main-&gt;&gt;PoW: NewProofOfWork(block)\\n        PoW-&gt;&gt;PoW: prepareData(block.Nonce)\\n        PoW-&gt;&gt;PoW: SHA256(data)\\n        PoW-&gt;&gt;PoW: \u68c0\u67e5 hash &lt; target?\\n\\n        alt \u9a8c\u8bc1\u901a\u8fc7\\n            PoW--&gt;&gt;Main: \u8fd4\u56de true\\n            Main-&gt;&gt;Main: \u8f93\u51fa \\\"\u533a\u5757 i \u9a8c\u8bc1\u7ed3\u679c: true\\\"\\n        else \u9a8c\u8bc1\u5931\u8d25\\n            PoW--&gt;&gt;Main: \u8fd4\u56de false\\n            Main-&gt;&gt;Main: \u8f93\u51fa \\\"\u533a\u5757 i \u9a8c\u8bc1\u7ed3\u679c: false\\\"\\n        end\\n    end\\n\\n    Main-&gt;&gt;Main: \u9a8c\u8bc1\u5b8c\u6210\\n\");<\/script><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u76f4\u60f3\u624b\u5199\u4e00\u6b21\u533a\u5757\u94fe\u6765\u7406\u89e3\uff0c\u7ec8\u4e8e\u8865\u5145\u4e86\u3002 \u9996\u5148\u4e0a\u4ee3\u7801\uff1a \/\/ \u533a\u5757\u94feDemo &#8211; Go\u8bed\u8a00\u5b9e\u73b0 \/\/ \u672c\u7a0b\u5e8f\u6f14&hellip;<\/p>\n <a href=\"https:\/\/www.db2go.net\/?p=789\" title=\"\u4ece\u624b\u5199\u533a\u5757\u94fedemo\u6765\u7406\u89e3\u533a\u5757\u94fe\" class=\"entry-more-link\"><span>Read More<\/span> <span class=\"screen-reader-text\">\u4ece\u624b\u5199\u533a\u5757\u94fedemo\u6765\u7406\u89e3\u533a\u5757\u94fe<\/span><\/a>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[16],"tags":[],"class_list":["entry","author-suredandan","post-789","post","type-post","status-publish","format-standard","category-16"],"views":627,"_links":{"self":[{"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/posts\/789","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.db2go.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=789"}],"version-history":[{"count":4,"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/posts\/789\/revisions"}],"predecessor-version":[{"id":793,"href":"https:\/\/www.db2go.net\/index.php?rest_route=\/wp\/v2\/posts\/789\/revisions\/793"}],"wp:attachment":[{"href":"https:\/\/www.db2go.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.db2go.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.db2go.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}