91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

區塊鏈簡易公鏈從0到1開發手冊

發布時間:2020-07-12 12:56:06 來源:網絡 閱讀:30512 作者:暗黑魔君 欄目:編程語言

從0到1簡易區塊鏈開發手冊V0.1

從0到1簡易區塊鏈開發手冊V0.2-創建錢包
https://blog.51cto.com/clovemfong/2161923
從0到1簡易區塊鏈開發手冊V0.3-數據持久化與創世區塊
https://blog.51cto.com/clovemfong/2162169
從0到1簡易區塊鏈開發手冊V0.4-實現轉賬交易的思路分析
https://blog.51cto.com/clovemfong/2163057
從0到1簡易區塊鏈開發手冊V0.5-實現余額查詢
https://blog.51cto.com/clovemfong/2163109
從0到1簡易區塊鏈開發手冊V0.6-實現打印區塊
https://blog.51cto.com/clovemfong/2163211

前言

這是我這段時間學習區塊鏈開發以來打造的第一個區塊鏈平臺,之所以叫做簡易區塊鏈,是因為它確實比較簡易,僅僅是實現了底層的一些功能,不足以作為一個真正的公鏈使用,但通過學習,我們能夠通過代碼更加理解比特幣白皮書中描述的各種比特幣原理,區塊鏈世界,無論是研究理論的,還是實戰開發的,甚至炒幣玩資本的,都離不開比特幣的影子,區塊鏈技術畢竟是從比特幣中剝離抽象而來,所以,作為一個技術人員,無論是研究以太坊,超級賬本,甚至是各種公鏈,包括某些山寨公鏈,都需要先去理解比特幣原理,而對于開發者而言,理解原理最好的方式就是將其通過代碼實現,當然,我們這里實現的一些原理只是應用實戰范圍之內可以實現的,比如橢圓加密算法,我們要實現的只是使用橢圓加密去實現某些加密功能,而非用代碼去實現一個完整的橢圓加密代碼庫,這個不再本文的討論范圍內,所以本文面向的群體是:

  • 對比特幣原理不了解,但沒時間看太多的資料文獻的初學者
  • 對比特幣原理有所了解,但是停留在理論階段的研究者
  • 沒有對比特幣進行研究,想直接研究以太坊,超級賬本的實戰者(大神除外)
  • 對Golang熟悉,但是不知道如何入手區塊鏈的開發者或者是像我一樣的運維 :-)

本文中,我們先通過命令行的方式演示區塊鏈的工作流程以及相關原理,涉及到比較重要的內容,比如Sha256哈希,橢圓加密,Base58編碼等內容,我會根據時間以及后期的工作情況進行適當調整,這注定是一個短期內沒有結尾的故事。

為表尊敬,寫在前面,建議先閱讀該文檔

本文的學習資料來自這位liuxhengxu前輩翻譯的資料

能將資料翻譯得如此完美,相比其技術功能也是相當深厚的,感謝分享

建議大家可以先看該資料后再來看我的這系列文章,否則可能會有一些難度,由于該資料是通過循序漸進的方式進行版本迭代,慢慢引導開發者不斷對原有的代碼進行優化,拓展,非常認真并細心,希望大家時間充裕的時候以及對某些本文并未寫清楚的地方,強烈建議閱讀該資料。

本文在此基礎上進行了一些修改(談不上改進),我摒棄一些過于基礎的以及后期需要大量重構的代碼,直接通過該項目的執行流程進行代碼分析,這樣可以稍微節省一些大家的時間,把有限的精力放在對業務有更大提升的技術研究上。

一. 功能描述

Usage:
        createwallet
                        -- 創建錢包
        getaddresslists
                        -- 獲取所有的錢包地址
        createblockchain -address address
                        -- 創建創世區塊
        send -from SourceAddress -to DestAddress -amount Amount
                        -- 轉賬交易
        printchain
                        -- 打印區塊
        getbalance -address address
                        -- 查詢余額

本文圍繞著幾個功能進行講解

  • 創建錢包

    通過橢圓加密算法創建錢包地址

  • 獲取錢包地址

    獲取區塊鏈中所有的錢包地址

  • 創建創世區塊

    實現創世區塊的創建,并生成區塊鏈

  • 實現轉賬交易

    通過轉賬交易,生成區塊,并存入區塊鏈

  • 打印區塊

    打印出所有的區塊信息,實現轉賬交易的溯源

  • 查詢余額

    查詢出對應錢包的余額狀態

隨著代碼的不斷完善,我們將會對以上進行改進,并提供更多的功能點進行分析探討,我們先通過下圖簡單演示一下如上功能

區塊鏈簡易公鏈從0到1開發手冊

關于效果圖,大家先大致看下即可,不需要刻意研究,在后期的課程中都會涉及。

二. 實現命令行功能

區塊鏈簡易公鏈從0到1開發手冊

1.定義結構體

定義一個空結構體

type CLI struct {

}

2.結構體方法

重要!初學者必看

這里提到的結構體方法并不是真正實現功能的方法,而是命令行對象的方法,這些方法中會調用實際的功能對象方法進行功能實現,在本章節中,創建結構體方法即可,功能代碼可以為空,如:

例子:
func (cli *CLI) CreateWallet() {
}
func (cli *CLI) GetAddressLists() {
}
.....

其他的可以在后期逐步實現,為了讓有基礎的同學對項目整體提前有些印象,所以,代碼內容我直接復制粘貼進來,不做刪減,在后期的內容中,會逐步涉及到每個調用的對象方法或者函數的作用。

2.1 創建錢包CreateWallet
func (cli *CLI) CreateWallet() {
    _, wallets := GetWallets() //獲取錢包集合對象
    wallets.CreateNewWallets() //創建錢包集合

}
2.2 獲取錢包地址GetAddressLists
func (cli *CLI) GetAddressLists() {
    fmt.Println("錢包地址列表為:")
        //獲取錢包的集合,遍歷,依次輸出
    _, wallets := GetWallets() //獲取錢包集合對象
    for address, _ := range wallets.WalletMap { 
        fmt.Printf("\t%s\n", address)
    }
}
2.3 創建創世區塊CreateBlockChain
func (cli *CLI) CreateBlockChain(address string) {
    CreateBlockChainWithGenesisBlock(address)
    bc :=GetBlockChainObject()
    if bc == nil{
        fmt.Println("沒有數據庫")
        os.Exit(1)
    }
    defer bc.DB.Close()
    utxoSet:=&UTXOSet{bc}
    utxoSet.ResetUTXOSet()
}
2.4 創建轉賬交易Send
func (cli *CLI) Send(from, to, amount []string) {
    bc := GetBlockChainObject()
    if bc == nil {
        fmt.Println("沒有BlockChain,無法轉賬。。")
        os.Exit(1)
    }
    defer bc.DB.Close()

    bc.MineNewBlock(from, to, amount)
    //添加更新
    utsoSet :=&UTXOSet{bc}
    utsoSet.Update()
}
2.5 查詢余額GetBalance
func (cli *CLI) GetBalance(address string) {
    bc := GetBlockChainObject()
    if bc == nil {
        fmt.Println("沒有BlockChain,無法查詢。。")
        os.Exit(1)
    }
    defer bc.DB.Close()
    //total := bc.GetBalance(address,[]*Transaction{})
    utxoSet :=&UTXOSet{bc}
    total:=utxoSet.GetBalance(address)

    fmt.Printf("%s,余額是:%d\n", address, total)
}
2.6 打印區塊PrintChains
func (cli *CLI) PrintChains() {
    //cli.BlockChain.PrintChains()
    bc := GetBlockChainObject() //bc{Tip,DB}
    if bc == nil {
        fmt.Println("沒有BlockChain,無法打印任何數據。。")
        os.Exit(1)
    }
    defer bc.DB.Close()
    bc.PrintChains()
}

3. 相關函數

3.1 判斷參數是否合法 isValidArgs
func isValidArgs() {
    if len(os.Args) < 2 {
        printUsage()
        os.Exit(1)
    }
}

判斷終端命令是否有參數輸入,如果沒有參數,則提示程序使用說明,并退出程序

3.2 程序使用說明
func printUsage() {
    fmt.Println("Usage:")
    fmt.Println("\tcreatewallet\n\t\t\t-- 創建錢包")
    fmt.Println("\tgetaddresslists\n\t\t\t-- 獲取所有的錢包地址")
    fmt.Println("\tcreateblockchain -address address\n\t\t\t-- 創建創世區塊")
    fmt.Println("\tsend -from SourceAddress -to DestAddress -amount Amount\n\t\t\t-- 轉賬交易")
    fmt.Println("\tprintchain\n\t\t\t-- 打印區塊")
    fmt.Println("\tgetbalance -address address\n\t\t\t-- 查詢余額")
}
3.3 JSON解析的函數
func JSONToArray(jsonString string) []string {
    var arr [] string
    err := json.Unmarshal([]byte(jsonString), &arr)
    if err != nil {
        log.Panic(err)
    }
    return arr
}

通過該函數將JSON字符串格式轉成字符串數組,用于在多筆轉賬交易中實現同時多個賬戶進行兩兩轉賬的功能。

3.4 校驗地址是否有效
func  IsValidAddress(address []byte) bool {

    //step1:Base58解碼
    //version+pubkeyHash+checksum
    full_payload := Base58Decode(address)

    //step2:獲取地址中攜帶的checkSUm
    checkSumBytes := full_payload[len(full_payload)-addressCheckSumLen:]

    versioned_payload := full_payload[:len(full_payload)-addressCheckSumLen]

    //step3:versioned_payload,生成一次校驗碼
    checkSumBytes2 := CheckSum(versioned_payload)

    //step4:比較checkSumBytes,checkSumBytes2
    return bytes.Compare(checkSumBytes, checkSumBytes2) == 0

}

以下三個功能實現之前需要先調用該函數進行地址校驗

  • 創建創世區塊
  • 轉賬交易
  • 查詢余額

4.命令行主要方法Run

Usage:
        createwallet
                        -- 創建錢包
        getaddresslists
                        -- 獲取所有的錢包地址
        createblockchain -address address
                        -- 創建創世區塊
        send -from SourceAddress -to DestAddress -amount Amount
                        -- 轉賬交易
        printchain
                        -- 打印區塊
        getbalance -address address
                        -- 查詢余額

我們將如上功能展示的實現功能寫在Run方法中,實現命令行功能的關鍵是了解os.Argsflag

關于這兩個功能,此處不再贅述,否則篇幅會無限臃腫。

代碼塊均在方法體Run中,下文將分步驟對代碼實現進行體現

func (cli *CLI) Run() {
}
4.1 判斷命令行參數是否合法
isValidArgs()
4.2 創建flagset命令對象
    createWalletCmd := flag.NewFlagSet("createwallet", flag.ExitOnError)
    getAddresslistsCmd := flag.NewFlagSet("getaddresslists", flag.ExitOnError)
    CreateBlockChainCmd := flag.NewFlagSet("createblockchain", flag.ExitOnError)
    sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
    printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
    getBalanceCmd := flag.NewFlagSet("getbalance", flag.ExitOnError)
    testMethodCmd := flag.NewFlagSet("test", flag.ExitOnError)

如上,通過flag.NewFlagSet方法創建命令對象,如createwallet,getaddresslists,createblockchain等命令對象

固定用法,掌握即可。

4.3 設置命令后的參數對象
    flagCreateBlockChainData := CreateBlockChainCmd.String("address", "GenesisBlock", "創世區塊的信息")
    flagSendFromData := sendCmd.String("from", "", "轉賬源地址")
    flagSendToData := sendCmd.String("to", "", "轉賬目標地址")
    flagSendAmountData := sendCmd.String("amount", "", "轉賬金額")
    flagGetBalanceData := getBalanceCmd.String("address", "", "要查詢余額的賬戶")

通過命令對象的String方法為命令后的參數對象

  • createblockchain命令后的參數對象:address
  • send命令后的參數對象: from | to |amount
  • getbalance命令后的參數對象: address

