摘要:比原項(xiàng)目倉(cāng)庫(kù)地址地址該部分主要針對(duì)用戶(hù)自己管理私鑰和地址,并通過(guò)來(lái)構(gòu)建和發(fā)送交易。其中創(chuàng)建單簽地址參考代碼進(jìn)行相應(yīng)改造為創(chuàng)建多簽地址參考代碼進(jìn)行相應(yīng)改造為找到可花費(fèi)的找到可花費(fèi)的,其實(shí)就是找到接收地址或接收是你自己的。
比原項(xiàng)目倉(cāng)庫(kù):
Github地址:https://github.com/Bytom/bytom
Gitee地址:https://gitee.com/BytomBlockc...
該部分主要針對(duì)用戶(hù)自己管理私鑰和地址,并通過(guò)utxo來(lái)構(gòu)建和發(fā)送交易。
1.創(chuàng)建私鑰和公鑰
2.根據(jù)公鑰創(chuàng)建接收對(duì)象
3.找到可花費(fèi)的utxo
4.通過(guò)utxo構(gòu)造交易
5.組合交易的input和output構(gòu)成交易模板
6.對(duì)構(gòu)造的交易進(jìn)行簽名
7.提交交易上鏈
注意事項(xiàng):
以下步驟以及功能改造僅供參考,具體代碼實(shí)現(xiàn)需要用戶(hù)根據(jù)實(shí)際情況進(jìn)行調(diào)試,具體可以參考單元測(cè)試案例代碼blockchain/txbuilder/txbuilder_test.go#L255
1.創(chuàng)建私鑰和公鑰該部分功能可以參考代碼crypto/ed25519/chainkd/util.go#L11,可以通過(guò) NewXKeys(nil) 創(chuàng)建主私鑰和主公鑰
func NewXKeys(r io.Reader) (xprv XPrv, xpub XPub, err error) { xprv, err = NewXPrv(r) if err != nil { return } return xprv, xprv.XPub(), nil }2.根據(jù)公鑰創(chuàng)建接收對(duì)象
接收對(duì)象包含兩種形式:address形式和program形式,兩者是一一對(duì)應(yīng)的,任選其一即可。其中創(chuàng)建單簽地址參考代碼account/accounts.go#L267進(jìn)行相應(yīng)改造為:
func (m *Manager) createP2PKH(xpub chainkd.XPub) (*CtrlProgram, error) { pubKey := xpub.PublicKey() pubHash := crypto.Ripemd160(pubKey) // TODO: pass different params due to config address, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.ActiveNetParams) if err != nil { return nil, err } control, err := vmutil.P2WPKHProgram([]byte(pubHash)) if err != nil { return nil, err } return &CtrlProgram{ Address: address.EncodeAddress(), ControlProgram: control, }, nil }
創(chuàng)建多簽地址參考代碼account/accounts.go#L294進(jìn)行相應(yīng)改造為:
func (m *Manager) createP2SH(xpubs []chainkd.XPub) (*CtrlProgram, error) { derivedPKs := chainkd.XPubKeys(xpubs) signScript, err := vmutil.P2SPMultiSigProgram(derivedPKs, len(derivedPKs)) if err != nil { return nil, err } scriptHash := crypto.Sha256(signScript) // TODO: pass different params due to config address, err := common.NewAddressWitnessScriptHash(scriptHash, &consensus.ActiveNetParams) if err != nil { return nil, err } control, err := vmutil.P2WSHProgram(scriptHash) if err != nil { return nil, err } return &CtrlProgram{ Address: address.EncodeAddress(), ControlProgram: control, }, nil }3.找到可花費(fèi)的utxo
找到可花費(fèi)的utxo,其實(shí)就是找到接收地址或接收program是你自己的unspend_output。其中utxo的結(jié)構(gòu)為:(參考代碼account/reserve.go#L39)
// UTXO describes an individual account utxo. type UTXO struct { OutputID bc.Hash SourceID bc.Hash // Avoiding AssetAmount here so that new(utxo) doesn"t produce an // AssetAmount with a nil AssetId. AssetID bc.AssetID Amount uint64 SourcePos uint64 ControlProgram []byte AccountID string Address string ControlProgramIndex uint64 ValidHeight uint64 Change bool }
涉及utxo構(gòu)造交易的相關(guān)字段說(shuō)明如下:
SourceID 前一筆關(guān)聯(lián)交易的mux_id, 根據(jù)該ID可以定位到前一筆交易的output
AssetID utxo的資產(chǎn)ID
Amount utxo的資產(chǎn)數(shù)目
SourcePos 該utxo在前一筆交易的output的位置
ControlProgram utxo的接收program
Address utxo的接收地址
上述這些utxo的字段信息可以從get-block接口返回結(jié)果的transaction中找到,其相關(guān)的結(jié)構(gòu)體如下:(參考代碼api/block_retrieve.go#L26)
// BlockTx is the tx struct for getBlock func type BlockTx struct { ID bc.Hash `json:"id"` Version uint64 `json:"version"` Size uint64 `json:"size"` TimeRange uint64 `json:"time_range"` Inputs []*query.AnnotatedInput `json:"inputs"` Outputs []*query.AnnotatedOutput `json:"outputs"` StatusFail bool `json:"status_fail"` MuxID bc.Hash `json:"mux_id"` } //AnnotatedOutput means an annotated transaction output. type AnnotatedOutput struct { Type string `json:"type"` OutputID bc.Hash `json:"id"` TransactionID *bc.Hash `json:"transaction_id,omitempty"` Position int `json:"position"` AssetID bc.AssetID `json:"asset_id"` AssetAlias string `json:"asset_alias,omitempty"` AssetDefinition *json.RawMessage `json:"asset_definition,omitempty"` Amount uint64 `json:"amount"` AccountID string `json:"account_id,omitempty"` AccountAlias string `json:"account_alias,omitempty"` ControlProgram chainjson.HexBytes `json:"control_program"` Address string `json:"address,omitempty"` }
utxo跟get-block返回結(jié)果的字段對(duì)應(yīng)關(guān)系如下:
`SourceID` - `json:"mux_id"` `AssetID` - `json:"asset_id"` `Amount` - `json:"amount"` `SourcePos` - `json:"position"` `ControlProgram` - `json:"control_program"` `Address` - `json:"address,omitempty"`4.通過(guò)utxo構(gòu)造交易
通過(guò)utxo構(gòu)造交易就是使用spend_account_unspent_output的方式來(lái)花費(fèi)指定的utxo。
第一步,通過(guò)utxo構(gòu)造交易輸入TxInput和簽名需要的數(shù)據(jù)信息SigningInstruction,該部分功能可以參考代碼account/builder.go#L169進(jìn)行相應(yīng)改造為:
// UtxoToInputs convert an utxo to the txinput func UtxoToInputs(xpubs []chainkd.XPub, u *UTXO) (*types.TxInput, *txbuilder.SigningInstruction, error) { txInput := types.NewSpendInput(nil, u.SourceID, u.AssetID, u.Amount, u.SourcePos, u.ControlProgram) sigInst := &txbuilder.SigningInstruction{} if u.Address == "" { return txInput, sigInst, nil } address, err := common.DecodeAddress(u.Address, &consensus.ActiveNetParams) if err != nil { return nil, nil, err } switch address.(type) { case *common.AddressWitnessPubKeyHash: derivedPK := xpubs[0].PublicKey() sigInst.WitnessComponents = append(sigInst.WitnessComponents, txbuilder.DataWitness([]byte(derivedPK))) case *common.AddressWitnessScriptHash: derivedPKs := chainkd.XPubKeys(xpubs) script, err := vmutil.P2SPMultiSigProgram(derivedPKs, len(derivedPKs)) if err != nil { return nil, nil, err } sigInst.WitnessComponents = append(sigInst.WitnessComponents, txbuilder.DataWitness(script)) default: return nil, nil, errors.New("unsupport address type") } return txInput, sigInst, nil }
第二步,通過(guò)utxo構(gòu)造交易輸出TxOutput
該部分功能可以參考代碼protocol/bc/types/txoutput.go#L20:
// NewTxOutput create a new output struct func NewTxOutput(assetID bc.AssetID, amount uint64, controlProgram []byte) *TxOutput { return &TxOutput{ AssetVersion: 1, OutputCommitment: OutputCommitment{ AssetAmount: bc.AssetAmount{ AssetId: &assetID, Amount: amount, }, VMVersion: 1, ControlProgram: controlProgram, }, } }5.組合交易的input和output構(gòu)成交易模板
通過(guò)上面已經(jīng)生成的交易信息構(gòu)造交易txbuilder.Template,該部分功能可以參考blockchain/txbuilder/builder.go#L92進(jìn)行改造為:
type InputAndSigInst struct { input *types.TxInput sigInst *SigningInstruction } // Build build transactions with template func BuildTx(inputs []InputAndSigInst, outputs []*types.TxOutput) (*Template, *types.TxData, error) { tpl := &Template{} tx := &types.TxData{} // Add all the built outputs. tx.Outputs = append(tx.Outputs, outputs...) // Add all the built inputs and their corresponding signing instructions. for _, in := range inputs { // Empty signature arrays should be serialized as empty arrays, not null. in.sigInst.Position = uint32(len(inputs)) if in.sigInst.WitnessComponents == nil { in.sigInst.WitnessComponents = []witnessComponent{} } tpl.SigningInstructions = append(tpl.SigningInstructions, in.sigInst) tx.Inputs = append(tx.Inputs, in.input) } tpl.Transaction = types.NewTx(*tx) return tpl, tx, nil }6.對(duì)構(gòu)造的交易進(jìn)行簽名
賬戶(hù)模型是根據(jù)密碼找到對(duì)應(yīng)的私鑰對(duì)交易進(jìn)行簽名,這里用戶(hù)可以直接使用私鑰對(duì)交易進(jìn)行簽名,可以參考簽名代碼blockchain/txbuilder/txbuilder.go#L82進(jìn)行改造為:(以下改造僅支持單簽交易,多簽交易用戶(hù)可以參照該示例進(jìn)行改造)
// Sign will try to sign all the witness func Sign(tpl *Template, xprv chainkd.XPrv) error { for i, sigInst := range tpl.SigningInstructions { h := tpl.Hash(uint32(i)).Byte32() sig := xprv.Sign(h[:]) rawTxSig := &RawTxSigWitness{ Quorum: 1, Sigs: []json.HexBytes{sig}, } sigInst.WitnessComponents = append([]witnessComponent(rawTxSig), sigInst.WitnessComponents...) } return materializeWitnesses(tpl) }7.提交交易上鏈
該步驟無(wú)需更改任何內(nèi)容,直接參照wiki中提交交易的APIsubmit-transaction的功能即可
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/24255.html
摘要:一引文設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),組合了許多技術(shù)點(diǎn),如,,,,,,等。采用樹(shù),其中的數(shù)據(jù)可快速證明,可以快速證明每一份狀態(tài)機(jī)是否一致。四是在狀態(tài)機(jī)的轉(zhuǎn)化過(guò)程被啟動(dòng)運(yùn)行,也就是這一步驟。是指發(fā)布該資產(chǎn)時(shí)需要執(zhí)行的程序。的邏輯結(jié)構(gòu)則是用二叉樹(shù)來(lái)管理。 一、引文 設(shè)計(jì)Bytom 數(shù)據(jù)結(jié)構(gòu),組合了許多技術(shù)點(diǎn),如 patricia tree,utxo, bvm, account model,protobuf,...
摘要:比原項(xiàng)目倉(cāng)庫(kù)地址地址一合約簡(jiǎn)述是的一種智能合約語(yǔ)言,是一門(mén)聲明性謂詞語(yǔ)言。詳細(xì)說(shuō)明請(qǐng)參考官方合約相關(guān)介紹。編譯合約,返回結(jié)果便是可鎖定的合約。三解鎖合約流程合約交易被區(qū)塊打包成功之后,可以查看具體的合約交易內(nèi)容,找到對(duì)應(yīng)的。 比原項(xiàng)目倉(cāng)庫(kù): Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBl...
摘要:當(dāng)使用構(gòu)建完成一筆交易并簽名后,若沒(méi)有全節(jié)點(diǎn)的幫助,也需要自己實(shí)現(xiàn)網(wǎng)絡(luò)協(xié)議將交易廣播到其他節(jié)點(diǎn)。其中,第一個(gè)依賴(lài)是的封裝,可用于查詢(xún)可用的以及提交交易第二個(gè)依賴(lài)用于構(gòu)建交易以及對(duì)交易進(jìn)行離線(xiàn)簽名。 嚴(yán)格來(lái)說(shuō),tx-signer并不屬于SDK,它是bytomd中構(gòu)建交易、對(duì)交易簽名兩大模塊的java實(shí)現(xiàn)版。因此,若想用tx-signer對(duì)交易進(jìn)行離線(xiàn)簽名,需要由你在本地保管好自己的私鑰。...
摘要:流程總結(jié)就是下載安裝插件錢(qián)包,如果自己的不需要跳過(guò)這一步。然后將編譯后的合約參數(shù)配置在的配置文件,如下圖全紅部分是測(cè)試網(wǎng)合約配置參數(shù)調(diào)用插件錢(qián)包。開(kāi)發(fā)出優(yōu)秀的應(yīng)用。 安裝使用插件錢(qián)包 1. 打開(kāi)Google瀏覽器的應(yīng)用商店,搜索Bystore showImg(https://segmentfault.com/img/bVbq0Ol?w=2554&h=1312); 下載鏈接:http:/...
摘要:函數(shù)總共操作有兩步從緩存中查詢(xún)值,如果查到則返回如果為從緩存中查詢(xún)到則回調(diào)回調(diào)函數(shù)。回調(diào)函數(shù)會(huì)將從磁盤(pán)上獲得到塊信息存儲(chǔ)到緩存中并返回該塊的信息。回調(diào)函數(shù)實(shí)際上調(diào)取的是下的,它會(huì)從磁盤(pán)中獲取信息并返回。 作者:Derek 簡(jiǎn)介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockc......
閱讀 1217·2023-04-25 20:31
閱讀 3723·2021-10-14 09:42
閱讀 1494·2021-09-22 16:06
閱讀 2663·2021-09-10 10:50
閱讀 3531·2021-09-07 10:19
閱讀 1778·2019-08-30 15:53
閱讀 1176·2019-08-29 15:13
閱讀 2823·2019-08-29 13:20