# How to build a social component

By [Rickey](https://paragraph.com/@amenetwork) · 2024-04-13

---

Ame Network has been deployed on multiple [testnets](https://github.com/HelloRickey/ame?tab=readme-ov-file#ame-world-contracts). This tutorial will guide you to quickly build a social component.

### Component Structure

You can copy the [Component](https://github.com/HelloRickey/ame/blob/main/contracts/Ame/Component.sol) template directly, or implement a component based on [IComponent](https://github.com/HelloRickey/ame/blob/main/contracts/Ame/IComponent.sol).

![](https://storage.googleapis.com/papyrus_images/e48ac9f59f595e6b7b1e304687a0a21bca48f5ea9bf763068e41a9b03cf30570.png)

**Component introduction:**

The `methodRequests` and `methodResponses` are used to define the request parameter type and response data type of Method. [Type](https://github.com/HelloRickey/ame/blob/main/contracts/Ame/Types.sol) is a data type Library, which contains all data types of solidity.

    mapping (string=>Types.Type[]) methodRequests;
    mapping (string=>Types.Type[]) methodResponses;
    

Method Types has 4 request types, GET, POST, PUT, OPTIONS. `methods` is used to store the method name array of each request type.

    mapping (MethodTypes=>string[]) methods;
    

The `options` function will return the request method type supported by the component.

    function options()public pure returns(MethodTypes[] memory){
      MethodTypes[] memory methodTypes=new MethodTypesUnsupported embed;
      methodTypes[0]=MethodTypes.GET;
      methodTypes[1]=MethodTypes.POST;
      methodTypes[2]=MethodTypes.PUT;
      methodTypes[3]=MethodTypes.OPTIONS;
      return methodTypes;
    }
    

The `setMethod` is used to set the request parameter type and response data type of the method.

    function setMethod(string memory _methodName,MethodTypes _methodType,Types.Type[] memory _methodReq,Types.Type[] memory _methodRes)  private  {
      methods[_methodType].push(_methodName);
      methodRequests[_methodName]=_methodReq;
      methodResponses[_methodName]=_methodRes;
     }
    

The `getMethods` returns the response method names according to the request type.

    function getMethods(MethodTypes _methodTypes)public view returns (string[] memory){
        return methods[_methodTypes];
    } 
    

The `getMethodReqAndRes` is used to obtain the request parameter type and response value type of the method based on the method name.

    function getMethodReqAndRes(string memory _methodName)public view returns(Types.Type[] memory ,Types.Type[] memory ){
      return(
        methodRequests[_methodName],
        methodResponses[_methodName]
      );
    }
    

Implement the functions of each method in `get`, `post`, and `put` .

    function get(string memory _methodName,bytes memory _methodReq)public pure returns(bytes memory){
      return abi.encode(_methodName,_methodReq);
    }
    
    function post(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){
      return abi.encode(_methodName,_methodReq);
    }
    
    function put(string memory _methodName,bytes memory _methodReq)public pure returns(bytes memory){
      return abi.encode(_methodName,_methodReq);
    }
    

### Component Data

Component data is designed based on the functions provided by your component. Our example will implement user creation, query and modification.Each user has two data fields: name and age.

    struct Profiles{
      string name;
      uint256 age;
    }
    mapping (address=>Profiles) users;
    

### Initialization Method Data Type

Initialize the methods you provide in the constructor. We initialize three request methods:

GET request, `getUser`, obtains the user's name and age.POST request, `createUser`, creates a user.PUT request, `updateUserName`, updates the user's name.

    constructor(){
      Types.Type[] memory getReqArray = new Types.TypeUnsupported embed;
      getReqArray[0] = Types.Type.ADDRESS;
      Types.Type[] memory dataTypeArray = new Types.TypeUnsupported embed;
      dataTypeArray[0] = Types.Type.STRING;
      dataTypeArray[1] = Types.Type.UINT256;
      Types.Type[] memory putReqArray = new Types.TypeUnsupported embed;
      putReqArray[0] = Types.Type.ADDRESS;
      putReqArray[1] = Types.Type.STRING;
      setMethod("getUser",MethodTypes.GET,getReqArray,dataTypeArray);
      setMethod("createUser",MethodTypes.POST,dataTypeArray,new Types.TypeUnsupported embed);
      setMethod("updateUserName",MethodTypes.PUT,putReqArray,new Types.TypeUnsupported embed);
    }
    

### Implement Request Methods

Implement each request method in GET, POST, and PUT.

        function get(string memory _methodName,bytes memory _methodReq)public view returns(bytes memory){
            if(compareStrings(_methodName,"getUser")){
                address user=abi.decode(_methodReq, (address));
                bytes memory userData=abi.encode(users[user].name,users[user].age);
                return userData;
            }else{
                return abi.encode("");
            }  
        }
    
        function post(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){
            if(compareStrings(_methodName,"createUser")){
                (string memory name,uint256 age)=abi.decode(_methodReq, (string,uint256));
                users[msg.sender]=Profiles(name,age);
                bytes memory resBytes=abi.encode(name,age);
                emit  Response(resBytes);
                return resBytes;
            }
            return abi.encode("");
        }
    
        function put(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){
            if(compareStrings(_methodName,"updateUserName")){
                (address userAddress,string memory name)=abi.decode(_methodReq, (address,string));
                require(userAddress==msg.sender);
                users[userAddress].name=name;
            }
            return abi.encode("");
        }
    

### Deploy Contract

All code can be viewed at [ComponentExample](https://github.com/HelloRickey/ame/blob/main/contracts/Components/Example/ComponentExample.sol).

This component example has been deployed on multiple [testnets](https://github.com/HelloRickey/ame/blob/main/contracts/Components/Example/README.md#network).

### How to Use Ame Components Scan

[Ame Components Scan](https://scan.ame.network/) is a manager for viewing social components of various networks. You can use it directly to interact with components.

1\. Please select a network and connect your wallet.

![](https://storage.googleapis.com/papyrus_images/c182300c2b48f726a58d8e79fe1b073e19c63c88f45c5dd24542f721e498e301.png)

2\. Register as a new user

![](https://storage.googleapis.com/papyrus_images/9d5160560a2433d831ec14729004731a317e1ef70f361d307e5b139df9541bdd.png)

3\. Enter component address to search.

![](https://storage.googleapis.com/papyrus_images/c01d366e5ae0d09f922881f4be497fa9035f675b06fd64efc2091cd7b7bd4bb8.png)

4\. Call methods in GET, POST, and PUT

![](https://storage.googleapis.com/papyrus_images/934b4471a1a5d2b7d59693e9c31796a76827184076267b5ec2cae719c1d57770.png)

### **Finale**

If you want to contribute your components, you can refer to the [component standard](https://github.com/HelloRickey/ame/blob/main/contracts/Components/README.md), I am still actively building Ame Network. If you are also interested, you can contact me on Twitter at any time.

---

*Originally published on [Rickey](https://paragraph.com/@amenetwork/how-to-build-a-social-component)*
