The most expensive version of Conway's Game of Life - running on the Ethereum Blockchain

Overview

GameOfLife

The most expensive implementation of Conway's Game of Life ever - over $2,000 per step! (Probably the slowest too!)

Conway's Game of Life running as a smart contract on the Ethereum Blockchain.

This application would be able to run 'forever' - so long as there was some funds in an Ethereum account that could be used to run each 'step'.

However, the cost of Ethereum (and therefore 'gas') used to run smart contracts is so high that it would cost (in March 2021) over $80 just to register the smart contract, and to run a single 'step' of the game would cost over $2,000! No doubt that the code could be made more efficient and consume less resources, but hey that's just too much work for a concept app, so I have simply registered the contract on the Kovan test network instead, and use some 'fake' Ethereum to run the system. The app is the same, but it just points to the 'Kovan' test network instead of the Ethereum mainnet.

You can see it in action here

The application consists of three parts:

  • Front end Javascript application using the p5js library which runs in your browser
  • A Python Flask app implemented as a google cloud function
  • An Ethereum smart contract written in Solidity which runs on the (Kovan) Ethereum blockchain

p5js - client application

There are just three files in the app: a very simple index.html to host the javascript application in sketch.js along with a simple style.css stylesheet. When started, the app requests the 32x32 grid from the blockchain (via the flask app). Nothing will happen until you press the start button. Once this is pressed the app will request a new step on a timed basis (about one per minute). This will continue until the stop button is pressed. There are a couple of other buttons that will create a random selection on the screen, clear the screen, and add a few gliders. You can also use the mouse to select/deselect individual cells.

Python Flask google cloud function

This started as a bog standard Flask application, but I converted it into a google cloud function to avoid the hassle of having to host it somewhere. Most of the functionality here could have also been included in the browser-based javascript application, but because of my greater familiarity with python and my uncertainty about how to secure the private key needed to sign the solidity transactions I left it running on the server side. The main.py needs some environment variables for it to work. These are configured as part of the deployment script when pushing the flask app to the google cloud service:

gcloud functions deploy gameoflife \
--runtime python38 \
--trigger-http \
--allow-unauthenticated \
--env-vars-file env.yaml
env.yaml:
---
network_name: Kovan
HTTPProvider: 'https://kovan.infura.io/v3/PUT-YOUR-INFURA-KEY-HERE'
contract_address: '0x51B92cef4C0847EF552e4129a28d817c26a4A053'
private_key: 'PUT-THE-PRIVATE-KEY-OF-YOUR-ACCOUNT-HERE'
chain_id: '42'

Ethereum smart contract

The smart contract was written in Solidity. I used VS Code with a solidity extension that highlighted any syntax errors. The testing of the contract was done with the Truffle/Ganache suite of applications, and to get it onto the blockchain I simply used the remix online tool with the metamask browser extension.

I decided that a 32 x 32 cell structure would be big enough the showcase how the game works. In order to reduce the size requirements of data to be stored on the block chain, I used an array of 4 x 256 bit unsigned integers and used this as a bit field. There are three entry points in the contract (apart from the constructor): setCells(), getCells() and step()

Step

The step function mainly consists of loop iterating through the cells, creating/removing cells according to the rules of the game. I didn't make much effort to reduce the amount of work done in order to run a single cell, so I did run foul of one specific issue - the amount of gas consumed. At times it would exceed the limits of even the test networks, and so I ignored some of the cells on the edge of the whole cell universe. It would then take about 11M gas to process it, which is just below the 12M limit for the Kovan network.

for (int16 row=4; row<rows-4; row++) {
    for (int16 col=4; col<cols-4; col++) {
                
        int16 pos = (col + row*cols);
        int count = 0;

        // count_neighbours - count the number of cells that are direct neighbours   
        count += get(pos - cols - 1);  //(row-1,col-1); 
        count += get(pos - cols);      //(row-1,col  );
        count += get(pos - cols + 1);  //row-1,col+1);
        
        count += get(pos - 1); //(row,col-1);
        count += get(pos + 1); //(row,col+1);
        
        count += get(pos + cols -1); //(row+1,col-1);
        count += get(pos + cols); //(row+1,col  );
        count += get(pos + cols + 1); //(row+1,col+1);
                
        // if current cell is alive
        if (get(pos) == 1) {
            if (count > 3) {
                set(pos,0);
            } else if (count == 2 || count == 3) {
                set(pos,1);
            } else if (count < 2) {
                set(pos,0);
            }
        } else { // dead cell
            if (count == 3) {
                set(pos,1);
            }
        }
    }
}

