Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
138 0 0
比原项目仓库:9 {! t& Y1 @# e3 I3 F
Github地址:https://github.com/Bytom/bytom1 K- S" ]8 K; J2 [0 x& h0 n: E
Gitee地址:https://gitee.com/BytomBlockchain/bytom
; S' a& j% n7 k. q7 a该部分主要针对用户使用bytom自带的账户模式发送交易3 O% z3 H! n6 X
1、构建交易
2 _8 ~; A" N/ E- \! iAPI接口 build-transaction,代码api/transact.go#L120& x) K+ |- J2 m# R9 Z. X" X
以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:7 |* w4 |$ X0 }( p# ]7 P: M6 N" v5 P
{$ I% F2 q) B3 p
  "base_transaction": null,' B3 [5 H9 Y1 z
  "actions": [5 ~5 X4 @+ T; B* ]! O7 g+ a; ^
    {
6 y! D# n* `8 `8 _3 j8 n      "account_id": "0ER7MEFGG0A02",
. ]3 V! `$ v- z4 l      "amount": 20000000,, [0 R1 E- [0 t. k1 u4 s' h/ E
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",# V4 ?  `6 N+ `* w% V. A" K
      "type": "spend_account"% ?9 j& n! s9 v9 l( D( c/ `
    },' W, D3 ~' o1 L( ?. |% i8 Y
    {+ O' ~) P' [9 W4 ~+ ~
      "account_id": "0ER7MEFGG0A02",
- R2 H# l, B5 [- h! K$ x) ~      "amount": 99,
' |3 v; u) v: {) }2 H. Y      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
' J% A3 i6 M/ c" ?) _" ^      "type": "spend_account"
  k) O' ~! {) j3 S) x6 {    },% M% v8 ]& x6 k: O
    {
: U, N0 z3 u* K2 A: i6 G      "amount": 99,! {: m6 _) O: m3 B! h5 s
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
# j9 D5 E6 s' D: w) G  I0 e2 H      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
5 ^' y3 a# ]/ p      "type": "control_address"
7 Y) Q$ ~$ X: j    }7 {8 y4 y. L' n$ b* g
  ],
4 ^+ ^0 M8 b6 Q5 B! V, ?0 M  "ttl": 0,( ^7 L5 _' l, O8 k; Y& y
  "time_range": 0) |/ ~+ ^0 y, {9 m; W! G
}* g6 r8 ]: }4 @  Y
对应源代码的请求对象如下:
7 f- I+ ]( V2 P7 i" \# ~  \// BuildRequest is main struct when building transactions1 p$ l7 r+ T0 A! j5 u
type BuildRequest struct {
+ C* D3 C/ a0 S; C% V  P        Tx        *types.TxData            `json:"base_transaction"`
6 o5 r# B. {) ]9 L1 k) o        Actions   []map[string]interface{} `json:"actions"`, K) G7 R, u. e, t# d; q
        TTL       json.Duration            `json:"ttl"`
$ B" I7 c7 {% ]2 R5 ?        TimeRange uint64                   `json:"time_range"`
) F. {  p- O3 g}8 f$ t  m) N( Q2 X; M9 U
结构字段说明如下:
+ X  P' C2 v0 m6 b; \& mTx 交易的TxData部分,该字段为预留字段,为空即可
, a- g# I  b$ W: y  x* a* eTTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟
* I' `5 O  i% y1 s" z) yTimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效0 Y; ?8 R9 n- G( _  |8 }& {( w
Actions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:: P7 n: Q2 t8 }1 \2 L
input action 类型:
9 F8 c2 E: M& W. g& c$ iissue 发行资产
  R% Q: X* D" @& Zspend_account 以账户的模式花费utxo
  f" L) D; T0 _7 |8 O0 Mspend_account_unspent_output 直接花费指定的utxo
