Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
97 0 0
比原项目仓库:
1 t% K+ z  d2 rGithub地址:https://github.com/Bytom/bytom# n3 q& S$ o5 d* J
Gitee地址:https://gitee.com/BytomBlockchain/bytom
* h7 a% D3 f& x% y/ X+ vtx_signer* n  X2 `9 G0 u* ~' `( O" U; F
Java implementation of signing transaction offline to bytomd.
1 o0 i5 F( q: w; |Pre: F( E  s8 P7 _. m
Get the source code
( P7 R& v( z7 S% g  ]) J: c$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom# o; N1 u0 M( a0 B: ]% c/ ]% o/ }
git checkout
( R9 L6 B: n  a, e- ?$ git checkout dev) Z+ T1 l. _3 g  m# s, w1 L: F& M
Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.+ }& l. N' t9 ^3 R1 {5 W: ~
Build; n; w  A) P7 v1 f' W
$ cd $GOPATH/src/github.com/bytom
5 V8 F; `2 S9 s  K1 S! X  h$ make bytomd    # build bytomd
6 b) G' J) O7 T1 h- |$ make bytomcli  # build bytomcli. |& C" V0 }3 A/ h  c
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.) x2 G& N: W) p) T) C
Initialize
# V3 R; a; S0 I, j, W$ SFirst of all, initialize the node:3 N, b/ @  r4 e6 U7 ?! [4 q1 b2 O
$ cd ./cmd/bytomd# c5 Q9 S0 R. w# ~  z# D
$ ./bytomd init --chain_id solonet/ P. S# M$ E" u
launch
3 L: z! U" i% T0 f5 e% _1 \9 N/ f$ ./bytomd node --mining
1 b7 O7 c* W& K- r" F1 HUsage
3 r, u7 F# t' ]# l: Y. O( gBuild jar5 J) Y) M0 c7 Y7 O4 V) F8 L% S

  • 6 Y1 n% v: g1 N: \: @! H1 o" ifirst get source code5 A1 Q9 T. G) x! R/ T  U  ^
    git clone https://github.com/successli/tx_signer.git
    / w0 Z' M$ E; k+ d
  • + t- Y* M5 s2 O5 y: M0 b) M0 h' E
    get jar package) X* Z9 R) a5 e- j5 ?
    $ mvn assembly:assembly -Dmaven.test.skip=true
    3 {& l9 h9 B5 Z, e# J' F! i1 t6 GYou can get a jar with dependencies, and you can use it in your project.+ g6 g5 i6 d5 {  @# N

    2 z! I2 @* o  d: A4 B2 [
    4 O$ n: I& ~: L% v1 l" \Test cases8 {2 W; s& g8 u$ q# S( u
    Need 3 Parameters:
    % l8 I) }/ p1 Q3 p2 e
  • 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 api2 S1 m. ~# U0 E5 E7 S, {: h

    , r) v- \; ~( Q) O) E& gCall method:
    8 k6 L7 R3 U" ~' h// return a Template object signed offline basically.
    0 q+ a5 u: Y0 n4 ]8 h& H- t* h/ w8 OTemplate result = signatures.generateSignatures(privates, template, rawTransaction);, Q( V0 Z, w* `
    // use result's raw_transaction call sign transaction api to build another data but not need password or private key., W1 Z2 L0 L3 p4 Z% n# i+ I, E
    Single-key Example:& k# o* K3 Q6 d: ^# V  [
    @Test% ~) B. i+ T# h- i0 P9 O1 ~1 C
    // 使用 SDK 来构造 Template 对象参数, 单签4 y% x8 ]' k. j
    public void testSignSingleKey() throws BytomException {
    ! D/ t5 R* p& T; v    Client client = Client.generateClient();
    ) ^6 X1 }' p, V( p6 C    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ) t7 X7 M& B: L    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";4 I" z4 g% X; E0 b+ }
        // build transaction obtain a Template object
    ' a) U2 B2 {( {& H9 e    Template template = new Transaction.Builder()- H6 ~* L# `  }  P; z# }0 m
            .addAction(; F4 s0 c% g/ |2 r  z$ t
            new Transaction.Action.SpendFromAccount()
    . `6 R) N: X) n& F        .setAccountId("0G0NLBNU00A02")! Q  N5 n0 i( R# y+ P1 M
            .setAssetId(asset_id)
      u( \( }1 ~% [) |; m8 k/ G/ U, T        .setAmount(40000000)
    ( j; ~& {5 @' M+ k$ R& O: S    ): r2 R+ O' {. C: m+ J
            .addAction(! F# K8 }  v9 t$ k, P  d* [& D& z) o
            new Transaction.Action.SpendFromAccount()
    " i* C5 n( x0 M5 ^( e        .setAccountId("0G0NLBNU00A02")
    0 _# k+ I. \: _        .setAssetId(asset_id)
    + o5 Y% _; w& \, S2 a3 \4 x3 b        .setAmount(300000000)- ]! m" w1 T8 R
        )" D  T3 I" W3 |+ x, M8 E: {% }
            .addAction(
      n4 H. {8 w1 x2 ?3 i& y. c        new Transaction.Action.ControlWithAddress()& V  M& a* F9 W- V! d6 V) R
            .setAddress(address)
    4 s: F; d. F9 Q" S5 k: k* M        .setAssetId(asset_id)
    . A7 d9 f9 L$ x        .setAmount(30000000)
    . m6 g( @6 S  X* j  L* f# l5 i    ).build(client);
    6 n5 c! E& a! C5 }    logger.info("template: " + template.toJson());
    " {& D4 I; [* y+ v- |- p/ M    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    9 w1 X7 J  s4 H$ O. p. ^    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    6 k! H1 Y( h& L' l3 f' z    logger.info("decodeTx: " + decodedTx.toJson());
    " t7 _: T2 m- Z8 q1 V$ L    // need a private key array
    9 \  @2 [1 g9 X2 b    String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    ) D7 `) P7 J, M  e    logger.info("private key:" + privateKeys[0]);6 x3 P% v9 K. b4 U, I' o' b
        // call offline sign method to obtain a basic offline signed template
    / w) @2 J# _  ?4 V/ {& B    Signatures signatures = new SignaturesImpl();
    6 D+ n1 s# |8 z( S4 [+ |/ o/ E7 q+ a    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);* H1 K- m2 s  t- U4 `
        logger.info("basic signed raw: " + basicSigned.toJson());
    1 U3 l: Z' S% v* m* X    // call sign transaction api to calculate whole raw_transaction id
    6 ~6 e# e# n  n    // sign password is None or another random String
    7 p* z! ]! n' d# i1 w, W    Template result = new Transaction.SignerBuilder().sign(client,+ a+ y  F% b! y3 C/ O7 J& e& w
                                                               basicSigned, "");% w( C9 i$ R) W/ }% c2 j5 [
        logger.info("result raw_transaction: " + result.toJson());; r+ T6 r$ L( w4 p. a$ ^
        // success to submit transaction( K  A3 e: f0 R8 _( t5 a. q3 p
    }$ k; a+ S: W, ]5 }0 f- v
    Multi-keys Example:0 S- a2 P; M: p8 u' ]

    / N- k1 ~: e& c0 C5 KNeed an account has two or more keys.1 C- f. p: b2 O, i+ s

    3 `3 r. t5 L& j@Test
    ! h5 O' Q, k* L7 i// 使用 SDK 来构造 Template 对象参数, 多签) m: ?$ [' U! }
    public void testSignMultiKeys() throws BytomException {5 X' R7 u3 z) W9 A) |7 W+ v7 V" c
        Client client = Client.generateClient();
    ! D5 \, A( h. F  e9 m    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ; a5 r7 q) x! n. J# U3 J    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    0 v: V: x9 N6 V% e' Q3 W    // build transaction obtain a Template object) Y1 }$ S1 n$ v! w0 Y. x
        // account 0G1RPP6OG0A06 has two keys# T0 V$ w* {+ ?5 u$ Y+ w6 I7 W: q: z
        Template template = new Transaction.Builder(). l5 H4 H, l2 y" ?
            .setTtl(10)
    2 T2 D9 J. `; e: b( f( _        .addAction(6 ~, X$ w  Q$ k
            new Transaction.Action.SpendFromAccount()
    7 ~; N  z. A5 h5 F        .setAccountId("0G1RPP6OG0A06")5 _  `( N  K, I# W" h
            .setAssetId(asset_id)
    3 t# e. x+ X5 T3 i) P        .setAmount(40000000)5 Y6 l) _1 B' X8 N  X9 k. E; j4 V
        )
      F0 p4 a" U/ C        .addAction(& Y  t& r+ N7 A
            new Transaction.Action.SpendFromAccount()
    % k( s/ o6 f9 I" ^5 p2 s. f        .setAccountId("0G1RPP6OG0A06"); F, T0 k7 D/ J* V" ?
            .setAssetId(asset_id)4 M2 l3 l2 c( H% `8 [# b
            .setAmount(300000000)
    ; `2 T8 e3 @4 H, E6 z* o% z    )1 V( X) \0 b1 w7 F" z8 x
            .addAction(
    0 i5 n8 `1 G% o* d$ h( N% [# V        new Transaction.Action.ControlWithAddress()
    ( M, u  U/ C" Y' K& n  x6 \        .setAddress(address)8 F& R& D( j/ ?4 J' b
            .setAssetId(asset_id)
      N& [. m  C3 y' C/ _: M        .setAmount(30000000)
    $ E6 n5 [9 [! x, u    ).build(client);
    0 E+ n$ q% ~) s! W3 b    logger.info("template: " + template.toJson());! ~5 [& k/ W6 d. m/ N
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    5 b  u( \% B- n- b: |, S5 f    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);: ?* B8 `% b7 M, b. @
        logger.info("decodeTx: " + decodedTx.toJson());  q! P' b1 f4 l, w  @- w
        // need a private key array; j+ U- S  _$ ~5 }$ v
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",$ a9 h7 b. F7 b& P3 K/ _
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};3 t4 q, O$ @& V  o: h( \
        logger.info("private key 1:" + privateKeys[0]);. x/ U8 N& c- [- E6 `/ O+ W8 t
        logger.info("private key 2:" + privateKeys[1]);
    7 k, `8 E6 Q' k' O  b( L3 j, P    // call offline sign method to obtain a basic offline signed template
    & Q) K* S; J" r3 K, o( U: B1 ^    Signatures signatures = new SignaturesImpl();8 D) B4 \1 O9 l$ M$ Y- K2 X; N
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ' B1 O+ _/ C0 o/ B$ g/ J9 b2 C    logger.info("basic signed raw: " + basicSigned.toJson());; S/ P0 {* Z* n2 o7 H
        // call sign transaction api to calculate whole raw_transaction id6 m% t9 `- K: [/ f  ]
        // sign password is None or another random String: f- S% j' }( v: h$ M$ }4 R5 W
        Template result = new Transaction.SignerBuilder().sign(client,
    7 {; |' Q1 g8 k9 p9 Q. a' z/ q# K# E                                                           basicSigned, "");
    % x& p7 Z% _/ \7 |6 G/ H* _4 c    logger.info("result raw_transaction: " + result.toJson());4 f5 @( j4 u3 o$ k- G
        // success to submit transaction
    9 C8 O) x& @1 b# P  J2 L6 l- r}
      g$ T: I8 P4 J) Z$ t) ^) N; wMulti-keys and Multi-inputs Example:: F3 {5 S5 \. {5 e1 X, p% [
    @Test
    3 s! R$ j( J/ q% T: D+ x! W  d// 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    9 _7 I9 o1 y* L, lpublic void testSignMultiKeysMultiInputs() throws BytomException {
    # O) w' p( h" K5 |5 c    Client client = Client.generateClient();# B  s, ^/ _) V! r
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";  S4 G9 X3 @6 g9 x1 ^7 v, K
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    7 P* l6 `' C" i! U' c    // build transaction obtain a Template object
    8 \% _% }0 d/ \. o6 \6 T# Z    Template template = new Transaction.Builder()( Q: ]( n+ q% C* [6 T
            .setTtl(10)' y  N  J- z6 Z+ x7 v0 E
            // 1 input
    - a2 L6 I4 T% {' }  a" ~        .addAction(
    1 p2 S/ `# b' g        new Transaction.Action.SpendFromAccount()
    , c: j. Y) ~1 j        .setAccountId("0G1RPP6OG0A06") // Multi-keys account6 U, d' q* f2 H2 Z- e( [8 a5 Z
            .setAssetId(asset_id)0 c' p' i/ l5 H  B* Z
            .setAmount(40000000)
    . j3 P3 ~) f. W0 z) Y  e0 E    )0 P$ [9 ]  S  i: o5 d- X* a- _
            .addAction(
    3 B$ B5 r" g6 |  I- @  {        new Transaction.Action.SpendFromAccount()9 E7 d; o* ?8 j8 Q8 x
            .setAccountId("0G1RPP6OG0A06")
    / H) P& j) [: b* Y1 J* K/ P        .setAssetId(asset_id)* P% }$ {& D* u8 p6 b5 p" L
            .setAmount(300000000)
    & N# |7 U; w: c5 \6 b9 x3 |# E    )    // 2 input* Z* S! U& t- o
            .addAction(
    + M4 D8 z6 X; i4 f0 B        new Transaction.Action.SpendFromAccount()# O/ @; P* Y& E
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account8 a0 W* }3 p( r& V, W* W
            .setAssetId(asset_id)
    1 p" P% g* }4 n' t# R        .setAmount(40000000)
    8 {: d' B! a: D    )
    4 d; |) `4 L% N" h. e( ~8 j        .addAction(
    0 l5 A1 g, O3 N        new Transaction.Action.SpendFromAccount()
    / d2 [) ]: ^1 b# ~$ j        .setAccountId("0G1Q6V1P00A02")2 U6 i, B- ]3 s$ c6 C$ b. u/ B
            .setAssetId(asset_id)
    1 d; k* q( {% _) w/ B1 m! G1 F! C9 B        .setAmount(300000000)
    , U5 E1 `; V/ t$ j& \( Z; R: m    )
    1 ~; ^: `) T  A4 f6 Y# `! ~3 F$ X        .addAction(( ]$ t) x$ k& O+ A5 V2 N8 e; i
            new Transaction.Action.ControlWithAddress()  `2 H2 o2 B3 P* T$ o
            .setAddress(address)
    . P  J- x8 e' x8 ]        .setAssetId(asset_id)
    ( |/ h  T; x& k' d+ |/ D        .setAmount(60000000): W6 @* a8 _4 a  x
        ).build(client);* f3 k/ t) k% u3 l  i
        logger.info("template: " + template.toJson());
    2 C& R; d. z. M* H$ V/ o    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    / F  j3 S/ S& o! v; R; y+ ~    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    0 T9 P* o" H! h- L    logger.info("decodeTx: " + decodedTx.toJson());6 |5 Z  v8 M  S0 @, n8 P
        // need a private key array- z! H. C+ B. n; I% T) j6 a' O, f
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    " a) S+ a& `/ l: x$ w                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    + u) z1 m+ f7 o4 y8 U1 t- D: I  C                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};3 H' v- V* D# G+ \4 [0 n/ `- A# E
        logger.info("private key 1:" + privateKeys[0]);
    " M& l5 p7 t  \, E. j3 L, W    logger.info("private key 2:" + privateKeys[1]);
    % K" S( B. `, p0 E# B    // call offline sign method to obtain a basic offline signed template
    0 t3 Q! q( j. T1 \    Signatures signatures = new SignaturesImpl();
    ' f4 x$ [- u! Y, d( ~( ^3 |    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    9 d/ f( f8 I, H. y" l    logger.info("basic signed raw: " + basicSigned.toJson());5 @- F. R( {( [
        // call sign transaction api to calculate whole raw_transaction id
    4 g$ |0 }8 d2 a    // sign password is None or another random String3 O' ^: h* {4 S+ N  x
        Template result = new Transaction.SignerBuilder().sign(client,
    - v5 z" G% M. c                                                           basicSigned, "");
    ! e1 F0 R. |' ]& L- t    logger.info("result raw_transaction: " + result.toJson());
    # [, e) C5 s$ ?    // success to submit transaction
    " g# T: }9 k+ b9 d# T}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13