nns: make domain registration price dependant on length
Port 8ac2b80734
.
This commit is contained in:
parent
14c9858df2
commit
dea82ac4dd
2 changed files with 106 additions and 55 deletions
|
@ -29,7 +29,8 @@ const (
|
||||||
// prefixAccountToken contains map from (owner + token key) to token ID,
|
// prefixAccountToken contains map from (owner + token key) to token ID,
|
||||||
// where token key = hash160(token ID) and token ID = domain name.
|
// where token key = hash160(token ID) and token ID = domain name.
|
||||||
prefixAccountToken byte = 0x02
|
prefixAccountToken byte = 0x02
|
||||||
// prefixRegisterPrice contains price for new domain name registration.
|
// prefixRegisterPrice contains list of prices for new domain name registration
|
||||||
|
// depending on the domain name length.
|
||||||
prefixRegisterPrice byte = 0x10
|
prefixRegisterPrice byte = 0x10
|
||||||
// prefixRoot contains set of roots (map from root to 0).
|
// prefixRoot contains set of roots (map from root to 0).
|
||||||
prefixRoot byte = 0x20
|
prefixRoot byte = 0x20
|
||||||
|
@ -91,7 +92,13 @@ func _deploy(data interface{}, isUpdate bool) {
|
||||||
}
|
}
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
storage.Put(ctx, []byte{prefixTotalSupply}, 0)
|
storage.Put(ctx, []byte{prefixTotalSupply}, 0)
|
||||||
storage.Put(ctx, []byte{prefixRegisterPrice}, defaultRegisterPrice)
|
storage.Put(ctx, []byte{prefixRegisterPrice}, std.Serialize([]int{
|
||||||
|
defaultRegisterPrice, // Prices for all other lengths of domain names.
|
||||||
|
-1, // Domain names with a length of 1 are not open for registration by default.
|
||||||
|
-1, // Domain names with a length of 2 are not open for registration by default.
|
||||||
|
-1, // Domain names with a length of 3 are not open for registration by default.
|
||||||
|
-1, // Domain names with a length of 4 are not open for registration by default.
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symbol returns NeoNameService symbol.
|
// Symbol returns NeoNameService symbol.
|
||||||
|
@ -193,19 +200,31 @@ func Roots() iterator.Iterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPrice sets the domain registration price.
|
// SetPrice sets the domain registration price.
|
||||||
func SetPrice(price int) {
|
func SetPrice(priceList []int) {
|
||||||
checkCommittee()
|
checkCommittee()
|
||||||
if price < 0 || price > maxRegisterPrice {
|
if len(priceList) == 0 {
|
||||||
panic("The price is out of range.")
|
panic("price list is empty")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(priceList); i++ {
|
||||||
|
if i == 0 && priceList[i] == -1 {
|
||||||
|
panic("default price is out of range")
|
||||||
|
}
|
||||||
|
if priceList[i] < -1 || priceList[i] > maxRegisterPrice {
|
||||||
|
panic("price is out of range")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
storage.Put(ctx, []byte{prefixRegisterPrice}, price)
|
storage.Put(ctx, []byte{prefixRegisterPrice}, std.Serialize(priceList))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrice returns the domain registration price.
|
// GetPrice returns the domain registration price depending on the domain name length.
|
||||||
func GetPrice() int {
|
func GetPrice(length int) int {
|
||||||
ctx := storage.GetReadOnlyContext()
|
ctx := storage.GetReadOnlyContext()
|
||||||
return storage.Get(ctx, []byte{prefixRegisterPrice}).(int)
|
priceList := std.Deserialize(storage.Get(ctx, []byte{prefixRegisterPrice}).([]byte)).([]int)
|
||||||
|
if length >= len(priceList) {
|
||||||
|
length = 0
|
||||||
|
}
|
||||||
|
return priceList[length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAvailable checks whether provided domain name is available.
|
// IsAvailable checks whether provided domain name is available.
|
||||||
|
@ -222,6 +241,9 @@ func IsAvailable(name string) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if GetPrice(len(fragments[0])) < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if !parentExpired(ctx, 0, fragments) {
|
if !parentExpired(ctx, 0, fragments) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -306,7 +328,13 @@ func Register(name string, owner interop.Hash160, email string, refresh, retry,
|
||||||
if !runtime.CheckWitness(owner) {
|
if !runtime.CheckWitness(owner) {
|
||||||
panic("not witnessed by owner")
|
panic("not witnessed by owner")
|
||||||
}
|
}
|
||||||
runtime.BurnGas(GetPrice())
|
price := GetPrice(len(fragments[0]))
|
||||||
|
if price < 0 {
|
||||||
|
checkCommittee()
|
||||||
|
} else {
|
||||||
|
runtime.BurnGas(price)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tokenKey = getTokenKey([]byte(name))
|
tokenKey = getTokenKey([]byte(name))
|
||||||
oldOwner interop.Hash160
|
oldOwner interop.Hash160
|
||||||
|
@ -390,7 +418,17 @@ func Renew(name string) int {
|
||||||
if len(name) > maxDomainNameLength {
|
if len(name) > maxDomainNameLength {
|
||||||
panic("invalid domain name format")
|
panic("invalid domain name format")
|
||||||
}
|
}
|
||||||
runtime.BurnGas(GetPrice())
|
fragments := splitAndCheck(name, true)
|
||||||
|
if fragments == nil {
|
||||||
|
panic("invalid domain name format")
|
||||||
|
}
|
||||||
|
price := GetPrice(len(fragments[0]))
|
||||||
|
if price < 0 {
|
||||||
|
checkCommittee()
|
||||||
|
} else {
|
||||||
|
runtime.BurnGas(price)
|
||||||
|
}
|
||||||
|
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
ns := getNameState(ctx, []byte(name))
|
ns := getNameState(ctx, []byte(name))
|
||||||
ns.Expiration += millisecondsInYear
|
ns.Expiration += millisecondsInYear
|
||||||
|
|
|
@ -39,8 +39,10 @@ func newNSClient(t *testing.T, registerComTLD bool) *neotest.ContractInvoker {
|
||||||
|
|
||||||
func TestNameService_Price(t *testing.T) {
|
func TestNameService_Price(t *testing.T) {
|
||||||
const (
|
const (
|
||||||
minPrice = int64(0)
|
minPrice = int64(-1)
|
||||||
maxPrice = int64(10000_00000000)
|
maxPrice = int64(10000_00000000)
|
||||||
|
defaultPrice = 10_0000_0000
|
||||||
|
committeePrice = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
c := newNSClient(t, false)
|
c := newNSClient(t, false)
|
||||||
|
@ -50,28 +52,38 @@ func TestNameService_Price(t *testing.T) {
|
||||||
cAcc := c.WithSigners(acc)
|
cAcc := c.WithSigners(acc)
|
||||||
cAcc.InvokeFail(t, "not witnessed by committee", "setPrice", minPrice+1)
|
cAcc.InvokeFail(t, "not witnessed by committee", "setPrice", minPrice+1)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("get, default value", func(t *testing.T) {
|
t.Run("get, default value", func(t *testing.T) {
|
||||||
c.Invoke(t, defaultNameServiceDomainPrice, "getPrice")
|
c.Invoke(t, defaultPrice, "getPrice", 0)
|
||||||
|
c.Invoke(t, committeePrice, "getPrice", 1)
|
||||||
|
c.Invoke(t, committeePrice, "getPrice", 2)
|
||||||
|
c.Invoke(t, committeePrice, "getPrice", 3)
|
||||||
|
c.Invoke(t, committeePrice, "getPrice", 4)
|
||||||
|
c.Invoke(t, defaultPrice, "getPrice", 5)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("set, too small value", func(t *testing.T) {
|
t.Run("set, too small value", func(t *testing.T) {
|
||||||
c.InvokeFail(t, "The price is out of range.", "setPrice", minPrice-1)
|
c.InvokeFail(t, "price is out of range", "setPrice", []interface{}{minPrice - 1})
|
||||||
|
c.InvokeFail(t, "price is out of range", "setPrice", []interface{}{defaultPrice, minPrice - 1})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("set, too large value", func(t *testing.T) {
|
t.Run("set, too large value", func(t *testing.T) {
|
||||||
c.InvokeFail(t, "The price is out of range.", "setPrice", maxPrice+1)
|
c.InvokeFail(t, "price is out of range", "setPrice", []interface{}{minPrice - 1})
|
||||||
|
c.InvokeFail(t, "price is out of range", "setPrice", []interface{}{defaultPrice, minPrice - 1})
|
||||||
|
})
|
||||||
|
t.Run("set, negative default price", func(t *testing.T) {
|
||||||
|
c.InvokeFail(t, "default price is out of range", "setPrice", []interface{}{committeePrice, minPrice + 1})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("set, success", func(t *testing.T) {
|
t.Run("set, success", func(t *testing.T) {
|
||||||
txSet := c.PrepareInvoke(t, "setPrice", int64(defaultNameServiceDomainPrice+1))
|
txSet := c.PrepareInvoke(t, "setPrice", []interface{}{defaultPrice - 1, committeePrice, committeePrice, committeePrice, committeePrice, committeePrice})
|
||||||
txGet := c.PrepareInvoke(t, "getPrice")
|
txGet1 := c.PrepareInvoke(t, "getPrice", 5)
|
||||||
c.AddBlockCheckHalt(t, txSet, txGet)
|
txGet2 := c.PrepareInvoke(t, "getPrice", 6)
|
||||||
|
c.AddBlockCheckHalt(t, txSet, txGet1, txGet2)
|
||||||
c.CheckHalt(t, txSet.Hash(), stackitem.Null{})
|
c.CheckHalt(t, txSet.Hash(), stackitem.Null{})
|
||||||
c.CheckHalt(t, txGet.Hash(), stackitem.Make(defaultNameServiceDomainPrice+1))
|
c.CheckHalt(t, txGet1.Hash(), stackitem.Make(committeePrice))
|
||||||
|
c.CheckHalt(t, txGet2.Hash(), stackitem.Make(defaultPrice-1))
|
||||||
|
|
||||||
// Get in the next block.
|
// Get in the next block.
|
||||||
c.Invoke(t, stackitem.Make(defaultNameServiceDomainPrice+1), "getPrice")
|
c.Invoke(t, stackitem.Make(committeePrice), "getPrice", 2)
|
||||||
|
c.Invoke(t, stackitem.Make(committeePrice), "getPrice", 5)
|
||||||
|
c.Invoke(t, stackitem.Make(defaultPrice-1), "getPrice", 6)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,17 +160,17 @@ func TestRegisterAndRenew(t *testing.T) {
|
||||||
e := c.Executor
|
e := c.Executor
|
||||||
mail, refresh, retry, expire, ttl := "sami@nspcc.ru", int64(101), int64(102), int64(millisecondsInYear/1000*100), int64(104)
|
mail, refresh, retry, expire, ttl := "sami@nspcc.ru", int64(101), int64(102), int64(millisecondsInYear/1000*100), int64(104)
|
||||||
|
|
||||||
c.InvokeFail(t, "TLD not found", "isAvailable", "neo.com")
|
c.InvokeFail(t, "TLD not found", "isAvailable", "neo-go.com")
|
||||||
c.Invoke(t, true, "register", "org", c.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.Invoke(t, true, "register", "org", c.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeFail(t, "TLD not found", "isAvailable", "neo.com")
|
c.InvokeFail(t, "TLD not found", "isAvailable", "neo-go.com")
|
||||||
c.Invoke(t, true, "register", "com", c.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.Invoke(t, true, "register", "com", c.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.Invoke(t, true, "isAvailable", "neo.com")
|
c.Invoke(t, true, "isAvailable", "neo-go.com")
|
||||||
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceSysfee, "register", "neo.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceSysfee, "register", "neo-go.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeFail(t, "one of the parent domains is not registered", "register", "docs.neo.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeFail(t, "one of the parent domains is not registered", "register", "docs.neo-go.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeFail(t, "invalid domain name format", "register", "\nneo.com'", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeFail(t, "invalid domain name format", "register", "\nneo-go.com'", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeFail(t, "invalid domain name format", "register", "neo.com\n", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeFail(t, "invalid domain name format", "register", "neo-go.com\n", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceSysfee, "register", "neo.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceSysfee, "register", "neo-go.org", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceDomainPrice, "register", "neo.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeWithFeeFail(t, "GAS limit exceeded", defaultNameServiceDomainPrice, "register", "neo-go.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
var maxLenFragment string
|
var maxLenFragment string
|
||||||
for i := 0; i < maxDomainNameFragmentLength; i++ {
|
for i := 0; i < maxDomainNameFragmentLength; i++ {
|
||||||
maxLenFragment += "q"
|
maxLenFragment += "q"
|
||||||
|
@ -167,13 +179,13 @@ func TestRegisterAndRenew(t *testing.T) {
|
||||||
c.Invoke(t, true, "register", maxLenFragment+".com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.Invoke(t, true, "register", maxLenFragment+".com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.InvokeFail(t, "invalid domain name format", "register", maxLenFragment+"q.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeFail(t, "invalid domain name format", "register", maxLenFragment+"q.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
|
|
||||||
c.Invoke(t, true, "isAvailable", "neo.com")
|
c.Invoke(t, true, "isAvailable", "neo-go.com")
|
||||||
c.Invoke(t, 3, "balanceOf", e.CommitteeHash) // org, com, qqq...qqq.com
|
c.Invoke(t, 3, "balanceOf", e.CommitteeHash) // org, com, qqq...qqq.com
|
||||||
c.Invoke(t, true, "register", "neo.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.Invoke(t, true, "register", "neo-go.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
topBlock := e.TopBlock(t)
|
topBlock := e.TopBlock(t)
|
||||||
expectedExpiration := topBlock.Timestamp + uint64(expire*1000)
|
expectedExpiration := topBlock.Timestamp + uint64(expire*1000)
|
||||||
c.Invoke(t, false, "register", "neo.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.Invoke(t, false, "register", "neo-go.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
c.Invoke(t, false, "isAvailable", "neo.com")
|
c.Invoke(t, false, "isAvailable", "neo-go.com")
|
||||||
|
|
||||||
t.Run("domain names with hyphen", func(t *testing.T) {
|
t.Run("domain names with hyphen", func(t *testing.T) {
|
||||||
c.InvokeFail(t, "invalid domain name format", "register", "-testdomain.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
c.InvokeFail(t, "invalid domain name format", "register", "-testdomain.com", e.CommitteeHash, mail, refresh, retry, expire, ttl)
|
||||||
|
@ -182,12 +194,12 @@ func TestRegisterAndRenew(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
props := stackitem.NewMap()
|
props := stackitem.NewMap()
|
||||||
props.Add(stackitem.Make("name"), stackitem.Make("neo.com"))
|
props.Add(stackitem.Make("name"), stackitem.Make("neo-go.com"))
|
||||||
props.Add(stackitem.Make("expiration"), stackitem.Make(expectedExpiration))
|
props.Add(stackitem.Make("expiration"), stackitem.Make(expectedExpiration))
|
||||||
props.Add(stackitem.Make("admin"), stackitem.Null{}) // no admin was set
|
props.Add(stackitem.Make("admin"), stackitem.Null{}) // no admin was set
|
||||||
c.Invoke(t, props, "properties", "neo.com")
|
c.Invoke(t, props, "properties", "neo-go.com")
|
||||||
c.Invoke(t, 5, "balanceOf", e.CommitteeHash) // org, com, qqq...qqq.com, neo.com, test-domain.com
|
c.Invoke(t, 5, "balanceOf", e.CommitteeHash) // org, com, qqq...qqq.com, neo.com, test-domain.com
|
||||||
c.Invoke(t, e.CommitteeHash.BytesBE(), "ownerOf", []byte("neo.com"))
|
c.Invoke(t, e.CommitteeHash.BytesBE(), "ownerOf", []byte("neo-go.com"))
|
||||||
|
|
||||||
t.Run("invalid token ID", func(t *testing.T) {
|
t.Run("invalid token ID", func(t *testing.T) {
|
||||||
c.InvokeFail(t, "token not found", "properties", "not.exists")
|
c.InvokeFail(t, "token not found", "properties", "not.exists")
|
||||||
|
@ -198,10 +210,10 @@ func TestRegisterAndRenew(t *testing.T) {
|
||||||
|
|
||||||
// Renew
|
// Renew
|
||||||
expectedExpiration += millisecondsInYear
|
expectedExpiration += millisecondsInYear
|
||||||
c.Invoke(t, expectedExpiration, "renew", "neo.com")
|
c.Invoke(t, expectedExpiration, "renew", "neo-go.com")
|
||||||
|
|
||||||
props.Add(stackitem.Make("expiration"), stackitem.Make(expectedExpiration))
|
props.Add(stackitem.Make("expiration"), stackitem.Make(expectedExpiration))
|
||||||
c.Invoke(t, props, "properties", "neo.com")
|
c.Invoke(t, props, "properties", "neo-go.com")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetAddGetRecord(t *testing.T) {
|
func TestSetAddGetRecord(t *testing.T) {
|
||||||
|
@ -594,43 +606,44 @@ func TestNNSRegisterArbitraryLevelDomain(t *testing.T) {
|
||||||
cBoth.Invoke(t, true, "register", args...)
|
cBoth.Invoke(t, true, "register", args...)
|
||||||
|
|
||||||
c1 := c.WithSigners(acc)
|
c1 := c.WithSigners(acc)
|
||||||
|
// Use long (>4 chars) domain name to avoid committee signature check.
|
||||||
// parent domain is missing
|
// parent domain is missing
|
||||||
args[0] = "testnet.fs.neo.com"
|
args[0] = "testnet.filestorage.neo.com"
|
||||||
c1.InvokeFail(t, "one of the parent domains is not registered", "register", args...)
|
c1.InvokeFail(t, "one of the parent domains is not registered", "register", args...)
|
||||||
|
|
||||||
args[0] = "fs.neo.com"
|
args[0] = "filestorage.neo.com"
|
||||||
c1.Invoke(t, true, "register", args...)
|
c1.Invoke(t, true, "register", args...)
|
||||||
|
|
||||||
args[0] = "testnet.fs.neo.com"
|
args[0] = "testnet.filestorage.neo.com"
|
||||||
c1.Invoke(t, true, "register", args...)
|
c1.Invoke(t, true, "register", args...)
|
||||||
|
|
||||||
acc2 := c.NewAccount(t)
|
acc2 := c.NewAccount(t)
|
||||||
c2 := c.WithSigners(c.Committee, acc2)
|
c2 := c.WithSigners(c.Committee, acc2)
|
||||||
args = newArgs("mainnet.fs.neo.com", acc2)
|
args = newArgs("mainnet.filestorage.neo.com", acc2)
|
||||||
c2.InvokeFail(t, "not witnessed by admin", "register", args...)
|
c2.InvokeFail(t, "not witnessed by admin", "register", args...)
|
||||||
|
|
||||||
c1.Invoke(t, stackitem.Null{}, "addRecord",
|
c1.Invoke(t, stackitem.Null{}, "addRecord",
|
||||||
"something.mainnet.fs.neo.com", int64(nns.A), "1.2.3.4")
|
"something.mainnet.filestorage.neo.com", int64(nns.A), "1.2.3.4")
|
||||||
c1.Invoke(t, stackitem.Null{}, "addRecord",
|
c1.Invoke(t, stackitem.Null{}, "addRecord",
|
||||||
"another.fs.neo.com", int64(nns.A), "4.3.2.1")
|
"another.filestorage.neo.com", int64(nns.A), "4.3.2.1")
|
||||||
|
|
||||||
c2 = c.WithSigners(acc, acc2)
|
c2 = c.WithSigners(acc, acc2)
|
||||||
c2.Invoke(t, stackitem.NewBool(false), "isAvailable", "mainnet.fs.neo.com")
|
c2.Invoke(t, stackitem.NewBool(false), "isAvailable", "mainnet.filestorage.neo.com")
|
||||||
c2.InvokeFail(t, "parent domain has conflicting records: something.mainnet.fs.neo.com",
|
c2.InvokeFail(t, "parent domain has conflicting records: something.mainnet.filestorage.neo.com",
|
||||||
"register", args...)
|
"register", args...)
|
||||||
|
|
||||||
c1.Invoke(t, stackitem.Null{}, "deleteRecords",
|
c1.Invoke(t, stackitem.Null{}, "deleteRecords",
|
||||||
"something.mainnet.fs.neo.com", int64(nns.A))
|
"something.mainnet.filestorage.neo.com", int64(nns.A))
|
||||||
c2.Invoke(t, stackitem.NewBool(true), "isAvailable", "mainnet.fs.neo.com")
|
c2.Invoke(t, stackitem.NewBool(true), "isAvailable", "mainnet.filestorage.neo.com")
|
||||||
c2.Invoke(t, true, "register", args...)
|
c2.Invoke(t, true, "register", args...)
|
||||||
|
|
||||||
c2 = c.WithSigners(acc2)
|
c2 = c.WithSigners(acc2)
|
||||||
c2.Invoke(t, stackitem.Null{}, "addRecord",
|
c2.Invoke(t, stackitem.Null{}, "addRecord",
|
||||||
"cdn.mainnet.fs.neo.com", int64(nns.A), "166.15.14.13")
|
"cdn.mainnet.filestorage.neo.com", int64(nns.A), "166.15.14.13")
|
||||||
result := stackitem.NewArray([]stackitem.Item{
|
result := stackitem.NewArray([]stackitem.Item{
|
||||||
stackitem.NewByteArray([]byte("166.15.14.13")),
|
stackitem.NewByteArray([]byte("166.15.14.13")),
|
||||||
})
|
})
|
||||||
c2.Invoke(t, result, "resolve", "cdn.mainnet.fs.neo.com", int64(nns.A))
|
c2.Invoke(t, result, "resolve", "cdn.mainnet.filestorage.neo.com", int64(nns.A))
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
Loading…
Reference in a new issue