其中createwallet,getaddresslists,printchain命令沒有參數對象。

4.4 解析命令對象
switch os.Args[1] {
    case "createwallet":
        err := createWalletCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "getaddresslists":
        err := getAddresslistsCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "createblockchain":
        err := CreateBlockChainCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "send":
        err := sendCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "getbalance":
        err := getBalanceCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "printchain":
        err := printChainCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "test":
        err := testMethodCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    default:
        printUsage()
        os.Exit(1)

    }

匹配對應的命令,用命令對象的Parse方法對os.Args[2:]進行解析。

4.5 執行對應功能
    //4.1 創建錢包--->交易地址
    if createWalletCmd.Parsed() {
        cli.CreateWallet()
    }
    //4.2 獲取錢包地址
    if getAddresslistsCmd.Parsed() {
        cli.GetAddressLists()
    }
    //4.3 創建創世區塊
    if CreateBlockChainCmd.Parsed() {
        if !IsValidAddress([]byte(*flagCreateBlockChainData)) {
            fmt.Println("地址無效,無法創建創世前區塊")
            printUsage()
            os.Exit(1)
        }
        cli.CreateBlockChain(*flagCreateBlockChainData)
    }
    //4.4 轉賬交易
    if sendCmd.Parsed() {
        if *flagSendFromData == "" || *flagSendToData == "" || *flagSendAmountData == "" {
            fmt.Println("轉賬信息有誤")
            printUsage()
            os.Exit(1)
        }
        //添加區塊
        from := JSONToArray(*flagSendFromData)     //[]string
        to := JSONToArray(*flagSendToData)         //[]string
        amount := JSONToArray(*flagSendAmountData) //[]string
        for i := 0; i < len(from); i++ {
            if !IsValidAddress([]byte(from[i])) || !IsValidAddress([]byte(to[i])) {
                fmt.Println("地址無效,無法轉賬")
                printUsage()
                os.Exit(1)
            }
        }

        cli.Send(from, to, amount)
    }
    //4.5 查詢余額
    if getBalanceCmd.Parsed() {
        if !IsValidAddress([]byte(*flagGetBalanceData)) {
            fmt.Println("查詢地址有誤")
            printUsage()
            os.Exit(1)
        }
        cli.GetBalance(*flagGetBalanceData)
    }

    //4.6 打印區塊信息
    if printChainCmd.Parsed() {
        cli.PrintChains()
    }

5. 測試代碼

在main.go中中添加測試代碼

package main
func main() {
    cli:=BLC.CLI{}
    cli.Run()
}

編譯運行

$ go build -o mybtc main.go

測試思路

  1. 查看命令行列表是否可以正常顯示
  2. 輸入非法字符查看是否有錯誤提示

業務功能此處暫未實現,測試時忽略。

從0到1簡易區塊鏈開發手冊V0.2-創建錢包
https://blog.51cto.com/clovemfong/2161923
從0到1簡易區塊鏈開發手冊V0.3-數據持久化與創世區塊
https://blog.51cto.com/clovemfong/2162169
從0到1簡易區塊鏈開發手冊V0.4-實現轉賬交易的思路分析
https://blog.51cto.com/clovemfong/2163057
從0到1簡易區塊鏈開發手冊V0.5-實現余額查詢
https://blog.51cto.com/clovemfong/2163109
從0到1簡易區塊鏈開發手冊V0.6-實現打印區塊
https://blog.51cto.com/clovemfong/2163211
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌鲁木齐市| 务川| 元谋县| 微山县| 淅川县| 赣州市| 房产| 湄潭县| 六安市| 旌德县| 东乡族自治县| 阿拉善盟| 新田县| 调兵山市| 房山区| 玛多县| 土默特右旗| 乐山市| 霸州市| 介休市| 赤壁市| 晋宁县| 营山县| 武鸣县| 忻城县| 巩义市| 分宜县| 富裕县| 平陆县| 观塘区| 永川市| 博爱县| 正镶白旗| 康平县| 稻城县| 昌宁县| 句容市| 和林格尔县| 手游| 兴安县| 海晏县|