From 705e6430ca30353ed0526a84651db66bf29bbd66 Mon Sep 17 00:00:00 2001 From: Chris Whinfrey Date: Sun, 18 Feb 2018 19:34:31 -0500 Subject: [PATCH 1/2] Add delegated storage contracts --- contracts/Coordinator/Coordinator.sol | 61 +++++++++++++++ .../CoordinatorStorageDelegate.sol | 76 +++++++++++++++++++ .../DelegatedStorage/DelegatedStorage.sol | 21 +++++ .../DelegatedStorage/KeyManagerInterface.sol | 5 ++ .../DelegatedStorage/UpgradableContract.sol | 13 ++++ contracts/Proxy/DelegateManagable.sol | 17 +++++ contracts/Proxy/DelegateManagerInterface.sol | 5 ++ contracts/StorageConsumer/BasicStorage.sol | 9 +++ 8 files changed, 207 insertions(+) create mode 100644 contracts/Coordinator/Coordinator.sol create mode 100644 contracts/Coordinator/CoordinatorStorageDelegate.sol create mode 100644 contracts/DelegatedStorage/DelegatedStorage.sol create mode 100644 contracts/DelegatedStorage/KeyManagerInterface.sol create mode 100644 contracts/DelegatedStorage/UpgradableContract.sol create mode 100644 contracts/Proxy/DelegateManagable.sol create mode 100644 contracts/Proxy/DelegateManagerInterface.sol create mode 100644 contracts/StorageConsumer/BasicStorage.sol diff --git a/contracts/Coordinator/Coordinator.sol b/contracts/Coordinator/Coordinator.sol new file mode 100644 index 0000000..8750938 --- /dev/null +++ b/contracts/Coordinator/Coordinator.sol @@ -0,0 +1,61 @@ +pragma solidity ^0.4.18; + +import '../DelegatedStorage/DelegatedStorage.sol'; +import '../DelegatedStorage/KeyManagerInterface.sol'; +import '../Proxy/DelegateManagerInterface.sol'; +import 'zeppelin-solidity/contracts/ownership/Ownable.sol'; +import './CoordinatorStorageDelegate.sol'; + +contract Coordinator is KeyManagerInterface, DelegateManagerInterface, Ownable { + + CoordinatorStorageDelegate public _storage; + CoordinatorStorageDelegate public delegate; + + function Coordinator(address coordinatorStorageDelegate) public { + _storage = CoordinatorStorageDelegate(new DelegatedStorage(this, this)); + delegate = CoordinatorStorageDelegate(coordinatorStorageDelegate); + } + + function setContract(string _key, address _contract) public onlyOwner { + _storage.setRegisteredContract(keccak256(_key), _contract); + _storage.setRegisteredContractKey(_contract, keccak256(_key)); + } + + function removeContract(string _key) public onlyOwner { + _storage.deleteRegisteredContract(keccak256(_key)); + } + + function setStorageDelegate(string _key, address _delegate) public onlyOwner { + _storage.setRegisteredStorageDelegate(keccak256(_key), _delegate); + } + + function setDelegate(string _key, address _delegate) public onlyOwner { + _storage.setRegisteredDelegate(keccak256(_key), _delegate); + } + + // KeyManagerInterface + function keyForContract(address _contract) public view returns (bytes32) { + if (_contract == address(this)) + return keccak256("Coordinator"); + return _storage.getRegisteredContractKey(_contract); + } + + // DelegateManagerInterface + function delegateForContract(address _contract) public view returns (address) { + if (msg.sender == address(_storage)) { + return getRegisteredStorageDelegate(_contract); + } else { + return getRegisteredDelegate(_contract); + } + } + + function getRegisteredStorageDelegate(address _contract) private view returns (address) { + if (_contract == address(this)) + return delegate; + return _storage.getRegisteredStorageDelegate(keyForContract(_contract)); + } + + function getRegisteredDelegate(address _contract) private view returns (address) { + return _storage.getRegisteredDelegate(keyForContract(msg.sender)); + } +} diff --git a/contracts/Coordinator/CoordinatorStorageDelegate.sol b/contracts/Coordinator/CoordinatorStorageDelegate.sol new file mode 100644 index 0000000..7940eeb --- /dev/null +++ b/contracts/Coordinator/CoordinatorStorageDelegate.sol @@ -0,0 +1,76 @@ +pragma solidity ^0.4.18; + +import '../Storage/BaseStorage.sol'; + +contract CoordinatorStorageDelegate is BaseStorage { + + /**** Get Methods ***********/ + + /// @param key The key for the record + function getRegisteredContract(bytes32 key) public view returns (address) { + return getAddress(keccak256("registeredContracts", key)); + } + + /// @param _contract The address of the contract + function getRegisteredContractKey(address _contract) public view returns (bytes32) { + return getBytes32(keccak256("registeredContractKeys", _contract)); + } + + /// @param key The key for the record + function getRegisteredStorageDelegate(bytes32 key) public view returns (address) { + return getAddress(keccak256("registeredStorageDelegates", key)); + } + + /// @param key The key for the record + function getRegisteredDelegate(bytes32 key) public view returns (address) { + return getAddress(keccak256("registeredDelegates", key)); + } + + /**** Set Methods ***********/ + + /// @param key The key for the record + /// @param _contract The address of the contract + function setRegisteredContract(bytes32 key, address _contract) public { + setAddress(keccak256("registeredContracts", key), _contract); + } + + /// @param _contract The address of the contract + /// @param key The key for the record + function setRegisteredContractKey(address _contract, bytes32 key) public { + setBytes32(keccak256("registeredContractKeys", _contract), key); + } + + /// @param key The key for the record + /// @param delegate The delegate for the contract key + function setRegisteredStorageDelegate(bytes32 key, address delegate) public { + setAddress(keccak256("registeredStorageDelegates", key), delegate); + } + + /// @param key The key for the record + /// @param delegate The delegate for the contract key + function setRegisteredDelegate(bytes32 key, address delegate) public { + setAddress(keccak256("registeredDelegates", key), delegate); + } + + /**** Delete Methods ***********/ + + /// @param key The key for the record + function deleteRegisteredContract(bytes32 key) public { + deleteAddress(keccak256("registeredContracts", key)); + } + + /// @param _contract The address of the contract + function deleteRegisteredContractKey(address _contract) public { + deleteBytes32(keccak256("registeredContractKeys", _contract)); + } + + /// @param key The key for the record + function deleteRegisteredStorageDelegate(bytes32 key) public { + deleteAddress(keccak256("registeredStorageDelegates", key)); + } + + /// @param key The key for the record + function deleteRegisteredDelegate(bytes32 key) public { + deleteAddress(keccak256("registeredDelegates", key)); + } +} diff --git a/contracts/DelegatedStorage/DelegatedStorage.sol b/contracts/DelegatedStorage/DelegatedStorage.sol new file mode 100644 index 0000000..f9894d5 --- /dev/null +++ b/contracts/DelegatedStorage/DelegatedStorage.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.4.18; + +import '../Storage/BaseStorage.sol'; +import '../Proxy/DelegateManagerInterface.sol'; +import '../Proxy/DelegateManagable.sol'; +import './KeyManagerInterface.sol'; + +contract DelegatedStorage is BaseStorage, DelegateManagable { + + KeyManagerInterface keyManager; + + function DelegatedStorage(KeyManagerInterface _keyManager, DelegateManagerInterface _delegateManager) public + DelegateManagable(_delegateManager) + { + keyManager = _keyManager; + } + + function scopedKey(bytes32 _key) internal view returns(bytes32) { + return keccak256(keyManager.keyForContract(msg.sender), _key); + } +} diff --git a/contracts/DelegatedStorage/KeyManagerInterface.sol b/contracts/DelegatedStorage/KeyManagerInterface.sol new file mode 100644 index 0000000..4990161 --- /dev/null +++ b/contracts/DelegatedStorage/KeyManagerInterface.sol @@ -0,0 +1,5 @@ +pragma solidity ^0.4.18; + +contract KeyManagerInterface { + function keyForContract(address _contract) public view returns (bytes32 key); +} diff --git a/contracts/DelegatedStorage/UpgradableContract.sol b/contracts/DelegatedStorage/UpgradableContract.sol new file mode 100644 index 0000000..c2576c2 --- /dev/null +++ b/contracts/DelegatedStorage/UpgradableContract.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.18; + +import '../Proxy/DelegateManagable.sol'; +import '../Proxy/DelegateManagerInterface.sol'; +import '../StorageConsumer/BasicStorage.sol'; + +contract UpgradableContract is BasicStorage, DelegateManagable { + + function UpgradableContract(address storageAddress, DelegateManagerInterface delegateManager) public + BasicStorage(storageAddress) + DelegateManagable(delegateManager) + { } +} diff --git a/contracts/Proxy/DelegateManagable.sol b/contracts/Proxy/DelegateManagable.sol new file mode 100644 index 0000000..e5d0bb4 --- /dev/null +++ b/contracts/Proxy/DelegateManagable.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.4.18; + +import './BaseProxy.sol'; +import './DelegateManagerInterface.sol'; + +contract DelegateManagable is BaseProxy { + DelegateManagerInterface delegateManager; + + function DelegateManagable(DelegateManagerInterface _delegateManager) public { + delegateManager = _delegateManager; + } + + // Overrides implementation() in BaseProxy.sol + function implementation() public view returns (address) { + return delegateManager.delegateForContract(msg.sender); + } +} diff --git a/contracts/Proxy/DelegateManagerInterface.sol b/contracts/Proxy/DelegateManagerInterface.sol new file mode 100644 index 0000000..5024edd --- /dev/null +++ b/contracts/Proxy/DelegateManagerInterface.sol @@ -0,0 +1,5 @@ +pragma solidity ^0.4.18; + +contract DelegateManagerInterface { + function delegateForContract(address _contract) public view returns (address delegate); +} diff --git a/contracts/StorageConsumer/BasicStorage.sol b/contracts/StorageConsumer/BasicStorage.sol new file mode 100644 index 0000000..1926693 --- /dev/null +++ b/contracts/StorageConsumer/BasicStorage.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.4.18; + +contract BasicStorage { + address public _storage; + + function BasicStorage(address storageAddress) public { + _storage = storageAddress; + } +} From 67f299db39d3ab1621b3971e58518f27e5309ef9 Mon Sep 17 00:00:00 2001 From: Chris Whinfrey Date: Sun, 18 Feb 2018 20:16:18 -0500 Subject: [PATCH 2/2] Separate out delegate functions --- contracts/Coordinator/Coordinator.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/Coordinator/Coordinator.sol b/contracts/Coordinator/Coordinator.sol index 8750938..50b12c6 100644 --- a/contracts/Coordinator/Coordinator.sol +++ b/contracts/Coordinator/Coordinator.sol @@ -49,6 +49,8 @@ contract Coordinator is KeyManagerInterface, DelegateManagerInterface, Ownable { } } + /* Private functions */ + function getRegisteredStorageDelegate(address _contract) private view returns (address) { if (_contract == address(this)) return delegate;