0

I have a simple timelock contract however it doesn't work with modern solidity compilers,

Could anyone make my contract compatible with solidity newer than 0.5.16? Thanks.

Here is the code, it only works with solidity version 0.3.5

contract timeLock
{
    struct accountData
    {
        uint balance;
        uint releaseTime;
    }

    mapping (address => accountData) accounts;

    function payIn(uint lockTimeS)
    {
        uint amount = msg.value;
        payOut();
        if (accounts[msg.sender].balance > 0)
            msg.sender.send(msg.value);
        else
        {
            accounts[msg.sender].balance = amount;
            accounts[msg.sender].releaseTime = now + lockTimeS;
        }
    }

    function payOut()
    {
        if (accounts[msg.sender].balance != 0 && accounts[msg.sender].releaseTime < now)
        {
            msg.sender.send(accounts[msg.sender].balance);
            accounts[msg.sender].balance = 0;
            accounts[msg.sender].releaseTime = 0;
        }
    }

    function getMyLockedFunds() constant returns (uint x)
    {
        return accounts[msg.sender].balance;
    }

    function getMyLockedFundsReleaseTime() constant returns (uint x)
    {
        return accounts[msg.sender].releaseTime;
    }

    function getNow() constant returns (uint x)
    {
        return now;
    }
}

Thanks in advance!

1

The code below compiles with ^0.5.16. There were a few updates needed.

1 - constant is no longer used. You need to use either view or pure more info here I made all view because they read the state.

2 - I needed to set the visibility for each of the functions. I made all public. More options here

3 - payIn is a function that sends money to the contract, so the function must be marked as payable.

Note: I didn't make this update because the code compiles, but Remix suggest:

Consider using 'transfer' instead of msg.sender.send(msg.value)


Updated Contract:

pragma solidity ^0.5.16;

contract timeLock
{
    struct accountData
    {
        uint balance;
        uint releaseTime;
    }

    mapping (address => accountData) accounts;

    function payIn(uint lockTimeS) public payable
    {
        uint amount = msg.value;
        payOut();
        if (accounts[msg.sender].balance > 0)
            msg.sender.send(msg.value);
        else
        {
            accounts[msg.sender].balance = amount;
            accounts[msg.sender].releaseTime = now + lockTimeS;
        }
    }

    function payOut() public
    {
        if (accounts[msg.sender].balance != 0 && accounts[msg.sender].releaseTime < now)
        {
            msg.sender.send(accounts[msg.sender].balance);
            accounts[msg.sender].balance = 0;
            accounts[msg.sender].releaseTime = 0;
        }
    }

    function getMyLockedFunds() public view returns (uint x)
    {
        return accounts[msg.sender].balance;
    }

    function getMyLockedFundsReleaseTime() public view returns (uint x)
    {
        return accounts[msg.sender].releaseTime;
    }

    function getNow() public view returns (uint x)
    {
        return now;
    }
}
| improve this answer | |
  • Thank you very much! – Chance Han Jan 14 at 20:55
0

Here you go. I changed .send() to .transfer(), because transfer throws on failure while send is returning false on failure and you are not checking it anywhere.

Had to setup visibility for all the functions and replace constant with view, because constant got deprecated in the latest versions. Next time just place your code into https://remix.ethereum.org/ and just read the warnings.

pragma solidity 0.6.0;

contract timeLock {
    struct accountData
    {
        uint balance;
        uint releaseTime;
    }

    mapping (address => accountData) accounts;

    function payIn(uint _lockTimeS) public payable {
        uint amount = msg.value;
        payOut();
        if (accounts[msg.sender].balance > 0)
            msg.sender.transfer(msg.value);
        else
        {
            accounts[msg.sender].balance = amount;
            accounts[msg.sender].releaseTime = now + _lockTimeS;
        }
    }

    function payOut() public {
        if (accounts[msg.sender].balance != 0 && accounts[msg.sender].releaseTime < now)
        {
            msg.sender.transfer(accounts[msg.sender].balance);
            accounts[msg.sender].balance = 0;
            accounts[msg.sender].releaseTime = 0;
        }
    }

    function getMyLockedFunds() view public returns (uint x)
    {
        return accounts[msg.sender].balance;
    }

    function getMyLockedFundsReleaseTime() view public returns (uint x)
    {
        return accounts[msg.sender].releaseTime;
    }

    function getNow() view public returns (uint x)
    {
        return now;
    }
}
| improve this answer | |
  • Thank you very much! – Chance Han Jan 14 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.