Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
156 0 0
比原项目仓库:; N( e, H0 h9 p: e8 Y
Github地址:https://github.com/Bytom/bytom- k$ `: Y& j$ d  m; w
Gitee地址:https://gitee.com/BytomBlockchain/bytom
  P8 S8 _5 u8 F( W4 s9 ltx_signer8 Q+ e' K8 A+ D  a* R) Z' G$ U
Java implementation of signing transaction offline to bytomd.  d5 [2 L/ Q4 N/ M
Pre- D3 k6 ^3 O; W+ C1 \
Get the source code6 b. \% O, v: s: [9 C' g
$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom3 u# S& v/ W" H% }; b0 I
git checkout( w5 b( m9 H. O) Q! e* v
$ git checkout dev
6 {* b9 U8 r+ |2 tWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
, U0 d: z# O6 }) m" ^  `Build
7 J/ }! a& Q: u% |8 u. W$ cd $GOPATH/src/github.com/bytom, |! Z0 c% Y: G" N
$ make bytomd    # build bytomd+ E  x& y6 @+ B! z+ c! E/ Y& e
$ make bytomcli  # build bytomcli
, G. X9 x9 |9 J9 dWhen successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.4 y2 `1 _4 x4 h: H2 E% T
Initialize
: d0 x9 h' v' X" B) A8 w5 D. H6 _First of all, initialize the node:
( f- C5 h+ _6 L! S& h& \: l$ cd ./cmd/bytomd/ s# D0 Q8 c, r) K
$ ./bytomd init --chain_id solonet  r7 Y+ y/ T; q1 c
launch
; L1 P: p0 Q- M( v$ ./bytomd node --mining) l& j( j6 B: s( ~$ i9 C
Usage
- @: }. B5 y! J) P6 KBuild jar! q4 A. o' ^/ Z( d& q8 w
  • ! [$ o' d5 U, H
    first get source code
    - U+ P# U8 [2 {7 z0 S, igit clone https://github.com/successli/tx_signer.git  [7 C7 N# d% y9 w% R& G
  • 8 N: ~0 E9 i" ^  o4 V& h
    get jar package2 s4 b0 P% ~3 c. g
    $ mvn assembly:assembly -Dmaven.test.skip=true
    6 Z+ ^' l. U# I( N! L; V9 IYou can get a jar with dependencies, and you can use it in your project.9 k. T- Y9 Z: X7 L! Q9 A8 w2 c
    4 u1 i; u5 v' p+ U$ D, S

    / @! L) \2 [- \' c  _Test cases
    7 m" C/ Q* J9 |/ {; n- HNeed 3 Parameters:
    ' f( i# i+ T% E" s9 u& f$ c( C
  • 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 api3 {& R) b7 J  w0 j

    . _/ ?( ^9 c4 U( K- G' V! fCall method:9 O/ o( A8 h2 X2 y/ o$ E
    // return a Template object signed offline basically.; t7 A& v3 `( e
    Template result = signatures.generateSignatures(privates, template, rawTransaction);  U- v; U/ L* d
    // use result's raw_transaction call sign transaction api to build another data but not need password or private key.
    0 E) z' S; O3 x8 n& L7 _; }: _0 y! [1 eSingle-key Example:
    7 f, g- Y, ]& x8 n@Test3 E3 J/ A2 A# x+ b2 S
    // 使用 SDK 来构造 Template 对象参数, 单签0 \$ E2 @' h0 T- I: B& X3 j% }( ?# R
    public void testSignSingleKey() throws BytomException {
    4 n, A+ X, a9 S    Client client = Client.generateClient();- V; O9 @( F' u
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";$ N1 l8 o) Y7 P5 l) X8 i+ A% R
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ! B/ O1 J# w7 ?    // build transaction obtain a Template object
    " w3 ?6 p' c; i; |' Y3 T    Template template = new Transaction.Builder()
    , p; u( z: a! A: P# G' O4 I* U        .addAction(! ^6 N: p' O: w6 C9 u8 W9 m# G
            new Transaction.Action.SpendFromAccount()$ ^  F# K3 X1 P7 M, v+ R- X
            .setAccountId("0G0NLBNU00A02")* S2 i4 z* l- X& Y, U. j; G6 f
            .setAssetId(asset_id)
    9 u7 P+ U( U1 F8 h        .setAmount(40000000)
    4 }0 C. e  W8 I7 d, J4 e    )2 x3 N! t, }" q- r: I/ l$ B
            .addAction(
    / F/ j  g5 p% M' K2 }* c        new Transaction.Action.SpendFromAccount()
    6 d* P8 G7 Q' i# r8 F5 r        .setAccountId("0G0NLBNU00A02")
    0 {' u( X) }" }# J7 v        .setAssetId(asset_id)
    % y0 z2 p( }4 k$ e# p) W& y        .setAmount(300000000)
    1 V9 R3 `6 `6 a8 D) ]: D. s    )
    ' R& S( c$ Z3 G" F9 q6 {4 K        .addAction(
    6 }% P2 E# B( m5 G" ~: [3 q: K        new Transaction.Action.ControlWithAddress()! }4 q/ k# I# r3 \) l# T
            .setAddress(address)
    ( C8 Q0 H% n5 y3 @/ h- H/ E        .setAssetId(asset_id)% T! f  f, y1 A' X3 n
            .setAmount(30000000)
    * M9 K& y: o# d, n0 @! m6 W/ K    ).build(client);4 z* ?: W4 i% d* y5 P# H; g
        logger.info("template: " + template.toJson());
    # y3 H3 g' K5 c4 x+ L    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object$ N5 y& C' o& _7 s$ z( O$ i, h
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);" w4 \6 V* l8 Q, g1 z
        logger.info("decodeTx: " + decodedTx.toJson());5 \0 u  b. R0 v6 ^$ ?# i# }
        // need a private key array2 P" p" u& y. p" N0 c; j
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    5 U. f! G2 s/ v* s9 x6 i    logger.info("private key:" + privateKeys[0]);
    3 l3 D; S$ J* w8 K, e6 ]& w* ]( u    // call offline sign method to obtain a basic offline signed template
    % X! h2 B/ m/ V' S    Signatures signatures = new SignaturesImpl();
    / `: L: L1 b! n( F" @* [4 V0 w    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    + o) A3 a8 t! q: S4 P+ s* V    logger.info("basic signed raw: " + basicSigned.toJson());! L' m& Q% @1 h, L9 m1 |$ |
        // call sign transaction api to calculate whole raw_transaction id
    ) Y' y. H# d2 b! @% C( h3 X" A    // sign password is None or another random String+ _* t) C: x* N: L2 P
        Template result = new Transaction.SignerBuilder().sign(client,5 S3 B) ^8 Z% u! D0 s& D
                                                               basicSigned, "");
    ) C' e9 d  l$ o& b    logger.info("result raw_transaction: " + result.toJson());$ |0 P, U- N8 t8 D% j+ G( W; z! C
        // success to submit transaction
    2 O) a0 `3 p2 B6 ^" p8 @8 i) \}
    8 B) u: M3 \$ x' h* nMulti-keys Example:9 s$ w' W- J- h5 N% t

    4 \' }: Y6 I4 X# u" iNeed an account has two or more keys.
    ' V" ?; y7 H0 }% K* E0 k! U

    2 a5 m3 C3 [8 ~  f@Test
    ) f! }+ {2 H& ?# ?: e( O4 Z. B// 使用 SDK 来构造 Template 对象参数, 多签
    7 o* }. \+ m3 q0 Epublic void testSignMultiKeys() throws BytomException {5 L5 Q7 i6 m( a" P, P
        Client client = Client.generateClient();# R  Y, J* ^" M' K3 j+ J& j
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";7 Y, C& k% b  E" _" J' x
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";7 x- m/ ]* c3 w/ ~9 q# b) B
        // build transaction obtain a Template object5 p! X' {8 }8 t! e. g2 S! v
        // account 0G1RPP6OG0A06 has two keys
    : X5 R; G; L. Y2 J7 J    Template template = new Transaction.Builder()
    : M. I& |! \" {        .setTtl(10)( f# e2 ]1 Q+ v* ]+ Q4 W* Y
            .addAction(2 J! {/ D# e( E: x& I' w) P2 ?
            new Transaction.Action.SpendFromAccount()8 ^5 l! D9 X$ V0 A$ U( N8 b
            .setAccountId("0G1RPP6OG0A06")
    , V4 x' r% h8 K9 w        .setAssetId(asset_id)7 Q7 f9 F8 X! z% U
            .setAmount(40000000)
    " P5 q7 C$ V2 Y6 f+ j- b    )' C( W  r4 b0 d
            .addAction(
    ' ?- J: }* y; x* |        new Transaction.Action.SpendFromAccount()
    , Y, ]) l. P0 D+ s7 d. E- z        .setAccountId("0G1RPP6OG0A06")5 e$ B- N+ c* T$ O$ D
            .setAssetId(asset_id)
    # C- g1 r' u2 D6 J        .setAmount(300000000)
    ' g3 j% K8 h8 q0 q9 v4 g    )& z% A2 }9 p! s7 V
            .addAction() `! K, i+ v+ D9 G/ t, x7 A
            new Transaction.Action.ControlWithAddress()
    4 _; k! Q+ `/ a- r( j        .setAddress(address)
    ! w+ w0 E6 {* T6 _5 e        .setAssetId(asset_id)1 U* |! ]6 m. i& P2 x# J
            .setAmount(30000000)
      U* M( H6 }# x7 Q- u, n    ).build(client);/ D" n  f% ]: w. m* f
        logger.info("template: " + template.toJson());, e" X" q' Z* w
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object6 m2 k3 ]0 B3 f; f0 z4 F9 v
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);" \# J! B, F% @4 W7 {2 f- S0 o& I
        logger.info("decodeTx: " + decodedTx.toJson());
    + I7 y+ N3 ?, |; Z* o, E8 D    // need a private key array
    # P  m1 I7 D, J& v. ~: x. t# v    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    8 h1 e8 ]1 P: P4 n7 Z6 }                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    9 J! O4 d1 j& A) d1 J- ?# e. ?    logger.info("private key 1:" + privateKeys[0]);
    . k9 q8 g' g; Z9 M    logger.info("private key 2:" + privateKeys[1]);' j8 w" K0 t8 T: g" c  w. ?
        // call offline sign method to obtain a basic offline signed template9 }6 |1 Q( o5 Z; x
        Signatures signatures = new SignaturesImpl();
    2 S  _5 S' d) m# T* m" B$ o: t    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);* n+ O( b% V4 _
        logger.info("basic signed raw: " + basicSigned.toJson());9 T0 _  q3 z& r! H. `9 I) x
        // call sign transaction api to calculate whole raw_transaction id
    , W- p! P. |; O$ h: F    // sign password is None or another random String3 P+ |  b! Q7 N
        Template result = new Transaction.SignerBuilder().sign(client,9 f8 m/ J+ n7 l4 J* D  T4 y
                                                               basicSigned, "");1 Z% h( J3 r4 u' ~) s6 b) Y
        logger.info("result raw_transaction: " + result.toJson());( {& z; r& j- B: \1 ~3 n! l
        // success to submit transaction
    2 }; D! H; i- Q8 l}$ [% ]  t9 S4 h: e( a* }
    Multi-keys and Multi-inputs Example:$ i/ P" M+ A- J4 X; [: k
    @Test
    & \  t1 ^, R9 T2 g// 使用 SDK 来构造 Template 对象参数, 多签, 多输入1 ]; F' B. j* y6 t' ~1 K
    public void testSignMultiKeysMultiInputs() throws BytomException {
    0 t4 n! _' O1 b% c1 X8 o    Client client = Client.generateClient();0 Q9 s! S1 y* J: t4 Z! o
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    . K. [# l; g+ o; g    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";) S1 S( m! D& x- l0 g4 r) Q( e& m; u
        // build transaction obtain a Template object
    / B1 D) ^1 c; n! y: d    Template template = new Transaction.Builder()
    ' P  S/ C% R0 j' i. m        .setTtl(10)9 z. u& y6 V& Z+ H; |$ H* ?* {& s
            // 1 input
      F7 t. {9 z; ^8 M, J9 G        .addAction(# A2 l. f9 s& q# W3 H1 c, b
            new Transaction.Action.SpendFromAccount()
    5 X) O3 V  |# O# @: }        .setAccountId("0G1RPP6OG0A06") // Multi-keys account0 b4 M4 u& h* s  q: f
            .setAssetId(asset_id); X, M  A1 q( q7 A. J# V
            .setAmount(40000000); w9 P; H/ r0 M2 z( ~
        )
    2 i6 B+ y! Z1 d4 v        .addAction(
    . I- ^8 c) P2 G/ \0 f' P/ {" D        new Transaction.Action.SpendFromAccount()
    6 c& }( }1 r. R        .setAccountId("0G1RPP6OG0A06")
    3 [, F" g1 `  p+ B        .setAssetId(asset_id)
    4 N$ l- m5 z! D/ \3 P" o        .setAmount(300000000)
    6 o- O" R: m: f! B    )    // 2 input) b" T. d8 m# ^6 N. Q3 E# ]5 J6 G' E
            .addAction(
    ( M( `! w; c* z/ k5 z: l        new Transaction.Action.SpendFromAccount()8 h( v& m  [  e
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account
    3 h, j- i6 U" v/ ^4 R# S        .setAssetId(asset_id); a8 C) m5 W& C+ C$ w% g% {6 @
            .setAmount(40000000)* m8 L: O' E$ E0 V: H$ _; c
        )) F! @% i( A  U% O
            .addAction(
    % W7 n: \$ B$ Y/ |6 W/ z        new Transaction.Action.SpendFromAccount()% j' S$ M. J9 j  B8 W) x
            .setAccountId("0G1Q6V1P00A02")
    7 A  H: A# A0 v7 E: z        .setAssetId(asset_id)
    , K( J7 D* y8 j& {# G( M        .setAmount(300000000)5 p& ~' q( v1 [- v
        )1 Y8 }; [/ v+ s  q  f' Z
            .addAction(* j8 N. p+ k/ `, T; w0 H. M
            new Transaction.Action.ControlWithAddress()
    8 n! t* W. m2 z8 o0 Q6 V9 M        .setAddress(address)
    / Y- B0 u( Z. `) _/ V, N6 ^        .setAssetId(asset_id)
    6 v- M& E$ M4 |. a# m        .setAmount(60000000)
    ( C( S- z  d: n! W* _    ).build(client);
    1 F3 `/ `6 r# k8 i    logger.info("template: " + template.toJson());5 W( @, S- v5 q+ i! b- k
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object" ^" h9 ^& ]* `$ d+ e1 E* w9 `: W( A
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);1 x9 K/ Q$ q" S
        logger.info("decodeTx: " + decodedTx.toJson());
    8 ^% a/ l9 b" M1 a" I% X    // need a private key array! i2 X; o" s4 l
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    2 F& m; [$ w  q* k& ~                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",0 P0 c" n& t/ r- b# ]2 x
                                            "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
    / W7 {& M' i+ ^0 X4 w9 @    logger.info("private key 1:" + privateKeys[0]);/ B0 ~2 P  |, ?/ u1 J- p9 m
        logger.info("private key 2:" + privateKeys[1]);3 y/ @3 ^$ V% Z0 z% c8 h$ h" L
        // call offline sign method to obtain a basic offline signed template
    % g5 p. U4 L% [$ G; O8 R    Signatures signatures = new SignaturesImpl();" d' F2 I# ~  L0 A2 [$ F
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ) i5 Y2 K2 b, ~2 O3 _    logger.info("basic signed raw: " + basicSigned.toJson());
    2 @" Z! F! C) @9 M4 a$ ^    // call sign transaction api to calculate whole raw_transaction id' J3 P( Z2 R" H7 W, n7 ~
        // sign password is None or another random String
    2 c. S6 Q  t9 J6 V$ B5 W    Template result = new Transaction.SignerBuilder().sign(client,
    , m3 a+ [5 a5 }1 q" J                                                           basicSigned, "");1 m2 ^1 q6 b' V) R4 {/ w
        logger.info("result raw_transaction: " + result.toJson());
    8 N, T' ]# ?+ N$ m    // success to submit transaction
      T% d. P9 c7 t6 m1 M8 m" ~}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13