Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
164 0 0
比原项目仓库:: ]. O. G& v& \/ [0 H4 i9 w' v
Github地址:https://github.com/Bytom/bytom
! U/ o& @8 B  A3 m4 J7 I' ~Gitee地址:https://gitee.com/BytomBlockchain/bytom" g9 I5 [/ ^$ F/ i6 M  B: N' R
该部分主要针对用户使用bytom自带的账户模式发送交易
+ Y6 A% Z7 ^0 F% F! m1、构建交易
7 @8 H0 C& Z: M* t1 T2 @API接口 build-transaction,代码api/transact.go#L1204 `- c! a/ T) Q- H* L6 |$ f
以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:; \& k, \3 O" w1 M/ }2 m
{7 K: F1 a0 S& ^6 O$ I  n% i' Z
  "base_transaction": null,
! ]6 Q) y& ?% N  "actions": [1 f* e% m/ u* a1 ]9 P6 f8 F
    {
7 T* T; w( g4 Y) Q7 j3 Z8 M1 @      "account_id": "0ER7MEFGG0A02",9 c7 Z0 T( L0 u; g& n
      "amount": 20000000,
$ V2 D( X! B5 q      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" k* T( F6 I% u/ S( n/ E8 r      "type": "spend_account", Y3 c# S* h# L% h
    },7 }- j( a: A& O& V. m
    {& X8 g/ V- I7 O4 [; S  F+ J
      "account_id": "0ER7MEFGG0A02",9 @# a# r, V- F7 H" u7 o
      "amount": 99,
( s" @# A& R9 P) p9 J% }6 Y      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",* {) [& N4 \0 y3 w" `
      "type": "spend_account"/ e# \" f6 z! S; U) N! L! H
    },
$ E3 g$ m' W  I- b    {7 F9 L1 ?2 V% Z+ z% b- u
      "amount": 99,
# K( X; R* W9 F! s* X/ Q( J      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",: u% }9 ?4 R, X, {* h& {
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",. A6 z& M2 M- S. q$ v% P
      "type": "control_address"3 \% s- E$ i0 a  \/ o( ?+ q; O1 m
    }! O2 f# t6 s* D
  ],
* h, w% Q! `0 r- E6 J  "ttl": 0,, |; G$ @  c% M' |# F# T
  "time_range": 09 E: y1 ^3 L/ n# Z! w
}
( @! f  k# a4 A2 w6 w对应源代码的请求对象如下:
6 }+ v* ]0 T7 q// BuildRequest is main struct when building transactions
7 Q1 d$ N) h. K8 p, c! |type BuildRequest struct {
2 c  {4 v% [8 b5 p$ Y& c        Tx        *types.TxData            `json:"base_transaction"`
9 m& P5 ]9 n8 A$ D2 K1 X% ?+ S        Actions   []map[string]interface{} `json:"actions"`' l- s! G* O" c. z) g5 B
        TTL       json.Duration            `json:"ttl"`
' @; [% D& X4 f0 G3 k) s- ]( E        TimeRange uint64                   `json:"time_range"`
7 l' x( D7 N$ f* O+ Z, ]}
& m, V5 o/ N% t3 ^8 h: ^9 K( ?+ Z结构字段说明如下:
% N* ^. n; Z, OTx 交易的TxData部分,该字段为预留字段,为空即可; B" G3 t) N8 H! i3 ~
TTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟
: V  d6 b* |% E' u* s) _- K9 \TimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
0 c& O$ w1 J  f7 [4 `% _Actions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:6 Z' ]3 W5 K. A% O( V" C& i% h
input action 类型:
% D1 D; A. P: Z& E" O3 sissue 发行资产, j: w% G! J9 q3 a! m6 s9 A0 I* c
spend_account 以账户的模式花费utxo
0 l: e  S5 ~* R% M; o+ ~5 dspend_account_unspent_output 直接花费指定的utxo
% k8 n( }& R8 z+ x* P0 ^output action 类型:
# |! V' |, Z( x( M, j1 Gcontrol_address 接收方式为地址模式7 n9 [5 N8 b0 Q2 f
control_program 接收方式为(program)合约模式
6 E& D, F/ x. x( e- pretire 销毁资产4 X" n' b# b9 i3 z' x* G% `

. L8 p9 j" ^4 b6 t& a  F& ], Z- F3 A
9 q0 M8 }/ P, z  E
5 X) R9 }. `) J5 a0 b. u0 y, y8 c注意事项:
' e: R1 l9 F3 Q4 R一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。
/ u$ R' M4 ]( |* N- E8 L除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。
. T1 z2 z# P! I% ?. a2 }$ F! K' p: ?交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量9 O  m. R0 Q6 t% N4 `/ S
交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu& M. i* T: P8 S' z6 F- ~; |, f- _
) k3 E3 H8 U, C5 E5 S
action简介& D) y/ R6 C  w" o
下面对构建交易时用到的各种action类型进行详细说明:  O( T! _1 z! D
issue' z4 D# N9 ~9 E' [0 y& J) k6 j
issueAction结构体源代码如下:
: @, y) w6 _6 k0 m/ v% ~- |8 Gtype issueAction struct {
2 x% U6 y+ S" C, G- b2 z2 \2 K        assets *Registry
( D1 h  h4 U) ]8 r" p! b        bc.AssetAmount- k5 A+ m/ O8 S) f3 t" p% o
}
9 E2 f/ }7 a# U; |1 M, g4 }/ atype AssetAmount struct {; s9 C+ d3 O2 k4 S
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
, }& \& c5 [* ~& |5 \! X8 M0 N        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`) e- ?6 \1 u6 |  J/ A
}
1 _% g6 M3 c) f2 V$ N  G结构字段说明如下:
; T0 a' {; ?, `/ u" lassets 主要用于资产的管理,无需用户设置参数
" w9 m) F" O& j) [. q: GAssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID
& v; U: X( C8 c( ?$ F
1 S  m) |/ Y& s: q" n: |3 b5 WissueAction的json格式为:
7 N% S2 c! G# v! S{
% N' e4 }) x  `! x  "amount": 100000000,4 h4 ~& y# z. Q: W; V! ?
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",# r# ~8 X' w9 ^$ S$ T
  "type": "issue"1 S* W5 Z3 W3 b4 g2 s; ]. Q
}
' ~5 Y4 d1 {$ m$ _例如发行一笔资产的交易示例如下:
* D6 f% K9 Q& H& ~4 y2 t" x(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)
& C7 J$ O5 e/ {7 r) u7 z- Q, n$ k{
  N$ y/ i1 v: V3 N- T, x, M  "base_transaction": null,5 {* ?8 j4 w% z1 n
  "actions": [5 N. M( l9 I4 S
    {' B" Q3 e9 i& I: J
      "account_id": "0ER7MEFGG0A02",1 {; B4 |% L. \2 J6 a* I& ?
      "amount": 20000000,% V8 b- s9 X: f
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",8 h/ V4 z: H  n
      "type": "spend_account"% ?8 P) D- y, W/ c7 T- Z
    },
" e/ g& z( r9 t" r7 w    {
6 F7 m* V0 D! h' }      "amount": 900000000,
9 f7 W0 L; f* v" z( Z9 L0 h      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",0 l1 t# i9 l% w1 i6 }7 ]  U& `% J
      "type": "issue"  F$ |5 |1 c. e3 L
    },
: s+ p! M& F, ?3 O" H    {
; s& L- q$ H/ \6 ^      "amount": 900000000,
2 c: f: j7 y5 v0 F, X- F      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",* U2 u3 V! @+ s+ T
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",2 s# M5 N: N; B
      "type": "control_address"
* ~  [0 m: o( y    }
% P* }5 B8 q  H( e1 S  ],
0 j" ]3 x5 a" x. C  "ttl": 0,
" S. ^& h; O4 f; P0 r: `  "time_range": 0
& R" a4 D' o. j' g% }}( p) `6 ~% s6 z5 d, e- }0 |8 C
5 ~5 S1 H" K! j6 Q0 r
spend_account) V9 S; H& p, H4 H" w1 O& `
spendAction结构体源代码如下:$ G  Z7 A+ B! |6 P7 u
type spendAction struct {* m# Z" V( u+ M+ t8 H7 A7 y
        accounts *Manager
. z; r2 ~6 K# G' A% r' E( `        bc.AssetAmount% I! R4 [8 e2 Z# N3 b( Q
        AccountID   string  `json:"account_id"`, _" A& ~/ e4 S7 t% Y
        ClientToken *string `json:"client_token"`! z8 a# \# V. ]1 n: c+ V0 `% G. ]
}  V; U7 M3 Y& J+ j6 U% T3 N
type AssetAmount struct {
. C, @3 j) d0 z: }6 a" ^( o        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
8 M, u' W9 s% ]- c9 y        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`$ E% n  c! y* w7 X, L& ]
}; {0 N8 `! c3 j: U5 B+ k3 F
结构字段说明如下:
% \# V1 r- b; k, c, D: x( ], gaccounts 主要用于账户的管理,无需用户设置参数
6 r4 A9 k$ I0 S0 y# qAccountID 表示需要花费资产的账户ID" z- f& C4 ?! L* _4 D8 A8 Y
AssetAmount 表示花费的资产ID和对应的资产数目
* Q4 T" w- D! [& `0 T0 i8 \ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
; O% x! k& h; x% q) L' W$ W* p/ g5 e& c
spendAction的json格式为:( w; C: Q- a( y- V- C0 I# s3 y
{
* d6 T4 h% G0 y5 _3 l: n; R  "account_id": "0BF63M2U00A04",8 R9 k5 H9 q4 p5 V) z
  "amount": 2000000000,
& s, [! ]; J+ _8 _. q  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",: u3 ?2 t7 d# `. F
  "type": "spend_account"' _4 f: T. O. W
}  g/ a& y7 H/ |8 ?- B
例如转账一笔资产的交易示例如下:* @! [0 M5 Z* {* c1 f) W% N
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)4 t% S* h: B0 I4 [; Q  {
{3 p+ a, P, U$ x- F/ }" t1 j- q
  "base_transaction": null,
1 s4 s& F0 H5 h$ H  "actions": [6 q0 `5 w% {( ^+ Q  B; a
    {
( r: b- B  |- j" A) z% i. ?( W- h: H      "account_id": "0ER7MEFGG0A02",; x8 c& ~) S+ w! L
      "amount": 120000000,
4 Q+ e+ b. |. U& i      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",$ E5 F" B6 {3 a4 K" A9 t" Z) n5 T, q
      "type": "spend_account"5 o& X, B5 f" E
    },. L1 V' U, d. U8 @8 ]" N
    {
4 D3 A' y- Q& L( ?+ K# x; l      "amount": 100000000,
8 P" k( F/ D- x" w& o+ {$ ?      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" r. ~9 i0 n8 J( A% G! A! T% Y% C0 f      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
3 p! Z5 R" `7 E$ Y      "type": "control_address"* E+ h9 C  y  o6 o# w# p9 `
    }
2 H; m! B0 R  R1 k9 E  ],+ r+ R: z" @1 d9 s. p
  "ttl": 0," C- U4 V6 m  o( P# f: C
  "time_range": 0
6 Y8 `/ ]5 ~# F( @}5 a5 }: N- R$ d7 S! O
( y0 a& A. q  S5 @6 K* J
spend_account_unspent_output7 ?) d$ l* J& f/ w6 x: W- U
spendUTXOAction结构体源代码如下:1 K: u! g& K. R7 r* K
type spendUTXOAction struct {
  M0 j- ]9 x  _4 z4 }        accounts *Manager+ h  y, L8 e2 L6 C* [
        OutputID *bc.Hash `json:"output_id"`
) d7 a$ h! {8 M' U        ClientToken *string `json:"client_token"`9 G% j3 u2 g6 y& |4 V; H/ s! T/ n% d
}
& f1 L2 |* m  K! u结构字段说明如下:6 w/ x3 `" q. y7 i! ?
accounts 主要用于账户的管理,无需用户设置参数
# H, @" _( Z" X; m) Z* l" cOutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段
  G  Q. ?3 t5 A2 x0 ZClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可3 h" m0 p1 ]' K
8 m$ I' h4 ~2 _8 }. |
spendUTXOAction的json格式为:
  |( X) z" n# w5 L, f% V{/ \3 T2 Q' C, g' K
  "type": "spend_account_unspent_output",
1 w+ C2 N2 J) R% D; \* G( a  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9", V' b) w7 h+ v5 n
}
7 x1 C% u4 r) D: f' z例如通过花费UTXO的方式转账一笔资产的交易示例如下:- f( |# f( \* U
(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量): `+ j1 F8 Y- ]# U0 m0 J+ C9 {
{+ d  N4 S$ d* a( ^" X/ D, Z" o
  "base_transaction": null,5 D5 O: y+ A8 f( _( ~1 x) `
  "actions": [, ]$ ]' I) J, ^$ i/ a9 G
    {
2 z2 a- L7 V7 Q! P9 p1 c      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",  \3 S7 B, `6 y" F
      "type": "spend_account_unspent_output"
0 s( ]+ S' ?% R6 u7 B2 w    },
/ B) p" X7 T; r8 J8 \    {
+ Z4 B% Z3 V* D+ ?2 x      "amount": 100000000,
+ l! W3 E9 X( V2 d& N7 i      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",6 R0 m  [) H4 z6 }
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",4 J( d5 f0 n7 L4 r/ j5 Z: f
      "type": "control_address"
4 ?9 S$ q; P+ u2 ]- `7 Q; Z    }# g! _2 X0 W" @+ M- j9 k
  ]," q8 B; h, d6 g! u4 |* u1 i* I
  "ttl": 0,
+ l  ~6 b  T9 f$ S1 Q; J: `  "time_range": 0
8 ~, M( {) E" |: X! Y}) m& m$ e/ X( j( @$ s" M

  B& m2 _/ j0 W9 J: I0 g+ }control_address" O  d% i  K$ Q# [# ~; a0 `3 L1 L0 c
