Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
155 0 0
比原项目仓库:, [; H" R+ g- x- o
Github地址:https://github.com/Bytom/bytom' u% O$ X4 @7 ?) [8 |5 f
Gitee地址:https://gitee.com/BytomBlockchain/bytom
  a1 Y3 T" H: o5 C9 r- _该部分主要针对用户使用bytom自带的账户模式发送交易
* E+ @% d: O4 ~) x1、构建交易
! ^5 b' J/ V4 @# W, jAPI接口 build-transaction,代码api/transact.go#L120
# v7 Z* p9 N" o7 j: w8 E以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:( h! z  ]2 ?9 Z1 O
{+ t' T- a) Q3 D+ d3 j
  "base_transaction": null,
) ~# l: c9 a* m( z/ d' x  [  "actions": [
( A6 w9 u+ T& U0 q    {
. ?/ D% H' B" T: }$ ^  q      "account_id": "0ER7MEFGG0A02",$ a; ]9 m$ ~8 F0 `
      "amount": 20000000,8 h+ b+ C& e1 D( Z. ?$ T
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
. k6 s2 P9 v5 I  M8 ?& j4 w( [      "type": "spend_account"
" O" ]/ V, Y- a/ J    },
9 f, g" m/ ~' a" \5 I    {
6 t; O" x5 n4 p8 N  R      "account_id": "0ER7MEFGG0A02",5 J7 r! D" q7 u& x1 M5 |! @
      "amount": 99,
; ]4 F0 o7 J/ Q  p  M' Q      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",  H  m# l. Y# e  f: `( J4 X" r
      "type": "spend_account"( }0 ]! g  H1 i( l  k
    },/ i+ s! y- Q# v( G  p6 \
    {
& a( P/ m& _* ]) z      "amount": 99,- y9 r* h/ Y: v1 c$ x, ^4 ?3 U
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",% E( v2 t5 F% c# h
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
  W2 @( i. Y9 W5 }) b; a      "type": "control_address"
7 @  n- ]) r' F6 X! b5 l    }3 W- z+ c/ f8 N" U0 D& W6 i. J
  ],
) p/ _8 q0 B# Y- t) M! ~  A  "ttl": 0,
) q% c% o' R0 D, O- V, u' a7 g- M  "time_range": 06 Y" D2 q7 ]4 ]0 D7 l
}
0 W; K( T) k0 u1 o2 `- C& x( o对应源代码的请求对象如下:
) o8 r% |9 g& i// BuildRequest is main struct when building transactions( q2 P! M! [) I  z. Q
type BuildRequest struct {5 I- w1 m) K+ j: V; q; b) \8 g
        Tx        *types.TxData            `json:"base_transaction"`  h4 z+ B: V  n: D+ o5 X' B: R
        Actions   []map[string]interface{} `json:"actions"`
% m" Y' j* L+ X' Y+ U  \        TTL       json.Duration            `json:"ttl"`) K1 b7 _4 a, w! A9 u/ `1 n) ]% k7 ~
        TimeRange uint64                   `json:"time_range"`
# h6 l7 s; z+ F) j. i1 I}
# [2 M% M/ c0 [  z1 K6 @5 `结构字段说明如下:
* ]+ w% M3 t* f) F! i' GTx 交易的TxData部分,该字段为预留字段,为空即可% _# r* o; k5 w; v; _
TTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟
  w# a; L; Q$ l* j* H4 @' }TimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效* d; B+ _2 O( J! O' Z# g
