Pizza Hackathon is the 1st blockchain hackathon event in Thailand which would be held on 25-26 August 2018. The objective of this event is to educate blockchain technologies as well as building thai blockchain developers. The event consists of educating and project hacking sessions where all participating developers are freely to develop any project based on blockchain technologies. There would eventually be a project competition among teams of developers at the end of the event.
To find the winner team, we developed a voting system called the Pizza Coin (PZC). The PZC is a voting system based on Ethereum blockchain's smart contract compatible with ERC-20 token standard. Each event participant (i.e., all the participating developers and the event staffs) would be registered to the PZC contract. The PZC contract allows a group of developers create and join a team. Any authorized staff is able to perform operations such as kicking some developer from a team, kicking a whole team, changing contract states, etc. All participants would receive equal voting tokens. With the PZC contract, a participating developer is able to give votes to his/her favourite projects developed by other different teams whereas a staff has freedom to vote to any teams. Each voter can spend voting tokens according to his/her own balance. Specifically, all the voting results would be transacted and recorded on the blockchain. As a result, the winner team who gets a maximum voting tokens would be judged transparently by the developed PZC contract without any possible interference even by any event staff.
One of the biggest challenges when developing an Ethereum smart contract is the way to handle 'Out-of-Gas' error while deploying the contract to the blockchain network, due to the block gas limit on Ethereum blockchain. The prototype of our PZC contract also confronted with this limitation since our contract requires several functional subsystems such as staff management, team and player management and voting management subsystems. To avoid the block gas limit problem, we decided to develop the PZC contract using the contract factory method (we will describe the brief details later).
The PZC contract consists of eight dependencies including Staff contract, Player contract, Team contract, Staff Deployer library, Player Deployer library, Team Deployer library, CodeLib library and CodeLib2 library.
The PZC contract acts as the mother contract of all dependencies. the PZC has three children contracts, namely Staff, Player and Team contracts which would be deployed by the libraries named Staff Deployer, Player Deployer and Team Deployer respectively. Furthermore, the PZC also has another two libraries named CodeLib and CodeLib2 which would be used as the external source code libraries for the PZC mother contract itself.
There were two stages when deploying the PZC contract to the blockchain. In the first stage, the PZC contract's dependencies including Staff Deployer, Player Deployer, Team Deployer, CodeLib and CodeLib2 libraries had to be deployed to the blockchain as seperate transactions. The previously deployed libraries' addresses would then be linked and injected as dependency instances in order to deploy the PZC mother contract to Ethereum network as shown in Figure 2.
In the second stage, the deployed PZC mother contract had to be initialized by creating its children contracts--including Staff, Player and Team contracts--as shown in Figure 3. At this point, we employed the contract factory method using the contract deployer libraries, i.e. Staff Deployer, Player Deployer and Team Deployer, to deploy each corresponding child contract. The resulting children contracts' addresses would then be returned to store on the PZC contract. This way make the PZC contract know where its children contracts were located.
The PZC contract would be considered as a contract coordinator or a reverse proxy contract for Staff, Player and Team contracts. When a user needs to interact with any contract function, he/she just makes a call to the PZC contract right away. For example, a user wants to join some specific team, he/she can achieve this by invoking the registerPlayer() function of the PZC contract. The PZC contract would then interact with its children contracts in order to do register the calling user as a player to the specified team.
On the prototype of our PZC contract, we faced 'Out-of-Gas' error when deploying the contract because the contract contains too many functions. 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 in the PZC contract to store on another external libraries named CodeLib and CodeLib2 instead as shown in Figure 4.
For example, when a user makes a call to the registerPlayer() function of the PZC contract (let's call PZC.registerPlayer() for short), the PZC.registerPlayer() will forward the request to CodeLib.registerPlayer() in order to process the requesting transaction on behalf of the PZC contract instead. Note that, the CodeLib.registerPlayer() in question is the mapped function of the PZC.registerPlayer() which is stored on the external CodeLib library. Then, the CodeLib.registerPlayer() will hand over the process to the real worker function called Player.registerPlayer(). With this code migration method, we can significantly reduce a gas consumption when deploying the PZC mother contract.
- Install MetaMask on Chrome browser.
- Get free ETH on test network, by googling using keywords like ropsten faucet, rinkeby faucet or kovan faucet.
- Go to remix.ethereum.org
- Choose 📁, select all files in Smart-Contract/contracts/
- Open PizzaCoin.sol on the left panel
- Select Run tab on the right panel
- Select PizzaCoin on the list below
- 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.
- Select Deployed Contract pane below and then invoke the following contract functions: createStaffContract(), createPlayerContract(), createTeamContract() and startRegistration().
- 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.
cd Smart-Contract/
npm install
Register to get a free api. Note that, the api will be sent to your registered e-mail.
echo "'your-infura-api'" > infura-api.secret // Your Infura api must be marked with single quotes
echo "'your-secret-mnemonic'" > mnemonic.secret // Your secret mnemonic must be marked with single quotes
truffle compile
truffle migrate --network mainnet // Deploy to Ethereum public main network via Infura
truffle migrate --network ropsten // Deploy to Ropsten testnet via Infura
truffle migrate --network rinkeby // Deploy to Rinkeby testnet via Infura
truffle migrate --network kovan // Deploy to Kovan testnet via Infura
truffle migrate --network rinkeby_localsync // Deploy to Rinkeby testnet via local Geth node
truffle migrate --network ganache // Deploy to Ganache local test environment
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 node only
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 5.
cd DApp
npm install
npm run serve
cd live-feed
npm install
npm run serve
cd live-feed
TBD