-
Notifications
You must be signed in to change notification settings - Fork 0
/
303_atomic_swap.html
379 lines (311 loc) · 12.8 KB
/
303_atomic_swap.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous">
</head>
<div class="container">
<h1>3.5 サンプルプログラム応用編</h1>
<h3>アトミックスワップ</h3>
<!-- div block1 -->
<h3>deposit to</h3>
<div id="address"></div>
<div class="collapse" id="result1">
<button id="button1" class="btn btn-primary" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
承認中...
</button>
</div>
<!-- div block2 -->
<div class="collapse" id="result2">
<h3>signedLockTx on PublicChain</h3><textarea id="signedTx" rows="8" class="form-control"></textarea>
<h3>status</h3><div id="status"><ul></ul></div>
<div id="wait2" class="spinner-border text-primary" role="status">
<span class="sr-only">承認中...</span>
</div>
</div>
<!-- div block3 -->
<div class="collapse" id="result3">
<h3>confirmed</h3><div id="confirmed"><ul></ul></div>
<button id="button3" class="btn btn-primary" type="button" >BobのPrivate資産をロック</button>
</div>
<!-- div block4 -->
<div class="collapse" id="result4">
<h3>signedLockTx on PrivateChain</h3><textarea id="signedTx4" rows="8" class="form-control"></textarea>
<h3>status</h3><div id="status4"><ul></ul></div>
<div id="wait4" class="spinner-border text-primary" role="status">
<span class="sr-only">承認中...</span>
</div>
</div>
<!-- div block5 -->
<div class="collapse" id="result5">
<h3>signedProofTx on PrivateChain</h3>BobのPrivate資産をAliceが取得<textarea id="signedTx5_0" rows="8" class="form-control"></textarea>
<h3>status</h3><div id="status5_0"><ul></ul></div>
<h3>confirmed</h3><div id="confirmed5"><ul></ul></div>
<button id="button5" class="btn btn-primary" type="button" >AliceのPublic資産をBobが取得</button>
</div>
<!-- div block6 -->
<div class="collapse" id="result6">
<h3>signedProofTx on PublicChain</h3><textarea id="signedTx6" rows="8" class="form-control"></textarea>
<h3>status</h3><div id="status6"><ul></ul></div>
<div id="wait6" class="spinner-border text-primary" role="status">
<span class="sr-only">承認中...</span>
</div>
</div>
<!-- div block7 -->
<div class="collapse" id="result7">
<h3>confirmed</h3><div id="confirmed7"><ul></ul></div>
<h3>account</h3><div id="account7"><ul></ul></div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous">
</script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous">
</script>
<script src="nem2-sdk-0.14.1.js"></script>
<script>$(function() {
const nem = require("/node_modules/nem2-sdk");
const rxjs = require("/node_modules/rxjs/operators");
const sha3_256 = require("/node_modules/js-sha3").sha3_256;
const alicePublic = nem.Account.generateNewAccount(nem.NetworkType.MIJIN_TEST);
const alicePrivate = nem.Account.generateNewAccount(nem.NetworkType.MIJIN_TEST);
const bobPrivate = nem.Account.createFromPrivateKey('BB68B933E188D9800A987E3DB055E9C4C05BDE53915308BF62910005A797A94D', nem.NetworkType.MIJIN_TEST);
const bobPublic = nem.Account.generateNewAccount(nem.NetworkType.MIJIN_TEST); //空
$('#address').text(alicePublic.address.address);
const NODE_PUBLIC = "https://jp5.nemesis.land:3001/";
const GEN_HASH_PUBLIC = "17FA4747F5014B50413CCF968749604D728D7065DC504291EEE556899A534CBB";
const txHttpPublic = new nem.TransactionHttp(NODE_PUBLIC);
const accountHttpPublic = new nem.AccountHttp(NODE_PUBLIC);
const NODE_PRIVATE = "http://fushicho.48gh23s.xyz:3000";
const GEN_HASH_PRIVATE = "9A7949B3ED05DE9C771B8BEB16226E1CEBCA4C50428F27445796C8B4D9B0A9D6";
const txHttpPrivate = new nem.TransactionHttp(NODE_PRIVATE);
const accountHttpPrivate = new nem.AccountHttp(NODE_PRIVATE);
const random = nem.Crypto.randomBytes(10);
const proof = random.toString('hex');
const hash = sha3_256.create();
const aliceSecret = hash.update(random).hex().toUpperCase();
console.log(aliceSecret);
const wsEndpointPublic = NODE_PUBLIC.replace('https', 'wss');
const wsEndpointPrivate = NODE_PRIVATE.replace('http', 'ws');
const listenerPublic = new nem.Listener(wsEndpointPublic, WebSocket);
const listenerPrivate = new nem.Listener(wsEndpointPrivate, WebSocket);
var isInit = true;
listenerPublic.open().then(() => {
listenerPublic
.unconfirmedAdded(alicePublic.address)
.subscribe(_=> $('#result1').collapse('show'),err => console.error(err));
listenerPublic
.confirmed(alicePublic.address)
.subscribe(
function(_){
if(isInit){
$('#button1').prop("disabled", false);
$('#button1').empty();
$('#button1').text("AliceのPublic資産をロック");
isInit = false;
}
},
err => console.error(err)
);
});
listenerPrivate.open().then(() => {
});
function process(){
//TX1 public alice->Lock(bob)
const lockTxPublic = nem.SecretLockTransaction.create(
nem.Deadline.create(),
new nem.Mosaic(
new nem.MosaicId('308F144790CD7BC4'),
nem.UInt64.fromUint(10000000)
),
nem.UInt64.fromUint(96 * 3600 / 15),
nem.HashType.Op_Sha3_256,
aliceSecret,
bobPublic.address,
nem.NetworkType.MIJIN_TEST,
nem.UInt64.fromUint(100000)
);
const lockTxPublicSigned = alicePublic.sign(lockTxPublic, GEN_HASH_PUBLIC);
showInfo(NODE_PUBLIC,lockTxPublicSigned,alicePublic);
txHttpPublic
.announce(lockTxPublicSigned)
.subscribe(x => {
console.log(x);
}, err => console.error(err));
//TX2 private bob->Lock(alice) by alice's secret
listenerPublic
.unconfirmedAdded(alicePublic.address)
.subscribe(x => {
console.log(x);
$('#wait2').remove();
$('#result3').collapse('show');
}, err => console.error(err));
}
function process3(){
accountHttpPublic.unconfirmedTransactions(alicePublic.address)
.pipe(
rxjs.mergeMap(_ => {
console.log(_);
return _;
}),
rxjs.filter((tx) => {
console.log(tx);
return tx.transactionInfo !== undefined && tx.type === nem.TransactionType.SECRET_LOCK
}),
rxjs.map(_ => {
console.log(_);
const lockTxPrivate = nem.SecretLockTransaction.create(
nem.Deadline.create(),
new nem.Mosaic(
new nem.MosaicId('308F144790CD7BC4'),
nem.UInt64.fromUint(10000000)
),
nem.UInt64.fromUint(84 * 3600 / 15),
nem.HashType.Op_Sha3_256,
_.secret,
alicePrivate.address,
nem.NetworkType.MIJIN_TEST,
nem.UInt64.fromUint(100000)
);
console.log(lockTxPrivate);
const lockTxPrivateSigned = bobPrivate.sign(lockTxPrivate, GEN_HASH_PRIVATE);
const hash4 = lockTxPrivateSigned.transactionInfo.hash;
$('#signedTx4').val(lockTxPrivateSigned.signature);
$('#status4 ul').append(strLi(NODE_PRIVATE,'/transaction/' + hash4 + '/status' ,hash4 + '/status'));
$('#confirmed5 ul').append(strLi(NODE_PRIVATE,'/transaction/' + hash4 ,hash4 ));
return txHttpPrivate
.announce(lockTxPrivateSigned)
})
)
.subscribe(x => {
console.log(x);
//TX3:private Lock(bob)->alice using proof
listenerPrivate
.confirmed(bobPrivate.address)
.pipe(
rxjs.filter((tx) => tx.transactionInfo !== undefined && tx.type === nem.TransactionType.SECRET_LOCK ),
rxjs.mergeMap(_ => {
const aliceProof = random.toString('hex');
//private (Lock)Bob->Alice 作ったaliceProofで取り出す
const proofTxPrivate = nem.SecretProofTransaction.create(
nem.Deadline.create(),
nem.HashType.Op_Sha3_256,
aliceSecret,
alicePrivate.address,
aliceProof,
nem.NetworkType.MIJIN_TEST
);
console.log(proofTxPrivate);
const proofTxPrivateSigned = alicePrivate.sign(proofTxPrivate, GEN_HASH_PRIVATE);
const hashx = proofTxPrivateSigned.hash;
$('#signedTx5_0').val(proofTxPrivateSigned.payload);
$('#status5_0 ul').append(strLi(NODE_PRIVATE,'/transaction/' + hashx + '/status' ,hashx + '/status'));
// $('#confirmed5 ul').append(strLi(NODE_PRIVATE,'/transaction/' + hashx ,hashx ));
return txHttpPrivate.announce(proofTxPrivateSigned);
})
)
.subscribe(
function(_){
$('#wait4').remove();
$('#result5').collapse('show');
},
err => console.error(err)
);
}, err => console.error(err));
}
function process5(){
//TX4:public Lock(alice)->bob by alice's proof
accountHttpPrivate.unconfirmedTransactions(alicePrivate.publicAccount)
.pipe(
rxjs.mergeMap(_ => _),
rxjs.filter(tx => {
console.log(tx);
return tx.transactionInfo !== undefined && tx.type === nem.TransactionType.SECRET_PROOF;
}),
rxjs.mergeMap(_ => {
const proofTxPublic = nem.SecretProofTransaction.create(
nem.Deadline.create(),
nem.HashType.Op_Sha3_256,
_.secret,
bobPublic.address,
_.proof,
nem.NetworkType.MIJIN_TEST
);
console.log(proofTxPublic);
const proofTxPublicSigned = bobPublic.sign(proofTxPublic, GEN_HASH_PUBLIC);
const hash6 = proofTxPublicSigned.hash;
$('#signedTx6').val(proofTxPublicSigned.payload);
$('#status6 ul').append(strLi(NODE_PUBLIC,'/transaction/' + hash6 + '/status' ,hash6 + '/status'));
$('#confirmed7 ul').append(strLi(NODE_PUBLIC,'/transaction/' + hash6 ,hash6 ));
$('#account7 ul').append(strLi(NODE_PUBLIC,'/account/' + alicePublic.publicKey ,'/public/alice' ));
$('#account7 ul').append(strLi(NODE_PUBLIC,'/account/' + bobPublic.publicKey ,'/public/bob' ));
$('#account7 ul').append(strLi(NODE_PRIVATE,'/account/' + alicePrivate.publicKey ,'/private/alice' ));
$('#account7 ul').append(strLi(NODE_PRIVATE,'/account/' + bobPrivate.publicKey ,'/private/bob' ));
return txHttpPublic.announce(proofTxPublicSigned)
})
)
.subscribe(
function(_){
console.log("--confirmed transaction(alice private)--");
console.log(_);
},
err => console.error(err)
);
listenerPublic
.confirmed(bobPublic.address)
.pipe(
rxjs.filter((tx) => tx.transactionInfo !== undefined && tx.type === nem.TransactionType.SECRET_PROOF ),
)
.subscribe(
function(_){
$('#wait6').remove();
$('#result7').collapse('show');
},
err => console.error(err)
);
}
function showInfo(node,signedTx,account){
const pubkey = account.publicKey ;
const address = account.address.address ;
const hash = signedTx.hash;
$('#signedTx').val(signedTx.payload);
$('#status ul').append(strLi(node,'/transaction/' + hash + '/status' ,hash + '/status'));
$('#confirmed ul').append(strLi(node,'/transaction/' + hash ,hash ));
}
function strLi(node,href,text){
return '<li><a target="_blank" href="' + node + href + '">' + text + '</a></li>';
}
$("#button1").click(
function(){
process();
$('#result2').collapse('show');
return false;
}
);
$("#button3").click(
function(){
process3();
$('#result4').collapse('show');
return false;
}
);
$("#button5").click(
function(){
process5();
$('#result6').collapse('show');
return false;
}
);
});</script>
</body>
</html>