controlAddressAction结构体源代码如下:
& z5 z$ j- Q2 O; u5 X) wtype controlAddressAction struct {- c# B3 E+ b! {: b7 e
        bc.AssetAmount7 [0 o: m2 @' w; `; ]% y4 ~0 J0 r/ ]
        Address string `json:"address"`
- o/ H* l) ~8 t: g. Y0 l/ T}, H8 E" }9 W4 e$ J  k
type AssetAmount struct {
6 C; G5 L3 B$ f) u- [* b        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`3 ~4 }, H& b  B
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`' Y! s5 q8 G( a7 o) _7 k7 F( Y% u
}% |+ s$ D$ [1 w  S0 d8 p
结构字段说明如下:, M  K+ k$ q: P- V
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址+ d& B* t; t3 ^+ D4 ?+ a  M" g) U
AssetAmount 表示接收的资产ID和对应的资产数目
9 W. O; `, o9 {% d* W* i
! ~0 p" R. e$ \/ x# G. W: e% rcontrolAddressAction的json格式为:
1 [  |! {9 }# W$ s' t, E{4 r% ?; Q/ f! R. R  R- S
  "amount": 100000000,
/ I, h% h- r  W( _( }5 a  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9 z- }, P7 J: X* _8 K; P8 I  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",
- k- [8 g: _1 J+ d  V& G! l9 F  "type": "control_address"
+ E5 l' O% z& }6 o4 P2 p}
" q( L" ~; e/ Q+ _: y; C) O例如转账一笔资产的交易示例如下:
2 R& w' Y7 s/ B' @( B7 T(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)
! u4 k0 H2 R3 y" y+ T{
9 b1 c$ Y% Y1 [: r: L  "base_transaction": null,) s; j6 T- m" Z8 O$ ~
  "actions": [; n5 D; p1 O/ e  |' N) D3 R
    {2 O5 ~, i% h- H& \8 O9 |
      "account_id": "0ER7MEFGG0A02",
% r$ E: j. ^9 R7 Z      "amount": 120000000,
4 h$ j# @* U# D1 ?      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",; N6 [+ I& D; M  A0 a# g
      "type": "spend_account") e3 A3 E1 `4 Z. N9 M$ b+ W- Z/ V
    },
