三solidity 交易 transfer 的使用《实战NFT web3 solidity(新版本0.8.+)》

Posted 1_bit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三solidity 交易 transfer 的使用《实战NFT web3 solidity(新版本0.8.+)》相关的知识,希望对你有一定的参考价值。

《web3 solidity0.8.+版本(持续更新新版本内容) 基础到实战NFT开发》会及时更新新版本 solidity 内容,以及完成最终的 NFT 实战商业项目部分。

注:由于是付费专栏内容,若有错误请及时联系@1_bit,博客链接:https://blog.csdn.net/A757291228 ,或在文章下留言,收到后将会对错误进行改正,若是版本更新导致的问题也希望大家对错误进行提交,尽力去保证付费用户该得到的权益。

文章目录可查看:目录(文章更新中…)
更新内容将会在目录中更新…

友情提示:本系列文章读者最好学过一门编程语言,面向对象语言更佳,文章所有代码将会完整贴出。

一、查看余额与支付到合约

在 solidity 中交易是核心知识点,交易贯穿了几乎大部分的智能合约操作。咱们在正式学习交易之前,首先了解一下如何给合约转账以及如何查看合约中的余额。

以下是一个有关查看合约地址余额和给合约地址转账的sol 代码示例:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract  PayDemo
    
    function payToContract() public payable
    
    
    function getBalance() public view returns(uint256)
        return address(this).balance;
    

以上合约 PayDemo 中,payToContract 方法是一个空函数,并且接收合约转账的方法,因为在其中使用了 payable 对其进行修饰。payable 修饰后的方法可以让方法在调用时接收附带的 ether,那如何附带 ether 呢?这个暂时先放一下,等下讲解完所有 sol 代码后再讲解如何操作,并让方法接收附带的 ether。

此时我们可以查看 getBalance 方法,在这个方法中 使用了 return 返回 address(this).balance;,在这里 this 表示本身地址,但在 0.8 版本中需要使用 address 函数对 this 进行强转,强转之后才能调用 balance 获取余额,那么 getBalance 的作用就是返回余额。

接下来开始部署合约,部署完毕之后如下(红色的按钮表示 payable function):


首先我们可以调用 getBalance 查看当前的合约余额:

接着我们开始往合约中传入 ether,此时我们可以选择需要支付的合约:

选择完毕之后在 VALUE 中输入你要传入的多少 ether,当然你也要选择对应的单位:

输入完毕后调用 payToContract 方法:

此时我们点击 getBalance 后可以查看到余额:

并且选择的虚拟地址的 ether 也相对应的减少了:

二、transfer 转账与取款

对某地址进行转账

在 solidity 中我们可以通过 transfer 对合约进行转账、对某地址进行转账以及对合约中的余额进行提现。

我们继续使用第一点中的合约,在合约中添加方法实现 transfer 的操作。

首先我们实现对某个合约进行转账,此时方法编写如下:

//合约给某个地址转 ether
function toEther(address payable _toAdrr)public payable
    _toAdrr.transfer(msg.value);

此时这个 toEther 方法接收一个参数 _toAdrr,这个 _toAdrr 表示接收方需要使用 payable 进行修饰,注意这个方法是一个 payable 的方法。

接着在这个方法中编写了这么一条语句: _toAdrr.transfer(msg.value);

其中 transfer 是转账的方法,其参数是 msg.value 表示转账的金额,_toAdrr 为接收转账的地址,那么这个余额是怎么来的呢?

还记得第一点中的 VALUE 吗:

这个 VALUE 就是这个 msg.value,表示我们调用合约时所在此处添加的 VALUE,那么这就很好理解了,在这里填入数值后进行方法调用,传入对应的接受地址,那么就可以对该地址进行转账。

查询某地址余额

查询某地址余额就很容易了,直接接收一个参数为地址,通过这个地址取出 balances 就ok了,这个方法如下:

//查询某地址 balances
function getAdrrBalance(address _adrr)public view returns(uint256)
    return address(_adrr).balance;

不过一定要注意,在调用 balance 之前需要对应的为其强转 address。

取款

在第一点中我们还需要一点补充,那就是将余额付给合约后,那没有取款的方法那不是很惨了?

所以在这里我们添加一个方法,取出这个合约中的余额:

//取款
function withdraw()public payable
    payable(msg.sender).transfer(address(this).balance);

