你存进合约的 ETH,到底放在哪里?
想象这样一个场景你往银行卡里存了 3 万块钱。打开手机 App账面上清清楚楚写着活期余额 3 万元。但如果你去银行金库翻找绝对找不到一个贴着你名字、放着你那三万现金的小抽屉。你的钱早就和别人的钱混在了一起变成了银行资金池的一部分。你能取钱、能转账靠的从来不是“钞票上写了你的名字”而是银行系统里的那本账某某某存款 3 万元。以太坊上的智能合约底层逻辑其实一模一样。很多人刚学 Solidity 时常常被msg.sender、msg.value、address(this).balance和balances[msg.sender]搞得晕头转向。其实这不怪你语法没学好而是因为很多人在一开始没有分清最核心的一件事链上的钱和合约里的账从来都不是一回事。一、先搞清楚谁持有 ETH在以太坊的世界里所有的 ETH 都只属于一样东西——地址Address。这里主要有两种类型的地址EOA外部账户也就是你在 MetaMask 里用私钥控制的钱包地址。它能主动发起交易也能持有 ETH但它肚子里没有半行代码。合约账户部署了智能合约代码的地址。它也有自己的余额、能存数据、能被调用但它没有私钥不会自己主动发起交易。它就像一台老式自动售货机有钱、有程序但只有当你投币、按键时它才会按照写好的逻辑吐出东西。所以第一层认知很简单ETH 永远属于某个地址。用户钱包里的 ETH 属于用户地址合约里的 ETH 属于合约地址。合约代码本身只是说明书。只有当它被部署到链上、生成了一个具体的合约地址后那个地址才真正具备了装钱的能力。合约代码不能凭空变出钱它必须通过代码逻辑把 ETH 从一个地址转到另一个地址。二、真实的钱与虚拟的账假设有三方Alice用户0xAAA钱包里有 10 ETHBigBank合约0xBBB当前余额 0现在Alice 向 BigBank 转了 3 ETH。交易完成后链上发生了两件事Alice 的钱包余额变成了 7 ETH。BigBank 合约地址的余额变成了 3 ETH。钱确实进到合约地址了。但问题来了合约怎么知道这 3 ETH 到底是谁存的它默认是不知道的除非开发者在合约里写了一本账mapping(address uint256) public balances;当 Alice 存款时合约会顺手记上一笔balances[msg.sender] msg.value;于是链上同时存在了两种截然不同的数据address(this).balance 3 ETH合约实际金库里有多少钱balances[Alice] 3ETH合约账本上写着 Alice 存了多少这就是 Solidity 最容易踩坑的地方金库里的总资金和账本上的个人存款完全是两码事。三、谁在叫我看清msg.sendermsg.sender是新手最容易产生误解的变量。它其实只有一句话的定义msg.sender是当前这次函数调用的直接调用者不一定是最终用户。1. 用户直接调用如果是 Alice 直接调用合约bigBank.deposit{value: 1 ether}();此时在deposit()函数内部msg.sender就是 Alice 的地址。msg.value是 Alice 这次塞进来的 1 ETH。address(this).balance是 BigBank 当前总共的钱。msg.sender.balance是 Alice 钱包里剩余的钱。2. 合约调用合约最容易迷路的地方如果流程变成了Alice → 合约 A → 合约 B那么在合约 B 眼里msg.sender不是 Alice而是合约 A 的地址。这就好比你让秘书去银行代办业务。银行柜员眼里记录的经办人是秘书而不是坐在办公室里的你。虽然业务是你的意愿但“直接和银行交手”的人是秘书。所以编写涉及跨合约调用的代码时千万别盲目信任msg.sender就是最终的用户。四、变量的职责划分把 Solidity 常见的几个全局和状态变量按功能归纳一下其实很清晰变量 / 表达式回答的问题本质是什么msg.sender谁在直接敲门当前调用的直接发起者msg.value这次带了多少钱本次调用附带的 ETH 数量address(this).balance合约金库里总共有多少当前合约地址实际持有的 ETHbalances[addr]账本上记录他有多少额度合约状态变量里记录的映射数据msg.value不是用户的总资产只是这一次交易附带的小费或本金而balances只是合约数据库里的一行数字不能直接当成现金用。五、写一个极简的银行合约把上面的逻辑串起来就是一个标准的存取款合约骨架// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract SimpleBank { address public admin; mapping(address uint256) public balances; constructor() { admin msg.sender; } // 存款既要收钱也要记账 function deposit() external payable { require(msg.value 0, Must send ETH); balances[msg.sender] msg.value; } // 取款查账、清零、转账 function withdraw() external { uint256 amount balances[msg.sender]; require(amount 0, No balance); // 防重入先清零账本再把钱转走 balances[msg.sender] 0; (bool success, ) payable(msg.sender).call{value: amount}(); require(success, Transfer failed); } function getContractBalance() external view returns (uint256) { return address(this).balance; } }这里藏着一个极具实战意义的开发习惯先清零账本再转账。如果把顺序反过来先给用户转钱、最后才把balances[msg.sender] 0恶意合约可能会在收到钱的一瞬间疯狂发起回调把钱从合约里掏空也就是大名鼎鼎的重入攻击。先更新状态再进行外部交互Checks-Effects-Interactions 模式是写智能合约的保命法则。六、回到最开始的银行比喻银行 App 里的数字是合约账本balances。银行金库里的现金堆是合约地址余额address(this).balance。柜台前递材料的人是直接调用者msg.sender。搞懂了这几层关系Solidity 里那些让人头疼的转账、记账和权限控制其实也就不过如此了。Tips为了方便查阅更多可以关注我的gz号全网同名第一时间更新。

相关新闻

云服务器docker的安装

云服务器docker的安装

# 安装docker 参考文档:https://help.aliyun.com/document_detail/60742.html?spma2c4g.11174283.6.548.24c14541ssYFIZ第一步:安装必要的一些系统工具yum install -y yum-utils device-mapper-persistent-data lvm2第二步:添加软件源信息yu…

2026/10/28 8:22:24 阅读更多 →
基于GRU神经网络的英文诗歌生成:从毕设选题到答辩全流程实战

基于GRU神经网络的英文诗歌生成:从毕设选题到答辩全流程实战

毕设开题周最折磨人的一件事,不是怕题目难,而是怕题目选了之后根本不知道从哪里下手。我去年在选题时盯上了“基于GRU神经网络的英文诗歌生成系统”,当时纯粹是觉得生成诗歌这个方向好展示——训练完能跑出看得见、读得懂、还能当场演示的Dem…

2026/11/8 11:12:42 阅读更多 →
置信学习如何解决目标检测标签噪声:约束模型下的实操指南

置信学习如何解决目标检测标签噪声:约束模型下的实操指南

以目标检测里的那些烂标签为切入点。做检测项目的人基本都遇到过这种情况:数据标注回来,肉眼看着框没啥问题,训练出来的模型却被某些样本反复教坏。分类不对、框偏了、或者压根标漏了。早期我把这些问题归咎于“数据质量”,后来发…

2026/10/25 7:38:15 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/8 1:19:03 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/7 12:08:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/8 1:35:05 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/8 1:38:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/7 12:08:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/8 1:23:14 阅读更多 →

日新闻

周新闻

月新闻