Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom交易说明(账户管理模式)

V刘晨曦
108 0 0
比原项目仓库:& c1 {( `' r# h
Github地址:https://github.com/Bytom/bytom
) p& ?+ h6 O; Z) ~# n* q# `Gitee地址:https://gitee.com/BytomBlockchain/bytom5 b6 |, G# N+ Q: ~
该部分主要针对用户使用bytom自带的账户模式发送交易
7 @+ U4 G- V  J- L, K1、构建交易
$ j& k" F6 c) m1 o' AAPI接口 build-transaction,代码api/transact.go#L120( P6 e% y3 Y  n( I7 K' j) b4 E
以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:. s, s# N9 ^. x. Q
{
1 Y$ X/ y, Y" Z* ^$ h3 _  "base_transaction": null,' }) l5 ]) w& N+ s# h! C
  "actions": [
  n. Q# ?  u0 A8 V4 n    {/ L. y- U9 |$ v2 e
      "account_id": "0ER7MEFGG0A02",* T. x& A. D8 L
      "amount": 20000000,
. [% o, u* X5 k: W      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",: X  h5 m: K6 E0 w+ T1 K
      "type": "spend_account"- U5 h0 U; V, w5 ^9 X
    },
. H4 |' {. J6 d    {
9 R0 ]3 V( T& w- t      "account_id": "0ER7MEFGG0A02",
4 S3 Z4 D3 A# @4 u9 w' O      "amount": 99,+ u* W* O5 C/ f) [
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
; k! q( K+ p" q4 j      "type": "spend_account"5 y( ]: j  l, u  B# ]
    },
/ V& x8 w" y% U! h, Q- l- d$ e    {; s0 v1 r7 W, \& T0 {" e6 M, Y
      "amount": 99,
- t! b, S, A! [0 c! }7 j      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",2 D$ D% g; T  w) I4 @1 G
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me"," r' t+ }6 U0 l2 Q+ [
      "type": "control_address"  O0 F$ Y. S+ @& z9 X2 `
    }0 ], A* Q3 @8 V& c1 P6 u3 g6 j
  ],
/ G3 w4 O7 T) i" C8 v  "ttl": 0,8 h, |3 T% G: F4 Y8 R! H
  "time_range": 00 `8 }/ \/ Z0 y1 L/ M$ \4 T
}
2 R1 q' A" ]- q' \对应源代码的请求对象如下:
& c6 u4 A+ B0 D) W  ?, t0 M. T3 l// BuildRequest is main struct when building transactions
+ t% X# d4 r( ]$ Q) p! ntype BuildRequest struct {9 n8 w0 @4 D) B. ], d, e9 O: f7 m
        Tx        *types.TxData            `json:"base_transaction"`: G* x1 u) F! L# l& R* v3 F  o1 T1 A
        Actions   []map[string]interface{} `json:"actions"`  {9 s+ u  L$ N8 E8 u* G
        TTL       json.Duration            `json:"ttl"`
* z) _2 g; b$ m* z. ]) p' [        TimeRange uint64                   `json:"time_range"`  l4 H; c( i& L2 \' w( L
}
- F; s! ~( X& L8 U6 m" J6 c% F结构字段说明如下:
- h: L+ ~8 z: w' PTx 交易的TxData部分,该字段为预留字段,为空即可
$ }0 ~, H4 ?& Y: {; jTTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟' e0 x; E6 E& Q+ a. _6 ^6 t
TimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
# m+ k& k* U$ O4 Y8 W# c! B& AActions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:2 W) d- ?0 U2 f  I8 Q; e
input action 类型:9 H2 V' L1 A* x0 R- f  N. {2 K2 I
issue 发行资产
) Y9 Q' J: [( U2 b" W2 Tspend_account 以账户的模式花费utxo
% X, v( ~) j2 T0 \spend_account_unspent_output 直接花费指定的utxo
- k9 P2 ~  Y7 A; n% i! E) woutput action 类型:
" m2 c* ]. i4 c, t5 }$ r2 j1 `control_address 接收方式为地址模式% C9 {% s2 a2 S! O; ^3 ]
control_program 接收方式为(program)合约模式# ^7 `, m. u  w% H! Z) F3 O
retire 销毁资产
4 D; W$ L) b6 S' S, w# J, m
+ V  Y6 f* v) x% a8 @/ l- x- f
" [- u9 z7 g  u4 ~: f1 l" z; K9 N" q5 v4 n; }
注意事项:
! U7 r8 `$ E# l$ u; j0 ^7 F  Q0 v一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。
  l& [4 f" g# q. M8 c+ C6 c; e除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。+ }# w7 b. `. |6 A) }2 }8 Y
