Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Commit

Permalink
Merge 8677d09 into baef7f2
Browse files Browse the repository at this point in the history
  • Loading branch information
satello committed Jul 25, 2018
2 parents baef7f2 + 8677d09 commit 7948fcc
Show file tree
Hide file tree
Showing 13 changed files with 403 additions and 210 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@
"dependencies": {
"babel-runtime": "^6.26.0",
"eth-sig-util": "^1.4.2",
"ethereumjs-util": "^5.2.0",
"ethjs": "^0.4.0",
"kleros": "^0.0.6",
"kleros-interaction": "^0.0.17",
"kleros-interaction": "^0.0.18",
"lodash": "^4.17.4",
"minimetoken": "^0.2.0",
"truffle-contract": "^2.0.5",
Expand Down
111 changes: 37 additions & 74 deletions src/contracts/abstractions/Arbitrable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import Eth from 'ethjs'

import getContractAddress from '../../utils/getContractAddress'

import AbstractContract from '../AbstractContract'

/**
Expand All @@ -17,76 +21,87 @@ class ArbitrableContract extends AbstractContract {
* @param {string} partyB - Ethereum address of the other party in the contract.
* @param {bytes} arbitratorExtraData - Extra data for the arbitrator.
* @param {string} email - Email address of the contract creator (default empty string).
* @param {string} title - Title of the contract (default empty string).
* @param {string} description - Description of what the contract is about (default empty string).
* @param {...any} args - Extra arguments for the contract.
* @returns {object | Error} - The contract object or an error.
*/
deploy = async (
account,
value,
hashContract,
arbitratorAddress,
timeout,
partyB,
arbitratorExtraData = '',
email = '',
title = '',
description = '',
metaEvidence = {},
...args
) => {
const web3Provider = this._contractImplementation.getWeb3Provider()
const eth = new Eth(web3Provider)
const txCount = await eth.getTransactionCount(account)
// determine the contract address WARNING if the nonce changes this will produce a different address
const contractAddress = getContractAddress(account, txCount)
const metaEvidenceUri = this._StoreProvider.getMetaEvidenceUri(
account,
contractAddress
)
const contractInstance = await this._contractImplementation.constructor.deploy(
account,
value,
hashContract,
arbitratorAddress,
timeout,
partyB,
arbitratorExtraData,
this._contractImplementation.getWeb3Provider(),
metaEvidenceUri,
web3Provider,
...args
)

if (contractInstance.address !== contractAddress)
throw new Error('Contract address does not match meta-evidence uri')

const newContract = await this._StoreProvider.updateContract(
account,
contractInstance.address,
{
hashContract,
partyA: account,
partyB,
arbitrator: arbitratorAddress,
timeout,
email,
title,
description
metaEvidence
}
)

return newContract
}

/**
* Submit evidence.
* Submit evidence. FIXME should we determine the hash for the user?
* @param {string} account - ETH address of user.
* @param {string} name - Name of evidence.
* @param {string} description - Description of evidence.
* @param {string} url - A link to an evidence using its URI.
* @param {string} hash - A hash of the evidence at the URI. No hash if content is dynamic
* @returns {string} - txHash Hash transaction.
*/
submitEvidence = async (account, name, description = '', url) => {
const txHash = await this._contractImplementation.submitEvidence(
submitEvidence = async (account, name, description, url, hash) => {
const contractAddress = this._contractImplementation.contractAddress
// get the index of the new evidence
const evidenceIndex = await this._StoreProvider.addEvidenceContract(
contractAddress,
account,
name,
description,
url
url,
hash
)

await this._StoreProvider.addEvidenceContract(
this._contractImplementation.contractAddress,
// construct the unique URI
const evidenceUri = this._StoreProvider.getEvidenceUri(
account,
name,
description,
url
contractAddress,
evidenceIndex
)
const txHash = await this._contractImplementation.submitEvidence(
account,
evidenceUri
)

return txHash
Expand All @@ -104,40 +119,6 @@ class ArbitrableContract extends AbstractContract {
return userProfile.contracts
}

/**
* Get evidence for contract.
* @param {string} contractAddress - Address of arbitrable contract.
* @returns {object[]} - Array of evidence objects.
*/
getEvidenceForArbitrableContract = async () => {
const arbitrableContractData = await this._contractImplementation.getData()
const partyAContractData = await this._StoreProvider.getContractByAddress(
arbitrableContractData.partyA,
this._contractImplementation.contractAddress
)
const partyBContractData = await this._StoreProvider.getContractByAddress(
arbitrableContractData.partyB,
this._contractImplementation.contractAddress
)

const partyAEvidence = (partyAContractData
? partyAContractData.evidence
: []
).map(evidence => {
evidence.submitter = arbitrableContractData.partyA
return evidence
})
const partyBEvidence = (partyBContractData
? partyBContractData.evidence
: []
).map(evidence => {
evidence.submitter = arbitrableContractData.partyB
return evidence
})

return partyAEvidence.concat(partyBEvidence)
}

/**
* Fetch all data from the store on the current contract.
* @returns {object} - Store data for contract.
Expand All @@ -151,24 +132,6 @@ class ArbitrableContract extends AbstractContract {
this._contractImplementation.contractAddress
)
}

/**
* Get data from the store and contract for Arbitrable Contract.
* @param {string} account - ETH address of user.
* @returns {object} - Contract data.
*/
getData = async account => {
const contractData = await this._contractImplementation.getData()

let storeData = {}
if (account)
storeData = await this._StoreProvider.getContractByAddress(
account,
this._contractImplementation.contractAddress
)

return Object.assign({}, storeData, contractData)
}
}

export default ArbitrableContract
104 changes: 104 additions & 0 deletions src/contracts/implementations/arbitrable/Arbitrable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import _ from 'lodash'

import ContractImplementation from '../../ContractImplementation'
import EventListener from '../../../utils/EventListener'
import httpRequest from '../../../utils/httpRequest'

/**
* Provides interaction with standard Arbitrable contracts
*/
class Arbitrable extends ContractImplementation {
/**
* Constructor ArbitrableTransaction.
* @param {object} web3Provider instance
* @param {string} contractAddress of the contract
*/
constructor(web3Provider, contractArtifact, contractAddress) {
super(web3Provider, contractArtifact, contractAddress)
}

/**
* Get the meta evidence for the contract. Arbitrable Transaction can only have
* one meta-evidence that is submitted on contract creation. Look up meta-evidence event
* and make an http request to the resource.
*/
getMetaEvidence = async () => {
const metaEvidenceLog = await EventListener.getEventLogs(
this,
'MetaEvidence',
0,
'latest',
{ _metaEvidenceID: 0 }
)

if (!metaEvidenceLog[0]) return {} // NOTE better to throw errors for missing meta-evidence?

const metaEvidenceUri = metaEvidenceLog[0].args._evidence
// FIXME caching issue need a query param to fetch from AWS
const metaEvidenceResponse = await httpRequest(
'GET',
metaEvidenceUri + '?nocache'
)

if (metaEvidenceResponse.status >= 400)
throw new Error(`Unable to fetch meta-evidence at ${metaEvidenceUri}`)
return metaEvidenceResponse.body || metaEvidenceResponse
}

/**
* Get the evidence submitted in a dispute.
*/
getEvidence = async () => {
await this.loadContract()
const arbitratorAddress = await this.contractInstance.arbitrator()
await this.loadContract()
const disputeId = (await this.contractInstance.disputeID()).toNumber()

// No evidence yet as there is no dispute
if (_.isNull(disputeId)) return []

const evidenceLogs = await EventListener.getEventLogs(
this,
'Evidence',
0,
'latest',
{ _disputeID: disputeId, _arbitrator: arbitratorAddress }
)

// TODO verify hash and data are valid if hash exists
return Promise.all(
evidenceLogs.map(async evidenceLog => {
const evidenceURI = evidenceLog.args._evidence
const evidence = await httpRequest('GET', evidenceURI)
const submittedAt = (await this._Web3Wrapper.getBlock(
evidenceLog.blockNumber
)).timestamp
return {
...evidence.body,
...{ submittedBy: evidenceLog.args._party, submittedAt }
}
})
)
}

/**
* Fetch all standard contract data.
*/
getContractData = async () => {
await this.loadContract()

const [metaEvidence, partyA, partyB] = await Promise.all([
this.getMetaEvidence(),
this.contractInstance.partyA(),
this.contractInstance.partyB()
])

return {
partyA,
partyB,
metaEvidence
}
}
}

export default Arbitrable
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import ArbitrablePermissionListArtifact from 'kleros-interaction/build/contracts/ArbitrablePermissionList'

import * as ethConstants from '../../../constants/eth'
import Arbitrable from './Arbitrable'
import deployContractAsync from '../../../utils/deployContractAsync'

/**
* Provides interaction with an Arbitrable Transaction contract deployed on the blockchain.
*/
class ArbitrablePermissionList extends Arbitrable {
/**
* Constructor ArbitrableTransaction.
* @param {object} web3Provider instance
* @param {string} contractAddress of the contract
*/
constructor(web3Provider, contractAddress) {
super(web3Provider, ArbitrablePermissionListArtifact, contractAddress)
}

/**
* Deploy ArbitrablePermissionList. TODO
* @param {object} account Ethereum account (default account[0])
* @param {number} value funds to be placed in contract
* @param {object} web3Provider web3 provider object
* @returns {object} truffle-contract Object | err The deployed contract or an error
*/
// static deploy = async (
// account,
// value = ethConstants.TRANSACTION.VALUE,
// web3Provider
// ) => {
// // const contractDeployed = await deployContractAsync()
// //
// // return contractDeployed
// }

getItemByDisputeId = async disputeId => {
await this.loadContract()

return this.contractInstance.disputeIDToItem(disputeId)
}
}

export default ArbitrablePermissionList

0 comments on commit 7948fcc

Please sign in to comment.