日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

区块链项目 - 9 UTXO优化

發布時間:2024/1/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 区块链项目 - 9 UTXO优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

9 UTXO優化

9.1 查找未花費輸出

之前我們要查詢 某個地址的余額需要遍歷整個數據庫,隨著數據量的增大,這個工作量會很大,我們現在來嘗試優化

/Users/xxx/go/src/publicChain/part63-UTXOSet/BLC/UTXO_Set.go

const utxoTableName = "utxoTableName"type UTXOSet struct {Blockchain *Blockchain }func (utxoSet *UTXOSet) ResetUTXOSet() {err := utxoSet.Blockchain.DB.Update(func(tx *bolt.Tx) error {b := tx.Bucket([]byte(utxoTableName))if b != nil {tx.DeleteBucket([]byte(utxoTableName))b, _ := tx.CreateBucket([]byte(utxoTableName))if b != nil {}}return nil})if err != nil {log.Panic(err)} }

/Users/xxx/go/src/publicChain/part62-UTXOSet/BLC/Transaction_TXOutputs.go

type TXOutputs struct {TxOutputs []*TXOutput }

/Users/xxx/go/src/publicChain/part62-UTXOSet/BLC/Blockchain.go

func (blockchain *Blockchain) FindUTXOMap() map[string]*TXOutputs {//define an Iterator variable to attain blockblockchainIterator := blockchain.Iterator()//store all UTXOs have been spentspentableUTXOsMap := make(map[string][]*TXInput)utxoMaps := make(map[string]*TXOutputs)for {//attain blocksblock := blockchainIterator.Next()//range all index of Txs slicefor i := len(block.Txs) - 1; i >= 0; i-- {//attain Txstx := block.Txs[i]//judging if tx is in coinbase and put all txInput into sliceif tx.IsCoinbaseTransaction() == false {for _, txInput := range tx.Vins {//convert []byte to stringtxHash := hex.EncodeToString(txInput.TxHash)spentableUTXOsMap[txHash] = append(spentableUTXOsMap[txHash], txInput)}}//define an instance of &TXOutputstxOutputs := &TXOutputs{[]*TXOutput{}}//convert []byte to stringtxHash := hex.EncodeToString(tx.TxHash)workOutLoop://range if a value has been spentfor index, out := range tx.Vouts {//convert []byte to stringtxHash := hex.EncodeToString(tx.TxHash)//attain []*TXInputtxInputs := spentableUTXOsMap[txHash]//judging and put out into sliceif len(txInputs) > 0 {isSpent := falsefor _, in := range txInputs {outPublicKey := out.Ripemd160HashinPublicKey := in.PublicKeyif bytes.Compare(outPublicKey, Ripemd160Hash(inPublicKey)) == 0 {if index == in.Vouts {isSpent = truecontinue workOutLoop}}}if isSpent == false {txOutputs.TxOutputs = append(txOutputs.TxOutputs, out)}} else {txOutputs.TxOutputs = append(txOutputs.TxOutputs, out)}}//set key-value pairsutxoMaps[txHash] = txOutputs}var hashInt big.InthashInt.SetBytes(block.PreBlockHash)if hashInt.Cmp(big.NewInt(0)) == 0 {break}}return utxoMaps }

相應的命令行工具也改一下,編譯并運行,結果能夠正常輸出

./bc test map[8e578e4d1d1ef2f5101bdd72e5bd922cb8d85956333977e03c4260975db0223c:0xc00000ca50] ./bc send -from '["1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ"]' -to '["1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723"]' -amount '["2"]' ./bc getBalance -address "1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ" 1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ has 18 token ./bc send -from '["1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ","1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723"]' -to '["1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723","1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ"]' -amount '["3","4"]'

嘗試進行多筆轉賬會出錯,我們下一節會詳細講解

9.2 多筆交易中的數字簽名

我們完善一下相關函數

func NewSimpleTransaction(from, to string, amount int, blockchain *Blockchain, txs []*Transaction) *Transaction {--//signatureblockchain.SignTransaction(tx, wallet.PrivateKey, txs)return tx } func (blockchain *Blockchain) SignTransaction(tx *Transaction, privateKey ecdsa.PrivateKey, txs []*Transaction) {--for _, vin := range tx.Vins {prevTX, err := blockchain.FindTransaction(vin.TxHash, txs)-- } func (blockchain *Blockchain) FindTransaction(ID []byte, txs []*Transaction) (Transaction, error) {for _, tx := range txs {if bytes.Compare(tx.TxHash, ID) == 0 {return *tx, nil}}bci := blockchain.Iterator()for {block := bci.Next()for _, tx := range block.Txs {if bytes.Compare(tx.TxHash, ID) == 0 {return *tx, nil}}var hashInt big.InthashInt.SetBytes(block.PreBlockHash)if big.NewInt(0).Cmp(&hashInt) == 0 {break}}return Transaction{}, nil }

最后重新編譯運行

./bc send -from '["1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ"]' -to '["1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723"]' -amount '["2"]' ./bc getBalance -address "1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ" 1Eubsorq2zfZ1vmuA8NRcNxPwptSG6c8BJ has 29 token ./bc getBalance -address "1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723" 1B5y2naPTzkXLztVk2ffLPd3wbpoQg6723 has 1 token

9.3 遍歷并存儲UXTO

/Users/xxx/go/src/publicChain/part63-UTXOSet/BLC/Transaction_TXOutputs.go

//SerializeBlockfunc (txOutput *TXOutputs) Serialize() []byte {var result bytes.Bufferencoder := gob.NewEncoder(&result)err := encoder.Encode(txOutput)if err != nil {log.Panic(err)}return result.Bytes() }//DeserializeBlockfunc DeserializeTXOutputs(txOutputsBytes []byte) *TXOutputs {var txOutputs TXOutputsdecoder := gob.NewDecoder(bytes.NewReader(txOutputsBytes))err := decoder.Decode(&txOutputs)if err != nil {log.Panic()}return &txOutputs }

/Users/xxx/go/src/publicChain/part63-UTXOSet/BLC/UTXO_Set.go

const utxoTableName = "utxoTableName"type UTXOSet struct {Blockchain *Blockchain }func (utxoSet *UTXOSet) ResetUTXOSet() {err := utxoSet.Blockchain.DB.Update(func(tx *bolt.Tx) error {b := tx.Bucket([]byte(utxoTableName))if b != nil {err := tx.DeleteBucket([]byte(utxoTableName))if err != nil {log.Panic(err)}}b, _ = tx.CreateBucket([]byte(utxoTableName))if b != nil {txOutputMap := utxoSet.Blockchain.FindUTXOMap()for keyHash, outs := range txOutputMap {txHash, _ := hex.DecodeString(keyHash)b.Put(txHash, outs.Serialize())}}return nil})if err != nil {log.Panic(err)} }

在終端中運行,程序能夠正常運行

9.3 FindUTXOMap方法優化

我們直接通過utxoSet來獲取余額

func (cli CLI) getBalance(address string) {fmt.Println("Address:" + address)blockchain := BlockChainObject()defer blockchain.DB.Close()utxoSet := &UTXOSet{blockchain}amount := utxoSet.GetBalance(address)fmt.Printf("%s has %d token\n", address, amount) }

我們再來完善一下需要調用的方法

func (utxoSet *UTXOSet) FindUTXOForAddress(address string) []*UTXO {} func (utxoSet *UTXOSet) GetBalance(address string) int64 {// }

我們再改為下列結構體,其他文件相應的也變更

type TXOutputs struct {UTXOS []*UTXO }

/Users/xxx/go/src/publicChain/part63-UTXOSet/BLC/UTXO_Set.go

func (utxoSet *UTXOSet) GetBalance(address string) int64 {UTXOS := utxoSet.FindUTXOForAddress(address)var amount int64for _, utxo := range UTXOS {amount += utxo.Output.Value}return amount } func (utxoSet *UTXOSet) FindUTXOForAddress(address string) []*UTXO {var utxos []*UTXOutxoSet.Blockchain.DB.View(func(tx *bolt.Tx) error {//assume bucket exists and has keysb := tx.Bucket([]byte(utxoTableName))c := b.Cursor()for k,v := c.First();k != nil; k,v = c.Next() {fmt.Printf("key=%s, value=%s\n",k,v)txOutputs := DeserializeTXOutputs(v)for _,utxo := range txOutputs.UTXOS {if utxo.Output.UnlockScriptPublicKeyWithAddress(address) {utxos = append(utxos,utxo)}}}return nil})return utxos }

在終端中的重新創建區塊并查詢余額,結果能夠正常輸出,現在我們每次查詢余額就不需要遍歷數據庫了

./bc creatBlockChain -address "1JfaJ6AtBCSop8npzv1UBhayhM9AxNnu9N" ./bc getBalance -address "1JfaJ6AtBCSop8npzv1UBhayhM9AxNnu9N" 1JfaJ6AtBCSop8npzv1UBhayhM9AxNnu9N has 10 token

9.4 修改CoinbaseTransaction交易哈希導致的bug

我們修改一下如下代碼,調用ResetUTOXSet方法重置UTOX

func (cli *CLI) testMethod() {//attain blockchainblockchain := BlockChainObject()defer blockchain.DB.Close()//attain utxoSetutxoSet := &UTXOSet{blockchain}//call method utxoSet.ResetUTXOSet() }

? 接著我們在終端中編譯并運行

./bc send -from '["1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY"]' -to '["17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN"]' -amount '["2"]'

我們發現在終端轉賬不能正常運行,我們修改一下部分代碼

func (tx *Transaction) HashTransaction() {var result bytes.Bufferencoder := gob.NewEncoder(&result)err := encoder.Encode(tx)if err != nil {log.Panic(err)}resultBytes := bytes.Join([][]byte{IntToHex(time.Now().Unix()), result.Bytes()}, []byte{})hash := sha256.Sum256(resultBytes)tx.TxHash = hash[:] }

改好之后在次編譯重置即可查詢余額

./bc getBalance -address "17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN" 17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN has 2 token ./bc getBalance -address "1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY" 1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY has 18 token ./bc send -from '["1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY","17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN"]' -to '["17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN","1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY"]' -amount '["3","4"]' 17pGGPVzFrzvLLoHWJoJ926Eemwm1DJKRN has 1 token 1Dh46KP31Gfkd55wqdmnpqy2TQh1cvwpzY has 29 token

一次性轉多筆也是能夠實現的

總結

以上是生活随笔為你收集整理的区块链项目 - 9 UTXO优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 蘑菇福利视频一区播放 | 无码人妻丰满熟妇区毛片18 | 欧美xxxxxhd| 91精品久久久久久久久 | 超碰在线播放97 | 亚洲精品色图 | 美女露胸无遮挡 | juliaann第一次和老师 | 少妇人妻一级a毛片 | 黄色网址视频在线观看 | 女同av在线播放 | 久久国产精品国产精品 | 欧美丝袜一区二区 | av亚洲在线观看 | 91在线视频观看 | 19禁大尺度做爰无遮挡电影 | 九九热精品视频在线观看 | 天堂av成人 | 活大器粗np高h一女多夫 | 91男女视频 | 91嫩草欧美久久久九九九 | 蜜桃视频在线播放 | 亚洲国产精品免费视频 | 黄色操人视频 | 黄色午夜影院 | www.国产色| 美女毛片视频 | 伊人影院在线观看 | 久久无码人妻一区二区三区 | 一区二区亚洲精品 | 三级a毛片 | 午夜av福利 | 91亚洲精品在线观看 | 日本在线视频观看 | 91系列在线观看 | 老司机精品福利视频 | 成人免费一区二区三区在线观看 | 日韩人妻精品在线 | 69精品一区二区 | a v视频在线观看 | 性欧美欧美巨大69 | 成人免费看片载 | 日本aa在线观看 | 一级黄色片免费在线观看 | 第一毛片 | 国产精品一区二区三区免费观看 | 免费看欧美成人a片无码 | 久久精品国产亚洲av麻豆色欲 | 久久国产经典 | 久久香蕉网站 | 调教一区 | 在线观看亚洲区 | 欧美激情区 | 欧日韩在线 | 麻豆传媒在线看 | 久久精视频 | 香蕉久久精品 | 一级做a免费视频 | 精品黑人一区二区三区 | 亚拍一区 | 欧美一级啪啪 | 亚洲乱亚洲乱 | 欧美熟妇精品黑人巨大一二三区 | 老司机深夜免费福利 | 日本wwwxxx | 久久精品视频18 | 男女裸体无遮挡做爰 | 麻豆传媒在线视频 | 自拍视频网址 | 国产美女黄色 | 三级黄色免费网站 | 亚洲成人午夜在线 | 寂寞d奶大胸少妇 | 日韩欧美国产另类 | 激情五月色综合国产精品 | 男女无遮挡免费视频 | 伊人春色在线观看 | 欧美草草| 99热热 | 四虎成人av | 久久调教 | 亚洲av毛片一区二二区三三区 | 蜜桃成人无码区免费视频网站 | 小向美奈子在线观看 | 欧美黑人性生活 | 久久午夜电影网 | 操皮视频 | 欧美日韩一区免费 | 性xxx18| jizz中国少妇 | 午夜宫| 欧美精品片 | 国产高清免费在线观看 | 自拍偷拍亚洲综合 | 国产精品久久久久久久一区探花 | 欧美性猛交 xxxx | 老鸭窝久久 | 国产欧美中文字幕 | 日本色www |