Implementing an Inheritance Contract on Celo: A Practical Guide to Creating Smart Contract for Transferring Assets to Next of Kin

Implementing an Inheritance Contract on Celo: A Practical Guide to Creating Smart Contract for Transferring Assets to Next of Kin https://celo.academy/uploads/default/optimized/2X/4/4ebdd197ac7aac7672b77be8b4ee70d6c5c48a3d_2_1024x576.png
none 0.0 0

Introduction

In a world where digital assets and cryptocurrencies are fast becoming an integral part of our lives, ensuring the smooth transfer of these assets to loved ones after demise has become a crucial consideration. The decentralized and secure nature of blockchain technology opens up new possibilities for creating inheritance contracts that can automate and streamline asset transfers to next of kin.

Celo, with its focus on financial inclusion and mobile-first approach, provides a robust platform for implementing such inheritance contracts. By leveraging the power of smart contracts on Celo, individuals can establish a transparent and immutable mechanism to distribute their assets among their chosen beneficiaries.

In this practical guide, we will delve into the process of creating an inheritance smart contract on Celo. We will explore the fundamental concepts of smart contracts, address inheritance rules and considerations, and provide step-by-step instructions for implementing a secure and efficient asset transfer mechanism.

You can find the repository for this tutorial Here

Prerequisites

To follow this tutorial, you will need the following:

  • Basic understanding of Solidity and smart contracts.
  • A Development Environment Like Remix.
  • The Celo Extension Wallet which can be downloaded here.
  • To get testnest funds, go to Celo faucet

Contract Developement

The complete code contract look like this;


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract AssetTransfer {
    address public owner;
    bool public deceased;
    uint256 public createdAt;
    uint256 public celoBalance;

    address[] familyWallets;
    mapping(address => uint256) inheritance;

    event InheritanceSet(address indexed wallet, uint256 amount);
    event Payout(address indexed wallet, uint256 amount);
    event Deceased();

    constructor() payable {
        owner = msg.sender;
        createdAt = block.timestamp;
        celoBalance = msg.value;
        deceased = false;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can call this function");
        _;
    }

    modifier mustBeDeceased() {
        require(deceased == true, "The owner must be marked as deceased");
        _;
    }

    function getTotalInheritance() public view returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < familyWallets.length; i++) {
            total += inheritance[familyWallets[i]];
        }
        return total;
    }

    function setInheritance(address wallet, uint256 amount) public onlyOwner {
        require(wallet != address(0), "Invalid wallet address");
        require(amount > 0, "Inheritance amount must be greater than zero");
        require(
            celoBalance >= getTotalInheritance() + amount,
            "Total inheritance exceeds contract balance"
        );

         familyWallets.push(wallet);
         inheritance[wallet] = amount;
  
         emit InheritanceSet(wallet, amount);
     }

    function payout() private mustBeDeceased {
        for (uint256 i = 0; i < familyWallets.length; i++) {
            address payable wallet = payable(familyWallets[i]);
            uint256 amount = inheritance[wallet];
            wallet.transfer(amount);

            emit Payout(wallet, amount);
        }
    }

    function markAsDeceased() public onlyOwner {
        deceased = true;
        payout();

        emit Deceased();
    }

    receive() external payable {
        // Allow the contract to receive funds
    }
}

Code Breakdown

Let’s look at our smart contract in detail.

State Variables

    address public owner;
    bool public deceased;
    uint256 public createdAt;
    uint256 public celoBalance;

    address[] familyWallets;
    mapping(address => uint256) inheritance;   
  • owner: Stores the address of the contract owner.
  • deceased: Indicates whether the owner is marked as deceased or not.
  • createdAt: Stores the timestamp when the contract was created.
  • celoBalance: Stores the balance of CELO tokens in the contract.
  • familyWallets: An array to store the addresses of the family wallets.
  • inheritance: A mapping to store the inheritance amount corresponding to each family wallet address.

Events

    event InheritanceSet(address indexed wallet, uint256 amount);
    event Payout(address indexed wallet, uint256 amount);
    event Deceased();
  • InheritanceSet: Triggered when an inheritance amount is set for a family wallet.
  • Payout: Triggered when a payout is made to a family wallet.
  • Deceased: Triggered when the owner is marked as deceased.

Constructor

    constructor() payable {
        owner = msg.sender;
        createdAt = block.timestamp;
        celoBalance = msg.value;
        deceased = false;
    }

