solidity实现账户地址向合约账户转账

一个合约最多有一个 receive 函数, 声明函数为: receive() external payable { … }
不需要 function 关键字,也没有参数和返回值并且必须是 external 可见性和 payable 修饰. 它可以是 virtual 的,可以被重载也可以有 修改器modifier 。
在对合约没有任何附加数据调用(通常是对合约转账)是会执行 receive 函数. 例如 通过 .send() or .transfer() 如果 receive 函数不存在, 但是有payable 的 fallback 回退函数 那么在进行纯以太转账时,fallback 函数会调用.
如果两个函数都没有,这个合约就没法通过常规的转账交易接收以太(会抛出异常).
更糟的是,receive 函数可能只有 2300 gas 可以使用(如,当使用 send 或 transfer 时), 除了基础的日志输出之外,进行其他操作的余地很小。下面的操作消耗会操作 2300 gas :
写入存储
创建合约
调用消耗大量 gas 的外部函数
发送以太币

合约可以最多有一个回退函数。函数声明为: fallback () external [payable] 或 fallback (bytes calldata _input) external [payable] returns (bytes memory _output)
没有 function 关键字。 必须是 external 可见性,它可以是 virtual 的,可以被重载也可以有 修改器modifier 。
如果在一个对合约调用中,没有其他函数与给定的函数标识符匹配fallback会被调用. 或者在没有 receive 函数 时,而没有提供附加数据对合约调用,那么fallback 函数会被执行。
fallback 函数始终会接收数据,但为了同时接收以太时,必须标记为 payable 。
如果使用了带参数的版本,_input 将包含发送到合约的完整数据(等于 msg.data ),并且通过 _output 返回数据。 返回数据不是 ABI 编码过的数据,相反,它返回不经过修改的数据。
更糟的是,如果回退函数在接收以太时调用,可能只有 2300 gas 可以使用,参考 receive接收函数
与任何其他函数一样,只要有足够的 gas 传递给它,回退函数就可以执行复杂的操作。

一个没有定义 fallback 函数或  receive 函数的合约,直接接收以太币(没有函数调用,即使用 send 或 transfer)会抛出一个异常, 并返还以太币

不定义fallback或receiver回退函数,call仍然可以执行 send或transfer无法执行

通过在账户地址指定msg.value实现向合约账户转账

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

// 向合约账户转账 
contract terans{
// 向合约账户转账 ev
event TransEvent(address,uint);

//trigger recevier function
//纯转账调用receiver回退函数,例如对每个空empty calldata的调用
function transderToContract() payable public {
    payable(address(this)).transfer(msg.value);
}
// 获取合约账户余额 
function getBalanceOfContract() public view returns (uint256) {
    return address(this).balance;
}
//trigger recevier function
//纯转账调用receiver回退函数,例如对每个空empty calldata的调用
//对函数方法的调用 出发receiver回退函数 
function CallTransTest()payable public{
     (bool success,) = address(this).call(abi.encodeWithSignature("transderToContract()"));
         //emit TransEvent(address(this),2);
}
//trigger fallback function
    // 除了纯转账外,所有的调用都会调用这个函数.
    // (因为除了 receive 函数外,没有其他的函数).
    // 任何对合约非空calldata 调用会执行回退函数(即使是调用函数附加以太).
function CallNoexistTest()payable public{
     (bool success,) = address(this).call(abi.encodeWithSignature("noFunction()"));
         //emit TransEvent(address(this),2);
}
fallback() external payable {
            emit TransEvent(address(this),1);
}
receive() external payable {
        emit TransEvent(address(this),2);
}
}

在这里插入图片描述

(注意使用前先将IP改为自己的IP或127.0.0.1) 本软件是使用套接字、ReceiveCallBack(IAsyncResult AR)函数为例的客服实例,修正了关闭客户端会导致异常的Bug;并且还是一个RichTextBox颜色使用的范例,不同的事件使用不同的颜色:如用户登录用红色、用户名用绿色、聊天内容用黑色^_^! 代码附赠全套注释,帮助初学者学习使用。 下面是核心代码 private void ReceiveCallBack(IAsyncResult AR) { try { DateTime dt = DateTime.Now; //如果服务器突然关闭后,客户端还坚持与之连接就会弹出异常; //检查是否套接字还连接上就可以避免这一问题。 if (!ClientSocket.Connected) { return; } //挂起AR,独占的使用AR来接收传过来的内容 int REnd = ClientSocket.EndReceive(AR); string StrOfREnd=Encoding.Unicode.GetString(MsgBuffer, 0, REnd); //截断的传输过来的字符串,"\n"前的是用户名 "\n"后的是聊天的内容 string UsersName = StrOfREnd.Substring(0, StrOfREnd.LastIndexOf("\n")); string Content = StrOfREnd.Substring(StrOfREnd.LastIndexOf("\n")+1); string Login=StrOfREnd.Substring(0,2); //MessageBox.Show("缓存中的内容:" + StrOfREnd + "\n" + "截断的用户名:" + UsersName + "\n" + "截断的内容:" + Content); if (Login != "登录") { //第一个字符不为“登陆” int oldlenth = tb_RecieveMsg.TextLength; this.tb_RecieveMsg.Select(oldlenth, 0); this.tb_RecieveMsg.SelectionColor = Color.Green; string str = Encoding.Unicode.GetString(MsgBuffer, 0, REnd); str = str.Substring(1, str.Length - 1); //用户使用绿色字体 this.tb_RecieveMsg.AppendText(" " + string.Format("{0:T}", dt) + " " + "用户:" + UsersName + "说:" + "\r\n"); this.tb_RecieveMsg.SelectionColor = Color.Black; this.tb_RecieveMsg.AppendText(" " + Content + "\r\n"); this.tb_RecieveMsg.AppendText("\r\n"); } else {
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值