Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
108 0 0
比原项目仓库:
, s3 x% ~* V/ a! e+ c- tGithub地址:https://github.com/Bytom/bytom' I1 f$ L1 y# \% S/ u
Gitee地址:https://gitee.com/BytomBlockchain/bytom& `7 e0 [) X7 M+ K; Q; G  F
tx_signer3 S3 ^: b; u: [0 |' q4 W
Java implementation of signing transaction offline to bytomd.
6 f; a2 S& o% F% r9 Z2 ]Pre. m0 o) c: R& u/ m) x) ^! x
Get the source code
( x. p6 N" _! H' y8 p) Y# o- [3 o+ F$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom! O! L1 |. H  A$ i1 R
git checkout
( o7 P' K& u. U% t0 Z$ git checkout dev3 p' R4 Q3 N7 o' q
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
; r/ K/ M+ e. }, @Build
- v& J8 m3 x& C. W$ cd $GOPATH/src/github.com/bytom( C# ^3 Q- a9 h$ K. {; m1 l, N6 c
$ make bytomd    # build bytomd/ S! p: P9 Z6 z5 P0 `
$ make bytomcli  # build bytomcli- j* `, p  f! V* _0 i5 p& }
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
& w  q4 Q/ b4 z7 k+ j. pInitialize
( Y5 W2 m- e+ F' s2 nFirst of all, initialize the node:
' S, f! k2 Q4 v9 `+ ]; W- N$ cd ./cmd/bytomd2 {# I( @- B# i4 s4 F
$ ./bytomd init --chain_id solonet, h5 }9 B& M0 I8 H/ [7 }
launch$ H& x& S) {( I4 J9 n  P
$ ./bytomd node --mining
5 x- d) c) ]* X" z9 J, C7 rUsage
: M, p: i1 H& J* QBuild jar
  H7 L8 \2 _2 D2 A3 D; ~& w

  • * b  W7 u* U/ ^# L7 ]+ n" x8 lfirst get source code
    + X" w3 x! |, n3 m9 ~0 B5 N8 rgit clone https://github.com/successli/tx_signer.git+ z) }5 B* }9 p4 u+ J

  • 1 I) j; r+ c* c+ v% `' x2 x+ Qget jar package
    - N' r. L  S$ Q7 t$ mvn assembly:assembly -Dmaven.test.skip=true
    & s7 i$ u! A2 e, A# y) T" F- @You can get a jar with dependencies, and you can use it in your project.
    & J3 X8 ]6 v( [4 T( O, i
    1 |9 F' J5 H$ m; _# W
    5 ~5 A" r6 U  z% {4 w6 ?; WTest cases" ]9 A; g3 r/ l; F  ]' }* g! v
    Need 3 Parameters:: b& Y3 E$ d: c) ]0 @5 B% ?; w- z
  • 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
    : f1 M3 U# x' C/ j) I

    , s4 }+ l& M! [$ f! J: i" X8 O! c0 KCall method:9 b- K0 F5 v% W/ I: ]$ Y; N
    // return a Template object signed offline basically.# @& d0 c% F$ o2 ~2 `
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    8 U; P1 `4 @/ Z5 d1 M( K// use result's raw_transaction call sign transaction api to build another data but not need password or private key.4 j% d6 U# {% \
    Single-key Example:
    - s- j, W: t. T& F! i6 q@Test
    6 {8 a! y2 I3 U8 q// 使用 SDK 来构造 Template 对象参数, 单签: P4 ?, q  z& o3 r/ Z
    public void testSignSingleKey() throws BytomException {
    % ^( W  j# d$ [1 x- R( W% S/ a    Client client = Client.generateClient();
    1 [) i) n( _6 S+ @    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    + {0 `1 Z  d$ a3 [' O2 T! o    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ; V3 L3 o8 J0 C# i6 L    // build transaction obtain a Template object, K+ z6 w8 f& N) k# d6 Y
        Template template = new Transaction.Builder()
      ~' g6 d, p' N( e3 t1 d0 q' I0 B* U        .addAction(4 N" L% x& H. Y% R0 U* l' [
            new Transaction.Action.SpendFromAccount()
    / V- T4 K  V3 D; C! E" ^3 g        .setAccountId("0G0NLBNU00A02")
    . d6 k! i5 A; ~% V& f2 J        .setAssetId(asset_id)
    / K, \. \* U1 r# z        .setAmount(40000000)
    " q1 m2 V; c1 ^& e% ?    )4 M# T; L2 a6 Q
            .addAction(6 z1 n8 F7 q. y, |5 Z# d6 f
            new Transaction.Action.SpendFromAccount()8 S* ~& |2 g! ?6 p' F! |1 K" v
            .setAccountId("0G0NLBNU00A02")
    ( M' j0 F3 z% S        .setAssetId(asset_id)
    " [, W8 b7 Z3 H' A# W! a        .setAmount(300000000)
    1 d( r) ^/ c" ^# \" v) l7 v* |# x# c* v    )% ?8 z( b2 H+ L: z2 n6 E$ F
            .addAction(4 W$ W8 O7 t' L* u6 ?" t- r; z
            new Transaction.Action.ControlWithAddress()- C  C5 m7 j: E7 k$ d
            .setAddress(address)* W# F0 A- C0 L) [
            .setAssetId(asset_id); C( p. y1 {: |3 A0 |, V
            .setAmount(30000000)
    4 M7 ]' B8 Y, j; G2 d. Z    ).build(client);
    & k" I7 Z* \8 {( e% Y, F( B    logger.info("template: " + template.toJson());
    ) O* Z9 K& Z3 d* @/ r! s# K- L    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    9 d" B" y" @0 n    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    . F) G( g( q2 q) M: K: @    logger.info("decodeTx: " + decodedTx.toJson());
    7 j1 v. N9 q3 E- f# C    // need a private key array
    5 l. E9 j+ {: M% L1 e$ E2 ^: I. r9 y! S    String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    2 j& f) S$ G2 k! Q  q+ w# g    logger.info("private key:" + privateKeys[0]);
    ) \# h! ?" B! T! N% M6 H    // call offline sign method to obtain a basic offline signed template5 U1 B/ ]' u' \
        Signatures signatures = new SignaturesImpl();
    & a) m9 u! d# a    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);" o0 a8 O1 Z5 b- i$ w2 r
        logger.info("basic signed raw: " + basicSigned.toJson());% `9 t5 p1 G' B. v6 N8 K
        // call sign transaction api to calculate whole raw_transaction id
    ( V1 T' l1 R+ J7 K    // sign password is None or another random String
    ' E/ i( h% c+ M. r- z    Template result = new Transaction.SignerBuilder().sign(client,- R5 K" I9 Z( I
                                                               basicSigned, "");
    $ S5 h3 P: S  l( H0 t* U1 M' O- M5 e    logger.info("result raw_transaction: " + result.toJson());" E/ M0 b9 S; u9 k! U" F" |0 A
        // success to submit transaction% ]6 ?* C, L, F- _; f! {! _
    }
    % O/ V2 O- o; H. mMulti-keys Example:
    & U9 i; g6 Y3 J; U! k
    6 L' i) W9 g+ }* JNeed an account has two or more keys.& @& k' L$ r5 ^/ f/ g

    / B# @# m: o; a$ o: j0 t4 W@Test. w9 R; v$ N4 B: V0 J2 _. e
    // 使用 SDK 来构造 Template 对象参数, 多签
    ' @# P; ?1 ^* o0 ipublic void testSignMultiKeys() throws BytomException {
    + ^& v- L  s$ P5 g( f    Client client = Client.generateClient();5 e. |) A2 J' t- k( P1 s: u  w
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    / A4 }9 f0 J5 N    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";% _2 I7 g$ L+ [6 a2 q9 }) l) }- E
        // build transaction obtain a Template object
    + b# f; X3 ?* Q, z/ j& d* Y    // account 0G1RPP6OG0A06 has two keys) N) Q2 C0 Q  b9 O! W; _' a  J* q
        Template template = new Transaction.Builder()
    & W% N  d% Z6 v        .setTtl(10)
    ( J  p: X' `: f8 ?8 B        .addAction(
    ' s; ?& N1 [# c' `7 K& e        new Transaction.Action.SpendFromAccount()
    * d' D4 _( J; W* w        .setAccountId("0G1RPP6OG0A06")$ |/ z1 i; \3 m5 W4 h8 p8 O
            .setAssetId(asset_id)
    # C- t& Z2 [/ O4 O# v- M3 S        .setAmount(40000000)' K" z( L3 k2 Z% R, {! u
        )& h6 x( |! I% v5 V& H: O. f
            .addAction(
    8 u+ _: v& I5 h6 O        new Transaction.Action.SpendFromAccount()
    & {  o  o9 S6 |6 q8 A        .setAccountId("0G1RPP6OG0A06")
    / S4 i, W$ L% u8 X( p* @  O* S; z        .setAssetId(asset_id)
    , o) p0 u0 w9 U5 W* e2 k$ f        .setAmount(300000000)
    " o5 U6 N5 Y0 k5 S    )
    ( O1 B6 f( I' o# h7 ?* h        .addAction(5 ]/ }- a/ g) X( b2 p* N; L
            new Transaction.Action.ControlWithAddress()/ l! A( d6 s: |: h. @% M1 B1 Y
            .setAddress(address)9 ~: w1 h# O& ~  K  R
            .setAssetId(asset_id)+ w) [! Y& H! d5 g2 B
            .setAmount(30000000)
    # g) h. L) B( z& f+ p" r# V: e    ).build(client);
    3 b$ ~' y7 L) L& s! ^2 Z    logger.info("template: " + template.toJson());% b/ @4 g+ p0 k& K" y* _
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    ( `" }' L& a4 l2 S0 E# p+ H; f) y8 {    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    0 E/ e1 e5 ^: G6 D. r8 m. ]    logger.info("decodeTx: " + decodedTx.toJson());  ]& J5 J/ g+ o7 ]
        // need a private key array
    + `' K. l' c" K6 C7 K3 C    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",, }: v0 i7 Y% Q# {! Z
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    ( j' Q+ p, T* n2 V    logger.info("private key 1:" + privateKeys[0]);
    ! b/ N1 I  q. N3 N7 M4 C0 B    logger.info("private key 2:" + privateKeys[1]);
    , K1 D9 E  ?; v2 A" z    // call offline sign method to obtain a basic offline signed template5 J# V  o" x) o2 l& A" Y/ k
        Signatures signatures = new SignaturesImpl();  A) ?" T: P% G4 O
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ' d; u$ D# u" a! i7 n4 z7 E  n  [5 Y6 \    logger.info("basic signed raw: " + basicSigned.toJson());
    . b" P) F& L( R, H/ c1 d    // call sign transaction api to calculate whole raw_transaction id
    1 n2 L0 E- B/ d9 m0 v. L    // sign password is None or another random String
    # n7 _) C7 Y7 `  k3 c  V    Template result = new Transaction.SignerBuilder().sign(client,) W7 y) |3 l5 P& N. G* _
                                                               basicSigned, "");
    ) T2 |# @# F; ]. f! `9 r* A; U" I    logger.info("result raw_transaction: " + result.toJson());
    - l) G9 D0 x2 [7 s$ F    // success to submit transaction
    + I1 [4 ]  o% ]; C}
    ( b6 z* s" l+ ^1 \7 @; v- GMulti-keys and Multi-inputs Example:- ]  l) z/ ~5 ^: }
    @Test
    " ^( `7 E6 A0 y' t2 B// 使用 SDK 来构造 Template 对象参数, 多签, 多输入' |5 u4 Q* t) ]" Y/ d+ f8 a$ s1 h( T
    public void testSignMultiKeysMultiInputs() throws BytomException {
    ! ~8 h2 S3 g) O( i7 O2 k8 Q    Client client = Client.generateClient();- z7 w- m' p5 }1 P3 P* d3 O; P4 m
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";4 `" W* h# x: F; O/ o
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    . o/ E& D$ V& ~+ _% U" p    // build transaction obtain a Template object9 b) \; O% c) }. m
        Template template = new Transaction.Builder()
    & U' C5 f/ ~6 F3 Z) ?/ w        .setTtl(10)% Y; U: x1 F& x& K. k* _3 \4 z
            // 1 input5 d6 X7 ^6 B5 w) H' s
            .addAction(8 C4 p6 ^- F; X( b9 |, R1 q/ I
            new Transaction.Action.SpendFromAccount()
    ) [+ }& r" a. `( o- F6 q        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    - i! J+ L. }* p* m        .setAssetId(asset_id)
    , b- ^4 b" @. ]5 P' }. F) Q        .setAmount(40000000)7 v5 X1 [/ n  e
        )" k3 ^* s. g! [% s
            .addAction(
    " `6 _! `  C0 |* a7 }1 l0 D* p! t        new Transaction.Action.SpendFromAccount()
    ) T2 C; p  p2 b# Y9 I5 ]        .setAccountId("0G1RPP6OG0A06")- [( ]" o! N5 s+ w2 n  N
            .setAssetId(asset_id)0 L  t8 y& m1 Y% e0 b, T& J
            .setAmount(300000000)  K) n& _6 m8 K' n/ J
        )    // 2 input& b# g* B: M% ^9 T$ ~1 c4 G1 h
            .addAction(' E9 n* e$ J$ `& y" w. B5 S" m
            new Transaction.Action.SpendFromAccount()4 K, R$ |5 W- |* W6 ], V5 q5 Q
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account& s: M7 r' I' g/ q. O4 g
            .setAssetId(asset_id)
    , M: t1 y) D3 T' w! ~$ Q( O; x        .setAmount(40000000)" @' C( m' [) p7 k/ W+ l9 W
        )$ A! {* Y3 o0 p4 ^0 S% \
            .addAction(
    & B, A' C& p* B# V. `  |7 ^        new Transaction.Action.SpendFromAccount()7 _& r3 w% O1 V; c
            .setAccountId("0G1Q6V1P00A02")
    2 B/ j/ A4 @+ k7 Z- E+ W9 Z        .setAssetId(asset_id), t/ |0 P3 Q* g
            .setAmount(300000000)
    * F: F" l: W% y' M, B    )5 d% y: m% ^: F
            .addAction(. w+ m: M6 I; q4 X
            new Transaction.Action.ControlWithAddress()
    ' ~& c+ x6 A3 X, ?5 c7 ^# R! |        .setAddress(address)5 y+ \; o) A; v7 T  Q
            .setAssetId(asset_id)5 y; w; Y3 s5 \7 C9 F. q
            .setAmount(60000000)
      e/ q& J9 n* A9 j! L" @    ).build(client);% R% f0 s" R$ b
        logger.info("template: " + template.toJson());8 P, U, O6 J/ C0 s
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object/ Q( g1 I- i* a9 E
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    * n7 }! s. K( S1 k$ b5 h5 B6 i    logger.info("decodeTx: " + decodedTx.toJson());
    5 a( R9 Y% x- ~' v+ t( u! ~" g/ ^    // need a private key array
    : ^  O3 a( N2 t4 B* }% {/ G: K    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    , K9 t, q. M5 z+ n& S                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",  f$ n; U1 G5 K2 _) k/ `
                                            "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
    6 |4 d- C9 o1 |8 i4 `) a    logger.info("private key 1:" + privateKeys[0]);: P, n! {; i0 s
        logger.info("private key 2:" + privateKeys[1]);- D* m( Y7 e5 u9 ~: c+ `# a
        // call offline sign method to obtain a basic offline signed template
    3 y; @3 t7 w) F1 W9 y' {. Q    Signatures signatures = new SignaturesImpl();+ K3 U' j* r+ O3 u8 u
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    0 J+ ^  y0 ?9 P& [    logger.info("basic signed raw: " + basicSigned.toJson());* N% g: Z4 M1 R1 e# a6 [! m% U
        // call sign transaction api to calculate whole raw_transaction id
    & z. w2 d) r1 y+ l6 r    // sign password is None or another random String% i& q3 s7 R& E& Z( k2 v
        Template result = new Transaction.SignerBuilder().sign(client,
    6 X. y" ]' O' \% g! j9 f; h9 T                                                           basicSigned, "");4 x; m( o  T& l  V8 W1 b, v
        logger.info("result raw_transaction: " + result.toJson());
    4 [. G+ O9 @5 E. o5 h5 F* v7 x$ c$ K    // success to submit transaction2 H1 v& T) q- i' z
    }
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13