Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
88 0 0
比原项目仓库:1 P( }% p5 [7 M' m; P8 B( J
Github地址:https://github.com/Bytom/bytom3 b! e. ~2 M& ^: f
Gitee地址:https://gitee.com/BytomBlockchain/bytom  y5 f2 H7 [! W9 [+ B
tx_signer
7 h1 F3 |) O- @, ^# U) q0 D6 K! LJava implementation of signing transaction offline to bytomd.
* P% P' V) }2 d7 lPre
- z; W: Y7 K: w% V5 \, I8 u/ mGet the source code
7 l" w5 Y9 J- x8 L$ h* D* q- ]2 A$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom4 d8 M* K, o1 ~+ ?  V
git checkout/ A7 E% J9 \/ \* h" q0 m
$ git checkout dev
4 d# U6 K; V; r% VWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.5 ^/ O9 k, D  t/ g  a" ?2 V
Build
: H6 y' @. @6 c2 n* ^$ cd $GOPATH/src/github.com/bytom1 |+ F; b7 v; ~- L
$ make bytomd    # build bytomd8 t4 Q! q. y! L  F3 E
$ make bytomcli  # build bytomcli
# \5 c8 e0 C# R! Q" k0 E3 }When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
9 Z$ G0 `- @( t- G$ B' W) [Initialize3 u9 e+ B7 F( t5 a; S
First of all, initialize the node:
1 \( k! G6 a" Z7 E+ s9 |4 x/ V+ M$ cd ./cmd/bytomd( x: k  m% O) R# L* M/ |6 D
$ ./bytomd init --chain_id solonet) j- o8 U' j( W! J
launch
- I2 P: @$ z! v* ~$ ./bytomd node --mining
# X  M- D- b4 T8 _/ s* GUsage
: ~) T: d) T$ q  KBuild jar
7 z/ i# Q, E, w" X+ \; H9 N; a
  • % P; o% W# u0 O
    first get source code
    4 r/ p0 b/ X# t( Ngit clone https://github.com/successli/tx_signer.git
    " u6 E  ?, }4 K8 `
  • + e6 M/ H- m$ o$ P/ ]
    get jar package
    $ ?: Z  Y& k, O# ^9 c$ mvn assembly:assembly -Dmaven.test.skip=true
    + G! y6 i2 F: {* s' z* a& HYou can get a jar with dependencies, and you can use it in your project.5 |6 P( i* V$ @5 G
    $ o5 a. A2 f, ~: q
    : F2 O  `5 g8 j7 |
    Test cases
    . C+ u, r. w9 ]Need 3 Parameters:2 N( u$ b/ f; S  O# l3 O' L2 |
  • 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: j0 S. R( O$ ^! q9 j3 r

    : S' a4 y3 m' ~# I# t9 gCall method:
      P8 _& |; |9 \2 ?* j5 ]// return a Template object signed offline basically.
    8 |- v3 c+ H- A: ?) J4 }% dTemplate result = signatures.generateSignatures(privates, template, rawTransaction);4 _: P4 X. Y+ m; u4 E9 M) h
    // use result's raw_transaction call sign transaction api to build another data but not need password or private key.
    , A) s6 R; o' j8 }Single-key Example:' A; {/ j$ K! J+ g; j
    @Test
    * E! w# e. S. x  ^. I: z// 使用 SDK 来构造 Template 对象参数, 单签
    * e* k+ a* p/ o2 h* Zpublic void testSignSingleKey() throws BytomException {6 y5 F$ F. @2 E% E8 d8 {8 [0 e
        Client client = Client.generateClient();1 N& g3 R9 m5 I/ \1 F, i6 s4 j! l
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";: e# N# c) T; u$ u$ I
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    1 y" r! q; q* v# ~- I7 E    // build transaction obtain a Template object8 \, e  a& y; Q% A( Q/ j4 x5 d5 L
        Template template = new Transaction.Builder()
    ) r* C0 a- r. R6 R; T# W; o+ O        .addAction(* u+ C* x' G# k! u* N9 I: `' L* v
            new Transaction.Action.SpendFromAccount()
    % k3 P# j( [: x3 L1 }- u        .setAccountId("0G0NLBNU00A02")2 F" M$ T, @' Z( ?" I  @
            .setAssetId(asset_id)
    : e3 q2 y# {' B) R" y# g# j        .setAmount(40000000)
    ( n0 q  m" r  v( l    )
    : r! j" J' ^4 h6 G3 `        .addAction(3 }' b/ b% y6 \5 `1 y
            new Transaction.Action.SpendFromAccount()7 R( Z5 a$ Q( X+ Z7 k$ {5 O! g
            .setAccountId("0G0NLBNU00A02")
    - g, K8 c2 f5 t" Y8 t        .setAssetId(asset_id)5 f2 F: N( n! r( g
            .setAmount(300000000)
    , p9 W5 v! {5 c    )
    : c4 G: `, H6 u        .addAction(0 H/ I% W9 h2 h* Z. r) O
            new Transaction.Action.ControlWithAddress()# U3 \! i0 e1 {6 v' t/ g
            .setAddress(address)
    ; q$ T- L3 t* S2 v        .setAssetId(asset_id)
    0 d. j5 j$ d- ]4 E& n8 ~3 a        .setAmount(30000000)
    ' H  Q( j& l' ^( x2 w& Z$ }" I9 q    ).build(client);
    + q: m, A& e- |8 w6 O    logger.info("template: " + template.toJson());
    , x- k7 e, o' W  j    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ' p3 J8 m  l; [/ W6 W    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    5 I* Q6 N9 ?" e* w) D    logger.info("decodeTx: " + decodedTx.toJson());
    5 b, J1 a& f0 b, F5 X# i1 S    // need a private key array) p$ E$ z' k: C" V
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};% F$ r+ A% E. s4 q" |
        logger.info("private key:" + privateKeys[0]);
      }( J6 z& s1 M$ e    // call offline sign method to obtain a basic offline signed template9 ~0 t4 O/ v7 a! m/ K! l' C
        Signatures signatures = new SignaturesImpl();
    8 A: q* K5 y, Z7 t* F# l4 p    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);. ~$ `9 a2 M8 p  A6 o* ]' g
        logger.info("basic signed raw: " + basicSigned.toJson());
    1 W0 k1 W4 F5 ]! P4 y# S8 U    // call sign transaction api to calculate whole raw_transaction id
    7 F/ m1 X$ {4 H; b    // sign password is None or another random String
    ! r1 ?  `% J1 ^/ D+ \- k) b* h    Template result = new Transaction.SignerBuilder().sign(client,
    " g" P4 t$ i( w: w7 }/ C, g                                                           basicSigned, "");
    4 ^% J; ]+ F; s+ T7 n7 u7 }9 ?    logger.info("result raw_transaction: " + result.toJson());9 T4 Y( f! r9 h
        // success to submit transaction
    + p' T* O: L8 B$ U}& N+ i3 a6 j; K( x3 c; G
    Multi-keys Example:
    ! y: v. F9 q# U' V2 J0 h# K4 d3 j1 x7 t# `1 n7 t, I' J! z) r) A+ ~: j
    Need an account has two or more keys.
    . R  A" A3 n8 b; A( W* I' E- s; y6 W

    * Y5 |( ?+ J3 {: h0 [# v3 b@Test
    4 i4 k3 @$ n3 h' k$ x// 使用 SDK 来构造 Template 对象参数, 多签& S; \+ l& p1 [/ a) _, }
    public void testSignMultiKeys() throws BytomException {
    ! X. J  y  I/ n9 `: E- o    Client client = Client.generateClient();
    9 j$ m, L; R9 n    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";5 W" r% u5 h0 ?; c) P! v
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";* i' \9 s/ M+ E
        // build transaction obtain a Template object1 z/ H# @/ y0 [8 M
        // account 0G1RPP6OG0A06 has two keys: P/ y3 r' ~8 V6 B' [- {
        Template template = new Transaction.Builder()
    ' k) d+ }/ h; F% r/ g; u5 W        .setTtl(10)
    - q$ p% R6 ?5 ~- s6 E0 ]- r        .addAction(
    7 D/ G+ k$ A+ E        new Transaction.Action.SpendFromAccount()
    / t7 z8 l. ?- Q) j4 y5 y6 a        .setAccountId("0G1RPP6OG0A06")1 Z. k/ `2 r/ C: `: T0 ~* ?
            .setAssetId(asset_id)2 G/ k/ h# K. G. E5 ^" W
            .setAmount(40000000)
    4 J: }  j4 G  d6 i    )
    5 G; S5 R2 Y, s8 d6 q& k* x% A6 K        .addAction(
    * D: ?% D; [: R: ^5 T# P        new Transaction.Action.SpendFromAccount()
      i1 v- T& u7 }6 a/ U        .setAccountId("0G1RPP6OG0A06")" R+ j  j' M4 |8 D. s. h
            .setAssetId(asset_id)1 z$ g! N; c* b9 T* H5 Z
            .setAmount(300000000), H, ?  [0 @( f5 {6 |
        )1 |" H. F; h/ I4 |
            .addAction(
    4 A' H: g- v, l! B- C        new Transaction.Action.ControlWithAddress()' g* ^& F+ D) m2 s; v3 ?4 o. F
            .setAddress(address)$ f$ V" P; B7 u' p8 h
            .setAssetId(asset_id)8 M( \& }7 L+ J  [( e5 k
            .setAmount(30000000)6 i# `$ K# B% u( D: |% h" O/ |+ C, Z& L
        ).build(client);
    6 A: }6 ]  S! m    logger.info("template: " + template.toJson());' n( O' y& c- W0 o
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ' V# V, d' t! ]/ J( ~: K    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);: v5 B4 g$ w. Z% F% _
        logger.info("decodeTx: " + decodedTx.toJson());. e+ }3 F2 I6 L# K
        // need a private key array7 U. Y3 r- S: F9 d4 a# v+ P+ P& C2 @* i
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    " T" W' f, L- S$ P1 F) }3 V                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};" G; ?0 m2 O% a7 v( H9 z" M% i) [
        logger.info("private key 1:" + privateKeys[0]);2 X  h( g3 o+ v) l' i1 a$ A2 V
        logger.info("private key 2:" + privateKeys[1]);/ e0 l$ f; a% {' p1 b6 H
        // call offline sign method to obtain a basic offline signed template( r9 }( e  N5 s1 E0 }
        Signatures signatures = new SignaturesImpl();) O- {7 G1 O1 e1 q* ]
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    * Z- E2 y; c- X( s    logger.info("basic signed raw: " + basicSigned.toJson());3 [0 [! E. E( G, b3 v% ?
        // call sign transaction api to calculate whole raw_transaction id
    7 W! e$ E  _) m; T6 B' I6 a5 z    // sign password is None or another random String
    & \0 C& V0 X7 x0 @* ~8 k3 Y3 \    Template result = new Transaction.SignerBuilder().sign(client,& G& {6 y( C) D, B8 A
                                                               basicSigned, "");2 E4 m$ ^- A6 `  N: u
        logger.info("result raw_transaction: " + result.toJson());
    6 _% _& }! D: x    // success to submit transaction* L$ ^2 d: c) N1 O  w2 r
    }, z& c! C  M7 l
    Multi-keys and Multi-inputs Example:
    2 C+ e+ _, N0 u' N7 ?, U% K; ?6 N# _@Test
    # V6 o$ g0 W' u1 m0 q" \// 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    2 Z) [* H" j: I- s# i  D" Ipublic void testSignMultiKeysMultiInputs() throws BytomException {4 n) W; a4 S$ O! W' A9 n. a
        Client client = Client.generateClient();
    3 c9 \& G- Q  Y: ~# W4 F    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    + ^) g& \0 V4 X1 \* e' C    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    $ J" K4 C/ y" B2 \) x! Y( |! D& G    // build transaction obtain a Template object
    5 W8 S2 ?+ m# d    Template template = new Transaction.Builder()1 y8 N' ^7 O. b/ K
            .setTtl(10)
      g7 Q2 q/ p& E/ M& ^        // 1 input
    " [' J- F6 c/ B/ s        .addAction(& R+ E2 [1 Y9 q0 e- E0 z: _6 A
            new Transaction.Action.SpendFromAccount()
    ) L) @# x  e, w: Z        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    / x. Y% Z4 V5 l: F$ k- E. D6 I        .setAssetId(asset_id), r& ^& [! v' T5 ^0 ?/ [, f
            .setAmount(40000000)9 s% C' p" X# u# j
        )
      b0 {, c/ L9 ~0 U, k        .addAction(6 n6 L  K9 Y. b$ D: h) X
            new Transaction.Action.SpendFromAccount()- g$ p* F7 H- Z" R) x
            .setAccountId("0G1RPP6OG0A06")2 O6 N* f  l9 z7 I6 {( ?
            .setAssetId(asset_id)
    & p) X: D* n" c7 u4 _        .setAmount(300000000)
    & N$ g, @- T+ d    )    // 2 input
    ; Y1 j% L+ [9 N  L        .addAction(
    1 T$ i) d! N3 b5 N0 g: U2 g( W        new Transaction.Action.SpendFromAccount()- G0 q1 n! ]+ P6 d$ L+ P& R% U/ I
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account
    ( F& t1 s/ s$ Y/ }- c% f- b% l        .setAssetId(asset_id)# i$ q) N+ G; O! F$ R8 L. B( a: d# E
            .setAmount(40000000)
    1 {8 E3 e# {( Q    )
    5 E8 d1 c7 t$ y( p1 ?        .addAction(
    0 g( Y) u1 m* \: V. W        new Transaction.Action.SpendFromAccount(), S3 ]  k  G, Y& [; ~$ ?$ z
            .setAccountId("0G1Q6V1P00A02")+ I1 ]: J: e* Z( W( ^' O
            .setAssetId(asset_id)8 K7 R2 e% F/ H  n' b
            .setAmount(300000000)* X* q- q" G# O; f& n  b
        )0 o" b% M$ Z5 |, g% c# C
            .addAction(5 }. p, ]# O2 J# @7 C
            new Transaction.Action.ControlWithAddress()
    4 q& Y- @" Z! w- ?: u4 \        .setAddress(address)1 R$ {0 Y- z6 N5 \' T- `- b
            .setAssetId(asset_id)
    2 p: W& ]" B7 O! f        .setAmount(60000000)
    8 c: i# _3 x. i9 t' ~* Y# W    ).build(client);( l( F) _1 e# k& ?0 Q4 [6 e' t; u+ U
        logger.info("template: " + template.toJson());
    3 Q/ c' b9 W- g% M! \) F    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object4 w+ w+ o! W  d$ S6 n. r- K
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    ) M$ d2 t9 H  l3 K6 [    logger.info("decodeTx: " + decodedTx.toJson());
    % D4 n- N) ~6 H% r" d8 {1 p3 X    // need a private key array
    + w  Q% i# c4 ?  o% |5 F. j    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    8 n. @) U  ?  p( F) b: x. d( N2 z( ?                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    . C/ m, A/ e" Y' }" R                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
    5 a- o4 T0 I- P' [    logger.info("private key 1:" + privateKeys[0]);- I+ O  Z4 U# i5 q4 O9 I7 E
        logger.info("private key 2:" + privateKeys[1]);
    # ^7 q, R+ X* T) r, H    // call offline sign method to obtain a basic offline signed template
    ' R0 o) }, I; y: N, n6 b    Signatures signatures = new SignaturesImpl();
    # @# e' b4 H8 \! F    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);  k7 ]7 E- r# H/ b
        logger.info("basic signed raw: " + basicSigned.toJson());" |2 t; B: ]* P" r" u  T+ x
        // call sign transaction api to calculate whole raw_transaction id
    . ^. f# e- @8 P& J- |1 k; J. n    // sign password is None or another random String
    6 f8 s- Y' Y9 L& \5 y) \    Template result = new Transaction.SignerBuilder().sign(client,
    $ {$ y6 O8 Q7 P( h' ~                                                           basicSigned, "");
    1 _$ N; t2 N, _3 s9 o& ^    logger.info("result raw_transaction: " + result.toJson());  J9 i7 N6 ?; D' d9 m4 M
        // success to submit transaction  |: W* F* H) O/ o
    }
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13