Schema的文件格式
一个完整的schema由三部分组成组成:前缀列表、class、predicate
前缀列表
定义前缀,是为了更简短的描述一个资源。
如果没有前缀,那么需要采用完整的URI来描述资源,如描述Person_001实体:
<http://relationlabs.ai/entity/Person_001>
定义了前缀之后,我们描述同样的实体,只需要使用简短字符:
完整的前缀列表:
PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
需要说明的是,rdf:
、xsd:
和 rdfs:
是W3C提供的标准前缀,:
和 p:
是 Relation Protocol中定义的前缀,分别用于表示实体和属性。
Class
Class是对实体的抽象,实体是class的具体实例。比如,我们定义一组Soul实体,那么可以首先定义一个Soul的class,使用rdf描述为:
Predicate
Predicate也叫做属性,用于描述主语和宾语的关系。Predicate通常需要定义domain
和range
,比如:
p:following a rdf:Property ;
rdfs:domain :Soul ;
rdfs:range :Soul .
这段Schema定义了:
谓词p:following
是一个Property。
Schema示例
我们以Name Service的需求为例:
用户对持有的域名设置解析,将域名解析到自己的地址上
想要实现上面场景,我们需要有Soul实体表示用户的地址,Namen实体表示名称。 还需要谓词来描述两者的关系,这里有两个状态需要描述,分别为hold表示地址持有域名,resolved表示地址已被该域名解析。
因此,我们在schema里需要有下面的class和predicate
基于上面定义的class和predicate,我们组装成一个完整的schema:
PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
###################
# class
###################
:Soul a rdfs:Class ;
rdfs:label "Soul" ;
rdfs:comment "A soul." .
:Name a rdfs:Class ;
rdfs:label "Name" ;
rdfs:comment "A name." .
###################
# predicate
###################
p:hold a rdf:Property ;
rdfs:label "hold" ;
rdfs:comment "A Soul to own a name." ;
rdfs:domain :Soul ;
rdfs:range :Name .
p:resolved a rdf:Property ;
rdfs:label "resolved" ;
rdfs:comment "The resolved name of a soul." ;
rdfs:domain :Soul ;
rdfs:range :Name .
p:profileURI a rdf:Property ;
rdfs:label "profileURI" ;
rdfs:comment "The profileURI of a soul." ;
rdfs:domain :Soul ;
rdfs:range xsd:string .
一个完整的持有域名的rdf示例:
:Soul_0x0000000000000000000000000000000000000011 p:hold :Name_example.
一个完整的被域名解析的rdf示例:
:Soul_0000000000000000000000000000000000000011 p:resolved :Name_resolve.
Schema对合约的约束
schema定义了RDF数据格式,作为合约数据模型的词汇表,需要合约内的数据模型定义跟schema保持一致(见图 4-2),这样合约生成的RDF数据才可以被Graph Indexer正确解析。
为此,我们在合约初始化时,需要传入参数schemaURI、className以及Predicate,将schema定义的内容转化成合约可读的代码结构。其中,schemaURI可以访问得到完整的schema内容;className为schema里定义的class名称;Predicate由schema里定义的predicate名称以及range类型组成。
下面是一个初始化合约传入的参数:
const name = 'Relation Name Service V1';
const symbol = 'SBT';
const baseURI = 'https://api.example.com/v1/';
const schemaURI = 'ar://PsqAxxDYdxfk4iYa4UpPam5vm8XaEyKco3rzYwZJ_4E';
const className = ["Domain"];
const predicates = [["hold", 3], ["resolved", 3], ["profileURI", 1]];
await semanticSBT.initialize(
owner.address,
name,
symbol,
baseURI,
schemaURI,
className,
predicates);
可以看到, schemaURI是Arweave上的交易哈希,可以通过Arweave的网关直接访问schema完整内容。className以及predicates与schema里定义的class和predicate是一致的。