比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
147
0
0
Javaimplementationofsigningtransactionofflinetobytomd.) t( @/ }) u, M& n
Pre
Getthesourcecode
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom% V- Y8 N( v- r/ @" r
gitcheckout
$gitcheckoutdev1 E% L( N: D* V6 N/ G$ U' Q m
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.$ Q. t' j% i& Y
Build( Y# ]2 m- A( Z0 B% l
$cd$GOPATH/src/github.com/bytom) V+ k8 Y& x2 R, q! D; s
$makebytomd#buildbytomd' ~" ?. e0 D: g, i8 \
$makebytomcli#buildbytomcli
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively./ `4 f: @- X6 f- e) m! @ ^
Initialize
Firstofall,initializethenode:
$cd./cmd/bytomd* i) h0 a+ K+ n1 o) @
$./bytomdinit--chain_idsolonet- M" }; x* H5 g) w3 v" G5 m" }2 n" ?
launch
$./bytomdnode--mining2 }( H' Q8 j! e8 l' \2 y5 g2 M3 m
Usage
Buildjar
firstgetsourcecode' e1 P; w$ Q' \. w: B# P# H h$ I
gitclonehttps://github.com/successli/tx_signer.git* M |- d: j+ Y5 K& N. |4 I7 D
getjarpackage
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject.
Testcases. ~6 P1 n U" K8 e/ r; F% m
Need3Parameters: x6 G+ [- n7 \- z5 c0 W
PrivateKeysArray$ i- X) G+ v' k+ N: d0 Z
TemplateObject- k* S1 B8 ?; X
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi
usebytomjavasdkreturnaTemplateobject.
RawTransaction, K5 z: P& c# A; x! {* s) B1 L
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:
//returnaTemplateobjectsignedofflinebasically.; o I5 p9 S" _/ E
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);! Q' O" w3 J( _
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.7 u4 r3 C% [+ t5 f
Single-keyExample:
@Test- \) ~- b$ W. H$ C( D5 x$ \ n
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{* M) k( R3 m& ? s" N% Y* {
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";. F1 l ?1 Z ~0 B( s0 }
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject2 x6 _8 I+ x8 ~$ ~+ B
Templatetemplate=newTransaction.Builder()1 ~' U0 g9 [" }7 K% ?! n
.addAction(# R5 ?, L- W2 F* g/ H0 K# u
newTransaction.Action.SpendFromAccount()9 T; R0 J8 e; N3 L* s
.setAccountId("0G0NLBNU00A02")4 Y' A$ Y4 L$ z5 O6 L4 k
.setAssetId(asset_id)7 U" `& ]4 M, `) B/ o
.setAmount(40000000)* @( w6 ` t6 }- d: z- {) t* V& h
)
.addAction(( i4 J2 p, S! _" g; H0 j+ i
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)% A; A0 W+ y8 b$ {) ~% w! H# q; n* p h
.setAmount(300000000)
)
.addAction(! J2 z. R( H( m8 g1 T5 w& B
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)8 W$ U8 ?( @6 z# W( d, f. ]1 U
.setAmount(30000000)6 E3 }5 o% h) {; u+ ^6 ^
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject9 G, g7 s5 e2 ^ E8 X+ L
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);, k4 J; i2 f( y2 I! e
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};4 X" n1 O; E) Q3 _( u+ i, ^
logger.info("privatekey:"+privateKeys[0]);. [: Z$ O- v. S# j' _/ x
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();4 C% _/ L" t$ |
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());# n+ ] z" g8 I; }" i7 I& e
//callsigntransactionapitocalculatewholeraw_transactionid: F; @8 f: ^8 z$ a, I! N
//signpasswordisNoneoranotherrandomString2 G4 @! B! ^: n
Templateresult=newTransaction.SignerBuilder().sign(client,9 s$ f0 H6 J: n: K* S7 W l6 }/ W
basicSigned,"");) M5 y) g2 M4 b1 p: d& b6 s( w
logger.info("resultraw_transaction:"+result.toJson());& g! F' `5 p. ]- m. V
//successtosubmittransaction
}1 I2 g" p( X1 K7 e1 V$ z* t, w
Multi-keysExample:
Needanaccounthastwoormorekeys.
@Test
//使用SDK来构造Template对象参数,多签% i9 u9 \! `+ m, [, k9 e
publicvoidtestSignMultiKeys()throwsBytomException{6 v) w8 M/ |) k0 }) i0 l; D5 R4 O
Clientclient=Client.generateClient();/ f9 q/ ]8 X# j- z9 j2 n2 u- K' ]# E
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";% T: V' X/ M7 [9 G1 n. Y* R. D
//buildtransactionobtainaTemplateobject$ k& O! v0 `2 V! y
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()
.setTtl(10)7 c' b' D) Q7 J! Z; J
.addAction(
newTransaction.Action.SpendFromAccount()8 Z7 A. c2 W; r
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(40000000)3 B; C% U' b1 {/ n% \9 @
)8 L% d9 i z+ N7 \( | k
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")- J! C' V0 {7 v G
.setAssetId(asset_id)
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)
.setAmount(30000000)
).build(client);. t2 }0 S1 _; A" k
logger.info("template:"+template.toJson());9 m; a3 X5 `- F* R0 H) `0 f$ e/ Z$ ~# m
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);1 x" w. }% C# w1 [' `
logger.info("decodeTx:"+decodedTx.toJson());- Q1 R% c+ p' J
//needaprivatekeyarray) Q% n8 ]) I0 Z; s
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",! p/ Y+ I3 `8 H* ]2 V
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
logger.info("privatekey1:"+privateKeys[0]);4 ]4 [9 d7 u. p5 v5 P+ H1 z
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate, P$ G& \4 b# H3 w3 n0 s9 e/ t
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString. L, |- g7 \7 r' t# I k
Templateresult=newTransaction.SignerBuilder().sign(client,9 O" g! |3 c1 z! \3 H F
basicSigned,"");3 `+ D8 w! ?3 ^) p6 n6 z$ @
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}
Multi-keysandMulti-inputsExample:
@Test5 K' }2 J) w" B" z) d8 c
//使用SDK来构造Template对象参数,多签,多输入3 l& r, C8 m: m' ^' i4 [) d1 p
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";; ]3 t& y Z6 m
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject$ Q, I# c# C. X# K9 W) H, @# p
Templatetemplate=newTransaction.Builder()) V; Y$ k; \; a9 F) y3 i' {
.setTtl(10)
//1input5 ~) I' h0 Y5 Y" t
.addAction(
newTransaction.Action.SpendFromAccount()7 x8 p& Q$ l$ [. [" r
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount L1 t) P) o& b p
.setAssetId(asset_id)
.setAmount(40000000)
)2 I0 c. B9 G) i; h& _! e
.addAction(5 i+ a6 l8 }) O4 h* i3 b5 {8 n* J% F
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")/ i/ g1 X+ @: U. h8 G' h
.setAssetId(asset_id): V. t M; L2 b# i9 H
.setAmount(300000000)
)//2input
.addAction(" W8 R" o9 m# l& A3 u: Y& k- }- `
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount
.setAssetId(asset_id)
.setAmount(40000000)0 x5 b1 k1 G$ e& T
)3 f5 k0 p3 D5 d! `
.addAction(& E* w4 m5 O+ D! C% D
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")" z/ j6 w) d( u; j( ]8 s* E* h( s
.setAssetId(asset_id)
.setAmount(300000000)
)) E4 V! X: U- ~: b5 o Z* g
.addAction(, g( |+ D: [* [& |
newTransaction.Action.ControlWithAddress()4 W/ \5 E5 R& j
.setAddress(address)
.setAssetId(asset_id)
.setAmount(60000000)) K- s' [& w& Q! H+ m$ H: [$ ]
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());3 @. n$ j( X5 |8 q$ l J% i
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",. ?# f6 a1 A4 x- }8 W2 a( L
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"}; [% s9 M- j h4 \, A
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);# J4 I9 d3 g* }: S
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid5 F6 b+ }3 }4 z5 h& N6 G
//signpasswordisNoneoranotherrandomString; }5 t$ |' _; i+ D" w; {
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");) e/ h8 B9 V5 c* H/ P9 G6 G
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction* g" v! l/ N! p3 L$ ^
}
成为第一个吐槽的人