Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

V刘晨曦
162 0 0
比原项目仓库:
6 d$ x5 R3 z2 ^7 CGithub地址:https://github.com/Bytom/bytom+ U. `; [. c9 M4 _6 X5 G7 Z" e7 ]. |
Gitee地址:https://gitee.com/BytomBlockchain/bytom
, N) r) X' Q1 c( _5 R* ]. Y7 t该部分主要针对用户使用bytom自带的账户模式发送交易
! m/ T. n8 w. {5 l1、构建交易
' t* B$ ]4 n; ~0 k; D0 o/ Z. qAPI接口 build-transaction,代码api/transact.go#L120
1 r; D% }" M* s; R- x以标准的非BTM资产转账交易为例,资产ID为全F表示BTM资产,在该示例中BTM资产仅作为手续费,该交易表示花费99个特定的资产到指定地址中。其中构建交易的输入请求json格式如下:
; K! a& [; {0 \, u  f7 X{5 [$ w: m# s' @3 z; D) j
  "base_transaction": null,& Z/ \, h6 A8 N. W! W
  "actions": [, ^, ?( _4 |& ~% y. Y& Z
    {
( Z# e/ g% Z( x# P      "account_id": "0ER7MEFGG0A02",
. ~* t! L0 K3 [  u) T) K) m7 j3 q3 k& K      "amount": 20000000,' x- b) y4 b. t% F# M3 {, F" S
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",7 Z* |, C7 _! V0 A
      "type": "spend_account"
: V! o4 Q3 K( a    },1 I9 |. `0 k" I7 p7 }- v) y& a
    {
* R5 N: V+ [* s9 ]; p+ P5 e      "account_id": "0ER7MEFGG0A02",
6 G6 g& `: f) r: |+ c3 I! V3 g      "amount": 99,
# x; C0 O* h5 ?( Q      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",1 O9 D/ ~9 }+ `
      "type": "spend_account"
3 f  q3 Y1 X" |2 l2 ~    }," f) Z6 q! b2 L+ b
    {
1 |5 R' f) Z7 x  \/ f      "amount": 99,0 F2 g, _. z' e; f! R" [) Q
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",4 i2 ~* g7 M, s* j
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
5 Z' {. F4 k6 }9 p      "type": "control_address"0 p$ D* k, r+ s# y! b/ T/ e' u" S( x
    }
" q; C" l0 N5 |  ],; }: x# j5 o2 U2 m0 Q  ]8 u8 C
  "ttl": 0,6 c, \5 L/ J, t$ [
  "time_range": 0
# Y, u3 v, L# C5 [  |}1 y8 p' K4 B" Y7 ]1 y4 F6 B
对应源代码的请求对象如下:
* U) d/ b% d* L( {/ O- R" y// BuildRequest is main struct when building transactions" ~3 u$ J3 m( m9 f0 N
type BuildRequest struct {, e- ?- h( n4 x: }( z$ A  Q  M: w
        Tx        *types.TxData            `json:"base_transaction"`
: q7 @) h3 k/ b' E1 o6 p6 \% m        Actions   []map[string]interface{} `json:"actions"`" u$ G6 H1 P: p
        TTL       json.Duration            `json:"ttl"`
: j. c- n+ O2 v3 j4 o" I: w        TimeRange uint64                   `json:"time_range"`
5 s8 a4 v$ r4 l0 ~8 F3 w4 W* g}# T# s3 p/ ~% G% `4 N3 j8 t. @. f
结构字段说明如下:* n+ h$ ~6 b9 g0 i) J
Tx 交易的TxData部分,该字段为预留字段,为空即可" F# I1 k. M5 j3 ?7 e  e  ?
TTL 构建交易的生存时间(单位为毫秒),意味着在该时间范围内,已经缓存的utxo不能用于再一次build交易,除非剩余的utxo足以构建一笔新的交易,否则会报错。当ttl为0时会被默认设置为600s,即5分钟
* N* j# x$ V1 U3 Y4 |1 H; oTimeRange 时间戳,意味着该交易将在该时间戳(区块高度)之后不会被提交上链,为了防止交易在网络中传输延迟而等待太久时间,如果交易没有在特定的时间范围内被打包,该交易便会自动失效
% n" k  s/ p# I! v3 @) lActions 交易的actions结构,所有的交易都是由action构成的,map类型的interface{}保证了action类型的可扩展性。其中action中必须包含type字段,用于区分不同的action类型,action主要包含input和output两种类型,其详细介绍如下:. i0 n7 H7 ~4 {) \: G  |  }
input action 类型:
. y/ H; b) E: M, V( Bissue 发行资产
2 A5 T, {! L2 U8 J, g: D0 N3 cspend_account 以账户的模式花费utxo
8 T8 F+ g- `& qspend_account_unspent_output 直接花费指定的utxo
1 E$ r4 q/ x% O% A0 foutput action 类型:+ _9 l5 B# Q0 b) g/ W
control_address 接收方式为地址模式
) i$ ?0 L: g, Y( h; Dcontrol_program 接收方式为(program)合约模式6 L3 z6 k& u2 C. l3 ~( B
retire 销毁资产% Q7 S" i  e- e5 B" b( Y& R

- f1 [& Y) K6 G7 b: E: `
3 b! B0 L, V4 F/ i+ G0 @2 J2 _& w& H1 W, U& F/ c
注意事项:% R0 S5 Y, n4 k
一个交易必须至少包含一个input和output(coinbase交易除外,因为coinbase交易是由系统产生,故不在此加以描述),否则交易将会报错。
0 ]. `. J- Z3 [9 U: R  C! d7 b0 c除了BTM资产(所有交易都是以BTM资产作为手续费)之外,其他资产在构建input和output时,所有输入和输出的资产总和必须相等,否则交易会报出输入输出不平衡的错误信息。# D; G# i9 _% w% b
交易的手续费: 所有inputs的BTM资产数量 - 所有outputs的BTM资产数量
4 b  z2 \! X3 O8 I交易中的资产amount都是neu为单位的,BTM的单位换算如下:1 BTM = 1000 mBTM = 100000000 neu
& E/ \: `# }! F" `/ X: J" N& |- `8 W
action简介2 |$ ^% ~# U4 F/ W2 D" L7 ]
下面对构建交易时用到的各种action类型进行详细说明:% I7 ^5 S. U' L" u; F& F/ @7 E, [# e
issue
0 m$ U. c) K9 f( ^1 {) VissueAction结构体源代码如下:
- M( Z) Q3 ]& g2 P6 G9 y  u, ~type issueAction struct {
: r9 I+ ]9 P1 b        assets *Registry' s. H3 e, }: P; c9 E
        bc.AssetAmount" l4 p$ n2 X0 I- Q1 {1 L; t7 r; q
}1 a( z1 M  a+ ]; }# ^
type AssetAmount struct {
: r/ k" }: U2 |2 \4 [; T& p7 S) q% M        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
& N( \3 L: h8 E$ b/ f/ R/ x$ m        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
/ F2 h! ]- |: K) v, h# K}
" b; c6 m/ M+ V, u" F结构字段说明如下:6 L/ n' V( q3 V
assets 主要用于资产的管理,无需用户设置参数
9 K  h& Z$ J* Q- A9 p/ e3 h7 p9 dAssetAmount 表示用户需要发行的资产ID和对应的资产数目,这里的AssetID需要通过create-asset创建,并且这里不能使用BTM的资产ID& c# P$ S5 q. G$ ]
7 c/ ^- c( q- E" g7 l, K' B* {* ~
issueAction的json格式为:9 b5 m$ |+ f! j' T) E
{3 Z1 b& b5 r5 D5 [
  "amount": 100000000,5 T" U, V- L3 C' ]* q  V0 D/ I
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",; r. M9 V% ~0 f4 E0 j
  "type": "issue"; U) w' K1 r) ^
}; u9 B- u0 S' l/ i8 R9 ~
例如发行一笔资产的交易示例如下:: F4 p8 ^' l* E  I) m# o+ V2 @
(该交易表示发行数量为900000000个assetID的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu的BTM资产)4 a1 N; M3 T( b' i8 r
{0 H$ }, e1 q" W6 c3 B  Q
  "base_transaction": null,
( X; p, l: M3 X% u* ]4 @8 z, F  "actions": [8 }; W. }( e0 U( k0 d
    {2 W. j1 b. H/ M7 o" s/ z
      "account_id": "0ER7MEFGG0A02",
; m) f2 N3 h" n7 s      "amount": 20000000,* |  N# i! e! x4 e2 R2 ?
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
$ p; y" R2 r- r' r& T, ~+ m      "type": "spend_account") P9 `9 i8 g! \  s, v
    },! g: y. A0 l( |2 d
    {( Z2 r( R' e% D
      "amount": 900000000,9 v0 Z2 d5 t$ ^: Z
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",+ g8 g  b" d" u0 q3 x
      "type": "issue"
7 ~0 x+ D+ p; ^6 Y& g    },# h9 _2 Q2 G/ c9 q
    {
2 o3 ?; ^5 V9 N6 Y, g9 k0 H" F      "amount": 900000000,
5 P( o( J) C: Z  K$ p' b6 ]5 M' p0 a      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
8 h+ U4 A% c! N6 n8 Z/ p6 \. k      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
+ M$ b1 c& b; x  r, @      "type": "control_address"( Z" _& @- y; u# w. k1 @
    }
- s0 T" n7 ?. Q( I8 y7 C- u& L  ],
3 \: ^" F( }* a9 p( Q  "ttl": 0,
) q* \: \/ `: A. G8 [$ h  "time_range": 0
& C9 t7 D4 ^7 i  x+ n+ L+ J9 o6 r}
( H; b% q( m  V* }+ X1 o. b1 x2 A$ G, B7 W: Q) S% m7 t; V
spend_account; z$ h3 r0 n/ r
spendAction结构体源代码如下:5 y' L/ E" r* n4 c& ]1 ~! p
type spendAction struct {2 d0 S6 E5 W2 _. ]! V
        accounts *Manager
7 h' Z) [# a( F# Z% r) Q        bc.AssetAmount/ X! N: n! u$ O8 _9 l
        AccountID   string  `json:"account_id"`
0 x5 _. l/ ?% q0 \        ClientToken *string `json:"client_token"`+ O! M( ?0 L6 E( r; J; p
}; A4 [% n, l) C, Q5 M3 X( s; x
type AssetAmount struct {0 ^& ~+ ^$ A" o! h- u
        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`  @4 U$ c4 ~- b- R7 V5 P
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`+ r9 g  w& J' O4 f: F8 D# b  P5 _
}) j. k. [7 V7 `& P- C; {2 h
结构字段说明如下:2 S2 |5 g' c7 m; E7 Y
accounts 主要用于账户的管理,无需用户设置参数# J. n3 v# y  @; e9 m
AccountID 表示需要花费资产的账户ID
# S6 t+ L8 p. a+ ~! fAssetAmount 表示花费的资产ID和对应的资产数目
  o/ }6 I' v$ L, ~6 o9 A3 WClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可
- o4 i" g4 g- L& }6 i/ J% O8 N
7 T0 {+ e3 ]8 n+ V8 u8 \6 kspendAction的json格式为:
% [% f$ Y, ^9 C# x  w  C1 v{
  {! l- }( F  W& l  "account_id": "0BF63M2U00A04",' s. }7 g3 b4 ~+ c
  "amount": 2000000000,
6 c, H; }8 @/ i0 }. }. X  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
/ J4 z. |' T; _2 L1 ?" I  "type": "spend_account"6 k7 J  }$ {; G5 N* L# a* A
}* @" U1 e8 z& L$ [' p% `
例如转账一笔资产的交易示例如下:
# X/ e' i8 N6 U+ }( a4 ~9 _(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入BTM资产数量 - 输出BTM资产数量)
2 W/ k* [: X* q: M+ N) g{
+ ~/ t/ h) S; e- K  V' p  "base_transaction": null,5 v' G( w) }; p/ u! [
  "actions": [
- \1 V/ s+ c8 J3 i( q    {" [/ e: O( z6 D! Q" c% Z! C
      "account_id": "0ER7MEFGG0A02",
0 O4 m$ g5 |; I/ \" ~( A0 L& l  D      "amount": 120000000,! `. @7 {* G( }6 k  F( t
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",/ n1 C; Z. }. @  l( Y) \
      "type": "spend_account"# p- E! T& ?. s- I; G
    },
4 ?2 s% @3 h5 _0 s    {
+ K6 y' H/ ]) i# k, H      "amount": 100000000,) n3 X, M5 k  X) y+ L
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",; K) C$ N, I4 V* J6 L1 `
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
$ K/ ^+ O. U8 e      "type": "control_address"1 X6 f9 a' h3 H
    }# t2 s/ v, i0 \9 X: i- [
  ],
5 {. x7 h0 L# F  "ttl": 0,
; J6 C1 ]0 K5 U5 ^8 J4 s" K9 r1 r  "time_range": 0
5 z' a" ~0 j& @1 O) S4 w# M}( K: J+ q' t: n, z  F: X
+ \" u* `/ V6 C
spend_account_unspent_output
/ s- H4 B2 z/ K2 ?# C) u1 h3 H8 GspendUTXOAction结构体源代码如下:$ s) Y- t  L' g" Y
type spendUTXOAction struct {
0 P1 K6 F; d1 S3 y( ?8 t9 l& z2 X        accounts *Manager" S5 U) n8 m2 x9 }
        OutputID *bc.Hash `json:"output_id"`
1 G% [3 Q# g2 t! s( h( z0 Z- b        ClientToken *string `json:"client_token"`
: V- S) Q5 i/ @7 I0 u" p+ \}) T: `; [; J5 p9 z; w5 L
结构字段说明如下:- ^0 [8 |8 [- B
accounts 主要用于账户的管理,无需用户设置参数
' U/ W, y# X8 R1 J0 sOutputID 表示需要花费的UTXO的ID,可以根据list-unspent-outputs查询可用的UTXO,其中OutputID对应该API返回结果的id字段
  x9 _  G/ p; a* @ClientToken 表示Reserve用户UTXO的限制条件,目前不填或为空即可; W9 _$ o& [- R; L0 ]! z# |! X
) @# F  a5 l1 ^8 }/ H7 F
spendUTXOAction的json格式为:- \( I7 o6 N3 u2 `4 O  l
{
) p+ d, a. t/ A$ T* j* P' w( Y  "type": "spend_account_unspent_output",
3 M3 h$ L9 l, L; U% D8 u7 G  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9": w- H" n) e) V
}% N6 N1 z  w- _' j! O
例如通过花费UTXO的方式转账一笔资产的交易示例如下:! ^6 z& c# p! s, b; j
(该交易表示通过直接花费UTXO的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入BTM资产的UTXO值 - 输出BTM资产数量)
- N( l4 ~, K  v" k{
2 m- C3 A# F6 [# K  "base_transaction": null,  f' W$ d  v" |" J9 i9 j$ B
  "actions": [  V  W. v, I; {  F# R
    {7 U5 m! c+ P9 _* t
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
# R4 J% {# I( \/ q+ L% n2 M      "type": "spend_account_unspent_output"
$ B9 O! x8 l$ M4 K5 u0 a8 l# y0 D    },
% P* O/ p% j9 y1 d6 A    {
: N5 A2 e' b# b! t/ ]4 S1 N      "amount": 100000000,
" _$ o+ L# P* J* H& O      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",6 Z2 {1 [3 |3 P4 o# h# x
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",' d( p& M. m- d+ o% [
      "type": "control_address"
0 ^  K. j3 m9 X: r2 X4 v1 Y: v, a    }/ n' ]: i) }9 c/ R
  ],5 X9 S: w* q1 o/ i; j# Q6 n
  "ttl": 0,
- D) D2 F' {5 w" F/ p  "time_range": 0
% A, s5 z9 s4 q, u" ]4 J}+ {; g! r, T% P, t- d" ?1 D

4 S/ k# k6 B/ Ocontrol_address7 |* Z7 H1 [( B1 {- x
controlAddressAction结构体源代码如下:8 e, k6 J4 [+ h4 s$ c) G
type controlAddressAction struct {: k! a4 ^. V9 s' ?4 r
        bc.AssetAmount' [3 z/ l- Z$ s- K+ z2 R
        Address string `json:"address"`
3 `) f$ B- `! J+ q}2 r& M# r( ]+ V9 w
type AssetAmount struct {
( X6 Q$ G. W/ R8 `8 a0 [+ M% z0 ]8 @        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`+ l% i$ }" D* l- @
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
  D& m9 v! i7 A' U3 Z: H4 R: l! T}
) {  Z! m! P+ O* p2 \结构字段说明如下:7 ~) t1 X) A+ E' T
Address 表示接收资产的地址,可以根据 create-account-receiver API接口创建地址/ }7 b1 t/ \' i
AssetAmount 表示接收的资产ID和对应的资产数目) I- P* d* p6 D" k1 S

8 ]4 ^/ l$ f3 n9 x  I9 kcontrolAddressAction的json格式为:, @4 j7 U8 n: W( I: j
{
, {; F/ `( J/ s5 ]% V1 y& \7 s5 q  "amount": 100000000,
& E/ E5 h: L4 |( i& ?- I; I  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",. ^+ i6 E& ~# `% T4 W8 ~
  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",% A3 p) O* u2 @' U8 Z
  "type": "control_address"9 s3 L1 g' M  g$ w+ G  H
}% C' |2 `) ]7 \& f2 v9 f
例如转账一笔资产的交易示例如下:
! _* l+ p' [% w0 n$ ]0 ~(该交易表示通过账户的方式转账100000000neu的BTM资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)" {$ J8 d; D" C& D2 k+ F
{
# Y  W' \( Y0 G( W9 [4 W+ E& Z3 d  "base_transaction": null,) D: f3 Q4 _6 t7 V) ^' ~
  "actions": [
* ]1 `2 t! h* W    {/ b/ B. G0 X: _) U8 [: f( `0 R
      "account_id": "0ER7MEFGG0A02",
1 n2 F7 M: m. J3 P# ^      "amount": 120000000," C" t7 D$ v9 n; ^
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
4 b. o) X& Q4 @2 g- ?      "type": "spend_account"9 {2 `4 J. @1 `, E$ }& L) O
    },
, u1 j* o  z* H7 Q3 t% o    {
" S! t/ h9 R: \$ d% D      "amount": 100000000,8 a( I5 G. @6 q6 v$ A* j% P
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
& G2 Z8 p# W/ _: C5 M" x8 `) o      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
* k* r5 d: n% ]  c6 \      "type": "control_address"
! a$ _" b7 I0 k4 x" _  T    }
" L6 r. B; C. n6 l( u  [  ],  B* A# B: m# N) }& R4 S2 A- Q
  "ttl": 0,2 }! I" ^: i% m! F6 M5 N
  "time_range": 0
# Y" @, p' I$ L: [7 ?3 G}
0 H2 m; ]: M* P- @4 A% w; H
+ E$ m/ u" P9 A4 A& p, a* b  o* ?control_program& u7 F- e0 P3 A" ^
controlProgramAction结构体源代码如下:. V" ]9 m+ d3 H$ Y0 J! g/ g
type controlProgramAction struct {1 [: c6 k0 G$ K
        bc.AssetAmount. ?) m1 a. b7 A; ^
        Program json.HexBytes `json:"control_program"`
( W7 e, H, X* f* M2 j- I" f}
/ K$ U5 s+ b8 _2 c) ntype AssetAmount struct {
( n0 m) a1 `/ S        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
* |% @7 p. ]8 h        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
  k! ^  Z+ X2 f* H  M0 X+ d) Z; i- Z}" k* u$ [7 J1 v( F% ^
结构字段说明如下:; z+ A) l! h/ e* R" }
Program 表示接收资产的合约脚本,可以根据 create-account-receiver API接口创建接收program(返回结果的 program 和 address 是一一对应的)% s- x" a: o- D' i. d
AssetAmount 表示接收的资产ID和对应的资产数目! `6 E+ D( W  P+ A* M$ c
  P! M. q9 m! L: l
controlProgramAction的json格式为:* h2 a( s9 h+ E$ c! N) ~& g) O( i
{7 f& o0 f; J0 \& n, M
  "amount": 100000000,; E+ O4 q4 w: i1 H- a
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",1 M7 F4 U: ~( A$ a$ B3 K
  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
( s, [0 _* S4 s1 D4 L" g2 O* g/ Z* ~  "type": "control_program"
' A9 ~' ]; [1 n& J3 A- M% f}
" [6 g2 U& A, ?2 ~例如转账一笔资产的交易示例如下:
1 F5 @# Y" x" @/ s(该交易表示通过账户的方式转账100000000neu的BTM资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)4 Q1 _7 h. A# X1 _4 |$ I" k
{
* |/ X- w% I9 g( A" V7 U" ], V  "base_transaction": null,
/ K2 U2 Q" ^, E3 L+ N' K5 _: o! D  "actions": [
0 N' @: I% k' j6 _    {
) Q0 ^) [" Z! T      "account_id": "0ER7MEFGG0A02",5 E! e- N& q% e: U% Q
      "amount": 120000000,& k1 q- Y* d0 s' w8 m$ i( D( Q% x# A
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",2 s5 B7 w, Y/ ]) a
      "type": "spend_account": [) N; S+ i7 q& M. T# l  }
    },
$ P2 Q5 n9 y  k4 \8 ?    {1 K  j, p  S; l& u' F0 y
      "amount": 100000000,8 D8 Z; j# S# v: L% J4 [) c
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",0 d% I8 A% `5 V
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
. S& n/ g( C5 ]- k' W3 _" {/ p# Q  u! g      "type": "control_program"
! [# `) v7 D, j7 u    }
; c% [7 W2 E9 U  ],
- b7 r. h$ r2 e& g9 [+ R  "ttl": 0,
, X' F2 X" N7 S( i) k) d  "time_range": 0
8 ?. A7 E' X1 n9 v, T. j6 e}
' \+ J  _1 v. @; R, Q2 A7 p. u8 \" O4 I5 E' B/ `
retire8 ?! S$ F6 `) j) [/ j1 f
retireAction结构体源代码如下:" L' t+ z5 d4 o( t1 W: V' T  u& P
type retireAction struct {
+ r/ d% P6 ^# S; I, v1 o        bc.AssetAmount
* r+ R7 ?# x* [9 I4 B}
1 A5 U7 j3 P! _1 L' i. E' f: _$ g( h+ Ytype AssetAmount struct {
) ~) R8 g2 w5 h) G: l        AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`3 s& T# Q4 Y+ i4 T
        Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`5 b( k+ `. X. c4 d
}! v: t, x0 V  |/ O
结构字段说明如下:
+ ]2 t3 P1 X% |5 Y0 q. mAssetAmount 表示销毁的资产ID和对应的资产数目
! F% \% L6 o+ e1 m8 t0 k, |! ]8 Q6 n( j2 v
retireAction的json格式为:% V3 [( y( U# z% h4 n8 l
{$ I! w9 L+ U1 ?3 @+ m' J
  "amount": 900000000,
4 ^6 F, ~8 _1 `: _: V% T8 W3 n  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
7 L% V* a* P/ h, `% H5 L  "type": "retire"
4 D- e2 J3 f9 F( Q; F( Y2 f}
% P5 ~4 M9 {9 r1 `$ S  Z例如销毁一笔资产的交易示例如下:
5 T& L# ]6 y+ B- y- C4 \(该交易表示通过账户的方式将100000000neu的BTM资产销毁, retire表示销毁指定数量的资产)
6 s, x8 @: P& G: ^% B0 j{
" b' |. _7 B/ i( @* s  "base_transaction": null,
& H  e& S2 R' s. d9 o  "actions": [- ^8 R8 @7 Q0 Q6 g+ N& W7 a
    {
. |) G: C0 ^+ b+ r/ E5 ?1 n      "account_id": "0ER7MEFGG0A02",
' j3 P# |& B0 E  S8 V+ M0 S      "amount": 120000000,
' U# V+ X* P2 K      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",, _5 K2 W7 U& r: B9 l
      "type": "spend_account"9 l8 n. _" O  H+ d. n. f
    },
/ b7 ~9 R# f" {9 w3 {% {    {
$ x0 q7 F1 W# |9 T      "amount": 100000000,
3 ^0 I) O" c6 k3 Q      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
0 S9 y0 y7 m1 ~2 o1 q( N      "type": "retire"4 r( S  x; |6 q8 K# H' T
    }
/ _7 h% a7 E  W% W7 O9 i  ],' F' S; P; o9 O) @/ A: A2 h! q
  "ttl": 0,
6 C- s3 i9 ?# p8 `  "time_range": 0
5 M/ O8 |. ^, R}
$ V3 d! t$ w% E0 x( E: M
" A+ }+ ^- B9 U6 `; ybuild-transaction的输入构造完成之后,便可以通过http的调用方式进行发送交易,构建交易请求成功之后返回的json结果如下:
$ _  Z, {+ v. ]6 b9 b0 c3 v{
+ ^# n% L* c( v# i4 C) j3 U  "allow_additional_actions": false,
6 |! I! ^: y  x4 F4 z  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",' v' G0 V( Z0 u
  "signing_instructions": [
. K0 s  d- E+ T  z    {  I3 @* R6 f0 i( d) C! b
      "position": 0,
# A; e1 f1 s$ L      "witness_components": [. I# a  U) n' x' V: q( `6 J
        {
! p0 _0 ^+ Y" f9 W& R          "keys": [
% Q  L! I+ _5 V) b            {! F2 t3 ~1 |- g' X: ?: \
              "derivation_path": [
, z, m& U. e+ e" G9 u; T8 v! C$ Z  ]                "010100000000000000",
6 f/ e9 p- R% W% @                "0100000000000000"
9 s' T. c2 s5 A" m6 S# P# [  W              ],
: y! w5 I: ]' {( C9 h0 S* o0 d              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8". ~3 I7 u) w, j7 C8 A
            }
7 k9 v: v0 ~* k1 b          ],
% G$ B* E7 ^- F3 P' j: r          "quorum": 1," x% K3 q0 L; Q0 K8 Z" \9 ^0 q. L
          "signatures": null,, F) n5 [8 c- {; h8 u
          "type": "raw_tx_signature"
5 J3 [7 U+ g* S        },
' ]  h! q4 Z" ^2 o5 f        {% ]" v" U) X% D( T
          "type": "data",
0 Z! Q8 u# Y. L/ \. u( R          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
, h- q) L0 i7 f/ e0 c! O: z- f        }
7 {, K/ I( p/ @, I      ]  a& Z) N; d/ _! R4 Z2 n
    },
8 X8 g# E8 E) n7 p8 X    {
( n  B0 _  \# m  ]+ q1 {, ^7 N      "position": 1,% h- \) n1 e# C3 {0 T
      "witness_components": [
) G: G7 h8 t, P; h3 M        {$ C- D( Q" A! O: z; O. P, U$ P; |
          "keys": [4 I5 `4 Y8 X' Q* Y, l
            {  e1 ?- i0 u% F" P: }0 Z- ^. r! W
              "derivation_path": [9 F8 P8 s8 F: b2 G! u: X
                "010100000000000000",1 f6 X7 J3 [( R* p, G/ D( J7 W/ G" |
                "0800000000000000"/ t  m0 Y8 a: ]3 v
              ],
! b' O! |7 W) N* l4 U# v! b              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
! J9 I0 H" A- O( U6 q# |/ Q9 S) A            }
+ S4 g. _/ r- D/ ?1 q          ],* ]0 w9 p8 l, C$ J: J' a
          "quorum": 1,% o  s7 P5 I$ s- k  G
          "signatures": null,
+ U& J! d7 \# i* y$ U          "type": "raw_tx_signature"
1 L0 G# ?, _/ W+ {- q0 L1 @! b        },
9 K2 t& Q  e# O5 [" ?5 r5 O        {' g$ O3 @8 \* q
          "type": "data",  ?) V( r( T8 B4 c* S  Z
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
7 P: R4 `: l( s2 o# G        }
9 y4 w3 ?' P/ D9 Q/ \# }      ]! P3 P9 \+ u# s: @, t6 U
    }0 P1 o7 z5 m+ P  _
  ]8 y' b0 B: i$ [
}
7 h) N4 a0 Q; m  }. v对应响应对象的源代码如下:
9 q; N% {) e' d# F* v. I' k// Template represents a partially- or fully-signed transaction.% A! X# v7 r2 X' t5 k& }2 p. M
type Template struct {0 q$ ]9 ]" _$ g! B# j# `' l" _+ U9 i
        Transaction         *types.Tx             `json:"raw_transaction"`- l2 ~; {1 @: Q! i" x
        SigningInstructions []*SigningInstruction `json:"signing_instructions"`
3 i- u% S& b4 D* s        // AllowAdditional affects whether Sign commits to the tx sighash or
9 Z) ^5 a- X9 r% j        // to individual details of the tx so far. When true, signatures' K) i" @9 ~8 r" M
        // commit to tx details, and new details may be added but existing  Y  L8 [0 g& I9 k) }- r
        // ones cannot be changed. When false, signatures commit to the tx' ~1 y' {0 p$ t5 t6 A9 C
        // as a whole, and any change to the tx invalidates the signature.
) X6 t% O% M$ \& S. r        AllowAdditional bool `json:"allow_additional_actions"`0 ]0 V3 W- c7 x! d4 a* `
}
+ j0 \0 a0 S+ ]9 p+ Y结构字段说明如下:
3 P1 b# }, \& U' ]Transaction 交易相关信息,该字段包含TxData和bc.Tx两个部分:" V" e) i2 ~3 N, {" X
TxData 表示给用户展示的交易数据部分,该部分对用户可见- U" w2 v! M. Z* U
Version 交易版本  Q7 R, y8 U/ c7 U9 W/ W
SerializedSize 交易序列化之后的size) q0 j  t# m! N, W! C+ s9 S* r2 a
TimeRange 交易提交上链的最大时间戳(区块高度)(主链区块高度到达该时间戳(区块高度)之后,如果交易没有被提交上链,该交易便会失效)  I: E% v8 D  |6 e4 h
Inputs 交易输入3 `0 M) m& [) p+ M
Outputs 交易输出
1 X4 I" l, X% x+ E) n" N/ ^7 u9 ebc.Tx 表示系统中处理交易用到的转换结构,该部分对用户不可见,故不做详细描述9 t9 |' C8 g. \, V
SigningInstructions 交易的签名信息
! u/ [# A3 T2 k2 r0 g7 k, f; dPosition 对input action签名的位置5 M2 p, t5 [! f+ x7 c$ N( D1 O
WitnessComponents 对input action签名需要的数据信息,其中build交易的signatures为null,表示没有签名; 如果交易签名成功,则该字段会存在签名信息。该字段是一个interface接口,主要包含3种不同的类型:
2 D& b0 o& U/ ]SignatureWitness 对交易模板Template中交易input action位置的合约program进行哈希,然后对hash值进行签名
$ x9 z+ W, A) X9 o0 g- Csignatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
; ?+ \* v# {5 ^* @  X* Mkeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名
) ~0 W1 L% u. N6 u, g( E" U6 P# [) yquorum 账户key 的个数,必须和上面的keys的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户+ b" P6 X# C2 ^8 V' u0 k) m
program 签名的数据部分,program的hash值作为签名数据。如果program为空,则会根据当前交易ID和对应action位置的InputID两部分生成一个hash,然后把它们作为指令数据自动构造一个program
4 J# @4 t) [8 X" f. P) `8 ?RawTxSigWitness 对交易模板Template的交易ID和对应input action位置的InputID(该字段位于bc.Tx中)进行哈希,然后对hash值进行签名7 F. i1 \* _: s2 ], f% T5 G
signatures (数组类型)交易的签名,sign-transaction执行完成之后才会有值存在
: @  d; w8 t! Y) akeys (数组类型)包含主公钥xpub和派生路径derivation_path,通过它们可以在签名阶段找到对应的派生私钥child_xprv,然后使用派生私钥进行签名7 c4 Q* Q. d! {: v; z9 _3 e
quorum 账户key的个数,必须和上面的keys 的长度相等。如果quorum 等于1,则表示单签账户,否则为多签账户, S: p9 {2 w2 m4 I# }
DataWitness 该类型无需签名,验证合约program的附加数据7 d# I5 r  l$ H! U+ z+ ]
, t  P0 s7 y; Y' b1 F- D0 Q
AllowAdditional 是否允许交易的附加数据,如果为true,则交易的附加数据会添加到交易中,但是不会影响交易的执行的program脚本,对签名结果不会造成影响; 如果为false,则整个交易作为一个整体进行签名,任何数据的改变将影响整个交易的签名6 J4 R8 G7 N6 Z  s
+ \, H* ^8 d& [+ j) @/ }3 s
估算手续费
2 l4 Z/ Y3 i3 a+ ~. w+ H+ K估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:
$ x, d6 q8 m- g; O) a" T' b; c9 [3 a% Z! W  build - estimate - build - sign - submit
$ j) S4 N8 ?8 H估算手续费的输入请求json格式如下:
% N) B( Q* J# e6 A2 _) Z: B; _{
. z6 _# P4 e7 x6 E! }1 k  "transaction_template": {+ I2 Q; ?5 w% r
    "allow_additional_actions": false,
* w" H8 @1 Q, N8 l) }  c- t    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",5 e  t; X% C5 u6 c! Q4 g. s0 j  j% a
    "signing_instructions": [
" K2 j; z" ~- ^5 ]      {' h7 z, H3 d7 R9 y: Y( ?5 Z1 E
        "position": 0,3 Q) z; ^6 [$ G9 f- V7 b
        "witness_components": [/ d) l8 Y& [+ [3 }7 {7 {3 T
          {
# A4 K0 o! _4 k* `" F            "keys": [+ @! a8 I1 m% \9 j5 y; q/ Q: K9 c
              {
! y6 m2 b4 z4 H' M                "derivation_path": [
: z% s' p: _/ W                  "010100000000000000",
* m. Q( P% V5 z, R7 T% a" }# v- N% U                  "0100000000000000"
% Z* Z+ ]0 g+ j5 W2 t/ l                ],
, W3 S0 p. ]/ z9 Q                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
2 a3 t& Q* }7 z& L/ E              }
! e' V, s  K5 Y: x2 B) ]            ],
( J' ^8 A, s# G" Y) T: ^8 l            "quorum": 1,
' F% P; M$ ?4 _            "signatures": null,
0 E7 P/ Q1 {2 C6 X5 g$ P            "type": "raw_tx_signature"
) [  N+ {  Z+ Y3 A! f+ ?$ Z! N) S          },
. F+ l# j% q4 P* H          {
/ v7 F) t4 S) j/ t0 ^1 C            "type": "data"," e; R4 F! [6 N# Z+ m9 V
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"2 C; G# @2 {2 A$ q9 _
          }
) }: J/ n  }8 ?2 W5 J6 K        ]
+ }/ C) t( r8 |/ r1 z) x  \      },
8 b. p# z+ D& c  O' c: @, E" Y( j      {
7 z/ e9 _! t! a3 K$ X- t" {- g        "position": 1,9 P4 k7 w5 ^* c
        "witness_components": [
) V, K3 x4 n/ B          {
5 K. v) ~' ]/ L  o2 `            "keys": [% ]# C( L; l, k
              {- ^; n5 S* K; d( j, v: l7 X
                "derivation_path": [. `: S; I1 R2 S* m
                  "010100000000000000",* H1 l' x% v" c8 x; g" b
                  "0800000000000000"
1 U" }3 C) [4 }                ],5 P0 ]& j  a5 Y) o
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
: `8 |( }* M. I2 C4 t+ P              }
$ {, J- M" I  [5 ]7 |$ n8 `            ],
4 v4 n7 K$ H6 m6 |, k  N            "quorum": 1,
  Y5 {2 p$ g4 ~) a6 V7 A  s! t            "signatures": null,' j0 Y1 Q9 M! {/ I
            "type": "raw_tx_signature"
" |! H  k) l3 l4 ~& u4 G8 }          },) l: p" }3 P% n: O7 R: q
          {3 {6 J9 J! M$ ^& R. m# u6 y4 R
            "type": "data",. ~# I! l/ |$ x
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
1 l$ b+ t/ f6 U0 \. U          }
( D% z1 \+ H8 K- O        ]+ B  o: c) ~! X2 w9 d1 r
      }
+ u1 X# U1 e$ A3 [. p$ O' @6 S    ]
/ J" ?- }( P- ^- |6 N! ~, I  }# S; m' }/ }) V3 y" q; B
}
8 M2 S: R2 c. L4 t对应响应对象的源代码如下:
/ b0 j  ]8 ?4 F$ ctype request struct{
) ^8 p% _+ P$ Z% t- M, k- ]* K        TxTemplate txbuilder.Template `json:"transaction_template"`  I& y8 q2 w& D- W. `  y* y
}
/ q. r& R- \9 w2 ~// Template represents a partially- or fully-signed transaction.
+ L0 r$ b) b3 t6 K- _" V" otype Template struct {. p: j# F2 t. q, F( J4 U& f- X
        Transaction         *types.Tx             `json:"raw_transaction"`
( x# _6 y+ {- `! d, r, F) c        SigningInstructions []*SigningInstruction `json:"signing_instructions"`! k6 `% l" w* @3 n1 `# d  J8 y- a. B
        // AllowAdditional affects whether Sign commits to the tx sighash or
