Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save drandreaskrueger/ae3027daa95492465f4c37940de40de7 to your computer and use it in GitHub Desktop.
Save drandreaskrueger/ae3027daa95492465f4c37940de40de7 to your computer and use it in GitHub Desktop.
ordered concatenation of all 20 solidity contracts at https://github.com/energywebfoundation/ew-origin/tree/master/contracts on 2018 September 11th (Latest commit b724754 on Jul 31)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ordered concatenation of all 20 solidity contracts at
// https://github.com/energywebfoundation/ew-origin/tree/master/contracts
// on 2018 September 11th (Latest commit b724754 on Jul 31)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Simon Jentzsch, simon.jentzsch@slock.it
contract Owned {
/// @dev `owner` is the only address that can call a function with this
modifier onlyOwner { require (msg.sender == owner); _; }
event LogChangeOwner(address _newOwner);
address public owner;
/// @notice The Constructor assigns the message sender to be `owner`
function Owned(address _initOwner) public { owner = _initOwner;}
/// @notice `owner` can step down and assign some other address to this role
/// @param _newOwner The address of the new owner. 0x0 can be used to create
function changeOwner (address _newOwner) public onlyOwner {
require(_newOwner != address(0));
owner = _newOwner;
LogChangeOwner(_newOwner);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title this contracts provides those functions that both consuming and producing assets share
contract AssetGeneralDefinition is Owned {
struct GeneralInformation {
address smartMeter;
address owner;
uint operationalSince;
uint lastSmartMeterReadWh;
bool active;
bytes32 lastSmartMeterReadFileHash;
uint lastMeterReadReceived;
bool exists;
}
/// @notice function to set all the location Informations for an asset, gets called internally
/// @param _loc the storage location of the location informations
/// @param _country The country where the asset is located
/// @param _region The region / state where the asset is located
/// @param _zip The zip-code of the region where the asset is located
/// @param _city The city where the asset is located
/// @param _street The streetname where the asset is located
/// @param _houseNumber the housenumber where the asset is located
/// @param _gpsLatitude The gps-latitude
/// @param _gpsLongitude The gps-longitude
function initLocationInternal(
LocationDefinition.Location storage _loc,
bytes32 _country,
bytes32 _region,
bytes32 _zip,
bytes32 _city,
bytes32 _street,
bytes32 _houseNumber,
bytes32 _gpsLatitude,
bytes32 _gpsLongitude
)
internal
{
_loc.country = _country;
_loc.region = _region;
_loc.zip = _zip;
_loc.city = _city;
_loc.street = _street;
_loc.houseNumber = _houseNumber;
_loc.gpsLatitude = _gpsLatitude;
_loc.gpsLongitude = _gpsLongitude;
_loc.exists = true;
}
/// @notice internal function to set the general information
/// @param _gi storage location of the general information
/// @param _smartMeter smartMeter-address
/// @param _owner owner-of the asset
/// @param _operationalSince operatinal since that timestamp
/// @param _lastSmartMeterReadWh the last meterreading in Wh
/// @param _active flag if the asset is active
/// @param _lastSmartMeterReadFileHash the last filehash
function setGeneralInformationInternal(
GeneralInformation storage _gi,
address _smartMeter,
address _owner,
uint _operationalSince,
uint _lastSmartMeterReadWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
internal
{
_gi.smartMeter = _smartMeter;
_gi.owner = _owner;
_gi.operationalSince = _operationalSince;
_gi.lastSmartMeterReadWh = _lastSmartMeterReadWh;
_gi.active = _active;
_gi.lastSmartMeterReadFileHash = _lastSmartMeterReadFileHash;
_gi.lastMeterReadReceived = 0;
_gi.exists = true;
}
/// @notice function to get the informations about the location of a struct
/// @param _loc storage location of the locationInformations
/// @return country, region, zip, city, street, houseNumber, gpsLatitude, gpsLongitude
function getAssetLocationInternal(LocationDefinition.Location memory _loc)
internal
pure
returns(
bytes32 country,
bytes32 region,
bytes32 zip,
bytes32 city,
bytes32 street,
bytes32 houseNumber,
bytes32 gpsLatitude,
bytes32 gpsLongitude
)
{
country = _loc.country;
region = _loc.region;
zip = _loc.zip;
city = _loc.city;
street = _loc.street;
houseNumber = _loc.houseNumber;
gpsLatitude = _loc.gpsLatitude;
gpsLongitude = _loc.gpsLongitude;
return (country, region, zip, city, street, houseNumber, gpsLatitude, gpsLongitude);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title this interface defines the functions that both consuming and producing assets are sharing
interface AssetDbInterface {
function getActive(uint _assetId) external view returns(bool);
function getExistStatus(uint _assetId) external view returns (bool general, bool location, bool asset);
function createAsset() external returns (uint);
function initLocation(uint _assetId, bytes32 _country, bytes32 _region, bytes32 _zip, bytes32 _city, bytes32 _street, bytes32 _houseNumber, bytes32 _gpsLatitude, bytes32 _gpsLongitude) external;
function setActive(uint _assetId, bool _active) external;
function setAssetExistStatus(uint _assetId, bool _exist) external;
function setCapacityWh(uint _assetId, uint _capacityWh) external;
function setLastSmartMeterReadDate(uint _assetId, uint _timestamp) external;
function setLastSmartMeterReadFileHash(uint _assetId, bytes32 _lastSmartMeterReadFileHash) external;
function setSmartMeter(uint _assetId, address _smartMeter) external;
function getAssetListLength() external view returns (uint);
function getAssetLocation(uint _assetId) external view returns(bytes32 country, bytes32 region, bytes32 zip, bytes32 city, bytes32 street, bytes32 houseNumber, bytes32 gpsLatitude, bytes32 gpsLongitude);
function getLastSmartMeterRead(uint _assetId) external returns (uint);
function getLastSmartMeterReadDate(uint _assetId) external returns(uint);
function getLastSmartMeterReadFileHash(uint _assetId) external view returns(bytes32);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
//
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuechler@slock.it
pragma solidity ^0.4.18;
/// @title The Database contract for the Asset Registration
/// @notice This contract only provides getter and setter methods
contract AssetConsumingRegistryDB is Owned, AssetGeneralDefinition, AssetDbInterface {
struct ConsumingProperties {
uint capacityWh;
bool maxCapacitySet;
uint certificatesUsedForWh;
}
struct Asset {
GeneralInformation general;
ConsumingProperties consumingProps;
LocationDefinition.Location location;
bool exists;
}
/// @notice An array containing all registerd assets
Asset[] private assets;
/// @dev empty structs for initializing, used to avoid compile warnings
GeneralInformation generalEmpty;
LocationDefinition.Location locationEmpty;
ConsumingProperties consumingEmpty;
/// @notice Constructor
/// @param _owner The owner of the contract
function AssetConsumingRegistryDB(address _owner)
public
Owned(_owner)
{
}
/// @notice function to create a new empty asset
/// @return returns the array-position and thus the index / identifier of this new asset
function createAsset()
external
onlyOwner
returns (uint _assetId)
{
_assetId = assets.length;
assets.push(AssetConsumingRegistryDB.Asset({
general: generalEmpty,
consumingProps: consumingEmpty,
location: locationEmpty,
exists: false
}));
}
/// @notice Sets the general information for an asset
/// @param _assetId The index / identifier for that asset
/// @param _smartMeter The address of the smart meter
/// @param _owner The address of the asset owner
/// @param _operationalSince The timestamp since the asset is operational
/// @param _capacityWh The capacity in Wh of the asset
/// @param _lastSmartMeterReadWh The smart meter read in Wh
/// @param _certificatesUsedForWh The amount of Wh used to issue certificates
/// @param _active true if active
/// @param _lastSmartMeterReadFileHash The last meter read file hash
function initGeneral (
uint _assetId,
address _smartMeter,
address _owner,
uint _operationalSince,
uint _capacityWh,
bool _maxCapacitySet,
uint _lastSmartMeterReadWh,
uint _certificatesUsedForWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
onlyOwner
external
{
Asset storage a = assets[_assetId];
GeneralInformation storage gi = a.general; // just want to doublecheck, gi is a pointer to the storage, right?
ConsumingProperties storage cp = a.consumingProps;
setGeneralInformationInternal(gi, _smartMeter, _owner, _operationalSince,_lastSmartMeterReadWh, _active, _lastSmartMeterReadFileHash);
cp.certificatesUsedForWh = _certificatesUsedForWh;
cp.capacityWh = _capacityWh;
cp.maxCapacitySet = _maxCapacitySet;
}
/// @notice function to set all the location Informations for an asset
/// @param _assetId The identifier / index of an asset
/// @param _country The country where the asset is located
/// @param _region The region / state where the asset is located
/// @param _zip The zip-code of the region where the asset is located
/// @param _city The city where the asset is located
/// @param _street The streetname where the asset is located
/// @param _houseNumber the housenumber where the asset is located
/// @param _gpsLatitude The gps-latitude
/// @param _gpsLongitude The gps-longitude
function initLocation(
uint _assetId,
bytes32 _country,
bytes32 _region,
bytes32 _zip,
bytes32 _city,
bytes32 _street,
bytes32 _houseNumber,
bytes32 _gpsLatitude,
bytes32 _gpsLongitude
)
onlyOwner
external
{
LocationDefinition.Location storage loc = assets[_assetId].location;
initLocationInternal(loc, _country, _region, _zip, _city, _street, _houseNumber, _gpsLatitude, _gpsLongitude);
}
/// @notice Sets if an entry in the asset registry is active
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _active true if active
function setActive(uint _assetId, bool _active)
onlyOwner
external
{
assets[_assetId].general.active = _active;
}
/// @notice function to set the existing status of an asset
/// @param _assetId The index position / identifier of an asset
/// @param _exist flag if the asset should exist
function setAssetExistStatus(uint _assetId, bool _exist)
external
onlyOwner
{
assets[_assetId].exists = _exist;
}
/// @notice Sets the capacity in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _capacityWh The capacity in Wh
function setCapacityWh(uint _assetId, uint _capacityWh)
onlyOwner
external
{
assets[_assetId].consumingProps.capacityWh = _capacityWh;
}
/// @notice Sets amount of Wh used to issue certificates belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _certificatesUsedForWh The amount of Wh used to issue certificates
function setCertificatesUsedForWh(uint _assetId, uint _certificatesUsedForWh)
onlyOwner
external
{
assets[_assetId].consumingProps.certificatesUsedForWh = _certificatesUsedForWh;
}
/// @notice Sets a timestamp for the last meterreading
/// @param _assetId the id belonging to an entry in the asset registry
/// @param _timestamp new UNIX-timestamp
function setLastSmartMeterReadDate(uint _assetId, uint _timestamp)
onlyOwner
external
{
assets[_assetId].general.lastMeterReadReceived = _timestamp;
}
/// @notice Sets last meter read file hash
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _lastSmartMeterReadFileHash Last meter read file hash
function setLastSmartMeterReadFileHash(uint _assetId, bytes32 _lastSmartMeterReadFileHash)
onlyOwner
external
{
assets[_assetId].general.lastSmartMeterReadFileHash = _lastSmartMeterReadFileHash;
}
/// @notice Sets the last smart meter read in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _lastSmartMeterReadWh The smart meter read in Wh
function setLastSmartMeterReadWh(uint _assetId, uint _lastSmartMeterReadWh)
onlyOwner
external
{
assets[_assetId].general.lastSmartMeterReadWh = _lastSmartMeterReadWh;
}
/// @notice Sets the location-country of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @param _country the new country
function setLocationCountry(uint _assetId, bytes32 _country)
onlyOwner
external
{
assets[_assetId].location.country = _country;
}
/// @notice Sets the location-region of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @param _region the new region
function setLocationRegion(uint _assetId, bytes32 _region)
onlyOwner
external
{
assets[_assetId].location.region = _region;
}
/// @notice Sets the operational since field of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _operationalSince The timestamp since the asset is operational
function setOperationalSince(uint _assetId, uint _operationalSince)
onlyOwner
external
{
assets[_assetId].general.operationalSince = _operationalSince;
}
/// @notice Sets the owner of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _owner The new owner
function setOwner(uint _assetId, address _owner)
onlyOwner
external
{
assets[_assetId].general.owner = _owner;
}
/// @notice Sets the smart meter address belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _smartMeter The new smart meter address
function setSmartMeter(uint _assetId, address _smartMeter)
onlyOwner
external
{
assets[_assetId].general.smartMeter = _smartMeter;
}
/// @notice Sets multiple information of a meterreading
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _newMeterRead the new meterreading
/// @param _lastSmartMeterReadFileHash the filehash belonging to that reading
/// @param _timestamp the timestamp of that reading
function setSmartMeterReadData(uint _assetId, uint _newMeterRead, bytes32 _lastSmartMeterReadFileHash, uint _timestamp)
onlyOwner
external
{
assets[_assetId].general.lastSmartMeterReadWh = _newMeterRead;
assets[_assetId].general.lastSmartMeterReadFileHash = _lastSmartMeterReadFileHash;
assets[_assetId].general.lastMeterReadReceived = _timestamp;
}
/// @notice Gets if an entry in the asset registry is active
/// @param _assetId The id belonging to an entry in the asset registry
/// @return true if asset is active
function getActive(uint _assetId)
onlyOwner
external
view
returns(bool)
{
return assets[_assetId].general.active;
}
/// @notice Gets the general information of an asset
/// @param _assetId The id belonging to an entry in the asset registry
/// @return general information of an asset
function getAssetGeneral(uint _assetId)
onlyOwner
external
view
returns(
address _smartMeter,
address _owner,
uint _operationalSince,
uint _capacityWh,
bool _maxCapacitySet,
uint _lastSmartMeterReadWh,
uint _certificatesUsedForWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
{
Asset storage asset = assets[_assetId];
GeneralInformation memory gi = asset.general;
ConsumingProperties memory cp = asset.consumingProps;
_smartMeter = gi.smartMeter;
_owner = gi.owner;
_operationalSince = gi.operationalSince;
_capacityWh = cp.capacityWh;
_maxCapacitySet = cp.maxCapacitySet;
_lastSmartMeterReadWh = gi.lastSmartMeterReadWh;
_certificatesUsedForWh = cp.certificatesUsedForWh;
_active = gi.active;
_lastSmartMeterReadFileHash = gi.lastSmartMeterReadFileHash;
}
/// @notice function to get the amount of assets
/// @return amount of assets
function getAssetListLength()
onlyOwner
external
view
returns (uint)
{
return assets.length;
}
/// @notice function to get the informations about the location of a struct
/// @param _assetId The id belonging to an entry in the asset registry
/// @return country, region, zip, city, street, houseNumber, gpsLatitude, gpsLongitude
function getAssetLocation(uint _assetId)
onlyOwner
external
view
returns(
bytes32 country,
bytes32 region,
bytes32 zip,
bytes32 city,
bytes32 street,
bytes32 houseNumber,
bytes32 gpsLatitude,
bytes32 gpsLongitude
)
{
LocationDefinition.Location memory loc = assets[_assetId].location;
return getAssetLocationInternal(loc);
}
/// @notice Gets the capacity in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the capacity in Wh
function getCapacityWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].consumingProps.capacityWh;
}
/// @notice Gets amount of Wh used to issue certificates belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the amount of Wh used to issue certificates
function getCertificatesUsedForWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].consumingProps.certificatesUsedForWh;
}
/// @notice gets the consuming properties of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return the consuming properteis
function getConsumingProperies(uint _assetId)
onlyOwner
external
view
returns (
uint _capacityWh,
bool _maxCapacitySet,
uint _certificatesUsedForWh
)
{
ConsumingProperties memory c = assets[_assetId].consumingProps;
_capacityWh = c.capacityWh;
_maxCapacitySet = c.maxCapacitySet;
_certificatesUsedForWh = c.certificatesUsedForWh;
}
/// @notice function the retrieve the existing status of the general information, the location information and the asset itself
/// @param _assetId The index position / identifier of the asset
/// @return existing status of the general informaiton, existing status of the location informaiton and where the asset-structs exists
function getExistStatus(uint _assetId)
onlyOwner
external
view
returns (bool general, bool location, bool asset)
{
Asset memory a = assets[_assetId];
return(a.general.exists, a.location.exists, a.exists);
}
/// @notice function to retrieve the last smartmeter-reading of an asset
/// @param _assetId the asset-id
/// @return the last smartmeter-reading
function getLastSmartMeterRead(uint _assetId)
onlyOwner
external
returns (uint)
{
return assets[_assetId].general.lastSmartMeterReadWh;
}
/// @notice function to retrieve the timestamp of the last smartmeter-reading
/// @param _assetId the asset-id
/// @return the timestamp of the last smartmeter-reading
function getLastSmartMeterReadDate(uint _assetId)
onlyOwner
external
returns(uint)
{
return assets[_assetId].general.lastMeterReadReceived;
}
/// @notice Gets last smart merter read file hash
/// @param _assetId The id belonging to an entry in the asset registry
/// @return last smart merter read file hash
function getLastSmartMeterReadFileHash(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].general.lastSmartMeterReadFileHash;
}
/// @notice Gets the last smart merter read in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the last loged smart meter read in Wh
function getLastSmartMeterReadWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].general.lastSmartMeterReadWh;
}
/// @notice Gets the location country of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return country where the asset is based
function getLocationCountry(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].location.country;
}
/// @notice Gets the location region of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return region of the country where the asset is based
function getLocationRegion(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].location.region;
}
/// @notice Gets the operational since field of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return date when the asset went into production
function getOperationalSince(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].general.operationalSince;
}
/// @notice Gets the owner of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the owner address
function getOwner(uint _assetId)
onlyOwner
external
view
returns(address)
{
return assets[_assetId].general.owner;
}
/// @notice Gets the smart meter address belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the smart meter address
function getSmartMeter(uint _assetId)
onlyOwner
external
view
returns(address)
{
return assets[_assetId].general.smartMeter;
}
}// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuechler@slock.it
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @notice contract for managing the rights and roles
contract RoleManagement {
/// @notice central registry contract
CoO public cooContract;
/// @notice all possible available roles
/*
no role: 0x0...0000000
TopAdmin: 0x0...------1
UserAdmin: 0x0...-----1-
AssetAdmin: 0x0...----1--
AgreementAdmin: 0x0...---1---
AssetManager: 0x0...--1----
Trader: 0x0...-1-----
Matcher: 0x0...1-----
*/
enum Role{
TopAdmin,
UserAdmin,
AssetAdmin,
AgreementAdmin,
AssetManager,
Trader,
Matcher
}
/// @notice modifier for checking if an user is allowed to execute the intended action
modifier onlyRole (RoleManagement.Role _role) {
require (isRole(_role, msg.sender));
_;
}
modifier onlyAccount(address accountAddress) {
require(msg.sender == accountAddress);
_;
}
modifier userExists(address _user){
require(RolesInterface(cooContract.userRegistry()).doesUserExist(_user));
_;
}
modifier userHasRole(RoleManagement.Role _role, address _user){
require (isRole(_role, _user));
_;
}
/// @notice constructor
/// @param _cooContract CoO.sol-registry contract
function RoleManagement (CoO _cooContract) public {
cooContract = _cooContract;
}
/// @notice funciton for comparing the role and the needed rights of an user
/// @param _role role of a user
/// @param _caller the address calling that function
/// @return whether the user has the corresponding rights for the intended action
function isRole(RoleManagement.Role _role, address _caller) public view returns (bool) {
require(uint(_role) <= 7);
if (cooContract.owner() == _caller) {
return true;
}
/// @dev reading the rights for the user from the userDB-contract
uint rights = RolesInterface(cooContract.userRegistry()).getRolesRights(_caller);
/// @dev converting the used enum to the corresponding bitmask
uint role = uint(2) ** uint(_role);
/// @dev comparing rights and roles, if the result is not 0 the user has the right (bitwise comparison)
/// we also don't have to check for a potential overflow here, because the used enum will prevent using roles that do not exist
return (rights & role != 0);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title this interface defines the required update-function that every updatable-contract has to implement
interface Updatable {
function update(address _newLogic) external;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title Contract for storing the current logic-contracts-addresses for the certificate of origin
contract AssetLogic is RoleManagement, Updatable {
event LogAssetCreated(address sender, uint indexed _assetId);
event LogAssetFullyInitialized(uint indexed _assetId);
event LogAssetSetActive(uint indexed _assetId);
event LogAssetSetInactive(uint indexed _assetId);
AssetDbInterface public db;
modifier isInitialized {
require(address(db) != 0x0);
_;
}
/// @notice Constructor
/// @param _cooContract The address of the coo contract
function AssetLogic(CoO _cooContract)
public
RoleManagement(_cooContract)
{
}
/// @notice function to create a new empty asset, triggers event with created AssetID. To actually create an Asset the functions initGeneral and initLocations have to be called
function createAsset()
external
onlyRole(RoleManagement.Role.AssetAdmin)
isInitialized
{
uint assetId = db.createAsset();
LogAssetCreated(msg.sender, assetId);
}
/// @notice function toinizialize the database, can only be called once
/// @param _dbAddress address of the database contract
function init(address _dbAddress)
public
onlyRole(RoleManagement.Role.TopAdmin)
{
require(address(db) == 0x0);
db = AssetDbInterface(_dbAddress);
}
/// @notice Sets the location information of an asset in the database
/// @param _assetId the The index / identifier of an asset
/// @param _country The country where the asset is located
/// @param _region The region where the asset is located
/// @param _zip The zip coe where the asset is located
/// @param _city The city where the asset is located
/// @param _street The street where the asset is located
/// @param _houseNumber The house number where the asset is located
/// @param _gpsLatitude The gps-latitude of the asset
/// @param _gpsLongitude The gps-longitude of the asset
function initLocation (
uint _assetId,
bytes32 _country,
bytes32 _region,
bytes32 _zip,
bytes32 _city,
bytes32 _street,
bytes32 _houseNumber,
bytes32 _gpsLatitude,
bytes32 _gpsLongitude
)
external
isInitialized
onlyRole(RoleManagement.Role.AssetAdmin)
{
db.initLocation(_assetId, _country, _region, _zip, _city, _street, _houseNumber, _gpsLatitude, _gpsLongitude);
updateAssetExistStatus(_assetId);
}
/// @notice Sets active to false
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _active flag if the asset is asset or not
function setActive(uint _assetId, bool _active)
external
isInitialized
onlyRole(RoleManagement.Role.AssetAdmin)
{
db.setActive(_assetId, _active);
if (_active) {
LogAssetSetActive(_assetId);
} else {
LogAssetSetInactive(_assetId);
}
}
/// @notice Updates the logic contract
/// @param _newLogic Address of the new logic contract
function update(address _newLogic)
external
onlyAccount(address(cooContract))
{
Owned(db).changeOwner(_newLogic);
}
/// @notice gets the active flag on an asset
/// @param _assetId the assetId
/// @return the active flag
function getActive(uint _assetId)
external
view
returns (bool)
{
return db.getActive(_assetId);
}
/// @notice Gets the last filehash of the smart reader
/// @param _assetId the assetId
/// @return the alst smartmeterread-filehash
function getLastSmartMeterReadFileHash(uint _assetId)
external
view
returns (bytes32 datalog)
{
return db.getLastSmartMeterReadFileHash(_assetId);
}
/// @notice Function to get the amount of all assets
/// @dev needed to iterate though all the asset
/// @return the amount of all assets
function getAssetListLength()
external
view
returns (uint)
{
return db.getAssetListLength();
}
/// @notice Funtion to get the informaiton of the location of an asset
/// @param _assetId The identifier / index of the asset
/// @return country, region, zip-code, city, street, houseNumber, gpsLatitude, gpsLongitude
function getAssetLocation(uint _assetId)
external
view
returns(
bytes32 country,
bytes32 region,
bytes32 zip,
bytes32 city,
bytes32 street,
bytes32 houseNumber,
bytes32 gpsLatitude,
bytes32 gpsLongitude
)
{
return db.getAssetLocation(_assetId);
}
/// @notice Changes the address of a smart meter belonging to an asset
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _newSmartMeter The address of the new smart meter
function updateSmartMeter(uint _assetId, address _newSmartMeter)
external
isInitialized
onlyRole(RoleManagement.Role.AssetAdmin)
{
db.setSmartMeter(_assetId, _newSmartMeter);
}
/// @notice Checks if a fully Asset-struct is created, enabled if asset all information are there
/// @dev only for internal use
/// @param _assetId the The index / identifier of an asset
function updateAssetExistStatus(uint _assetId)
internal
{
var (general, location, asset) = db.getExistStatus(_assetId);
if(general && location && !asset) {
db.setAssetExistStatus(_assetId,true);
LogAssetFullyInitialized(_assetId);
db.setLastSmartMeterReadDate(_assetId, now);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @title The logic contract for the asset registration
/// @notice This contract provides the logic that determines how the data is stored
/// @dev Needs a valid AssetProducingRegistryDB contract to function correctly
contract AssetConsumingRegistryLogic is AssetLogic {
event LogNewMeterRead(
uint indexed _assetId,
bytes32 indexed _fileHash,
uint _oldMeterRead,
uint _newMeterRead,
uint _certificatesUsedForWh,
bool _smartMeterDown
);
/// @notice Constructor
/// @param _cooContract The address of the coo contract
function AssetConsumingRegistryLogic(CoO _cooContract)
public
AssetLogic(_cooContract)
{
}
/// @notice Sets the general information of an asset in the database
/// @param _assetId the The index / identifier of an asset
/// @param _smartMeter The address of the smart meter
/// @param _owner The address of the asset owner
/// @param _operationalSince The timestamp since the asset is operational
/// @param _capacityWh The capacity in Wh of the asset
/// @param _maxCapacitySet flag whether there should be a max capacity
/// @param _active true if active
function initGeneral (
uint _assetId,
address _smartMeter,
address _owner,
uint _operationalSince,
uint _capacityWh,
bool _maxCapacitySet,
bool _active
)
external
isInitialized
userHasRole(RoleManagement.Role.AssetManager, _owner)
onlyRole(RoleManagement.Role.AssetAdmin)
{
AssetConsumingRegistryDB(db).initGeneral(_assetId, _smartMeter, _owner, _operationalSince, _capacityWh, _maxCapacitySet, 0, 0, _active, 0x0);
updateAssetExistStatus(_assetId);
}
/// @notice Logs meter read
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _newMeterRead The current meter read of the asset
/// @param _lastSmartMeterReadFileHash Last meter read file hash
/// @param _smartMeterDown flag whether the smartmeter was down
/// @dev The client needs to check if the blockgas limit could be reached and if so the log should be splitted
function saveSmartMeterRead(uint _assetId, uint _newMeterRead, bytes32 _lastSmartMeterReadFileHash, bool _smartMeterDown)
external
isInitialized
onlyAccount(AssetConsumingRegistryDB((db)).getSmartMeter(_assetId))
{
require(db.getActive(_assetId));
uint oldMeterRead = AssetConsumingRegistryDB((db)).getLastSmartMeterReadWh(_assetId);
LogNewMeterRead(_assetId, _lastSmartMeterReadFileHash, oldMeterRead, _newMeterRead, AssetConsumingRegistryDB((db)).getCertificatesUsedForWh(_assetId), _smartMeterDown);
/// @dev need to check if new meter read is higher then the old one
AssetConsumingRegistryDB((db)).setSmartMeterReadData(_assetId, _newMeterRead, _lastSmartMeterReadFileHash, now);
}
/// @notice Gets an asset
/// @param _assetId The id belonging to an entry in the asset registry
/// @return general information of an asset
function getAssetGeneral(uint _assetId)
external
view
returns (
address _smartMeter,
address _owner,
uint _operationalSince,
uint _capacityWh,
bool _maxCapacitySet,
uint _lastSmartMeterReadWh,
uint _certificatesUsedForWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
{
return AssetConsumingRegistryDB(address(db)).getAssetGeneral(_assetId);
}
/// @notice gets the consuming properties of an asset
/// @param _assetId the assetId
/// @return retuns capacity, maxCapacitySet-falg and certificatesUsedForWh
function getConsumingProperies(uint _assetId)
external
view
returns (
uint capacityWh,
bool maxCapacitySet,
uint certificatesUsedForWh
)
{
(capacityWh, maxCapacitySet, certificatesUsedForWh) = AssetConsumingRegistryDB(address(db)).getConsumingProperies(_assetId);
}
/// @notice sets the consumption for a period (in Wh)
/// @param _assetId assetId
/// @param _consumed the amount of energy consumed
function setConsumptionForPeriode(uint _assetId, uint _consumed)
external
onlyAccount(address(cooContract.demandRegistry()))
{
AssetConsumingRegistryDB(db).setCertificatesUsedForWh(_assetId, _consumed);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
//
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Heiko Burkhardt, heiko.burkhardt@slock.it
/// @title The Database contract for the Asset Registration
/// @notice This contract only provides getter and setter methods
contract AssetProducingRegistryDB is AssetGeneralDefinition, AssetDbInterface {
struct ProducingProperties {
uint assetType;
uint capacityWh;
uint certificatesCreatedForWh;
uint lastSmartMeterCO2OffsetRead;
uint cO2UsedForCertificate;
uint registryCompliance;
bytes32 otherGreenAttributes;
bytes32 typeOfPublicSupport;
}
struct Asset {
AssetGeneralDefinition.GeneralInformation general;
ProducingProperties producingProps;
LocationDefinition.Location location;
bool exists;
}
/// @notice An array containing all registerd assets
Asset[] private assets;
/// @dev empty structs for initializing, used to avoid compile warnings
AssetGeneralDefinition.GeneralInformation generalEmpty;
LocationDefinition.Location locationEmpty;
ProducingProperties producingEmpty;
/// @notice Constructor
/// @param _owner The owner of the contract
function AssetProducingRegistryDB(address _owner)
public
Owned(_owner)
{
}
/// @notice function to create a new empty asset
/// @return returns the array-position and thus the index / identifier of this new asset
function createAsset()
external
onlyOwner
returns (uint _assetId)
{
_assetId = assets.length;
assets.push(AssetProducingRegistryDB.Asset({
general: generalEmpty,
producingProps: producingEmpty,
location: locationEmpty,
exists: false
}));
}
/// @notice function to set the general information for an asset
/// @param _assetId the ID belonging to the asset
/// @param _smartMeter the smart-meter address
/// @param _owner the owner of the asset
/// @param _operationalSince timestamp of when the asset started producing energy
/// @param _lastSmartMeterReadWh the last reading of the smartmeter
/// @param _active active-flag
/// @param _lastSmartMeterReadFileHash the last filehash of the smartmeter-readings
function initGeneral(
uint _assetId,
address _smartMeter,
address _owner,
uint _operationalSince,
uint _lastSmartMeterReadWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
onlyOwner
external
{
Asset storage a = assets[_assetId];
setGeneralInformationInternal(a.general, _smartMeter, _owner, _operationalSince,_lastSmartMeterReadWh, _active, _lastSmartMeterReadFileHash);
}
/// @notice function to set the producing-properties of an asset
/// @param _assetId the ID belonging to the asset
/// @param _assetType the assetType of the asset
/// @param _lastSmartMeterCO2OffsetRead the last CO2-Offsetreading of the smartmeter
/// @param _cO2UsedForCertificate the amount of CO2 used for certificates already
/// @param _capacityWh the capacity of the asset in Wh
/// @param _certificatesCreatedForWh the amount of Wh already certificated
/// @param _registryCompliance the registry-compliance
/// @param _otherGreenAttributes other green attributes
/// @param _typeOfPublicSupport type of public support
function initProducing(
uint _assetId,
uint _assetType,
uint _lastSmartMeterCO2OffsetRead,
uint _cO2UsedForCertificate,
uint _capacityWh,
uint _certificatesCreatedForWh,
uint _registryCompliance,
bytes32 _otherGreenAttributes,
bytes32 _typeOfPublicSupport
)
onlyOwner
external
{
Asset storage a = assets[_assetId];
a.producingProps.assetType = _assetType;
a.producingProps.lastSmartMeterCO2OffsetRead = _lastSmartMeterCO2OffsetRead;
a.producingProps.cO2UsedForCertificate = _cO2UsedForCertificate;
a.producingProps.certificatesCreatedForWh = _certificatesCreatedForWh;
a.producingProps.capacityWh = _capacityWh;
a.producingProps.registryCompliance = _registryCompliance;
a.producingProps.otherGreenAttributes = _otherGreenAttributes;
a.producingProps.typeOfPublicSupport = _typeOfPublicSupport;
}
/// @notice function to set all the location Informations for an asset
/// @param _assetId The identifier / index of an asset
/// @param _country The country where the asset is located
/// @param _region The region / state where the asset is located
/// @param _zip The zip-code of the region where the asset is located
/// @param _city The city where the asset is located
/// @param _street The streetname where the asset is located
/// @param _houseNumber the housenumber where the asset is located
/// @param _gpsLatitude The gps-latitude
/// @param _gpsLongitude The gps-longitude
function initLocation(
uint _assetId,
bytes32 _country,
bytes32 _region,
bytes32 _zip,
bytes32 _city,
bytes32 _street,
bytes32 _houseNumber,
bytes32 _gpsLatitude,
bytes32 _gpsLongitude
)
onlyOwner
external
{
LocationDefinition.Location storage loc = assets[_assetId].location;
initLocationInternal(loc,_country,_region,_zip,_city,_street,_houseNumber,_gpsLatitude,_gpsLongitude);
}
/// @notice Sets if an entry in the asset registry is active
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _active true if active
function setActive(uint _assetId, bool _active)
onlyOwner
external
{
assets[_assetId].general.active = _active;
}
/// @notice function to set the existing status of an asset
/// @param _assetId The index position / identifier of an asset
/// @param _exist flag if the asset should exist
function setAssetExistStatus(uint _assetId, bool _exist)
external
onlyOwner
{
Asset storage a = assets[_assetId];
a.exists = _exist;
}
/// @notice Sets the fuel type belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _assetType The new fuel type
function setAssetType(uint _assetId, uint _assetType)
onlyOwner
external
{
assets[_assetId].producingProps.assetType = _assetType;
}
/// @notice Sets the capacity in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _capacityWh The capacity in Wh
function setCapacityWh(uint _assetId, uint _capacityWh)
onlyOwner
external
{
assets[_assetId].producingProps.capacityWh = _capacityWh;
}
/// @notice Sets amount of Wh used to issue certificates belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _certificatesCreatedForWh The amount of Wh used to issue certificates
function setCertificatesCreatedForWh(uint _assetId, uint _certificatesCreatedForWh)
onlyOwner
external
{
assets[_assetId].producingProps.certificatesCreatedForWh = _certificatesCreatedForWh;
}
/// @notice Sets amount of saved CO2 used to issue certificates belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _used The amount of saved CO2 used to issue certificates
function setCO2UsedForCertificate(uint _assetId, uint _used)
onlyOwner
external
{
assets[_assetId].producingProps.cO2UsedForCertificate = _used;
}
/// @notice Sets the last smart meter read in saved CO2 of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _lastCO2OffsetReading The new amount of saved CO2
function setLastCO2OffsetReading(uint _assetId, uint _lastCO2OffsetReading)
onlyOwner
external
{
assets[_assetId].producingProps.lastSmartMeterCO2OffsetRead = _lastCO2OffsetReading;
}
/// @notice Sets the timestamp of the last smartmeter-reading
/// @param _assetId the id belonging to the asset
/// @param _timestamp the new timestamp of reading
function setLastSmartMeterReadDate(uint _assetId, uint _timestamp)
onlyOwner
external
{
assets[_assetId].general.lastMeterReadReceived = _timestamp;
}
/// @notice Sets last meter read file hash
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _lastSmartMeterReadFileHash Last meter read file hash
function setLastSmartMeterReadFileHash(uint _assetId, bytes32 _lastSmartMeterReadFileHash)
onlyOwner
external
{
assets[_assetId].general.lastSmartMeterReadFileHash = _lastSmartMeterReadFileHash;
}
/// @notice Sets the last smart meter read in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _lastSmartMeterReadWh The smart meter read in Wh
function setLastSmartMeterReadWh(uint _assetId, uint _lastSmartMeterReadWh)
onlyOwner
external
{
assets[_assetId].general.lastSmartMeterReadWh = _lastSmartMeterReadWh;
}
/// @notice Sets the location-country of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @param _country the new country
function setLocationCountry(uint _assetId, bytes32 _country)
onlyOwner
external
{
assets[_assetId].location.country = _country;
}
/// @notice Sets the location-region of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @param _region the new region
function setLocationRegion(uint _assetId, bytes32 _region)
onlyOwner
external
{
assets[_assetId].location.region = _region;
}
/// @notice Sets multiple information of a meterreading
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _newMeterRead the new meterreading of the smart meter
/// @param _CO2OffsetMeterRead the new CO2-offset reading
/// @param _lastSmartMeterReadFileHash the filehash belonging to that reading
/// @param _timestamp the timestamp of that reading
function setSmartMeterReadData(
uint _assetId,
uint _newMeterRead,
uint _CO2OffsetMeterRead,
bytes32 _lastSmartMeterReadFileHash,
uint _timestamp
)
onlyOwner
external
{
assets[_assetId].producingProps.lastSmartMeterCO2OffsetRead = _CO2OffsetMeterRead;
assets[_assetId].general.lastSmartMeterReadWh = _newMeterRead;
assets[_assetId].general.lastSmartMeterReadFileHash = _lastSmartMeterReadFileHash;
assets[_assetId].general.lastMeterReadReceived = _timestamp;
}
/// @notice Sets the operational since field of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _operationalSince The timestamp since the asset is operational
function setOperationalSince(uint _assetId, uint _operationalSince)
onlyOwner
external
{
assets[_assetId].general.operationalSince = _operationalSince;
}
/// @notice Sets the owner of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _owner The new owner
function setOwner(uint _assetId, address _owner)
onlyOwner
external
{
assets[_assetId].general.owner = _owner;
}
/// @notice Sets the smart meter address belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _smartMeter The new smart meter address
function setSmartMeter(uint _assetId, address _smartMeter)
onlyOwner
external
{
assets[_assetId].general.smartMeter = _smartMeter;
}
/// @notice Gets if an entry in the asset registry is active
/// @param _assetId The id belonging to an entry in the asset registry
/// @return true if asset is active
function getActive(uint _assetId)
onlyOwner
external
view
returns(bool)
{
return assets[_assetId].general.active;
}
/// @notice Returns the general information of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return smartmeter-address, owner-address, operationalSince, lastSmartMeterReading in Wh, active flag and the filehash of the last reading
function getAssetGeneral(uint _assetId)
onlyOwner
external
view
returns
(
address _smartMeter,
address _owner,
uint _operationalSince,
uint _lastSmartMeterReadWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
{
Asset memory asset = assets[_assetId];
_smartMeter = asset.general.smartMeter;
_owner = asset.general.owner;
_operationalSince = asset.general.operationalSince;
_lastSmartMeterReadWh = asset.general.lastSmartMeterReadWh;
_active = asset.general.active;
_lastSmartMeterReadFileHash = asset.general.lastSmartMeterReadFileHash;
}
/// @notice function to get the amount of assets
/// @return amount of assets
function getAssetListLength()
onlyOwner
external
view
returns (uint)
{
return assets.length;
}
/// @notice function to get the informations about the location of a struct
/// @param _assetId The id belonging to an entry in the asset registry
/// @return country, region, zip, city, street, houseNumber, gpsLatitude, gpsLongitude
function getAssetLocation(uint _assetId)
onlyOwner
external
view
returns(
bytes32 country,
bytes32 region,
bytes32 zip,
bytes32 city,
bytes32 street,
bytes32 houseNumber,
bytes32 gpsLatitude,
bytes32 gpsLongitude
)
{
LocationDefinition.Location memory loc = assets[_assetId].location;
return getAssetLocationInternal(loc);
}
/// @notice function to get the producing-properties of an asset
/// @param _assetId the id belonging to the asset
/// @return returns the producing-properties of an asset
function getAssetProducingProperties(uint _assetId)
onlyOwner
external
view
returns (
uint assetType,
uint capacityWh,
uint certificatesCreatedForWh,
uint lastSmartMeterCO2OffsetRead,
uint cO2UsedForCertificate,
uint registryCompliance,
bytes32 otherGreenAttributes,
bytes32 typeOfPublicSupport
)
{
Asset memory a = assets[_assetId];
ProducingProperties memory pp = a.producingProps;
assetType = pp.assetType;
capacityWh = pp.capacityWh;
certificatesCreatedForWh = pp.certificatesCreatedForWh;
lastSmartMeterCO2OffsetRead = pp.lastSmartMeterCO2OffsetRead;
cO2UsedForCertificate = pp.cO2UsedForCertificate;
registryCompliance = pp.registryCompliance;
otherGreenAttributes = pp.otherGreenAttributes;
typeOfPublicSupport = pp.typeOfPublicSupport;
}
/// @notice Gets the asset type belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the type of asset
function getAssetType(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].producingProps.assetType;
}
/// @notice Gets the capacity in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the capacity in Wh
function getCapacityWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].producingProps.capacityWh;
}
/// @notice Gets amount of Wh used to issue certificates belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the amount of Wh used to issue certificates
function getCertificatesCreatedForWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].producingProps.certificatesCreatedForWh;
}
/// @notice Gets the amount of already used CO2-offset for creating certificates
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the aount of already used CO2-offset
function getCo2UsedForCertificate(uint _assetId)
onlyOwner
external
view
returns (uint)
{
return assets[_assetId].producingProps.cO2UsedForCertificate;
}
/// @notice function the retrieve the existing status of the general information, the location information and the asset itself
/// @param _assetId The index position / identifier of the asset
/// @return existing status of the general informaiton, existing status of the location informaiton and where the asset-structs exists
function getExistStatus(uint _assetId)
onlyOwner
external
view
returns (bool general, bool location, bool asset)
{
Asset memory a = assets[_assetId];
return(a.general.exists && a.producingProps.capacityWh > 0, a.location.exists, a.exists);
}
/// @notice function to get the last smartmeter-reading of an asset
/// @param _assetId the id belonging to the asset
/// @return the last smartmeter-reading
function getLastSmartMeterRead(uint _assetId)
onlyOwner
external
returns (uint)
{
return assets[_assetId].general.lastSmartMeterReadWh;
}
/// @notice Gets the last CO2-offset read of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the last logged CO2-offset read tru
function getlastSmartMeterCO2OffsetRead(uint _assetId)
onlyOwner
external
view
returns (uint)
{
return assets[_assetId].producingProps.lastSmartMeterCO2OffsetRead;
}
/// @notice gets the timestamp of the last reading
/// @param _assetId the Id belonging to an entry in the asset registry
/// @return the timestamp of the last reading
function getLastSmartMeterReadDate(uint _assetId)
onlyOwner
external
returns(uint)
{
return assets[_assetId].general.lastMeterReadReceived;
}
/// @notice Gets last smart merter read file hash
/// @param _assetId The id belonging to an entry in the asset registry
/// @return last smart merter read file hash
function getLastSmartMeterReadFileHash(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].general.lastSmartMeterReadFileHash;
}
/// @notice Gets the last smart merter read in Wh of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the last loged smart meter read in Wh
function getLastSmartMeterReadWh(uint _assetId)
onlyOwner
external
view
returns(uint)
{
return assets[_assetId].general.lastSmartMeterReadWh;
}
/// @notice Gets the location country of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return country where the asset is based
function getLocationCountry(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].location.country;
}
/// @notice Gets the location region of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return region of the country where the asset is based
function getLocationRegion(uint _assetId)
onlyOwner
external
view
returns(bytes32)
{
return assets[_assetId].location.region;
}
/// @notice Gets the operational since field of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
function getOperationalSince(uint _assetId)
external
onlyOwner
view
returns(uint)
{
return assets[_assetId].general.operationalSince;
}
/// @notice Gets the owner of an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the owner address
function getOwner(uint _assetId)
external
onlyOwner
view
returns(address)
{
return assets[_assetId].general.owner;
}
/// @notice Gets the smart meter address belonging to an entry in the asset registry
/// @param _assetId The id belonging to an entry in the asset registry
/// @return the smart meter address
function getSmartMeter(uint _assetId)
external
onlyOwner
view
returns(address)
{
return assets[_assetId].general.smartMeter;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Jonas Bentke, jonas.bentke@slock.it
/// @title The logic contract for the asset registration
/// @notice This contract provides the logic that determines how the data is stored
/// @dev Needs a valid AssetProducingRegistryDB contract to function correctly
contract AssetProducingRegistryLogic is AssetLogic {
event LogNewMeterRead(uint indexed _assetId, bytes32 indexed _fileHash, uint _oldMeterRead, uint _newMeterRead, bool _smartMeterDown, uint _certificatesCreatedForWh, uint _oldCO2OffsetReading, uint _newCO2OffsetReading, bool _serviceDown);
enum AssetType {
Wind,
Solar,
RunRiverHydro,
BiomassGas
}
enum Compliance{
none,
IREC,
EEC,
TIGR
}
/// @notice Constructor
/// @param _cooContract The address of the coo contract
function AssetProducingRegistryLogic(CoO _cooContract)
public
AssetLogic(_cooContract)
{
}
/// @notice Sets the general information of an asset in the database
/// @param _assetId the The index / identifier of an asset
/// @param _smartMeter The address of the smart meter
/// @param _owner The address of the asset owner
/// @param _operationalSince the timestamp of when the asset was activated for production
/// @param _active true if active
function initGeneral(
uint _assetId,
address _smartMeter,
address _owner,
uint _operationalSince,
bool _active
)
external
isInitialized
userHasRole(RoleManagement.Role.AssetManager, _owner)
onlyRole(RoleManagement.Role.AssetAdmin)
{
AssetProducingRegistryDB((db)).initGeneral(_assetId, _smartMeter, _owner, _operationalSince,0, _active, 0x0);
updateAssetExistStatus(_assetId);
}
/// @notice sets the producing properties of an asset
/// @param _assetId the id belonging to an asset
/// @param _assetType the asset-type
/// @param _capacityWh the capacity of the asset
/// @param _registryCompliance the compliance
/// @param _otherGreenAttributes other green attributes
/// @param _typeOfPublicSupport type of public support
function initProducingProperties(
uint _assetId,
AssetType _assetType,
uint _capacityWh,
Compliance _registryCompliance,
bytes32 _otherGreenAttributes,
bytes32 _typeOfPublicSupport
)
external
isInitialized
onlyRole(RoleManagement.Role.AssetAdmin)
{
AssetProducingRegistryDB((db)).initProducing(_assetId, uint(_assetType), 0, 0, _capacityWh, 0, uint(_registryCompliance), _otherGreenAttributes, _typeOfPublicSupport);
updateAssetExistStatus(_assetId);
}
/// @notice Logs meter read
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _newMeterRead The current meter read of the asset
/// @param _smartMeterDown flag if there was an error with the smart meter
/// @param _lastSmartMeterReadFileHash Last meter read file hash
/// @param _CO2OffsetServiceDown flag if there was an error with the co2-offset-server
/// @param _CO2OffsetMeterRead The new CO2-offset reading
/// @dev The client needs to check if the blockgas limit could be reached and if so the log should be splitted
function saveSmartMeterRead(
uint _assetId,
uint _newMeterRead,
bool _smartMeterDown,
bytes32 _lastSmartMeterReadFileHash,
uint _CO2OffsetMeterRead,
bool _CO2OffsetServiceDown
)
external
isInitialized
onlyAccount(AssetProducingRegistryDB(db).getSmartMeter(_assetId))
{
require(db.getActive(_assetId));
LogNewMeterRead(_assetId, _lastSmartMeterReadFileHash, AssetProducingRegistryDB(db).getLastSmartMeterReadWh(_assetId), _newMeterRead, _smartMeterDown, AssetProducingRegistryDB(db).getCertificatesCreatedForWh(_assetId), AssetProducingRegistryDB(db).getlastSmartMeterCO2OffsetRead(_assetId), _CO2OffsetMeterRead, _CO2OffsetServiceDown);
/// @dev need to check if new meter read is higher then the old one
AssetProducingRegistryDB(address(db)).setSmartMeterReadData(_assetId, _newMeterRead, _CO2OffsetMeterRead, _lastSmartMeterReadFileHash, now);
}
/// @notice function to set the amount of CO2 used for certificates
/// @param _assetId the assetId
/// @param _co2 the amount of CO2 saved
function setCO2UsedForCertificate(uint _assetId, uint _co2)
external
isInitialized
onlyAccount(address(cooContract.certificateRegistry()))
{
uint currentCO = AssetProducingRegistryDB(address(db)).getCo2UsedForCertificate(_assetId);
uint fullCO = AssetProducingRegistryDB(address(db)).getlastSmartMeterCO2OffsetRead(_assetId);
uint temp = currentCO + _co2;
assert(temp >= currentCO);
// we have to check that we can only account that amount of CO2 that was actually saved
require(temp <= fullCO);
AssetProducingRegistryDB(address(db)).setCO2UsedForCertificate(_assetId, temp);
}
/// @notice increases the amount of wh used for the creation of certificates
/// @param _assetId The id belonging to an entry in the asset registry
/// @param _whUsed The amount of wh that is about to be used for a new certificate
function useWhForCertificate(uint _assetId, uint _whUsed)
external
isInitialized
onlyAccount(address(cooContract.certificateRegistry()))
returns(bool)
{
uint temp = AssetProducingRegistryDB(address(db)).getCertificatesCreatedForWh(_assetId) + _whUsed;
require(AssetProducingRegistryDB(address(db)).getLastSmartMeterReadWh(_assetId) >= temp);
AssetProducingRegistryDB(address(db)).setCertificatesCreatedForWh(_assetId, temp);
return true;
}
/// @notice Gets the general information of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return the general information of an asset
function getAssetGeneral(uint _assetId)
external
view
returns(
address _smartMeter,
address _owner,
uint _operationalSince,
uint _lastSmartMeterReadWh,
bool _active,
bytes32 _lastSmartMeterReadFileHash
)
{
return AssetProducingRegistryDB(address(db)).getAssetGeneral(_assetId);
}
/// @notice get the producing properties of an asset
/// @param _assetId the id belonging to an entry in the asset registry
/// @return the producing properties
function getAssetProducingProperties(uint _assetId)
external
view
returns(
uint assetType,
uint capacityWh,
uint certificatesCreatedForWh,
uint lastSmartMeterCO2OffsetRead,
uint cO2UsedForCertificate,
uint registryCompliance,
bytes32 otherGreenAttributes,
bytes32 typeOfPublicSupport
)
{
return AssetProducingRegistryDB(address(db)).getAssetProducingProperties(_assetId);
}
/// @notice Function to get the Asset-Type
/// @dev The asset-type gets converted from unsigned integer to an Asset-type enum, can still be accessed as uint
/// @param _assetId The identifier / index of an asset
/// @return AssetType as enum
function getAssetType(uint _assetId)
external
view
returns(
AssetType
)
{
return AssetType(AssetProducingRegistryDB(address(db)).getAssetType(_assetId));
}
/// @notice function to get the compliance
/// @param _assetId the assetId
/// @return the compliance
function getCompliance(uint _assetId)
external
view
returns (Compliance c)
{
var ( , , , , , ctemp, , ) = AssetProducingRegistryDB(address(db)).getAssetProducingProperties(_assetId);
c = Compliance(ctemp);
}
/// @notice Function to get the amount of already used CO2 for creating certificates
/// @param _assetId The identifier / index of an asset
/// @return the amount of already used CO2 for creating certificates
function getCo2UsedForCertificate(uint _assetId)
external
view
returns (uint)
{
return AssetProducingRegistryDB(address(db)).getCo2UsedForCertificate(_assetId);
}
/// @notice function to calculated how much CO2-offset can be used for a certificate
/// @param _assetId The identifier / index of an asset
/// @param _wh The amount of wh produced
/// @return amount of CO2-offset used for a certificate
function getCoSaved(uint _assetId, uint _wh) external view returns(uint) {
uint lastRead = AssetProducingRegistryDB(address(db)).getLastSmartMeterReadWh(_assetId);
uint lastUsedWh = AssetProducingRegistryDB(address(db)).getCertificatesCreatedForWh(_assetId);
uint availableWh = lastRead - lastUsedWh;
// we have to check for an underflow and if there are even availale Wh
assert(lastUsedWh <= lastRead);
if (availableWh == 0) return 0;
uint coRead = AssetProducingRegistryDB(address(db)).getlastSmartMeterCO2OffsetRead(_assetId);
uint coUsed = AssetProducingRegistryDB(address(db)).getCo2UsedForCertificate(_assetId);
uint availableCo = coRead - coUsed;
assert(coUsed <= coRead);
return (availableCo*((_wh*1000000)/availableWh))/1000000;
}
/// @notice returns whether an asset exists
/// @param _assetId The identifier of an asset
/// @return bool if asset exists, false if some information are missing
function getExistStatus(uint _assetId) external view returns (bool) {
var (general, location, asset) = db.getExistStatus(_assetId);
return (general && location && asset);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Jonas Bentke, jonas.bentke@slock.it
/// @title The Database contract for the Certificate of Origin list
/// @notice This contract only provides getter and setter methods
contract CertificateDB is Owned {
struct Certificate {
uint assetId;
address owner;
uint powerInW;
bool retired;
bytes32 dataLog;
uint coSaved;
address escrow;
uint creationTime;
}
/// @notice An array containing all created certificates
Certificate[] private certificateList; // why is it private read? People can still read it, just not use from within a smart contract (even there it is possible)
/// @notice Constructor
/// @param _certificateLogic The address of the corresbonding logic contract
function CertificateDB(address _certificateLogic) Owned(_certificateLogic) public {
}
/// @notice Creates a new certificate
/// @param _assetId The id of the Certificate
/// @param _owner The owner of the Certificate
/// @param _powerInW The amount of Watts the Certificate holds
/// @return The id of the certificate
function createCertificate(uint _assetId, address _owner, uint _powerInW, bytes32 _dataLog, uint _coSaved, address _escrow) public onlyOwner returns (uint _certId) {
_certId = certificateList.length;
certificateList.push(Certificate(_assetId, _owner, _powerInW, false, _dataLog, _coSaved, _escrow, now));
}
/// @notice sets the escrow-address of a certificate
/// @param _certificateId certificateId
/// @param _escrow new escrow-address
function setCertificateEscrow(uint _certificateId, address _escrow)
public
onlyOwner
{
certificateList[_certificateId].escrow = _escrow;
}
/// @notice Sets the owner of a certificate
/// @param _certificateId The array position in which the certificate is stored
/// @param _owner The address of the new owner
function setCertificateOwner(uint _certificateId, address _owner) public onlyOwner {
certificateList[_certificateId].owner = _owner;
}
/// @notice Sets a certificate to retired
/// @param _certificateId The array position in which the certificate is stored
function retireCertificate(uint _certificateId) public onlyOwner {
certificateList[_certificateId].retired = true;
}
/// @notice Returns the certificate that corresponds to the given array id
/// @param _certificateId The array position in which the certificate is stored
/// @return all elements of the certificate
function getCertificate(uint _certificateId)
public
view
returns (
uint _assetId,
address _owner,
uint _powerInW,
bool _retired,
bytes32 _dataLog,
uint _coSaved,
address _escrow,
uint _creationTime
)
{
Certificate memory c = certificateList[_certificateId];
_assetId = c.assetId;
_owner = c.owner;
_powerInW = c.powerInW;
_retired = c.retired;
_dataLog = c.dataLog;
_coSaved = c.coSaved;
_escrow = c.escrow;
_creationTime = c.creationTime;
}
/// @notice Returns the certificate owner
/// @param _certificateId The array position in which the certificate is stored
/// @return address owner
function getCertificateOwner(uint _certificateId)
public
onlyOwner
view
returns (address)
{
return certificateList[_certificateId].owner;
}
/// @notice Getter for state of retirement
/// @param _certificateId The id of the requested certificate
/// @return bool if it is retired
function isRetired(uint _certificateId)
public
onlyOwner
view
returns (bool)
{
return certificateList[_certificateId].retired;
}
/// @notice function to get the amount of all certificates
/// @return the amount of all certificates
function getCertificateListLength()
public
onlyOwner
view
returns (uint)
{
return certificateList.length;
}
/// @notice function to get the escrow-address of a certificate
/// @param _certificateId certificate-ID
/// @return escrow-address
function getCertificateEscrow(uint _certificateId)
public
onlyOwner
view
returns (address)
{
return certificateList[_certificateId].escrow;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Jonas Bentke, jonas.bentke@slock.it
/// @title The logic contract for the Certificate of Origin list
/// @notice This contract provides the logic that determines how the data is stored
/// @dev Needs a valid CertificateDB contract to function correctly
contract CertificateLogic is RoleManagement, Updatable {
///@notice The address of a CertificateDB contract
CertificateDB public certificateDb;
/// @notice Logs the creation of an event
event LogCreatedCertificate(uint indexed _certificateId, uint powerInW, address owner, address escrow);
/// @notice Logs the request of an retirement of a certificate
event LogRetireRequest(uint indexed _certificateId, bool _retire);
event LogCertificateOwnerChanged(uint indexed _certificateId, address _oldOwner, address _newOwner, address _oldEscrow, address _newEscrow);
/// @notice Checks if the contract is initialized
modifier isInitialized() {
require(certificateDb != CertificateDB(0x0));
_;
}
/// @notice Constructor
/// @param _coo The Master contract
function CertificateLogic(CoO _coo) RoleManagement(_coo) public {
}
/// @notice Initialises the contract by binding it to a logic contract
/// @param _database Sets the logic contract
function init(address _database) public onlyRole(RoleManagement.Role.TopAdmin) {
require(certificateDb == CertificateDB(0x0));
certificateDb = CertificateDB(_database);
}
/// @notice Creates a certificate of origin. Checks in the AssetRegistry if requested wh are available.
/// @param _assetId The id of the Certificate
/// @param _owner The owner of the Certificate
/// @param _powerInW The amount of Watts the Certificate holds
function createCertificate(uint _assetId, address _owner, uint _powerInW)
public
isInitialized
onlyAccount(address(cooContract.demandRegistry()) )
returns (uint)
{
return createCertificateIntern(_assetId, _owner, _powerInW, 0x0);
}
/// @notice Creates a certificate of origin. Checks in the AssetRegistry if requested wh are available.
/// @param _assetId The id of the Certificate
/// @param _owner The owner of the Certificate
/// @param _powerInW The amount of Watts the Certificate holds
/// @param _escrow The escrow of a certificate
/// @return a certificate-id
function createCertificateIntern(uint _assetId, address _owner, uint _powerInW, address _escrow)
internal
isInitialized
returns (uint)
{
uint co = AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).getCoSaved(_assetId, _powerInW);
require(AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).useWhForCertificate(_assetId, _powerInW));
bytes32 dataLog = AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).getLastSmartMeterReadFileHash(_assetId);
uint certId = certificateDb.createCertificate(_assetId, _owner, _powerInW, dataLog, co, _escrow);
LogCreatedCertificate(certId, _powerInW, _owner, _escrow);
AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).setCO2UsedForCertificate(_assetId,co);
return certId;
}
/// @notice Creates a certificate of origin for the asset owner. Checks in the AssetRegistry if requested wh are available.
/// @dev the msg.sender (a matcher) will become the escrow-of that certificate and is allowed to change the change the ownership
/// @param _assetId The id of the Certificate
/// @param _powerInW The amount of Watts the Certificate holds
/// @return the certificate-id
function createCertificateForAssetOwner(uint _assetId, uint _powerInW)
public
onlyRole(RoleManagement.Role.Matcher)
isInitialized
returns (uint)
{
require( AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).getExistStatus(_assetId));
var ( , ownerAddress, , , , ) = AssetProducingRegistryLogic(address(cooContract.assetProducingRegistry())).getAssetGeneral(_assetId);
return createCertificateIntern(_assetId, ownerAddress, _powerInW, msg.sender);
}
/// @notice Request a certificate to retire. Only Certificate owner can retire
/// @param _id The id of the certificate
function retireCertificate(uint _id)
public
isInitialized
{
var (, owner, , retired,, ,,) = certificateDb.getCertificate(_id);
require(owner == msg.sender);
if (!retired) {
certificateDb.setCertificateEscrow(_id, 0x0);
certificateDb.retireCertificate(_id);
LogRetireRequest(_id, true);
}
}
/// @notice function to allow an escrow-address to change the ownership of a certificate
/// @dev this function can only be called by the demandLogic
/// @param _id the certificate-id
/// @param _newOwner the new owner of the certificate
function transferOwnershipByEscrow(uint _id, address _newOwner)
public
isInitialized
onlyAccount(address(cooContract.demandRegistry()) )
{
address oldOwner;
bool retired;
address oldEscrow;
( ,oldOwner,,retired,,,oldEscrow,) = certificateDb.getCertificate(_id);
require(!retired);
certificateDb.setCertificateOwner(_id, _newOwner);
certificateDb.setCertificateEscrow(_id, 0x0);
LogCertificateOwnerChanged(_id, oldOwner, _newOwner, oldEscrow, 0x0);
}
/// @notice Sets a new owner for the certificate
/// @param _id The id of the certificate
/// @param _newOwner The address of the new owner of the certificate
function changeCertificateOwner(uint _id, address _newOwner)
public
isInitialized()
userExists(_newOwner)
{
require(msg.sender == certificateDb.getCertificateOwner(_id) && !(certificateDb.isRetired(_id)));
certificateDb.setCertificateOwner(_id, _newOwner);
address oldOwner = certificateDb.getCertificateOwner(_id);
address oldEscrow = certificateDb.getCertificateEscrow(_id);
LogCertificateOwnerChanged(_id, oldOwner, _newOwner, oldEscrow, oldEscrow);
}
/// @notice Getter for a specific Certificate
/// @param _certificateId The id of the requested certificate
/// @return the certificate as single values
function getCertificate(uint _certificateId)
public
view
returns (
uint _assetId,
address _owner,
uint _powerInW,
bool _retired,
bytes32 _dataLog,
uint _coSaved,
address _escrow,
uint _creationTime
)
{
return certificateDb.getCertificate(_certificateId);
}
/// @notice Getter for a specific Certificate
/// @param _certificateId The id of the requested certificate
/// @return the certificate as single values
function getCertificateOwner(uint _certificateId)
public
view
returns (address)
{
return certificateDb.getCertificateOwner(_certificateId);
}
/// @notice Getter for a specific Certificate
/// @param _certificateId The id of the requested certificate
/// @return the certificate as single values
function isRetired(uint _certificateId)
public
view
returns (bool)
{
return certificateDb.isRetired(_certificateId);
}
/// @notice Getter for the length of the list of certificates
/// @return the length of the array
function getCertificateListLength()
public
view
returns (uint)
{
return certificateDb.getCertificateListLength();
}
/// @notice Updates the logic contract
/// @param _newLogic Address of the new logic contract
function update(address _newLogic)
external
onlyAccount(address(cooContract))
{
require(address(cooContract) == msg.sender);
certificateDb.changeOwner(_newLogic);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title Contract for storing the current logic-contracts-addresses for the certificate of origin
contract CoO is Owned {
event LogUserRegistryUpdated(address _old, address _new);
event LogAssetProducingRegistryUpdated(address _old, address _new);
event LogCertificateRegistryUpdated(address _old, address _new);
event LogDemandRegistryUpdated(address _old, address _new);
event LogAssetConsumingRegistryUpdated(address _old, address _new);
Updatable public userRegistry;
Updatable public assetProducingRegistry;
Updatable public certificateRegistry;
Updatable public demandRegistry;
Updatable public assetConsumingRegistry;
/// @notice The constructor of the UserDB
function CoO()
Owned(msg.sender)
public
{
}
/// @notice function to initialize the contracts, setting the needed contract-addresses
/// @param _userRegistry user-registry logic contract address
/// @param _assetProducingRegistry producing-asset-registry logic contract address
/// @param _certificateRegistry certificate-registry logic contract address
/// @param _demandRegistry demand-registry logic contract address
/// @param _assetConsumingRegistry consuming-asset-registry logic contract address
function init(
Updatable _userRegistry,
Updatable _assetProducingRegistry,
Updatable _certificateRegistry,
Updatable _demandRegistry,
Updatable _assetConsumingRegistry
)
onlyOwner
external
{
require(
_userRegistry != address(0) && _assetProducingRegistry != address(0) && _certificateRegistry != address(0) && _demandRegistry != address(0) && _assetConsumingRegistry != address(0)
&& userRegistry == address(0) && assetProducingRegistry == address(0) && certificateRegistry == address(0) && demandRegistry == address(0) && assetConsumingRegistry == address(0)
);
userRegistry = _userRegistry;
assetProducingRegistry = _assetProducingRegistry;
certificateRegistry = _certificateRegistry;
demandRegistry = _demandRegistry;
assetConsumingRegistry = _assetConsumingRegistry;
}
/// @notice function to update one or more logic-contracts
/// @param _userRegistry address of the new user-registry-logic-contract
/// @param _assetProducingRegistry address of the new asset-registry-logic-contract
/// @param _certificateRegistry address of the new certificate-registry-logic-contract
/// @param _demandRegistry demand-registry logic contract address
/// @param _assetConsumingRegistry consuming-asset-registry logic contract address
function update(
Updatable _userRegistry,
Updatable _assetProducingRegistry,
Updatable _certificateRegistry,
Updatable _demandRegistry,
Updatable _assetConsumingRegistry
)
onlyOwner
external
{
if (_userRegistry != address(0)) {
LogUserRegistryUpdated(userRegistry, _userRegistry);
userRegistry.update(_userRegistry);
userRegistry = _userRegistry;
}
if (_assetProducingRegistry != address(0)) {
LogAssetProducingRegistryUpdated(assetProducingRegistry, _assetProducingRegistry);
assetProducingRegistry.update(_assetProducingRegistry);
assetProducingRegistry = _assetProducingRegistry;
}
if (_certificateRegistry != address(0)) {
LogCertificateRegistryUpdated(certificateRegistry, _certificateRegistry);
certificateRegistry.update(_certificateRegistry);
certificateRegistry = _certificateRegistry;
}
if (_demandRegistry != address(0)) {
LogDemandRegistryUpdated(demandRegistry, _demandRegistry);
demandRegistry.update(_demandRegistry);
demandRegistry = _demandRegistry;
}
if(_assetConsumingRegistry != address(0)) {
LogAssetConsumingRegistryUpdated(assetConsumingRegistry, _assetConsumingRegistry);
assetConsumingRegistry.update(_assetConsumingRegistry);
assetConsumingRegistry = _assetConsumingRegistry;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Energy Web Foundation
// This file is part of the Origin Application brought to you by the Energy Web Foundation,
// a global non-profit organization focused on accelerating blockchain technology across the energy sector,
// incorporated in Zug, Switzerland.
//
// The Origin Application is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY and without an implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
//
// @authors: slock.it GmbH, Martin Kuechler, martin.kuchler@slock.it
/// @title The Database contract for the AgreementDB of Origin list
/// @notice This contract only provides getter and setter methods and only its logic-contract is able to call the functions
contract DemandDB is Owned {
/// @notice struct for all the data belonging to the matcher
struct MatcherProperties {
// how many Wh per Period
uint targetWhPerperiod;
// amount of Wh the demand has already received
uint currentWhPerperiod;
uint certInCurrentperiod;
uint productionLastSetInPeriod;
// simple address of privateKey-keypair
address matcher;
}
/// @notice struct for all the information belonging to the coupling, can be 0
struct Coupling {
uint producingAssets;
uint consumingAssets;
}
/// @notice struct for all the information that can affect a price
struct PriceDriving {
LocationDefinition.Location location;
uint registryCompliance;
uint assettype;
// proportion between CO2 and wh in percent (100 * CO2 / Wh)
uint minCO2Offset;
bytes32 otherGreenAttributes;
bytes32 typeOfPublicSupport;
bool isInitialized;
}
/// @notice struct for all the general information about a demand
struct GeneralInfo {
address originator;
address buyer;
uint startTime;
uint endTime;
uint timeframe;
uint pricePerCertifiedKWh;
uint currency;
}
/// @notice struct for gather all information
struct Demand {
GeneralInfo general;
Coupling couple;
PriceDriving priceDriving;
MatcherProperties matchProp;
bool enabled;
uint created;
uint demandMask;
}
GeneralInfo generalEmpty;
Coupling coupleEmpty;
PriceDriving priceDrivingEmpty;
MatcherProperties matchPropEmpty;