Skip to content

Instantly share code, notes, and snippets.

@tempe-techie
Created April 21, 2023 15:04
Show Gist options
  • Save tempe-techie/1620247ca59416e17e30df852dcc1756 to your computer and use it in GitHub Desktop.
Save tempe-techie/1620247ca59416e17e30df852dcc1756 to your computer and use it in GitHub Desktop.
Ethereum Follow Protocol ideas

Brainstorming EFP implementation ideas (WIP)

The original idea: https://twitter.com/BrantlyMillegan/status/1648794925754974209

  • Lists of accounts being followed
  • Each list is an NFT (ERC-721) and is transferable

The code below should be considered as pseudocode as it wasn't compiled or tested, just written off the top of my head.

Non-NFT example

Let's start first with an non-NFT example because it is less complex to develop which allows us to focus on the core functionality.

Storage

A mapping of the follower's address and all the addresses the follower is following.

mapping (address => address[]) public followingList; // follower => list of followed addresses

It's worth researching other ways of storing followed accounts to find the optimal solution in terms of gas usage and usability.

Functions

Get all followed addresses of an account:

function getFollows(address _follower) external view returns(address[] memory) {
  return followingList[_follower];
}

Add an address to the list:

function follow(address _following) external {
  followingList[msg.sender].push(_following);
}

Remove an address from the list:

function unfollow(uint256 _index) external {
  delete followingList[msg.sender][_index];
}

The removing part is a bit trickier because "following" has many-to-many relationship (one account can follow many accounts, and one account can be followed by many accounts). So unfollowing an address (if we use the kind of mapping-array storage as defined in the first code snippet) has an O(n) complexity if we want to find and delete it by address (it would require looping through the array).

The alternative is to do the looping externally (on a client/frontend) and to remove an address based on its position in the array (index number). That's why the index is used in the code example above.

Check if an address is followed by another address:

This one is also tricky for the same reason as explained before. The array needs to be looped to figure out if a certain address is being followed by a given user or not.

The looping could occur in the smart contract...

function isFollowing(address follower, address following) public view returns (bool) {
    address[] memory followingListForFollower = followingList[follower];
    for (uint i = 0; i < followingListForFollower.length; i++) {
        if (followingListForFollower[i] == following) {
            return true;
        }
    }
    return false;
}

... or it could take place off-chain.

View/getter function calls from frontends don't require any gas to be paid, but nodes usually have a gas limit on view calls. So technically if a following array is too big, the isFollowing function call could fail.

Again, the alternative is to do the looping off-chain or to have a different follow data structure with a lower (constant) complexity (e.g. 2D mapping), but this comes with other trade-offs.

Additional features

Pay to follow

An address could require a potential follower to pay before they can follow them.

Storage:

mapping (address => uint256) public followPrice; // address to be followed => price in wei

The follow function would then need to be updated like this:

function follow(address _following) payable external {
  if (followPrice[_following] > 0) {
    (bool success, ) = payable(_following).call{value: msg.value}("");
    require(success, "Payment to followed address failed.");
  }

  followingList[msg.sender].push(_following);
}

NFT example

  • A list of followed addresses would need to be mapped to an NFT ID instead of a follower's address.
  • It would allow an address to have multiple lists.
  • A nice-to-have feature would be the ability to name each list, preferably using NFT metadata (and to also add other information like a description).

WIP

The other way round (list of followers)

The examples above are for a list of followed addresses. Meaning that a user has their own list of addresses that they follow.

But it could also be done the other way around, as a list of followers. So an account would have a list of addresses that follow this account.

The account could then be able to set gating rules to get on that list, or even be able to manually remove addresses from their list.

WIP


Please add your feedback and ideas in the comment section below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment