forked from TrueCloudLab/frostfs-contract
nns: update to the latest version
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
e779f436b2
commit
effa9b3863
2 changed files with 55 additions and 13 deletions
|
@ -1,7 +1,8 @@
|
||||||
name: "NameService"
|
name: "NameService"
|
||||||
supportedstandards: ["NEP-11"]
|
supportedstandards: ["NEP-11"]
|
||||||
safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "ownerOf",
|
safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "ownerOf",
|
||||||
"tokens", "properties", "roots", "getPrice", "isAvailable", "getRecord", "resolve"]
|
"tokens", "properties", "roots", "getPrice", "isAvailable", "getRecord",
|
||||||
|
"resolve", "getAllRecords"]
|
||||||
events:
|
events:
|
||||||
- name: Transfer
|
- name: Transfer
|
||||||
parameters:
|
parameters:
|
||||||
|
|
|
@ -66,6 +66,13 @@ const (
|
||||||
millisecondsInYear = 365 * 24 * 3600 * 1000
|
millisecondsInYear = 365 * 24 * 3600 * 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RecordState is a type that registered entities are saved to.
|
||||||
|
type RecordState struct {
|
||||||
|
Name string
|
||||||
|
Type RecordType
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
// Update updates NameService contract.
|
// Update updates NameService contract.
|
||||||
func Update(nef []byte, manifest string) {
|
func Update(nef []byte, manifest string) {
|
||||||
checkCommittee()
|
checkCommittee()
|
||||||
|
@ -353,6 +360,15 @@ func Resolve(name string, typ RecordType) string {
|
||||||
return resolve(ctx, name, typ, 2)
|
return resolve(ctx, name, typ, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllRecords returns an Iterator with RecordState items for given name.
|
||||||
|
func GetAllRecords(name string) iterator.Iterator {
|
||||||
|
tokenID := []byte(tokenIDFromName(name))
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
_ = getNameState(ctx, tokenID) // ensure not expired
|
||||||
|
recordsKey := getRecordsKey(tokenID, name)
|
||||||
|
return storage.Find(ctx, recordsKey, storage.ValuesOnly|storage.DeserializeValues)
|
||||||
|
}
|
||||||
|
|
||||||
// updateBalance updates account's balance and account's tokens.
|
// updateBalance updates account's balance and account's tokens.
|
||||||
func updateBalance(ctx storage.Context, tokenId []byte, acc interop.Hash160, diff int) {
|
func updateBalance(ctx storage.Context, tokenId []byte, acc interop.Hash160, diff int) {
|
||||||
balanceKey := append([]byte{prefixBalance}, acc...)
|
balanceKey := append([]byte{prefixBalance}, acc...)
|
||||||
|
@ -437,20 +453,35 @@ func putNameStateWithKey(ctx storage.Context, tokenKey []byte, ns NameState) {
|
||||||
// getRecord returns domain record.
|
// getRecord returns domain record.
|
||||||
func getRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType) string {
|
func getRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType) string {
|
||||||
recordKey := getRecordKey(tokenId, name, typ)
|
recordKey := getRecordKey(tokenId, name, typ)
|
||||||
record := storage.Get(ctx, recordKey)
|
recBytes := storage.Get(ctx, recordKey)
|
||||||
return record.(string)
|
if recBytes == nil {
|
||||||
|
return recBytes.(string) // A hack to actually return NULL.
|
||||||
|
}
|
||||||
|
record := std.Deserialize(recBytes.([]byte)).(RecordState)
|
||||||
|
return record.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
// putRecord stores domain record.
|
// putRecord stores domain record.
|
||||||
func putRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType, record string) {
|
func putRecord(ctx storage.Context, tokenId []byte, name string, typ RecordType, record string) {
|
||||||
recordKey := getRecordKey(tokenId, name, typ)
|
recordKey := getRecordKey(tokenId, name, typ)
|
||||||
storage.Put(ctx, recordKey, record)
|
rs := RecordState{
|
||||||
|
Name: name,
|
||||||
|
Type: typ,
|
||||||
|
Data: record,
|
||||||
|
}
|
||||||
|
recBytes := std.Serialize(rs)
|
||||||
|
storage.Put(ctx, recordKey, recBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRecordsKey returns prefix used to store domain records of different types.
|
||||||
|
func getRecordsKey(tokenId []byte, name string) []byte {
|
||||||
|
recordKey := append([]byte{prefixRecord}, getTokenKey(tokenId)...)
|
||||||
|
return append(recordKey, getTokenKey([]byte(name))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRecordKey returns key used to store domain records.
|
// getRecordKey returns key used to store domain records.
|
||||||
func getRecordKey(tokenId []byte, name string, typ RecordType) []byte {
|
func getRecordKey(tokenId []byte, name string, typ RecordType) []byte {
|
||||||
recordKey := append([]byte{prefixRecord}, getTokenKey(tokenId)...)
|
recordKey := getRecordsKey(tokenId, name)
|
||||||
recordKey = append(recordKey, getTokenKey([]byte(name))...)
|
|
||||||
return append(recordKey, []byte{byte(typ)}...)
|
return append(recordKey, []byte{byte(typ)}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,8 +617,14 @@ func checkIPv6(data string) bool {
|
||||||
for i, f := range fragments {
|
for i, f := range fragments {
|
||||||
if len(f) == 0 {
|
if len(f) == 0 {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
if len(fragments[1]) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
nums[i] = 0
|
nums[i] = 0
|
||||||
} else if i == l-1 {
|
} else if i == l-1 {
|
||||||
|
if len(fragments[i-1]) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
nums[7] = 0
|
nums[7] = 0
|
||||||
} else if hasEmpty {
|
} else if hasEmpty {
|
||||||
return false
|
return false
|
||||||
|
@ -613,6 +650,9 @@ func checkIPv6(data string) bool {
|
||||||
nums[idx] = n
|
nums[idx] = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if l < 8 && !hasEmpty {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
f0 := nums[0]
|
f0 := nums[0]
|
||||||
if f0 < 0x2000 || f0 == 0x2002 || f0 == 0x3ffe || f0 > 0x3fff { // IPv6 Global Unicast https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
|
if f0 < 0x2000 || f0 == 0x2002 || f0 == 0x3ffe || f0 > 0x3fff { // IPv6 Global Unicast https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
|
||||||
|
@ -646,10 +686,12 @@ func resolve(ctx storage.Context, name string, typ RecordType, redirect int) str
|
||||||
records := getRecords(ctx, name)
|
records := getRecords(ctx, name)
|
||||||
cname := ""
|
cname := ""
|
||||||
for iterator.Next(records) {
|
for iterator.Next(records) {
|
||||||
r := iterator.Value(records).([]string)
|
r := iterator.Value(records).(struct {
|
||||||
key := []byte(r[0])
|
key string
|
||||||
value := r[1]
|
rs RecordState
|
||||||
rTyp := key[len(key)-1]
|
})
|
||||||
|
value := r.rs.Data
|
||||||
|
rTyp := r.key[len(r.key)-1]
|
||||||
if rTyp == byte(typ) {
|
if rTyp == byte(typ) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -668,7 +710,6 @@ func resolve(ctx storage.Context, name string, typ RecordType, redirect int) str
|
||||||
func getRecords(ctx storage.Context, name string) iterator.Iterator {
|
func getRecords(ctx storage.Context, name string) iterator.Iterator {
|
||||||
tokenID := []byte(tokenIDFromName(name))
|
tokenID := []byte(tokenIDFromName(name))
|
||||||
_ = getNameState(ctx, tokenID)
|
_ = getNameState(ctx, tokenID)
|
||||||
recordsKey := append([]byte{prefixRecord}, getTokenKey(tokenID)...)
|
recordsKey := getRecordsKey(tokenID, name)
|
||||||
recordsKey = append(recordsKey, getTokenKey([]byte(name))...)
|
return storage.Find(ctx, recordsKey, storage.DeserializeValues)
|
||||||
return storage.Find(ctx, recordsKey, storage.None)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue