首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >理解以太坊智能合约的三个地址以及转账

理解以太坊智能合约的三个地址以及转账

作者头像
Maic
发布2025-11-13 19:12:53
发布2025-11-13 19:12:53
970
举报
文章被收录于专栏:Web技术学苑Web技术学苑

智能合约的地址通常来讲来自有三个地址,一个是创建合约的地址,一个能与合约交互的地址,另一个部署合约时会产生一个地址【即合约就是这个地址】

初识以太坊,这三个地址似乎会有点绕,以一个简单的例子来深刻理解这三个地址

代码语言:javascript
复制
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

contract Own {
 // 申明了一个owner地址
  address public owner;

  constructor() {
    // 部署Own这个合约时所属钱包的地址
    owner = msg.sender;
  }
  // 获取由哪个钱包部署智能合约的钱包地址
  function getOwner() public view returns (address) {
    return owner;
  }
  // 获取部署这个智能合约的地址
  function getContractAddress() public view returns (address) {
    return address(this);
  }
  // 获取钱包与智能合约交互的那个地址
  function getSenderAddress() public view returns(address) {
    return msg.sender;
  }
}

从以上代码来分析,我们发现,创建合约的地址,owner也不会发生变化contructor这是msg.sender当前钱包地址赋值给了owner,注意,如果这个合约代码没有任何变化,一旦部署合约,合约地址就不会发上变化,当前部署的owner不会发生变化

address(this)这是这个Own智能合约的地址,当我们部署智能合约成功时,返回这个智能合约地址就是这个地址

msg.sender这个 msg 是个全局变量,是返回当前钱包与合约交互的这个钱包地址

具体我们可以使用在 remix 在线编辑器中测试这个合约

首先我选择的钱包地址是0x5B38Da6a701c568545dCfcB03FcB875f56beddC4这个虚拟钱包地址

当我们部署完成后,我们会发现

与合约交互的地址与当前部署钱包的地址可以是同一个地址,当我们部署合约完成时,当你修改当前钱包地址地址时,owner地址不会发生改变,如果合约代码不变,那么合约地址就是唯一的

我们获取一下这三个地址的余额

代码语言:javascript
复制
  ...
  // 获取当前交互的钱包地址
  function getSenderAddressBalance() public view returns(uint) {
    return msg.sender.balance;
  }
  // 获取Sender钱包地址的余额【与智能合约交互的钱包地址,或者部署当前智能合约的钱包地址】
  function getSenderAddressBalance(address _address) public view returns(uint) {
    return _address.balance;
  }
  // 查询智能合约的余额地址
  function getContractAddressBalance() public view returns(uint) {
        return address(this).balance;
  }
   // 根据输入地址查询余额
  function getAddressBalance(address _address) public view returns(uint) {
    return _address.balance;
  }

通过balance就可以查询这个三个地址的余额,并且我们从中可以知道查询余额是公开的 api 方法,并不会产生gas费用转账

我们在合约内部可以一个钱包地址给另一个钱包地址转账,也可以给合约地址转账,那么这是怎么实现的呢,首先我们先来看钱包与钱包地址的转账。

  • 钱包与钱包转账
代码语言:javascript
复制
...
 function send(address payable  _address) public payable {
    // bool send = _address.send(msg.value);
    // require(send, "sender error");
    (bool succeess,) = _address.call{value: msg.value}("");
    是另一个钱包地址, 我们想另一个钱包进行转账操作 首先 1 是我们当前钱包部署的钱包地址,2 是两外一个钱包地址,我们可以从 1 钱包转到 2 钱包一个 wei 的钱(succeess, "Failed to send Ether");
  }

代码非常简单,首先我们尝试使用send方法,在官方已经不推荐使用 send 方法转账而是推荐使用call或者transfer,但是官方最终推荐 call 方法进行转账

我们发现_address是另一个钱包地址, 我们可以进行想另一个钱包进行转账操作 首先 1 是我们当前钱包部署的钱包地址,2 是两外一个钱包地址,我们可以从 1 钱包转到 2 钱包一个 wei 的钱

我们由这前后两张图比较知道 2 地址已经加了 1wei

但是如果这个_address修改成合约地址,那会怎么样?

如果_address 是一个转账合约地址那么这个合约必需要满足有receive或者fallback,否则转账到合约地址里一定会失败

代码语言:javascript
复制

    event Received(uint amount);
    receive() external payable {
        // 空函数或 emit event 一般不会超过 2300 gas
    }

我们会发现已经向合约地址转账成功,并且能查询到合约地址账户的余额

总结

  • 深刻理解以太坊三个地址,一个当前钱包地址ownAddress,一个又当前钱包部署的合约地址contractAddress,还有一个与合约交互的钱包地址senderAddress【与合约交互的钱包地址可以是当前部署合约的钱包地址】
  • 当部署合约地址成功后,owenAddress不会发生变化,因为在 constructor 中,当部署合约成功后,会执行 constructor,msg.sender 地址就已经唯一赋值了,所以不管如何切换交互钱包地址这个 ownerAddress 不会发生变化,即初始钱包的地址
  • 当部署合约成功时,即会产生一个合约地址,如果合约代码没有发生变化,编译并部署合约后,合约地址并不会发生变化
  • 钱包地址之间在合约代码中如何实现转账,普通交互钱包地址可以使用call转账,注意这个合约方法必需payable, 且地址_address也必须时 address 类型payable允许发送eth
  • 当我们向智能合约地址转账时,此时这个合约own必需要有receive() external payable { }否则就会被拒绝,转账报错
  • code example[1]

参考资料

[1]

code example: https://github.com/maicFir/SolidityLesson/blob/master/18-test/contracts/Own.sol

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Web技术学苑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档