Skip to content

Pizza Coin developed for the 1st Thailand's blockchain hackathon (Pizza Hackathon 2018)

Notifications You must be signed in to change notification settings

pizzahackathon/PizzaCoin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vue logo

Pizza Coin

Brief Synopsis of Pizza Hackathon

Pizza Hackathon was the 1st blockchain hackathon event in Thailand which was held on 25-26 August 2018. The objective of this event was to educate blockchain technologies as well as building up thai blockchain developers. The event consisted of education and project hacking sessions in which all participating developers had freedom to develop any project based on any blockchain technologies. There was eventually the project competition among teams of developers at the end of the event.

To find the winning team, we developed a voting system named PizzaCoin. PizzaCoin is a voting system based on Ethereum blockchain’s smart contract compatible with ERC-20 token standard. Each event participant (i.e., all participating developers and all event staffs) would be registered to PizzaCoin contract. The contract allowed a group of developers create and join a team. Meanwhile, any authorized staff was able to perform operations such as revoking some developer from a team, revoking a whole team, changing contract states, etc. All participants would receive equal voting tokens. With PizzaCoin contract, a participating developer was able to give his/her votes to any favourite projects developed by other different teams whereas a staff had freedom to vote to any teams. Each voter could spend voting tokens according to his/her own balance. Specifically, all voting results would be transacted and recorded on the blockchain. As a result, the winning team, who got maximum voting tokens, was judged transparently by the developed PizzaCoin contract automatically without any possible interference even by any event staff.


Integral Components of PizzaCoin

PizzaCoin (Smart Contract)

Figure 1. Example of PizzaCoin contract's source code


Workflow Design for PizzaCoin Contract

One of the biggest challenges when developing Ethereum smart contract is to find a solution to handling β€˜Out-of-Gas’ error during deploying the contract onto the blockchain network, due to some block gas limits on Ethereum blockchain. The prototype of our PizzaCoin contract also confronted with these limitations since our contract requires several functional subsystems such as staff management, team and player management, and voting management subsystems. To avoid block gas limit problems, PizzaCoin contract was designed and developed using several advanced concepts and techniques.

PizzaCoin contract consists of eight dependencies including three contracts: PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam, and five libraries: PizzaCoinStaffDeployer, PizzaCoinPlayerDeployer, PizzaCoinTeamDeployer, PizzaCoinCodeLib and PizzaCoinCodeLib2.

PizzaCoin contract acts as a mother contract of all dependencies. In more detail, the contract has three special children contracts, namely PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam contracts which would be deployed by the three deployer libraries named PizzaCoinStaffDeployer, PizzaCoinPlayerDeployer and PizzaCoinTeamDeployer respectively. Furthermore, PizzaCoin contract also has another two proxy libraries named PizzaCoinCodeLib and PizzaCoinCodeLib2 which would be used as libraries for migrating source code of PizzaCoin mother contract.


Figure 2. Deployment of PizzaCoin contract


There are two stages when deploying PizzaCoin contract onto the blockchain. In the first stage, PizzaCoin contract's dependencies including PizzaCoinStaffDeployer, PizzaCoinPlayerDeployer, PizzaCoinTeamDeployer, PizzaCoinCodeLib and PizzaCoinCodeLib2 libraries have to be deployed onto the blockchain one by one as separate transactions. The previously deployed libraries' addresses would then be linked and injected as dependency instances in order to deploy PizzaCoin mother contract to the ethereum network as illustrated in Figure 2.


Figure 3. Initialization of PizzaCoin contract


In the second stage, the previously deployed PizzaCoin mother contract must get initialized by a project deployer (a staff who previously deployed PizzaCoin contract). A project deployer initiates three transactions (steps 1.1, 2.1 and 3.1) in order to deploy PizzaCoin children contracts--including PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam contracts--as shown in Figure 3. At this point, we employed a contract factory pattern using the deployer libraries, i.e. PizzaCoinStaffDeployer, PizzaCoinPlayerDeployer and PizzaCoinTeamDeployer, to deploy each corresponding child contract (steps 1.2 - 1.3, 2.2 - 2.3 and 3.2 - 3.3). The resulting children contracts' addresses would then be returned to store on PizzaCoin contract (steps 1.4, 2.4 and 3.4). This way makes PizzaCoin contract know where its children contracts are located on the ethereum blockchain.

