Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
116 0 0
比原项目仓库:. M+ S/ ^0 G( a2 i1 _9 J
Github地址:https://github.com/Bytom/bytom, N8 a  d$ l. H
Gitee地址:https://gitee.com/BytomBlockchain/bytom+ ~( I  J8 N0 T  M8 K  n! n
该部分主要针对用户使用bytom自带的账户模式发送交易
; o$ b" Y4 m( H3 @3 J: P4 e9 [1、构建交易) F' Y/ S, ]# {$ f
API接口 build-transaction,代码api/transact.go#L1208 A9 Y7 l4 \8 q) Y( K; f- {
以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:9 H) G! g4 M0 ^1 Q9 m( D6 [; E
{  A$ C" e/ C8 I  K! H
  "base_transaction": null,3 [2 U5 N& ?5 e
  "actions": [
) Q' u' u) S- |! ^    {, C. j" s* d: d8 t
      "account_id": "0ER7MEFGG0A02",
$ @9 j- E* [# V1 I& X      "amount": 20000000,
8 E0 u* G5 V& E9 w* T( u8 w* ^      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",. M! Y  i- S  K2 a  e( q
      "type": "spend_account"2 N! P$ C: c. _9 J2 m' P. g& ^
    },
0 x$ n: B1 j, }* [    {) p2 {0 n; G# ^- M1 T0 s* \" [
      "account_id": "0ER7MEFGG0A02",1 d$ b0 v/ r4 j- P
      "amount": 99,
5 S$ [5 O0 H- V) [" M0 q' S      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
5 k& V) W3 u, C5 p' t& F      "type": "spend_account"0 I/ `& t; v1 ^7 B8 _
    },' ?. i7 P& v% i  _3 P/ ]8 N
    {
! e! S  e' K+ v/ Z, L/ E; u' \      "amount": 99,
* o0 r$ d1 r; k6 Z      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",1 G, Z. @. t) l' S; u
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
2 J7 i* ^9 q0 j      "type": "control_address"+ |! Z' s, n1 P+ j' y8 _
    }( j: ]7 b7 R: v3 _( G+ x" a
  ],
3 X: B. k  u" b  S( i) ~2 [  "ttl": 0,4 F. G, b" l- m9 r: X$ @
  "time_range": 00 a2 s# m# i3 T( v
}0 V. V2 H) M) V( ?  r  p1 E
对应源代码的请求对象如下:
* i, o, y( O) ^$ w  v4 Y  H7 H: |// BuildRequest is main struct when building transactions
# r7 g$ X" p' s  F# `- P0 S" U2 _type BuildRequest struct {
$ A" h1 H7 q! Q6 H2 T        Tx        *types.TxData            `json:"base_transaction"`9 r8 g$ w! d, Q1 U# R% [
        Actions   []map[string]interface{} `json:"actions"`4 ~" T% N* [1 y% N' N3 O
        TTL       json.Duration            `json:"ttl"`3 N; c5 b9 ?9 m7 E( x' K' v4 X7 q! }% C
        TimeRange uint64                   `json:"time_range"`
# b/ C9 S; J8 m  b3 l* i}- [0 y  o0 t; `; o* S
结构字段说明如下:
; z& L! q& D" l/ t+ pTx 交易的TxData部分,该字段为预留字段,为空即可
6 G" ^/ k9 Y- ^2 GTTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟
# I" P" k( N) {% F' iTimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
* o6 Z) @4 ~# [Actions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:# U; e' W- z4 S, u4 X3 T
input action 类型:
+ ?3 [8 `0 l2 }' \issue 发行资产& [6 c  P; V' z9 h7 b5 @& Q
spend_account 以账户的模式花费utxo* p( f0 J. V& A/ B
spend_account_unspent_output 直接花费指定的utxo5 K8 @3 [& N6 {) X4 |. d8 j8 ]
output action 类型:
& S* k$ x/ S, Y, Q( |. Jcontrol_address 接收方式为地址模式# P; T! V) d. D- o
control_program 接收方式为(program)合约模式( n0 U4 O. B5 @8 w
retire 销毁资产/ J" }4 Q' B  d+ @9 [* h

7 X3 {1 Y: Y6 ?! q$ g9 s- S' o+ u1 L' ^1 W+ b# s% C

( t$ Q4 N8 s; `: \8 L/ B$ w注意事项:5 T" E* K* \/ V* \# x  ^8 n
一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。3 K7 K+ k& u& j3 ~; Q$ x& W
除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。
1 q& V+ ^) ~8 Z/ u' p, g交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量
6 B0 v4 y  v. K8 E8 ]交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu3 v6 c! e1 ]/ R2 O
: |  y/ h5 H! `5 I
action简介# r" u8 G0 W* m( r; E
下面对构建交易时用到的各种action类型进行详细说明:
0 p8 v  o, q* ]issue1 U" p8 M! M' D! y" E2 x' Y
issueAction结构体源代码如下:
) N; h& c; Y% P7 v& ktype issueAction struct {) w4 O/ l# M2 h1 I
        assets *Registry
  K, Y. ?3 O/ N8 G" S7 V        bc.AssetAmount4 i* ]6 D" q! z: p1 f# k9 z3 y
}& k$ Q$ m, E9 {  w7 z& R
type AssetAmount struct {
; B7 g; y$ ?3 z& N        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`$ {0 o$ a9 ?" N9 M' U
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`7 N) q3 L0 x& Q% C2 ~
}+ G% v; O8 f' d) `) y
结构字段说明如下:
! ~. E7 f, l- p9 M! q  eassets 主要用于资产的管理,无需用户设置参数
( \7 F2 ]# e4 p/ ]AssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID! r& a/ u# r% s2 _6 w% s

