Highlight Smart Contracts: Interoperability & Provenance

Prerequisite reading -

Overview

Extensibility

Cost

Communication is difficult. This problem permeates most things we interact with. Typically, communication is facilitated through standards that communicating entities agree to. An example of a standard is language. Rich standards are key for good communication, since standards inevitably compress data. We’ll discuss how the Highlight protocol is interoperable within web3, using standards so that creators can leverage the entire network of smart contracts. We’ll also discuss how Highlight’s creator-owned community contracts empower creator provenance. Ultimately this combination of interoperability and provenance helps creators build communities that are composable with the wider ecosystem.

Interoperability

Royalties

The Community smart contracts adhere to both ERC-2981 and expose a royalty recipient address and amount in contract metadata, auto-configuring royalty splits for Opensea. When creators set up a community on Highlight, they invoke a function on the factory smart contract that deploys a royalty splitter for the community and exposes the splitter’s address via both ERC-2981 and contract metadata.

Since contract metadata exists off-chain on Arweave, we face an interesting challenge of having to know the royalty split address before the factory function is called. Since royalty splits on SplitMain (a factory for royalty split contracts) are created via the Create2 opcode, we can do that. However, since splits and communities have a one-to-one relationship, communities uniquely determine the input into the creation of the splits contract. Therefore, our community factory needs to be able to predict the community address as well. This results in a nested prediction chain where we:

  1. Predict the community address off-chain

  2. Predict the splits address with the predicted community address as input off-chain

  3. Upload the splits address as a field in metadata to Arweave

  4. Invoke the community setup function on Arweave

function _createBeaconProxyBytecode(
  address _beacon,
  address _creatorAdmin,
  address _defaultAdmin,
  address _owner,
  string calldata _communityName,
  address _trustedForwarder
) internal view returns (bytes memory) {
  bytes memory bytecode = type(BeaconProxy).creationCode;
 
  // this is encoding the arguments to the beacon proxy constructor in the beacon proxy contract creation bytecode
  // the arguments are the beacon address and the bytes containing the call to initialize on the community
  // the bytes containing the call has to be encoded as well
  // end up with 3 layers of encoding
  return
    abi.encodePacked(
      bytecode,
      abi.encode(
      _beacon,
      abi.encodeWithSelector(
        ICommunity(address(0)).initialize.selector,
        _creatorAdmin,
        _defaultAdmin,
        permissionsRegistry,
        _owner,
        _communityName,
        _trustedForwarder
      )
    )
  );
}
 
function predictRoyaltySplitAddress(
  address _beacon,
  address _creatorAdmin,
  address _platformAdmin,
  address _owner,
  address _platformRoyaltySecondaryController,
  string calldata _communityName,
  uint256 userDefinedNonce
) public view returns (address) {
    address[] memory _secondaryAccounts = new address[](1);
    address[] memory _secondaryControllers = new address[](2);
    uint32[] memory _secondaryAllocations = new uint32[](1);
    _secondaryAccounts[0] = _creatorAdmin;
    _secondaryControllers[0] = _platformRoyaltySecondaryController;
    _secondaryControllers[1] = _creatorAdmin;
    _secondaryAllocations[0] = 700000;
    return ISplitMain(splitMain).predictSplitAddress(
      ISplitMain.Split(
        1,
        300000,
        0,
        _secondaryAllocations,
        _platformAdmin,
        _secondaryControllers,
        _secondaryAccounts
      ), // this is the default split created by this factory 
      predictSetupCommunityAddress(_beacon, _creatorAdmin, _owner, _communityName, userDefinedNonce)
    );
}

These two functions surmise the prediction and deployment of communities/splits addresses that helps us stay interoperable with most NFT marketplaces.

Standard Events

The smart contracts also integrate standard events used for ERC-1155 smart contracts. This helps the wider ecosystem recognize when community contracts have been deployed, and enables inspection via tools like Dune. It also enables our own system to manage token benefits. When any token transfer occurs on a Highlight community, our systems pick up the transfer and manage token benefits accordingly. For example, if a user gives away a token conferring access to private portions of a Discord server, our system will automatically remove the role granting them access in the server, after catching the event.

Provenance

As discussed in Highlight Smart Contracts: Extensibility, communities are extensible by the creator, or any other entity that the creator wishes. This extensibility enables true ownership of the smart contracts, as creators can configure their communities at a high granularity. Creator-owned smart contracts don’t offer much to the owner if they are a low resolution interface. We encourage creators to develop their own TokenManagers and other community utility smart contracts to customize their communities.

Thanks for reading. Explore the protocol directly here. Interested in working on cutting edge smart contract architecture and web3 infrastructure? We’re hiring.

Subscribe to Highlight
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.