英文:
Is there a way to change the owner of a smart contract?
问题
I've translated the content as requested:
"我已经学了很长时间了,感谢所有帮助我的人。这一次,我有一个问题,我不太知道如何解决,希望你可以帮我理解。我有一个智能合约 contractA 和另一个 contractB,我想知道是否可以在没有拥有者权限的情况下从 contractB 调用 contractA 的函数。ContractA 是我在互联网上找到的一个示例,contractB 是我用来测试的,但我无法理解和使 owner == msg.sender 的条件发生。
这是 contractA:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract contractA {
string data;
uint public blocknumber;
address public owner;
constructor() payable {
owner = msg.sender;
}
function set_data(string memory _data) public {
require(owner == msg.sender, "You are not the owner of the contract");
data = _data;
blocknumber = block.number;
}
}
这是我的 contractB:
我尝试调用 contractA 的 set_data 函数,但我不太明白为什么不能做到。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "./blockchain_tour.sol";
contract contractB {
contractA public new;
address public owner;
constructor(address _contractAddress) {
new = contractA(_contractAddress);
owner = new.owner();
}
function callSetData(string memory _data) public {
new.set_data(_data);
}
}
我总是收到“您不是合同的所有者”的消息。如果有人有任何想法,或者如果我做错了,或者它不能做到,请告诉我。"
英文:
I've been learning around here for a long time and I thank everyone who helps. This time I have a question that I don't quite know how to approach and I hope you can help me understand. I have a smart contract contractA and another contractB and I want to know if it is possible to call a function of contractA from contractB without being the owner. ContractA is an example I found on the internet and contractB is the one I've made to test but I'm not able to understand and make the condition of owner == msg.sender happen
this is contratA
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract contractA{
string data;
uint public blocknumber;
address public owner;
constructor() payable {
owner = msg.sender;
}
function set_data(string memory _data) public {
require(owner == msg.sender,"You are not the owner of the contract");
data = _data;
blocknumber = block.number;
}
}
and this is my contractB
I have tried to call the function set_data from contractA but I don't quite understand why it can't be done.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "./blockchain_tour.sol";
contract contracB {
contractA public new;
address public owner;
constructor(address _contractAddress) {
new = contractA(_contractAddress);
owner = new.owner();
}
function callSetData(string memory _data) public {
new.set_data(_data);
}
}
I always get the message that I am not the owner of the contract. If anyone has any idea or if I'm doing it wrong or it can't be done, please tell me.
答案1
得分: 1
在contractB
的构造函数中,你正在设置owner
。
constructor(address _contractAddress) {
new = contractA(_contractAddress);
owner = new.owner();
}
这个owner
变量在Solidity中设置,以允许只有所有者调用某些函数。
当你调用contractA
的setData
函数时,msg.sender
始终是部署了contractB
的地址(因为你是从contractB
调用的),我不认为你可以修改msg.sender
。所以通过改变owner = new.owner()
对msg.sender
没有影响。
你可以在contractA
中定义一个setOwnership
函数:
function setOwnership(address newOwner) private {
owner = payable(newOwner);
}
然后在setData
函数内调用这个函数:
function set_data(string memory _data) public {
owner = setOwnership(msg.sender);
require(owner == msg.sender, "You are not the owner of the contract");
data = _data;
blocknumber = block.number;
}
这将解决你的问题,你的代码将执行,但我认为这不是一种合适的逻辑和安全的做法。你可以考虑创建一个whiteList
映射:
mapping(address => bool) private whiteList;
只允许在这个映射中的地址调用setData
函数。你还可以在构造函数中将contractA
的部署者添加到这个映射中。
英文:
in contractB
s constructor you are setting owner
constructor(address _contractAddress) {
new = contractA(_contractAddress);
owner = new.owner();
}
this owner
variable is set in Solidity, to allow only the owner to call certain functions.
When you call contractA
s setData
function, msg.sender
is always the address that deployed the contractB
(since you are calling this from contractB) and i do not think that you can modify the msg.sender
. so by changing owner = new.owner()
you have no effect on msg.sender
.
you could define a setOwnership
function in contractA
function setOwnership(address newOwner) private {
owner = payable(newOwner);
}
then you call this function inside setData
function set_data(string memory _data) public {
owner=setOwnership(msg.sender);
require(owner == msg.sender,"You are not the owner of the contract");
data = _data;
blocknumber = block.number;
}
this will solve your problem, your code will execute but I do not think that it is something logical and secure. you could maybe create a whiteList
mapping,
mapping(address => bool) private whiteList;
and allow only addresses in this mapping call the setData
function. you can also add the deployer of contractA
to this mapping inside the constructor.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论