Code Monkey home page Code Monkey logo

ara-contracts's Introduction

ara-contracts

Build Status

Blockchain interactions in Ara modules.

Overview

This repository contains all contracts deployed by Ara. There are five global contracts used throughout the entire network:

  1. AraToken.sol - The Ara ERC20 token contract
Network Type Address Verified Source
Ropsten Proxy 0x06be7386f99c38d26d53d83cbf1b9f438930694b https://ropsten.etherscan.io/address/0x06be7386f99c38d26d53d83cbf1b9f438930694b#code
Ropsten Implementation 0xc349b831e83248368aa69c42fa717f700fecb8ce https://ropsten.etherscan.io/address/0xc349b831e83248368aa69c42fa717f700fecb8ce#code
Mainnet Proxy 0xa92e7c82b11d10716ab534051b271d2f6aef7df5 https://etherscan.io/address/0xa92e7c82b11d10716ab534051b271d2f6aef7df5#code
Mainnet Implementation 0xb8ca408aff631b65021850cd7ebf8eac7f3c0312 https://etherscan.io/address/0xb8ca408aff631b65021850cd7ebf8eac7f3c0312#code
  1. AFS.sol - The AFS standard contract defines the API for interacting with AFSs on the blockchain (see the accompanying RFC). The current AFS Standard version is 4. Future Standards are not necessarily sequential or superseding in nature and may exist in parallel (e.g., another AFS Standard may be named ecommerce which can be used for an entirely different class of AFSs). In order to estimate costs for interacting with the Standard without needing to deploy a proxy beforehand, we additionally deploy a version of all AFS Standards without modifiers which are named ${version name}_estimate. The current AFS Estimate Standard version is 4_estimate.
Network Version Address Verified Source
Ropsten 6 0x54a206a07e18a1fed118e3f946db4e3b7de35049 https://ropsten.etherscan.io/address/0x54a206a07e18a1fed118e3f946db4e3b7de35049#code
Ropsten 6_estimate 0x5437dF777Fa849dadD67A7F7fD88F9deB657166A https://ropsten.etherscan.io/address/0x5437df777fa849dadd67a7f7fd88f9deb657166a#code
Mainnet 2 0x7bd36ca16161d8290986d4dca8265c2b5ca340fe https://etherscan.io/address/0x7bd36ca16161d8290986d4dca8265c2b5ca340fe#code
Mainnet 2_estimate 0x39798776e91874583abf1e36c77a49446a8f3cea https://etherscan.io/address/0x39798776e91874583abf1e36c77a49446a8f3cea#code
  1. Library.sol - The contract where content ownership across the network is consolidated and tracked
Network Type Address Verified Source
Ropsten Proxy 0xec26659b209e9e89a23d26298ba0359b1b6c7f76 https://ropsten.etherscan.io/address/0xec26659b209e9e89a23d26298ba0359b1b6c7f76#code
Ropsten Implementation 0x991198dac7e5aa586ed129735e142c01ad81ed69 https://ropsten.etherscan.io/address/0x991198dac7e5aa586ed129735e142c01ad81ed69#code
Mainnet Proxy 0xC04B27294bb3d1abaAC39F2F97B4A95810bA91dd https://etherscan.io/address/0xc04b27294bb3d1abaac39f2f97b4a95810ba91dd#code
Mainnet Implementation 0x991198dac7e5aa586ed129735e142c01ad81ed69 https://etherscan.io/address/0xfdb1b5adf9cc13d8434f3d493f345a8bc46afcdc#code
  1. Registry.sol - The contract where AFS proxies and AFS standards are created, linked, and tracked
Network Type Address Verified Source
Ropsten Proxy 0xdb8f8d6cc69a346d608e64c2ddb5b3ed7e4b32d6 https://ropsten.etherscan.io/address/0xdb8f8d6cc69a346d608e64c2ddb5b3ed7e4b32d6#code
Ropsten Implementation 0xbbc4d435c7426cef12c4b6d4d12552a1e7de24ef https://ropsten.etherscan.io/address/0xbbc4d435c7426cef12c4b6d4d12552a1e7de24ef#code
Mainnet Proxy 0x17a6033535b1ab8cbbb430c62782d164d8f6ac45 https://etherscan.io/address/0x17a6033535b1ab8cbbb430c62782d164d8f6ac45#code
Mainnet Implementation 0x814F2ca790454c795F5e515A394CbFB7bE499737 https://etherscan.io/address/0x814f2ca790454c795f5e515a394cbfb7be499737#code
  1. AraRegistry.sol - The contract used to deploy the Library, Registry, and AraToken contracts