and the get and set functions are implemented as bit twiddlers.

    function set(int16 pos, int8 value) internal {
        // the linear array is held in 4 x 256 unsigned integers 
        uint32 i = uint32(pos) / 256;
        uint32 j = uint32(pos) % 256;
        // if value is 1 then set the j-th bit
        if (value>0){
            newcells[i] |= (1 << j);  // set this bit
        } else {
            newcells[i] &= ~(1 << j);  // turn off this bit
        }   
    }
    function get(int32 pos) view internal returns (int) {

        if (pos<0) {
            pos += rows*cols;
        } 
        if (pos >= rows*cols) {
            pos -= rows*cols;
        }
        // make sure pos always is a valid value
        pos = pos % int32(rows*cols);
        // the linear array is held in 4 x 256 unsigned integers
        uint32 i = uint32(pos) / 256;
        uint32 j = uint32(pos) % 256;
        // if the j-th bit set?
        if ((cells[i] >> j) & 0x01 == 1 ) {
            return 1;
        } else {
            return 0;
        }
    }
Simple progressbar for discord

⚙️ DiscordProgressbar 📂 Установка | Installation pip install discordbar 📚 Документация | Documentation 📞 Связаться со мной | Сontact with me 📜 Ли

DenyS 26 Nov 30, 2022
Project made to analyse movie trends

MovieTrends Project to analyse the daily movie trends from the website The Movie DataBase. The main idea is upload the results to a PostgreSQL server

Jazmín López Chacón 0 Feb 15, 2022
Dodo - A graphical, hackable email client based on notmuch

Dodo Dodo is a graphical email client written in Python/PyQt5, based on the comm

Aleks Kissinger 44 Nov 12, 2022
Python functions to run WASS stereo wave processing executables, and load and post process WASS output files.

wass-pyfuns Python functions to run the WASS stereo wave processing executables, and load and post process the WASS output files. General WASS (Waves

Mika Malila 3 May 13, 2022
This is new discord nitro generator for discord

Hello! This is new discord nitro generator for discord. If you want use it, To generator i added checker for no seraching generator and checker. This tool maked by .

ItzBolt 1 Jan 16, 2022
A Python interface module to the SAS System. It works with Linux, Windows, and mainframe SAS. It supports the sas_kernel project (a Jupyter Notebook kernel for SAS) or can be used on its own.

A Python interface to MVA SAS Overview This module creates a bridge between Python and SAS 9.4. This module enables a Python developer, familiar with

SAS Software 319 Dec 19, 2022
A Python library for rendering ASS subtitle file format using libass.

ass_renderer A Python library for rendering ASS subtitle file format using libass. Installation pip install --user ass-renderer Contributing # Clone

1 Nov 02, 2022
A python SDK for interacting with quantum devices on Amazon Braket

Amazon Braket Python SDK The Amazon Braket Python SDK is an open source library that provides a framework that you can use to interact with quantum co

Amazon Web Services 213 Dec 14, 2022
A simple Discord bot written in Python

Acolyte A small and simple little Discord bot written in Python that utilizes the discord.py library. Dependencies The bot depends on Python 3.9 and u

0 Jul 17, 2021
Takes upcoming items from a Google Calendar and posts them to Slack.

Google Calendar to Slack by Jason Snell - [email protected] This Python s

6 Aug 21, 2022
Discord Bot Sending Members - Leaked by BambiKu ( Me )

Wokify Bot Discord Bot Sending Members - Leaked by BambiKu ( Me ) Info The Bot was orginaly made by someone else! Ghost-Dev just wanted to sell "priva

bambiku 6 Jul 05, 2022
A Discord Tool which checks for valid tokens and adds them to a server

Discord-Server-Botter A Discord Tool which checks for valid tokens and adds them to a server Usage Choice 1 is for checking tokens Choice 2 is for add

Bless 3 Jul 01, 2022
Pythonic wrapper for the Aladhan prayer times API.

aladhan.py is a pythonic wrapper for the Aladhan prayer times API. Installation Python 3.6 or higher is required. To Install aladhan.py with pip: pip

HETHAT 8 Aug 17, 2022
The Github repository for the Amari API wrapper.

Amari.py Amari.py is an async, easy to use API wrapper for the AmariBot. Installation Enter any of these commands to install the library: pip install

TheF1ng3r 5 Dec 19, 2022
pylunasvg - Python bindings for lunasvg

pylunasvg - Python bindings for lunasvg Pylunasvg is a simple wrapper around lunasvg that uses pybind11 to create python bindings. All public API of t

Eren 6 Jan 05, 2023
Chronocalc - Calculates the dates and times when the sun or moon is in a given position in the sky

Chronocalc I wrote this script after I was busy updating my article on chronoloc

16 Dec 13, 2022
A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier

A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier

Amazon Web Services - Labs 1.9k Jan 07, 2023
The modern Lavalink wrapper designed for discord.py

Pomice The modern Lavalink wrapper designed for discord.py This library is heavily based off of/uses code from the following libraries: Wavelink Slate

Gstone 1 Feb 02, 2022
Unofficial WebApp for WhatsApp Web created in PyQt6

Unofficial WebApp for WhatsApp Web created in PyQt6 using PyQt6-WebEngine

Rafael Tosta Santos 126 Dec 20, 2022
My personal discord bot using discord.py

Rara-chan My personal discord bot that I use for stuff that I find interesting. Features Responds to certain messages ChatBot capabilities NHentai scr

Mikask 3 Nov 06, 2022