以太币支付的相关写法和注意事项

由于Solidity是基于以太坊(Ethereum)的,故而其语言层面可以直接支持货币支付。


payable标识的函数


函数上增加payable标识,即可接收ether,并会把ether存在当前合约,如下述示例中的deposit函数。

pragma solidity ^0.4.0;

contract supportPay{

  //存入一些ether用于后面的测试
  function deposit() payable{
  }

  //查询当前的余额
  function getBalance() constant returns(uint){
      return this.balance;
  }
}

在上面的代码中,你可以通过deposit()向当前合约存入ether,注意这是通过函数调用,在调用中通过address.call(某个方法).value(要发送的ether)来实现的,这里可以参考: http://me.tryblockchain.org/Solidity-call-callcode-delegatecall.html 。


send()函数发送ether


地址对象中的send()可以向某地址直接进行支付,下面是一个向合约帐户支付的示例:

当我们使用address.send(ether to send)向某个地址转帐,如果是普通地址将会直接收到,就非常简单了。我们这里将用合约来模拟发送与接收:

pragma solidity ^0.4.0;

contract SendAndReceiveByContract{

  //fallback函数对应记录事件
  event fallbackTrigged(bytes data);
  //合约接收send()的 ether时,必须存在
  function() payable{fallbackTrigged(msg.data);}

  //存入一些ether用于后面的测试
  function deposit() payable{
  }

  //查询当前的余额
  function getBalance() constant returns(uint){
      return this.balance;
  }

  event SendEvent(address to, uint value, bool result);
  //使用send()发送ether
  function sendEther(){
        //使用this来模拟从另一个合约发送
       //result是布尔型,如果后面的this.send(1)执行成功,那么result的值就是true,否则就是false
      bool result = this.send(1);
      SendEvent(this, 1, result);
  }
}

在上述的代码中,我们先要使用deposit()合约存入一些ether,否则由于余额不足,调用send()函数将报错。存入ether后,我们调用sendEther(),使用send()向合约发送数据,将会触发下述事件:

SendEvent[
  "0xc35f7ac1351648b0b8a699c5f07dd6a78f626714",
  "1",
  "true"
]
fallbackTrigged[
  "0x"
]

可以看到,我们成功使用send()发送了1wei到合约。

这里需要特别注意的是,下面大家先记着,后面 http://me.tryblockchain.org/blockchain-solidity-fallback.html 会说明,合约要接收通过send()函数发送的ether,有下面的限制:

  1. 如果我们要在合约中通过send()函数接收,就必须定义fallback函数,否则会抛异常。
  2. fallback函数必须增加payable关键字,否则send()执行结果将会始终为false


支付中可能的失败

send()失败

由于调用者可以强制指定调用堆栈的深度,当调用的栈深超过指定值时,一般是1024;或者接收地址处理支付过程中out of gas。由于失败,此时的send()的结果是false

合约的fallback()

如果是合约地址,在执行send()时,会默认关联执行fallback()(如果存在这个函数)。这是EVM的默认行为,不可被阻止。所以这个函数引起out of gas或其它失败,整个交易被撤销。由于失败,此时的send()的结果是false


payable标识

细心的读者可能发现在deposit函数上有一个payable关键字,如果一个函数需要进行货币操作,必须要带上payable关键字,这样才能正常接收msg.value

总结:1、如果一个函数需要进行货币操作,必须要带上payable关键字

            2、向当前合约支付:this.send(10)

            3、如果一个合约要用到send()方法,那么必须要定义fallback函数,否则会出异常


          (转自:tryblockchain.org)

       

                 

你可能感兴趣的:(学习笔记)