-
Notifications
You must be signed in to change notification settings - Fork 0
/
primary_registrar.ral
113 lines (96 loc) · 3.69 KB
/
primary_registrar.ral
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
Contract PrimaryRegistrar(
mut registrarOwner: Address,
recordTemplateId: ByteVec,
credentialTokenTemplateId: ByteVec,
minRegistrationDuration: U256
) extends Constants() implements Registrar {
fn cost(duration: U256) -> U256 {
return 1e-15 alph * duration
}
fn getCredentialTokenPath(name: ByteVec, caller: Address) -> ByteVec {
let node = keccak256!(name)
let record = Record(subContractId!(node))
checkCaller!(caller == record.getOwner(), ErrorCodes.InvalidCaller)
let ttl = record.getTTL()
assert!(blockTimeStamp!() < ttl, ErrorCodes.NameHasExpired)
return node ++ u256To32Byte!(ttl)
}
@using(preapprovedAssets = true)
pub fn mintCredentialToken(name: ByteVec, payer: Address) -> () {
let path = getCredentialTokenPath(name, callerAddress!())
let (tokenImmFields, tokenMutFields) = CredentialToken.encodeFields!(selfContractId!(), name) // TODO: add the ANS prefix
copyCreateSubContractWithToken!{payer -> ALPH: 1 alph}(
path,
credentialTokenTemplateId,
tokenImmFields,
tokenMutFields,
1,
payer
)
}
@using(preapprovedAssets = true)
pub fn burnCredentialToken(name: ByteVec, payer: Address) -> () {
let path = getCredentialTokenPath(name, callerAddress!())
let credentialTokenId = subContractId!(path)
burnToken!(payer, credentialTokenId, 1)
CredentialToken(credentialTokenId).destroy(payer)
}
fn preRegister(node: ByteVec, currentTs: U256) -> () {
let recordId = subContractId!(node)
if (contractExists!(recordId)) {
let record = Record(recordId)
let ttl = record.getTTL()
assert!(currentTs >= ttl, ErrorCodes.NameHasBeenRegistered)
record.destroy()
}
}
@using(preapprovedAssets = true, assetsInContract = true, checkExternalCaller = false)
pub fn register(
name: ByteVec,
owner: Address,
payer: Address,
duration: U256
) -> () {
assert!(size!(name) != 0, ErrorCodes.InvalidArgs)
assert!(isAssetAddress!(payer), ErrorCodes.ExpectAssetAddress)
assert!(duration >= minRegistrationDuration, ErrorCodes.InvalidArgs)
let node = keccak256!(name)
let currentTs = blockTimeStamp!()
preRegister(node, currentTs)
transferTokenToSelf!(payer, ALPH, cost(duration))
let ttl = currentTs + duration
let (recordImmFields, recordMutFields) = Record.encodeFields!(selfContractId!(), owner, ttl, payer)
copyCreateSubContract!{payer -> ALPH: 1 alph}(
node,
recordTemplateId,
recordImmFields,
recordMutFields
)
emit NameRegistered(name, owner, ttl)
}
@using(preapprovedAssets = true, assetsInContract = true)
pub fn renew(name: ByteVec, payer: Address, duration: U256) -> () {
assert!(isAssetAddress!(payer), ErrorCodes.ExpectAssetAddress)
assert!(duration >= minRegistrationDuration, ErrorCodes.InvalidArgs)
let node = keccak256!(name)
let record = Record(subContractId!(node))
checkCaller!(callerAddress!() == record.getOwner(), ErrorCodes.InvalidCaller)
let currentTs = blockTimeStamp!()
let currentTTL = record.getTTL()
assert!(currentTs < currentTTL, ErrorCodes.NameHasExpired)
transferTokenToSelf!(payer, ALPH, cost(duration))
let newTTL = currentTTL + duration
record.setTTL(newTTL)
emit NameRenewed(name, newTTL)
}
@using(preapprovedAssets = true, assetsInContract = true)
pub fn withdraw(to: Address, amount: U256) -> () {
checkCaller!(callerAddress!() == registrarOwner, ErrorCodes.InvalidCaller)
transferTokenFromSelf!(to, ALPH, amount)
}
@using(updateFields = true)
pub fn updateRegistrarOwner(newOwner: Address) -> () {
checkCaller!(callerAddress!() == registrarOwner, ErrorCodes.InvalidCaller)
registrarOwner = newOwner
}
}