Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
163 0 0
比原项目仓库:+ }) X( \; N6 A
Github地址:https://github.com/Bytom/bytom
1 B% [9 x0 C- R5 o$ d/ T* c# g2 D( bGitee地址:https://gitee.com/BytomBlockchain/bytom$ e' @6 O, \, X" [0 J
该部分主要针对用户使用bytom自带的账户模式发送交易
, }9 p. v( S) `9 @/ {1、构建交易
$ S* C5 I7 h8 C4 K: G1 Q/ @" gAPI接口 build-transaction,代码api/transact.go#L120) Q, J6 j# Y  ?6 p
以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:
  b, m' r# b4 `  [1 X$ t{9 b5 i) q! o5 p* @: Z6 Q* x
  "base_transaction": null,
: s+ A/ J5 y! F6 c$ T! F  "actions": [
4 \) N- L. C: j    {# `- I6 Z8 V" }! i
      "account_id": "0ER7MEFGG0A02",- n: X* X& ~  w) M: n) e; K
      "amount": 20000000,
0 b0 k) V4 x! q3 h/ u* X      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",, g2 Y! j5 q& y$ a. n
      "type": "spend_account"( l% r& D6 ?6 W
    },8 s9 D+ K+ c5 p2 h4 ?
    {
4 p1 ^3 r/ P( Q1 D& S7 c- J$ f      "account_id": "0ER7MEFGG0A02",
# N( J6 X5 L4 X' ^4 ?      "amount": 99,  F8 }7 r* y( r9 R: h' {+ S$ R( I
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
! T$ D) J1 |# s6 i6 C7 q      "type": "spend_account"8 q! i, g" e. Y+ l! R' q
    },4 ~0 q( `3 ^+ M
    {1 a' _' Q. e% w# ?; ^+ @
      "amount": 99,! `+ A: f# k+ y  h/ H$ ^  T- G" A! Q
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
+ _. j- w% S  D7 v" C. a5 f      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",% p4 H( ?& v  Y* A9 d3 A6 o, |" V
      "type": "control_address"7 Y! K& s9 d7 s& M+ [
    }
" d# r) x& v2 u+ _  ],7 w) T- [/ {: O3 }- E* I
  "ttl": 0,
% k* f) w) l7 B, s  "time_range": 00 H5 J! b! W7 R
}8 j' ~* P7 A" i$ w2 c
对应源代码的请求对象如下:
6 E' @% o& n9 r: _// BuildRequest is main struct when building transactions# u# g2 ^- r7 e3 v
type BuildRequest struct {/ l- n# ]  o& T" v0 x  ^6 I' j
        Tx        *types.TxData            `json:"base_transaction"`6 s0 L' R* w7 o9 M1 y: m
        Actions   []map[string]interface{} `json:"actions"`5 A9 s0 ]0 A5 s( p
        TTL       json.Duration            `json:"ttl"`
8 d0 E: k7 f4 r! J0 F        TimeRange uint64                   `json:"time_range"`
3 l/ F$ {4 E/ Y: n}; {: V: A) f0 |" o+ E- c/ W$ y
结构字段说明如下:4 K& j  G( n$ Y1 n8 w2 K+ n
Tx 交易的TxData部分,该字段为预留字段,为空即可
; h3 T% l: o8 m, M0 WTTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟% T) i- J* B- o3 a; g* B
TimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
% h/ I. r6 c! x7 x% i3 t9 q- p; DActions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:
& ~5 y1 q4 h+ n- Y3 ^input action 类型:# S; S+ \7 S+ |2 ]& \) G
issue 发行资产3 k1 [$ p; M. x& F: H# g7 O4 `
spend_account 以账户的模式花费utxo' @4 k4 K  O' R# ~3 c
spend_account_unspent_output 直接花费指定的utxo
7 S4 o! C$ d8 Houtput action 类型:# b6 K7 b9 R4 ?# h' D
control_address 接收方式为地址模式
& H1 _: A5 j( i5 |) ]4 Ocontrol_program 接收方式为(program)合约模式
" q& S7 s# k% S/ G8 j: Pretire 销毁资产8 r/ f+ H! ?' S! r9 y: q) _- C- \
5 C( K) ?) c- g' V0 W" r
' F+ X* @3 B4 M& Q

. J! r0 N: J! W8 p! K/ j% i- I" p注意事项:, y+ Z( r. T9 M) u
一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。
# S  P& L- i0 P. H: c- H* U7 j除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。" F) \( H- |) v9 R. \9 W
交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量
& k: k; \% G' }: o$ Y交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu
" ~' k5 h/ E, m7 ?* ~. i$ q+ g7 k+ b. k9 `
action简介
$ k; |9 V5 D4 K$ X9 f4 v下面对构建交易时用到的各种action类型进行详细说明:
- C0 ~6 I( F9 eissue) U2 `; r! j# Y- y
issueAction结构体源代码如下:
* {. L0 F; E1 t; w) L! wtype issueAction struct {
8 j$ ]5 y& [' m6 z6 {' H        assets *Registry
$ A# g2 h* G. l( _# z3 d6 x        bc.AssetAmount2 ~# K) p7 z  ^6 o( F# U+ |* C
}
7 v9 i  T$ |8 v. H% u; z+ w2 z5 @type AssetAmount struct {8 o2 V7 X# M# l  _
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
* i$ a% M' o/ z4 R        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`9 }2 P& y% R. u& O+ U* J- b
}- i# e4 g2 y* t* A2 Z' P- a
结构字段说明如下:
3 B) e! e: u1 y! o+ D0 S" m) Iassets 主要用于资产的管理,无需用户设置参数
, A# u, A: D2 z& ZAssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID8 T5 K# |: p6 k' S  o: k) I" @$ P6 b
, `! K. v. e# ?. G
issueAction的json格式为:1 N' s, K9 Q! h; {/ X1 ]  E
{
1 |# F0 R7 p# I! A  "amount": 100000000,5 R! e, j$ Z! D$ Q- T
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
- g* |5 R# D/ L% s" @4 H: ?- \! x  "type": "issue"
/ j1 [3 e1 o# A+ g! s) O/ R}
5 |. w. E; X2 r/ ?例如发行一笔资产的交易示例如下:
: f, O. q$ A$ Z# |(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)  E0 g6 N- S+ V# h: d9 a
{
2 v! w, y5 r3 P' x1 T. ?  "base_transaction": null,. ^8 y& A# a+ u: i1 _
  "actions": [, U, ?7 V4 D9 w9 Z% k- z7 ~
    {3 d! Y4 K9 G+ K* x5 ^% _
      "account_id": "0ER7MEFGG0A02",* t" e  M, @. P( l; y
      "amount": 20000000,1 d4 {* F7 F+ R" d5 W3 ~
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
& q/ v$ Q, }% l8 @8 z* s      "type": "spend_account"
5 Y" \  D/ r: c    },( I: |% m5 O' [" a! \
    {
) y" v" q  t7 V5 ~  {( x7 a      "amount": 900000000,( P( @) O4 Z% Q5 c5 t
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
: [; j; A1 n* L, I  w: ~+ w" U      "type": "issue"% @$ t4 ]) m# M: C. P  L/ r" d
    },
/ z1 |1 g' m. B7 e  s7 C    {& U! c% X3 }" i- B
      "amount": 900000000,& ^" x* `# E6 H
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",% ^" I; m/ M! H
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",: s) m/ p! S) }; `9 E
      "type": "control_address"
