# Follow

"Follow" is a term used on social media platforms to describe the act that a user follows another to monitor the latter's new posts. This increases interaction between users.

The "Follow" contract we provide is used to describe a one-way action of following.

## Schema

### FollowRegister

The [schema](https://arweave.net/auPfoCDBtJ3RJ_WyUqV9O7GAARDzkUT4TSuj9uuax-0) corresponding to the FollowRegister contract is saved to Arweave in the form of a ttl file, with the transaction hash as the schemaURI to be passed to the contract during its initialization stage. For example:

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

To describe the Follow contract address of a certain address, we can use the following rdf as an example:

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

* The list of prefixes.

```
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" means the address for accepting and bounding a name. ":Contract" means the address of the "Follow" contract.

```
: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" is used to describe the addresses of the "follow" contracts owned by a particular address.

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

### Follow

The [schema](https://arweave.net/-2hCuTMqo1fz2iyzf7dbEbzoyceod5KFOyGGqNiEQWY) corresponding to the Follow contract is saved to Arweave in the form of a ttl file, with the transaction hash as the schemaURI to be passed to the contract during its initialization stage. For example:

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

To describe that certain address is following the owner of the current contract, we can use the following rdf as an example:

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

* Prefix of a namespace.

```
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" means the address for accepting and bounding a name. ":Contract" means the address of the "Follow" contract.

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

```

* Predicate

"p:following" is used to describe the "follow" relationship between addresses.

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

## Contract

The contract template for the Follow contract. We use FollowRegister as the factory pattern and registration center to deploy and record a user's Follow contract.

### FollowRegister

```solidity
interface IFollowRegister is ISemanticSBT {

    /**
     * Deploy a follow contract.
     * @param addr : The address to accept a Follow contract.
     * @return tokenId 
     */
    function deployFollowContract(address addr) external returns (uint256);

    /**
     * Query the Follow contract address of a certain address.
     * @param owner : The owner of the address of the Follow contract.
     * @return contractAddress : The Follow contract address.
     */
    function ownedFollowContract(address owner) external view returns (address);
}
```

### Follow

```solidity

interface IFollow is ISemanticSBT {


    /**
     * Initialize the contract
     */
    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;

    /**
     * Follow the owner of the current contract.
     * @return tokenId 
     */
    function follow() external returns (uint256);

    /**
     * Unfollow
     * @return tokenId 
     */
    function unfollow() external returns (uint256);

    /**
     * Returns whether the `addr` is following the owner of the current contract
     * @return isFollowing  
     */
    function isFollowing(address addr) external view returns (bool);
    
}

```

### Contract implementation note

As a factory pattern, registration center and router contract, the "FollowRegister" has the following business logic:

* deployFollowContract: To deploy the "Follow" contract.
* ownedFollowContract: To query the "Follow" contract owned by an address.

As the contract actually records a user's "follow" relationships, "Follow" can be owned by each user. When a new fan follows a user, a token will be minted by the user's "Follow" contract and distributed to the fan.

* follow: A fan will mint a token via the "Follow" contract of the person he/she follows.
* unfollow: When a fan cancels the "follow" relationship and burns the token generated by that particular relationship.

Full source code:

* [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/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.