/ O  |) w/ z" z7 L. k* Y7 z    {. H& V. R* _3 p% d7 n( L& i0 [! o
      "amount": 100000000,6 f) l5 V7 t! [. m+ e  U
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",1 g2 x+ E7 o( ]; `9 y7 M
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",! t% M* y( U. b+ m8 a5 l9 J: n
      "type": "control_address"9 f  R0 q9 ~# L, f  c! b: F8 ^
    }
( i9 |5 P( q: ^/ I# m  ],
* i* X$ F6 [# T1 G' z5 Y$ t) x  "ttl": 0,+ f6 X% q: u1 D
  "time_range": 0, r8 {' \/ U% {: ]
}
' m0 V/ Y9 J& v# j2 @0 x7 Q( _% A& }. l
control_program
2 T5 \3 T8 G4 b, l, F* ]8 Q7 OcontrolProgramAction结构体源代码如下:1 Y& q( B7 A; @/ K) Y. ^/ ^
type controlProgramAction struct {
& n" ?8 C  r% k1 Z( v        bc.AssetAmount
+ c5 q1 M, d- D, N# o% V+ d6 G        Program json.HexBytes `json:"control_program"`
* Q  c* D- r, |& I5 U; w}0 |. S; }1 r" L
type AssetAmount struct {
  @. U2 `9 Y: U# w2 r, T* f        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
' h8 A% K% J7 D: [. n4 ]- H        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`0 L$ @9 |  C5 q
}
- l# ?# T% h5 X+ ]4 S结构字段说明如下:$ ^9 U# J4 E9 n7 x) v9 C8 @
Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)( _7 h, t' ?% O% O8 p
AssetAmount 表示接收的资产ID和对应的资产数目$ B0 x! `: @. l9 O7 j9 s

. u! R, w! D6 ~; M! A' t0 t7 x0 V6 HcontrolProgramAction的json格式为:4 k+ j0 s. h; u+ ~' Z! l
{
  i) H  {& @5 C  x) R( b( m  "amount": 100000000,2 Z  Q6 U4 V# ?1 Y9 _3 v
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
& ~  [9 F7 u& u/ y8 J  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
$ W' m& B; M) `: j4 i  "type": "control_program"
% S9 x# b0 |) B" n3 v6 t  F$ j8 X}# B! ?; N/ \# o+ V) ^1 N
例如转账一笔资产的交易示例如下:8 }' z9 U+ c* n/ X  }; U+ s: m
(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)+ r" B- q/ j0 n( @" B* ]) e  l
{
& T3 l* ~" A( O8 n  "base_transaction": null,
- z: a; y  v! M. c  "actions": [; t8 g1 H; U2 D
    {6 m% {' a* @" ]
      "account_id": "0ER7MEFGG0A02",9 t. d1 m8 @/ {0 i9 o* g5 x! |
      "amount": 120000000,# A# }7 E/ w- B* C% m, _
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",7 m0 ]& A" S3 n5 W5 K% R# T
      "type": "spend_account"
+ U* [6 j  Q. _/ z6 A( ]    },5 h7 X& O0 i% \: \, z) `
    {+ U) L3 l$ L# e! G& }
      "amount": 100000000,
" b) Y' s6 }( |- e      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"," o* r1 M: ^( F( @, ]/ a/ q
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
- L. W( c/ x. M0 O0 V2 \! H7 ]      "type": "control_program"  e; E, o# p, c5 N; h5 d5 P+ [7 h2 B5 t
    }1 J; v0 O; }& C
  ],; f7 |4 C6 K% j3 z; s8 A, l
  "ttl": 0,
9 \8 u$ U5 Q, s0 y& b  "time_range": 0, @* y1 [3 Q$ D% K1 m+ X: H) f
}, d; y' L8 i, {/ o( c8 {
# k4 A& n9 U4 w  X" h  o
retire
5 w& |- v# v+ m! v6 X7 eretireAction结构体源代码如下:$ n/ i' V0 n# J/ m
type retireAction struct {/ h( c. N* s. T. Y5 c
        bc.AssetAmount* P' E8 V# \8 [, m1 w6 U2 y
}; d- g! @4 ~$ B2 W: M
type AssetAmount struct {% }* K& w3 _2 X  _9 T
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
& J- ]- R/ w/ z7 V5 F3 L        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`2 H' S' ?6 ^. R
}
& @9 b) d$ j" ~- I结构字段说明如下:4 o# a. U- o) @. P: `; l" |2 e
AssetAmount 表示销毁的资产ID和对应的资产数目
0 J) P: m7 Q6 b; [8 Z
5 q& D) }0 m1 b- V! n1 aretireAction的json格式为:9 M9 A7 H  `( t) e& q1 l2 T) F5 I
{& Y3 `6 w: r, ~: q7 g: D
  "amount": 900000000,) z5 e, L" Z0 s7 S9 c9 v) D' g. m
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",# W0 Z8 D. W) g5 `+ v
  "type": "retire"
