实现内容:从remix上的虚拟账户上转账给自己编写的智能合约账户
前提基础:对solidity有一些基础了解,对以太坊的账户机制有一定了解。
账户
在以太坊中账户的唯一标识是地址(address)。
在solidity中即地址类型。但是地址类型也分为两种:address
和 address payable
。地址类型最常用的成员变量有balance
,即当前账户余额。具体成员变量可查看文档
而address payable
和 address
相同,不过还具有成员transfer()
和 send()
这样使得其可以接收向该账户的转账。
receive()函数
一个合约最多有一个 receive
函数, 声明函数为: receive() external payable { ... }
在对合约没有任何附加数据调用(通常是对合约转账)是会执行 receive
函数。例如:通过 .send()
或者 .transfer()
如果 receive
函数不存在,但是有payable的 fallback 回退函数,那么在进行纯以太转账时,fallback 函数会调用.
如果两个函数都没有,这个合约就没法通过常规的转账交易接收以太(会抛出异常)。
fallback()函数
在一个合约中最多有一个fallback()
函数,函数声明为: fallback () external [payable]{...}
,这个函数不能有参数和返回值。(高级版本中可以,文档)
作用:当调用一个合约中不存在的函数或者调用空方法时,亦或使用合约地址的内置函数transfoer()
和send()
的时,若没有receive()
函数,则会执行目标合约的fallback()函数。
所以在我们对合约账户进行转账的例子中,必须包含fallback()
函数,否则运行时会报错失败。规范写的话则需要包含receive()
函数和 fallback()
函数
代码:
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.7.0;
contract transferTest {
// 向合约账户转账
function transderToContract() payable public {
payable(address(this)).transfer(msg.value);
}
// 获取合约账户余额
function getBalanceOfContract() public view returns (uint256) {
return address(this).balance;
}
fallback() external payable {}
receive() external payable {}
}
// 使用的编译器版本为:0.7.5
代码比较简单,但需要注意的几点:
- 得到账户合约地址使用:
address(this)
address
转address payable
是显式转换:payable(address)
address payable
转address
是隐式转换。msg.value
是调用者传入的
操作:
-
点击compile对合约代码进行编译
-
点击DEPLOY&RUN TRANSACTIONS,并点击Deploy进行部署
-
底下Deployed Contracts中会出现一个已经部署好的合约,我们可以通过点击
transderToContract()
进行调用函数。假设我们需要向合约地址转账10个以太币
图中我们向合约用户转账10个以太币,右下方的控制台中可以查看到交易的hash码,也可以debug去查看运行细节。
-
点击
getBalanceOfContract()
进行查看当前合约用户中的余额。这里是以wei为单位,所以有一大串的0。
以上就是整个demo的全部内容,若有不当之处欢迎讨论。