> For the complete documentation index, see [llms.txt](https://relationlabs.gitbook.io/protocol/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://relationlabs.gitbook.io/protocol/protocol-zh/contract-open-standard/relationship/follow.md).

# Follow

"Follow" 是一种社交媒体术语，用于表示一个用户关注了另一个用户的帐户，以便随时获得该用户发布的最新更新和内容。通过关注其他用户，人们可以获得感兴趣的内容和信息，以及与其他用户进行交流和互动的机会。

我们提供了Follow合约，用于表示单向的关注关系。

## Schema

### FollowRegister

FollowRegister对应的[schema](https://arweave.net/auPfoCDBtJ3RJ_WyUqV9O7GAARDzkUT4TSuj9uuax-0) 以ttl文件的形式保存至Arweave，交易哈希将作为schemaURI，在初始化合约时传入，参数示例：

```
ar://auPfoCDBtJ3RJ_WyUqV9O7GAARDzkUT4TSuj9uuax-0
```

用于描述某个地址的Follow合约地址，完整的rdf示例如下：

```
:Soul_0x0000000000000000000000000000000000000011 p:connectionContract :Activity_0x12345678901111111000000000
```

* 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表示接受和绑定域名解析的地址;:Contract用于表示Follow合约的地址

```

:Soul a rdfs:Class ;
    rdfs:label "Soul" ;
    rdfs:comment "A soul." .

:Contract a rdfs:Class ;
    rdfs:label "Contract" ;
    rdfs:comment "A contract." .
```

* Predicate

p:followContract用于描述某个地址持有的follow合约地址

```
p:followContract a rdf:Property ;
    rdfs:label "followContract" ;
    rdfs:comment "The soul's follow contract." ;
    rdfs:domain :Soul ;
    rdfs:range :Contract .
```

### Follow

Follow合约对应的[schema](https://arweave.net/-2hCuTMqo1fz2iyzf7dbEbzoyceod5KFOyGGqNiEQWY) 以ttl文件的形式保存至Arweave，交易哈希将作为schemaURI，在初始化合约时传入，参数示例：

```
ar://-2hCuTMqo1fz2iyzf7dbEbzoyceod5KFOyGGqNiEQWY
```

描述某个地址following了当前合约的owner，完整的rdf示例如下：

```
:Soul_0x0000000000000000000000000000000000000022 p:following :Soul_0x0000000000000000000000000000000000000011
```

* 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表示接受和绑定域名解析的地址;:Contract用于表示Follow合约的地址

```

:Soul a rdfs:Class ;
    rdfs:label "Soul" ;
    rdfs:comment "A soul." .

```

* Predicate

p:following 描述地址间的follow关系

```
p:following a rdf:Property ;
    rdfs:label "following" ;
    rdfs:comment "Following a soul." ;
    rdfs:domain :Soul ;
    rdfs:range :Soul .
```

## 合约

Follow的合约模版，我们把FollowRegister作为工厂合约和注册中心，用于部署和记录用户的Follow合约。

### FollowRegister

```solidity
interface IFollowRegister is ISemanticSBT {

    /**
     * 部署follow合约
     * @param addr 接受Follow合约的地址
     * @return tokenId 
     */
    function deployFollowContract(address addr) external returns (uint256);

    /**
     * 查询地址的Follow合约地址
     * @param owner Follow合约的地址持有者
     * @return contractAddress Follow合约地址 
     */
    function ownedFollowContract(address owner) external view returns (address);
}
```

### Follow

```solidity

interface IFollow is ISemanticSBT {


    /**
     * 初始化合约，由FollowRegister进行调用
     */
    function initialize(
        address owner,
        address minter,
        string memory name_,
        string memory symbol_,
        string memory baseURI_,
        string memory schemaURI_,
        string[] memory classes_,
        Predicate[] memory predicates_
    ) external;

    /**
     * 关注
     * @return tokenId 
     */
    function follow() external returns (uint256);

    /**
     * 取消关注
     * @return tokenId 
     */
    function unfollow() external returns (uint256);

    /**
     * 查询是否关注
     * @return isFollowing 是否关注当前合约的owner 
     */
    function isFollowing(address addr) external view returns (bool);
    
}

```

### 合约实现说明

FollowRegister作为工厂合约、注册中心和路由合约，业务逻辑包含：

* deployFollowContract 部署Follow合约
* ownedFollowContract 查找地址所持有的Follow合约

Follow作为实际记录用户follow关系的合约，每个用户都有属于自己的Follow合约，当有粉丝follow了该用户，会在用户的Follow合约mint一个token给到粉丝。

* follow 粉丝会在被关注的用户Follow合约上mint一个token
* unfollow 粉丝取消关注，将原来的token销毁

完整的合约代码可访问：

* [FollowRegister](https://github.com/relationlabs/semanticSBT/blob/main/contracts/template/FollowRegister.sol)
* [Follow](https://github.com/relationlabs/semanticSBT/blob/main/contracts/template/Follow.sol)