/ G* Z6 s3 y0 z5 V1 S    }. C  \& {- q3 G/ S: [5 ?6 ]3 w& F
  ],
1 ?" b* w" l( {1 \8 F  "ttl": 0,
$ v! I( I/ T/ L/ h1 W' I, q+ M  "time_range": 06 u, C& l. h5 @3 D& X, X
}
- X& @8 `8 |1 }$ I; e- ~* ?2 A( h
. N$ Z& L, Z3 Mspend_account
* e, G  r; I+ @: u: GspendAction结构体源代码如下:1 m4 q8 |( W: O
type spendAction struct {/ \" x( N8 ]! S9 f( y7 x
        accounts *Manager' f6 F$ f% }: L: w7 r0 J
        bc.AssetAmount
9 x- k$ t! @+ P' D$ k        AccountID   string  `json:"account_id"`7 O/ i( [4 @( P" c
        ClientToken *string `json:"client_token"`7 x" _) {. y9 J4 y* z' D' f% o! W
}
/ t2 K7 d. `9 m2 ^( J+ c2 ctype AssetAmount struct {# E/ C6 ?3 W2 P7 @2 q4 e4 u
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`1 I) T0 I4 W3 G3 _+ `
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`5 n  a& x- X& F; y0 }3 Y0 T
}
4 v* r& C; i7 u& y- K7 }结构字段说明如下:
, U4 R% ]' I3 X8 m" T% t% B' Waccounts 主要用于账户的管理,无需用户设置参数) w0 f- E& B) r& G
AccountID 表示需要花费资产的账户ID/ {6 ~  a# P+ `* y7 F7 \5 Q) |0 V& z
AssetAmount 表示花费的资产ID和对应的资产数目
' T# O; Z0 O2 Q( i6 t/ bClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可  y1 i$ m( q8 u& R. D* X. x
& o& M8 {7 N: w& p
spendAction的json格式为:% ?2 ~" i9 }" g  l- r; o4 ?
{
9 @2 m; L1 [6 w7 k  I. H  "account_id": "0BF63M2U00A04",  n6 H+ _  _7 m3 [
  "amount": 2000000000,
; f' C- H, s; M( [* Q* h  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
9 R6 C. K0 x7 h2 w9 Y  "type": "spend_account"' k4 V/ v1 [; o2 k  Z0 G1 a- j$ ?- A+ ]
}
) Y& `! i' G" v$ V例如转账一笔资产的交易示例如下:5 T7 W. v7 h9 t* w% S9 Q9 G
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)9 j/ U3 `  U" |3 ]
{
% P- I7 d! R0 d" h3 g' d* o  "base_transaction": null,+ m% }1 L; N8 o3 y
  "actions": [
, l: c5 W8 x# {8 E; A: g& t    {
# p8 s7 K* A; d# n2 |) f% W$ y      "account_id": "0ER7MEFGG0A02",
7 k, {0 W; [" e! V      "amount": 120000000,
( O9 h. d% x; Q4 k9 E3 w5 x      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
$ x5 Q# `  X  I( _$ F9 Z  g& C( W      "type": "spend_account"2 j( Z0 a% n4 t* W5 W
    },# [& F$ q4 I; J- X+ B% O
    {
* ?& K0 M* k+ z% I6 e* ]: X      "amount": 100000000,
- E$ C4 ?. f  z      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",% |/ L" n& x. M8 [) Z
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",9 p- `$ j# h, P/ B1 Y. @
      "type": "control_address"# F& C3 u+ G& y( L2 T' g
    }+ ^3 G! Y" H$ {" S3 j/ n2 f
  ],+ |7 f! `5 v/ C& D/ {" }- a
  "ttl": 0,
( u( m1 R3 d6 I+ w1 {  "time_range": 0
+ [8 {, [  [, t}4 z) b: r; @. i8 v+ G5 O& g
* u8 y, I: I. y# L7 [( s
spend_account_unspent_output
# E* B/ ]! e; x' n1 e* J& dspendUTXOAction结构体源代码如下:
. \$ f( t* |( Q$ P: qtype spendUTXOAction struct {
/ }: a* A; h$ F' T        accounts *Manager
" [5 ~0 {! u6 Y  y. J        OutputID *bc.Hash `json:"output_id"`
- \( y" s4 Z  `        ClientToken *string `json:"client_token"`" r4 i( J& j+ A& C' o& b) J# ?! Z
}
+ I; l+ t0 s% b: Q; p/ M; D% v结构字段说明如下:
; n( s( I! E% R% u7 F0 Taccounts 主要用于账户的管理,无需用户设置参数7 Z7 P2 W$ V/ S4 u
OutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段& g1 Y2 o* g8 z- i
ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
/ v. e7 D+ [! N, g- W% c
0 X1 S8 J% {7 o: }! j! G! ZspendUTXOAction的json格式为:8 K& P  ~& }/ P# B2 Y
{
, J1 _* t* F( ~; H  "type": "spend_account_unspent_output",
6 ?9 h  n# ^- L8 s% K- O5 S0 ]  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"
- _6 Q- C- r. w& @* I}4 {4 j! X: m9 q- i
例如通过花费UTXO的方式转账一笔资产的交易示例如下:' i& S" y( u* L2 V% R: C% a
(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
( `6 P& G3 N6 \4 c) [" L{8 g8 v; O0 [! J2 X7 {8 y' u
  "base_transaction": null,$ p5 w, f1 z( h
  "actions": [
' B- b" K- C% N( q# E9 C    {, M. J5 M8 O% {  h. C& Y0 p
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
: H! f# e$ n( l8 I      "type": "spend_account_unspent_output"
' |8 }3 w( b5 x" Z1 b& C- T    },
# V; o( S" |& E    {5 j' k3 `2 w' Q& S2 \$ [; J8 f$ g
      "amount": 100000000,
1 z/ L0 u1 [: E! a" k      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",+ {7 e  g9 [  t" O$ N
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
+ V7 n8 }( ]1 \7 [) o      "type": "control_address") `0 ]' y& a# J6 t* z. a
    }' P8 C: M# A/ N- P+ ^
  ],
1 c' J7 ]2 i5 \/ ^2 \/ j/ L$ g( x$ e  "ttl": 0,
* @1 h+ E3 J3 g6 B, J% M  "time_range": 01 o* p' ^+ E  z, e( T9 t' i
}
: B& M+ k$ c# K+ l. F$ T. U& D- B; F  e) r+ b
control_address' v1 {- K& k' M0 ^! t: I; P+ ]
controlAddressAction结构体源代码如下:, I8 L6 e  a0 i' l" U6 ~4 a
type controlAddressAction struct {7 X$ r5 O  F& n0 m# S6 m. E7 `, ~& G
        bc.AssetAmount
+ a+ Q" F4 a: `        Address string `json:"address"`
; I& c' ?( n, c, D$ L7 u}
* I: y% k) V8 n. D- {8 Ttype AssetAmount struct {4 A# |0 C, R" F: u& O4 b4 Q
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
- X& `( W& u9 P4 l; C0 Y) H- \% w, x        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`5 a+ D: i+ f+ i6 W
}8 ?) h- a1 g/ i7 c, p) j+ q% L
结构字段说明如下:4 Q+ @5 n. z' S, F' Z( B, I
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址- k2 S; ?9 F) Y- w
AssetAmount 表示接收的资产ID和对应的资产数目+ Y5 j% W( w+ T0 L* n9 h

$ w9 ]) ~  F! Q& P' h: tcontrolAddressAction的json格式为:
* B! g. I, i1 z{
7 }. `# P3 v: G+ a$ n; g' d' v  "amount": 100000000,
* W# x1 s; y" X/ v: q  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
# b  Z# h  d8 q( G  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",4 T& c$ Z9 y' o+ d/ k! M
  "type": "control_address"
; G/ Q" \, m7 j: c: V3 E}- z$ P7 X3 D1 z
例如转账一笔资产的交易示例如下:# ]6 J* G  j) t3 Y& O$ m
(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)' i2 i  D% B; q: i" B. A, ?
{& a( ]: n7 g; X6 u2 L, w4 V
  "base_transaction": null,% ^4 Z, |% H' s! e" l; [
  "actions": [
6 Z, u2 t; M- m+ n) U# I/ ^    {. G* ~3 S% r$ c
      "account_id": "0ER7MEFGG0A02"," b. e& e6 Q, t& L+ w7 v$ e
      "amount": 120000000,
; ]  [3 S9 A: D& _( c9 \      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",: X2 d' m  E) G) |$ _: z
      "type": "spend_account"1 s4 c  U& ]8 m7 e  s3 O, P# {/ P
    },
' ^! v! a: N/ i) ^6 M    {
5 ?2 j4 [/ d( |# J: j8 }$ C7 y      "amount": 100000000,
- h/ P5 q/ W  l5 R4 n  n      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",! @' ]3 W* ^. o9 l( H
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",* I; O$ E& @9 d+ m( Z
      "type": "control_address"$ F  }3 Y4 U. ^( ^' A8 p' h
    }
' Z2 Z" E) l2 j4 h5 X* }: V4 d4 n  ],/ Z+ Z6 y9 k7 P4 p9 u' A8 J
  "ttl": 0,% j% P! U' S4 D, @2 m9 c3 C
  "time_range": 01 R0 J; e! ~2 y  V6 a
}
; ?# d( @7 l' f9 F
* u3 q. g. F0 n+ ^" q, V; ~1 t; Ucontrol_program
) R# s( I1 ~1 W9 D1 a( VcontrolProgramAction结构体源代码如下:3 @6 N: \; {' d/ a' s- H; x6 Z8 r0 q
type controlProgramAction struct {
# l6 i5 [) |. y% G; O3 C, I# I" c        bc.AssetAmount: a& Y& I3 ?- b# N1 O
        Program json.HexBytes `json:"control_program"`
7 K1 a  n  \* ~}& i2 \! g+ M: B4 [- G
type AssetAmount struct {
: j% w/ n7 i& M        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`& u7 Y5 x  l& z9 c- e7 u, e
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
  [* C8 E  b* ^! `( t' M}$ [4 r* _. |5 ?. e$ [2 T
结构字段说明如下:9 S( ~  Q! N' x/ A' M  S/ r0 N
Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)
) T" Z: L6 Y! T, TAssetAmount 表示接收的资产ID和对应的资产数目
0 p  o* k% V0 \/ H! ]( E3 j: g1 P+ {! J. q
controlProgramAction的json格式为:6 m( t, |3 Q1 P2 H8 u' M& A4 P7 {/ v
{
' M4 p; t+ Z. l  "amount": 100000000,
: a# W6 ~1 l( ^6 Q  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",4 g4 Y' r+ l/ q+ Y. I2 f9 [8 n
  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",9 |1 ~( `. y  g' t  t
  "type": "control_program"/ m& ]1 P! r1 ?2 r
}
; c- Y' G- z" k- D* j例如转账一笔资产的交易示例如下:
) M2 u5 W3 I" S(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)
" j, D6 G7 F3 V5 s{" Y  e9 s6 g- q' R  [
  "base_transaction": null,
; J- |$ ?8 {# S  Y, }; N" ]  "actions": [
( I% o8 w7 M( ~    {
4 h, @) b( \, Y+ h      "account_id": "0ER7MEFGG0A02",
; I& S8 \3 ]+ f" u: F      "amount": 120000000,9 M2 o8 G, H2 ?( Q9 W% j
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
) }8 P" B. S- _: X      "type": "spend_account"
# t  B# j" |0 Q: a* b# X: \  |0 o- t    },
. z2 F0 x. @. @/ r6 e% Y    {$ f! l( M0 f) V. y+ c
      "amount": 100000000,
9 P+ i$ c: I) X' o5 \6 b6 L& @      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
( i" N: [5 T" {      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",: V1 M5 P) Y0 L
      "type": "control_program"
8 A) B* v4 u6 D9 |6 T    }
# V) f- k3 L! r$ F  x) Q  ],
6 [8 U3 V6 }4 j  c  "ttl": 0,0 a3 e0 T" I, Q; D. V& Z
  "time_range": 0
1 g* M( h$ ]: I3 f0 H  {}7 g, o( }, `4 N& [; o" o' l
: G+ I3 i6 a* b/ p& }
retire
- L+ R9 R) w9 LretireAction结构体源代码如下:2 P# V, [$ a3 i7 h) `* M
type retireAction struct {  W" z1 k0 h9 b! l/ `+ s4 {
        bc.AssetAmount
6 o+ b: C3 y" K; B2 W}
8 a# R4 U: R/ Y' N  Dtype AssetAmount struct {# M  d. u5 I: b4 U& D& t# q) N4 e: A/ w
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
6 Q2 c" S& K7 L8 O        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`* u6 ~' D8 ~" D+ o1 P, l
}) g5 U  y! N& {0 H
结构字段说明如下:9 L& w* n2 }8 Q
AssetAmount 表示销毁的资产ID和对应的资产数目
' z4 P4 c% F. Q6 w( _1 g; R# g! s: J, `
retireAction的json格式为:; s+ [3 S' g6 Q, b
{& W- L+ [; e$ k2 B  K& d
  "amount": 900000000,4 z0 v" I. H  q2 {- T
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
$ v, w, I4 S- R- D, n' i8 ]  "type": "retire"
5 k! v- L. Y7 e9 Q2 F  u4 \! ~0 r}
2 o5 }- m( X" B0 R% O5 e: K; W例如销毁一笔资产的交易示例如下:
& K  F9 }, `8 ]$ [+ a$ b  X(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)
8 m% n' l& F3 h{
* Z# h( d* y  D( y, Q. A' {9 r/ G  "base_transaction": null,
4 K" w( n- V% q* [: y. D  "actions": [. B; Z  \( l1 Q$ V8 _6 E
    {* x! }) C$ x* F. l9 _' B
      "account_id": "0ER7MEFGG0A02",6 M- d2 [5 e3 X! m
      "amount": 120000000,# ~# `& l0 F2 K9 r  l2 W/ ]2 y0 l; P
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",/ p) f: G8 t+ i) g  `8 @( U
      "type": "spend_account"1 w. i  ]; U$ |2 N6 m
    },3 C+ U, J6 h$ d( W! U# G
    {1 z, L1 v% O: G1 ^' ]2 z! G
      "amount": 100000000,
' t5 B& F8 ~' v, _: A4 {# n      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",2 ~; b% A: b$ A5 q9 D) D  _
      "type": "retire", j! e, t$ r$ j* K- ~0 W
    }
4 \/ x1 w' Z7 [- K4 R! j  ],% {, T% k, V% ^4 M1 B
  "ttl": 0,9 N1 r& O  j4 t) j8 b$ p9 m
  "time_range": 0
' A! H. r/ L8 R' S! W0 [  R4 @  i}  ~% D6 }' P! a: p0 D5 d5 F+ f

# |7 ?2 |* h. s0 I+ ~: U; kbuild-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:
: x: v  T$ T4 J; i! d  v* Q9 z0 Z" g{! x9 s, m& S/ F
  "allow_additional_actions": false," e5 F5 n4 c+ M) \3 p/ K
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
5 S; _8 }  B$ u0 s0 o" N4 ]$ q; o  "signing_instructions": [: F$ c+ D; W5 r* c$ u
    {7 {% x/ k8 N0 K  r. ^
      "position": 0,) G  l* ^& \2 X' D' u  ]
      "witness_components": [
' G( m0 R- V1 W9 l" D        {+ f+ G) ^; G# x9 w. F8 m' {
          "keys": [) s  q% I- Y5 r2 U% p# W5 V
            {: k+ z( x; y) w
              "derivation_path": [
6 p4 E9 N% }0 p3 D" C4 }" K                "010100000000000000",
3 O3 ]: |0 O% T" h. z                "0100000000000000"
0 b: c6 |' N/ |+ l9 I              ],% u2 K1 T# _! N% }5 ~! T& j$ |
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"5 q- T' M( k' n
            }
) J3 D7 {' m, d$ r5 S3 g9 V; R          ],
$ ]5 T- \. G3 j+ a% m* x: Y& s          "quorum": 1,- j6 [1 d* h; z+ K0 v+ m. {
          "signatures": null,
. {+ {4 s# l4 H. s6 K4 h: g% L          "type": "raw_tx_signature"
) @" }" k9 `6 z" c        },9 O+ R( P/ ~- @! M: i7 i
        {7 p* n- O5 O% x4 f
          "type": "data",) h3 \# R" ~, T% w$ W
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"' G6 n: s1 B" j* h3 l2 R* I& R7 |  k" j
        }3 X7 X2 J* M$ X4 M3 d/ U- K
      ]* f& A$ Y  A, V2 f% d
    },$ M0 Z9 X* d) n- n" S
    {
+ B& I8 D+ \0 X" R* E  }# [. m4 I      "position": 1,+ @  `  t4 P$ L) b3 i' p) j
      "witness_components": [  [! ?/ j/ a! m+ t, F  O3 X
        {
' G- [2 s3 O$ \          "keys": [
3 ^# c# M$ {& v, O5 s7 L, E            {# ~2 i; ^. r# D% M$ Z( n' H
              "derivation_path": [* |9 d- N9 u! m3 V" T0 p# H
                "010100000000000000",
  _. w& H( i. g# i* e                "0800000000000000"
9 T! z! e+ @4 F' ^8 o              ]," c8 U+ o3 G- H2 Z5 R/ B! J! g
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"9 E0 S- h4 ?1 \. g1 e6 J
            }- N2 F5 p  i1 ^8 Z' n% ?
          ],2 B. m/ |9 t( x  N
          "quorum": 1,
+ j: s2 I! `7 |4 ~/ |$ b& x* F+ t  l          "signatures": null,
, k2 d+ P9 [% y+ T! H# ~9 y          "type": "raw_tx_signature"
/ H5 O4 @+ R7 [0 {$ j4 S        },
/ M' u" K- m  Y, |. w- Z: d        {* t/ s+ {! O, W1 P  S& y/ h
          "type": "data",* Q9 l3 T3 E* l1 O
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
: s( K! t. Y" h        }2 q$ O/ Q4 A2 @% s
      ]/ K7 X: C, N8 A0 Y3 ]
    }
, z2 Q' b1 j* p9 u  ]
* e5 M! ?6 P" h$ _}
! G( C8 b7 G) m7 x对应响应对象的源代码如下:
- N' H! w4 s4 [- s5 N// Template represents a partially- or fully-signed transaction.8 v2 l4 S  u3 ]" _5 Y# N
type Template struct {
9 Q. V6 y; [. T6 \# |        Transaction         *types.Tx             `json:"raw_transaction"`$ M" c6 A/ h3 r
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
% }5 G9 ^! l( {- s- {        // AllowAdditional affects whether Sign commits to the tx sighash or  x  R8 D( ?2 K3 o5 Q* h
        // to individual details of the tx so far. When true, signatures
. i1 {4 I$ Q8 ?9 x5 j4 {+ E        // commit to tx details, and new details may be added but existing
  `2 J( T' w. V  T9 U# I- @+ y        // ones cannot be changed. When false, signatures commit to the tx! |( {5 \: S4 B& f3 M, C
        // as a whole, and any change to the tx invalidates the signature.
6 c' D6 U0 {( i" F( {        AllowAdditional bool `json:"allow_additional_actions"`
" g- ^9 u' l, V3 [}
: V3 K" H  K1 u1 M0 ^! |( x( I结构字段说明如下:3 o! _7 ^2 t1 B( W  e1 u) r- q
Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:
% ?$ Z' |0 {0 k+ g: W7 x4 S4 xTxData 表示给用户展示的交易数据部分,该部分对用户可见2 y  h5 z9 c4 u/ D
Version 交易版本( l, e( z7 P/ y6 J% A
SerializedSize 交易序列化之后的size
: M  g1 l2 ]- M/ F( F9 B6 mTimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)
0 l, O# K/ O. F7 T$ S( M( b+ EInputs 交易输入  e2 A, b& q$ [. _# k3 n
Outputs 交易输出
9 S5 A( `4 f, z$ O) [5 H6 wbc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述
! h  a$ Y& P) V3 Z! r6 ]+ ASigningInstructions 交易的签名信息7 E+ n) G, ]/ _" Y8 j
Position 对input action签名的位置7 D) a9 j  {) ~; s
WitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:' M2 {, H" N4 ~+ T4 K% R- b
SignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名; z! }9 P7 J% S9 z9 O/ ^7 [
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
, Z0 O; y- j$ H1 k, hkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
. d+ B  e, F1 v9 D) T- c8 Q: G3 rquorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
% I1 V! W' m) b5 Mprogram 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
/ \0 b! L' C; i. y! o7 kRawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名" M1 _$ G" U( a, x$ ?) c
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
8 s# J4 W. C) I8 n6 hkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
8 l  V1 u* _+ |5 _1 ?( P: v( Fquorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户
( `, _; I3 Z# @, r" gDataWitness 该类型无需签名,验证合约program的附加数据% Z+ H4 c1 M( j4 t5 p: z
& a& h0 b  b$ k/ X" Y
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名* T/ i4 r* X# e% H3 X, {
0 a3 n( d  o7 G
估算手续费
/ A# m3 U4 N/ j; V( g, d/ o% X, i; s估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:
& _7 Z. ]' @) m  x$ G6 R  build - estimate - build - sign - submit
1 P8 w- [: Q$ Z3 Q: Z. Z估算手续费的输入请求json格式如下:8 l" f. v& A/ B- Q
{
1 }  c3 B* Z5 ^  "transaction_template": {
# v2 T, M8 K+ A/ K6 p& p    "allow_additional_actions": false,
+ Z: v3 l3 n& r8 T) M    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",8 E9 y* f" g! {, h- K- \( w: a* [6 {
    "signing_instructions": [
$ J: n; r$ u3 f      {
+ `+ u- ], w% i, @        "position": 0,$ N- {' p& k2 b+ m
        "witness_components": [7 s% g  J0 e4 b# E& k
          {
5 c" t- k% m7 d            "keys": [. M. e' H/ L1 H
              {" K3 y! O7 r9 i! [$ M) Y  ~
                "derivation_path": [0 d1 v% x: }4 [2 M: T# x% h. D- ~
                  "010100000000000000",# H9 s) |) Q5 b, z- p9 H
                  "0100000000000000"9 |2 g5 N: W9 y5 {9 w+ `
                ],9 u3 y# c% f" T7 n8 z  }) z
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"6 d# b5 R2 w3 W) i3 B0 ~( n; B
              }$ }# J& x5 \1 G) H* z4 P
            ],
  S+ \1 |. C+ U9 p            "quorum": 1,5 c  f! p8 Z" j8 L
            "signatures": null,7 l: K# U. l2 I$ B" O7 q
            "type": "raw_tx_signature"
4 q. n; P3 Z* L4 O  n          },5 q. F9 Z9 a) k% m) V
          {
( `; h; T% h8 L2 |# w, f# b0 ~            "type": "data",. W- W8 H4 E! J" s# D! N- T* |
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"# r6 I& g- }: v, d+ o8 g
          }; h3 y, _4 f4 p0 P% V. J# o7 W7 q
        ]
: X: N8 {9 g$ O/ X& w; m      },
4 [+ ]9 j  o8 F+ z3 s# i4 l6 Q+ j      {" v6 o# n# Z& T* W# _7 k& E: u
        "position": 1,& j, ^& O1 U- U& N# S. D1 S* D
        "witness_components": [7 t- _1 D  C* ~
          {) M! I, L; ?* J! m
            "keys": [9 H1 P: N% n# B* q% g
              {
; y- L2 d" H) o                "derivation_path": [
; Y1 C) q2 l( q# U) I1 b' ?8 x8 c                  "010100000000000000",3 y8 t; Z& C" n+ X1 t( ?6 ~4 K9 L) m
                  "0800000000000000"
5 T1 V3 h" M5 ^3 F                ],
# e0 \) k, h( P4 @                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"  y: u; H. L8 i  Q+ J/ ~
              }
5 b4 \* v/ ^, p( L, S8 Y; R- j            ],$ W) L3 l/ P9 I8 V
            "quorum": 1,
( E6 l8 ~0 h+ @3 [( H( w            "signatures": null,
7 P* E0 O* i+ a  S+ J2 e. J            "type": "raw_tx_signature"
9 y1 t0 Q1 A/ s5 h4 z% r9 P          },
; t4 e" L/ L% H          {1 V# D( K7 g( b( o8 O, X. i
            "type": "data",# h' d6 s/ t, e, a1 g2 e
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419") f. r) w: I/ A, q# ~$ q# q
          }
1 V5 R' z1 y6 T1 ~# C        ]* u- u% t. q  O$ B
      }/ q' q7 U' O3 @+ S% e( W: C" N: ]
    ]8 T. c. B$ n' L1 G5 q% a$ {
  }3 h9 {/ f5 T0 ]3 }8 Z% C2 S
}9 M8 U1 F) c8 ?) @9 _( Q0 F3 ^
对应响应对象的源代码如下:
' D( n) q$ Z. p8 y  Ctype request struct{
0 u$ J$ K  s% d- e        TxTemplate txbuilder.Template `json:"transaction_template"`7 u& k( u( P0 Z: H. H
}
/ w) n9 K9 T$ `7 y8 r// Template represents a partially- or fully-signed transaction.
7 l$ `- E" h9 htype Template struct {
. u! k6 z' m4 t6 Z        Transaction         *types.Tx             `json:"raw_transaction"`  U3 O4 e& k7 ?# c
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
( `, X, y( {4 k- |4 J. B. B        // AllowAdditional affects whether Sign commits to the tx sighash or
# |3 N5 F# N7 h) R  ^, t4 e6 |8 X. H        // to individual details of the tx so far. When true, signatures
  V* h# F1 ~' U/ W5 F0 V        // commit to tx details, and new details may be added but existing- a3 G1 a% l$ ~( @
        // ones cannot be changed. When false, signatures commit to the tx
: A# d5 q5 E6 `4 {  \1 v        // as a whole, and any change to the tx invalidates the signature.
. x/ T+ f' Z( Z  {. r$ h        AllowAdditional bool `json:"allow_additional_actions"`
8 D# B/ Q; d- L+ i/ y$ u' J: b}) o# h5 `/ I  m
其中TxTemplate相关字段的说明见build-transaction的结果描述: [) ^, \" W# R* r  m  V  U
调用estimate-transaction-gas接口成功之后返回的json结果如下:5 g6 i; F! ?3 m# N( {& O
{0 P  Y, Q0 k( i1 O' O
  "total_neu": 5000000,, ]8 v9 J9 ^5 }: M2 \) Y& }
  "storage_neu": 3840000,3 S" T, Z0 R# B6 y1 V
  "vm_neu": 14190004 C2 I' ]1 M% ?( d
}( ^% T0 E. P# Z* ?; w% t* b
对应响应对象的源代码如下:1 Q: Z8 D4 j" f4 M& t/ x: z
// EstimateTxGasResp estimate transaction consumed gas8 d8 n" {5 v8 z  l% E
type EstimateTxGasResp struct {6 s. h4 p" l! \! c
        TotalNeu   int64 `json:"total_neu"`9 I1 v- K  w: q$ y8 ]" x
        StorageNeu int64 `json:"storage_neu"`
6 v- Z8 V/ }- L2 U+ e6 a        VMNeu      int64 `json:"vm_neu"`4 b3 I0 j$ o5 z! x  }/ h8 z
}
: A' V& x( I8 h# p结构字段说明如下:
7 q3 N8 L3 N( I- a* e+ z6 ATotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可( Y9 C2 Q1 t# U; v
StorageNeu 存储交易的手续费
( @+ {6 u. I7 q9 S. N. T* OVMNeu 运行虚拟机的手续费
. d) _/ U; `% Z% e4 S* D
. R3 E; f  Q6 y' B/ j3 ^2、签名交易3 B4 k0 Q9 n  {
API接口 sign-transaction,代码api/hsm.go#L53
4 Z& G8 I3 a5 a% I9 ?签名交易的输入请求json格式如下:% A( J3 C; I! d
{# R- Y: s* {# s3 n: J
  "password": "123456",2 U( w, s% P) i; o0 v
  "transaction": {
+ ?8 G. ?. _" G% a2 l    "allow_additional_actions": false,/ R% h# A; F) L. h
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",  \6 a2 }% z# t5 P9 l
    "signing_instructions": [
2 E% e. F0 q: r* b' G  H# W      {
* G( {# y" p, a5 t! e1 j& M. K        "position": 0,: \) x( P1 p1 x0 @. ?
        "witness_components": [: o2 F* k9 `5 J. `' g/ l
          {
0 s4 A: x2 h) e            "keys": [
( M0 t- l. O# V7 N4 K              {8 P: J. Q8 m; N0 C
                "derivation_path": [
; h1 \8 U7 ]7 n! k7 a4 M                  "010100000000000000",0 Z6 A$ @7 q) J# R  y+ `! s
                  "0100000000000000"
. V: {+ J0 D  O  H                ],
; I$ l" G, y9 v/ b" O: R                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"" I/ V5 z0 O8 ]3 u7 W& `4 x
              }0 M# Y+ H5 F+ H0 ?. O1 l
            ],) T5 ~* i$ X4 A1 u
            "quorum": 1,  H$ W& j9 ?2 Z5 |
            "signatures": null,- U9 G" O8 M; E- _" D6 R" a
            "type": "raw_tx_signature"
4 n/ ]; H' X- k5 e          },+ @. P4 l) T; Q* z, b4 R
          {
4 W' ]5 d2 g5 {3 x) h            "type": "data",
# g+ A9 |$ k5 X! ^5 y. R2 a# r            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"  @! u# S0 v! M" ~
          }7 `! ^* k9 ?  p$ E+ D& B3 z
        ]5 [: B) S( c. C9 v$ ?3 Z
      },: F' r  P6 o8 H) Y" }" \* @* d
      {
- h% {8 ]; \0 @0 F& c        "position": 1,
. k  W$ i* F1 I, _& i        "witness_components": [/ |  o7 I2 r# c  ^! n
          {
- C7 Y7 M, o; d# |            "keys": [6 v6 U! F: }) T9 L
              {" D; t& U7 y7 ~/ [$ j; z$ S+ u
                "derivation_path": [8 t7 G2 a! w, c9 O+ b, k
                  "010100000000000000",( v4 y7 Z& S* o9 B+ W
                  "0800000000000000"# t$ n$ S3 e& W* ~, `
                ],  }3 O4 e9 K  A: Z: ^. v
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"! x# o% H+ ^" H4 e1 Q, Q- R
              }
# U* p9 {3 n: D2 y+ w6 P, M            ],3 U' l" V, A$ z& e, B4 T
            "quorum": 1,
6 k  s" N& i& O4 s            "signatures": null,
$ w( N7 [2 T$ p+ s3 k% j/ m            "type": "raw_tx_signature"
# H0 h  Z; o' j+ w8 i; h          },: F9 j- r, {9 v4 a% b( a! H& z( l. `
          {
7 x) C; u$ g6 ^$ y            "type": "data",
/ F) {& F% I) E, C) r5 A  t" t            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
8 w; ~* {' a* I8 I$ B7 J0 h1 L( i          }( t1 U7 ~4 X2 ?6 r) o" A7 J
        ]
$ i1 l  f0 _+ n$ ?- E: h9 u      }
1 n! X0 Q. F  M7 `+ S    ]: o, f8 k; z5 W/ L
  }& x) s5 H, G0 X( f' P3 H
}) i5 `$ M2 N: H* e
对应请求对象的源代码如下:
+ D" s% r+ {# W+ L3 B: Z" ctype SignRequest struct {    //function pseudohsmSignTemplates request/ K) g! I# c# u
        Password string             `json:"password"`5 d$ a0 D. G1 F4 U8 Z" d
        Txs      txbuilder.Template `json:"transaction"`& i* B# N  g$ }* [
}& R+ S$ _; p. }$ u3 I
结构字段说明如下:
% ]) R- `. a. j2 |" c+ C& c2 ^Password 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名
& G6 C+ |2 u/ LTxs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述
' d5 |' T/ S, z2 u) E" `2 Z
$ x1 p' k) C! z  o签名交易sign-transaction请求成功之后返回的json结果如下:7 w9 `; J% u/ d% i( w
{! R& r0 X0 L' _) S9 Z! Q
  "sign_complete": true,
" F* ^' [! }; B. F9 M+ Y9 }3 K  "transaction": {
! }# Z; e  Y. ~5 l, U    "allow_additional_actions": false,
: K. i. A# F/ n/ M# \* c0 q" u4 H6 s    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",! ^) X2 N  P3 o" g6 z. p2 I! I
    "signing_instructions": [& I2 ^$ F9 T4 ~5 R7 D) G% d
      {4 K+ R6 b1 `( ?& h; s. R) l
        "position": 0,4 p" B/ e$ E( g+ ^' H- ~
        "witness_components": [# d0 c  W# `! @- i# ~8 F
          {  s3 k4 \. o! A& ?+ O# l/ o% e
            "keys": [
; g% F! }0 n8 n+ e& V' f              {
. v% o' S) k0 y+ H) B7 C                "derivation_path": [
1 O8 D4 Y/ p# P+ |                  "010100000000000000",; I- ^5 ?* ~8 e/ w
                  "0100000000000000"
( @  |2 y$ l" E" [                ],
5 q$ {4 H+ q; w5 t: ~& u                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
; N$ p0 [; T  T  I              }
9 |# `( w/ a( S! }% w& `/ J# O- T            ],
. B& D! N; H: i4 P! d! S9 i1 G            "quorum": 1,9 U; r: B3 J0 T/ P3 {' W- I* V) W
            "signatures": [
1 ^* L2 B) n2 k: H% ^              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"* M: _& Y& g! U
            ],
  T0 c! v- R3 Q* Z- |8 N( }. O) n            "type": "raw_tx_signature"3 j+ f0 b; x) T7 U9 ^
          },
, k+ F. V8 i( {0 R8 x: }          {
: l: t# J; r8 j            "type": "data",. @. k3 r  Z, q9 J1 \. z
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
- D2 d7 u9 D  _4 {2 V) o2 L; m          }4 t& B/ T+ c5 l! }
        ]& T1 ?. T6 W/ m* [  C3 E3 a/ P! F
      },
8 b6 S2 e7 M3 a& C      {6 i, h  N# }) O$ U8 n4 M: K
        "position": 1,
, e+ _$ J; b( R2 m6 K0 V        "witness_components": [7 X" o' c' T: g3 y4 X+ U7 b
          {
5 s( ], c) ~4 f9 s            "keys": [
$ G. G/ ]6 @1 r! b3 G  S  \  k- r8 F) P8 @              {
" C2 z; k8 j! u+ i' P! f! h                "derivation_path": [: Q$ p" [' X  E% r( g/ {
                  "010100000000000000",. _+ B/ @5 M) Y7 C) I/ `
                  "0800000000000000": G; \$ Y. D! ~* w6 c- n) w
                ],3 B; ~2 w& Z( [; B/ E3 r2 s
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
$ Q% G- N3 E5 |/ ]              }
& s* H. V6 t9 k8 Y$ B            ],/ r- @  w& K/ T( K& O9 s! F
            "quorum": 1,! @4 N( [  G5 `/ V# C' ?
            "signatures": [& W' W2 j% [( y% P- r' S
              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d", ^* H; I7 ?7 V5 U, {& J2 V
            ]," z# X( H3 f7 F9 h
            "type": "raw_tx_signature"
; @3 S+ L' N( z. S& T; l          },, G$ u& W2 I% `3 h7 `
          {
$ L: B" N' P+ n  t" D( F+ p            "type": "data",/ ?6 B7 z: N( f9 ]# Z5 ~4 V4 g
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
& F. q0 C: Q" T5 W5 @          }, c& o5 `/ v" X
        ], c' B+ Q6 z+ }
      }5 E, q' n6 ]; P. Z
    ]  k5 D. ]! k' t: c
  }! D! @- v3 p! u2 B# ~9 N
}# V- L. K1 F, u
对应响应对象的源代码如下:
( s2 l3 t& x6 q' I- t( L# Ctype signResp struct {1 {5 h- y/ {( H" u
        Tx           *txbuilder.Template `json:"transaction"`
# O' v- p2 ?# [+ n/ P        SignComplete bool                `json:"sign_complete"`; ^) s& v! y9 e9 P; d
}2 ?+ p* H3 a) Y3 z! k. a, e
结构字段说明如下:: Q' t, s. ~  {8 \
Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息
& ~6 z- a( W# W$ g( g7 KSignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易
/ v# p1 P2 A7 H: q2 V( ]! f$ {8 z9 m% ?# G
3、提交交易7 ~4 J7 Y+ }! c" C2 M$ K& p
API接口 submit-transaction,代码api/transact.go#L135
7 r1 \  {/ {  w$ W5 |提交交易的输入请求json格式如下:
3 R* ]& e: F6 g) z0 U{+ K; X, j4 ?/ }! R) r
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
' ~( }6 Q1 _: [' S1 t}3 Q+ w- |8 x4 a+ x$ a( c
对应源代码的请求对象如下:
) T7 A( T* M# `& w1 K+ {# j5 ^type SubmitRequest struct {    //function submit request2 [( c  _" ~0 Q" R7 o
        Tx types.Tx `json:"raw_transaction"`# u) q0 H+ T. @8 X6 M2 n/ p
}! j  n1 R% Z- ]0 N+ x( k! N3 W
结构字段说明如下:
' ?0 B0 h+ D' Z- r$ f! o- HTx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。# e* D# y% a$ J, q4 {) O3 P

  I6 a0 ]: n# E  u& J0 ^3 ~submit-transaction请求成功之后返回的json结果如下:
) s7 c9 j" T- r7 }2 s* O* Q8 W+ g* k{' S. r# }9 H0 Q4 X$ K
  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"
4 ~' r( h+ g+ s' X}
8 O7 X3 m% x' q$ c% d/ ]% u) e9 r对应源代码的响应对象如下:# q6 j! v0 _% m  q% r: y' Z
type submitTxResp struct {
5 u2 R* O$ {( g/ k        TxID *bc.Hash `json:"tx_id"`
: p' B! ?- b" `4 A+ P3 t}5 V3 o; G7 C( I' h$ S8 s/ T' Y
结构字段说明如下:
' T0 q" T2 m  I* t( s  rTxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败& H: {- E# \& d
$ U- Z# e7 C, d; q: h4 G9 z4 H! q
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14