1 v9 e. [4 R( O; x- i% FissueAction的json格式为:% `3 d1 B; v. S1 r9 l6 y% ?
{5 T- w9 J7 i% _7 {" o; g( x, x/ h( r
  "amount": 100000000,. G* d; A0 K. O
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",* m6 [7 f( ^/ r7 V) S# h; a' ]
  "type": "issue"
% l+ h* w9 V! ]7 @3 ]}8 n2 j& k* Y4 b" [6 t0 L
例如发行一笔资产的交易示例如下:; Z$ |  h+ Y+ Q* w" Q" j
(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)
, v' ], k# t8 \1 z4 l{; d7 ^6 _# b# h1 m
  "base_transaction": null,
* Y8 R* W5 f" C9 i- @0 l' @0 f% N) @  "actions": [
/ k9 t8 H1 l3 @; Y    {
! S* \" v) l4 a. }      "account_id": "0ER7MEFGG0A02",( i3 {) u: d2 `$ ^  l+ y4 D
      "amount": 20000000,
: A. |% ^# \. ~3 C6 k. N+ x      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",# P, L3 Y+ J$ D
      "type": "spend_account"6 w5 J1 \$ d: A3 Y+ A- t' d$ M& d  u% U
    },
- n% [0 Q7 w, f4 V0 ^0 b    {9 T$ ~' D" L+ P  k
      "amount": 900000000,4 _3 o. Q, D+ v& R0 X8 A
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
, M9 {& X# r9 X8 g1 n6 ^" }/ M      "type": "issue"3 ^  B% j& F/ B, Q- n, Z
    },
( H+ z3 y/ }& Y* Z( N7 |    {2 U$ w! D$ A& N* J
      "amount": 900000000,3 t) B- {4 i( b& o
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
0 ?5 v+ c1 M" m+ M! j: P      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",3 B: E% I; G# i+ h, y
      "type": "control_address"
9 I& w6 c: z4 y( |    }' Z4 ^5 [! G  V- A" G0 ?' S
  ],. f) I9 K7 y, c" G- C9 o0 ]% E
  "ttl": 0,
$ ^: e# E& D6 T  "time_range": 0' n, H+ P. u2 ~
}* Y* ^' S  N" j  X/ O/ t

  R  S5 A; X5 ~! S5 U( ]2 Fspend_account& s, R4 w- f; O+ ^
spendAction结构体源代码如下:
5 y+ V2 d- D1 _9 F! ]1 y* ]( Z& ?type spendAction struct {1 g$ W. A! R- r8 e! p( `
        accounts *Manager
' d8 {$ |6 q( Q: @$ n( r        bc.AssetAmount+ @9 O( s+ p& g' i5 U1 C
        AccountID   string  `json:"account_id"`
6 p6 q; f" u* D        ClientToken *string `json:"client_token"`( o8 L  g0 ~4 ]; I+ n) o4 V" X! k
}- B$ S9 J( N1 f% E+ N
type AssetAmount struct {6 G$ h8 h& T' b0 t+ H  X5 b! \7 H
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
( b4 s7 W1 Q4 l% U! s        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
/ {- Z5 `3 F3 o}
1 T4 p$ I1 P" @  s8 z结构字段说明如下:  A& g$ ~  ^2 _) f3 k, \
accounts 主要用于账户的管理,无需用户设置参数
0 w" Q4 S. f- Z1 E/ U# H2 x# b# F) EAccountID 表示需要花费资产的账户ID
' d6 a, x/ h) V$ U+ @( n( O4 {AssetAmount 表示花费的资产ID和对应的资产数目
0 ?6 d8 n% `/ |% ^. n% DClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
+ y2 [1 b' s# U% G; u: b# w/ [# N. P3 w# y5 G& Q$ O: y
spendAction的json格式为:
7 G& E' `) \" r5 V/ W  i/ N{
$ `: q3 @2 H7 ~3 @1 p  "account_id": "0BF63M2U00A04",
" W5 m1 ~# M. R: F8 n9 r& A. g4 Q  "amount": 2000000000,# \6 ~  e$ t& P6 r
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",3 ^6 r+ R2 w( Q  J2 K( K
  "type": "spend_account"- h0 x& O) X" V" ?5 I
}2 M  j5 u) \. n$ ^% \5 G6 P4 z4 Q9 P0 c
例如转账一笔资产的交易示例如下:
6 t9 h4 w: s6 T% Z2 c. F: i(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)- G% T6 P; `. C' x! @8 L
{
) _  e. x* z" I; z& U* B5 W  "base_transaction": null,
! W, O. }( B' Z  "actions": [
  n+ g! z8 ^: ]1 g8 A$ V$ `. r    {* B7 d8 r" _2 g; F
      "account_id": "0ER7MEFGG0A02",( J7 a' B" Z# U6 Q5 o
      "amount": 120000000," s( Y: R2 Z: J+ [$ {- c; w: y0 s, {8 C
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",- s! ?0 N1 }) D7 B- c& y
      "type": "spend_account"
; i$ z! s, ]& Z* n; i. N9 j' l% p    },; L( b7 f8 H! A' d8 i: p
    {
% x' \* _+ h; e0 I      "amount": 100000000,
+ i6 F+ {1 Q0 ^/ ~9 |! P$ |      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",! }9 w6 C' _9 ^. W# [- B
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",, `* F( o( k* P1 l& y
      "type": "control_address"8 w/ I% a. V, X. b9 o
    }
- U# H1 L7 u' a) `/ a2 ]# D! ^  ],
4 I8 X: m2 j+ @1 y) a9 }  "ttl": 0,( }4 G( j" m3 z8 {, m: t/ U/ Y
  "time_range": 0
$ H( K+ K5 v5 r0 l6 r5 F2 v}+ b3 I6 l1 P  n
5 |! e( \/ \( s! N. N; Z" H
spend_account_unspent_output
1 N2 a9 e& I$ IspendUTXOAction结构体源代码如下:+ O3 j# p9 G0 t/ x& J  {1 G  S
type spendUTXOAction struct {
, v7 `# D7 ?" y6 x: b+ q% b$ t, V        accounts *Manager
$ k" A9 f& i  S( ^% k6 A        OutputID *bc.Hash `json:"output_id"`
# ]; U! r( p% Y2 `" r: Y        ClientToken *string `json:"client_token"`
, P: F1 e5 a' J- h1 J! v! d6 H8 A}' ?: x5 m' N3 j- s6 R! ~
结构字段说明如下:7 F# n: y" K8 [( }& H% Z: X2 X
accounts 主要用于账户的管理,无需用户设置参数% R4 h. h; Q5 e! x! a
OutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段
2 @1 a- w0 u; d6 x# H; O! g& }ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
! j8 V8 T/ h4 S6 f0 {. o" {& t/ J! N7 f5 r# \9 S: A
spendUTXOAction的json格式为:1 }/ t1 O6 }8 {4 w5 z1 P
{
5 m1 o8 ^# \2 X; C$ a  "type": "spend_account_unspent_output",$ v; c  _% K4 M$ y
  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"% Y: L. K1 Z; Y
}
( Y; K( W0 P3 E+ C- h7 |例如通过花费UTXO的方式转账一笔资产的交易示例如下:  V8 g8 P# S! C- b5 L$ a' }
(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
; B) u" K# }' V) f{6 A' I% s5 g8 w( v' H0 _6 H. g( l
  "base_transaction": null,
( T6 {' h4 P/ ~/ L3 h; I7 Z  "actions": [/ D% d- T* f9 W; Y( U* W
    {1 l3 |% R  S! E7 }; K; K
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"," j( h8 q' S! [2 b4 d
      "type": "spend_account_unspent_output"
6 L: i0 T; w% @0 E" d: M9 a    },
4 v& j$ U9 @/ V/ s$ i9 G+ a) L    {" I* S& c/ Q- s, M7 @
      "amount": 100000000,
% y% n5 ?7 b8 V$ \2 a  s# V% Q      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",& i. Q4 C- m" F; l
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
, H% P. P3 A. s# U7 u% X) Z+ f      "type": "control_address": [. M: S9 i3 o. @
    }
" f, L$ B+ T/ A- D  ],
& C' c" Y& D; W$ k, p# k  "ttl": 0,1 H* Y8 C' r/ \6 @, D. z
  "time_range": 0
6 f0 f  x- X$ I}
# t. P$ G7 u( N* q8 U
9 |+ Z8 J8 e2 T* kcontrol_address
* Q1 t2 W6 t( _0 e. {7 |9 zcontrolAddressAction结构体源代码如下:
  k! [9 W& K- S6 P$ ]type controlAddressAction struct {4 ?' p0 K  w# y3 H, D
        bc.AssetAmount
. }  l. `7 B; U        Address string `json:"address"`9 a5 A) L. x; s8 S4 n) C5 x
}
6 B& R8 r( f/ H$ t# z8 @2 Ptype AssetAmount struct {
' C5 o# Y" R3 Z2 K# [        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`- G; _" d, F) I# a( W
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
; \8 x7 Z& ^  y5 \}
/ }4 e1 A7 _3 o9 F) r结构字段说明如下:
: l, u5 w% W$ w  E- c& y0 @" @Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址
% o& l% v$ f* ^AssetAmount 表示接收的资产ID和对应的资产数目% g8 L+ s% I% }& ^* J: X/ S

  a) `! a7 e" ?0 T- B- ncontrolAddressAction的json格式为:
7 F- j- J- I; b5 O3 M{
( |. j9 e! X! F2 ^( A* R  "amount": 100000000,( R; V+ z+ |( ?
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",3 [/ P( N4 f& k
  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",* S, |$ O( |% s: L1 A7 d8 P
  "type": "control_address"5 q2 z9 J* O' v: m
}
% V% {" \8 E2 @4 s( S例如转账一笔资产的交易示例如下:
. D9 L. t) Y1 S; M! b" }(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)3 z* ~- G( w$ H' ?* f2 u' T6 D3 b( g
{9 T- }" Q: e% H- J
  "base_transaction": null,( y" `' n- }7 w  J2 T- d8 w
  "actions": [: N. u# H* a# N: i5 g" y4 R8 l
    {
0 X9 Z8 C% F2 N2 W& ^      "account_id": "0ER7MEFGG0A02",  c' E! M' b! C2 P- d$ y
      "amount": 120000000," v: O5 ]- k- W
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
5 g/ X( x+ J% W$ ?9 W; P      "type": "spend_account"4 r9 k) U0 N: ^" `
    },$ f2 W( E- l$ h( V3 Q8 U
    {
9 w' m( @# Y( E8 c  C2 f6 z9 v      "amount": 100000000,5 F) W' p* N; A  n' O9 |
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
4 Y: T# g! T% a& b5 A# |6 Q      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
* a0 D9 Y; f- H      "type": "control_address"
$ ~$ m) _9 d/ ~9 }# J    }# @. O/ l( m4 F& A3 g
  ],. f0 D( q. R' W! _
  "ttl": 0,
! X# }1 F* O/ t9 r" C$ |( D2 r- ?# z& D  "time_range": 02 y3 U; Q  c! Y0 s3 Z
}2 s) U- Q0 J/ n
! }4 T. m5 ]. Q9 l7 }) P) V/ f
control_program: G7 A# A1 b3 f' m
controlProgramAction结构体源代码如下:
! G0 S9 G8 k. v+ B, ]5 i$ b) Vtype controlProgramAction struct {
0 [8 z) R4 K; n, w5 y: A4 {        bc.AssetAmount6 H9 n9 O9 \. A" |9 ?7 ^
        Program json.HexBytes `json:"control_program"`
1 i5 u/ g8 v2 X4 N: T3 o' t}( w" t7 ]; r  D# c( R
type AssetAmount struct {
5 D% n+ ]. l  |: e8 z        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
2 \/ B" k! V' c/ e: x        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`& A7 g! s' ?) \4 c* D4 O  o) p
}
( o/ N; |7 L1 w结构字段说明如下:6 W. u' I: I$ f' }3 v% D+ u7 P
Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)5 V' o1 @: a' u3 M8 k1 V
AssetAmount 表示接收的资产ID和对应的资产数目* M, V9 |/ s6 H- g

