Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
173 0 0
比原项目仓库:3 @1 k! I3 w- D4 b# d5 ~5 v
Github地址:https://github.com/Bytom/bytom
) P- I( z% U# q7 n' {Gitee地址:https://gitee.com/BytomBlockchain/bytom
( j4 |6 o& M$ `4 n6 e& D2 k) L该部分主要针对用户使用bytom自带的账户模式发送交易
4 M0 X+ X8 B( l1 p; K1、构建交易
) M/ M4 @/ C# j" zAPI接口 build-transaction,代码api/transact.go#L120
  c3 {# d7 I, }. |( m以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:
3 t7 I" t' G: F{
( m: c0 B# u6 S/ g* }7 g2 r  "base_transaction": null,- ^8 S. z, R( T9 [
  "actions": [
# _, A; c4 j+ e+ [+ J    {
3 {2 C0 k2 |; @& R- a0 `/ G2 [      "account_id": "0ER7MEFGG0A02",
) {3 F) W8 d% P$ z# F2 S- t      "amount": 20000000,8 y7 o: D( x9 B
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",8 ?. c- g: m. H* C
      "type": "spend_account"
; x0 ?" g; k# o3 U    },: p+ [- c# u7 ?7 f& ]
    {4 g2 y9 |# ]6 q2 I+ d, S  y$ T
      "account_id": "0ER7MEFGG0A02",6 ]1 l* k# p& v0 U
      "amount": 99,
/ k: u& I% v! Z9 j      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
/ z$ O3 L2 U' [      "type": "spend_account"2 Q3 x% J8 f0 @+ t+ d' Z" r6 L; Q4 h
    },
( z8 ~% F, m) H- s& W8 ^1 a' I- l    {
2 u; q; F& |8 ]1 c: G      "amount": 99,
& d* j5 w: Z  m" \, ?      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
6 b4 D/ G+ M9 S# R( |" S2 k5 `( S      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
* }0 W, g2 Y9 z- }: q      "type": "control_address"
6 @! n- E! P9 O' _' O; t    }
5 g% i9 S  r* Q( p* p  ],7 s' u  E) ?' G$ i9 H- g0 m
  "ttl": 0,
; p5 K/ p" T- [  "time_range": 0' r! N2 k* A" w; S  R
}
# b" O" g7 J) A8 [% R对应源代码的请求对象如下:4 \: n( v) ~% P% R
// BuildRequest is main struct when building transactions
: w; D" d0 [) ?6 N3 o1 ztype BuildRequest struct {
" d0 r+ F3 v% B+ ?/ n* V6 F        Tx        *types.TxData            `json:"base_transaction"`
6 ^7 a' ]; z3 w# ^  L- P" ?        Actions   []map[string]interface{} `json:"actions"`
8 a* E1 ?. v# o        TTL       json.Duration            `json:"ttl"`
1 X8 B+ l. k2 F5 |        TimeRange uint64                   `json:"time_range"`* W4 @) l* l) k2 B5 }3 i4 i: K& o% ]
}0 G" z; K" t) O3 k) Q
结构字段说明如下:: _" j. }; Q5 _& |  y# m
Tx 交易的TxData部分,该字段为预留字段,为空即可$ `7 H6 b6 _$ d7 Z
TTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟5 o5 ^) O2 |$ j9 i" R
TimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
1 s5 H8 |. r+ _4 J/ q  SActions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:- O0 N5 j% N2 n( X- {
input action 类型:
/ p# m9 r9 X* g' b/ D0 Zissue 发行资产
1 l! ~/ T# N' n- l6 K" Ospend_account 以账户的模式花费utxo
( |& k. g' e5 i2 d: S1 cspend_account_unspent_output 直接花费指定的utxo7 ?' M/ r6 j3 L9 j
output action 类型:8 t5 F( S% F3 ]- N
control_address 接收方式为地址模式
6 ]' A/ q6 O" c% Z  Ccontrol_program 接收方式为(program)合约模式: [7 G9 ]) n2 v, [/ \# H8 Y
retire 销毁资产
9 E  V$ h+ [# z, |" [9 f2 s# y  s# x3 Q4 T! Q* o

; S! c  ]2 q) a8 I" Y. |& G
) T% J" C3 M  c注意事项:- @, W( c$ d" z8 v
一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。
2 C  P4 p7 g6 B6 z9 m除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。1 b+ x5 I' w- ^8 |
交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量
6 a& x, A8 T8 d: y6 L3 ]- @交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu! _- r0 b1 J7 x
0 \: H: i$ w, e* }% h
action简介
2 q& B% A1 t4 h* l下面对构建交易时用到的各种action类型进行详细说明:; H$ n/ D1 e' \' W- R! [( Q( F, ~# l
issue
7 h8 S: D  G0 _( k: ~6 [issueAction结构体源代码如下:% v/ w3 i$ ?& S
type issueAction struct {
+ v+ X% T! H0 Z% {6 X! o7 ~$ x* q        assets *Registry* z" v; G& p6 h7 M% e' n" z6 I
        bc.AssetAmount5 F0 N5 S# l+ P! e4 e
}
/ t0 {" L4 z6 g9 i& M& a7 ttype AssetAmount struct {
, [: l. X3 {# A: E        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
' @* H, m5 q3 q" ?6 Q% A; |0 y        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
3 h) w; U1 h6 s! c1 \- k( S}
1 @, `/ L( C" V; `- d3 c结构字段说明如下:
$ K$ S) d/ P- ~' Passets 主要用于资产的管理,无需用户设置参数( ~, I7 ]" d6 m, s4 Y% u7 x
AssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID
6 b6 r  l3 ]; G. `9 E) |$ A. a+ o8 m$ v8 x
issueAction的json格式为:3 [2 ~- [, F+ ^: s
{
# m( n5 H/ `% `! D7 e  "amount": 100000000,
2 e5 }. x. j; V/ v8 Z! a  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",$ \2 ~$ R/ x2 x+ t' _' P; f
  "type": "issue"* @/ D& ~/ P' D8 u" [
}5 Y5 y0 i" L& h2 b- d9 K$ o
例如发行一笔资产的交易示例如下:0 _/ A1 |$ K# |  N+ u
(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产), |+ T) d% E5 T, X8 Q
{
) l8 }% d, `% \3 d; ?3 ^, g  "base_transaction": null,$ G# H6 ~/ x% H" d; r: r
  "actions": [3 ~, r% b( I3 `
    {1 V. C; Y$ [: r, ]: ^9 W' O1 }/ a
      "account_id": "0ER7MEFGG0A02",. r: K; p2 H) N! u* `/ |
      "amount": 20000000,
$ P  @* E0 m% X4 Y3 X  t% V8 l      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",3 e, G+ ]6 R1 I( O; h& z+ ^
      "type": "spend_account"
& j) i, a' t2 F3 Q0 _    },' J  [' Y, p- L8 [! H) }* T" b
    {
+ u3 S+ f& N/ u* f. u$ k      "amount": 900000000,
& e) g* O" {( j$ N% Y1 y5 {      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",& p2 }3 z; m* _
      "type": "issue"7 b# h  y( K/ l
    },( S3 q6 q, i  X) T4 s. E
    {- a  s1 j/ ?9 `: R. c6 M: Q8 w
      "amount": 900000000,
0 Y; k, e5 W* K8 s- ], Q      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",1 d# q/ v+ P+ [2 z% @% r
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
3 o6 n  P: C0 k; I- c4 R. E0 B      "type": "control_address"
, j. s/ G+ M" N1 E- P3 @    }+ O6 E. d. l7 b! G1 b! t
  ],  M5 I1 s/ k, W
  "ttl": 0,
$ [9 T* l, {8 W1 Q4 `) y% Q  "time_range": 0' @- U9 _! b+ F6 K# \* O6 p
}! O  f" |6 L/ l) `/ l

