mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
Merge pull request #1 from ethereum/swarm
getting up to date with upsteam
This commit is contained in:
commit
d9fb99c4b3
18 changed files with 1254 additions and 1344 deletions
|
|
@ -117,19 +117,11 @@ web3._extend({
|
||||||
property: 'ens',
|
property: 'ens',
|
||||||
methods:
|
methods:
|
||||||
[
|
[
|
||||||
new web3._extend.Method({
|
|
||||||
name: 'deployRegistrar',
|
|
||||||
call: 'ens_deployRegistrar',
|
|
||||||
}),
|
|
||||||
new web3._extend.Method({
|
|
||||||
name: 'deployResolver',
|
|
||||||
call: 'ens_deployResolver',
|
|
||||||
}),
|
|
||||||
new web3._extend.Method({
|
new web3._extend.Method({
|
||||||
name: 'register',
|
name: 'register',
|
||||||
call: 'ens_register',
|
call: 'ens_register',
|
||||||
params: 2,
|
params: 1,
|
||||||
inputFormatter: [null, null]
|
inputFormatter: [null]
|
||||||
}),
|
}),
|
||||||
new web3._extend.Method({
|
new web3._extend.Method({
|
||||||
name: 'setContentHash',
|
name: 'setContentHash',
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const (
|
||||||
|
|
||||||
// by default ens root is north internal
|
// by default ens root is north internal
|
||||||
var (
|
var (
|
||||||
toyNetEnsRoot = common.HexToAddress("0x606aabab27f8aa98b772bf593b18e550ede87176")
|
toyNetEnsRoot = common.HexToAddress("0xd344889e0be3e9ef6c26b0f60ef66a32e83c1b69")
|
||||||
)
|
)
|
||||||
|
|
||||||
// separate bzz directories
|
// separate bzz directories
|
||||||
|
|
|
||||||
60
swarm/cmd/makegenesis/genesis.json
Normal file
60
swarm/cmd/makegenesis/genesis.json
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"nonce": "0x42",
|
||||||
|
"gasLimit": "0x47e7c4",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"alloc": {
|
||||||
|
"866b5394fe446751e932b7ef77280f4ab7ea3afe": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "01c51307a94a7800"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000000": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "3aecf856b58800"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000001": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "01"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000002": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "01"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000003": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "01"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000004": {
|
||||||
|
"code": "",
|
||||||
|
"storage": {},
|
||||||
|
"balance": "01"
|
||||||
|
},
|
||||||
|
"cb7152b03774fd01a8480001b2bcdfebc4f04363": {
|
||||||
|
"code": "6060604052361561004b5760e060020a60003504632dff694181146100535780633b3b57de1461007557806341b9dc2b146100a0578063c3d014d614610139578063d5fa2b00146101b2575b61022b610002565b61022d6004356000818152600260205260408120549081141561027057610002565b61023f600435600081815260016020526040812054600160a060020a03169081141561027057610002565b61025c60043560243560007f6164647200000000000000000000000000000000000000000000000000000000821480156100f05750600083815260016020526040812054600160a060020a031614155b8061013257507f636f6e74656e740000000000000000000000000000000000000000000000000082148015610132575060008381526002602052604081205414155b9392505050565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a031691909114905061027557610002565b61022b600435602435600080546040805160e060020a6302571be30281526004810186905290518593600160a060020a033381169416926302571be392602482810193602093839003909101908290876161da5a03f11561000257505060405151600160a060020a03169190911490506102c157610002565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b919050565b6000838152600260209081526040918290208490558151848152915185927f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc92908290030190a2505050565b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916851790558151600160a060020a0385168152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a250505056",
|
||||||
|
"storage": {
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000": "d344889e0be3e9ef6c26b0f60ef66a32e83c1b69"
|
||||||
|
},
|
||||||
|
"balance": ""
|
||||||
|
},
|
||||||
|
"d344889e0be3e9ef6c26b0f60ef66a32e83c1b69": {
|
||||||
|
"code": "606060405260e060020a60003504630178b8bf811461004757806302571be31461006e5780631896f70a14610091578063569cd595146100c55780635b0fc9c3146100fc575b005b610130600435600081815260208190526040902060010154600160a060020a03165b919050565b610130600435600081815260208190526040902054600160a060020a0316610069565b6100456004356024356000828152602081905260409020548290600160a060020a0390811633919091161461014d57610002565b6100456004356024356044356000838152602081905260408120548490600160a060020a039081163391909116146101bf57610002565b6100456004356024356000828152602081905260409020548290600160a060020a0390811633919091161461025957610002565b60408051600160a060020a03929092168252519081900360200190f35b60408051600160a060020a0384168152905184917f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0919081900360200190a2506000828152602081905260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916821790555050565b60408051868152602081810187905282519182900383018220600160a060020a03871683529251929450869288927fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e8292908290030190a382600060005060008460001916815260200190815260200160002060005060000160006101000a815481600160a060020a03021916908302179055505050505050565b60408051600160a060020a0384168152905184917fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266919081900360200190a2506000828152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff191682179055505056",
|
||||||
|
"storage": {
|
||||||
|
"859ecef2e168dc10231b000bd53493b42bc9d944cac29d94582c1e1d43592131": "582c767cca9d78699b04ba8dd7c33071f2d74003"
|
||||||
|
},
|
||||||
|
"balance": ""
|
||||||
|
},
|
||||||
|
"582c767cca9d78699b04ba8dd7c33071f2d74003": {
|
||||||
|
"code": "606060405260e060020a6000350463d22057a9811461001b575b005b61001960043560243560025460408051918252602082810185905260008054835194859003840185207f02571be300000000000000000000000000000000000000000000000000000000865260048601819052935193949193600160a060020a03909116926302571be39260248181019391829003018187876161da5a03f11561000257505060405151915050600160a060020a0381166000148015906100d4575033600160a060020a031681600160a060020a031614155b156100de57610002565b60408051600080546002547f569cd59500000000000000000000000000000000000000000000000000000000845260048401526024830188905230600160a060020a039081166044850152935193169263569cd595926064818101939291829003018183876161da5a03f11561000257505060008054600154604080517f1896f70a00000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a0392831660248201529051929091169350631896f70a926044828101939192829003018183876161da5a03f11561000257505060008054604080517f5b0fc9c300000000000000000000000000000000000000000000000000000000815260048101879052600160a060020a0388811660248301529151929091169350635b0fc9c3926044828101939192829003018183876161da5a03f115610002575050505050505056",
|
||||||
|
"storage": {
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000": "d344889e0be3e9ef6c26b0f60ef66a32e83c1b69",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000001": "cb7152b03774fd01a8480001b2bcdfebc4f04363",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000002": "93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"
|
||||||
|
},
|
||||||
|
"balance": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
103
swarm/cmd/makegenesis/makegenesis.js
Normal file
103
swarm/cmd/makegenesis/makegenesis.js
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
var Account = require('ethereumjs-account');
|
||||||
|
var async = require('async');
|
||||||
|
var fs = require('fs');
|
||||||
|
var rlp = require('rlp');
|
||||||
|
var solc = require('solc');
|
||||||
|
var Transaction = require('ethereumjs-tx');
|
||||||
|
var Trie = require('merkle-patricia-tree');
|
||||||
|
var utils = require('ethereumjs-util');
|
||||||
|
var VM = require('ethereumjs-vm');
|
||||||
|
|
||||||
|
var stateTrie = new Trie();
|
||||||
|
var vm = new VM(stateTrie);
|
||||||
|
|
||||||
|
var privatekey = utils.sha3("swarm");
|
||||||
|
var accountAddress = utils.privateToAddress(privatekey);
|
||||||
|
|
||||||
|
var accounts = {
|
||||||
|
"0000000000000000000000000000000000000001": "0x1",
|
||||||
|
"0000000000000000000000000000000000000002": "0x1",
|
||||||
|
"0000000000000000000000000000000000000003": "0x1",
|
||||||
|
"0000000000000000000000000000000000000004": "0x1",
|
||||||
|
};
|
||||||
|
accounts[accountAddress.toString('hex')] = "0x200000000000000";
|
||||||
|
|
||||||
|
var source = fs.readFileSync('../../services/ens/contract/ens.sol').toString();
|
||||||
|
var compiled = solc.compile(source, 1)
|
||||||
|
var deployer = "0x" + compiled.contracts['DeployENS'].bytecode;
|
||||||
|
|
||||||
|
var transactions = [
|
||||||
|
{
|
||||||
|
nonce: '0x00',
|
||||||
|
gasPrice: '0x4a817c800',
|
||||||
|
gasLimit: '0x3d0900',
|
||||||
|
value: '0x00',
|
||||||
|
data: deployer
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function createAccounts(cb) {
|
||||||
|
async.each(Object.keys(accounts), function(addr, next) {
|
||||||
|
var account = new Account();
|
||||||
|
account.balance = accounts[addr];
|
||||||
|
stateTrie.put(new Buffer(addr, 'hex'), account.serialize(), next);
|
||||||
|
}, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTx(cb) {
|
||||||
|
async.each(transactions, function(txdata, next) {
|
||||||
|
var tx = new Transaction(txdata);
|
||||||
|
tx.sign(privatekey);
|
||||||
|
vm.runTx({tx: tx}, next);
|
||||||
|
}, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dumpState(cb) {
|
||||||
|
var stream = stateTrie.createReadStream();
|
||||||
|
|
||||||
|
var accountList = [];
|
||||||
|
stream.on('data', function(data) {
|
||||||
|
accountList.push(data);
|
||||||
|
});
|
||||||
|
stream.on('end', function(err) {
|
||||||
|
var accountData = {};
|
||||||
|
async.each(accountList, function(data, next) {
|
||||||
|
var storage = {};
|
||||||
|
|
||||||
|
var account = new Account(data.value);
|
||||||
|
var storageTrie = stateTrie.copy();
|
||||||
|
storageTrie.root = account.stateRoot;
|
||||||
|
|
||||||
|
var storageStream = storageTrie.createReadStream();
|
||||||
|
storageStream.on('data', function(data) {
|
||||||
|
storage[data.key.toString('hex')] = rlp.decode(data.value).toString('hex')
|
||||||
|
});
|
||||||
|
storageStream.on('end', function(err) {
|
||||||
|
account.getCode(stateTrie, function(err, code) {
|
||||||
|
var address = data.key.toString('hex');
|
||||||
|
accountData[address] = {
|
||||||
|
code: code.toString('hex'),
|
||||||
|
storage: storage,
|
||||||
|
balance: account.balance.toString('hex')
|
||||||
|
};
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}, function(err) {
|
||||||
|
console.log(JSON.stringify({
|
||||||
|
nonce: '0x42',
|
||||||
|
gasLimit: '0x47e7c4',
|
||||||
|
difficulty: '0x20000',
|
||||||
|
alloc: accountData
|
||||||
|
}, null, 4));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
createAccounts,
|
||||||
|
runTx,
|
||||||
|
dumpState
|
||||||
|
], function(err) {
|
||||||
|
console.log("Error: " + err);
|
||||||
|
});
|
||||||
15
swarm/cmd/makegenesis/package.json
Normal file
15
swarm/cmd/makegenesis/package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "makegenesis",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^2.0.1",
|
||||||
|
"ethereumjs-account": "^2.0.3",
|
||||||
|
"ethereumjs-block": "^1.2.2",
|
||||||
|
"ethereumjs-tx": "^1.1.2",
|
||||||
|
"ethereumjs-util": "^4.5.0",
|
||||||
|
"ethereumjs-vm": "^1.4.0",
|
||||||
|
"merkle-patricia-tree": "^2.1.2",
|
||||||
|
"rlp": "^2.0.0",
|
||||||
|
"solc": "0.3.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,9 +27,11 @@ contract chequebook is mortal {
|
||||||
if(owner != ecrecover(hash, sig_v, sig_r, sig_s)) return;
|
if(owner != ecrecover(hash, sig_v, sig_r, sig_s)) return;
|
||||||
// Attempt sending the difference between the cumulative amount on the cheque
|
// Attempt sending the difference between the cumulative amount on the cheque
|
||||||
// and the cumulative amount on the last cashed cheque to beneficiary.
|
// and the cumulative amount on the last cashed cheque to beneficiary.
|
||||||
|
if (amount - sent[beneficiary] >= this.balance) {
|
||||||
if (beneficiary.send(amount - sent[beneficiary])) {
|
if (beneficiary.send(amount - sent[beneficiary])) {
|
||||||
// Upon success, update the cumulative amount.
|
// Upon success, update the cumulative amount.
|
||||||
sent[beneficiary] = amount;
|
sent[beneficiary] = amount;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Upon failure, punish owner for writing a bounced cheque.
|
// Upon failure, punish owner for writing a bounced cheque.
|
||||||
// owner.sendToDebtorsPrison();
|
// owner.sendToDebtorsPrison();
|
||||||
|
|
|
||||||
|
|
@ -2,63 +2,33 @@
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Full documentation for the Ethereum Name Service [can be found as EIP]()
|
Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/ethereum/EIPs/issues/137)
|
||||||
Swarm offers a simple phase-one interface that streamlines the registration of swarm content hashes to arbitrary utf8 domain names.
|
Swarm offers a simple phase-one interface that streamlines the registration of swarm content hashes to arbitrary utf8 domain names.
|
||||||
The interface is offered through the ENS RPC API module under the `ens` namespace. The API can be used via the console, rpc or web3.js.
|
The interface is offered through the ENS RPC API module under the `ens` namespace. The API can be used via the console, rpc or web3.js.
|
||||||
|
|
||||||
### `ens.deployRegistrar()`
|
### `ens.register(name)`
|
||||||
|
|
||||||
sends a contract creation transaction from your bzz account deploying an open registrar contract which can serve as ENS root resolver. A root resolver is deployed on the testnet and set as default for EnsRoot. Alternative can be given by changing the `ENSRoot` parameter in swarm `config.json` file.
|
Sends a transaction that registers a name as a top-level domain, giving ownership to the current account, and automatically deploying a simple resolver contract for it.
|
||||||
|
|
||||||
To deploy an alternative top-level domain root resolver:
|
This line registers the top-level domain `swarm`:
|
||||||
|
|
||||||
```js
|
|
||||||
registrarAddr=ens.deployRegistrar()
|
|
||||||
// "0xa90b9572f094660f8f314b591a365985e98d2fd0"
|
|
||||||
eth.getCode(registrarAddr) // check if contract was successfully deployed
|
|
||||||
// "0x" // not mined yet
|
|
||||||
// miner.start(1) // to start mining on a private chain
|
|
||||||
// true
|
|
||||||
```
|
|
||||||
|
|
||||||
### `ens.deployResolver()`
|
|
||||||
|
|
||||||
sends a contract creation transaction from your bzz account deploying a simple personal resolver contract, that can be registered with a (sub)domain on the root resolver. As a result the root resolver will delegate all hostnames under that domain to the child resolver.
|
|
||||||
|
|
||||||
To deploy a personal resolver:
|
|
||||||
|
|
||||||
```js
|
|
||||||
resolverAddr = ens.deployResolver()
|
|
||||||
// "0x2ba72b924a7d654c54467f7bda035ddc2f6fb4eb"
|
|
||||||
eth.getCode(registrarAddr) // check if contract was successfully deployed
|
|
||||||
// "0x" // not mined yet
|
|
||||||
// miner.start(1) // to start mining on a private chain
|
|
||||||
// true
|
|
||||||
```
|
|
||||||
|
|
||||||
### `ens.register(name, address)`
|
|
||||||
|
|
||||||
Sends a transaction that registers a resolver contract with domain on the top-level resolver.
|
|
||||||
As a result the bzz account becomes the owner of that domain.
|
|
||||||
This line registers the (already deployed) personal resolver at address `resolverAddr` to the top-level domain `swarm`
|
|
||||||
|
|
||||||
```
|
```
|
||||||
ens.register("swarm",resolverAddr)
|
ens.register("swarm")
|
||||||
// {}
|
// {}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `ens.setContentHash(name, hash)`
|
### `ens.setContentHash(name, hash)`
|
||||||
|
|
||||||
sends a transaction that sets a content hash to a name using a (sub-domain) resolver:
|
Sends a transaction that sets a content hash to a name using a (sub-domain) resolver:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
ens.setContentHash("swarm","0x7420f14a28e276dd39da6a967dec332a932256717451155fbd3870b202b561c4")
|
ens.setContentHash("swarm","0x7420f14a28e276dd39da6a967dec332a932256717451155fbd3870b202b561c4")
|
||||||
// {}
|
// {}
|
||||||
```
|
```
|
||||||
|
|
||||||
The content hash argument is the bzz hash as returned by a swarm upload, e.g., using `bzz.upload`:
|
To function, the domain must have a resolver deployed that supports the `setContent` function, and the sending account must have permission to call that function. `ens.register()` deploys a resolver for you that meets this requirement.
|
||||||
The name here will allow the name setting, if the top-level domain is 'swarm', it dispatches to the
|
|
||||||
resolver just registered.
|
The content hash argument is the bzz hash as returned by a swarm upload, e.g., using `bzz.upload`. The name here will allow the name setting, if the top-level domain is 'swarm', it dispatches to the resolver just registered.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
bzz.upload("path/to/my/directory", "index.html")
|
bzz.upload("path/to/my/directory", "index.html")
|
||||||
|
|
@ -66,7 +36,7 @@ bzz.upload("path/to/my/directory", "index.html")
|
||||||
|
|
||||||
Here the second argument to `bzz.upload` is the relative path to the asset mapped on to the root hash of entire collection, effectively the landing page served on the bare hash (and therefore the root of the domain registered with that hash) as url.
|
Here the second argument to `bzz.upload` is the relative path to the asset mapped on to the root hash of entire collection, effectively the landing page served on the bare hash (and therefore the root of the domain registered with that hash) as url.
|
||||||
|
|
||||||
The same resolver will allow setting subdomains:
|
`setContentHash` can also be used on subdomains:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
ens.setContentHash("album.swarm","7a59235e5f9c23bf74deb4838e24f75a77f786163f404c8004d79b5674625db0")
|
ens.setContentHash("album.swarm","7a59235e5f9c23bf74deb4838e24f75a77f786163f404c8004d79b5674625db0")
|
||||||
|
|
@ -88,20 +58,10 @@ This same backend method is used within swarm to resolve hostnames in urls, henc
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
The ABI and BIN files in contract subdirectory implement simple registrar and personal resolver contracts; they're used in tests, and can be used to deploy these contracts for your own purposes.
|
The SOL file in contract subdirectory implements the ENS root registry, a simple first-in-first-served registrar for the root namespace, and a simple resolver contract; they're used in tests, and can be used to deploy these contracts for your own purposes.
|
||||||
|
|
||||||
The solidity source code can be found at [github.com/arachnid/ens/](https://github.com/arachnid/ens/).
|
The solidity source code can be found at [github.com/arachnid/ens/](https://github.com/arachnid/ens/).
|
||||||
|
|
||||||
The ABI and BIN files in the contract subdirectory were generated by
|
|
||||||
|
|
||||||
```shell
|
|
||||||
solc -o `pwd` --optimise --abi --bin OpenRegistrar.sol
|
|
||||||
solc -o `pwd` --optimise --abi --bin PersonalResolver.sol
|
|
||||||
```
|
|
||||||
|
|
||||||
using the .sol files in [revision 1cbd90d0631e8e30e1c28a394c128e7503ea85c6](https://github.com/Arachnid/ens/commit/1cbd90d0631e8e30e1c28a394c128e7503ea85c6)
|
|
||||||
with solc version 0.3.2-e3c54185
|
|
||||||
|
|
||||||
The go bindings for ENS contracts are generated using `abigen` via the go generator:
|
The go bindings for ENS contracts are generated using `abigen` via the go generator:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
[{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"id","type":"bytes32"}],"name":"getExtended","outputs":[{"name":"data","type":"bytes"}],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"qtype","type":"bytes32"},{"name":"index","type":"uint16"}],"name":"resolve","outputs":[{"name":"rcode","type":"uint16"},{"name":"rtype","type":"bytes16"},{"name":"ttl","type":"uint32"},{"name":"len","type":"uint16"},{"name":"data","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"resolver","type":"address"},{"name":"nodeId","type":"bytes12"}],"name":"register","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"label","type":"bytes32"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"label","type":"bytes32"}],"name":"findResolver","outputs":[{"name":"rcode","type":"uint16"},{"name":"ttl","type":"uint32"},{"name":"rnode","type":"bytes12"},{"name":"raddress","type":"address"}],"type":"function"}]
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
6060604052610348806100126000396000f3606060405236156100565760e060020a60003504635b0fc9c381146100585780638021061c1461007a578063a16fdafa14610097578063a1f8f8f0146100c0578063deb931a2146100e5578063edc0277c1461010b575b005b610056600435602435600081600160a060020a03166000141561023357610002565b6101516004356000606081905260a060405260809081525b919050565b6101bf6004356024356044356000808080808781146100b557600394505b939792965093509350565b610056600435602435604435600082600160a060020a03166000141561028057610002565b6101e5600435600081815260208190526040902060010154600160a060020a0316610092565b6102026004356024356000818152602081905260408120819081908190868214158061014357506001810154600160a060020a031682145b15610320576003945061033e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b50505061ffff919091166060908152608082905260a082815260c083905260e092909252f35b60408051600160a060020a03929092168252519081900360200190f35b61ffff93909316606090815263ffffffff92909216608090815260a091909152600160a060020a039290921660c052f35b828152602081905260409020600181015433600160a060020a0390811691161461025c57610002565b600101805473ffffffffffffffffffffffffffffffffffffffff1916909117905550565b83815260208190526040812060018101549091600160a060020a03909116148015906102bd5750600181015433600160a060020a03908116911614155b156102c757610002565b60018101805460c0604052606085905260808490523360a0819052835460a060020a8087040273ffffffffffffffffffffffffffffffffffffffff199182168817600160a060020a031617855590911617905550505050565b8054610e10945060a060020a808204029350600160a060020a031691505b509295919450925056
|
|
||||||
|
|
@ -1,366 +0,0 @@
|
||||||
// This file is an automatically generated Go binding. Do not modify as any
|
|
||||||
// change will likely be lost upon the next re-generation!
|
|
||||||
|
|
||||||
package contract
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenRegistrarABI is the input ABI used to generate the binding from.
|
|
||||||
const OpenRegistrarABI = `[{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"id","type":"bytes32"}],"name":"getExtended","outputs":[{"name":"data","type":"bytes"}],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"qtype","type":"bytes32"},{"name":"index","type":"uint16"}],"name":"resolve","outputs":[{"name":"rcode","type":"uint16"},{"name":"rtype","type":"bytes16"},{"name":"ttl","type":"uint32"},{"name":"len","type":"uint16"},{"name":"data","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"resolver","type":"address"},{"name":"nodeId","type":"bytes12"}],"name":"register","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"resolver","type":"address"},{"name":"nodeId","type":"bytes12"}],"name":"setResolver","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"label","type":"bytes32"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"label","type":"bytes32"}],"name":"findResolver","outputs":[{"name":"rcode","type":"uint16"},{"name":"ttl","type":"uint32"},{"name":"rnode","type":"bytes12"},{"name":"raddress","type":"address"}],"type":"function"}]`
|
|
||||||
|
|
||||||
// OpenRegistrarBin is the compiled bytecode used for deploying new contracts.
|
|
||||||
const OpenRegistrarBin = `606060405261083b806100126000396000f36060604052361561007f576000357c0100000000000000000000000000000000000000000000000000000000900480635b0fc9c3146100815780638021061c146100a2578063a16fdafa14610126578063a1f8f8f0146101a5578063a9f2a1b2146101cf578063deb931a2146101f9578063edc0277c1461023b5761007f565b005b6100a060048080359060200190919080359060200190919050506102bc565b005b6100b86004808035906020019091905050610392565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101185780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61014e60048080359060200190919080359060200190919080359060200190919050506103c6565b604051808661ffff168152602001856fffffffffffffffffffffffffffffffff191681526020018463ffffffff1681526020018361ffff168152602001826000191681526020019550505050505060405180910390f35b6101cd600480803590602001909190803590602001909190803590602001909190505061041f565b005b6101f760048080359060200190919080359060200190919080359060200190919050506105ac565b005b61020f60048080359060200190919050506106c0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61025a600480803590602001909190803590602001909190505061070f565b604051808561ffff1681526020018463ffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff191681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200194505050505060405180910390f35b600060008273ffffffffffffffffffffffffffffffffffffffff1614156102e257610002565b600060005060008460001916815260200190815260200160002060005090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561035f57610002565b818160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b505050565b6020604051908101604052806000815260200150602060405190810160405280600081526020015090506103c1565b919050565b60006000600060006000600074010000000000000000000000000000000000000000028873ffffffffffffffffffffffffffffffffffffffff191614151561041357600394508450610414565b5b939792965093509350565b600060008373ffffffffffffffffffffffffffffffffffffffff16141561044557610002565b60006000506000856000191681526020019081526020016000206000509050600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156104c357610002565b60606040519081016040528084815260200183815260200133815260200150600060005060008660001916815260200190815260200160002060005060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff0219169083740100000000000000000000000000000000000000009004021790555060408201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055509050505b50505050565b600060008373ffffffffffffffffffffffffffffffffffffffff1614156105d257610002565b600060005060008560001916815260200190815260200160002060005090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561064f57610002565b828160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550818160000160146101000a8154816bffffffffffffffffffffffff021916908374010000000000000000000000000000000000000000900402179055505b50505050565b6000600060005060008360001916815260200190815260200160002060005060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061070a565b919050565b6000600060006000600060006000506000876000191681526020019081526020016000206000509050600074010000000000000000000000000000000000000000028773ffffffffffffffffffffffffffffffffffffffff19161415806107c65750600073ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156107d657600394508450610831565b610e10935083508060000160149054906101000a90047401000000000000000000000000000000000000000002925082508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915081505b509295919450925056`
|
|
||||||
|
|
||||||
// DeployOpenRegistrar deploys a new Ethereum contract, binding an instance of OpenRegistrar to it.
|
|
||||||
func DeployOpenRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *OpenRegistrar, error) {
|
|
||||||
parsed, err := abi.JSON(strings.NewReader(OpenRegistrarABI))
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, nil, nil, err
|
|
||||||
}
|
|
||||||
address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(OpenRegistrarBin), backend)
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, nil, nil, err
|
|
||||||
}
|
|
||||||
return address, tx, &OpenRegistrar{OpenRegistrarCaller: OpenRegistrarCaller{contract: contract}, OpenRegistrarTransactor: OpenRegistrarTransactor{contract: contract}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrar is an auto generated Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrar struct {
|
|
||||||
OpenRegistrarCaller // Read-only binding to the contract
|
|
||||||
OpenRegistrarTransactor // Write-only binding to the contract
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarCaller is an auto generated read-only Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrarCaller struct {
|
|
||||||
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarTransactor is an auto generated write-only Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrarTransactor struct {
|
|
||||||
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarSession is an auto generated Go binding around an Ethereum contract,
|
|
||||||
// with pre-set call and transact options.
|
|
||||||
type OpenRegistrarSession struct {
|
|
||||||
Contract *OpenRegistrar // Generic contract binding to set the session for
|
|
||||||
CallOpts bind.CallOpts // Call options to use throughout this session
|
|
||||||
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarCallerSession is an auto generated read-only Go binding around an Ethereum contract,
|
|
||||||
// with pre-set call options.
|
|
||||||
type OpenRegistrarCallerSession struct {
|
|
||||||
Contract *OpenRegistrarCaller // Generic contract caller binding to set the session for
|
|
||||||
CallOpts bind.CallOpts // Call options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
|
|
||||||
// with pre-set transact options.
|
|
||||||
type OpenRegistrarTransactorSession struct {
|
|
||||||
Contract *OpenRegistrarTransactor // Generic contract transactor binding to set the session for
|
|
||||||
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarRaw is an auto generated low-level Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrarRaw struct {
|
|
||||||
Contract *OpenRegistrar // Generic contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrarCallerRaw struct {
|
|
||||||
Contract *OpenRegistrarCaller // Generic read-only contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenRegistrarTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
|
|
||||||
type OpenRegistrarTransactorRaw struct {
|
|
||||||
Contract *OpenRegistrarTransactor // Generic write-only contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOpenRegistrar creates a new instance of OpenRegistrar, bound to a specific deployed contract.
|
|
||||||
func NewOpenRegistrar(address common.Address, backend bind.ContractBackend) (*OpenRegistrar, error) {
|
|
||||||
contract, err := bindOpenRegistrar(address, backend.(bind.ContractCaller), backend.(bind.ContractTransactor))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &OpenRegistrar{OpenRegistrarCaller: OpenRegistrarCaller{contract: contract}, OpenRegistrarTransactor: OpenRegistrarTransactor{contract: contract}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOpenRegistrarCaller creates a new read-only instance of OpenRegistrar, bound to a specific deployed contract.
|
|
||||||
func NewOpenRegistrarCaller(address common.Address, caller bind.ContractCaller) (*OpenRegistrarCaller, error) {
|
|
||||||
contract, err := bindOpenRegistrar(address, caller, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &OpenRegistrarCaller{contract: contract}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOpenRegistrarTransactor creates a new write-only instance of OpenRegistrar, bound to a specific deployed contract.
|
|
||||||
func NewOpenRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*OpenRegistrarTransactor, error) {
|
|
||||||
contract, err := bindOpenRegistrar(address, nil, transactor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &OpenRegistrarTransactor{contract: contract}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// bindOpenRegistrar binds a generic wrapper to an already deployed contract.
|
|
||||||
func bindOpenRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor) (*bind.BoundContract, error) {
|
|
||||||
parsed, err := abi.JSON(strings.NewReader(OpenRegistrarABI))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return bind.NewBoundContract(address, parsed, caller, transactor), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call invokes the (constant) contract method with params as input values and
|
|
||||||
// sets the output to result. The result type might be a single field for simple
|
|
||||||
// returns, a slice of interfaces for anonymous returns and a struct for named
|
|
||||||
// returns.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
|
|
||||||
return _OpenRegistrar.Contract.OpenRegistrarCaller.contract.Call(opts, result, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer initiates a plain transaction to move funds to the contract, calling
|
|
||||||
// its default method if one is available.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.OpenRegistrarTransactor.contract.Transfer(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transact invokes the (paid) contract method with params as input values.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.OpenRegistrarTransactor.contract.Transact(opts, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call invokes the (constant) contract method with params as input values and
|
|
||||||
// sets the output to result. The result type might be a single field for simple
|
|
||||||
// returns, a slice of interfaces for anonymous returns and a struct for named
|
|
||||||
// returns.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
|
|
||||||
return _OpenRegistrar.Contract.contract.Call(opts, result, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer initiates a plain transaction to move funds to the contract, calling
|
|
||||||
// its default method if one is available.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.contract.Transfer(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transact invokes the (paid) contract method with params as input values.
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.contract.Transact(opts, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindResolver is a free data retrieval call binding the contract method 0xedc0277c.
|
|
||||||
//
|
|
||||||
// Solidity: function findResolver(nodeId bytes12, label bytes32) constant returns(rcode uint16, ttl uint32, rnode bytes12, raddress address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCaller) FindResolver(opts *bind.CallOpts, nodeId [12]byte, label [32]byte) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Ttl uint32
|
|
||||||
Rnode [12]byte
|
|
||||||
Raddress common.Address
|
|
||||||
}, error) {
|
|
||||||
ret := new(struct {
|
|
||||||
Rcode uint16
|
|
||||||
Ttl uint32
|
|
||||||
Rnode [12]byte
|
|
||||||
Raddress common.Address
|
|
||||||
})
|
|
||||||
out := ret
|
|
||||||
err := _OpenRegistrar.contract.Call(opts, out, "findResolver", nodeId, label)
|
|
||||||
return *ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindResolver is a free data retrieval call binding the contract method 0xedc0277c.
|
|
||||||
//
|
|
||||||
// Solidity: function findResolver(nodeId bytes12, label bytes32) constant returns(rcode uint16, ttl uint32, rnode bytes12, raddress address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) FindResolver(nodeId [12]byte, label [32]byte) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Ttl uint32
|
|
||||||
Rnode [12]byte
|
|
||||||
Raddress common.Address
|
|
||||||
}, error) {
|
|
||||||
return _OpenRegistrar.Contract.FindResolver(&_OpenRegistrar.CallOpts, nodeId, label)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindResolver is a free data retrieval call binding the contract method 0xedc0277c.
|
|
||||||
//
|
|
||||||
// Solidity: function findResolver(nodeId bytes12, label bytes32) constant returns(rcode uint16, ttl uint32, rnode bytes12, raddress address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCallerSession) FindResolver(nodeId [12]byte, label [32]byte) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Ttl uint32
|
|
||||||
Rnode [12]byte
|
|
||||||
Raddress common.Address
|
|
||||||
}, error) {
|
|
||||||
return _OpenRegistrar.Contract.FindResolver(&_OpenRegistrar.CallOpts, nodeId, label)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtended is a free data retrieval call binding the contract method 0x8021061c.
|
|
||||||
//
|
|
||||||
// Solidity: function getExtended(id bytes32) constant returns(data bytes)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCaller) GetExtended(opts *bind.CallOpts, id [32]byte) ([]byte, error) {
|
|
||||||
var (
|
|
||||||
ret0 = new([]byte)
|
|
||||||
)
|
|
||||||
out := ret0
|
|
||||||
err := _OpenRegistrar.contract.Call(opts, out, "getExtended", id)
|
|
||||||
return *ret0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtended is a free data retrieval call binding the contract method 0x8021061c.
|
|
||||||
//
|
|
||||||
// Solidity: function getExtended(id bytes32) constant returns(data bytes)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) GetExtended(id [32]byte) ([]byte, error) {
|
|
||||||
return _OpenRegistrar.Contract.GetExtended(&_OpenRegistrar.CallOpts, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtended is a free data retrieval call binding the contract method 0x8021061c.
|
|
||||||
//
|
|
||||||
// Solidity: function getExtended(id bytes32) constant returns(data bytes)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCallerSession) GetExtended(id [32]byte) ([]byte, error) {
|
|
||||||
return _OpenRegistrar.Contract.GetExtended(&_OpenRegistrar.CallOpts, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOwner is a free data retrieval call binding the contract method 0xdeb931a2.
|
|
||||||
//
|
|
||||||
// Solidity: function getOwner(label bytes32) constant returns(address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCaller) GetOwner(opts *bind.CallOpts, label [32]byte) (common.Address, error) {
|
|
||||||
var (
|
|
||||||
ret0 = new(common.Address)
|
|
||||||
)
|
|
||||||
out := ret0
|
|
||||||
err := _OpenRegistrar.contract.Call(opts, out, "getOwner", label)
|
|
||||||
return *ret0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOwner is a free data retrieval call binding the contract method 0xdeb931a2.
|
|
||||||
//
|
|
||||||
// Solidity: function getOwner(label bytes32) constant returns(address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) GetOwner(label [32]byte) (common.Address, error) {
|
|
||||||
return _OpenRegistrar.Contract.GetOwner(&_OpenRegistrar.CallOpts, label)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetOwner is a free data retrieval call binding the contract method 0xdeb931a2.
|
|
||||||
//
|
|
||||||
// Solidity: function getOwner(label bytes32) constant returns(address)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCallerSession) GetOwner(label [32]byte) (common.Address, error) {
|
|
||||||
return _OpenRegistrar.Contract.GetOwner(&_OpenRegistrar.CallOpts, label)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve is a free data retrieval call binding the contract method 0xa16fdafa.
|
|
||||||
//
|
|
||||||
// Solidity: function resolve(nodeId bytes12, qtype bytes32, index uint16) constant returns(rcode uint16, rtype bytes16, ttl uint32, len uint16, data bytes32)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCaller) Resolve(opts *bind.CallOpts, nodeId [12]byte, qtype [32]byte, index uint16) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Rtype [16]byte
|
|
||||||
Ttl uint32
|
|
||||||
Len uint16
|
|
||||||
Data [32]byte
|
|
||||||
}, error) {
|
|
||||||
ret := new(struct {
|
|
||||||
Rcode uint16
|
|
||||||
Rtype [16]byte
|
|
||||||
Ttl uint32
|
|
||||||
Len uint16
|
|
||||||
Data [32]byte
|
|
||||||
})
|
|
||||||
out := ret
|
|
||||||
err := _OpenRegistrar.contract.Call(opts, out, "resolve", nodeId, qtype, index)
|
|
||||||
return *ret, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve is a free data retrieval call binding the contract method 0xa16fdafa.
|
|
||||||
//
|
|
||||||
// Solidity: function resolve(nodeId bytes12, qtype bytes32, index uint16) constant returns(rcode uint16, rtype bytes16, ttl uint32, len uint16, data bytes32)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) Resolve(nodeId [12]byte, qtype [32]byte, index uint16) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Rtype [16]byte
|
|
||||||
Ttl uint32
|
|
||||||
Len uint16
|
|
||||||
Data [32]byte
|
|
||||||
}, error) {
|
|
||||||
return _OpenRegistrar.Contract.Resolve(&_OpenRegistrar.CallOpts, nodeId, qtype, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve is a free data retrieval call binding the contract method 0xa16fdafa.
|
|
||||||
//
|
|
||||||
// Solidity: function resolve(nodeId bytes12, qtype bytes32, index uint16) constant returns(rcode uint16, rtype bytes16, ttl uint32, len uint16, data bytes32)
|
|
||||||
func (_OpenRegistrar *OpenRegistrarCallerSession) Resolve(nodeId [12]byte, qtype [32]byte, index uint16) (struct {
|
|
||||||
Rcode uint16
|
|
||||||
Rtype [16]byte
|
|
||||||
Ttl uint32
|
|
||||||
Len uint16
|
|
||||||
Data [32]byte
|
|
||||||
}, error) {
|
|
||||||
return _OpenRegistrar.Contract.Resolve(&_OpenRegistrar.CallOpts, nodeId, qtype, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register is a paid mutator transaction binding the contract method 0xa1f8f8f0.
|
|
||||||
//
|
|
||||||
// Solidity: function register(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactor) Register(opts *bind.TransactOpts, label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.contract.Transact(opts, "register", label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register is a paid mutator transaction binding the contract method 0xa1f8f8f0.
|
|
||||||
//
|
|
||||||
// Solidity: function register(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) Register(label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.Register(&_OpenRegistrar.TransactOpts, label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register is a paid mutator transaction binding the contract method 0xa1f8f8f0.
|
|
||||||
//
|
|
||||||
// Solidity: function register(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactorSession) Register(label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.Register(&_OpenRegistrar.TransactOpts, label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
|
|
||||||
//
|
|
||||||
// Solidity: function setOwner(label bytes32, newOwner address) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactor) SetOwner(opts *bind.TransactOpts, label [32]byte, newOwner common.Address) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.contract.Transact(opts, "setOwner", label, newOwner)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
|
|
||||||
//
|
|
||||||
// Solidity: function setOwner(label bytes32, newOwner address) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) SetOwner(label [32]byte, newOwner common.Address) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.SetOwner(&_OpenRegistrar.TransactOpts, label, newOwner)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
|
|
||||||
//
|
|
||||||
// Solidity: function setOwner(label bytes32, newOwner address) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactorSession) SetOwner(label [32]byte, newOwner common.Address) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.SetOwner(&_OpenRegistrar.TransactOpts, label, newOwner)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResolver is a paid mutator transaction binding the contract method 0xa9f2a1b2.
|
|
||||||
//
|
|
||||||
// Solidity: function setResolver(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactor) SetResolver(opts *bind.TransactOpts, label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.contract.Transact(opts, "setResolver", label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResolver is a paid mutator transaction binding the contract method 0xa9f2a1b2.
|
|
||||||
//
|
|
||||||
// Solidity: function setResolver(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarSession) SetResolver(label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.SetResolver(&_OpenRegistrar.TransactOpts, label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResolver is a paid mutator transaction binding the contract method 0xa9f2a1b2.
|
|
||||||
//
|
|
||||||
// Solidity: function setResolver(label bytes32, resolver address, nodeId bytes12) returns()
|
|
||||||
func (_OpenRegistrar *OpenRegistrarTransactorSession) SetResolver(label [32]byte, resolver common.Address, nodeId [12]byte) (*types.Transaction, error) {
|
|
||||||
return _OpenRegistrar.Contract.SetResolver(&_OpenRegistrar.TransactOpts, label, resolver, nodeId)
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
[{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"rootNodeId","type":"bytes12"},{"name":"name","type":"bytes32[]"}],"name":"deletePrivateRR","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"isPersonalResolver","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"id","type":"bytes32"}],"name":"getExtended","outputs":[{"name":"data","type":"bytes"}],"type":"function"},{"constant":false,"inputs":[{"name":"rootNodeId","type":"bytes12"},{"name":"name","type":"string"},{"name":"rtype","type":"bytes16"},{"name":"ttl","type":"uint32"},{"name":"len","type":"uint16"},{"name":"data","type":"bytes32"}],"name":"setRR","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"rootNodeId","type":"bytes12"},{"name":"name","type":"bytes32[]"},{"name":"rtype","type":"bytes16"},{"name":"ttl","type":"uint32"},{"name":"len","type":"uint16"},{"name":"data","type":"bytes32"}],"name":"setPrivateRR","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"qtype","type":"bytes32"},{"name":"index","type":"uint16"}],"name":"resolve","outputs":[{"name":"rcode","type":"uint16"},{"name":"rtype","type":"bytes16"},{"name":"ttl","type":"uint32"},{"name":"len","type":"uint16"},{"name":"data","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"rootNodeId","type":"bytes12"},{"name":"name","type":"string"}],"name":"deleteRR","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"nodeId","type":"bytes12"},{"name":"label","type":"bytes32"}],"name":"findResolver","outputs":[{"name":"rcode","type":"uint16"},{"name":"ttl","type":"uint32"},{"name":"rnode","type":"bytes12"},{"name":"raddress","type":"address"}],"type":"function"},{"inputs":[],"type":"constructor"}]
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -1,31 +1,226 @@
|
||||||
/**
|
/**
|
||||||
* ENS resolver interface.
|
* The ENS registry contract.
|
||||||
*/
|
*/
|
||||||
contract Resolver {
|
contract ENS {
|
||||||
bytes32 constant TYPE_STAR = "*";
|
struct Record {
|
||||||
|
address owner;
|
||||||
|
address resolver;
|
||||||
|
}
|
||||||
|
|
||||||
// Response codes.
|
mapping(bytes32=>Record) records;
|
||||||
uint16 constant RCODE_OK = 0;
|
|
||||||
uint16 constant RCODE_NXDOMAIN = 3;
|
|
||||||
|
|
||||||
// These methods are shared by all resolvers
|
// Logged when the owner of a node assigns a new owner to a subnode.
|
||||||
function findResolver(bytes12 nodeId, bytes32 label) constant
|
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
|
||||||
returns (uint16 rcode, uint32 ttl, bytes12 rnode, address raddress);
|
|
||||||
function resolve(bytes12 nodeId, bytes32 qtype, uint16 index) constant
|
|
||||||
returns (uint16 rcode, bytes16 rtype, uint32 ttl, uint16 len,
|
|
||||||
bytes32 data);
|
|
||||||
function getExtended(bytes32 id) constant returns (bytes data);
|
|
||||||
|
|
||||||
// These methods are implemented by personal resolvers
|
// Logged when the owner of a node transfers ownership to a new account.
|
||||||
function isPersonalResolver() constant returns (bool);
|
event Transfer(bytes32 indexed node, address owner);
|
||||||
function setRR(bytes12 rootNodeId, string name, bytes16 rtype, uint32 ttl, uint16 len, bytes32 data);
|
|
||||||
function setPrivateRR(bytes12 rootNodeId, bytes32[] name, bytes16 rtype, uint32 ttl, uint16 len, bytes32 data);
|
|
||||||
function deleteRR(bytes12 rootNodeId, string name);
|
|
||||||
function deletePrivateRR(bytes12 rootNodeId, bytes32[] name);
|
|
||||||
|
|
||||||
// These methods are implemented by open registrar implementations.
|
// Logged when the owner of a node changes the resolver for that node.
|
||||||
function register(bytes32 label, address resolver, bytes12 nodeId);
|
event NewResolver(bytes32 indexed node, address resolver);
|
||||||
function setOwner(bytes32 label, address newOwner);
|
|
||||||
function setResolver(bytes32 label, address resolver, bytes12 nodeId);
|
// Permits modifications only by the owner of the specified node.
|
||||||
function getOwner(bytes32 label) constant returns (address);
|
modifier only_owner(bytes32 node) {
|
||||||
|
if(records[node].owner != msg.sender) throw;
|
||||||
|
_
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ENS registrar, with the provided address as the owner of the root node.
|
||||||
|
*/
|
||||||
|
function ENS(address owner) {
|
||||||
|
records[0].owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address that owns the specified node.
|
||||||
|
*/
|
||||||
|
function owner(bytes32 node) constant returns (address) {
|
||||||
|
return records[node].owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the resolver for the specified node.
|
||||||
|
*/
|
||||||
|
function resolver(bytes32 node) constant returns (address) {
|
||||||
|
return records[node].resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) only_owner(node) {
|
||||||
|
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 setOwner(bytes32 node, bytes32 label, address owner) only_owner(node) {
|
||||||
|
var subnode = sha3(node, label);
|
||||||
|
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) only_owner(node) {
|
||||||
|
NewResolver(node, resolver);
|
||||||
|
records[node].resolver = resolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A registrar that allocates subdomains to the first person to claim them. It also deploys
|
||||||
|
* a simple resolver contract and sets that as the default resolver on new names for
|
||||||
|
* convenience.
|
||||||
|
*/
|
||||||
|
contract FIFSRegistrar {
|
||||||
|
ENS ens;
|
||||||
|
PublicResolver defaultResolver;
|
||||||
|
bytes32 rootNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param ensAddr The address of the ENS registry.
|
||||||
|
* @param node The node that this registrar administers.
|
||||||
|
*/
|
||||||
|
function FIFSRegistrar(address ensAddr, bytes32 node) {
|
||||||
|
ens = ENS(ensAddr);
|
||||||
|
defaultResolver = new PublicResolver(ensAddr);
|
||||||
|
rootNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a name, or change the owner of an existing registration.
|
||||||
|
* @param subnode The hash of the label to register.
|
||||||
|
* @param owner The address of the new owner.
|
||||||
|
*/
|
||||||
|
function register(bytes32 subnode, address owner) {
|
||||||
|
var node = sha3(rootNode, subnode);
|
||||||
|
var currentOwner = ens.owner(node);
|
||||||
|
if(currentOwner != 0 && currentOwner != msg.sender)
|
||||||
|
throw;
|
||||||
|
|
||||||
|
// Temporarily set ourselves as the owner
|
||||||
|
ens.setOwner(rootNode, subnode, this);
|
||||||
|
// Set up the default resolver
|
||||||
|
ens.setResolver(node, defaultResolver);
|
||||||
|
// Set the owner to the real owner
|
||||||
|
ens.setOwner(node, owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Resolver {
|
||||||
|
event AddrChanged(bytes32 indexed node, address a);
|
||||||
|
event ContentChanged(bytes32 indexed node, bytes32 hash);
|
||||||
|
|
||||||
|
function has(bytes32 node, bytes32 kind) returns (bool);
|
||||||
|
function addr(bytes32 node) constant returns (address ret);
|
||||||
|
function content(bytes32 node) constant returns (bytes32 ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple resolver anyone can use; only allows the owner of a node to set its
|
||||||
|
* address.
|
||||||
|
*/
|
||||||
|
contract PublicResolver is Resolver {
|
||||||
|
ENS ens;
|
||||||
|
mapping(bytes32=>address) addresses;
|
||||||
|
mapping(bytes32=>bytes32) contents;
|
||||||
|
|
||||||
|
modifier only_owner(bytes32 node) {
|
||||||
|
if(ens.owner(node) != msg.sender) throw;
|
||||||
|
_
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param ensAddr The ENS registrar contract.
|
||||||
|
*/
|
||||||
|
function PublicResolver(address ensAddr) {
|
||||||
|
ens = ENS(ensAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback function.
|
||||||
|
*/
|
||||||
|
function() {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the specified node has the specified record type.
|
||||||
|
* @param node The ENS node to query.
|
||||||
|
* @param kind The record type name, as specified in EIP137.
|
||||||
|
* @return True if this resolver has a record of the provided type on the
|
||||||
|
* provided node.
|
||||||
|
*/
|
||||||
|
function has(bytes32 node, bytes32 kind) returns (bool) {
|
||||||
|
return (kind == "addr" && addresses[node] != 0) ||
|
||||||
|
(kind == "content" && contents[node] != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address associated with an ENS node.
|
||||||
|
* @param node The ENS node to query.
|
||||||
|
* @return The associated address.
|
||||||
|
*/
|
||||||
|
function addr(bytes32 node) constant returns (address ret) {
|
||||||
|
ret = addresses[node];
|
||||||
|
if(ret == 0)
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content hash associated with an ENS node.
|
||||||
|
* @param node The ENS node to query.
|
||||||
|
* @return The associated content hash.
|
||||||
|
*/
|
||||||
|
function content(bytes32 node) constant returns (bytes32 ret) {
|
||||||
|
ret = contents[node];
|
||||||
|
if(ret == 0)
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the address associated with an ENS node.
|
||||||
|
* May only be called by the owner of that node in the ENS registry.
|
||||||
|
* @param node The node to update.
|
||||||
|
* @param addr The address to set.
|
||||||
|
*/
|
||||||
|
function setAddr(bytes32 node, address addr) only_owner(node) {
|
||||||
|
addresses[node] = addr;
|
||||||
|
AddrChanged(node, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the content hash associated with an ENS node.
|
||||||
|
* May only be called by the owner of that node in the ENS registry.
|
||||||
|
* @param node The node to update.
|
||||||
|
* @param hash The content hash to set.
|
||||||
|
*/
|
||||||
|
function setContent(bytes32 node, bytes32 hash) only_owner(node) {
|
||||||
|
contents[node] = hash;
|
||||||
|
ContentChanged(node, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract DeployENS {
|
||||||
|
function DeployENS() {
|
||||||
|
var ens = new ENS(this);
|
||||||
|
var registrar = new FIFSRegistrar(ens, 0);
|
||||||
|
ens.setOwner(0, registrar);
|
||||||
|
selfdestruct(msg.sender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
//go:generate abigen --sol contract/ens.sol --pkg contract --out contract/ens.go
|
//go:generate abigen --sol contract/ENS.sol --pkg contract --out contract/ens.go
|
||||||
|
|
||||||
package ens
|
package ens
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
|
@ -13,182 +14,150 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var qtypeChash = [32]byte{0x43, 0x48, 0x41, 0x53, 0x48}
|
|
||||||
var rtypeChash = [16]byte{0x43, 0x48, 0x41, 0x53, 0x48}
|
|
||||||
|
|
||||||
// swarm domain name registry and resolver
|
// swarm domain name registry and resolver
|
||||||
// the ENS instance can be directly wrapped in rpc.Api
|
|
||||||
type ENS struct {
|
type ENS struct {
|
||||||
transactOpts *bind.TransactOpts
|
*contract.ENSSession
|
||||||
contractBackend bind.ContractBackend
|
contractBackend bind.ContractBackend
|
||||||
rootAddress common.Address
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) *ENS {
|
// NewENS creates a struct exposing convenient high-level operations for interacting with
|
||||||
return &ENS{
|
// the Ethereum Name Service.
|
||||||
transactOpts: transactOpts,
|
func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) {
|
||||||
contractBackend: contractBackend,
|
ens, err := contract.NewENS(contractAddr, contractBackend)
|
||||||
rootAddress: contractAddr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ENS) DeployRegistrar() (common.Address, error) {
|
|
||||||
addr, _, _, err := contract.DeployOpenRegistrar(self.transactOpts, self.contractBackend)
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, err
|
|
||||||
}
|
|
||||||
return addr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ENS) DeployResolver() (common.Address, error) {
|
|
||||||
addr, _, _, err := contract.DeployPersonalResolver(self.transactOpts, self.contractBackend)
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, err
|
|
||||||
}
|
|
||||||
return addr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ENS) newResolver(contractAddr common.Address) (*contract.ResolverSession, error) {
|
|
||||||
resolver, err := contract.NewResolver(contractAddr, self.contractBackend)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &contract.ResolverSession{
|
|
||||||
Contract: resolver,
|
return &ENS{
|
||||||
TransactOpts: *self.transactOpts,
|
&contract.ENSSession{
|
||||||
|
Contract: ens,
|
||||||
|
TransactOpts: *transactOpts,
|
||||||
|
},
|
||||||
|
contractBackend,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve is a non-tranasctional call, returns hash as storage.Key
|
// DeployENS deploys an instance of the ENS nameservice, with a 'first in first served' root registrar.
|
||||||
func (self *ENS) Resolve(name string) (storage.Key, error) {
|
func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (*ENS, error) {
|
||||||
return self.resolveName(self.rootAddress, name)
|
// Deploy the ENS registry
|
||||||
}
|
ensAddr, _, _, err := contract.DeployENS(transactOpts, contractBackend, transactOpts.From)
|
||||||
|
|
||||||
func (self *ENS) nextResolver(resolver *contract.ResolverSession, nodeId [12]byte, label string) (*contract.ResolverSession, [12]byte, error) {
|
|
||||||
hash := crypto.Sha3Hash([]byte(label))
|
|
||||||
ret, err := resolver.FindResolver(nodeId, hash)
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("error resolving label '%v': %v", label, err)
|
|
||||||
return nil, [12]byte{}, err
|
|
||||||
}
|
|
||||||
if ret.Rcode != 0 {
|
|
||||||
err = fmt.Errorf("error resolving label '%v': got response code %v", label, ret.Rcode)
|
|
||||||
return nil, [12]byte{}, err
|
|
||||||
}
|
|
||||||
nodeId = ret.Rnode
|
|
||||||
resolver, err = self.newResolver(ret.Raddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, [12]byte{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolver, nodeId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ENS) findResolver(rootAddress common.Address, host string) (*contract.ResolverSession, [12]byte, error) {
|
|
||||||
resolver, err := self.newResolver(self.rootAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, [12]byte{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(host) == 0 {
|
|
||||||
return resolver, [12]byte{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
labels := strings.Split(host, ".")
|
|
||||||
|
|
||||||
var nodeId [12]byte
|
|
||||||
for i := len(labels) - 1; i >= 0; i-- {
|
|
||||||
var err error
|
|
||||||
resolver, nodeId, err = self.nextResolver(resolver, nodeId, labels[i])
|
|
||||||
if err != nil {
|
|
||||||
return nil, [12]byte{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolver, nodeId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ENS) resolveName(rootAddress common.Address, host string) (storage.Key, error) {
|
|
||||||
resolver, nodeId, err := self.findResolver(rootAddress, host)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := resolver.Resolve(nodeId, qtypeChash, 0)
|
ens, err := NewENS(transactOpts, ensAddr, contractBackend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error looking up RR on '%v': %v", host, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
if ret.Rcode != 0 {
|
|
||||||
return nil, fmt.Errorf("error looking up RR on '%v': got response code %v", host, ret.Rcode)
|
// Deploy the registrar
|
||||||
|
regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return storage.Key(ret.Data[:]), nil
|
|
||||||
|
// Set the registrar as owner of the ENS root
|
||||||
|
_, err = ens.SetOwner([32]byte{}, regAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
func ensParentNode(name string) (common.Hash, common.Hash) {
|
||||||
* Registers a new domain name for the caller, making them the owner of the new name.
|
|
||||||
*/
|
|
||||||
func (self *ENS) Register(name string, resolverAddress common.Address) (*types.Transaction, error) {
|
|
||||||
// Find the resolver that we should register with (the one that controls the parent domain)
|
|
||||||
parts := strings.SplitN(name, ".", 2)
|
parts := strings.SplitN(name, ".", 2)
|
||||||
|
label := crypto.Keccak256Hash([]byte(parts[0]))
|
||||||
baseName := ""
|
if len(parts) == 1 {
|
||||||
if len(parts) > 1 {
|
return [32]byte{}, label
|
||||||
baseName = parts[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
resolver, nodeId, err := self.findResolver(self.rootAddress, baseName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if nodeId != [12]byte{} {
|
|
||||||
return nil, fmt.Errorf("cannot register domains on %v: not a root node", baseName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send it a register transaction
|
|
||||||
hash := crypto.Sha3Hash([]byte(parts[0]))
|
|
||||||
return resolver.Register(hash, resolverAddress, [12]byte{})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Steps through name components until it finds a PersonalResolver contract.
|
|
||||||
* Returns the resolver, the node ID, and the remaining name components.
|
|
||||||
*/
|
|
||||||
func (self *ENS) findPersonalResolver(name string) (*contract.ResolverSession, [12]byte, string, error) {
|
|
||||||
var nodeId [12]byte
|
|
||||||
|
|
||||||
resolver, err := self.newResolver(self.rootAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, [12]byte{}, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
labels := strings.Split(name, ".")
|
|
||||||
|
|
||||||
for i := len(labels) - 1; i >= 0; i-- {
|
|
||||||
if personal, _ := resolver.IsPersonalResolver(); personal {
|
|
||||||
return resolver, nodeId, strings.Join(labels[0:i+1], "."), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resolver, nodeId, err = self.nextResolver(resolver, nodeId, labels[i])
|
|
||||||
if err != nil {
|
|
||||||
return nil, [12]byte{}, "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if personal, _ := resolver.IsPersonalResolver(); !personal {
|
|
||||||
return nil, [12]byte{}, "", fmt.Errorf("Personal resolver not found in any name component")
|
|
||||||
} else {
|
} else {
|
||||||
return resolver, nodeId, "", nil
|
parentNode, parentLabel := ensParentNode(parts[1])
|
||||||
|
return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
func ensNode(name string) common.Hash {
|
||||||
* Sets the content hash associated with a name.
|
parentNode, parentLabel := ensParentNode(name)
|
||||||
*/
|
return crypto.Keccak256Hash(parentNode[:], parentLabel[:])
|
||||||
func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
|
}
|
||||||
resolver, nodeId, name, err := self.findPersonalResolver(name)
|
|
||||||
|
func (self *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) {
|
||||||
|
resolverAddr, err := self.Resolver(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolver.SetRR(nodeId, name, rtypeChash, 3600, 20, [32]byte(hash))
|
resolver, err := contract.NewPublicResolver(resolverAddr, self.contractBackend)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &contract.PublicResolverSession{
|
||||||
|
Contract: resolver,
|
||||||
|
TransactOpts: self.TransactOpts,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) {
|
||||||
|
registrarAddr, err := self.Owner(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
registrar, err := contract.NewFIFSRegistrar(registrarAddr, self.contractBackend)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &contract.FIFSRegistrarSession{
|
||||||
|
Contract: registrar,
|
||||||
|
TransactOpts: self.TransactOpts,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve is a non-transactional call that returns the content hash associated with a name.
|
||||||
|
func (self *ENS) Resolve(name string) (storage.Key, error) {
|
||||||
|
node := ensNode(name)
|
||||||
|
|
||||||
|
resolver, err := self.getResolver(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := resolver.Content(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage.Key(ret[:]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register registers a new domain name for the caller, making them the owner of the new name.
|
||||||
|
// Only works if the registrar for the parent domain implements the FIFS registrar protocol.
|
||||||
|
func (self *ENS) Register(name string) (*types.Transaction, error) {
|
||||||
|
parentNode, label := ensParentNode(name)
|
||||||
|
|
||||||
|
registrar, err := self.getRegistrar(parentNode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := self.TransactOpts
|
||||||
|
opts.GasLimit = big.NewInt(200000)
|
||||||
|
return registrar.Contract.Register(&opts, label, self.TransactOpts.From)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContentHash sets the content hash associated with a name. Only works if the caller
|
||||||
|
// owns the name, and the associated resolver implements a `setContent` function.
|
||||||
|
func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) {
|
||||||
|
node := ensNode(name)
|
||||||
|
|
||||||
|
resolver, err := self.getResolver(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := self.TransactOpts
|
||||||
|
opts.GasLimit = big.NewInt(200000)
|
||||||
|
return resolver.Contract.SetContent(&opts, node, hash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
//go:generate abigen --abi contract/OpenRegistrar.abi --bin contract/OpenRegistrar.bin --pkg contract --type OpenRegistrar --out contract/OpenRegistrar.go
|
|
||||||
//go:generate abigen --abi contract/PersonalResolver.abi --bin contract/PersonalResolver.bin --pkg contract --type PersonalResolver --out contract/PersonalResolver.go
|
|
||||||
package ens
|
package ens
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -8,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
@ -23,21 +20,16 @@ var (
|
||||||
func TestENS(t *testing.T) {
|
func TestENS(t *testing.T) {
|
||||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAccount{addr, big.NewInt(1000000000)})
|
contractBackend := backends.NewSimulatedBackend(core.GenesisAccount{addr, big.NewInt(1000000000)})
|
||||||
transactOpts := bind.NewKeyedTransactor(key)
|
transactOpts := bind.NewKeyedTransactor(key)
|
||||||
ens := NewENS(transactOpts, common.Address{}, contractBackend)
|
// Workaround for bug estimating gas in the call to Register
|
||||||
registrarAddr, err := ens.DeployRegistrar()
|
transactOpts.GasLimit = big.NewInt(1000000)
|
||||||
|
|
||||||
|
ens, err := DeployENS(transactOpts, contractBackend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error, got %v", err)
|
t.Fatalf("expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
contractBackend.Commit()
|
contractBackend.Commit()
|
||||||
|
|
||||||
ens = NewENS(transactOpts, registrarAddr, contractBackend)
|
_, err = ens.Register(name)
|
||||||
resolverAddr, err := ens.DeployResolver()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("expected no error, got %v", err)
|
|
||||||
}
|
|
||||||
contractBackend.Commit()
|
|
||||||
|
|
||||||
_, err = ens.Register(name, resolverAddr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error, got %v", err)
|
t.Fatalf("expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -56,5 +48,4 @@ func TestENS(t *testing.T) {
|
||||||
if vhost.Hex() != hash.Hex()[2:] {
|
if vhost.Hex() != hash.Hex()[2:] {
|
||||||
t.Fatalf("resolve error, expected %v, got %v", hash.Hex(), vhost)
|
t.Fatalf("resolve error, expected %v, got %v", hash.Hex(), vhost)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,8 +138,11 @@ func NewSwarm(ctx *node.ServiceContext, config *api.Config, swapEnabled, syncEna
|
||||||
|
|
||||||
// set up high level api
|
// set up high level api
|
||||||
transactOpts := bind.NewKeyedTransactor(self.privateKey)
|
transactOpts := bind.NewKeyedTransactor(self.privateKey)
|
||||||
// backend := ethereum.ContractBackend()
|
|
||||||
self.dns = ens.NewENS(transactOpts, config.EnsRoot, self.backend)
|
self.dns, err = ens.NewENS(transactOpts, config.EnsRoot, self.backend)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
glog.V(logger.Debug).Infof("[BZZ] -> Swarm Domain Name Registrar @ address %v", config.EnsRoot.Hex())
|
glog.V(logger.Debug).Infof("[BZZ] -> Swarm Domain Name Registrar @ address %v", config.EnsRoot.Hex())
|
||||||
|
|
||||||
self.api = api.NewApi(self.dpa, self.dns)
|
self.api = api.NewApi(self.dpa, self.dns)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue