内容简介:当我们基于比原做应用的时候,在构建交易过程中会遇到以下两种情况。多个地址向一个地址转账,还有一种就是从一个地址分批次向多个地址转账。那我们今天就来介绍一下这两种交易构建的具体流程,以及贴出具体实现的代码。当我们从多个钱包地址一次性转到一个地址的时候,为了提高用户体验。我们可以选择链式交易,把多笔交易一次性打包。那我们下面就来看一下链式交易的流程。
当我们基于比原做应用的时候,在构建交易过程中会遇到以下两种情况。多个地址向一个地址转账,还有一种就是从一个地址分批次向多个地址转账。那我们今天就来介绍一下这两种交易构建的具体流程,以及贴出具体实现的代码。
链式交易
当我们从多个钱包地址一次性转到一个地址的时候,为了提高用户体验。我们可以选择链式交易,把多笔交易一次性打包。那我们下面就来看一下链式交易的流程。
接下来我们来看一下build-transaction接口的代码实现过程,代码如下:
// POST /build-chain-transactions func (a *API) buildChainTxs(ctx context.Context, buildReqs *BuildRequest) Response { //验证请求id subctx := reqid.NewSubContext(ctx, reqid.New()) //构建交易,方法的具体过程在下面 tmpls, err := a.buildTxs(subctx, buildReqs) if err != nil { return NewErrorResponse(err) } return NewSuccessResponse(tmpls) }
核心的实现方法,buildTxs方法的实现如下:
func (a *API) buildTxs(ctx context.Context, req *BuildRequest) ([]*txbuilder.Template, error) { //验证参数的合法性 if err := a.checkRequestValidity(ctx, req); err != nil { return nil, err } //合并处理交易输入输出的类型组合 actions, err := a.mergeSpendActions(req) if err != nil { return nil, err } //构建一笔新的交易模板 builder := txbuilder.NewBuilder(time.Now().Add(req.TTL.Duration)) //声明交易模板 tpls := []*txbuilder.Template{} //遍历交易的输入输出类型组合 for _, action := range actions { //类型组合的输入为apend_account if action.ActionType() == "spend_account" { //构建花费的输入输出类型组合并且自动合并UTXO tpls, err = account.SpendAccountChain(ctx, builder, action) } else { //构建交易输入输出类型组合 err = action.Build(ctx, builder) } if err != nil { //回滚 builder.Rollback() return nil, err } } //构建交易 tpl, _, err := builder.Build() if err != nil { //回滚 builder.Rollback() return nil, err } tpls = append(tpls, tpl) return tpls, nil }
build方法的实现过程:
// Build build transactions with template func (b *TemplateBuilder) Build() (*Template, *types.TxData, error) { // Run any building callbacks. for _, cb := range b.callbacks { err := cb() if err != nil { return nil, nil, err } } tpl := &Template{} tx := b.base if tx == nil { tx = &types.TxData{ Version: 1, } } if b.timeRange != 0 { tx.TimeRange = b.timeRange } // Add all the built outputs. tx.Outputs = append(tx.Outputs, b.outputs...) // Add all the built inputs and their corresponding signing instructions. for i, in := range b.inputs { instruction := b.signingInstructions[i] instruction.Position = uint32(len(tx.Inputs)) // Empty signature arrays should be serialized as empty arrays, not null. if instruction.WitnessComponents == nil { instruction.WitnessComponents = []witnessComponent{} } tpl.SigningInstructions = append(tpl.SigningInstructions, instruction) tx.Inputs = append(tx.Inputs, in) } tpl.Transaction = types.NewTx(*tx) tpl.Fee = CalculateTxFee(tpl.Transaction) return tpl, tx, nil }
到此,我们的链式交易的代码到此就讲解到这儿。如果感兴趣想仔细阅读源码,点击源码地址: https://git.io/fhAsr
花费未确认的交易
下面我们来介绍一下花费未确认的交易,我们首先介绍一下什么是花费未确认的交易。我们知道UTXO模型在交易的过程中,如果交易未打包确认。再进行第二笔转账就会存在“双花”问题,就不能再发起交易或者需要等一段时间才能再发起一笔交易。如果使用花费未确认的交易就可以避免这个问题。
那么花费未确认的交易实现机制是什么样的呢?我们在创建第一笔交易的时候,会找零,此时交易是未确认的状态。找零存在交易池中,我们发第二笔交易的时候就直接使用在交易池中找零地址里面的资产。
那我们来看一下花费未确认交易的代码实现过程,花费过程结构体如下:
type spendAction struct { accounts *Manager //存储账户及其相关的控制程序参数 bc.AssetAmount //资产id和资产数量的结构体 AccountID string `json:"account_id"` //账户id UseUnconfirmed bool `json:"use_unconfirmed"` //是否未确认 }
方法如下:
// MergeSpendAction merge common assetID and accountID spend action func MergeSpendAction(actions []txbuilder.Action) []txbuilder.Action { //声明变量,map resultActions := []txbuilder.Action{} spendActionMap := make(map[string]*spendAction) //遍历交易的输入输出类型组合 for _, act := range actions { switch act := act.(type) { case *spendAction: //actionKey字符串拼接 actionKey := act.AssetId.String() + act.AccountID //遍历spendActionMap if tmpAct, ok := spendActionMap[actionKey]; ok { tmpAct.Amount += act.Amount tmpAct.UseUnconfirmed = tmpAct.UseUnconfirmed || act.UseUnconfirmed } else { spendActionMap[actionKey] = act resultActions = append(resultActions, act) } default: resultActions = append(resultActions, act) } } return resultActions }
上面只是简单的贴出了核心的实现代码,如果感兴趣想仔细阅读源码,点击地址: https://git.io/fhAsw
这一期的内容我们到此就结束了,如果你感兴趣可以加入我们的社区一起讨论。如果在阅读的过程中有什么疑问可以在下方给我们留言,我们将第一时间为你解答。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 每日一道算法题--leetcode 746--使用最小花费爬楼梯--python
- 花费大量精力也招不到合适的人,只因你不会人才画像
- Apache Spark 2.0 在作业完成时却花费很长时间结束
- 在《我的世界》里从零打造一台计算机有多难?复旦本科生大神花费了一年心血
- 一探0 day漏洞交易背后的黑市交易
- 资源就是生产力,使用BiClub交易所资源可免交易手续费
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。