/ B2 w, f( H( Y: }output action 类型:; ]% |, P0 n( g1 a, Y; ]! @8 C
control_address 接收方式为地址模式
# L- X7 `, T' c; C- J  kcontrol_program 接收方式为(program)合约模式
" y4 t6 y. p4 p0 b% D% |4 }- oretire 销毁资产+ {3 O# T& h& L: k$ C( }
1 i' t- s/ y; {
! N5 |$ k7 B$ z! {
/ f3 E9 l/ H$ j+ o5 r  f+ Z, Q
注意事项:, v$ p  b, o* T/ h( S3 ~
一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。2 z; _$ `! O7 V6 T+ a3 J
除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。
0 H, X9 ~! }* m! A交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量$ }3 a4 ^& B* Y7 ?4 h3 T1 U
交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu, k1 s" d0 {+ ?6 C7 y/ u2 w2 @0 @

4 b7 \/ o7 e; Q. E2 w* u1 Qaction简介/ W0 U8 h# n  h' m- e3 P% X+ p' V
下面对构建交易时用到的各种action类型进行详细说明:% L% n* b) T2 l1 G, k0 e: W# q
issue
1 e6 u2 A4 f1 m3 eissueAction结构体源代码如下:
' m: ?9 j, O" C9 G3 }type issueAction struct {9 R5 a3 F1 }: e$ R, i7 F
        assets *Registry
3 U" n" P1 y% C8 O6 `6 z# L6 B. c0 c6 {        bc.AssetAmount
) B$ x( T5 u6 }! a* R}9 ]# S" p# O1 M! `& Q/ k% o' A
type AssetAmount struct {3 E3 O& x; J# B- I, a4 z& d
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`9 v) h4 W6 j) ?2 @9 v. J1 `
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
) G8 k/ ~2 B( T: S. W}
( z' @- u, [5 Y8 E3 Y7 B结构字段说明如下:# }* v0 P# `9 U: Z3 B/ }: p" N
assets 主要用于资产的管理,无需用户设置参数
: k# w( a2 m5 i" `) @! zAssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID7 t, D+ |  T( @* G

& f8 x; \2 R5 t, N% j6 gissueAction的json格式为:
1 ~3 C- S* ^$ c& d& q  G{
: p* e+ O6 [" Q3 S  "amount": 100000000,6 i' F/ o3 n; C2 V4 k% w8 U& k
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
: F' B5 g1 _0 N! |  "type": "issue"
5 {, ]  G0 |: _% F$ Y}
0 J/ |1 p5 s/ ?! H7 t' y" G4 [例如发行一笔资产的交易示例如下:" \, K  W: a2 \# m
(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)
& M$ N' f9 [! N! d* m; u" e{
2 y. q* A8 W4 I/ ^  "base_transaction": null,
6 \0 D5 l1 }4 V* ?) ?" x  "actions": [
7 d0 `6 K" r3 L/ ?+ c    {
3 x1 O6 I( o) F8 a$ T. r9 v      "account_id": "0ER7MEFGG0A02",9 D8 m" }* ?( \6 \* R  @* R. |
      "amount": 20000000,8 y1 G0 r( _3 {% j8 u
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",3 J  M+ z. k% M. E1 B- N
      "type": "spend_account": z( U, a- `5 W! M0 w; ~
    },3 v: m# ?  M/ r+ c
    {
5 [% Y$ x$ r- I" [* X7 a& y. k      "amount": 900000000,4 C! C# U: F, M! Z6 }
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
8 ?9 p; f/ s' g& @& k      "type": "issue"( R9 y% U8 N6 q2 e; D' U
    },
, u$ B) T! U2 _. H8 ?- b2 r    {0 I; z( f! ~6 x
      "amount": 900000000,, g; j2 B. l! v% y
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
, h! N% E4 d, h      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
$ H% n( g( p" J- Y; a. _1 [2 v      "type": "control_address"0 V( i  o3 F; Y% }  E+ l& F
    }
( b! K& d8 S! E  ],
- @% t' N  T, A+ }7 t$ U+ {9 d: W  "ttl": 0,. J7 a1 Z! t& A% ]  w5 u3 s3 M1 Q' ^
  "time_range": 0
& [* M+ n* q. y; j. R}6 U4 b" B" o" F  I7 b, ^+ q9 R

* a% q1 |: V7 z3 Nspend_account
5 J, T" I. c" g! O) ~% J( g$ X7 ospendAction结构体源代码如下:
: }) e  V. K* T: H+ G$ @6 Ftype spendAction struct {
2 l6 R* _' J2 P1 Y; K        accounts *Manager9 x4 I4 I" `5 l
        bc.AssetAmount
6 L' `8 S; @6 ~$ J. J% G        AccountID   string  `json:"account_id"`
+ ~/ V3 y/ }: q        ClientToken *string `json:"client_token"`, q8 w7 F( n5 C0 y0 l7 [4 p
}
5 \& H8 ~; x$ M8 Q* Z1 v3 @. Btype AssetAmount struct {
4 ?& [- X% X  l; l        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`; k9 G' I* |8 k2 l3 t
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
" [2 O' c; P/ S; `8 f$ y}7 H: I' A! ~$ }! F' z, f- B) F
结构字段说明如下:
4 F* e, W1 x1 d* d% `accounts 主要用于账户的管理,无需用户设置参数* I8 \! D2 ^2 t0 b
AccountID 表示需要花费资产的账户ID. t! f! C; b& E. p. ^0 r
AssetAmount 表示花费的资产ID和对应的资产数目3 L+ u/ E( `* g. f( t: X
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
1 ~, }% P) [! ]. w2 J3 \1 E# d
4 i3 `  Y0 N4 ^8 g, {+ E# ospendAction的json格式为:
9 S, H  X7 w. p: M{
8 L1 ?- p/ c8 N. ^% x) t& t" q  "account_id": "0BF63M2U00A04",% z0 j/ N8 b9 Z' m5 H/ e: J
  "amount": 2000000000,
$ V3 h, z7 h5 G/ L  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",3 R7 t3 o% m9 B' k  o% N
  "type": "spend_account"
0 [5 q. v  J! W7 Z, [$ [- P2 ]}
1 d7 R2 R1 E: N+ z$ O- t+ o4 n例如转账一笔资产的交易示例如下:8 ]" Y1 i. _8 F8 O0 Z6 Q5 b
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)0 a7 q! ^; W" D
{+ Q. z' K1 W9 I3 e$ }
  "base_transaction": null,
, f) B7 F8 b6 |  "actions": [+ h6 m+ D$ G& j0 K/ l: u
    {
* C) c1 U8 w/ v9 ^$ n7 I      "account_id": "0ER7MEFGG0A02",
0 A& ], c7 z8 e) N* x, u      "amount": 120000000,
' H0 `% u" l; R. X/ |0 T9 p5 g      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
) \! c4 E* ]+ M: E      "type": "spend_account"+ X% u- B: K+ t- Z" I
    },
& M& {) T: [& R) ]    {1 j* [5 r: D* G3 H4 O
      "amount": 100000000,: N8 D) w) c$ m1 l, C) n
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
7 }1 J) \1 R+ `  I8 ^6 t+ ^      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
: S) M$ C; C- p: U# k0 B      "type": "control_address") L/ z( T* n3 m2 N( R
    }+ o8 B1 \+ X! j
  ],8 Q( ]# S1 U+ V; a' }# Y# h2 d
  "ttl": 0,3 J& I' m1 D- e# i/ _: t; y
  "time_range": 0( P1 A; e. D& }- g+ S  ]* j
}
( f, Y! u1 x$ w  M9 f1 ?
; a0 H% w( `2 G, }' s0 z, K& Qspend_account_unspent_output5 j. d( U) g1 W- s, `0 z, [7 V- L
spendUTXOAction结构体源代码如下:
/ m1 y. q+ b3 j  n" O6 Btype spendUTXOAction struct {4 J* `9 N& o' Q/ ^0 j8 f6 i% C
        accounts *Manager: ~. i7 N  H$ q2 A! i0 I
        OutputID *bc.Hash `json:"output_id"`4 c7 B; P3 ]9 y) h
        ClientToken *string `json:"client_token"`