Network Type Address Verified Source
Ropsten Implementation 0x6bda4b9fcb082e72b30081393d4ae7b05360e517 https://ropsten.etherscan.io/address/0x6bda4b9fcb082e72b30081393d4ae7b05360e517#code
Mainnet Implementation 0xf8314584346fc84e96b36113784f6b562e5b01af https://etherscan.io/address/0xf8314584346fc84e96b36113784f6b562e5b01af#code

This repository also provides programmatic (see the API section) and command-line interfaces (see the Usage section) for interacting with the contracts.

AFS Proxies

In addition to these global contracts, Ara deploys a proxy contract for each individual AFS that gets committed to the blockchain (see ara-filesystem and proxy architecture). This contract serves as the storage layer for AFSs on the blockchain, while the AFS Standard serves as the API (business logic layer) for interacting with AFSs on the blockchain.

Stability

Stability: 2 - Stable. Compatibility with the npm ecosystem is a high priority.

Although the API is stable, this project is still in alpha development and is not yet ready to be used in a production environment.

Dependencies

Installation

$ npm install arablocks/ara-contracts --save

Usage

See CLI Usage docs here.

Ara Privatenet

The contracts in this repository are currently deployed on Ara Privatenet and Ethereum Ropsten Testnet. You must be connected to one of these networks in order to be on the same network as the rest of the Ara team during development and to use the addresses in constants.js. You may run a local Ganache instance for local development.

API

Any value inputted into token functions must be strings to avoid precision error All transaction callbacks (onhash, onreceipt, onconfirmation, onerror, and onmined) are optional. For more information, see ara-util.

Purchase

Registry

Library

Rewards

Token

Ownership

async purchase(opts)

Purchases an AFS and adds it to the requester's library.

  • opts
    • requesterDid - The DID of the person making the purchase
    • contentDid - The DID of the content being purchased
    • password - The requester's password
    • budget - The budget in Ara to allocate for the initial download job
    • gasPrice - Optional gas price in GWei
    • approve - Optional boolean indicating whether to send the Approve transaction prior to the Purchase transaction
    • keyringOpts - Optional keyring options
    • approveCallbacks - Optional callbacks for the Approve transaction
      • onhash
      • onreceipt
      • onconfirmation
      • onerror
      • onmined
    • purchaseCallbacks - Optional callbacks for the Purchase transaction
      • onhash
      • onreceipt
      • onconfirmation
      • onerror
      • onmined

Returns object:

  • receipt - Transaction receipt
  • jobId - The job ID generated for the initial download
const requesterDid = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const contentDid = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const budget = 100
const { receipt, jobId } = await purchase({
  requesterDid,
  contentDid,
  password,
  budget
})

async registry.proxyExists(contentDid)

Checks if the proxy for a content DID exists.

  • contentDid - The DID of the content to check

Returns a boolean indicating whether a proxy contract exists for a contentDid.

const exists = await registry.proxyExists(contentDid)

async registry.getProxyAddress(contentDid)

Gets the address of a proxy given a content DID

  • contentDid - The DID of the content
const address = await registry.getProxyAddress(contentDid)

async registry.upgradeProxy(opts)

Upgrades a proxy to another AFS standard.

  • opts
    • contentDid - The DID of the content
    • password - The password of the owner of the proxy
    • afsPassword - The password of the AFS
    • version - The AFS standard version to upgrade to
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns a boolean indicating whether the proxy was successfully upgraded.

const upgraded = await registry.upgradeProxy({ contentDid, password, afsPassword, version: '1' })

async registry.deployProxy(opts)

Deploys a proxy to an AFS standard.

  • opts
    • contentDid - The DID of the content to deploy a proxy for
    • password - The password of the owner of the AFS
    • afsPassword - The password of the AFS
    • version - The version to use with this proxy
    • estimate - Optional flag to check cost of deployProxy
    • ownerDid - Optional owner DID used in conjunction with estimate to bypass needing a real AFS
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns the address at which the proxy was deployed.

const address = await registry.deployProxy({ contentDid, password, afsPassword, version: '1' })

async registry.getProxyVersion(contentDid)