" |  w; u' L7 a( C! e6 v$ Y        // to individual details of the tx so far. When true, signatures' O: ^: h9 W4 F! }4 Z1 R6 m
        // commit to tx details, and new details may be added but existing
: [5 m8 X8 w, ^& \, \. ]' @        // ones cannot be changed. When false, signatures commit to the tx( b* A/ }3 ~4 f2 A6 M6 x0 K# y
        // as a whole, and any change to the tx invalidates the signature.
  w/ h1 ]0 z: C; Y( x        AllowAdditional bool `json:"allow_additional_actions"`
! x3 X5 R& z1 V+ ]$ K3 w}7 u! H  m- B; M% o
其中TxTemplate相关字段的说明见build-transaction的结果描述8 c) a$ Z7 f" J5 c/ z
调用estimate-transaction-gas接口成功之后返回的json结果如下:  r. `0 l# b/ X# m5 s( f5 `
{7 m* M: e5 n/ q( O) x. n  L2 P# h, f
  "total_neu": 5000000,
8 @3 A! j2 y, s5 _3 g8 t% f  "storage_neu": 3840000,! P& T3 ?" o! S/ {) r8 T6 q& A$ j
  "vm_neu": 1419000
- i7 F5 W; |( R- j}
/ m0 T2 g0 m8 f' f8 l% C! J1 S8 S$ M对应响应对象的源代码如下:
  j" ]6 @& p, d8 l# u/ k. U5 d9 v// EstimateTxGasResp estimate transaction consumed gas* Y- S3 N* _! j5 S+ j+ K; f
type EstimateTxGasResp struct {& d. G- H+ R8 n3 b2 E+ m, e
        TotalNeu   int64 `json:"total_neu"`
6 |: s* ]- k5 P  v0 ]        StorageNeu int64 `json:"storage_neu"`7 \+ P. {  R% m
        VMNeu      int64 `json:"vm_neu"`' {. i, d0 W$ o# v4 \( W/ Z
}3 r! T0 I5 t6 r2 S4 _
结构字段说明如下:
$ o# c" {4 w' |, n& |' ~# W1 S1 ?2 ETotalNeu 预估的总手续费(单位为neu),该值直接加到build-transaction的BTM资产输入action中即可
' R/ n$ W- v1 |StorageNeu 存储交易的手续费
  ]0 S9 W! Y. d. C- ~8 }6 PVMNeu 运行虚拟机的手续费