8 I1 q2 Y: ~, Z) i  t: Q) y}2 o% m: C$ |  J, d% }9 K. m1 V
结构字段说明如下:
0 b0 N$ E6 O& K5 n1 f7 `accounts 主要用于账户的管理,无需用户设置参数2 r% B9 z7 W1 c: K& n
OutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段/ X) s' ~5 J$ \
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可1 |+ _6 c  d" \6 k9 w% |0 N( ?

% Q, R$ b  q; ?5 k6 G: P/ b/ H; aspendUTXOAction的json格式为:
% n1 T# w/ I& }: B& s9 t% j3 f- T; j{
. m- C3 x( n; f' Y  "type": "spend_account_unspent_output",5 x4 r1 V9 i3 D  b; w
  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"+ m9 q1 n1 }9 ~8 g2 U
}
- @) r  j1 Y9 Y  H8 p, x0 D例如通过花费UTXO的方式转账一笔资产的交易示例如下:
, _* L% p7 g7 D* \* v8 Q(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
: l0 `0 W2 h; i" }4 J) x{, _7 \, [- e$ M2 P4 A0 y3 N# f
  "base_transaction": null,+ V( d$ r( g* Z4 B" v: D  {
  "actions": [* f" ^# x+ L2 r: Z7 g
    {* ~1 X$ Z: j! ?$ G6 S+ g, I. a
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
2 w! U% z* M1 g+ G! E+ j5 e% P      "type": "spend_account_unspent_output"- H& B5 n0 K4 B  u; F4 N
    },! L4 k# C5 G8 k: v( k
    {
( \) j, K7 J  r8 M# ^5 r      "amount": 100000000,. V" Y; Q' H6 f2 R+ Z
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",# X  S: z# i1 d: `) l
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
, K8 h; J* w- Q0 _      "type": "control_address"; y: _; ]9 J- n2 G* ~9 G& |
    }
- [* G4 f2 g7 F' k+ ?, g  ],, ]. ]7 @# D) i* u  |) Y+ z' a
  "ttl": 0,2 j+ a" E4 Q6 O  q
  "time_range": 0
3 a: O& q/ z. H}4 N& {0 z" B3 H+ H2 ]2 G: v
  d( r6 a7 p2 e+ `$ E. a9 M* I
control_address
2 F/ Z  W1 C7 M5 h) H8 ccontrolAddressAction结构体源代码如下:
4 U1 h- ^) {5 G* n: s% stype controlAddressAction struct {
8 p) b6 ?! v8 F9 d; M        bc.AssetAmount
% i$ J3 O( y4 _$ {  Q6 h  U        Address string `json:"address"`
& ]0 a- {0 ?! H1 L: J}
1 i3 }; K" O" F" d, G2 h/ Q4 G) Ptype AssetAmount struct {( S. {) w! f1 h6 C
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
# I$ ~9 t( @! J0 ~  h        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`: a$ q! y. d- L  u. H) O
}; e2 `% `! [+ Q$ Z( j1 D
结构字段说明如下:3 K( ]/ H0 \5 ?4 H1 i
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址
" {, G# h, M  V. Y9 Y) `. VAssetAmount 表示接收的资产ID和对应的资产数目, a4 l& q+ B' C, e  H
) _5 P. k* ?' R4 S
controlAddressAction的json格式为:
0 I* Y2 D8 K! O$ g9 \2 W5 G$ Z7 w5 C{
) c$ |5 {* n# W4 O1 n) K3 c( t  "amount": 100000000,
! R- N, j, z& |( ^" }$ W4 v  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
/ Y( P7 }. |  X  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",
0 N& y" A( F# Y7 C  "type": "control_address"
2 T, \" a4 }0 N}, g+ q  e1 g# \$ Y* ?
例如转账一笔资产的交易示例如下:
% y% V6 e" [: m: G/ f7 N0 T0 G( G(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)
8 u, T- P  q4 J; ?/ ?{
9 a. x4 v3 i3 j7 i- Z8 ?  "base_transaction": null,
8 n2 ]! U$ Z1 Y9 y  "actions": [1 p# B! D; P8 H8 i8 [* Y* O
    {
9 {7 d9 g: R! v1 q  l9 B, m      "account_id": "0ER7MEFGG0A02",+ F0 p' ]& M5 P6 v$ |6 ]9 P5 s
      "amount": 120000000,% K8 u& F6 q3 l4 A2 z$ U: P# C, b
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",, t1 S! {7 N6 k- u" H
      "type": "spend_account"
* f, c. ^/ s% j' {2 Y5 Q    },' b, A: G9 r. w
    {7 h: S, _; Y; P% C/ t. ~+ I
      "amount": 100000000,7 V/ R; m1 i: X: A( h: W
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",; k' P6 U3 Z7 y, e
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
8 J$ X& h" L$ h. X, Z2 d+ x      "type": "control_address"
& ]3 Z8 s6 X! G1 i" }' D    }! m9 u8 N# X8 F5 f) S! K
  ],; o  u( h% b. B
  "ttl": 0,! W" A' n9 H! r/ k8 l) ~; H+ o; V
  "time_range": 0
' q$ e* c' j( m$ `% E2 _}3 v% U" L, i  i) a: @( X! t3 J

: {0 v0 |. T5 b$ J3 ^- g3 `8 tcontrol_program. F2 ~  L% P! M& Y) f" b8 @
controlProgramAction结构体源代码如下:
$ V. L% ^) f* F# h9 C! r( dtype controlProgramAction struct {0 c2 z9 h6 x2 M8 d2 D9 b7 Y
        bc.AssetAmount$ T% Z1 `9 }/ m. c, I2 m/ w+ B. |
        Program json.HexBytes `json:"control_program"`
' ?8 x/ M4 k% ^% ~9 X5 |}5 Y" Z' M( f7 r* s( H/ G
type AssetAmount struct {  r9 H  l" K, S8 P/ m; \
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
) |; C/ ]* O& |  b: [0 @        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
$ H/ y9 s5 O( b1 z# k; Z}; r* \2 t) r" p7 k: t
结构字段说明如下:
- P9 L0 t+ S1 F7 t6 D: X% ZProgram 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)# E! B* `- q8 E! ?
AssetAmount 表示接收的资产ID和对应的资产数目
/ l4 }# R! D5 w$ o/ A1 M7 ^. w9 q* e# j4 N% g( c- t# t. @/ y% c
controlProgramAction的json格式为:
" j8 v2 X6 h# K: [: [" }" t{6 \# m9 h& U* u! q
  "amount": 100000000,
8 I: m, Q; s3 f7 Q+ _5 C  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" Z# R# S8 O# Q! a, u3 n, ?  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
# a7 m. ~8 y+ l# E) |  y) K  "type": "control_program", n* w7 B% Q. K6 b
}- f1 D) F* _' R9 {
例如转账一笔资产的交易示例如下:
$ u/ G3 l: N9 H& m# n( r(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)0 W6 b9 D8 h7 H
{8 j5 ?5 G# i: j! @( _- M$ }
  "base_transaction": null,- j0 V/ `+ w$ l& R: B
  "actions": [
, x. \6 [; V3 E' Q: ?    {
- P0 S+ f- E) x- W0 T  R& K) S      "account_id": "0ER7MEFGG0A02",
; q8 h/ q+ e8 l- h$ D* j$ t      "amount": 120000000,2 M) t  o& \4 f3 f4 @3 E' y% }
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9 q/ R2 m8 J5 w) d  ?      "type": "spend_account"
/ `/ F  x) }( [    },7 ]9 D  z# s) g5 ]# S& r
    {# Y1 \- b, j4 R8 {
      "amount": 100000000," }, C9 ^3 g  G
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",( t8 j9 i& T. [+ L! A; o. x4 o
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
3 p3 A0 I" R. c4 v2 M7 B% p- W5 f      "type": "control_program"
- z* r. U( T2 g' T6 |    }5 u( k$ z9 I, K/ D! D# ]
  ],* S+ O: r4 c' l1 _9 K) O5 e+ c
  "ttl": 0,
3 D2 S  u0 u& Q; W5 X. }/ v  u% D  "time_range": 0( N2 R# x! e: c' d0 u, k
}
/ H' E0 J( Y, W, ~1 c. X: k. d' f" o3 \  q7 ~
retire' d2 C' Z# |; h& ~$ ?& p/ _
retireAction结构体源代码如下:
# z/ c8 N, B4 a0 H* A' u# _2 Btype retireAction struct {, F* v+ z* [# J* L
        bc.AssetAmount
+ c+ N, ~& K! o( c& |+ n. }}
! o+ i8 L' {, l* o. ?2 P4 U2 btype AssetAmount struct {
( F: ?6 j" m) o: x( [! }        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`( R" u; ]  f' L
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
1 ?, ?" A1 }9 S0 X3 x}
5 s! F. v) V% x* J& V6 e结构字段说明如下:
# }- Q/ m2 [, M, G0 bAssetAmount 表示销毁的资产ID和对应的资产数目8 _6 U. P, Y3 a' X
& k$ w/ y# d& u- o+ X3 M
retireAction的json格式为:/ w. A8 o6 O! ?5 P
{
# i+ r) h: A3 A: e. Q! ]  "amount": 900000000,
  R: R% ~0 ]% a2 _5 i' U  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",* u: N, l9 k( u& ~1 W2 o7 f  u
  "type": "retire"( c' Z* |4 g& }! e
}" m% Z7 m! t5 i. w& ?6 P8 |
例如销毁一笔资产的交易示例如下:' z% ^/ C% [% m, B3 B' V! D; E; F! B
(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)
5 Q8 R+ {) ?1 w$ f4 D{- R; D7 H! k1 e' y  }7 k# C0 k
  "base_transaction": null,
+ m; s, n" Z: M8 Z  "actions": [- N& A0 z! a! Z
    {" K$ E" |* f& Q" w: V
      "account_id": "0ER7MEFGG0A02",, ?% e6 I; l% [) @0 d2 E
      "amount": 120000000,
: D, D9 l2 V8 P- r' f3 W; ]4 \      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",0 I( H: H# v0 I  g
      "type": "spend_account"$ ?; X4 U# Q4 h5 F
    },2 n/ R& U  @) S$ f! Q
    {
' G. |5 d! c9 |+ n5 h/ b* z. q      "amount": 100000000,
* M  l; S$ O: g  g9 _      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
" b. Y) r7 l1 H# Y      "type": "retire"9 T) {5 l# E4 r8 l5 V0 C! q
    }
6 o# o0 m2 |3 h' Z) s+ d2 }+ E  ],! J1 O1 P6 F: {: j: d
  "ttl": 0,) o& t) x' V- K6 X! j( [7 j
  "time_range": 0
7 c+ V* [% t/ X}5 U: [$ ^9 \5 ?9 s1 D% O

2 s# a8 X9 ]/ @: Q1 G$ _build-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:, T' l3 i% [9 W+ a* g+ ^
{; O5 o) h( L' \9 t7 N" e& N5 q
  "allow_additional_actions": false,! ?$ r) y' |( T; k7 B+ a
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
! J% P* c9 ^5 x1 U  "signing_instructions": [& A6 \" B0 }1 Z% C, j5 Q  v, I* E/ g+ W
    {
6 p& |6 l9 O* r3 }+ u      "position": 0,
) C1 x' ?& E4 w/ f9 s* i      "witness_components": [8 b. H1 a0 T3 a7 R7 ]& @. ~
        {' K+ |( |5 t5 f
          "keys": [
) f- E( B5 M4 Q9 X+ ~            {
, s; P" z# Z6 K+ ?0 b" K              "derivation_path": [
) |6 U; M$ r+ _8 I8 @                "010100000000000000",4 g; w/ k- p, R- P+ v
                "0100000000000000"" g0 H0 e6 Q8 c; S5 _
              ],- J8 j/ o$ z7 ]# P- M& }! B
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
6 n1 N3 }2 ~$ F  i4 j6 s            }' c2 J8 c0 y4 n3 e- O3 |4 a
          ],$ Y0 ^1 h% u* Q) p# j% S! F# g9 h
          "quorum": 1,( R4 X" Q  ?9 g$ O
          "signatures": null,
  y* i" P4 k9 w* P& U- |          "type": "raw_tx_signature"
! ~& u( @% t8 e        },! o2 ?/ {1 ?5 q" A1 h7 U( o+ w
        {& Q0 f/ O' u% q3 m+ V- v
          "type": "data",; i3 q6 W& f$ ~* v6 n0 L. b
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
# k; M- A1 D! y5 R4 F        }2 P& z0 J: p1 H/ J' i5 q
      ]
, d4 o" J2 `: T3 h    },
' @" c6 A0 h1 E5 u1 i    {
$ J3 W' ]# h1 }      "position": 1,1 ~7 X, w& H2 p& F9 W9 E* Q+ z
      "witness_components": [
4 W; u1 S5 x3 d" w2 ]        {7 [7 y( p* u" n* M1 Q6 ?
          "keys": [1 ]/ s( V) u' J) C/ G2 Y8 {
            {
: L" T/ b  G% P, e$ m) {) z              "derivation_path": [+ {3 Y) |, R5 C* x1 p$ Z
                "010100000000000000",. Z) b6 h2 E8 x- L
                "0800000000000000"8 u& I( u1 V/ {1 ^# Y9 @
              ],0 V& q* v# i) p/ K% ?$ W: _, v( l
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8", T3 q% B0 L3 |
            }
/ V' D6 Y, S7 D" E          ],
  K" H8 V' w  m! r) p+ h+ _1 p8 p9 K) n          "quorum": 1,
" r+ k* u1 F- H' O          "signatures": null,
2 G, H+ V. k' b- W, \  c          "type": "raw_tx_signature"
6 m0 p& O- m( A2 u" m5 ^/ b  q        },
( d2 P8 j' `" N        {6 Q7 ]2 \5 W- R  C) x
          "type": "data",& i  I8 T( h& t/ Z3 O( q
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"; y5 ~2 H) J6 W; R* h
        }! s/ {8 u) |) n! \* i: b3 o
      ]) t  T7 [) v5 \, U
    }# g$ T3 R6 ~: I* h5 w
  ]
$ Q' r1 Y5 o" [2 D}5 v  y% W9 h3 e: V# S1 R
对应响应对象的源代码如下:
) X) L( ]+ x% s7 B6 L; U; Z0 p+ ?9 i// Template represents a partially- or fully-signed transaction.
7 S% w) T% @! R! r6 r2 N1 Ctype Template struct {
! e: x+ b" }$ P& a( I$ W        Transaction         *types.Tx             `json:"raw_transaction"`
& \% G4 E* j1 w. |# \* x' @" _        SigningInstructions []*SigningInstruction `json:"signing_instructions"`$ G' A: F7 t. ~& Z' {
        // AllowAdditional affects whether Sign commits to the tx sighash or$ \% Y6 [( Q9 s/ T
        // to individual details of the tx so far. When true, signatures0 Q9 T) m' x; I2 l1 |3 u
        // commit to tx details, and new details may be added but existing% o  U9 h2 N7 N2 N
        // ones cannot be changed. When false, signatures commit to the tx
/ N. M, E. l( N0 T. m        // as a whole, and any change to the tx invalidates the signature.  e4 ^. G% ?! h; W
        AllowAdditional bool `json:"allow_additional_actions"`
1 o& r, D% Q4 K8 c2 }; k  T}
" _0 I$ k9 ?  q结构字段说明如下:5 x4 h7 @7 G3 L4 M) l
Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:* G" N6 q  F6 k
TxData 表示给用户展示的交易数据部分,该部分对用户可见
( `( C1 \0 P$ e+ C0 T2 {Version 交易版本
+ r1 j) _' N  z* f2 mSerializedSize 交易序列化之后的size
0 S$ K0 s# t2 L, s: e7 WTimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)
+ A, E1 n' p! D% U  [9 R* {7 jInputs 交易输入
# C- M9 m% x+ y: g) JOutputs 交易输出
1 N5 |5 [" V( d8 Jbc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述
" y: c3 Q3 C3 u# W" J" J7 ASigningInstructions 交易的签名信息
, l" i; g$ G4 E* N$ jPosition 对input action签名的位置
2 m7 n5 I/ V( ^" {6 V6 t( L; DWitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:( T6 ^( `, p. s  g
SignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名* F  U# [4 Z8 @
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
6 F/ \8 T% T* O1 K# H- skeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
- v' h4 ^; [7 equorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
2 h1 w9 P4 O& I) H. m; ]7 mprogram 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
# M0 M- v9 e/ _* u2 d6 iRawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名( y3 q# K0 h/ n4 P2 M$ \
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在5 ?( }+ l, I% H  d
keys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名1 h. ^! h/ [* W$ q3 `
quorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户3 Y7 E  k) R! p; `3 j, x( Y
DataWitness 该类型无需签名,验证合约program的附加数据
; P+ X  b1 |7 l6 |
) e$ A7 P, y& ~/ C3 YAllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名
  C' K- N) b  U* g0 `% \6 D/ _5 T5 p; n% p
估算手续费& k! y! Q- X1 z- Y) {* Y
估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:
# h) j  g" v& B8 s. E1 C( ?( |3 V  build - estimate - build - sign - submit% Q* P! [% x" r( F) h, n# L
估算手续费的输入请求json格式如下:
* |* {: k0 e2 Q& a* t! h{/ w  N7 \1 L- O$ y8 O
  "transaction_template": {( R  n4 I4 K" v. a
    "allow_additional_actions": false,
0 x4 _) H" E3 q    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
) U5 m- [' {$ V3 e" K    "signing_instructions": [% s0 J6 C1 ~' v: c: L: u7 d
      {# \) W9 }" R: p- a- s
        "position": 0,- `: q) T4 b% K2 _+ p$ E( Y
        "witness_components": [0 f$ C% p  V) D! C
          {, P; V( b+ \1 e$ K" z2 I
            "keys": [
! j1 O2 ?8 ]6 _: O5 K" S              {% o1 |; Y) K+ M7 y# L
                "derivation_path": [6 g4 X2 X" _4 u. b% `$ F
                  "010100000000000000",0 ]# o% g$ _6 z
                  "0100000000000000"
- e8 Y0 x0 _0 g4 T: u  `" E, A, C                ],
7 K3 d2 A) q# [9 L                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
% n( L# s$ s4 c, k& z4 T& }8 k              }' t3 V2 T: E: g  N( F: \" J8 e- Q  W
            ],
8 I3 p( k; Y, f- k8 D            "quorum": 1,. J% Z8 A+ o; l& P, l* V! Y
            "signatures": null,) O8 i# P' z$ U
            "type": "raw_tx_signature"
. T# n7 _, F3 S7 D, s          },' n1 u) h0 S* J: ~8 k2 U8 ?
          {
+ y8 H" v1 S: Z' E1 _7 e            "type": "data",( X% E% ]# t5 g7 z. T
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"( ]! P" N$ i7 m" h, v( m
          }* b" k# R" ]0 I) g% ]% i- F  H! S6 _
        ]1 e" U5 Z5 n! U/ ?: f: E
      },
, P4 C* o+ c- @8 _; j4 e      {2 n8 l$ N% }1 _  f0 w
        "position": 1,
& h4 s4 d. ^$ d4 L7 l7 m  D        "witness_components": [) k' T! Z  f! ~
          {
8 J& V2 L7 B7 r0 g' y) _            "keys": [
' _1 M/ ?2 J3 [/ o: m  }              {
8 R1 d$ h* d- f% w, F1 ?( f                "derivation_path": [
! v) a. c  D  T                  "010100000000000000",
- z0 ~9 N0 A/ i# S! c! c                  "0800000000000000". _3 g; A% s: P2 Q4 z
                ],1 E  T5 y* Q! [& B
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
4 W' A  L* |5 C/ C: Y& r/ e              }/ j) l+ S! R# u; y2 Z
            ],! f4 y7 K! m6 Y# M' `
            "quorum": 1,# u6 K1 h8 \& Q( i' A
            "signatures": null,
; ?+ [2 E) ^7 O, v            "type": "raw_tx_signature"
8 T# |- [0 ]) N$ h# J# C          },
5 x: z. c8 U) q# X& R+ F          {( e: ?7 k) T! k' e5 |
            "type": "data",
6 m; R% ]# r# z% {            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"  G" V7 {) }: C7 i$ U
          }! n7 h8 |! S& ?- V8 o
        ]8 M7 r# ?6 {  a5 ~" ~. X( b
      }
6 T# @1 f0 M2 v& ^" |    ]( t3 w- T, A  {% f4 X! a0 _/ b
  }
3 t$ h. ^0 d; h* x1 \6 h}
* O' F- \; q# {# l- r' ~对应响应对象的源代码如下:+ A( }* L0 }6 _5 L3 ?' x9 ]9 w2 c
type request struct{# ^) K3 f! P3 @( |+ @/ @
        TxTemplate txbuilder.Template `json:"transaction_template"`% m; N- z' z7 F4 M' L3 k
}
! s# C/ ]/ D3 x) r( I// Template represents a partially- or fully-signed transaction.8 R7 A1 s$ K" ~* C; ~9 M
type Template struct {( x9 t# ~1 M, L) V8 `
        Transaction         *types.Tx             `json:"raw_transaction"`+ P1 d! D! ^# Y+ Z" U$ l! p
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
: u. G- [; q5 U3 g        // AllowAdditional affects whether Sign commits to the tx sighash or
: F! I+ J. I* Y1 T4 M4 v        // to individual details of the tx so far. When true, signatures
& {3 n: n& V# [; W        // commit to tx details, and new details may be added but existing
& f$ _, K3 F4 _: _        // ones cannot be changed. When false, signatures commit to the tx! F$ B4 V1 ^+ w: W% @. S: `
        // as a whole, and any change to the tx invalidates the signature.9 B. T$ a' J( [  O1 w
        AllowAdditional bool `json:"allow_additional_actions"`
2 Y6 R5 n) U+ n6 O. d, d}  `* R% |0 C# c) N
其中TxTemplate相关字段的说明见build-transaction的结果描述1 b" p/ X8 c) E% L
调用estimate-transaction-gas接口成功之后返回的json结果如下:
5 s8 J7 Q* Z, P3 Y{! L, ]6 c- W" e( P
  "total_neu": 5000000,
4 [) b, \6 V3 n  "storage_neu": 3840000,6 G6 Y2 z* r+ M, Q6 c2 c
  "vm_neu": 14190001 e! M4 b* S: W; M
}
; n- V/ K3 H" @# r8 {对应响应对象的源代码如下:: Y& d: z. A1 S$ w4 _3 e/ K* l
// EstimateTxGasResp estimate transaction consumed gas
9 u0 ]) R1 p5 f2 H' ~/ n4 ztype EstimateTxGasResp struct {1 K/ l  z' m9 Q# H* m
        TotalNeu   int64 `json:"total_neu"`
# _; P9 O9 Q9 y6 [3 d- L        StorageNeu int64 `json:"storage_neu"`
6 L0 _1 x8 s( E' W& B& b1 B        VMNeu      int64 `json:"vm_neu"`
) Q5 V' ^4 y3 l0 g  v6 ?, T}
: q; \, J/ A! ~0 M- ~+ j% b结构字段说明如下:* j5 a7 v" ?- j6 Q
TotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
  A1 d. P$ k+ a( K. {0 K' WStorageNeu 存储交易的手续费; Q  b+ h* w9 R5 _' [
VMNeu 运行虚拟机的手续费2 m- Z0 \% u2 P. R8 a: X
9 ?! u! ]- R: t7 t# x! q* N6 s7 C
2、签名交易
8 ]2 w: D' U: C7 JAPI接口 sign-transaction,代码api/hsm.go#L53
' h, H% a; g. s$ N/ o; }3 R  |签名交易的输入请求json格式如下:
$ ?. v$ U( n8 C& o7 K( {, O% B% i" l{0 T0 E. e! _4 y* m& r
  "password": "123456",
( X9 Q0 Y& a. r5 M9 \  "transaction": {
4 T: Q4 \4 ~: T4 Q! \    "allow_additional_actions": false,( s& ^% w# N6 a6 `8 f
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",/ j7 C& f0 [# j) O. o% u( k
    "signing_instructions": [$ _( Q0 X8 g6 h! r! A, F
      {2 }, b' \# }4 ~
        "position": 0,
' n' n% P9 k5 l, Y% x1 x        "witness_components": [
# B" i( M& Z4 h& ^5 p/ e+ n( `          {
2 ^! f; w  j7 Q; J9 U$ D& T            "keys": [0 m' {9 S* I- s+ v
              {
& E7 m0 t+ g0 z% {3 [5 I* K                "derivation_path": [
8 w7 n8 ^, k. c  I6 ]                  "010100000000000000",, }* z7 W- n1 R2 p" b
                  "0100000000000000"8 m6 P5 ?0 e  M8 V3 S3 W+ n' h
                ],
7 r0 P4 j+ B# [                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
2 n% o% |7 u$ i- G              }
/ ?+ J8 r8 B" S0 @* d$ k$ |  t            ],
$ J6 W! Z  h( v( V* [            "quorum": 1,
# P6 c, d0 {! F% o/ w7 U+ ?' r0 ~            "signatures": null,
- x4 _( y! c' c) ^, v( W) O4 f  B            "type": "raw_tx_signature"6 w" x# g7 A& @" y1 _+ P
          },1 s. A& N! @& G% x
          {1 U  A! z$ B( _5 b( U7 L
            "type": "data",
* I+ n  r5 M( }- T( l) z            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
) h/ ~- J% M6 n+ d  Q- M" s          }3 k" q# R' c( n1 g$ ]( z4 L
        ]
+ P- L+ ?4 f. y, ]; Z5 ^  V      },& t) h& I6 t- c
      {) Q3 U0 ^9 X% O- n
        "position": 1,
- z+ M$ x5 B! F/ y/ Z9 J1 ?        "witness_components": [/ `) b! `2 g  y! _" N
          {5 V' {' W3 G, V2 g6 @. o1 k- U
            "keys": [6 A) J: R9 h7 @
              {
5 \. T7 H$ W% ~1 O                "derivation_path": [
, P( h1 n( X9 H, ]( D% l, F, v7 _                  "010100000000000000",+ i! |. L. Z6 F
                  "0800000000000000"
2 [4 p9 x) w. Z: U$ Q5 D4 Z1 D5 c                ],9 {' m1 O" I! N# j; Y, w
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"7 f6 Z* H( d! \; Z/ p
              }
+ n/ \( U3 n: [; u            ],
$ a4 ]0 n9 b2 T( `5 c; P            "quorum": 1,+ f6 m$ ~& ^. @! B, F6 g
            "signatures": null,5 Z) i+ }3 V& a9 B6 }6 R% V+ O
            "type": "raw_tx_signature"2 }$ n8 d7 y$ T9 H6 b
          },
: r5 u, M6 \. ?9 t  |, B: j6 O          {8 }+ l. u7 n7 ^$ v
            "type": "data",+ N$ E2 }5 @5 P
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"4 k# y5 P1 x' L+ ]
          }) c7 {) b5 S, Y8 D  ~; A
        ]
5 r$ |4 k3 _+ b( E9 w. k  p& C" S      }4 Y( V- _# ]( S
    ]
) z+ I+ m( [( U- Z8 c/ |6 w) ]  }! d* X$ _" o5 b& }) V3 o
}$ g; ]  C1 ^) `
对应请求对象的源代码如下:
. b9 X1 n$ v3 Y0 btype SignRequest struct {    //function pseudohsmSignTemplates request" ^" E: p, V. K, ^# {
        Password string             `json:"password"`
$ k3 L# I$ N" P+ C+ G4 y        Txs      txbuilder.Template `json:"transaction"`) _: O: G, O4 o* z* W& \6 ~7 J% ?' a
}
# C- {' B- p1 A" C, Z结构字段说明如下:
. q$ U: G% Z7 ?2 _' t7 dPassword 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名
8 `/ Y' z/ U) P# g* M! hTxs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述* o7 `$ W# Y# r3 u6 e0 G; \8 n# e) d
3 o5 w/ z" |% s9 X0 s. G8 p* m
签名交易sign-transaction请求成功之后返回的json结果如下:
2 X. h& s: o, T4 }{
9 K$ m" V" ?" P  W. [  "sign_complete": true,
- b6 E' _* b! y# s. ~& y& O" d  "transaction": {
3 ~  M3 T* N& r  }( f    "allow_additional_actions": false,
' p/ T8 y5 k9 C/ {1 K3 ~3 k    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",3 p' H* [! e& v
    "signing_instructions": [7 E$ j  a# z. |2 \
      {+ ^9 V9 D) ^3 C! f0 e! [: o
        "position": 0,) A$ p2 g5 k% n) e8 {6 u
        "witness_components": [4 x5 R! l2 Y% W4 i
          {
% N7 I3 D/ e4 o  G, B            "keys": [( G! d4 Z4 n  }; t: y
              {
" T; T! r! v7 k% g3 z                "derivation_path": [: ~7 r: M4 s1 O4 H, g" R
                  "010100000000000000",
- B3 I0 c4 y1 [. X* y                  "0100000000000000"
! W, T% K% @/ |) L% L. P* Q* I                ],
( S& g5 q% a+ a                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"# E, Y9 H8 x( n1 N( O
              }
3 m$ [  z8 H% e7 J5 s3 O            ],/ r! r0 O0 L6 M& F; m* ?& x& L
            "quorum": 1,* S9 \' J, J; p& X3 `
            "signatures": [, z! v2 Y# e! I( _. d( E
              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"/ n9 S5 @8 ?- Q/ r) P  H
            ],6 d8 P! \" j& s
            "type": "raw_tx_signature"
3 E# G) {1 t. d) S  u' h, ]          },/ v! ?* |+ g$ d. t2 c
          {* w( _' E$ J: g6 L+ X6 m
            "type": "data",
/ [3 u: L' m2 q% }# G3 A            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5": C' ~" R! C, E% _: S6 R* W
          }
' l* r4 g9 T2 ?0 A! x* c        ]9 q0 f% N) D  e' g) l
      },1 z, d4 W: a% {5 C" v1 u/ b
      {* E8 Q& U% _" v- H; \* I
        "position": 1,) u) C; y! r$ m2 b0 A
        "witness_components": [
3 }& o* L7 T6 v- p          {0 U; v$ R5 ~& B7 v
            "keys": [' q/ o/ ?5 \( C7 r! C# B, Q: v( \
              {
& g8 o5 U" ^1 G$ P7 R, C5 P, S7 M                "derivation_path": [! m9 }. }/ A& S/ X" _* R' J7 [
                  "010100000000000000",
" q* w, {+ R# p                  "0800000000000000"! B* q- w2 \7 K* x
                ],2 Q" w( m' q, H% C3 v5 S* \
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"- I6 |/ X) p* m! z$ E
              }
  ]9 A6 {8 N5 c# |            ],- P1 C' j4 d. x# l3 t2 T4 \
            "quorum": 1,
1 r. m! j- u0 o: d$ A            "signatures": [
; b" {# B+ R( K, {              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"0 d1 m9 c# O& K; d+ }# `/ X
            ],3 r9 W0 O7 \* N6 ?: J
            "type": "raw_tx_signature"+ g& t0 x- A: B$ N
          },4 i8 Q& ^2 z  S' }
          {* x% f( ~/ }7 d$ B- C6 i) t, S3 W
            "type": "data",0 n: u1 r7 b" a; n1 T7 ]
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
9 a* f$ x+ v0 z: N8 Z          }
& u0 e" V$ h: w8 B# u        ]
9 s4 Q6 n$ y) q: C      }
8 Q( a3 {2 T' C    ]
7 D: j- p' M# f: I* b  }, W* A$ a, o' }! t  R4 P
}
9 V& c7 u! {! u( _6 ?' E4 S对应响应对象的源代码如下:
8 w1 P: O% M8 D5 b7 H, _' t- Ztype signResp struct {
$ ?3 ~4 N/ I" x+ [) I$ p        Tx           *txbuilder.Template `json:"transaction"`' s% e' X8 _0 N8 K8 l: _& [6 m
        SignComplete bool                `json:"sign_complete"`: n& b3 Z8 {/ Q7 {% f. W0 T: W
}9 D4 _5 _" _* x2 P. q9 `6 o
结构字段说明如下:. {/ }0 V. ^/ S/ b
Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息
6 N1 d/ W+ s% H0 Z) W5 xSignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易  s- K4 T! y! ]9 e5 T" D4 W
$ D. j) o; \0 m1 a
3、提交交易, W( T9 Q: N/ o$ i: F5 ^( ^8 D
API接口 submit-transaction,代码api/transact.go#L135& O9 A# d4 G# `2 K- G9 {9 J; n
提交交易的输入请求json格式如下:
3 t+ Y1 |7 ^0 a{2 X8 R9 u) e$ m- G
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"; \0 Z' g2 s7 W6 S% T, c" v
}* U# e# j- N& H' a6 C2 B" z& U
对应源代码的请求对象如下:
/ O$ _  |6 w/ ^2 A. E# ^" b6 Ktype SubmitRequest struct {    //function submit request. H3 p/ ~6 `- P+ X
        Tx types.Tx `json:"raw_transaction"`/ i( V- n9 M2 b8 Z
}
" h3 y9 y7 k. o+ L) ]结构字段说明如下:  Y* O3 y1 C4 |: Y0 W- `, V
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。
4 v  t: T; W6 l" n; I
. y2 h; r# F: W" ?submit-transaction请求成功之后返回的json结果如下:
: r& a) S( X: ?- w{
6 p$ l: u- h5 O8 n/ i  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"  N* j1 C4 }/ P- g
}
$ Z, A. J5 A1 A: ~' ~对应源代码的响应对象如下:
; N- L/ M2 ]4 h6 n. s# H) Itype submitTxResp struct {
9 N' E0 o+ D( J4 Z  X: f0 l        TxID *bc.Hash `json:"tx_id"`
& W1 i6 b4 i' V, s% a}
5 }7 k6 b- k6 R4 j- h: {结构字段说明如下:8 }8 x$ U1 W3 z* w8 x; G
TxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败, H1 @! ?2 W: e( S

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

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14