比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
110
0
0
Javaimplementationofsigningtransactionofflinetobytomd.
Pre
Getthesourcecode" Q* @- t# w# @4 t6 L2 b- G
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom
gitcheckout
$gitcheckoutdev* H8 F' R$ E5 |- e8 p7 T
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build1 b5 F6 {* W0 o) p" L
$cd$GOPATH/src/github.com/bytom
$makebytomd#buildbytomd9 N& _) ]* T* N
$makebytomcli#buildbytomcli
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.
Initialize
Firstofall,initializethenode:8 v# G5 f; T) Y: ~! }5 g7 ^
$cd./cmd/bytomd
$./bytomdinit--chain_idsolonet
launch
$./bytomdnode--mining
Usage
Buildjar
9 I/ g- m- M) v+ h& Q% Q
firstgetsourcecode/ F( Y `# G# u4 D
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage
$mvnassembly:assembly-Dmaven.test.skip=true
Youcangetajarwithdependencies,andyoucanuseitinyourproject.
# c6 d. p6 D! W* N% I! s
Testcases6 h6 Z* f5 Q' d, Y# A# c2 l8 [( p+ U
Need3Parameters:
PrivateKeysArray' N! d5 u" G1 ^
TemplateObject2 P7 @2 R- Q) [8 k
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi3 G$ r$ \! X' x7 y) E
usebytomjavasdkreturnaTemplateobject.7 E7 s! k8 h/ w( ]; s1 [
RawTransaction
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi
Callmethod:' m L. w2 R1 M# D: { B2 D
//returnaTemplateobjectsignedofflinebasically." F5 D7 E# ~3 j4 ~9 e2 f
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.; U# ]4 [ w% S
Single-keyExample:
@Test4 Z. g+ D6 V+ ~, [2 t) i7 U
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";2 F8 x5 a5 N% F, L, E. A
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject3 W2 b( j4 ]# e. w# O; Y1 ^
Templatetemplate=newTransaction.Builder()& w$ m' V% P# w+ f! j& M/ R
.addAction(; Q; [+ Y% C* |$ u3 \
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)- [. _" E6 } F# h
.setAmount(40000000)
)5 ?9 u; ?9 f, O0 N( u
.addAction(! ]- `- `3 E9 g
newTransaction.Action.SpendFromAccount()
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)
.setAmount(300000000)# F( L/ y8 q( }) j% s% I
)7 g8 b! e2 l/ z. w4 ]8 p7 s' n3 E
.addAction(! a2 y7 q& O' `0 u/ |1 P
newTransaction.Action.ControlWithAddress()# I7 ]! c2 {; _* D$ l
.setAddress(address)
.setAssetId(asset_id)5 c( n. V3 z; |, g$ b& i) Z
.setAmount(30000000)
).build(client);2 G' S: j$ K+ @* Z" z
logger.info("template:"+template.toJson());3 m0 u$ ?( R% f1 ~
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);" i+ R4 e0 E H( p# V% N2 e
logger.info("decodeTx:"+decodedTx.toJson());2 s% b3 k. |% b4 N6 G
//needaprivatekeyarray% n. @/ q3 L; i7 y8 {
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};
logger.info("privatekey:"+privateKeys[0]);9 _/ p: K, M# g8 U
//callofflinesignmethodtoobtainabasicofflinesignedtemplate% l! n; z7 y: |: y4 e
Signaturessignatures=newSignaturesImpl();+ c; _* _! Y# b( p1 t8 d3 S
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);( n! L5 P7 P" a$ k: A
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");+ U# D/ e3 k) T, L" b2 G( a
logger.info("resultraw_transaction:"+result.toJson());* @; Y% `' y5 I4 C- P
//successtosubmittransaction/ D; j2 x X P* F2 D. S
}6 C+ t/ |+ E V2 v, I
Multi-keysExample:. U$ K- Y- U5 o: p! ?- T
Needanaccounthastwoormorekeys.. x# J! D8 I6 ~( e) ]
@Test) D/ V' C5 g V
//使用SDK来构造Template对象参数,多签" @1 s6 j& K! u8 t0 n
publicvoidtestSignMultiKeys()throwsBytomException{7 n% N/ _) T, \9 u' p. H' [1 Z2 k
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";% i+ a9 k: H* C* r& @6 @7 _
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em"; E" c* s9 V1 h7 F( x$ v1 ~2 u* [
//buildtransactionobtainaTemplateobject+ H; Z8 H2 z$ Q2 j$ ]4 `
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()6 w' }2 I [7 i$ o& o8 v6 P6 [7 U
.setTtl(10)
.addAction(
newTransaction.Action.SpendFromAccount()4 J3 w I0 J& l
.setAccountId("0G1RPP6OG0A06")2 {3 E$ X: \$ j( i. C
.setAssetId(asset_id)
.setAmount(40000000)( Y* M7 ]5 o# L5 E
)4 [1 M. [) H) d7 ]8 H$ }4 L; i
.addAction(
newTransaction.Action.SpendFromAccount()* l0 b$ K, b8 _0 _# b' ?
.setAccountId("0G1RPP6OG0A06")) x& G ~ L* a- n1 Z- v
.setAssetId(asset_id)
.setAmount(300000000)/ G) O+ @5 M, a" N h2 j; R
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)' o$ e2 J) ~/ o% Y9 d* @9 A
.setAssetId(asset_id)/ k) @! Y- D- x7 t1 R* I5 a$ f
.setAmount(30000000), O4 E3 F- k S: L1 j, |+ G
).build(client);
logger.info("template:"+template.toJson());6 ]! g( V$ G" K# {$ Z
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject6 I% j' D, u7 A9 R2 ?/ ]) \
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray0 _; Q# U: D! O. `; Z: P
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};: z8 M6 C* H/ Y* x. O+ a- B- w
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);8 R# ?+ F) l: F0 R* l5 \% G+ [6 t
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();" C6 X, P% g/ y
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);/ F" y* h$ t) I
logger.info("basicsignedraw:"+basicSigned.toJson());$ ^* B) F0 v2 c7 e
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}& N4 ^* o! G. x3 ]
Multi-keysandMulti-inputsExample:
@Test Y4 M. X; L" y# J
//使用SDK来构造Template对象参数,多签,多输入) |: L, c+ @+ E% F; o
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{/ s9 q1 \6 @; s) f7 g5 @
Clientclient=Client.generateClient();" m- h( o6 t& `7 W# g
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";) f/ s8 A5 d' |9 l# @/ Z R
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()
.setTtl(10): L8 [, H# ]) B9 W% s
//1input
.addAction(
newTransaction.Action.SpendFromAccount()+ U$ }: d+ u+ z7 v3 o
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount& c! X% C: [. c/ V7 T5 B. z
.setAssetId(asset_id)
.setAmount(40000000)
) |% m1 P& H! X( H+ D
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)& W+ ]/ e+ J9 l. F [ G8 m1 j
.setAmount(300000000)
)//2input
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount! y: p2 u- Y$ d9 @, G
.setAssetId(asset_id)1 n3 n( J2 O1 s
.setAmount(40000000)! Y; b, ~$ s8 k# X& G7 o
)0 G& m5 X, C( `! j+ Q
.addAction(" ]3 L" u. Q$ N& H" `1 J
newTransaction.Action.SpendFromAccount(). x/ {/ G4 s r: `$ t
.setAccountId("0G1Q6V1P00A02")
.setAssetId(asset_id): E+ M9 w) Z3 E2 k
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)$ K6 \! C7 y) h, ]$ _9 ~ k
.setAssetId(asset_id)7 q. I5 Y: w( j3 Q/ d: Q) r
.setAmount(60000000)
).build(client);' w6 U# v, o! V. z" m" J6 A
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject! z/ b1 a1 X- Z8 A4 b, \+ D
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);% L9 [% z4 \- A0 N: x3 K* n
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",' A+ M9 z0 u! X) n/ h+ e7 v
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",$ T4 a& ?& i {/ F8 }# p+ ]* }
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};
logger.info("privatekey1:"+privateKeys[0]);. ]2 x/ q7 a* T$ R
logger.info("privatekey2:"+privateKeys[1]);; U- i' n' Q2 O: |6 |+ s
//callofflinesignmethodtoobtainabasicofflinesignedtemplate) U& O3 m5 q9 M( L7 h
Signaturessignatures=newSignaturesImpl();& O& l) ^" [ L% o+ x% L. R% R6 ?: v. C
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid% d. W# V" z4 f- j
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}9 n, p7 v3 `3 p# F' Y+ ] L
\; q4 r8 b7 k8 v* \2 ]1 z
成为第一个吐槽的人