9 Z' K9 [% h( l4 v! ]/ r3 t6 K# w+ y9 t6 u3 ]; T6 v
2、签名交易
& k1 L+ w9 M  c& k2 T, HAPI接口 sign-transaction,代码api/hsm.go#L53$ X! N; O# t) R, H, l/ j2 c
签名交易的输入请求json格式如下:
8 r! }; H$ [( m8 N5 ~{
: [0 `: r0 b* ~% c6 Y8 m. r  "password": "123456",
& ]2 V0 j8 Y$ j/ L1 K9 t  "transaction": {& l; ]- _3 \* l& ^" X2 G
    "allow_additional_actions": false,
1 u3 {5 g9 @7 V1 T$ L    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
* @6 T8 {9 m( [) r    "signing_instructions": [% R# [' E9 S% I5 e+ L7 \; [
      {* i5 Z: k$ w6 t% B$ o
        "position": 0,
! d! [3 K  I' [$ |" h: A6 Q) i        "witness_components": [
0 x( O; T5 s8 P% i% f% {, v          {
4 H3 M) Z+ c7 V( N% p$ W2 p            "keys": [
& A# x4 m4 i, ~0 C              {. M7 a8 {7 [6 e4 I+ G) z
                "derivation_path": [$ j* f/ O) ?, J5 L
                  "010100000000000000",
' }% j! V4 O3 a0 U5 `" _, G                  "0100000000000000". J& I% I  B; W; u0 w/ X' \! x
                ],
: L# f, h; C6 ?/ r; L                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"5 g- P, i/ @" T0 }9 X6 b
              }
, i* u1 ~7 Y0 e* _; o, p, a3 ^            ],- |  G. }; Y5 f$ T. Z6 ]! Z
            "quorum": 1,
