solidity中转账接收者与发起者的问题

问题描述

准备写个转账的代码时,发现solidity语言中转账的函数有三个,分别是send、transfer、call。用法也很简单:

			目标接收者地址.transfer(金额);
			目标接收者地址.send(金额);
			目标接收者地址.call.value(金额)();

但使用过程中,总是转账失败,返回revert错误,显示没有钱发送。此时我就很想知道到底是谁再给目标地址转账了。
可以很明显的看出,代码很明显指出接收者是谁,但是发送者到底是谁呢?

基础知识

1、address(this)

标题这个代码到底代表的是谁的地址?我们用代码来展示一下

	function getAddress() public view returns(address,uint256){
        return (address(this),address(this).balance);
    }

运行结果图:
函数运行结果
这个地址是什么呢?下图可以给出答案:
合约地址
很明显,address(this)是合约地址,那么自然,address(this).balance也是没有余额的。

2、msg.sender

	function getMsgAddress() public view returns(address){
        return address(msg.sender);
    }

合约部署:
合约部署信息
运行结果:
msg调用
在这里插入图片描述
调用该合约的账号地址为上图所示,msg.sender显示出来的也是该账户。所以我们可以知道msg.sender是个账户地址

2.2 账户地址分析

那么这个账户地址是调用该合约的用户地址,还是部署该合约的用户地址呢?
只需要将账户地址换一个,再调用一次即可:
新用户
换成如上图所示的地址看看。
msg新用户信息
很明显,msg.sender就是合约调用者的地址

问题解决

扯了那么多,到底转账发送者是谁呢?到底是合约地址,还是合约调用者呢?

1、我的问题

首先先讲讲我碰到的无法转账的问题。(显示余额不足)

contract transfer{
    address accountAddress;
    address payable targetAddress;

    constructor(){
        accountAddress=msg.sender;
    }
    function getAccountAddress() view public returns(address){
        return accountAddress;
    }
    //设置目标地址
    function setTargetAddress(address payable target)  public {
        targetAddress=target;
    }
    function getTargetAddress() view public returns(address){
        return targetAddress;
    }
    //向目标账户转账
    function EFT() payable public{
        targetAddress.transfer(100 wei);
    }
    //据说这两个代码是必须的,下面给个链接,你们可以学习学习
    fallback() external payable {}
    //https://blog.csdn.net/weixin_43343144/article/details/88173747
    receive() external payable {}
}

代码中学习的链接地址

合约部署信息:
合约部署信息
合约账户与目标账户设置:
部署账户
设置目标账户
合约调用者是0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
转账目标接收者是:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

随后点击EFT转账,错误信息如下;
error infomation
很明显这是钱不够导致的。那么我也不卖关子了,需要在下图位置给出金额:
error location

注意:前面所有的操作都不需要给以太币数量赋值,只需要设置为0.。只有当要点击EFT进行转账过程了,需要把以太币数量赋值为转账金额(多一点没关系,少一点就会出现上面我出现的失败)。

2、 到底谁是转账的发送者呢?

为了让结果更加明显,我将代码改为:

	//向目标账户转账
    function EFT() payable public{
        targetAddress.transfer(1 ether);
    }

账户初始金额如下图所示:
合约调用者金额99.9发送者
接收者金额99.9在这里插入图片描述
调用EFT函数以后:
合约调用者余额

总结

由上面可知:谁调用了合约,谁就可以作为主体账户,无论是转账还是其他操作,消耗的都是调用合约的地址的以太币。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Solidity 是一种用于编写智能合约的语言,而 HTML 则是一种用于构建网页的标记语言。因此,它们在实现登陆和注册功能时通常需要与其他技术一起使用,例如 JavaScript 和后端服务器。 以下是一种可能的实现方式: 1. 创建一个包含用户名和密码的 Solidity 智能合约。 ``` contract User { struct UserData { bytes32 passwordHash; bool exists; } mapping (string => UserData) users; function register(string memory username, bytes32 passwordHash) public { require(!users[username].exists, "User already exists"); users[username] = UserData(passwordHash, true); } function login(string memory username, bytes32 passwordHash) public view returns (bool) { return users[username].exists && users[username].passwordHash == passwordHash; } } ``` 2. 创建一个包含注册和登录表单的 HTML 页面,并使用 JavaScript 将表单数据发送到智能合约。 ``` <!DOCTYPE html> <html> <head> <title>Login/Register Page</title> </head> <body> <form id="register-form"> <label>Username:</label> <input type="text" name="username" required> <br> <label>Password:</label> <input type="password" name="password" required> <br> <button type="submit">Register</button> </form> <form id="login-form"> <label>Username:</label> <input type="text" name="username" required> <br> <label>Password:</label> <input type="password" name="password" required> <br> <button type="submit">Login</button> </form> <script> const web3 = new Web3(Web3.givenProvider); const contractAddress = "0x123..."; // 智能合约地址 const contractAbi = [ { ... } ]; // 智能合约 ABI const contract = new web3.eth.Contract(contractAbi, contractAddress); document.getElementById("register-form").addEventListener("submit", async (event) => { event.preventDefault(); const username = event.target.username.value; const passwordHash = web3.utils.sha3(event.target.password.value); await contract.methods.register(username, passwordHash).send({ from: web3.eth.defaultAccount }); alert("Registration successful!"); }); document.getElementById("login-form").addEventListener("submit", async (event) => { event.preventDefault(); const username = event.target.username.value; const passwordHash = web3.utils.sha3(event.target.password.value); const result = await contract.methods.login(username, passwordHash).call(); if (result) { alert("Login successful!"); } else { alert("Incorrect username or password."); } }); </script> </body> </html> ``` 请注意,这只是一种基本实现方式,您可能需要根据具体需求进行修改和优化。此外,还需要一些其他步骤,例如在后端服务器设置 Solidity 智能合约并将其与前端进行交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值