Gets the AFS Standard version a proxy is using.

  • contentDid - The DID of the content
const version = await registry.getProxyVersion(contentDid)

async registry.getLatestStandard()

Gets the latest AFS contract standard.

const address = await registry.getLatestStandard()

async registry.getStandard(version)

Gets the address of an AFS contract standard.

  • version - The version of the AFS contract standard
const address = await registry.getStandard('1')

async registry.deployNewStandard(opts)

Compiles and deploys a new AFS standard.

  • opts
    • requesterDid - The DID of the person deploying the standard
    • password - The password of the person deploying the standard
    • version - The version of the standard
    • paths - The solidity dependencies of the standard
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns the address at which the standard was deployed.

const version = '1'
const paths = ['./contracts/ignored_contracts/AFS.sol',
               './contracts/ignored_contracts/Library.sol',
               './contracts/ignored_contracts/Registry.sol',
               './contracts/AraProxy.sol',
               './contracts/ignored_contracts/AraToken.sol']
const address = await registry.deployNewStandard({
  requesterDid,
  password,
  version,
  paths
})

async library.getLibrary(requesterDid)

Gets the content DIDs purchased by the requesterDID.

  • requesterDid - The DID of the owner of the library
const lib = await library.getLibrary(did)

async library.getLibrarySize(requesterDid)

Gets the size of requesterDid's library.

  • requesterDid - The DID of the owner of the library
const size = await library.getLibrarySize(did)

async library.getLibraryItem(opts)

Gets the DID of the item at the provided index in requesterDid's library.

  • opts
    • requesterDid - The DID of the owner of the library
    • index - The index of the content to retrieve
const contentDid = await library.getLibraryItem({ requesterDid, index: 1 })

async library.hasPurchased(opts)

  • opts
    • contentDid - DID of the content to check the purchase of
    • purchaserDid - DID of purchaser
    • keyringOpts - optional Keyring options
const purchased = await library.hasPurchased({
  contentDid: 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85',
  purchaserDid: 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
})

async rewards.submit(opts)

Submits new DCDN job.

  • opts
    • requesterDid - The DID of the person submitting the job
    • contentDid - The DID of the content this job is for
    • password - The password of the person submitting the job
    • job
      • jobId - The jobId of the job being submitted
      • budget - The budget to allocate for the job
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const jobId = '0x7dc039cfb220029c371d0f4aabf4a956ed0062d66c447df7b4595d7e11187271'
const budget = 10
const receipt = await rewards.submit({
  requesterDid,
  contentDid,
  password,
  job: {
    jobId,
    budget
  }
})

async rewards.allocate(opts)

Allocates rewards amongst farmers for jobId.

  • opts
    • requesterDid - The DID of the person who submitted the job
    • contentDid - The DID of the content the job is for
    • password - The password of the person who submitted the job
    • job
      • jobId - The jobId of the job to allocate for
      • farmers - The Ethereum addresses of the farmers to reward
      • rewards - The reward amounts in Ara tokens to split amongst farmers, respectively
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined
const jobId = '0x7dc039cfb220029c371d0f4aabf4a956ed0062d66c447df7b4595d7e11187271'
const farmers = ['0xF9403C6DA32DB4860F1eCB1c02B9A04D37c0e36e',
                 '0x70693d8f4e1c9bA1AE0870C35128BaDfDcF28FBc',
                 '0x19d6a7D8bB09e8A6d733a9c8D9fe7b964fD8F45e',
                 '0x629483C72b5191C1b522E887238a0A522b1D4F74']
const distribution = [10, 20, 30, 40]
await rewards.allocate({
  requesterDid,
  contentDid,
  password,
  job: {
    jobId,
    farmers,
    rewards: distribution
  }
})

async rewards.redeem(opts)

Redeem Ara tokens (resulting from allocation return or from rewards) from AFS contract.

  • opts
    • farmerDid - The DID of the person redeeming tokens
    • contentDid - The DID of the content to redeem from
    • password - The password of the person redeeming tokens
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns the number of Ara tokens redeemed.

const balance = await rewards.redeem({
  farmerDid,
  contentDid,
  password
})

async rewards.getBudget(opts)

Gets the budget for jobId.

  • opts
    • contentDid - The DID of the content that has jobId
    • jobId - The jobId of the job to get the budget for
const budget = await rewards.getBudget({
  contentDid,
  jobId
})

async rewards.getJobOwner(opts)

Gets the address of the owner of a jobId.

  • opts
    • contentDid - The DID of the content that has jobId
    • jobId - The jobId of the job to get the owner for
const owner = await rewards.getJobOwner({
  contentDid,
  jobId
})

async rewards.getRewardsBalance(opts)

Gets the balance (resulting from allocation return or from rewards) of farmerDid stored in contentDid.

  • opts
    • farmerDid - The DID of the person to check the balance of
    • contentDid - The DID of the content where the balance is stored
    • password - The password of the person to check the balance of
    • keyringOpts - optional Keyring options
const balance = await rewards.getRewardsBalance({
  farmerDid,
  contentDid,
  password
})

async token.balanceOf(did, keyringOpts)

Queries for the balance in Ara of an identity.

  • did - The DID of the account to get the balance for
  • keyringOpts - optional Keyring options
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const balance = await token.balanceOf(did) // 100.5

async token.totalSupply()

Gets the total circulating supply of Ara tokens.

const supply = await token.totalSupply() // 1000000000

async token.allowance(opts)

Gets the amount in Ara that a spender is allowed to spend of an owner.

  • owner - DID of the owner of the Ara tokens to be spent
  • spender - DID of the account that will be spending owner's tokens
const owner = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const spender = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const allowance = await token.allowance({ owner, spender })

async token.transfer(opts)

Transfers Ara from one account to another.

  • opts
    • did - DID of the account that is sending the Ara
    • password - Password of the account sending Ara
    • to - DID of the account to receive the tokens
    • val - Amount to transfer
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'
const recipient = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'

const receipt = await token.transfer({
  did,
  password,
  to: recipient,
  val: '500'
})

async token.approve(opts)

Sets the approved token amount to be spent on an owner's behalf. This will overwrite any previous approvals.

  • opts
    • did - DID of the account that owns the Ara
    • password - Password of the owning account
    • spender - DID of the account that will be spending the tokens
    • val - Amount to approve
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'
const recipient = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'

const receipt = await token.approve({
  did,
  password,
  spender,
  val: '500'
})

async token.transferFrom(opts)

Transfers Ara from one address to another. This differs from transfer by requiring the tokens to be first approved to be spent.

  • opts
    • from - The DID of the origin account of the Ara tokens to transfer (this account must approve did to perform the transfer beforehand)
    • to - DID of the account that will be receiving the tokens
    • val - Amount of Ara to transfer
    • did - DID of the account initiating the transfer on behalf of from
    • password - Password of the account initiating the transfer
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const origin = 'did:ara:08228219008e3c7ab8b7f23a161c196be44ff33525ebea01d841b707b34b7adc'
const recipient = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'

const receipt = await token.transferFrom({
  from: origin,
  to: recipient,
  val: '500',
  did,
  password,
})

async token.increaseApproval(opts)

Increases the approved amount that a spender can spend on behalf of an owner. This will not overwrite any existing approved amount, just increase it.

  • opts
    • spender - DID of the spender
    • did - DID of the account that owns the Ara
    • password - Password of the owning account
    • val - Amount to increase the approval by
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const spender = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'

const receipt = await token.increaseApproval({
  spender,
  did,
  password,
  val: '10'
})

async token.decreaseApproval(opts)

Decreases the approved amount that a spender can spend on behalf of an owner. This will not overwrite any existing approved amount, just decrease it.

  • opts
    • spender - DID of the spender
    • did - DID of the account that owns the Ara
    • password - Password of the owning account
    • val - Amount to decrease the approval by
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'
const spender = 'did:ara:114045f3883a21735188bb02de024a4e1451cb96c5dcc80bdfa1b801ecf81b85'

const receipt = await token.decreaseApproval({
  spender,
  did,
  password,
  val: '10'
})

async token.modifyDeposit(opts)

Modifies the current amount deposited for rewards for a particular account.

  • opts
    • did - DID of the account to update the deposit for
    • password - password of the account
    • val - value as string to deposit/withdraw
    • withdraw - boolean whether this should be a deposit or withdraw (defaults to false if not given)
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

// deposits 50 Ara
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'

const receipt = await token.modifyDeposit({
  did,
  password,
  val: '50'
})

// withdraws 50 Ara from deposit
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const password = 'password'

const receipt = await token.modifyDeposit({
  did,
  password,
  val: '50',
  withdraw: true
})

