2

I am trying to write a simple function which should return me Keccak256 of an incoming uint using Solidity inline assembly function, however it returns me out of gas exception when trying to execute the function on remix, can someone help me fix the issue here ?

   pragma solidity ^0.4.18;


contract HashedTimelock {


        address sender = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
        address receiver = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c;
        bytes32 hashlock = 0x731dc163f73d31d8c68f9917ce4ff967753939f70432973c04fd2c2a48148607; // sha-2 sha256 hash
        uint  timelock = 1522660821; // UNIX timestamp seconds - locked UNTIL this time

   function HashedTimelock() payable{}


    function withdraw(bytes32 _preimage)
        external returns(bytes32 sample)
    {
        uint  timenow = now;
        assembly {
            // first check if the pre image matches with internal hashlockMatches
            // check the timelock
            // use selfdestruct to transfer the funds
            if eq(1,lt(timenow, sload(timelock_slot))){
               let selfptr := mload(add(_preimage, 0x20))
               sample := keccak256(selfptr, 32)

            }
        }

    }



}
NaN
  • 194
  • 7
  • Can you give us informations about the failure? Maybe give the tx hash? – Elisha Drion Apr 01 '18 at 10:33
  • Updated with the full code you can try in Remix, please ignore the global storage variables they are not doing anything currently - – NaN Apr 01 '18 at 10:35
  • Are you using Ropsten? – Aniket Apr 01 '18 at 10:40
  • No just using Javasscript VM inside Remix to test the code, https://remix.ethereum.org/#optimize=false&version=soljson-v0.4.21+commit.dfe3193c.js – NaN Apr 01 '18 at 10:42
  • 1
    I will plunge into it deeper later, but the error is in let selfptr := mload(add(_preimage, 0x20)) – Elisha Drion Apr 01 '18 at 10:47
  • At a quick glance, I think it's because you are trying to load data from an address (in memory) that doesn't exist. – Elisha Drion Apr 01 '18 at 10:56
  • So my motif here is the calculate the assembly level keccak(p,n) of _preimage, I am trying to take the incoming preimage value and calculate keccak and return its value, but it just keeps giving me out of gas exception – NaN Apr 01 '18 at 11:00

1 Answers1

2

Here's the solution I came up with.

function withdraw(bytes32 _preimage)
    external view returns(bytes32 sample)
{
    uint  timenow = now;
    assembly {
        let freemem_pointer := mload(0x40)
        mstore(add(freemem_pointer,0x00), _preimage)
        sample := keccak256(freemem_pointer, 32)
        }

}

Firstly, I changed the function to a view because, for now, you don't change the contract's state.

Secondly, about the code itself, keccak256 has to be used on data in memory, according to the documentation here (you can find the same information in the yellow paper). So, we need to write the data in memory first. This post tells you more about where you can write it.

Once it's done, it's over. You just have to assign to sample the result of keccak256.

P-S : Why use assembly for this since the keccak256 function is implemented in Solidity already?

Elisha Drion
  • 2,641
  • 9
  • 16
  • That worked, Thanks Elisha for detailed explanation :) Regarding why I am using assembly just wanted to see what are the execution gas costs for HTLC if we are using Solidity and inline assembly, its an experiment – NaN Apr 01 '18 at 13:35