Skip to content

Yuandi-Sherry/UnionLottoDAPP

Repository files navigation

Block Chain Final Project - A Union Lotto DAPP

This is a demo simulating union lotto (双色球), a type of welfare lottery with 1 chosen blue ball and 6 chosen red balls, in real life. It aims to solve the problem of automatically computing the price of each level prize, transferring prize to the winners, the individual income tax to tax authorities and part of income to the charity.

The main procedure of issuing a new union lotto, betting on a lotto and announcing the results is as follows:

The main page of assigned authority

The main page of betting

The main page of checking the result

Background

What is Union Lotto?

It is a lottery issued by lottery issued authority to gather some money from buyers and use 35% as donation, 49% as prize for winners.

The basic rules

Issuing, Buying and Announcing

The buyers should choose 6 red balls from No.1 to No. 33 and 1 blue ball from No.1 to No.16 as a note(注) of lottery with 2 ether per note.

Three union lottos are issued every week with the unique sequence number and date when the authority will announce the results.

Distribution of incomes

Prize: 50% of total income of a union lotto.

Donation: 35% of total income of a union lotto.

Issuing cost: 15% of total income of a union lotto.


Why is it necessary to operating it on ethereum?

Immutability

This property of block chain guarantees the authentication and fairness of each union lotto. Once a buyer or an authority gets involved in the operation of a union lotto, all transactions will be recorded and visible for all users, which can constraint authority's behavior. (It is not a centralized contract because every account can be assigned as the authority)

Anonymity

Some winners of the first prize rejected their prize due to the fear that other people will know his prize and threaten him or just borrow money from him. So putting the drawing and distribution part in the block and transferring the prize to an Ethereum account will fade their worries.

Automatically transferring

The trust of charity and taxation of lottery issuing authority are doubted recent years. The transferring part of the smart contract can solve this problem. Once the results comes out, the donation to charity from authorities will be transferred to assigned charity account directly, and the taxes from the winners will be transferred to tax authorities directly, which makes it get rid of the hands of a middle man, the lottery issuing authorities.

Instruction

Environment and Dependency

  • Geth: 1.8.17-stable
  • Metamask chrome extenstion: 5.2.2
  • Vue, web3js, nodejs

Running the geth and starting the private chain

> geth --rpc --nodiscover --datadir data0 --port 30303 --rpcapi "db,eth,net,web3" --rpccorsdomain "*" --networkid 1001 --ipcdisable console 2>>geth.log

Deployment of the Smart Contract Senior Authority

This step only needs to be done at the first time

The contract SeniorAuthority acts like the god of the union lotto world. This contract assigns who can be the authority to issue union lottos.

The intention of setting this contract is that there're many agencies to issue lotteries all over the country right now. And it still needs some time before everyone becoming a legal lottery issuing authority, which may be realized in the future.

This step will be done on the remix website to get the address, or in node js.

Deploy with remix website

I used this version of solidity compiler. And then the contract can be deployed in web3 provider by choosing the environment and click Deploy button.

Then the console of remix will be like follows.

And in geth console, the account can be unlocked. Then the deploy button on the remix web page must be clicked again.

Then the miner can start mining until a new contract has been deployed in remix website.

Copy the address of deployed contract to SeniorAuthority.js and paste it.

Deploy with nodejs

> Web3 = require('web3')
> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
> solc = require('solc')
> CONTRACT_FILE = 'SeniorAuthority.sol'
> content =fs.readFileSync(CONTRACT_FILE).toString()
> input = {
  language: 'Solidity',
  sources: {
    [CONTRACT_FILE]: {
      content: content
    }
  },
  settings: {
    outputSelection: {
      '*': {
        '*': ['*']
      }
    }
  }
}
> compiled = solc.compile(JSON.stringify(input))
> output = JSON.parse(compiled)
> abi = output.contracts[CONTRACT_FILE]['SeniorAuthority'].abi
> bytecode = output.contracts[CONTRACT_FILE]['SeniorAuthority'].evm.bytecode.object
> bytecode = '0x'+bytecode
> SeniorAuthority = web3.eth.contract(abi)
> deployedContract = SeniorAuthority.new({from: web3.eth.accounts[0], data: bytecode, gas: 4700000})
> deployedContract.address

paste the return value of deployedContract.address to SeniorAuthority.js