6 c# @6 R0 y. z5 Qspend_account
6 e3 Z" E$ ^+ R) \: |- ZspendAction结构体源代码如下:8 @' d2 z/ b# R0 }9 W
type spendAction struct {0 P$ U9 W3 Z1 b8 A% `6 z
        accounts *Manager* R5 m3 u: [  \* N1 V7 j
        bc.AssetAmount" ]. c9 r7 Y( d' s. M& R, D* ]
        AccountID   string  `json:"account_id"`
8 T) {$ s7 X7 L  o5 R/ l" z" X        ClientToken *string `json:"client_token"`
& L8 B8 r2 v1 w  D8 y}
3 S, r5 \0 q6 M# Ktype AssetAmount struct {5 D- z8 a! O+ M0 V
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
3 G- |( ?5 c2 h1 n& C+ X# s        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`- ?3 x7 n) h8 o6 U
}
6 s+ b3 q2 c$ v+ V1 u7 [# e结构字段说明如下:
# S. \2 ~+ ]0 t. V6 h, waccounts 主要用于账户的管理,无需用户设置参数# U7 }' J4 q, M7 `/ `3 z
AccountID 表示需要花费资产的账户ID6 B$ P" ]& _/ O4 [
AssetAmount 表示花费的资产ID和对应的资产数目
& k# t+ B4 f) DClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可) g; P4 L7 b4 E

/ h1 g6 T  _8 A$ n* e3 fspendAction的json格式为:% V' E9 L) z. z
{
. \7 N1 Z; l9 X+ n2 g1 [  "account_id": "0BF63M2U00A04",
& E* w7 ^& W" q4 c- O  "amount": 2000000000,
6 U2 e5 r$ i% z6 [$ T4 t- r  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  S4 a/ l) K$ X! P% c, A) @  "type": "spend_account"
# n8 ^+ n! m' s+ I}
% z6 G  Q3 N2 ]例如转账一笔资产的交易示例如下:6 ~6 w! p6 e. f+ J- ~! I$ H
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)' ], n$ g* E3 K0 A  o% q" o* V9 `
{# p0 c8 X: E6 {! `, S! d0 T' i
  "base_transaction": null,2 v3 t" \5 _# \) ^, u
  "actions": [
7 a6 K% g# G1 F5 v    {
2 b( J8 f2 j5 H4 z, A1 C      "account_id": "0ER7MEFGG0A02",
( ]% m- V& ^. t  [      "amount": 120000000,
; O7 |2 M; P" \5 o: [      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",2 O, f8 _% `; J
      "type": "spend_account"3 x. s2 v9 C1 @+ @2 O7 m
    },
# N7 [8 [1 `" `4 O/ l6 j6 F& h$ j    {  g4 j6 I8 k7 T) G  U% }
      "amount": 100000000,9 M' o$ [& a! c6 A) [" A9 x! P% V: p
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",2 z. s% e) z$ [, W8 ?4 F6 y
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
3 v- d9 b1 B- W1 r5 Z) \      "type": "control_address"5 ]' x4 h' ]8 H) B+ b; o: O2 ?
    }# E6 R# z. w7 P" @0 ^" q5 i2 l6 u
  ],) R: Q6 P: A8 o  r% z$ c
  "ttl": 0,! P( Z4 s; x/ K& a2 A: c- v4 B1 f1 X; Z
  "time_range": 0
6 }; o: Y$ q* Z3 p8 t}
5 s8 x- y8 F; [6 I4 ]9 ?& v$ J# N2 W- B) q1 \
spend_account_unspent_output8 D( H. Q1 \8 D. |. l
spendUTXOAction结构体源代码如下:
: e6 ]* s7 W! E: S, J/ o$ Y8 Ztype spendUTXOAction struct {
( ^9 J& i$ z) @6 N        accounts *Manager$ ~" Y% |- y% F, d7 e5 `8 c
        OutputID *bc.Hash `json:"output_id"`
7 H+ q+ f& `  I6 O, C# H; c        ClientToken *string `json:"client_token"`
" z- ^9 T8 M- U1 [}
  o8 R7 x! ]7 W( V$ {结构字段说明如下:; k1 t) J# M$ z
accounts 主要用于账户的管理,无需用户设置参数
: M) i: {" W, X7 X0 gOutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段8 }) `, i" v+ k. h
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可6 D! _4 r/ E' Z5 P; s/ F2 x% d' D
2 J8 ]1 Q5 K, e* k1 E$ f: ^
spendUTXOAction的json格式为:
! f( k! O( g; e' T! @* [* H' P{1 Q4 _/ Y8 c; D/ ~& h
  "type": "spend_account_unspent_output",8 i- @) \! z3 F7 u7 z# \3 U; p
  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"
7 O: t# L: A) g# \& I}9 S* {+ ]  u, R2 H1 v# E/ l  J
例如通过花费UTXO的方式转账一笔资产的交易示例如下:+ u3 g, C6 r, b) u1 o' F0 D
(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
  X) U1 K. u$ d. j{7 C0 E4 ?, O. o) H
  "base_transaction": null,
5 w. ~' H2 z# n5 _- y2 |* r" J  "actions": [9 v, u% }& W7 r3 }/ Y
    {; T/ L( ]( _. w% a1 E/ f6 |
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
% r! h% H1 A1 p8 m( O# d# ~      "type": "spend_account_unspent_output"2 u4 c' x6 y* i3 ~' P1 a& g
    },
$ W3 S0 V5 D& G' q3 F    {
9 a5 w6 X9 m' H7 F, K      "amount": 100000000,  g4 O# L8 T$ S- j+ i1 }' W. L1 L
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",! F7 R6 \; F1 O9 a
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
9 l% `* o+ i4 s* F3 u      "type": "control_address"
; I& }$ K5 g/ t' x2 z. U! ?    }/ j# |7 A# w+ c; ~6 X
  ],$ J7 [" i9 R% \8 B( E; ?9 m
  "ttl": 0,& x# e2 {( W# v" m& }0 X- \
  "time_range": 0
+ |6 b8 K5 f5 D7 e$ |: j}
0 ]1 u! C, S+ p& q% Z6 ~, o& q" d9 T, L, L' S
control_address! c5 l6 f' p- M3 Z. v$ S, b
controlAddressAction结构体源代码如下:& ]4 B3 Y! ]- j3 I7 f& `( `6 ^
type controlAddressAction struct {
" R: m0 ~# t" L* X: b% J( @, Y$ r        bc.AssetAmount
9 g0 s) d, y0 _  L6 h% R$ A        Address string `json:"address"`! [3 T+ H8 L' M" ?. ]$ O
}
" a; f" \2 u4 c5 mtype AssetAmount struct {' ?8 B1 }+ T, o# l
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
+ ~0 a- ~+ }2 u4 P4 t- m+ Y9 L        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
* Y' L2 B* Z2 C}% u4 H- u3 O$ k1 a* J9 i0 t
结构字段说明如下:: j2 z' I2 ~3 ^5 ~3 N0 i  Y% A
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址4 L/ n- Y4 J8 X
AssetAmount 表示接收的资产ID和对应的资产数目
% v9 p/ B' X6 i. Y; J2 X0 P$ d* t! l' U( c% ], e+ {1 I
controlAddressAction的json格式为:. t+ c+ @) P1 f' ^9 B  ~  X0 O
{
1 P, }6 X# j' ]$ K  e6 T$ Q( C  "amount": 100000000,
! x) B* S) p" R9 v! p! R  W  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",# c4 ]) X  U4 F4 s) D1 Z9 |# ]
  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",3 N/ S8 ]$ B5 C9 Y7 ?
  "type": "control_address"
  d# [9 |0 L% q- q% \6 i7 `1 u}
7 @% n* D) R( ~9 }( W6 K3 n例如转账一笔资产的交易示例如下:2 @  w7 h0 Y5 w6 I" k/ K3 i5 k
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式), t! T" {* W( L$ }5 K. u
{7 j7 X+ W, j) t! {# \
  "base_transaction": null,( Z, y) Z& H/ W" ~
  "actions": [
  g$ \: Z! O* i5 }3 }& m: A& @    {0 j# v  N2 Z/ m4 `3 t( I% I
      "account_id": "0ER7MEFGG0A02",
- W, e1 @2 I+ l! j( [      "amount": 120000000,7 ^) F3 |" j" Z: h& l1 X
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",% W8 k. H" r+ O% Z; Y' Y
      "type": "spend_account"
! z5 }0 h6 ~9 k3 h    },
  x# O1 m+ ~" z5 G6 D    {
- z9 y4 `3 `  o% [      "amount": 100000000,( w- |* S# ^/ H* E) T- u
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",/ J/ X- w8 e( q* h) x
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",/ J: W, ]/ B% k
      "type": "control_address"
) x* w# K: O$ t( a" H    }" o; D# z) H5 y0 R
  ],
( ?  S: F' W! |* z7 g; f  "ttl": 0,3 ^, q+ l1 u, |3 X/ Y
  "time_range": 0
8 u5 R( c, q3 y! v7 u* u, h}* b" [* Z+ }0 c4 F
* J  T6 I1 S5 O+ R9 @
control_program- @* c$ ^3 ]. v& ^% ~) s# K
controlProgramAction结构体源代码如下:
9 f3 |% Q, E  J& x# A2 Etype controlProgramAction struct {
# V) K# z8 E" J( D        bc.AssetAmount
* m# M; i# c5 [7 O2 x: L        Program json.HexBytes `json:"control_program"`
1 \; A/ p) p$ Z/ f/ }+ G9 o, [}/ a8 [/ h" u& w5 r, P" Y
type AssetAmount struct {
0 x) I! U9 w: n: y        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
! Q9 G; ?* p( e7 r' @4 I3 f        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`1 o7 |) k# g0 j9 C2 W
}
" u, w8 }4 R2 L9 k' n结构字段说明如下:
6 l. r2 G. @& ?* C+ A) w8 D/ F- `Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)
& \0 Y0 c5 @" @, A& Q7 {9 BAssetAmount 表示接收的资产ID和对应的资产数目# J/ q. W" x  R( x6 @' G) K

: J! X- L* g! F3 W* o6 A# k. ~controlProgramAction的json格式为:
) B9 O' Q) S8 y{
$ z& i  `# }+ ^/ t* J0 x  "amount": 100000000,) Y, F3 X0 H; I0 {
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",9 s5 T& G; p2 R: t% U
  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
