为什么我们不能通过智能合约将以太币发送到以太坊地址 0x1
Why we can't send ether to ethereum address 0x1 via smart contracts
使用下面的代码,我试图通过智能合约将以太币发送到以太坊钱包地址 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)
}
}
Why we can't send ether to address 0x1 via contracts ?
参考:
直接从我的钱包发送以太币成功
https://ropsten.etherscan.io/tx/0x1fdc3a9d03e23b0838c23b00ff99739b775bf4dd7b5b7f2fa38043056f731cdc
done()函数成功
https://ropsten.etherscan.io/tx/0xd319c40fcf50bd8188ae039ce9d41830ab795e0f92d611b16efde0bfa1ee82cd
fail() 函数失败
https://ropsten.etherscan.io/tx/0x0c98eafa0e608cfa66777f1c77267ce9bdf81c6476bdefe2a7615158d17b59ad
更新:
在研究了以太坊预编译合约之后,我在下面写了这个代码,通过智能合约将以太币发送到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()
功能。正常工作:)
您不小心发现了一个鲜为人知的以太坊 "features"。该链实际上有一些预编译的合约(黄皮书中的附录 E),其中之一位于 0x0000000000000000000000000000000000000001
(ecrecover
合约)。
由于 ecrecover
合约的后备执行将需要比 transfer
方法转发的 2300 gas
更多的 gas,因此您的 fail()
函数失败.
0x0
地址不是特殊合约,因此与任何其他地址一样,常规转账调用工作正常。
使用下面的代码,我试图通过智能合约将以太币发送到以太坊钱包地址 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)
}
}
Why we can't send ether to address 0x1 via contracts ?
参考:
直接从我的钱包发送以太币成功 https://ropsten.etherscan.io/tx/0x1fdc3a9d03e23b0838c23b00ff99739b775bf4dd7b5b7f2fa38043056f731cdc
done()函数成功 https://ropsten.etherscan.io/tx/0xd319c40fcf50bd8188ae039ce9d41830ab795e0f92d611b16efde0bfa1ee82cd
fail() 函数失败 https://ropsten.etherscan.io/tx/0x0c98eafa0e608cfa66777f1c77267ce9bdf81c6476bdefe2a7615158d17b59ad
更新:
在研究了以太坊预编译合约之后,我在下面写了这个代码,通过智能合约将以太币发送到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()
功能。正常工作:)
您不小心发现了一个鲜为人知的以太坊 "features"。该链实际上有一些预编译的合约(黄皮书中的附录 E),其中之一位于 0x0000000000000000000000000000000000000001
(ecrecover
合约)。
由于 ecrecover
合约的后备执行将需要比 transfer
方法转发的 2300 gas
更多的 gas,因此您的 fail()
函数失败.
0x0
地址不是特殊合约,因此与任何其他地址一样,常规转账调用工作正常。