GithubHelp home page GithubHelp logo

classicvalues / blockchain-monopoly Goto Github PK

View Code? Open in Web Editor NEW

This project forked from phzietsman/blockchain-monopoly

0.0 0.0 0.0 420 KB

#blockchainallthethings

License: Apache License 2.0

HTML 15.74% JavaScript 84.26%

blockchain-monopoly's Introduction

Blockchain Tech Session

Requirements

Don't use the .deb if your are on Ubuntu, I had some issue starting a private node with it. Probably a PEBCAC issue :)

  • Nodejs + npm
  • Geth + Tools Link
  • Wallet Link

Nice to haves:

  • VSCode + Solidity plugin

Tools


Crip Notes

  • Start bootnode: ./bootnode --nodekey=boot.key
  • Start geth: ./geth --datadir blockchaindata --networkid 123 --rpc --bootnodes enode_url
  • Windows IPC: \\.\pipe\geth.ipc
  • Linux IPC: blochaindata/geth.ipc
  • Javascript console: ./geth attach ipc:blockchaindata/geth.ipc
  • Attach mist: ./wallet --rpc blockchaindata/geth.ipc
  • Set etherbase: > miner.setEtherbase(personal.listAccounts[0])
  • Start miner: > miner.start(1)

Starting a development Ethereum blockchain

This is a handy way to start an Ethereum sandbox you can test and play in. The --dev flags does a bit of setup in the background to create a temporary private Ethereum blockchain 'instance'.

Start a dev ethereum node:

$ git clone https://github.com/phzietsman/blockchain-monopoly.git
$ cd blockchain-monopoly
$ mkdir downloads
$ cd downloads
$ cp your_download_directory/geth geth 
$ cp your_download_directory/wallet wallet 
$ ./geth --rpc --nat none --dev

Look for the following line after the node has started:

IPC endpoint opened: your_ipc_endpoint

Start an interactive wallet and client, hooked up to your local running node:

$ ./wallet --rpc your_ipc_endpoint
$ ./geth attach ipc:your_ipc_endpoint

Using the interactive client (Javascript console), create an account and start your miner:

> personal.newAccount()
> miner.setEtherbase(personal.listAccounts[0]) 
> miner.start()
> eth.getBalance(personal.listAccounts[0])

Starting a PRIVATE Ethereum blockchain

Official Resource

Other less official resources on creating a private network

Genesis block

First you need a genesis block. This will be the first block in your blockchain and other networks / blockchains with a different genesis block will not sync with this private one. Especially take note of the chainId, we will be using it later in the startup of our nodes.

