Merge pull request #452 from embark-framework/DomainNameResolution

ENS Domain name resolution initial integration
This commit is contained in:
Iuri Matias 2018-05-27 08:12:26 -04:00 committed by GitHub
commit 8fa325a7af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2490 additions and 2086 deletions

View File

@ -272,6 +272,51 @@ EmbarkJS.Messages.listenTo = function(options, callback) {
return this.currentMessages.listenTo(options, callback); return this.currentMessages.listenTo(options, callback);
}; };
EmbarkJS.Names = {};
EmbarkJS.Names.Providers = {};
EmbarkJS.Names.registerProvider = function(providerName, obj) {
EmbarkJS.Names.Providers[providerName] = obj;
}
EmbarkJS.Names.setProvider = function(provider, options) {
let providerObj = this.Providers[provider];
if (!providerObj) {
throw new Error('Unknown name system provider');
}
this.currentNameSystems = providerObj;
return providerObj.setProvider(options);
};
// resolve resolves a name into an identifier of some kind
EmbarkJS.Names.resolve = function(name) {
if (!this.currentNameSystems) {
throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")');
}
return this.currentNameSystems.resolve(name);
}
// the reverse of resolve, resolves using an identifier to get to a name
EmbarkJS.Names.lookup = function(identifier) {
if (!this.currentNameSystems) {
throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")');
}
return this.currentNameSystems.lookup(name);
}
// To Implement
/*
// register a name
EmbarkJS.Names.register = function(name, options) {
}
*/
EmbarkJS.Utils = { EmbarkJS.Utils = {
fromAscii: function(str) { fromAscii: function(str) {
var _web3 = new Web3(); var _web3 = new Web3();

View File

@ -45,6 +45,7 @@ Config.prototype.loadConfigFiles = function(options) {
this.loadBlockchainConfigFile(); this.loadBlockchainConfigFile();
this.loadStorageConfigFile(); this.loadStorageConfigFile();
this.loadCommunicationConfigFile(); this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadContractsConfigFile(); this.loadContractsConfigFile();
this.loadPipelineConfigFile(); this.loadPipelineConfigFile();
@ -63,6 +64,7 @@ Config.prototype.reloadConfig = function() {
this.loadBlockchainConfigFile(); this.loadBlockchainConfigFile();
this.loadStorageConfigFile(); this.loadStorageConfigFile();
this.loadCommunicationConfigFile(); this.loadCommunicationConfigFile();
this.loadNameSystemConfigFile();
this.loadContractsConfigFile(); this.loadContractsConfigFile();
this.loadPipelineConfigFile(); this.loadPipelineConfigFile();
this.loadContractsConfigFile(); this.loadContractsConfigFile();
@ -228,6 +230,20 @@ Config.prototype.loadStorageConfigFile = function() {
this.storageConfig = this._mergeConfig(configFilePath, configObject, this.env); this.storageConfig = this._mergeConfig(configFilePath, configObject, this.env);
}; };
Config.prototype.loadNameSystemConfigFile = function() {
// todo: spec out names for registration in the file itself for a dev chain
var configObject = {
"default": {
"available_providers": ["ens"],
"provider": "ens"
}
};
let configFilePath = this._getFileOrOject(this.configDir, 'namesystem', 'namesystem');
this.namesystemConfig = this._mergeConfig(configFilePath, configObject, this.env);
};
Config.prototype.loadCommunicationConfigFile = function() { Config.prototype.loadCommunicationConfigFile = function() {
var configObject = { var configObject = {
"default": { "default": {

View File

@ -105,6 +105,7 @@ class Engine {
"deployment": this.deploymentService, "deployment": this.deploymentService,
"fileWatcher": this.fileWatchService, "fileWatcher": this.fileWatchService,
"webServer": this.webServerService, "webServer": this.webServerService,
"namingSystem": this.namingSystem,
"ipfs": this.ipfsService, "ipfs": this.ipfsService,
"web3": this.web3Service, "web3": this.web3Service,
"libraryManager": this.libraryManagerService, "libraryManager": this.libraryManagerService,

View File

@ -123,6 +123,7 @@ class Embark {
engine.startService("pipeline"); engine.startService("pipeline");
engine.startService("deployment"); engine.startService("deployment");
engine.startService("codeGenerator"); engine.startService("codeGenerator");
engine.startService("namingSystem");
// TODO: this should be just 'storage' and the storage should figure out the module // TODO: this should be just 'storage' and the storage should figure out the module
engine.startService(engine.config.storageConfig.provider); engine.startService(engine.config.storageConfig.provider);

296
lib/modules/ens/embarkjs.js Normal file
View File

@ -0,0 +1,296 @@
const namehash = require('eth-ens-namehash');
/*global web3*/
let __embarkENS = {};
// registry interface for later
__embarkENS.registryInterface = [
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "resolver",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "resolver",
"type": "address"
}
],
"name": "setResolver",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "label",
"type": "bytes32"
},
{
"name": "owner",
"type": "address"
}
],
"name": "setSubnodeOwner",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "owner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"type": "function"
}
];
__embarkENS.resolverInterface = [
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "addr",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "content",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
}
],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "kind",
"type": "bytes32"
}
],
"name": "has",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "addr",
"type": "address"
}
],
"name": "setAddr",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "hash",
"type": "bytes32"
}
],
"name": "setContent",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "name",
"type": "string"
}
],
"name": "setName",
"outputs": [],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "node",
"type": "bytes32"
},
{
"name": "contentType",
"type": "uint256"
}
],
"name": "ABI",
"outputs": [
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"type": "function"
}
];
__embarkENS.registryAddresses = {
// Mainnet
"1": "0x314159265dd8dbb310642f98f50c066173c1259b",
// Ropsten
"3": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
// Rinkeby
"4": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
};
__embarkENS.setProvider = function () {
// get network id and then assign ENS contract based on that
let registryAddresses = this.registryAddresses;
this.ens = web3.eth.net.getId().then(id => {
if (registryAddresses[id] !== undefined) {
return new web3.eth.Contract(this.registryInterface, registryAddresses[id]);
}
// todo: deploy at this point
return undefined;
});
};
__embarkENS.resolve = function(name) {
const self = this;
if (self.ens === undefined) return undefined;
let node = namehash(name);
self.ens.methods.resolver(node).call().then((resolverAddress) => {
let resolverContract = new web3.eth.Contract(self.resolverInterface, resolverAddress);
return resolverContract.methods.addr(node).call();
}).then((addr) => {
return addr;
}).catch(err => err);
};
__embarkENS.lookup = function(address) {
const self = this;
if (self.ens === undefined) return undefined;
if (address.startsWith("0x")) address = address.slice(2);
let node = namehash(address.toLowerCase() + ".addr.reverse");
self.ens.methods.resolver(node).call().then((resolverAddress) => {
let resolverContract = new web3.eth.Contract(self.resolverInterface, resolverAddress);
return resolverContract.methods.name(node).call();
}).then((name) => {
if (name === "" || name === undefined) throw Error("ENS name not found");
return name;
}).catch(err => err);
};

