博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bytom的链式交易和花费未确认的交易
阅读量:6952 次
发布时间:2019-06-27

本文共 3901 字,大约阅读时间需要 13 分钟。

当我们基于比原做应用的时候,在构建交易过程中会遇到以下两种情况。多个地址向一个地址转账,还有一种就是从一个地址分批次向多个地址转账。那我们今天就来介绍一下这两种交易构建的具体流程,以及贴出具体实现的代码。

链式交易

当我们从多个钱包地址一次性转到一个地址的时候,为了提高用户体验。我们可以选择链式交易,把多笔交易一次性打包。那我们下面就来看一下链式交易的流程。

接下来我们来看一下build-transaction接口的代码实现过程,代码如下:

// POST /build-chain-transactionsfunc (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 templatefunc (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.baseif 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}复制代码

到此,我们的链式交易的代码到此就讲解到这儿。如果感兴趣想仔细阅读源码,点击源码地址:

花费未确认的交易

下面我们来介绍一下花费未确认的交易,我们首先介绍一下什么是花费未确认的交易。我们知道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 actionfunc 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}复制代码

上面只是简单的贴出了核心的实现代码,如果感兴趣想仔细阅读源码,点击地址:

这一期的内容我们到此就结束了,如果你感兴趣可以加入我们的社区一起讨论。如果在阅读的过程中有什么疑问可以在下方给我们留言,我们将第一时间为你解答。

转载地址:http://obnil.baihongyu.com/

你可能感兴趣的文章
多媒体之录音
查看>>
何为程序员思维
查看>>
【导入导出】compress 值为y对导入对象所占空间的影响
查看>>
mysql 分区类型详解
查看>>
ORACLE同义词总结
查看>>
iOS 设备类型和版本判断
查看>>
ios字体设置
查看>>
【SICP练习】51 练习2.19
查看>>
solveCrossprod求 X'X的逆, ( X' == t(X), 即X的行列变换矩阵 )
查看>>
PostgreSQL column cryptographic use pgcrypto extension and optional openssl lib
查看>>
通过支付宝服务中断事件看系统可靠性和YunOS的可靠性
查看>>
oVirt VM (CentOS) template & clone
查看>>
Linux内核编译与启动流程
查看>>
Flutter框架分析(二)-- 初始化
查看>>
mac更新系统后Android studio Git不能用,提示missing xcrun at
查看>>
微信公众号排版
查看>>
常用布局-1
查看>>
Swift基础语法学习-3.类型转换
查看>>
向你安利了一个编辑器,并丢给你一堆插件
查看>>
Flutter 入门之 ListTile 使用指南
查看>>