Excepción de falta de gas al calcular el ensamblaje de solidez en línea Keccak256

Estoy tratando de escribir una función simple que debería devolverme Keccak256 de un uint entrante usando la función de ensamblaje en línea de Solidity, sin embargo, me devuelve una excepción sin gas cuando intento ejecutar la función en remix, ¿alguien puede ayudarme a solucionar el problema aquí?

   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)

            }
        }

    }



}
¿Puede darnos información sobre la falla? ¿Tal vez dar el hash tx?
Actualizado con el código completo que puede probar en Remix, ignore las variables de almacenamiento global que no están haciendo nada actualmente.
¿Estás usando Ropsten?
No solo use Javasscript VM dentro de Remix para probar el código, remix.ethereum.org/…
Me adentraré más en ello más adelante, pero el error está enlet selfptr := mload(add(_preimage, 0x20))
De un vistazo rápido, creo que es porque está intentando cargar datos desde una dirección (en la memoria) que no existe.
Entonces, mi motivo aquí es calcular el nivel de ensamblaje keccak (p, n) de _preimage, estoy tratando de tomar el valor de preimagen entrante y calcular keccak y devolver su valor, pero sigue dándome una excepción de gas

Respuestas (1)

Aquí está la solución que se me ocurrió.

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)
        }

}

En primer lugar, cambié la función a viewporque, por ahora, no cambias el estado del contrato.

En segundo lugar, sobre el código en sí, keccak256debe usarse en datos en la memoria, de acuerdo con la documentación aquí (puede encontrar la misma información en el papel amarillo ). Entonces, primero debemos escribir los datos en la memoria. Esta publicación le brinda más información sobre dónde puede escribirlo.

Una vez hecho, se acabó. Solo tienes que asignar al sampleresultado de keccak256.

PD: ¿Por qué usar ensamblador para esto si la keccak256función ya está implementada en Solidity?

Eso funcionó, gracias Elisha por la explicación detallada :) En cuanto a por qué estoy usando ensamblaje, solo quería ver cuáles son los costos de gas de ejecución para HTLC si estamos usando Solidity y ensamblaje en línea, es un experimento