πŸ’§ Integration of TCRs, CPM and Ocean Tokens in Solidity
Clone or download
aabdulwahed Merge pull request #280 from oceanprotocol/refactor/contracts
small changes to contracts and deployment, getting ready for sol 0.5.x
Latest commit f062dec Jan 23, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Standardize contrib guidelines across public repos Nov 30, 2018
.travis Push report files to new repo Jan 7, 2019
artifacts 0.6.0 -> kovan Jan 21, 2019
contracts small changes to contracts and deployment, getting ready for sol 0.5.x Jan 23, 2019
doc upgraded to zos 2.0.2 Jan 9, 2019
migrations Contracts upgraded to zos Jan 8, 2019
scripts Changing artifacts UID and GID Jan 22, 2019
src/main/java removing java stubs Nov 22, 2018
test dont fail if file is not there Jan 18, 2019
.bumpversion.cfg Bumped version 0.6.8 -> 0.6.9 Jan 21, 2019
.dockerignore remove ganache from docker handling Dec 20, 2018
.editorconfig proper js linting Jun 19, 2018
.eslintrc adapted eslint Sep 17, 2018
.gitattributes make GitHub's Linguist detect Solidity code Sep 7, 2018
.gitignore ignore .zos.lock Jan 17, 2019
.maven.xml debug Nov 5, 2018
.release-it.json disabled npm publish Aug 8, 2018
.solcover.js fix unit tests code coverage by excluding test contracts Jan 16, 2019
.soliumignore removed migrations from .soliumignore again Sep 13, 2018
.soliumrc.json fixed linting issue Jan 9, 2019
.travis.yml Fix setuptools pip Jan 21, 2019
Dockerfile Added jq to docker image Jan 21, 2019
LICENSE readme cleanup Jun 18, 2018
MANIFEST.in Fix packaging of contracts in whl distribution. Jul 17, 2018
README.md 0.6 addresses Jan 21, 2019
RELEASE_PROCESS.md Update link Jan 8, 2019
bumpversion.sh Included helper script Aug 24, 2018
ethpm.json rename repo to keeper-contracts Jun 19, 2018
package-lock.json remove branching and use require instead in fitchain conditions Jan 22, 2019
package.json Bumped version 0.6.8 -> 0.6.9 Jan 21, 2019
pom.xml Bumped version 0.6.8 -> 0.6.9 Jan 21, 2019
requirements_dev.txt Minnor fixes Jan 10, 2019
setup.cfg Bumped version 0.6.8 -> 0.6.9 Jan 21, 2019
setup.py Bumped version 0.6.8 -> 0.6.9 Jan 21, 2019
truffle.js small changes to contracts and deployment, getting ready for sol 0.5.x Jan 23, 2019

README.md

banner

keeper-contracts

πŸ’§ Integration of TCRs, CPM and Ocean Tokens in Solidity oceanprotocol.com

Dockerhub TravisCI Ascribe Greenkeeper
Docker Build Status Build Status js ascribe Greenkeeper badge

πŸ²πŸ¦‘ THERE BE DRAGONS AND SQUIDS. This is in alpha state and you can expect running into problems. If you run into them, please open up a new issue. πŸ¦‘πŸ²


Ocean Keeper implementation where we put the following modules together:

  • TCRs: users create challenges and resolve them through voting to maintain registries;
  • Ocean Tokens: the intrinsic tokens circulated inside Ocean network, which is used in the voting of TCRs;
  • Marketplace: the core marketplace where people can transact with each other with Ocean tokens.

Table of Contents


Get Started

For local development you can either use Docker, or setup the development environment on your machine.

Docker

The most simple way to get started is with Docker:

git clone git@github.com:oceanprotocol/keeper-contracts.git
cd keeper-contracts/

docker build -t oceanprotocol/keeper-contracts:0.1 .
docker run -d -p 8545:8545 oceanprotocol/keeper-contracts:0.1

or simply pull it from docker hub:

docker pull oceanprotocol/keeper-contracts
docker run -d -p 8545:8545 oceanprotocol/keeper-contracts

Which will expose the Ethereum RPC client with all contracts loaded under localhost:8545, which you can add to your truffle.js:

module.exports = {
    networks: {
        development: {
            host: 'localhost',
            port: 8545,
            network_id: '*',
            gas: 6000000
        },
    }
}

Local development

As a pre-requisite, you need:

  • Node.js >=6, <=v10.13.0
  • npm

Clone the project and install all dependencies:

git clone git@github.com:oceanprotocol/keeper-contracts.git
cd keeper-contracts/

# install dependencies
npm i

# install RPC client globally
npm install -g ganache-cli

Compile the solidity contracts:

npm run compile

In a new terminal, launch an Ethereum RPC client, e.g. ganache-cli:

ganache-cli

Switch back to your other terminal and deploy the contracts:

npm run migrate

# for redeployment run this instead
npm run migrate -- --reset

Testnet deployment

Nile Testnet

Follow the steps for local deployment. Make sure that the address 0x90eE7A30339D05E07d9c6e65747132933ff6e624 is having enough (~1) Ether.

export NMEMORIC=<your nile nmemoric>
npm run migrate:nile

The transaction should show up on the account: 0x90eE7A30339D05E07d9c6e65747132933ff6e624

The contract addresses deployed on Ocean Nile testnet:

Contract Version Address
AccessConditions v0.6.0 0x416276914b5a6dd1b88bb0e35096200b08131113
ComputeConditions v0.6.0 0x575ab120a815488ced316545ef32a25be1e93d3f
DIDRegistry v0.6.0 0xc3a017f586a92b836525814733a479eaf744e03c
Dispenser v0.6.0 0x8f5ceb3faffa39d265dfcaff3791d9aa5a621e31
FitchainConditions v0.6.0 0x9068f22f687f328f66323e8472fef29fde70fe8a
OceanToken v0.6.0 0xdf4c75a5a64c86e22ac5aa2282c96bee7ae6f951
PaymentConditions v0.6.0 0x918e5bce975865bf2ff3435b1d3b4cacfd89b91c
ServiceExecutionAgreement v0.6.0 0x57ae92819e5ea05d6c7af0686617e96d741a54c9

Kovan Testnet

Follow the steps for local deployment. Make sure that the address 0x2c0d5f47374b130ee398f4c34dbe8168824a8616 is having enough (~1) Ether.

If you managed to deploy the contracts locally do:

export INFURA_TOKEN=<your infura token>
export NMEMORIC=<your kovan nmemoric>
npm run migrate:kovan

The transaction should show up on: https://kovan.etherscan.io/address/0x2c0d5f47374b130ee398f4c34dbe8168824a8616

The contract addresses deployed on Kovan testnet:

Contract Version Address
AccessConditions v0.6.0 0x294aabd9559b547069c48b45d14bb1ea8d81e440
ComputeConditions v0.6.0 0x7319f48f48868b0894071e7a654705723371b785
DIDRegistry v0.6.0 0x2499c2969b6170c7484044cbecf26ea9d3c3903b
Dispenser v0.6.0 0x06e303d09d79a396dbe3fd2d00cfdc39906e6306
FitchainConditions v0.6.0 0xa5c5114d62119754ab2b123352ce482bbafb9452
OceanToken v0.6.0 0x3df8b3699bc735c8ac7a6132052b791c24d3a3c4
PaymentConditions v0.6.0 0xde5c235c92a828c119532e6fad1d63f77f676d21
ServiceExecutionAgreement v0.6.0 0xd7ab46800adfd662ffe47af8bcc46e3297bef822

Libraries

To facilitate the integration of the Ocean Keeper Smart Contracts, Python and Javascript libraries are ready to be integrated. Those libraries include the Smart Contract ABI's. Using these libraries helps to avoid compiling the Smart Contracts and copying the ABI's manually to your project. In that way the integration is cleaner and easier. The libraries provided currently are:

  • JavaScript npm package - As part of the @oceanprotocol npm organization, the npm keeper-contracts package provides the ABI's to be imported from your JavaScript code.
  • Python Pypi package - The Pypi keeper-contracts package provides the same ABI's to be used from Python.
  • Java Maven package - It's possible to generate the maven stubs to interact with the smart contracts. It's necessary to have locally web3j and run the scripts/maven.sh script

