在智能合约中接受以太币

Posted

技术标签:

【中文标题】在智能合约中接受以太币【英文标题】:accepting ether in smart contract 【发布时间】:2018-06-29 06:48:21 【问题描述】:

我正在尝试创建一个简单的智能合约来学习可靠性和以太坊的工作原理。

据我了解,在方法上使用修改应付将使它接受一个值。然后我们从发件人中扣除并将其添加到其他地方,在这段代码中,我试图将其发送给合同的所有者。

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;
    

当我通过 remix 与此合约交互时,我收到“VM Exception while processing transaction: out of gas”的错误,它创建了一个交易,当我尝试时,gas 价格为 21000000000,值为 0.00 ETH从执行此方法的任何人那里获得 2 个以太币。

代码有什么问题?或者,我可以添加一个变量来输入他们想要发送的值,以及一个withdraw方法,对吗?但为了学习,我想保持简单。但即使是这段代码也感觉有点简单,感觉好像少了点什么。

【问题讨论】:

【参考方案1】:

我认为你迷失的地方是合约内置了接收和持有以太币的机制。例如,如果你想让你的 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 以太币

现在,假设 0x02 调用 accept() TWICE,两次都传递了 2 个以太:

0x01 = 48 以太币

0x02 = 16 以太币

0xc0 = 6 以太币

合约持有发送给它的所有以太币。但是,您的合约还包含状态(您在代码中定义的 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

【讨论】:

感谢您的回答,这确实有助于更好地理解这一切。我如何以及在哪里可以找到正确的教程来创建合同资金的提款/转移到并且仅限于合同所有者的地址? 当我在remix中与this交互时,执行accept方法时没有指定值的字段? Solidity 文档拥有一切。 solidity.readthedocs.io/en/develop 运行选项卡,右上角。值字段。下拉让您指定要发送的类型(ether、wei 等) 如何存储余额以便在生产阶段将其转换为真实的以太币?

以上是关于在智能合约中接受以太币的主要内容,如果未能解决你的问题,请参考以下文章

比特币与以太坊智能合约比较

什么是以太坊?什么是智能合约?

以太坊智能合约入门项目-众筹项目

比特币与以太坊智能合约比较

比特币与以太坊智能合约比较

通过以太币与 BSC 上的智能合约进行通信会给出 -32603 错误代码