Figure 4. PizzaCoin contract acts as a contract coordinator for PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam contracts


On the prototype of PizzaCoin contract, we faced 'Out-of-Gas' error when deploying the contract because the contract contains too many function definitions. The solution to avoiding such the error we have used on a production version is to migrate almost all the logical source code of each function on PizzaCoin contract to store on proxy libraries named PizzaCoinCodeLib and PizzaCoinCodeLib2 instead as depicted in Figure 4.

PizzaCoin contract is considered as a contract coordinator or a reverse proxy contract for PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam contracts. When a user needs to interact with any contract function, a user just makes a call to PizzaCoin contract right away. For example, a user wants to join some specific team, he/she can achieve this by invoking registerPlayer function on PizzaCoin contract. The contract would then interact with its children contracts in order to do register the calling user as a player to the specified team.

In more technical detail when a user makes a call to PizzaCoin.registerPlayer() function on PizzaCoin contract, the function will instead forward the request to the delegated function named PizzaCoinCodeLib.registerPlayer() on the proxy library PizzaCoinCodeLib in order to process the requesting transaction on behalf of PizzaCoin contract. Next, the delegated function will hand over the process to the real worker function named PizzaCoinPlayer.registerPlayer() which is on PizzaCoinPlayer child contract. With these code migration techniques, we can significantly reduce gas consumption when deploying the PizzaCoin mother contract.


State Transition on PizzaCoin Contract

Figure 5. State transition on PizzaCoin contract


There are five states representing the status of PizzaCoin contract including Initial, Registration, Registration Locked, Voting and Voting Finished. Each state defines a different working context to the contract and it is changable by a staff privilege only. The contract state is unidirectional as illustrated in Figure 5. This means that if the state has been changed from one to another, we cannot change it back to any previous state.

Initial is the first state that is automatically set during PizzaCoin contract getting deployed. The contract state can be changed from Initial to Registration if and only if all the three children contracts (i.e., PizzaCoinStaff, PizzaCoinPlayer and PizzaCoinTeam contracts) have been created by a project deployer (a staff who deployed PizzaCoin contract). A project deployer can create the children contracts by invoking the following functions on PizzaCoin contract in no particular order: createStaffContract, createPlayerContract and createTeamContract (steps 1.1, 2.1 and 3.1 in Figure 3).

Once PizzaCoin contract's state is changed to Registration, the contract is opened for registration. During this state, a staff can register a selected user as a new staff. A player can create a team and/or join to an existing team. Furthermore, a staff is allowed to revoke some player from a specific team or even revoke a whole team if necessary. PizzaCoin contract would be closed for registration once the state is changed to Registration Locked. Later, a staff can enable voting by changing the contract state to Voting. The vote would be opened until the contract state is moved to Voting Finished. In this state, PizzaCoin contract would determine the winning team automatically.

Figure 6. An interaction among contracts when a staff changes the contract state


Let's say a staff changes PizzaCoin contract's state from Registration Locked to Voting. Figure 6 illustrates how PizzaCoin contract interacts with its children contracts. What happens is that as soon as a staff executes PizzaCoin.startVoting() function on PizzaCoin contract (step 1), the function would call to the delegated function PizzaCoinCodeLib2.signalChildrenContractsToStartVoting() on PizzaCoinCodeLib2 library (step 2). Later, the delegated function would order all the three children contracts to change their state to Voting by respectively executing PizzaCoinStaff.startVoting(), PizzaCoinPlayer.startVoting() and PizzaCoinTeam.startVoting() (steps 3.1 - 3.3).


In addition to understanding the detailed implementation of PizzaCoin voting system, please check out the series of articles named "PizzaCoin the series" below.

