我正在构建一个包含3个智能合约的应用程序。目的是让控制器控制其他两个(图像中的合同A和B)。以前,如果我想限制对智能联系人的访问,则可以通过修饰符来实现
例:
modifier onlyController {
require(msg.sender == controller);
_;
}
在创建联系人时,智能合约会将控制器设置为等于我要进行这些调用的任何以太坊地址(例如,部署智能合约的地址)。问题在于,现在我希望控制器智能合约的地址成为控制器(在修饰符中)。考虑到我想使用松露同时部署这些智能联系人集,如何最好地做到这一点。链接它们的最佳方式是什么,以便控制器智能合约只能对A和B进行调用。此外,必须如何实现控制器,以便用户可以在A和B中调用函数控制器(因此用户先在控制器中调用一个函数,然后控制器在A或B中调用相应的函数)?
最佳答案
我不是Solidity方面的专家。但是尝试回答,因为我发现它有点有趣。
您似乎正在尝试实现proxy pattern
,这种方式在诸如java
的其他编程语言中非常常见,因此您在这种情况下提供了对某些类的非常受限的访问。
在代理设计模式中,代理和要限制的类都将实现相同的接口!我对您的智能合约详细信息了解不多。
假设合同A和B实现相同的接口:
假设接口为Base。
interface Base{
function getValue() external view returns (string);
}
我需要提供对
contracts
和ContractA
的受控访问,以便只有控制器可以调用。因此,让我们创建一个修饰符。contract ControlledAccess{
address controller;
constructor() public {
controller = msg.sender;
}
modifier onlyController() {
require(msg.sender == controller);
_;
}
}
现在,
ContractB
和ContractA
应该实现接口ContractB
并继承Base
合同。contract ContractA is Base, ControlledAccess{
function getValue() public view onlyController returns (string){
return "Hi";
}
}
contract ContractB is Base, ControlledAccess{
function getValue() public view onlyController returns (string){
return "Hello";
}
}
为了将控制器地址设置为
ControlledAccess
地址,ProxyController本身应在其构造函数中创建这些协定。由于我们的ProxyController
合同应该能够控制多个合同,因此我认为ProxyController
可能是一个不错的选择。contract ProxyController is Base{
string public contractKey = "a";
mapping(string => Base) base;
constructor() public {
base["a"]=new ContractA();
base["b"]=new ContractB();
}
function setContractKey(string _contractKey) public{
contractKey = _contractKey;
}
function getValue() public view returns (string){
return base[contractKey].getValue();
}
}
因此您可以通过
mapping
切换到A和B。假设A和B之间没有共同的功能:
删除上面示例中的接口,然后实现类似这样的操作。
contract ProxyController{
ContractA a;
ContractB b;
constructor() public {
a=new ContractA();
b=new ContractB();
}
function AgetValue() public view returns (string){
return a.getValue();
}
function BgetValue() public view returns (string){
return b.getValue();
}
}
我对此进行了测试,看来效果很好。但是我不确定性能等其他问题。
关于ethereum - 在部署时将智能合约链接在一起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50819979/