在部署时将智能合约链接在一起
Linking together smart contracts at deployment
我正在构建一个由 3 个智能合约组成的应用程序。目的是让控制器控制另外两个(图中的合约 A 和 B)。以前,如果我想限制对智能联系人的访问,我会通过修饰符来实现
示例:
modifier onlyController {
require(msg.sender == controller);
_;
}
在创建联系人时,智能合约会将控制器设置为等于我想要进行这些调用的任何以太坊地址(例如部署智能合约的地址)。问题是现在我希望控制器智能合约的地址成为控制器(在修饰符中)。考虑到我想使用松露同时部署这些智能联系人集,最好怎么做。 link 这些的最佳方法是什么,以便控制器智能合约只能调用 A 和 B。此外,必须如何实现控制器才能让用户调用 A 中的函数和B通过控制器(所以用户调用控制器中的函数,然后控制器调用A或B中的相应函数)?
你不能轻松地将控制器合约设置为
contract ControllerContract is ContractA, ContractB {
...
}
从而让它同时访问合约A和合约B中的函数?
我不确定为什么这种方式会比您描述的更糟糕。
我不是 Solidity 方面的专家。但试着回答,因为我觉得它有点有趣。
您似乎在尝试实现 proxy pattern
,这在 java
等其他编程语言中很常见,但您提供对某些 class 的非常有限的访问权限es 在这种情况下 contracts
.
在代理设计模式中,代理和要限制的 class 将实现相同的接口!我不太了解你的智能合约细节。
假设合约A和B实现相同的接口:
假设接口是 Base。
interface Base{
function getValue() external view returns (string);
}
我需要提供对 ContractA
和 ContractB
的受控访问,以便只有控制器可以调用。因此,让我们创建一个修饰符。
contract ControlledAccess{
address controller;
constructor() public {
controller = msg.sender;
}
modifier onlyController() {
require(msg.sender == controller);
_;
}
}
现在 ContractA
和 ContractB
应该实现接口 Base
并继承 ControlledAccess
契约。
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";
}
}
为了将控制器地址设置为 ProxyController
地址,ProxyController 本身应该在其构造函数中创建这些契约。由于我们的ProxyController
合约应该可以控制超过1个合约,我认为mapping
可能是一个不错的选择。
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();
}
}
因此您可以通过 setContractKey
.
切换到 A 和 B
假设 A 和 B 之间没有共同的功能:
删除上面的接口example.Then实现类似这样的东西。
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();
}
}
我对此进行了测试,它似乎工作正常。但是我不确定性能等其他问题
您可以在以下 link 处找到一些解决方案:
1.) https://ethereum.stackexchange.com/questions/36524/multiple-smart-contracts
关于智能合约与 Solidity 之间的交互的完整文章:
https://zupzup.org/smart-contract-interaction/
A link另一篇文章和示例项目:https://hackernoon.com/ethereum-smart-contracts-lifecycle-multiple-contracts-message-sender-e9195ceff3ec
希望它能解决您的问题。此外,您还可以加入此社区以获得排他性:https://ethereum.stackexchange.com/
modifier onlyController {
require(msg.sender == controller);
_;
}
在创建联系人时,智能合约会将控制器设置为等于我想要进行这些调用的任何以太坊地址(例如部署智能合约的地址)。问题是现在我希望控制器智能合约的地址成为控制器(在修饰符中)。考虑到我想使用松露同时部署这些智能联系人集,最好怎么做。 link 这些的最佳方法是什么,以便控制器智能合约只能调用 A 和 B。此外,必须如何实现控制器才能让用户调用 A 中的函数和B通过控制器(所以用户调用控制器中的函数,然后控制器调用A或B中的相应函数)?
你不能轻松地将控制器合约设置为
contract ControllerContract is ContractA, ContractB {
...
}
从而让它同时访问合约A和合约B中的函数?
我不确定为什么这种方式会比您描述的更糟糕。
我不是 Solidity 方面的专家。但试着回答,因为我觉得它有点有趣。
您似乎在尝试实现 proxy pattern
,这在 java
等其他编程语言中很常见,但您提供对某些 class 的非常有限的访问权限es 在这种情况下 contracts
.
在代理设计模式中,代理和要限制的 class 将实现相同的接口!我不太了解你的智能合约细节。
假设合约A和B实现相同的接口:
假设接口是 Base。
interface Base{
function getValue() external view returns (string);
}
我需要提供对 ContractA
和 ContractB
的受控访问,以便只有控制器可以调用。因此,让我们创建一个修饰符。
contract ControlledAccess{
address controller;
constructor() public {
controller = msg.sender;
}
modifier onlyController() {
require(msg.sender == controller);
_;
}
}
现在 ContractA
和 ContractB
应该实现接口 Base
并继承 ControlledAccess
契约。
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";
}
}
为了将控制器地址设置为 ProxyController
地址,ProxyController 本身应该在其构造函数中创建这些契约。由于我们的ProxyController
合约应该可以控制超过1个合约,我认为mapping
可能是一个不错的选择。
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();
}
}
因此您可以通过 setContractKey
.
假设 A 和 B 之间没有共同的功能:
删除上面的接口example.Then实现类似这样的东西。
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();
}
}
我对此进行了测试,它似乎工作正常。但是我不确定性能等其他问题
您可以在以下 link 处找到一些解决方案:
1.) https://ethereum.stackexchange.com/questions/36524/multiple-smart-contracts
关于智能合约与 Solidity 之间的交互的完整文章:
https://zupzup.org/smart-contract-interaction/
A link另一篇文章和示例项目:https://hackernoon.com/ethereum-smart-contracts-lifecycle-multiple-contracts-message-sender-e9195ceff3ec
希望它能解决您的问题。此外,您还可以加入此社区以获得排他性:https://ethereum.stackexchange.com/