56
lib/modules/ens/index.js Normal file
View File

@ -0,0 +1,56 @@
const fs = require('../../core/fs.js');
const utils = require('../../utils/utils.js');
class ENS {
constructor(embark, options) {
this.logger = embark.logger;
this.events = embark.events;
this.web3 = options.web3;
this.namesConfig = options.namesConfig;
this.embark = embark;
this.addENSToEmbarkJS();
this.addSetProvider();
}
addENSToEmbarkJS() {
const self = this;
// TODO: make this a shouldAdd condition
if (this.namesConfig === {}) {
return;
}
if ((this.namesConfig.available_providers.indexOf('ens') < 0) && (this.namesConfig.provider !== 'ens' || this.namesConfig.enabled !== true)) {
return;
}
self.events.request("version:get:eth-ens-namehash", function(EnsNamehashVersion) {
let currentEnsNamehashVersion = require('../../../package.json').dependencies["eth-ens-namehash"];
if (EnsNamehashVersion !== currentEnsNamehashVersion) {
self.events.request("version:getPackageLocation", "eth-ens-namehash", EnsNamehashVersion, function(err, location) {
self.embark.registerImportFile("eth-ens-namehash", fs.dappPath(location));
});
}
});
let code = "";
code += "\n" + fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Names.registerProvider('ens', __embarkENS);";
this.embark.addCodeToEmbarkJS(code);
}
addSetProvider() {
let config = JSON.stringify({});
let code = "\nEmbarkJS.Names.setProvider('ens'," + config + ");";
let shouldInit = (namesConfig) => {
return (namesConfig.provider === 'ens' && namesConfig.enabled === true);
};
this.embark.addProviderInit('names', code, shouldInit);
}
}
module.exports = ENS;

4154
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,7 @@
"css-loader": "^0.28.11", "css-loader": "^0.28.11",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"ejs": "^2.5.8", "ejs": "^2.5.8",
"eth-ens-namehash": "^2.0.8",
"eth-lib": "^0.2.8", "eth-lib": "^0.2.8",
"ethereumjs-testrpc": "^6.0.3", "ethereumjs-testrpc": "^6.0.3",
"ethereumjs-wallet": "^0.6.0", "ethereumjs-wallet": "^0.6.0",

View File

@ -0,0 +1,6 @@
{
"default": {
"available_providers": ["ens"],
"provider": "ens"
}
}

View File

@ -0,0 +1,6 @@
{
"default": {
"available_providers": ["ens"],
"provider": "ens"
}
}