比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
107
0
0
Javaimplementationofsigningtransactionofflinetobytomd.
Pre$ z$ Y3 T- ]; D* a7 }: d9 Y e6 }
Getthesourcecode% C9 s8 ?( b* e* n
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom6 a* F5 |5 A, S) f) F0 `7 G
gitcheckout
$gitcheckoutdev! I) r# q5 p8 Z4 j9 ?
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids./ P7 [7 u# k+ g H, A; {" N1 T
Build# o. l. r( V; E+ V0 G5 K
$cd$GOPATH/src/github.com/bytom; @. G) |5 G% N& C ?
$makebytomd#buildbytomd
$makebytomcli#buildbytomcli2 f5 Q7 t) ]0 I. U) H: R- C0 p, U
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.! f: W r8 D2 e9 n& w z/ X( {# D
Initialize. E6 P! z8 ?9 {
Firstofall,initializethenode:8 Q4 S2 r5 Z3 O. q7 c" O9 g+ I$ E
$cd./cmd/bytomd! z# }% i `! E
$./bytomdinit--chain_idsolonet/ o- ^' U1 V; b: f1 f* V( ?
launch+ d4 P) ]$ ~- B
$./bytomdnode--mining
Usage
Buildjar& _+ y" f0 i/ X% d, m
firstgetsourcecode
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject./ {9 O [8 `$ y- e; h5 I* U! Z
( n' Y! k( X+ _6 m: W6 l: `/ `
Testcases, E5 v, N( q/ z$ v0 I
Need3Parameters:
PrivateKeysArray+ y: a) ~! c5 W& u
TemplateObject- w, A- n0 ^, m- p
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi: O( p7 z" j* i/ m: Y$ a
usebytomjavasdkreturnaTemplateobject.5 r; s6 G o: R ^/ n$ i$ N4 ]4 r
RawTransaction
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:) n3 i2 [3 U2 h; u
//returnaTemplateobjectsignedofflinebasically.
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.
Single-keyExample:. W- @1 K: N) r$ k* |* i3 b. c. X
@Test
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{1 B8 g9 k b$ ]: v q9 \1 ?' |& q- E
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";0 _; V2 I9 E+ ?+ ^: J4 f7 B) K) R. g
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject; j+ E8 V1 m, |" B7 J
Templatetemplate=newTransaction.Builder()
.addAction(# S7 ~# g. G; Q
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")8 N9 J" Z5 T8 g7 ^8 N
.setAssetId(asset_id)
.setAmount(40000000)7 b; c( K3 H' T! i _
)
.addAction(
newTransaction.Action.SpendFromAccount()' `% k7 Z/ g5 Y I
.setAccountId("0G0NLBNU00A02")9 q2 C& A" A/ p( u
.setAssetId(asset_id)
.setAmount(300000000)
)# r) w% ?( x, }6 S( w4 J
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)
.setAmount(30000000)
).build(client);8 k9 V& g4 H1 n5 y5 T) ~4 _" W
logger.info("template:"+template.toJson());- H& C1 j* @5 [6 X6 [
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject& k' j1 Q( r$ d5 ~: `# e X$ \
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};$ q7 i1 w6 j, K/ b. \% E
logger.info("privatekey:"+privateKeys[0]);, @$ {6 f7 f ~! {
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());; {- H! r0 t; M4 _% Z) _( C
//callsigntransactionapitocalculatewholeraw_transactionid/ B n, B) X$ G, M; ?; ^/ k0 `
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");. b1 s- B' H4 V
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction* y/ t s" }* y
}
Multi-keysExample:
Needanaccounthastwoormorekeys.
@Test/ N2 N8 Z$ ]0 U! ?5 i3 b
//使用SDK来构造Template对象参数,多签" v, E Q& x: w& P: T
publicvoidtestSignMultiKeys()throwsBytomException{
Clientclient=Client.generateClient();2 J% w1 k ^2 W
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject a% ~* k# [, P: h: Z
//account0G1RPP6OG0A06hastwokeys+ }% B& c7 s4 a) e% b
Templatetemplate=newTransaction.Builder()
.setTtl(10)* B2 E; r) ~3 v0 K J
.addAction(0 f" C; y* F- O9 o
newTransaction.Action.SpendFromAccount()' T- q; u& l) M2 k# @
.setAccountId("0G1RPP6OG0A06") p4 y2 F0 R# I3 }" U' _
.setAssetId(asset_id)
.setAmount(40000000)
)
.addAction(# A* p4 ~/ P; g+ K" L& j& e( X
newTransaction.Action.SpendFromAccount()+ e$ }& o7 {- a2 i$ B5 J
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(300000000)
)/ {: q* c; N* G$ N& ^9 \+ a
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)# c) C, r" d" q5 v. b7 h5 ]' o r
.setAssetId(asset_id)
.setAmount(30000000)
).build(client);" {7 A* q; K( E' U3 @1 |( s
logger.info("template:"+template.toJson());' o" u1 z- l; c
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);9 N6 K/ Q4 Z" s% {* S0 T+ f3 j% X2 w* G
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};3 r# V$ |/ N0 n* a# X8 Z2 g
logger.info("privatekey1:"+privateKeys[0]);1 y" o `5 X2 X
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate+ z. }+ q# Q6 Q9 F: j& H o7 b
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);; ~( p. K: J; [. n4 p, i
logger.info("basicsignedraw:"+basicSigned.toJson()); r" H$ H* z2 H2 n: {
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString7 K. \) |2 [! \0 l" i- y6 `$ V
Templateresult=newTransaction.SignerBuilder().sign(client,: z; s' F- i8 ~- ]. U( @+ E$ I$ a6 s
basicSigned,"");5 P: f6 V3 w7 Z/ {
logger.info("resultraw_transaction:"+result.toJson());; D' W3 E0 W# R
//successtosubmittransaction
}$ w' s" y3 `4 |1 N* ]! G7 X
Multi-keysandMulti-inputsExample:
@Test7 O& C. L* j) i) o# L7 m
//使用SDK来构造Template对象参数,多签,多输入+ _2 u9 x1 ]" j4 t3 O
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{$ Z* S! }/ ^; @: H5 q: ~# L
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";6 Z- |" `8 |0 U
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()
.setTtl(10)7 u8 W$ U8 F% Y; B& n
//1input8 T2 u9 \( G. F1 |# n1 \; {
.addAction(
newTransaction.Action.SpendFromAccount()9 h4 Z& t% \3 J3 Q4 m" j
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount9 P O1 w! J% i+ c" h
.setAssetId(asset_id)
.setAmount(40000000)9 [; ~' w q' T
)
.addAction(
newTransaction.Action.SpendFromAccount()( x V. p J0 P {2 f @# T
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)4 X* q. }2 G, S
.setAmount(300000000)# h" X0 r$ y1 X$ C
)//2input2 u. ^& c' U5 b1 |, e4 D& y
.addAction(0 A( x6 \1 b, w! Y7 ^1 v6 w1 b
newTransaction.Action.SpendFromAccount()7 r, |9 t4 Q/ T% @4 l7 K
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount4 _/ q" h: B( U7 U
.setAssetId(asset_id)
.setAmount(40000000)" A% B2 X; e+ R+ c6 ?! f! C' {) {
)1 u1 V) g* f0 D( [+ K3 i+ [
.addAction(8 _/ C% X/ ~) S5 f( _
newTransaction.Action.SpendFromAccount()6 A, O/ J5 ?( w' Z7 Q. y
.setAccountId("0G1Q6V1P00A02")
.setAssetId(asset_id)9 h, F a2 Y* u! D
.setAmount(300000000)8 u+ _. Y. U" B8 D. [ Y
); y9 [8 X' z1 b
.addAction(
newTransaction.Action.ControlWithAddress(); K: x1 u( R; `* U, O0 j
.setAddress(address)
.setAssetId(asset_id); }8 r6 Y, a" `( J7 h
.setAmount(60000000); l' z, J: n9 E5 ]$ R
).build(client);. l+ D w# z/ A; b U
logger.info("template:"+template.toJson());* W* r! ], b8 a8 {5 W9 Z
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject8 x- Y5 n5 ?- |/ J: b; I8 w
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);% W0 K5 M* ~8 f) T' x$ @8 {! y
logger.info("decodeTx:"+decodedTx.toJson());. ^4 @% m* L; U2 a" Y% k+ i
//needaprivatekeyarray0 x3 X" K3 x) t ^
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",+ M1 y" M8 v, O
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid8 J* \. G- W+ |' i. ^
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}
2 T; z' V* n4 S8 d5 O! Q
成为第一个吐槽的人