async token.getAmountDeposited(did)

Gets the current amount deposited by an account to be used for redeeming rewards.

  • did - DID of the account to get the deposit balance for
  • keyringOpts - optional Keyring options
const did = 'did:ara:a51aa651c5a28a7c0a8de007843a00dcd24f3cc893522d3fb093c2bb7a323785'
const amount = await token.getAmountDeposited(did) // '100'

token.constrainTokenValue(val)

Constrains token amount used in the EVM to its nominal value (Ara supports 18 decimals).

  • val - The unconstrained token value as a String
const expandedValue = '1000000000000000000' // 1 Ara Token
const constrainedValue = token.constrainTokenValue(expandedValue) // constrainedValue === '1'

token.expandTokenValue(val)

Expands nominal token value to its expanded form used in the EVM (Ara supports 18 decimals).

  • val - The expanded token value as a String
const constrainedValue = '1'
const expandedValue = token.expandTokenValue(constrainedValue) // expandedValue === '1000000000000000000'

async ownership.approveOwnershipTransfer(opts)

Approves an AFS ownership transfer request.

  • opts
    • contentDid - The DID of the content to transfer ownership
    • password - The password of the current owner
    • afsPassword - The password of the AFS
    • newOwnerDid - The DID of the account to transfer ownership to
    • estimate - optional Flag to check cost of approveOwnershipTransfer
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const receipt = await ownership.approveOwnershipTransfer({
  contentDid,
  password,
  afsPassword,
  newOwnerDid
})

async ownership.revokeOwnershipRequest(opts)

Revokes an outstanding ownership request of an AFS.

  • opts
    • requesterDid - The DID of the account requesting ownership
    • contentDid - The DID of the content to transfer ownership
    • password - The password of the account requesting ownership
    • estimate - optional Flag to check cost of revokeOwnershipRequest
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const receipt = await ownership.revokeOwnershipRequest({
  requesterDid,
  contentDid,
  password
})

async ownership.requestOwnership(opts)

Requests ownership of an AFS.

  • opts
    • requesterDid - The DID of the account requesting ownership
    • contentDid - The DID of the content to transfer ownership
    • password - The password of the account requesting ownership
    • estimate - optional Flag to check cost of requestOwnership
    • gasPrice - Optional gas price in GWei
    • keyringOpts - Optional keyring options
    • onhash
    • onreceipt
    • onconfirmation
    • onerror
    • onmined

Returns transaction receipt object.

const receipt = await ownership.requestOwnership({
  requesterDid,
  contentDid,
  password
})

async ownership.hasRequested(opts)

Checks if a requester DID has requested ownership of an AFS.

  • opts
    • requesterDid - The DID of the account requesting ownership
    • contentDid - The DID of the content in question
    • keyringOpts - optional Keyring options

Returns boolean.

const hasRequested = await ownership.hasRequested({ requesterDid, contentDid })

async ownership.getOwner(contentDid)

Gets the Ethereum address of the owner of an AFS.

  • contentDid - The DID of the content to get the owner for
const owner = await ownership.getOwner(contentDid)

Contributing

Releases follow Semantic Versioning

See Also

License

LGPL-3.0

ara-contracts's People

Contributors

bplaster avatar cckelly avatar hdao1121 avatar madelinecameron avatar markgeeromano avatar vipyne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ara-contracts's Issues

Migration doesn't deploy standard

truffle migrate deploys all necessary contracts except the standard. This has to be done in a separate command. Including it in the migration after the rest of the contracts are deployed would make all of this possible in one step.

Info statements should be in units of Ara

Expected Behavior

submit in rewards.js should have info statements print values in units of Ara.

Actual Behavior

in the following statement, _budget is not in units of Ara.

_budget in

    await proxyContract.events.BudgetSubmitted({ fromBlock: 'latest', function(error) { debug(error) } })
      .on('data', (log) => {
        const { returnValues: { _did, _jobId, _budget } } = log
        info(requesterDid, 'budgeted', _budget, 'tokens for job', _jobId)
      })
      .on('changed', (log) => {
        debug(`Changed: ${log}`)
      })
      .on('error', (log) => {
        debug(`error:  ${log}`)
      })

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

Index event parameters

If we index event parameters, we can use the filter option provided by web3 to query for events whose return values we specify. It's a minimal change and shouldn't cost much gas

