-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathDexNS_Frontend.sol
432 lines (396 loc) · 14.3 KB
/
DexNS_Frontend.sol
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
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
pragma solidity ^0.4.15;
import './DexNS_Storage.sol';
import './safeMath.sol';
/*
* The following is an implementation of the Naming Service that aims to boost
* the usability of smart-contracts and provide a human-friendly utility
* to work with low-level smart-contract interactions.
*
* In addition it can be used as a central controlling unit of the system
* with dynamically linked smart-contracts.
*
* Current implementation aims to simplify searches by contract names
* and automated loading of ABIs for smart-contracts.
* This can be used to provide an automated token adding
* to the web wallet interfaces like ClassicEtherWallet as well.
*
* Designed by Dexaran, [email protected]
*
*/
contract NameReceiver {
function onNameOwnerChanged(string _name, address _sender, bytes _data);
}
contract DexNS_Abstract_Interface {
function name(string) constant returns (bytes32);
function getName(string) constant returns (address _owner, address _associated, string _value, uint _end, bytes32 _sig);
function ownerOf(string) constant returns (address);
function addressOf(string) constant returns (address);
function valueOf(string) constant returns (string);
function endtimeOf(string) constant returns (uint);
function updateName(string, string);
function updateName(string, address);
function updateName(string, address, string);
function registerName(string) payable returns (bool);
function registerAndUpdateName(string, address, address, string, bool, bool) payable returns (bool);
function changeNameOwner(string, address, bytes);
function hideNameOwner(string);
function extendNameBindingTime(string) payable;
function appendNameMetadata(string, string);
}
/** contract Test
* {
* address constant_name_service;
* function() payable
* {
* DexNS_Storage dexns = DexNS_Storage(constant_name_service);
* dexns.addressOf("Recipient name").send(msg.value);
* }
*}
*/
/**
* @title Frontend DexNS contract.
* @dev The frontend contract is executed when a user wants to register new Name or adjust any parameter
* of the already existing Name.
*/
contract DexNS_Frontend
{
using SafeMath for uint256;
event Error(bytes32);
event NamePriceChanged(uint indexed _price);
event OwningTimeChanged(uint indexed _period);
event DebugDisabled();
event NameRegistered(string _name, address indexed _owner);
event NameUpdated(bytes32 indexed _signature);
event NameTransferred(address indexed _sender, address indexed _receiver, bytes32 indexed _signature, bytes _data);
event Assignment(address indexed _owner, string _name);
event Unassignment(string _name);
DexNS_Storage public db;
modifier only_owner
{
if ( msg.sender != db.ownerOf(DexNS_owner) )
revert();
_;
}
modifier only_name_owner(string _name)
{
if ( msg.sender != db.ownerOf(_name) )
revert();
_;
}
modifier only_debug
{
if ( !debug )
revert();
_;
}
bool public debug = true;
uint public owningTime = 31536000; //1 year in seconds
uint public namePrice = 0;
string public constant DexNS_owner = "DexNS owner";
mapping (bytes32 => uint256) public expirations;
/**
* @dev Constructor
*/
function DexNS_Frontend()
{
db = DexNS_Storage(0x28fc417c046d409c14456cec0fc6f9cde46cc9f3);
bytes32 _sig = sha256(DexNS_owner);
expirations[_sig] = 2524608000; // 01/01/2050 @ 12:00am (UTC)
}
/**
* @dev Returns keccak-256 hash of the Name.
*
* @return hash The hash of the name.
*/
function name(string _name) constant returns (bytes32 hash)
{
return bytes32(sha256(_name));
}
/**
* @dev Registers a new name with predefined content.
*
* This function will return `true` in case of successful execution. It will revert() The
* transaction in case of failure and thus send back money.
*
* @param _name The name that the user wants to register.
* @param _owner Address that will become the owner of the Name after the registration.
* @param _destination The address to which this name will be indicated.
* @param _metadata Metadata of the Name.
* @param _hideOwner If true, then DexNS will throw on any attempt to access the name owner.
* @param _assign Assign Name to the _destination address after registration.
*
* @return ok True on successful Name registration, false in any other cases.
*/
function registerAndUpdateName(string _name, address _owner, address _destination, string _metadata, bool _hideOwner, bool _assign) payable returns (bool ok)
{
if(!(msg.value < namePrice))
{
bytes32 _sig = sha256(_name);
if(expirations[_sig] < now)
{
db.registerAndUpdateName(_name, _owner, _destination, _metadata, _hideOwner);
if(_assign)
{
db.assignName(_name, _destination);
}
expirations[_sig] = now.add(owningTime);
if (db.addressOf(DexNS_owner).send(namePrice))
{
if(msg.value.sub(namePrice) > 0)
{
msg.sender.transfer(msg.value.sub(namePrice));
}
NameRegistered(_name, _owner);
return true;
}
}
}
revert();
}
/**
* @dev Registers a new name with default content.
*
* @param _name The name that the user wants to register.
*
* @return ok True on successful Name registration, false in any other cases.
*/
function registerName(string _name) payable returns (bool ok)
{
if(!(msg.value < namePrice))
{
bytes32 _sig = sha256(_name);
if(expirations[_sig] < now)
{
db.registerName(msg.sender, _name);
expirations[_sig] = now.add(owningTime);
if (db.addressOf(DexNS_owner).send(namePrice))
{
if(msg.value.sub(namePrice ) > 0)
{
msg.sender.transfer(msg.value.sub(namePrice));
}
NameRegistered(_name, msg.sender);
return true;
}
}
}
revert();
}
/**
* @dev Returns the time when the ownership of the name expires (in Unix seconds).
*
* @param _name Name the validity of which we are checking.
*
* @return _expires The expiration date of the name in Unix seconds.
*/
function endtimeOf(string _name) constant returns (uint _expires)
{
return expirations[sha256(_name)];
}
/**
* @dev Updates a content of the Name.
*
* Function is overloaded to allow any configurations of Name updates
* ie. update only destination address, only metadata or destination address and metadata.
*
* @param _name Name that the user wants to update.
* @param _addr The address to which this name will be indicated.
* @param _value Metadata of the Name.
*/
function updateName(string _name, address _addr, string _value) only_name_owner(_name)
{
db.updateName(_name, _addr, _value);
NameUpdated(db.signatureOf(_name));
}
/**
* @dev Updates a content of the Name.
*
* Function is overloaded to allow any configurations of Name updates
* ie. update only destination address, only metadata or destination address and metadata.
*
* @param _name Name that the user wants to update.
* @param _value Metadata of the Name.
*/
function updateName(string _name, string _value) only_name_owner(_name)
{
db.updateName(_name, _value);
NameUpdated(db.signatureOf(_name));
}
/**
* @dev Updates a content of the Name.
*
* Function is overloaded to allow any configurations of Name updates
* ie. update only destination address, only metadata or destination address and metadata.
*
* @param _name Name that the user wants to update.
* @param _addr The address to which this name will be indicated.
*/
function updateName(string _name, address _addr) only_name_owner(_name)
{
db.updateName(_name, _addr);
NameUpdated(db.signatureOf(_name));
}
/**
* @dev Appends the characters to current metadata of the Name.
*
* @param _name Name that the user wants to update.
* @param _value Characters to add to current metadata of the Name.
*/
function appendNameMetadata(string _name, string _value) only_name_owner(_name)
{
db.appendNameMetadata(_name, _value);
NameUpdated(db.signatureOf(_name));
}
/**
* @dev Transfer ownership of the Name.
*
* If the user attempts to transfer the ownership of the Name
* to the smart-contract then the `onNameOwnerChanged` function
* of the receiver contract should be executed. If the receiver contract
* does not implement the `onNameOwnerChanged` function then the fallback
* function of the receiver contract will be invoked.
*
* The execution will be thrown if the name owner is not accessible for
* smart-contracts (hideNameOwner = true).
*
* @param _name Name that the user wants to update.
* @param _newOwner Address to which a user want to transfer Name ownership.
* @param _data Additional transaction metadata.
*/
function changeNameOwner(string _name, address _newOwner, bytes _data) only_name_owner(_name)
{
NameTransferred(msg.sender, _newOwner, sha256(_name), _data);
db.changeNameOwner(_name, _newOwner);
if(isContract(_newOwner))
{
NameReceiver(_newOwner).onNameOwnerChanged(_name, msg.sender, _data);
}
}
/**
* @dev Force contract to throw if ownerOf function is executed.
*
* @param _name Name that the user wants to update.
* @param _hide If true then contract will throw on `ownerOf`
* if false then contract will successfully return owner.
*/
function hideNameOwner(string _name, bool _hide) only_name_owner(_name)
{
db.hideNameOwner(_name, _hide);
NameUpdated(db.signatureOf(_name));
}
/**
* @dev Create the assignation between the Name and its owner's address.
*
* This may be necessary for blockchain explorers to display a human-readable Name
* instead of hex address.
*
* @param _name Name that will be assigned to the _assignee's address
* if the address is the owner of the Name.
* @param _assignee Address that will be assigned to this Name (this address
* could be replaced with the Name).
*/
function assignName(string _name, address _assignee) only_name_owner(_name)
{
db.assignName(_name, _assignee);
Assignment(_assignee, _name);
}
/**
* @dev Destroy the assignation between the Name and its owner's address.
*
* @param _name Name that will no longer be assigned to its owner's address.
*/
function unassignName(string _name) only_name_owner(_name)
{
db.unassignName(_name);
Unassignment(_name);
}
/**
* @dev Extends ownership of the Name for `owningTime` seconds from the current moment of time.
*
* @param _name Name that will be extended.
*/
function extend_Name_Binding_Time(string _name) payable only_name_owner(_name)
{
if(msg.value >= namePrice)
{
if(db.addressOf(DexNS_owner).send(namePrice))
{
expirations[sha256(_name)] = now.add(owningTime);
if(msg.value.sub( namePrice ) > 0)
{
msg.sender.transfer(msg.value.sub(namePrice));
}
}
}
}
/**
* @dev Debugging function that changes the address of DexNS storage contract.
*
* @param _newStorage Address to be considered a storage contract.
*/
function change_Storage_Address(address _newStorage) only_owner
{
db = DexNS_Storage(_newStorage);
}
/**
* @dev Debugging function that disables debugging mode of DexNS frontend contract.
*/
function disable_Debug() only_owner only_debug
{
debug = false;
DebugDisabled();
}
/**
* @dev Debugging function that changes default period of time of Name term of ownership.
*
* @param _newOwningTime New period of time that will be considered a default Name term of ownership.
*/
function set_Owning_Time(uint _newOwningTime) only_owner only_debug
{
owningTime = _newOwningTime;
OwningTimeChanged(_newOwningTime);
}
/**
* @dev Debugging function that changes Name price.
*
* @param _newNamePrice New Name price.
*/
function change_Name_Price(uint _newNamePrice) only_owner only_debug
{
namePrice = _newNamePrice;
NamePriceChanged(_newNamePrice);
}
/**
* @dev Debugging function that destroys the contract.
*/
function dispose() only_owner only_debug
{
selfdestruct(db.addressOf(DexNS_owner));
}
/**
* @dev Assemble the code of the target contract to decide whether it is a contract or not.
*/
function isContract(address _addr) private returns (bool is_contract) {
uint length;
assembly {
//retrieve the size of the code on target address, this needs assembly
length := extcodesize(_addr)
}
return (length > 0);
}
/**
* @dev Debugging function that allows to send a custom call from this contract.
* For example extract stuck tokens.
*
* @param _target Address that will be called from this contract.
* @param _gas gasLimit of the call.
* @param _data Execution data.
*/
function debugCall(address _target, uint _gas, bytes _data) payable only_owner only_debug
{
if(!_target.call.gas(_gas).value(msg.value)(_data))
{
Error(0);
}
}
}