commit
ac0a4e27ef
@ -0,0 +1,11 @@ |
||||
const EventEmitter = require('events') |
||||
|
||||
class ClickInstance extends EventEmitter { |
||||
command (index) { |
||||
index = index + 2 |
||||
this.api.click('.instance:nth-of-type(' + index + ') > div > button').perform(() => { this.emit('complete') }) |
||||
return this |
||||
} |
||||
} |
||||
|
||||
module.exports = ClickInstance |
@ -1,359 +0,0 @@ |
||||
'use strict' |
||||
var init = require('../helpers/init') |
||||
var sauce = require('./sauce') |
||||
|
||||
module.exports = { |
||||
before: function (browser, done) { |
||||
init(browser, done) |
||||
}, |
||||
'@sources': function () { |
||||
return sources |
||||
}, |
||||
'Test Simple Contract': function (browser) { |
||||
console.log('testSimpleContract') |
||||
browser.testContracts('Untitled.sol', sources[0]['browser/Untitled.sol'], ['test1', 'test2']) |
||||
}, |
||||
'Test Success Import': function (browser) { |
||||
console.log('testSuccessImport') |
||||
browser.addFile('Untitled1.sol', sources[1]['browser/Untitled1.sol']) |
||||
.addFile('Untitled2.sol', sources[1]['browser/Untitled2.sol']) |
||||
.switchFile('browser/Untitled1.sol') |
||||
.verifyContracts(['test6', 'test4', 'test5']) |
||||
}, |
||||
|
||||
'Test Failed Import': function (browser) { |
||||
console.log('testFailedImport') |
||||
browser.addFile('Untitled3.sol', sources[2]['browser/Untitled3.sol']) |
||||
.clickLaunchIcon('solidity') |
||||
.assert.containsText('#compileTabView .error pre', 'Unable to import "browser/Untitled11.sol": File not found') |
||||
}, |
||||
'Add Lib Test File': function (browser) { |
||||
browser.addFile('Untitled5.sol', sources[5]['browser/Untitled5.sol']) |
||||
}, |
||||
'Test Auto Deploy Lib': function (browser) { |
||||
console.log('testAutoDeployLib') |
||||
let addressRef |
||||
browser.verifyContracts(['test']) |
||||
.selectContract('test') |
||||
.createContract('') |
||||
.getAddressAtPosition(0, (address) => { |
||||
console.log('testAutoDeployLib ' + address) |
||||
addressRef = address |
||||
}) |
||||
.waitForElementPresent('.instance:nth-of-type(2)') |
||||
.click('.instance:nth-of-type(2) > div > button') |
||||
.perform((done) => { |
||||
browser.testConstantFunction(addressRef, 'get - call', '', '0: uint256: 45').perform(() => { |
||||
done() |
||||
}) |
||||
}) |
||||
}, |
||||
'Test Manual Deploy Lib': function (browser) { |
||||
console.log('testManualDeployLib') |
||||
browser.click('i[class^="clearinstance"]') |
||||
.pause(5000) |
||||
.clickLaunchIcon('settings') |
||||
.click('#generatecontractmetadata') |
||||
.clickLaunchIcon('solidity') |
||||
.click('#compileTabView button[title="Compile"]') // that should generate the JSON artefact
|
||||
.verifyContracts(['test']) |
||||
.selectContract('lib') // deploy lib
|
||||
.createContract('') |
||||
.perform((done) => { |
||||
browser.getAddressAtPosition(0, (address) => { |
||||
console.log(address) |
||||
checkDeployShouldFail(browser, () => { |
||||
checkDeployShouldSucceed(browser, address, () => { |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
||||
}) |
||||
}, |
||||
'Test Signature': function (browser) { |
||||
let hash, signature |
||||
browser.signMessage('test message', (h, s) => { |
||||
hash = h |
||||
signature = s |
||||
console.log('hash', hash) |
||||
console.log('signature', signature) |
||||
browser.assert.ok(typeof hash.value === 'string', 'type of hash.value must be String') |
||||
browser.assert.ok(typeof signature.value === 'string', 'type of signature.value must be String') |
||||
}) |
||||
.addFile('signMassage.sol', sources[6]['browser/signMassage.sol']) |
||||
.switchFile('browser/signMassage.sol') |
||||
.selectContract('ECVerify') |
||||
.createContract('') |
||||
.waitForElementPresent('.instance:nth-of-type(4)') |
||||
.click('.instance:nth-of-type(4) > div > button') |
||||
.perform((done) => { |
||||
browser.getAttribute('.instance:nth-of-type(4)', 'id', (result) => { |
||||
// skip 'instance' part of e.g. 'instance0x692a70d2e424a56d2c6c27aa97d1a86395877b3a'
|
||||
const address = result.value.slice('instance'.length) |
||||
console.log('Test Signature', result) |
||||
var inputs = `"${hash.value}","${signature.value}"` |
||||
console.log('Test Signature Input', inputs) |
||||
browser.clickFunction('ecrecovery - call', { types: 'bytes32 hash, bytes sig', values: inputs }) |
||||
.pause(5000) |
||||
.verifyCallReturnValue( |
||||
address, |
||||
['0: address: 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c']) |
||||
.perform(() => { |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
||||
.end() |
||||
}, |
||||
tearDown: sauce |
||||
} |
||||
|
||||
function checkDeployShouldFail (browser, callback) { |
||||
let config |
||||
browser.switchFile('browser/test.json') |
||||
.getEditorValue((content) => { |
||||
config = JSON.parse(content) |
||||
config.deploy['VM:-'].autoDeployLib = false |
||||
}) |
||||
.perform(() => { |
||||
browser.setEditorValue(JSON.stringify(config)) |
||||
}) |
||||
.switchFile('browser/Untitled5.sol') |
||||
.selectContract('test') // deploy lib
|
||||
.createContract('') |
||||
.assert.containsText('div[class^="terminal"]', '<address> is not a valid address') |
||||
.perform(() => { callback() }) |
||||
} |
||||
|
||||
function checkDeployShouldSucceed (browser, address, callback) { |
||||
let addressRef |
||||
let config |
||||
browser.switchFile('browser/test.json') |
||||
.getEditorValue((content) => { |
||||
config = JSON.parse(content) |
||||
config.deploy['VM:-'].autoDeployLib = false |
||||
config.deploy['VM:-']['linkReferences']['browser/Untitled5.sol'].lib = address |
||||
}) |
||||
.perform(() => { |
||||
browser.setEditorValue(JSON.stringify(config)) |
||||
}) |
||||
.switchFile('browser/Untitled5.sol') |
||||
.selectContract('test') // deploy lib
|
||||
.createContract('') |
||||
.getAddressAtPosition(1, (address) => { |
||||
addressRef = address |
||||
}) |
||||
.waitForElementPresent('.instance:nth-of-type(3)') |
||||
.click('.instance:nth-of-type(3) > div > button') |
||||
.perform(() => { |
||||
browser |
||||
.testConstantFunction(addressRef, 'get - call', '', '0: uint256: 45') |
||||
.perform(() => { callback() }) |
||||
}) |
||||
} |
||||
|
||||
/* |
||||
function testGitHubImport (browser, callback) { |
||||
contractHelper.addFile(browser, 'Untitled4.sol', sources[3]['browser/Untitled4.sol'], () => { |
||||
browser.pause(10000) |
||||
.perform(function () { |
||||
contractHelper.verifyContract(browser, ['browser/Untitled4.sol:test7', 'github.com/ethereum/ens/contracts/AbstractENS.sol:AbstractENS', 'github.com/ethereum/ens/contracts/ENS.sol:ENS'], function () { |
||||
callback(null, browser) |
||||
}) |
||||
}) |
||||
}) |
||||
} |
||||
*/ |
||||
|
||||
var abstractENS = ` |
||||
contract AbstractENS { |
||||
function owner(bytes32 node) public view returns(address); |
||||
function resolver(bytes32 node) public view returns(address); |
||||
function ttl(bytes32 node) public view returns(uint64); |
||||
function setOwner(bytes32 node, address owner) public; |
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public; |
||||
function setResolver(bytes32 node, address resolver) public; |
||||
function setTTL(bytes32 node, uint64 ttl) public; |
||||
|
||||
// Logged when the owner of a node assigns a new owner to a subnode.
|
||||
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); |
||||
|
||||
// Logged when the owner of a node transfers ownership to a new account.
|
||||
event Transfer(bytes32 indexed node, address owner); |
||||
|
||||
// Logged when the resolver for a node changes.
|
||||
event NewResolver(bytes32 indexed node, address resolver); |
||||
|
||||
// Logged when the TTL of a node changes
|
||||
event NewTTL(bytes32 indexed node, uint64 ttl); |
||||
}` |
||||
|
||||
var ENS = `pragma solidity ^0.4.0;
|
||||
|
||||
import './AbstractENS.sol'; |
||||
|
||||
/** |
||||
* The ENS registry contract. |
||||
*/ |
||||
contract ENS is AbstractENS { |
||||
struct Record { |
||||
address owner; |
||||
address resolver; |
||||
uint64 ttl; |
||||
} |
||||
|
||||
mapping(bytes32=>Record) records; |
||||
|
||||
// Permits modifications only by the owner of the specified node.
|
||||
modifier only_owner(bytes32 node) { |
||||
if (records[node].owner != msg.sender) revert(); |
||||
_; |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new ENS registrar. |
||||
*/ |
||||
constructor() public { |
||||
records[0].owner = msg.sender; |
||||
} |
||||
|
||||
/** |
||||
* Returns the address that owns the specified node. |
||||
*/ |
||||
function owner(bytes32 node) public view returns (address) { |
||||
return records[node].owner; |
||||
} |
||||
|
||||
/** |
||||
* Returns the address of the resolver for the specified node. |
||||
*/ |
||||
function resolver(bytes32 node) public view returns (address) { |
||||
return records[node].resolver; |
||||
} |
||||
|
||||
/** |
||||
* Returns the TTL of a node, and any records associated with it. |
||||
*/ |
||||
function ttl(bytes32 node) public view returns (uint64) { |
||||
return records[node].ttl; |
||||
} |
||||
|
||||
/** |
||||
* Transfers ownership of a node to a new address. May only be called by the current |
||||
* owner of the node. |
||||
* @param node The node to transfer ownership of. |
||||
* @param owner The address of the new owner. |
||||
*/ |
||||
function setOwner(bytes32 node, address owner) public only_owner(node) { |
||||
emit Transfer(node, owner); |
||||
records[node].owner = owner; |
||||
} |
||||
|
||||
/** |
||||
* Transfers ownership of a subnode sha3(node, label) to a new address. May only be |
||||
* called by the owner of the parent node. |
||||
* @param node The parent node. |
||||
* @param label The hash of the label specifying the subnode. |
||||
* @param owner The address of the new owner. |
||||
*/ |
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public only_owner(node) { |
||||
bytes32 subnode = keccak256(abi.encodePacked(node, label)); |
||||
emit NewOwner(node, label, owner); |
||||
records[subnode].owner = owner; |
||||
} |
||||
|
||||
/** |
||||
* Sets the resolver address for the specified node. |
||||
* @param node The node to update. |
||||
* @param resolver The address of the resolver. |
||||
*/ |
||||
function setResolver(bytes32 node, address resolver) public only_owner(node) { |
||||
emit NewResolver(node, resolver); |
||||
records[node].resolver = resolver; |
||||
} |
||||
|
||||
/** |
||||
* Sets the TTL for the specified node. |
||||
* @param node The node to update. |
||||
* @param ttl The TTL in seconds. |
||||
*/ |
||||
function setTTL(bytes32 node, uint64 ttl) public only_owner(node) { |
||||
emit NewTTL(node, ttl); |
||||
records[node].ttl = ttl; |
||||
} |
||||
}` |
||||
|
||||
var sources = [ |
||||
{ |
||||
'browser/Untitled.sol': {content: 'contract test1 {} contract test2 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled1.sol': {content: 'import "./Untitled2.sol"; contract test6 {}'}, |
||||
'browser/Untitled2.sol': {content: 'contract test4 {} contract test5 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled3.sol': {content: 'import "./Untitled11.sol"; contract test6 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'}, |
||||
'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS} |
||||
}, |
||||
{ |
||||
'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'}, |
||||
'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS}, |
||||
'github.com/ethereum/ens/contracts/AbstractENS.sol': {content: abstractENS} |
||||
}, |
||||
{ |
||||
'browser/Untitled5.sol': {content: `library lib {
|
||||
function getInt () public view returns (uint) { |
||||
return 45; |
||||
} |
||||
} |
||||
|
||||
contract test { |
||||
function get () public view returns (uint) { |
||||
return lib.getInt(); |
||||
} |
||||
}`}
|
||||
}, |
||||
{ |
||||
'browser/signMassage.sol': {content: ` |
||||
contract SignMassageTest { |
||||
function testRecovery(bytes32 h, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { |
||||
return ecrecover(h, v, r, s); |
||||
} |
||||
} |
||||
|
||||
library ECVerify { |
||||
function ecrecovery(bytes32 hash, bytes memory sig) public pure returns (address) { |
||||
bytes32 r; |
||||
bytes32 s; |
||||
uint8 v; |
||||
|
||||
if (sig.length != 65) { |
||||
return address(0); |
||||
} |
||||
|
||||
assembly { |
||||
r := mload(add(sig, 32)) |
||||
s := mload(add(sig, 64)) |
||||
v := and(mload(add(sig, 65)), 255) |
||||
} |
||||
|
||||
if (v < 27) { |
||||
v += 27; |
||||
} |
||||
|
||||
if (v != 27 && v != 28) { |
||||
return address(0); |
||||
} |
||||
|
||||
return ecrecover(hash, v, r, s); |
||||
} |
||||
|
||||
function ecverify(bytes32 hash, bytes memory sig, address signer) public pure returns (bool) { |
||||
return signer == ecrecovery(hash, sig); |
||||
} |
||||
}`}
|
||||
} |
||||
] |
@ -0,0 +1,115 @@ |
||||
'use strict' |
||||
var init = require('../helpers/init') |
||||
var sauce = require('./sauce') |
||||
|
||||
module.exports = { |
||||
before: function (browser, done) { |
||||
init(browser, done) |
||||
}, |
||||
'@sources': function () { |
||||
return sources |
||||
}, |
||||
'Add Lib Test File': function (browser) { |
||||
browser.addFile('Untitled5.sol', sources[0]['browser/Untitled5.sol']) |
||||
}, |
||||
'Test Auto Deploy Lib': function (browser) { |
||||
let addressRef |
||||
browser.verifyContracts(['test']) |
||||
.selectContract('test') |
||||
.createContract('') |
||||
.getAddressAtPosition(0, (address) => { |
||||
console.log('testAutoDeployLib ' + address) |
||||
addressRef = address |
||||
}) |
||||
.waitForElementPresent('.instance:nth-of-type(2)') |
||||
.click('.instance:nth-of-type(2) > div > button') |
||||
.perform((done) => { |
||||
browser.testConstantFunction(addressRef, 'get - call', '', '0: uint256: 45').perform(() => { |
||||
done() |
||||
}) |
||||
}) |
||||
}, |
||||
'Test Manual Deploy Lib': function (browser) { |
||||
console.log('testManualDeployLib') |
||||
browser.click('i[class^="clearinstance"]') |
||||
.pause(5000) |
||||
.clickLaunchIcon('settings') |
||||
.click('#generatecontractmetadata') |
||||
.clickLaunchIcon('solidity') |
||||
.click('#compileTabView button[title="Compile"]') // that should generate the JSON artefact
|
||||
.verifyContracts(['test']) |
||||
.selectContract('lib') // deploy lib
|
||||
.createContract('') |
||||
.perform((done) => { |
||||
browser.getAddressAtPosition(0, (address) => { |
||||
console.log(address) |
||||
checkDeployShouldFail(browser, () => { |
||||
checkDeployShouldSucceed(browser, address, () => { |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
||||
}) |
||||
}, |
||||
tearDown: sauce |
||||
} |
||||
|
||||
function checkDeployShouldFail (browser, callback) { |
||||
let config |
||||
browser.switchFile('browser/test.json') |
||||
.getEditorValue((content) => { |
||||
config = JSON.parse(content) |
||||
config.deploy['VM:-'].autoDeployLib = false |
||||
}) |
||||
.perform(() => { |
||||
browser.setEditorValue(JSON.stringify(config)) |
||||
}) |
||||
.switchFile('browser/Untitled5.sol') |
||||
.selectContract('test') // deploy lib
|
||||
.createContract('') |
||||
.assert.containsText('div[class^="terminal"]', '<address> is not a valid address') |
||||
.perform(() => { callback() }) |
||||
} |
||||
|
||||
function checkDeployShouldSucceed (browser, address, callback) { |
||||
let addressRef |
||||
let config |
||||
browser.switchFile('browser/test.json') |
||||
.getEditorValue((content) => { |
||||
config = JSON.parse(content) |
||||
config.deploy['VM:-'].autoDeployLib = false |
||||
config.deploy['VM:-']['linkReferences']['browser/Untitled5.sol'].lib = address |
||||
}) |
||||
.perform(() => { |
||||
browser.setEditorValue(JSON.stringify(config)) |
||||
}) |
||||
.switchFile('browser/Untitled5.sol') |
||||
.selectContract('test') // deploy lib
|
||||
.createContract('') |
||||
.getAddressAtPosition(1, (address) => { |
||||
addressRef = address |
||||
}) |
||||
.waitForElementPresent('.instance:nth-of-type(3)') |
||||
.click('.instance:nth-of-type(3) > div > button') |
||||
.perform(() => { |
||||
browser |
||||
.testConstantFunction(addressRef, 'get - call', '', '0: uint256: 45') |
||||
.perform(() => { callback() }) |
||||
}) |
||||
} |
||||
|
||||
var sources = [ |
||||
{ |
||||
'browser/Untitled5.sol': {content: `library lib {
|
||||
function getInt () public view returns (uint) { |
||||
return 45; |
||||
} |
||||
} |
||||
|
||||
contract test { |
||||
function get () public view returns (uint) { |
||||
return lib.getInt(); |
||||
} |
||||
}`}
|
||||
} |
||||
] |
@ -0,0 +1,89 @@ |
||||
'use strict' |
||||
var init = require('../helpers/init') |
||||
var sauce = require('./sauce') |
||||
|
||||
module.exports = { |
||||
before: function (browser, done) { |
||||
init(browser, done) |
||||
}, |
||||
'@sources': function () { |
||||
return sources |
||||
}, |
||||
'Test Signature': function (browser) { |
||||
let hash, signature |
||||
browser.clickLaunchIcon('run').signMessage('test message', (h, s) => { |
||||
hash = h |
||||
signature = s |
||||
console.log('hash', hash) |
||||
console.log('signature', signature) |
||||
browser.assert.ok(typeof hash.value === 'string', 'type of hash.value must be String') |
||||
browser.assert.ok(typeof signature.value === 'string', 'type of signature.value must be String') |
||||
}) |
||||
.addFile('signMassage.sol', sources[0]['browser/signMassage.sol']) |
||||
.switchFile('browser/signMassage.sol') |
||||
.selectContract('ECVerify') |
||||
.createContract('') |
||||
.clickInstance(0) |
||||
.perform((done) => { |
||||
browser.getAddressAtPosition(0, (address) => { |
||||
// skip 'instance' part of e.g. 'instance0x692a70d2e424a56d2c6c27aa97d1a86395877b3a'
|
||||
console.log('Test Signature address', address) |
||||
var inputs = `"${hash.value}","${signature.value}"` |
||||
console.log('Test Signature Input', inputs) |
||||
browser.clickFunction('ecrecovery - call', { types: 'bytes32 hash, bytes sig', values: inputs }) |
||||
.pause(5000) |
||||
.verifyCallReturnValue( |
||||
address, |
||||
['0: address: 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c']) |
||||
.perform(() => { |
||||
done() |
||||
}) |
||||
}) |
||||
}) |
||||
.end() |
||||
}, |
||||
tearDown: sauce |
||||
} |
||||
|
||||
var sources = [ |
||||
{ |
||||
'browser/signMassage.sol': {content: ` |
||||
contract SignMassageTest { |
||||
function testRecovery(bytes32 h, uint8 v, bytes32 r, bytes32 s) public pure returns (address) { |
||||
return ecrecover(h, v, r, s); |
||||
} |
||||
} |
||||
|
||||
library ECVerify { |
||||
function ecrecovery(bytes32 hash, bytes memory sig) public pure returns (address) { |
||||
bytes32 r; |
||||
bytes32 s; |
||||
uint8 v; |
||||
|
||||
if (sig.length != 65) { |
||||
return address(0); |
||||
} |
||||
|
||||
assembly { |
||||
r := mload(add(sig, 32)) |
||||
s := mload(add(sig, 64)) |
||||
v := and(mload(add(sig, 65)), 255) |
||||
} |
||||
|
||||
if (v < 27) { |
||||
v += 27; |
||||
} |
||||
|
||||
if (v != 27 && v != 28) { |
||||
return address(0); |
||||
} |
||||
|
||||
return ecrecover(hash, v, r, s); |
||||
} |
||||
|
||||
function ecverify(bytes32 hash, bytes memory sig, address signer) public pure returns (bool) { |
||||
return signer == ecrecovery(hash, sig); |
||||
} |
||||
}`}
|
||||
} |
||||
] |
@ -0,0 +1,169 @@ |
||||
'use strict' |
||||
var init = require('../helpers/init') |
||||
var sauce = require('./sauce') |
||||
|
||||
module.exports = { |
||||
before: function (browser, done) { |
||||
init(browser, done) |
||||
}, |
||||
'@sources': function () { |
||||
return sources |
||||
}, |
||||
'Test Simple Contract': function (browser) { |
||||
browser.testContracts('Untitled.sol', sources[0]['browser/Untitled.sol'], ['test1', 'test2']) |
||||
}, |
||||
'Test Success Import': function (browser) { |
||||
browser.addFile('Untitled1.sol', sources[1]['browser/Untitled1.sol']) |
||||
.addFile('Untitled2.sol', sources[1]['browser/Untitled2.sol']) |
||||
.switchFile('browser/Untitled1.sol') |
||||
.verifyContracts(['test6', 'test4', 'test5']) |
||||
}, |
||||
|
||||
'Test Failed Import': function (browser) { |
||||
browser.addFile('Untitled3.sol', sources[2]['browser/Untitled3.sol']) |
||||
.clickLaunchIcon('solidity') |
||||
.assert.containsText('#compileTabView .error pre', 'Unable to import "browser/Untitled11.sol": File not found') |
||||
.end() |
||||
}, |
||||
tearDown: sauce |
||||
} |
||||
|
||||
var abstractENS = ` |
||||
contract AbstractENS { |
||||
function owner(bytes32 node) public view returns(address); |
||||
function resolver(bytes32 node) public view returns(address); |
||||
function ttl(bytes32 node) public view returns(uint64); |
||||
function setOwner(bytes32 node, address owner) public; |
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public; |
||||
function setResolver(bytes32 node, address resolver) public; |
||||
function setTTL(bytes32 node, uint64 ttl) public; |
||||
|
||||
// Logged when the owner of a node assigns a new owner to a subnode.
|
||||
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); |
||||
|
||||
// Logged when the owner of a node transfers ownership to a new account.
|
||||
event Transfer(bytes32 indexed node, address owner); |
||||
|
||||
// Logged when the resolver for a node changes.
|
||||
event NewResolver(bytes32 indexed node, address resolver); |
||||
|
||||
// Logged when the TTL of a node changes
|
||||
event NewTTL(bytes32 indexed node, uint64 ttl); |
||||
}` |
||||
|
||||
var ENS = `pragma solidity ^0.4.0;
|
||||
|
||||
import './AbstractENS.sol'; |
||||
|
||||
/** |
||||
* The ENS registry contract. |
||||
*/ |
||||
contract ENS is AbstractENS { |
||||
struct Record { |
||||
address owner; |
||||
address resolver; |
||||
uint64 ttl; |
||||
} |
||||
|
||||
mapping(bytes32=>Record) records; |
||||
|
||||
// Permits modifications only by the owner of the specified node.
|
||||
modifier only_owner(bytes32 node) { |
||||
if (records[node].owner != msg.sender) revert(); |
||||
_; |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new ENS registrar. |
||||
*/ |
||||
constructor() public { |
||||
records[0].owner = msg.sender; |
||||
} |
||||
|
||||
/** |
||||
* Returns the address that owns the specified node. |
||||
*/ |
||||
function owner(bytes32 node) public view returns (address) { |
||||
return records[node].owner; |
||||
} |
||||
|
||||
/** |
||||
* Returns the address of the resolver for the specified node. |
||||
*/ |
||||
function resolver(bytes32 node) public view returns (address) { |
||||
return records[node].resolver; |
||||
} |
||||
|
||||
/** |
||||
* Returns the TTL of a node, and any records associated with it. |
||||
*/ |
||||
function ttl(bytes32 node) public view returns (uint64) { |
||||
return records[node].ttl; |
||||
} |
||||
|
||||
/** |
||||
* Transfers ownership of a node to a new address. May only be called by the current |
||||
* owner of the node. |
||||
* @param node The node to transfer ownership of. |
||||
* @param owner The address of the new owner. |
||||
*/ |
||||
function setOwner(bytes32 node, address owner) public only_owner(node) { |
||||
emit Transfer(node, owner); |
||||
records[node].owner = owner; |
||||
} |
||||
|
||||
/** |
||||
* Transfers ownership of a subnode sha3(node, label) to a new address. May only be |
||||
* called by the owner of the parent node. |
||||
* @param node The parent node. |
||||
* @param label The hash of the label specifying the subnode. |
||||
* @param owner The address of the new owner. |
||||
*/ |
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public only_owner(node) { |
||||
bytes32 subnode = keccak256(abi.encodePacked(node, label)); |
||||
emit NewOwner(node, label, owner); |
||||
records[subnode].owner = owner; |
||||
} |
||||
|
||||
/** |
||||
* Sets the resolver address for the specified node. |
||||
* @param node The node to update. |
||||
* @param resolver The address of the resolver. |
||||
*/ |
||||
function setResolver(bytes32 node, address resolver) public only_owner(node) { |
||||
emit NewResolver(node, resolver); |
||||
records[node].resolver = resolver; |
||||
} |
||||
|
||||
/** |
||||
* Sets the TTL for the specified node. |
||||
* @param node The node to update. |
||||
* @param ttl The TTL in seconds. |
||||
*/ |
||||
function setTTL(bytes32 node, uint64 ttl) public only_owner(node) { |
||||
emit NewTTL(node, ttl); |
||||
records[node].ttl = ttl; |
||||
} |
||||
}` |
||||
|
||||
var sources = [ |
||||
{ |
||||
'browser/Untitled.sol': {content: 'contract test1 {} contract test2 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled1.sol': {content: 'import "./Untitled2.sol"; contract test6 {}'}, |
||||
'browser/Untitled2.sol': {content: 'contract test4 {} contract test5 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled3.sol': {content: 'import "./Untitled11.sol"; contract test6 {}'} |
||||
}, |
||||
{ |
||||
'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'}, |
||||
'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS} |
||||
}, |
||||
{ |
||||
'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'}, |
||||
'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS}, |
||||
'github.com/ethereum/ens/contracts/AbstractENS.sol': {content: abstractENS} |
||||
} |
||||
] |
Loading…
Reference in new issue