您好,登錄后才能下訂單哦!
這篇文章主要介紹“Bystack跨鏈技術怎么使用”,在日常操作中,相信很多人在Bystack跨鏈技術怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Bystack跨鏈技術怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Bystack是由比原鏈團隊提出的一主多側鏈架構的BaaS平臺。其將區塊鏈應用分為三層架構:底層賬本層,側鏈擴展層,業務適配層。底層賬本層為Layer1,即為目前比較成熟的采用POW共識的Bytom公鏈。側鏈擴展層為Layer2,為多側鏈層,vapor側鏈即處于Layer2。
Vapor側鏈采用DPOS和BBFT共識,TPS可以達到數萬。此處就分析一下連接Bytom主鏈和Vapor側鏈的跨鏈模型。
主側鏈協同工作模型
1、技術細節
POW當前因為能源浪費而飽受詬病,而且POW本身在提高TPS的過程中遇到諸多問題,理論上可以把塊變大,可以往塊里面塞更多的交易。TPS是每秒出塊數*塊里面的交易數。但是也存在問題:小節點吃不消存儲這么大的容量的內容,會慢慢變成中心化的模式,因為只有大財團和大機構才有財力去組建機房設備,成為能出塊的節點。同時傳輸也存在問題,網絡帶寬是有限的,塊的大小與網絡傳輸的邊際是有關的,不可能無限的去增加塊的大小,網絡邊際上的人拿不到新塊的信息,也會降低去中心化的程度,這就是為什么POW不能在提高可靠性的情況下,提高TPS的原因。
而BFT雖然去中心化較弱,但其效率和吞吐量高,也不需要大量的共識計算,非常環保節能,很符合Bystack側鏈高TPS的性能需求
(1)跨鏈模型架構
在Bystack的主側鏈協同工作模型中,包括有主鏈、側鏈和Federation。主鏈為bytom,采用基于對AI 計算友好型PoW(工作量證明)算法,主要負責價值錨定,價值傳輸和可信存證。側鏈為Vapor,采用DPOS+BBFT共識,高TPS滿足垂直領域業務。主鏈和側鏈之間的資產流通主要依靠Federation。
(2)節點類型
跨鏈模型中的節點主要有收集人、驗證人和聯邦成員。收集人監控聯邦地址,收集交易后生成Claim交易進行跨鏈。驗證人則是側鏈的出塊人。聯邦成員由側鏈的用戶投票通過選舉產生,負責生成新的聯邦合約地址。
(3)跨鏈交易流程
主鏈到側鏈
主鏈用戶將代幣發送至聯邦合約地址,收集人監控聯邦地址,發現跨鏈交易后生成Claim交易,發送至側鏈
側鏈到主鏈
側鏈用戶發起提現交易,銷毀側鏈資產。收集人監控側鏈至主鏈交易,向主鏈地址發送對應數量資產。最后聯邦在側鏈生成一筆完成提現的操作交易。
2、代碼解析
跨鏈代碼主要處于federation文件夾下,這里就這部分代碼進行一個介紹。
(1)keeper啟動
整個跨鏈的關鍵在于同步主鏈和側鏈的區塊,并處理區塊中的跨鏈交易。這部份代碼主要在mainchain_keerper.go和sidechain_keerper.go兩部分中,分別對應處理主鏈和側鏈的區塊。keeper在Run函數中啟動。
func (m *mainchainKeeper) Run() { ticker := time.NewTicker(time.Duration(m.cfg.SyncSeconds) * time.Second) for ; true; <-ticker.C { for { isUpdate, err := m.syncBlock() if err != nil { //.. } if !isUpdate { break } } } }
Run函數中首先生成一個定時的Ticker,規定每隔SyncSeconds秒同步一次區塊,處理區塊中的交易。
(2)主側鏈同步區塊
Run函數會調用syncBlock函數同步區塊。
func (m *mainchainKeeper) syncBlock() (bool, error) { chain := &orm.Chain{Name: m.chainName} if err := m.db.Where(chain).First(chain).Error; err != nil { return false, errors.Wrap(err, "query chain") } height, err := m.node.GetBlockCount() //.. if height <= chain.BlockHeight+m.cfg.Confirmations { return false, nil } nextBlockStr, txStatus, err := m.node.GetBlockByHeight(chain.BlockHeight + 1) //.. nextBlock := &types.Block{} if err := nextBlock.UnmarshalText([]byte(nextBlockStr)); err != nil { return false, errors.New("Unmarshal nextBlock") } if nextBlock.PreviousBlockHash.String() != chain.BlockHash { //... return false, ErrInconsistentDB } if err := m.tryAttachBlock(chain, nextBlock, txStatus); err != nil { return false, err } return true, nil }
這個函數受限會根據chainName從數據庫中取出對應的chain。然后利用GetBlockCount函數獲得chain的高度。然后進行一個偽確定性的檢測。
height <= chain.BlockHeight+m.cfg.Confirmations
主要是為了判斷鏈上的資產是否已經不可逆。這里Confirmations的值被設為10。如果不進行這個等待不可逆的過程,很可能主鏈資產跨鏈后,主鏈的最長鏈改變,導致這筆交易沒有在主鏈被打包,而側鏈卻增加了相應的資產。在此之后,通過GetBlockByHeight函數獲得chain的下一個區塊。
nextBlockStr, txStatus, err := m.node.GetBlockByHeight(chain.BlockHeight + 1)
這里必須滿足下個區塊的上一個區塊哈希等于當前chain中的這個頭部區塊哈希。這也符合區塊鏈的定義。
if nextBlock.PreviousBlockHash.String() != chain.BlockHash { //.. }
在此之后,通過調用tryAttachBlock函數進一步調用processBlock函數處理區塊。
(3)區塊處理
processBlock函數會判斷區塊中交易是否為跨鏈的deposit或者是withdraw,并分別調用對應的函數去進行處理。
func (m *mainchainKeeper) processBlock(chain *orm.Chain, block *types.Block, txStatus *bc.TransactionStatus) error { if err := m.processIssuing(block.Transactions); err != nil { return err } for i, tx := range block.Transactions { if m.isDepositTx(tx) { if err := m.processDepositTx(chain, block, txStatus, uint64(i), tx); err != nil { return err } } if m.isWithdrawalTx(tx) { if err := m.processWithdrawalTx(chain, block, uint64(i), tx); err != nil { return err } } } return m.processChainInfo(chain, block) }
在這的processIssuing函數,它內部會遍歷所有交易輸入Input的資產類型,也就是AssetID。當這個AssetID不存在的時候,則會去在系統中創建一個對應的資產類型。每個Asset對應的數據結構如下所示。
m.assetStore.Add(&orm.Asset{ AssetID: assetID.String(), IssuanceProgram: hex.EncodeToString(inp.IssuanceProgram), VMVersion: inp.VMVersion, RawDefinitionByte: hex.EncodeToString(inp.AssetDefinition), })
在processBlock函數中,還會判斷區塊中每筆交易是否為跨鏈交易。主要通過isDepositTx和isWithdrawalTx函數進行判斷。
func (m *mainchainKeeper) isDepositTx(tx *types.Tx) bool { for _, output := range tx.Outputs { if bytes.Equal(output.OutputCommitment.ControlProgram, m.fedProg) { return true } } return false } func (m *mainchainKeeper) isWithdrawalTx(tx *types.Tx) bool { for _, input := range tx.Inputs { if bytes.Equal(input.ControlProgram(), m.fedProg) { return true } } return false }
看一下這兩個函數,主要還是通過比較交易中的control program這個標識和mainchainKeeper這個結構體中的fedProg進行比較,如果相同則為跨鏈交易。fedProg在結構體中為一個字節數組。
type mainchainKeeper struct { cfg *config.Chain db *gorm.DB node *service.Node chainName string assetStore *database.AssetStore fedProg []byte }
(4)跨鏈交易(主鏈到側鏈的deposit)處理
這部分主要分為主鏈到側鏈的deposit和側鏈到主鏈的withdraw。先看比較復雜的主鏈到側鏈的deposit這部分代碼的處理。
func (m *mainchainKeeper) processDepositTx(chain *orm.Chain, block *types.Block, txStatus *bc.TransactionStatus, txIndex uint64, tx *types.Tx) error { //.. rawTx, err := tx.MarshalText() if err != nil { return err } ormTx := &orm.CrossTransaction{ //.. } if err := m.db.Create(ormTx).Error; err != nil { return errors.Wrap(err, fmt.Sprintf("create mainchain DepositTx %s", tx.ID.String())) } statusFail := txStatus.VerifyStatus[txIndex].StatusFail crossChainInputs, err := m.getCrossChainReqs(ormTx.ID, tx, statusFail) if err != nil { return err } for _, input := range crossChainInputs { if err := m.db.Create(input).Error; err != nil { return errors.Wrap(err, fmt.Sprintf("create DepositFromMainchain input: txid(%s), pos(%d)", tx.ID.String(), input.SourcePos)) } } return nil }
這里它創建了一個跨鏈交易orm。具體的結構如下。可以看到,這里它的結構體中包括有source和dest的字段。
ormTx := &orm.CrossTransaction{ ChainID: chain.ID, SourceBlockHeight: block.Height, SourceBlockTimestamp: block.Timestamp, SourceBlockHash: blockHash.String(), SourceTxIndex: txIndex, SourceMuxID: muxID.String(), SourceTxHash: tx.ID.String(), SourceRawTransaction: string(rawTx), DestBlockHeight: sql.NullInt64{Valid: false}, DestBlockTimestamp: sql.NullInt64{Valid: false}, DestBlockHash: sql.NullString{Valid: false}, DestTxIndex: sql.NullInt64{Valid: false}, DestTxHash: sql.NullString{Valid: false}, Status: common.CrossTxPendingStatus, }
創建這筆跨鏈交易后,它會將交易存入數據庫中。
if err := m.db.Create(ormTx).Error; err != nil { return errors.Wrap(err, fmt.Sprintf("create mainchain DepositTx %s", tx.ID.String())) }
在此之后,這里會調用getCrossChainReqs。這個函數內部較為復雜,主要作用就是遍歷交易的輸出,返回一個跨鏈交易的請求數組。具體看下這個函數。
func (m *mainchainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types.Tx, statusFail bool) ([]*orm.CrossTransactionReq, error) { //.. switch { case segwit.IsP2WPKHScript(prog): //.. case segwit.IsP2WSHScript(prog): //.. } reqs := []*orm.CrossTransactionReq{} for i, rawOutput := range tx.Outputs { //.. req := &orm.CrossTransactionReq{ //.. } reqs = append(reqs, req) } return reqs, nil }
很顯然,這個地方的交易類型有pay to public key hash 和 pay to script hash這兩種。這里會根據不同的交易類型進行一個地址的獲取。
switch { case segwit.IsP2WPKHScript(prog): if pubHash, err := segwit.GetHashFromStandardProg(prog); err == nil { fromAddress = wallet.BuildP2PKHAddress(pubHash, &vaporConsensus.MainNetParams) toAddress = wallet.BuildP2PKHAddress(pubHash, &vaporConsensus.VaporNetParams) } case segwit.IsP2WSHScript(prog): if scriptHash, err := segwit.GetHashFromStandardProg(prog); err == nil { fromAddress = wallet.BuildP2SHAddress(scriptHash, &vaporConsensus.MainNetParams) toAddress = wallet.BuildP2SHAddress(scriptHash, &vaporConsensus.VaporNetParams) } }
在此之后,函數會遍歷所有交易的輸出,然后創建跨鏈交易請求,具體的結構如下。
req := &orm.CrossTransactionReq{ CrossTransactionID: crossTransactionID, SourcePos: uint64(i), AssetID: asset.ID, AssetAmount: rawOutput.OutputCommitment.AssetAmount.Amount, Script: script, FromAddress: fromAddress, ToAddress: toAddress, }
創建完所有的跨鏈交易請求后,返回到processDepositTx中一個crossChainInputs數組中,并存入db。
for _, input := range crossChainInputs { if err := m.db.Create(input).Error; err != nil { return errors.Wrap(err, fmt.Sprintf("create DepositFromMainchain input: txid(%s), pos(%d)", tx.ID.String(), input.SourcePos)) } }
到這里,對主鏈到側鏈的deposit已經處理完畢。
(5)跨鏈交易(側鏈到主鏈的withdraw)交易處理
這部分比較復雜的邏輯主要在sidechain_keeper.go中的processWithdrawalTx函數中。這部分邏輯和上面主鏈到側鏈的deposit邏輯類似。同樣是創建了orm.crossTransaction結構體,唯一的改變就是交易的souce和dest相反。這里就不作具體描述了。
3、跨鏈優缺點
優點
(1) 跨鏈模型、代碼較為完整。當前有很多項目使用跨鏈技術,但是真正實現跨鏈的寥寥無幾。
(2) 可以根據不同需求實現側鏈,滿足多種場景
缺點
(1) 跨鏈速度較慢,需等待10個區塊確認,這在目前Bytom網絡上所需時間為30分鐘左右
(2) 相較于comos、polkadot等項目,開發者要開發側鏈接入主網成本較大
(3) 只支持資產跨鏈,不支持跨鏈智能合約調用
**4、**跨鏈模型平行對比Cosmos
可擴展性
bystack的主測鏈協同工作模型依靠Federation,未形成通用協議。其他開發者想要接入其跨鏈網絡難度較大。Cosmos采用ibc協議,可擴展性較強。
代碼開發進度
vapor側鏈已經能夠實現跨鏈。Cosmos目前暫無成熟跨鏈項目出現,ibc協議處于最終開發階段。
跨鏈模型
vapor為主側鏈模型,Cosmos為Hub-Zone的中繼鏈模型。
5、參考建議
側鏈使用bbft共識,非POW的情況下,無需等待10個交易確認,增快跨鏈速度。
到此,關于“Bystack跨鏈技術怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。