比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
165
0
0
Javaimplementationofsigningtransactionofflinetobytomd.
Pre
Getthesourcecode
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom1 ]! ]9 K0 _/ [0 j2 G* t
gitcheckout
$gitcheckoutdev I1 l$ y+ ]* V$ [8 }
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build( c5 h! u1 [% l3 Y& s* W
$cd$GOPATH/src/github.com/bytom
$makebytomd#buildbytomd
$makebytomcli#buildbytomcli
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.9 B( W- q6 r# b( C; r
Initialize
Firstofall,initializethenode:
$cd./cmd/bytomd
$./bytomdinit--chain_idsolonet! s5 ^ U7 ~& J# E% O/ n8 n
launch
$./bytomdnode--mining/ W* p! E6 ]. j4 H$ {7 v( z
Usage: }4 g* A2 ] [: K; j
Buildjar
7 O: @' Z o& a' B' v) E9 F
firstgetsourcecode- f1 ~: f$ {0 E3 |7 z# a2 A
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage
$mvnassembly:assembly-Dmaven.test.skip=true' {$ H, N% d- [2 ~
Youcangetajarwithdependencies,andyoucanuseitinyourproject.
Testcases6 Y2 J" l7 W e$ Z7 U! H. D
Need3Parameters:" A- L4 b6 Z! r/ W
PrivateKeysArray( E$ A5 P) C& }, n: p
TemplateObject( i# B! t* M) q! s5 z' M( }
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi
usebytomjavasdkreturnaTemplateobject.
RawTransaction$ t9 ?7 v( D# w0 Y7 p
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:
//returnaTemplateobjectsignedofflinebasically.3 p, K9 Q3 Y2 u9 I
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);/ {" c3 @* T I$ a+ x" ~5 B5 M) q
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.8 Y' n' Z, {6 ?3 o& `: G& q; K; L
Single-keyExample:$ |/ |* c @: Z; z: {6 I
@Test
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{& @& v8 P, S6 Y4 g1 K$ _
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()# ~$ n, V6 @2 {+ x3 X
.addAction(* Z8 v% L7 Q9 a! D7 j
newTransaction.Action.SpendFromAccount()7 a$ h6 x0 t" X
.setAccountId("0G0NLBNU00A02")% g4 [" l( e1 Y# B" y/ Z- v! j
.setAssetId(asset_id)% |; ]. f, ^2 a. H3 C
.setAmount(40000000)
)
.addAction(, I2 {8 A! `& P( B# P, `9 L7 Q
newTransaction.Action.SpendFromAccount()5 Y! H7 _. A! I3 ]8 J0 b6 H
.setAccountId("0G0NLBNU00A02")% @. [; ]$ u) p# S2 K4 H7 @5 B
.setAssetId(asset_id)
.setAmount(300000000)* c+ p. Y4 ^. ]3 K! i, R4 }
)
.addAction(5 ^1 u1 b# e8 C' q
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)
.setAmount(30000000). n, `. {/ `: k+ z2 p
).build(client);% r3 F+ w& c- L, n8 D6 ]
logger.info("template:"+template.toJson());9 I8 h( M* a6 n R# X
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject6 I% q: A) |$ c! o
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);# ^8 Y" W, O$ ^# o# ^* Y
logger.info("decodeTx:"+decodedTx.toJson());) H4 m* X9 N" M* p3 y2 P7 |$ K4 Y
//needaprivatekeyarray8 b$ J3 r3 @1 ]) B8 X
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};' v) F4 ?# {% \* ~; z$ Q- V
logger.info("privatekey:"+privateKeys[0]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,: H% h P2 b& M
basicSigned,"");1 t& Y9 G" @: b/ T
logger.info("resultraw_transaction:"+result.toJson());. y* {% F+ |0 D: i2 z1 d6 `
//successtosubmittransaction7 w. ~, {4 S) I
}
Multi-keysExample:
Needanaccounthastwoormorekeys.
@Test
//使用SDK来构造Template对象参数,多签; C4 N/ ~/ r" s' M5 N
publicvoidtestSignMultiKeys()throwsBytomException{" v( j: \0 t: V4 O% Y+ w; i: T
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";5 G3 f4 j5 [8 c; [* c
//buildtransactionobtainaTemplateobject
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()
.setTtl(10)
.addAction(. [8 s& X3 Q% O0 t& C8 p
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(40000000)
)9 d0 U' C; i0 x, P$ q) y6 N) I
.addAction(
newTransaction.Action.SpendFromAccount()' J1 H$ Z3 e$ N* c, f g
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)
.setAmount(300000000), b4 {& @& \, `( n$ E- ^% k
)* l- X; g# m! x- Y8 n. I
.addAction(# H4 i7 N' l( H3 ~' Y! [0 N
newTransaction.Action.ControlWithAddress()7 ~! o% J3 d" G# g8 I9 v1 c
.setAddress(address)
.setAssetId(asset_id)2 G. B# q7 B0 x7 d7 f, A" a
.setAmount(30000000)
).build(client);8 n4 i# {7 x- w9 j3 k$ x% a5 l5 z
logger.info("template:"+template.toJson());) F1 @$ R) i" `% }3 ?
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject) D- X- p, ]/ G+ { h1 d" t: N& {
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());2 X, {' P8 X4 V1 q2 \
//needaprivatekeyarray$ Y; L# T5 `. ~0 t
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};4 x9 J/ T7 ?) e# o" K; c
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate! Y9 d: F- S* k
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());; N( X. s2 ?1 \+ u, g7 Y, G: {. R
//callsigntransactionapitocalculatewholeraw_transactionid/ v/ }4 ]5 `3 c' r8 V
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,""); ?+ m& I; _9 Y; C0 ~% b: b
logger.info("resultraw_transaction:"+result.toJson());! x, d) S1 `6 D- K4 T3 l5 J' r, M2 `
//successtosubmittransaction& m) f& @2 e% p0 T* t8 ?
}" G$ v% N1 Y5 M, U( ]
Multi-keysandMulti-inputsExample:
@Test
//使用SDK来构造Template对象参数,多签,多输入3 ?" V5 m3 u) d' b& z
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{" E( T a) I' k6 E( r1 h
Clientclient=Client.generateClient();* m7 \' o* b, @/ }% d! q! e
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";5 [4 E/ l n3 _! p7 E+ O3 ~, S6 @
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()
.setTtl(10)
//1input
.addAction(
newTransaction.Action.SpendFromAccount()% I" N& @* ~& p; G
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount2 ?& x2 z5 w- R; ^0 c* ~
.setAssetId(asset_id)/ M |: x6 q/ l( ]/ g' c
.setAmount(40000000)4 y8 v/ _" A# `1 ?+ L4 O
)/ F) }6 g" b+ x6 w+ f5 S
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")/ J( u& f2 P6 u0 Q8 A
.setAssetId(asset_id)
.setAmount(300000000)
)//2input$ k: D3 H% U5 b, ~- m& g. g
.addAction(
newTransaction.Action.SpendFromAccount()" ~2 Y0 a9 ~# X- v: V
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount; A. [1 B) Y6 w& a/ r! T
.setAssetId(asset_id)
.setAmount(40000000)% [. l9 F0 n1 {2 R9 T7 @* ]
)2 ~( L t0 ]& t. q2 j2 e5 F8 h
.addAction(1 z# e% N `3 A$ c1 W3 q4 C' ^
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")
.setAssetId(asset_id)- O, H3 j) H9 F3 L. Q) J
.setAmount(300000000)
)
.addAction(0 B8 Q6 T# v* V9 C
newTransaction.Action.ControlWithAddress()( c2 f- j" z/ B6 T' o# z* c
.setAddress(address)# S% O2 u3 _1 s( a% `9 X% X& ` Y6 v
.setAssetId(asset_id)
.setAmount(60000000)
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject, e) X8 J* B5 J3 J
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);- \: u/ A. C; p- c
logger.info("decodeTx:"+decodedTx.toJson());# w# T+ O4 `; a+ [
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",) C) N) k3 d; e. A7 L3 d0 R
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};( ~+ {: o, ?& }; W
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);8 z( s& L1 Z- O+ W( |1 e
//callofflinesignmethodtoobtainabasicofflinesignedtemplate& [: c' C% N8 O& U. D m
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString8 E3 B& o s) ~4 N, j8 ^
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());0 }( @& T4 q1 @5 R
//successtosubmittransaction5 z* Y) h F4 G7 M
}
成为第一个吐槽的人