5 q9 L: J3 \$ Z/ M; K5 e; p$ J& V# u}
4 J5 V% u! d2 I3 I0 }例如销毁一笔资产的交易示例如下:0 W' X6 q. U) ?9 Z7 }2 B: Y
(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)  d6 v  |( x7 b
{
7 Q- e, n' O- @5 b+ m7 Y$ L% b  "base_transaction": null,
8 z( c; E9 f$ I1 A7 D  "actions": [
3 J7 g4 }* A+ D1 m$ g    {# _' f& n  j+ Y
      "account_id": "0ER7MEFGG0A02",; r% z* C# ?( {* [' K- u0 ?8 A; {
      "amount": 120000000,/ L7 g) x" @# B
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",# C$ K. Q3 q6 z3 ?8 p" @
      "type": "spend_account"1 p! O# O" E! K; c2 q
    },
& w" ~" u8 @9 ^$ e: q. d7 J    {
) R$ }" t; `) {* J0 Z7 L, \      "amount": 100000000,, g7 p# `  a: Z2 X6 a3 ]5 C+ R4 U
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",8 ~/ |. n" w+ M9 b# ]- e
      "type": "retire"7 R8 T! q2 l. N  C7 s
    }
5 S. q( V( L9 x" i5 @% s4 V8 c  ],5 s& K4 S1 i" F2 ]& \
  "ttl": 0,
+ y+ M# J1 R  U  "time_range": 0
$ ~. D* f# _  a7 U1 D}% l7 g& H' J2 H$ A

; ]: _+ c1 V5 {. J5 Ubuild-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:
* Q$ b. \6 B/ @( R# Z{- L0 D& h, Z& c6 }2 K2 J( @) u3 T' _
  "allow_additional_actions": false,8 _+ {9 P' v7 U5 c. I) C- L$ g
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",+ @7 ^- P, B: a) U, @4 M
  "signing_instructions": [
& \9 N0 D, D, l5 E9 U: [    {4 T7 X" ]& _! }- g1 H
      "position": 0,8 \* K6 a. s. R5 _# k
      "witness_components": [4 T% |9 h3 f; M; X2 a) j
        {% x$ K! F7 }6 Y( o2 e
          "keys": [
5 n- U0 x! M2 o            {
$ f0 Z5 X: R7 x6 {6 Z' y& D' E              "derivation_path": [
3 r' I/ s  ]  g+ e% x3 |; t                "010100000000000000",3 D5 ]5 L3 }+ h# \6 v. h$ [6 Q
                "0100000000000000"6 ~& A/ {( h0 [- i
              ],  }3 ?& v) j- X; r9 i
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
6 e. m' T) A9 l) H            }
$ O' f5 n+ j9 E# f# H- @          ],! M7 }; D  d$ L8 r8 h$ I
          "quorum": 1,
& ^3 }$ [3 C8 |          "signatures": null,
" x8 R7 P: R& A, G6 L% g+ m: `          "type": "raw_tx_signature"  w9 O9 D( a% {$ c* }# R
        },- [- D9 m; j" L7 {: P- F
        {) p( K# V( P1 H) b
          "type": "data",1 |9 k& @0 |9 v
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"5 c' U8 Z+ O9 X9 \/ `
        }( T$ }6 F, o/ g2 ~
      ]- M3 H( v7 q0 ^) ?8 ^* C
    },# Q& S8 }' h- \; v4 h$ E; b
    {& Q: N9 B; X: H2 g6 v, ~8 V
      "position": 1,' G6 x$ J9 _* v  ~/ g# |8 A9 z$ G  S
      "witness_components": [
( w1 L# s4 z8 I. d) G: w9 z+ ^! W) c3 N        {; P; p: W2 Q0 L- o, _
          "keys": [- {  M0 T; Z& |1 Y& C; s
            {
- M# v' R! s5 b7 u; ^              "derivation_path": [
# d8 h$ r8 S4 G7 m* c                "010100000000000000",
) W3 K- M- G2 L$ `$ y# P: c( X                "0800000000000000"0 K6 v- O( {$ _  r( V& M
              ],
* b" w5 o6 z- G5 [/ c              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
7 Z% y0 H) I3 k" l8 P* g3 O! I. l            }, U, p) k4 x& q3 v
          ],# W. `2 ?4 [% R2 e# {. c
          "quorum": 1,! r8 i' L3 H) z- I  i
          "signatures": null,
! Q8 K+ b5 I; }) P: T/ O& [          "type": "raw_tx_signature"
3 F8 S8 [' _4 |        },
$ N# o; g7 N- W. n( f# f        {
# `& H, z' V! M+ _* y          "type": "data",9 A6 T8 n+ a+ Y9 [8 R! Y
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
- E8 G) k- T& n# O        }1 D9 }; g% v7 A- Z* M( {" E
      ]) T' n/ B& y+ w5 J3 m; g4 T
    }
1 |3 s* q# B5 N4 b. {; Z  j# k  ]
. {8 L; V7 ~: C) a  y}/ H; y( B  D  j" d2 T4 Q0 X' i
对应响应对象的源代码如下:
9 m0 r' o* k' M3 z// Template represents a partially- or fully-signed transaction.
! I5 T% j* [1 m1 B- H4 X! Btype Template struct {( ?8 Z: b! s# Y; w
        Transaction         *types.Tx             `json:"raw_transaction"`
- j# v7 y0 N2 N* V# T0 T        SigningInstructions []*SigningInstruction `json:"signing_instructions"`0 q* Y: S' H& N% S+ X* y6 e' l
        // AllowAdditional affects whether Sign commits to the tx sighash or
% U6 ~- A6 i  u" w$ f        // to individual details of the tx so far. When true, signatures
$ [  ?8 P+ d( l$ q. B        // commit to tx details, and new details may be added but existing- s  W. q8 u1 h9 R2 E
        // ones cannot be changed. When false, signatures commit to the tx
) A$ h9 x& `# ]5 E) `" S        // as a whole, and any change to the tx invalidates the signature.
" o# k# a7 p9 s* F        AllowAdditional bool `json:"allow_additional_actions"`
5 ?4 N# f5 Q' A3 x}
: x6 r8 _  w" }- W7 {结构字段说明如下:
6 z' t7 k6 F/ S/ K; I9 i2 m0 ~Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:; u( \/ m% ]# ?$ @7 B* U1 T% Y3 m; M
TxData 表示给用户展示的交易数据部分,该部分对用户可见
, \( M- V& l: I4 WVersion 交易版本  W/ A( p5 C1 p4 m7 O8 k
SerializedSize 交易序列化之后的size% O' q4 M6 }  J! a
TimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)
: F- a7 K1 ?* q- P2 c9 gInputs 交易输入
! {6 }; [; p9 l5 X* g; |9 rOutputs 交易输出
1 T. K; d+ p" ~, Obc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述
# }9 t+ Z% v& {# ESigningInstructions 交易的签名信息) _8 B' G$ M& y1 f/ _
Position 对input action签名的位置
9 u" _3 g6 x9 C/ h& k% U& iWitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:
' D) b  x+ a: g6 h+ Q, USignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名4 N& n: y$ s2 a7 \5 O/ E5 [
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
. r8 o2 ?: v+ A& t3 xkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名: k* J; Y( O, ^3 Y  d: q) S3 f& g
quorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
. B9 f7 `  a+ J9 h' Gprogram 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program$ U/ @4 ]% K; i
RawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名+ [$ B* [/ _) M4 j
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在0 g6 b, X- `) C* O  m
keys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
+ R: o7 ^! g" K2 squorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户5 f1 P4 n4 z* a6 ~" c
DataWitness 该类型无需签名,验证合约program的附加数据
2 f( z8 X8 Y, V% [. B- v$ I' n7 x5 i( A: K0 {
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名/ \: O/ A, `. Y( l

( P2 Y  y6 t& ^4 q估算手续费
# x- p2 k- {  X& v4 q9 v( c估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:: S1 C. K6 g! Y6 m% j
  build - estimate - build - sign - submit5 v) b- j5 x' S9 B& k  O1 V$ Y
估算手续费的输入请求json格式如下:
# q% E* n, _1 d) H; s0 @{5 Q& @3 a. W1 ?  q0 d2 Y1 B' e
  "transaction_template": {
% v1 e. r2 |7 |* `7 }    "allow_additional_actions": false,
! x4 m0 S$ s9 |; n0 E& a    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
3 x9 E& x$ Y* O' V+ J    "signing_instructions": [7 C; w) q6 C/ U- g$ m7 g
      {
* _; L$ r8 j5 C. A2 T$ w# F. _7 c        "position": 0,4 p! [& ]: m. c
        "witness_components": [0 `( o' ^) e6 V/ c' m
          {: u* a7 ~1 A' I) x$ d$ G
            "keys": [" h! L2 J! N+ Z( p  @3 I
              {$ A, J) O  a) Z* J; A* ~- v4 a
                "derivation_path": [- y! {. ]$ ?" U1 I# c
                  "010100000000000000",
, ^: Y( M; u: t! p+ V  P) ~2 N                  "0100000000000000"
. T$ i, G  n3 m& N7 l" `                ],7 d/ }' d) `. ~5 W3 S; k
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
( p/ K# ]1 u* ?( D# y              }
/ V+ j3 }. E7 ~& c  {: R( K) S8 g            ],( N8 {* u  V( r% d( x
            "quorum": 1,) G5 c$ K9 i7 C: a. k
            "signatures": null,
! n: f. V& N2 T& ~1 _1 O. `            "type": "raw_tx_signature"/ J: ?. e# O8 y  n- a/ g% Q
          },
- [$ }" i4 I. @: v* `! r: P          {
7 z1 g: l: b1 L, F/ Z- a7 O& ^            "type": "data",7 s3 ^  M7 |0 U  t+ s
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
6 P, ]7 D2 I+ v( j' P: e; p8 r          }
6 I; o! F& q' B4 \. \1 M& P        ]7 ]' {3 |& q" F3 b
      },
7 H; l3 l+ b3 K$ K      {
6 f4 a- I$ @7 I! Y9 }        "position": 1,
8 K/ c) X( ^3 ~/ @8 j        "witness_components": [; ]4 A: M; S; K6 R- X% M( z; ~
          {
6 W3 W7 @6 I. d4 \0 o& K            "keys": [  y3 f' Q1 q) U. t$ f
              {% p; ?: E3 e4 [
                "derivation_path": [2 s' c1 }  c5 r5 }2 h
                  "010100000000000000",
# f' m$ U9 F3 x" r# \0 [                  "0800000000000000"+ t3 h/ ^5 ^# y# B0 M9 C
                ],
6 S1 U8 U. B1 k+ [% C* V$ R                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"0 g! z2 G+ U  f
              }6 P( \# x$ G$ O0 D6 B! X' W
            ],/ z0 _  A, l+ d" c0 A$ o8 U( S
            "quorum": 1,
: K8 p# |. X5 F5 H            "signatures": null,
; e. b9 g# [- i* R1 Y8 A" ?0 Y            "type": "raw_tx_signature"0 M; R0 q* D. J, s- x
          },
' ?; e1 ~3 y, m% J; ?) `$ P7 N          {
4 x7 @( N5 ?3 t# c            "type": "data",
4 Y' N8 H! @  s1 y+ Q+ W            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
1 H: N! f4 r3 D, V7 L5 T          }1 o* T. F# H$ j0 a5 R, v
        ]
- X0 [5 d' I  `      }% c0 J& I: h$ s, g: J
    ]/ V- m- ~% c$ W
  }
9 P9 ^6 O8 w! B: ]* U9 e; i# k}
: j& ~  t' c. W% M对应响应对象的源代码如下:# y% c8 ^5 F! p  |/ E. i
type request struct{" n( |7 r0 S* i0 m6 u3 I% x
        TxTemplate txbuilder.Template `json:"transaction_template"`
3 T8 L3 w$ }$ ]+ Z+ P}. E7 }; Q1 W% O# p
// Template represents a partially- or fully-signed transaction.
0 C- K, m' Z/ f$ E! ktype Template struct {
' p$ z) a$ n* _& n: H        Transaction         *types.Tx             `json:"raw_transaction"`
0 U( b4 v' {0 }        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
& L2 Z2 b9 O( l' C. N6 f        // AllowAdditional affects whether Sign commits to the tx sighash or
; K0 }. f4 X/ h0 U& s  c        // to individual details of the tx so far. When true, signatures
- N1 x/ a5 s3 I4 `. p1 f, ]4 w        // commit to tx details, and new details may be added but existing
7 @& m% {# }8 S' }; o  p        // ones cannot be changed. When false, signatures commit to the tx9 i6 {: f. B1 R% q5 C7 H
        // as a whole, and any change to the tx invalidates the signature.
8 N- F# q) S0 x/ _2 w        AllowAdditional bool `json:"allow_additional_actions"`
4 }6 q) a' }3 |7 P- q# ~9 l}) S, C& x. d! d; h- r
其中TxTemplate相关字段的说明见build-transaction的结果描述) w) |4 u  m- {* g) Q
调用estimate-transaction-gas接口成功之后返回的json结果如下:
3 R' J7 g; `2 a9 _4 V2 B{
3 c, G* N# w( U2 @3 ?. Z  "total_neu": 5000000,
% U9 `& Q8 |; j/ F# [/ c  "storage_neu": 3840000,; n/ u, {5 D" P- M# _5 W
  "vm_neu": 1419000# }, }4 M& y4 M+ H5 p
}) r, o) i% u2 b% }& t6 {! H5 @- c
对应响应对象的源代码如下:
% ?. j* E* h) V: B4 p// EstimateTxGasResp estimate transaction consumed gas! Z0 C5 g. \8 b* r- E+ t
type EstimateTxGasResp struct {
) s/ H# v  G" b, l5 \- m        TotalNeu   int64 `json:"total_neu"`+ S" o& \; u9 [: }" o" p1 e
        StorageNeu int64 `json:"storage_neu"`- q. F* W& ]5 p( \3 h$ Z
        VMNeu      int64 `json:"vm_neu"`
: d5 ?# Z3 I  I: p}
5 f  j# h" M: t/ O! [! G结构字段说明如下:
. A) @- D! `3 ?- ?2 g2 @TotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可2 N& ~: p4 G# e% a: d
StorageNeu 存储交易的手续费, N" U* p( j! [4 }
VMNeu 运行虚拟机的手续费" V3 G- T, w+ D& R  s

& |0 d. S/ _; T# F; C+ Q2、签名交易8 I% f4 e6 E5 t' N% x& b1 f
API接口 sign-transaction,代码api/hsm.go#L53
/ n' M# J0 {. @* B1 K/ _4 b( F7 F签名交易的输入请求json格式如下:4 P5 o6 i$ w; C6 F! r4 {
{$ \2 V5 r% s3 n7 V
  "password": "123456",
8 j% f  z$ U" _! J. d4 {& |  "transaction": {
  l) D; f, K$ H. m    "allow_additional_actions": false,
# [( t3 `+ B( ~" o  ?* V) P    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",; \! s9 s# x1 T, o7 M
    "signing_instructions": [
. d3 v/ g7 v2 d( j/ X      {
* M+ c. C4 R5 [7 i        "position": 0,
6 t$ H; L. s) g; T        "witness_components": [' a( y4 x( z, I1 S
          {, n+ o3 z" e# U( S: l. [) P
            "keys": [
7 d( C8 z1 G8 M+ G0 C( n              {
, r1 D0 r7 b! G0 R0 y# p" ~7 X. z# n                "derivation_path": [
& Z; u) X9 a. A: d' f5 ]                  "010100000000000000",+ Z0 `, a  v7 ?7 u% C% f
                  "0100000000000000"8 t9 Q( ~1 G) d
                ],' x2 P* N& ]2 ~( [* P. t" d  O
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"! H5 g  d# Q5 e) r# ~9 t! U
              }" `( D1 ^9 K- G8 P$ Y* Q, B
            ],
/ [! v) G) r2 t9 X9 C. M8 K            "quorum": 1,
" p2 X% s, {) `+ F) P  b            "signatures": null,; g" E$ n8 Q: g2 `
            "type": "raw_tx_signature"3 E: M. E# m  W9 S5 t
          },
- B2 V2 @  Z* O+ o. \4 o3 A$ s- M          {
) r7 n# z" I/ A+ F+ I            "type": "data",$ b' p5 p4 I4 F1 H# u8 p* |
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
, L6 o% Z& {6 F0 Q$ r0 {7 i; n          }
- l. b( h5 j; v+ S* ?1 F" J  E        ]
( c: ^5 Y) j; B5 X" `: q      },
; J9 |, {) o4 N# s      {
0 `1 @' I* @( I& U( B        "position": 1,
! W1 j- o- m" C+ |6 S        "witness_components": [' v( H$ \& H4 Q8 @
          {! J, W- |1 H3 B) _* v7 p% }
            "keys": [
  }* @: i* N! W& t1 {4 X              {
/ o, l. ~2 z2 d+ t" @                "derivation_path": [9 Z; ~3 ?, Y* M' ~! O" r+ C# Y2 ^' ^
                  "010100000000000000",6 S* _" D; L& g+ f3 U
                  "0800000000000000"5 K) T4 y$ B" C9 Y+ W1 O/ |
                ],0 C$ p+ j$ I  h& z+ j. K4 r, `
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"6 D6 M, X5 A' `$ R
              }
- d0 V# F" C, J' v+ G* c3 s            ],
9 k0 e2 a! I" c7 ^            "quorum": 1,
1 |3 |7 D; ?( g! i3 [            "signatures": null,
- ~# _( ?% T% l            "type": "raw_tx_signature"
/ g! k" `5 X/ l% r# h% T- n          },
) }8 ~- p+ }  `1 i2 W4 W          {/ R2 h$ a0 m  J3 K0 y
            "type": "data",
* `: v& s6 e2 w0 {            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
  `1 d2 b" ]  U; v1 T3 _9 C          }
) d+ `0 x8 F, T4 n2 e. f7 O        ]
6 ^' }8 J  E8 d2 c      }3 @- ~( g  J" w  c; [
    ]
7 \- g4 Z% B- t$ e* |  }
4 d' V' o* j! M}& Y/ a3 I6 {; A( h' e
对应请求对象的源代码如下:
; [! h9 G: O5 Q: Ytype SignRequest struct {    //function pseudohsmSignTemplates request' N2 U1 r) D9 ^- O
        Password string             `json:"password"`& n4 w9 D2 o& z$ j
        Txs      txbuilder.Template `json:"transaction"`
, n. |1 R5 o* e}
5 C& h% ^6 A- y' G结构字段说明如下:
5 p  g' g3 ?9 `$ K+ @( BPassword 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名5 F2 C8 O% u1 [+ q7 N
Txs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述" ]/ I* N/ A9 R7 D2 y2 g# h; S
# ]. }) F+ Q' U! H, a( j" _
签名交易sign-transaction请求成功之后返回的json结果如下:5 i3 R  L! C: D7 G
{( J; r% o, P( d1 e% X: r1 L  I
  "sign_complete": true,
1 B# ^# [: N3 Z1 Q) l  "transaction": {
3 r4 A) H3 h; }3 r    "allow_additional_actions": false,$ W" F3 x! U' ^& K
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",0 w* Y) k$ Y( m
    "signing_instructions": [
0 D- p( H6 l8 s9 i7 r1 i* n      {
- y) [- O5 B5 k* @* U5 w+ _+ V        "position": 0,% A  b; f! D" I4 I1 N' m/ L% G' R
        "witness_components": [8 |. w' ~4 }5 S+ P; _
          {
  V5 [+ \- E1 x- C8 V1 H            "keys": [5 V- ~( o" t* Q9 d# Y6 Q" n
              {$ ~/ J+ O9 o5 J5 o9 x9 O: X
                "derivation_path": [
+ x( E" @- Q9 J' D0 t                  "010100000000000000",
6 w1 L6 r; y0 {# X0 M! b- O                  "0100000000000000"4 F) j% _8 H) X- D' E; j
                ],, D  X0 S; G- l- C
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
0 Q. r% r$ V/ i+ @( P8 c" v4 L/ y# S              }
+ e; l, ~3 ^3 q: g            ],! z6 _1 X/ s3 c* ^
            "quorum": 1,* h2 G/ E5 ?! v( ?: E
            "signatures": [/ W! ^- [% P0 X% @! D
              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806": m6 _$ c5 w( s% B, q. i
            ],
# w2 ]+ s6 i4 B$ V            "type": "raw_tx_signature"# a( w7 ?* g& ?& `$ Z
          },) P  Q: i! `6 M$ K) A: u3 S
          {
& E% J: g  l3 L4 V& X$ T            "type": "data",
. e8 s" i9 N9 I            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
8 H9 j# X) O/ C  ~$ U          }. X* c+ ~" R$ n3 f- n
        ]
, m& s: d1 a* r$ i& }" O# J2 |      },# I! r, W4 G4 ?0 |" i
      {! l: B" a; |; Z8 {5 [& i0 l
        "position": 1,
4 }- a. X3 i* }% b        "witness_components": [
) B+ L6 Q' X# V          {
4 l, J" i7 I& _4 g. x* M# c% j4 w            "keys": [$ {4 W8 u+ ~) Z, _# Z
              {
4 P! c5 e- M3 @$ S6 M! y                "derivation_path": [. T) F% o# O* c, m
                  "010100000000000000",
" x9 D0 a5 r' k" }                  "0800000000000000"
  @  C- B- {( A; w                ],0 Q' {9 h0 X( \7 F6 \0 X: h! D
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8": C9 \. ]+ j, F7 {" Z* F
              }& T5 b3 j+ p' a  @5 T% L# t* K  j- Q
            ],
  I- g; ]6 Y! v7 t            "quorum": 1,
( ]' }; [8 M  N            "signatures": [
2 a2 W3 z! S- B/ E8 ^, T' X* R% _              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"
9 o' L' v2 b( u            ],
# F) i3 M4 X' P9 y* W+ H            "type": "raw_tx_signature"
) q0 H) @0 p4 h5 E" G% E          },
( ]4 N8 J4 F7 Q- E          {2 [/ v: I9 R0 ]- v
            "type": "data",4 m7 X* Y8 {" v/ u' o
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"2 B5 Y1 P, C- f. P4 @
          }
6 Q3 \" \' [& M" G4 Y* @; I; A        ]& ~* o: C+ N$ S% s; p* S
      }" B: |' D; L3 g4 f' K4 b
    ]' S: Q  G$ k% i  F" ]3 ^
  }  \: t4 Y6 T% ~8 @& h; ]! Y, x. J: j
}
* f8 |) }. y  T对应响应对象的源代码如下:( t- M9 l1 K9 M; l$ M7 d# ~3 d
type signResp struct {
* R1 I2 d  m% G& R" H3 m( E        Tx           *txbuilder.Template `json:"transaction"`
' ~5 b& p7 h+ q8 W+ f: U2 E: o, e; G        SignComplete bool                `json:"sign_complete"`
3 o/ W! O/ |# s, s% N# ?+ D8 C6 q}
2 P  E' ?  b& X% I/ N结构字段说明如下:
& h% _9 y- Q) B2 w" MTx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息# f  N$ U$ T# o# N
SignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易
* s! x% U' }2 _- o  V
5 V3 Y* x8 Q: c3、提交交易
) v" v7 Z  Z& U9 N. N9 TAPI接口 submit-transaction,代码api/transact.go#L135
' i% v! I" S& T; l2 q8 J7 V提交交易的输入请求json格式如下:
, \! _) J& p' s0 k{, H' U8 ^7 T3 t1 h3 Z1 e& Z
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
) z, _; H- K/ J6 a2 V9 d+ d}+ u3 s$ H" `: S7 o7 W" J6 R9 s
对应源代码的请求对象如下:
$ X0 q1 K9 w; T  p# E/ b/ s4 ~type SubmitRequest struct {    //function submit request
' t: t! N6 O8 b- @  |        Tx types.Tx `json:"raw_transaction"`
- D  J  ^& _$ M7 _9 w( N# j}8 ?: T" H& \4 {+ A
结构字段说明如下:
4 K! f1 B" F" I: b7 D) LTx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。
; n% R  Y: \9 x/ m& k1 x
4 g( r# y6 x' n. m3 W6 s& ?5 Zsubmit-transaction请求成功之后返回的json结果如下:; J* }5 D+ z0 N- f# R
{
% d$ r+ S/ _3 m! D3 A5 n* N1 H6 F6 n  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"
2 f, U8 B: R# R8 M" [}
  M- V: r) M( f) U4 [" c对应源代码的响应对象如下:
+ d  H/ L7 [# T9 N4 X2 R1 g" d% `type submitTxResp struct {, h6 c8 w/ @! j* z" \8 a: K
        TxID *bc.Hash `json:"tx_id"`
6 }+ D& G& [% Z5 D2 b}
$ l+ B$ V, `" j9 l结构字段说明如下:
* z. m" L3 y9 I2 Y7 _/ v" I2 STxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败0 f0 o/ s; d! g' }8 z0 o

* i5 O1 ?0 h( a* I  `* s
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14