交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量$ k/ X# v2 r; J9 S# l0 g: h& c6 g. u
交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu
+ T) Z% V& i! t& h+ Q# o) c4 }* V1 k* Z
action简介( P$ t/ ^0 o0 d) y' T
下面对构建交易时用到的各种action类型进行详细说明:9 y, \" U, c* e4 g1 G3 i: y$ b* ?
issue1 E( K0 D# L% }3 g+ L
issueAction结构体源代码如下:1 R* j0 w) j6 S& K' V" G1 r$ ^
type issueAction struct {3 S  |; @6 a! e9 K1 {' y
        assets *Registry
: k: O$ ^6 p8 i9 r        bc.AssetAmount
2 W4 Q1 M/ x5 F; C0 r+ S" N& v}& |& R$ s( C# N7 N" H2 Z# h' V" Q
type AssetAmount struct {4 ~; F2 x4 u/ E9 L# R  N/ e
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
1 I  ?7 {9 _$ ~5 Z/ f! Y! {" Q4 v        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
) m, e. L( I* ?6 `5 F! S  f( d# [}% K' @7 Y- l; f$ c. R* G
结构字段说明如下:
) O) d; i  D% T! A9 o8 w, x' Jassets 主要用于资产的管理,无需用户设置参数) ~/ |4 n0 j& J) U8 }5 j
AssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID8 l' S$ j1 w3 K2 x3 c, H" {
/ X4 t2 f3 k, w! r4 p# N2 U
issueAction的json格式为:$ A, k' ?1 w! i& f
{) q; E9 s0 i2 r% ]9 O
  "amount": 100000000,
1 ?8 U' P! ^: L' o. F  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",6 ?/ F  U# {, o/ G2 S. W
  "type": "issue"3 ?# r1 ?& N; V4 k
}: T$ t1 d% o. L0 w8 e) L
例如发行一笔资产的交易示例如下:
. I' _5 _8 Y# M- |, ^(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)+ ?, v% U: v! k' B) X, E, i1 W
{, T6 w8 n, \) ~9 Z
  "base_transaction": null,# f5 h/ G5 @3 n* \- J
  "actions": [! l$ d+ ?4 P  L
    {
) A& u% D/ v& h" x. N      "account_id": "0ER7MEFGG0A02",4 f* {/ H" g! D8 \% o( s
      "amount": 20000000,
9 K( S, K" \) @) W% p      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
3 J6 N+ E$ Z* N; Y* b      "type": "spend_account": P' V% g% b$ k" Y
    },
( \6 [, X4 G9 H6 o6 n) [$ r7 C" Q    {
: N; S! W- \1 s2 M) Q% K      "amount": 900000000,
& I- g- Q2 ~9 ], L" Y9 m      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",, R' r; |3 Z" p0 N
      "type": "issue"
3 r* Z. N5 u* D* y8 i. g, M; V    },1 I- k/ s/ K: q2 \4 b
    {( i5 F2 S! y/ Y* [( ~! m
      "amount": 900000000,
3 S" P+ r6 o, b" e7 S      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
" e) E0 `) ~; G( _7 z3 o7 B      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
5 f0 H* c# k# g, j  [0 I; M0 a; z      "type": "control_address"! N& ?: p- P, C8 z8 K9 z
    }
: J. p% d/ {0 R0 t. U  ],
& n$ p% @1 O) y- N6 B  "ttl": 0,$ m% I# l& m- s% B( G% k: Q: b0 z
  "time_range": 0
6 q& }0 S( H: Y}5 D/ q0 _6 `3 I1 Y1 ~
0 Z2 d6 u  m' _2 {* e% v7 B
spend_account3 A/ d; T7 T: e5 \+ U
spendAction结构体源代码如下:$ Z; J6 d! }% b
type spendAction struct {" f8 Z4 R/ \: Q' T- C" _1 c
        accounts *Manager
# B$ f& ?1 k3 b        bc.AssetAmount
$ [8 Z3 C6 O/ ^% I) L$ z        AccountID   string  `json:"account_id"`
" C1 P: r4 o$ |        ClientToken *string `json:"client_token"`7 X6 l" c: c( J) \
}/ k; B) I: x! [$ K6 E& q3 U
type AssetAmount struct {  n7 m4 N% g1 D: d/ v
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`/ P( L# @+ h' ]! k5 U$ V+ i
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`, d. E  t* A( W
}/ {, l' ~& l% _2 A  K( R8 f0 f
结构字段说明如下:
( P' l4 `" R/ M. ~( Jaccounts 主要用于账户的管理,无需用户设置参数: w1 d/ w" c* V9 I4 t9 @! V
AccountID 表示需要花费资产的账户ID/ A/ V) D6 m4 k# R3 L
AssetAmount 表示花费的资产ID和对应的资产数目
; ^; ?, W( o% r' [( zClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
1 ?6 A, t" s) T6 E# [4 C
( |& C9 K) \4 nspendAction的json格式为:
; [) y/ H; @( M" e" m{. k4 ?* x$ B2 v
  "account_id": "0BF63M2U00A04",! `2 r& f6 H- }' w. U, W' x
  "amount": 2000000000,2 @) {. G+ G1 `9 K: X3 ]. s
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",9 P1 ^9 W8 Q5 Z0 A
  "type": "spend_account"
/ J6 P9 N6 B5 B& c8 A$ h+ h: u}/ i) S& A5 R+ q' n; _
例如转账一笔资产的交易示例如下:
, ^% P3 r0 ?  R* z0 o1 p(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量). Q+ n5 s$ f% @: n! I* `8 b
{
% O& q; U1 o$ k8 b6 L1 ~+ k  "base_transaction": null,9 r8 f* R) A; ^, }$ w0 y
  "actions": [4 K, I4 c- K) T5 }. }; _: n0 A
    {
9 \) R5 u  H, [9 g% k      "account_id": "0ER7MEFGG0A02",4 {) E- \% a$ ?( g" Y
      "amount": 120000000,- U& ^" p; i  M. c! {1 f; |4 A
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
3 b$ T  {: z0 c, R/ {# O      "type": "spend_account"* y) f. f" g% c8 Q  M8 k
    },
. |; \) g6 ^) X' x$ e9 H1 J0 T  j    {
1 q* L2 }& e1 W& F7 V      "amount": 100000000,' w& E- h& G; C$ }
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
4 S  M) ?0 Z  k& _      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",# Q, P4 H4 x6 F4 Q; G( X
      "type": "control_address"; \& O8 M9 }) [/ J! ?
    }2 Z- X- L7 p7 |& ~' u
  ],& h5 s$ a$ u2 N0 u
  "ttl": 0,* {, f8 C6 d' e+ t& g8 G9 _/ x
  "time_range": 01 L# z1 Y9 t0 z2 K3 v8 ~
}. M) m8 l6 I; C. X6 m( ~) b7 v

: F0 U4 Z, P; w# l  x9 tspend_account_unspent_output8 F8 B$ |7 P8 i+ h+ [
spendUTXOAction结构体源代码如下:. Y7 C; P% j/ ~3 }1 ]% E: }2 V
type spendUTXOAction struct {9 }2 b! o- }8 t" t
        accounts *Manager( J0 I+ g; F6 T  S- Z/ W# k1 ~* m0 t
        OutputID *bc.Hash `json:"output_id"`
; ]+ Q4 x4 ]0 o1 |( g        ClientToken *string `json:"client_token"`
4 o1 ~" f, Z: l0 _}
4 C4 f) E0 M: _) Z, K  j* P  g结构字段说明如下:
# Y* Y8 Y* z8 Zaccounts 主要用于账户的管理,无需用户设置参数& @) J, z1 B2 q) I
OutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段5 t: _7 L; G& {% E5 ~9 S
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
+ ^& j, F* K/ M1 M; ^" s, y9 ~& x! _4 b" n& f5 l0 z  ]
spendUTXOAction的json格式为:& C; ?, L$ @. r
{
- s' v) G, p  Z' T  "type": "spend_account_unspent_output",% ?$ G: G* ^: B
  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"
, k! X% }' k( y' W}
* \8 _" M+ `! e4 ^. }: U7 P; g例如通过花费UTXO的方式转账一笔资产的交易示例如下:
9 Y, r4 [. \) J' s* c; u(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
. y! ?6 z: A3 q{
8 |8 y$ k6 M: H  "base_transaction": null,2 |" e) Z9 Y  B6 o5 Q4 C0 Q
  "actions": [" `" ^- K' X1 \5 L$ B) H6 i
    {3 }( U2 {; ]( @& k( t4 R
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
# D. B, w& U" p$ J) a$ [6 _- Q      "type": "spend_account_unspent_output"# g) R+ C6 e: W9 m+ O. V
    },  d0 [6 ]" w& ~3 n
    {* U  U& o# t9 P/ R7 f7 g. {/ w
      "amount": 100000000,
% }- ~: X6 z& o( \" u# o! {  W      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",/ h5 H! a0 I" M6 o* N
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",, u4 P3 k0 d  y0 Y
      "type": "control_address"
7 d1 t4 y7 [( Y8 ?6 L) _2 t    }
$ q4 [; X+ @' u  ],: @. D* g# c. f! D) _3 b
  "ttl": 0,
' H  p  b) S- z  U' i  "time_range": 0
- p  `* Q3 t& s: s; {3 ?/ d}
! v3 ^) a* g+ d% X/ l. T9 w( g8 ?
5 `* x& [5 ?% V2 V8 j* Tcontrol_address  ~; w7 }7 P  b
controlAddressAction结构体源代码如下:
) ~* L. J* z; s- o4 z. x2 ltype controlAddressAction struct {+ n/ L4 g" ~+ p; t$ C# }# M
        bc.AssetAmount
: Y! B$ s; G5 t+ ~$ I1 k3 \        Address string `json:"address"`. ~% p9 A" N" w+ {0 b2 i% m
}: p. D; {: T0 V. V4 V* v, T4 T
type AssetAmount struct {
1 p* N  }; ^; Q: j/ m        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
5 z4 l; U7 V: S( y5 \6 p4 K        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
) M% N. a: E+ M& C; A- v}
# t& |$ z7 P  e! a: X( t  Q结构字段说明如下:
/ r, v% L9 J' z& J$ s0 iAddress 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址% v# a0 o  F6 M
AssetAmount 表示接收的资产ID和对应的资产数目
* B  c) y+ I# ?
# E/ V3 a: x8 l! b7 G: fcontrolAddressAction的json格式为:
, C$ U0 Z. F7 W- ~6 s/ K/ z  W{
8 V* x9 }8 O/ ^) I% y  "amount": 100000000,
9 O; @  a4 q- M- u7 M% M  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
8 \! `+ Z/ M$ `5 p1 C2 |% ~4 E$ c  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",
. p( J, ~1 |) v% K/ L+ M6 ~  "type": "control_address"
  A! R4 s4 E% J( F8 G2 j0 C}
' o! a1 v% O5 g; i  |例如转账一笔资产的交易示例如下:, `# |; `6 ^9 E' I, n. @( ~
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)
: t( p* Z1 y9 c- v: A{1 R7 K$ B1 H$ W: g# h8 E
  "base_transaction": null,
( V- P  R, Z+ I7 P  "actions": [
% @0 y; r1 o# Y2 o    {+ ]) b6 P4 ]2 t/ \( i
      "account_id": "0ER7MEFGG0A02",
  |, a, Q# e( ^+ u# U$ V      "amount": 120000000,
! V& `" \+ G3 z' b% \' ^3 M$ y      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  a2 j( V  x7 `. ]      "type": "spend_account"+ L5 X0 C4 t4 O# y( L2 D9 E
    },
/ n3 i0 Y9 V0 A$ v9 h* k5 i  }    {
# Q! |# Y. t3 n8 C      "amount": 100000000,( g3 ?, X9 {: A% Q
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
7 z$ ~3 O/ s7 c      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",: q. G; {6 `# C. k" F4 j- }9 {1 d
      "type": "control_address": J% Q/ e0 X/ p( T; F
    }& p9 P4 B8 \- a4 A  `$ E
  ],
: a6 |/ H- j8 E5 o3 N  "ttl": 0,
5 S8 C2 Q8 A! ^, P: J% X) ?! s  "time_range": 0
+ O! V; P4 ^( ^}$ }7 V5 A, Q9 t
" j, v  r, m3 [) e8 w. C2 T) C
control_program% K( v. @; v. ]4 B5 w3 w6 F9 u
controlProgramAction结构体源代码如下:
' R  V! c1 n* ltype controlProgramAction struct {* y) e' F# i3 ?/ s9 d& B
        bc.AssetAmount0 ?* M3 `6 V. f# X: s# m2 p7 t8 b
        Program json.HexBytes `json:"control_program"`( S- H# b9 ~5 m' ]0 t( B
}
7 i' z. E( O, V' t) E* a/ Btype AssetAmount struct {
4 s9 Q# c0 l. R9 S8 L        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`& h$ A- }7 I" ~7 _* j/ i" R% {
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`/ L6 S) p& B( B3 s# {
}( e3 n% z! i7 J( h3 q2 ~
结构字段说明如下:
5 Z. g2 x' `6 M0 |0 i$ s) }Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)/ Z! f4 `& a) _2 |9 f7 E! X3 l, d
AssetAmount 表示接收的资产ID和对应的资产数目
" _( x" n5 q9 u0 t- e# \8 e! b: n/ e3 d+ q$ ~
controlProgramAction的json格式为:+ Z9 g# |  Q: T1 R# `: O# B7 @
{
3 w& a/ R" R% y; g  V+ T  "amount": 100000000,
: n' w4 {8 m/ y2 |( u; u  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" X& q7 @1 }' A9 d- |5 T" N$ u0 f  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",/ a) \: ?1 C7 p( ^- ^4 S, o
  "type": "control_program"# d& t2 _# F! d* b: {/ E
}  e2 P: |% e& U$ s; d
例如转账一笔资产的交易示例如下:
# Q# u/ V$ o1 Q/ c% u(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)% x& V+ }; t$ H0 S) U2 A
{; h& _+ U) j% Z# x- Q/ d$ C
  "base_transaction": null,
9 `  L" i: y# ?" }" _8 |  "actions": [& q5 q! w6 \) ^  k- U; R
    {0 g! ~0 U3 N1 B# R5 g0 r
      "account_id": "0ER7MEFGG0A02",+ z: \& Y& ?( I
      "amount": 120000000,
- B& W- S: h- `3 f) N      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",1 [2 @' C3 O, i# E1 `  t: E
      "type": "spend_account"" m$ B: w/ l  |! _- I
    },
7 G" Y0 f, w/ h" h4 n3 e5 A& [    {
# y2 y/ u# I5 p9 z6 {3 s9 Y! e      "amount": 100000000,6 V  Z& p5 `! ?. G1 M
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" `1 }$ G- e* t' M- R+ A0 U; G& }      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",+ U, C. S# q+ W% V0 G
      "type": "control_program"% n7 o7 u! p9 w9 m, @' q
    }
2 X; b( O, ?2 @. K4 p  ],& n1 \" L9 s8 V2 n! }
  "ttl": 0,
3 O( @6 w' B, g, g/ R9 F; W  "time_range": 0
3 f/ i7 U) Q. m! k+ c8 V# Y}
" P6 d* x8 D7 b" t8 e
% X  X# g/ e0 V& r; Nretire/ P! g/ S, ]: o' z* z, N( k( y. S
retireAction结构体源代码如下:
; M8 x; F7 d) k9 i0 N) }type retireAction struct {$ L6 O: G- {) J" a/ V1 b, h
        bc.AssetAmount0 f! J( \! ~) W+ Z8 p' K
}( `  n' U  G" k( K' i$ F0 y
type AssetAmount struct {+ z" _; D0 @+ f/ Y; g
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`! c% f& P6 V9 o" E
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`1 k- N- `; U6 g/ F# p2 Q9 t5 t' _! R
}
3 l' k  o0 N+ L# q8 i结构字段说明如下:
8 K# P8 @6 y" Z* K& X3 zAssetAmount 表示销毁的资产ID和对应的资产数目
, H& F( I+ l( }0 S
# H! K* ]: F/ [, `retireAction的json格式为:$ \# ?; I; Y; B/ G/ y2 \8 r6 {
{/ m* G* a) F' d
  "amount": 900000000,% J- V, V' S) J" r. ]3 V* [; h- Y7 S
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",, S+ q. s0 F6 e/ H: O6 C
  "type": "retire"
% _$ L) D# E! x& a}
" s7 x! ~1 c- r( s0 `! s! a例如销毁一笔资产的交易示例如下:# U3 W* E. E" {% t4 ]/ K) W
(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)6 A# ?2 X+ K' i4 L* ^( ^/ D1 _  r
{
0 i% H9 @! S/ e) u; r. U  "base_transaction": null,4 H" t* {: a' S  q5 Z7 ]4 w2 [3 T
  "actions": [
8 P: W5 l# {( r( h) T1 m    {/ S' \, M0 `. j0 e; ~
      "account_id": "0ER7MEFGG0A02",
3 g" K/ E4 `7 v3 ]      "amount": 120000000,
$ k) |7 o/ K4 o. r      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",+ S! O+ ^# ]! y+ x9 J' U
      "type": "spend_account"# H' |+ n8 p) A- O
    },: S7 u: Q( f* e0 d
    {
8 }' q8 l8 Q' l& z      "amount": 100000000,
5 @" {8 X' G) N0 C$ d      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1 G& U! q/ D, w- c" `5 P( d% l      "type": "retire"
1 v  N, f1 z: ]* x6 k# p) e    }; D  K" I9 d: q- K0 P2 T- `
  ],
