Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
100 0 0
比原项目仓库:& p( k* a+ a. Q4 c3 s0 C, l
Github地址:https://github.com/Bytom/bytom( A' ~. w1 _+ x' `
Gitee地址:https://gitee.com/BytomBlockchain/bytom' S# y* E7 C1 |/ j
tx_signer) A+ N2 q6 {. S  j/ `  R7 x: [
Java implementation of signing transaction offline to bytomd.
) K  q0 u% m$ ]# l+ iPre# c( {8 {0 b, U/ F0 j
Get the source code0 y: P$ M7 M$ b: Z# l- B( r4 V
$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
1 ?- l# [, C- l* ~git checkout
, F  p: R- [5 c8 B$ git checkout dev) }  G/ S% b% {
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
* V% n* K4 P% I6 kBuild2 ^. I. v* j* Q1 [2 v) M, o
$ cd $GOPATH/src/github.com/bytom
7 l2 y# W  k0 ], d1 Y$ make bytomd    # build bytomd
4 \' [& a0 o) ?4 g/ X) v8 q2 H$ make bytomcli  # build bytomcli
  v; @' G  N+ o1 f# U2 A4 s" |When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
- L9 [9 O3 P# Z: a/ b( x; c" y1 I) ?; `  EInitialize; i1 u& N* g( k! v& l# s" C- ^
First of all, initialize the node:! _( i- B* r/ Z# f7 U; t% g# U
$ cd ./cmd/bytomd
8 m, X4 k( g6 d0 H( n. O- x4 i$ ./bytomd init --chain_id solonet
  d  e5 B; W% [& u# Q; ulaunch! f$ ?1 q: ]% |3 J5 @
$ ./bytomd node --mining4 ^$ N4 c7 y# Z3 b' B
Usage2 O* A! D  w* T/ ^4 ]
Build jar
/ Z+ h* P+ N% j! t

  • ( r, `5 I  }; l% C  \. cfirst get source code
    & v: N: L1 Q+ O4 d$ {# fgit clone https://github.com/successli/tx_signer.git
    9 C4 m2 M( s7 J8 Z7 g

  •   ~7 ?7 v8 B/ Z+ t, T2 ?% Oget jar package
    * p; L" L) N9 X+ K0 v7 p7 I/ d$ h  R$ mvn assembly:assembly -Dmaven.test.skip=true
    3 M5 O! o7 v$ jYou can get a jar with dependencies, and you can use it in your project.
    8 ^7 g6 z. _7 c( j1 w/ n8 e- _1 H7 y
    & a, ^' D( {  s6 k1 h
    Test cases$ Y) n) E  g6 U5 G8 y
    Need 3 Parameters:0 R* b' I2 V& r4 Y# ?$ r
  • 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
    & u) d  B* j2 O1 l% h& v

    ( b- W) H* ?$ r/ NCall method:6 d4 _4 W! m" Y1 I
    // return a Template object signed offline basically.& G9 E) V  Q: Z
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    $ |2 v9 u' a+ _// use result's raw_transaction call sign transaction api to build another data but not need password or private key.- ?# z5 u( f2 |+ P
    Single-key Example:
    7 N1 \- @3 {6 p- u: j@Test5 a/ U  |) Q; R
    // 使用 SDK 来构造 Template 对象参数, 单签: a, i% M1 k' |$ s$ S* \$ m
    public void testSignSingleKey() throws BytomException {, t5 U" C) p# ^  J0 L& c0 M( a4 e
        Client client = Client.generateClient();
    ; }  R  U) v8 f/ a9 ~' D4 p    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";. z2 w4 v! S+ p) W/ G' B! z
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ' Q' ~' \: F, Z1 }& A: I    // build transaction obtain a Template object
    2 m! Q) ^; B7 A* ~; A3 t2 D    Template template = new Transaction.Builder()
    - J6 M9 I& i3 R3 ^7 @9 q        .addAction(/ V9 U+ r& M. P4 q( X9 U+ G6 }
            new Transaction.Action.SpendFromAccount()
    ' F: e, x: u) ?. G5 b        .setAccountId("0G0NLBNU00A02")
    & \6 Q! F: `  a, O# J' n7 i        .setAssetId(asset_id)
    . M. N8 k- o, u6 N8 s        .setAmount(40000000)
    , j5 z: R/ f5 x' p: A1 @    )1 M; Y# H: k+ |/ Y$ U) b: {
            .addAction(( G. v! ]  ~. r- W7 F% o
            new Transaction.Action.SpendFromAccount()! z# d7 N* y  f& F
            .setAccountId("0G0NLBNU00A02")6 a( `- p3 U3 N% p5 l% z
            .setAssetId(asset_id)
    9 F9 {6 T0 s: v; L# X1 S. c+ n! ]        .setAmount(300000000)
    & @, O. X# Q+ O8 L3 E    )
    . ~7 j- c1 A+ V4 b) v& N        .addAction(
    9 t, ]1 r# T3 W" Q        new Transaction.Action.ControlWithAddress()
    9 I  c: ~) k; e% {        .setAddress(address)
    6 q' e0 O" N* G: \  M- n4 S. V        .setAssetId(asset_id)( l! ^7 T( q; z4 Y' b% e; r- g
            .setAmount(30000000). f9 v9 j/ i: G" S" z
        ).build(client);8 D7 B3 P4 ?% p, I, [0 m( l
        logger.info("template: " + template.toJson());
    . U  ]6 a) e' c7 b    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    * W) V/ z$ P, ~, t    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    5 N  t2 X0 ]) A5 Z6 M3 W    logger.info("decodeTx: " + decodedTx.toJson());
    5 S5 u9 B1 t0 Q: z" [" B    // need a private key array* [  D5 x( P9 Q
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};& r" r# t) Z- S  m
        logger.info("private key:" + privateKeys[0]);8 `: H1 Y$ _" L" y6 m9 j2 a
        // call offline sign method to obtain a basic offline signed template; Z! S; Z- g2 Z3 T  N5 C( c
        Signatures signatures = new SignaturesImpl();
    9 p. z' Z6 b- ^1 U% Z4 Q. r    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    5 r* X, e& _* }8 N    logger.info("basic signed raw: " + basicSigned.toJson());
    $ @+ k" r: s! z5 t6 I. d+ I5 M    // call sign transaction api to calculate whole raw_transaction id7 e* b$ Z. H, p4 \/ c0 v
        // sign password is None or another random String' L" d9 O6 H1 P, G4 Z
        Template result = new Transaction.SignerBuilder().sign(client,
    & l1 @4 V! \" J5 ?; B9 v5 r* B! ^3 ]9 e                                                           basicSigned, "");
    . c( h  D( ~: m) Z: f! I    logger.info("result raw_transaction: " + result.toJson());
    ! y6 x5 ~: i, D$ |# c9 i  x    // success to submit transaction! S) q$ r- r' i9 `- y' b# a
    }5 L& s" w& |' V( w$ L( U, G
    Multi-keys Example:5 r4 V6 G- I8 a9 O5 q% o+ v
    ( c" ~; ~, x. n, T
    Need an account has two or more keys.. d% e" W0 L, _! _$ P: L0 ~* H

    , b2 S" h+ R, u( p, c& p5 N@Test
    0 v) c( i9 w+ I' F* ~- p8 K// 使用 SDK 来构造 Template 对象参数, 多签
    2 C. P! W. X& D: lpublic void testSignMultiKeys() throws BytomException {
    4 F: @5 Z  F. E1 j+ W  s    Client client = Client.generateClient();
    ! s3 s4 T$ Y6 F/ K7 `# W    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ) F! S+ n9 y' [6 J* q* p  i    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";+ O- G: p* l, L9 r' U% q2 f
        // build transaction obtain a Template object
    " l* ~, J! }! ^    // account 0G1RPP6OG0A06 has two keys3 h% X% q/ B, X1 b
        Template template = new Transaction.Builder()
    # U+ _7 B* {$ E6 C9 t2 u        .setTtl(10)
    4 X0 |) A* q; H, s3 y        .addAction() e* I; ]. `& O4 h
            new Transaction.Action.SpendFromAccount()
    ) s) k. j; \/ K, m8 J  X        .setAccountId("0G1RPP6OG0A06")
    . z) H8 d$ k) ]9 A$ d& R. h        .setAssetId(asset_id)- P/ l3 q$ q; z, ?5 t2 N
            .setAmount(40000000)! |; j& N" @3 B  l% O+ y3 d
        ); C, h& _' b0 f  E  z& [
            .addAction(7 p7 ~' F4 D9 f' P+ a, B
            new Transaction.Action.SpendFromAccount()
    1 S! y7 N" b" [8 w        .setAccountId("0G1RPP6OG0A06")  y6 U8 F+ H5 c: ]! p
            .setAssetId(asset_id)0 K# G! m" _* m+ F% ^
            .setAmount(300000000)4 X- P; k1 \0 {1 _+ o
        )
    2 r8 |3 ?( u4 {        .addAction(- i( c$ ^9 c* P8 B1 K* a& Z
            new Transaction.Action.ControlWithAddress()
    5 }1 {8 @' C, g- [/ G6 r        .setAddress(address)
    ( ?1 m8 K  R- W: G0 P; W! |        .setAssetId(asset_id)6 x# L( Q, x) Z, L% L$ M4 N
            .setAmount(30000000)
    7 D: m, X/ j' z; z    ).build(client);: M* R- q. D* ]. D  F
        logger.info("template: " + template.toJson());
    & y3 U5 b+ x* }2 \' E. s: |/ Q9 i/ c    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object1 V% {0 a& o. v+ k" i7 V) ?8 C- }
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);0 x, }6 }! f1 v% v4 u1 T& B7 w1 J1 N
        logger.info("decodeTx: " + decodedTx.toJson());6 V, j5 F" ^5 }" n! {& ^0 I; l- {1 N
        // need a private key array
    ( j# a7 E5 F0 S& p2 L. l  u    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",) M# m) `4 D: c: F& j
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    " j3 ?, V$ g: @0 G: v3 `% K    logger.info("private key 1:" + privateKeys[0]);& T' ~5 }- Q% D: H
        logger.info("private key 2:" + privateKeys[1]);& m2 L5 T# x1 Y
        // call offline sign method to obtain a basic offline signed template
    $ d: n/ S' f5 X" D* Q; S  h2 V    Signatures signatures = new SignaturesImpl();
    " }# t- ?& E# e% g    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);- ~" T) g! s5 |9 ^2 N: g6 g
        logger.info("basic signed raw: " + basicSigned.toJson());
    8 T' `5 V3 d: p+ v5 u1 ?    // call sign transaction api to calculate whole raw_transaction id  C6 l$ K: s; N7 _/ S# z
        // sign password is None or another random String
    % Q& ~( _. S  g    Template result = new Transaction.SignerBuilder().sign(client,
    1 e6 V4 A/ u- X( e                                                           basicSigned, "");2 Z7 j5 Y4 \; i
        logger.info("result raw_transaction: " + result.toJson());7 [$ P% K2 F) r2 m3 x
        // success to submit transaction
    $ n: y# \" W4 a3 m0 ]( P$ V}3 {) _% L$ J* h$ u! s* f% L
    Multi-keys and Multi-inputs Example:1 d3 I( _( s% m0 t
    @Test# M5 P2 `, X+ ^
    // 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    / C. c5 J$ P% q# L3 ?6 npublic void testSignMultiKeysMultiInputs() throws BytomException {
    ( o, n" O% B- m6 j2 ]    Client client = Client.generateClient();
    ) s& S6 H1 g7 w# }0 I2 n* L/ F    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    $ Z! L8 N2 e5 w    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";" X! @) ^! E% }4 Z# ?0 e( ^
        // build transaction obtain a Template object
    7 B; V# P( p( ]9 ]    Template template = new Transaction.Builder()
    3 d8 T# R. w+ n5 u$ D, u. N# b        .setTtl(10)
    % q% f( [8 k4 ]" U& q        // 1 input  |* ~) @) G1 @
            .addAction(
    : t5 n; @" u/ o' \/ W/ {) N        new Transaction.Action.SpendFromAccount()- N2 k: G$ O8 U' h
            .setAccountId("0G1RPP6OG0A06") // Multi-keys account; \. y2 E6 T4 v3 F& W) o/ X
            .setAssetId(asset_id)+ n" ^0 h! c2 Z
            .setAmount(40000000)5 y. z0 l4 s- {' P8 D
        )
    " K& S1 h% ~1 G4 @/ {        .addAction(. u6 W; F% v# R5 F
            new Transaction.Action.SpendFromAccount()' @* E6 ^4 w8 B
            .setAccountId("0G1RPP6OG0A06"), {! u! X3 j$ ~( x, J+ h$ H
            .setAssetId(asset_id)$ e1 N7 b# F( K* L- T
            .setAmount(300000000)
    % o3 V: `3 Z/ G3 }  J1 r7 f    )    // 2 input. y& L& U: ]" j6 [. y
            .addAction(
    7 H- f2 R% ?3 x% \) i5 W% z        new Transaction.Action.SpendFromAccount()- m( W4 z7 w' S0 n! S# _/ \8 c
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account# U- P/ ]' W* a: `; J: B5 S
            .setAssetId(asset_id)3 H: z; b, O6 Z- W$ P+ x
            .setAmount(40000000)' ]/ L4 {: A1 s) [, X) e
        )' b  _$ ^2 O: I
            .addAction(+ R9 z& k5 E& A  d) v" g+ N
            new Transaction.Action.SpendFromAccount()) m' t5 @$ W2 P# b1 C
            .setAccountId("0G1Q6V1P00A02")
    6 M5 q  y9 J* q5 g+ J) A        .setAssetId(asset_id)( |9 C0 n7 T. L5 y7 e- T
            .setAmount(300000000)& }: J8 G7 R$ l2 q3 \7 l
        )
    2 @- Y) S: W, U; V+ a, `        .addAction(
    5 E, V6 P& U5 p; [& x7 _6 v; K& a# `        new Transaction.Action.ControlWithAddress()2 r2 u0 K( ^, a" I2 A
            .setAddress(address)) v' T' s# ]) D, n
            .setAssetId(asset_id)
    ; y  S+ @+ h# D! S! Y5 \        .setAmount(60000000)
    . J+ `& j' z% u% G! S9 n1 q5 f" ~    ).build(client);
    * o9 E! u2 C) |+ b, r    logger.info("template: " + template.toJson());
    / v  ]5 i7 v9 F$ S8 F  @5 d7 |" X    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    : F' R6 ^7 U: Y/ L+ V/ r# P    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);- T3 }* G% H! `4 m
        logger.info("decodeTx: " + decodedTx.toJson());+ w+ ]. z0 I5 t) g
        // need a private key array
    , A8 i1 S) [0 n# l    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",, ~* M/ S. Q$ y" }
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    0 ~# {$ P3 K, n4 }+ B5 m$ z                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
    5 l* K. v6 u/ t: i    logger.info("private key 1:" + privateKeys[0]);
    8 t: k. L! e8 ~  t( f0 C    logger.info("private key 2:" + privateKeys[1]);% m5 E: |+ N1 _
        // call offline sign method to obtain a basic offline signed template' {4 R' Q7 p! Q
        Signatures signatures = new SignaturesImpl();
    ( R, @2 l* A8 H8 f    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);8 T  P, J/ D1 v0 K( y) S, S
        logger.info("basic signed raw: " + basicSigned.toJson());* N) h4 h; U  g( x
        // call sign transaction api to calculate whole raw_transaction id
    + Z  H5 z/ l! \    // sign password is None or another random String
    & @+ N/ g. [3 w0 A3 f; T    Template result = new Transaction.SignerBuilder().sign(client,
    4 |& h3 S. d6 X0 R" L                                                           basicSigned, "");
    5 H% e7 }4 J: m) G4 A    logger.info("result raw_transaction: " + result.toJson());
    ; E5 f, X# ?3 A    // success to submit transaction
      H% `! O, D$ L- ]/ \}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13