Etho-Boost is a crowdfunding platform built on the Ethereum Blockchain. View the production frontend or backend
App Setup Instructions
- To install Pipenv on a Mac, you can run
$ brew install pipenv
- You should have Python 3.8.5
$ python3 --version
=> Python 3.8.5
- You should have Postgres
$ which psql
=> /Applications/Postgres.app/Contents/Versions/latest/bin/psql
- You should have pipenv
$ pipenv --version
=> pipenv, version 2020.8.13
- Fork and clone down the repository
- Change into the directory
$ cd eth_crowdfund_be
- You will need to work in a virtual environment. Why? Using a virtual environment for Python projects allows us to have an isolated working copy of Python so we can work on a specific project without worrying about affecting other projects.
- Within the root directory:
a. Run# pipenv --three
to create the virtual environment
c. Run$ pipenv install
to install all dependencies
d. Run$ createdb eth_crowdfund_api_db
to create the app database
e. Run$ createdb eth_crowdfund_api_db_test
to create the testing database
f. Run$ touch .env
to create an enviornment file e. Within the.env
file add appropriate environment values for flask enviornment, database URLs, and localhost port
FLASK_ENV=development
SQLALCHEMY_DATABASE_URI="postgresql://postgres:password@localhost/eth_crowdfund_api_db"
SQLALCHEMY_TEST_DATABASE_URI="postgresql://postgres:password@localhost/eth_crowdfund_api_db_test"
PORT=3000
- Run the following to activate the project virtual environment. When you are done working on the project, you should execute
$ exit
to exit the virtual environment
$ pipenv shell
$ python3 run.py
=> * Serving Flask app "src.app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
* Restarting with stat
/Users/username/.local/share/virtualenvs/eth_crowdfund_be-TvIDdz62/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:833: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
warnings.warn(FSADeprecationWarning(
* Debugger is active!
* Debugger PIN: 312-766-617
- In your browser, navigate to http://localhost:3000/ and you should see
Etherium for life
- To stop the server,
ctrl + c
Database Setup Instructions
Path: `eth_crowdfund_be`- Run
$ python3 manage.py db stamp head
$ python3 manage.py db init
$ python3 manage.py db upgrade
=> INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 96a8d065e5ea, empty message
if you do not recieve: INFO [alembic.runtime.migration] Running upgrade -> 96a8d065e5ea, empty message
you may need to delete the alembic_version
Run
$ psql
=# \c eth_crowdfund_api_db
=# DELETE FROM alembic_version
DELTETE 1
=# \q
$ python3 manage.py db stamp head
$ python3 manage.py db downgrade
$ python3 manage.py db upgrade
- You can check the database by running
$ psql
$ \c eth_crowdfund_api_db
$ \dt
=> List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+----------------
public | alembic_version | table | postgres
public | campaign_contributor | table | postgres
public | campaigns | table | postgres
public | contributor | table | postgres
public | requests | table | postgres
$ SELECT * FROM campaigns;
=> id | name | description | image | manager | contributors | upvote | min_contribution | address | expiration | created_at | updated_at
----+------+-------------+-------+---------+--------------+--------+------------------+---------+------------+------------+------------
$ SELECT * FROM requests;
=> id | campaign_id | description | image | value | recipient | approved | finalized | approvals | created_at | updated_at
----+-------------+-------------+-------+-------+-----------+----------+-----------+-----------+------------+------------
- To exit the database,
exit
or\q
Database Seeding Instructions
Within the `pipenv shell` virtual environment, run the following:- Ensure you are at
/eth_crowdfund_be
- Run
$ python3 manage.py seed
- Start server with
$ python3 run.py
- Visit
localhost:3000/api/v1/campaigns
andlocalhost:3000/api/v1/requests
and you should see seeded Campaigns and Requests.
Updating the Database Instructions
Path: /eth_crowdfund_be
To make updates to the database and run a new migration, run the following:
$ python3 manage.py db stamp head
$ python3 manage.py db init
$ python3 manage.py db migrate
$ python3 manage.py db upgrade
- Note: If you encounter any root errors, such as
ERROR [root] Error: Target database is not up to date.
orERROR [root] Error: Relative revision -1 didn't produce 1 migrations
, run$ python3 manage.py db stamp head
to reset the target database to your current database head.
Create a campaign
- Path:
POST http://localhost:3000/api/v1/campaigns/
- Example JSON post body:
{
"name": "Test Campaign",
"description": "test description",
"image": "test.jpg",
"contributors": "1",
"upvote": "2",
"manager": "3",
"address": "1",
"min_contribution": 5.0
}
- Example response body:
{
"address": "1",
"contributors": 1,
"created_at": "2020-09-06T15:49:49.445152",
"description": "test description",
"expiration": null,
"id": 1,
"image": "test.jpg",
"manager": "3",
"min_contribution": 5.0,
"name": "Test Campaign",
"requests": [],
"updated_at": "2020-09-06T15:49:49.445158",
"upvote": 2
}
Get a Campaign by ID number
- Path:
GET http://localhost:3000/api/v1/campaigns/<insert campaign id here>
- No body required
- Example response body
{
"address": "1",
"contributors": 1,
"created_at": "2020-09-06T15:49:49.445152",
"description": "test description",
"expiration": null,
"id": 4,
"image": "test.jpg",
"manager": "3",
"min_contribution": 5.0,
"name": "Test Campaign",
"requests": [],
"updated_at": "2020-09-06T15:49:49.445158",
"upvote": 2
}
Get all Campaigns
- Path:
GET http://localhost:3000/api/v1/campaigns
- No body required
- Example response body
[
{
"address": "4",
"contributors": 1,
"created_at": "2020-09-05T20:31:17.196051",
"description": "test description",
"expiration": null,
"id": 1,
"image": "test.jpg",
"manager": "3",
"min_contribution": 5.0,
"name": "Test Campaign",
"requests": [
{
"approvals": 1,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-05T20:41:47.774790",
"description": "test description",
"finalized": false,
"id": 1,
"image": "test.jpg",
"recipient": "1",
"updated_at": "2020-09-05T20:41:47.774800",
"value": 1.0
}
],
"updated_at": "2020-09-05T20:31:17.196090",
"upvote": 2
},
{
"address": "2",
"contributors": 2,
"created_at": "2020-09-06T16:59:05.367795",
"description": "test description b",
"expiration": null,
"id": 5,
"image": "test_b.jpg",
"manager": "1",
"min_contribution": 5.0,
"name": "Test Campaign B",
"requests": [],
"updated_at": "2020-09-06T16:59:05.367801",
"upvote": 5
}
]
Update a Campaign by ID number
- Path:
PUT http://localhost:3000/api/v1/campaigns/<insert campaign id here>
- Example JSON put body
{
"description": "test description updated",
"name": "Better Name Campaign",
"upvote": 4
}
- Example response body
{
"address": "1",
"contributors": 1,
"created_at": "2020-09-06T15:49:49.445152",
"description": "test description updated",
"expiration": null,
"id": 4,
"image": "test.jpg",
"manager": "3",
"min_contribution": 5.0,
"name": "Better Name Campaign",
"requests": [],
"updated_at": "2020-09-06T16:48:19.902997",
"upvote": 4
}
Delete a Campaign by ID number
- Path:
DELETE http://localhost:3000/api/v1/campaigns/<insert campaign id here>
- No body required
- Example response body
{
"address": "1",
"contributors": 1,
"created_at": "2020-09-06T15:49:49.445152",
"description": "test description updated",
"expiration": null,
"id": 4,
"image": "test.jpg",
"manager": "3",
"min_contribution": 5.0,
"name": "Better Name Campaign",
"requests": [],
"updated_at": "2020-09-06T16:48:19.902997",
"upvote": 4
}
Create a Request
- Path
POST http://localhost:3000/api/v1/requests/
- Example JSON post body.
campaign_id
,value
, andrecipient
are required.
{
"campaign_id": "1",
"description": "test description a",
"image": "request.jpg",
"value": 1.0,
"recipient": "1"
}
- Example response body
{
"approvals": null,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-06T17:11:23.639004",
"description": "test description a",
"finalized": false,
"id": 2,
"image": "request.jpg",
"recipient": "1",
"updated_at": "2020-09-06T17:11:23.639042",
"value": 1.0
}
Get a Request by ID number
- Path:
GET http://localhost:3000/api/v1/requests/<insert request id here>
- No body required
- Example response body
{
"approvals": null,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-06T17:11:23.639004",
"description": "test description a",
"finalized": false,
"id": 2,
"image": "request.jpg",
"recipient": "1",
"updated_at": "2020-09-06T17:11:23.639042",
"value": 1.0
}
Get all Requests
- Path
GET http://localhost:3000/api/v1/requests
- No body required
- Example response body
[
{
"approvals": 1,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-05T20:41:47.774790",
"description": "test description",
"finalized": false,
"id": 1,
"image": "test.jpg",
"recipient": "1",
"updated_at": "2020-09-05T20:41:47.774800",
"value": 1.0
},
{
"approvals": null,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-06T17:11:23.639004",
"description": "test description a",
"finalized": false,
"id": 2,
"image": "request.jpg",
"recipient": "1",
"updated_at": "2020-09-06T17:11:23.639042",
"value": 1.0
}
]
Update a Request by ID number
- Path:
PUT http://localhost:3000/api/v1/requests/<insert request id here>
- Example JSON put body
{
"description": "better description",
"image": "better_image.jpg",
"approvals": "5"
}
- Example response body
{
"approvals": "5",
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-06T17:11:23.639004",
"description": "better description",
"finalized": false,
"id": 2,
"image": "better_image.jpg",
"recipient": "1",
"updated_at": "2020-09-06T17:11:47.639042",
"value": 1.0
}
Delete a Request by ID number
- Path:
DELETE http://localhost:3000/api/v1/requests/<insert request id here>
- No body required
- Example response body
{
"approvals": null,
"approved": false,
"campaign_id": 1,
"created_at": "2020-09-06T18:05:01.891894",
"description": "test description b",
"finalized": false,
"id": 3,
"image": "request_b.jpg",
"recipient": "1",
"updated_at": "2020-09-06T18:05:01.891901",
"value": 2.0
}
Add a Contributor to a Campaign
- Path:
POST http://localhost:3000/api/v1/campaigns/<campaign_address>/contributor/<contributor_address>
- No body required
- Example response body
{
"address": "Hf84jhGE9fdjF9ehfdse45",
"created_at": "2020-09-06T18:41:57.156262",
"description": "Need help serving community",
"expiration": "2020-10-25T00:00:00",
"id": 16,
"image": "https://picsum.photos/200/300",
"manager": "LJHhf82u3hr0d9uhUg4g",
"min_contribution": 1.5,
"name": "Market St. Soup Kitchen",
"requests": [
{
"approvals": 0,
"approved": false,
"campaign_id": 16,
"created_at": "2020-09-06T18:41:57.238755",
"description": "Cleaning supplies",
"eth_id": null,
"finalized": false,
"id": 15,
"image": "https://picsum.photos/200/300",
"recipient": "jhF97hdfha97",
"updated_at": "2020-09-06T18:41:57.238757",
"value": 25.0
}
],
"updated_at": "2020-09-06T18:41:57.156266",
"upvote": 50,
"value": null
}
View Campaigns by Contributor Address
- Path:
GET http://localhost:3000/api/v1/contributor/<contributor_address>/campaigns
- No body required
- Example response body
[
{
"address": "Hf84jhGE9fdjF9ehfdse45",
"created_at": "2020-09-06T18:41:57.156262",
"description": "Need help serving community",
"expiration": "2020-10-25T00:00:00",
"id": 16,
"image": "https://picsum.photos/200/300",
"manager": "LJHhf82u3hr0d9uhUg4g",
"min_contribution": 1.5,
"name": "Market St. Soup Kitchen",
"requests": [
{
"approvals": 0,
"approved": false,
"campaign_id": 16,
"created_at": "2020-09-06T18:41:57.238755",
"description": "Cleaning supplies",
"eth_id": null,
"finalized": false,
"id": 15,
"image": "https://picsum.photos/200/300",
"recipient": "jhF97hdfha97",
"updated_at": "2020-09-06T18:41:57.238757",
"value": 25.0
}
],
"updated_at": "2020-09-06T18:41:57.156266",
"upvote": 50,
"value": null
},
{
"address": "DFjh489GD74hgls8",
"created_at": "2020-09-06T18:41:57.156312",
"description": "Serving communities hit hard by Covid19",
"expiration": "2020-10-25T00:00:00",
"id": 17,
"image": "https://picsum.photos/200/300",
"manager": "jhF8dfh4jjgfdkjs45",
"min_contribution": 1.5,
"name": "Arc Thrift",
"requests": [],
"updated_at": "2020-09-06T18:41:57.156322",
"upvote": 50,
"value": null
}
]
Convert Wei to USD
- Path:
GET http://localhost:3000/api/v1/price_converter?wei={wei_amount}
- Requires query params with a key of 'wei' and value of the amount of wei to be converter
- No body required
- Example response
{
"USD": 357
}