Testing

Run tests with npm test, e.g.:

npm test -- test/Auth.Test.js

Code Linting

Linting is setup for JavaScript with ESLint & Solidity with Ethlint.

Code style is enforced through the CI test process, builds will fail if there're any linting errors.

Documentation

Use Case 1: Register data asset

const Market = artifacts.require('OceanMarket.sol')
...
// get instance of OceanMarket contract
const market = await Market.deployed()
...
// generate resource id
const name = 'resource name'
const resourceId = await market.generateId(name, { from: accounts[0] })
const resourcePrice = 100

// register data asset on-chain
await market.register(resourceId, resourcePrice, { from: accounts[0] })

Use Case 2: Authorize access with OceanAuth contract

Here is an example of authorization process with OceanAuth contract.

accounts[0] is provider and accounts[1] is consumer.

Note that different cryptographic algorithms can be chosen to encrypt and decrypt access token using key pairs (i.e., public key and private key). This example uses URSA to demonstrate the process for illustration purpose.

const Token = artifacts.require('OceanToken.sol')
const Market = artifacts.require('OceanMarket.sol')
const Auth = artifacts.require('OceanAuth.sol')
...
const ursa = require('ursa')
const ethers = require('ethers')
const Web3 = require('web3')
...
// get instances of deployed contracts
const token = await Token.deployed()
const market = await Market.deployed()
const auth = await Auth.deployed()
...
// consumer request some testing tokens to buy data asset
await market.requestTokens(200, { from: accounts[1] })
// consumers approve withdraw limit of their funds
await token.approve(market.address, 200, { from: accounts[1] })
...
// consumer generates temporary key pairs in local
const modulusBit = 512
const key = ursa.generatePrivateKey(modulusBit, 65537)
const privatePem = ursa.createPrivateKey(key.toPrivatePem())
const publicPem = ursa.createPublicKey(key.toPublicPem())
const publicKey = publicPem.toPublicPem('utf8')
...
// consumer initiate a new access request and pass public key
await auth.initiateAccessRequest(resourceId, accounts[0], publicKey, expireTime, { from: accounts[1] })
// provider commit the access request
await auth.commitAccessRequest(accessId, true, expireTime, '', '', '', '', { from: accounts[0] })
...
// consumer sends the payment to OceanMarket contract
await market.sendPayment(accessId, accounts[0], price, expireTime, { from: accounts[1] })
...
// provider encrypt "JSON Web Token" (JWT) using consumer's temp public key
const encJWT = getPubKeyPem.encrypt('JWT', 'utf8', 'hex')
// provider delivers the encrypted JWT on-chain
await auth.deliverAccessToken(accessId, `0x${encJWT}`, { from: accounts[0] })
...
// consumer generate signature of encrypte JWT and send to provider
const prefix = '0x'
const hexString = Buffer.from(onChainencToken).toString('hex')
const signature = web3.eth.sign(accounts[1], `${prefix}${hexString}`)
...
// provider verify the signature from consumer to prove delivery of access token
const sig = ethers.utils.splitSignature(signature)
const fixedMsg = `\x19Ethereum Signed Message:\n${onChainencToken.length}${onChainencToken}`
const fixedMsgSha = web3.sha3(fixedMsg)
await auth.verifyAccessTokenDelivery(accessId, accounts[1], fixedMsgSha, sig.v, sig.r, sig.s, { from: accounts[0] })

New Version / New Release

See RELEASE_PROCESS.md

Contributing

See the page titled "Ways to Contribute" in the Ocean Protocol documentation.

Prior Art

This project builds on top of the work done in open source projects:

License

Copyright 2018 Ocean Protocol Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.