Actions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:
4 P* w! V; o5 w+ z9 y# G9 Sinput action 类型:; O, V! h( \! ~- j3 a
issue 发行资产
$ J5 P6 |3 w: m& V% espend_account 以账户的模式花费utxo" O% t0 a: w. s) w2 |# u
spend_account_unspent_output 直接花费指定的utxo; S2 g2 h5 k3 R
output action 类型:
' y/ o5 n2 V3 u& Rcontrol_address 接收方式为地址模式
; \3 H7 J1 t) {+ m) y$ ccontrol_program 接收方式为(program)合约模式: Q( i1 R5 Y# Q$ l4 Y/ X7 C
retire 销毁资产
# z2 P' g0 i2 a7 `- |" s0 Q
& H8 u' f9 ~5 ?# I! a' l- m
; v  ]7 m  s. R  I# P
  \3 W  b8 l$ v( b- ^注意事项:
3 \& M1 n3 p; _( _一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。0 i5 t4 _: C; U* @- d( [
除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。
8 w+ N' `+ H4 V) K* i& y* e* |7 o交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量  ?0 t; \4 d! {6 f! R* c$ `
交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu
6 [- P* }( ^/ u9 Q0 {/ l4 P) [% t, u" K( n2 o8 Q! x$ h
action简介/ e" [. q0 `0 O3 W# T/ ^
下面对构建交易时用到的各种action类型进行详细说明:
4 [5 F& p# g: R, ?5 T! ?. D6 \issue! d& X4 t) k7 A
issueAction结构体源代码如下:; B2 ]# Y. h" D/ A$ B3 |' p: d. R- Q2 _
type issueAction struct {( f, J' F* a% [( _2 G& U' n
        assets *Registry
  o9 f! V7 r6 x/ U) o        bc.AssetAmount
7 m' q/ ]8 a( n- [/ S2 k. n4 l}; F/ f9 k( G" \9 D% h, P
type AssetAmount struct {" a/ S+ K, k6 i1 c
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`8 }- I2 u+ J4 K# H! D- Q
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`: A! h# J/ J9 T# y$ d+ z$ q8 U
}
8 K! W# u' d( s结构字段说明如下:
$ O7 R( q, ^" m5 D+ H9 Xassets 主要用于资产的管理,无需用户设置参数" L9 J6 E: Z1 O# f2 m5 ^/ y
AssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID
' q6 j, y" u) Y/ m) ^
2 E( `! z5 {; ~% j( A$ CissueAction的json格式为:
9 k5 j0 [4 [9 x% L{# z+ g, |% w* k& }# k  [% ^/ M) I
  "amount": 100000000,
9 y4 _" X+ q5 c! k$ _2 ~1 J  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",$ L* f" e4 v+ y( Q8 z) V' W6 H
  "type": "issue"# g5 d" Q& p! |3 \7 n: {2 w
}
3 J; N- |  b5 O1 M例如发行一笔资产的交易示例如下:  [! B8 f% u; }8 H3 l! Q
(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)% g5 F/ u% A3 @0 V
{
( I, E" z$ T, o; P* V  "base_transaction": null,8 Q" C; o9 k0 U5 G$ L) d; h( I
  "actions": [$ v2 @; P" t# A5 w5 q9 [
    {
( J# D* @8 F* k      "account_id": "0ER7MEFGG0A02",6 Y, Q' r; A2 h) f
      "amount": 20000000,
- {0 n0 p2 T; ]0 }) R; p& T; ?8 `# V      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
% ]2 ~% E# }9 ?      "type": "spend_account"
9 P4 b# n/ X: i( \2 R    },
. M% x2 X( i8 f: Q% G4 [( ~    {8 L% o6 t( ^# @
      "amount": 900000000,
; k  P. T# h% _% k0 a4 g. M      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
' V& r) j3 Z# ^: o2 k! S      "type": "issue"
3 _4 l0 `+ T) M" K/ S9 }2 D+ d' i    },+ b& D% c2 j' r+ s5 e0 K
    {2 i0 R" u2 ~& D  r, T+ }
      "amount": 900000000,
5 j  C/ X8 ?% @# [5 `. Q) U+ o      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
- {9 [' K; i! A, y, p  K      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
) M3 I  A  w8 W, D- e      "type": "control_address"
3 X3 z4 B5 o) Z" ~$ ~+ V* c    }
+ ?& }0 b; `8 r2 h  ],
  r. x9 J5 b3 n1 |( q  "ttl": 0,0 G* @/ S$ s# ]$ z6 d4 \0 ~
  "time_range": 03 k' J% v$ o2 y1 \
}, H9 e1 v! E3 \; }

( ]* g& z0 J/ X1 p) cspend_account
" I( z2 r* c) yspendAction结构体源代码如下:! }, P6 o+ i* Y( o
type spendAction struct {# X- N" X' K" O8 z, |
        accounts *Manager2 A. J& ]" }- @; j( L: o
        bc.AssetAmount6 g' j/ C4 m9 @
        AccountID   string  `json:"account_id"`: q8 x# c2 o: t* d
        ClientToken *string `json:"client_token"`& T- K( E3 d* _' S8 S* A" o
}
$ ~3 X: @/ Y6 ftype AssetAmount struct {
# s8 h4 z& {$ \- t% n        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
5 l- `: H  F: d9 X" M) H5 M8 w        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`1 c7 q% \  U+ d
}* X  y2 f5 I; m
结构字段说明如下:
! C0 W1 w& ^# ]accounts 主要用于账户的管理,无需用户设置参数
2 i: Z, q' {5 E7 U, TAccountID 表示需要花费资产的账户ID  N- R8 l3 {. q) Q7 Q% I0 Q! H
AssetAmount 表示花费的资产ID和对应的资产数目
, A) m( S! L/ l& dClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可% B1 g' n( L* \# c+ [2 ?$ x6 m

$ q" U0 r2 C' N! t& E3 l: `2 yspendAction的json格式为:& h" v/ o" }6 K/ H
{
/ h& X3 C4 V- F) c3 G/ e  "account_id": "0BF63M2U00A04",
: u* V5 k2 i4 x' A  "amount": 2000000000,
& o; R2 L3 V4 B+ ?9 O8 q4 I2 K" [  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",& z; r$ }) l# g; q+ w
  "type": "spend_account"
3 j" {* z' }' W' V- a4 _$ `}
! P/ P8 I: `) s* K4 q' o  I0 L例如转账一笔资产的交易示例如下:& I( {; ]* _8 k' ^; V' e
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)- f, O' J. [; q8 F$ L2 @
{) {6 U2 K$ i( ^: C- C" O. b' j9 V/ o
  "base_transaction": null,, U# p: a* C" |
  "actions": [2 x) P# g0 k- _0 k& d
    {
% H4 G+ R& Q5 z- Y# J5 n9 K+ ^      "account_id": "0ER7MEFGG0A02",
2 Y* }; X+ d: R: K- G1 K- g      "amount": 120000000,
; \1 ?) L+ g- c0 u" c6 t+ X8 q      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",) f9 y6 k2 K" e- V' j) V8 x
      "type": "spend_account"
6 J& e; S$ l: ]6 A6 z  x, V    },
0 S7 ?+ p  K5 O: T6 W    {2 ?  ?& t* D: B3 |4 h2 [- t
      "amount": 100000000,  c/ K! t! v/ F9 u1 Y- M" O
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
& ~/ y6 I  d$ Q3 L. o      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",) ]& R% ?4 m4 y! L/ J8 Z" r: J
      "type": "control_address"
. l) e2 F7 W9 z( T    }
  A' E1 J* `5 S# D  ],5 h2 q6 b: I& m' E* I. h$ k8 R2 `
  "ttl": 0,' E1 {( ]: ?  X# k5 L0 C% o" a( n" `8 V
  "time_range": 0/ C/ O) ]9 |! A+ f" S& P$ ?
}
% }/ G) V* }% y5 B
# K+ s* N/ o% `8 b; ^% T$ k" lspend_account_unspent_output$ k* _2 e' z+ B. N
spendUTXOAction结构体源代码如下:
, c  S: {( s5 {! u. Qtype spendUTXOAction struct {# x  j: P1 Y, p
        accounts *Manager
$ f9 l: Y" k2 t& P+ ]        OutputID *bc.Hash `json:"output_id"`
. D+ u, u9 V0 _9 f        ClientToken *string `json:"client_token"`9 u6 s1 K: m" N' K2 }. X' Y+ R
}+ p: t, G2 b1 y2 Q' N# ^
结构字段说明如下:* U: Z5 K/ a1 A& k  ?( n
accounts 主要用于账户的管理,无需用户设置参数
# n$ {+ q( v, C0 r$ i- a& ]: rOutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段+ D6 {/ [3 n  z/ b) d
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可3 [' n# Q6 {$ N3 t! Y* Z, O' i- W

, s2 I: V+ p7 [7 w5 ispendUTXOAction的json格式为:; `5 P! r* Q, t
{
2 L3 C2 w# V' [: \6 E  "type": "spend_account_unspent_output",
; H& R* D% N% |9 ^; r  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9", l& D+ I. I  P8 c: H6 K' k; h
}
/ F7 W) h5 f, t) E3 z) H; g例如通过花费UTXO的方式转账一笔资产的交易示例如下:
( v- {- U) t" t& r# W- t(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)' P* Z4 Y$ n' f( n; z/ q  u+ d0 m
{
/ P! s* {) W' E+ M  "base_transaction": null,
# ^1 s; ]( C; x  A, P- C% ?6 Q  "actions": [& N  C" ?3 E% z; h
    {
. N# p( M* ^# T# J3 e      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
- V# C0 j: u! r  L0 ^      "type": "spend_account_unspent_output"
/ X. S" i% I7 u* y  h2 E' n5 s: [    },4 Z) o9 Z  H- b: H
    {* U; q+ [! G; M1 n$ A- ?
      "amount": 100000000,
' n$ L2 p& C( F' M! n/ S' N" U, S9 h: [      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
& I- ?. W4 n; O5 W; `1 }+ ~9 T      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",, r. f+ E& x! E$ R7 J% E- t+ X
      "type": "control_address": b4 \; e- }9 u6 h2 E+ F
    }
9 P" i' h8 M+ ~# }  ],9 f3 k- J( g7 o- Q9 {# O7 n
  "ttl": 0," O* i8 {9 ^9 p1 f6 O3 L; F$ e
  "time_range": 0
; ?; h# k  X3 A1 t9 U/ k. ~( d" D}, h! S  U& m% q, d2 R6 X& m

7 q+ v$ m; a- {control_address
+ O. e: |2 m& b7 c; M* M8 c6 ^controlAddressAction结构体源代码如下:
, }6 n5 O: m* o( etype controlAddressAction struct {
* [9 O. O+ {5 \, J, O( O- R        bc.AssetAmount6 |, Z3 |+ N% {* k
        Address string `json:"address"`- k+ ~% T3 f3 p0 T7 v7 e
}
- u; \7 O3 l$ |4 v, j0 i$ }( C- P( X; X& ftype AssetAmount struct {& n& a$ n* l( L$ y
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`3 q  ~) c8 C" s9 M- b3 j: N
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
0 i/ R5 w. L- h; A7 R. C5 i}
" }/ ^2 g$ A2 R1 j结构字段说明如下:; V# {! P) X; A
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址& h! M4 A+ W: e7 N# h( l& }
AssetAmount 表示接收的资产ID和对应的资产数目% x3 a, M) k' @4 j1 w

$ t- Q0 ?) ~) A; A$ T2 q& ncontrolAddressAction的json格式为:
6 V7 L0 O6 K! u9 Y7 k$ l' y; ]" ]{
4 \0 W/ w1 S$ g% p  "amount": 100000000,
0 x. O9 {! I( \2 d2 Y$ k4 A  W/ K  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
) l  g, M" U5 k8 R  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",0 }9 J! p5 U& W3 x4 Y& |; N  U
  "type": "control_address"
& T$ E( p* z, L/ o, `% t' _, [; c( Y}
* l' Y/ p$ S+ N3 a例如转账一笔资产的交易示例如下:
! H% J. z1 |+ V9 A' }( K(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)
0 v0 ^; |2 O8 G' ~/ Q) ^% p{& `7 A1 D5 P  M) I, |$ p+ ?- @1 n
  "base_transaction": null,
- p4 K2 f- Q! b  "actions": [' l+ z0 Y: w7 M( U+ |' i* M
    {
/ |# i) b+ d9 W- v$ L0 E; U      "account_id": "0ER7MEFGG0A02",1 M, Y' c3 F; j' ]; d
      "amount": 120000000,' |" o0 x) |& W( M2 f" N
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
' h3 T7 b* W+ g( q3 H% s7 Z      "type": "spend_account") m1 T- z% n0 Z7 ~
    },
2 o! |  s0 i, m4 V# x$ l, M7 B  l# m' V    {3 f% m/ \& o. D9 V% i- s# Z
      "amount": 100000000,
( _+ t* `3 a6 Z4 o/ F      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
% U7 ~- E) J2 T( R9 L      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",' K5 K& i9 g6 a  F9 I
      "type": "control_address"6 V7 o' n( z, B$ C$ O- U6 \1 O' o
    }: j* |7 ~! y0 a3 `7 I  M9 f1 ^" k
  ],* {$ f9 W  {" W8 |' Z- G
  "ttl": 0,
) b5 e! k# S" M$ P0 u) \  "time_range": 0
( y9 r: g6 W( h2 c7 W$ y}! W2 a% u1 t7 X7 U, }7 j' _6 |) x
# ~: E& B5 L, W$ w
control_program
! L% Z. Y: v: d2 y1 v% d7 TcontrolProgramAction结构体源代码如下:
# U) h4 @$ Y2 k: U8 v2 Q+ @$ ytype controlProgramAction struct {8 e4 ?# \& s1 E# t3 r7 L
        bc.AssetAmount
) B6 H* s* t6 E7 `$ o  }. V        Program json.HexBytes `json:"control_program"`
9 `" t9 w: R  F$ V1 ?" U}* Y! d% r; J: v7 {, Z0 U* L
type AssetAmount struct {
1 s( \! Y, y$ [! @, J        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`& ^; H) y, J' z, I& v$ n" ?% ]
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
( [3 ]$ g6 J, N9 s}
; w- v+ J6 P7 V* O* j$ H结构字段说明如下:1 M+ j  [' p" K' `2 [( ]
Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)9 v9 J) O' {4 t2 O; Y- a& B+ r+ H
AssetAmount 表示接收的资产ID和对应的资产数目* e6 ]! u4 _8 \, g3 f, w' v

6 g2 K: R8 c1 a( ?+ dcontrolProgramAction的json格式为:& R- V" v- y7 R! r* M$ e
{  q  U9 v, v! ^" }1 z' w4 W& \* W
  "amount": 100000000,0 Z) @# w, F2 e5 d4 w' E0 E; Q0 Q
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
4 P6 e7 N7 `6 J" z; h( G1 D  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
- q1 K2 O, ]2 b  "type": "control_program"
+ }" R! ^' y$ p; {9 R7 v}' D. O) b2 M+ t+ ~0 w; O# m
例如转账一笔资产的交易示例如下:
* X, U6 @6 b3 ~7 P! J8 I, L(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)
" l8 @3 ?# f$ r- `! {+ c{- x+ n8 ^1 r" G* r' U8 S
  "base_transaction": null,  b- i3 Z7 |& v' {& J
  "actions": [
/ A5 b& p1 \( H! s0 K# u    {
7 _) R" g% v/ x2 x' G+ c      "account_id": "0ER7MEFGG0A02",/ q4 v& L( y) j- s5 X" i
      "amount": 120000000,3 w2 R! Q( G( Z- W8 @6 o
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",' S- S5 C4 r( Z' l1 B) q! x
      "type": "spend_account"
& d. v$ i$ }0 l. W# g" R( E! o! o    },3 y3 s% |  B3 b: ^/ q
    {: w5 K: o! U; ~  u! R
      "amount": 100000000,- ~* @5 |' g- u8 a. I
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9 u, @& q1 a0 Q# N- u" ?8 b. n      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",3 D8 y4 c/ z$ ~7 W+ M+ V' k2 m
      "type": "control_program"
; A. R1 u2 z/ ?    }: x- [% W0 x8 x. E. D
  ],
8 w7 @/ w% p5 V, T. G  "ttl": 0,7 m- ]; b9 J6 E. ?; o
  "time_range": 0
  {$ H, f7 ?" W$ u9 ?1 c}' j1 X& `1 Y- D1 h( ?
0 z# E' B4 l- t$ w/ F8 s. f: }
retire
9 G% X5 a2 A. L. Y* Q. ZretireAction结构体源代码如下:- m6 h9 A, _8 p2 u
type retireAction struct {
  C3 z0 O. q; n8 b+ R: i7 o/ U5 p        bc.AssetAmount
9 w' r3 [  j  \/ N. M: d}
  ]5 N" f( |& v* @+ B) Q' Mtype AssetAmount struct {# u  g; A! F& Y8 Y" j2 I
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`/ y5 @, _! p# m4 T
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
5 S7 v; k0 ]( B) I8 \' s! z}2 n+ N1 G$ g3 l7 m+ D7 J
结构字段说明如下:. `, U/ q$ I, P8 R4 E
AssetAmount 表示销毁的资产ID和对应的资产数目
, U4 ^+ A/ N$ Y( p8 N, D% ^" y
9 }5 J' s, n5 }3 D, e( [& [retireAction的json格式为:
8 W7 @3 Y% j7 x8 [  g: x{- }; b/ M3 |% B2 z; g" p0 g
  "amount": 900000000,
# h5 ]# T$ S7 p5 D% x6 E( H8 n8 X  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",2 u$ G" B4 B1 h3 _
  "type": "retire"5 x, G2 |2 R% F# U. `
}9 b$ F$ S7 b# a* X: h/ E% z
例如销毁一笔资产的交易示例如下:
- }  P6 n+ A# K5 C) N( l8 r(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)1 _% a# S( Z4 D) d* i! M
{
4 n* t0 |* G) w! b" q  "base_transaction": null,
) h; S" r" X& l" N  "actions": [: m* o8 H" z0 D
    {
: a6 t5 R8 z+ G. D, ~# |      "account_id": "0ER7MEFGG0A02",
, ]1 a0 K7 O4 I: I      "amount": 120000000,0 z2 ^6 S- \+ P# \6 I
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
! H. ?0 E; |) }" G$ u5 |2 s- D2 C% k      "type": "spend_account"
8 o& |3 d6 e! T3 O; x1 k2 v5 S  ?    },
7 T' @7 p! ?4 d1 B+ S% O# q    {
5 ?. _5 O5 a. q2 ?, f( H      "amount": 100000000,9 ?$ I1 Q5 }9 e& L  f
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
* W$ e" o3 q# \: M) C- i" S      "type": "retire"
& V4 ^' u$ H+ [; ], z, ]    }% f: _  g& f4 ?8 O9 @5 A, t( z  e! F
  ],
2 {4 e2 z' `1 o+ d  "ttl": 0,
. b- M) F. Q, m9 F5 R+ V1 }  "time_range": 0( E" d1 |" A1 V0 F; s$ ]0 q
}
" h4 @) ]* J! l0 j$ S3 A3 v# p! ^
build-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:
% u% B0 _" d+ N& N{
$ ^" X7 f; g* H, o  "allow_additional_actions": false,) M' `7 z7 g) {
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",: H" D' |$ ^' y/ ^( G, k6 z5 ~! k
  "signing_instructions": [7 U1 ^6 R: l4 c  s  v# b
    {1 o- k: S- L* X
      "position": 0,  _$ w+ U. g( ?  _
      "witness_components": [% I2 ~: H4 ]' Z7 M$ X5 B  m9 I# n
        {
% X2 z5 j/ A: q) b# _" O          "keys": [
1 G- a' d7 m1 k+ B( h1 f            {" F9 M* L* \9 E& D
              "derivation_path": [5 Y) v$ z2 ~+ P) Q4 M' z
                "010100000000000000",9 w2 g8 X8 p, r! W# F; H
                "0100000000000000"
% z1 X' G1 l" X* a) C; R2 [) G              ],6 f& |. z1 o* `! g( m
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
. }# e1 P/ h! O8 ^            }2 g% I& a7 P% R$ O& q' z( @
          ],
# d: u+ t" X2 [9 N          "quorum": 1,
$ A# N/ U. z' t          "signatures": null,2 y* X, `* V6 k, _0 |
          "type": "raw_tx_signature"; _9 [; c" Q0 d: c- O4 i; R
        },
, L$ a4 H) b! ^. V# |- z        {" Y! y0 f3 E8 y1 z# h
          "type": "data",
% y: z7 t9 J! @0 K) L$ B' r: Q, ?          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"& L1 I( k9 U$ ^# l
        }  M( O/ W* a* D( U9 C) M
      ]! x/ w; V: N+ b* @
    },
6 {# R% G+ ?) _7 w- A    {. d0 J8 D, z. g$ _- j, \
      "position": 1,; G. o( @4 h$ ]  ]
      "witness_components": [
7 Z3 h* l0 R& ?  T+ C  F: |        {2 `) h) i' R6 ?' y
          "keys": [0 H+ A' f$ J5 v: |. _# r. n
            {3 A8 L$ d: e% S! w
              "derivation_path": [
) m0 U5 @3 N3 n4 e; u, n* d; G  v                "010100000000000000",
, H/ R3 d% d" C4 R6 {                "0800000000000000"
0 t) ^, W1 h8 i1 ~. |; R              ],
, i- S. p4 P1 z3 Y              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
3 n0 F! P9 G4 {% w            }
! x( W" D- p+ }; _" s" K* X; a          ],& B) k! V7 X1 k# c. [
          "quorum": 1,5 w3 N  x; u, L) {; T
          "signatures": null,. u0 ?+ }7 w7 W# \+ M- C
          "type": "raw_tx_signature"
" D' B, @+ T4 b. c9 ~9 h0 B        },
6 O3 k- x, S1 ?# @! ?! R        {
) I! o) g4 {5 M0 J) z- Q% j) V          "type": "data",
' Y, S7 e5 X0 d) X6 C! k3 N          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
6 E- {: D3 g2 `        }" b. Q$ Z7 ^+ `1 c1 d" A
      ]
( J( i% e) r* \8 p+ j% {; K7 i    }7 o+ w( t% f' S1 Q0 s; N; K
  ]3 A- J" ^5 d5 m, y, @6 C
}! s' Q/ S% L' G1 X" u* Q2 E
对应响应对象的源代码如下:$ h! h: D& N$ Z  s# x
// Template represents a partially- or fully-signed transaction.$ b5 _* q. d" {# b- }9 l2 l+ d
type Template struct {
  W1 r1 j2 r2 E        Transaction         *types.Tx             `json:"raw_transaction"`
) P% V9 w8 W/ J4 ]0 r        SigningInstructions []*SigningInstruction `json:"signing_instructions"`; j4 S; V* h* ^1 @) A! c7 |
        // AllowAdditional affects whether Sign commits to the tx sighash or
2 {( W2 m6 P* m        // to individual details of the tx so far. When true, signatures. G; p! t$ W  k' U; F6 B4 `% a
        // commit to tx details, and new details may be added but existing
) Z+ M% T% n9 e; M        // ones cannot be changed. When false, signatures commit to the tx* {. O; I( K, n1 b5 H. n& D
        // as a whole, and any change to the tx invalidates the signature.
. |8 D7 D, V4 m* F$ q- H! J        AllowAdditional bool `json:"allow_additional_actions"`. G2 a% C6 h* ]3 P1 M
}
& ]& K0 |4 v( M1 L5 W+ z9 v结构字段说明如下:
, z6 O" e! V5 gTransaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:+ m" v5 U; ~) m# _# M0 D, L
TxData 表示给用户展示的交易数据部分,该部分对用户可见
  P0 M! r" \8 k; o0 m# ?/ NVersion 交易版本( }3 j0 ]. g- l' ]4 B
SerializedSize 交易序列化之后的size& O. l" U% }% _) \
TimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)
& l& V3 r1 A$ L8 J# F  b4 ZInputs 交易输入
. a/ e3 g5 y8 n" sOutputs 交易输出) g; _3 O) [3 b5 _  @! A/ ^
bc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述# U/ n% g* l/ g7 t
SigningInstructions 交易的签名信息
; ~/ t# G" k! mPosition 对input action签名的位置
. `1 S' M* n! A1 |4 eWitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:
* d# G. w1 [8 {, [+ F' mSignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名" j2 @4 [! \( W" H2 G( b  A
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
2 G$ Q' g4 w4 m0 Ikeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名% P: b! T# w3 g( \$ C, s
quorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
5 U' @0 s; S) Q- P& G$ B/ M# bprogram 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
; V7 f. w2 m% i; E, i) U! m  @8 D9 a& oRawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名
9 Y+ U$ ^% c8 |9 s6 m9 _, a  gsignatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在8 q3 H- b4 G: l9 a( `0 [% R9 d. V: Y
keys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名+ I( ?9 i5 H2 W
quorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
  @6 C9 y4 C3 J4 |DataWitness 该类型无需签名,验证合约program的附加数据
! B+ F3 x* L9 L5 @* x( J! K( K5 X( L8 O/ e
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名
3 [0 J- E) \- b1 J1 q* J9 W) L5 j- T1 p4 @3 R) C8 G
估算手续费+ C: S2 v+ E7 H  T3 t+ U& _, b
估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:, O) i' i3 w! Z. K. M8 ?/ U
  build - estimate - build - sign - submit
) Z7 P5 V" n3 z4 d8 _) w9 a: r估算手续费的输入请求json格式如下:! {7 n" h9 c; J7 y9 u1 t1 L
{
8 T$ u. T( v% s. Y5 u  "transaction_template": {& F' {- G# E! d9 W1 J. J! [8 P
    "allow_additional_actions": false,' f7 d2 ?( H" \$ L$ V' `! p: Z# H
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
, e% b1 o; g" @$ z    "signing_instructions": [- {3 h* s5 v9 \9 k8 W  c
      {- f6 m5 X* x/ ?* D$ i% y+ J
        "position": 0,
5 X5 h. e( H2 d! j3 Q        "witness_components": [0 o. {" W4 T: S0 J/ ]: C* n
          {
& R7 p+ e: l( T  M            "keys": [8 Z4 |. v7 z8 B2 N1 [9 m$ |
              {! J* |9 S1 i! S+ y
                "derivation_path": [
7 m% m" O" K( Z7 g9 N- j) Q) i                  "010100000000000000",
  _8 }( V; O5 }7 ^                  "0100000000000000"/ |2 i' o$ [/ O( r( z8 t
                ],
# s4 Y. _# ^. {; p) O3 W                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
" ~) w5 l; O3 D5 m% z, S- E5 y              }
8 f, N" p" r" }* q            ],/ k7 {1 _, S5 j/ T7 ?- T8 a
            "quorum": 1,
/ V# c" O2 P9 O/ ~  {9 Y0 f' j$ B$ K            "signatures": null,
7 g% l+ u% m1 o. f            "type": "raw_tx_signature"
+ r3 Q% i' c) Y. w          },7 M$ y2 W2 ^5 t6 ~6 l/ O
          {
; V. ^. d1 s) V% K# _            "type": "data",
7 X2 }. J* Z0 I/ F% a' C$ G            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
+ e% f0 d# r$ b& |: j. u/ f/ n          }
/ H+ X5 B3 @* d; D$ I" B        ]
  B0 u0 C" n8 }1 H; j( Q# U      },+ v% e; j& u  c1 x
      {
" v# E, d% G3 }. b+ C/ T        "position": 1,
! |/ A# g8 Y2 }; }4 M1 g        "witness_components": [6 L; C4 r+ @7 V2 v$ J2 I9 U
          {
. V3 T: Y/ x; z, e4 ^$ ]            "keys": [
: i( r  P9 H( w0 L1 A              {
) S* F4 r3 l/ e7 c, R                "derivation_path": [
* R9 H; c' l- ^) `                  "010100000000000000",  H- G6 b0 w' S5 E# x6 _
                  "0800000000000000"
6 v' S4 c; |( `! `1 V) e% V                ],
) C9 ^4 |9 s0 r1 O- \                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
+ A+ h( t: _% X$ `              }
) e, F: W& @7 q5 |, X7 }            ],* E# \! T1 D( c+ y$ t' N+ F
            "quorum": 1,
1 v2 I7 S$ H* [- }' M9 [5 @  ^. z            "signatures": null,( I) d* C" ]& c
            "type": "raw_tx_signature"* H/ a, l6 P9 ^8 B# h' }# G. G
          },
: t/ `( \' W0 S- S8 Z# T          {2 U8 j; c9 u* {2 ?) ?* n
            "type": "data",
+ H3 x$ X& r/ V& j$ [6 D            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"* y1 f) D% i, M- W  q6 M3 v* }
          }, g: x! h* C1 |7 ^
        ]
4 E6 ?' I7 v9 ?! o4 K& [      }
/ i7 }0 b6 Z- ]  J3 J5 H    ]! z9 M, p- o9 v. Q" F4 I, Q
  }! D" ^) Z8 \3 r0 Z9 u  }. Y
}
% |7 C3 y/ y- r2 s) S对应响应对象的源代码如下:
5 F% U( g# U) a* o# z& Atype request struct{
$ ~/ L7 z  N5 Z        TxTemplate txbuilder.Template `json:"transaction_template"`
. c$ v. F2 E3 [+ F( y. y}3 h* F% _# `* {0 J& Q, ^
// Template represents a partially- or fully-signed transaction.' f& e1 s% Q  h6 T- ^1 ~7 y
type Template struct {, f+ Y8 ]$ l* }8 F, C* Z; J
        Transaction         *types.Tx             `json:"raw_transaction"`
# j9 [: j% x0 O: \5 y; W        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
0 I% e  S2 M7 U3 \7 b+ F! B4 L1 }! m        // AllowAdditional affects whether Sign commits to the tx sighash or
+ k' |* f! t9 D, ?+ u( H: x: G/ s        // to individual details of the tx so far. When true, signatures7 N( w& j' }; k
        // commit to tx details, and new details may be added but existing
; T0 k5 x* Q; T+ a) E        // ones cannot be changed. When false, signatures commit to the tx
, v: ]" k2 e" i3 Q/ {) }5 j        // as a whole, and any change to the tx invalidates the signature.# C# j( Y1 P5 a. {- ~7 h  [# B- I2 {( N
        AllowAdditional bool `json:"allow_additional_actions"`; p, d1 m: Y! G; N/ A: l  R9 o
}
+ U+ E2 T, q7 H$ J7 t$ _7 T2 w其中TxTemplate相关字段的说明见build-transaction的结果描述1 Z/ b" ]4 Q3 i7 S! |$ E" U4 x
调用estimate-transaction-gas接口成功之后返回的json结果如下:
5 s6 M* ~& k* E$ p! ]# ~{: D7 z/ I+ ]8 F1 D9 O0 `
  "total_neu": 5000000,% E$ n' m/ ?4 D0 D6 X
  "storage_neu": 3840000,' i, u; ]  T, x7 V* y
  "vm_neu": 1419000
