# 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://relationlabs.gitbook.io/protocol/protocol-zh/contract-open-standard/relationship/follow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
