На remix.ethereum.org функция blockhash всегда обнуляет все переменные

У меня проблема с функцией blockhash на сайте remix.ethereum.org. Несмотря на несколько попыток с разными кодами, функция blockhash всегда вызывает проблемы, и в результате все переменные возвращаются с нулевым значением.

В приведенном ниже случае переменная _previousBlockNumber всегда возвращает нулевое значение. Если строка хэш-функции закомментирована, то ошибка не возникает и, по крайней мере, переменная _previousBlockNumber возвращается корректно.

Я пробовал несколько разных версий компиляторов.

pragma solidity ^0.5.5;
contract Test {
    constructor() public {
    }
    function rand() public view returns(uint,bytes32) {
        uint _previousBlockNumber;
        bytes32 _previousBlockHash;
        _previousBlockNumber = uint(block.number - 1);
        bytes32 _previousBlockHash = bytes32(blockhash(_previousBlockNumber)); 
        return (_previousBlockNumber,_previousBlockHash);
    }   
}

Это проблема с ошибкой?

Спасибо за любую помощь.


person leorzz    schedule 16.03.2019    source источник
comment
Привет, попробуйте сделать так, чтобы ваша функция не отображалась, вы можете видеть, что если задание выполняется, транзакция возвращается. Итак, поскольку вы выполняете локальное чтение, вы получаете 0. Возможно, это проблема с виртуальной машиной Javascript. Вы пробовали запускать локальную сеть и прикреплять ремикс к работающему инстансу, я думаю, что в этом случае должно сработать   -  person Briomkez    schedule 18.03.2019


Ответы (1)


Я попытался запустить этот код, чтобы решить проблему, и он работает у меня с некоторыми изменениями. Такой же контракт вы можете найти на Rinkebey Testnet по этому адресу 0x86ee6d633fd691e77dc79cbdb2a9fb108f79ecbd.

pragma solidity ^0.5.5;
contract Test {
    uint256 i;
    constructor() public {
    }
    function rand() public view returns(uint,bytes32) {
        uint _previousBlockNumber;
        bytes32 _previousBlockHash;
        _previousBlockNumber = uint(block.number - 1);
        _previousBlockHash = bytes32(blockhash(_previousBlockNumber)); 
        return (_previousBlockNumber,_previousBlockHash);
    }  

    function setI(uint256 k) public{
        i = k;
    }
}

Изначально вы объявляли _previousBlockHash два раза, а второй раз — в строке функции blockhash. Я исправляю это и работает нормально.

Во-вторых, в текущем коде контракта вы не меняете никакого состояния контракта и не выполняете никаких транзакций, rand() — это просто вызов, который не добавит никакого другого блока. Так что он всегда будет оставаться 0. Я добавляю одну фиктивную функцию транзакции для тестирования, которая теперь работает нормально.

Наконец, попробуйте запустить это в реальной тестовой сети, чтобы увидеть реальные вещи. Надеюсь, это сработает.

скриншот

person Abdullah Aziz    schedule 19.03.2019
comment
попробуйте использовать настоящую тестовую сеть, например rinkebey или ropsten, вам нужна метамаска, установленная в браузере, а в ремиксе используйте внедренный web3 вместо Javascript VM. В моем понимании в локальной машине это нулевой блок. попробуйте в реальной тестовой сети. - person Abdullah Aziz; 21.03.2019
comment
Я отредактировал свой ответ с дополнительным объяснением, пожалуйста, проверьте @leorzz - person Abdullah Aziz; 21.03.2019
comment
Спасибо за помощь. Теперь я понимаю, как обойти эту проблему. - person leorzz; 24.03.2019