9 X4 o, k4 U7 F* g6 k            "signatures": null,: j. V; V( e0 ~3 ?3 J' Z
            "type": "raw_tx_signature"8 i5 {0 V) h/ h/ F8 d8 e
          },. t9 F+ `/ {$ d! ?  R2 L
          {
2 |2 |$ X7 _5 y; q            "type": "data",
/ \2 c$ w8 ~! ]7 R0 q            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
8 T$ ~9 S( A+ I+ {          }/ z9 W! W( x6 x# y; M! z- o
        ]
3 L6 h1 d6 e5 W5 m) _2 |      },2 }0 b8 z/ v' F5 L' u
      {
0 L$ n9 Y2 E$ G0 d/ b/ n5 G0 b        "position": 1,1 m! k  p) T& A- u9 r
        "witness_components": [, `+ ~, @/ m+ B" f
          {" \6 c. a6 M( Q7 ?! v
            "keys": [7 J- Q; M2 ]: H( ]: ?5 @4 K
              {5 F( Y& Z# P9 i8 B( s4 B3 t
                "derivation_path": [( o  A4 Q+ ?- O6 y1 F+ x
                  "010100000000000000",9 Z+ q: K- k, a, o' G
                  "0800000000000000"
2 K. X# G1 I; A+ i0 S                ],: J. ~2 q8 |! K7 s
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
$ D7 k, e2 M& s: _              }
: [( o6 O! S/ J. \; @4 F6 m7 ]            ],# s7 a, a. o) g
            "quorum": 1,
$ U# V/ F7 _/ S% O  s! V            "signatures": null,: T/ g9 C# X& @( J! t/ ^
            "type": "raw_tx_signature". ]: N' C6 i( U4 K! B. [& d( L
          },
- q- h, b; T8 A& U( o8 `          {5 @3 T' k9 P0 W
            "type": "data",( v1 e3 M6 W/ k, a
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
+ N( K+ ^7 w& J3 B- H  R! s* {0 F          }
# o) L% @- f! j9 g        ]" e: Q7 r* ^5 t$ {4 G
      }3 p# F( J* y/ |4 j9 K' H
    ]
) n( D6 I5 }- F( K; T4 {0 w  }; G' |: H* K% S: `, f( L' V
}
5 K4 y( R; T6 g$ Y9 O对应请求对象的源代码如下:  }2 ~8 i) T6 a# U
type SignRequest struct {    //function pseudohsmSignTemplates request
: w' T- k, N2 T  l7 Z        Password string             `json:"password"`  E: T& W* T; \8 W5 r( h
        Txs      txbuilder.Template `json:"transaction"`4 U  }) g& f6 M9 R( r* C+ {
}/ D5 Y1 d. D' Q( h# D
结构字段说明如下:
6 o; E3 b0 I, t* OPassword 签名的密码,根据密码可以从节点服务器上解析出用户的私钥,然后用私钥对交易进行签名
$ W% v1 B& h+ T" y4 m+ d3 k  BTxs 交易模板,build-transaction的返回结果,结构类型为 txbuilder.Template,相关字段的说明见build-transaction的结果描述4 `6 O7 }8 W0 S$ M8 M5 K$ `
$ s2 l. g# `* \" |* c+ @. o
签名交易sign-transaction请求成功之后返回的json结果如下:
$ b3 X) \0 @& }) I8 j  ?  p' @1 s{
* K- n) O$ T6 {; M3 y* @, A  "sign_complete": true,1 k) G- v, v! j; d0 ^0 U: B* ?* \3 \, {
  "transaction": {& B2 O! G7 I. Z2 |0 c, a  z3 Y! x
    "allow_additional_actions": false,( X  x1 R) H- B
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",+ P. K5 P* u) Y6 Z0 i  P. z
    "signing_instructions": [9 h! L4 I) Y- X  }$ v1 w
      {8 c6 r+ w* X. ?% O& J1 ?
        "position": 0,/ o  w  q7 b6 F1 R- K
        "witness_components": [5 T( P6 N2 D$ T  `) k& P/ B# A0 R# h
          {0 i' m; j4 V; A0 v4 ]& w
            "keys": [
  k( m% \0 H9 z4 ?! B              {
3 e( p1 A' y- m                "derivation_path": [) F, h+ @$ s4 P: I7 l% j% _. X
                  "010100000000000000",& d* |5 C7 j5 O9 V5 n) f
                  "0100000000000000", n/ q4 G) f7 k" p- A
                ],4 A7 ], L# h& G9 O& G: `8 z; }+ T
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8". N, l3 r/ E# Q: P5 F( d
              }* s# y: _5 R* |" X- ~" A
            ],
; b8 A, @; Y' T7 \0 s& W8 `) h            "quorum": 1,4 U6 U0 Z' t! |0 R8 w& }+ [& ?
            "signatures": [
6 r! [3 I6 X  Y) n1 l! N              "273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"
) X# m- D+ N. W" ~            ],
; {1 z; _7 ~' l' N            "type": "raw_tx_signature"$ |' y# g  a+ y. o
          },
0 v- H8 l' |$ e' N          {$ ^: W- ~$ |) v3 h  I" E+ D6 B# r  `
            "type": "data",* ?3 c7 Q/ u8 ^9 A3 B% ]4 x
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
" i# l* [+ E% ]$ D( ^7 L          }& Y, N+ _& y2 G4 s7 U! ~) J2 }; t
        ]