{
  "config": {
    "chainId": 123,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "nonce": "0x0000000000000045",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x8900000",
  "difficulty": "0x400",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0xdefault_account",
  "alloc": {
    "0xdefault_account" : {"balance" : "10000000000000000000"} 
  }
}

Ignore for now

I have not dug into this, but it feels like the chicken and the egg problem. Create a default account, this account will be seeded with ether in the genesis block. On a private network this is not important since mining is easy and your earn ether pretty quickly.

$./geth account new

Starting your nodes

Each node in the network should use the same genesis block / json file to setup their node

To create a database that uses this genesis block, run the following command. This will import and set the canonical genesis block for your chain.

$ ./geth --datadir blockchaindata init "../genesis.json"

Future runs of geth on this data directory will use the genesis block you have defined.

Note the networkid matches the chainId in the genesis block. The main ethereum network uses chainId=1. The --identity flag simply gives your node a friendly name, this is not required.

$ ./geth --datadir blockchaindata --identity "MyNodeName" --networkid 123 --rpc

Network Connectivity

For nodes to discover each other, you need a bootnode (one of the tools in the Ethereum toolbox). This node needs to be reachable by all the nodes you want to connect together. It is possible to run network without a peer node, if you know the enode address of someone in the network.

$ bootnode --genkey=boot.key
$ bootnode --nodekey=boot.key

Connecting your peer nodes to the network:

$ ./geth --datadir blockchaindata --networkid 123 --rpc --bootnodes bootnode_enode_url_from_above

Notice when you start up a node the console will print out your node's own enode url, this can be used by other nodes to connect to the network. To add a static node to your config, you can add in one of two ways. Adding it to blockchaindata/static-nodes.json (this should be the same folder that your chaindata and keystore folders are in):

[
  "enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303",
  "enode://pubkey@ip:port"
]

Or using the JavaScript console, using admin.addPeer():

> admin.addPeer("enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303")

Mining on a PRIVATE network

In a private network, a single CPU miner instance is more than enough for practical purposes as it can produce a stable stream of blocks at the correct intervals without needing heavy resources (consider running on a single thread, no need for multiple ones either). To start a Geth instance for mining, run it with all your usual flags, extended by:

This is buggy >>

$ ./geth <usual-flags> --mine --minerthreads=1 --etherbase=your_eth_account

Which will start mining bocks and transactions on a single CPU thread, crediting all proceedings to the account specified by --etherbase. You can further tune the mining by changing the default gas limit blocks converge to (--targetgaslimit) and the price transactions are accepted at (--gasprice).

Note I had some issue to get my miner to run via the commandline args, but the JavaScript console with Mist worked just fine.

Open Mist and create a new account:

$ ./wallet --rpc your_ipc_endpoint

In the JavaScript console, start your miner.

$ ./geth attach blockchaindata/geth.ipc
> miner.setEtherbase(your_address_from_mist) 
> miner.start(1)

You will notice after you start your miner it will start to build a DAG. This first needs to finish before you will actually start mining Ether. To check your Ether balance using the JavaScript console:

> eth.getBalance(your_address_from_mist)

Network Connectivity, again

To check how many peers the client is connected to in the interactive console, the net module has two attributes give you info about the number of peers and whether you are a listening node.

> net.listening
true
> net.peerCount
4

To get more information about the connected peers, such as IP address and port number, supported protocols, use the peers() function of the admin object. admin.peers() returns the list of currently connected peers.

> admin.peers
[{
  ID: 'a4de274d3a159e10c2c9a68c326511236381b84c9ec52e72ad732eb0b2b1a2277938f78593cdbe734e6002bf23114d434a085d260514ab336d4acdc312db671b',
  Name: 'Geth/v0.9.14/linux/go1.4.2',
  Caps: 'eth/60',
  RemoteAddress: '5.9.150.40:30301',
  LocalAddress: '192.168.0.28:39219'
}, {
  ID: 'a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c',
  Name: 'Geth/v0.9.15/linux/go1.4.2',
  Caps: 'eth/60',
  RemoteAddress: '52.16.188.185:30303',
  LocalAddress: '192.168.0.28:50995'
}, {
  ID: 'f6ba1f1d9241d48138136ccf5baa6c2c8b008435a1c2bd009ca52fb8edbbc991eba36376beaee9d45f16d5dcbf2ed0bc23006c505d57ffcf70921bd94aa7a172',
  Name: 'pyethapp_dd52/v0.9.13/linux2/py2.7.9',
  Caps: 'eth/60, p2p/3',
  RemoteAddress: '144.76.62.101:30303',
  LocalAddress: '192.168.0.28:40454'
}, {
  ID: 'f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0',
  Name: '++eth/Zeppelin/Rascal/v0.9.14/Release/Darwin/clang/int',
  Caps: 'eth/60, shh/2',
  RemoteAddress: '129.16.191.64:30303',
  LocalAddress: '192.168.0.28:39705'
} ]

To check the ports used by geth and also find your enode URI run:

> admin.nodeInfo
{
  Name: 'Geth/v0.9.14/darwin/go1.4.2',
  NodeUrl: 'enode://3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694@[::]:30303',
  NodeID: '3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694',
  IP: '::',
  DiscPort: 30303,
  TCPPort: 30303,
  Td: '2044952618444',
  ListenAddr: '[::]:30303'
}

The [::] is a short hand for localhost / 127.0.0.1.


Blockchain Monopoly

Monopoly Guidelines

  • 8 players (Battleship, Boot, Scottie, Iron, Racecar, Hat, Thimble, Wheelbarrow)
  • Total money in circulation: $15140
  • Each player receives $1500 before round one
  • Bank owns all the property at the start, players buy property from the bank
  • Bank owns all the money at the start of the game
  • The bank pays each player $200 everytime they pass Start
  • Fines gets paid in a Fines Pool and is not owned by anybody
  • Claiming the money in the Fines Pool needs another player / all the player's consensus
  • Players pay 'Rent' to each other when landing on an owned property

To simplify the game, the token owner controls the bank. This can be a player or an external party. A more betterer solution would be to remove the bank owner with claims against the bank which gets approved by the other players.

Application "design"

The Contracts

The application will be split up into multiple contracts, it is neccesary for this use case, but it is fun.

contract Owned {
  /*
    This contract will be used to assign an owner to other cotracts
    and make the execution of certain functions privileged
  */
}
contract Bank {
  /*
    This will function much the same as the Owned contract, but can have a different
    controlling address assigned to it. It will also have a 'bank balance' 
  */
}
contract MonopolyGame {
  /*
    This a contract that creates contracts. When ever someone other than the contract 
    owner wants to play monopoly, they can run this contract and they will get their own "instance"
    of monopoly. This can be compared to buying a copy of a game.
  */
}
contract MonopolyBank is Owned, Bank {
  /*
    The actual monopoly game bank.
    MonopolyBank will be derived from Bank and Owned and will have access to their funtions
  */
}

Modifiers

A modifier are a special type of function that can be called before the function is executed and modify the behaviour of the function, we will build 3 modifiers:

  • onlyOwner
  • onlyBankManager
  • onlyPlayers

Modifiers

Game owner functions

  • NewGame()
  • SetPlayer(string, address)
  • BankPayPlayer(string, int)
  • RefundBank()

Deploying the contracts

We will be deploying via mist, although this can be done using truffle.js which is a MUCH better way to do it.

  1. Ensure your node, miner (not required when cnnected to a network) and mist is running
  2. Make sure mist is running a private-net, otherwise the main Ethereum blockchain will start to sync to your PC

private_net

  1. Open mist and go to the contracts section and click on DEPLOY NEW CONTRACT button

deploy_new_contract

  1. To deploy, copy the code in the monopoly_dao.sol file (in the contracts folder) into the code editing area and select to deploy the Monopoly Game contract

deploy_monopoly_game

  1. The contract will take a while to deploy, but once deploy it should sit under your list of contracts.

To start a monopoly bank

  1. Run the monopoly game contract (give it a name and currency symbol)

new_monopoly_bank.png

  1. After the contract has executed, there should be an entry in the list of created games for your account's address
  2. Memorize or copy this entry (also an address)
  3. Go to the contracts page and WATCH a CONTRACT

watch_contract.png

  1. Enter the entry you cpoied into the address field and give it a name
  2. Copy the content from the MonopolyBank.json file into the interface section and click OK
  3. Start playing monopoly

Other Stuff

  • mapping types are declared as mapping(_KeyType => _ValueType). Here _KeyType can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct. _ValueType can actually be any type, including mappings.
  • mappings with a _KeyType string cannot be made public, since there is no accesor for it. You probably could write one yourself. I did not.
  • Writing to storage is an expensive exercise
  • Deleting contracts from your wallet, open the developer console and do this:
> CustomContracts.find().fetch()
> CustomContracts.remove("S4nttHyBq6wuY3sHN")

BONUS

web3js

Simple demo of how to interact with your local node. To run it:

  • npm install
  • change the contractAddress to the correct address
  • ensure the --rpc flag is set for your node
  • run the node monopoly.js The app will console log everytime the Paid event gets fired.

TODO

  • trufflejs
  • inteface with contacts using only web3
  • bring in more game logic

blockchain-monopoly's People

Contributors

phzietsman avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.