Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
102 0 0
比原项目仓库:+ V0 \5 X* L! p( `
Github地址:https://github.com/Bytom/bytom! ~$ G" L9 ~4 c) w; K* L
Gitee地址:https://gitee.com/BytomBlockchain/bytom5 O# }5 s  y! W8 L/ V
tx_signer3 r+ i/ {: d, _; V
Java implementation of signing transaction offline to bytomd.
0 q7 b. x  X* [5 S9 }7 H) [. APre# x7 y- E  j0 |
Get the source code- N8 _- x) |& ~9 [& B
$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
( n# t( t4 F+ s) y; y% r. Sgit checkout
. e. }  d" M: n/ X- m2 n$ git checkout dev$ ^3 @" j6 C: X# y
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
4 h9 ^4 f4 J. C( oBuild
) T9 w: R/ f0 K9 b7 h! f$ cd $GOPATH/src/github.com/bytom
% v# M( q# s9 @& k9 E$ make bytomd    # build bytomd
4 b6 e. l2 w7 j" n3 e$ make bytomcli  # build bytomcli8 Q2 _& H' O3 s& _+ |$ o; Y+ L1 @
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively./ c; ]. r/ W# ^1 |( s4 ?  p
Initialize
6 e' B: M+ ?- K, W% ~First of all, initialize the node:
/ ~! `, \4 L( S2 S$ cd ./cmd/bytomd
/ P) h2 x9 i; D" ]( X# G4 s" S) }$ ./bytomd init --chain_id solonet
) B2 f2 u* x' h; y% v! \0 vlaunch  ^0 \: ^$ j; I$ ]- P; h' d
$ ./bytomd node --mining
5 d9 r. W. v2 r' D: ]Usage* U" q) ]4 s# ~) @7 o3 }
Build jar
: I) ]$ K& O2 V7 M6 m
  • " G# D. L, ]# s3 B( E0 E3 }
    first get source code  }( P1 F9 G2 p( y3 H+ h4 M
    git clone https://github.com/successli/tx_signer.git( }4 S4 o; Q7 R) A, L0 T
  • 3 z' C0 o$ r; E9 y: T8 e
    get jar package
    ! w% ?) ]1 @1 g$ mvn assembly:assembly -Dmaven.test.skip=true
    % V# Q5 K' B, S- M+ U1 m. n# KYou can get a jar with dependencies, and you can use it in your project.9 U9 Z: R0 D8 A  z2 n+ ]
    $ c( D- [+ U& V* z3 ^

    6 k( |! e# L" A, V7 [9 }, U9 STest cases; d4 N% S/ ^( q* W4 y
    Need 3 Parameters:
    2 L7 X7 p1 M1 y9 S! t4 A
  • 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 api5 o+ |3 G% t0 y7 @7 {+ b
    + J' a. _. o/ J1 o: Y/ P9 T6 Y
    Call method:, @3 E0 g* \! E9 K  d
    // return a Template object signed offline basically.
    2 y4 K8 b* t& y3 P2 dTemplate result = signatures.generateSignatures(privates, template, rawTransaction);
    , i* G8 Z6 }% U; X// use result's raw_transaction call sign transaction api to build another data but not need password or private key.
    " t1 `5 r% {6 D2 hSingle-key Example:
    4 L) z: p! w: h; e@Test
    0 {' |7 D6 Y4 M/ Q# t3 N// 使用 SDK 来构造 Template 对象参数, 单签2 S: T9 c5 N1 t) U
    public void testSignSingleKey() throws BytomException {$ e  A4 |% A0 l  e. _
        Client client = Client.generateClient();
    * |( D' h* _+ ]    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    3 d; Z# T3 z& K& T6 t- n9 @    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";! ?8 x7 @: K, J% z; a0 h) n
        // build transaction obtain a Template object
    / k/ ~: B2 J1 ^" a$ B0 N    Template template = new Transaction.Builder()0 ~0 R$ A- |2 d: F% D4 J% f2 o
            .addAction(
    ! W$ r7 r2 J6 j        new Transaction.Action.SpendFromAccount()
    # c+ j- }, N2 s# B3 d7 }: E# A- m        .setAccountId("0G0NLBNU00A02")
    3 a) K8 l, E! ^4 B. [        .setAssetId(asset_id)& D5 T9 y" k& }0 R: E# n( R3 V
            .setAmount(40000000); \- a' `7 A6 c$ z. q$ L. k7 K
        )% S0 i5 j1 m8 [8 t8 @2 M& L* t1 r
            .addAction(
    1 u( M8 Z) t( l4 I- i! |        new Transaction.Action.SpendFromAccount()3 Z6 Z7 t! S5 k7 _* u0 m5 R8 \& Y* l
            .setAccountId("0G0NLBNU00A02"). k$ Q" n9 b& F6 B7 b3 N
            .setAssetId(asset_id)
    1 w* ~4 z3 ?5 m) J# ?. o. w, N8 t' A        .setAmount(300000000)
    5 a* C7 D# u5 R$ @( f0 R    )8 E9 L' ~" c7 _& Y
            .addAction(
    7 u0 g5 g. E) C) ?: X  D" K        new Transaction.Action.ControlWithAddress()
    & K3 L+ O* h! e        .setAddress(address)* ?0 d; ~$ {& @
            .setAssetId(asset_id): x& y9 |) `( R0 `/ w5 ]
            .setAmount(30000000)
    0 \$ i- @' m: A    ).build(client);
    # t2 ?) L0 ?1 [  ?; ]& U, l    logger.info("template: " + template.toJson());
    ( G0 k% _5 G/ G& A* Q    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object& k1 ^, y1 I: _; c( B+ P
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);( D1 n4 X0 q6 j, A3 e
        logger.info("decodeTx: " + decodedTx.toJson());
    0 x2 K* h, n/ m' i4 i5 D- y    // need a private key array/ Y" L" \0 H+ h; J$ j; D: y3 J
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};3 Y1 r5 t9 t& n% e) U& d
        logger.info("private key:" + privateKeys[0]);1 l, P* X5 P/ P0 i6 K
        // call offline sign method to obtain a basic offline signed template
    / N! z  Q1 S6 K* x    Signatures signatures = new SignaturesImpl();
    ' t! M/ b$ g+ v' T    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    9 |* f$ Z, c) x+ u& S( r) R' p    logger.info("basic signed raw: " + basicSigned.toJson());- s) w! p2 T# @2 V. _3 y1 t
        // call sign transaction api to calculate whole raw_transaction id6 ?" f7 \7 R. ]0 D: Y
        // sign password is None or another random String
    4 n3 ?- Q1 H" t8 y( Z    Template result = new Transaction.SignerBuilder().sign(client,' m* G  P+ Y  \* o: K) \0 @+ w
                                                               basicSigned, "");$ B  I0 N7 E: L+ L- P; ^
        logger.info("result raw_transaction: " + result.toJson());
      M" L3 D5 c/ j& I    // success to submit transaction
    + u6 d: [. L( p5 Y3 A8 [  ~}
    0 Z) r5 Y- w5 [& Q1 u+ F  VMulti-keys Example:! }& I) {+ f2 w4 C' Y4 Z2 L
    6 d  |) y/ _: h0 X$ u
    Need an account has two or more keys.) x# c2 f! i0 ^: ~6 w5 M
    9 Z% `' g, ^8 ~
    @Test
    9 w4 l- _% H; P// 使用 SDK 来构造 Template 对象参数, 多签2 L4 z/ U/ v9 H
    public void testSignMultiKeys() throws BytomException {
      ^* F6 b* u/ j    Client client = Client.generateClient();9 o, j; l1 U' O, l; m
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";$ S" k5 H* m1 e, t2 k# ?; ?* Y* Y
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";% f/ ~# b* z4 x- a6 S, Y0 l
        // build transaction obtain a Template object
    4 q+ K4 R" b1 d' k% r* m& j$ ^! D  q    // account 0G1RPP6OG0A06 has two keys7 q1 |1 C# F0 ^% k8 r& Y
        Template template = new Transaction.Builder()
    # W8 |) T7 m) H. x# {1 Z# O0 Y" Z        .setTtl(10)
    6 a9 |( E* g# r) j0 @5 j        .addAction(
    1 T- o! K$ g) b/ e9 C  ]$ }        new Transaction.Action.SpendFromAccount(), o" H4 M7 Q* ?. G$ f
            .setAccountId("0G1RPP6OG0A06")
    , G+ o2 i0 ?% ?, f# c. R        .setAssetId(asset_id)# w; Y" B: B8 y1 b$ t# i
            .setAmount(40000000)' V! U' F* i! Y2 t
        )
    4 K( f  P1 }2 o4 J& O        .addAction(
      e  M6 W8 M9 D) ^7 }" K9 `        new Transaction.Action.SpendFromAccount()+ m7 D4 E& F1 W: N6 y
            .setAccountId("0G1RPP6OG0A06")
    ; L0 j# L' j4 Y8 X% }        .setAssetId(asset_id)
    2 }+ o0 ~8 K% h9 G, N4 _        .setAmount(300000000)
    ) x5 F2 r, t' ~. ], y3 F4 \    )
    6 ]2 }1 q) Q1 k$ G; C% f' }3 r1 P        .addAction(- f( K( ^8 ^' K" {1 N) K1 E
            new Transaction.Action.ControlWithAddress()
    ! q/ K# j& T' L2 h2 ]        .setAddress(address)' a7 M7 [8 W, t5 g3 S3 B+ W, Z
            .setAssetId(asset_id)
    ; i- t1 E+ V4 L1 H3 B        .setAmount(30000000)
    6 c" i& w4 g8 x% ^+ p& i    ).build(client);
    ' x( }, r% l+ O; l* J$ b! N    logger.info("template: " + template.toJson());5 k7 t9 T  `+ I: L
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object5 Z" v4 y- a+ H- D+ f5 s
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);, V5 K( ^) R& e# o! _
        logger.info("decodeTx: " + decodedTx.toJson());: F+ e; _2 r+ e7 s' D- x7 a
        // need a private key array+ j. S$ A, O3 m. e) t4 W. n6 F0 Q
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",: E7 U# }* T+ m4 G' L2 d
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};7 B- N* N0 ~, M0 b( w$ \* |
        logger.info("private key 1:" + privateKeys[0]);
    " P, w. y9 l$ G0 c$ q. d9 X5 r    logger.info("private key 2:" + privateKeys[1]);
    1 \1 S  t! h2 C( u2 I    // call offline sign method to obtain a basic offline signed template3 {6 k1 [( b% D
        Signatures signatures = new SignaturesImpl();& [( j# B' Z. Y; i
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ( ]3 q! U9 a/ \; O. |7 l    logger.info("basic signed raw: " + basicSigned.toJson());
    6 {' ~7 Z& t" M2 I7 [    // call sign transaction api to calculate whole raw_transaction id
    : r  i& I: Z, g    // sign password is None or another random String6 _- e2 J. Y) J1 Z
        Template result = new Transaction.SignerBuilder().sign(client,
    1 P5 p# E  q% r/ r- u% d2 j                                                           basicSigned, "");# X1 w: Y; @! F; A# c9 K$ x1 }
        logger.info("result raw_transaction: " + result.toJson());
    7 [" \" Y' S2 q3 o9 t) }    // success to submit transaction& t, k- W* {* ]0 A* B
    }
    - v% x7 O! ?0 R. C6 ~$ {Multi-keys and Multi-inputs Example:
    ) U: w" f; s$ j6 C@Test
    5 w* T( L+ t5 R// 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    4 ~7 R- u# V# l& npublic void testSignMultiKeysMultiInputs() throws BytomException {' L! m6 k5 N6 v' M+ r! F% D# W# W. x
        Client client = Client.generateClient();/ e9 K; f: p+ h) B4 r5 h) I
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    : M% n* E1 |0 D1 j1 E' H3 C* A: f    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    + {0 K4 {/ v1 O. @* `9 |    // build transaction obtain a Template object
    $ J+ y  U+ G% [$ s% J    Template template = new Transaction.Builder()# W" H# s  q$ a2 @
            .setTtl(10)
    + Y4 o* o/ f4 e7 ]+ U8 P7 g; Q: e        // 1 input
    ) d5 ~( t  `' x( H! p        .addAction(7 @& w6 s2 P8 w/ @/ e$ r
            new Transaction.Action.SpendFromAccount()1 n$ {$ Q6 }  _: j; ~8 g
            .setAccountId("0G1RPP6OG0A06") // Multi-keys account
      \! y  I' b; K3 {7 \! Z' W+ j3 ]        .setAssetId(asset_id)$ m+ T& S% ^: Y. B
            .setAmount(40000000)
    & \# L8 P/ Y8 \    )
    " ?3 A+ Y- P% g& O$ x! k' Q        .addAction(
    - f" J, j# t- e) j2 \  n, O4 s        new Transaction.Action.SpendFromAccount()
    3 Z8 C& M& o: P7 S7 c( b        .setAccountId("0G1RPP6OG0A06")' Y# R9 n5 F- L- a( _
            .setAssetId(asset_id). p1 u; P  I/ N' W
            .setAmount(300000000)8 G4 I  R9 c" @: J1 l8 R# r
        )    // 2 input
    $ Z9 {: @% q' u3 B- N8 {        .addAction(/ N  a) {5 }( ]4 |. ^
            new Transaction.Action.SpendFromAccount()
    + J, [, B' u) }; S$ \        .setAccountId("0G1Q6V1P00A02") // Multi-keys account
    ( Y, h5 J$ H$ K( F* L' n* v        .setAssetId(asset_id)/ {: t) g$ ^6 j7 @! ]
            .setAmount(40000000)
    " w' O/ C) `1 Z    )
    ( H0 O6 S2 W) O3 I        .addAction(6 f5 B9 C, R0 z, H) w
            new Transaction.Action.SpendFromAccount(): j5 D% u8 [* B! f0 n- E" @6 y
            .setAccountId("0G1Q6V1P00A02")( t5 V& b9 ?# j! K" X1 e
            .setAssetId(asset_id)% R- M# _& I* D" o- C& r* T
            .setAmount(300000000)+ `! F. p# B8 J% \
        )
    0 y8 D! k( O$ d% ^        .addAction(9 Q; t8 Y3 o7 e! W  M, U- v+ D
            new Transaction.Action.ControlWithAddress()
    4 ~8 U# p# B" T: H0 J+ [        .setAddress(address)
    . u" v; f7 C( E+ o3 M9 Z8 G1 n- B        .setAssetId(asset_id)
    * t8 A2 L2 @  a# P3 ]3 x        .setAmount(60000000)
      q& ^- [1 U8 P7 A1 M' v    ).build(client);6 x+ }- J! l8 g1 R
        logger.info("template: " + template.toJson());) V- _, I: H3 i; C& N
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    * \  z. ^8 c8 Z9 x3 @    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);5 c1 j: `/ a- r" q% ~: w7 D% [& y
        logger.info("decodeTx: " + decodedTx.toJson());
    / ~7 U  @( _  L2 F- W/ ^- t/ O    // need a private key array* ~) m9 s, V' |# x
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    $ Q; {' q9 Z: \+ P# f$ H. Z' ]                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    2 r' v! S8 ~) ]2 w                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};& s5 W/ I! h7 O9 y% H2 q) h
        logger.info("private key 1:" + privateKeys[0]);# d9 W; p9 C# [8 I7 c9 M' b
        logger.info("private key 2:" + privateKeys[1]);
    / ^8 T3 H; q5 X" R; x    // call offline sign method to obtain a basic offline signed template3 g& P8 z, p( k1 w3 F. B  @9 {" R) l
        Signatures signatures = new SignaturesImpl();" }1 {% U+ n% @  ]5 m: I7 R
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    - K! m: l' }, b) }    logger.info("basic signed raw: " + basicSigned.toJson());8 Q: ?0 ^1 o) ]1 F4 K8 Y5 R
        // call sign transaction api to calculate whole raw_transaction id
    + z6 @/ ~& c1 u9 W3 ^5 H$ u" ?7 A) W    // sign password is None or another random String  k* u+ T9 Q) V6 p
        Template result = new Transaction.SignerBuilder().sign(client,( Y" z, W# K8 N
                                                               basicSigned, "");
    * w, q0 B/ G$ }! L3 I1 l( R8 A( ]    logger.info("result raw_transaction: " + result.toJson());* F5 c% H. S/ A& A" M" h4 {0 {' I
        // success to submit transaction& m0 M4 C7 y: M: B
    }
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13