我试图创建一个简单的智能合约来学习可靠性以及以太坊的运作方式。
根据我的理解,使用方法上的修改应付将使其接受一个值。然后我们从发件人中扣除并在其他地方添加,在此代码中我尝试将其发送给合同所有者。
contract AcceptEth {
address public owner;
uint public bal;
uint public price;
mapping (address => uint) balance;
function AcceptEth() {
// set owner as the address of the one who created the contract
owner = msg.sender;
// set the price to 2 ether
price = 2 ether;
}
function accept() payable returns(bool success) {
// deduct 2 ether from the one person who executed the contract
balance[msg.sender] -= price;
// send 2 ether to the owner of this contract
balance[owner] += price;
return true;
}
}
当我通过混音与此合约互动时,我在处理交易时遇到错误" VM Exception:out of gas"当我试图从执行此方法的任何人那里获得2以太时,它创建了一个交易并且天然气价格是21000000000,价值是0.00 ETH。
代码有什么问题?或者,我可以添加一个变量来输入他们想要发送的值,以及一个撤销方法,对吧?但为了学习,我想保持简单。但即使这段代码感觉有点简单,感觉就像缺少一些东西。
答案 0 :(得分:8)
我认为你迷路的地方是合同内置了接收和保持以太的机制。例如,如果你想这样做,那么你的accept()
方法就会收到2个以太(或者你设置price
的任何东西),你会做这样的事情:
contract AcceptEth {
address public owner;
uint public price;
mapping (address => uint) balance;
function AcceptEth() {
// set owner as the address of the one who created the contract
owner = msg.sender;
// set the price to 2 ether
price = 2 ether;
}
function accept() payable {
// Error out if anything other than 2 ether is sent
require(msg.value == price);
// Track that calling account deposited ether
balance[msg.sender] += msg.value;
}
}
现在,假设您有两个帐户,余额如下:
0x01 = 50以太
0x02 = 20以太
此合同已部署,地址为0xc0。所有地址都可以保留以太,因此即使合同本身也有余额。由于它刚刚部署(并且未部署任何初始以太网),因此它的余额为0。
现在说0x01调用accept()
发送2以太。交易将执行,我们示例中的3个地址将具有以下余额:
0x01 = 48以太
0x02 = 20以太
0xc0 = 2 ether
现在,假设0x02调用accept()
TWICE,两次传递2以太:
0x01 = 48以太
0x02 = 16以太
0xc0 = 6 ether
合同中包含发送给它的所有以太币。但是,您的合同还包含状态(您在代码中定义的balance
地图),该地图跟踪谁存放了什么。所以,你从那个映射知道0x01沉积了2个以太,而0x02沉积了4个以太。如果你想引入一个发送以太的refund()
方法,你可以像这样写
function refund(uint amountRequested) public {
require(amountRequested > 0 && amountRequested <= balance[msg.sender]);
balance[msg.sender] -= amountRequested;
msg.sender.transfer(amountRequested); // contract transfers ether to msg.sender's address
}