在 Solidity 开发中,tx.origin 与 msg.sender 存在哪些关键区别?为何在智能合约中不推荐采用 tx.origin?
考察说明
考察对 Solidity 全局变量语义的理解以及基于 tx.origin 的安全风险。
回答思路
- 【回答框架 1】tx.origin 返回整个交易的最初发起者地址,即外部账户(EOA),而 msg.sender 是直接调用当前合约的地址,可能是外部账户也可能是另一个合约。
- 【回答框架 2】二者差异在于调用链:当用户调用合约A,A再调用B时,B中 msg.sender 为A,tx.origin 为用户地址。
- 【回答框架 3】不建议使用 tx.origin 的原因:存在钓鱼攻击风险,若用户先调用恶意合约,恶意合约再调用目标合约,目标合约若用 tx.origin 校验权限,会误认为用户直接授权,导致资金损失。
- 【回答框架 4】安全实践:使用 msg.sender 进行权限校验,或在关键操作中采用显式授权机制。
- 【关键点 1】tx.origin 是交易发起者,msg.sender 是直接调用者。
- 【关键点 2】合约间调用时 tx.origin 可能保持不变,msg.sender 变化。
- 【关键点 3】tx.origin 校验易遭钓鱼攻击,应避免使用。
- 【关键点 4】权限控制应基于 msg.sender。
- 【易错点 1】误以为 tx.origin 等同于 msg.sender 的父级,忽略其安全风险。
- 【易错点 2】在权限校验中错误使用 tx.origin,导致恶意合约利用。
- 【易错点 3】忽略 msg.sender 可能为合约地址,需结合业务判断。