event Transfer(address from, address to, uint256 value);

becomes

event Transfer(address indexed from, address indexed to, uint256 value);

If we don't index, querying becomes unscalable. This is the current function that sums all rewards a given user has earned for a given AFS.

const totalRewards = (await AFSContract.getPastEvents('Redeemed'))
  .reduce((sum, { returnValues }) =>
     returnValues._sender === userEthAddress
	  ? sum += Number(araContracts.token.constrainTokenValue(returnValues._amount))
	  : sum
 0)

It pulls back alllll the Redeemed events the contract ever fired then filters out the ones we don't want. Instead, we could do:

const totalRewards = (await AFSContract.getPastEvents('Redeemed', { filter: { _farmer: did }))
  .reduce((sum, { returnValues }) =>
    ? sum += Number(araContracts.token.constrainTokenValue(returnValues._amount))
    : sum
 0)

This only pulls back the Redeemed events for the given DID.

https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#getpastevents
https://www.reddit.com/r/ethdev/comments/78ugki/do_indexed_parameters_in_events_cost_more_gas/

purchase cli fails if no job

Expected Behavior

Purchase cli should succeed even without a job

Actual Behavior

Purchase cli fails if job is not true and prints:
ara: error: fatal: Expecting job Id.

(This is because purchase.js requires that job is an object, and purchase cli passes in an empty but valid object if job is false.

  } else if (opts.job && 'object' !== typeof opts.job) {
    throw TypeError('Expecting job object.')
  }

Steps to Reproduce the Problem

  1. call act purchase with job not set

Specifications

  • Version:
  • Platform:
  • Subsystem:

allocate rewards fails because it passes non-strings to expandTokenValue

Expected Behavior

allocate in rewards.js should pass strings to expandTokenValue, or expandTokenValue should accept non-strings.

Actual Behavior

expandTokenValue in token.js expects a string, but allocate in rewards.js passes in numbers.

  const validRewards = isValidArray(rewards, (reward) => {
    if (reward <= 0) {
      return false
    }
  })

  rewards = rewards.map(i => token.expandTokenValue(i))

add to library on deploy

Expected Behavior

When a user deploys a proxy, it should be added to their library.

Actual Behavior

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

Can't purchase AFS that is "free"

Expected Behavior

Should be able to call purchase on an AFS contract with price set to null.

Actual Behavior

Throws an err
Error purchasing item: TypeError: Value must be greater than 0 at _validateApprovalOpts

npm audit warnings

                       === npm audit security report ===                        
                                                                                
┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Sandbox Breakout / Arbitrary Code Execution                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ static-eval                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ No patch available                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ 175f97706277aaebd67361d0a54f282e5ef2f8f37e275d6e48cede031d8… │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ 175f97706277aaebd67361d0a54f282e5ef2f8f37e275d6e48cede031d8… │
│               │ > brfs > static-module > static-eval                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/758                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Sandbox Breakout / Arbitrary Code Execution                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ static-eval                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ No patch available                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ 5080b18143afb317a971b6e5f6094a1f69fd29530443f3af0ae7ff2013b… │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ 5080b18143afb317a971b6e5f6094a1f69fd29530443f3af0ae7ff2013b… │
│               │ >                                                            │
│               │ 175f97706277aaebd67361d0a54f282e5ef2f8f37e275d6e48cede031d8… │
│               │ > brfs > static-module > static-eval                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/758                       │
└───────────────┴──────────────────────────────────────────────────────────────┘

Specifications

  • Version: 0.23.0
  • Platform:
  • Subsystem:

Purchase should return jobId

Expected Behavior

In order to use the jobId that is generated during purchase, the purchase method should return the jobId.

submit and allocate rewards should check library.hasPurchased

Expected Behavior

When calling submit or allocate, should error if user has not purchased content

Actual Behavior

Submit and Allocate revert without reason if have not purchased content

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

AFS Contract 'didPurchase' method

Feature Request

Add method in AFS contract to check if user has purchased an AFS. This would be helpful for a quick (free) way to validate if a user has the right to download a piece of content. The only alternatives currently are iterating through a users library, or iterating through purchase events, which can be time consuming.

Mapping owners -> published afs

For the dapp, there is a 'Published' view in the ui, that displays all of the files published under the AID of the user. Currently, there's no mapping of owners directly to their afs. This would be a really nice feature to have for the dapp, and probably for any other projects built off ara and the probably for the users themselves. We could just make a call to one of the contracts, and return an array of did we could render to the app.

isEmpty function

A helper function that returns a boolean indicating is a proxy has not been committed to.

Pass price into Purchased event

If you pass price_ as a third parameter into the Purchased event, it will be much faster to calculate earnings. Currently to get earnings, I have to query all Purchased and PriceSet events from the contract. These are not trivial, and they each take a good amount of time. Then I have to loop through each Purchased event, look at the block number, and match it up with a PriceSet based on its block number, furthering time complexity.

By adding price to the emit, this process can be sped up alot, and will make for a faster app experience for users. It should only cost a few hundred more gas, which is really a very small fee I think.

Log more accurate error when `$ act purchase` fails

Expected Behavior

$ act purchase <purchaser> <did>
...
ara: error: fatal: ongoing transaction; failed to submit the new transaction

Actual Behavior

$ act purchase <purchaser> <did>
...
ara: error: fatal: replacement transaction underpriced

Steps to Reproduce the Problem

  1. Make two purchases at the same time via CLI

Specifications

  • Version: 0.11.3
  • Platform:
  • Subsystem:

Error not thrown with incorrect CL args

Expected Behavior

Incorrect combination of CL args should throw error

$ echo 'pass' | act token transfer did:ara:8a98c8305035dcbb1e8fa0826965200269e232e45ac572d26a45db9581986e67 $(aid whoami) 1000
 ara: error: 'transfer' is not a act token command. See 'act token--help'.
 ara: error: An error occured when invoking 'transfer' command. See 'act token --help'.

Actual Behavior

$ echo 'pass' | act token transfer did:ara:8a98c8305035dcbb1e8fa0826965200269e232e45ac572d26a45db9581986e67 $(aid whoami) 1000



Just hangs forever.

Steps to Reproduce the Problem

Specifications

  • Version: 0.4.6
  • Platform: macos
  • Subsystem: bash version 4.4.19

Use yargs .help rather than custom help catch

Expected Behavior

-h / --help will always work without passing any options and exits successfully

Actual Behavior

If a command uses positionals, the command exits with code 1

Steps to Reproduce the Problem

  1. Run any command with required options or positionals
  2. Run echo $?

Specifications

  • Version: 0.2.7

Get job owner

Expected Behavior

Method for getting the owner of job (in order to allow a peer to validate that another peer is the owner of a job)

Actual Behavior

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

CLI options -D, -s, -n, and -k broken

Expected Behavior

Options -D, -s, -n, and -k should work globally

Actual Behavior

Using these options results in Unknown argument error due to use of strict() (result of #117)

Steps to Reproduce the Problem

  1. Run any CLI command using one of those options

Include estimate opt for redeem

An estimate option would probably be good to have for users, that way we can give them an estimate cost for redeeming rewards instead of sending a tx immediately.

Deprecate proxyExists

The proxyExists function internally calls getProxyAddress and returns a boolean, so everywhere we need to call getProxyAddress, we also need to call proxyExists before it, introducing overhead and a potential gotcha.

This issue proposes deprecating the proxyExists method and modifying the getProxyAddress function to just throw an Error if the requested proxy doesn't exist.

Migrate does not update Testnet addresses correctly

Expected Behavior

truffle migrate --network testnet should automatically update constants.js with the new Testnet contract addresses.

Actual Behavior

Only privatenet addresses are updated after migration, regardless of selected network

Steps to Reproduce the Problem

  1. Use privatenet provider
  2. truffle migrate --network testnet
  3. constants.js privatenet addresses are updated

isValidArray should use function to validate elements

Expected Behavior

isValidArray function should use passed in fn to validate elements

Actual Behavior

isValidArray returns true if Array, but does not factor in fn results

Suggested fix

function isValidArray(arr, fn) {
  if (arr && Array.isArray(arr) && arr.length > 0) {
    let valid = true
    arr.forEach((args) => {
      valid = valid && fn(args)
    })
    return valid
  }
  return false
}

Also, in rewards.js in allocate, farmers needs to be let, since variable changes in isValidArray callback.

estimate deploy proxy without needing to create afs

Expected Behavior

deployProxy method should be able to handle estimating cost without needing to have a valid did passed in.

Actual Behavior

Steps to Reproduce the Problem

Specifications

  • Version:
  • Platform:
  • Subsystem:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.