Skip to content

Commit a874805

Browse files
committed
Created missing Objects added signing and missing API calls. Models are now closer to the default IOTA objects (Maybe add converter from IOTA objects to JS and other way around)
1 parent 460fc64 commit a874805

16 files changed

+659
-139
lines changed

README.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ If you have any ideas please submit a request (I am totally not a Java guy so...
99

1010
#### Multisig
1111
- [x] composeAddress
12-
- [x] updateLeafToRoot (needs testing)
12+
- [x] updateLeafToRoot
1313
- [x] getDigest
1414

1515
#### Model.Transfer
16-
- [x] prepare (needs testing)
17-
- [x] compose (needs testing)
16+
- [x] prepare
17+
- [x] compose
1818
- [x] close (needs testing)
19-
- [ ] applyTransfers
20-
- [ ] appliedSignatures
21-
- [ ] getDiff
22-
- [ ] sign
19+
- [x] applyTransfers
20+
- [x] appliedSignatures
21+
- [ ] getDiff (not used at the moment)
22+
- [x] sign
2323

2424

2525

@@ -28,6 +28,7 @@ If you have any ideas please submit a request (I am totally not a Java guy so...
2828
1. Clone repo
2929
2. Update maven ressources
3030
3. That's it.
31+
4. You can run a test transaction by running the main func in the Main Class.
3132

3233

3334

iotaflashlibjswrapper.iml

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
<orderEntry type="sourceFolder" forTests="false" />
1414
<orderEntry type="library" name="Maven: com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0" level="project" />
1515
<orderEntry type="library" name="Maven: com.github.iotaledger:iota~lib~java:v0.9.10" level="project" />
16+
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.2" level="project" />
1617
</component>
1718
</module>

pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626
<artifactId>iota~lib~java</artifactId>
2727
<version>v0.9.10</version>
2828
</dependency>
29+
<!-- Gson: Java to Json conversion -->
30+
<dependency>
31+
<groupId>com.google.code.gson</groupId>
32+
<artifactId>gson</artifactId>
33+
<version>2.8.2</version>
34+
<scope>compile</scope>
35+
</dependency>
2936
</dependencies>
3037

3138
<!-- https://maven.apache.org/settings.html#Properties -->

res/iota.flash.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9472,7 +9472,7 @@ var is_null = function(arr) {
94729472
}
94739473

94749474
var trits_to_words = function(trits) {
9475-
if (trits.length != 243) {
9475+
if (trits.length != 243) {
94769476
throw "Invalid trits length";
94779477
}
94789478

src/main/java/Helpers.java

+40-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import Model.*;
22

33
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.stream.Collectors;
46

57
public class Helpers {
68
public static ArrayList<Bundle> createTransaction(UserObject user, ArrayList<Transfer> transfers, boolean shouldClose) {
@@ -11,18 +13,18 @@ public static ArrayList<Bundle> createTransaction(UserObject user, ArrayList<Tra
1113
System.out.println("No more addresses in channel.");
1214
}
1315

14-
ArrayList<Transaction> newTransfers;
16+
ArrayList<Transfer> newTransfers;
1517

1618
if (shouldClose) {
17-
newTransfers = new ArrayList<>();
18-
// newTransfers = IotaFlashBridge.close(user.getFlash().getSettlementAddresses(), user.getFlash().deposits);
19+
newTransfers = IotaFlashBridge.close(user.getFlash().getSettlementAddresses(), user.getFlash().getDeposits());
1920
} else {
2021
newTransfers = IotaFlashBridge.prepare(
2122
user.getFlash().getSettlementAddresses(),
2223
user.getFlash().getDeposits(),
2324
user.getUserIndex(),
2425
transfers
2526
);
27+
2628
}
2729

2830
ArrayList<Bundle> bundles = IotaFlashBridge.compose(
@@ -42,6 +44,33 @@ public static ArrayList<Signature> signTransaction(UserObject user, ArrayList<Bu
4244
return IotaFlashBridge.sign(user.getFlash().getRoot(), user.getSeed(), bundles);
4345
}
4446

47+
public static ArrayList<Bundle> appliedSignatures(ArrayList<Bundle> bundles, ArrayList<Signature> signatures) {
48+
ArrayList<Bundle> clonedBundles = clone(bundles);
49+
bundles.clone();
50+
51+
for (int i = 0; i < bundles.size(); i++) {
52+
Signature sig = signatures.get(i);
53+
Bundle b = bundles.get(i);
54+
if (sig == null) {
55+
continue;
56+
}
57+
58+
ArrayList<Transaction> transactions = b.getBundles();
59+
String addy = transactions.stream().filter(tx -> tx.getValue() < 0).findFirst().get().getAddress();
60+
List<Transaction> tmp = transactions.stream()
61+
.filter(tx -> tx.getAddress().equals(addy))
62+
.collect(Collectors.toList());
63+
64+
tmp = tmp.subList(sig.getIndex(), sig.getIndex() + sig.getSignatureFragments().size());
65+
66+
for (int j = 0; j < tmp.size(); j++) {
67+
tmp.get(j).setSignatureFragments(sig.getSignatureFragments().get(j));
68+
}
69+
}
70+
71+
return clonedBundles;
72+
}
73+
4574
public static void applyTransfers(UserObject user, ArrayList<Bundle> bundles) {
4675
IotaFlashBridge.applayTransfers(
4776
user.getFlash().getRoot(),
@@ -52,4 +81,12 @@ public static void applyTransfers(UserObject user, ArrayList<Bundle> bundles) {
5281
bundles
5382
);
5483
}
84+
85+
public static ArrayList<Bundle> clone(ArrayList<Bundle> bundles) {
86+
ArrayList<Bundle> clonedBundles = new ArrayList<>();
87+
for (Bundle b : bundles) {
88+
clonedBundles.add(b.clone());
89+
}
90+
return clonedBundles;
91+
}
5592
}

src/main/java/IotaFlashBridge.java

+34-42
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ public static void boot() throws IOException {
2525
engine.executeVoidScript(file);
2626
multisig = (V8Object) engine.executeScript("iotaFlash.multisig");
2727
transfer = (V8Object) engine.executeScript("iotaFlash.transfer");
28+
29+
Model.Console console = new Model.Console();
30+
V8Object v8Console = new V8Object(engine);
31+
engine.add("console", v8Console);
32+
v8Console.registerJavaMethod(console, "log", "log", new Class<?>[] { String.class });
33+
v8Console.registerJavaMethod(console, "err", "err", new Class<?>[] { String.class });
34+
v8Console.release();
35+
engine.executeScript("console.log('Connected JS console to V8Engine output.');");
2836
}
2937

3038
/**
@@ -93,11 +101,8 @@ public static CreateTransactionHelperObject updateLeafToRoot(MultisigAddress roo
93101

94102
V8Object ret = multisig.executeObjectFunction("updateLeafToRoot", params);
95103
int generate = ret.getInteger("generate");
96-
Map<String, ? super Object> multiSigMap = V8ObjectUtils.toMap((V8Object) ret.getObject("multisig"));
97-
// Parse result into Java Obj.
98-
String addr = (String) multiSigMap.get("address");
99-
int secSum = (Integer) multiSigMap.get("securitySum");
100-
MultisigAddress multisig = new MultisigAddress(addr, secSum);
104+
V8Object multisigObject = (V8Object) ret.getObject("multisig");
105+
MultisigAddress multisig = V8Converter.multisigAddressFromV8Object(multisigObject);
101106
return new CreateTransactionHelperObject(generate, multisig);
102107
}
103108

@@ -110,7 +115,7 @@ public static CreateTransactionHelperObject updateLeafToRoot(MultisigAddress roo
110115
* @param transfers array of all transfers (value, address) pairs
111116
* @return
112117
*/
113-
public static ArrayList<Transaction> prepare(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, int index, ArrayList<Transfer> transfers) {
118+
public static ArrayList<Transfer> prepare(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits, int index, ArrayList<Transfer> transfers) {
114119

115120
// Now put all params into JS ready array.
116121
List<Object> params = new ArrayList<>();
@@ -121,21 +126,28 @@ public static ArrayList<Transaction> prepare(ArrayList<String> settlementAddress
121126

122127
// Call js function.
123128
V8Array ret = transfer.executeArrayFunction("prepare", V8ObjectUtils.toV8Array(engine, params));
124-
List<Object> transfersReturnJS = V8ObjectUtils.toList(ret);
129+
return V8Converter.transferListFromV8Array(ret);
130+
}
125131

126-
ArrayList<Transaction> returnTransfers = new ArrayList<>();
127132

128-
for (Object b: transfersReturnJS) {
129-
Map<String, ? super Object> values = (Map<String, ? super Object>) b;
130-
String obsoleteTag = (String) values.get("obsoleteTag");
131-
String address = (String) values.get("address");
132-
Integer value = (Integer) values.get("value");
133+
/**
134+
*
135+
* @param settlementAddresses
136+
* @param deposits
137+
* @return
138+
*/
139+
public static ArrayList<Transfer> close(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits) {
140+
V8Array saJS = V8ObjectUtils.toV8Array(engine, settlementAddresses);
141+
// Deposits
142+
V8Array depositsJS = V8ObjectUtils.toV8Array(engine, deposits);
133143

134-
returnTransfers.add(new Transaction(address, value, "", "", 0));
135-
}
144+
// Add to prams
145+
ArrayList<Object> paramsObj = new ArrayList<Object>();
136146

137-
// Call js.
138-
return returnTransfers;
147+
paramsObj.add(saJS);
148+
paramsObj.add(depositsJS);
149+
V8Array res = transfer.executeArrayFunction("close", V8ObjectUtils.toV8Array(engine, paramsObj));
150+
return V8Converter.transferListFromV8Array(res);
139151
}
140152

141153
/**
@@ -146,7 +158,7 @@ public static ArrayList<Transaction> prepare(ArrayList<String> settlementAddress
146158
* @param root
147159
* @param remainderAddress
148160
* @param history
149-
* @param transactions
161+
* @param transfers
150162
* @param close
151163
* @return
152164
*/
@@ -156,7 +168,7 @@ public static ArrayList<Bundle> compose(int balance,
156168
MultisigAddress root,
157169
MultisigAddress remainderAddress,
158170
ArrayList<Bundle> history,
159-
ArrayList<Transaction> transactions,
171+
ArrayList<Transfer> transfers,
160172
boolean close) {
161173

162174

@@ -170,11 +182,10 @@ public static ArrayList<Bundle> compose(int balance,
170182
params.add(V8Converter.multisigToV8Object(engine, root));
171183
params.add(V8Converter.multisigToV8Object(engine, remainderAddress));
172184
params.add(V8Converter.bundleListToV8Array(engine, history));
173-
params.add(V8Converter.transactionListToV8Array(engine, transactions));
185+
params.add(V8Converter.transferListToV8Array(engine, transfers));
174186

175187
// Call js function.
176188
V8Array ret = transfer.executeArrayFunction("compose", V8ObjectUtils.toV8Array(engine, params));
177-
List<Object> transfersReturnJS = V8ObjectUtils.toList(ret);
178189

179190
return V8Converter.bundleListFromV8Array(ret);
180191
}
@@ -193,8 +204,9 @@ public static ArrayList<Signature> sign(MultisigAddress root, String seed, Array
193204
List<Object> params = new ArrayList<>();
194205
params.add(V8Converter.multisigToV8Object(engine, root));
195206
params.add(seed);
196-
params.add(V8Converter.bundleListToV8Array(engine, bundles));
197207

208+
// Create bundle nested list by incoding all bundles
209+
params.add(V8Converter.bundleListToV8Array(engine, bundles));
198210
V8Array returnArray = transfer.executeArrayFunction("sign", V8ObjectUtils.toV8Array(engine, params));
199211

200212
return V8Converter.v8ArrayToSignatureList(returnArray);
@@ -256,26 +268,6 @@ public static void applayTransfers(MultisigAddress root,
256268
transfer.executeFunction("applyTransfers", V8ObjectUtils.toV8Array(engine, params));
257269
}
258270

259-
/**
260-
*
261-
* @param settlementAddresses
262-
* @param deposits
263-
* @return
264-
*/
265-
public static Object close(ArrayList<String> settlementAddresses, ArrayList<Integer> deposits) {
266-
V8Array saJS = V8ObjectUtils.toV8Array(engine, settlementAddresses);
267-
// Deposits
268-
V8Array depositsJS = V8ObjectUtils.toV8Array(engine, deposits);
269-
270-
// Add to prams
271-
ArrayList<Object> paramsObj = new ArrayList<Object>();
272-
273-
paramsObj.add(saJS);
274-
paramsObj.add(depositsJS);
275-
V8Object res = transfer.executeObjectFunction("close", V8ObjectUtils.toV8Array(engine, paramsObj));
276-
return res;
277-
}
278-
279271
/// Utils
280272

281273
/**

src/main/java/Main.java

+59-6
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public static void main(String[] argv) throws Exception {
7272

7373
// Build flash trees
7474
for (int i = 1; i < oneMultisigs.size(); i++) {
75-
System.out.println("Adding child (" + oneMultisigs.get(i).toString() + ") to root :" + oneMultisigs.get(i - 1).toString() );
75+
System.out.println(oneMultisigs.get(i - 1).toString() + " -> " + oneMultisigs.get(i).toString());
7676
oneMultisigs.get(i - 1).push(oneMultisigs.get(i));
7777
}
7878

@@ -100,13 +100,12 @@ public static void main(String[] argv) throws Exception {
100100
ArrayList<Transfer> transfers = new ArrayList<>();
101101
transfers.add(new Transfer(twoSettlement, 200));
102102

103-
System.out.println("Creating a transaction");
103+
System.out.println(oneFlash);
104+
105+
System.out.println("Creating a transaction: 200 to " + twoSettlement);
104106
ArrayList<Bundle> bundles = Helpers.createTransaction(oneFlash, transfers, false);
105107

106-
System.out.println("createTransaction completed");
107-
for (Bundle b: bundles) {
108-
System.out.println(b.toString());
109-
}
108+
System.out.println("[SUCCESS] createTransaction completed");
110109

111110
// Sign the bundles.
112111
// Get signatures for the bundles
@@ -115,12 +114,20 @@ public static void main(String[] argv) throws Exception {
115114
// Generate USER TWO'S Singatures
116115
ArrayList<Signature> twoSignatures = Helpers.signTransaction(twoFlash, bundles);
117116

117+
System.out.println("[SUCCESS] Created signatures for users.");
118+
118119
// Sign bundle with your USER ONE'S signatures
119120
ArrayList<Bundle> signedBundles = IotaFlashBridge.appliedSignatures(bundles, oneSignatures);
120121

122+
System.out.println("[SUCCESS] Parial applied Signature for User one on transfer bundle");
123+
124+
121125
// ADD USER TWOS'S signatures to the partially signed bundles
122126
signedBundles = IotaFlashBridge.appliedSignatures(signedBundles, twoSignatures);
123127

128+
System.out.println("[SUCCESS] Signed bundle bu second user. Bundle ready.");
129+
130+
124131
/////////////////////////////////
125132
/// APPLY SIGNED BUNDLES
126133

@@ -134,9 +141,55 @@ public static void main(String[] argv) throws Exception {
134141
Helpers.applyTransfers(twoFlash, signedBundles);
135142
// Save latest channel bundles
136143
twoFlash.setBundles(signedBundles);
144+
System.out.println("[SUCCESS] Apply Transfer to flash channel.");
145+
137146

138147
System.out.println("Transaction Applied!");
148+
System.out.println(
149+
"Transactable tokens: " +
150+
oneFlash.getFlash().getDeposits().stream().mapToInt(v -> v.intValue()).sum()
151+
);
152+
153+
System.out.println("Closing channel... not yet working...");
154+
/*
155+
156+
// Supplying the CORRECT varibles to create a closing bundle
157+
bundles = Helpers.createTransaction(
158+
oneFlash,
159+
oneFlash.getFlash().getSettlementAddresses(),
160+
true
161+
);
162+
163+
/////////////////////////////////
164+
/// SIGN BUNDLES
165+
166+
// Get signatures for the bundles
167+
oneSignatures = Helpers.signTransaction(oneFlash, bundles)
168+
169+
// Generate USER TWO'S Singatures
170+
twoSignatures = Helpers.signTransaction(twoFlash, bundles)
171+
172+
// Sign bundle with your USER ONE'S signatures
173+
signedBundles = transfer.appliedSignatures(bundles, oneSignatures)
174+
175+
// ADD USER TWOS'S signatures to the partially signed bundles
176+
signedBundles = transfer.appliedSignatures(signedBundles, twoSignatures)
177+
178+
/////////////////////////////////
179+
/// APPLY SIGNED BUNDLES
180+
181+
// Apply transfers to User ONE
182+
oneFlash = Helpers.applyTransfers(oneFlash, signedBundles)
183+
// Save latest channel bundles
184+
oneFlash.bundles = signedBundles
185+
186+
// Apply transfers to User TWO
187+
twoFlash = Helpers.applyTransfers(twoFlash, signedBundles)
188+
// Save latest channel bundles
189+
twoFlash.bundles = signedBundles
139190
191+
console.log("Channel Closed")
192+
console.log("Final Bundle to be attached: ")*/
140193
}
141194

142195
private static void setupUser(UserObject user, int TREE_DEPTH) {

0 commit comments

Comments
 (0)