-
Notifications
You must be signed in to change notification settings - Fork 1
cyber.domain_contract.md
Cмарт-контракт cyber.domain
обеспечивает создание и обработку доменных имен, создание или удаление привязки доменных имен к аккаунтам, создание имен пользователей с привязкой к аккаунту, смену владельцев доменных имен, а также покупку доменных имен на аукционе.
В состав смарт-контракта cyber.domain
входят:
- группа экшен-операций, используемых для покупки доменного имени на аукционе, в том числе:
checkwin
,biddomain
,biddmrefund
,newdomain
иdeclarenames
; - группа внутренних доменных экшен-операций, в том числе:
passdomain
,linkdomain
,unlinkdomain
иnewusername
. Код данных экшен-операций находится в ядре, но их вызов происходит через смарт-контракт; - объявления используемых в транзакциях имен.
Доменные имена в CyberWay формируются в соответствии с правилами и процедурами Domain Name System (DNS). К структуре доменных имен предъявляются следующие требования:
- общее количество символов в доменном имени не должно превышать 253 шт.;
- доменное имя состоит из отдельных частей, разделенных символом «точка»;
- наличие нахождения рядом двух символов «точка» недопустимо;
- количество символов в отдельной части доменного имени не должно превышать 63 шт.;
- допустимыми символами в доменном имени являются буквенно-цифровые, а также символ «дефис»;
- наличие прописных букв в доменном имени недопустимо;
- символ «дефис» не должен находиться в начале или конце любой части доменного имени;
- самая правая часть доменного имени должна содержать хотя бы один буквенный символ. Наличие в ней только цифровых символов недопустимо.
Экшен-операции checkwin
, biddomain
, biddmrefund
и newdomain
используются для покупки доменного имени на аукционе. Процедура покупки доменного имени на аукционе выполняется аналогично процедуре покупки имени аккаунта. В процедуре действуют следующие правила:
- ставки на покупку любого доменного имени принимаются на аукционе в любой момент;
- по самой крупной ставке определяется единственное доменное имя, которое может быть выкуплено в настоящий момент;
- доменное имя считается выкупленным на аукционе, если были выполнены следующие условия:
- после трансфера ставки на данное доменное имя прошло не более суток;
- с момента предыдущего выкупа любого доменного имени прошло не менее суток;
- количество выкупленных доменных имен на аукционе в течение суток должно быть не более одного;
- по завершении аукциона победителю трансфер не возвращается. Победитель может воспользоваться следующими возможностями:
- создать самостоятельно доменное имя с использованием операции
newdomain
и стать его владельцем; - владелец доменного имени может создать от него поддоменные имена добавлением к нему слева символа «точка» и части имени (например, владелец домена
golos.io
может создавать поддоменыapi.golos.io
,ws.golos.io
и т.д. Следует заметить, что в отличие от аккаунтов вcyberway
, где имена формируются добавлением частей справа, отcyber
могут быть образованыcyber.msig
,cyber.domain
). При этом допускается только прямое наследование доменных имен (например, если владелец создал домен для второго уровня, то создание домена для третьего уровня будет недопустимым).
- создать самостоятельно доменное имя с использованием операции
Примечания:
- В EOSIO имеются экшен-операции, прописанных непосредственно в ядре. У этой группы экшен-операций часть логики выполняется в ядре, а часть — в смарт-контракте (например, у
newaccount
создание самогоaccount
, обработка данных памяти и выделение ресурсовbandwidth
выполняется в ядре). Такое разделение логики дает возможность гибко задавать дополнительные ограничения и обработку без изменения кода ядра, то есть обходиться без проведения хардфорка, ограничиваясь изменениями смарт-контракта. (В дальнейшем необходимо окончательно определиться с местом объявления таких экшен-операций). - Экшен-операции смарт-контракта
cyber.domain
изначально предназначались для распределения доменных имен на основе аукциона. Впоследствии эта группа экшен-операций была дополнена другими, в том числе обеспечивающими такие функции: создание домена, передача домена, привязка/отвязка домена, объявление использованных имен в транзакциях, создание имени пользователя.
Экшен-операция checkwin
используется для контроля появления владельца (победителя) доменного имени на аукционе. Данная операция не требует специального вызова и вызывается автоматически с определенной периодичностью.
Экшен-операция checkwin
имеет следующий вид:
[[eosio::action]] void checkwin();
Данная операция не имеет входных параметров. Для ее вызова требуются права контракта cyber.domain
.
Экшен-операция biddomain
позволяет аккаунту делать ставки на аукционе для покупки доменного имени. Данная операция имеет следующий вид:
[[eosio::action]] void biddomain(
name bidder,
domain_name name,
asset bid
);
Параметры:
bidder
— имя аккаунта, делающего ставку на аукционе на покупку доменного имени;
name
— доменное имя (строковое значение в соответствии с требованиями), на которое делается ставка. ;
bid
— значение в виде структуры, задающее ставку.
Для выполнение данной экшен-операции требуется, чтобы аккаунт смарт-контракта cyber.domain
был наделен правами аккаунта bidder
. В случае, если на аукционе появляется ставка с большим значением, осуществляется возврат ставки аккаунту bidder
. Возврат выполняется автоматически внутренним вызовом biddmrefund
из biddomain
.
Экшен-операция biddmrefund
используется для возврата с аукциона ставки на покупку доменного имени в случае, если для того же доменного имени была сделана ставка с бо́льшим значением. Данная операция имеет вид:
[[eosio::action]] void biddmrefund(
name bidder,
domain_name name
);
Параметры:
bidder
— имя аккаунта, которому делается возврат средств с аукциона;
name
— доменное имя, на покупку которого была сделана ставка.
В случае возникновения нестандартной ситуации (появление сбоя в сети или ошибки в работе узла) возможен вызов biddmrefund
отдельно от вызова biddomain
(нестандартный вызов biddmrefund
).
Экшен-операция newdomain
используется для создания нового доменного имени. Данная операция имеет следующий вид:
[[eosio::action]] void newdomain(
eosio::name creator,
domain_name name
);
Параметры:
creator
— имя аккаунта, создающего доменное имя;
name
— создаваемое доменное имя.
Экшен-операция newdomain
может быть выполнена в следующих вариантах:
- создание доменного имени системным аккаунтом
cyber.domain
; - создание собственного доменного имени победителем аукциона доменных имен;
- создание суб-доменного имени владельцем прямого родительского домена.
Аккаунт смарт-контракта cyber.domain
должен быть привилегированным или иметь разрешения на перевод средств с cyber.namesaccount
(в случае возврата средств). По завершении выполнения данной экшен-операции аккаунт creator
становится владельцем созданного доменного имени.
Для определения имени пользователя только одного доменного имени недостаточно. Имя пользователя привязывается к аккаунту-владельцу и аккаунту-области (обычно это смарт-контракт) и имеет вид структуры имя@домен
. Доменная часть определяет область. В разных областях могут существовать аккаунты с одинаковыми именами.
Имеются несколько синтаксисов, поддерживаемых данные username
, которые позволяют текстовому представлению имени пользователя сопоставить имя аккаунта.
Ограничения, введенные на значение username
К структуре имени пользователя предъявляются следующие требования:
- общее количество символов в имени пользователя не должно превышать 32 шт.;
- имя пользователя может состоять из отдельных частей, разделенных символом «точка»;
- наличие нахождения рядом двух символов «точка» недопустимо;
- допустимыми символами в имени пользователя являются буквенно-цифровые, а также символ «дефис»;
- наличие прописных букв в имени пользователя недопустимо;
- символ «дефис» не может находиться в начале или в конце имени пользователя.
Объявление declarenames
используется для передачи списка структур с информацией об использованных в транзакциях доменных именах (или именах пользователей) и соответствующих им аккаунтам.
[[eosio::action]] void declarenames(
vector<name_info> domains
);
Параметр:
domains
— массив описаний, каждое описание представляет собой структуру name_info
.
Объявление declarenames
может быть выполнена любым аккаунтом.
Объявление newusername
используется для создания имени пользователя. При создании имени пользователя используются три поля — creator
, owner
, name
. Объявление newusername
имеет следующий вид:
[[eosio::action]] void newusername(
name creator,
name owner,
username name
);
Параметры:
creator
— имя аккаунта, в области которого создается имя пользователя;
owner
— имя аккаунта, являющимся владельцем имени пользователя;
name
— текстовое представление имени пользователя.
Объявлению newusername
передаются списки структур с информацией об использованных именах и соответствующих им аккаунтам. Объявление newusername
может быть создано любым аккаунтом.
Выполнение операции newusername
транзакция должна быть подписана аккаунтом creator
.
Объявление passdomain
используется для передачи доменного имени от одного аккаунта другому (для смены владельца доменного имени). Объявление passdomain
имеет следующий вид:
[[eosio::action]] void passdomain(
name from,
name to,
domain_name name
);
Параметры:
from
— имя аккаунта, от которого передается доменное имя и который является его владельцем;
to
— имя аккаунта, которому передается доменное имя и который будет является его владельцем;
name
— строковое представление передаваемого доменного имени.
Для выполнения операции в транзакции требуется подпись аккаунта from
— владельца доменного имени.
Объявление linkdomain
используется для привязки доменного имени к имени аккаунта. Объявление linkdomain
имеет следующий вид:
[[eosio::action]] void linkdomain(
name owner,
name to,
domain_name name
);
Параметры:
owner
— имя аккаунта, от которого удаляется привязка доменного имени и который был его владельцем;
to
— имя аккаунта, к которому добавляется привязка доменного имени и который становится его владельцем;
name
— строковое представление доменного имени.
Объявление unlinkdomain
используется для удаления привязки доменного имени от имени аккаунта. Объявление unlinkdomain
имеет следующий вид:
[[eosio::action]] void unlinkdomain(
name owner,
domain_name name
);
Параметры:
owner
— имя аккаунта, от которого удаляется привязка доменного имени и который был его владельцем;
name
— строковое представление доменного имени.
Пример использования объявлений linkdomain и unlinkdomain
Пусть аккаунту, который имеет контракт, присвоено трудно запоминаемое имя ajhgsd23qw
.
Для устранения этого недостатка данный аккаунт, используя linkdomain
, привязывает доменное имя helloworld
к своему контракту.
Пользователям легче запомнить домен @helloworld
и отправлять трансфер на это имя, в отличие от трансфера на имя аккаунта ajhgsd23qw
. Доменное имя @helloworld
будет разрешаться в ajhgsd23qw
и в транзакции будет добавлено экшен-операция declarenames
с указанием использованных доменных имен.
Для прекращения использования доменного имени @helloworld
аккаунт должен вызвать экшен-операцию unlinkdomain
. После этого доменное имя @helloworld
не будет разрешаться в ajhgsd23qw
и, следовательно, отправка трансфера на него будет невозможна.
Аккаунт ajhgsd23qw
в своем окружении может также создать себе имя пользователя, например, admin
. В этом случае имя admin@@helloworld
будет разрешаться в имя ajhgsd23qw
. При добавлении доменного имени можно использовать admin@helloworld
.
Структура name_info
используется для проверки наличия всех элементов в момент их применения, а также наличия связи доменного имени с указанным аккаунтом. Объявление name_info
имеет следующий вид:
struct name_info {
domain_name domain;
name account;
vector<username> users;
};
Параметры:
domain
— доменное имя;
account
— имя аккаунта, соответствующее доменному имени;
users
— список имен пользователей доменного имени.
Объявление declarenames
принимает на вход массив структур. Количество принимаемых структур не должно быть нулевым. При попытке отправления пустого массива возникает ошибка.
Для имен пользователей отсутствуют соответствия, так как имя пользователя, в отличие от доменного имени, в течение всего времени не меняет свой аккаунт.
Вводятся следующие дополнительные ограничения:
- структуры должны быть отсортированы по доменному имени, то есть имена доменов должны располагаться по возрастанию. Исключение составляет для доменного имени, являющегося пустой строкой. Это возможно, когда имя пользователя указывается не на доменном имени, а явно в смарт-контракте. В этом случае сортировка должна быть выполнена по имени аккаунта по полю
.account
; - доменное имя не должно содержать два одинаковых значения
.domain
, за исключением пустых значений (“”); - поле
.account
в доменном имени не должно содержать пустое значение.
- Вместе с
declarenames
для внутреннего использования могут присутствовать короткие имена аккаунтов, заменяемые реальные имена аккаунтов. Преобразование внутренних коротких имен в реальные имена аккаунтов выполняется на уровне эксплорера. - В настоящей реализации нет проверки, что указанные в
declarenames
аккаунты существуют в других экшен-операциях. Реализация проверки затруднена, так как непосредственно процесс проверки требует большие ресурсы, затрачиваемые на чтение файла формата ABI и десериализацию действия. Риск отсутствия такой проверки — добавление отправителем транзакции больше информации, чем ее необходимо для проверки. В результате ему нужно будет дополнительно заплатить за излишне используемые ресурсыbandwidth
. - В настоящей реализации отсутствует информация о позициях используемых доменовских или пользовательских именах.Транзакция может содержать действие с несколькими именами аккаунтов в качестве аргументов, например,
someaction( name 1, name 2, name 3, name 4, name 5)
. В случае, если пользователь отправит действие видаsomeaction( acc1, one@golos, two@golos, acc1, three@golos)
и оно разрешится на том же аккаунте (someaction(acc1, acc1, acc1, acc1, acc3)
) , тоdeclarenames
будет содержать только используемые имена пользователей или доменные имена. При этом нельзя определить позиции, на которых были использованы имена пользователей, например:
declarenames([{
domain:"golos",
account:N(acc1),
users:["one","two","three"]
}])
- Реализована поддержка имен вида
username@@account
(наличие символов «@@» в имени означает, что правая часть — не доменное имя, а имя аккаунта). Например, если транзакция разрешает имена видаalice@@token
,bob@@token
,admin@@golos.io
, то объявлениеdeclarenames
будет содержать следующие аргументы:
declarenames([
{domain:"", account:N(golos.io), users:["admin"]},
{domain:"", account:N(token), users:["alice","bob"]}
])