- E1 n4 J; `5 G, LcontrolProgramAction的json格式为:& z$ c( P- r+ ?' t& t
{* B! `, m" z/ P; s+ r5 Z
  "amount": 100000000,( o% b* [. q2 k: @2 x
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
/ F5 L# u' c: F8 s. O' A7 a& N  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
. e, ~6 Y8 C. X  "type": "control_program"! ~8 I7 S5 j+ C6 |* X
}
+ ~2 Q  S$ K% G/ J例如转账一笔资产的交易示例如下:$ v7 w. S4 V2 d# H6 a
(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)
9 c* S0 U1 o& W! f! w4 o. V0 d{: Z6 o8 g9 r$ @  h, j
  "base_transaction": null,
# M( H0 M" N0 g( t- n' u8 P  c9 M  "actions": [
) U6 ^1 a' W6 v4 t6 x1 y" R1 H    {
5 R5 F) [$ Q* f; `; F4 w) [0 M+ r- T      "account_id": "0ER7MEFGG0A02",
* ~) B; `  R8 F1 G4 `' x- I' D      "amount": 120000000,4 C+ Q; W# H) }7 q
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" W. X0 H/ a% _& P: f8 K5 x' |% K: ~      "type": "spend_account"
0 T  X% O0 h  S5 U% v0 J+ F+ s    },$ i9 H6 K: P- q8 S& ^
    {
1 q" F/ C; {8 B* _      "amount": 100000000,
/ y  B. R& b4 G& V% Q" P! R      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",7 L# N& G; F- o( Z9 @/ r# b( z
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",2 V/ R* a) \; Y. }
      "type": "control_program"' b& _! C3 r3 y1 M- l$ t' {
    }6 Z3 u0 x& Q/ q" k
  ],
1 y% I) m3 b; h: e0 `  "ttl": 0,7 j# J) G4 d0 m: F& K7 @7 v
  "time_range": 0( Y+ B+ m7 }! ^3 N; Z
}
$ i# [0 O  L5 \% |; F2 ^) J/ g; t& p# ^
retire4 l  N( U. N! T) E' d7 }. X3 S1 I
retireAction结构体源代码如下:
: r& [+ w% B8 u# Gtype retireAction struct {% m) N6 t4 U  R* @  g
        bc.AssetAmount1 H' p# |0 y" p* [, U" k
}1 R0 o1 K/ T8 x, u9 o' e
type AssetAmount struct {4 I2 ]' o& H4 _. |- P
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
4 ~, A) u8 K7 Q6 Q4 V5 ?' v7 v        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
6 L" Z7 I" G2 Y3 u! v$ w}
3 |* M# Z# v( Q7 x+ c: t& @1 m7 g结构字段说明如下:
) I, I, X0 R0 k3 G5 HAssetAmount 表示销毁的资产ID和对应的资产数目
, s- {. k2 \1 r3 ]1 W3 t( T% X3 j) z% S  s" m6 Y) ?  d: p
retireAction的json格式为:: P/ b, N. t/ m; C
{2 b$ w2 a2 W8 w: @) E9 P  _+ E
  "amount": 900000000,
- u; k/ w6 `2 ?" Z1 h, J' @) a( u4 \  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
8 U8 A8 \; m* Z0 O  "type": "retire"
& j  \7 y: ?2 Z& w" t}
0 q! V0 x+ f) u1 F* X例如销毁一笔资产的交易示例如下:
% o  q0 m6 f/ N$ [/ Z8 D(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)
4 Y* i2 L6 U' A- H& U; X, U6 k{
  Y  Z7 b6 z* x2 N, |; e3 y0 k* ]  "base_transaction": null,- n, D! R& Q4 D( S
  "actions": [  Y# n6 y- a! `+ P- t
    {
; S: z5 J" q: P0 @. B. y      "account_id": "0ER7MEFGG0A02",
3 K; K: c: O% A) B) \, K, q      "amount": 120000000,2 E* Q. d+ o* ]1 B  |
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",7 f) r* Q+ n8 h5 c+ A; `# F
      "type": "spend_account"0 [( a/ O( [% ^& A" X% A, l! R7 L$ |
    },
! T, N0 a6 x9 k* r+ G8 O4 l    {) h% q7 W- n. u0 c; ~: L: `0 r
      "amount": 100000000,
1 e7 Y6 k$ t( |$ [( W! S      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9 m( [9 x7 K  \      "type": "retire"
  D, c8 N+ U1 T+ N: a    }
2 ?; b! s* t/ N9 M8 i4 O  q  ],  ?- j3 D6 S! M# P' j1 U1 O0 M
  "ttl": 0,: p. e: E- i9 ]( R
  "time_range": 00 C5 M8 k" U# r3 x% q+ e
}
5 l, r! x# @6 u6 O0 Z- G  i: ]! _; ?; K! Q$ a# V6 _. F
build-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:& }; B$ D" y, J7 ^( H* {
{8 h* {! p( j+ K: o+ b
  "allow_additional_actions": false,' ?9 p4 W9 e6 }8 j1 C9 M
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",9 _: y  [& ?* j0 q9 e5 t
  "signing_instructions": [
: T0 M8 y3 s7 `' D5 s    {
9 P' N9 H1 s2 _- F7 ^2 W6 V      "position": 0,3 v& @) t% \1 o; U4 Q) i9 Q
      "witness_components": [
* i2 x& H; v* j5 M* P! r0 c. K        {- B( \* [' \7 {( }- O  m
          "keys": [( ]+ E" _! E/ o2 F8 t
            {
+ p3 N' z/ I! F( v; m              "derivation_path": [" f0 p* @( W# S6 M  w- W9 v
                "010100000000000000",# D4 z0 x* k- k7 M3 d+ `
                "0100000000000000"
) P+ f+ W' a6 W2 I0 G. f( T7 G              ],
+ A! E# `$ d3 H0 L8 u1 d1 A              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
; R3 j- G5 U) _' S, f* F0 {4 W            }
- t$ V3 @# C" u3 g( P          ],
$ s8 s7 `* ], |. U0 q- |) U          "quorum": 1,- K$ `4 d3 v5 L' U
          "signatures": null,
3 ^% u% Z: f/ C. C6 W, m& K1 i+ p9 L: [          "type": "raw_tx_signature"
6 O- L7 t9 \- s6 P' p- J        },, j4 X6 l7 t- q) |9 K
        {
2 R& y3 x5 U# f' \4 |/ k; A          "type": "data",4 n: H# g9 @6 z0 l: p
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
" T7 Y6 Z+ X. R, j        }
" f* V5 O6 e% o# [  H, I( s! o      ]1 B4 \5 I( m7 o9 \1 n
    },# k. W' f) u' F
    {1 T$ w4 U' O+ b2 G" `# J7 \6 M
      "position": 1,
! Y& `$ ^: B, J+ Y2 R      "witness_components": [
9 n, C+ w! F" Z# L0 R, I        {" c5 L# y" w% C* R& f4 \
          "keys": [9 c0 m  [6 _. t5 M: s
            {. }" |5 V) [$ w# S  ~! L/ J( v/ q' ~
              "derivation_path": [
5 O* o: c; H8 B: ^# {                "010100000000000000",- M/ H4 ]6 {8 k5 _' h3 }. }* r3 X3 A
                "0800000000000000"
/ H$ |! S& H( S              ],
4 i& ^* [2 g0 K/ F              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
# }# S! I) s" C6 k0 M7 M6 i            }
+ M. x* @/ ^7 x% Y5 ^0 @  L$ O* u          ],. u4 Z+ l" O& \4 v
          "quorum": 1,
' x. h$ O0 I. U, p5 f' g          "signatures": null,! H. Z0 M. ^$ J2 n
          "type": "raw_tx_signature"
! C; g8 w; q5 D: j        },
% z! e4 G) f! `) O# ?6 q( l- m3 ~        {  i, k7 k: m: Q; O- \
          "type": "data"," g9 m7 x# u$ A3 @, Z
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
, N6 ~$ _+ h5 g9 a5 ?1 W$ W7 U        }
' R' f( [: U( o, \9 o9 Z: m      ]* a" C: f/ a& z' T( G0 r7 j
    }
# Q; T" U- ^& H  ]2 p6 H: ^) Q- T8 Z
}5 S! F6 v5 y3 v3 B* h1 X
对应响应对象的源代码如下:
, H7 C( W: }( Q// Template represents a partially- or fully-signed transaction.; L  |6 [- D) Y( l5 k
type Template struct {
2 @# a/ g2 [, O8 C( X3 c        Transaction         *types.Tx             `json:"raw_transaction"`% N! h6 {+ v# }- H" F
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`! O7 C/ r2 \  z$ k+ N$ m4 q: Z6 |
        // AllowAdditional affects whether Sign commits to the tx sighash or5 J' P/ P7 m" O) j! I
        // to individual details of the tx so far. When true, signatures
. Z5 u; k+ W& ]- {3 ~( b* {) I6 ~        // commit to tx details, and new details may be added but existing7 Y/ @- L' O: Y: P0 J- K! H. Y, `6 F
        // ones cannot be changed. When false, signatures commit to the tx
1 H4 Z1 k# v4 M2 K- Y+ t. z% h5 V        // as a whole, and any change to the tx invalidates the signature.; n- M: m0 @9 a( H% x* s
        AllowAdditional bool `json:"allow_additional_actions"`
5 B# r1 s( p. S. w& s( f" A}) \- B7 _8 {8 A! r$ B
结构字段说明如下:
6 u! S; y% A* D4 j- V$ [Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:
% T' P: Z7 a1 r# @. ^TxData 表示给用户展示的交易数据部分,该部分对用户可见5 Q" r2 C- h; U  [9 ~
Version 交易版本  ~- N4 b. N1 w0 w
SerializedSize 交易序列化之后的size
  i5 e& |( O, `- l; B% ~. JTimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)/ e# ^2 E, S" Q2 J' p
Inputs 交易输入, ?+ F8 h8 W: k" I; U- g5 E( K
Outputs 交易输出
! Q9 k7 J2 }4 ~0 V8 i0 j' a/ }bc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述# Y0 Z) }1 J, a# J
SigningInstructions 交易的签名信息  K& F2 K5 W; @* b
Position 对input action签名的位置
2 v& ]* R' h* p2 K1 wWitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:
8 E' \, d' _8 T0 F3 \7 }SignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名0 _& c- ^9 ~- o+ r- s
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
+ n8 ?/ [1 C* f8 ?, Wkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
# {) c$ X" V" a2 W% q8 E- d9 cquorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户# j& t8 h1 `# `; S7 _  T  k2 D
program 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
* y1 _# j- x7 J3 SRawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名
. \* q2 o0 ?. ?7 j4 o, Qsignatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
7 h+ d0 T" a0 z+ q8 B! s4 C0 t9 hkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
8 u. W. t5 S! K& q8 f& ~6 a1 P3 Xquorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户7 N" `' M1 e, O1 L7 c( v& Q! L) V( b. K
DataWitness 该类型无需签名,验证合约program的附加数据
& I, I9 n% A* }/ o: R8 n: N$ t; ]% [, W! |7 |. o
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名
1 B0 I" H- X! M5 q  ^) ]2 e1 i# m5 ^# h# L* @" H# U' a, N6 p
估算手续费# c: t+ L6 h: `1 K: y
估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:' I% a: G# _$ s6 v
  build - estimate - build - sign - submit
: L1 S& `) ]1 ^* s9 @) I估算手续费的输入请求json格式如下:
8 k$ R+ `1 b; j{, _  f" t; V9 ]5 y' D3 l
  "transaction_template": {, c9 @% u0 I- d
    "allow_additional_actions": false,
; b4 t6 g, x, X) O3 n& o    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",. n' [! Z& z" f5 d5 ?
    "signing_instructions": [7 M4 C; M' k$ z: V2 N' J/ y
      {% z: H5 K) L+ i' U1 l- c
        "position": 0,
6 i4 @6 O5 t, [/ M- t* \7 F        "witness_components": [& d! ^9 F* b& A3 y. `
          {  k4 B! l- G9 [6 d
            "keys": [+ q' U: x4 ?* k( j+ |
              {
6 }: o4 a  ~5 _# q                "derivation_path": [) V& N  Y+ m/ |4 `5 P; F7 {
                  "010100000000000000",
  \$ I3 F- z) g; }                  "0100000000000000": w) y% M7 o5 y0 g/ n) C$ N# c7 |% }
                ],' s5 _% w+ s9 `. K
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
( M5 F2 B9 Y$ B7 A, f              }" t( {! c% M2 g( q' N7 @  C4 o
            ],) [7 h8 ]4 E0 Q) ^$ d
            "quorum": 1,
. k7 v, p* ~/ l( H            "signatures": null,/ B1 l7 k; O8 }, f! |( Y
            "type": "raw_tx_signature"/ {1 j$ Y; c9 ]2 ^5 t; G
          },
, \  }- W7 O: X          {
: T/ ~1 \' a7 o- F2 r) Q5 x# G            "type": "data",
2 e/ R( ?1 _) w  b7 i0 D            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
8 ?, ^  o4 `# K7 O8 y; f2 K          }  Z: @2 S8 s1 p. K6 ~
        ]
! D% G1 a; E* t  Q6 W. }% q% [' j      },5 P) E, B3 {/ H- N1 w
      {0 h" Y8 C: j; I9 V! H( W- R+ Y
        "position": 1,* s. m' I/ s) B( ~8 ]( I% r& @
        "witness_components": [: Q! \/ B3 G2 _' Z
          {3 z$ _3 L/ T  m- f9 w/ [- M* J/ {6 D. T
            "keys": [2 ^5 P* S. U5 p- j9 E
              {
  |' s, X% P7 W9 B; e                "derivation_path": [
4 h# @: a4 R- K. r: x8 e& e                  "010100000000000000",, E: \& G% X' @- {
                  "0800000000000000"
4 v/ D/ N! B& _; C/ a& b* Y                ],# N) c, B% h5 G8 [% Q& y
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"- G7 R  w& f1 C1 b& T
              }7 g1 t) ~+ q6 u6 R; \
            ],# K3 z1 H, a9 O2 V% Q8 P' q) N
            "quorum": 1,
: H, z0 |' ^% w# x% A. i            "signatures": null,6 d) j$ R, B  w; r
            "type": "raw_tx_signature"- _, C$ |1 o! y
          },
4 O- [5 k4 v7 k3 y4 w4 Y% w" u5 ?          {
' w: I- h0 x/ \6 t+ C% H+ i            "type": "data",/ v4 L- [/ P( _% l: y& r
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
" E5 m0 z5 j1 L5 \          }
3 t; d& e7 m8 S1 T, r/ Y1 s        ], g$ E! V# i1 O4 \
      }
: P9 s3 r, s" e: j# U    ]7 I6 ]& O5 D8 Q9 S
  }/ Y, \: u' \) e2 c- I% |6 |( Y9 `) i
}+ U4 U# F! X% M0 L5 |
对应响应对象的源代码如下:# y- d/ {2 J  ]  e5 ?
type request struct{
; a- i$ _0 g0 U1 h        TxTemplate txbuilder.Template `json:"transaction_template"`
. u1 V) X* b8 C8 w}: f  ?! Q0 u0 o" I+ I3 S
// Template represents a partially- or fully-signed transaction.
- \; P$ _0 ]2 v0 i: v" J  x2 ^type Template struct {
/ }0 n4 |. E) Y% O2 X        Transaction         *types.Tx             `json:"raw_transaction"`
# \4 V1 Q) a/ x/ Q. p+ ^        SigningInstructions []*SigningInstruction `json:"signing_instructions"`6 E) S" e' i: @" ?8 k% I, |( `1 K
        // AllowAdditional affects whether Sign commits to the tx sighash or* M! g& z' w/ Q; C1 F
        // to individual details of the tx so far. When true, signatures' L* E' s  _. ^8 Y  Q$ k
        // commit to tx details, and new details may be added but existing
) ]( z4 X/ {- B9 f( J! P0 X) R. V        // ones cannot be changed. When false, signatures commit to the tx/ n% q3 x6 `% a/ q& N
        // as a whole, and any change to the tx invalidates the signature.+ ^0 p# B' S0 p" ^3 R% O2 c) b
        AllowAdditional bool `json:"allow_additional_actions"`
) |9 _: ?5 T7 ?+ i}5 @, |$ I4 d  Y9 R3 o$ r$ V
其中TxTemplate相关字段的说明见build-transaction的结果描述$ j5 l% e( t! L. ]3 p) j
调用estimate-transaction-gas接口成功之后返回的json结果如下:3 Q1 G8 J7 ~- L4 v# `9 p
{
+ F2 l( |* S5 d/ b" F5 Y; {  "total_neu": 5000000,+ m0 ^: V+ o- n6 Q5 ?' B
  "storage_neu": 3840000,; ?: G* k0 [9 v* W
  "vm_neu": 1419000) `7 V* n2 J0 C$ [" m
}! k6 Q0 W9 w& \. H: H7 I
对应响应对象的源代码如下:2 i7 v7 a& P" w; X. w: S% F' s  N
// EstimateTxGasResp estimate transaction consumed gas
; o% q5 Y" Y# B8 C- gtype EstimateTxGasResp struct {
) p0 K, N8 {3 y+ ^# ^+ q! C& B) x        TotalNeu   int64 `json:"total_neu"`
) V, p: V" Z- ?: q: H$ x* T5 B        StorageNeu int64 `json:"storage_neu"`; \& }- U1 Q: y/ T
        VMNeu      int64 `json:"vm_neu"`' `4 n* J7 q8 _, p
}
0 ?) c- b0 k/ z' K结构字段说明如下:
8 a% i8 G% k/ t2 z* z2 X! Q+ n7 C6 K# zTotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
+ d7 e4 H4 G$ i" ]% m" pStorageNeu 存储交易的手续费7 X  [7 W4 ^8 X. I: {7 e2 ?* V
VMNeu 运行虚拟机的手续费
  r& y# e' {6 K3 l7 U, ^7 d) h7 K+ M  v8 U
2、签名交易
1 N3 b/ K/ ?0 C) a: ]/ UAPI接口 sign-transaction,代码api/hsm.go#L532 l# a4 t8 i2 I4 j
签名交易的输入请求json格式如下:4 V# s* a# g5 x  Y7 @) D3 A/ m% G, b
{; `& L! ?' l+ D0 c
  "password": "123456",
9 {! ~4 i1 t6 n8 L9 h' G  "transaction": {
# U/ A& I* c$ t6 H3 V& A    "allow_additional_actions": false,
+ h4 H& P' n& J$ j" ?    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",8 P4 h7 e' d: G# \: ~
    "signing_instructions": [
3 b2 l# K0 Z2 [      {
6 K* p+ g5 u: Y3 R. t        "position": 0,6 M. l! |* @" q8 d& F
        "witness_components": [
  Y9 |' K8 |/ d+ t" [6 \  R          {
/ o5 H; q9 R" o% X            "keys": [2 I8 U) Q7 d% `6 O* `3 r
              {
2 V$ D2 [0 m/ d6 w* U# _                "derivation_path": [
5 {) V5 x9 s: n                  "010100000000000000",
7 f7 P$ }  |( P# t# E$ B                  "0100000000000000"% Q, D9 }! _& _, r. \4 K5 c
                ],
6 l, P$ K0 W: G+ N                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"# F  s; A3 i1 W& L" V/ E
              }
8 {; z: q( \* q) l4 W            ],. V- @8 E0 g: r7 d
            "quorum": 1,
- E8 y7 V1 A0 K; c' L0 n+ e' E/ ^3 F# J            "signatures": null,' P4 F! A; N$ R5 M" f
            "type": "raw_tx_signature"
# h6 Z& d7 B, i' |0 B/ T9 u. L          },  X( ~6 A9 p. X. a) ~/ K
          {5 j' n% T- s# F  n  {% p
            "type": "data",8 M( S* K; U# p
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"4 r/ U) B; p' s7 X! Y
          }; O# L" q& D; r4 E, r- c+ k% r( g
        ]( h7 ]# v" m! g! g
      },! `' n* m3 z/ f/ n& ]# m4 M- b
      {* [+ R) a1 ^3 w; Q1 V" m; Z
        "position": 1,  [0 r: h# Z2 C. w' Z& s% c
        "witness_components": [
$ v$ X' M, K9 Y! K          {/ z1 `9 O3 C! M" z$ i: K9 {
            "keys": [# d8 C9 F1 U. o0 G7 K! s* o' w
              {
; K& ]6 w+ d/ W; C1 t5 J                "derivation_path": [2 {7 D. S/ T' ~: u) q5 f- H
                  "010100000000000000",/ b( h% d) b" g3 Z
                  "0800000000000000"
  q5 y2 o$ c6 g1 Q9 |( G  r                ],
: ^/ P; Q6 o' Y' [; |, m$ I0 `                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"1 c; A7 m/ o. E, l
              }, `3 g) U0 i* L+ u! ?
            ],
, `5 i$ H0 c$ H: f5 A            "quorum": 1,+ M) v+ _% D; M- j
            "signatures": null,! l. ?0 a$ z2 X5 h* p8 V
            "type": "raw_tx_signature"
3 E1 v5 }- `$ @          },
6 ?& G' p4 Y9 ]* S5 o; e7 D          {" X0 S1 W$ T" O4 T9 C  {2 B4 v
            "type": "data",
) j! V3 r/ p1 O, b1 F1 E            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"- Q7 g; g$ H0 J
          }9 H8 j* h+ z) W- u2 c
        ]. |7 b( J. r! W) b6 ~
      }
  w" H  @: q' Y. U! |1 h0 g! [% x    ]- G. F: J7 z" J+ A( g3 D
  }
