比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
162
0
0
Javaimplementationofsigningtransactionofflinetobytomd." ~5 ^. `5 |3 e5 D
Pre
Getthesourcecode
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom1 c# ^8 e* M" m
gitcheckout
$gitcheckoutdev
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build
$cd$GOPATH/src/github.com/bytom
$makebytomd#buildbytomd
$makebytomcli#buildbytomcli E& ]! e; |$ _9 X. ~
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.
Initialize
Firstofall,initializethenode:+ m) q2 X# v; z. u; h1 d' ?% H( ]
$cd./cmd/bytomd- s/ L4 l. I$ `5 A
$./bytomdinit--chain_idsolonet; ^( o. n y( H+ C2 \9 x5 K
launch! D6 J' ], ?0 R# o/ ]! {
$./bytomdnode--mining3 f: e6 S* x/ @, @% i; h
Usage' w! E; d( Z" i1 y- i1 z1 J. a
Buildjar
firstgetsourcecode1 f, ^0 P+ ]& l) D$ J1 x$ Z
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage q. _( N7 }8 O7 J& U" r4 W
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject." ?/ V8 b2 s0 K6 Y# ~3 W
% s9 |4 z5 _- R' A+ R
Testcases
Need3Parameters:
PrivateKeysArray" N: j0 r" g$ O2 ]
TemplateObject( l2 y+ N. U5 R& P
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi
usebytomjavasdkreturnaTemplateobject.5 _5 z2 z, p7 V3 y! }6 t
RawTransaction" o% L! {) |$ f! ]& [/ b$ z. ^: D# ]
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi3 m( @( o+ y3 r& j8 x
Callmethod:; N ]$ [( _" ?
//returnaTemplateobjectsignedofflinebasically.- `. b/ d3 t; x3 w' j" |) R, a; t
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);0 u2 [# l& ]! V4 t- o6 u. q( J
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.3 L1 f0 a9 M+ X7 A5 }# a4 E2 y
Single-keyExample:
@Test
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{: N+ r: U Y K: G* I/ F
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";( S+ ]6 d' m$ d# S
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()' U9 L- q% a4 [3 \+ c ?
.addAction(7 S. W x* a- t: g& F
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)
.setAmount(40000000). ?* I1 r& |7 U6 D- x- T
) j" M4 W- w) o. N5 ^( ]0 j
.addAction(0 I8 I) K; T+ Y
newTransaction.Action.SpendFromAccount()% z: ~* x5 e' p) g
.setAccountId("0G0NLBNU00A02")5 A' O8 T/ q- e1 @5 r8 i' f
.setAssetId(asset_id)
.setAmount(300000000)
)% f. G; U1 f' U0 }$ r; y* k
.addAction(' u8 k; Z- }. R! T
newTransaction.Action.ControlWithAddress()" L( [1 @. e) v# I
.setAddress(address)
.setAssetId(asset_id)2 w* ?+ m2 b! Z: E& {
.setAmount(30000000) `; J# o+ t# D* O z- C/ C
).build(client);/ ^" j0 _" f+ k- G$ K
logger.info("template:"+template.toJson());/ C9 h( u9 ?0 s; q& `3 |* p
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);9 ?0 v5 r8 E5 G. Q0 S
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray$ X1 D, }. i$ N3 W9 w
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};. Y! D, e; U A/ j
logger.info("privatekey:"+privateKeys[0]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();# C9 C! \$ \+ f
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);; H1 V3 ]' X0 ^5 A( a1 u; R! w
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString) O- E. Z& r. Z4 m
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");" M" }, P( ]6 r2 Y2 s( v
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction& ?7 ?6 s4 N& K& V. m$ x) I; _
}
Multi-keysExample:
Needanaccounthastwoormorekeys.3 R* T, D: [0 |. W# m. V
@Test; S- U4 E' f8 C; I6 \' E
//使用SDK来构造Template对象参数,多签1 t& F8 {0 {( I% w) U" ]
publicvoidtestSignMultiKeys()throwsBytomException{8 C0 A; D; J' S" P" @0 }
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";5 X S: @0 a+ b$ c+ S
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()
.setTtl(10)" z: ?6 b, p/ l6 n( P! J- l; e- P
.addAction(. h" x# R& z3 {
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(40000000)
)7 R& H! o- I+ n h4 x. T/ e
.addAction(( h( @8 Z9 o4 ~" P! f% |3 q9 a) H4 [
newTransaction.Action.SpendFromAccount(), [: R5 {( @0 ]$ L, M( W. B
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()$ F% D" d6 d" f7 d6 f4 z
.setAddress(address)4 X* A1 @& o- I/ E. z: y
.setAssetId(asset_id)
.setAmount(30000000)" E" y A: X$ t8 c7 k
).build(client);# y2 o7 E6 m& j9 C& Z1 A
logger.info("template:"+template.toJson());$ r, K( @/ B6 U$ S3 k
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject" P$ a0 Z: C4 e$ L; \* r/ j: M! v
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",5 x5 q6 \3 t' H3 k% t. i+ j) p
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};7 H6 i1 u4 g) [& l% A
logger.info("privatekey1:"+privateKeys[0]);2 ?. Q: b/ E3 S- c' A8 i
logger.info("privatekey2:"+privateKeys[1]);- c8 X) B1 ]$ P* H# s A* x
//callofflinesignmethodtoobtainabasicofflinesignedtemplate% I$ n0 A/ K, D+ |" X
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);! R+ U# E# e! l2 x% r9 f& g
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid/ m0 k" d( v% \" \8 {5 B( ]. L
//signpasswordisNoneoranotherrandomString% A# h8 T5 b" u
Templateresult=newTransaction.SignerBuilder().sign(client,2 T* V+ {8 x) |: m$ P* Q! q
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());+ g. _* W9 F( f7 @
//successtosubmittransaction
}
Multi-keysandMulti-inputsExample:) K: k7 O$ W! S$ a$ J% a- ~$ T
@Test
//使用SDK来构造Template对象参数,多签,多输入
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";* Q4 i5 B) q$ S
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";% a8 B7 ]# J" x6 u
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()
.setTtl(10)4 P9 _; _9 R' T) s' u% {/ Q* u7 Y
//1input
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount8 w# b+ E& X& M- H( n. T
.setAssetId(asset_id)0 M y& e' }9 G8 d# s
.setAmount(40000000): p. F. @; D) s) j0 q3 {( t
): n/ [ x1 `8 m, V
.addAction(
newTransaction.Action.SpendFromAccount()/ ?# y. w# i2 |
.setAccountId("0G1RPP6OG0A06")+ S$ ^ K5 G$ Y: n
.setAssetId(asset_id)( l. q! `' M" n( D
.setAmount(300000000)
)//2input
.addAction(5 u/ p8 c- u; h) U
newTransaction.Action.SpendFromAccount()& m% N5 O7 w; e( Z7 y
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount
.setAssetId(asset_id)
.setAmount(40000000)
)" E: V$ |# D* [7 b4 V0 I3 b9 c& m: d
.addAction(
newTransaction.Action.SpendFromAccount()/ _' M# R5 a" \0 W2 q: _' u
.setAccountId("0G1Q6V1P00A02")
.setAssetId(asset_id)
.setAmount(300000000)+ G3 Z8 M" G- m# m% M$ t' c
)5 p7 |; a [: a, d
.addAction(
newTransaction.Action.ControlWithAddress()* X5 T& x p% `
.setAddress(address)
.setAssetId(asset_id)
.setAmount(60000000)2 u i: ?6 c" o9 P
).build(client);
logger.info("template:"+template.toJson());" g7 Z7 a0 F1 h1 Y
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray) e# N/ i5 G8 b) W8 y3 T+ ]
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",6 j# J9 m2 Q {
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};$ n+ @: K3 d8 o% y6 n4 Z
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);: N2 p2 B- r" c
//callofflinesignmethodtoobtainabasicofflinesignedtemplate9 M. Q. O, d; v( }0 i( Y {/ r, A
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);3 }. }" x3 A8 O! f W/ |2 s: o
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid s1 X6 x& v R& ^4 B
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,- ` W% ]8 v9 i8 F0 L1 p, F1 d+ S2 o4 @
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction( m, s. V5 }: R+ |: a
}
( w ]9 k6 y: {3 Z l0 P
成为第一个吐槽的人