4 J. I3 x$ P  V$ t2 I. a  "ttl": 0,
: Z; `) H9 M" ~6 ]+ _* j  "time_range": 0% n, B) L( o" x7 m" i' ^# s
}
# }" k* o: g4 i! b  A
6 m( Y5 G5 a. Z' G5 |; N8 ^, xbuild-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:6 p8 i; k( v- }! M! Z  J
{. @' D. y  u( O/ L; ^7 m
  "allow_additional_actions": false,
0 Q0 L* E6 ~3 L4 S  c4 D  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"," r) c9 P2 }' S  X4 C
  "signing_instructions": [1 P& c2 W5 F. T6 h! B1 W7 O: F* d
    {# b' m; F" I& G+ k! k. w. p* V# J
      "position": 0,
$ d9 ?% ]# D; `2 P      "witness_components": [- Y( Y; ?" t& J$ a! @
        {6 R% O2 R& }- `0 ?1 M/ Y! m# S
          "keys": [
% Y* E) l7 ^) e& i. l            {+ d$ {) b" Q0 ^+ ?2 I
              "derivation_path": [2 ]$ F! O: S) t0 \
                "010100000000000000",! H0 k  g& L- O/ V- X
                "0100000000000000"
! J7 K) X% a" O6 _& h! d/ l              ],
# i* |. E! q9 ?6 C6 S              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
1 q  K# X* d6 c2 L; F& k$ u: Z4 ?            }
" ^: H1 Y' p; p, e2 \          ],
) V# u' U. D: N) p1 z' a          "quorum": 1,+ r% y/ {4 ]1 C0 P
          "signatures": null,0 g& e* V! Q1 j
          "type": "raw_tx_signature"
: h1 e1 F0 p% B  C/ N        },, E2 _3 Q% B! {1 E- W4 H5 n4 M- ~9 N
        {' J0 z3 q* U' f& N" z
          "type": "data",
/ s+ N' G  ]7 d9 ~( `7 r$ c          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
  V9 W, m2 h7 ]  H        }% y0 p! ?! `  w$ R, U% L& v9 p5 o# ?# j
      ]
9 v3 I2 r4 h5 j4 v. G    },
9 V. Q  Q6 x! y* z; A    {0 N" Q2 ^' L" _' p/ F! L
      "position": 1,' j6 p6 {! m9 L2 L- D9 {: N
      "witness_components": [  C  ]! Z5 o1 e0 B+ D
        {: v5 L4 @, T8 {, g2 ]& [8 A) D0 T
          "keys": [2 u5 a3 X9 @# N* t# I# Y% d
            {5 s* I- v( Z, v4 b, D' F1 v# w
              "derivation_path": [1 X7 |9 i- B3 {8 [# q1 `. U
                "010100000000000000",( b1 [8 T: X" |4 x
                "0800000000000000"
5 S5 r4 u, H+ Q5 h0 k4 N4 F% E              ],1 g& Q: \* x; K+ W
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8": [' J1 w/ A" v! m
            }