+ b. {' X' P1 B) ?- ]2 j. O}
+ C0 T( M1 _* e  |: [$ g对应请求对象的源代码如下:
$ f( n9 Q( [* V6 B# E3 btype SignRequest struct {    //function pseudohsmSignTemplates request
8 X! V* `& ^9 N) r, [0 ?        Password string             `json:"password"`0 b" w% z% B* t7 f
        Txs      txbuilder.Template `json:"transaction"`8 B  L7 b" }" t. Z9 s2 D
}2 t9 `% m, ?$ b4 {4 r
结构字段说明如下:
7 w3 x- V% I8 x/ o/ J5 JPassword 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名3 I% d. K$ T! _. @1 s. _$ i
Txs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述2 @# r# a; @# G+ N, W. ?5 ~5 a2 b

8 J* t) f* m) l* x0 S% m签名交易sign-transaction请求成功之后返回的json结果如下:
8 ]0 I5 R5 ^2 U3 E{. m, P: u( N" X: e' _$ _0 Q, ?
  "sign_complete": true,$ ]* v, P1 O  S, D) g' T* D
  "transaction": {
4 }# H2 i. s4 b4 r" z    "allow_additional_actions": false,
! m, j/ h) t$ O! a    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
0 K; n+ v: }' ]5 ]. m( T/ ]    "signing_instructions": [
4 I, w- t8 V& k# y      {
' m/ w) l. p0 c        "position": 0,
8 S, ^5 i0 u# a% J- a. T        "witness_components": [$ O, u8 D8 m/ Q# N' s
          {. q8 q% e6 x* C: q: ~! G9 r
            "keys": [8 t3 p; |3 C% b* ~; S# w: R
              {
% }, _, @$ K. v: X                "derivation_path": [% t, [1 T+ S/ G/ O
                  "010100000000000000",
( v, G0 B% R) z* x- ~                  "0100000000000000"% V* n; T' `- ~: g7 b' A6 Q
                ],  O' `* V$ r% y7 _# D
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
' g7 z& _0 s! R3 A              }
) O: Q. J& z' R: \            ],
, t( @) x& m; D# A# v            "quorum": 1,
* s: I0 Y, ]$ x5 x            "signatures": [
3 K: D  D" O% z# Z# D" _              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"
: ^: c( K1 y* b3 k+ X            ],
% d$ B: N3 x! ]( n: |) j            "type": "raw_tx_signature"
8 V5 }: ~' @! I1 A$ X  [          },
6 H* N# U# o" R7 p2 I  @% S1 X0 r          {
; l% y9 J8 A8 ~. p' l2 @            "type": "data",
* t# [: Y) F9 p8 j            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"" V, _( P. ]: a; v* N& R# {2 Y; j
          }
