Bytom Trading Instructions (UTXO user's own management mode)

Source: Internet
Author: User

Compared to the original project warehouse:

GitHub Address: Https://github.com/Bytom/bytom

Gitee Address: Https://gitee.com/BytomBlockc ...

This section mainly for the user to manage the private key and address, and through the Utxo to build and send transactions.

    • 1. Create a private key and public key
    • 2. Create a Receive object from the public key
    • 3. Find what you can spendutxo
    • 4. Through utxo structuring transactions
    • 5. Combined trading input and composition of the output transaction template
    • 6. Sign a structured transaction
    • 7. Submit the Trading link

Precautions:

The following steps and functional modifications are for reference only, the specific code implementation needs the user to debug according to the actual situation, specific reference unit test case Code blockchain/txbuilder/txbuilder_test.go#l255

1. Create a private key and public key

This section of functionality can be referenced by code CRYPTO/ED25519/CHAINKD/UTIL.GO#L11, by NewXKeys(nil) creating a master private key and a master public key

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. Create a Receive object from the public key

The Receiving object contains two forms: address form and program form, both of which correspond to one by one, whichever is the same. Where you create a single-sign address reference code account/accounts.go#l267 the corresponding transformation to:

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}

Create a multi-sign address reference code account/accounts.go#l294 the corresponding transformation to:

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. Find utxo that can be spent

Finding the utxo that can be spent is actually finding the receiving address or receiving program it yourself unspend_output . Where the structure of Utxo is: (Reference code 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}

The related fields involved in Utxo structuring transactions are described below:

    • SourceIDThe mux_id of the previous associated transaction, which can be used to locate the output of the previous transaction
    • AssetIDUtxo's Asset ID
    • AmountUtxo Number of assets
    • SourcePosThe position of the utxo in the output of the previous transaction
    • ControlProgramUtxo's Receiving program
    • AddressUtxo's receiving address

The field information of these utxo can be get-block found in the transaction of the interface return result, and its related structure is as follows: (Reference code API/BLOCK_RETRIEVE.GO#L26)

BLOCKTX is the TX struct for getblock functype 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 ' js On: "Account_id,omitempty" ' Accountalias string ' JSON: "Account_alias,omitempty" ' Controlprogram chain Json. Hexbytes ' JSON: ' Control_program ' ' Address string ' json: ' Address,omitempty '}

The field correspondence between the Utxo and Get-block returns results is as follows:

`SourceID`       - `json:"mux_id"``AssetID`        - `json:"asset_id"``Amount`         - `json:"amount"``SourcePos`      - `json:"position"``ControlProgram` - `json:"control_program"``Address`        - `json:"address,omitempty"`

4. Through utxo structuring transactions

Structuring transactions through Utxo is a way to use Spend_account_unspent_output to spend the specified utxo.

The first step, through the utxo construction of the transaction input TxInput and signature required data information SigningInstruction , this part of the function can refer to the code account/builder.go#l169 the corresponding transformation to:

Utxotoinputs convert an utxo to the Txinputfunc 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} si Ginst.witnesscomponents = Append (sigInst.witnesscomponents, Txbuilder. Datawitness (script)) Default:return nil, nil, errors. New ("Unsupport Address Type")} return Txinput, Siginst, nil}

The second step, by utxo structuring the trade outputTxOutput
This section of the function can refer to the code PROTOCOL/BC/TYPES/TXOUTPUT.GO#L20:

// NewTxOutput create a new output structfunc 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 and output of the combined transaction constitute the transaction template

Structuring the transaction through the generated trading information above txbuilder.Template , this part of the function can be referred to blockchain/txbuilder/builder.go#l92 to transform to:

type InputAndSigInst struct {    input *types.TxInput    sigInst *SigningInstruction}// Build build transactions with templatefunc 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. Sign a structured transaction

The account model is to find the corresponding private key based on the password to sign the transaction, where the user can directly use the private key to sign the transaction, you can refer to the signature code blockchain/txbuilder/txbuilder.go#l82 to transform to: (The following transformation only support single-sign transactions, Multi-sign trading users can refer to this example for modification)

// Sign will try to sign all the witnessfunc 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. Submit the Trading link

This step does not need to change anything, just refer to the apisubmit-transaction function of the wiki to submit the transaction.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.