Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
123 0 0
比原项目仓库:; P+ a% E: e) D/ r6 n' Q
Github地址:https://github.com/Bytom/bytom
& u8 y. N; D  Z* C  sGitee地址:https://gitee.com/BytomBlockchain/bytom. p' A) \0 F0 E' ]# x6 ?+ K8 n9 r
tx_signer, {3 B* G7 O  d
Java implementation of signing transaction offline to bytomd.7 |3 r7 b3 A& @! n5 Y1 K# e
Pre" b0 i5 [* p/ L' r# l6 {
Get the source code) g# ^+ s; R, G8 [  T2 l, j$ z
$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
: \8 v$ p; d, O* w, dgit checkout
9 S. [& `6 J) w# X! b8 B! C. F5 L$ git checkout dev
. I3 {  P) H4 W, u0 J5 E! \% E0 C  K) rWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.1 u  r  H) N9 j
Build
" ?1 @. s" I3 N0 ]* T' m' g$ cd $GOPATH/src/github.com/bytom8 W" m# K' B# f: ^
$ make bytomd    # build bytomd
! I9 i. a  F# n6 {8 a4 r$ make bytomcli  # build bytomcli4 r( H9 S( e. i& V) D
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively./ ~& O8 E! ^6 t+ q# J
Initialize
) [3 k% g1 }9 r3 U7 QFirst of all, initialize the node:; \8 l8 l2 l# }& a$ r
$ cd ./cmd/bytomd
  Z0 ~" b9 f) F3 ~: ~- H! J2 r$ ./bytomd init --chain_id solonet
1 E5 y3 j! C" v2 b! Qlaunch  `) `% ^+ O2 }& q1 {; m
$ ./bytomd node --mining4 P" d# m6 X& X' {$ u
Usage
( F. f- I6 M6 T+ lBuild jar
7 U) [5 ]  x% L$ a5 Y5 L# o
  • 1 a  _+ }: `0 d+ O. g$ \# E; I  f
    first get source code. ~$ c+ J. c- g& c0 p% U
    git clone https://github.com/successli/tx_signer.git- L  H+ p! X" j$ D  g

  • % M) j1 \; R# l3 Z) O" l1 i0 H) E) aget jar package
    1 y0 l$ T, n  Y- i; o$ mvn assembly:assembly -Dmaven.test.skip=true
    4 {* e. v0 i. j) e- l0 g- RYou can get a jar with dependencies, and you can use it in your project.
    1 }5 l, b2 V& _1 L. X! M" }" m
    0 i) v9 H$ @* i' Z5 `8 w
    ! Q3 h8 k8 _1 }( MTest cases
    9 P. [# u. M! ]& X3 m0 rNeed 3 Parameters:
    % F  M5 h1 Q- e3 K, 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
    4 c9 `8 P% f6 T' M

    2 g# ]& A% A6 \! T) v" |) cCall method:
    9 o7 N; c# f6 f# N// return a Template object signed offline basically.! w6 C% E, _1 [+ a. f) E5 p
    Template result = signatures.generateSignatures(privates, template, rawTransaction);; S) z% G4 b; K# ]
    // use result's raw_transaction call sign transaction api to build another data but not need password or private key.+ K% T, w* H$ F
    Single-key Example:' P, _: q2 \1 P' m" X7 R
    @Test
    , M1 V% f& D0 B8 i// 使用 SDK 来构造 Template 对象参数, 单签; v( @* {3 i8 l# T8 K$ T7 s
    public void testSignSingleKey() throws BytomException {2 \& y" c& s) o: u
        Client client = Client.generateClient();$ D( |9 r0 s1 g7 G2 G
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";' O, q% ?8 Q0 F) Z
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";7 c' B: N# z! Z" Q  N
        // build transaction obtain a Template object; \5 R6 _% F3 x0 i* J2 E9 u
        Template template = new Transaction.Builder()8 \& e0 c! X2 o( O' `8 b0 O' v/ G
            .addAction(
    6 B* D3 g/ W3 c; o7 Z4 ]+ F        new Transaction.Action.SpendFromAccount()
    * X& ?4 k( ~9 V" F9 j        .setAccountId("0G0NLBNU00A02")5 q& K* P# U' L  l5 ]2 G. S# f, N
            .setAssetId(asset_id)  S5 u% k6 C* M$ c8 h$ S
            .setAmount(40000000)
    + P* t( m. t+ P: [    )' r% U: R) |: x( x7 l8 i
            .addAction(9 J& `6 Q7 y6 G( a
            new Transaction.Action.SpendFromAccount()
    # V  f) W$ ]8 O" b        .setAccountId("0G0NLBNU00A02")7 ^4 ~7 u2 K9 T6 F, ]6 Y6 m
            .setAssetId(asset_id)4 i8 p4 |; F9 O7 i+ R9 i4 p" |5 q
            .setAmount(300000000)1 Q" o7 ~2 w8 A3 f& M: _
        )# c  j! R2 i, y) C
            .addAction(
    1 j7 l" W# C0 i* l5 y( {        new Transaction.Action.ControlWithAddress()7 @# O/ P! \, k
            .setAddress(address)+ A8 z5 \$ S# ?0 z+ N
            .setAssetId(asset_id)
    ; }% Z- k9 e6 V* b' {" Q3 o        .setAmount(30000000)
    - a" V: m5 c3 ?/ c) P9 X    ).build(client);
    7 @5 G% S/ p+ @6 j, E    logger.info("template: " + template.toJson());
    / R' T( ]. C$ {2 r0 R. \0 `    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    & M) F  m( `% `. J/ k7 C; z1 m    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    . R7 t5 ~* O" c) d    logger.info("decodeTx: " + decodedTx.toJson());6 D& j' e* p& T+ g/ c
        // need a private key array- h9 A+ Y8 N; V  [. G% W$ z
        String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    4 I/ v0 u+ H! G6 y: v( G! v; `    logger.info("private key:" + privateKeys[0]);6 D3 a7 p: T5 m2 ?5 b6 q: v9 D
        // call offline sign method to obtain a basic offline signed template
    5 U1 T" |- K  |2 i) O, l    Signatures signatures = new SignaturesImpl();
    , x8 R3 Q* ^! k7 w1 n# ^4 T. H    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    ( _- R% V/ y" H+ N$ v: Z    logger.info("basic signed raw: " + basicSigned.toJson());% I5 `( p6 m4 K8 U6 k
        // call sign transaction api to calculate whole raw_transaction id
    : c3 m% Z5 p! C% s1 O3 [1 y    // sign password is None or another random String
    8 {+ B5 W" B0 m0 y* q- W2 @' C7 z    Template result = new Transaction.SignerBuilder().sign(client,: V, t. C) Z% M
                                                               basicSigned, "");6 E: w5 L. g2 o3 J" ?8 \6 g
        logger.info("result raw_transaction: " + result.toJson());( Q1 W& H: Q) ~0 f5 S: N
        // success to submit transaction# x4 W/ z7 s8 ?) `) X4 i5 \* x
    }; H# q+ q* q  ?3 X8 M  b0 w# w
    Multi-keys Example:* P& U; H  Q4 J$ ~  J: ~) ~

    ( W7 l/ z6 `; @- vNeed an account has two or more keys.
      o/ m; s+ n! V! t
    " C; V! _6 r) Y- X' X: K
    @Test
    8 \6 U2 g- s7 p0 c' N. u1 t// 使用 SDK 来构造 Template 对象参数, 多签0 N; c, g% W6 e- q9 p: Q
    public void testSignMultiKeys() throws BytomException {
    ; C5 q/ `% \4 P. O# \( S! a    Client client = Client.generateClient();
    1 a6 O& y" I/ H9 {    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    ' e$ m$ n% u+ W3 l" `. G    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";  K  E( n6 E3 L% v
        // build transaction obtain a Template object) X( Z- x$ B+ D* ?+ ]) J0 U
        // account 0G1RPP6OG0A06 has two keys
    $ K! W$ m2 F/ B, S( \    Template template = new Transaction.Builder()$ C) V  |! O3 r, l# J( Q' N1 b# Y2 p( E
            .setTtl(10)
    * e/ U# {( b+ x. O4 I$ L        .addAction() z+ e; c1 N$ @) e: ]
            new Transaction.Action.SpendFromAccount()  [/ v7 R4 H! U
            .setAccountId("0G1RPP6OG0A06")$ n5 Q6 V. {% z9 W) k
            .setAssetId(asset_id)/ V3 r4 Q- L. |) ]  Q4 m
            .setAmount(40000000)+ p0 x: @* U* `) c& o
        )- m& \" {0 c7 Z/ k2 x" @8 }
            .addAction(
    1 m: z+ G. p  b2 z) k8 y: s        new Transaction.Action.SpendFromAccount()
    ' f3 D% ]8 `& d" x; x* i9 o        .setAccountId("0G1RPP6OG0A06")% E+ v+ l9 ?: s- _& P
            .setAssetId(asset_id)
    ( C$ G! n( [5 z        .setAmount(300000000)- R$ M) t% W' y" _, t" B
        )5 [% }  N, Q4 N2 G: f; _1 Z3 f
            .addAction(
    2 B3 N  @) N: i        new Transaction.Action.ControlWithAddress()) H0 e# L! c  F+ t+ I8 q" Y
            .setAddress(address)
    # c$ R6 {0 i: j% W  e& C* |" j        .setAssetId(asset_id)
    : A9 {9 T9 g7 T9 g; }        .setAmount(30000000). ~, r+ K- u7 y  V! s
        ).build(client);
    # o, Z9 H; a: O4 R, V& J# V: H    logger.info("template: " + template.toJson());7 u! t% v4 V$ _2 a9 N' Q" \
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    3 j2 R8 V; z8 b( U4 ^    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    % A2 s, q6 x# l  ^' w    logger.info("decodeTx: " + decodedTx.toJson());0 h& T6 C) @" i4 O. {
        // need a private key array  d( P: r% B7 l" f) x" B& ^
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",, W% f* A7 E" U6 t2 F9 b
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
    . {) G1 k: ~6 N. K/ }    logger.info("private key 1:" + privateKeys[0]);
    4 L9 E9 v2 P- p- w' A2 n    logger.info("private key 2:" + privateKeys[1]);6 @8 l# L3 |: r, ~  K! m: b
        // call offline sign method to obtain a basic offline signed template, l: F2 T$ E' i1 Q5 P1 \) s
        Signatures signatures = new SignaturesImpl();" O/ T$ F# u5 q5 o. {
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);( ~1 r8 _( [" U; H
        logger.info("basic signed raw: " + basicSigned.toJson());$ A4 i) x6 S# S9 [
        // call sign transaction api to calculate whole raw_transaction id# |+ b8 b1 O! B2 Y% P) I
        // sign password is None or another random String
    ; C4 o7 ]1 p# @' m/ ^    Template result = new Transaction.SignerBuilder().sign(client,: @, S8 T8 b' |. D/ N! c$ a, R
                                                               basicSigned, "");8 u# }! ?) I4 U+ g. A* j) k5 s, e
        logger.info("result raw_transaction: " + result.toJson());3 ?1 g  Q: ?3 l2 b
        // success to submit transaction2 Q2 y, T$ P! i6 V) x
    }
    ; C; A1 L. V- R( r6 o$ l0 DMulti-keys and Multi-inputs Example:
    ! f! d* N, W' k" W% f@Test. g' s7 Q+ ]5 g
    // 使用 SDK 来构造 Template 对象参数, 多签, 多输入
    , v- V" }; g2 r; s3 upublic void testSignMultiKeysMultiInputs() throws BytomException {
    , w7 u  E* V; |    Client client = Client.generateClient();8 V5 d/ y2 z6 }( F% w. }
        String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";8 j7 c' {! c/ M) e9 f0 ]" z
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ( f9 z0 u- Q! |$ \9 ]5 U    // build transaction obtain a Template object3 ?. e- ^$ J' Q* S& x1 Y* T
        Template template = new Transaction.Builder()
    , F- P, j/ B( `- P/ I/ b* A, _& d        .setTtl(10); f- U1 P5 o! {& ?  p8 d  {" j
            // 1 input! F% w3 R/ T) C) }- T9 I2 y2 y* i0 p' i
            .addAction(
    4 e4 S+ b7 \! B/ `        new Transaction.Action.SpendFromAccount()
    8 V7 a, T# L8 A' b$ M        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    , H( [5 u: ]" t+ M( v  H        .setAssetId(asset_id)
    2 e4 l9 ^) L4 ^7 R1 c        .setAmount(40000000)
    1 p+ m3 `. x) z, |0 H! u' c0 o% N    )9 _' ?8 B0 j1 @8 X
            .addAction(
    $ X5 x0 B' D1 X, ~8 Q6 U. `# ^% W        new Transaction.Action.SpendFromAccount()
    % Z  i8 e7 [( T- a        .setAccountId("0G1RPP6OG0A06")
    # f# o6 R& t' B1 J" l- @        .setAssetId(asset_id)
      l1 i, k4 Y. G; t5 a; g; O8 ?        .setAmount(300000000)$ W# H: A! \- ~+ b' k2 j
        )    // 2 input  B( p4 q4 \) I8 Q
            .addAction(
    2 }4 p& n4 a3 y# N. Q. |        new Transaction.Action.SpendFromAccount()' m$ s- Y9 P, H( V; K6 n$ M
            .setAccountId("0G1Q6V1P00A02") // Multi-keys account3 k9 _; C; F2 }2 t) \+ B- Y
            .setAssetId(asset_id)
    8 W/ {/ {$ r  w# S9 q# Z        .setAmount(40000000)+ \' j: S4 F7 f# z, B# I" V
        ), f0 L. T* r' [, T/ }
            .addAction(. W2 }( x% l; a! C3 z
            new Transaction.Action.SpendFromAccount()
    " {4 ^2 s. M- M! g+ h  |3 E+ o/ T        .setAccountId("0G1Q6V1P00A02")# D6 T. t" V4 x' O/ F0 y( N# |6 `: U- U
            .setAssetId(asset_id)8 J. U: q, ~9 r0 U& q. G
            .setAmount(300000000)* G  r" x2 J& Z. u5 y* b
        )
    6 n) c& Q6 V" i$ C        .addAction(
    ( J: Q3 ]; C! W) x+ E, u4 i$ Z        new Transaction.Action.ControlWithAddress()  Q  i* o2 M' L& {+ b/ E+ [9 w: J
            .setAddress(address)
    5 l2 e/ p- C/ u% |0 _* F        .setAssetId(asset_id)
    % `) C% V8 p$ L2 l' C        .setAmount(60000000)
    2 v7 Q% ?% \( K: x* K  w& j0 b3 H0 D# Q    ).build(client);$ w/ h  H) n. V
        logger.info("template: " + template.toJson());! S8 ~# `# T0 t% S" B& u$ r8 X
        // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object2 g4 C# P/ [3 o( K! {
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    . r: f- h  t- z( \    logger.info("decodeTx: " + decodedTx.toJson());
    ' g3 e" O  ]: |3 g& R$ h    // need a private key array+ h, x* t! h  |% E" b" h. @; o. G, p
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",1 ^4 g& }; W, U. }2 ?
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    , {- P+ ~+ ]! l                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
    . Q4 F9 e6 D+ D' }    logger.info("private key 1:" + privateKeys[0]);
    5 o; G4 Z: G! S5 ^; U    logger.info("private key 2:" + privateKeys[1]);/ n, A" f/ Q4 Z! w$ X
        // call offline sign method to obtain a basic offline signed template
    ( b5 }5 Q6 b9 P8 w    Signatures signatures = new SignaturesImpl();
    ) o2 P" `' _2 g- }  m' x7 {    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);5 [. C& C1 d0 ]9 x3 W
        logger.info("basic signed raw: " + basicSigned.toJson());$ o- S1 [1 M3 r( }5 i
        // call sign transaction api to calculate whole raw_transaction id4 j4 k3 k9 _% m
        // sign password is None or another random String
    - ?7 Z# m1 S3 ?( ~7 n8 J    Template result = new Transaction.SignerBuilder().sign(client,/ p& v5 v( U7 y
                                                               basicSigned, "");! W5 X& V6 i, i: I( b
        logger.info("result raw_transaction: " + result.toJson());
    + C0 R, t& ^- ]5 P    // success to submit transaction' i7 n7 b* w2 w6 \- [% b( K
    }
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13