* _9 x1 f. h. T4 X: M' R# \8 f& c          ],4 h4 w$ O$ {4 V
          "quorum": 1,7 Y2 }6 K5 I2 g3 \4 q, M. {; u
          "signatures": null,
2 t$ h% P6 W6 b- |          "type": "raw_tx_signature"
& \* a7 P; T. p3 U( ^2 L0 \1 w, f) m        },
3 t. [3 q# g9 h+ `8 U        {5 b! D- A. G, L% `
          "type": "data",
% ]2 I$ i0 \- P$ C/ U6 {: Z9 h          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"" p/ [# o% K1 g) }. [1 {0 }
        }
7 `' d4 V2 O3 C" [      ]) R8 L- f. _* Q7 y8 v  `4 t
    }# c8 P! {3 t* |, o5 h
  ]8 I' F7 ~4 f3 t6 ~
}8 E* y+ V2 m* Q+ h$ U* j) N) k5 M+ ]
对应响应对象的源代码如下:2 l3 n: e/ i  @- T. T! G6 C
// Template represents a partially- or fully-signed transaction.& L) L0 |8 j! N; ~
type Template struct {
! M3 W! C  R2 s0 M6 g0 ^6 l/ ^0 f        Transaction         *types.Tx             `json:"raw_transaction"`9 P$ _- l" x" b9 X0 }; j' W/ U2 z; S+ V
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`2 ^1 r' s7 p+ ~* U( s  V; r1 L
        // AllowAdditional affects whether Sign commits to the tx sighash or. f5 b: G( V9 V/ D% W! }& I7 a
        // to individual details of the tx so far. When true, signatures& M! y' Q" Z4 ^- e; K
        // commit to tx details, and new details may be added but existing
0 H1 ]" B+ ]$ ^' o+ k! Y3 C        // ones cannot be changed. When false, signatures commit to the tx4 c2 y: ]4 d, a5 u( L3 P' O4 K+ ]
        // as a whole, and any change to the tx invalidates the signature.6 H: g1 a' b: [
        AllowAdditional bool `json:"allow_additional_actions"`
; b' o, R3 Y/ L1 K# B, m}
: u! T' H- j2 S' H) B- a! l结构字段说明如下:9 |) l0 z; R* \3 Y9 g9 Y
Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:, U$ v8 s! h" g- B( ]# y
TxData 表示给用户展示的交易数据部分,该部分对用户可见- ^# U  s0 @7 ^1 X8 m( |
Version 交易版本
/ Z7 N7 T2 V7 c& D% B; ?SerializedSize 交易序列化之后的size
; U8 o! F7 n% J# z  v% r$ LTimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)2 q, l- R$ `3 \  G- m$ P6 t( p
Inputs 交易输入9 [. N, ~" [0 v, l
Outputs 交易输出% @3 R# D9 k7 M8 y/ Q
bc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述" [, N0 F4 i8 p2 v' j$ \) C; w
SigningInstructions 交易的签名信息
5 U6 G( |1 H9 ~0 ~7 x6 {Position 对input action签名的位置" l8 C- [5 f6 p( n' D* [1 m
WitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:0 r0 t2 p2 N/ g" l
SignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名& t2 g! u0 ~* {( _# L
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
' r" P# o0 x2 s! Jkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
3 K3 [; q9 S* X5 g% k: B5 \/ ?quorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
2 H8 |  Q! T. _& T4 rprogram 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
8 k% u' u1 M4 m; aRawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名' L) U5 g* M# N( j
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
5 w' \# n5 w9 N' n2 f2 Kkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名- o, S: N+ v* t3 q, {4 p+ `
quorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
* C, c& g- z) d+ r' R; PDataWitness 该类型无需签名,验证合约program的附加数据
5 y& b7 Z! J" _* o  F' z) D0 B/ w) _8 n! f' K
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名7 D2 L3 Y6 l4 X$ |8 t) i( q

$ s' ]+ T5 p) I& ~1 |) m估算手续费
7 Y* N" l( |8 m: `' `( @估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:
% X  s* b& k' ~1 A  ?6 `( M! d  build - estimate - build - sign - submit
% b4 s' H5 b; h  r' l估算手续费的输入请求json格式如下:! f8 U1 Z! A  l* d& s
{
  U0 u% [7 @- t  "transaction_template": {* q3 ?; x( h  T" I8 |/ B/ W! V
    "allow_additional_actions": false,
, u) w0 Z% b$ |. ^; t    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
/ _4 }0 Z5 \" x* p- U+ K* B2 z    "signing_instructions": [( U3 [2 v! F: X& n7 {
      {% H) n3 y( T& a9 Q0 |. g
        "position": 0,
! ^$ u& n( ~4 \6 P        "witness_components": [
/ k3 e: x8 I2 U( d  d1 C* k- P6 l. o          {
! i5 r5 z/ _4 b  R$ G            "keys": [$ [$ K. }- c% n: @, c1 k/ d
              {
/ J: s! B3 ~! ~0 C" [                "derivation_path": [
% T6 o1 u" V3 a9 O1 N                  "010100000000000000",% s- M; C. F5 Y! h& d/ @
                  "0100000000000000"& U1 v' K( n+ s' e( P
                ],# {5 F7 k% h3 o2 ^
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
, y. n2 s* K; ]* t% r7 j              }
/ S2 f( `" S7 \! U$ T, w            ],
( \8 I$ ]) v* p4 k            "quorum": 1,
. @) a9 |1 J9 P, i4 O            "signatures": null,
9 N+ [, H, V. a, A/ W- ?( u            "type": "raw_tx_signature"
+ z* m3 g$ U8 A! L          },
0 Y) ]! A' _! i' U3 P6 L4 g# \          {
. i1 @/ @3 ^5 Q8 N/ }* `6 P            "type": "data",) h( _/ }, e; p! n7 K9 h. d$ w
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
2 n$ Z: k4 v0 t6 N          }
. l8 o" G- \! k  C        ]
) u' C8 F- M0 q3 I+ ~0 L      },& X( _7 G% y9 S0 h1 i: L- _/ C) @8 k& o
      {" K- B6 H/ |* i% r& B; v$ M
        "position": 1,) _; W1 U# i1 G; y+ e
        "witness_components": [
4 P/ f! r9 q' w! ?1 i) j          {( f( m3 D+ c; Z/ C
            "keys": [2 `0 G! p. S; c* A: V
              {
6 ?) v7 p8 k. e                "derivation_path": [& u! Q, ~" ]  T( J: e
                  "010100000000000000",6 Z8 s- H: ]) w  z! ~1 u" Z+ I; d
                  "0800000000000000"
3 s+ }* V0 r5 [2 C# m- ?: j                ]," J9 }2 k  M7 o% J, O* V  U6 d
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
) [9 G* g& O" ]0 m+ P              }$ @/ y0 X$ X/ a
            ],; J! y1 e& y3 q  n* e$ I! X
            "quorum": 1,
5 R$ M- g  j2 i+ ~4 M; t            "signatures": null,
" Q$ U6 j% ~8 [' L" U. t            "type": "raw_tx_signature"
+ ~" K! u: B0 I/ }% r          },
1 _$ s/ t6 A/ E          {
. N: C: X6 F) e# I, y            "type": "data",1 S4 K4 c$ h# u- e; f% O
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
2 B+ ^0 i, q' l  h5 g7 D          }
& H! r  @- n, [+ u( Q' r5 E        ]
4 E; {! @( z1 u      }
; r. D% V3 G3 b& z    ]
' C. {( S  W9 [6 n$ V7 f. B" ?  }
! Z. a4 I6 e# \+ ^, v$ \7 J}7 a3 {( ^: t9 t( c: b% k
对应响应对象的源代码如下:
( B; ^$ h' |+ b. S' btype request struct{: v! Y+ |$ K' V- Z: }( ^4 p
        TxTemplate txbuilder.Template `json:"transaction_template"`6 J% r, L1 o# [$ A8 i
}: U8 v0 K+ L" o7 c9 {$ x% \
// Template represents a partially- or fully-signed transaction.
2 W/ g7 G0 v2 @  Rtype Template struct {
; n( n: y8 u+ I  |: e+ _        Transaction         *types.Tx             `json:"raw_transaction"`5 t5 Q; N1 |) F& \1 p4 M* K) i
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
$ J8 {9 }( e6 B$ j: u        // AllowAdditional affects whether Sign commits to the tx sighash or1 W6 H$ I4 S- ~' F. W5 v
        // to individual details of the tx so far. When true, signatures
6 s- T$ T7 K' K+ ^7 @        // commit to tx details, and new details may be added but existing* e: a$ a# K8 q! \# \) M
        // ones cannot be changed. When false, signatures commit to the tx$ w2 T# S$ X: h/ k
        // as a whole, and any change to the tx invalidates the signature.
" ?3 S2 b, R  H        AllowAdditional bool `json:"allow_additional_actions"`
  P/ T% u8 Q- v" T* V8 A}9 x* s, V# ?4 q0 X- H' |1 A, t
其中TxTemplate相关字段的说明见build-transaction的结果描述$ p- H; M8 b: _- p/ X
调用estimate-transaction-gas接口成功之后返回的json结果如下:4 z* @7 z$ U1 w" U
{
# m. H  u6 A, w/ b1 e* ?0 `  "total_neu": 5000000,
! M; f+ n$ T6 u$ m+ {+ e  "storage_neu": 3840000,3 z3 L  s7 f  ?9 p# H8 |
  "vm_neu": 1419000
3 A! F7 C/ K+ L; B) f8 U}
8 N1 _0 Z- h; A' J( g对应响应对象的源代码如下:  e: l; M7 T% |3 Z9 g
// EstimateTxGasResp estimate transaction consumed gas
1 H0 P2 m( ?1 E) J" ?type EstimateTxGasResp struct {
; m1 y1 U& d6 K. q        TotalNeu   int64 `json:"total_neu"`
, j2 v0 e6 I- M5 w3 t4 y) U0 `7 g        StorageNeu int64 `json:"storage_neu"`
7 o5 z: B. i2 r  S9 p! A        VMNeu      int64 `json:"vm_neu"`
' q; P4 h. F+ B' M0 G: d8 b}8 @5 i& W/ G* q, ?# |" C
结构字段说明如下:
) y/ p, a8 w4 t$ p" V0 _+ KTotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
6 W6 F1 u, C; b2 {8 BStorageNeu 存储交易的手续费/ X3 {) e1 g2 z2 Q
VMNeu 运行虚拟机的手续费  R8 J2 e/ s2 H$ p' q+ f7 ~9 s4 g* A

# n7 ^" K3 ]- l: }- `- q( P2、签名交易
5 j- @0 s* k7 d; d8 U5 @1 HAPI接口 sign-transaction,代码api/hsm.go#L53% i5 f. Y* O3 L3 F: Y
签名交易的输入请求json格式如下:
1 C; P3 ?! a  I" h5 h) w{
% x5 q; T! K# x! _  "password": "123456",
8 S5 d9 B0 ?# m; s9 q  "transaction": {$ G; r+ R; B5 p+ q4 {
    "allow_additional_actions": false,
4 J. A3 ~; C8 r    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",+ U- ^* f) u; s) P4 n
    "signing_instructions": [" p, J( h* T5 o' K
      {, B4 Q" {- X. B3 p# X4 l
        "position": 0,
3 g" S$ U: T0 |# @7 H# \        "witness_components": [1 [& C7 B6 m4 z1 ]5 x/ d
          {
3 l7 T1 b- G0 n            "keys": [
+ |; A2 p' j" o  @  y" r0 W! e              {
2 z( [7 d. `) V/ a6 ?* g  T                "derivation_path": [; p6 ]) Y8 X0 ?+ V/ ]# o& }. R
                  "010100000000000000"," s1 @/ [! p* c; k5 Q
                  "0100000000000000"  R+ F" R, e5 y8 A7 l% w3 u! A, k
                ]," t9 i& x6 X3 u. S- N( f* Q
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
7 I) H2 \0 L+ `' b9 {& F              }0 a* s% _0 T" n* J. [0 x3 e8 y
            ],
  v  G/ `& Y; R) F6 g2 b8 _& t( x            "quorum": 1,- M( h  e0 _6 Z$ l" I0 ]
            "signatures": null,' Z  z% g* m* Q* M
            "type": "raw_tx_signature"
; u, B, @6 P0 Y- H          },4 g+ N, c6 T7 d0 H  F
          {
% r) ^4 |1 S  l9 ~4 d            "type": "data",2 s- j% M/ [- F" n6 w
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
( W, G$ ~+ w$ e          }' f# u, v0 L( E$ z1 [
        ]
3 T1 L6 ?) L) u; S: i5 }- f      },
+ X" L! @5 X; R3 z      {& F. P' Y6 _. s
        "position": 1,
/ U2 P% U1 @  J- c5 ]        "witness_components": [7 s9 q, M( ], E- k" w- v$ J/ X7 J+ K
          {
5 Q( Q8 r6 `  f  p1 |            "keys": [
6 q# _1 R$ s8 S' D$ j( f0 W              {
0 e" U- W1 H8 p+ h$ H( \                "derivation_path": [
- J/ Y$ y  v" I6 m8 B, o                  "010100000000000000",( f* K& @( b4 R3 A  M
                  "0800000000000000"
4 h& q+ W% u9 ~5 h3 ^2 M; b                ],) E; g- T; [- _- y
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
9 f0 B  B  _! X              }
3 _; c# t! h2 Q+ ?  H; Q% @: K; V6 O            ],
7 P0 }& c& L, u" ~+ l            "quorum": 1,8 l5 n  P* q- _2 `8 L
            "signatures": null,
) X3 B0 y! P8 L. ~/ G) D            "type": "raw_tx_signature"' R% @# k4 I. }$ Z
          }," v& p% q; K$ e5 B$ |
          {/ @% ?' \9 T" F* ]
            "type": "data",
, u& F6 V% p  ^: M            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
* w) X6 |( A: n' u+ p! C          }  h& h# |& u$ g) c7 B3 Y: e
        ]" S- H; b8 X. U5 g. z9 E6 f4 |
      }7 O4 w  N6 B$ i" g* c" n4 \5 p, T
    ]+ p# R/ g# ]9 {0 s+ K6 Z
  }
' j( K3 J2 O7 h% |2 a8 C* H- F}
" y$ S: K5 Y% d: \' I5 r/ j0 n对应请求对象的源代码如下:/ c' K% s: H5 C9 A- j7 T9 G
type SignRequest struct {    //function pseudohsmSignTemplates request$ r$ L0 j+ T* i$ z5 y
        Password string             `json:"password"`& C% [" U# ]% }# ]
        Txs      txbuilder.Template `json:"transaction"`! Q5 T/ k) r7 _: ?* V# m
}2 b  o1 a7 G, h$ G
结构字段说明如下:: {8 p7 b2 O! X' A* `
Password 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名2 K& e) l( B. ^- ^! j
Txs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述  X  e) h0 }) t2 P  a, x2 p

# t* q2 [1 f2 `! _5 l" N签名交易sign-transaction请求成功之后返回的json结果如下:
2 f! M2 s) b$ h{
8 Q9 t# d! K( B  R- m! o* p% U  "sign_complete": true,' g, C8 A, |* Q/ _' U
  "transaction": {
' R1 |6 s8 v  c( s) q- @# V1 @' I! O    "allow_additional_actions": false,
& d* a$ K7 D. [; v/ V* z: T    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
6 m  Z, S" l5 j5 w% a    "signing_instructions": [
/ a" ?# w1 @8 Y# ^      {
; [1 h- f5 c0 S$ t; [% C% T- Q        "position": 0,
; v+ f& W5 g& B; N3 s) S) p        "witness_components": [
6 ^; m  x) E5 P* ?6 t+ _          {+ ?/ m3 t2 x- U8 |. \1 h
            "keys": [
& v. Z' }+ M; F# o              {
% l8 p8 ?2 I$ [' w9 T                "derivation_path": [3 \6 U0 u8 j" L# b- W# _( N
                  "010100000000000000",1 B; @7 W0 w) r' D6 ^
                  "0100000000000000"
2 t0 l2 \4 F) [4 a5 d  e$ L                ],
9 _* A: k& u/ ]7 _* I. K( W                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"% j7 X- u4 S, S& l; I; B
              }7 t5 z' I' O$ s0 m& d- |# Y% x
            ],
  A. L$ s4 l# ]: S& I& P- p            "quorum": 1,- s) j' D; h7 \! R& n. a# }6 y, ^2 q# J
            "signatures": [' A' [6 N& ]8 c9 n
              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"  \, c; ^! q+ N. }5 V$ s% i
            ],
# p: M. A  [8 i, u% e( L            "type": "raw_tx_signature"
7 I* ]' g: B* {2 ~          },  D. S0 f7 c5 H5 B5 O, a
          {
. j* n1 C4 U$ k2 w- B, n            "type": "data",( F- {6 ^+ U6 W4 h, N3 n
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
1 F) y" y+ r( T6 {, d& |          }
0 {7 m, L0 X/ o7 F7 ^& c% U0 ^        ]
  j: P1 L% {8 L+ v% R      },
6 t6 s+ M1 q  e9 }8 W0 q      {) O8 H4 X3 z( A5 u  ~" D9 p" M
        "position": 1,
: [" C& i4 n0 ?* ~( |        "witness_components": [+ ^4 z: ?: D4 `/ Y
          {& b: O& ^; Y7 W% {
            "keys": [1 O, u) I7 m& R: o3 ~& h( }5 `
              {
; w2 i& I/ W5 W1 K8 T# u+ d0 P                "derivation_path": [- [6 O' B' R2 \( T$ r) r7 t
                  "010100000000000000",& O" U5 `- ~4 h9 `1 l/ I7 k
                  "0800000000000000"1 `1 p, N( R4 g* u7 d5 M
                ],9 t( M; f4 Z' p0 S
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
/ \0 s6 q. P2 x              }
" @1 B" f4 Q1 w- c& f            ],# ]8 O5 f# A! ^. i; s; p
            "quorum": 1,
9 [8 d! b. L1 M( l; V+ t. k            "signatures": [
& R6 ^& _* G2 u0 c  `" q              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"
/ `, ?( w0 [  v( Z* b            ],! K9 x$ P3 N; e% o- F. b
            "type": "raw_tx_signature"
( h4 k% N. F+ ~: l1 ?          },
  P& S7 L" D# s* ]" i- c          {. V; U' n& s$ n& P8 I+ B/ t7 U+ y' H
            "type": "data",
0 y+ [) s* U* s4 Y            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"1 T( P& {: i" p2 Z- H
          }7 A% ^: X  d# y
        ]
% q7 O2 R$ `% Y+ L& }' ^& x8 U      }
" q4 g: ~0 f1 y$ G) B1 S7 P    ]
& l0 k8 @4 O/ K( M/ c  }
' t" o1 n- x( z3 e4 _! L}0 U# H3 o! H+ d  U
对应响应对象的源代码如下:
( n+ R6 {! O+ B4 U; {+ V5 atype signResp struct {2 `. x5 A; R" k5 I6 n1 e
        Tx           *txbuilder.Template `json:"transaction"`
7 i+ N: _* s) o# G9 K. M        SignComplete bool                `json:"sign_complete"`3 P4 f$ z6 U; v3 z
}
, f9 {/ G% o# J5 m5 c& n结构字段说明如下:% ~* G2 n& F# [* E
Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息  r; r* E. _6 b. H& |# v% `
SignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易
* k$ ]1 p; |* J6 B
7 S$ R) A$ [( `3、提交交易
& `+ Q, f5 Y5 P. m: rAPI接口 submit-transaction,代码api/transact.go#L1350 d' ^' H9 Y' B4 w
提交交易的输入请求json格式如下:
7 L; z: w! q# Q* K{
% P; u3 J, `' V* d5 f: Q6 }. i5 j7 j  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
: |8 s/ w0 h, z: X4 H5 Z5 F}& c( _6 m/ [) D/ S
对应源代码的请求对象如下:+ j1 T0 S! S: n/ J  |2 B
type SubmitRequest struct {    //function submit request" |4 y( M$ ^4 ~: E! M
        Tx types.Tx `json:"raw_transaction"`# g! h% M6 m6 f. x
}
9 F6 [/ e6 a- Z! {. G8 d结构字段说明如下:0 J% ~6 g, [* L
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。& w! M8 }; i8 J) I& k. W1 Y7 r4 O
  S# e2 T1 f) b) _/ V
submit-transaction请求成功之后返回的json结果如下:
) ?- @+ N3 I7 l) p$ F3 n{
. s/ g  _, Z& e. {8 ~: U+ W3 n3 C* d  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"  Y9 {9 c9 i# [7 X
}
6 B; Y- `1 h! f' q) C7 a对应源代码的响应对象如下:6 T1 P) [) g: S) |! V! m- [4 [( _
type submitTxResp struct {0 _- [* W( z0 \5 [
        TxID *bc.Hash `json:"tx_id"`
( o6 ^4 V% `; C% ^8 m}
9 D8 K) r$ h- v& q! g结构字段说明如下:
7 ]1 [( L) H, K( r. k, gTxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败1 ]2 k$ {$ l9 }: G' S; m$ {4 a% s

' [: h1 `; w# E; ]* j
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14