Modularized code in Solidity

Make Library to act like an object

This is one of the trick that I love most. In solidity, there is no such keyword of “class”. The similar thing would be “contract” in solidity. You can have a contract, and deploy a contract and take that deployed contract to act like an instance in an object oriented language.

library Human {
struct Object {
string name;
uint256 age;
}

function greeting(Object memory self) internal pure returns (string memory) {
return string(abi.encodePacked("Hi, I am ", self.name, "!"));
}

function publicAge(Object memory self) internal pure returns (uint256) {
if (self.age > 25) {
return 25;
}
return self.age;
}
}
contract Example {
using Human for Human.Object;

Human.Object alice;
Human.Object bob;

constructor() public {
alice = Human.Object("Alice", 30);
bob = Human.Object("Bob", 20);
}

function aliceGreeting() public view returns (string memory) {
return alice.greeting();
}

function aliceAge() public view returns (uint256) {
return alice.publicAge();
}

function bobAge() public view returns (uint256) {
return bob.publicAge();
}
}

Registry contract with an interface

Okay, so what if you really want to decouple the code and you’re willing to pay some one time deployment gas cost? The pattern of a registry contract returning contract with an interface is what I like a lot.

interface Animal {
function move() external pure returns (string memory);
}
contract Bird is Animal {
function move() public pure returns (string memory) {
return "I fly";
}
}
contract Fish is Animal {
function move() public pure returns (string memory) {
return "I swim";
}
}
contract AnimalRegistry {
mapping (string => Animal) _animals;

function animals(string memory name) public view returns (Animal) {
return _animals[name];
}

function register(string memory name, Animal animalContract) public {
require(address(animalContract) != address(0), "Do not register empty contract.");
require(address(_animals[name]) == address(0), "Such animal has already beed registered");

_animals[name] = animalContract;
}
}
contract Example {
string constant BIRD = "bird";
string constant FISH = "fish";

AnimalRegistry registry;
constructor(AnimalRegistry _registry) public {
registry = _registry;
registry.register(BIRD, new Bird());
registry.register(FISH, new Fish());
}

function testBird() public view returns (string memory) {
return registry.animals(BIRD).move();
}

function testFish() public view returns (string memory) {
return registry.animals(FISH).move();
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store