22
33import io .bytom .common .Constants ;
44import io .bytom .common .ExpandedPrivateKey ;
5+ import io .bytom .types .*;
56import org .bouncycastle .jcajce .provider .digest .SHA3 ;
67import org .bouncycastle .util .encoders .Hex ;
78
89import java .io .ByteArrayOutputStream ;
910import java .io .IOException ;
1011import java .math .BigInteger ;
11- import java .util .Arrays ;
12+ import java .util .* ;
1213
13- import org .bouncycastle .util .encoders .Hex ;
1414
1515/**
1616 * Created by liqiang on 2018/10/24.
@@ -21,7 +21,7 @@ public String signTransaction(SignTransaction tx, BigInteger[] keys) {
2121
2222 String txSign = null ;
2323 //组装计算program、inputID、sourceID(muxID)、txID, json数据中这些字段的值为测试值,需重新计算
24- buildData (tx );
24+ mapTransaction (tx );
2525
2626 //签名得到signatures
2727 generateSignatures (tx ,keys );
@@ -136,14 +136,76 @@ public byte[] hashFn(byte[] hashedInputHex, byte[] txID) {
136136 return digest256 .digest (data );
137137 }
138138
139- public SignTransaction buildData (SignTransaction signTransaction ) {
140- //build program by address
139+ public void mapTransaction (SignTransaction signTransaction ) {
140+ Map <Hash , Entry > entryMap = new HashMap <>();
141+ ValueSource [] muxSources = new ValueSource [signTransaction .inputs .size ()];
142+ List <Spend > spends = new ArrayList <>();
141143
142- //build sourceId(muxId), inputId, txId
144+ try {
145+ for (int i = 0 ; i < signTransaction .inputs .size (); i ++) {
146+ SignTransaction .AnnotatedInput input = signTransaction .inputs .get (i );
147+ Program proc = new Program (1 , Hex .decode (input .controlProgram ));
143148
144- return signTransaction ;
149+ AssetID assetID = new AssetID (input .assetId );
150+ AssetAmount assetAmount = new AssetAmount (assetID , input .amount );
151+
152+ Hash sourceID = new Hash (input .sourceId );
153+ ValueSource src = new ValueSource (sourceID , assetAmount , input .sourcePosition );
154+ Output prevout = new Output (src , proc , 0 );
155+ Hash prevoutID = addEntry (entryMap , prevout );
156+
157+ input .spentOutputId = prevoutID .toString ();
158+
159+ Spend spend = new Spend (prevoutID , i );
160+ Hash spendID = addEntry (entryMap , spend );
161+
162+ input .inputID = spendID .toString ();
163+
164+ muxSources [i ] = new ValueSource (spendID , assetAmount , 0 );
165+ spends .add (spend );
166+ }
167+
168+ Mux mux = new Mux (muxSources , new Program (1 , new byte []{0x51 }));
169+ Hash muxID = addEntry (entryMap , mux );
170+
171+ for (Spend spend : spends ) {
172+ Output spendOutput = (Output ) entryMap .get (spend .spentOutputID );
173+ spend .setDestination (muxID , spendOutput .source .value , spend .ordinal );
174+ }
175+
176+ List <Hash > resultIDList = new ArrayList <>();
177+ for (int i = 0 ; i < signTransaction .outputs .size (); i ++) {
178+ SignTransaction .AnnotatedOutput output = signTransaction .outputs .get (i );
179+
180+ AssetAmount amount = new AssetAmount (new AssetID (output .assetId ), output .amount );
181+ ValueSource src = new ValueSource (muxID , amount , i );
182+ Program prog = new Program (1 , Hex .decode (output .controlProgram ));
183+ Output oup = new Output (src , prog , i );
184+
185+ Hash resultID = addEntry (entryMap , oup );
186+ resultIDList .add (resultID );
187+
188+ output .id = resultID .toString ();
189+
190+ ValueDestination destination = new ValueDestination (resultID , src .value , 0 );
191+ mux .witnessDestinations .add (destination );
192+ }
193+
194+ TxHeader txHeader = new TxHeader (signTransaction .version , signTransaction .size , signTransaction .timeRange , resultIDList .toArray (new Hash []{}));
195+ Hash txID = addEntry (entryMap , txHeader );
196+ signTransaction .txID = txID .toString ();
197+ } catch (Exception e ) {
198+ throw new RuntimeException (e );
199+ }
145200 }
146201
202+ private Hash addEntry (Map <Hash , Entry > entryMap , Entry entry ) {
203+ Hash id = entry .entryID ();
204+ entryMap .put (id , entry );
205+ return id ;
206+ }
207+
208+
147209 public SignTransaction generateSignatures (SignTransaction signTransaction , BigInteger [] keys ) {
148210 SignTransaction .AnnotatedInput input = signTransaction .inputs .get (0 );
149211 input .witnessComponent .signatures = new String [keys .length ];
0 commit comments