& n, X  c+ E$ F5 Z: ~}
2 O. C* V. p( p* f$ t对应响应对象的源代码如下:! ~/ d4 r$ W7 d( x) u/ i# a( H; R/ _" Y
// EstimateTxGasResp estimate transaction consumed gas: H( h  j7 e! J0 w! I
type EstimateTxGasResp struct {; H& U) d& a( s8 M& z
        TotalNeu   int64 `json:"total_neu"`+ U2 ?7 w, T8 x; A5 S3 ?
        StorageNeu int64 `json:"storage_neu"`" }0 a  i9 N9 {! P% T, ?
        VMNeu      int64 `json:"vm_neu"`
8 u6 L1 p9 l7 H3 Q8 _  K! M+ V  x}
! z6 p, w) C, f% g. b* v结构字段说明如下:
& R' q; v- W' OTotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
7 t! N4 l! J# N. \; o& KStorageNeu 存储交易的手续费
& ~; ~7 N3 c! H! ], e; CVMNeu 运行虚拟机的手续费
2 S1 e8 U# s( P# f; Y3 [* f
7 v+ m  q' T: ?6 }+ G; X2、签名交易0 X' s/ m* o8 f  V$ ], K4 m* {  i
API接口 sign-transaction,代码api/hsm.go#L53+ a% I' m# P; C" U+ ~. F
签名交易的输入请求json格式如下:
( X& E2 @8 l  ~( K{
; s' |8 x- ?/ U' e+ d( Y' Z0 E  "password": "123456",; u1 h8 E7 b: r8 j; U
  "transaction": {
' k) p/ ^$ Z( ~8 I! L$ k7 |9 M7 n    "allow_additional_actions": false,& ?  ], {) ]# Z. G
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
& X+ I2 {5 U! j1 _& B, j! S    "signing_instructions": [+ |/ I" Z0 k! [+ |2 p, ?1 T
      {1 U+ n& [# r8 D: Y: Q/ T5 ~5 ^$ O/ ~
        "position": 0,
5 @8 p8 ^3 W% k" @- \5 J        "witness_components": [6 T/ ^6 P- |3 D, B/ b; }' o
          {
$ ?6 r/ {! E6 T- a            "keys": [' o5 k4 B3 S$ O: S
              {
/ b$ |1 i" A$ E  l5 v7 X                "derivation_path": [: }6 N/ r$ \/ M' u
                  "010100000000000000",% x( x5 ]  `" D$ p  g8 W
                  "0100000000000000"
+ U+ C8 o1 s8 S( D$ O4 l0 z  x                ],0 b( s& X% H5 Y6 F+ T, o
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"3 Y2 |. y- l5 [( a( g! A
              }% a  Y" A; q. K1 Z$ f
            ],
  J& n9 q' D7 O# b  [            "quorum": 1,
4 d9 ]$ J0 Y" U8 r$ M  l* [+ m) m            "signatures": null,
/ E0 n7 ^7 n. c) D            "type": "raw_tx_signature"
, y0 ^4 U, o! r( |  W; b" W: L          },; a% A; a, q2 x+ N8 n, X
          {4 n( [9 P- L. Q3 u' ?% T
            "type": "data",; y8 ?( [5 e& e" |4 W1 ?! ?- I
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
3 P1 C& _9 J; a/ I  b) h          }  @: m: t8 C2 j: Q8 P) p; K) V
        ]0 f4 D1 u3 o* Z$ A7 c; t) X5 w
      },
" _; k+ [) ]7 z6 x      {
+ w4 `) f1 i" L6 n5 F5 T, M        "position": 1,
+ `8 i$ l0 u  G9 c        "witness_components": [, [6 }9 \8 q4 c/ o6 b3 Q/ [
          {
, p8 W' z- j: J& Z2 j: t9 V0 w1 v9 l            "keys": [
: g8 L5 `' X! c% p2 U( U0 v1 g              {7 t# d# `' N5 @, S5 j  \
                "derivation_path": [* `6 o) y8 s! U# Q! D* |
                  "010100000000000000",) H1 v! W! f# K' a3 p
                  "0800000000000000"
' w( m3 [. J# w% j2 W+ b                ],
2 Y1 X; V& a, i, e                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8": I$ N7 i. ^) D+ y
              }
" N+ G! m8 a$ `/ }8 ~( M5 {! \+ M            ],
$ r" x" r/ f' H0 c! U            "quorum": 1,* F4 X0 B- ], X3 q# X
            "signatures": null,3 Z% ^5 r$ X6 o- D; B6 r9 o( }
            "type": "raw_tx_signature"
9 \# ?: `/ u6 I2 t. m4 n          },  T1 i9 H  K- V
          {: o; A0 O2 M9 b5 K: ?- h: \: I& T
            "type": "data",
" v8 l* E) c3 }! `2 d            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
/ {5 j6 v+ ?3 _+ {0 d          }$ V. j! H, Q/ d
        ]
9 a, @- ]& z6 ]- b& i8 W      }8 j: s! g0 h0 w! f. p
    ]/ A* Z2 B( i( S+ }2 v) Z8 I9 U
  }
. D$ W( z7 |' z* X( q}
. e1 q, O: `' t6 w对应请求对象的源代码如下:; ~( X) ]4 Q* c+ ?' B0 B: E
type SignRequest struct {    //function pseudohsmSignTemplates request  E* I# z' o7 y$ D
        Password string             `json:"password"`& \( ?" [- v& h! J% G; i
        Txs      txbuilder.Template `json:"transaction"`
: s  {( X$ y; C}* g+ D3 i1 i/ I1 P% h$ k% ^6 D6 W. }
结构字段说明如下:
& ?! T# j; H' T, ^Password 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名
# k( e7 Z  E9 c4 a% ?5 d/ ZTxs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述& j: n9 U) t0 q0 d# i

9 f* |! c6 c1 L* b6 o/ J签名交易sign-transaction请求成功之后返回的json结果如下:
0 p1 Y* N! R) ^" ^0 L; p  J. b. F{
/ ^6 N: X7 M, }  "sign_complete": true,
2 V2 r& E" s+ e5 v5 B  "transaction": {, X3 c: f. N. G* o: b; J, O( o. _
    "allow_additional_actions": false,5 L7 g) n/ W& ]. `
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",% h& l7 Z0 B2 P" W$ H
    "signing_instructions": [  b9 w& P4 V+ ]/ O* }
      {4 M. v4 H1 W" k1 v' C* L. \' I
        "position": 0,9 F+ w6 ^" w4 L- A8 Q$ }% ?
        "witness_components": [/ O& e: A8 L, d/ C9 [! o1 `
          {
5 \3 I5 l1 M" y8 W: \            "keys": [
/ \: R  u" ?, Z6 t              {9 f, }- q. }) ?; p0 V
                "derivation_path": [. m+ d# l: c/ w5 P. k1 Y- l. C) [% i
                  "010100000000000000",
. F# n0 U4 T8 Y$ c; u- Q0 ]                  "0100000000000000"$ E& A9 n# h/ W9 z9 G" _7 `6 i( ~
                ],
$ I0 u. F" _: n$ b1 q                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
% W# n" N$ J. M) B0 M6 G1 Z              }
, B: |3 X& e2 A4 ^/ w            ],! i- d6 x) d4 v0 m1 c
            "quorum": 1,! B5 |! B, @, ]1 F! P0 `2 Z
            "signatures": [# ^& s' i( ^$ q1 y* d
              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"
% |9 y- @; k8 M0 g6 [            ]," _: K$ m+ I( Y
            "type": "raw_tx_signature"2 F7 M5 b7 L: K! e0 D
          },
' p7 R( ?; B: P3 n- i. u          {
( N6 R( t2 m" k9 e% m1 O0 K2 i! Y, O            "type": "data",
0 w9 ?, G$ v% \2 J            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"9 ~6 T1 @7 R. s2 X3 T5 p, ]3 O
          }
& b& H' v, [! }, \" Q        ]" X" V+ k' q9 N- G2 a# r6 g
      },
- W6 V5 x1 Y' J) G9 q- h" @$ i' ?      {# U, \7 P3 M% n* M+ R; D8 I
        "position": 1,
# e0 l" \2 c6 x/ a9 q: C# k  \4 i        "witness_components": [4 f# M( z+ T0 ~5 Y
          {- H  g, o+ I  }7 `! t, Z5 D2 W2 r
            "keys": [
; @  R- F* ^: t              {
: i7 q) W' o( Z/ O6 ]                "derivation_path": [9 \- \( L+ T' _/ z  f- b5 C
                  "010100000000000000",8 Z# }# O! h6 z' e7 @3 C4 W% U
                  "0800000000000000"
9 v3 e8 c* }1 q                ],
9 i; r2 [2 Q5 f* z! @+ Y                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"- w6 J( E! O5 |+ ^/ o4 ^/ q$ E
              }
& Z7 P, \( X( s) Q- T3 i( t( ~% [            ],
: d) E4 A4 p3 B! `: U! j% r( Q( c% |            "quorum": 1,9 d# y, v5 R4 |
            "signatures": [$ z  @* V% q, Z0 @% ~3 Q
              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"" X- j5 G! S! X" g( {  x
            ],
6 f7 j% Y2 z" G, e* x0 k3 k3 U            "type": "raw_tx_signature"
4 ^) g1 F  v+ r; s: p% h( E0 `          },5 \7 {% y* O. r
          {/ h  Q7 i" |- I0 B
            "type": "data",6 j" Y. N0 I, U/ B* Y
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
6 ?8 @7 B! r$ {" _3 [0 H; ?  {" P1 D          }& e3 D8 q- M" n+ Y2 w7 H% G  Y" Q- k
        ]
0 A2 U! v0 c2 [, a6 E& |; f      }' n) F0 c2 L8 x: W
    ]
! z3 Y6 Q$ q1 M& @  e' s3 c  }
- R2 v1 r  B8 [& D, l}
) d( M$ B4 H/ C# y. W# \对应响应对象的源代码如下:; Z) u, [& B; P0 t: V
type signResp struct {% L5 J5 i0 |/ _) |/ R
        Tx           *txbuilder.Template `json:"transaction"`
  d2 l0 _0 `. E* [' }        SignComplete bool                `json:"sign_complete"`' C! I: W( x; l, o
}
* }- E. C7 T( V3 b结构字段说明如下:( B6 Q) S  q8 t# T0 J. U
Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息* f$ O$ ~) Q& [. f1 S0 R4 m- \
SignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易& X9 B5 t6 g, r# s0 X! H& l3 d8 U( l
1 A* ]. @+ \& j$ k9 @
3、提交交易
' A% R7 y* M. H. }API接口 submit-transaction,代码api/transact.go#L135
! v/ @; O/ V$ E. V; M# l3 v提交交易的输入请求json格式如下:4 a& U" j# o  t4 Q( k
{
4 H$ w* q& ]6 x* \* i% H( ?  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
) u/ j5 E9 w/ M/ U# A}; N5 Y" |' l7 Z8 X5 T6 U2 V  j4 U
对应源代码的请求对象如下:( B9 ?. U3 q9 x: ^3 k
type SubmitRequest struct {    //function submit request
/ t4 L) D( F5 Y' n        Tx types.Tx `json:"raw_transaction"`
3 \2 J/ }5 y9 A" r2 |}$ t( c$ @- h2 v9 F1 J' E
结构字段说明如下:: M& g1 S- q0 e- a' C* g$ f  A. b
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。# a3 n) _8 Y1 `' l
8 u; u, Y$ \9 U$ J; E  ~, ?
submit-transaction请求成功之后返回的json结果如下:1 P7 ^) A* L; M
{. ^6 {) f+ x, Z
  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"2 @4 R' c, E, N
}4 C. U. [5 I. s7 k# s% r
对应源代码的响应对象如下:2 f8 ^/ c% H( M5 P) _! F) C/ q
type submitTxResp struct {+ z* _4 g( U; c3 N2 z( O0 f
        TxID *bc.Hash `json:"tx_id"`) u. J! _- W$ T; m- B6 N4 u6 `" ]
}3 y& [; c5 }* _: x$ N$ O" T2 D
结构字段说明如下:5 C! s$ ^& B3 x. m# r4 w0 S0 N& P
TxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败7 @8 a7 K9 D9 u! i& }& Q7 V. ~

. s4 d" E+ C) _, t) |+ }/ y
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14