如何从合同实例A.foo()中获取正确的味精。
我被困在思想中,我需要一点澄清才能向前推进。
(描述是关于真正的问题,代码是最好的(我希望如此。)理解我)
我有使用ERC20令牌及其传输功能的主要合同A,也有遗传的拥有和白名单,并具有访问合同的地址,例如 我将一个地址传达给
我创建的a b in B构造函数(因为在bi中计算抵押品,我想分开两份不同的合同),可以
使用拥有的Antable Atable Aterable AT,而在与A相互作用的同时,它可以从3 party中访问A的A,这是足够的。在B中拥有不起作用,因为无法使用正确的味精。如果没有修改器,就可以在合同中创建B实例并可以访问我的A,不是吗?
谢谢提前的
编辑:我更改了代码以了解更多了解
// SPDX-License-Identifier: MIT
pragma solidity 0.8;
contract Ownable {
mapping (address => bool) private whiteListed;
modifier onlyWhiteListed {
require(whiteListed[msg.sender] == true, "You're not whitelisted");
_;
}
constructor () {
whiteListed[msg.sender] = true;
}
function setWhiteListed(address addr, bool trueOrFalse) public onlyWhiteListed {
whiteListed[addr] = trueOrFalse;
}
function getWhiteListed(address addr) public view returns (bool) {
return whiteListed[addr];
}
}
contract A is Ownable {
B public b;
event LogMsgSender(address who);
constructor() {
b = new B(address(this));
//setWhiteListed(address(this),true);
setWhiteListed(address(b),true);
}
function callMe() public onlyWhiteListed { // here I can only get real caller msg.sender
emit LogMsgSender(msg.sender); // when interact with that contract, not outside of contract
}
function callSender(address sender) public onlyWhiteListed { // here I can get real caller msg.sender from other contract
emit LogMsgSender(sender); // but is it worth to passing addresses ?
} // and HERE is my question: is this aproach secure??
}
contract B is Ownable {
A public a;
constructor(address addr) { //in remix I can't deploy in one time while
a = A(addr); //deploying A, I have to deploy copying addresses of A and do it separately
} //and after deploying also setWhiteListed() to whiteList in A
function callMe() public onlyWhiteListed { // this call isn't good for interact with sender, it's exlusive for calling as contract B
a.callMe(); // copies of this contract can
}
function callSender() public onlyWhiteListed { // modifiers protect from 3rd party contracts but
a.callSender(msg.sender); // that way it only can be used by deployer and whitelisted, (without modifiers they aren't secure)
} // bad idea ofc is adding to whitelist all over and over and
// it's impossible to recognize which to add which not
}
contract C {
B public b;
constructor(address addr) {
b = B(addr);
}
function callMe() public { //when modifiers is added this contract can't call these functions
b.callMe(); // but with modifiers functions can't be used to get right sender address
}
function callSender() public {
b.callSender();
}
}
,所以现在我决定继承,例如A是A,而我只是找到正确的发件人,您怎么看?
I got stucked in thoughts guys and I need bit of clarification to move it forward.
(Description is about real problem, code is for best (I hope so..) understanding me)
I have main contract A that uses erc20 token and its transfer functions, there is also inherited Ownable and whitelist with accessing addresses of contracts e.g. B,
I passing A address to the B constructor
I created instance of A in B (because in B I calculate collateral and I want to split to two different contracts)
Protecting A using Ownable it's enough from accessing A from 3rd party while interacting with A from A, Ownable in B isnt work because can't use right msg.sender, without modifiers someone can create instance of B in his contract and have access to my A, isn't it?
Thanks in advance
EDIT: I change a code for more to understand
// SPDX-License-Identifier: MIT
pragma solidity 0.8;
contract Ownable {
mapping (address => bool) private whiteListed;
modifier onlyWhiteListed {
require(whiteListed[msg.sender] == true, "You're not whitelisted");
_;
}
constructor () {
whiteListed[msg.sender] = true;
}
function setWhiteListed(address addr, bool trueOrFalse) public onlyWhiteListed {
whiteListed[addr] = trueOrFalse;
}
function getWhiteListed(address addr) public view returns (bool) {
return whiteListed[addr];
}
}
contract A is Ownable {
B public b;
event LogMsgSender(address who);
constructor() {
b = new B(address(this));
//setWhiteListed(address(this),true);
setWhiteListed(address(b),true);
}
function callMe() public onlyWhiteListed { // here I can only get real caller msg.sender
emit LogMsgSender(msg.sender); // when interact with that contract, not outside of contract
}
function callSender(address sender) public onlyWhiteListed { // here I can get real caller msg.sender from other contract
emit LogMsgSender(sender); // but is it worth to passing addresses ?
} // and HERE is my question: is this aproach secure??
}
contract B is Ownable {
A public a;
constructor(address addr) { //in remix I can't deploy in one time while
a = A(addr); //deploying A, I have to deploy copying addresses of A and do it separately
} //and after deploying also setWhiteListed() to whiteList in A
function callMe() public onlyWhiteListed { // this call isn't good for interact with sender, it's exlusive for calling as contract B
a.callMe(); // copies of this contract can
}
function callSender() public onlyWhiteListed { // modifiers protect from 3rd party contracts but
a.callSender(msg.sender); // that way it only can be used by deployer and whitelisted, (without modifiers they aren't secure)
} // bad idea ofc is adding to whitelist all over and over and
// it's impossible to recognize which to add which not
}
contract C {
B public b;
constructor(address addr) {
b = B(addr);
}
function callMe() public { //when modifiers is added this contract can't call these functions
b.callMe(); // but with modifiers functions can't be used to get right sender address
}
function callSender() public {
b.callSender();
}
}
So now I'm deciding to inherite e.g. B is A and I simply get right sender, what do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您发布的代码中有很多语法/逻辑错误。您不仅缺少
唯一的athower
修饰符,而且您在b中的呼叫是通过 type a:a.receivetoken()
与a.receivetoken()
...因此,您可能在发布问题时可能会键入几个错字(应该说a = a(aaddr);在构造函数等中)。当B调用A.SendToken()时,MSG.SENDER将为“ B”,但TX.origin将不变。检查MSG.Sender检查哪个合同给您。换句话说,它正在检查(在A.Sendtoken的仅限内部)B是否称为A.SendToken()。
首先修复所有错误,然后为自己插入一些调试日志记录,以便您可以在呼叫过程中查看MSG.sender的变化。您还可以记录tx.origin,以了解如何保持原始发件人。
关键是B创建的A的所有者是B(B)的特定实例。因此,在B内部可以将A. Whate()作为A的所有者称为“自然”。
You've got a lot of syntax/logic errors in the code you posted. Not only are you missing
onlyOwner
modifiers, but your calls in B are via the type A:A.receiveToken()
is not the same asa.receiveToken()
... so you've probably made several typos in posting your question (Should say a=A(aAddr); in the constructor etc).The msg.sender will be "b" when b calls a.sendToken() but tx.origin will be unchanged. Checking msg.sender checks which contract called you. In other words, it is checking (inside onlyOwner of A.sendToken) whether b is the one that called a.sendToken().
Start by fixing all the errors and then insert some debug logging for yourself, so you can see how msg.sender is changing during the calls. You can also log tx.origin to see how that remains the original sender.
The point is that the owner of the A that B created is that particular instance of B (b). It's therefore "natural" that inside B, it can call a.whatever() as a's owner.
您没有指定,但是如果您使用 openzezeppelin 您需要通过要保护的方法传递修饰符
唯一的家庭
。前任:You didn't specify, but if you are using the Ownable contract from openzeppelin you need to pass the modifier
onlyOwner
for the methods that you want to be protected. Ex: