比原链Java版本离线签名
yuan081608
发表于 2022-11-13 23:54:55
119
0
0
Javaimplementationofsigningtransactionofflinetobytomd.0 ?& M" Z% @4 X, x
Pre
Getthesourcecode8 T/ p3 c5 |0 `/ {0 G3 E3 @
$gitclonehttps://github.com/Bytom/bytom.git$GOPATH/src/github.com/bytom
gitcheckout+ x1 a7 {! w) Q% h% v5 P
$gitcheckoutdev
Whyneeddevbranch?Becauseyoucouldcalldecodetransactionapifromdevbranchandobtaintx_idandsomeinputsids.
Build+ g' O+ p6 S) o3 U
$cd$GOPATH/src/github.com/bytom1 }) G) b4 C, r4 P+ C
$makebytomd#buildbytomd
$makebytomcli#buildbytomcli
Whensuccessfullybuildingtheproject,thebytomandbytomclibinaryshouldbepresentincmd/bytomdandcmd/bytomclidirectory,respectively.
Initialize
Firstofall,initializethenode:
$cd./cmd/bytomd
$./bytomdinit--chain_idsolonet) L& K3 ^( ~1 D! m7 V6 c
launch* W! p) P( a4 e+ p# p, v
$./bytomdnode--mining
Usage9 a$ W! B2 Y7 P# t- i6 ~- ~4 t
Buildjar% e. J) a, J+ \
^: [* U# r9 M x% v# Z6 T
firstgetsourcecode; l. z5 `2 i# D2 @
gitclonehttps://github.com/successli/tx_signer.git
getjarpackage+ ~0 d p/ `) `4 I
$mvnassembly:assembly-Dmaven.test.skip=true- [/ s# T* u; r# J5 V: g3 k' o
Youcangetajarwithdependencies,andyoucanuseitinyourproject.
. [" F' w3 Z+ ?0 P7 e: A
Testcases
Need3Parameters:' `, ]& t& J* \( ~# I% o% x
PrivateKeysArray: |& n# s0 d( A1 b; n" p( j! T
TemplateObject
AftercallbuildtransactionapireturnaTemplatejsonobject.buildtransactionapi
usebytomjavasdkreturnaTemplateobject. M$ f9 Z2 ]9 ~; m C L
RawTransaction8 l0 W) b9 {$ L
calldecoderaw-transactionapifromdevbranch.decoderaw-transactionapi9 j' `( u; Z; s5 u+ M# P+ ?( `
Callmethod:
//returnaTemplateobjectsignedofflinebasically.
Templateresult=signatures.generateSignatures(privates,template,rawTransaction);; @- a! J. c5 q& Y. s" S8 k
//useresult'sraw_transactioncallsigntransactionapitobuildanotherdatabutnotneedpasswordorprivatekey.
Single-keyExample:
@Test
//使用SDK来构造Template对象参数,单签
publicvoidtestSignSingleKey()throwsBytomException{& D$ Y% e$ ~+ S7 v( E# s! B
Clientclient=Client.generateClient();, A8 ]0 [' C4 w- C: ~
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";0 P% E: D. U, i; a
//buildtransactionobtainaTemplateobject0 c3 f; g) U' k' U0 r$ g
Templatetemplate=newTransaction.Builder()" C3 i, W1 x3 ?' j5 j
.addAction(
newTransaction.Action.SpendFromAccount()8 Y# A) d1 m& Z# K+ G2 K2 P
.setAccountId("0G0NLBNU00A02")
.setAssetId(asset_id)
.setAmount(40000000)
)
.addAction(
newTransaction.Action.SpendFromAccount()% t* i% N4 \4 _/ u1 [7 N
.setAccountId("0G0NLBNU00A02")$ U; n6 O# f- ?; F7 I1 U+ Z# _# s) T
.setAssetId(asset_id), ]( I+ k: e0 }: d& W# x
.setAmount(300000000)
)5 `9 `' t$ Y: L/ y3 `
.addAction(
newTransaction.Action.ControlWithAddress()/ F+ l% f6 T9 r6 _2 h5 z( |; t
.setAddress(address)
.setAssetId(asset_id)
.setAmount(30000000): j; F/ }% U, c: {: q: Y- Y2 [. Q3 i- _
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);* j9 t9 U& d# B2 u2 R/ S
logger.info("decodeTx:"+decodedTx.toJson());0 G% K5 S+ o( H( I8 d
//needaprivatekeyarray9 U7 P, a+ Q$ B) x2 R( a
String[]privateKeys=newString[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};* N9 ?$ m6 U. I- ^% @1 A) v1 f: b& {
logger.info("privatekey:"+privateKeys[0]);6 ^1 S8 z% g5 k9 \) [. j8 Q k, k) N
//callofflinesignmethodtoobtainabasicofflinesignedtemplate+ q+ J2 g0 ]/ A' E$ } W! \
Signaturessignatures=newSignaturesImpl();
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);2 ~; ~( T& ]0 B& S+ h0 @
logger.info("basicsignedraw:"+basicSigned.toJson());
//callsigntransactionapitocalculatewholeraw_transactionid
//signpasswordisNoneoranotherrandomString
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}
Multi-keysExample:& U7 {- ?* Y* m8 `+ T# g9 E5 ~- U
Needanaccounthastwoormorekeys.5 W8 T- `( a% I' F, Q
@Test
//使用SDK来构造Template对象参数,多签
publicvoidtestSignMultiKeys()throwsBytomException{6 W i0 c. B9 P# b- m3 E
Clientclient=Client.generateClient(); T- S8 s6 C# d$ l8 {& i
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";3 R& _5 y" H- A; ^. l
//buildtransactionobtainaTemplateobject6 r: U: V- m& t
//account0G1RPP6OG0A06hastwokeys
Templatetemplate=newTransaction.Builder()$ c8 J3 V4 \& f8 U3 f$ d [1 ?. L
.setTtl(10)# o9 b7 y( C& _' ] X6 t+ S: Y
.addAction($ f! t" ^. l! j$ {; {# j
newTransaction.Action.SpendFromAccount()* t+ m9 }' p7 R: J: u0 n$ T& K
.setAccountId("0G1RPP6OG0A06")
.setAssetId(asset_id)/ c% Z' i3 y2 h, V% @
.setAmount(40000000)
)3 [+ d" \- i @
.addAction(' {7 ~( E; f' E# N
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")+ i- L) I: u; Q( C$ o# c5 b& L
.setAssetId(asset_id)
.setAmount(300000000)
)
.addAction(
newTransaction.Action.ControlWithAddress()
.setAddress(address)
.setAssetId(asset_id)' W0 r" \9 c( D, M
.setAmount(30000000). D4 F7 W, C+ [; U/ ~
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray4 w# _" _6 u2 S( n2 i
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",+ P3 g! _- L% j
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};
logger.info("privatekey1:"+privateKeys[0]);
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate" H5 k+ g# E8 ?
Signaturessignatures=newSignaturesImpl();4 I% W0 s7 H. [0 Q8 s3 X
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);" G3 V. q/ ^# M0 S0 `+ n: ^
logger.info("basicsignedraw:"+basicSigned.toJson());! q5 X e! A: U8 Q
//callsigntransactionapitocalculatewholeraw_transactionid! g' i/ L4 ?4 l- b
//signpasswordisNoneoranotherrandomString8 z" w( {* s& M4 I0 \6 a+ J
Templateresult=newTransaction.SignerBuilder().sign(client,& y7 U: w! ~/ U2 B
basicSigned,"");
logger.info("resultraw_transaction:"+result.toJson());
//successtosubmittransaction
}
Multi-keysandMulti-inputsExample:
@Test1 u! Z$ A% x1 A# H. y
//使用SDK来构造Template对象参数,多签,多输入
publicvoidtestSignMultiKeysMultiInputs()throwsBytomException{
Clientclient=Client.generateClient();
Stringasset_id="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";9 @! V& l- J: g, {/ m0 B$ F1 }
Stringaddress="sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";
//buildtransactionobtainaTemplateobject
Templatetemplate=newTransaction.Builder()5 X! G) y3 d" m6 @
.setTtl(10)
//1input
.addAction(
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1RPP6OG0A06")//Multi-keysaccount
.setAssetId(asset_id)* d# \) \9 m6 ?/ X
.setAmount(40000000): {5 ^7 V, t; Q
)
.addAction(6 F, I. X2 W# w8 C; b8 H# Q
newTransaction.Action.SpendFromAccount()* ~9 G9 k, p8 O0 v- K2 Y' s
.setAccountId("0G1RPP6OG0A06")' G0 @) l, f$ }
.setAssetId(asset_id)
.setAmount(300000000)
)//2input
.addAction(* d. {' ~ u$ X; s! W4 }
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")//Multi-keysaccount; e# J1 E% }+ o2 }' i- b
.setAssetId(asset_id)
.setAmount(40000000); l( L( d4 F( @5 Z; g- X M y
)& G& z; _& E b
.addAction(; L! P. K0 W( v- j) D- R
newTransaction.Action.SpendFromAccount()
.setAccountId("0G1Q6V1P00A02")9 h% _) J6 S% I" C0 P; ^9 Q7 d w
.setAssetId(asset_id)% h6 o# B' A% ~( D4 y1 W# |& u
.setAmount(300000000)
)% ]& |1 z% t$ j% P4 S
.addAction(
newTransaction.Action.ControlWithAddress()+ j$ [; Z4 ~2 P8 m- Y
.setAddress(address)
.setAssetId(asset_id)3 O: P4 E, I( |+ h1 z
.setAmount(60000000)3 Z( m* h: P! a; X4 T" R/ }
).build(client);
logger.info("template:"+template.toJson());
//useTemplateobject'sraw_transactionidtodecoderaw_transactionobtainaRawTransactionobject
RawTransactiondecodedTx=RawTransaction.decode(client,template.rawTransaction);8 q9 y2 U0 P4 E
logger.info("decodeTx:"+decodedTx.toJson());
//needaprivatekeyarray# D1 ]7 g- }2 Z! a4 Y1 }
String[]privateKeys=newString[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",# g; V9 d C" s! o5 N
"40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",
"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};( M( t0 ~9 }7 W4 l9 G( z* N9 @6 _
logger.info("privatekey1:"+privateKeys[0]);" c+ X4 A9 q& h5 j5 J% m5 }
logger.info("privatekey2:"+privateKeys[1]);
//callofflinesignmethodtoobtainabasicofflinesignedtemplate
Signaturessignatures=newSignaturesImpl();$ o. {& e* v5 J& L% r$ Q
TemplatebasicSigned=signatures.generateSignatures(privateKeys,template,decodedTx);
logger.info("basicsignedraw:"+basicSigned.toJson());: [& L0 G, e& c- t
//callsigntransactionapitocalculatewholeraw_transactionid3 y: H' Q1 R N) ]7 ~
//signpasswordisNoneoranotherrandomString4 ]8 _8 | e4 }1 x. ~
Templateresult=newTransaction.SignerBuilder().sign(client,
basicSigned,"");% y4 _& M- R! s q, k# Y$ h
logger.info("resultraw_transaction:"+result.toJson());& X/ s1 q9 e' d* s( d: ?8 B: S
//successtosubmittransaction
}2 {' p, E6 O2 A4 B6 W( H9 t/ o
成为第一个吐槽的人