; n! y; O& D5 C  A, B      },# |' O: o4 i( F2 z: s- ~
      {# r* b/ l* V: b" z" m6 {
        "position": 1,2 i4 `# x. U# ?* u: Q
        "witness_components": [
  x9 X( q3 e: O" f) y$ ]  a          {
7 x2 \7 c% j) V: f* x  r            "keys": [9 ^# Q' f6 I2 z0 l8 R
              {
3 N/ x3 {6 A( R5 \5 G                "derivation_path": [! n$ x0 {. k9 F1 @& n
                  "010100000000000000",/ y( ]1 C4 e( T) b0 A4 h
                  "0800000000000000"1 ~" z6 r) G: I" ?- I3 r* r
                ],
4 T  D6 W. R$ c6 ~9 n0 M                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"4 m5 m/ X  {  [# {3 O* Z
              }
$ n( k% i& F2 c% z$ {# ~            ],9 o% Y4 j: y, I1 r! J
            "quorum": 1,* V' }+ P/ e. J3 d
            "signatures": [- H( |$ l9 o, n% O6 U
              "0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"- r- _) j$ k. {7 A$ ?- s' p
            ],
! f& h# Z4 R1 A" M' L! e            "type": "raw_tx_signature"; p% R$ l+ X- D* u( K
          },
$ J% S+ c( X( R6 Q/ [. E5 {% [          {8 F! l" B% o- f$ j
            "type": "data",
$ u7 [: `  {! V" ?& k            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
3 N- d( Z/ B6 O2 ]7 W1 H          }+ l1 {. Z: I' h
        ]
0 ^' r* T9 F/ [      }" D# S; @; Y/ V/ X& H0 u
    ]& e5 U8 A) n$ c/ E9 W
  }
