Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
155 0 0
比原项目仓库:
: P1 N& j3 k( W0 DGithub地址:https://github.com/Bytom/bytom% o# r0 d% o+ d8 l% D" ^8 I
Gitee地址:https://gitee.com/BytomBlockchain/bytom
) F- O: K4 N8 T, W6 {tx_signer
! S9 z% U$ a( w; h3 L: dJava implementation of signing transaction offline to bytomd.
; }( f8 f7 L: }! D. zPre5 ]# R4 ~, \' S; _4 E
Get the source code
1 H" s) A# w/ }; _* U$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
4 H7 B/ `( c4 e+ W9 {git checkout. R" n5 P/ F6 K* e% j) j" O. `
$ git checkout dev/ r5 y: |" s- G* y% N
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
3 P( [0 ]  A9 B4 _Build
" R- e) b$ M/ a2 ^4 c  \" J! C0 k" X$ cd $GOPATH/src/github.com/bytom
5 c" [/ z! M1 q% S4 ~& ]1 ?6 M# l$ make bytomd    # build bytomd
1 M8 M- J6 g& ~" ?$ make bytomcli  # build bytomcli- W4 v+ R5 m. A/ a& ~! U
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.) N% b( l4 C, J. D; S3 G
Initialize
& P( A$ t  M4 p0 Y* [First of all, initialize the node:
4 j$ w: ~( l, E' N$ cd ./cmd/bytomd+ y: L6 f. ]. W/ U* y( p, K8 k
$ ./bytomd init --chain_id solonet
' ~: m) N) c. G& P: D/ H, ulaunch
" }0 ?, k! ?5 F$ L) {' |$ ./bytomd node --mining, }4 S% A8 v! o1 P( [9 P9 j
Usage
% x& o# U# g" k& a% J5 f3 W% V6 QBuild jar# S5 r+ }  P: Y9 @& J$ d
  • ; W+ q- G0 Q. U' U+ j  W
    first get source code! E* y/ p9 r$ p) N" r0 ]7 B4 J
    git clone https://github.com/successli/tx_signer.git
    $ O) K( f5 {# _5 O* @  t

  • 2 T. a7 i) p$ Y, d2 lget jar package( }, h. N, h' G+ C* u3 ~
    $ mvn assembly:assembly -Dmaven.test.skip=true' _: R, W; I, R7 R
    You can get a jar with dependencies, and you can use it in your project.( P, P, Y/ l1 v( {4 M  d

    8 b1 ^/ S' N5 u( Z9 ^6 T( K3 R9 b0 B- P* ?& Q9 y* W+ G
    Test cases  E; Y3 g. v; U6 x4 U& F' ^
    Need 3 Parameters:
    3 D6 W% N2 \- D4 c! Y2 |
  • Private Keys Array
  • Template Object
  • After call build transaction api return a Template json object. build transaction api
  • use bytom java sdk return a Template object.
  • Raw Transaction
  • call decode raw-transaction api from dev branch. decode raw-transaction api
    ) H( Z+ q" ]( V/ ?- _$ u% L6 Y
    8 F+ p: y* u6 i$ J* J
    Call method:
      [% O( N/ `! ^$ }" \// return a Template object signed offline basically." w3 D2 j. C& G7 L2 Z
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    . {7 o# {7 @5 E! e* f; |% k// use result's raw_transaction call sign transaction api to build another data but not need password or private key.6 L* f9 E" V0 ~2 f' |
    Single-key Example:/ ]1 t- q# Z" u
    @Test+ ^8 S+ c8 C, Y# q7 N6 ]
    // 使用 SDK 来构造 Template 对象参数, 单签: R& V9 c6 I$ k& K5 |) P
    public void testSignSingleKey() throws BytomException {
    4 R4 p5 `( W% [+ b! J/ ~) X& T* \    Client client = Client.generateClient();
    6 a- r3 R$ P" R! }! Z    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    9 W, Y$ Y) k2 z+ u2 u5 o& ]    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    # H6 H8 L; t) ~( u6 J    // build transaction obtain a Template object, |; C# J- q3 G3 [. \! X7 A$ E
        Template template = new Transaction.Builder()
    * B4 Z' O5 m. s( j. C- Q* y, |        .addAction(" f3 T! L- T8 U5 U
            new Transaction.Action.SpendFromAccount()* j) r$ N& M2 s
            .setAccountId("0G0NLBNU00A02")+ o4 \$ \, j2 A8 @
            .setAssetId(asset_id)
    ) ~2 T4 d; \4 @- C" ]! Y        .setAmount(40000000). l9 @! Y2 z0 a8 m+ ]( c
        )
    5 M1 w& Q8 U7 ^) n        .addAction(& S' ?4 S8 G) P& r5 _: C3 H, J
            new Transaction.Action.SpendFromAccount()9 i- J7 z. p+ p* e
            .setAccountId("0G0NLBNU00A02")4 @9 p  z1 |# b4 B* w+ F
            .setAssetId(asset_id)
    3 t5 r. _9 M0 |: \  Y$ j6 O        .setAmount(300000000)
    ! B& q$ _5 D  H9 m, P    )4 T; W* ~4 C" [; i1 k
            .addAction(' v) e5 U8 b" T6 H& p$ G
            new Transaction.Action.ControlWithAddress()# e. p' {+ Y  d/ H8 k
            .setAddress(address)6 `4 E  u! h, ^% a
            .setAssetId(asset_id)0 n6 e7 G1 \9 r8 f$ i
            .setAmount(30000000)
    , d: f* b7 d* H4 y- {$ W. c$ o    ).build(client);6 t6 D6 p- B( \
        logger.info("template: " + template.toJson());
    3 y' x! m. z& N/ i0 F    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    $ a/ q* A  b2 F0 X0 w& A5 M    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    ' v" a" }& M) ?. Z( I! `    logger.info("decodeTx: " + decodedTx.toJson());
    : k; `5 d0 o, R8 ]5 d    // need a private key array9 l( R$ m' b/ k
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    ; T! h7 H: l& _- r9 r    logger.info("private key:" + privateKeys[0]);
    5 l6 i6 f4 m/ M7 U8 n* A* j: @( p    // call offline sign method to obtain a basic offline signed template
    , _, p$ n  L! x7 b1 v- x    Signatures signatures = new SignaturesImpl();
    , f0 q! A* `/ m  q4 }  @    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ; U& j( s4 @3 G    logger.info("basic signed raw: " + basicSigned.toJson());& q: x, I/ `" u3 d. j
        // call sign transaction api to calculate whole raw_transaction id
    2 y% G! D7 i0 m1 Q* i( z) R" \) {) R6 M    // sign password is None or another random String
    7 I' S  `2 d# P1 K: [, r& X    Template result = new Transaction.SignerBuilder().sign(client,' w( z# k8 ?8 B' s6 R; _; C3 d
                                                               basicSigned, "");/ D* u/ C' @/ Y+ E( ~/ H
        logger.info("result raw_transaction: " + result.toJson());, a& y$ F+ M: r# |( C7 H% [
        // success to submit transaction
    $ Q* p9 @6 m% @% t$ j2 e}# K, s" J3 J9 h! v/ a2 i
    Multi-keys Example:2 d9 D! h  U3 t' b9 D
      G5 {7 Y% A& N7 f8 T+ ?6 I" x6 X
    Need an account has two or more keys.) |. x3 ]' o% N% F3 n

    - Y/ @0 L6 j& u  W$ J@Test: o6 b: F5 p% k3 }0 H
    // 使用 SDK 来构造 Template 对象参数, 多签0 u. Z0 x  v9 Y  s  \/ R1 D
    public void testSignMultiKeys() throws BytomException {
    : W8 @* K- E( K: |0 m$ ?+ S/ j5 r    Client client = Client.generateClient();$ j6 L! z8 F- B/ S! B! ^. r
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";: ~$ k# s# @; Y9 ~
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";' Z  \& v3 K! R, b) m" H- _
        // build transaction obtain a Template object
    & r2 g8 j2 k9 U# i9 z/ Z    // account 0G1RPP6OG0A06 has two keys
    + N* z- D! c/ d" a    Template template = new Transaction.Builder(), T0 U5 @. d1 m' g; q+ H
            .setTtl(10)
    9 d. ]  z: `% C( p6 [5 H1 q2 N3 o        .addAction(* v  Z/ C) u% {8 p  i! S) A
            new Transaction.Action.SpendFromAccount()' w( h) P5 N' R+ K( a0 D, k
            .setAccountId("0G1RPP6OG0A06")$ X) e3 f: g$ G4 Z  A
            .setAssetId(asset_id)
    8 j9 J" V1 |: y        .setAmount(40000000)( ?+ N: p5 v& B) b9 ~; Z
        )
    - O" z3 [: u7 q6 h! P# s( H        .addAction(8 u) {) c1 ]1 F0 I; G, S& b2 o* Z
            new Transaction.Action.SpendFromAccount()
    ! U8 E, @- ]5 x" u) I9 s        .setAccountId("0G1RPP6OG0A06")) y" v9 Z7 |& @6 n* j  T5 Q$ Y
            .setAssetId(asset_id)
    / I  n# J$ F$ b        .setAmount(300000000)/ A# r! `( k7 x% @3 N" z" }0 f
        )+ J  e1 P* x1 Y8 H0 W
            .addAction(! N3 t& y% @: w
            new Transaction.Action.ControlWithAddress()0 k, R) Y0 Y$ f; W
            .setAddress(address)  I# s# J) {1 Y0 v! @
            .setAssetId(asset_id)- Z' D4 p- e) H8 H, E
            .setAmount(30000000)1 ~: X; |! m; C; w- l
        ).build(client);
    / B" H; u, L  f; ~    logger.info("template: " + template.toJson());
    6 y8 ?( h4 R: T4 B0 J. s/ p6 N  Q    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ' d$ f) o5 o2 Y7 H) q! W7 j    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    : A5 |2 s$ r7 `( k8 n( k0 N* s    logger.info("decodeTx: " + decodedTx.toJson());
    ; d- t7 c8 z3 F+ a    // need a private key array0 ^0 \; J; g" x) q; q! G! P1 y
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",! Z) B% [% L4 x! H7 v
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    ( e& H1 d2 {! Z" G4 g    logger.info("private key 1:" + privateKeys[0]);- z  R8 Y) F/ H0 O5 Q0 |
        logger.info("private key 2:" + privateKeys[1]);( |5 g- J2 W& C5 X
        // call offline sign method to obtain a basic offline signed template
    5 Z% k+ A0 |' ~* X    Signatures signatures = new SignaturesImpl();
    $ t" @; \2 L/ {: D5 y% G. q    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);( b, C& I' G; O
        logger.info("basic signed raw: " + basicSigned.toJson());4 Y0 l7 V3 P2 E& a% s* J
        // call sign transaction api to calculate whole raw_transaction id
    0 X) f! H# J, f8 I9 o$ T1 b    // sign password is None or another random String
    7 }: L, s6 v/ l    Template result = new Transaction.SignerBuilder().sign(client,6 V# [' h" M: M! o8 @) s
                                                               basicSigned, "");9 @  G, f% C/ N: `9 s0 [/ P* H
        logger.info("result raw_transaction: " + result.toJson());" b( j" n( j! F8 @6 I+ H
        // success to submit transaction2 y, q+ ?+ u! t  P2 S
    }! u+ Z( U0 s( U# b# ]$ ]* v; y8 Z
    Multi-keys and Multi-inputs Example:
    2 N' @  k+ {6 O& j/ D@Test/ V% s& i/ _% ?) n) @
    // 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    ! g1 Q, W  Z! r1 X3 lpublic void testSignMultiKeysMultiInputs() throws BytomException {
    5 V: f. G& z  q# o! s. V    Client client = Client.generateClient();
    + |4 ^" m/ x7 a) G% l    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ( E# @# @8 ^# `9 m, t+ F: m6 |    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    * ~+ B) i) b9 c1 X' P- [    // build transaction obtain a Template object6 Z" C" t0 v- n8 U$ x' e
        Template template = new Transaction.Builder()
    6 W* N1 z% ?( _- D0 Q/ [, b  |        .setTtl(10)
    % V/ _# O4 h0 S        // 1 input
    0 r8 `3 v; P5 H" x' F& Q        .addAction(
    / W. r% _  U  _5 s        new Transaction.Action.SpendFromAccount()
    . O! p- I0 x" R: a8 Q& S4 w        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    ( k9 w0 V7 [1 F# W" t; S- G1 E- n        .setAssetId(asset_id)
    1 ?$ v4 H9 U+ p8 T2 h* z        .setAmount(40000000)6 q$ a5 p, m* d' g  Y5 f
        )7 s1 C( b2 N6 k, ?' B. ]
            .addAction(, v8 N& Y, E3 j& G, @/ D
            new Transaction.Action.SpendFromAccount()
    ( J; Q" K/ b* M. l$ l& {+ p5 R2 }; j4 u        .setAccountId("0G1RPP6OG0A06")* d0 _$ E5 w3 L9 V* p
            .setAssetId(asset_id)
    7 g( c7 G6 @9 r, ^2 n* U; M        .setAmount(300000000)0 J( P" M; t9 W! y6 j$ h
        )    // 2 input
    4 u4 z. b' i5 c/ H$ c/ @2 ?        .addAction(
    % q; z1 T- ^5 G3 O+ Y3 j        new Transaction.Action.SpendFromAccount()4 g  I! N. F4 `0 d
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account& W5 F5 |6 P8 d) u& E
            .setAssetId(asset_id)
    2 J- Z9 w# d! V# L' X. a. i        .setAmount(40000000)
    ( [# r7 e  j. _; f/ N+ W$ h3 n    )7 f6 L+ e3 ]. p
            .addAction(  B( n/ ^' w2 I; b
            new Transaction.Action.SpendFromAccount()& g1 p) t. U+ w" k5 g, E
            .setAccountId("0G1Q6V1P00A02")
      {8 Q) m+ s7 `8 g        .setAssetId(asset_id)
    6 ^) D8 O1 X4 `        .setAmount(300000000)
    - c: }- K' S  c/ @# i    )
    $ C9 X9 B# E# i" {9 |        .addAction(
    6 v* ~4 E( X4 ^) m2 l        new Transaction.Action.ControlWithAddress()
    3 E0 p. _" H8 M* s/ e        .setAddress(address)8 Z; a' o1 j6 S, Y/ e
            .setAssetId(asset_id)0 }2 ]" l8 g3 m. w9 @7 b9 B
            .setAmount(60000000)
    ; c: ]  E  `1 _6 u: m4 y6 I5 {$ `    ).build(client);$ C) I) V: {( l& r2 W
        logger.info("template: " + template.toJson());
    5 v* F) f) P% l& |& H% R2 [0 W    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    1 z! M/ O( @1 J& O: J    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    3 @3 @; C5 L% P    logger.info("decodeTx: " + decodedTx.toJson());
    0 H' x& Y$ d8 B/ D# H- \5 M; ]0 R+ i    // need a private key array6 R% ?6 h* J) u# {: Y! x
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",# {0 s6 F" X% V, `
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    # o5 ~: q* t+ J                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};9 h% k" R4 \9 Z" G) M" }* ]
        logger.info("private key 1:" + privateKeys[0]);; c1 R- t' Y: S. ]8 B
        logger.info("private key 2:" + privateKeys[1]);! m# v7 z; S; b9 U1 e- v
        // call offline sign method to obtain a basic offline signed template; r# u; Y# S9 y2 a9 f
        Signatures signatures = new SignaturesImpl();
    ( q- V3 J8 p  v) }4 {, ~    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);# ?' ?- Q8 i& G% ?6 O
        logger.info("basic signed raw: " + basicSigned.toJson());
    ' H/ o& i3 @6 q, g$ P    // call sign transaction api to calculate whole raw_transaction id
    9 o. y( f8 A7 V% \" g4 _    // sign password is None or another random String+ G& o/ l% f: O+ ?2 d" o# C
        Template result = new Transaction.SignerBuilder().sign(client,
    , z8 X( A  @6 n4 u* h+ u                                                           basicSigned, "");# X* A! G( m* E$ k; V
        logger.info("result raw_transaction: " + result.toJson());
    7 ^3 t! [# q. Y* X) @( J6 E1 M    // success to submit transaction& ?& X; ^) H/ z3 N
    }
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13