-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
369 lines (319 loc) · 18.8 KB
/
index.html
File metadata and controls
369 lines (319 loc) · 18.8 KB
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
<!DOCTYPE html>
<html lang="en" ng-app="annsol">
<head>
<meta charset="UTF-8">
<title>Ann.sol - A cryptographic announcement framework</title>
<script src="/js/1_config.js" type="application/javascript"></script>
<script src="/js/ramda.min.js" type="application/javascript"></script>
<script src="/js/moment.min.js" type="application/javascript"></script>
<script src="/js/bundle.js" type="application/javascript"></script>
<script src="/js/web3.min.js" type="application/javascript"></script>
<script src="/js/ann-sol.js" type="application/javascript"></script>
<script src="/js/ensutils-testnet.js" type="application/javascript"></script>
<script src="/js/ensutils.js" type="application/javascript"></script>
<script src="/js/angular.min.js" type="application/javascript"></script>
<script src="/js/ann-sol-ng.js" type="application/javascript"></script>
<link href="css/basscss.min.css" rel="stylesheet">
<link href="css/ann-sol.css" rel="stylesheet">
<base href="/">
</head>
<body ng-controller="AnnSolController as annsol">
<div class="flex flex-column" style="min-height:100vh">
<header class="fixed top-0 z3 bg-silver border-bottom" style="width: 100vw" id="header">
<div class="flex flex-justify flex-start flex-stretch">
<div class="flex">
<h2 class="m2">Ann.sol - Cryptographically Secure Announcements</h2>
</div>
<div class="ml2 right-align mt2 flex-auto">
<div ng-show="showLogs" class="rounded p2 bg-white border overflow-scroll fixed dib" style="max-height: 30vh; left: 15rem">
<span ng-show="annsol.logs.length === 0">No logs yet.</span>
<ul ng-show="annsol.logs.length > 0">
<li class="h6" ng-repeat="logItem in annsol.logs track by $index">{{logItem}}</li>
</ul>
</div>
</div>
<div class="flex">
<button class="btn btn-primary m2" ng-click="showLogs = !showLogs">Show/Hide Logs</button>
</div>
<div class="flex">
<a class="btn btn-outline m2" href="https://github.com/exo-one/ann-sol.com" target="_blank">Source
Code</a>
</div>
<div class="flex">
<button class="btn btn-outline m2" ng-click="annsol.swapTestnet()">
<span ng-show="annsol.testnet">Ropsten</span>
<span ng-show="!annsol.testnet">Mainnet</span>
</button>
</div>
<div class="border-left px2 flex"
ng-if="annsol.awaitingTxs.size > 0"
style="min-height: 4.5rem">
<div class="">
<div class="block mx-auto">{{annsol.awaitingTxs.size}} Txs...</div>
<div class="loader mx-auto block"></div>
</div>
</div>
</div>
<div class="bg-red flex-auto" ng-show="annsol.error">
<div class="h2 border-right p1 inline-block" ng-click="annsol.error = ''" style="cursor: pointer;">×
</div>
<div class="p1 bg-red white inline-block">
(Error) {{annsol.error}}
</div>
</div>
</header>
<main class="container flex-auto mx-auto" style="max-width: 1100px; margin-top: 5rem;">
<div class="clearfix flex flex-center">
<div class="">
<expandable title="What is Ann.sol?" small="true" hide="true">
<p>
Ann.sol is a full solution for distributing announcements cryptographically. It allows
maintainers
of token sales and DAOs to securely issue updates via a centralised, accessibly source.
</p>
<p>
Ann.sol only allows updates to be published after they've been audited by other parties. This
ensures token sale contract addresses will never be replaced.
</p>
<p>
Ideally the announcer will have an ENS domain ready to go. Ideally they'd point the domain (or a
subdomain,
e.g.
ann.cooltoken.eth) to their announcement contract.
</p>
<p>
The announcement contract accepts an IPFS hash (or arbitrary string, really) from the announcer
(which
is
the owner).
Before that announcement goes live, though, it must be approved by some of the auditors.
</p>
<p>
The auditors are set at the time of the contract creation and there is some minimum number
required
to
release an announcement.
The owner might set herself as the auditor (or some other accounts they control) - this is a Bad
Idea
(tm) in most cases. An exception might be at least 2 of 3 auditors required, where 1 auditor is
an offline key held by the announcer, and 2 auditors are well known community members.
Ideally
the auditors are reasonably well known figures in the community and their role is to verify
announcements
are legitimate
before they are published. Users should therefore be suspicious if the auditors are not publicly
declared
and confirmed.
The verification process for the announcement can be done however they choose,
such as over video chat, though they
may
also
choose
a more rigorous process. The idea is that this step, even if conducted in a very low effort
manner,
will
prevent
99% of bad announcements getting through. (And, of course, it doesn't necessarily prevent the $5
wrench
attack, but
that's a topic for another day). Crucially, this is dependent on <i>people and meaning</i>, not
just
cryptography or
the security of a web server.
</p>
<p>
Additionally, the auditors may choose to sound an alarm instead of giving the okay for any
announcement.
There is also
a threshold for the number of alarms that must be triggered before an announcement is
blacklisted.
</p>
<p>
If the announcement is an IPFS hash then the contents will be shown in the browser, otherwise
the
raw
string
will be shown.
</p>
<p>
Additionally, all config URLs are stored in js/1_config.js. If you download the repository and
replace
the
URLs with
local nodes you can use this site locally.
</p>
<p>
Finally: <strong>If you use a node with unlocked accounts this page will allow you to publish
new announcements or audit announcements provided the account has the right
permissions.</strong>
</p>
<h3>Open Source Stuff</h3>
Please see the /vendor folder for licenses.<br><br>
Web3 is distributed under LGPL-3<br>
js-ipfs-api is distributed under MIT<br>
angularjs is distributed under MIT<br>
ensutils is distributed under CC0-1.0<br>
ramda is distributed under MIT<br>
basscss is distributed under MIT<br>
moment.js is distributed under MIT<br>
</expandable>
<expandable title="Announcement ENS Domain / Address" hide="annsol.showDomainSetter">
<p>
Enter an ENS domain (or a raw address) here supporting the Ann.sol interface to begin:
</p>
<form ng-submit="annsol.showDomainSetter = !annsol.showDomainSetter; annsol.checkEnsDomain();">
<input class="field" ng-model="annsol.domain" type="text"
placeholder="Enter an ENS domain or contract address" size="50">
<button class="btn btn-primary">Go!</button>
</form>
<ul>
<li>Examples:</li>
<li>ann-sol.eth (announcements for Ann.sol, Mainnet)</li>
<li>0xbf74cC2839b4B639062E37b6Ea53F3ed7964132c (ann-sol.eth address, Mainnet)</li>
<li>testann.test (Ropsten)</li>
<li>0x88505b6BCe01ad9efA39AF57d3466739b3b04A12 (Ropsten)</li>
<li>0xFDB130F24Cd1A5A6dF0010fff3C385E2Eb710f10 (Ropsten)</li>
<li>0xbf74cC2839b4B639062E37b6Ea53F3ed7964132c (Mainnet)</li>
</ul>
</expandable>
<h2 ng-show="annsol.showLoading">Loading...</h2>
<div ng-show="annsol.showResults">
<expandable title="Announcements ({{annsol.getNMsgs()}})" title-bg-class="bg-green">
<expandable
ng-repeat="annObj in annsol.getRenderedMsgs() track by $index"
title="Date: {{annsol.renderTs(annObj.ts)}}"
small="true"
title-bg-class="bg-olive"
hide="$first ? false : true"
>
<h4>Content</h4>
<pre class="border p1 m1 rounded">{{annObj.msg}}</pre>
<span ng-if="annObj.isIpfs">Hosted via IPFS ({{annObj.rawMsg}})</span>
<span ng-if="!annObj.isIpfs">Raw String in Blockchain</span>
</expandable>
<h4 ng-show="annsol.getNMsgs === 0">No announcements.</h4>
</expandable>
<expandable title="Pending Announcements ({{annsol.getNPending()}})" hide="true"
ng-show="annsol.getNPending() > 0">
<expandable
ng-repeat="annObj in annsol.getPendingMsgs() track by $index"
title="Date: {{annsol.renderTs(annObj.timestamp)}}, Audits: {{annObj.nAudits}}, Alarms: {{annObj.nAlarms}}"
small="true"
title-bg-class="bg-navy"
hide="$first ? false : true"
>
<h4>Content</h4>
<pre class="border p1 m1 rounded">{{annObj.msg}}</pre>
</expandable>
<h4 ng-show="annsol.getNPending() === 0">No pending announcements.</h4>
</expandable>
<expandable title="Alarms (Flagged Announcements) ({{annsol.getNAlarms()}})" title-bg-class="bg-red"
hide="true"
ng-show="annsol.getNAlarms() > 0">
<expandable
ng-repeat="annObj in annsol.getAlarmedMsgs() track by $index"
title="Date: {{annsol.renderTs(annObj.timestamp)}}, Audits: {{annObj.nAudits}}, Alarms: {{annObj.nAlarms}}"
small="true"
title-bg-class="bg-maroon"
hide="$first ? false : true"
>
<h4>Content</h4>
<pre class="border p1 m1 rounded">{{annObj.msg}}</pre>
</expandable>
<h4 ng-show="annsol.getNPending() === 0">No pending announcements.</h4>
</expandable>
<expandable title="Contract Details">
<h4>Address: {{annsol.address}}</h4>
<h5>Total Announcements: {{annsol.nMsg}}</h5>
<h5>Pending Announcements: {{ annsol.getNPending() }}</h5>
<h5>Alarmed Announcements: {{ annsol.getNAlarms() }}</h5>
<h5>Owner: {{annsol.owner}}</h5>
<h5>Auditors: {{ annsol.auditors.join(', ') }}</h5>
</expandable>
<div ng-show="annsol.accounts.length > 0">
<expandable title="Contract Functions">
<form>
<label for="annsolFrom">From:</label>
<select id="annsolFrom" ng-model="annsol.fromAddr">
<option ng-repeat="addr in annsol.accounts track by $index" value="{{addr}}">
{{annsol.renderAddr(addr)}}
</option>
</select>
<div class="border m2 p2">
<div ng-show="annsol.isOwner(annsol.fromAddr)">
<h4>Create Announcement</h4>
<label for="newAnnString">Content (IPFS MH)</label>
<input class="field" id="newAnnString" size="50" type="text"
ng-model="annsol.newAnnString">
<button class="btn btn-primary" ng-click="annsol.sendNewAnn()">Sign and send
(via
Eth
node)
</button>
</div>
<div ng-show="annsol.isAuditor(annsol.fromAddr)">
<h4>Audit Announcement</h4>
<label for="nMsgWaitingI">nMsgWaiting ({{annsol.getNPending()}})</label>
<select id="nMsgWaitingI" ng-model="annsol.auditNMsgWaiting">
<option ng-repeat="(i, obj) in annsol.msgWaitingMap"
value="{{i}}">
{{obj.timestamp}} - {{obj.msg}}
</option>
</select>
<button class="btn btn-primary m1 block" ng-click="annsol.sendAuditGood()">
Confirm good announcement
</button>
<button class="btn btn-outline bg-red white m1"
ng-click="annsol.sendAuditBad()">
Bad Audit! Sound the Alarm!
</button>
</div>
<div ng-show="false">
<h4>Create new Ann.sol contract.</h4>
<p>
This will create a new Ann.sol instance owned by {{annsol.fromAddr}}.
Please put ALL auditor addresses in below, separated by commas.
</p>
<label for="auditorsInput">Auditors:</label>
<input id="auditorsInput" placeholder="e.g. 0x123...456,0xabc...def"
ng-model="annsol.newAnnSol.auditors">
<label for="nAuditorsI">nAudits required:</label>
<input id="nAuditorsI" type="number" value="2"
ng-model="annsol.newAnnSol.nAudits">
<label for="nAlarmsI">nAlarms required:</label>
<input id="nAlarmsI" type="number" value="2"
ng-model="annsol.newAnnSol.nAlarms">
<button class="btn btn-primary" ng-click="annsol.createNewInstance()">Create New
Ann.sol Instance
</button>
</div>
</div>
</form>
</expandable>
</div>
</div>
<expandable title="Config" hide="true">
<h4 class="p0 mt2">Web3 URL:</h4>
<form ng-submit="annsol.updateWeb3()">
<input class="field" type="text" size="50" ng-model="annsol.web3URL"><br>
<button class="btn btn-primary" type="submit">Update</button>
<button class="btn btn-outline" type="button" ng-click="annsol.setLocalhostWeb3()">Set Localhost
</button>
</form>
<hr class="p2">
<h4 class="p0 mt2">IPFS URL:</h4>
<form ng-submit="annsol.updateIpfs()">
<input class="field" type="text" size="30" ng-model="annsol.ipfsURL.host"><br>
<input class="field" type="text" size="10" ng-model="annsol.ipfsURL.port"><br>
<input class="field" type="text" size="10" ng-model="annsol.ipfsURL.protocol"><br>
<button class="btn btn-primary" type="submit">Update</button>
<button class="btn btn-outline" type="button" ng-click="annsol.setLocalhostIpfs()">Set Localhost
</button>
</form>
</expandable>
</div>
</div>
</main>
</div>
</body>
</html>