7 X, Q1 c! E  c* }6 Z0 Z  "type": "control_program"5 E* ]6 M( \# w
}
  K( q: _% y" f  U# J0 A例如转账一笔资产的交易示例如下:9 ?; X: P$ t/ T, F6 I; |* b: j
(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)4 X/ k) y: l8 V( G* e  n' p. Q
{
3 D  i, _9 ?! }$ z8 d  "base_transaction": null,
/ ]- r' I) I( U$ ~& T1 P  "actions": [! x4 z0 G7 |+ o  J! z# u
    {
! L; [/ R2 E, q7 n1 Z0 U      "account_id": "0ER7MEFGG0A02",
( K+ v: g1 ?; B2 q; M( @      "amount": 120000000,, ?7 w% S# j. M& _9 c% o% `) g% ]
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
$ b: e, d) ]+ e9 i# a  C  c      "type": "spend_account"
) I9 n4 u) m' [. |    },
2 Z( p! Q* a+ M- |- H0 Q    {- y6 ^, s, Y& V' e3 k5 q7 X( q
      "amount": 100000000,
2 p% s* N: s$ q4 U  e" N" G      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",8 r- ?( q2 V" a  Q) D% K: y( t4 ^
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",  D. \, k" v' m
      "type": "control_program"
0 h+ G; G9 Z; M    }
% [) K( ]- }$ z6 E8 e  ],
( t, m/ P* q$ S( L) E! _2 m2 H  "ttl": 0,5 ~7 a1 A3 @# B# o% s
  "time_range": 0
6 v7 y, {3 m0 |7 ~7 L}! b( T  q2 \; W# m+ k
# b' z! R: }( x$ m4 l  L1 I
retire
: G$ T3 T6 r# H5 [; Y! s" {+ zretireAction结构体源代码如下:
; e0 s6 j4 R  [! V5 K4 Ztype retireAction struct {
9 N. o1 y+ _) L) q8 ~/ D        bc.AssetAmount4 T9 j6 g- J% G* Q
}4 x4 s) c* X( ?: j: P: m4 D$ f
type AssetAmount struct {/ A) J; ^; e" N8 j% W, P
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`6 o: c+ R0 w2 k: ?# w7 X
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
/ T3 R3 S# c. O: S}  T  }- v" _* U1 f$ ^; k3 d
结构字段说明如下:
" P* N3 P$ N# W. j# H9 qAssetAmount 表示销毁的资产ID和对应的资产数目
0 j: s2 I5 Q. [  j4 z1 k  V3 j6 R! x" p; S4 p; j' q) f6 l
retireAction的json格式为:
) S0 i0 F. W5 H$ C! E{, j3 @; T+ }2 ?( F% T
  "amount": 900000000,
+ c9 X0 t9 E7 H1 J! |  r% d  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
3 K- K( E; A. H  "type": "retire"
: ~  d1 P6 i- m" x5 N7 A" a}% Y- l! ?+ _, ]* t
例如销毁一笔资产的交易示例如下:
8 B8 \" \' K6 }/ G8 J(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)4 v) I& N: o; M1 z. L, {. Q
{
3 K6 S, y: ~8 ~* ?9 i, u  "base_transaction": null,: h/ \2 V7 f7 q8 x& C  U5 ?
  "actions": [
7 y0 L; |: K9 c, R" o7 x' K    {3 m6 e0 X6 t* J
      "account_id": "0ER7MEFGG0A02",* |4 v, Y% U) i2 G
      "amount": 120000000,
% v8 i4 l9 R- A  C( e2 B      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",: u( b/ e2 L( K" I0 w( Q
      "type": "spend_account"# b. v  X6 `: ^! D0 ^4 r
    },  [2 J; @# b( T4 i. f3 S2 o
    {
7 O4 d  @+ ~% l2 ^      "amount": 100000000,
) b! |) R. v/ A3 E0 j& N* t      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",! i: M- X5 o  n# z' s9 g  l
      "type": "retire"+ P0 A* ]2 @% }4 A3 U, l
    }* a: b5 D1 L. T! L& v
  ],+ V" Y( i6 G7 o" K( n9 Z% K
  "ttl": 0,
+ s, Z* B! c' c3 H" N  "time_range": 0& J$ M) G5 f  z) f7 I& m" p6 f8 `: h
}2 X3 n9 P+ k/ a

