Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
157 0 0
比原项目仓库:, p1 {( Y( _2 e9 _- i$ o8 _
Github地址:https://github.com/Bytom/bytom
" `. L$ `1 t8 a2 wGitee地址:https://gitee.com/BytomBlockchain/bytom1 @+ a1 L) @6 ?0 K0 W' C. d
tx_signer6 ]5 ^# S& H  G. x8 c% c- u
Java implementation of signing transaction offline to bytomd.
; N! i6 F( T, J/ SPre
% t1 B. \4 \( u  Q6 {7 \$ ZGet the source code% G, s- L2 m, {
$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
+ k$ L" R& u6 X% I# Z1 tgit checkout
' w6 q5 |: ?+ j0 y2 H4 r8 R$ git checkout dev
% E  L* G  |! J: \! S. w! BWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.* q. o/ Q5 z2 \. `" d2 D4 [$ D
Build4 w6 n+ H$ e) _; v) q! C8 d/ i
$ cd $GOPATH/src/github.com/bytom. b! j- E& ~9 e7 l) C/ L( u. a" {* X
$ make bytomd    # build bytomd
: g* p; H' `6 P$ make bytomcli  # build bytomcli& i4 |( q: H" A5 i: h
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
; G) t6 n6 L, c  ~- hInitialize. Y7 ]! r; w) R1 \
First of all, initialize the node:
4 t$ a" F& _6 P' Q/ [# X( q& y$ cd ./cmd/bytomd
2 J" t/ n; O& \9 H% J3 f$ ./bytomd init --chain_id solonet4 R8 |( m0 D' g- b  T$ {' `0 C/ O
launch) {. U6 V7 T% @6 H) [' h$ y
$ ./bytomd node --mining
8 B4 S5 E* U& J( i6 w$ kUsage0 T' M6 i$ u5 {  w! s/ k
Build jar: S1 r/ }( f" J, J/ \, Q) Z
  • / K% G2 i  i0 A) S: f& N1 C1 \
    first get source code9 {& q! p8 k; n* `0 O4 w
    git clone https://github.com/successli/tx_signer.git, h8 f6 X4 J8 g' p9 q

  • ( q7 T3 A, x- b" bget jar package
    ( m: e8 o7 n! H8 ~5 h) \7 [/ [' E1 M$ mvn assembly:assembly -Dmaven.test.skip=true( b6 M6 r1 p. D+ z( ]' ~
    You can get a jar with dependencies, and you can use it in your project.8 P9 R6 B* C2 X8 F1 @' a
    2 t9 |9 r( i3 l+ ?+ S

    : ~- Z: q0 M3 m  m3 q4 W( FTest cases
    / V( b* Q- R( d* K$ H! JNeed 3 Parameters:
    ) a% G+ V4 E  y9 j
  • 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
      }9 k) k1 n) q* i) X, r( Q
    * b0 @. F: M" g( C0 j0 N
    Call method:
    5 Y( C5 {* h  W3 W8 g% ], A, i// return a Template object signed offline basically.5 S2 ~% I4 \4 x( e: o4 ]% c
    Template result = signatures.generateSignatures(privates, template, rawTransaction);4 {5 R5 l8 x- E; X. f
    // use result's raw_transaction call sign transaction api to build another data but not need password or private key.0 U, Q2 h* G: ]! q$ P: D' f
    Single-key Example:0 B( c3 W: s" |( A, D! m+ J
    @Test' b0 b4 s  e  [1 S! N
    // 使用 SDK 来构造 Template 对象参数, 单签
    " {3 I9 K4 J+ h  h9 {9 O8 Opublic void testSignSingleKey() throws BytomException {
    9 S$ J5 h" g. k3 x    Client client = Client.generateClient();6 G" C. c( o, u
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ( ]" ^- d# l( c2 J, b3 n) g    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";1 _4 e: a# m: B
        // build transaction obtain a Template object
    3 S7 u2 e4 t/ x    Template template = new Transaction.Builder()* G/ d7 r  W# k% s4 j; D) N% B/ J
            .addAction(
    0 E$ O# @0 p& a0 L* N        new Transaction.Action.SpendFromAccount()
    ; i- K  W2 b! N7 T' p        .setAccountId("0G0NLBNU00A02")
    # v+ G9 }6 @! ]! L" C7 v" i* z6 n        .setAssetId(asset_id)- K4 `- T' u4 j) ~2 j/ [1 p8 P
            .setAmount(40000000)
    " B8 `* d3 A# ?+ ]    )
    7 D# K- S9 o6 V) H2 M0 p9 w        .addAction(. D. k3 |# |8 o+ R  x  W. b
            new Transaction.Action.SpendFromAccount()! F* [& A* Z. k) p: ~
            .setAccountId("0G0NLBNU00A02")
    " [& @9 ]1 q5 X( t* x4 i; O        .setAssetId(asset_id)
    + p8 s/ [  [3 `6 p5 `1 t        .setAmount(300000000), Y9 m% k  _+ G8 W# v
        )7 i: W- n$ d% I7 \6 f. C9 e
            .addAction(; T% }' R! G2 T1 p& o
            new Transaction.Action.ControlWithAddress()
    : Y; H2 S/ [4 s3 w        .setAddress(address)/ b; c/ a, J: W% C8 ]5 ?1 U
            .setAssetId(asset_id)
    / v  y( H* h( I4 d% M' J        .setAmount(30000000)
    2 h' W0 @* {& w' T+ d; G1 Z    ).build(client);
    ) l- p) [# v1 r- \% i    logger.info("template: " + template.toJson());
    ' N6 V; x' }8 H; y+ E! Q- z7 r    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    9 X, |, b2 X) z& y- m    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);0 P: u# h- f9 Q+ e0 j% e
        logger.info("decodeTx: " + decodedTx.toJson());
    0 \/ b5 s$ D; q3 `    // need a private key array( [# u% m' k1 D5 }$ r
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    / J9 U" f4 U" P# y  p! Z- B; l    logger.info("private key:" + privateKeys[0]);
    % a2 G( [  N# v7 e    // call offline sign method to obtain a basic offline signed template+ N6 Z: e! B1 Q2 j  k+ g. b
        Signatures signatures = new SignaturesImpl();
    ) ^$ ^" M: a1 s3 v  S  w    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    + p1 m# i* h( o$ @0 ?    logger.info("basic signed raw: " + basicSigned.toJson());
    $ t) a* v: s  m* g  j    // call sign transaction api to calculate whole raw_transaction id
    % u, q4 {1 j  v5 p2 W    // sign password is None or another random String1 S7 S, X! i5 {( C! N. ]- B9 S
        Template result = new Transaction.SignerBuilder().sign(client,2 l9 E& k$ S' T
                                                               basicSigned, "");
    2 `% \- v5 a2 j! C# n4 p0 Q! r    logger.info("result raw_transaction: " + result.toJson());% I2 O9 b. I5 e: ~, O
        // success to submit transaction
    * U5 h1 n" X- L* b' L/ S* e}
    $ }6 s0 r& ]- I; o* PMulti-keys Example:* |% `; [4 E, p, k
    $ @; A6 p& @/ v3 U2 W' Q
    Need an account has two or more keys.
    " z, V% e) f6 T( S1 {, R
    % s( C7 F; u* F+ w# K
    @Test! @& j1 d" B- A! M6 X6 X% m' r
    // 使用 SDK 来构造 Template 对象参数, 多签4 k1 ]2 s  y) K/ o* _* B
    public void testSignMultiKeys() throws BytomException {
    9 d1 [% b6 o: b+ W( p& V    Client client = Client.generateClient();
    % H7 n0 ]) _- s, H7 K    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    3 Y8 y2 v& z0 R5 W& \- J2 P    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";4 u* b. m! g1 ?& |3 r6 H* l
        // build transaction obtain a Template object2 ?* A$ x2 T+ |% V' G
        // account 0G1RPP6OG0A06 has two keys
    7 T! B3 e( m, J" _: {    Template template = new Transaction.Builder()
    + D. C3 D1 q: M2 L% d% F& \        .setTtl(10)% U+ Q* F& E2 i, T3 r
            .addAction(* m5 R; [' j* [7 K
            new Transaction.Action.SpendFromAccount()
    0 z+ K" N7 J) a& C4 m" c" K        .setAccountId("0G1RPP6OG0A06")  s5 k1 W: c7 J1 ]) Z6 a0 q5 B
            .setAssetId(asset_id)
    6 H* r& G' {- o9 N7 h4 }        .setAmount(40000000)! u4 f( N$ l. r9 X) T2 p
        )
    ( w  T" y6 k, J: Z/ |) H8 C+ y' I# a        .addAction(
    2 i' p$ X; k6 o9 a4 }* B1 n        new Transaction.Action.SpendFromAccount()" G! `; _$ W8 s0 O& J0 v1 O
            .setAccountId("0G1RPP6OG0A06")
    4 M9 b8 T6 S* i+ ]2 f2 {# q        .setAssetId(asset_id)& T; m. x" t7 E4 f: U
            .setAmount(300000000)
    4 V0 i$ l( c2 l7 h/ U# `3 Z  O    )7 q& H7 a( C8 q$ m* _. P
            .addAction(
    ) b& O& m3 {" F% a# f  [        new Transaction.Action.ControlWithAddress()
    + H& k  D% J# G7 k9 k        .setAddress(address)
    ' U* a8 C. F5 i. x- S% ~* T4 C+ l$ ~0 [        .setAssetId(asset_id)* a5 a5 ?( Q! \4 E' y0 i% m& ?
            .setAmount(30000000)) v" {# e4 X# y4 R& R0 {7 |
        ).build(client);
    4 P0 {+ \4 }7 m1 D7 U$ R    logger.info("template: " + template.toJson());
    $ L. h3 B" N- F1 q# R8 Y# {    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    + G, l# R6 Y# o- Z) }    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);' Q! _* g( U% ?4 x1 k
        logger.info("decodeTx: " + decodedTx.toJson());
    7 q% U- l6 l& {' R, v  P    // need a private key array9 W+ s/ u: X# K8 Y, T3 _6 f
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",: `' N. j- N$ y$ \, B
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    : j! }/ [8 J4 h: J# t% C    logger.info("private key 1:" + privateKeys[0]);9 u) N6 n! u3 \/ F* L$ V6 V3 Y! [
        logger.info("private key 2:" + privateKeys[1]);% m$ L/ g$ k5 Q
        // call offline sign method to obtain a basic offline signed template* `% S& D: n1 \' C
        Signatures signatures = new SignaturesImpl();4 A) f* {/ X. X6 `2 B
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);) a* T- P0 Q. f) B' O
        logger.info("basic signed raw: " + basicSigned.toJson());
    6 T1 j% k: [2 U" v; C  y    // call sign transaction api to calculate whole raw_transaction id& L' e* E, V, T% H' V) [5 W' L
        // sign password is None or another random String
    ! b8 j) j8 @1 }    Template result = new Transaction.SignerBuilder().sign(client,' b" v& P' b1 R( l( X! h
                                                               basicSigned, "");
    # k1 B9 O/ C/ `9 H    logger.info("result raw_transaction: " + result.toJson());
    # k' c5 o' [- p( X3 z: T# s+ i! m    // success to submit transaction
    - |- z- M  v; j}
    1 f1 `: f- s2 X( J# {% rMulti-keys and Multi-inputs Example:' [% ]- w7 G7 F& ~( X( k
    @Test3 j, t% ]$ ~) M- A' C: d9 D$ \
    // 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    / ^7 D+ L' j3 ~$ g+ h$ \: epublic void testSignMultiKeysMultiInputs() throws BytomException {
    + Z' i/ p. V- C1 _0 @& i& _    Client client = Client.generateClient();& x  k& i3 i$ g! I1 T
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";  y4 K& J% x- E" p1 I
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";; K7 `3 A( x/ q) R# ~7 {" n# T
        // build transaction obtain a Template object
    $ `0 G9 o2 Q6 e- g    Template template = new Transaction.Builder()
    , ?! @+ k$ e2 _$ |0 M9 E        .setTtl(10)
    7 I4 ~1 q- j" p5 b6 {+ l        // 1 input+ |% V/ \2 Q6 y" V/ w/ P
            .addAction(, V" I5 e' X1 l' r
            new Transaction.Action.SpendFromAccount()
    0 L" Z( I. n6 h% n$ u( s. L4 i        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    , s, E7 Q6 E" |9 |& o        .setAssetId(asset_id)' q- f- F* D" p, s# B
            .setAmount(40000000)- l- R( j4 ^) g1 C' ~
        )
    $ x- v+ w. n& Z6 I8 G: E        .addAction(
      J9 B, V* V( \! B; \) c: q        new Transaction.Action.SpendFromAccount()  r' {5 r1 m8 J
            .setAccountId("0G1RPP6OG0A06")
    + m' j3 E5 y% y# Q. S        .setAssetId(asset_id)8 d; z  o) U# n2 R* V
            .setAmount(300000000)* D8 ]5 H  |. z. D: R
        )    // 2 input/ Y4 I, {0 T) n
            .addAction(
    + t4 r. w5 c1 r- |1 {5 ?" T  N        new Transaction.Action.SpendFromAccount()# I0 c; j- g" W
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account3 T* S- v/ ~: ~; C% d
            .setAssetId(asset_id)
    ; a, T& ]; t4 N; c3 k/ C        .setAmount(40000000)
      _3 @  q1 \  K; B    )
    & i9 D/ d% N8 [        .addAction(
    2 [# a8 |) Y& h# H9 W1 l6 Z$ _' ]        new Transaction.Action.SpendFromAccount()2 |7 q* U8 J- f
            .setAccountId("0G1Q6V1P00A02")9 k# ~0 ~8 A9 V" L) n, P0 G, t
            .setAssetId(asset_id)) b. l( }9 X$ c+ P7 {- I6 W
            .setAmount(300000000)
    0 f7 U8 Y" ^/ P/ m    )
    8 Q4 i7 U" V( b7 i5 O        .addAction(1 C. P& g# g- D: @
            new Transaction.Action.ControlWithAddress(), T4 Z# i2 {, J1 j( u* a7 X
            .setAddress(address)
    ( j: R& u- b6 Z0 F' N$ D        .setAssetId(asset_id), s! v8 l) D8 B5 n9 d; H
            .setAmount(60000000)# z9 w* Q4 p/ ]9 L8 s1 g& A( z
        ).build(client);0 q+ C% w+ _/ J4 [' l( O3 c
        logger.info("template: " + template.toJson());
    ' {- y4 ^2 L$ O+ A2 Z- w1 O- ^8 \    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    . z, R8 D$ x4 n0 K    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);8 d) y* }$ S  l5 g4 W( m
        logger.info("decodeTx: " + decodedTx.toJson());
    - c4 V9 p9 m* T# X7 D    // need a private key array0 \# R7 W  ?% u& K# I. O" P, M& }! }
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",. }: [- M/ @1 C9 r9 D
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    3 ?4 i1 m  C! U                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};: P. G" M0 @5 m' C
        logger.info("private key 1:" + privateKeys[0]);
    4 t$ ?+ k8 h$ B    logger.info("private key 2:" + privateKeys[1]);
    8 O* ~3 m  }# `    // call offline sign method to obtain a basic offline signed template! W+ G& r) l5 I$ Q5 _! o
        Signatures signatures = new SignaturesImpl();' w5 o' O+ H' k# T* l- f+ o
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);6 d, z4 u, t% _6 N9 @
        logger.info("basic signed raw: " + basicSigned.toJson());
    ! {, d8 N. u" s9 c    // call sign transaction api to calculate whole raw_transaction id  W  P& C4 n1 W1 H( I4 `
        // sign password is None or another random String1 Q$ o" U! r+ O2 t( b
        Template result = new Transaction.SignerBuilder().sign(client,  P) J* @$ X! \  ~3 D9 P! Y5 e
                                                               basicSigned, "");
    , g1 w& i4 |0 S. g: [! N    logger.info("result raw_transaction: " + result.toJson());; |* G0 E+ N6 j) V
        // success to submit transaction
    & ^: p0 T' h" @$ }/ Z2 e}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13