Building a Smart Contract for Inheritance on Ethereum

Unlocking the future of digital inheritance with Solidity and Ethereum


Author: Artsiom Tsvirko Published on: June 15, 2023

Building a Smart Contract for Inheritance on Ethereum

Introduction

In today’s rapidly evolving digital landscape, the way we manage assets is changing dramatically. Cryptocurrencies and blockchain technology have introduced new possibilities for asset ownership and transfer. One intriguing application is the concept of digital inheritance—ensuring that your digital assets are passed on according to your wishes. In this article, we’ll explore a simple smart contract that enables inheritance on the Ethereum blockchain using Solidity.

Whether you’re new to blockchain or an experienced developer, this project showcases how smart contracts can offer innovative solutions to real-world problems. Let’s dive in!

The Problem: Inheritance in the Digital Age

Traditional inheritance processes involve legal documents, intermediaries, and sometimes lengthy probate procedures. With digital assets like cryptocurrencies, the process becomes even more complex due to security measures like private keys and wallets.

Challenge: How can we ensure that digital assets are securely and automatically transferred to an heir if something happens to the owner?

The Solution: An Inheritance Smart Contract

To address this challenge, I created a Solidity smart contract that automates the inheritance process on the Ethereum blockchain. The contract includes the following features:

  • Owner Withdrawals: The owner can withdraw any amount of Ether (ETH) from the contract at any time.
  • Heir Designation: The owner can designate an heir who is eligible to claim ownership if the owner becomes inactive.
  • Inactivity Timer: If the owner doesn’t withdraw any ETH for over 30 days, the heir can claim ownership of the contract.
  • Reset Mechanism: The owner can reset the inactivity timer by withdrawing even 0 ETH, signaling they are still active.

Understanding the Smart Contract

Here’s a breakdown of how the contract works:

1. Contract Variables

  • owner: The address of the current owner.
  • heir: The address of the designated heir.
  • lastWithdrawalTimestamp: The timestamp of the last withdrawal made by the owner.

2. Constructor Function

When the contract is deployed, the constructor sets the deployer as the owner and records the deployment time as the lastWithdrawalTimestamp.

constructor() {
    owner = msg.sender;
    lastWithdrawalTimestamp = block.timestamp;
}

3. Owner Functions

  • Withdraw Function: Allows the owner to withdraw any amount of ETH from the contract, including zero. This action updates the lastWithdrawalTimestamp.

    function withdraw(uint256 amount) public onlyOwner {
        payable(msg.sender).transfer(amount);
        lastWithdrawalTimestamp = block.timestamp;
    }
    
  • Designate Heir Function: Enables the owner to set a new heir.

    function designateHeir(address newHeir) public onlyOwner {
        heir = newHeir;
    }
    

4. Heir Function

  • Claim Inheritance Function: Allows the heir to claim ownership if 30 days have passed since the last owner withdrawal.

    function claimInheritance() public {
        require(block.timestamp - lastWithdrawalTimestamp >= 30 days, "One month has not passed since the last withdrawal");
        require(msg.sender == heir, "Only the heir can claim inheritance");
        owner = heir;
        heir = address(0);
        lastWithdrawalTimestamp = block.timestamp;
    }
    

5. Fallback Function

The contract includes a receive function to accept ETH transfers.

receive() external payable {}

Ensuring Reliability with Comprehensive Testing

A robust smart contract requires thorough testing to ensure it behaves as expected under various scenarios. I developed an extensive test suite using TypeScript, Hardhat, and Chai assertion library. Here are some of the critical tests performed:

  1. Deployment Test: Verifies that the deployer is set as the owner.
  2. Owner Withdrawal Test: Confirms that the owner can withdraw funds and that the lastWithdrawalTimestamp updates correctly.
  3. Heir Designation Test: Checks that only the owner can designate an heir.
  4. Inheritance Claim Test: Ensures the heir can claim ownership after 30 days of owner inactivity.
  5. Reset Mechanism Test: Validates that withdrawing 0 ETH resets the inactivity timer.
  6. Security Tests: Confirms that non-owners cannot withdraw funds and non-heirs cannot claim inheritance.
  7. Edge Case Tests: Handles scenarios like no heir designated, heir set to zero address, and owner designating themselves as the heir.

Example Test Case:

it('should allow the heir to claim inheritance after 30 days', async function() {
  await contract.connect(owner).designateHeir(heir.address)
  await ethers.provider.send('evm_increaseTime', [31 * 24 * 60 * 60])
  await ethers.provider.send('evm_mine', [])
  await contract.connect(heir).claimInheritance()
  expect(await contract.owner()).to.equal(heir.address)
})

Deploying the Contract to the Ethereum Sepolia Test Network

Deploying the contract to a test network allows for real-world interaction without risking actual funds. Here’s how I deployed the contract:

  1. Network Configuration: Set up the Sepolia network in the Hardhat configuration with the appropriate RPC URL and account private key.

  2. Deployment Script: Created a deployment script using Hardhat.

    const contractFactory = await ethers.getContractFactory(
      'InheritanceContract'
    )
    const contract = await contractFactory.deploy()
    await contract.deployed()
    console.log('Contract deployed to address:', contract.address)
    
  3. Running Deployment: Executed the deployment script using the command:

    npx hardhat run scripts/deploy.ts --network sepolia
    
  4. Verification: Verified the contract on Sourcify for transparency.

    • Contract Address: 0x4D3dBE618Fe0B53c4092F385CBD038499BB7CdD0
    • Verification Link: Sourcify Repository

How to Interact with the Contract

You can interact with the deployed contract using a tool like Remix, Etherscan, or by writing scripts with ethers.js.

Example: Owner Withdraws Funds

await contract.connect(owner).withdraw(ethers.utils.parseEther('1.0'))

Example: Designate an Heir

await contract.connect(owner).designateHeir('0xHeirAddress')

Example: Heir Claims Inheritance

await contract.connect(heir).claimInheritance()

Skills Demonstrated

Through this project, I’ve applied and demonstrated several key skills:

  • Solidity Programming: Writing secure and efficient smart contracts.
  • Blockchain Concepts: Understanding Ethereum’s blockchain mechanics, including addresses, transactions, and time manipulation.
  • Testing and Development Tools: Utilizing Hardhat for development, testing, and deployment, along with TypeScript and Chai for writing comprehensive tests.
  • Smart Contract Deployment: Deploying contracts to Ethereum test networks and verifying them for public transparency.
  • Problem-Solving: Addressing real-world issues like digital inheritance with innovative blockchain solutions.

Conclusion

This inheritance smart contract represents a step towards modernizing how we handle digital assets. By automating the inheritance process on the blockchain, we reduce the reliance on intermediaries and ensure assets are transferred according to the owner’s wishes.

Whether you’re interested in blockchain development or looking for ways to manage digital assets securely, I hope this project provides valuable insights into the possibilities that smart contracts offer.

Thank you for reading! Feel free to reach out if you have any questions or thoughts on this project.

Get the Code

The full source code and tests are available on GitHub. Clone the repository to explore the code and run the tests yourself.

git clone git@github.com:lArtiquel/SolidityInheritanceContract.git