【Solidity入门系列】以太币支付

2017/2/19 posted in  Solidity入门系列

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

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来模拟从另一个合约发送
      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标识2

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

关于作者
专注基于以太坊(Ethereum)的相关区块链(Blockchain)技术,了解以太坊,Solidity,Truffle等。个人博客:http://me.tryblockchain.org

处于某些特定的环境下,可以看到评论框,欢迎留言交流^_^。

友情链接: 区块链技术中文社区    深入浅出区块链