以上是一个取款方法,记得需要使用 payable进行修饰,其实看到这里大家应该明白了,只要是涉及转账、接收的函数那么就需要使用 payable进行修饰,并且在调用转账方法前,也需要对某一个地址进行payable 修饰,在函数体重代码为 payable(msg.sender).transfer(address(this).balance);,也对 msg.sender 进行了修饰,msg.sender 表示当前的调用合约的人,就是一个地址,进行了 payable 修饰后,对这个人进行转账,这个月就是当前地址的余额。

演示

接下来我们部署合约,先设置一下 msg.value 的值,我们往这个合约中添加余额:

之后调用第一点中的 payTo 方法,此时当前合约已经有了 10ETH 了:

接着我们选择一个虚拟账户,复制一下他的地址:

往这个合约中转10个 ether(记得切换回来对应的付款地址):

在此一定要注意设置 msg.value 的值:

接着调用方法发现虚拟账户中一个账户余额变少了一个账户余额变多了:

也可以复制地址参数使用方法进行查询:

接着使用取款按钮取出最开始给合约的 10个 ether:

此时余额发生改变:

并且对应的合约余额也无了:

第二点完整 solidity 代码:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract  PayDemo
    //给合约 ether
    function payToContract() public payable
    
    //查看 balance
    function getBalance() public view returns(uint256)
        return address(this).balance;
    

    //合约给某个地址转 ether
    function toEther(address payable _toAdrr)public payable
        _toAdrr.transfer(msg.value);
    

    //查询某地址 balances
    function getAdrrBalance(address _adrr)public view returns(uint256)
        return address(_adrr).balance;
    

    //取款
    function withdraw()public payable
        payable(msg.sender).transfer(address(this).balance);
    


三、transfer 补充

补充一 多余 ether 的流入

在 solidity 中可以手动设置对应的转账数额,单位有 weg、gwei、ether 等,在此使用 ether 作为示例。

修改 toEther 方法:

//合约给某个地址转 ether
function toEther(address payable _toAdrr)public payable
    _toAdrr.transfer(10 ether);

接下来我会给另一个账户(120ether 账户)转账:

此时复制了这个地址作为 toEther 方法的参数,并且设置了 VALUE 值:

此时是大于了 10 ether的,那么将会发生什么情况?

调用方法后,发现接收方的地址多了 10个 ether:

那剩下的 10个 ether在哪了呢?此时这 10 个ether 被转入了当前合约之中:

设置提现权限

在提现的时候不可能随便任何一个人可以提现,在此我们需要便携一个条件,只有合约拥有者可以提现:

//取款
function withdraw()public payable
    require(owner==msg.sender,"not allow withdraw");
    payable(msg.sender).transfer(address(this).balance);

以上代码中使用了 require(owner==msg.sender,"not allow withdraw"); 对合约拥有者进行判断,require 将会判断 msg.sender 当前调用者是否等于 owner,owner 则是当前合约者,如果等于则继续往下执行,否则将会报错 “not allow withdraw”。

此时编写一个方法接收 ether:

function pay()public payable
    

那么这个 owner 怎么来呢?直接使用构造函数在部署的时候就传入部署者即可:

address owner;
constructor()
    owner=msg.sender;

接着部署完毕后,设置 VALUE 后使用 pay 方法传入 ether:

接着切换一个账户:

使用提现方法:

此时将会报错,这时再切换成部署合约的地址:


提现成功操作:


该小点完整代码:

// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
contract  PayDemo
    address owner;
    constructor()
        owner=msg.sender;
    

    function pay()public payable 

    //取款
    function withdraw()public payable
        require(owner==msg.sender,"not allow withdraw");
        payable(msg.sender).transfer(address(this).balance);
    


以上是关于三solidity 交易 transfer 的使用《实战NFT web3 solidity(新版本0.8.+)》的主要内容,如果未能解决你的问题,请参考以下文章

三solidity 交易 transfer 的使用《实战NFT web3 solidity(新版本0.8.+)》

solidity msg.sender.transfer发送给谁

solidity msg.sender.transfer发送给谁

solidity笔记——冻结和交易属性——2021.5.10

智能合约实战 solidity 语法学习 06 [ transfer ]

智能合约实战 solidity 语法学习 05 [ for循环transfer ] 附代码