Welcome to Snack Coin Rewards! This Streamlit-based application reinvents the way customers earn and store rewards using smart contracts.
pip install x
; where 'x' is the package listed below:
python == 3.10.6
web3 == 5.31.1
streamlit == 1.13.0
- OpenZeppelin: Importing implementations of standard smart contracts in order to create the deployer, menu, and SNAK token
- smtp4dev: A dummy SMTP server to test email confirmation of orders
Images
: Directory containing images of menu itmes and sub directory of application examplesSolidity
: Directory containing the the token contract file, the menu and deployer contracts file, and the associated JSON files of the required abi for both contractsSolidity/SnackCoin.sol
Solidity/SnackMenu.sol
Solidity/abi-menu.json
Solidity/abi-token.json
SQL
: Directory containing the SQL files creating the database framework and the associated schema and queriesSQL/create_db.sql
SQL/insert_data.sql
snack.db
: Database containing the completed order information, including the Customers, Food, MenuItems, Menus, OrderItems, Orders, and Rewardsapp.py
: Python script containing the code that’s associated with the web interface of the applicationnotify.py
: Python script containing the code that's associated with the local smtp email confirmation
- Clone
Snack_Coin_Rewards
repository to a local drive. - Upload the smart contract files (
SnackCoin.sol
andSnackMenu.sol
) to Remix IDE. Compile both contracts. - Before deploying the contracts, make sure that “Ganache Provider” is selected as the environment and that the RPC Server from Ganache matches the one in Remix IDE.
- Add your mnemonic seed phrase (which Ganache provides as the RPC Server) to the SAMPLE.env file as WEB_PROVIDER_URI. Then rename the file to .env.
- Select an account from Ganache in Remix IDE to deploy the contracts.
- First, choose the
SnackCoinMenuDeployer
contract from the Contract pulldown and press DEPLOY. - Open the Deployed Contracts, specifically the
SNACKCOINMENUDEPLOYER
, and call thesnackcoin_menu_address
button and thesnackcoin_token_address
button. - Next, choose the
SnackCoinMenu
contract and paste thesnackcoin_menu_address
in the AT ADDRESS box under the DEPLOY.
- Scroll down and under the Deployed Contracts you will see the
SNACKCOINMENU
. - Next, choose the
SnackCoin
contract and follow the same instructions in step 9, except paste thesnackcoin_token_address
in the AT ADDRESS box under the DEPLOY. - Scroll down and under the Deployed Contracts and you will see the
SNACKCOIN
. - Due to limitations, paste both the
snackcoin_menu_address
and thesnackcoin_token_address
inapp.py
. - Save the updated
app.py
and run the file via Streamlit by running the following code in your bash or terminal:streamlit run app.py
- Optional: run
smtp4dev
in order to activate the confirmation email system - Make sure to fill out the sidebar menu before cotinuing to the Snack Menu.
Once installed, you can use the contracts and the python script to run the Snack Coin Rewards interface through Streamlit. The user will be able to add menu items to their order, use eth to pay for the order, and earn SNAK tokens based on the total cost of their order. The owner of the deployed contracts are even able to withdraw eth that customers used to pay for their order. And because we used SQLite, we are also able to see the data behind each order through the snack.db
.
After the application is launched, the user/customer can fill out their information in the sidebar, and then click the "Add Customer" button before moving on to the Snack Menu.
The customer can then browse the menu items, and scroll down and must click the "Start an Order" button before continuing.
Once menu items are added to the cart, the total amount due in eth will display. The customer can then complete their order by clicking on the "Place Order" button and get a receipt and find out how many SNAK tokens they earned.
Finally, the customer can check their SNAK token balance by going back to the sidebar and clicking on the "Check SNAK Balance" button.
As for the owner of the deployed contract, or the restaurant, on the sidebar under the "Admin Only" section, they are able to check the balance of the contract and withdraw any eth they were paid by the customers. However, only the owner of the contract can withdraw funds. If anyone else tries, an error will occur. If this was an actual app, we would not include the "Admin Only" section, but would include it on an owners-only protected page.
Unfortunately Streamlit's limitations did not allow us to create all of the features that we would have liked to make. And because the app was written in Python, we were not able to shift the app to a different framework, such as Django, in order to add more features.
Another challenge we faced was not being able to import environment variables such as the contract addresses, so those had to be hard-coded in the Python script after deploying the contracts in Remix IDE. We were also unable to index customers based on their wallets, and instead had to use customer_id as an index. Despite many attempts, we believe this is another Streamlit limitation. If we had more time, one option to adjust this would be to shift the app to a different framework with more options.
Additionally, another challenge with the app is that there is no way (using Streamlit) for multiple people to interact or order using the app at the same time. If multiple people try to use the app at the same time, the most recent order will combine with the next order that's attempting to complete. This also coincides with the issue that customers are not able to start a new order as a new customer unless the "Start New Order" button is selected. For example, if the page is refreshed, the order will continue with the last customer's order instead of starting new. Again, this seems to be a Streamlit limitation and if more time allowed, we would adjust and shift the app to a different framework that has more functionality.
If more time allowed, in addition to shifting the app to a different framework, our team would likely move the frontend and the backend to a server, and deploy the contract on the testnet.
- Lara Barger
- Bryan Follenweider
- Alec Gladkowski
- Alejandro Palacios