比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
166
0
0
Javaimplementationofsigningtransactionofflinetobytomd.
Pre
Getthesourcecode
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom% z- {8 C$ }& K: e2 G
gitcheckout
$gitcheckoutdev& w7 {' O/ N8 I; i
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build) u. {/ {. L+ B( j) A
$cd$GOPATH/src/github.com/bytom+ J; P' I! ]) r( o; F9 F# Y
$makebytomd#buildbytomd
$makebytomcli#buildbytomcli
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.
Initialize
Firstofall,initializethenode:
$cd./cmd/bytomd v$ F5 n: P# f; h/ V1 ]7 B; e
$./bytomdinit--chain_idsolonet
launch
$./bytomdnode--mining
Usage
Buildjar8 a+ `9 ?# Z1 L, L( S
firstgetsourcecode
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage9 L, n5 t5 t6 P% e% }
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject.
! A' ]8 \. k" @- _2 W
Testcases9 J1 [& g( H2 K
Need3Parameters:
PrivateKeysArray9 ?: O" w9 E1 p3 o% t# a, P' U
TemplateObject9 p, N$ V4 ]) x
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi, L% k, b6 m a7 [9 a0 s* {
usebytomjavasdkreturnaTemplateobject.
RawTransaction" J3 h! W3 n0 c5 z: {+ l
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:
//returnaTemplateobjectsignedofflinebasically.
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.
Single-keyExample:8 {1 G/ }# M0 f( n% ]) e3 x4 N
@Test
//使用SDK来构造Template对象参数,单签1 x) t' K7 f" e, w) t( N A
publicvoidtestSignSingleKey()throwsBytomException{) f# {& W, }% j; U: N
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";9 U! B8 H* y. Q8 c% U+ o/ X: }; `
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()
.addAction(, C/ B7 P, N, n$ S
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")/ N, |# A1 i% B8 d% K2 s
.setAssetId(asset_id)# q/ t X# e [
.setAmount(40000000)$ z; m' }5 x+ q* m5 r2 V
)9 B2 f9 c% B7 m2 p1 U" ^
.addAction(6 s3 D4 s; E& r' d* x
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)
.setAmount(300000000)2 V8 y5 l* E1 a
)
.addAction(: T2 O2 @; \. i+ I0 T
newTransaction.Action.ControlWithAddress(); Z; E$ p5 \: u' ^
.setAddress(address)1 c: |5 L5 k, Y+ _' u
.setAssetId(asset_id)
.setAmount(30000000)
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction); a( ?3 a' E+ o8 j2 t+ l0 C
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray; A: f8 ~& ]% D$ ~' K
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
logger.info("privatekey:"+privateKeys[0]);7 i3 w, |1 e" V. b9 a
//callofflinesignmethodtoobtainabasicofflinesignedtemplate' b+ V( U& b( f5 v) i
Signaturessignatures=newSignaturesImpl();4 b) j, L. {' _4 m4 `/ ?$ k
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString$ s1 `" H( Y# [' S7 s
Templateresult=newTransaction.SignerBuilder().sign(client,+ j4 h) \& I/ w+ }/ H k
basicSigned,"");& y; ~8 `# v' W2 x# b( }, K. _# H
logger.info("resultraw_transaction:"+result.toJson());; f! [; y" A+ @. u: q
//successtosubmittransaction B5 i! ?$ D$ ~/ b# i1 x
}* H# W# l" _ m$ Z
Multi-keysExample:) W" m& i2 a, `+ {; R
Needanaccounthastwoormorekeys.' e" ?5 m1 h# I
@Test
//使用SDK来构造Template对象参数,多签
publicvoidtestSignMultiKeys()throwsBytomException{; G9 y) U# {7 E) M: D
Clientclient=Client.generateClient();5 D2 e/ M' \7 x
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";1 v9 G5 I2 v i8 x u3 M
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject& e( c% g, G* J( b5 k5 P" M
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()
.setTtl(10)& x' M2 Q! \5 m, E; g7 Y
.addAction(
newTransaction.Action.SpendFromAccount()5 h4 f% r/ l3 t) K& M8 z
.setAccountId("0G1RPP6OG0A06")8 O. z+ m4 _. P9 d+ x* B1 x- Y
.setAssetId(asset_id)
.setAmount(40000000)' Y, G, S# ^. m4 G$ m: H. V
)+ T+ O( W9 C* S7 Y' |0 I
.addAction(! H% ^& W( m8 m8 ^
newTransaction.Action.SpendFromAccount(), |1 f; }: B i. g
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address) d3 d8 x2 r" v
.setAssetId(asset_id)( T( ^- c: e& [+ t5 a0 y" ?
.setAmount(30000000)
).build(client);
logger.info("template:"+template.toJson());1 S; w& h, x3 A) ?
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject E' U! ?7 s, n- S
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",* ?! Q7 t6 W4 S6 i6 ~3 X( P
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
logger.info("privatekey1:"+privateKeys[0]);4 d% [. x1 i4 N$ k
logger.info("privatekey2:"+privateKeys[1]);! E% P. J" U( N0 `2 `) B9 [
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);6 ?9 s5 Q n2 M+ w. ` k
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());- v. f4 ^' k% ?6 r- S# p
//successtosubmittransaction
} ^$ {* r. g8 d8 T1 l
Multi-keysandMulti-inputsExample:
@Test
//使用SDK来构造Template对象参数,多签,多输入
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()! J" ?3 j. Y6 E8 |0 x5 B
.setTtl(10)+ P6 n8 r# P0 @/ I9 k! Q+ Q
//1input1 y' u/ e/ L5 t. u) A0 h
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount$ O3 ]* U! b/ ^5 O3 I( v! B% z
.setAssetId(asset_id)% b1 R& G. T8 l
.setAmount(40000000)$ m# a6 b9 O2 V, k+ e. ?2 A' r
)' R, C: l$ M( |
.addAction(* R" q1 Y! C$ I2 e
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)" w( d* v3 a( q: m
.setAmount(300000000)) n7 `: Y8 M7 a* Y$ M! |. T. O
)//2input
.addAction(! \# W' {& w2 i4 r
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount/ j; L' H8 A( L' Y
.setAssetId(asset_id). o, l& N2 R8 a9 g7 Z- t1 p
.setAmount(40000000)
)4 y; {; h, P6 h6 D- u) s
.addAction(0 j# C5 t. V' \
newTransaction.Action.SpendFromAccount()" u% j. I' a/ Z+ Z
.setAccountId("0G1Q6V1P00A02")3 ~% Y' X2 h% A# e
.setAssetId(asset_id)
.setAmount(300000000)
)$ ?% k2 M& B2 o, |
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)! u* K {2 O0 {$ U! q. J$ c
.setAmount(60000000)
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);$ {# r, J& z* R
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",0 z- W* R; q+ Z1 X- I
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};/ K$ b/ b: Y. M5 l
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);- s2 q; U- s+ n
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();+ R* @- Z- _) j H* x
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString0 [+ c9 Y4 a5 s, N& |* P: s, H
Templateresult=newTransaction.SignerBuilder().sign(client,& j0 ~6 A# V& C. D: C0 x% j/ Y) H
basicSigned,"");: I9 g9 N* X* `5 | n" M
logger.info("resultraw_transaction:"+result.toJson());- p; W" p3 D4 i( d
//successtosubmittransaction
}1 \4 ~( Z. R% ^1 n/ e
- ~4 w; F; f2 Q4 d b9 I
成为第一个吐槽的人