Почему мы не можем отправить эфир по адресу эфира 0x1 по умным контрактам - PullRequest
0 голосов
/ 02 сентября 2018

С помощью приведенного ниже кода солидности я попытался отправить эфир на адрес кошелька ethereum 0x1 через смарт-контракт, и он стал неудачным. Но когда я пытаюсь отправить эфир по адресу 0x1 прямо из моего кошелька, он становится успешным.

pragma solidity ^0.4.24;

contract Transfer {

    constructor () public payable {
        // Deploy contract with 1000 wei for testing purpose
        require(msg.value == 1000);
    }

    function done() public {
        address(0).transfer(1); // Transaction success
    }

    function fail() public {
        address(1).transfer(1); // Transaction failed
    }

    function send(address account) public {
        account.transfer(1); // Transaction success (except 0x1)
    }

}

Почему мы не можем отправить эфир по адресу 0x1 через контракты?

ССЫЛКА:

  1. Успешная отправка эфира прямо из моего кошелька https://ropsten.etherscan.io/tx/0x1fdc3a9d03e23b0838c23b00ff99739b775bf4dd7b5b7f2fa38043056f731cdc

  2. Функция done () успешна https://ropsten.etherscan.io/tx/0xd319c40fcf50bd8188ae039ce9d41830ab795e0f92d611b16efde0bfa1ee82cd

  3. Функция fail () не выполнена https://ropsten.etherscan.io/tx/0x0c98eafa0e608cfa66777f1c77267ce9bdf81c6476bdefe2a7615158d17b59ad

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

После исследования об ethereum предварительно скомпилированных контрактах Я написал этот ниже код солидности для отправки эфира по адресу 0x1 через умный контракт, и он работает.

pragma solidity ^0.4.24;

contract Learning {

    constructor () public payable {
        // Deploy contract with 1000 wei for testing purpose
        require(msg.value == 1000);
    }

    function test() public returns (bool) {
        // Set minimum gas limit as 700 to send ether to 0x1
        transfer(0x0000000000000000000000000000000000000001, 1, 700);
        return true;
    }

    function transfer(address _account, uint _wei, uint _gas) private {
        require(_account.call.value(_wei).gas(_gas)());
    }
}

Для тестирования просто разверните контракт с 1000 wei и выполните функцию test(). Работает :)

0 голосов
/ 03 сентября 2018

Вы случайно наткнулись на одну из менее известных "особенностей" эфириума. На самом деле цепочка имеет несколько предварительно скомпилированных контрактов (Приложение E в желтой книге), один из которых имеет значение 0x0000000000000000000000000000000000000001 (ecrecover контракт).

Ваша функция fail() завершается с ошибкой из-за того, что для выполнения отката контракта ecrecover потребуется больше, чем 2300 gas, перенаправленное методом transfer.

Адрес 0x0 не является специальным контрактом, поэтому обычный вызов на переадресацию работает нормально, как и с любым другим адресом.

...