有没有一种方法可以更改智能合约的所有者?

huangapple go评论60阅读模式
英文:

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中设置,以允许只有所有者调用某些函数。

当你调用contractAsetData函数时,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 contractBs 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 contractAs 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.

huangapple
  • 本文由 发表于 2023年5月29日 23:32:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定