Starting the server on localhost: 8080

> npm start

input localhost:8080 in Google Chrome, and the following page will be seen.

If you haven't logged in the MetaMask, the main page will be like that, showing the message that you have to log in it.

Connect to geth private chain

Open the MetaMask extension, click the top-right loading progress circle and set the networks to http://127.0.0.1:8545 which depends on the port of your local private chain. And log in with your password, and your accounts will show up.

Notes that I used the import function in Metamask to get my accounts in geth by JSON files.

Then you can act like an authority or a buyer to interact with this DAPP.

As an authority

The main operation of an authority is shown in the main page, including issuing a new union lotto by inputting the announcing date and clicking the ISSUE button. Notes that it is the deployment of the smart contract UnionLotto.

To make it clearer and easier, we assume that there's only one authority assigned by the senior authority. (The name of this account is Miner&Authority) And the authority can issue the next union lotto only when the last union lotto is drawn.

And when it comes to the day of announcing the results, the authority can click the draw button to draw the results in the smart contract. At that time, the current union lotto comes to an end, and prize will be distributed automatically, and nobody can bet on an ended union lotto anymore.

Main Page

The 3 buttons on the main page can achieve the main function of the authority. Notes that the test drawing button is used to assign No.1 blue ball and No.2~No.7 red ball to the result of the latest union lotto instead of generating the result randomly, which is just used for testing.

As a buyer

Main Page

A buyer's main page may look like follows. Notice that there isn't issuing or drawing button.

Betting Page

Metamask part

It is a part for buyers to see their balance in real time, so the buyers don't need to click the MetaMask chrome extension to check their balance.


And the following part is the part of betting. Click one blue ball on the left part and six red balls on the right part, and then click the bet button. The pending circle and the transaction based on MetaMask will show up.

After clicking the CONFIRM in MetaMask, the transaction state will become pending. If REJECT is clicked, then the transaction will be denied, and nothing will be changed.

Then the miner has to start mining again until the state of the transaction become CONFIRMED.

in geth command line:

> miner.start()

Frankly speaking, in the real Ethereum, there're many miners mining successively. So the trouble of mining manually in geth command line every time after a transaction is confirmed is not inevitable anymore.


If a buyer wants to buy the same set of numbers for more than 1 note, he can modify the number in the input frame and then click the bet button. And the MetaMask will charge the buyer with corresponding amount of money.

As in the following example, the buyer wants to buy 4 notes, and he is charged 8 ETH.

Result Page

In the result page, it will display the bet record of current buyer. The top part is the same as that in bet page, a real-time record of account and balance of MetaMask data.

The part below the MetaMask is the result of current lotto. If it hasn't been drawn, there will be 7 question marks. If it has been drawn, the results will be shown.

The left column is a list of recent lottos, the yellow font color of which marks the current lotto chosen by the buyer to see the records. Click the button will change to the record of the same buyers of another union lotto.

And the right column shows the records of each bets from current buyers of the chosen lotto from the left column. This table includes 4 columns. The first 2 columns are the chosen blue ball and red balls. The third column is the amount of bets, and the last column is the level of prize.

If the chosen Union Lotto hasn't been announced

The level of Prize column displays TO BE EXPECTED. The result part displays 7 question marks.

If the chosen Union Lotto has been announced

The level of Prize column displays the result of each record. The result part displays the true result.

Test Report

As mentioned in the instruction part, the one-off deployment of SeniorAuthority makes it possible for publishing lottos and betting without the trouble of deploying the contract by web3 provider from remix website again.

The design of testing

