> 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/contract-open-standard/relationship/follow.md).

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