PizzaCoin the series consists of 6 articles as follows.
Part 1: How Did We Develop Ethereum-based Voting System for Pizza Hackathon?
Part 2: Workflow Design for PizzaCoin Voting System
Part 3: Detailed Implementation of Staff and Player Contracts
Part 4: Detailed Implementation of Team Contract
Part 5: Deploying Children Contracts with Contract Factories
Part 6: Integrating PizzaCoin Contract with Dependencies


Deploy with remix.ethereum.org

Install MetaMask

  • Install MetaMask on Chrome browser.
  • Get free ETH on test network, by googling using keywords like ropsten faucet, rinkeby faucet or kovan faucet.

Deploy PizzaCoin contract and its dependencies

  1. Go to remix.ethereum.org
  2. Choose πŸ“, select all files in Smart-Contract/contracts/
  3. Open PizzaCoin.sol on the left panel
  4. Select Run tab on the right panel
  5. Select PizzaCoin on the list below
  6. Specify _ownerName = "Your name" and _voterInitialTokens = 3 (i.e., the initial voting tokens every participant will get during a registration process). At this step, your Metamask will prompt you to confirm signing transaction 6 times.
  7. Select Deployed Contract pane below and then invoke the following contract functions: createStaffContract(), createPlayerContract(), createTeamContract() and startRegistration().
  8. Finally, configure your DApp by heading to the config file system.js which is in the directory ../DApp/src/store/. Then, define the following variables with corresponding settings: network, etherscanPrefix, ethereumNode, pizzaCoinAddr, pizzaCoinStaffAddr, pizzaCoinPlayerAddr and pizzaCoinTeamAddr.

Deploy with Truffle Framework

cd Smart-Contract/

To install Truffle Framework

 Follow this link

To install Node.JS dependency packages

npm install

To get Infura API for free

 Register to get a free api. Note that, the api will be sent to your registered e-mail.

To set up 'infura-api.secret' file

echo "'your-infura-api'" > infura-api.secret  // Your Infura api must be marked with single quotes

To set up 'mnemonic.secret' file

echo "'your-secret-mnemonic'" > mnemonic.secret  // Your secret mnemonic must be marked with single quotes

To compile PizzaCoin contract and its dependencies

truffle compile

To deploy PizzaCoin contract and its dependencies

truffle migrate --network mainnet  // Deploy to Ethereum public main network via Infura

or

truffle migrate --network ropsten  // Deploy to Ropsten testnet via Infura

or

truffle migrate --network rinkeby  // Deploy to Rinkeby testnet via Infura

or

truffle migrate --network kovan  // Deploy to Kovan testnet via Infura

or

truffle migrate --network rinkeby_localsync  // Deploy to Rinkeby testnet via local Geth node

or

truffle migrate --network ganache  // Deploy to Ganache local test environment

To initial PizzaCoin contract (use this when integrating the contract with DApp)

node init-contract.js <<ethereum_network>>  // For example, run 'node init-contract.js rinkeby'

To execute Node.JS based lazy-web3-wrapper functions (for demonstrating how to interact the contract with web3 node.js backend)

node web3-demo.js  // This script supports a connection to Ganache or local Geth/Parity node only


DApp (Decentralized Application)

Figure 7. Interaction between DApp and PizzaCoin contract


To facilitate our users, we developed Decentralized Application (DApp) as a web frontend connecting with PizzaCoin contract. DApp is a static web frontend application which runs at the client side without the need of any backend server. Our DApp connects with PizzaCoin contract through Web3.js library. The underlying protocal used by Web3.js is Json RPC over HTTP and/or Websocket as shown in Figure 7.


Figure 8. Example of DApp WebUI


Run Team Dashboard

cd DApp
npm install
npm run serve

Run Live Feed

cd live-feed
npm install
npm run serve

Run Live Feed Api server

cd live-feed
TBD


List of PizzaCoin Contract Address and Its Dependency Addresses

The following addresses point to PizzaCoin contract as well as its dependencies that were used at the hackathon event.



Contributors

Coders

  • Bright (Pizza Coin - Smart Contract)
  • Game (DApp WebUI)
  • Bank (DApp Leader Board and Live Feed)

Advisors

About

Pizza Coin developed for the 1st Thailand's blockchain hackathon (Pizza Hackathon 2018)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •