Smart Contracts

|--o--| uses two main contracts: Ships and Engine.

In the future, I will share more details on how they can be used by third party developers.

Ships

Ships is the ERC-721 smart contract that holds the token information.

In addition to IERC721Enumerable, Ships expose the following interface:


interface IShips is IERC721Enumerable, IAccessControl {
  
  function minter( address to, uint256 count, bytes16 blueprint, 
              uint8 engine, uint32 flags) external returns (uint);

  function price() external view returns (uint);
  function getValidParts() external returns (bytes memory) ;

  function ownedSince(uint256 shipId) external view returns (uint32) ;

  function getBlueprint(uint256 id) external view returns (string memory) ;
  function getBlueprintBytes16(uint256 id) external view returns (bytes16) ;
  
  function getFlags(uint256 id) external view returns (uint32);
  function getFlag(uint256 id, uint8 flag) external view returns (bool);
  function setFlag(uint256 id, uint8 flag, bool set) external returns (uint32);
  
  function getEngine(uint256 shipId) external view returns (uint32);
  function setEngine(uint256 shipId, uint8 engineId) external returns (address);
  function setEngineOwned(uint256 shipId, uint8 engineId) external returns (address);

  function upgradeShip(uint256 id1, uint256[32] calldata seq) external payable;
  function setNewParts(string memory _newParts, uint count) external;

}

Engine

The Engine contract is the one rendering ship metadata, including the SVG artwork. Specifically, Ships.tokenURI() calls Engine.metadata() to get the token metadata.

Using Ships.setEngineAddr(uint8 id, address addr), the administrator of the Ships smart contract can add new Engines (there are 256 slots). Then, a ship can use the engine at slot engineId using Ships.setEngineOwned(shipId, engineId).

New engines can provide alternative artworks, but they can also implement additional functionality such as games. For example an engine could allow two ships (that use it) to battle, and keep score, show damaged parts, etc.

Engine contracts must implement the IEngine interface:


interface IEngine {
  function metadata(uint shipId, bytes16 blueprint, uint32 flags, uint32 ownedSince) external view returns (bytes memory);
  function name() external view returns (string memory);
}