├── ABI ├── DexNS_Frontend.abi └── DexNS_Storage.abi ├── DexNS_Frontend.sol ├── DexNS_Storage.sol ├── HOWTO ├── HOWTO1.png ├── HOWTO2.png ├── HOWTO3.png ├── HOWTO4.png ├── HOWTO5.png ├── HOWTO6.png ├── HOWTO7.png ├── HOWTO8.png ├── HOWTO9.png └── simple_ABI.json ├── LICENSE ├── README.md ├── TEST_Name_Receiver.sol └── safeMath.sol /ABI/DexNS_Frontend.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": false, 4 | "inputs": [ 5 | { 6 | "name": "_name", 7 | "type": "string" 8 | } 9 | ], 10 | "name": "extend_Name_Binding_Time", 11 | "outputs": [], 12 | "payable": true, 13 | "stateMutability": "payable", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_name", 21 | "type": "string" 22 | } 23 | ], 24 | "name": "registerName", 25 | "outputs": [ 26 | { 27 | "name": "ok", 28 | "type": "bool" 29 | } 30 | ], 31 | "payable": true, 32 | "stateMutability": "payable", 33 | "type": "function" 34 | }, 35 | { 36 | "constant": false, 37 | "inputs": [ 38 | { 39 | "name": "_name", 40 | "type": "string" 41 | } 42 | ], 43 | "name": "unassignName", 44 | "outputs": [], 45 | "payable": false, 46 | "stateMutability": "nonpayable", 47 | "type": "function" 48 | }, 49 | { 50 | "constant": false, 51 | "inputs": [ 52 | { 53 | "name": "_name", 54 | "type": "string" 55 | }, 56 | { 57 | "name": "_addr", 58 | "type": "address" 59 | } 60 | ], 61 | "name": "updateName", 62 | "outputs": [], 63 | "payable": false, 64 | "stateMutability": "nonpayable", 65 | "type": "function" 66 | }, 67 | { 68 | "constant": false, 69 | "inputs": [ 70 | { 71 | "name": "_name", 72 | "type": "string" 73 | }, 74 | { 75 | "name": "_value", 76 | "type": "string" 77 | } 78 | ], 79 | "name": "appendNameMetadata", 80 | "outputs": [], 81 | "payable": false, 82 | "stateMutability": "nonpayable", 83 | "type": "function" 84 | }, 85 | { 86 | "constant": true, 87 | "inputs": [], 88 | "name": "DexNS_owner", 89 | "outputs": [ 90 | { 91 | "name": "", 92 | "type": "string" 93 | } 94 | ], 95 | "payable": false, 96 | "stateMutability": "view", 97 | "type": "function" 98 | }, 99 | { 100 | "constant": false, 101 | "inputs": [ 102 | { 103 | "name": "_name", 104 | "type": "string" 105 | }, 106 | { 107 | "name": "_value", 108 | "type": "string" 109 | } 110 | ], 111 | "name": "updateName", 112 | "outputs": [], 113 | "payable": false, 114 | "stateMutability": "nonpayable", 115 | "type": "function" 116 | }, 117 | { 118 | "constant": false, 119 | "inputs": [ 120 | { 121 | "name": "_name", 122 | "type": "string" 123 | }, 124 | { 125 | "name": "_addr", 126 | "type": "address" 127 | }, 128 | { 129 | "name": "_value", 130 | "type": "string" 131 | } 132 | ], 133 | "name": "updateName", 134 | "outputs": [], 135 | "payable": false, 136 | "stateMutability": "nonpayable", 137 | "type": "function" 138 | }, 139 | { 140 | "constant": false, 141 | "inputs": [ 142 | { 143 | "name": "_newOwningTime", 144 | "type": "uint256" 145 | } 146 | ], 147 | "name": "set_Owning_Time", 148 | "outputs": [], 149 | "payable": false, 150 | "stateMutability": "nonpayable", 151 | "type": "function" 152 | }, 153 | { 154 | "constant": false, 155 | "inputs": [], 156 | "name": "dispose", 157 | "outputs": [], 158 | "payable": false, 159 | "stateMutability": "nonpayable", 160 | "type": "function" 161 | }, 162 | { 163 | "constant": true, 164 | "inputs": [], 165 | "name": "db", 166 | "outputs": [ 167 | { 168 | "name": "", 169 | "type": "address" 170 | } 171 | ], 172 | "payable": false, 173 | "stateMutability": "view", 174 | "type": "function" 175 | }, 176 | { 177 | "constant": false, 178 | "inputs": [ 179 | { 180 | "name": "_newNamePrice", 181 | "type": "uint256" 182 | } 183 | ], 184 | "name": "change_Name_Price", 185 | "outputs": [], 186 | "payable": false, 187 | "stateMutability": "nonpayable", 188 | "type": "function" 189 | }, 190 | { 191 | "constant": true, 192 | "inputs": [], 193 | "name": "debug", 194 | "outputs": [ 195 | { 196 | "name": "", 197 | "type": "bool" 198 | } 199 | ], 200 | "payable": false, 201 | "stateMutability": "view", 202 | "type": "function" 203 | }, 204 | { 205 | "constant": false, 206 | "inputs": [ 207 | { 208 | "name": "_name", 209 | "type": "string" 210 | }, 211 | { 212 | "name": "_hide", 213 | "type": "bool" 214 | } 215 | ], 216 | "name": "hideNameOwner", 217 | "outputs": [], 218 | "payable": false, 219 | "stateMutability": "nonpayable", 220 | "type": "function" 221 | }, 222 | { 223 | "constant": true, 224 | "inputs": [ 225 | { 226 | "name": "_name", 227 | "type": "string" 228 | } 229 | ], 230 | "name": "name", 231 | "outputs": [ 232 | { 233 | "name": "hash", 234 | "type": "bytes32" 235 | } 236 | ], 237 | "payable": false, 238 | "stateMutability": "view", 239 | "type": "function" 240 | }, 241 | { 242 | "constant": false, 243 | "inputs": [ 244 | { 245 | "name": "_target", 246 | "type": "address" 247 | }, 248 | { 249 | "name": "_gas", 250 | "type": "uint256" 251 | }, 252 | { 253 | "name": "_data", 254 | "type": "bytes" 255 | } 256 | ], 257 | "name": "debugCall", 258 | "outputs": [], 259 | "payable": true, 260 | "stateMutability": "payable", 261 | "type": "function" 262 | }, 263 | { 264 | "constant": true, 265 | "inputs": [ 266 | { 267 | "name": "_name", 268 | "type": "string" 269 | } 270 | ], 271 | "name": "endtimeOf", 272 | "outputs": [ 273 | { 274 | "name": "_expires", 275 | "type": "uint256" 276 | } 277 | ], 278 | "payable": false, 279 | "stateMutability": "view", 280 | "type": "function" 281 | }, 282 | { 283 | "constant": false, 284 | "inputs": [ 285 | { 286 | "name": "_name", 287 | "type": "string" 288 | }, 289 | { 290 | "name": "_assignee", 291 | "type": "address" 292 | } 293 | ], 294 | "name": "assignName", 295 | "outputs": [], 296 | "payable": false, 297 | "stateMutability": "nonpayable", 298 | "type": "function" 299 | }, 300 | { 301 | "constant": false, 302 | "inputs": [ 303 | { 304 | "name": "_newStorage", 305 | "type": "address" 306 | } 307 | ], 308 | "name": "change_Storage_Address", 309 | "outputs": [], 310 | "payable": false, 311 | "stateMutability": "nonpayable", 312 | "type": "function" 313 | }, 314 | { 315 | "constant": true, 316 | "inputs": [], 317 | "name": "namePrice", 318 | "outputs": [ 319 | { 320 | "name": "", 321 | "type": "uint256" 322 | } 323 | ], 324 | "payable": false, 325 | "stateMutability": "view", 326 | "type": "function" 327 | }, 328 | { 329 | "constant": false, 330 | "inputs": [], 331 | "name": "disable_Debug", 332 | "outputs": [], 333 | "payable": false, 334 | "stateMutability": "nonpayable", 335 | "type": "function" 336 | }, 337 | { 338 | "constant": true, 339 | "inputs": [], 340 | "name": "owningTime", 341 | "outputs": [ 342 | { 343 | "name": "", 344 | "type": "uint256" 345 | } 346 | ], 347 | "payable": false, 348 | "stateMutability": "view", 349 | "type": "function" 350 | }, 351 | { 352 | "constant": false, 353 | "inputs": [ 354 | { 355 | "name": "_name", 356 | "type": "string" 357 | }, 358 | { 359 | "name": "_owner", 360 | "type": "address" 361 | }, 362 | { 363 | "name": "_destination", 364 | "type": "address" 365 | }, 366 | { 367 | "name": "_metadata", 368 | "type": "string" 369 | }, 370 | { 371 | "name": "_hideOwner", 372 | "type": "bool" 373 | }, 374 | { 375 | "name": "_assign", 376 | "type": "bool" 377 | } 378 | ], 379 | "name": "registerAndUpdateName", 380 | "outputs": [ 381 | { 382 | "name": "ok", 383 | "type": "bool" 384 | } 385 | ], 386 | "payable": true, 387 | "stateMutability": "payable", 388 | "type": "function" 389 | }, 390 | { 391 | "constant": false, 392 | "inputs": [ 393 | { 394 | "name": "_name", 395 | "type": "string" 396 | }, 397 | { 398 | "name": "_newOwner", 399 | "type": "address" 400 | }, 401 | { 402 | "name": "_data", 403 | "type": "bytes" 404 | } 405 | ], 406 | "name": "changeNameOwner", 407 | "outputs": [], 408 | "payable": false, 409 | "stateMutability": "nonpayable", 410 | "type": "function" 411 | }, 412 | { 413 | "constant": true, 414 | "inputs": [ 415 | { 416 | "name": "", 417 | "type": "bytes32" 418 | } 419 | ], 420 | "name": "expirations", 421 | "outputs": [ 422 | { 423 | "name": "", 424 | "type": "uint256" 425 | } 426 | ], 427 | "payable": false, 428 | "stateMutability": "view", 429 | "type": "function" 430 | }, 431 | { 432 | "inputs": [], 433 | "payable": false, 434 | "stateMutability": "nonpayable", 435 | "type": "constructor" 436 | }, 437 | { 438 | "anonymous": false, 439 | "inputs": [ 440 | { 441 | "indexed": false, 442 | "name": "", 443 | "type": "bytes32" 444 | } 445 | ], 446 | "name": "Error", 447 | "type": "event" 448 | }, 449 | { 450 | "anonymous": false, 451 | "inputs": [ 452 | { 453 | "indexed": true, 454 | "name": "_price", 455 | "type": "uint256" 456 | } 457 | ], 458 | "name": "NamePriceChanged", 459 | "type": "event" 460 | }, 461 | { 462 | "anonymous": false, 463 | "inputs": [ 464 | { 465 | "indexed": true, 466 | "name": "_period", 467 | "type": "uint256" 468 | } 469 | ], 470 | "name": "OwningTimeChanged", 471 | "type": "event" 472 | }, 473 | { 474 | "anonymous": false, 475 | "inputs": [], 476 | "name": "DebugDisabled", 477 | "type": "event" 478 | }, 479 | { 480 | "anonymous": false, 481 | "inputs": [ 482 | { 483 | "indexed": false, 484 | "name": "_name", 485 | "type": "string" 486 | }, 487 | { 488 | "indexed": true, 489 | "name": "_owner", 490 | "type": "address" 491 | } 492 | ], 493 | "name": "NameRegistered", 494 | "type": "event" 495 | }, 496 | { 497 | "anonymous": false, 498 | "inputs": [ 499 | { 500 | "indexed": true, 501 | "name": "_signature", 502 | "type": "bytes32" 503 | } 504 | ], 505 | "name": "NameUpdated", 506 | "type": "event" 507 | }, 508 | { 509 | "anonymous": false, 510 | "inputs": [ 511 | { 512 | "indexed": true, 513 | "name": "_sender", 514 | "type": "address" 515 | }, 516 | { 517 | "indexed": true, 518 | "name": "_receiver", 519 | "type": "address" 520 | }, 521 | { 522 | "indexed": true, 523 | "name": "_signature", 524 | "type": "bytes32" 525 | }, 526 | { 527 | "indexed": false, 528 | "name": "_data", 529 | "type": "bytes" 530 | } 531 | ], 532 | "name": "NameTransferred", 533 | "type": "event" 534 | }, 535 | { 536 | "anonymous": false, 537 | "inputs": [ 538 | { 539 | "indexed": true, 540 | "name": "_owner", 541 | "type": "address" 542 | }, 543 | { 544 | "indexed": false, 545 | "name": "_name", 546 | "type": "string" 547 | } 548 | ], 549 | "name": "Assignment", 550 | "type": "event" 551 | }, 552 | { 553 | "anonymous": false, 554 | "inputs": [ 555 | { 556 | "indexed": false, 557 | "name": "_name", 558 | "type": "string" 559 | } 560 | ], 561 | "name": "Unassignment", 562 | "type": "event" 563 | } 564 | ] 565 | -------------------------------------------------------------------------------- /ABI/DexNS_Storage.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [ 5 | { 6 | "name": "", 7 | "type": "bytes32" 8 | } 9 | ], 10 | "name": "name_assignation", 11 | "outputs": [ 12 | { 13 | "name": "", 14 | "type": "address" 15 | } 16 | ], 17 | "payable": false, 18 | "stateMutability": "view", 19 | "type": "function" 20 | }, 21 | { 22 | "constant": false, 23 | "inputs": [ 24 | { 25 | "name": "_name", 26 | "type": "string" 27 | } 28 | ], 29 | "name": "unassignName", 30 | "outputs": [], 31 | "payable": false, 32 | "stateMutability": "nonpayable", 33 | "type": "function" 34 | }, 35 | { 36 | "constant": false, 37 | "inputs": [ 38 | { 39 | "name": "_name", 40 | "type": "string" 41 | }, 42 | { 43 | "name": "_address", 44 | "type": "address" 45 | } 46 | ], 47 | "name": "updateName", 48 | "outputs": [], 49 | "payable": false, 50 | "stateMutability": "nonpayable", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": true, 55 | "inputs": [ 56 | { 57 | "name": "_name", 58 | "type": "string" 59 | } 60 | ], 61 | "name": "name_assignation", 62 | "outputs": [ 63 | { 64 | "name": "_assignee", 65 | "type": "address" 66 | } 67 | ], 68 | "payable": false, 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "constant": false, 74 | "inputs": [ 75 | { 76 | "name": "_name", 77 | "type": "string" 78 | }, 79 | { 80 | "name": "_value", 81 | "type": "string" 82 | } 83 | ], 84 | "name": "appendNameMetadata", 85 | "outputs": [], 86 | "payable": false, 87 | "stateMutability": "nonpayable", 88 | "type": "function" 89 | }, 90 | { 91 | "constant": false, 92 | "inputs": [ 93 | { 94 | "name": "_name", 95 | "type": "string" 96 | }, 97 | { 98 | "name": "_value", 99 | "type": "string" 100 | } 101 | ], 102 | "name": "updateName", 103 | "outputs": [], 104 | "payable": false, 105 | "stateMutability": "nonpayable", 106 | "type": "function" 107 | }, 108 | { 109 | "constant": false, 110 | "inputs": [ 111 | { 112 | "name": "_name", 113 | "type": "string" 114 | }, 115 | { 116 | "name": "_addr", 117 | "type": "address" 118 | }, 119 | { 120 | "name": "_value", 121 | "type": "string" 122 | } 123 | ], 124 | "name": "updateName", 125 | "outputs": [], 126 | "payable": false, 127 | "stateMutability": "nonpayable", 128 | "type": "function" 129 | }, 130 | { 131 | "constant": false, 132 | "inputs": [ 133 | { 134 | "name": "_newOwner", 135 | "type": "address" 136 | } 137 | ], 138 | "name": "change_Owner", 139 | "outputs": [], 140 | "payable": false, 141 | "stateMutability": "nonpayable", 142 | "type": "function" 143 | }, 144 | { 145 | "constant": true, 146 | "inputs": [ 147 | { 148 | "name": "_assignee", 149 | "type": "address" 150 | } 151 | ], 152 | "name": "assignation", 153 | "outputs": [ 154 | { 155 | "name": "_name", 156 | "type": "string" 157 | } 158 | ], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, 163 | { 164 | "constant": false, 165 | "inputs": [ 166 | { 167 | "name": "_from", 168 | "type": "address" 169 | }, 170 | { 171 | "name": "_name", 172 | "type": "string" 173 | } 174 | ], 175 | "name": "registerName", 176 | "outputs": [ 177 | { 178 | "name": "_ok", 179 | "type": "bool" 180 | } 181 | ], 182 | "payable": false, 183 | "stateMutability": "nonpayable", 184 | "type": "function" 185 | }, 186 | { 187 | "constant": false, 188 | "inputs": [ 189 | { 190 | "name": "_name", 191 | "type": "string" 192 | }, 193 | { 194 | "name": "_owner", 195 | "type": "address" 196 | }, 197 | { 198 | "name": "_destination", 199 | "type": "address" 200 | }, 201 | { 202 | "name": "_metadata", 203 | "type": "string" 204 | }, 205 | { 206 | "name": "_hideOwner", 207 | "type": "bool" 208 | } 209 | ], 210 | "name": "registerAndUpdateName", 211 | "outputs": [ 212 | { 213 | "name": "_ok", 214 | "type": "bool" 215 | } 216 | ], 217 | "payable": false, 218 | "stateMutability": "nonpayable", 219 | "type": "function" 220 | }, 221 | { 222 | "constant": false, 223 | "inputs": [ 224 | { 225 | "name": "_name", 226 | "type": "string" 227 | }, 228 | { 229 | "name": "_hide", 230 | "type": "bool" 231 | } 232 | ], 233 | "name": "hideNameOwner", 234 | "outputs": [], 235 | "payable": false, 236 | "stateMutability": "nonpayable", 237 | "type": "function" 238 | }, 239 | { 240 | "constant": true, 241 | "inputs": [ 242 | { 243 | "name": "_name", 244 | "type": "string" 245 | } 246 | ], 247 | "name": "name", 248 | "outputs": [ 249 | { 250 | "name": "_hash", 251 | "type": "bytes32" 252 | } 253 | ], 254 | "payable": false, 255 | "stateMutability": "view", 256 | "type": "function" 257 | }, 258 | { 259 | "constant": true, 260 | "inputs": [], 261 | "name": "frontend_contract", 262 | "outputs": [ 263 | { 264 | "name": "", 265 | "type": "address" 266 | } 267 | ], 268 | "payable": false, 269 | "stateMutability": "view", 270 | "type": "function" 271 | }, 272 | { 273 | "constant": true, 274 | "inputs": [ 275 | { 276 | "name": "_name", 277 | "type": "string" 278 | } 279 | ], 280 | "name": "getName", 281 | "outputs": [ 282 | { 283 | "name": "_owner", 284 | "type": "address" 285 | }, 286 | { 287 | "name": "_associatedAddress", 288 | "type": "address" 289 | }, 290 | { 291 | "name": "_value", 292 | "type": "string" 293 | }, 294 | { 295 | "name": "_signature", 296 | "type": "bytes32" 297 | } 298 | ], 299 | "payable": false, 300 | "stateMutability": "view", 301 | "type": "function" 302 | }, 303 | { 304 | "constant": false, 305 | "inputs": [ 306 | { 307 | "name": "_name", 308 | "type": "string" 309 | }, 310 | { 311 | "name": "_destination", 312 | "type": "address" 313 | } 314 | ], 315 | "name": "assignName", 316 | "outputs": [], 317 | "payable": false, 318 | "stateMutability": "nonpayable", 319 | "type": "function" 320 | }, 321 | { 322 | "constant": true, 323 | "inputs": [ 324 | { 325 | "name": "_name", 326 | "type": "string" 327 | } 328 | ], 329 | "name": "ownerOf", 330 | "outputs": [ 331 | { 332 | "name": "_owner", 333 | "type": "address" 334 | } 335 | ], 336 | "payable": false, 337 | "stateMutability": "view", 338 | "type": "function" 339 | }, 340 | { 341 | "constant": false, 342 | "inputs": [ 343 | { 344 | "name": "_name", 345 | "type": "string" 346 | }, 347 | { 348 | "name": "_newOwner", 349 | "type": "address" 350 | } 351 | ], 352 | "name": "changeNameOwner", 353 | "outputs": [], 354 | "payable": false, 355 | "stateMutability": "nonpayable", 356 | "type": "function" 357 | }, 358 | { 359 | "constant": true, 360 | "inputs": [ 361 | { 362 | "name": "_name", 363 | "type": "string" 364 | } 365 | ], 366 | "name": "signatureOf", 367 | "outputs": [ 368 | { 369 | "name": "_sig", 370 | "type": "bytes32" 371 | } 372 | ], 373 | "payable": false, 374 | "stateMutability": "view", 375 | "type": "function" 376 | }, 377 | { 378 | "constant": true, 379 | "inputs": [ 380 | { 381 | "name": "_name", 382 | "type": "string" 383 | } 384 | ], 385 | "name": "addressOf", 386 | "outputs": [ 387 | { 388 | "name": "_addr", 389 | "type": "address" 390 | } 391 | ], 392 | "payable": false, 393 | "stateMutability": "view", 394 | "type": "function" 395 | }, 396 | { 397 | "constant": true, 398 | "inputs": [ 399 | { 400 | "name": "_name", 401 | "type": "string" 402 | } 403 | ], 404 | "name": "metadataOf", 405 | "outputs": [ 406 | { 407 | "name": "_value", 408 | "type": "string" 409 | } 410 | ], 411 | "payable": false, 412 | "stateMutability": "view", 413 | "type": "function" 414 | }, 415 | { 416 | "constant": true, 417 | "inputs": [ 418 | { 419 | "name": "", 420 | "type": "bytes32" 421 | } 422 | ], 423 | "name": "resolution", 424 | "outputs": [ 425 | { 426 | "name": "owner", 427 | "type": "address" 428 | }, 429 | { 430 | "name": "addr", 431 | "type": "address" 432 | }, 433 | { 434 | "name": "metadata", 435 | "type": "string" 436 | }, 437 | { 438 | "name": "hideOwner", 439 | "type": "bool" 440 | }, 441 | { 442 | "name": "signature", 443 | "type": "bytes32" 444 | } 445 | ], 446 | "payable": false, 447 | "stateMutability": "view", 448 | "type": "function" 449 | }, 450 | { 451 | "constant": false, 452 | "inputs": [ 453 | { 454 | "name": "_newFrontEnd", 455 | "type": "address" 456 | } 457 | ], 458 | "name": "change_FrontEnd_Address", 459 | "outputs": [], 460 | "payable": false, 461 | "stateMutability": "nonpayable", 462 | "type": "function" 463 | }, 464 | { 465 | "inputs": [], 466 | "payable": false, 467 | "stateMutability": "nonpayable", 468 | "type": "constructor" 469 | }, 470 | { 471 | "anonymous": false, 472 | "inputs": [ 473 | { 474 | "indexed": false, 475 | "name": "", 476 | "type": "bytes32" 477 | } 478 | ], 479 | "name": "Error", 480 | "type": "event" 481 | } 482 | ] 483 | -------------------------------------------------------------------------------- /DexNS_Frontend.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.15; 2 | 3 | import './DexNS_Storage.sol'; 4 | import './safeMath.sol'; 5 | 6 | /* 7 | * The following is an implementation of the Naming Service that aims to boost 8 | * the usability of smart-contracts and provide a human-friendly utility 9 | * to work with low-level smart-contract interactions. 10 | * 11 | * In addition it can be used as a central controlling unit of the system 12 | * with dynamically linked smart-contracts. 13 | * 14 | * Current implementation aims to simplify searches by contract names 15 | * and automated loading of ABIs for smart-contracts. 16 | * This can be used to provide an automated token adding 17 | * to the web wallet interfaces like ClassicEtherWallet as well. 18 | * 19 | * Designed by Dexaran, dexaran@ethereumclassic.org 20 | * 21 | */ 22 | 23 | contract NameReceiver { 24 | function onNameOwnerChanged(string _name, address _sender, bytes _data); 25 | } 26 | 27 | contract DexNS_Abstract_Interface { 28 | function name(string) constant returns (bytes32); 29 | function getName(string) constant returns (address _owner, address _associated, string _value, uint _end, bytes32 _sig); 30 | 31 | function ownerOf(string) constant returns (address); 32 | function addressOf(string) constant returns (address); 33 | function valueOf(string) constant returns (string); 34 | function endtimeOf(string) constant returns (uint); 35 | function updateName(string, string); 36 | function updateName(string, address); 37 | function updateName(string, address, string); 38 | function registerName(string) payable returns (bool); 39 | function registerAndUpdateName(string, address, address, string, bool, bool) payable returns (bool); 40 | function changeNameOwner(string, address, bytes); 41 | function hideNameOwner(string); 42 | function extendNameBindingTime(string) payable; 43 | function appendNameMetadata(string, string); 44 | } 45 | 46 | 47 | /** contract Test 48 | * { 49 | * address constant_name_service; 50 | * function() payable 51 | * { 52 | * DexNS_Storage dexns = DexNS_Storage(constant_name_service); 53 | * dexns.addressOf("Recipient name").send(msg.value); 54 | * } 55 | *} 56 | */ 57 | 58 | 59 | /** 60 | * @title Frontend DexNS contract. 61 | * @dev The frontend contract is executed when a user wants to register new Name or adjust any parameter 62 | * of the already existing Name. 63 | */ 64 | contract DexNS_Frontend 65 | { 66 | using SafeMath for uint256; 67 | event Error(bytes32); 68 | event NamePriceChanged(uint indexed _price); 69 | event OwningTimeChanged(uint indexed _period); 70 | event DebugDisabled(); 71 | event NameRegistered(string _name, address indexed _owner); 72 | event NameUpdated(bytes32 indexed _signature); 73 | event NameTransferred(address indexed _sender, address indexed _receiver, bytes32 indexed _signature, bytes _data); 74 | event Assignment(address indexed _owner, string _name); 75 | event Unassignment(string _name); 76 | 77 | DexNS_Storage public db; 78 | 79 | modifier only_owner 80 | { 81 | if ( msg.sender != db.ownerOf(DexNS_owner) ) 82 | revert(); 83 | _; 84 | } 85 | 86 | modifier only_name_owner(string _name) 87 | { 88 | if ( msg.sender != db.ownerOf(_name) ) 89 | revert(); 90 | _; 91 | } 92 | 93 | modifier only_debug 94 | { 95 | if ( !debug ) 96 | revert(); 97 | _; 98 | } 99 | 100 | bool public debug = true; 101 | uint public owningTime = 31536000; //1 year in seconds 102 | uint public namePrice = 0; 103 | string public constant DexNS_owner = "DexNS owner"; 104 | 105 | mapping (bytes32 => uint256) public expirations; 106 | 107 | /** 108 | * @dev Constructor 109 | */ 110 | function DexNS_Frontend() 111 | { 112 | db = DexNS_Storage(0x28fc417c046d409c14456cec0fc6f9cde46cc9f3); 113 | bytes32 _sig = sha256(DexNS_owner); 114 | expirations[_sig] = 2524608000; // 01/01/2050 @ 12:00am (UTC) 115 | } 116 | 117 | /** 118 | * @dev Returns keccak-256 hash of the Name. 119 | * 120 | * @return hash The hash of the name. 121 | */ 122 | function name(string _name) constant returns (bytes32 hash) 123 | { 124 | return bytes32(sha256(_name)); 125 | } 126 | 127 | /** 128 | * @dev Registers a new name with predefined content. 129 | * 130 | * This function will return `true` in case of successful execution. It will revert() The 131 | * transaction in case of failure and thus send back money. 132 | * 133 | * @param _name The name that the user wants to register. 134 | * @param _owner Address that will become the owner of the Name after the registration. 135 | * @param _destination The address to which this name will be indicated. 136 | * @param _metadata Metadata of the Name. 137 | * @param _hideOwner If true, then DexNS will throw on any attempt to access the name owner. 138 | * @param _assign Assign Name to the _destination address after registration. 139 | * 140 | * @return ok True on successful Name registration, false in any other cases. 141 | */ 142 | function registerAndUpdateName(string _name, address _owner, address _destination, string _metadata, bool _hideOwner, bool _assign) payable returns (bool ok) 143 | { 144 | if(!(msg.value < namePrice)) 145 | { 146 | bytes32 _sig = sha256(_name); 147 | if(expirations[_sig] < now) 148 | { 149 | db.registerAndUpdateName(_name, _owner, _destination, _metadata, _hideOwner); 150 | if(_assign) 151 | { 152 | db.assignName(_name, _destination); 153 | } 154 | expirations[_sig] = now.add(owningTime); 155 | if (db.addressOf(DexNS_owner).send(namePrice)) 156 | { 157 | if(msg.value.sub(namePrice) > 0) 158 | { 159 | msg.sender.transfer(msg.value.sub(namePrice)); 160 | } 161 | NameRegistered(_name, _owner); 162 | return true; 163 | } 164 | } 165 | } 166 | revert(); 167 | } 168 | 169 | /** 170 | * @dev Registers a new name with default content. 171 | * 172 | * @param _name The name that the user wants to register. 173 | * 174 | * @return ok True on successful Name registration, false in any other cases. 175 | */ 176 | function registerName(string _name) payable returns (bool ok) 177 | { 178 | if(!(msg.value < namePrice)) 179 | { 180 | bytes32 _sig = sha256(_name); 181 | if(expirations[_sig] < now) 182 | { 183 | db.registerName(msg.sender, _name); 184 | expirations[_sig] = now.add(owningTime); 185 | if (db.addressOf(DexNS_owner).send(namePrice)) 186 | { 187 | if(msg.value.sub(namePrice ) > 0) 188 | { 189 | msg.sender.transfer(msg.value.sub(namePrice)); 190 | } 191 | NameRegistered(_name, msg.sender); 192 | return true; 193 | } 194 | } 195 | } 196 | revert(); 197 | } 198 | 199 | /** 200 | * @dev Returns the time when the ownership of the name expires (in Unix seconds). 201 | * 202 | * @param _name Name the validity of which we are checking. 203 | * 204 | * @return _expires The expiration date of the name in Unix seconds. 205 | */ 206 | function endtimeOf(string _name) constant returns (uint _expires) 207 | { 208 | return expirations[sha256(_name)]; 209 | } 210 | 211 | /** 212 | * @dev Updates a content of the Name. 213 | * 214 | * Function is overloaded to allow any configurations of Name updates 215 | * ie. update only destination address, only metadata or destination address and metadata. 216 | * 217 | * @param _name Name that the user wants to update. 218 | * @param _addr The address to which this name will be indicated. 219 | * @param _value Metadata of the Name. 220 | */ 221 | function updateName(string _name, address _addr, string _value) only_name_owner(_name) 222 | { 223 | db.updateName(_name, _addr, _value); 224 | NameUpdated(db.signatureOf(_name)); 225 | } 226 | 227 | /** 228 | * @dev Updates a content of the Name. 229 | * 230 | * Function is overloaded to allow any configurations of Name updates 231 | * ie. update only destination address, only metadata or destination address and metadata. 232 | * 233 | * @param _name Name that the user wants to update. 234 | * @param _value Metadata of the Name. 235 | */ 236 | function updateName(string _name, string _value) only_name_owner(_name) 237 | { 238 | db.updateName(_name, _value); 239 | NameUpdated(db.signatureOf(_name)); 240 | } 241 | 242 | /** 243 | * @dev Updates a content of the Name. 244 | * 245 | * Function is overloaded to allow any configurations of Name updates 246 | * ie. update only destination address, only metadata or destination address and metadata. 247 | * 248 | * @param _name Name that the user wants to update. 249 | * @param _addr The address to which this name will be indicated. 250 | */ 251 | function updateName(string _name, address _addr) only_name_owner(_name) 252 | { 253 | db.updateName(_name, _addr); 254 | NameUpdated(db.signatureOf(_name)); 255 | } 256 | 257 | /** 258 | * @dev Appends the characters to current metadata of the Name. 259 | * 260 | * @param _name Name that the user wants to update. 261 | * @param _value Characters to add to current metadata of the Name. 262 | */ 263 | function appendNameMetadata(string _name, string _value) only_name_owner(_name) 264 | { 265 | db.appendNameMetadata(_name, _value); 266 | NameUpdated(db.signatureOf(_name)); 267 | } 268 | 269 | /** 270 | * @dev Transfer ownership of the Name. 271 | * 272 | * If the user attempts to transfer the ownership of the Name 273 | * to the smart-contract then the `onNameOwnerChanged` function 274 | * of the receiver contract should be executed. If the receiver contract 275 | * does not implement the `onNameOwnerChanged` function then the fallback 276 | * function of the receiver contract will be invoked. 277 | * 278 | * The execution will be thrown if the name owner is not accessible for 279 | * smart-contracts (hideNameOwner = true). 280 | * 281 | * @param _name Name that the user wants to update. 282 | * @param _newOwner Address to which a user want to transfer Name ownership. 283 | * @param _data Additional transaction metadata. 284 | */ 285 | function changeNameOwner(string _name, address _newOwner, bytes _data) only_name_owner(_name) 286 | { 287 | NameTransferred(msg.sender, _newOwner, sha256(_name), _data); 288 | db.changeNameOwner(_name, _newOwner); 289 | if(isContract(_newOwner)) 290 | { 291 | NameReceiver(_newOwner).onNameOwnerChanged(_name, msg.sender, _data); 292 | } 293 | } 294 | 295 | /** 296 | * @dev Force contract to throw if ownerOf function is executed. 297 | * 298 | * @param _name Name that the user wants to update. 299 | * @param _hide If true then contract will throw on `ownerOf` 300 | * if false then contract will successfully return owner. 301 | */ 302 | function hideNameOwner(string _name, bool _hide) only_name_owner(_name) 303 | { 304 | db.hideNameOwner(_name, _hide); 305 | NameUpdated(db.signatureOf(_name)); 306 | } 307 | 308 | /** 309 | * @dev Create the assignation between the Name and its owner's address. 310 | * 311 | * This may be necessary for blockchain explorers to display a human-readable Name 312 | * instead of hex address. 313 | * 314 | * @param _name Name that will be assigned to the _assignee's address 315 | * if the address is the owner of the Name. 316 | * @param _assignee Address that will be assigned to this Name (this address 317 | * could be replaced with the Name). 318 | */ 319 | function assignName(string _name, address _assignee) only_name_owner(_name) 320 | { 321 | db.assignName(_name, _assignee); 322 | Assignment(_assignee, _name); 323 | } 324 | 325 | /** 326 | * @dev Destroy the assignation between the Name and its owner's address. 327 | * 328 | * @param _name Name that will no longer be assigned to its owner's address. 329 | */ 330 | function unassignName(string _name) only_name_owner(_name) 331 | { 332 | db.unassignName(_name); 333 | Unassignment(_name); 334 | } 335 | 336 | /** 337 | * @dev Extends ownership of the Name for `owningTime` seconds from the current moment of time. 338 | * 339 | * @param _name Name that will be extended. 340 | */ 341 | function extend_Name_Binding_Time(string _name) payable only_name_owner(_name) 342 | { 343 | if(msg.value >= namePrice) 344 | { 345 | if(db.addressOf(DexNS_owner).send(namePrice)) 346 | { 347 | expirations[sha256(_name)] = now.add(owningTime); 348 | if(msg.value.sub( namePrice ) > 0) 349 | { 350 | msg.sender.transfer(msg.value.sub(namePrice)); 351 | } 352 | } 353 | } 354 | } 355 | 356 | /** 357 | * @dev Debugging function that changes the address of DexNS storage contract. 358 | * 359 | * @param _newStorage Address to be considered a storage contract. 360 | */ 361 | function change_Storage_Address(address _newStorage) only_owner 362 | { 363 | db = DexNS_Storage(_newStorage); 364 | } 365 | 366 | /** 367 | * @dev Debugging function that disables debugging mode of DexNS frontend contract. 368 | */ 369 | function disable_Debug() only_owner only_debug 370 | { 371 | debug = false; 372 | DebugDisabled(); 373 | } 374 | 375 | /** 376 | * @dev Debugging function that changes default period of time of Name term of ownership. 377 | * 378 | * @param _newOwningTime New period of time that will be considered a default Name term of ownership. 379 | */ 380 | function set_Owning_Time(uint _newOwningTime) only_owner only_debug 381 | { 382 | owningTime = _newOwningTime; 383 | OwningTimeChanged(_newOwningTime); 384 | } 385 | 386 | /** 387 | * @dev Debugging function that changes Name price. 388 | * 389 | * @param _newNamePrice New Name price. 390 | */ 391 | function change_Name_Price(uint _newNamePrice) only_owner only_debug 392 | { 393 | namePrice = _newNamePrice; 394 | NamePriceChanged(_newNamePrice); 395 | } 396 | 397 | /** 398 | * @dev Debugging function that destroys the contract. 399 | */ 400 | function dispose() only_owner only_debug 401 | { 402 | selfdestruct(db.addressOf(DexNS_owner)); 403 | } 404 | 405 | /** 406 | * @dev Assemble the code of the target contract to decide whether it is a contract or not. 407 | */ 408 | function isContract(address _addr) private returns (bool is_contract) { 409 | uint length; 410 | assembly { 411 | //retrieve the size of the code on target address, this needs assembly 412 | length := extcodesize(_addr) 413 | } 414 | return (length > 0); 415 | } 416 | 417 | /** 418 | * @dev Debugging function that allows to send a custom call from this contract. 419 | * For example extract stuck tokens. 420 | * 421 | * @param _target Address that will be called from this contract. 422 | * @param _gas gasLimit of the call. 423 | * @param _data Execution data. 424 | */ 425 | function debugCall(address _target, uint _gas, bytes _data) payable only_owner only_debug 426 | { 427 | if(!_target.call.gas(_gas).value(msg.value)(_data)) 428 | { 429 | Error(0); 430 | } 431 | } 432 | } 433 | -------------------------------------------------------------------------------- /DexNS_Storage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.15; 2 | 3 | contract DexNS_Storage { 4 | 5 | event Error(bytes32); 6 | 7 | modifier only_owner 8 | { 9 | if ( msg.sender != resolution[sha256(DexNS_owner)].owner ) 10 | { 11 | revert(); 12 | } 13 | _; 14 | } 15 | 16 | modifier only_frontend 17 | { 18 | if ( msg.sender != frontend_contract ) 19 | { 20 | revert(); 21 | } 22 | _; 23 | } 24 | 25 | string private DexNS_owner = "DexNS owner"; 26 | address public frontend_contract; 27 | 28 | struct Resolution 29 | { 30 | address owner; 31 | address addr; 32 | string metadata; 33 | bool hideOwner; // do-not-return-owner variable 34 | bytes32 signature; 35 | } 36 | 37 | mapping (bytes32 => Resolution) public resolution; 38 | mapping (address => string) public assignation; 39 | mapping (bytes32 => address) public name_assignation; 40 | 41 | /** 42 | * @dev Constructor 43 | */ 44 | function DexNS_Storage() 45 | { 46 | bytes32 sig = bytes32(sha256(DexNS_owner)); 47 | resolution[sig].owner = msg.sender; 48 | resolution[sig].addr = msg.sender; 49 | resolution[sig].signature = sig; 50 | resolution[sig].metadata = "-ETC"; 51 | } 52 | 53 | /** 54 | * @dev Returns keccak-256 hash of the Name. 55 | * 56 | * @return hash The hash of the name. 57 | */ 58 | function name(string _name) constant returns (bytes32 _hash) 59 | { 60 | return bytes32(sha256(_name)); 61 | } 62 | 63 | /** 64 | * @dev Registers a new name with default content. 65 | * 66 | * This function will return `true` in case of successful execution. It will revert() The 67 | * transaction in case of failure and thus send back money. 68 | * 69 | * @param _from Address that attempts to register this Name. 70 | * @param _name The Name that the user wants to register. 71 | * 72 | * @return ok True on successful Name registration, false in any other cases. 73 | */ 74 | function registerName(address _from, string _name) only_frontend returns (bool _ok) 75 | { 76 | bytes32 sig = bytes32(sha256(_name)); 77 | resolution[sig].owner = _from; 78 | resolution[sig].addr = _from; 79 | resolution[sig].metadata = "-ETC"; 80 | resolution[sig].hideOwner = false; 81 | resolution[sig].signature = sig; 82 | return true; 83 | } 84 | 85 | /** 86 | * @dev Registers a new name with predefined content. 87 | * 88 | * This function will return `true` in case of successful execution. It will revert() The 89 | * transaction in case of failure and thus send back money. 90 | * 91 | * @param _name The name that the user wants to register. 92 | * @param _owner Address that will become the owner of the Name after the registration. 93 | * @param _destination The address to which this name will be indicated. 94 | * @param _metadata Metadata of the Name. 95 | * @param _hideOwner If true, then DexNS will throw on any attempt to access the name owner. 96 | * 97 | * @return ok True on successful Name registration, false in any other cases. 98 | */ 99 | function registerAndUpdateName(string _name, address _owner, address _destination, string _metadata, bool _hideOwner) only_frontend returns (bool _ok) 100 | { 101 | bytes32 sig = bytes32(sha256(_name)); 102 | resolution[sig].owner = _owner; 103 | resolution[sig].addr = _destination; 104 | resolution[sig].metadata = _metadata; 105 | resolution[sig].hideOwner = _hideOwner; 106 | resolution[sig].signature = sig; 107 | return true; 108 | } 109 | 110 | /** 111 | * @dev Returns a content of the Name. 112 | * 113 | * @param _name The name that the user wants to inspect. 114 | * 115 | * @return _owner Address that has permission to change a content of the Name. 116 | * Returns 0 if `hideOwner` is set to true for this Name. 117 | * @return _associatedAddress The address that is indicated to this Name. 118 | * @return _value Metadata of the Name. 119 | * @return _signature keccak-256 hash of the Name. 120 | */ 121 | function getName(string _name) constant returns (address _owner, address _associatedAddress, string _value, bytes32 _signature) 122 | { 123 | bytes32 sig = bytes32(sha256(_name)); 124 | address temp_owner = resolution[sig].owner; 125 | 126 | if(resolution[sig].hideOwner && msg.sender != frontend_contract) { 127 | temp_owner = address(0); 128 | } 129 | 130 | return (temp_owner, resolution[sig].addr, resolution[sig].metadata, resolution[sig].signature); 131 | } 132 | 133 | /** 134 | * @dev Returns metadata of the Name. 135 | * 136 | * @param _name The name that the user wants to inspect. 137 | * 138 | * @return _value Metadata of the Name. 139 | */ 140 | function metadataOf(string _name) constant returns (string memory _value) 141 | { 142 | bytes32 sig = bytes32(sha256(_name)); 143 | return resolution[sig].metadata; 144 | } 145 | 146 | /** 147 | * @dev Returns destination address of the Name. 148 | * 149 | * @param _name The name that the user wants to inspect. 150 | * 151 | * @return _value Metadata of the Name. 152 | */ 153 | function addressOf(string _name) constant returns (address _addr) 154 | { 155 | bytes32 sig = bytes32(sha256(_name)); 156 | return resolution[sig].addr; 157 | } 158 | 159 | /** 160 | * @dev Returns owner address of the Name or throws if the `hideOwner` is true for this name. 161 | * 162 | * @param _name The name that the user wants to inspect. 163 | * 164 | * @return _owner Address that has permission to change a content of this Name. 165 | */ 166 | function ownerOf(string _name) constant returns (address _owner) 167 | { 168 | bytes32 sig = bytes32(sha256(_name)); 169 | if(resolution[sig].hideOwner && msg.sender != frontend_contract) 170 | { 171 | revert(); 172 | } 173 | return resolution[sig].owner; 174 | } 175 | 176 | /** 177 | * @dev Returns keccak-256 hash of the Name. 178 | * 179 | * @param _name The name that the user wants to inspect. 180 | * 181 | * @return _sig Keccak-256 hash of the Name. 182 | */ 183 | function signatureOf(string _name) constant returns (bytes32 _sig) 184 | { 185 | bytes32 sig = bytes32(sha256(_name)); 186 | return sig; 187 | } 188 | 189 | /** 190 | * @dev Updates a content of the Name. 191 | * 192 | * Function is overloaded to allow any configurations of Name updates 193 | * ie. update only destination address, only metadata or destination address and metadata. 194 | * 195 | * @param _name Name that the user wants to update. 196 | * @param _addr The address to which this name will be resolved. 197 | * @param _value Metadata of the Name. 198 | */ 199 | function updateName(string _name, address _addr, string _value) only_frontend 200 | { 201 | bytes32 sig = bytes32(sha256(_name)); 202 | resolution[sig].addr = _addr; 203 | resolution[sig].metadata = _value; 204 | } 205 | 206 | /** 207 | * @dev Updates a content of the Name. 208 | * 209 | * Function is overloaded to allow any configurations of Name updates 210 | * ie. update only destination address, only metadata or destination address and metadata. 211 | * 212 | * @param _name Name that the user wants to update. 213 | * @param _value Metadata of the Name. 214 | */ 215 | function updateName(string _name, string _value) only_frontend 216 | { 217 | bytes32 sig = bytes32(sha256(_name)); 218 | resolution[sig].metadata = _value; 219 | } 220 | 221 | /** 222 | * @dev Updates a content of the Name. 223 | * 224 | * Function is overloaded to allow any configurations of Name updates 225 | * ie. update only destination address, only metadata or destination address and metadata. 226 | * 227 | * @param _name Name that the user wants to update. 228 | * @param _address The address to which this name will be resolved. 229 | */ 230 | function updateName(string _name, address _address) only_frontend 231 | { 232 | bytes32 sig = bytes32(sha256(_name)); 233 | resolution[sig].addr = _address; 234 | } 235 | 236 | 237 | // String functions 238 | 239 | struct slice 240 | { 241 | uint _len; 242 | uint _ptr; 243 | } 244 | 245 | function toSlice(string self) private returns (slice) 246 | { 247 | uint ptr; 248 | assembly { 249 | ptr := add(self, 0x20) 250 | } 251 | return slice(bytes(self).length, ptr); 252 | } 253 | 254 | function memcpy(uint dest, uint src, uint len) private 255 | { 256 | // Copy word-length chunks while possible 257 | for(; len >= 32; len -= 32) 258 | { 259 | assembly { 260 | mstore(dest, mload(src)) 261 | } 262 | dest += 32; 263 | src += 32; 264 | } 265 | 266 | // Copy remaining bytes 267 | uint mask = 256 ** (32 - len) - 1; 268 | assembly { 269 | let srcpart := and(mload(src), not(mask)) 270 | let destpart := and(mload(dest), mask) 271 | mstore(dest, or(destpart, srcpart)) 272 | } 273 | } 274 | 275 | function concat(slice self, slice other) private returns (string) 276 | { 277 | var ret = new string(self._len + other._len); 278 | uint retptr; 279 | assembly { retptr := add(ret, 32) } 280 | memcpy(retptr, self._ptr, self._len); 281 | memcpy(retptr + self._len, other._ptr, other._len); 282 | return ret; 283 | } 284 | 285 | function toString(slice self) internal returns (string) 286 | { 287 | var ret = new string(self._len); 288 | uint retptr; 289 | assembly { retptr := add(ret, 32) } 290 | 291 | memcpy(retptr, self._ptr, self._len); 292 | return ret; 293 | } 294 | 295 | function StringAppend(string _str1, string _str2) private constant returns (string) 296 | { 297 | return concat(toSlice(_str1), toSlice(_str2)); 298 | } 299 | 300 | /** 301 | * @dev Appends the characters to current metadata of the Name. 302 | * 303 | * @param _name Name that the user wants to update. 304 | * @param _value Characters to add to current metadata of the Name. 305 | */ 306 | function appendNameMetadata(string _name, string _value) only_frontend 307 | { 308 | bytes32 sig = bytes32(sha256(_name)); 309 | resolution[sig].metadata = StringAppend(resolution[sig].metadata, _value); 310 | } 311 | 312 | /** 313 | * @dev Transfer ownership of the Name. 314 | * 315 | * Frontend contract will call the handler function of the receiver 316 | * if the receiver is a smart-contract. 317 | * 318 | * @param _name Name that the user wants to update. 319 | * @param _newOwner Address to which a user want to transfer Name ownership. 320 | */ 321 | function changeNameOwner(string _name, address _newOwner) only_frontend 322 | { 323 | bytes32 sig = bytes32(sha256(_name)); 324 | resolution[sig].owner = _newOwner; 325 | } 326 | 327 | /** 328 | * @dev Set throw mode of the getName and ownerOf functions. 329 | * 330 | * @param _name Name that the user wants to update. 331 | * @param _hide True will make contract throw, false will make it returning ower normally. 332 | */ 333 | function hideNameOwner(string _name, bool _hide) only_frontend 334 | { 335 | bytes32 sig = bytes32(sha256(_name)); 336 | resolution[sig].hideOwner = _hide; 337 | } 338 | 339 | /** 340 | * @dev Create the assignation between the Name and its owner's address. 341 | * 342 | * This may be necessary for blockchain explorers to display a human-readable Name 343 | * instead of hex address. 344 | * 345 | * @param _name Name that will be assigned to the _destination address 346 | * if the address is the owner of the Name. 347 | * @param _destination Address that will be assigned with the Name. 348 | */ 349 | function assignName(string _name, address _destination) only_frontend 350 | { 351 | if(name_assignation[sha256(assignation[_destination])] != 0x0) throw; 352 | 353 | assignation[_destination] = _name; 354 | name_assignation[sha256(_name)] = _destination; 355 | } 356 | 357 | /** 358 | * @dev Destroy the assignation between the Name and its owner's address. 359 | * 360 | * @param _name Name that will no longer be assigned to its owner's address. 361 | */ 362 | function unassignName(string _name) only_frontend 363 | { 364 | assignation[name_assignation[sha256(_name)]] = ""; 365 | name_assignation[sha256(_name)] = 0x0; 366 | } 367 | 368 | /** 369 | * @dev Returns a Name that is assigned to the address. 370 | * 371 | * @param _assignee Address that a user wants to inspect. 372 | * 373 | * @return _name Name that is assigned to this address. 374 | */ 375 | function assignation(address _assignee) constant returns (string _name) 376 | { 377 | return assignation[_assignee]; 378 | } 379 | 380 | /** 381 | * @dev Returns an address that is assigned to the Name. 382 | * 383 | * @param _name Name that a user wants to inspect. 384 | * 385 | * @return _assignee Address that is assigned to this Name. 386 | */ 387 | function name_assignation(string _name) constant returns (address _assignee) 388 | { 389 | return name_assignation[sha256(_name)]; 390 | } 391 | 392 | // Debug functions. 393 | 394 | function change_Owner(address _newOwner) only_owner { 395 | resolution[bytes32(sha256(DexNS_owner))].owner =_newOwner; 396 | } 397 | 398 | function change_FrontEnd_Address(address _newFrontEnd) only_owner { 399 | frontend_contract = _newFrontEnd; 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /HOWTO/HOWTO1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO1.png -------------------------------------------------------------------------------- /HOWTO/HOWTO2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO2.png -------------------------------------------------------------------------------- /HOWTO/HOWTO3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO3.png -------------------------------------------------------------------------------- /HOWTO/HOWTO4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO4.png -------------------------------------------------------------------------------- /HOWTO/HOWTO5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO5.png -------------------------------------------------------------------------------- /HOWTO/HOWTO6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO6.png -------------------------------------------------------------------------------- /HOWTO/HOWTO7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO7.png -------------------------------------------------------------------------------- /HOWTO/HOWTO8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO8.png -------------------------------------------------------------------------------- /HOWTO/HOWTO9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthereumCommonwealth/DexNS/459f2721ccf51d4550bb278691519f7d21cae778/HOWTO/HOWTO9.png -------------------------------------------------------------------------------- /HOWTO/simple_ABI.json: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"registerName","outputs":[{"name":"ok","type":"bool"}],"payable":true,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"valueOf","outputs":[{"name":"_value","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"endblockOf","outputs":[{"name":"_endblock","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"extendNameBindingTime","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_value","type":"string"}],"name":"updateName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_addr","type":"address"},{"name":"_value","type":"string"}],"name":"updateName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_hide","type":"bool"}],"name":"hideNameOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"name","outputs":[{"name":"hash","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"getName","outputs":[{"name":"_owner","type":"address"},{"name":"_associatedAddress","type":"address"},{"name":"_value","type":"string"},{"name":"_endblock","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"ownerOf","outputs":[{"name":"_owner","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_newOwner","type":"address"}],"name":"changeNameOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"addressOf","outputs":[{"name":"_addr","type":"address"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_price","type":"uint256"}],"name":"NamePriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_blocks","type":"uint256"}],"name":"OwningTimeChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"DebugDisabled","type":"event"}] 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 4-Clause License 2 | 3 | Copyright (c) 2023, Callisto Enterprise 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. All advertising materials mentioning features or use of this software must 17 | display the following acknowledgement: 18 | This product includes software developed by [project]. 19 | 20 | 4. Neither the name of the copyright holder nor the names of its 21 | contributors may be used to endorse or promote products derived from 22 | this software without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR 25 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 27 | EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Decentralized Naming Service 2 | 3 | ## Overview 4 | 5 | DexNS allows to register human-readable names that could be resolved into Ethereum hex-addresses. Currently, names are free. You can own your name within 1 year after the moment of registration. You can extend name ownership after the certain amount of time will pass. DexNS provides names in human-readable text format. DexNS contract allows any names of any lengths and any characters, but third party services such as ClassicEtherWallet may filter confusing characters and weird names. As the result, it is not recommended to register names with whitespaces and names ending in ENS tld resolutions ( .eth / .etc / .reverse ). You can register your e-mail address as Name for example ( `dexaran@ethereumclassic.org` ). Any user will be able to send ETH, ETC, EXP, UBQ, MUSICOIN and testnet Ether to your address that is assigned to the registered name via ClassicEtherWallet. 6 | 7 | (1) Yes, you can use one DexNS Name on multiple chains to receive different currencies such are ETH, ETC, EXP, UBQ. 8 | 9 | (2) Yes, you can store multiple currencies in one Ethereum wallet address. 10 | 11 | ## Contracts 12 | 13 | DexNS 3.0 contracts are currently deployed on ETC mainnet. 14 | 15 | #### DexNS_Frontend.sol 16 | 17 | This contract serves to register and manage Names. 18 | DexNS frontend contract: [0x101f1920e4cD9c7e2aF056E2cB1954d0DD9647b9](https://gastracker.io/addr/0x101f1920e4cD9c7e2aF056E2cB1954d0DD9647b9) 19 | 20 | #### DexNS_Storage.sol 21 | 22 | This contract serves to access content of the already-registered Names. 23 | DexNS storage contract: [0x28fc417c046d409c14456cec0fc6f9cde46cc9f3](https://gastracker.io/addr/0x28fc417c046d409c14456cec0fc6f9cde46cc9f3) 24 | 25 | # How do I register a name? 26 | 27 | 1. Navigate to ClassicEtherWallet [contracts tab](https://ethereumproject.github.io/etherwallet/?network=ETC#contracts). 28 | 29 | 2. Choose DexNS Frontend Contract from default contracts list and click the "ACCESS" button. (make sure that contract address is `0x101f1920e4cD9c7e2aF056E2cB1954d0DD9647b9`) 30 | 31 | 3. (OPTIONAL: check name availability) Choose `endtimeOf` function name to check whether the name is available or not. 32 | 33 | 3.1 (OPTIONAL: check name availability) Type the desired name into `_name string` input box. You should just type Name in text format. For example `dexaran@ethereumclassic.org`. 34 | 35 | 3.2 (OPTIONAL: check name availability) Click "READ" button and check if the ` _expires uint256` field is equal to 0 or not. As you can see for `dexaran@ethereumclassic.org` it is not equal to zero which means that this name is already owned. You can not register a name that is already owned. You should pick an another name in this case. 36 | 37 | 4. Choose `registerName` function from the functions dropdown menu. 38 | 39 | 5. Type the desired Name into `_name string` input box. You should enter the name in text format. You must enter a name in text format as it will be available to others. 40 | 41 | 6. Unlock your wallet and click "WRITE" button. Make sure that you have provided enough gas for transaction to execute. You should keep in mind that longer Names will require more gas. 200 000 GAS is enough for most names. 42 | 43 | 7. Wait for transaction to submit. You will immediately become the owner of the name after the transaction is successfully submitted to the block. You will own this Name for 1 year. After 1 year you should visit DexNS contract again if you would like to extend Name ownership. 44 | 45 | ## Interaction with DexNS 46 | 47 | To register or manage names you should call the [DexNS frontend contract](https://github.com/EthereumCommonwealth/DexNS/blob/master/DexNS_Frontend.sol) contract (0x101f1920e4cD9c7e2aF056E2cB1954d0DD9647b9). 48 | 49 | To interact with the contents of already registered names, you should call [DexNS state storage contract](https://github.com/EthereumCommonwealth/DexNS/blob/master/DexNS_Storage.sol) (0x28fc417c046d409c14456cec0fc6f9cde46cc9f3). 50 | 51 | DexNS can also be used as a control unit for dynamically linking contracts in a contract system. You should interact with state storage contract to access names. 52 | Example: 53 | 54 | ```js 55 | // This will send 100 WEI to the "My Friend" address. 56 | DexNS_Storage dexns = DexNS_Storage(0x28fc417c046d409c14456cec0fc6f9cde46cc9f3); 57 | dexns.addressOf("My Friend").transfer(100); 58 | ``` 59 | 60 | DexNS contracts are deployed on **Ethereum CLassic mainnet**. You should connect to ETC network to work with DexNS contracts even if you want to access a data of the contract that is deployed on any of the alternative chains. 61 | 62 | # Description 63 | 64 | Service provides an opportunity to register a key-phrase 'Name' and associate one address (wallet or contract) and one string variable (metadata) with each key-phrase. External contracts can access Naming Service variables as follows: 65 | 66 | Addresses or data can be accessed from the external contract. 67 | Naming Service content can't be blocked, removed or censored in any other way. Everyone is allowed to do whatever he/she wants with it. 68 | 69 | # How do I register my ERC20/ERC223 token on DexNS? 70 | 71 | Coming soon ... 72 | 73 | ### Metadata specification 74 | 75 | As DexNS is planned to be used as crosschain smart-contract naming service, I advise to use the first flag for chain identifier. User interface that will work with DexNS **MUST** warn user if he is trying to send a transaction by the DexNS name that doesn't match the currently selected network. 76 | 77 | Use the following chain identifier flags: 78 | 79 | `-ETC` for Ethereum CLassic chain. 80 | 81 | `-ETH` for Ethereum chain. 82 | 83 | `-UBQ` for Ubiq chain. 84 | 85 | `-EXP` for Expanse chain. 86 | 87 | `-ROP` for Ropsten. 88 | 89 | `-RIN` for Rinkeby. 90 | 91 | `-KOV` for Kovan. 92 | 93 | `-CLO` for Callisto mainnet. 94 | 95 | `-CLT` for Callisto testnet. 96 | 97 | Use the following key flags before data chunks: 98 | 99 | `-A ` for ABI. 100 | 101 | `-L ` for attached link. 102 | 103 | `-S ` for source code reference. 104 | 105 | `-i` for informational data chunk. 106 | 107 | Example of metadata for DexNS contract: 108 | `-ETC -L https://author.me/ -S https://github.com/source -A [{"constant":false,"inputs":[],"name":"foo","outputs":[],"payable":false,"type":"function"}]` 109 | 110 | # Details 111 | 112 | - `Name` is a key-phrase that will be associated with name data. Each `Name` contains: 113 | - `owner` the owner of Name. 114 | - `addr` associated address. 115 | - `metadata` stringified associated data. 116 | - `hideOwner` If set to `true` then the contract will `throw` any attempt to access `ownerOf(Name)`. 117 | - `signature` sha256 hash of this Name key-phrase. 118 | 119 | 120 | You can register Name and became its owner. You will own the name before the expiry of the `nameOwning` time. If no one will claim your Name after `expiration[Name]`, then you will continue to be the Name owner. If the Name will be re-registered after the expiration, then you will lose control over this Name. You can extend the term of ownership of the Name before it expires. 121 | 122 | ### Functions 123 | 124 | ### `DexNS_Frontend.sol` contract 125 | 126 | ##### registerName 127 | 128 | ```js 129 | function registerName(string _name) payable returns (bool ok) 130 | ``` 131 | Register a new name at Naming Service. `msg.sender` will become `owner` and `address` of this name. `metadata` will be set to "-ETC" by default. 132 | 133 | ##### registerAndUpdateName 134 | 135 | ```js 136 | function registerAndUpdateName(string _name, address _owner, address _destination, string _metadata, bool _hideOwner) payable returns (bool ok) 137 | ``` 138 | Register a new `_name` at Naming Service. `_owner` will become `owner` and `_destination` will become the `address` of this name. `metadata` of this Name will be set to `_metadata`. `hideOwner` status will be set to `_hideOwner`. 139 | 140 | ##### addressOf 141 | 142 | ```js 143 | function addressOf(string _name) constant returns (address _addr) 144 | ``` 145 | Returns `address` of the destination of the name. 146 | 147 | ##### ownerOf 148 | ```js 149 | function ownerOf(string _name) constant returns (address _owner) 150 | ``` 151 | Returns `owner` of the name. 152 | 153 | ##### endtimeOf 154 | ```js 155 | function endtimeOf(string _name) constant returns (uint _expires) 156 | ``` 157 | Returns timestamp when the name will become free to re-register. Returns 0 for not registered names. 158 | 159 | NOTE: `endtime` is stored at the logical contract. Not in storage. Logic of registering and freeing names is part of logical contract. Storage only accepts calls from it. 160 | 161 | ##### updateName 162 | ```js 163 | function updateName(string _name, address _addr, string _value) { } 164 | function updateName(string _name, address _addr) { } 165 | function updateName(string _name, string _value) { } 166 | ``` 167 | 168 | Changes the contents of `_name` and sets the provided parameters. 169 | 170 | ##### appendNameMetadata 171 | ```js 172 | function appendNameMetadata(string _name, string _value) 173 | ``` 174 | Adds the provided `_value` to the end of the already-existing metadata string of the `_name`. 175 | 176 | ##### changeNameOwner 177 | ```js 178 | function changeNameOwner(string _name, address _newOwner) 179 | ``` 180 | Changes `_name` owner to `_newOwner`. 181 | 182 | ##### hideNameOwner 183 | ```js 184 | function hideNameOwner(string _name, bool _hide) 185 | ``` 186 | If `_hide` is true then `ownerOf(_name)` will `throw` whenever called. 187 | 188 | Rationale: add possibility to abort execution of transaction/call when someone is trying to interact with name `owner` from external contract. Address that is associated with each `_name` is `addressOf(_name)`, not `ownerOf(_name)` ! 189 | 190 | ##### assignName 191 | ```js 192 | function assignName(string _name) 193 | ``` 194 | 195 | Assigns `_name` to `msg.sender` if sender is an owner of the name. 196 | 197 | ##### unassignName 198 | ```js 199 | function unassignName(string _name) 200 | ``` 201 | 202 | Clears `_name` ussignation if `msg.sender` is an owner of the name. 203 | 204 | ##### extendNameBindingTime 205 | ```js 206 | function extendNameBindingTime(string _name) payable 207 | ``` 208 | 209 | Extends binding time of the `_name` by constant specified period if sender provided more funds that required to register/update name. (default 0, free names) 210 | 211 | #### Debugging functions (for owner only) 212 | 213 | ##### change_Storage_Address 214 | ```js 215 | function change_Storage_Address(address _newStorage) 216 | ``` 217 | 218 | Changes address of the storage to `_newStorage`. 219 | 220 | ##### change_Owner 221 | ```js 222 | function change_Owner(address _newOwner) 223 | ``` 224 | 225 | Changes owner of the contract to `_newOwner`. 226 | 227 | ##### disable_Debug 228 | ```js 229 | function disable_Debug() 230 | ``` 231 | 232 | Disables possibility to debug the contract. 233 | 234 | ##### set_Owning_Time 235 | ```js 236 | function set_Owning_Time(uint _newOwningTime) 237 | ``` 238 | 239 | Sets the specified time period for the name binding. 240 | 241 | ##### change_Name_Price 242 | ```js 243 | function change_Name_Price(uint _newNamePrice) 244 | ``` 245 | 246 | Sets the specified price for the name registering 247 | 248 | 249 | ## Events 250 | 251 | ##### Error 252 | 253 | ```js 254 | event Error(bytes32) 255 | ``` 256 | Triggered when error occurs. 257 | 258 | ##### NamePriceChanged 259 | 260 | ```js 261 | event NamePriceChanged(uint indexed _price) 262 | ``` 263 | Triggered when price of name is changed by the owner. 264 | 265 | ##### OwningTimeChanged 266 | 267 | ```js 268 | event OwningTimeChanged(uint indexed _period) 269 | ``` 270 | Triggered when binding preiod of time is changed by the owner. 271 | 272 | ##### DebugDisabled 273 | 274 | ```js 275 | event DebugDisabled() 276 | ``` 277 | Triggered when debug is disabled. 278 | 279 | 280 | ### `DexNS_Storage.sol` contract 281 | 282 | ##### functions that would be called from DexNS frontend contract to modify state 283 | 284 | ```js 285 | function registerName(string _name) payable returns (bool ok) { } 286 | function registerAndUpdateName(string, address, address, string, bool) returns (bool ok) { } 287 | function updateName(string _name, address _addr, string _value) { } 288 | function updateName(string _name, address _addr) { } 289 | function updateName(string _name, string _value) { } 290 | function appendNameMetadata(string _name, string _value) { } 291 | function changeNameOwner(string _name, address _newOwner) { } 292 | function hideNameOwner(string _name, bool _hide) { } 293 | function assignName(string _name) { } 294 | function unassignName(string _name) { } 295 | ``` 296 | 297 | #### functions to return contract data state 298 | 299 | ##### addressOf 300 | 301 | ```js 302 | function addressOf(string _name) constant returns (address _addr) 303 | ``` 304 | Returns `address` of the destination of the name. 305 | 306 | ##### ownerOf 307 | ```js 308 | function ownerOf(string _name) constant returns (address _owner) 309 | ``` 310 | Returns `owner` of the name. 311 | 312 | ##### metadataOf 313 | ```js 314 | function metadataOf(string _name) constant returns (string memory _value) 315 | ``` 316 | Returns `owner` of the name. 317 | 318 | ##### assignation 319 | ```js 320 | function assignation(address _assignee) constant returns (string _name) 321 | ``` 322 | Returns `_name` that is currently assigned to `_assignee`. 323 | 324 | ##### name_assignation 325 | ```js 326 | function name_assignation(string _name) constant returns (address _assignee) 327 | ``` 328 | Returns `_assignee` address that is currently assigned to `_name`. 329 | 330 | 331 | 332 | ##### Debugging functions (for owner only) 333 | 334 | ##### change_FrontEnd 335 | ```js 336 | function change_FrontEnd(address _newFrontEnd) 337 | ``` 338 | 339 | Changes address of the storage to `_newFrontEnd`. 340 | 341 | ##### change_Owner 342 | ```js 343 | function change_Owner(address _newOwner) 344 | ``` 345 | 346 | Changes owner of the contract to `_newOwner`. 347 | 348 | 349 | ### Events 350 | 351 | ##### Error 352 | 353 | ```js 354 | event Error(bytes32) 355 | ``` 356 | Triggered when error occurs. 357 | 358 | ## Notes 359 | 360 | `MyContract` / ` something strange` / `%20%20%11` are valid names for DexNS. It has no checks for inputs. All names that you can imagine are valid. 361 | 362 | It can be a good idea to use versions for testing contracts: `MyTest v1.0.0` / `MyTest v9.256.122` etc. 363 | 364 | # Deploying DexNS contracts. 365 | 366 | 1. Compile and deploy the [DexNS storage](https://github.com/EthereumCommonwealth/DexNS/blob/master/DexNS_Storage.sol) contract. 367 | 368 | 2. Update the DexNS Frontend contract to init a db on a valid address (or change it after the contract is deployed): https://github.com/EthereumCommonwealth/DexNS/blob/master/DexNS_Frontend.sol#L112 369 | 370 | 3. Call the [change_Frontend_Address](https://github.com/EthereumCommonwealth/DexNS/blob/master/DexNS_Storage.sol#L399) function of the Storage contract to upload the address of the Frontend contract. 371 | -------------------------------------------------------------------------------- /TEST_Name_Receiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.15; 2 | 3 | // This contract is designed to illustrate a process of Name transfer handling 4 | // by third party contract. 5 | 6 | contract NameReceiver { 7 | event I_have_received_a_name(address indexed _from); 8 | event InternalInvocation(uint256 indexed _test); 9 | 10 | function onNameOwnerChanged(string _name, address _sender, bytes _data) { 11 | I_have_received_a_name(_sender); 12 | 13 | if(_data.length > 0) { 14 | this.call.value(0)(_data); 15 | } 16 | } 17 | 18 | function internalInvocation(uint256 _num) { 19 | InternalInvocation(_num); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /safeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | /** 5 | * @title SafeMath 6 | * @dev Math operations with safety checks that throw on error 7 | */ 8 | library SafeMath { 9 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 10 | if (a == 0) { 11 | return 0; 12 | } 13 | uint256 c = a * b; 14 | assert(c / a == b); 15 | return c; 16 | } 17 | 18 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 19 | // assert(b > 0); // Solidity automatically throws when dividing by 0 20 | uint256 c = a / b; 21 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 22 | return c; 23 | } 24 | 25 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 26 | assert(b <= a); 27 | return a - b; 28 | } 29 | 30 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 31 | uint256 c = a + b; 32 | assert(c >= a); 33 | return c; 34 | } 35 | } 36 | --------------------------------------------------------------------------------