从外部合同调用时,solidity 合同状态变量值显示奇怪
solidity contract state variable value show strange when invoke from external contrace
描述
合约 A 有一个状态变量 owner
,它很好地初始化为 msg.sender
。
但是当从另一个合约函数调用时,这个 owner
变量变成了 0x0
,该函数获取合约 A 实例的地址并转换为 A 类型。
环境
- 编译器版本:0.4.25
- Framework/IDE:混音
- EVM执行环境:
在 Remix IDE 的 运行 选项卡上选择 'Javascript vm';
重现步骤:代码中描述了步骤。
(代码也可在 https://github.com/ethereum/solidity/issues/5210 获得)
pragma solidity 0.4.25;
contract A{
address public owner;
event Ret(string flag, address sender, address owner);
event ConstrutEvt(string flag, address owner );
function A() public{
owner = msg.sender;
emit ConstrutEvt("A", msg.sender);
}
function doSomething() public view returns(string flag, address sender, address owner){
emit Ret("A::doSomething", msg.sender, owner);
return ("A::doSomething", msg.sender, owner);
}
}
contract EvilDoer{
// step1: deploy contract A on remix IDE.
// and the log show `owner` is a valid address value.
// step2: deploy contract EvilDoer.
// step3: on remix IDE run tab, invoke doSomething() use the contract A address as argument.
// This time the log show that 'owner' is zero. Why ?
function doSomethingEvil(address instanceAddrOfA) public {
A contractA = A(instanceAddrOfA);
contractA.doSomething();
}
}
您的问题不在于 EvilDoer
,而是在于 A
中的 doSomething()
函数。
当您设置 return 值时,您就是在为它们分配值 string flag, address sender, address owner
。虽然这是一个有效的操作,但您无意中覆盖了上面定义的 owner
变量。
要解决此问题,请将 return 声明中 owner
的名称更改为类似 _owner
的名称,这样您就不会覆盖全局变量。
描述
合约 A 有一个状态变量 owner
,它很好地初始化为 msg.sender
。
但是当从另一个合约函数调用时,这个 owner
变量变成了 0x0
,该函数获取合约 A 实例的地址并转换为 A 类型。
环境
- 编译器版本:0.4.25
- Framework/IDE:混音
- EVM执行环境:
在 Remix IDE 的 运行 选项卡上选择 'Javascript vm';
重现步骤:代码中描述了步骤。
(代码也可在 https://github.com/ethereum/solidity/issues/5210 获得)
pragma solidity 0.4.25;
contract A{
address public owner;
event Ret(string flag, address sender, address owner);
event ConstrutEvt(string flag, address owner );
function A() public{
owner = msg.sender;
emit ConstrutEvt("A", msg.sender);
}
function doSomething() public view returns(string flag, address sender, address owner){
emit Ret("A::doSomething", msg.sender, owner);
return ("A::doSomething", msg.sender, owner);
}
}
contract EvilDoer{
// step1: deploy contract A on remix IDE.
// and the log show `owner` is a valid address value.
// step2: deploy contract EvilDoer.
// step3: on remix IDE run tab, invoke doSomething() use the contract A address as argument.
// This time the log show that 'owner' is zero. Why ?
function doSomethingEvil(address instanceAddrOfA) public {
A contractA = A(instanceAddrOfA);
contractA.doSomething();
}
}
您的问题不在于 EvilDoer
,而是在于 A
中的 doSomething()
函数。
当您设置 return 值时,您就是在为它们分配值 string flag, address sender, address owner
。虽然这是一个有效的操作,但您无意中覆盖了上面定义的 owner
变量。
要解决此问题,请将 return 声明中 owner
的名称更改为类似 _owner
的名称,这样您就不会覆盖全局变量。