To make it convenient to prove the execution of the smart contract. The chosen numbers and bets are as follows.

  • The first account (0x4C02D8D6CF951E636642a21F43BBB46C7fBF9342) is assigned as the authority by the senior authority contract. And it also acts as a miner. (So the change of balance in this account is not what we are concerned of.)

  • The other 7 accounts will bet the following notes:

    accounts name blue ball red balls bets expected prize level
    Buyer1 1 2, 3, 4, 5, 6, 7 1 1 (+about 741.75ether)
    Buyer2 2 2, 3, 4, 5, 6, 7 1 2 (+about 247.25 ether)
    Buyer3 1 8, 3, 4, 5, 6, 7 2 3 (+4 Ether * 2)
    Buyer4 2 8, 3, 4, 5, 6, 7 3 4 (+3 Ether * 3)
    Buyer5 2 8, 9, 4, 5, 6, 7 1 5 (+2 Ether)
    Buyer6 1 8, 9, 10, 11, 12, 13 2 6 (+1 Ether * 2)
    Miner & Authority 3 8, 9, 10, 11, 12, 13 1000 contribute the prize pool of lottery
  • Prizes:

    • Total income of this Union Lottos: 2020 ether
    • Total amount of lower level prize: $42+33+2+1*2 = 21ether$
    • Total amount of higher level prize: $total Income * 50% - totalAmount of LowerLevelPrize = 989 ether$
    • First Prize Amount: $higherPrize * 75% = 741.75$
    • Second Prize Amount: $higherPrize * 25% = 247.25$
  • The assigned winning numbers is: blue ball No.1, red balls No.2 to No.7

Recording the balance of each accounts before testing

Publish a new union lotto

The normal way of operation

After selecting the date and clicking the button, it will issue an union lotto.

Clicking the confirm in MetaMask. After miner mining the block, the union lotto is issued successfully.

The betting page will show the date of announcement of current Union Lotto.

The robustness of publishing procedure

  • If the date field, as the key of mapping from date to Union Lotto address, is not filled, the warning message is shown and the union lotto cannot be issued.

  • If the last union lotto haven't been drawn, it will trigger a warning message:

  • Apart from that, the date of the new union lotto should be later than the latest one.

Buy some notes of the union lottos

According to the current state, the results of buying and drawing is predicted in the table below.

accounts name balance after buying prize expected balance after announcing
Buyer1 2987 ether 741 ether 3728 ether
Buyer2 240 ether 247 ether 487 ether
Buyer3 78 ether 4 ether * 2 86 ether
Buyer4 316 ether 3 ether * 3 325 ether
Buyer5 72 ether 2 ether * 2 74 ether
Buyer6 10 ether 1 ether * 2 12 ether

The normal way of operation

Buyer1

Buyer2

Buyer3

There's a bug in the first image: the balance is shown in the unit of wei which should be in the unit of Ether. And this bug is fixed in the final version.

Buyer4

The highlight of blue ball No.6 is caused by mouse's hovering.

Buyer5

Buyer6

Contributor

Notes again that this 1000 notes aim to contribute the money to the prize pool.

The robustness of buying procedure

Draw the lottery

There're 2 draw buttons in the main page. One of them is for really drawing procedure where the results are drawn randomly, and the other is for assigning the result of the lotto as No.1 for one blue ball and No.2~No.7 for red balls, which makes it convenient for testing of the drawing procedure of UnionLotto Contract.

In the test, I used test button to generate the result of Blue ball No.1, Red balls No.2 to No.7.

The record page of each buyer is as follows.

Buyer1

Buyer2

Buyer3

Buyer4

Buyer5

Buyer6

Compare the balance of each account after the union lottos been drawn and the prize been distributed with the expected balance in the table above. I found that they are the same with gas fee ignored.

Room for improvement

Assign more than one account as authority

It is mentioned above for many times. The number of authorities can be more than one by changing the authority in SenoirAuthority contract from string type to string [].

Robustness of generating a random number

As you known, the miner can control how long a block generates, which can decide the random seed of the results and indirectly influence the results of a union lotto. I've found a method of generating it randomly published by Oracle, but failed in applying it on my project.

Assign the account of Tax Authorities and Charities in the contract

This function is easier than transferring the prize of the winners as long as we can get their account address. However, we have to secretly assign it without publishing it to the public to observe the anonymity of blockchain.

Transfer money as prize pool to the Union Lotto contract once it is created

I have to admit that it is a necessary function but I don't have enough time to implement and test it. But in the rule of union lotto, prize pool is required.

Change the price of each notes based on real-time exchange rate

I have to add another interface to interact with exchange rate provider, and poll it's data every small time slot to get the "real time" data.

Bugs Avoidance

[ethjs-rpc] rpc error with payload Error: invalid sender(on MetaMask)

https://blog.csdn.net/laixide110/article/details/83895013

CALL_AND_RETRY_LAST Allocation failed (on npm start)

https://blog.csdn.net/liub37/article/details/82866763

References

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published