This is my final project ("online marketplace") for the ConsenSys Developer Program 2018
.
Other documents:
Minimal Market is an Ethereum dapp build using truffle
, ipfs-api
, web3
, zeppelin-solidity
and VueJS
.
The dapp uses IPFS to store all data which is not strictly needed in the smart contracts: text, images, etc.
There is a development server provided by webpack
(hot reload) + nodemon
.
An admin can add store owners, store owners can add stores, to which store owners can add products, these can be bought for ETH by accounts having the shopper role.
Inside Minimal Market there are 4 user roles:
- Owner
- implemented using
zeppelin-solidity
Ownable.sol
- initially is set to deploy account
- is owner of all deployed contracts
- can enable/disable EmergencyStop
- implemented using
- Admin
- implemented in
Users.sol
- initially deploy account is set to have admin role
- can add/remove storeowner
- implemented in
- Owner
- implemented in
Users.sol
- can add/update/remove his/her stores
- can add/update/remove products to his/her stores
- can withdraw any collected funds from products sold (even works if account loses storeowner role)
- implemented in
- Shopper
- implemented in
Users.sol
- everyone who is not an admin/storeowner
- can purchase products
- implemented in
All user roles can view all pages: Owner(s), Store(s), Products(s).
- removed product/store/owner could still be shown in the list of products/stores/owners, solution for now: hard refresh
- removing a storeowner should only be possible if it has no more stores, but that limitation is currently not included, so it'll break the ui
- emergency stop is not implemented in the ui (but it is in the smart contracts + tests)
- updating a store/product is not yet implemented in the ui (but it is in the smart contracts + tests)
- only a few contract events are currently listened for in the ui, so the updating of the ui might not happen as expected, a hard refresh of the page should get you to the correct state.
- does not keep track of transaction that are
sent
vsmined
, this will be needed when using on mainnet/testnet to keep the user happy
creating stores/storeowners/products + purchasing products works!
truffle
(tested usingv4.1.14
)ganache-cli
(tested usingv6.1.3
)ipfs
(golang/js/any is ok as long as it runs on port5001
)MetaMask
NOTE: successfully tested inside VirtualBox
Ubuntu 16.04 Desktop.
ipfs init
# set CORS headers so that local browser can connect to this IPFS node's API
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
ipfs daemon
To prevent having to Import Account
in MetaMask every time you restart ganache-cli
, you could run it
with the deterministic flag to always get the same created accounts
ganache-cli -d
There is a truffle
script inside scripts/
which will seed the app with "real" demo data.
- It will retrieve random images and store/product names using
faker
. - It will generate random text using
lorem-ipsum
. - It will Upload (and pin) all images, store-/productcontent objects to ipfs
- It will create some store owners.
- It will create some stores for each store owner.
- It will create some random products in each store.
- It makes use of the
ganache-cli
provided accounts (add them to your MetaMask) with the layout as shown belowaccounts[0] = owner of all contracts + the only admin
accounts[1] = first storeowner
accounts[2] = second storeowner
accounts[3] = third storeowner
accounts[4] = fourth storeowner
accounts[5] = fifth storeowner
accounts[6] = shopper
git clone https://github.com/rmi7/minimal-market.git
cd minimal-market
npm i
- make sure
ipfs
is running - make sure
ganache-cli
is running truffle compile
truffle migrate
- (if you want demo data)
truffle exec scripts/seed-demo-data.js
npm start
to start the development server- open
localhost:8099
in your browser - add the first account from
ganache-cli
to MetaMask, this is the account used for deploying (user roleadmin
)
truffle test
There is an overall explanation of the tests inside the Avoiding Common Attacks file: Write Tests
Not yet implemented
Not yet implemented
I did not see any reason to use an EthPM
library in this project (EthPM
looks deserted).
I therefore added a LibraryDemo.sol
contract + tests + migration.
There are 2 EthPM modules which are tested in this contract, oraclize-api
and bytes
.
oraclize-api
This is a Contract
which you can inherit from. This contract is normally used to send requests to the Oraclize Oracle service.
We however are gonna test the helper function parseInt(string _num)
,
which converts an input number as string
to a uint
.
bytes
This is a Library
which provides some useful bytes
arrays functions.
We are gonna test the toAddress(bytes _bytes, uint _start)
function,
which extracts an Ethereum address from the _bytes
variable starting at index _start
.
MIT