8 X0 K& i  \4 i/ \0 P  rbuild-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:
, b- o5 c9 ?$ ~% ]# u{& M" c5 W. j% E! j
  "allow_additional_actions": false,1 J' @3 H) d6 M, f/ a! p9 S
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",8 }- W8 \% L) _: s
  "signing_instructions": [# g! k2 {4 l! D' `% w, @- a' {
    {' c7 r' }  e: }/ ?9 a; M
      "position": 0,
* k7 Y; x" C1 j      "witness_components": [) H) ]$ V5 W7 `% j, I
        {
9 K5 z2 L$ X9 ?5 F4 [& u$ ?* D          "keys": [: \1 q) z* }) l' P. A
            {4 b4 P2 x- D8 _
              "derivation_path": [* F4 o6 }, R4 `" u7 V# O; f
                "010100000000000000",
  ]' N* \& _  @" [+ V: f/ Y: Y                "0100000000000000"" X8 [, W, s0 I" Q; u
              ],6 M% `/ g2 L& Y) U( e0 X8 X
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
9 z: v, @1 a/ l( }1 m$ N( B            }
* y7 i) M( H4 g, H4 [+ ~; g          ],, h( d+ s( O/ C$ b
          "quorum": 1,
, Z- R) ?0 d  v0 ?0 H8 `          "signatures": null,) k) q7 f2 y/ z' v
          "type": "raw_tx_signature"
- I2 F2 [, m! G) t3 n) v        },
/ h" w) o% Y4 Y+ D  B/ }2 Z0 R* ?2 d        {, \- k3 R$ |4 c
          "type": "data",, b, a  c. q$ a" i* ^4 T% Y
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
# G: W4 e6 V* m$ X3 ]; G+ [        }5 T& |% b' x* I
      ]! A" o$ B- ?0 n# B$ ^
    },
9 g; ~2 j$ v. {8 ?    {( R! i* Z6 y: U, ^! l4 Z$ T& i
      "position": 1,$ D) R  @3 U$ k9 D7 Q# c
      "witness_components": [" G- I( o4 X( h2 [6 r- w
        {
- v- R: K2 E4 g- c$ m          "keys": [5 Z! N/ M3 i0 S3 R5 P* d& v
            {' Z) k8 {7 w& w4 O# ~9 x( z
              "derivation_path": [
: N8 B% F+ L; i( X/ v                "010100000000000000",
9 ?2 x; l; o; R                "0800000000000000"
, Q' |& _' c% ]4 [; e. q              ],3 f3 F# U9 W9 d7 _
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"* Z& G' r0 N1 B6 U
            }
# h0 A" ^5 h" N( I          ],
; O- I& g, @! c' Y, V) R+ i          "quorum": 1,
" B! x4 r& Y+ A+ H4 ^3 r          "signatures": null,1 \  j1 h% d4 r$ R
          "type": "raw_tx_signature"
+ a3 X* Y$ ~1 ~, m. F        },4 q* q* w7 ?2 y7 v- G( S2 B
        {+ J% }8 A# d8 i$ n- K" c
          "type": "data",0 q# e# [7 _& y) `+ e% N% L
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"( s" W+ M" x" {9 {  C& r, ]
        }$ O8 \2 ?  }$ a) z  X5 _
      ]+ c% K! o. j/ F' y5 a8 D2 W6 m: i
    }
: K; X( K2 q1 [: t) ?( t9 S  ]
9 T( O, m; w7 Y3 J( b}2 H1 z( D6 q- z$ I
对应响应对象的源代码如下:! Q) e  y9 S3 H
// Template represents a partially- or fully-signed transaction.' @) X/ K6 L6 [* O
type Template struct {+ M, J. ~: k' W* y
        Transaction         *types.Tx             `json:"raw_transaction"`/ E' B- x9 S0 z# k& Y0 N
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
% {. o$ w8 ]( N        // AllowAdditional affects whether Sign commits to the tx sighash or! n: s8 l3 x/ O2 P* A
        // to individual details of the tx so far. When true, signatures' X# a- p8 A% _! v# z7 `
        // commit to tx details, and new details may be added but existing- K- D# O# F' V* W
        // ones cannot be changed. When false, signatures commit to the tx7 a! K- x. S/ ?7 O* K& v( I
        // as a whole, and any change to the tx invalidates the signature.8 b6 s9 ]8 C% C" `. k
        AllowAdditional bool `json:"allow_additional_actions"`* }: Z# g! c0 T/ m! Y3 T& z
}
9 c" a: I. u6 S6 R  l结构字段说明如下:
/ o. z3 G! B5 s: A" WTransaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:
" B7 W% Z/ @) F8 T4 d2 KTxData 表示给用户展示的交易数据部分,该部分对用户可见( C8 |/ k5 d' R" ^7 W- v- U7 j
Version 交易版本& [+ b, g! W. E( P1 Y% T0 f# R6 K: o
SerializedSize 交易序列化之后的size. T0 m. a0 Y, P2 [  t( s
TimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效). {4 c5 E# Y4 X8 x& S
Inputs 交易输入
1 [( a/ q+ G' M% A: OOutputs 交易输出
( ^/ R& W" Z4 d3 x* [# @( i# ubc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述3 [; s# `$ P# {( q
SigningInstructions 交易的签名信息" x5 M' t7 e; f
Position 对input action签名的位置+ K! y% l+ K; k' F
WitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:
1 m6 G, X4 M! @% `. V  N" cSignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名
7 B# Y3 ]8 h! }5 N7 }signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
& i: d) w- f1 \; B8 D, U: qkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
; i% o2 ]4 l0 v. ]' [4 hquorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户4 O; r1 J( Y8 \9 _9 J9 h  Q/ I
program 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program: @: N; U  K3 v8 r8 Y" n
RawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名/ T: ?" K  ]7 M/ H; H( V6 y' w2 c
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在( A* W0 `1 P- a
keys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名1 q' E; v, x% H: J; e
quorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
& |4 A$ K6 T3 h4 x! p4 _0 X+ T) IDataWitness 该类型无需签名,验证合约program的附加数据
. C: l" r! y& O$ ^  v7 Z2 M: o- ?7 R  @7 m
6 d( G2 m5 [; _! w  D/ a6 `AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名6 n1 n$ i; K& p

4 a' l% m6 |- f, |! ^- @估算手续费" [& p* u" W0 g# Z
估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:
: J1 |6 D' \5 V4 m. j  build - estimate - build - sign - submit* N) Q" [% V4 S8 S; _" s
估算手续费的输入请求json格式如下:' \# v( ]4 Z) J3 Q1 Q
{
0 v; l, g8 l- w% ^  "transaction_template": {  ~% p6 J( R1 J
    "allow_additional_actions": false,8 n# i2 `! t0 p+ S  w
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",) h. |7 m( D) C: c0 z5 U
    "signing_instructions": [+ v& c& B% p' z7 ^1 I
      {
' \: ~7 |, _8 E: j1 y6 y: l        "position": 0,: i; V% h- ^& p/ |2 P, v( u8 L
        "witness_components": [
# u2 j- Q) g4 S. h  z6 c          {
7 f, H% P# K4 y; a( ~+ W1 }            "keys": [
$ v& x6 N0 Z6 H# c) p7 Q0 c              {
0 a" v. K! p, n0 h) ~+ \: ?                "derivation_path": [# W( u$ p" r3 R+ Y* K
                  "010100000000000000",
& r* Z. W) ]" V9 d                  "0100000000000000"" v1 R3 l: d4 h9 X' M; T8 T+ `* f
                ],
# ^' I; J3 v1 Z: i                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
- w8 U; `7 \  D0 _: O              }) J6 x) M, U( A9 L
            ],
2 i5 L! G; ^/ R( j( t9 ^1 C. H            "quorum": 1,
, Z# P" t$ S4 j: v8 S# }) _0 ]  V            "signatures": null,
: q* L' b" y8 t9 Z" |+ v% n2 K            "type": "raw_tx_signature"
/ G  i. k! e, T          },( M. q) E& Y3 }& |
          {% X6 U. s# E0 h% [8 X0 P
            "type": "data"," k' v5 [$ \6 f- X9 f! ^5 l
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
7 ^5 [2 V8 }# T8 Z5 {2 _7 E9 I* T          }  G/ D% b8 ^6 }) ]
        ]
$ ?7 X- T+ ~; Z. i& v5 j0 g  S      },0 h# Z2 z8 z4 _8 v% O$ E
      {( g) d1 ~* f. z" |5 D
        "position": 1,
8 ^7 o8 m9 k8 W3 m        "witness_components": [/ \% t$ o* a: @. Y
          {' y3 s5 F; j3 q% F
            "keys": [- V2 q' c7 o) H7 f3 S# ?1 l1 `2 Y
              {
! y7 S1 h' S# U, Q. H                "derivation_path": [% i1 M- n2 j0 i8 ]0 J/ G2 Y
                  "010100000000000000",
/ g' R5 ^/ L) z6 k                  "0800000000000000"
3 o/ V* w5 b9 g! h( n                ],  a# U* C5 J; u) h/ Y3 ^
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
8 J/ B) A- p( q! [  x4 \: f8 G              }1 N5 I3 G4 D5 o3 l
            ],5 k0 Z( ]* W8 F5 y
            "quorum": 1,
* R% g) N$ k$ {$ Y+ \6 B! O            "signatures": null,6 b2 N( S% @+ e' Z" C
            "type": "raw_tx_signature". v& q+ l3 `+ ]0 G# I& L" t0 ]
          },: ~7 e5 w, M5 T
          {
/ L$ C) \8 a6 g            "type": "data",% D5 x# C# d2 c! }0 r6 Z3 K
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"3 ?/ i$ f9 d2 x3 k! o
          }3 ?' l# [7 @" ~8 m* Y; [; v4 |
        ]( x/ e3 s1 e# m6 v. q4 G
      }. f! H4 y4 I1 ?
    ]2 F; _& x/ E2 {1 B
  }
4 }2 J  U0 E2 a% Z1 L) @}
; O7 F& A6 n! ]) x对应响应对象的源代码如下:
2 R. m8 b8 T4 v# s; l) M6 g/ utype request struct{2 M1 d8 A# `9 I) N5 Z
        TxTemplate txbuilder.Template `json:"transaction_template"`
* C6 [- A5 s& L8 F: o}; A8 q6 j$ L- X. H' r; |9 D' _8 y+ v
// Template represents a partially- or fully-signed transaction.+ ^: B  a8 t+ J0 W; d7 k$ H
type Template struct {, V1 V, s- l2 {/ N
        Transaction         *types.Tx             `json:"raw_transaction"`
5 Y8 _) c3 J9 v" w7 r        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
& H! x2 h9 m, ?% |: W+ C  ?        // AllowAdditional affects whether Sign commits to the tx sighash or0 r9 ~5 D1 Q. B% F5 M) K
        // to individual details of the tx so far. When true, signatures' c" S+ W$ Q8 d# d5 N7 R
        // commit to tx details, and new details may be added but existing
8 _' n. G: v% Y" i4 B1 _        // ones cannot be changed. When false, signatures commit to the tx
4 p2 H6 y/ r/ c4 m        // as a whole, and any change to the tx invalidates the signature.8 E% P, D3 @& _3 P; G) `, d6 l
        AllowAdditional bool `json:"allow_additional_actions"`
; x! {8 I$ _# I1 }6 w, a9 ~: J/ T}
3 z# Z4 @1 s: ^/ U# T其中TxTemplate相关字段的说明见build-transaction的结果描述3 g0 b+ q* ]$ j+ P9 b; v. }: @
调用estimate-transaction-gas接口成功之后返回的json结果如下:+ n" Y/ F/ D+ x* W# S
{) I+ A9 i8 e1 J0 \
  "total_neu": 5000000,) H0 Y% O: k7 f0 v
  "storage_neu": 3840000,* ^' y# Q5 V  d  z. ]* n/ b
  "vm_neu": 14190002 ~, w3 U- S6 I# R
}4 J6 m* E1 N' ^7 X3 v
对应响应对象的源代码如下:9 _" g6 H. Y$ @
// EstimateTxGasResp estimate transaction consumed gas
' y; v1 [: x! o5 G; K/ C- ktype EstimateTxGasResp struct {
- i3 S9 @0 [! [; A! W. p        TotalNeu   int64 `json:"total_neu"`
2 e; D4 H, `& a* ]        StorageNeu int64 `json:"storage_neu"`. G) m9 |5 n, Z7 `& L* M( C6 J
        VMNeu      int64 `json:"vm_neu"`1 w9 d8 E3 d- N2 k/ R, p+ }
}
6 _% U7 @& @; w  d: `  C# a. x结构字段说明如下:% V  p' m+ ?9 g- X, N6 T9 }
TotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
: r9 M: i2 \. b% K- [1 }StorageNeu 存储交易的手续费
9 ?  R$ k7 C7 [VMNeu 运行虚拟机的手续费
: |8 C- x! A( M
0 O7 \" y' O9 U, n/ t2、签名交易
/ \! Y( {) V0 Q& L4 eAPI接口 sign-transaction,代码api/hsm.go#L53
4 B% r6 m) }4 U1 {9 M2 n4 g/ w- \' \签名交易的输入请求json格式如下:: G& C9 \( s3 a. |
{9 w/ M3 G$ m' I# V( A6 p9 f
  "password": "123456",
& @% k. E% v. n6 }0 O  "transaction": {; j9 `7 O0 ~* S; x) N: M  B7 m$ k
    "allow_additional_actions": false,2 f9 H7 y& `2 Z0 Y
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",& r: m6 h( n1 M% a
    "signing_instructions": [. y' w! q& a; ?8 v
      {5 I- T( Z6 A, S8 }) B3 S0 g8 A
        "position": 0,
8 @! b) w6 U! g6 a4 Q        "witness_components": [
4 F2 r- A) C  X0 T' g$ L/ q% F4 t          {, o7 f0 D1 C0 p0 e+ x
            "keys": [  {% F, }4 X$ E% a# w  ]
              {
) R2 x3 ^5 l9 i' p) \/ P                "derivation_path": [
' D- d- ^6 C: V; _                  "010100000000000000",
) m; Q; M! p+ y6 g                  "0100000000000000"
- v  O7 l6 Z1 v0 T# \6 v                ],
& J; c" q2 @" X; Y+ u                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"! j8 @. u2 k/ J
              }
# [; Q" H# m! o: x* c) O            ],
/ R: K& m' V) s* `# [7 q            "quorum": 1,1 a2 B5 H' E* ~
            "signatures": null,1 r+ f+ r" S+ }& L) l: U6 @
            "type": "raw_tx_signature"
' e  n3 x; `! D- S          },; I( C9 U8 G/ u2 m3 {
          {& M4 x. N6 y6 q: _
            "type": "data",1 E+ h/ J, o) M" F1 a: D
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
% {0 _) r$ v2 l1 j          }$ H9 a, s5 p5 T+ t8 q
        ]
. `5 K! E! {: |; x      },
* ], [6 R) r. O      {" n7 t7 ?* o9 x
        "position": 1,! O; K; y3 w0 \! h3 ]' Q
        "witness_components": [
- C- t" U3 u0 V% S' x- D          {% b2 Y0 v8 ^$ a  V  \3 h
            "keys": [
" t# U& V+ G- s              {5 G5 Z( H/ _3 i. n% ~
                "derivation_path": [  |( m+ W4 J. O3 G( N0 h
                  "010100000000000000",
* H) _3 J# y4 K3 I( k: P                  "0800000000000000"' u! J- j( d$ f# Z
                ],* L4 U, i8 p3 o! N: `
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
0 Q; s/ u, N" n  j) |5 u( B" R              }- |6 [  o& s: C# [! K3 i% w
            ],% p7 V. p4 T7 ?, C2 i# {
            "quorum": 1,5 y  V; S$ t1 z/ |
            "signatures": null,* X9 D" ?+ t' f. \( x! L1 z
            "type": "raw_tx_signature"; i/ l- W0 V  `' H4 l, c9 I. }* k
          },
! s. O# P" }& E: M% N2 Y          {
# O0 s4 w, R3 \9 ~* y            "type": "data",
' ^, [1 j* A$ i/ [  i& \, n            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419": p8 J. E' I6 P- z" U
          }
. a6 x  ~: s" F7 g# g4 E- p        ]) m. Y" }6 g/ P- }2 \
      }1 f3 a! N* R; B
    ]
, g& g* X: u* {( [  }! ^: z& b' \+ X0 d# z5 q
}
! z2 @5 O& \: p% c4 n# m& L对应请求对象的源代码如下:
7 Z8 O0 V9 ]* o6 P  b3 Q0 {5 etype SignRequest struct {    //function pseudohsmSignTemplates request
0 X4 I' P; n+ u$ a        Password string             `json:"password"`
* q9 a( P# b- h' y9 r0 X8 W0 D        Txs      txbuilder.Template `json:"transaction"`! u' l0 Y# r5 M4 e
}6 t7 e' D& q$ l* A: v* _; d7 F
结构字段说明如下:
) q! `' U3 h6 y2 H& y1 N+ yPassword 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名
; N1 T4 e  V0 C0 B6 uTxs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述1 j4 v$ I7 l; r; o& g
% |" Z* {( \! }9 j/ M; W! X( O1 f- s
签名交易sign-transaction请求成功之后返回的json结果如下:* d( G! w* l2 r. t; H# \  Z
{$ L# A  [2 s% }' x! k
  "sign_complete": true,. q8 u1 S0 s. p( l, D: b# S% w+ P0 u
  "transaction": {, X  I, p, p6 \; u( k9 k$ s
    "allow_additional_actions": false,9 y( j& ]5 j2 [4 g8 n
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
  K3 J% D. Y7 v, R# Q2 M    "signing_instructions": [
; z) I/ Y+ d$ L" P- ^  M      {
- L4 l4 r! _! O$ ~: Q% J  |/ L) S        "position": 0,
; f- B) L  P% P4 T        "witness_components": [" R( M- w0 d' t+ y/ j
          {# a' ]; g6 X, m) h+ s
            "keys": [+ s" [0 I! j& @5 e3 _) x3 f
              {
& \2 [) a2 [6 V) F8 L                "derivation_path": [
0 V- ^2 O& n! ^" l4 G                  "010100000000000000",/ ?( X2 w- X- C7 n
                  "0100000000000000") H* w. e# h& m9 o6 A: ?- m; d- V3 d
                ],, Q5 t2 x) J, f* o2 b& Q# R
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
. e4 a1 e9 d; H. p0 l              }
5 C% U  X" R5 X( ?9 m( A! c; _% Y            ],
. q  C* k5 H( H, l2 u5 d            "quorum": 1,
4 H/ L) r: Q+ S& E6 D2 l            "signatures": [
' s6 j7 l- P0 E: E2 z% R$ p! u- A              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"
- S% s( Q9 f& w! h8 q            ],
' Y3 o& @7 T& |' T6 R4 u5 U            "type": "raw_tx_signature"" M+ Q7 c' j  F: ~
          },
) w9 C: ?, i8 q          {9 E+ ?0 |* t' M0 A" [& @! e7 {
            "type": "data",; c$ i, G% }/ Y- Q2 C
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
- ]9 o# d  o9 x3 m          }
( j, ]5 Y" g/ W' e/ s/ H# g        ]
, e- E/ N+ V, e1 N' S6 Q4 u  [) R' m2 p  f      },: ?/ O6 c- {) ~; ~
      {+ S. U+ ~4 ^/ h
        "position": 1,
+ V7 O/ o- A3 M0 J3 H- E        "witness_components": [6 k; B- a: E3 I2 D
          {% A: e6 t  s+ C9 c+ P* e( |* Q
            "keys": [
5 I- e+ |  L- o* u+ q/ W, W& s              {
- y! I3 A2 E" a8 _* j3 M                "derivation_path": [
1 x. P% H# V6 s$ H) Q7 ?% T2 z! y8 ?, D$ b                  "010100000000000000",; j7 ^& V; y, u) _" ?- T
                  "0800000000000000"8 X$ `3 q' [* g, H) E, G$ p
                ],/ Y: J2 }1 o9 k: O1 ~
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"6 V2 N# z- G! c
              }
( m7 Z  i  r# m; \/ L5 H' g% b9 x            ],
" k0 O4 h: f, m3 {* T3 m            "quorum": 1,
! K* F+ d& R% S+ s# F            "signatures": [
- D' X- c" j( z; l* P2 X              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"
9 T; k+ I- |4 A6 B0 h+ V            ],% q$ F, ~5 j  h, ~8 R7 K
            "type": "raw_tx_signature"8 i' ?+ f' g/ K! t" b8 e& O
          },
6 y2 a; _) v2 \$ I! h* n6 h9 }4 Z2 ?          {
- B' M% T& D7 r& t0 f            "type": "data",, M+ `' ]: U/ I0 v
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"6 }( }) b0 z2 ]2 g3 P/ Q$ Y& n
          }* R' g4 F8 Q- l+ f1 Z
        ]
: M4 G/ v8 J9 y& n' P      }9 ~7 Z  B3 F9 l3 w
    ]  B2 Z0 q1 R) q6 ?: F8 ~" o
  }
% Y* p! d- z- K* r}# d+ [+ D# I4 y" ]7 M. u$ }
对应响应对象的源代码如下:7 _* y; q' L1 E" r" g
type signResp struct {
/ a0 s/ K% @! J3 k- h; D        Tx           *txbuilder.Template `json:"transaction"`" Q: C! p1 R: K* S# f; d
        SignComplete bool                `json:"sign_complete"`1 x5 ~( |4 p7 `
}
. t) F% R7 g$ n6 d2 ~7 P" w$ u结构字段说明如下:0 a5 ^& S  A( M" ]
Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息3 \- @4 j, p0 c+ ^: y
SignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易+ c2 x4 L" t6 D- K- [
3 S7 V% y: s. D9 r# h
3、提交交易" N) Z# J$ Q; p
API接口 submit-transaction,代码api/transact.go#L1351 \! `5 \- G" f" v/ f0 e3 a( r4 x
提交交易的输入请求json格式如下:0 m# ~& F- |1 P2 X, s9 I: n
{
* L5 U0 l6 b% e* m  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"+ p+ u8 l! A6 b) F- g7 g
}
, T* F: S$ a& ?2 J. S  n$ E" R( W对应源代码的请求对象如下:! v# C: t1 w2 X: r! L
type SubmitRequest struct {    //function submit request
7 p# Z8 L: V; F3 N- A9 j. g        Tx types.Tx `json:"raw_transaction"`: U* Y2 K4 `4 \! n- _3 o2 F
}; g5 C$ t5 w' s. m3 S6 o+ x  e
结构字段说明如下:3 @8 E. w2 \0 @" a5 b! `- V7 s
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。
) p7 z- b: t/ X8 N& j* ~( N6 @: {9 n  ]. n8 c" }% D
submit-transaction请求成功之后返回的json结果如下:
, g! K+ _  J, M% y- M  X7 z7 |5 p{6 {. y0 ~. U! G
  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"
, S( t9 z- y/ J: k6 X# F% p}# U2 f# k* V0 R$ s8 N6 A
对应源代码的响应对象如下:
& v. I& f% P* s: Ytype submitTxResp struct {
/ p6 E# g4 D, U. P* j        TxID *bc.Hash `json:"tx_id"`9 u4 R3 F+ g( G. _7 ]* n
}& ]- H4 J0 J7 \( q3 b( m/ \
结构字段说明如下:6 F7 N$ @7 m1 L1 k: w) j/ D, r
TxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败
( m! ]0 l$ l! t, C) B
4 X* y+ V& ?: S$ Q4 F. W' T( a* p
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14