Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
109 0 0
比原项目仓库:
& v* R' e/ B2 p+ R! C% ?: g& dGithub地址:https://github.com/Bytom/bytom4 \' W9 D. n  t8 D+ r
Gitee地址:https://gitee.com/BytomBlockchain/bytom
6 G( |# z9 k) ~6 A1 t. u; D2 `- }! itx_signer
( @$ _5 }/ J2 K* Y" {Java implementation of signing transaction offline to bytomd.
  G* I" p4 F- k6 NPre+ {% A4 j; r4 K" Q
Get the source code
% ~( l: S" V! R! ?; s$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom! t/ o' ^; X3 A( k. F1 G
git checkout1 J( w) P: c2 [* F; R4 U
$ git checkout dev+ l3 t! }( K: H! q4 S) H! o
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
/ Q) K( k& X! N' F8 A8 f% e( JBuild: W; y& \7 K' @: \
$ cd $GOPATH/src/github.com/bytom& j0 Q2 q2 t) e! q6 ?  K) z1 |+ V
$ make bytomd    # build bytomd$ t* \, \0 w+ i8 d7 ]/ a
$ make bytomcli  # build bytomcli0 A8 e' x3 P& T* M% t
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
( G- u7 o+ K' s/ o: ~( pInitialize
' j' z6 Z! P; L4 F4 ?+ m2 V; L/ y6 OFirst of all, initialize the node:* f' ?& O* A8 e0 E$ R
$ cd ./cmd/bytomd) L, e8 v  W' u$ ?0 i
$ ./bytomd init --chain_id solonet' X2 [2 y2 ?0 D
launch9 j% M  x7 W, D9 ~2 L1 u7 ]* H
$ ./bytomd node --mining% i2 i/ g5 `: K$ ~/ q' Z" ~0 K% G
Usage9 A5 D* m. F( u" Y4 v/ ~
Build jar0 {' r. A3 g) S* [

  •   e! a# i$ O! n0 H' y0 Hfirst get source code
    9 M( C2 r2 O: L# _8 Z" kgit clone https://github.com/successli/tx_signer.git1 m- D. m* q, n+ [7 A

  • % W! i& {% J+ uget jar package- A3 z( }: z3 o
    $ mvn assembly:assembly -Dmaven.test.skip=true  P& Z' \. k7 p& Z8 }7 @
    You can get a jar with dependencies, and you can use it in your project.& i1 O  `$ j. b8 _
    , B  P# B" ^& ~7 g' E2 K% ]- M% Z

    * ?0 h9 @/ a/ v5 wTest cases
    & J+ |, @* \, v! e- `Need 3 Parameters:
    - O9 t  T1 n* d4 {
  • 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 api8 b+ n( ]5 b' H

    7 _6 S* G/ q9 `2 f9 L, Y6 bCall method:
    ( M9 O, o" C* ]' J9 a// return a Template object signed offline basically.  M* M) c3 ~( x2 X
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    ; o5 y* r. `. Q// use result's raw_transaction call sign transaction api to build another data but not need password or private key.3 C+ V) E/ T0 P# y
    Single-key Example:# h2 w+ a! J6 `8 o; U+ N* W
    @Test: |( _: Z! m( B% k  O
    // 使用 SDK 来构造 Template 对象参数, 单签
    - E. m0 \' D. k4 w) {public void testSignSingleKey() throws BytomException {
    8 e- @) H8 J1 C4 b1 i    Client client = Client.generateClient();9 _! _- }9 B) M
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";% ~9 Q4 k' I$ @' S
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    & V: z0 Q" |0 T/ `    // build transaction obtain a Template object
    * |9 q* Y# I( J+ K    Template template = new Transaction.Builder()
    + j! k! o7 a# c* ^        .addAction(
    - J* a2 t9 h7 }/ E) `6 X5 Q        new Transaction.Action.SpendFromAccount()
    4 j/ s3 C# Y) b0 I+ a# t! z4 r        .setAccountId("0G0NLBNU00A02")! M6 C- }* h% U" d" I8 F
            .setAssetId(asset_id)
    % `% D" B% [  ]        .setAmount(40000000)
    + k2 C" V: ^8 G9 E    )
    " j% |* }- g* \; `1 [0 i8 V        .addAction(
    3 l! w! _! f4 \1 u        new Transaction.Action.SpendFromAccount(), D8 H/ H! b0 j2 r
            .setAccountId("0G0NLBNU00A02")
    / |9 |  d: _' |( }5 Y        .setAssetId(asset_id). T6 E% u) o3 B2 Q9 g) p- ^
            .setAmount(300000000)
    5 ^# x2 N1 l9 t4 c. h    )
    1 q& N* e% U) M0 B        .addAction(
    2 v) d  _7 s% ?2 w* u; o( r        new Transaction.Action.ControlWithAddress()0 y& f& z: Z* E  h
            .setAddress(address)* t  B  a* T% i/ E7 ~" H/ C
            .setAssetId(asset_id)4 K% d3 E3 t# w" [, ]( l: i6 E
            .setAmount(30000000)
    9 b7 y$ e/ H+ d, X* P  r8 u    ).build(client);6 F0 r5 [, K( ^' w
        logger.info("template: " + template.toJson());* D( D3 a/ k9 J( a6 H9 @
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object! U. ~$ h) L" P$ ^1 {
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    ; h, I* f- h7 d+ M7 m; D    logger.info("decodeTx: " + decodedTx.toJson());
    1 g7 z: M% k: ^/ a. u    // need a private key array0 j  A9 `  N! t  h0 N3 x
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    # K" v" w6 ?. @    logger.info("private key:" + privateKeys[0]);7 h7 ]5 b; J: e+ w4 z% X
        // call offline sign method to obtain a basic offline signed template
    ! n5 _' w9 W$ b" L/ d( Z    Signatures signatures = new SignaturesImpl();
    9 Z7 {2 s1 _  ?    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);) w0 G$ [0 F- \$ ^
        logger.info("basic signed raw: " + basicSigned.toJson());
    8 a# Q% g$ G4 m; `# ~- U' n& ~    // call sign transaction api to calculate whole raw_transaction id2 \, p/ n# I, c( O7 s
        // sign password is None or another random String5 z; t$ v, d: T! J
        Template result = new Transaction.SignerBuilder().sign(client,
    ' D+ x" E% V* k" j+ S9 q                                                           basicSigned, "");8 }# }# b. Y+ b1 d
        logger.info("result raw_transaction: " + result.toJson());
    % W4 z1 V1 k/ |  v# D' u- A1 C# q5 f    // success to submit transaction
    ; v$ {7 \* y" Q' D$ i}
    - x1 p% H% ~# ], P1 yMulti-keys Example:
    3 E4 e4 t) q6 c2 W
    7 G& f5 A: d; e& A9 \* j6 q3 INeed an account has two or more keys.
    6 o0 p' J1 r, @0 E% u7 M  l

    7 |7 R) D3 d9 C@Test8 j4 l9 J; M& {) O* Z
    // 使用 SDK 来构造 Template 对象参数, 多签) c. @" O  I! g. Y! I0 n! `8 Z
    public void testSignMultiKeys() throws BytomException {" J3 B7 g& Y: i' p
        Client client = Client.generateClient();
    + v0 s) A. ~1 E  Q. S2 Q4 {9 H( ?    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ( ~3 {) ?8 S3 ^    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";5 X. L3 X8 B7 j9 V
        // build transaction obtain a Template object
    , ?( c' @" g8 |& v4 W: o    // account 0G1RPP6OG0A06 has two keys! F) Q9 q- {) o: I8 L
        Template template = new Transaction.Builder()
    ; M( r4 `  C# `4 B- U3 G4 B        .setTtl(10)
    : _  x# Z% }& }: f- H$ u0 ]0 E6 |        .addAction(
    6 ]7 j( Z  }) [! n$ y        new Transaction.Action.SpendFromAccount()
    4 k0 i% V- O9 o. J+ r. r        .setAccountId("0G1RPP6OG0A06")
    7 @. J1 @/ ?; S6 g- d- W        .setAssetId(asset_id)
    5 a5 }8 J+ u7 {' _        .setAmount(40000000)
    - \1 }8 G/ r9 ~  t  R- L    )
    * M: u6 b- e" A# p  F- i        .addAction(( y" t6 s! E. l' m8 V6 ]4 H
            new Transaction.Action.SpendFromAccount(): r5 `& b8 e1 T% o
            .setAccountId("0G1RPP6OG0A06")' F! D  \5 o$ \6 H) a
            .setAssetId(asset_id)  O8 b* n6 _' @* H* Z
            .setAmount(300000000)* l6 N8 G: h$ d$ }9 h( D
        )
    9 L# L4 X( e+ U0 B/ w        .addAction(
    8 d: F* ~, u* N7 k. i        new Transaction.Action.ControlWithAddress()
    ; f) i3 j( k% v        .setAddress(address)! P: t7 w2 z$ \2 c2 o8 N8 ]( {
            .setAssetId(asset_id)
    - W1 h8 u+ s& E5 L: A/ X        .setAmount(30000000)' i0 h4 X, D) g! W' `
        ).build(client);
    $ x: O- M2 u# r- F* p$ d: u    logger.info("template: " + template.toJson());/ l; U. `6 s* O' ^1 x1 P: y
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ! L* r/ L- A" l# g+ T! }# b! |0 F    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);' H) P" L: P: T$ D
        logger.info("decodeTx: " + decodedTx.toJson());4 k/ A% H; q$ t9 M) S
        // need a private key array
    " j! a( _4 E: o1 e8 F    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",3 A; ?( d0 n. J; ~4 d
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};  J. r+ A3 t1 m+ C+ S
        logger.info("private key 1:" + privateKeys[0]);
    1 B1 B' u) {+ r- B" Y6 I% u! o    logger.info("private key 2:" + privateKeys[1]);
    + P7 T9 w( O0 b2 D4 H    // call offline sign method to obtain a basic offline signed template3 P+ N# m! w8 L( G. ^
        Signatures signatures = new SignaturesImpl();/ Q* V8 ~9 x' h( }* ]3 o4 \# N
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    # l, x: H8 Y7 }7 A% l    logger.info("basic signed raw: " + basicSigned.toJson());
    ; m; m( V: m$ M3 S# u6 O* p    // call sign transaction api to calculate whole raw_transaction id
    " E4 x( I/ s) h9 r    // sign password is None or another random String1 o( Q- C& Y+ m4 L/ c( ]8 u
        Template result = new Transaction.SignerBuilder().sign(client,3 m! l8 S' l% N6 O; M0 P4 D, P  d* {
                                                               basicSigned, "");+ ^2 U9 V$ s6 z
        logger.info("result raw_transaction: " + result.toJson());
    4 i; \& U9 b# D7 Z1 W    // success to submit transaction
    " Z( E' h# m( @}
    7 ~! f# b$ |; q& o- c$ h" k1 t3 M$ tMulti-keys and Multi-inputs Example:  R* z* O! r' K; s, b1 n
    @Test
    0 @2 g7 ^8 @3 U: z0 b) u( l5 E// 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    ; ]1 a( c& x  T- f4 Spublic void testSignMultiKeysMultiInputs() throws BytomException {
    - {7 Y0 t* g# J6 {, g. D, c) W    Client client = Client.generateClient();+ a% G- K+ G( y! [, [
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ( K" I' n( D' k    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";  v( X* ?( o4 S7 c9 Z9 Z
        // build transaction obtain a Template object2 E1 }: R6 u- I( E. n6 S8 W
        Template template = new Transaction.Builder()
    4 w# S7 d* [; f% w" h# }        .setTtl(10)
    0 w2 U" f8 _, j) S" e# _        // 1 input1 z* L9 \$ _0 @( x* B2 I
            .addAction(  z, p9 Y, o# r1 H; A) s7 G
            new Transaction.Action.SpendFromAccount()8 ?. t; [; d3 Z, U
            .setAccountId("0G1RPP6OG0A06") // Multi-keys account. s6 r$ |2 q% j% a1 e2 P
            .setAssetId(asset_id)
    , ?( @; x1 j0 p  R' A8 @( F        .setAmount(40000000)$ [6 k' E7 ^7 S, }" P+ T+ ]; K
        )
    ' V! M, i  V5 o        .addAction(
    ' Z7 J2 r* t* O3 p* ]* G        new Transaction.Action.SpendFromAccount()
    & N) y) |3 W- R$ g) m0 b# y: P        .setAccountId("0G1RPP6OG0A06")
    ) e4 n9 e" X7 W2 `- m" q& u( ~        .setAssetId(asset_id)
    9 [3 ]" ^# F5 l4 u; \        .setAmount(300000000)
    9 g% s5 ?) Y+ D; c' S    )    // 2 input# v( G  I; @3 U/ M% o9 m5 X1 F
            .addAction(
    + w" `, ^$ {" [$ _4 Y  T! N        new Transaction.Action.SpendFromAccount()1 V3 O, {4 d( {: F& O& Y( G
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account$ c$ N3 T4 w* A, T4 q& e4 u
            .setAssetId(asset_id)
    8 l3 n5 z  r" q3 {        .setAmount(40000000)
    4 J0 J/ D# t6 q$ y3 `" Y6 ?  Q    )
    + J. u+ B2 f& |$ x        .addAction(. W& ]' |. o* X7 {+ E
            new Transaction.Action.SpendFromAccount()
    " X! M" v6 M- E. e        .setAccountId("0G1Q6V1P00A02")
    ' d) P4 q2 w: V  `        .setAssetId(asset_id)  p, W8 u+ `% m" M5 h& e
            .setAmount(300000000)
    2 t; \2 K6 k: J+ d8 d" X, v# r    )* u$ C1 F+ t, \
            .addAction(, m* U$ }( q* O
            new Transaction.Action.ControlWithAddress()
    0 e, U7 r3 W* W" G        .setAddress(address)
    ' t1 v% r  E% L4 d, ]        .setAssetId(asset_id)" ^! ?. G- u) ^! X, C. @* o
            .setAmount(60000000)
    * @& L; B& ?" o; T    ).build(client);4 E. z" ?" U7 j  j" N
        logger.info("template: " + template.toJson());
    ' F6 s6 s: J# B; ^0 v% \0 _2 {& |    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    2 S; n, W2 Q$ z8 C+ A1 J    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);1 V! x, X  i* V8 _+ @8 m7 p
        logger.info("decodeTx: " + decodedTx.toJson());
    % Y. D4 b4 n4 L! Q1 P    // need a private key array* B6 ?# W3 V6 \1 }2 e( z
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",8 E. l% r8 V; M
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
      ?8 |" S( }0 J% O/ \9 @4 K$ G! B! u                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};  w! }* v" Q& P0 @& r" r
        logger.info("private key 1:" + privateKeys[0]);
    $ e, K1 m' D" q, F  f    logger.info("private key 2:" + privateKeys[1]);
    2 I' \7 u9 C$ N7 w    // call offline sign method to obtain a basic offline signed template' C5 v/ i7 p! x  s9 y/ r
        Signatures signatures = new SignaturesImpl();; b( W& Z- K: w& ?0 X
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    * G+ U4 v% u* Q, S% A  s    logger.info("basic signed raw: " + basicSigned.toJson());" }' K5 {/ A) P7 _# P- E" P
        // call sign transaction api to calculate whole raw_transaction id* U; u+ l1 v- v) c0 W
        // sign password is None or another random String
    : I- o' y2 Z) o; v6 Q: m    Template result = new Transaction.SignerBuilder().sign(client,
    2 Q: p. g, D1 I/ z                                                           basicSigned, "");
    / z( n  x) d1 R" {1 s    logger.info("result raw_transaction: " + result.toJson());& t# O" ^" K/ K
        // success to submit transaction
    / O% \& X; `( O  X% o}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13