Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
130 0 0
比原项目仓库:
3 r/ o4 O( }# AGithub地址:https://github.com/Bytom/bytom' j* P# @5 c& S$ a
Gitee地址:https://gitee.com/BytomBlockchain/bytom' f! j# @0 [, Q
tx_signer
1 Y5 ]1 Z. a! T8 PJava implementation of signing transaction offline to bytomd.4 a7 I, r" [" k; l: p
Pre
8 k7 k' o; O3 U1 NGet the source code
8 b% p* B& w8 N$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
( n2 j; _) }! C" q* lgit checkout
$ R1 P8 b7 M$ a: x; A2 k6 z6 G6 [4 u$ git checkout dev
% l; _( d& b- d$ QWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.0 F) i" ~; s6 v- j
Build
) y! s2 Z+ o' a! m% y$ cd $GOPATH/src/github.com/bytom: ~2 x+ P- [2 j; z6 s
$ make bytomd    # build bytomd) T  [) u4 [; _2 b9 E4 z7 H
$ make bytomcli  # build bytomcli
* N# |$ V- s$ H4 bWhen successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
- W" o0 X3 r" f1 ^. Q$ g6 Z* CInitialize% ^5 e, e. i: n% ?9 h1 |& o/ r
First of all, initialize the node:
; h' i( e" Z! y0 Q$ cd ./cmd/bytomd
8 }: h6 V6 H% d) p$ k' h5 y$ ./bytomd init --chain_id solonet
* [/ G9 v0 f% G8 }7 r# k% C% Blaunch. i! e5 i# L7 i  I% h; t2 u
$ ./bytomd node --mining
5 z. q- j4 N$ |' P# _Usage) K2 Q; S! l, [. B# G6 ~
Build jar/ Y% Z' e3 x% [, ~2 l; {& T9 Q% T0 ^- f1 c
  • : P3 {9 H. o( y. R/ R
    first get source code3 x4 b: ^% H0 i! \& O
    git clone https://github.com/successli/tx_signer.git
    : t5 Z2 Y. u! d4 O' d
  • ( Z3 f' D3 \; H2 U! x
    get jar package
    + c% J4 O! Y  W% b3 I$ mvn assembly:assembly -Dmaven.test.skip=true
    * I4 M+ k% X9 LYou can get a jar with dependencies, and you can use it in your project.
    ' U: {' h: v+ O$ t8 O, \9 n  F8 @; k- ~, P' U9 k

    5 Z. b; D! |( H- `Test cases
    $ r. d+ A( W8 ?6 C9 W1 SNeed 3 Parameters:
    - a/ ]$ N4 H( X) E1 V# k0 b
  • 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( h% k: W+ I# y( g& R

    : h! _: Q( l" H3 J: W5 U# tCall method:) W, u; J, m: f# D/ U  G3 x
    // return a Template object signed offline basically.! Q* ~5 I4 {' x; A
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    7 Z- k' Z. B! z) Y& _* h! {// use result's raw_transaction call sign transaction api to build another data but not need password or private key.
    : t# |4 Y  ]/ A2 q0 eSingle-key Example:- ^1 N' w6 q+ F  A6 j' g
    @Test5 K0 F  Y' S4 C! v5 W
    // 使用 SDK 来构造 Template 对象参数, 单签: G" z/ u* R- `& B: `
    public void testSignSingleKey() throws BytomException {! N2 b- a4 Y- e7 f
        Client client = Client.generateClient();
    ! t9 W+ A0 g% C# R1 u    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ( l/ }* ]: m4 O    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    - D) J5 N( m, K; g- }    // build transaction obtain a Template object0 m, |. ^7 u' J+ d2 {! G  s. w
        Template template = new Transaction.Builder()0 M4 ^! M: Z1 n, ^: \/ e
            .addAction(6 J  k6 X5 G$ X
            new Transaction.Action.SpendFromAccount(). _5 w2 W8 S' F0 u' b
            .setAccountId("0G0NLBNU00A02")
    ; T; Z  R, i* k- _$ G! M        .setAssetId(asset_id)
    0 A. e7 Z6 D  n        .setAmount(40000000)0 `" r1 }! K! `1 n0 y
        )) y& Q. b, n2 b7 z9 u  W' }& I) e
            .addAction(" ~: r. r% s/ @  w
            new Transaction.Action.SpendFromAccount()% ~6 B" k% W+ E( S$ A# a6 f
            .setAccountId("0G0NLBNU00A02"); p$ |7 h" w1 x
            .setAssetId(asset_id)
    $ ?6 U1 E: M% i        .setAmount(300000000)% Q' `5 i+ Q, ?5 d
        ). d' S: o$ S5 V/ A) |
            .addAction(5 k, k& T2 ~% n8 g; {, R
            new Transaction.Action.ControlWithAddress()
    2 x! A) {9 I( ~3 r2 G* T5 S) e        .setAddress(address)
    ; F( e3 q: n; }! a9 ~        .setAssetId(asset_id)# h5 m5 e/ X; }6 F
            .setAmount(30000000)
    % `& W# ^6 I$ ^    ).build(client);
    : a# i: @6 }. Q$ t- r, ]    logger.info("template: " + template.toJson());$ C! x9 G6 f7 v& L4 U& u. r* y( T
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object. {+ }8 R9 s& R) P3 o5 _1 ^# s
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);. R' `# ^' N% B7 U- r1 O7 A+ F% n2 A1 h
        logger.info("decodeTx: " + decodedTx.toJson());
      s& E* f3 ~: X2 P    // need a private key array1 H" _+ H5 _$ z+ Q9 |
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    ) J5 w% z/ n' f! \    logger.info("private key:" + privateKeys[0]);
    / O6 F# |0 a6 O% j1 B  K* X    // call offline sign method to obtain a basic offline signed template* e5 V: `; U" `. q9 _3 Q. h
        Signatures signatures = new SignaturesImpl();2 B- A8 w8 R1 U5 E" ~$ J" F
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);, m8 q! k) W# P3 k
        logger.info("basic signed raw: " + basicSigned.toJson());# C9 z; f* K6 }1 p# T' T& f8 @
        // call sign transaction api to calculate whole raw_transaction id
    ' W/ A" G9 e5 @6 e0 l, B2 F0 h    // sign password is None or another random String1 V9 T9 [+ N0 S
        Template result = new Transaction.SignerBuilder().sign(client,
    ! g) U& o* Z4 x5 ?" G* ]                                                           basicSigned, "");
    ; t3 h* j" L( o8 Y    logger.info("result raw_transaction: " + result.toJson());0 J1 Z7 w. m" A3 R: a
        // success to submit transaction
    ; P3 \( q8 y5 v! b8 A! W$ m/ O/ {}9 k- ?7 s4 U, R$ t! n
    Multi-keys Example:
    8 n) `. m1 l) H1 b# }; I  ^0 U: y& t1 F
    Need an account has two or more keys.
    4 ]& x4 B; o5 t3 B

    : d# i& E  @  k7 `9 t@Test
    4 r  T, D3 [! S$ j5 B" G& w// 使用 SDK 来构造 Template 对象参数, 多签- u5 N  i  q1 }6 }* _
    public void testSignMultiKeys() throws BytomException {3 i9 F: U; I  F7 u3 L9 }2 N4 F# I
        Client client = Client.generateClient();
    7 E9 Z0 T5 F# _- f    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";0 o% Q/ S5 Z* B. {) R8 s: x
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";, w6 t5 Q" T" Y: D
        // build transaction obtain a Template object
    ' K4 R! Y% u# F    // account 0G1RPP6OG0A06 has two keys
    & k% ?0 V  L; _  Q    Template template = new Transaction.Builder()
    3 n% [* u2 P7 A; [# Y        .setTtl(10)
    4 l& F2 C- i  `  h        .addAction(+ f' [7 N) i/ D
            new Transaction.Action.SpendFromAccount()
    1 F7 r8 W# P' h, r, c        .setAccountId("0G1RPP6OG0A06")
    / m9 Q" q/ k3 E; Z9 r) L        .setAssetId(asset_id)
    5 I- [" t" `7 z$ M3 j& Y        .setAmount(40000000): V! g0 P0 q$ n$ Z+ ?6 K8 g. W
        )5 r7 D! P& X1 L6 ^0 o* F
            .addAction(
    . F/ L& ~3 l2 {* v$ i+ _, w        new Transaction.Action.SpendFromAccount()) c& ^  O; U$ N1 h& K: Y4 v* G
            .setAccountId("0G1RPP6OG0A06")
    8 \& o* m+ N1 T5 [        .setAssetId(asset_id)* U3 m- f6 K8 G. z
            .setAmount(300000000); }" Y( K8 Z; ?* m  y4 F
        )
    , \9 J9 Y  S" a# L: s6 |3 L        .addAction(" e' \4 q4 |- w" T* v/ Z7 O
            new Transaction.Action.ControlWithAddress()- _9 m7 O6 P' h
            .setAddress(address)
    . i  m6 j% _  N$ r$ e5 I% D5 |" A" h        .setAssetId(asset_id)! S4 m3 e% G! @1 P% \8 S
            .setAmount(30000000)% F/ E$ S; K" r; J! H7 i& w
        ).build(client);
      j9 Z7 }& A* U! v5 b    logger.info("template: " + template.toJson());
      n* J+ r* X& ~* b! ?! ~    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ) f- ^( a" Z, D6 a1 j    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);+ h% j+ u  v1 u
        logger.info("decodeTx: " + decodedTx.toJson());$ f" @0 O% D: \) }! _
        // need a private key array6 H  W7 A5 W9 c8 y$ B* N
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    0 O9 @5 `. |; J2 |+ N/ J0 W3 g                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    4 b$ f0 n4 c; P; ]( a7 O  b9 l    logger.info("private key 1:" + privateKeys[0]);+ `; E+ s8 h) {) C3 c
        logger.info("private key 2:" + privateKeys[1]);8 L6 r3 L7 \1 e5 m; |; s  W2 \
        // call offline sign method to obtain a basic offline signed template2 S* D! b! ?* h( g
        Signatures signatures = new SignaturesImpl();3 Y9 Y/ b2 \6 c% g# A3 X
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    5 n0 G+ L# I6 K$ a0 z  v4 W    logger.info("basic signed raw: " + basicSigned.toJson());
    - `4 C% T6 S  Y1 s9 Q+ ~( t    // call sign transaction api to calculate whole raw_transaction id
    $ Z7 I3 P* f# e    // sign password is None or another random String
    . k- X' @4 ~* d: d% @+ B    Template result = new Transaction.SignerBuilder().sign(client,( q( o! ]" g) Q& A  r4 x6 t
                                                               basicSigned, "");
    ! _4 [) g0 ^5 Q    logger.info("result raw_transaction: " + result.toJson());% Q1 N* [4 h, I( L3 L2 U
        // success to submit transaction7 j1 G/ `* V, y0 F
    }4 f6 C- v  `& j. W
    Multi-keys and Multi-inputs Example:& V. G+ V7 n+ F1 o* d
    @Test
    . v7 y' r3 W, |) O9 a// 使用 SDK 来构造 Template 对象参数, 多签, 多输入! [# @8 H5 O/ G' P' B* l
    public void testSignMultiKeysMultiInputs() throws BytomException {- g. X* C+ m. a3 n
        Client client = Client.generateClient();! }4 d% [7 X( H/ G3 I3 k
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";5 G. I3 v. a* ], U% `& R
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ( ?; t! {" n6 T( Y    // build transaction obtain a Template object; n% @, l$ e+ u- ], `% S9 z6 y
        Template template = new Transaction.Builder()
    : S5 R4 u# Q2 N  p& g        .setTtl(10)
    2 r' Z: u; u  X% }  y        // 1 input8 u5 d0 q6 I2 q" ?% p9 Z
            .addAction(
    + [! F8 K. q* i# f( l        new Transaction.Action.SpendFromAccount()4 B+ d' x! W6 \
            .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    & k1 v+ x- F, o2 C5 M        .setAssetId(asset_id)
    3 V  |  U! }7 b! ]        .setAmount(40000000)  |4 c8 i5 E- S
        )& j) O  b( j' W4 l, z" X# q8 l
            .addAction(6 k; H, S9 t" |7 [! k
            new Transaction.Action.SpendFromAccount()
    8 y) ^! `5 v6 n5 |        .setAccountId("0G1RPP6OG0A06"): j2 j& M$ P  a9 c) e, k6 q* c0 [
            .setAssetId(asset_id)
    / o7 x, k$ V2 y3 q* r+ t7 f9 b+ X        .setAmount(300000000)
    4 d1 D7 R; [1 _& ~6 S* }" S    )    // 2 input
    % m" w2 i' ~: S% Z: w0 C        .addAction(
    8 b2 K6 T$ h# |3 n) _8 y        new Transaction.Action.SpendFromAccount()
    + o% ~% {( y- @8 V7 p9 J        .setAccountId("0G1Q6V1P00A02") // Multi-keys account3 [4 C- q7 T# h) ^5 v- B3 |7 h
            .setAssetId(asset_id)
    ( u$ Q" p  W8 [& e7 N0 F$ d% E        .setAmount(40000000)
    * j/ S/ j9 B' I7 H* V- [' V1 |1 O- `    )
    ! L* M, q3 t+ _$ W# ^7 B        .addAction(
    / Q# k2 ?; N/ s9 I& D        new Transaction.Action.SpendFromAccount(); g& k2 Y) z) l* `/ D
            .setAccountId("0G1Q6V1P00A02")
    2 z0 ]6 R+ v/ v: J+ ], S/ v' U        .setAssetId(asset_id)
    0 e; o, @/ L# N8 b$ T        .setAmount(300000000)
    7 Y* y$ g; t5 |  F) _    )
    ( T/ l, f) [8 D8 N5 W$ I        .addAction(6 d- Y( b+ P. y+ s  a9 M3 H
            new Transaction.Action.ControlWithAddress()
    - P. C" P+ J. h& O% p        .setAddress(address)6 k; V0 a7 Z0 {8 Q2 a( b
            .setAssetId(asset_id)
    # a* n2 V% l. v        .setAmount(60000000)' N: l! [( l3 F' [' O+ f) a- x
        ).build(client);
    ( [: J9 v- U3 c$ R5 H    logger.info("template: " + template.toJson());8 C( y" I4 f- Q  x7 ^8 Q
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    - v$ Y* Y4 M4 X    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    1 p# s$ w' u" O: y1 D' ]0 k    logger.info("decodeTx: " + decodedTx.toJson());0 O0 E1 ?" }  ^
        // need a private key array
    ) w4 w* b( |' K& c    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    / }6 {0 a  a2 s                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    6 B3 D$ W8 _; {2 B9 l                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};% s8 D+ E$ z8 b" u2 d: _
        logger.info("private key 1:" + privateKeys[0]);
    2 y8 E5 h/ \3 ~  V    logger.info("private key 2:" + privateKeys[1]);9 F# H2 n' s: _+ G/ c9 n& P; R, o
        // call offline sign method to obtain a basic offline signed template
    4 i+ l4 @4 j* q    Signatures signatures = new SignaturesImpl();
    6 a, D6 j8 ~* u    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);' ]1 q; F, x" O9 ?% O
        logger.info("basic signed raw: " + basicSigned.toJson());
    : T, \- Q: U- p! I    // call sign transaction api to calculate whole raw_transaction id
      P; a+ S2 H* M3 v: H# P9 D: Q    // sign password is None or another random String! ^8 N- C. o, _7 ?& G% i$ E! s
        Template result = new Transaction.SignerBuilder().sign(client,
    , D& v- l* F- G: I8 Q4 @                                                           basicSigned, "");
    9 C  r7 l  i' N2 h; {& Q/ q    logger.info("result raw_transaction: " + result.toJson());( {; f9 N" G# x. R" ~" F
        // success to submit transaction
    4 r4 r2 D1 m; t" M9 x, \0 E0 e! J& F; G}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13