1
+ const debug = require ( "debug" ) ( "deployer:ens" ) ;
1
2
const { getEnsAddress, default : ENSJS } = require ( "@ensdomains/ensjs" ) ;
2
3
const contract = require ( "@truffle/contract" ) ;
3
4
const { sha3 } = require ( "web3-utils" ) ;
@@ -34,16 +35,79 @@ class ENS {
34
35
this . ens . registryAddress = ensRegistry . address ;
35
36
this . devRegistry = ensRegistry ;
36
37
this . setENSJS ( ) ;
38
+ await this . deployNewDevReverseRegistrar ( from ) ;
37
39
return ensRegistry ;
38
40
}
39
41
42
+ //this method should only be called when using a dev registry!
43
+ //do not call it otherwise!
44
+ async deployNewDevReverseRegistrar ( from ) {
45
+ const registryAddress = this . determineENSRegistryAddress ( ) ;
46
+ debug ( "from: %s" , from ) ;
47
+ debug ( "registryAddress: %s" , registryAddress ) ;
48
+ const ReverseRegistrarArtifact = require ( "./builtContracts/ReverseRegistrar" ) ;
49
+ const ReverseRegistrar = contract ( ReverseRegistrarArtifact ) ;
50
+ ReverseRegistrar . setProvider ( this . provider ) ;
51
+ //note: the resolver address we're supposed to pass in to the constructor
52
+ //is supposed to be the "default resolver"; I'm not sure what that means,
53
+ //but I figure using the resolver for "addr.reverse" ought to suffice,
54
+ //right? So let's set up a resolver for it.
55
+ const reverseResolutionSpecialName = "addr.reverse" ;
56
+ debug ( "made it here" ) ;
57
+ //but in order to set its resolver, we first have to set its owner.
58
+ await this . setNameOwner ( { from, name : reverseResolutionSpecialName } ) ;
59
+ debug ( "owner set" ) ;
60
+ //now we can actually set the resolver
61
+ const { resolverAddress } = await this . ensureResolverExists ( {
62
+ from,
63
+ name : reverseResolutionSpecialName
64
+ } ) ;
65
+ debug ( "resolver set: %s" , resolverAddress ) ;
66
+ //...but wait! we need it to be owned by the registry, not by us.
67
+ //(otherwise the deployment will revert.) so, let's hand over
68
+ //ownership to the registry.
69
+ await this . alienateNameOwner ( {
70
+ from,
71
+ owner : registryAddress ,
72
+ name : reverseResolutionSpecialName
73
+ } ) ;
74
+ debug ( "owner alienated" ) ;
75
+ //now we can do the deployment!
76
+ const reverseRegistrar = await ReverseRegistrar . new (
77
+ registryAddress ,
78
+ resolverAddress ,
79
+ {
80
+ from
81
+ }
82
+ ) ;
83
+ debug ( "deployed" ) ;
84
+ //except, we're not done... we need to transfer ownership from the registry
85
+ //to the reverse registrar.
86
+ //(if there were a previous reverse registrar, this would happen automatically,
87
+ //but there wasn't, so it doesn't.)
88
+ //so, first let's claim the name for ourself again
89
+ await this . setNameOwner ( { from, name : reverseResolutionSpecialName } ) ;
90
+ debug ( "reclaimed" ) ;
91
+ //and now let's give it away again
92
+ await this . alienateNameOwner ( {
93
+ from,
94
+ owner : reverseRegistrar . address ,
95
+ name : reverseResolutionSpecialName
96
+ } ) ;
97
+ debug ( "re-alienated" ) ;
98
+ }
99
+
40
100
async ensureResolverExists ( { from, name } ) {
41
101
// See if the resolver is set, if not then set it
102
+ debug ( "getting resolver" ) ;
42
103
const resolverAddress = await this . ensjs . name ( name ) . getResolver ( ) ;
104
+ debug ( "got resolver" ) ;
43
105
// names with no set resolver have 0x0 returned
44
106
if ( resolverAddress !== "0x0000000000000000000000000000000000000000" ) {
107
+ debug ( "getting addr" ) ;
45
108
const resolvedAddress = await this . ensjs . name ( name ) . getAddress ( "ETH" ) ;
46
- return { resolvedAddress } ;
109
+ debug ( "got addr" ) ;
110
+ return { resolvedAddress, resolverAddress } ;
47
111
}
48
112
// deploy a resolver if one isn't set
49
113
const PublicResolverArtifact = require ( "./builtContracts/PublicResolver" ) ;
@@ -52,9 +116,12 @@ class ENS {
52
116
53
117
let registryAddress = this . determineENSRegistryAddress ( ) ;
54
118
119
+ debug ( "deploying resolver" ) ;
55
120
const publicResolver = await PublicResolver . new ( registryAddress , { from } ) ;
121
+ debug ( "deployed; setting resolver" ) ;
56
122
await this . ensjs . name ( name ) . setResolver ( publicResolver . address , { from } ) ;
57
- return { resolvedAddress : null } ;
123
+ debug ( "set resolver" ) ;
124
+ return { resolvedAddress : null , resolverAddress : publicResolver . address } ;
58
125
}
59
126
60
127
async setAddress ( name , addressOrContract , { from } ) {
@@ -118,6 +185,35 @@ class ENS {
118
185
}
119
186
}
120
187
188
+ //this method assumes that the current owner is `from`,
189
+ //and sets the new owner to be `owner`.
190
+ async alienateNameOwner ( { name, from, owner } ) {
191
+ //setNameOwner goes down the tree, from top to bottom.
192
+ //here, however, we have to go *up* the tree.
193
+ //as such, we are going to process the labels in order, rather
194
+ //than in reverse order.
195
+
196
+ let remaining = name ;
197
+ while ( remaining !== "" ) {
198
+ let label , suffix ;
199
+ const dotIndex = remaining . indexOf ( "." ) ; //find the first dot
200
+ if ( dotIndex !== - 1 ) {
201
+ label = remaining . slice ( 0 , dotIndex ) ; //everything before the dot
202
+ suffix = remaining . slice ( dotIndex + 1 ) ; //everything after the dot
203
+ } else {
204
+ label = remaining ;
205
+ suffix = "" ;
206
+ }
207
+ await this . devRegistry . setSubnodeOwner (
208
+ suffix !== "" ? hash ( suffix ) : "0x0" ,
209
+ sha3 ( label ) ,
210
+ owner ,
211
+ { from }
212
+ ) ;
213
+ remaining = suffix ;
214
+ }
215
+ }
216
+
121
217
parseAddress ( addressOrContract ) {
122
218
if ( typeof addressOrContract === "string" ) return addressOrContract ;
123
219
try {
0 commit comments