比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
106
0
0
Javaimplementationofsigningtransactionofflinetobytomd.
Pre
Getthesourcecode
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom
gitcheckout, K% V0 t9 m3 n! y4 Q
$gitcheckoutdev) Y- b4 M2 ?- F" ~ I0 n2 w
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build8 s* ?- _5 ]; y5 u7 v
$cd$GOPATH/src/github.com/bytom& B6 N# _& ] l* |" Z o
$makebytomd#buildbytomd( Q, R2 r4 E6 }: o9 U8 \! a
$makebytomcli#buildbytomcli* i! |% j$ j$ ^ Z
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.
Initialize8 v, ]% b" W8 n/ M' A! U! L
Firstofall,initializethenode:" c' L1 K: W( \4 t* U
$cd./cmd/bytomd
$./bytomdinit--chain_idsolonet, f, z' v$ w; p- b
launch7 z( [# V, {' A/ {( k( m
$./bytomdnode--mining. Y3 L: G! v Y" u
Usage! l* \ P8 Y& i: p' B
Buildjar
2 B3 J. r! d7 e6 z& L5 Z
firstgetsourcecode
gitclonehttps://github.com/successli/tx_signer.git9 P# h% B. y0 k
getjarpackage
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject.# u" O6 d, c N* M6 Z
w1 G" W, o0 M# I/ {; z! r# e( c( ~
Testcases
Need3Parameters:$ W( S, E, W+ x; y0 w0 s% f( |' k
PrivateKeysArray5 c# E# P+ j9 u1 m( R: u5 p
TemplateObject3 o" o1 M2 K8 V9 c& w" x/ M6 U
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi% u5 {3 X( |1 `/ k) r8 q
usebytomjavasdkreturnaTemplateobject.
RawTransaction
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:
//returnaTemplateobjectsignedofflinebasically.
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);: z0 O; A5 N ?9 Y* [0 }
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey. v/ d9 a% k2 C. P% P2 F
Single-keyExample:5 o5 ^/ ~4 B# E$ I2 i
@Test$ p+ y/ J3 m" L, b9 Y% M# l
//使用SDK来构造Template对象参数,单签: {8 R, Q" |( T+ ]8 R* H8 S3 z
publicvoidtestSignSingleKey()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";' X$ ^4 L; T! }
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject) t& l9 |+ ^) B6 ~5 W3 V3 @" |
Templatetemplate=newTransaction.Builder()* f" A4 j. F4 b3 y/ i2 A' _
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")! O; y! T L( D* l$ z
.setAssetId(asset_id)8 o$ C( Y6 {) r, \( Z
.setAmount(40000000)
)+ Y7 D8 {& h' R' T+ w
.addAction(" _$ T% {0 H. o
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)
.setAmount(300000000)/ u1 S# a/ M% @/ J! f
)
.addAction(9 z5 v* {! I' _" w3 Z" }
newTransaction.Action.ControlWithAddress()
.setAddress(address)4 p8 A X1 c' R7 u9 A+ N
.setAssetId(asset_id)' O# @! @ c. {/ ~3 p- \! d
.setAmount(30000000)
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());/ C( T2 E: u2 F0 P! ~- e1 w
//needaprivatekeyarray
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};8 o @4 C% a$ D# J% ?5 X% q: E
logger.info("privatekey:"+privateKeys[0]);, V% T% I3 ] D0 i- l- p
//callofflinesignmethodtoobtainabasicofflinesignedtemplate6 Q/ V: `& F* z; }- ], [
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);- X, }3 h) o* t/ v8 [; Z; ?
logger.info("basicsignedraw:"+basicSigned.toJson());. L3 m! g' [0 t+ i5 c3 d2 R
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());: j" \& X. l* Q
//successtosubmittransaction
}
Multi-keysExample:% P5 `8 | q6 X3 C9 b
Needanaccounthastwoormorekeys.
@Test
//使用SDK来构造Template对象参数,多签
publicvoidtestSignMultiKeys()throwsBytomException{7 ^8 u4 @$ E1 P! n5 i# A
Clientclient=Client.generateClient();, S& e, \: d' Z0 ~, X j& O
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";* t; v7 P) h: J% a
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";! q3 m$ A' E' |
//buildtransactionobtainaTemplateobject+ R1 {7 R% Q: A( B& p
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()3 W! g% G% A: R- J8 S
.setTtl(10)- W4 o/ T9 `1 p, M7 E* g. P8 D
.addAction(- q- |# Q3 i) l: P1 X
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06"): N+ G/ A9 \9 F6 |4 r
.setAssetId(asset_id)/ w; Y9 I$ x( ?
.setAmount(40000000)% ]/ y1 I& B3 u5 X
)6 i+ O6 E& Y$ z0 p' N+ v7 z1 Q& |
.addAction(
newTransaction.Action.SpendFromAccount() V; m2 x! K4 u& p e
.setAccountId("0G1RPP6OG0A06")! T) i5 p! b5 R) C4 I7 ~5 t
.setAssetId(asset_id)9 S, |% m) g6 J
.setAmount(300000000)
)
.addAction(. C: |( z" o2 `& F- S2 ]
newTransaction.Action.ControlWithAddress()
.setAddress(address)6 X4 Z! m: ^: m: ?
.setAssetId(asset_id)6 q9 N/ {" g" M* x w) R- @
.setAmount(30000000)
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject' l# D( D" ^, U# F" b* D
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());5 l* ?0 ?* o1 K/ X
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67", I% q1 {4 g+ F4 z3 B
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
logger.info("privatekey1:"+privateKeys[0]);! |% T+ ^. j$ s$ _. q5 Y; d! I
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate5 W- r0 u* g; Q# B: P$ f
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);% F# _) Z, x, D: k- X4 P
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid, D7 B9 i0 B( b0 X
//signpasswordisNoneoranotherrandomString* l9 k. w; z1 y1 A$ c' K
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}: q& w, a& {1 R0 s2 [9 U
Multi-keysandMulti-inputsExample: Y! ?" y* ^1 Q8 P
@Test
//使用SDK来构造Template对象参数,多签,多输入/ K1 d: h; f& W' k5 _9 p
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{2 L8 j1 B$ Q9 a9 F% E- v3 O
Clientclient=Client.generateClient();2 {& b0 k% P# K2 B$ ]6 r) p3 d1 X; f
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()- s2 z% I9 I4 t2 @( K
.setTtl(10)+ C( i6 R2 q( q0 Y4 u% x8 L
//1input6 a; d9 T6 a4 B; ^0 m8 Q
.addAction(8 J* E R: Y0 c/ E. n) a, _% m" p" }
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount% a3 i( M* n v _! {. D% I
.setAssetId(asset_id)
.setAmount(40000000)
)7 ?) G! x" N/ ~7 j2 X. Y' ~8 ?
.addAction(5 l* X; F& L# |0 X! J& Q
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")) b+ a* s8 _9 w$ N9 w( e, `
.setAssetId(asset_id)- x! j/ ~. b/ T8 E/ P& w$ ~
.setAmount(300000000)2 b* ~7 y& B: C3 q- H" A3 X
)//2input
.addAction(' ?( Q/ Z# l+ I( Y0 l# }
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount; i; B9 o/ a& I0 ?9 F- z
.setAssetId(asset_id)5 q+ ?4 \% E: n* h! Y# |" ?
.setAmount(40000000)
) C2 U) t+ n. ~' s3 ~/ Y# Q @# q
.addAction(
newTransaction.Action.SpendFromAccount()" m/ Q% |- N. ?$ _' h9 ~
.setAccountId("0G1Q6V1P00A02")
.setAssetId(asset_id)* `* k1 [$ r6 N& }
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)
.setAmount(60000000)
).build(client);
logger.info("template:"+template.toJson());, j, E. R Z# P- p7 ]
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());! `, U* t d; L* L: l% N* H5 V% D
//needaprivatekeyarray; D8 x7 C* Y1 Q& Y+ B% {
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",* G1 p8 Y: H2 a* U" r& W$ d4 m
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",/ F5 P" v, \4 o6 P: \. L; @
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();. b, c- l* k/ E6 c K
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);- r* U+ B0 ^5 L/ K5 ^$ {* g$ h
logger.info("basicsignedraw:"+basicSigned.toJson());6 m, G6 z6 D7 Q! G# W; @- n" ?; j
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,% n) d; B4 P( m7 y1 u% d$ L
basicSigned,"");1 Y5 @) o G% P2 n' R9 d/ W
logger.info("resultraw_transaction:"+result.toJson());: J/ c* E9 j3 h2 M& d
//successtosubmittransaction% h( U2 D3 z. W1 o- e$ C3 F
}
成为第一个吐槽的人