Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Bytom Java版本离线签名

华胥
99 0 0
比原项目仓库:
) e/ ]. n4 [0 V6 U. o/ h( wGithub地址:https://github.com/Bytom/bytom
5 L* [. f  P5 u" x5 OGitee地址:https://gitee.com/BytomBlockchain/bytom) i1 d2 n$ ^  K( Z2 t/ R& M; S
tx_signer6 {$ I& q: b9 q+ s
Java implementation of signing transaction offline to bytomd.3 D4 ]! K  w4 x; Z
Pre
; [1 a; x3 a- U6 A/ v! y6 PGet the source code
; I1 d* T5 B$ e5 a& c$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom
* E8 C" X% d* Ogit checkout
9 D/ s+ W" r" Q$ g% z4 Z5 j3 r$ git checkout dev
$ `- D. T) ^5 j+ q, R, zWhy need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.
- [& I9 m" n2 I$ k* GBuild; f( }; p& L! T8 K; M
$ cd $GOPATH/src/github.com/bytom0 t: r+ h7 x- O; A" A" v6 u
$ make bytomd    # build bytomd! x/ A& d  O1 M% @! ^+ x& U
$ make bytomcli  # build bytomcli/ h9 ~( ~' p4 W" y
When successfully building the project, the bytom and bytomcli binary should be present in cmd/bytomd and cmd/bytomcli directory, respectively.
: C9 }0 p( x. m& C+ n# @# BInitialize
! r' `/ m4 {/ U  j. t0 PFirst of all, initialize the node:
/ f, }' a+ Y% w4 [$ cd ./cmd/bytomd
% m( C: D0 }# E% Q  L( d$ ./bytomd init --chain_id solonet
( E. |# t9 f- Z9 E. v; h5 K; qlaunch3 n( @& |% N; `1 |) R- X. ^3 |4 `
$ ./bytomd node --mining" _3 A! d' D$ h  _% j
Usage
* n; T5 F1 e, Y+ d+ ~/ zBuild jar
6 [. U% g8 H8 \9 u/ a
  • 5 U3 [( D& p/ ~& C4 i8 N- b
    first get source code
    5 x  Z9 ]9 _& g" O" w+ m; e' Dgit clone https://github.com/successli/tx_signer.git7 r  N* ?0 U' r4 E; L
  • ( a# \9 d. w: N% K4 h
    get jar package
    # s$ H* ]5 ^% ~0 N) k# H5 u, L0 L$ mvn assembly:assembly -Dmaven.test.skip=true
      J, S, C, ]+ n, H4 PYou can get a jar with dependencies, and you can use it in your project.
    * F$ X# A! K3 ?: b( K/ p4 Q3 T" g+ G$ S
    - M' o  y  ^0 i
    Test cases
    7 O2 K" D) m9 |2 INeed 3 Parameters:
    1 [& ?6 f) S$ m# [
  • 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
    ( f* y: q( q( B5 k/ m9 S- S
    $ c5 O* ^5 A- a7 {( p, l
    Call method:
    6 x. d! x. H8 c1 ]2 {: w& E// return a Template object signed offline basically.9 C# P" z/ P5 m" a3 k, y! s
    Template result = signatures.generateSignatures(privates, template, rawTransaction);
    # q9 W, _! X8 l6 N4 g- L/ \// use result's raw_transaction call sign transaction api to build another data but not need password or private key.
    + L* I0 l+ t2 \6 x8 f' Z' `Single-key Example:; w: J; I) O( s1 u
    @Test0 O& ?  p8 h8 W7 R
    // 使用 SDK 来构造 Template 对象参数, 单签1 S/ e1 b' o) Y
    public void testSignSingleKey() throws BytomException {1 H$ F* j9 i2 C0 I- S( p' P
        Client client = Client.generateClient();
    " X8 `0 ?, ~6 k8 d: o    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";2 |$ d) F% D, e9 d
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    6 p; {0 {& k* b: k- n" M    // build transaction obtain a Template object3 @8 j! S9 c, y5 Q
        Template template = new Transaction.Builder()! N8 S1 I8 C; n( R! }$ W" ]
            .addAction(
    : y9 m- m6 P* x4 {: o9 d        new Transaction.Action.SpendFromAccount()( g. i: {8 P# V
            .setAccountId("0G0NLBNU00A02")6 _/ e& \2 i) z( c
            .setAssetId(asset_id)' Q. }7 w% ]' ~5 b6 ?( f- y$ d
            .setAmount(40000000), ?2 T+ n$ P; e: @5 k2 T
        )) S" K* T% W4 a' y+ Y
            .addAction(
    % Z8 Y! U1 c/ ^% F- W' q7 ?" K        new Transaction.Action.SpendFromAccount(): C3 J. P0 P" w2 x" A/ f
            .setAccountId("0G0NLBNU00A02")
    : P" i9 L" Z" ]$ \$ Q3 Y        .setAssetId(asset_id). o( }9 q. h% p/ h' y# ?
            .setAmount(300000000): h( N- o- h: E$ v; x
        )$ w0 P( j: w% }* c+ S
            .addAction(% ]1 b' Q; T, S$ J+ q' y
            new Transaction.Action.ControlWithAddress(): h) d4 ^* `2 c! I* T" H, l
            .setAddress(address)3 t0 h3 T& i0 P  z
            .setAssetId(asset_id)
      [8 E2 A! o3 O+ t        .setAmount(30000000)
    . ?% }# Q2 A7 [2 ?5 \4 n2 o( y3 s    ).build(client);
    / p3 D' Q% T1 F* _5 c) Y    logger.info("template: " + template.toJson());
    % {* b& Q5 P2 C1 N) O& u    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    6 b- A0 Y: |) K0 s& t, m5 ]    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);) Z2 b! P) L2 F2 c3 ^7 ]4 x
        logger.info("decodeTx: " + decodedTx.toJson());
    , |! H1 u' K: U5 V( _    // need a private key array
      @+ t. ?0 J$ x* e4 n; `    String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
    3 w/ `* B  w. t' n    logger.info("private key:" + privateKeys[0]);
    3 Y. u* x% f& Y6 S- T9 Q) i# f    // call offline sign method to obtain a basic offline signed template+ X, M6 S% s" ~; n5 u
        Signatures signatures = new SignaturesImpl();8 l- ^+ O; x7 m$ b$ O3 d) |
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);3 z6 d/ ~( V4 j. q2 d
        logger.info("basic signed raw: " + basicSigned.toJson());
    " V0 @( f# S  b, f6 u1 M    // call sign transaction api to calculate whole raw_transaction id- z, Z9 k; y3 n) _7 M9 h
        // sign password is None or another random String
    : P) g0 L8 {& g    Template result = new Transaction.SignerBuilder().sign(client,
    & R" V4 E! K/ d) ~) M) O  H$ J                                                           basicSigned, "");
    ! R8 C! U/ H$ R( |6 ?! H    logger.info("result raw_transaction: " + result.toJson());
    2 G; y3 s" o; L6 ~) x8 [0 N    // success to submit transaction6 r7 \" T; N; _
    }
    # `* @( K" D5 l& UMulti-keys Example:
    , L9 i. q& {3 e1 F& d' K6 G- f$ G' y7 X# o# p, g1 m
    Need an account has two or more keys.$ F$ I" f; o% r+ Y; _; r
    ' B* D) D2 B6 D( X$ v
    @Test
    4 h% Y; `1 k# ?- d// 使用 SDK 来构造 Template 对象参数, 多签
    . Y( t5 B% B+ a% C( Dpublic void testSignMultiKeys() throws BytomException {
    # j/ E* s7 p/ g+ t5 h    Client client = Client.generateClient();
    ( d. i8 `" @* v! ^3 n8 s0 r, f+ C    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";, L# u; i  X% o4 q8 o4 ?5 E
        String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    ' |2 Q3 B$ }1 G* ?    // build transaction obtain a Template object
    6 [( l4 n. k  d# G- M5 }* x+ U' U    // account 0G1RPP6OG0A06 has two keys* C$ a0 }! Z+ M+ Z' H' V- L' I+ N) E: D
        Template template = new Transaction.Builder(). [& j( g/ s# k* e
            .setTtl(10), E" ?% x" p; q$ [- S/ H, t$ \
            .addAction(( G; I4 Q" w7 v$ a5 l
            new Transaction.Action.SpendFromAccount()1 G: k+ k2 P+ @) f# Q  H
            .setAccountId("0G1RPP6OG0A06")
    - P5 {5 A4 `' ^7 Q7 t2 Y        .setAssetId(asset_id)
    , E7 C! A9 A; K; F2 u        .setAmount(40000000)7 c, m2 i1 m: b% H" y
        )) x0 }/ W) Z' q
            .addAction(6 G8 t" k, Y+ Y0 X& j: Z
            new Transaction.Action.SpendFromAccount()
    # s! G5 j4 }8 h        .setAccountId("0G1RPP6OG0A06")
    , L$ @, }4 T( {$ _2 q. i. S/ l# m        .setAssetId(asset_id)
    / _# @  [8 k' U3 W8 O  O        .setAmount(300000000)) ~! M6 N# E; }( v5 J8 g
        )) n* q# x1 P7 x# t! `" V" P2 D
            .addAction(3 R8 T9 B2 E4 S- ]  k" F9 L! `
            new Transaction.Action.ControlWithAddress()
    6 _% d2 @7 g4 y. s: K5 D# E        .setAddress(address)' Y& o' ?# u# R* D. ]
            .setAssetId(asset_id)
    . A. w4 h! U) h4 R, p        .setAmount(30000000)
    ! r2 k- R3 ]) v8 E+ \" w; H. Z5 i    ).build(client);
    8 u. v3 d4 L3 I) M    logger.info("template: " + template.toJson());
    " |- u" s0 ?) d: `. g# T    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object% m' O% S% Y# o+ V! K
        RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);
    5 N( J7 N; X/ J2 l- |; A    logger.info("decodeTx: " + decodedTx.toJson());" R% D' v, W% |* q6 G
        // need a private key array
    , }" m. P  M% r, ?- }    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",& M: y2 O* ?6 N2 m4 L
                                            "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};! |" c2 D' V( `' `* s1 x" v8 }
        logger.info("private key 1:" + privateKeys[0]);3 Z0 H8 T0 F( D4 `8 ]
        logger.info("private key 2:" + privateKeys[1]);
    5 n" ~1 D) I- C! q" ~4 F    // call offline sign method to obtain a basic offline signed template
    ) J; F1 d4 w! g$ f    Signatures signatures = new SignaturesImpl();# N) {7 H& u1 p( M: Q
        Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);1 A+ e( V7 h, _$ Z6 A) L. I) I- s
        logger.info("basic signed raw: " + basicSigned.toJson());
    - X/ @* e; j- _3 W    // call sign transaction api to calculate whole raw_transaction id
    3 c7 K1 B4 |! d& w/ f! o    // sign password is None or another random String
    ( `+ [6 J5 D% I1 n/ G; B3 {/ n    Template result = new Transaction.SignerBuilder().sign(client,
    * ]( i5 I3 [0 K1 V) W                                                           basicSigned, "");5 Z) K( z- v; V9 a# @& j9 G
        logger.info("result raw_transaction: " + result.toJson());' |% v; H& K% c/ _  q% e: w
        // success to submit transaction7 ?& |+ ^: m! {4 b! V& m7 k4 _
    }- r. W$ I. D+ @( e) K! S7 t
    Multi-keys and Multi-inputs Example:. C" K8 E5 a+ i. m. M
    @Test
    * i# [# t9 P2 P6 z# M$ l$ _0 b5 x// 使用 SDK 来构造 Template 对象参数, 多签, 多输入8 o& |) q5 X! D, ]8 c, e. K/ l
    public void testSignMultiKeysMultiInputs() throws BytomException {; I3 t7 O- ]( G% M( z
        Client client = Client.generateClient();
      z& R  ^8 b# a& M" A0 ]8 R: \' V    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
    6 R4 [1 J% I4 v4 f8 g; s    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
    5 \2 Q1 X7 l( V/ [    // build transaction obtain a Template object0 ]: i" [! s" C; t, ^1 g
        Template template = new Transaction.Builder()' H' q* O3 i/ K
            .setTtl(10)
    " E8 K# s% h% |1 K# O: I0 p        // 1 input1 N( ^7 z# ^6 q6 h  q4 ~
            .addAction(9 e; ^# ^; B1 P% f! e
            new Transaction.Action.SpendFromAccount()
    0 }1 q; Y5 t; X+ M* k. I% p, ^6 P        .setAccountId("0G1RPP6OG0A06") // Multi-keys account
    + G0 h8 ]' L) Y        .setAssetId(asset_id)# T8 ~9 w/ i# h7 `, W: n4 J' {
            .setAmount(40000000)' |# G: |. m) |! j4 f: d
        )
    ' ?1 U# k! t. |+ Y% B4 j( L        .addAction(/ y! z. i% `0 D7 _! `5 ^
            new Transaction.Action.SpendFromAccount()
    6 w* w$ ?; X. M2 X; x2 b9 n        .setAccountId("0G1RPP6OG0A06")
    2 e! Z5 P9 @9 e# s: L        .setAssetId(asset_id)
    8 b- G7 k" ?" i8 ^$ }" r        .setAmount(300000000)/ q8 }! H9 \, J: i
        )    // 2 input4 B% Z0 ]* c& {! c" r' F& C
            .addAction(( w. d4 r- \1 k) p$ N) J; |
            new Transaction.Action.SpendFromAccount()
    * G! ^% Z6 z" s8 L! O" W        .setAccountId("0G1Q6V1P00A02") // Multi-keys account
    9 ?- S8 E6 b# z: {+ b/ T) T        .setAssetId(asset_id)
    3 D- l2 H7 E0 g) B9 m  U        .setAmount(40000000)
    8 R8 P$ j% B" Z! b    )' H- j* Q0 M5 U: O0 ]" g" A3 X
            .addAction(
    ; a: Q0 a( S4 q) K5 e6 t/ S        new Transaction.Action.SpendFromAccount()4 A; u- {3 e( e% Y( t
            .setAccountId("0G1Q6V1P00A02")
    5 b( _* ^! u- n9 t! P8 r$ b        .setAssetId(asset_id)
    / o+ J+ ~6 T4 ~8 Q3 l        .setAmount(300000000)" @6 N4 b8 g# N' |1 [5 P& {) C, W
        ), t; z- H3 m7 m7 a
            .addAction(
    % p& T0 {( @, F$ |" t! L# y2 g        new Transaction.Action.ControlWithAddress()7 j4 d; {  \& {! M5 p4 p4 x; x
            .setAddress(address)
    9 a! b* \! a7 w7 n& }        .setAssetId(asset_id)
    $ z# j% O: q. r2 d        .setAmount(60000000)" z3 s/ ]. N1 k, g5 d
        ).build(client);
    3 f- Q" U! O8 z8 _" y    logger.info("template: " + template.toJson());
    1 E- a$ s' p- M) G- v* \    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object
    5 A0 e: m/ `5 y4 l    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);% c& c& i4 d/ g1 N5 V9 C* j3 ~( G
        logger.info("decodeTx: " + decodedTx.toJson());
      o. i( n* G) ~4 \8 B7 g" H# B    // need a private key array, ]7 o  m1 @, {, k7 F1 x- o
        String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
    1 T, D2 B3 N3 }                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
    4 H; w& ?: I2 S1 b                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};9 C7 [( t9 {& W6 M0 V# @/ Y7 w
        logger.info("private key 1:" + privateKeys[0]);; S4 G4 B  x  c% F! E$ `, M
        logger.info("private key 2:" + privateKeys[1]);, {# s2 D8 s, J% \* r2 E- I
        // call offline sign method to obtain a basic offline signed template2 u6 C4 }6 c0 b; t
        Signatures signatures = new SignaturesImpl();
    1 c6 t; ]' e, x' p# [% g    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);
    6 e; ?1 w9 M  H0 W/ w- k; j" o& B    logger.info("basic signed raw: " + basicSigned.toJson());5 W5 u$ a+ {$ D5 H6 a8 q
        // call sign transaction api to calculate whole raw_transaction id% y, l$ w. v% ?$ N0 A: T( W9 Z# Y
        // sign password is None or another random String
    8 l& D! U7 K5 Y3 _: O5 j* {! m    Template result = new Transaction.SignerBuilder().sign(client,
    5 K- l$ f% K  B                                                           basicSigned, "");
    7 d& S6 t( Q( |2 N+ B* b& y    logger.info("result raw_transaction: " + result.toJson());
    , f7 \  n6 f3 Q1 b    // success to submit transaction
    2 s. `* W6 B! |' e$ S! z}
  • BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
    声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    成为第一个吐槽的人

    华胥 初中生
    • 粉丝

      0

    • 关注

      0

    • 主题

      13