' z4 x4 q1 f; N& G! k/ v# q}
/ |" A0 w* P4 e/ e9 ^, I对应响应对象的源代码如下:
1 E9 ?! j  F* h3 [: i# p4 b1 utype signResp struct {, e2 B' C+ E4 I3 G1 W
        Tx           *txbuilder.Template `json:"transaction"`
8 g- [- ?6 c4 H) T1 @- L+ u5 D* n        SignComplete bool                `json:"sign_complete"`( O) `, s% ^8 E8 O
}
7 T+ D6 G0 F! g; \- G结构字段说明如下:
' O/ B. u% c5 L9 R9 ~Tx 签名之后的交易模板txbuilder.Template,如果签名成功则signatures会由null变成签名的值,而raw_transaction的长度会变长,是因为bc.Tx部分添加了验证签名的参数信息
& D$ j6 n# \3 g# v1 r) v' f7 e( dSignComplete 签名是否完成标志,如果为true表示签名完成,否则为false表示签名未完成,单签的话一般可能为签名密码错误; 而多签的话一般为还需要其他签名。签名失败只需将签名的交易数据用正确的密码重新签名即可,无需再次build-transaction构建交易  M4 l% k1 ]6 ]$ N; H; {: c8 V0 K  b) L

3 Q0 U+ O9 B" d5 r0 B1 y  Z3、提交交易
& D. h) y+ u. W( |" SAPI接口 submit-transaction,代码api/transact.go#L135: R. Y& ~% \4 ?* a2 |& Z
提交交易的输入请求json格式如下:. m) {; ]; u: i7 x
{
2 P0 x9 m. L4 M( v" R  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"" M) F9 ?0 g2 L# V1 k
}9 r8 @& d+ v5 w9 ]
对应源代码的请求对象如下:
+ Z; a; N; f. ~5 E& L, I: K# C, U/ P0 Btype SubmitRequest struct {    //function submit request; j  S. c9 s0 K9 J
        Tx types.Tx `json:"raw_transaction"`& ?2 I1 Y- V! E
}  }5 r4 D5 X. X9 q3 M$ s
结构字段说明如下:2 Q1 n6 A- w+ A3 R* ]! m7 \
Tx 签名完成之后的交易信息。这里需要注意该字段中的raw_transaction不是签名交易sign-transaction的全部返回结果,而是签名交易返回结果中transaction中的raw_transaction字段。' P. v& a6 T. ?! A+ [

! y. `9 e" {+ @7 usubmit-transaction请求成功之后返回的json结果如下:
: e! i5 `* M' j, R+ ]% C{
' k* D2 _  S0 a, J; o5 l  "tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"
8 `- a+ A) O8 I6 x}
; c  M0 h% R) n7 |% b+ I$ ]对应源代码的响应对象如下:! n8 X) U2 D  C& P: ^. F
type submitTxResp struct {
4 R/ f; u4 j5 X, r. T* Z        TxID *bc.Hash `json:"tx_id"`3 o0 d" _  X' |( A- W3 ~( w/ `# d+ `
}6 K. }, m1 H$ S% |/ S+ d
结构字段说明如下:
7 e7 k; T) ]! e5 xTxID 交易ID,当交易被提交到交易池之后会显示该信息,否则表示交易失败9 k5 `, W2 C' X6 \0 f3 r  h
9 H3 m9 S% Y6 p7 P6 i
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

V刘晨曦 初中生
  • 粉丝

    0

  • 关注

    3

  • 主题

    14