The constructor is executed when the contract is deployed. It initializes the state variables:

  • Sets the owner as the address of the contract deployer (sender).
  • Sets the createdAt timestamp as the current block timestamp.
  • Sets the celoBalance as the value (CELO tokens) sent along with the contract deployment transaction.
  • Sets deceased as false initially.

Modifiers

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can call this function");
        _;
    }

    modifier mustBeDeceased() {
        require(deceased == true, "The owner must be marked as deceased");
        _;
    }
  • onlyOwner: Ensures that a function can only be called by the contract owner.
  • mustBeDeceased: Ensures that a function can only be called if the value od deceased become true.

The getTotalInheritance Function

    function getTotalInheritance() public view returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < familyWallets.length; i++) {
            total += inheritance[familyWallets[i]];
        }
        return total;
    }

The getTotalInheritance function iterates over the family wallets and adds up the corresponding asset value to calculate the total inheritance. This allows anyone to view the total amount of inheritance stored in the contract without modifying the contract state.

The setInheritance Function

     function setInheritance(address wallet, uint256 amount) public onlyOwner {
        require(wallet != address(0), "Invalid wallet address");
        require(amount > 0, "Inheritance amount must be greater than zero");
        require(
            celoBalance >= getTotalInheritance() + amount,
            "Total inheritance exceeds contract balance"
        );

        familyWallets.push(wallet);
        inheritance[wallet] = amount;

        emit InheritanceSet(wallet, amount);
    }

The setInheritance function allows the contract owner to set the inheritance amount for a specific family wallet. It performs input validations, checks the total inheritance against the contract balance, stores the inheritance amount, and emits an event to record the update.

The payout Function

    function payout() private mustBeDeceased {
        for (uint256 i = 0; i < familyWallets.length; i++) {
            address payable wallet = payable(familyWallets[i]);
            uint256 amount = inheritance[wallet];
            wallet.transfer(amount);

            emit Payout(wallet, amount);
        }
    }

The payout function is responsible for distributing the inheritance to the designated family wallets. It loops through the family wallets, transfers the corresponding amount of CELO to each wallet, and emits a Payout event for each successful transfer. The function can only be executed if the contract owner has been marked as deceased.

The markAsDeceased Function

    function markAsDeceased() public onlyOwner {
        deceased = true;
        payout();

        emit Deceased();
    }

The markAsDeceased function allows the contract owner to trigger the inheritance payout process by marking themselves as deceased. It sets the deceased flag, calls the payout function to distribute the inheritance, and emits a Deceased event.

Deployment

To deploy our smart contract, go to Remix IDE.

Copy and paste the smart contract > Compile File > Then Deploy in an Injected Provider environment.

Conclusion

In conclusion, the above smart contract provides a practical solution for implementing an inheritance mechanism on Celo. The contract allows the contract owner to designate family wallets and assign inheritance amounts to each wallet. Upon marking the owner as deceased, the contract automatically distributes the inheritance to the designated family wallets.

By leveraging the capabilities on Celo and incorporating checks and balances within the smart contract, the Inheritance contract provides a secure and efficient solution for transferring assets to next of kin or family members, enabling individuals to plan and manage their inheritance in a decentralized and automated manner.

Next Step

You may consider adding functionalities such as multi-signature authorization for inheritance decisions or implementing additional security measures to protect the contract and assets.

Also, additional function which allows our contract to receive additional funds can also be added.

The functionality of the contract can also become fully automated by connecting to oracles that can monitor death records.

About the Author​

Emiri Udogwu, a licensed medical doctor with a burning passion for technology and gifted with skills for spreading knowledge and propagating ideas. A web3 and frontend developer.

References

5 Likes

I’d love to see what the End product is for this topic, all I can think of right now are some of the limitations you’ll encounter

3 Likes

Yes sir…i i am glad to know youre interested in it. I will humbly inform if i run into any difficulties

2 Likes

Congratulations on your proposal being chosen as a standout this week at Celo Academy! As you prepare your tutorial, please ensure you follow our guidelines found here: Celo Sage Guidelines and Best Practices. Thank you for helping improve the experience of the developers learning at Celo Academy.

4 Likes

I’ll be reviewing this @EmiriDbest

3 Likes

Appears to have skipped Publish stage. Moving back @ishan.pathak2711 to confirm

2 Likes

No it didn’t @Celo_Academy

I moved it to publish before it was moved to tutorials by @ishan.pathak2711

5 Likes