Registry smart contract for SCN Node operator and SCPI party listings. For Ethereum-based networks.
There are a few concepts which first need to be explained. The Registry smart contract works on Ethereum-based blockchains. That might be ganache if running a local development blockchain, or the pre-production or production chain of the Energy Web Foundation's blockchain. These chains use Etheruem's public-private key cryptography. In the SCN they are used to identify Node operators and SCPI parties on the Smart Charging Network and can be generated in a variety of ways, for example by Metamask.
The SCN Registry allows for two ways of adding and maintaining listings. It can be done directly, whereby a single keypair signs the registry data and sends a transaction to the blockchain network, paying for the transaction fee in the process. This is arguably simpler but requires each keypair to be funded. Alternatively, "raw" transactions can be used, whereby the registry data is signed by the data owner's keypair and sent to the blockchain network using a different, funded keypair.
Therefore, in "direct" transactions, the signer and spender are one, named just the "signer". In contrast, in raw transactions, the "signer" is the data owner, and the "spender" is the one paying for the transaction.
The principle behind the registry is that the nodes, comprising the Smart Charging Network, need a way of discovering counterparties they are not directly connected to. This works in two stages: SCN Node operators (i.e. administrators) can list their node in the registry, which allows SCPI parties (i.e. Charge Point Operators or E-Mobility Service Providers) to link their services to a registered node.
Note that the registry listing must be done by the SCPI party before an SCN Node accepts their credentials registration, so that the SCN Node can ensure the party has correctly linked themselves to that node in the registry.
-
Operator signs a transaction stating they run the SCN Node on domain
https://node.scn.org
. The address of their wallet (0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4
), used to sign the transaction, now points to the domain name. -
SCPI party signs a transaction stating they use the SCN Node of
0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4
. The address of their wallet, (0x0B2E57DDB616175950e65dE47Ef3F5BA3bc29979
) now points to the wallet address of their SCN Node operator. -
SCPI party does the credentials registration handshake with the SCN Node at
https://node.scn.org
. -
Party is now able to send and receive SCPI requests from other SCPI parties on the network.
There are several ways to interact with the SCN Registry, including:
Clone this repository or install the registry npm package:
git clone https://bitbucket.org/smartcharging/scn-registry.git
cd scn-registry
npm install
npx ts-node src --help
npm install -g @smartcharging/registry
scn-registry --help
The private keys of the signer (and optionally spender) are needed for each transaction (modifying state of the contract). Contract calls (i.e. getting data) do not require this.
This can be done in two ways: environment variables or command line flags.
EXPORT SIGNER=0xbe367b774603c65850ee2cf479df809174f95cdb847483db2a6bcf1aad0fa5fd
If using a raw command, the spender is also required:
EXPORT SENDER=0x2f0810c5fc949c846ff64edb26b0b00ca28effaffb9ac867a7b9256c034fe849
Important: do not use these private keys outside of development! They were generated for this guide only.
Alternatively, flags allow setting the signer and spender for each command. Add --help
to any command to get
information about available flags.
By default, the registry will look for a local ganache instance running on http://localhost:8544
. This is the
development chain which can be started with npm run ganache
. This also provides 20 funded keypairs to play around
with (they are generated from a mnemonic, so won't change between restarts).
Each command can be run against additional networks on which the SCN Registry has been deployed using the -n
flag.
This includes Volta,
for the SCN public test environment, as well as the
Energy Web Chain
for production.
To check the domain of a single node operator on the network, use:
scn-registry get-node 0xEada1b2521115e07578DBD9595B52359E9900104
Where 0xEada1b2521115e07578DBD9595B52359E9900104
is the operator's keypair address.
To choose the network to use (as outlined above), set the -n
(--network
) flag:
scn-registry get-node 0xEada1b2521115e07578DBD9595B52359E9900104 --network=volta
scn-registry get-node 0xEada1b2521115e07578DBD9595B52359E9900104 -n prod
To return a list of all nodes and operators, use:
scn-registry list-nodes
SCN Node operators can make their node visible on the network by adding it to the SCN Registry. Creating and updating a listing can be done using the same command:
scn-registry set-node https://node.provider.net
Alternatively, using a raw transaction:
scn-registry set-node-raw https://node.provider.net
Remember to set the signer AND spender for the raw transaction. If not using environment variables, set with the following flags:
scn-registry set-node-raw https://node.provider.net
--signer=0xbe367b774603c65850ee2cf479df809174f95cdb847483db2a6bcf1aad0fa5fd
--spender=0x2f0810c5fc949c846ff64edb26b0b00ca28effaffb9ac867a7b9256c034fe849
Type --help
after any command for more information.
scn-registry set-node-raw --help
If an operator decides not to provide a node any longer, they can remove it from the registry:
scn-registry delete-node
Or as a raw transaction:
scn-registry delete-node-raw
Check the registered information of a given party using their address or SCPI credentials (country_code
and
party_id
):
scn-registry get-party -a 0x0B2E57DDB616175950e65dE47Ef3F5BA3bc29979
scn-registry get-party -c CH CPO
List all registered parties on the network:
scn-registry list-parties
To list a party, the following information is required:
country_code
andparty_id
- role
- SCN Node operator wallet address
The following commands can be used to both create and update the party information.
Using a direct transaction:
scn-registry set-party -c CH CPO -r CPO -o 0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4
Using a raw transaction:
scn-registry set-party-raw -c CH CPO -r CPO -o 0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4
scn-registry set-party -c CH ABC -r CPO EMSP -o 0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4
In this case, the platform must use different wallets for each party_id
:
scn-registry set-party -c CH CPO -r CPO -o 0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4 -s 0xd37f60f3a7c78a72d24e50b9105879c89d249e299699ba762d890276dea73fea
scn-registry set-party -c CH MSP -r EMSP -o 0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4 -s 0x0bdea97cf8736a66f85283d7b0241b5cba51edd809a67af5e8971f441aa8e22b
In this opt-in feature, an SCPI party can list their module implementations, so that other parties on the network can learn which requests are supported. As the usual SCPI version endpoints cannot be used by counterparties, this provides a way for them to discover supported SCPI 2.2 modules.
Implementations are split into sender
and receiver
interfaces. For example, an EMSP may implement the command
module's sender
interface, and a CPO the receiver
interface. Alternatively, a single party_id
with both CPO and
EMSP roles may implement both.
Note that as the purpose of this is to provide modules used typically used in peer-to-peer communication, not every module is available. The following modules can be listed: cdrs, chargingprofiles, commands, locations, sessions, tariffs, tokens.
Following typical SCPI implementations, a CPO could register their modules like so:
scn-registry set-modules \
--sender-interface cdrs locations session tariffs \
--receiver-interface chargingprofiles commands tokens
Whereas an EMSP may register the following modules:
scn-registry set-modules \
--sender-interface commands tokens \
--receiver-interface locations sessions tariffs
In the case that a party_id
implements multiple SCPI roles, both sets of interfaces can be listed.
When sending a request to either interface, the SCN Node of the recipient will know which interface it should
be forwarded to.
scn-registry set-modules \
--sender-interface commands cdrs locations \
--receiver-interface commands cdrs locations
Updating modules is done by the same command and can also be used to remove all listed modules (by providing none):
scn-registry set-modules
Raw transactions can also be used:
scn-registry set-modules-raw
Use the following command to remove a party listing from the registry:
scn-registry delete-party
And with raw transaction:
scn-registry delete-party-raw
npm install @smartcharging/registry
In your project source file, import the registry:
TypeScript:
import { Registry } from "@smartcharging/registry"
JavaScript:
const Registry = require("@smartcharging/registry").Registry
Then, instantiate the Registry class with the environment ("local"
or "volta"
). Optionally set the signer to gain
access to write methods on the contract:
const registryReadOnly = new Registry("local")
console.log(registryReadOnly.mode)
// "r"
const registryReadWrite = new Registry("local", "0xbe367b774603c65850ee2cf479df809174f95cdb847483db2a6bcf1aad0fa5fd")
console.log(registryReadWrite.mode)
// "r+w"
And use the contract:
registryReadOnly.getAllNodes().then(console.log)
registryReadWrite.setNode("https://node.provider.net").then(console.log)
An auto-generated Java library has been provided in ./java
.
Copy it to a project's sourcepath, then connect to it using Web3j:
import snc.openchargingnetwork.contracts.Registry
import org.web3j.protocol.Web3j
import org.web3j.protocol.http.HttpService
import org.web3j.tx.ClientTransactionManager
import org.web3j.tx.gas.StaticGasProvider
val web3 = Web3j.build(HttpService("http://localhost:8544"))
val txManager = ClientTransactionManager(web3, "0x9bC1169Ca09555bf2721A5C9eC6D69c8073bfeB4")
val gasProvider = StaticGasProvider(0.toBigInteger(), 10000000.toBigInteger())
val registry = Registry.load(contractAddress, web3, txManager, gasProvider)
And use it:
val tx = registry.setNode("https://node.provider.net").sendAsync().get()
Clone and install dependencies:
git clone https://bitbucket.org/smartcharging/scn-registry.git
cd scn-registry
npm install
Run Ganache for your local development blockchain:
npm run ganache
Ensure tests are working as expected:
npm test
Initial deployment of the smart contracts (STAGE defaults to "local" - see truffle.js
for more options):
npm migrate --network={{STAGE}}
Publish new contract definitions:
node bin/publish.js {{STAGE}}
The contract definitions are now available to be used in ./contract.defs.{{STAGE}}.json
.
The Java wrapper can be updated using web3j
:
npm run compile
web3j truffle generate ./build/contracts/Registry.json -o ./java -p snc.openchargingnetwork.contracts
Build the TypeScript library:
npm run build
Bump the version number (see https://docs.npmjs.com/cli/version for more):
npm version patch
Publish:
npm publish
You may also use Docker to aid development of other services using the registry. Simply run
docker-compose up
to start ganache and have the contracts deployed automatically. The registry
contract will always have the same owner and address:
- Address:
0x7ab1a34dEb3209a1d6Fd57Ae5f2f81E857bc5ba1
- Owner:
0x627306090abaB3A6e1400e9345bC60c78a8BEf57
If you make changes to the contracts, run docker-compose --build
. This will ensure that the
above is true, giving you the same address.