# r5 G/ Q8 z. p0 `$ v        ]9 X7 U. \( S8 m
      },  Q  x8 D8 X8 i- U$ l" N9 v8 O. E
      {- O& }) S# e0 J# ^9 i
        "position": 1,
* V9 q9 C) v4 `3 D9 J        "witness_components": [
: l" B6 X# J% x( n/ a          {
# N$ h! {- F8 R; k            "keys": [/ V+ J8 ~$ e# u3 ?' b! Q- {; m
              {
8 }1 M( i, z; c7 k: t: ?$ [                "derivation_path": [
# m% F& \- I0 c7 T2 }                  "010100000000000000",
$ R* _* R8 _$ U; z" d5 M) n                  "0800000000000000"- ^& \: m- c- D2 Y) F* ~
                ],
) V% {6 n4 B6 ~# \                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"; p" _3 }: q1 U  S' R- q
              }2 K5 O+ [8 c  S* @) I
            ],  A3 `% k+ _4 x+ o
            "quorum": 1,
( W/ N5 x1 K' t8 E* Y. O            "signatures": [9 E5 U" |1 _& h* e
              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"
* s- y+ B6 ]# }$ n* O            ],
8 }+ L; _0 y: ]: d            "type": "raw_tx_signature"
5 g" N0 P! W, v          },
: P4 d- l! k$ n( q          {; X' F( C- m- l$ q( G% N2 D
            "type": "data",
  Q8 C) V" H7 U. B( o6 E4 S$ Y! ^4 B            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"% y- ]1 J/ V) w/ w, O" R
          }
" \9 u. W2 c2 Y+ E/ [) W        ]
# e: k; F" X; l      }
7 N4 i* v7 X% n; E3 c    ]
! Y; t- X1 m; G* }& B# T6 q3 R  }
( Z9 F0 Y% j4 G}8 I) \/ w5 Q& @( z1 _' y0 w
对应响应对象的源代码如下:9 Q2 {% c$ d9 y" z' M8 Y
type signResp struct {
# O/ @/ I" T" \( x# {1 N        Tx           *txbuilder.Template `json:"transaction"`4 }7 R  ?: k7 t) z; q) \, @0 V2 m
        SignComplete bool                `json:"sign_complete"`5 F& O# g! R( C/ B  [  Z/ f
}$ Z, z$ Q: n5 F* [: g- N% F8 F
结构字段说明如下:
4 W  i9 x% F: i0 L: FTx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息( K/ O7 T9 Y) I2 S" a6 {
SignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易( r9 n# }2 V5 A, ?& h6 E' J

2 e: D' M  ?0 Q6 D! I2 q3、提交交易3 O3 {6 U* I2 ?( w. t
API接口 submit-transaction,代码api/transact.go#L1351 P& z3 I  z- x; h$ y' y+ f
提交交易的输入请求json格式如下:" ]! B5 ]9 L& a$ y/ ^
{
1 p& \7 T3 |! N& C; ]  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
4 C% O0 E: P' N& h}
7 o8 y& w4 |; \, E3 }5 n/ N/ E0 g对应源代码的请求对象如下:1 W- T$ p6 f' W, ~" M" i
type SubmitRequest struct {    //function submit request9 G! J. M& f7 T! u2 |5 J
        Tx types.Tx `json:"raw_transaction"`
( @" I. |" W* _# q}* m1 ]& A2 ?. V% S) Y
结构字段说明如下:8 y( a  O$ V# b- q: m4 g9 L
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。
- D! I5 A. [) M$ w0 b9 E& E- p! I* r2 \5 \, V9 J' {  H
submit-transaction请求成功之后返回的json结果如下:
! h# v  F2 H2 P& X$ f7 R5 }{' t" B/ n/ z+ j& Q  V/ g
  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"1 B. f) S+ q- y$ e
}
( q2 n+ H" w/ m+ f% Y; o/ q对应源代码的响应对象如下:
2 y3 [: U. L! X2 X- K0 Ctype submitTxResp struct {: U9 U% y, F$ p! R3 y
        TxID *bc.Hash `json:"tx_id"`
2 p, q# U) b0 r4 J  h: I}& {0 A+ _5 _+ H* ]& ?- ?
结构字段说明如下:. a3 b7 F6 ^( G5 ~8 ?
TxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败' `) A! B* |3 s: Z7 K

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

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14