├── Worlds-Engine
├── player
│ └── .placeholder
├── renderer.js
├── README.md
├── test
│ └── udp.sh
├── main.js
├── package.json
├── css
│ ├── styles.css
│ └── input.css
├── worldConnect.js
├── socket.js
├── server.js
├── actions.js
├── index.html
└── blockConnect.js
├── Worlds-Whitepaper
├── worlds
│ ├── Makefile
│ ├── whitepaper.pdf
│ ├── tokens.md
│ └── whitepaper.tex
└── distributed-db
│ ├── Makefile
│ ├── img
│ ├── nieve.pdf
│ ├── worlds.pdf
│ ├── worldsdb.pdf
│ ├── traditional.pdf
│ ├── tranditional.drawio
│ ├── worlds.drawio
│ ├── nieve.draio
│ └── worldsdb.drawio
│ ├── whitepaper.pdf
│ ├── whitepaper.aux
│ ├── whitepaper.tex
│ └── whitepaper.log
├── Graphics
└── Header.png
├── utils
├── itemMan
│ ├── config.py
│ ├── man.sh
│ ├── it.py
│ └── main.py
├── scp.sh
└── ftp
│ ├── serv
│ ├── ftp.sh
│ ├── createUser.sh
│ └── vsftpd.conf
│ └── client
│ └── moveItems.py
├── scripts
├── wor_unlock_wallet
├── wor_deploy_contract
├── wor_create_tokens
├── wor_issue_tokens
├── wor_transfer_tokens
├── wor_create_wallet
├── wor_run_chain
├── wor_create_account
├── wor_create_item
├── wor_get_token_balance
├── wor_init
├── wor_liquid_item
├── wor_transfer_item
├── wor_get_table
├── wor_delete_item
└── config.ini
├── .gitmodules
├── .gitignore
├── WSC
├── Makefile
├── WSC.hpp
└── WSC.cpp
├── source_env.sh
├── README.md
└── LICENCE
/Worlds-Engine/player/.placeholder:
--------------------------------------------------------------------------------
1 | 0
2 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/worlds/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | pdflatex whitepaper.tex
3 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | pdflatex whitepaper.tex
3 |
--------------------------------------------------------------------------------
/Graphics/Header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Graphics/Header.png
--------------------------------------------------------------------------------
/utils/itemMan/config.py:
--------------------------------------------------------------------------------
1 | root = "/home/worlds/players/"
2 | fifo = "/home/worlds/Worlds/Worlds/Realm.One/bin/fifo"
3 |
--------------------------------------------------------------------------------
/scripts/wor_unlock_wallet:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 | cleos wallet unlock -n worlds --password $EOS_PW
5 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Worlds/Realm.One"]
2 | path = Worlds/Realm.One
3 | url = https://github.com/Machine-Hum/Realm.One
4 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/worlds/whitepaper.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/worlds/whitepaper.pdf
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/nieve.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/distributed-db/img/nieve.pdf
--------------------------------------------------------------------------------
/scripts/wor_deploy_contract:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 |
5 | cleos -u $IP set contract -f wsc.code $PJ_ROOT/WSC -p wsc.code@active
6 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/worlds.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/distributed-db/img/worlds.pdf
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/whitepaper.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/distributed-db/whitepaper.pdf
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/worldsdb.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/distributed-db/img/worldsdb.pdf
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/traditional.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/o7-machinehum/Worlds/HEAD/Worlds-Whitepaper/distributed-db/img/traditional.pdf
--------------------------------------------------------------------------------
/scripts/wor_create_tokens:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 |
5 | cleos -u $IP push action wsc.code createwor '["wsc.code", "1000.00 WOR"]' -p wsc.code@active
6 |
--------------------------------------------------------------------------------
/scripts/wor_issue_tokens:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 |
5 | cleos -u $IP push action wsc.code issuewor '["turnip", "10.00 WOR", "Hi"]' -p wsc.code@active
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Worldcmd.pyc
2 | __pycache__
3 | *.pem
4 | AL/*
5 | Worlds-Whitepaper/whitepaper.aux
6 | Worlds-Whitepaper/whitepaper.log
7 | Worlds-Engine/node_modules/*
8 | *json
9 |
--------------------------------------------------------------------------------
/scripts/wor_transfer_tokens:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cleos -u http://192.168.10.35:8888 push action wsc.code transferwor '["turnip", "turnip2", "10.00 WOR", "Hi"]' -p turnip@active
4 |
--------------------------------------------------------------------------------
/scripts/wor_create_wallet:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | cleos wallet create -n worlds --to-console
3 | cleos wallet import -n worlds --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
4 |
--------------------------------------------------------------------------------
/Worlds-Engine/renderer.js:
--------------------------------------------------------------------------------
1 | // This file is required by the index.html file and will
2 | // be executed in the renderer process for that window.
3 | // All of the Node.js APIs are available in this process.
4 |
--------------------------------------------------------------------------------
/scripts/wor_run_chain:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 | nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --contracts-console --filter-on "*" --http-server-address=$IP:8888
5 |
--------------------------------------------------------------------------------
/utils/scp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | scp ../Worlds/Realm.One/bin/* worlds@192.168.10.35:~/Worlds/Worlds/Realm.One/bin/
4 | # scp ../Worlds/Realm.One/bin/serverRundb.sh worlds@192.168.10.35:~/Worlds/Worlds/Realm.One/bin/
5 |
--------------------------------------------------------------------------------
/scripts/wor_create_account:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 |
5 | cleos -u $IP create account eosio wsc.code $EOS_PUB
6 | cleos -u $IP create account eosio turnip $EOS_PUB
7 | cleos -u $IP create account eosio turnip2 $EOS_PUB
8 |
--------------------------------------------------------------------------------
/WSC/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for the worlds smart contact
2 |
3 | CC=eosio-cpp
4 | Contract=WSC
5 |
6 | all:
7 | @echo "Building"
8 | $(CC) $(Contract).cpp
9 |
10 | clean:
11 | rm -f $(Contract).abi
12 | rm -f $(Contract).wasm
13 |
--------------------------------------------------------------------------------
/scripts/wor_create_item:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 | cleos -u http://$IP:8888 push action wsc.code createitem '{"owner":"turnip","item_name":"Sword","item_class":"Weapon","nuance":"0001","stake":"1.00 WOR"}' -p turnip@active
5 |
--------------------------------------------------------------------------------
/utils/itemMan/man.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | inotifywait -mr /home/worlds/players/ -e create -e moved_to |
4 | while read path action file; do
5 | echo "The file '$file' appeared in directory '$path' via '$action'"
6 | python3 main.py $path $file
7 | done
8 |
--------------------------------------------------------------------------------
/scripts/wor_get_token_balance:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source wor_init
4 |
5 | if [ $# -eq 0 ]
6 | then
7 | echo "No arguments supplied, first argument is name of player"
8 | exit
9 | fi
10 |
11 | cleos -u $IP get currency balance wsc.code $1 WOR
12 |
--------------------------------------------------------------------------------
/Worlds-Engine/README.md:
--------------------------------------------------------------------------------
1 | #Worlds Engine
2 | The worlds engine is a JS application that communicates with the worlds smart contract.
3 |
4 | ## Running The Client
5 | ```bash
6 | npm install
7 | npm start
8 | ```
9 |
10 | ## Running The Server
11 | ```bash
12 | node server.js
13 | ```
14 |
--------------------------------------------------------------------------------
/scripts/wor_init:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | EOS_PW=PW5JM4my4QGYe8eoAjFHYLgMrRe3C7mdw5iB9VtaTPEgkZr5EfWGW
4 | EOS_PUB=EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
5 | # IP="http://127.0.0.1:8888"
6 | IP=$(ipconfig getifaddr en0 2>/dev/null || hostname -i)
7 | PJ_ROOT=/Users/machinehum/worlds
8 |
--------------------------------------------------------------------------------
/scripts/wor_liquid_item:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Make these into vars in the future
4 | cleos push action wsc.code liquiditem '{"tx_item":{"ItemName":"Sword", "ItemClass":"Weapon", "Nuance":"0000","Owner":"turnip", "OriginWorld":"turnip", "GenesisTime":"429717", "Stake":"1.00 WOR"}}' -p turnip@active
5 |
--------------------------------------------------------------------------------
/scripts/wor_transfer_item:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source init_wor
4 | cleos push action wsc.code transferitem '{"to":"turnip2", "tx_item":{"ItemName":"Sword", "ItemClass":"Weapon","Nuance":"0000", "Owner":"turnip", "OriginWorld":"turnip", "GenesisTime":"429762", "Stake":"1.00 WOR"}}' -p turnip@active
5 |
--------------------------------------------------------------------------------
/scripts/wor_get_table:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ $# -eq 0 ]
4 | then
5 | echo "No arguments supplied, first argument is name of player"
6 | exit
7 | fi
8 |
9 | source wor_init
10 |
11 | owner=wsc.code
12 | table=itemproofs
13 |
14 | cleos -u http://$IP:8888 get table $owner $1 $table
15 |
--------------------------------------------------------------------------------
/scripts/wor_delete_item:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | arg=''\''{"owner":"turnip","hash":"'$1'"}'\'''
4 | echo $arg
5 |
6 | # idk why this isn't working
7 | cleos push action wsc.code deleteitem '{"owner":"turnip","hash":"ce42a2e1454f00b8c286488468a1f23928664d778e225d272880da55da5fa7be"}' -p turnip@active
8 | # cleos push action wsc.code deleteitem $arg turnip@active
9 |
--------------------------------------------------------------------------------
/utils/ftp/serv/ftp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # FTP Code
4 | ## https://likegeeks.com/ftp-server-linux/
5 | ## We want FTP to be in passive mode. Meaning the connections are initiated by the client.
6 |
7 | # sudo apt install vsftpd
8 |
9 | systemctl start vsftpd # start the service
10 | systemctl enable vsftpd # Enable it to run at boot time
11 |
12 | cp vsftpd.conf /etc/ # Copy the configuration file
13 |
--------------------------------------------------------------------------------
/utils/ftp/client/moveItems.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | ## Example ./moveItems.sh 192.168.10.35 turnip test fname
3 |
4 | from ftplib import FTP
5 | import sys
6 | import pdb
7 |
8 | filename = str(sys.argv[4])
9 |
10 | ftp = FTP(str(sys.argv[1]))
11 | ftp.login(user=str(sys.argv[2]), passwd=str(sys.argv[3]))
12 | ftp.cwd('items') # change into user dir
13 |
14 | with open(filename, 'rb') as fp:
15 | ftp.storlines('STOR ' + filename, fp)
16 |
17 | ftp.sendcmd('SITE CHMOD 644 ' + filename)
18 |
--------------------------------------------------------------------------------
/Worlds-Engine/test/udp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # "Name": "turnip",
4 | # "PubKey": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
5 | # "Data": "1550005850284turnip",
6 | # "Proof": "SIG_K1_KX1VqVbdvSVXQLWb45utWcBB4TbNtXEEVPPs8sRLURsDLNjcyvpFeRukoYYcoH7Dq6DHtrWaPfaMxLCfaW95tiKuX1EqKg"
7 |
8 | # verify(Proof, Data, PubKey)
9 | echo "verify('SIG_K1_KX1VqVbdvSVXQLWb45utWcBB4TbNtXEEVPPs8sRLURsDLNjcyvpFeRukoYYcoH7Dq6DHtrWaPfaMxLCfaW95tiKuX1EqKg','1550005850284turnip', 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV')" > /dev/udp/127.0.0.1/40000
10 |
--------------------------------------------------------------------------------
/utils/ftp/serv/createUser.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | player=$1 # First CLI argument is the playername
4 | pw="test" # Change Later
5 |
6 | useradd $player
7 | echo -e "$pw\n$pw" | passwd $player
8 | mkdir -p /var/ftp/$player
9 | mkdir -p ~/players/$player/items
10 | mkdir -p ~/players/$player/exp
11 |
12 | mount --bind ~/players/$player /var/ftp/$player
13 | usermod -d /var/ftp/$player/ $player
14 |
15 | sudo chown -R $player:$player ~/players/$player/
16 |
17 | # NOTE: https://www.linuxquestions.org/questions/linux-newbie-8/500-oops-could-not-read-chroot-list-file-etc-vsftpd-chroot_list-4175426540/
18 |
--------------------------------------------------------------------------------
/Worlds-Engine/main.js:
--------------------------------------------------------------------------------
1 | const {app, BrowserWindow} = require('electron')
2 | let mainWindow
3 |
4 | function createWindow () {
5 |
6 | mainWindow = new BrowserWindow({width: 400, height: 800})
7 | mainWindow.loadFile('index.html')
8 | mainWindow.webContents.openDevTools()
9 |
10 | mainWindow.on('closed', function () {
11 | mainWindow = null
12 | })
13 | }
14 |
15 | app.on('ready', createWindow)
16 |
17 | app.on('window-all-closed', function () {
18 | if (process.platform !== 'darwin') {
19 | app.quit()
20 | }
21 | })
22 |
23 | app.on('activate', function () {
24 | if (mainWindow === null) {
25 | createWindow()
26 | }
27 | })
28 |
29 |
--------------------------------------------------------------------------------
/Worlds-Engine/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worlds-engine",
3 | "version": "0.0.1",
4 | "description": "The Worlds Engine is the application that lives in between the Game Engine and the Worlds Smart Contract (WSC)",
5 | "main": "main.js",
6 | "scripts": {
7 | "start": "electron --inspect ."
8 | },
9 | "author": "machinehum",
10 | "license": "ISC",
11 | "dependencies": {
12 | "dgram": "^1.0.1",
13 | "electron": "^11.5.0",
14 | "eosjs": "^16.0.8",
15 | "eosjs-ecc": "^4.0.4",
16 | "js-sha256": "^0.9.0",
17 | "node-cmd": "^3.0.0",
18 | "object-hash": "^1.3.1",
19 | "preact": "^8.3.1",
20 | "repl": "^0.1.3",
21 | "stylus": "^0.54.5"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/utils/itemMan/it.py:
--------------------------------------------------------------------------------
1 | # This is the item translation file. It translates all the items that are common in the worlds universe to items
2 | # the exist in the your personal world. The first element is the string that you world identifies the item as, the second
3 | # is the minimum amount of staked WOR against the item to allow it to pass.
4 |
5 | translation = {
6 | # WORLD MINETEST ITEMS COST
7 | "WoodSword" : ["default:sword_wood", 0.03 ],
8 | "StoneSword" : ["default:sword_stone", 0.06 ],
9 | "BronzeSword" : ["default:sword_bronze", 0.2 ],
10 | "SteelSword" : ["default:sword_steel", 0.27 ],
11 | "MeseSword" : ["default:sword_mese", 0.8 ],
12 | "DiamondSword" : ["default:sword_diamond", 1 ],
13 |
14 | "WoodPickaxe" : ["default:pickaxe_wood", 0.03 ],
15 | "StonePickaxe" : ["default:pickaxe_stone", 0.06 ],
16 | "BronzePickaxe" : ["default:pickaxe_bronze", 0.2 ],
17 | "SteelPickaxe" : ["default:pickaxe_steel", 0.27 ],
18 | "MesePickaxe" : ["default:pickaxe_mese", 0.8 ],
19 | "DiamondPickaxe" : ["default:pickaxe_diamond", 1 ]
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Worlds-Engine/css/styles.css:
--------------------------------------------------------------------------------
1 | body {background-color: #001011;}
2 |
3 | * {
4 | box-sizing: border-box;
5 | font-family: sans-serif;
6 | color: #3AAFB9 !important
7 | }
8 |
9 | /* Create two equal columns that floats next to each other */
10 | .column {
11 | float: below;
12 | width: 100%;
13 | padding: 10px;
14 | }
15 |
16 | /* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
17 | @media screen and (max-width: 600px) {
18 | .column {
19 | width: 100%;
20 | }
21 | }
22 |
23 | #content input
24 | {
25 | width:100%;
26 | box-sizing:border-box;
27 | -moz-box-sizing:border-box;
28 | color:#001011 !important
29 | }
30 |
31 | #content select
32 | {
33 | color:#001011 !important
34 | }
35 |
36 | #content option
37 | {
38 | color:#001011 !important
39 | }
40 |
41 | img {
42 | max-width: 100%;
43 | height: auto;
44 | }
45 |
46 | hr.new {
47 | border: 10px solid #001011;
48 | border-radius: 5px;
49 | width: 120%;
50 | margin: 0em;
51 | }
52 |
53 | .button {
54 | display: inline-block;
55 | line-height: 3em;
56 | background: #001011;
57 | background-clip: padding-box;
58 | border: none;
59 | width: 100%
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/Worlds-Engine/worldConnect.js:
--------------------------------------------------------------------------------
1 | // This is responcible to connected to the worlds client
2 | // Is has various commands for moving items into the game etc
3 |
4 | var net = require('net');
5 | var fs = require('fs')
6 |
7 | var world = {
8 | wor_sock: null,
9 | enter: function() {
10 |
11 | if (self.wor_sock == null) {
12 | console.log('Conecting');
13 | IP = document.getElementById("world_client_ip").value;
14 | Port = document.getElementById("world_client_port").value;
15 | self.wor_sock = new net.Socket();
16 | self.wor_sock.connect(Port, IP);
17 | console.log('Connecting ' + IP + Port);
18 | }
19 |
20 | // Time to get all your shit into the world
21 | files = fs.readdirSync('items')
22 | for(var i = 0 ; i < files.length ; i++) {
23 | if(files[i] == 'placeholder') {
24 | // delete files[i]
25 | files.splice(i)
26 | }
27 | }
28 |
29 | // Dump all the items over to the server meow.
30 | for(i = 0 ; i < files.length ; i++) {
31 | item = fs.readFileSync('items/' + files[i]);
32 | console.log('Sending' + item);
33 | self.wor_sock.write(item);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Worlds-Engine/socket.js:
--------------------------------------------------------------------------------
1 | /* socket.js
2 | sending
3 | const message = Buffer.from('Some bytes');
4 | const client = dgram.createSocket('udp4');
5 | client.send(message, 41234, 'localhost', (err) => {
6 | client.close();
7 | });
8 | */
9 |
10 | const dgram = require('dgram');
11 | const server = dgram.createSocket('udp4');
12 | var bc = require('./blockConnect')
13 |
14 | var client = null
15 | var outPort = null
16 |
17 | function processCmd(msg){
18 | bc.act(`${msg}`)
19 | }
20 |
21 | module.exports = {
22 | open: function (port){
23 | server.on('error', (err) => {
24 | console.log(`server error:\n${err.stack}`);
25 | server.close();
26 | });
27 | server.on('message', (msg, rinfo) => {
28 | processCmd(msg);
29 | });
30 |
31 | server.on('listening', () => {
32 | const address = server.address();
33 | console.log(`server listening ${address.address}:${address.port}`);
34 | });
35 |
36 | server.bind(port);
37 | },
38 |
39 | openOutgoing: function (port){
40 | outPort = port;
41 | const message = Buffer.from('Some bytes');
42 | client = dgram.createSocket('udp4');
43 | },
44 |
45 | send: function (msg){
46 | client.send(msg, outPort, 'localhost', (err) => {
47 | client.close();
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/tranditional.drawio:
--------------------------------------------------------------------------------
1 | 3VlRk5owEP41Pt4NEAR97OnZ67TXuRkf7vqYQiq0SJgQT+mvb5AESCKKiuL1Hm7Ikizw7bfZL+sATJabzwQmwTP2UTSwDH8zANOBZbljwP7nhqww2LZVGBYk9AuTWRnm4V/EjQa3rkIfpdJEinFEw0Q2ejiOkUclGyQEr+Vpv3AkPzWBC6QZ5h6MdOtr6NOgsI6GRmV/QuEiEE82DX5nCcVkbkgD6ON1zQQeB2BCMKbF1XIzQVGOncClWDdruFu+GEExbbXAsZ/f35avSfT9yV19Tb/4Y/OOB+MdRiv+wZMozB1aBn9ASjOBBcGr2Ee5O2MAHtZBSNE8gV5+d82Cz2wBXUZsZLJL7hgRijaNb2yWODD+ILxElGRsCl9gc+Q4dSyHj9e1QHBTUIuBWAZ56Bel4woddsEBOgIsoIE1R4R94U2AZRmnoeVcCi3L0TBBPsstPsSEBniBYxg9VtYHGbVqzjeME47Vb0RpxjcKuKJYRpKhRbK3+uBH7ux+KIbTDXdejDI+Sikk9FO+YTCDF8E0DT1hnoWRHKj8O/aHie1SkCwQ3YePvTueBEWQhu/yA3ZFhy99weE2XzkPgCPzABhKgFO8Ih7iq6oYs2+HWW1akk9Ij3/OrGm+eeb8sTSfXRRvXBG0xPB0ztpahk8hhT9hinrPbxXv3vPb0bDS8z32G1JKN9dzeBPSt9p1LYPZqErgfCDyt31iFvw/VBP1ONRwHu7AWdjOTN8hkMNsq/FrSF/NkVYPRoqjYoM6ex8wVV6OrpCn7k1xr6w5xnE1py1n++JiSRkRWnd87ype2tJR2752+GpgZFekEQVll9iNe9/fFbEL+ha7pq52byLH7ox7w7DlRHNGzoFU245eEAkZOEywC81H8B80wREm2+8Bsxlgf91WE8G6g3oQ9JnqanraLVWj5shWZdvwQmVHzZfRfjmpzT8gP0137/zLlDXzuLoW4zg/M/kwDbYblSmnWW5/gZTxPd5aLAOUpBe9DOsDlKHRAUa1pabqx2zHzK6CK2LZTXBvPWjAUjYUtVC1Fg6Ko7Kfdq2wHVcHP3jYVDV/cti0Y8G1w6Yf5ctmXf9iTz2ctVV7FzvMi1PneWqPk7+GVbPEYt5qfbV6n+0jHI2a5MHxeTJ25YRTHXWll5QXtq+hZ4B5Iqt2NXSVw7Vg0ZGavy2xzmjgXomB6uFc7e+0bhSpjdxLKXZVf12jUQQ6FV3/i6LWmg2nSmoLVF0c4auzQs+G1a+jxfTqJ2bw+A8=
--------------------------------------------------------------------------------
/source_env.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cat << "EOF"
4 | ,--,
5 | ,----.. ,---.'|
6 | .---. / / \ ,-.----. | | : ,---, .--.--.
7 | /. ./| / . : \ / \ : : | .' .' `\ / / '.
8 | .--'. ' ; . / ;. \; : \ | ' : ,---.' \ | : /`. /
9 | /__./ \ : |. ; / ` ;| | .\ : ; ; ' | | .`\ |; | |--`
10 | .--'. ' \' .; | ; \ ; |. : |: | ' | |__ : : | ' || : ;_
11 | /___/ \ | ' '| : | ; | '| | \ : | | :.'|| ' ' ; : \ \ `.
12 | ; \ \; :. | ' ' ' :| : . / ' : ;' | ; . | `----. \
13 | \ ; ` |' ; \; / |; | | \ | | ./ | | : | ' __ \ \ |
14 | . \ .\ ; \ \ ', / | | ;\ \; : ; ' : | / ; / /`--' /
15 | \ \ ' \ | ; : / : ' | \.'| ,/ | | '` ,/ '--'. /
16 | : ' |--" \ \ .' : : :-' '---' ; : .' `--'---'
17 | \ \ ; `---` | |.' | ,.'
18 | '---" `---' '---'
19 |
20 |
21 | Setting up the worlds enviornment. All scripts are prefixed
22 | with wor_, you show now have access with wor_
23 | EOF
24 |
25 | PATH=$PATH:$(pwd)/scripts
26 |
27 | # Create a folder required for the engine
28 | mkdir Worlds-Engine/items 2> /dev/null
29 |
--------------------------------------------------------------------------------
/Worlds-Engine/css/input.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 | body {
6 | display: grid;
7 | font-family: Avenir;
8 | -webkit-text-size-adjust: 100%;
9 | -webkit-font-smoothing: antialiased;
10 | }
11 | * {
12 | box-sizing: border-box;
13 | }
14 | .inp {
15 | position: relative;
16 | margin: auto;
17 | width: 100%;
18 | max-width: 280px;
19 | }
20 | .inp .label {
21 | position: absolute;
22 | top: 16px;
23 | left: 0;
24 | font-size: 16px;
25 | color: #9098a9;
26 | font-weight: 500;
27 | transform-origin: 0 0;
28 | transition: all 0.2s ease;
29 | }
30 | .inp .border {
31 | position: absolute;
32 | bottom: 0;
33 | left: 0;
34 | height: 2px;
35 | width: 100%;
36 | background: #07f;
37 | transform: scaleX(0);
38 | transform-origin: 0 0;
39 | transition: all 0.15s ease;
40 | }
41 | .inp input {
42 | -webkit-appearance: none;
43 | width: 100%;
44 | border: 0;
45 | font-family: inherit;
46 | padding: 12px 0;
47 | height: 48px;
48 | font-size: 16px;
49 | font-weight: 500;
50 | border-bottom: 2px solid #c8ccd4;
51 | background: none;
52 | border-radius: 0;
53 | color: #223254;
54 | transition: all 0.15s ease;
55 | }
56 | .inp input:hover {
57 | background: rgba(34,50,84,0.03);
58 | }
59 | .inp input:not(:placeholder-shown) + span {
60 | color: #5a667f;
61 | transform: translateY(-26px) scale(0.75);
62 | }
63 | .inp input:focus {
64 | background: none;
65 | outline: none;
66 | }
67 | .inp input:focus + span {
68 | color: #07f;
69 | transform: translateY(-26px) scale(0.75);
70 | }
71 | .inp input:focus + span + .border {
72 | transform: scaleX(1);
73 | }
74 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/worlds.drawio:
--------------------------------------------------------------------------------
1 | 5VrbcqMgGH6aXLajojG5bNPTTtudzvai3UuqRNkSySA57dMvRvCEOZvEbm8y8PGD8P1HmHTAYDS/Z3AcPlMfkY5l+PMOuOlYltsH4jcBFilg22YKBAz7KVQAXvFfJEFDohPso7gkyCklHI/LoEejCHm8hEHG6KwsNqSk/NUxDJAGvHqQ6Ogb9nmYoj3HyPEHhINQfdk05MgIKmEJxCH06awAgdsOGDBKedoazQeIJNwpXtJ5dytGs40xFPFtJvxyTBuRftRzHwNz8HnvPbn2hSnVE/OFOjHyBQGySxkPaUAjSG5z9JrRSeSjZFlT9HKZJ0rHEvyDOF9IbcIJpwIK+YjIUTTH/L3Q/i3axqXlyO5NYjyG6ixUJ+Js8V7sFKcl/XzesqcmxhwyfpXYggA8AuMYewq+w0RtKiUiOf1KgiUU0wnzlFTXfp6+j97G5OeDO3mMf/h988KShgpZgPgaOZCZgXAfREdIbFvMY4hAjqflfUBpyEEml+taNKS6d1G93R7Vu99O9ZZ9oO6XU8XR4KIgMKY44nFh5ZcEEAIyHJuuDEYyGgOzEjM2ybtGxe7SHeRWmB1lK8NcR+EUkomkYUAwWm7L1Ew2N8hE37MQc/Q6hksVzURCKhvfSrVOEeNoXoB0xchRu0yI1ZP9WSE5SCgs5AU1rXkv7rXHi7d1YunumR+3zomB7sS15Fsnit/rNllwk1fEhCG3wk0so21+4rTHT/bMdm5D2W4omgNKKFvSAIY9D3mpHKOfqDDy0XNsx2jWtVRdf/wEeZi5dNtjLnvWxd/LXA4tpfcrp5y15dFmeXuDfO9AefME5ZpSUV29Fp09EVXqNdA9XR6qD2t6datHmshXbhnRKIksPozDLLBsQ1DF+XR6Cud3as6vsN38RzNIYJXpt6u8pgFAzlpj2dWFslcVtVAaILSFGruT6NXWf6w2s9uQ2qoLHVFt9Wnc0LX0xW5HZutuR5at5+T2XY/ULuvuR+dPS9X70dnzEmg0LyX4C+QcsWiJWAbIKkb1jG59gUAo+L5U76RKU86esVArRcBpUxjQU9hHx+oSnmhmkjSDpGkoTHykAJ/dYzK6FH2W7jH2kTymPrdsRad5PDo17moYXl0Xmy2jU48/dXRGbaWz3zI6nSbD+bbFw7nCtL3inrxzjLa7GxY6cr3a/VZaq9ZAe18ON6l/hdZ2fe4Bfaf2O009r9SahKuZxDWh3qcXQqyXsSKA8bIRlF/ppMUUn/QkBAkOklrNE7YhamRwnYRD7EFyJQdG2PeX16O6YFoOt0MacXXFWpXndwquRpl3q6ZYrguu1ctmc6lfz/0H+OluxXJ7/bnqhfsWytV1GquTRTf/u00qnv9nCdz+Aw==
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/nieve.draio:
--------------------------------------------------------------------------------
1 | 5VrbctowEP0aHsPIli/w2JDQdNp0MsND0keNrWI3xmJkEXC/vjKWfJEw2NxM2zxkvIu8snePjo4WBnCy2HymaBk8Ex9HAxP4mwF8GJimO4b8f+ZIc4cFQO6Y09DPXUbpmIW/sXDKYavQx0ltICMkYuGy7vRIHGOP1XyIUrKuD/tJovqsSzTHmmPmoUj3voY+C3LvyAal/wmH80DObMj3WyA5WDiSAPlkXXHBxwGcUEJYfrXYTHCU5U7mJb9v2vBp8WAUx6zVDY71/PG2eF1G35/c1dfkiz827sw8ygeKVuKFJ1GYBTSBmCBhqcwFJavYx1k4MID36yBkeLZEXvbpmhef+wK2iLhl8EsRGFOGN41PbBR54PjBZIEZTfmQjcRKfoeAjukIe10phHAFlRrI25Ao/bwIXGaHX4gEdUgW1JI1w5S/4U0kywTHZcu5VLZMR8sJ9vnaEiahLCBzEqPosfTe17NWjvlGyFLk6hdmLBVEgVaM1DPJs0XTt6rxIws2tKX5sBHBcysVVsIQZZ8ywuAOL0JJEnrSPQ2jIvwmZG/bgK4BhZ1NYAxBVpytXc6QGWnFeME05MnliMl9eYKyrOwvOk8iWVEP78k2tAU5IjrHbF9ZrN0wojhCLPyoP8kuUIhbX0i4pQkBP+jU4QeBgqv8DcRdJbR4ylFaGbbMBiTN89jQrc8zBgpS84glbot3PB7KjrbwdWjHfgN6dHcVrgJPRgVLAqyNSDojaszdWKhQhr2DMqTvRMjYsA4ZS6WiBshogTTqGymB8kVxMvYMZ/c8F8Wee1PYK+gVDE27yrDGAX5tD9qDDJZTXV+oLcAlQeCO+V5wHHBV0twV60zYhbbCz6paVBdnw5q6KNal6N8lR+PeFZYiR2HfctTQ9ehNUMMdGAJg1eWXM3IOEMTWUgVSwih5xxMSEbp9HzidQv533k1Qou4w8fTJOypXWC0FlhbIMhQc2xfaLdX1MtrPONp4cGC8u3f8hRiq23Yckzg71fgoCbZEZdSXWeZ/QYzjPd56TAAL0Mtug9kB7H1hc3QAUW2hqcYx2iHzXMWVtTxPcW+9aFIBFISiblStVYwSqOh4Xats3fbBv7xs6iHk6LJpp5lrl83Syla00/oXe+qZsq3au1g7TR6WT1N7AvyVXDVLLB6t0vmqdsK6HOh6WycN8qD7OhnXO06a8DqXXlIe2LqGnoHGkaja1XIFdc0vUdRR87cF1gm9zishUO0UqG2p1v0ttbd6KcWu6q9rnPnhWUXXv6KotWbDsZLahGVLSWn9XGujh7o+u4+I9z4o9tge93mtBWf1vc/bjdnqXxVZKqX1nq1uX838J+xhKc1e0z2SPSz3QKCjqYOb5U8f8uHl70fg4x8=
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/whitepaper.aux:
--------------------------------------------------------------------------------
1 | \relax
2 | \@writefile{toc}{\contentsline {title}{Worlds.db: a Proveably Fair Database}{1}\protected@file@percent }
3 | \@writefile{toc}{\authcount {1}}
4 | \@writefile{toc}{\contentsline {author}{Ryan Walker\unskip \ \ignorespaces ryan.cjw@gmail.com}{1}\protected@file@percent }
5 | \@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}\protected@file@percent }
6 | \@writefile{toc}{\contentsline {section}{\numberline {2}Overview}{1}\protected@file@percent }
7 | \@writefile{toc}{\contentsline {section}{\numberline {3}Archatecture}{2}\protected@file@percent }
8 | \@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Existing Design}{2}\protected@file@percent }
9 | \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Traditional Design}}{2}\protected@file@percent }
10 | \newlabel{trad}{{1}{2}}
11 | \@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Naive Design}{2}\protected@file@percent }
12 | \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Naive Design}}{2}\protected@file@percent }
13 | \newlabel{naive}{{2}{2}}
14 | \@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Worlds Design}{3}\protected@file@percent }
15 | \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Worlds Design}}{3}\protected@file@percent }
16 | \newlabel{fig:Worlds}{{3}{3}}
17 | \@writefile{toc}{\contentsline {subsubsection}{Issues}{3}\protected@file@percent }
18 | \@writefile{toc}{\contentsline {section}{\numberline {4}Worlds.db}{3}\protected@file@percent }
19 | \@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Worlds.db}}{3}\protected@file@percent }
20 | \newlabel{fig:worldsdb}{{4}{3}}
21 | \@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Security}{4}\protected@file@percent }
22 | \@writefile{toc}{\contentsline {section}{\numberline {5}Advantages}{4}\protected@file@percent }
23 | \@writefile{toc}{\contentsline {section}{\numberline {6}Conclusion}{4}\protected@file@percent }
24 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/worlds/tokens.md:
--------------------------------------------------------------------------------
1 | ```
2 | _____________________
3 | < Token Cap Table V0.1>
4 | ---------------------
5 | \ ,-^-.
6 | \ !oYo!
7 | \ /./=\.\______
8 | ## )\/\
9 | ||-----w||
10 | || ||
11 | ```
12 |
13 | - When determining the cap table, three things should be kept in mind.
14 | 1) Game developers should be incentivised to integrate their games into Worlds
15 | 2) Gamers should be incentivised to play on Worlds
16 | 3) The developers of Worlds should be rewarded if the platform is successful.
17 | 4) We may need to raise capital (fiat)
18 | Outline
19 | ---------------------
20 | 1) Incentivisation of game developers
21 | A certain percentage of the total supply of WOR should be kept in a
22 | treasury - managed by the developers of Worlds. This is given to game
23 | developers through a faucet mechanism, as apposed to a lump sum. If the
24 | developers stop making progress, the faucet is turned off and the funds are
25 | no longer delivered.
26 |
27 | 2) Incentivation of Players
28 | Setup an air grab in several stages, the WOR tokens you can grab are a
29 | percentage of your owned mainnet token at a given time. The airgrab should
30 | happen after platform launch, once people know what it's capable of.
31 |
32 | 3) Incentiation of Worlds Developers
33 | The trick is fair distribution. What I propose it - everyone tracks
34 | their hours against a commit. The hour tracking is kept in a simple text
35 | format with the number of hours, and the sha of the commit next to it. When
36 | the time comes to divide up the WOR, it's done as a fraction of hours. Ideally
37 | there is more than one token distrobution cycle, to foster new developers
38 | coming to help.
39 |
40 | 4) Raising
41 | This is simple, we sell tokens to accredited investors, this cash would then be
42 | used to hire developers or pay ourselves to work full time.
43 |
44 | Proposed Distribution
45 | ---------------------
46 | 1) Game Developers - 40%
47 | 2) Players - 30%
48 | 3) Worlds Developers - 20%
49 | 4) Investment - 10%
50 |
--------------------------------------------------------------------------------
/utils/itemMan/main.py:
--------------------------------------------------------------------------------
1 | ## Purpose of this script. In the order of implementation.
2 | # 1. Write to the fifo file which is echoed into the gameserver. Commands are...
3 | # /give [ []] and whatever else is here: https://wiki.minetest.net/Server_commands
4 | # 2. Ensure players don't double deposit items. This is done with a .json file which records which items players have deposited.
5 | # 3. (Future) Sign outgoing items. Meaning if a player picks up an items in the gameworld some WOR should be staked into it. It should be submitted to the BC.
6 | # this is done by checking the sqlite database that is maintained by the server. Only some items should be submitted.
7 |
8 | import config as cfg
9 | import json
10 | import pdb
11 | import sys
12 | import it
13 |
14 | def writeFifo(string):
15 | with open(cfg.fifo, "w") as text_file:
16 | text_file.write(string)
17 |
18 | class Item:
19 | def __init__(self, path, item):
20 | with open(sys.argv[1] + sys.argv[2]) as json_file:
21 | self.item = json.load(json_file)
22 |
23 | if(self.Verify() == False):
24 | return
25 | self.name = str(self.item['Owner'])
26 | self.itemName = str(self.item['ItemName'])
27 | self.stake = float(str(self.item['Stake']).strip(' WOR'))
28 |
29 | if(self.Translate() == False): # Translate the item into something minetest cares about
30 | return
31 | self.giveItem() # Give the item to the player.
32 |
33 | # This function takes in sel
34 | def Translate(self):
35 | self.itemOut = it.translation[self.itemName][0]
36 |
37 | # Ensure there is enought stakes into the item.
38 | if(it.translation[self.itemName][1] > self.stake):
39 | return False
40 |
41 | def Verify(self):
42 | print('Right Here make sure the Items is onchain')
43 | return(True) # But right now we cheat.
44 |
45 | def giveItem(self):
46 | writeFifo('/give ' + self.name + ' ' + self.itemOut + '\r') # /give turnip default:torch
47 |
48 | if __name__ == '__main__':
49 | it = Item(sys.argv[1], sys.argv[2])
50 |
--------------------------------------------------------------------------------
/Worlds-Engine/server.js:
--------------------------------------------------------------------------------
1 | const dgram = require('dgram');
2 | const server = dgram.createSocket('udp4');
3 | const actions = require('./actions')
4 | const ecc = require('eosjs-ecc')
5 |
6 | var eos
7 |
8 | var account = {
9 | pubKey : "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
10 | privKey : "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3",
11 | chainID : "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f",
12 | EndPoint : "http://192.168.10.35:8888"
13 | }
14 |
15 | function connect() {
16 | console.log('Unlocking Wallet and connect to endpoint!');
17 | // sock.open(document.getElementById("world_port").value) // Open socket
18 |
19 | eos = actions.connectEndpoint(
20 | account.chainID,
21 | account.EndPoint,
22 | account.privKey
23 | )
24 |
25 | eos.getKeyAccounts(account.pubKey)
26 | }
27 |
28 | function verify(sig, data, pubkey){
29 | world.send(ecc.verify(sig, data, pubkey).toString())
30 | }
31 |
32 | // TODO: Create a whitelist / Blacklist.
33 | function act (cmd){
34 | eval(cmd)
35 | }
36 |
37 | function processCmd(msg){
38 | console.log("Executing: " + msg)
39 | act(`${msg}`)
40 | }
41 |
42 | var world = {
43 | IP : null,
44 | outPort : 40000,
45 | inPort : 40001,
46 | open: function (port){
47 | server.on('error', (err) => {
48 | console.log(`server error:\n${err.stack}`);
49 | server.close();
50 | });
51 |
52 | server.on('message', (msg, rinfo) => {
53 | console.log('Got Message: ' + msg)
54 | processCmd(msg);
55 | });
56 |
57 | server.on('listening', () => {
58 | const address = server.address();
59 | console.log(`server listening ${address.address}:${address.port}`);
60 | });
61 |
62 | console.log("Binding to port: " + port)
63 | server.bind(port);
64 | },
65 | openOutgoing: function (port){
66 | outPort = port;
67 | const message = Buffer.from('Some bytes');
68 | client = dgram.createSocket('udp4');
69 | },
70 | send: function (msg){
71 | client.send(msg, outPort, 'localhost', (err) => {
72 | // client.close();
73 | });
74 | }
75 | }
76 |
77 | connect() // Connect to blockchain
78 | world.open(world.outPort)
79 | world.openOutgoing(world.inPort)
80 |
81 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/img/worldsdb.drawio:
--------------------------------------------------------------------------------
1 | 3Vxbc5s4FP41ntl9iAdJgO3HJnHb3W13O5t2mvQNG9mmxeAFnIT++hUgGXQx5mawm4cEHYSQz/U758gZobvt67vA2m0++jZ2R1CzX0fofgQhMg3yOyHEGcHU9YywDhw7I4Gc8OD8xJSoUeresXHITYx8342cHU9c+p6HlxFHs4LAf+GnrXyXf+vOWmOJ8LC0XJn61bGjTUadGlpOf4+d9Ya9GWj0ztZikykh3Fi2/1IgofkI3QW+H2VX29c77Ca8Y3zJnnt75O5hYwH2oioPxEFszr99WT19n/ur+c/9nf5xfQMn2TLPlrunn3gT/maNoOmSRW9XPlmbbJ2Jxfxvn2z3FuSX5GpN/6aPhPsFI2mMRjZVIBeo2foZ+XfKpihmvMc2EQUd+kG08de+Z7nznHob+HvPxskHBGSUz/ng+ztK/I6jKKZ6Ze0jn5A20dald/GrEz2Sa21sGgYdP6VjTYN0fJ/ossYGMRt4URA/FgfZcxODjfPn0hF7MIysIHqTqCYheL6HGe2t47qHJ2w2Y+laYegsMyKdkux8RS7vfNcPUl4h28BTW0+XCvwfuHBnChfINOn2P+HA2eIIB/RFshJRvQr9fbBkNmDqH58ft1937t/vJ/u/wj/sGbiB1I7Jztc4KpmIUDYxkWbhFVRJ32Gf7CeIyQTqMrQxMsA0eybmnUGAXStynnnTtKiFrw8rHRb/5Dup/rIp/moVkr0WrIRw2YoLM3bJE6FiCbo5aEBuZwgJRifMR8wdNJwPZtx8cpHtmI0KDMxJqeHXcQKtLE9rZ3mAszpoNDI6WMvocpMq2h1oZw5VraGiMVRW9YJqlEq+bNcF73/nOjhVSCApBS/yl40T4YedlXLlhcR+XrxHOfmMgwi/VnEEkDcFqNPxSyEOU9KmEILZtDbMUpqJOWSA4s1kWCspRCcav/LQ1C6oINmKlKIAQ1mRcjdTyYr+xZZNKP94bqxUmg/WgsBkTtCW66y9hO2EaUl4vk0MxSFA9A29sXVsO9MpTPCYtUjXS9hNYxZZ3LgdGfdKAZQptGSRBzRNX8IBVnXIBgjo7WK02uhvABrrM34ROYp3FgiNUjRcwLBADW0HxrCQg7A9+Ig+4WunXqUTpHpDsoYmSl8bdApGASYloLAK6u3KXpA+hL6fRwNXK2wulyoNtCezhaYdNzRQamg9BEOz62ioVkPD4NVQNwSkle2UPtUixxLUHYHynAlM283XJ+XzDVQ6/5j5sU8DBBg7FbiW6YHEtc5sVK7w1AhoF4xemPNpD1+IH9cMVpeMuZVamowJxjo6A3op8xcFQT/ggHDnQpK5C8vmBgldnRY9OsrmxDg4XWJ1HFxMjcTltwlpzBf2XyZpFImALkSWE5FCnA/NHqp3RitF7rR6N2mmyPVK5lemyaxOfiEVP7ZvVcnPu4Aowdub2V+QUHNLBk+ytUnVMNsKN4coUWBQQv9kRQQgeSkFauignay5CMsYeVKHCnwyFHxitLaoRpCSmAccQbSn1oGzavlEV3iJybIb4V660JCQh+ii0VSVmrjQwWj7EpuMc39hsQEx6W4qNnGhM4pNCVMmrWDKBXRPukIp5+ueqFryV9A+Qe0Q7LVVEfuQb18VQW3GIwFQzafUrgiKFTjjRMVO2Jcw/zx5GJLbgKpC29FDUZdbaGNdsS4KbVCfGZxsbrqptKGxDmfFnwm/wvnKbswqVXW3S8ioLiylQp2i7l8lpYJipalpTiUudMakKvq2dV4+z1d/LoMv25l2/+jET8OWVWs15nKcV2h6PxVvHsF5yaFVuhUAZQhQuZUtqF7DJmG9LmHfFVRWMRXL/scjd+n81pFbqbOVT33AOqc+zhy8RS2sGaN5bTtuyqVNMw1ywmoZyWPlA2fsl6kKCZLMD6Sd5XFCZgfgE0HcZCfk35AJAO5e5dPxi0bH47N3yuQS2Ng3vkBCEQ8o8IXeK76QrVnF/Kr97r75qevD8bOsVlBg5+fAsp3ISSI0uXFvEddihXhwzomaeDhKP1SHuV6dMi8wFIFN01N6jfpzzVEIlEFIu2ZYT8VVsQNhNkTd0hGkSTXUXbshLW74VENatImyo0tdFUJmkt5f3HHoY86ldkUDodmYKzvw7DYTkARmmj4xk9/Tc/noejm12tW0KZWnJ6j4JGpsaCedVDLq7htpqlSoFCJciBfShepm1ROC8kKCFzqUTXtq8UBZDa/q+PykUfFgUqt4cI3H5zs/iFxIIYlnbGJEtesQM8E0xC9Li3UIsYwGSwJnn0fugYwqF7VTVE2VoirM1KuZoQ6cARji9ySGzp3YUYVrqoaCER/F+/FnlbxTqdPpv+ndyBGJBU5U5lg6cxrsm36FFtV+h4NnJyRxYmizlWBLjy0qNbvkTm4ZnL7yE0ZI8JpQbOJXP853YqFzw0+5EftlZ1sRZvFqEbBQ9RCl5F8qFRXNCIEkNTXzn/bWomwTyAXCFsZSr597uoM2WE4n4E3QNKczwImFztzPlVO6W9df/lhuLEc+3EA0OBoJp6yK+QgVfjF5oaTqNqaKR3zESjtjdFNgVKNTVkF7jlXpUTWkKZ65rGCEZJj/j6hMqvk/2kLz/wE=
--------------------------------------------------------------------------------
/Worlds-Engine/actions.js:
--------------------------------------------------------------------------------
1 | // Blockchain Actions
2 | // Example:
3 | // const actions = require('./actions')
4 | // actions.createItem("turnip", "Sword", "Weapon", "1.00 WOR")
5 |
6 |
7 | var options = {
8 | authorization: '',
9 | broadcast: true,
10 | sign: true
11 | }
12 |
13 | Eos = require('eosjs')
14 | var fs = require("fs");
15 | var hash = require("js-sha256")
16 |
17 | module.exports = {
18 | connectEndpoint: function(chainId, IP, PrivateKey){
19 | console.log('Chain ID: ' + chainId)
20 | console.log('IP: ' + IP)
21 |
22 | var config = {
23 | chainId: chainId,
24 | keyProvider: [PrivateKey],
25 | httpEndpoint: IP,
26 | expireInSeconds: 60,
27 | broadcast: true,
28 | debug: true,
29 | verbose: false, // API activity
30 | sign: true
31 | };
32 |
33 | console.log(config)
34 | return(Eos(config))
35 |
36 | },
37 |
38 |
39 | createItem: function(eos, name, itemName, itemClass, stake, ItemNuance){
40 |
41 | options.authorization = name + '@active'
42 | eos.contract('wsc.code').then(wsccode => {wsccode.createitem(name, itemName, itemClass, ItemNuance, stake, options)})
43 | t = Math.floor((new Date() / 1000) / 3600);
44 |
45 | // Move all this hashing into a function or something
46 | var item = itemName + itemClass + ItemNuance + name + name + t.toString() + stake
47 |
48 | console.log(item)
49 |
50 | var hash_i = hash(item);
51 | console.log(hash_i) // Hash should match what's onchain
52 |
53 | fs.writeFile('items/' + hash_i.substring(0,5) + '-' + name + '-' + itemName + '-' + t.toString() + '.json', JSON.stringify({'ItemName': itemName, 'ItemClass': itemClass, 'Nuance': ItemNuance, 'Owner': name, 'OriginWorld': name, 'GenesisTime': t.toString(), 'Stake': stake, 'Hash': hash_i }, null, 2), 'utf8', function(err){
54 | if(err) throw err;
55 | console.log('Written Item to File!')
56 | });
57 | },
58 |
59 |
60 | TXwor: function(eos, from, to, amount, memo){
61 | options.authorization = from + '@active'
62 | eos.contract('wsc.code').then(wsccode => {wsccode.transferwor(from, to, amount, memo, options)})
63 | },
64 |
65 |
66 | deleteItem: function(eos, name, hash){
67 | options.authorization = name + '@active'
68 | eos.contract('wsc.code').then(wsccode => {wsccode.deleteitem(name, hash, options)})
69 | },
70 |
71 |
72 | liquidItem: function(eos, item, name){
73 | options.authorization = name + '@active'
74 | eos.contract('wsc.code').then(wsccode => {wsccode.liquiditem({"tx_item":{"ItemName":item.ItemName, "ItemClass":item.ItemClass, "Nuance":item.Nuance,"Owner":item.Owner, "OriginWorld":item.OriginWorld, "GenesisTime":parseInt(item.GenesisTime), "Stake":item.Stake}}, options)})
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Worlds
2 |
3 |
4 |
5 | Worlds is an open protocol designed to manage the economic and game theoretical components of a distributed MMO. This repository is focused on implementing the minimum dependencies required for developers to get up and running. For more detailed info please read the paper [here](https://github.com/Machine-Hum/Worlds/blob/master/Worlds-Whitepaper/worlds/whitepaper.pdf). This repository contains three main components.
6 |
7 | * The Worlds Whitepaper
8 | * The Worlds Engine
9 | * The World Smart Contract
10 |
11 | ## Getting Started
12 | First you want to source the enviornment and create a wallet.
13 | ```bash
14 | source source_env.sh
15 | wor_create_wallet
16 | ```
17 |
18 | This will give you password, set up an init file to be called by other scripts.
19 | Replace , below with your password and pubkey. Keep in mind this is just
20 | for development, do not do something like this with actual credentials.
21 | ```bash
22 | echo "EOS_PW=" >> scripts/wor_init
23 | echo "EOS_PUB=" >> scripts/wor_init
24 | echo "PJ_ROOT=$(pwd)" >> scripts/wor_init
25 | echo "IP=$(ipconfig getifaddr en0)" >> scripts/wor_init # Or just hardcode in your IP address
26 | source wor_init
27 | ```
28 |
29 | Run the chain
30 | ```bash
31 | wor_run_chain
32 | ```
33 |
34 | Unlock your wallet and Create account. If cleos asked you to unlock your wallet,
35 | use this unlock wallet script.
36 | ```bash
37 | wor_unlock_wallet
38 | wor_create_account
39 | ```
40 |
41 | ## Worlds Smart Contract
42 | The Worlds Smart Contact (WSC) is an EOS contract that is responsible for
43 | managing player assets and WOR. WOR is a token that can be staked against items
44 | and used as a means of currency. The contract is still under development and
45 | subject to change!
46 |
47 | ### Building / Deploying
48 | ```bash
49 | cd Worlds-Smart-Contract/
50 | make
51 | wor_deploy_contract
52 | ```
53 |
54 | ### Dependencies
55 | The WSC is build using eosio.cdt 1.3+
56 | * [eosio](https://github.com/EOSIO/eos)
57 | * [eosio.cdt](https://github.com/EOSIO/eosio.cdt)
58 |
59 | ## Scripting
60 | Various simple scripts have been written to test the WSC.
61 |
62 | ```bash
63 | wor_create_tokens # Create tokens
64 | wor_issue_tokens # Issue tokens
65 | wor_get_token_balance turnip # Get token balance of a player
66 | wor_create_item # Create items
67 | wor_transfer_item # Transfer Items
68 | wor_get_table turnip # Check the tables onchain.
69 | wor_liquid_item # Liquidate items back into WOR
70 | ```
71 |
72 | ## Worlds Client (Worlds.js)
73 | The worlds client is wallet that enables players to view, create, trade and liquidate items, exp and WOR. The worlds client uses eosjs to call the WSC. It hosts a simple UDP server that will accept commands from the game client. It is also possible to manage game assets directly from the wallet. Please note the wallet is in beta!
74 |
75 | Running the wallet
76 | ```bash
77 | cd Worlds/Worlds-Engine
78 | npm install
79 | npm start
80 | ```
81 |
82 | ## Contribution
83 | If you wish to help with the project or are interested in developing a world, please reach out! Feedback welcome!
84 |
--------------------------------------------------------------------------------
/WSC/WSC.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * @copyright defined in eos/LICENSE.txt
4 | */
5 | #pragma once
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | namespace eosiosystem {
14 | class system_contract;
15 | }
16 |
17 | namespace eosio {
18 |
19 | using std::string;
20 |
21 | class [[eosio::contract("WSC")]] WSC : public contract {
22 | public:
23 | using contract::contract;
24 |
25 | /*This can just be a normal Struct*/
26 | struct item {
27 | string ItemName;
28 | string ItemClass;
29 | string Nuance;
30 | name Owner;
31 | name OriginWorld;
32 | uint32_t GenesisTime;
33 | asset Stake;
34 | };
35 |
36 | [[eosio::action]]
37 | void createitem( name owner, string item_name, string item_class, string nuance, asset stake );
38 |
39 | [[eosio::action]]
40 | void liquiditem( item tx_item );
41 |
42 | [[eosio::action]]
43 | void transferitem( name to, item tx_item );
44 |
45 | [[eosio::action]]
46 | void deleteitem( name owner, checksum256 hash );
47 |
48 | [[eosio::action]]
49 | void tradeitem( item tx_item, item rx_item );
50 |
51 | [[eosio::action]]
52 | void createwor( name issuer,
53 | asset maximum_supply);
54 |
55 | [[eosio::action]]
56 | void issuewor( name to, asset quantity, string memo );
57 |
58 | [[eosio::action]]
59 | void retirewor( asset quantity, string memo );
60 |
61 | [[eosio::action]]
62 | void transferwor( name from,
63 | name to,
64 | asset quantity,
65 | string memo );
66 |
67 | [[eosio::action]]
68 | void openwor( name owner, const symbol& symbol, name ram_payer );
69 |
70 | [[eosio::action]]
71 | void closewor( name owner, const symbol& symbol );
72 |
73 | static asset get_supply( name token_contract_account, symbol_code sym_code )
74 | {
75 | stats statstable( token_contract_account, sym_code.raw() );
76 | const auto& st = statstable.get( sym_code.raw() );
77 | return st.supply;
78 | }
79 |
80 | static asset get_balance( name token_contract_account, name owner, symbol_code sym_code )
81 | {
82 | accounts accountstable( token_contract_account, owner.value );
83 | const auto& ac = accountstable.get( sym_code.raw() );
84 | return ac.balance;
85 | }
86 |
87 | private:
88 | struct [[eosio::table]] itemproof{
89 | checksum256 itemHash;
90 |
91 | uint64_t primary_key() const {return *(uint64_t*)&itemHash;} // Primary Indices.
92 | };
93 |
94 | struct [[eosio::table]] tradechannel{
95 | checksum256 rx_item;
96 | checksum256 tx_item;
97 | name trader;
98 |
99 | uint64_t primary_key() const {return *(uint64_t*)&rx_item;} // Primary Indices.
100 | };
101 |
102 | struct [[eosio::table]] account {
103 | asset balance;
104 |
105 | uint64_t primary_key()const { return balance.symbol.code().raw(); }
106 | };
107 |
108 | struct [[eosio::table]] currency_stats {
109 | asset supply;
110 | asset max_supply;
111 | name issuer;
112 |
113 | uint64_t primary_key()const { return supply.symbol.code().raw(); }
114 | };
115 |
116 | typedef eosio::multi_index< "accounts"_n, account > accounts;
117 | typedef eosio::multi_index< "stat"_n, currency_stats > stats;
118 | typedef eosio::multi_index< "itemproofs"_n, itemproof > itemProof_table;
119 | typedef eosio::multi_index< "tradechannel"_n, tradechannel > tradechannel_table;
120 |
121 | void sub_balance( name owner, asset value );
122 | void add_balance( name owner, asset value, name ram_payer );
123 |
124 | checksum256 hashItem(WSC::item &item);
125 | checksum256 hashItemCreate(name owner, string item_name, string item_class, asset stake);
126 | checksum256 hashItemTransfer(name NewOwner, name PreviousOwner, WSC::item item);
127 |
128 | };
129 |
130 | } /// namespace eosio
131 |
--------------------------------------------------------------------------------
/Worlds-Engine/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | /bin/bash: q: command not found
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Worlds Engine
15 |
16 |
17 |
Worlds Engine
18 |
19 |
20 |
21 | SocketCommand:
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
Blockchain Credentials
32 | PrivateKey:
33 | PublicKey:
34 | Endpoint:
35 | ChainID:
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
Worlds Client Credentials
45 | Worlds Client IP:
46 | World Client Port:
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
Character
55 |
56 |
Balance: ?
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
Transfer
65 | To:
66 | Amount:
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
Create Item
76 | Item Name:
77 | Item Class:
78 | Stake:
79 | Nuance:
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
Delete Item
89 | Item Hash:
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
Items
99 |
100 |
101 |
Item Name:
102 |
Item Class:
103 |
Item Nuance:
104 |
Item Owner:
105 |
Origin World:
106 |
Genesis Time:
107 |
Item Stake:
108 |
109 | Recipient:
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/Worlds-Engine/blockConnect.js:
--------------------------------------------------------------------------------
1 | const actions = require('./actions')
2 | const sock = require('./socket')
3 | var fs = require('fs')
4 | const ecc = require('eosjs-ecc')
5 | const wc = require('./worldConnect')
6 |
7 | var eos
8 |
9 | var account = {
10 | pubKey : null,
11 | privKey : null,
12 | name : null,
13 | selectedName : null,
14 | balance : null
15 | }
16 |
17 |
18 | var selectedItem = {
19 | item : null,
20 | update : function(fname) {
21 | item = JSON.parse(fs.readFileSync('items/' + fname));
22 | document.getElementById("Item_Name").innerHTML = "Item Name: " + item.ItemName
23 | document.getElementById("Item_Class").innerHTML = "Item Class: " + item.ItemClass
24 | document.getElementById("Item_Nuance").innerHTML = "Item Nuance: " + item.Nuance
25 | document.getElementById("Item_Owner").innerHTML = "Item Owner: " + item.Owner
26 | document.getElementById("Item_OriginWorld").innerHTML = "Origin World: " + item.OriginWorld
27 | document.getElementById("Item_GenesisTime").innerHTML = "Genesis Time: " + item.GenesisTime
28 | document.getElementById("Item_Stake").innerHTML = "Stake: " + item.Stake
29 | },
30 | liquid : function() {
31 | actions.liquidItem(eos, item, account.selectedName)
32 | }
33 | }
34 |
35 |
36 | var socket = {
37 | execute: function(){
38 | eval(document.getElementById("SockCMD").value)
39 | document.getElementById("SockCMD").value = null
40 | var x = document.getElementById("SocketCommand");
41 | x.style.display = "none";
42 | },
43 | ignore: function(){
44 | document.getElementById("SockCMD").value = null
45 | var x = document.getElementById("SocketCommand");
46 | x.style.display = "none";
47 | }
48 | }
49 |
50 |
51 | // Exported Modules
52 | module.exports = {
53 | act: function (cmd) {
54 | var x = document.getElementById("SocketCommand");
55 | x.style.display = "block"; // Hide
56 | document.getElementById("SockCMD").value = cmd
57 | },
58 |
59 | prove: function (data) {
60 | return(ecc.sign(data, document.getElementById("PrivateKey").value))
61 | }
62 | }
63 |
64 |
65 | // Used to verify proof packages.
66 | function verify(sig, data, pubkey) {
67 | wc.send(ecc.verify(sig, data, pubkey).toString())
68 | }
69 |
70 |
71 | /* Connect to the blockchain and load characters*/
72 | function connect() {
73 | account.privKey = document.getElementById("PrivateKey").value
74 | account.pubKey = document.getElementById("PublicKey").value
75 |
76 | console.log('Unlocking Wallet and connect to endpoint!');
77 | // sock.open(document.getElementById("world_port").value) // Open socket
78 |
79 | eos = actions.connectEndpoint(
80 | document.getElementById("ChainID").value,
81 | document.getElementById("EndPoint").value,
82 | account.privKey
83 | )
84 |
85 | eos.getKeyAccounts(account.pubKey).then(addName)
86 | }
87 |
88 |
89 | function addName(result){
90 | account.name = result.account_names
91 |
92 | var x = document.getElementById("Chars");
93 |
94 | for(i = 0 ; i < account.name.length ; i++){
95 | var option = document.createElement("option");
96 | option.text = account.name[i]
97 | x.add(option)
98 | }
99 | updateChar()
100 | }
101 |
102 |
103 | function updateChar(){
104 | account.selectedName = document.getElementById("Chars").value
105 | eos.getCurrencyBalance('wsc.code', account.selectedName, 'WOR').then(function fun(result) {account.balance = result; updateHTML(result)})
106 | }
107 |
108 |
109 | function updateHTML(result) {
110 | document.getElementById("Balance").innerHTML = "Balance: " + account.balance
111 | }
112 |
113 |
114 | function TransferWor() {
115 | to = document.getElementById("TransferTo").value
116 | amount = document.getElementById("TransferAmt").value
117 | memo = 'future shit'
118 |
119 | actions.TXwor(eos, account.selectedName, to, amount, memo)
120 | }
121 |
122 |
123 | function createItem() {
124 |
125 | ItemName = document.getElementById("ItemName").value
126 | ItemClass = document.getElementById("ItemClass").value
127 | ItemStake = document.getElementById("ItemStake").value
128 | ItemNuance = document.getElementById("ItemNuance").value
129 |
130 | // TODO: Check to ensure the same item is not already made!!!
131 | if(account.balance < ItemStake){
132 | console.log('Insufficant Funds!')
133 | return(0)
134 | }
135 | console.log('Creating Item')
136 | actions.createItem(eos, account.selectedName, ItemName, ItemClass, ItemStake, ItemNuance)
137 | }
138 |
139 |
140 | function deleteItem() {
141 |
142 | ItemHash = document.getElementById("ItemHash").value
143 |
144 | console.log('Deleting item' + ItemHash)
145 | actions.deleteItem(eos, account.selectedName, ItemHash)
146 | }
147 |
148 |
149 | function loadItems() {
150 | files = fs.readdirSync('items')
151 |
152 | for(var i = 0 ; i < files.length ; i++){
153 | if(files[i] == 'placeholder'){
154 | // delete files[i]
155 | files.splice(i)
156 | }
157 | }
158 |
159 | // Remove all existing items
160 | var select = document.getElementById("Items_Select");
161 | var length = select.options.length;
162 | for (i = 0; i < length; i++) {
163 | select.options[i] = null;
164 | }
165 |
166 | var x = document.getElementById("Items_Select");
167 | for(i = 0 ; i < files.length ; i++){
168 | var option = document.createElement("option");
169 | option.text = files[i]
170 | x.add(option)
171 | }
172 |
173 | selectedItem.update(files[0])
174 | }
175 |
--------------------------------------------------------------------------------
/utils/ftp/serv/vsftpd.conf:
--------------------------------------------------------------------------------
1 | # Example config file /etc/vsftpd.conf
2 | #
3 | # The default compiled in settings are fairly paranoid. This sample file
4 | # loosens things up a bit, to make the ftp daemon more usable.
5 | # Please see vsftpd.conf.5 for all compiled in defaults.
6 | #
7 | # READ THIS: This example file is NOT an exhaustive list of vsftpd options.
8 | # Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
9 | # capabilities.
10 | #
11 | #
12 | # Run standalone? vsftpd can run either from an inetd or as a standalone
13 | # daemon started from an initscript.
14 | listen=NO
15 | #
16 | # This directive enables listening on IPv6 sockets. By default, listening
17 | # on the IPv6 "any" address (::) will accept connections from both IPv6
18 | # and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
19 | # sockets. If you want that (perhaps because you want to listen on specific
20 | # addresses) then you must run two copies of vsftpd with two configuration
21 | # files.
22 | listen_ipv6=YES
23 | #
24 | # Allow anonymous FTP? (Disabled by default).
25 | anonymous_enable=NO
26 | #
27 | # Uncomment this to allow local users to log in.
28 | local_enable=YES
29 | #
30 | # Uncomment this to enable any form of FTP write command.
31 | write_enable=YES
32 | #
33 | # Default umask for local users is 077. You may wish to change this to 022,
34 | # if your users expect that (022 is used by most other ftpd's)
35 | #local_umask=022
36 | #
37 | # Uncomment this to allow the anonymous FTP user to upload files. This only
38 | # has an effect if the above global write enable is activated. Also, you will
39 | # obviously need to create a directory writable by the FTP user.
40 | #anon_upload_enable=YES
41 | #
42 | # Uncomment this if you want the anonymous FTP user to be able to create
43 | # new directories.
44 | #anon_mkdir_write_enable=YES
45 | #
46 | # Activate directory messages - messages given to remote users when they
47 | # go into a certain directory.
48 | dirmessage_enable=YES
49 | #
50 | # If enabled, vsftpd will display directory listings with the time
51 | # in your local time zone. The default is to display GMT. The
52 | # times returned by the MDTM FTP command are also affected by this
53 | # option.
54 | use_localtime=YES
55 | #
56 | # Activate logging of uploads/downloads.
57 | xferlog_enable=YES
58 | #
59 | # Make sure PORT transfer connections originate from port 20 (ftp-data).
60 | connect_from_port_20=YES
61 | #
62 | # If you want, you can arrange for uploaded anonymous files to be owned by
63 | # a different user. Note! Using "root" for uploaded files is not
64 | # recommended!
65 | #chown_uploads=YES
66 | #chown_username=whoever
67 | #
68 | # You may override where the log file goes if you like. The default is shown
69 | # below.
70 | #xferlog_file=/var/log/vsftpd.log
71 | #
72 | # If you want, you can have your log file in standard ftpd xferlog format.
73 | # Note that the default log file location is /var/log/xferlog in this case.
74 | #xferlog_std_format=YES
75 | #
76 | # You may change the default value for timing out an idle session.
77 | #idle_session_timeout=600
78 | #
79 | # You may change the default value for timing out a data connection.
80 | #data_connection_timeout=120
81 | #
82 | # It is recommended that you define on your system a unique user which the
83 | # ftp server can use as a totally isolated and unprivileged user.
84 | #nopriv_user=ftpsecure
85 | #
86 | # Enable this and the server will recognise asynchronous ABOR requests. Not
87 | # recommended for security (the code is non-trivial). Not enabling it,
88 | # however, may confuse older FTP clients.
89 | #async_abor_enable=YES
90 | #
91 | # By default the server will pretend to allow ASCII mode but in fact ignore
92 | # the request. Turn on the below options to have the server actually do ASCII
93 | # mangling on files when in ASCII mode.
94 | # Beware that on some FTP servers, ASCII support allows a denial of service
95 | # attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
96 | # predicted this attack and has always been safe, reporting the size of the
97 | # raw file.
98 | # ASCII mangling is a horrible feature of the protocol.
99 | #ascii_upload_enable=YES
100 | #ascii_download_enable=YES
101 | #
102 | # You may fully customise the login banner string:
103 | #ftpd_banner=Welcome to blah FTP service.
104 | #
105 | # You may specify a file of disallowed anonymous e-mail addresses. Apparently
106 | # useful for combatting certain DoS attacks.
107 | #deny_email_enable=YES
108 | # (default follows)
109 | #banned_email_file=/etc/vsftpd.banned_emails
110 | #
111 | # You may restrict local users to their home directories. See the FAQ for
112 | # the possible risks in this before using chroot_local_user or
113 | # chroot_list_enable below.
114 | chroot_local_user=YES
115 | #
116 | # You may specify an explicit list of local users to chroot() to their home
117 | # directory. If chroot_local_user is YES, then this list becomes a list of
118 | # users to NOT chroot().
119 | # (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
120 | # the user does not have write access to the top level directory within the
121 | # chroot)
122 | #chroot_local_user=YES
123 | chroot_list_enable=YES
124 | # (default follows)
125 | chroot_list_file=/etc/vsftpd.chroot_list
126 | #
127 | # You may activate the "-R" option to the builtin ls. This is disabled by
128 | # default to avoid remote users being able to cause excessive I/O on large
129 | # sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
130 | # the presence of the "-R" option, so there is a strong case for enabling it.
131 | #ls_recurse_enable=YES
132 | #
133 | # Customization
134 | #
135 | # Some of vsftpd's settings don't fit the filesystem layout by
136 | # default.
137 | #
138 | # This option should be the name of a directory which is empty. Also, the
139 | # directory should not be writable by the ftp user. This directory is used
140 | # as a secure chroot() jail at times vsftpd does not require filesystem
141 | # access.
142 | secure_chroot_dir=/var/run/vsftpd/empty
143 | #
144 | # This string is the name of the PAM service vsftpd will use.
145 | pam_service_name=vsftpd
146 | #
147 | # This option specifies the location of the RSA certificate to use for SSL
148 | # encrypted connections.
149 | rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
150 | rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
151 | ssl_enable=NO
152 |
153 | #
154 | # Uncomment this to indicate that vsftpd use a utf8 filesystem.
155 | #utf8_filesystem=YES
156 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/whitepaper.tex:
--------------------------------------------------------------------------------
1 | \documentclass[runningheads,a4paper]{llncs}
2 |
3 | \usepackage{amssymb}
4 | \setcounter{tocdepth}{3}
5 | \usepackage{graphicx}
6 | \usepackage{tikz}
7 | \usepackage[T1]{fontenc}
8 | \usepackage[scaled]{beramono}
9 | \usepackage{listings}
10 | \usepackage{color}
11 | \usetikzlibrary{arrows,chains,positioning,scopes,quotes,calc}
12 | \usepackage{float}
13 | \usepackage[a4paper, total={6in, 10in}]{geometry}
14 |
15 | \newcommand{\keywords}[1]{\par\addvspace\baselineskip
16 | \noindent\keywordname\endspace\ignorespaces#1}
17 | \pagestyle{plain}
18 | \setlength\parindent{0pt}
19 |
20 | \definecolor{mygreen}{RGB}{28,172,0} % color values Red, Green, Blue
21 | \definecolor{mylilas}{RGB}{170,55,241}
22 |
23 | \newcommand*{\StrikeThruDistance}{0.15cm}%
24 | \newcommand*{\StrikeThru}{\StrikeThruDistance,\StrikeThruDistance}%
25 |
26 | \tikzset{strike thru arrow/.style={
27 | decoration={markings, mark=at position 0.5 with {
28 | \draw [blue, thick,-]
29 | ++ (-\StrikeThruDistance,-\StrikeThruDistance)
30 | -- ( \StrikeThruDistance, \StrikeThruDistance);}
31 | },
32 | postaction={decorate},
33 | }}
34 |
35 | \lstset{
36 | language=Python,
37 | showstringspaces=false,
38 | formfeed=\newpage,
39 | tabsize=4,
40 | commentstyle=\itshape,
41 | basicstyle=\ttfamily,
42 | morekeywords={models, lambda, forms}
43 | }
44 |
45 | \begin{document}
46 |
47 | \mainmatter % start of an individual contribution
48 |
49 | % This needs some work, big time.
50 | \title{Worlds.db: a Proveably Fair Database}
51 |
52 | \author{Ryan Walker\\
53 | ryan.cjw@gmail.com}
54 |
55 | \institute{} %Merp
56 |
57 | \maketitle
58 |
59 | \begin{abstract}
60 | This paper outlines how to move a traditional trusted database into the
61 | decentralized world. This yealds the advantege of using existing database
62 | structure, ie: SLQ and Mongo. Further enabling developers to work in a farmiliar
63 | ecosystem until the advantages of blockchain are realised in their context.
64 | \end{abstract}
65 |
66 | \section{Introduction}
67 | Before I begin, I should mention there are several centralised components in the
68 | following architecture. However I chosen to build use it for ``phase zero'' of
69 | Worlds. The goal of phase zero is simple, to drive adoption through rapid
70 | integration in existing MMO ecosystems. Simply put, we want remove the entrance
71 | barrier for developers. Several concepts in this whitepaper draw on concepts from
72 | the orriginal Worlds whitepaper.
73 | \\
74 |
75 | Blockchain infrastructure is being used to build decentralised games. However
76 | most games are build using traditional database infrasture. Success in techology
77 | usually spawns from: building your MVP first, being the first to market and the
78 | first to demonstrate the capabilities of your idea. Most gaming projects in the
79 | space have moved straight to the ideal without answering the core question of:
80 | How will you attract gamers?
81 | \\
82 |
83 |
84 | The anwer to the questions is simple, you need to build incrediable games. Execution
85 | on the answer is not simple, the gaming market is dominated by huge companies. Unless
86 | you have a silver bullet of a game, you're going to be hard pressed to drive adoption.
87 | \\
88 |
89 | The quickest way to drive adoption is to take existing MMO infrastrucutre and build
90 | around it. This is why I chose to write the document. I will outlinine how to
91 | port traditional trusted databases to reach a near trustless entity,
92 |
93 | \section{Overview}
94 | Nearly all MMO games are using a traditional databsese. This is SQL, Mongo or otherwise.
95 | These databases rely on a trusted design, meaning whomever hosts the database will not
96 | engage in malicious activity. However there is a way to build a ecosystem that relies
97 | on a central database without having to trust the database maintainer.
98 | \\
99 |
100 | Simply said, the contents on the datbase are verified on a blockchain, with the
101 | heavy lifting done by the database itself. This also has the added feature of
102 | not having to port existing games to having blockchain interaction. They can
103 | continue to work with their existing and known database interaction.
104 | \\
105 |
106 | If the maintainer of the database acts with malicious intent, the database can
107 | be reconstructed using the orrignal signed database query commands.
108 |
109 | \newpage
110 |
111 | \section{Archatecture}
112 | \subsection{Existing Design}
113 | The typical MMO archatecture is shown in Figure \ref{trad}. The data is kept in
114 | a normal trusted database. This issue being players can't have interoperability
115 | between servers.
116 |
117 | \begin{figure}[H]
118 | \centering
119 | \includegraphics[scale=1]{img/traditional.pdf}
120 | \caption{Traditional Design}
121 | \label{trad}
122 | \end{figure}
123 |
124 | \subsection{Naive Design}
125 | Someone might arrive at the nieve design shown in Figure \ref{naive} to crack
126 | the problem of player interoperability. This will allow player to move from game
127 | to game, however it's fondamentally flawed.
128 |
129 | \begin{figure}[H]
130 | \centering
131 | \includegraphics[scale=1]{img/nieve.pdf}
132 | \caption{Naive Design}
133 | \label{naive}
134 | \end{figure}
135 |
136 | The issue being... servers with malicious intent have write capabilities on the
137 | database, they can create unbounded wealth, distroy players assets, etc...
138 |
139 | \subsection{Worlds Design}
140 |
141 | \begin{figure}[H]
142 | \centering
143 | \includegraphics[scale=1]{img/worlds.pdf}
144 | \caption{Worlds Design}
145 | \label{fig:Worlds}
146 | \end{figure}
147 |
148 | A simplified version of the Worlds design is shown in Figure \ref{fig:Worlds}.
149 | For more details please see the orrignal Worlds whitepaper. This is the ideal
150 | and the nexus point where distributed games will be in the future, this will
151 | allow player to place full control over their items to be clear - this is the
152 | final goal.
153 | \\
154 |
155 | In the intereum, we need to build something a little bit easier for devleopers
156 | to build with.
157 |
158 | \subsubsection{Issues}
159 |
160 | The problem is game developement is challanging, and adding the additional later to games
161 | of querying a blockchain to understand the state of a game is simply too much to
162 | ask for developers.
163 |
164 | \section{Worlds.db}
165 | We want the best aspect from both the
166 | centralised and deventralised system.
167 |
168 | \begin{enumerate}
169 | \item Centralised databases enable simple integration.
170 | \item Blockchain grants user driven control of assets, and player interteroperability.
171 | \end{enumerate}
172 |
173 |
174 | \begin{figure}[H]
175 | \includegraphics[]{img/worldsdb.pdf}
176 | \caption{Worlds.db}
177 | \label{fig:worldsdb}
178 | \end{figure}
179 |
180 | Figure \ref{fig:worldsdb} depicts the proposed structure. At a glance it looks
181 | complicated. Howver the implementation is much simpler than Figure
182 | \ref{fig:Worlds}. Lets outline the flow.
183 |
184 | \begin{itemize}
185 | \item The traditional database becomes read only from the servers perspective.
186 | \item When servers want to update their game state they create $a$ - the database request.
187 | \begin{itemize}
188 | \item $a$ is just a string of the sql, mongo, etc... query.
189 | \end{itemize}
190 | \item $a$ sent to the supervisor (and broadcasted), the hash of $a$ .. $hs(a)$ is staked against and sent to the blockchain.
191 | \begin{itemize}
192 | \item The staked amount is a function of the database query itself.
193 | \end{itemize}
194 | \item The supervisor ensures $hs(a)$ is correct with $a$.
195 | \item The supervisor update the state in the traditional database.
196 | \end{itemize}
197 |
198 | \subsection{Security}
199 | It becomes obvious there are two centralised components of this structure. The
200 | supervisor and the database. However this is recourse for a malicious attack.
201 | Since $a$ is broadcast, the comminity can reconstruct the state of the database though the
202 | signed/submitted hashes to the blockchain. This allows for somewhat of a hard
203 | fork away from the malcious database.
204 | \\
205 |
206 | In addition you can incentivise the database maintainer to behave through a
207 | monetary incentive.
208 | \\
209 |
210 | If further security is required, the database system can horizontally scale to
211 | create redundant systems. This enables more robust error detection within
212 | several databases.
213 |
214 | \section{Advantages}
215 | The biggest advantage of this structure is the simplicity of implementation on the
216 | server side. Instead of modifying the code to quiery a blockchain directly
217 | developers can continue to query a traditional database with the only modification
218 | being instead of sending the mutable requests to the database, they are sent
219 | directly to the supervisor.
220 |
221 | \section{Conclusion}
222 | Time to build it.
223 |
224 | \end{document}
225 |
226 |
--------------------------------------------------------------------------------
/WSC/WSC.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * @copyright defined in eos/LICENSE.txt
4 | */
5 |
6 | #include "WSC.hpp"
7 | #include
8 | #include
9 |
10 | namespace eosio{
11 |
12 | void WSC::createitem( name owner, // Creator of this item.
13 | string item_name, // Name of the item.
14 | string item_class, // Class of the item.
15 | string nuance, // Special unique ID.
16 | asset stake // How much WOR to stake into the item.
17 | )
18 | {
19 |
20 | require_auth( owner );
21 | require_recipient( owner );
22 |
23 | WSC::item item;
24 |
25 | item.Owner = owner;
26 | item.OriginWorld = owner;
27 | item.ItemName = item_name;
28 | item.ItemClass = item_class;
29 | item.Nuance = nuance;
30 | item.Stake= stake;
31 |
32 | auto sym = stake.symbol;
33 |
34 | stats statstable( _self, sym.code().raw() );
35 | const auto& st = statstable.get( sym.code().raw() );
36 |
37 | check( stake.is_valid(), "invalid quantity" );
38 | check( stake.amount > 0, "must transfer positive quantity" );
39 | check( stake.symbol == st.supply.symbol, "symbol precision mismatch" );
40 | sub_balance( owner, stake ); // Subtract Balance.
41 |
42 | item.GenesisTime = current_time_point().sec_since_epoch() / 3600; // Convert to hours
43 | checksum256 calc_hash = hashItem(item);
44 |
45 | itemProof_table itemProof(_self, owner.value);
46 |
47 | // Place the hash onchain
48 | itemProof.emplace(owner, [&](auto& p) {
49 | p.itemHash = calc_hash;
50 | });
51 | };
52 |
53 | void WSC::liquiditem( item tx_item // Who's the owner.
54 | )
55 | {
56 | require_auth( tx_item.Owner );
57 | require_recipient( tx_item.Owner );
58 |
59 | checksum256 calc_hash = hashItem(tx_item);
60 |
61 | itemProof_table itemProof(_self, tx_item.Owner.value);
62 |
63 | auto chainHash = itemProof.get(*(uint64_t*)&calc_hash); // Check to see if the item is onchain.
64 | auto itr = itemProof.find(*(uint64_t*)&calc_hash);
65 |
66 | if(!(memcmp((void *) &calc_hash, (void *) &chainHash.itemHash, 32))){
67 | itemProof.erase(itr); // Remove the hash from the table.
68 | add_balance(tx_item.Owner, tx_item.Stake, tx_item.Owner);
69 | }
70 | }
71 |
72 | void WSC::transferitem( name to, // Who's getting the item.
73 | item tx_item // Actual item package.
74 | )
75 | {
76 | require_auth( tx_item.Owner );
77 | require_recipient( tx_item.Owner );
78 | require_recipient( to );
79 |
80 | checksum256 calc_hash = hashItem(tx_item);
81 |
82 | itemProof_table itemProofFrom(_self, tx_item.Owner.value);
83 |
84 | // Check to see if the item is onchain.
85 | auto chainHash = itemProofFrom.get(*(uint64_t*)&calc_hash);
86 | auto itr = itemProofFrom.find(*(uint64_t*)&calc_hash);
87 |
88 | if(!(memcmp((void *) &calc_hash, (void *) &chainHash.itemHash, 32))){
89 | itemProofFrom.erase(itr); // Remove the hash from the table.
90 | itemProof_table itemProofTo(_self, to.value);
91 | auto from = tx_item.Owner;
92 | tx_item.Owner = to;
93 | calc_hash = hashItem(tx_item);
94 |
95 | // 'from' is the gas payer.
96 | itemProofTo.emplace(from, [&](auto& p) {
97 | p.itemHash = calc_hash;
98 | });
99 | }
100 | }
101 |
102 | /*
103 | WARNING: This function deletes items without refunding WOR!
104 | It it mainly for refunding RAM if the user forgets the content of the items
105 | */
106 | void WSC::deleteitem( name owner,
107 | checksum256 hash
108 | )
109 | {
110 | require_auth( owner );
111 |
112 | itemProof_table itemProof(_self, owner.value);
113 | auto itr = itemProof.find(*(uint64_t*)&hash);
114 |
115 | print("Deleting Item");
116 | itemProof.erase(itr); // GONE!
117 | }
118 |
119 | /* This function isn't working yet */
120 | void WSC::tradeitem( item tx_item, // What are you trading
121 | item rx_item // What are you traing for
122 | )
123 | {
124 | require_auth( tx_item.Owner );
125 |
126 | checksum256 tx_hash = sha256((char*) &tx_item.ItemName, sizeof(tx_item));
127 | checksum256 rx_hash = sha256((char*) &rx_item.ItemName, sizeof(rx_item));
128 |
129 | itemProof_table itemProof_tx(_self, tx_item.Owner.value);
130 |
131 | // Check to see if the item is onchain.
132 | auto chainHash = itemProof_tx.get(*(uint64_t*)&tx_hash);
133 | auto itr = itemProof_tx.find(*(uint64_t*)&tx_hash);
134 |
135 | assert_sha256((const char*) &tx_item.ItemName, sizeof(tx_item), chainHash.itemHash); // Ensure hash matches matches
136 | print("TX Item on chain and belongs to proper person");
137 |
138 | /*At this point the item the user wants to trade does in fact belog to the user*/
139 | print("Removing Item");
140 | itemProof_tx.erase(itr); // Remove the hash from the table.
141 |
142 | tradechannel_table channel(_self, rx_item.Owner.value);
143 |
144 | auto itr_rx = channel.find(*(uint64_t*)&tx_hash); // Check to see if a trade channel isn't already open
145 | if(itr_rx == channel.end()){
146 | print("Found a trade channel open!");
147 | auto rx_channel = channel.get(*(uint64_t*)&tx_hash);
148 |
149 | if(rx_channel.tx_item == rx_hash){
150 | print("Trade Maches, Time to trade");
151 |
152 | checksum256 new_rx_hash, new_tx_hash;
153 | tx_item.Owner = rx_item.Owner;
154 | rx_item.Owner = tx_item.Owner;
155 |
156 | new_rx_hash = hashItem(rx_item);
157 | new_tx_hash = hashItem(tx_item);
158 |
159 | itemProof_table itemProof_rx(_self, rx_item.Owner.value);
160 | itemProof_table itemProof_tx(_self, tx_item.Owner.value);
161 |
162 | // Place the hash onchain
163 | itemProof_rx.emplace(tx_item.Owner, [&](auto& p) {
164 | p.itemHash = new_rx_hash;
165 | });
166 |
167 | // The ram payer should really be the person receiving the item
168 | itemProof_tx.emplace(tx_item.Owner, [&](auto& p) {
169 | p.itemHash = new_tx_hash;
170 | });
171 | }
172 | else{
173 | print("Trade does not match!");
174 | }
175 | }
176 | else{
177 | /* Now you need to create the trade channel and place it onchain */
178 | }
179 |
180 | /*
181 | -> Hash tx_item.
182 | -> Ensure it is on chain.
183 | -> Hash rx_item.
184 | -> Ensure there is not a trade channel open that has rx_item = hash(tx_item) && tx_item = hash(rx_item)
185 | -> If there is proceed to step X
186 | -> Then move the hash(tx_item) and hash(rx_item) into a trade channel
187 | -> This is a multi-index table that has two fields
188 | -> hash(tx_item)
189 | -> hash(rx_item)
190 | -> Delete the reference to tx_item on tx_item.Owner, it's now been moved into a trade channel.
191 |
192 | X-> Delete the trade channel and emplace tx_item on rx_item.Owners table. Then place rx_item on tx_item.Owners table!
193 | -> We've just made a trade :)
194 |
195 | */
196 | }
197 |
198 | void WSC::createwor( name issuer,
199 | asset maximum_supply )
200 | {
201 | require_auth( _self );
202 |
203 | auto sym = maximum_supply.symbol;
204 | check( sym.is_valid(), "invalid symbol name" );
205 | check( maximum_supply.is_valid(), "invalid supply");
206 | check( maximum_supply.amount > 0, "max-supply must be positive");
207 |
208 | stats statstable( _self, sym.code().raw() );
209 | auto existing = statstable.find( sym.code().raw() );
210 | check( existing == statstable.end(), "token with symbol already exists" );
211 |
212 | statstable.emplace( _self, [&]( auto& s ) {
213 | s.supply.symbol = maximum_supply.symbol;
214 | s.max_supply = maximum_supply;
215 | s.issuer = issuer;
216 | });
217 | }
218 |
219 |
220 | void WSC::issuewor( name to, asset quantity, string memo )
221 | {
222 | auto sym = quantity.symbol;
223 | check( sym.is_valid(), "invalid symbol name" );
224 | check( memo.size() <= 256, "memo has more than 256 bytes" );
225 |
226 | stats statstable( _self, sym.code().raw() );
227 | auto existing = statstable.find( sym.code().raw() );
228 | check( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
229 | const auto& st = *existing;
230 |
231 | require_auth( st.issuer );
232 | check( quantity.is_valid(), "invalid quantity" );
233 | check( quantity.amount > 0, "must issue positive quantity" );
234 |
235 | check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
236 | check( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
237 |
238 | statstable.modify( st, same_payer, [&]( auto& s ) {
239 | s.supply += quantity;
240 | });
241 |
242 | add_balance( st.issuer, quantity, st.issuer );
243 |
244 | if( to != st.issuer ) {
245 | SEND_INLINE_ACTION( *this, transferwor, { {st.issuer, "active"_n} },
246 | { st.issuer, to, quantity, memo }
247 | );
248 | }
249 | }
250 |
251 | void WSC::retirewor( asset quantity, string memo )
252 | {
253 | auto sym = quantity.symbol;
254 | check( sym.is_valid(), "invalid symbol name" );
255 | check( memo.size() <= 256, "memo has more than 256 bytes" );
256 |
257 | stats statstable( _self, sym.code().raw() );
258 | auto existing = statstable.find( sym.code().raw() );
259 | check( existing != statstable.end(), "token with symbol does not exist" );
260 | const auto& st = *existing;
261 |
262 | require_auth( st.issuer );
263 | check( quantity.is_valid(), "invalid quantity" );
264 | check( quantity.amount > 0, "must retire positive quantity" );
265 |
266 | check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
267 |
268 | statstable.modify( st, same_payer, [&]( auto& s ) {
269 | s.supply -= quantity;
270 | });
271 |
272 | sub_balance( st.issuer, quantity );
273 | }
274 |
275 | void WSC::transferwor( name from,
276 | name to,
277 | asset quantity,
278 | string memo )
279 | {
280 | check( from != to, "cannot transfer to self" );
281 | require_auth( from );
282 | check( is_account( to ), "to account does not exist");
283 | auto sym = quantity.symbol.code();
284 | stats statstable( _self, sym.raw() );
285 | const auto& st = statstable.get( sym.raw() );
286 |
287 | require_recipient( from );
288 | require_recipient( to );
289 |
290 | check( quantity.is_valid(), "invalid quantity" );
291 | check( quantity.amount > 0, "must transfer positive quantity" );
292 | check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
293 | check( memo.size() <= 256, "memo has more than 256 bytes" );
294 |
295 | auto payer = has_auth( to ) ? to : from;
296 |
297 | sub_balance( from, quantity );
298 | add_balance( to, quantity, payer );
299 | }
300 |
301 | void WSC::sub_balance( name owner, asset value ) {
302 | accounts from_acnts( _self, owner.value );
303 |
304 | const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" );
305 | check( from.balance.amount >= value.amount, "overdrawn balance" );
306 |
307 | from_acnts.modify( from, owner, [&]( auto& a ) {
308 | a.balance -= value;
309 | });
310 | }
311 |
312 | void WSC::add_balance( name owner, asset value, name ram_payer )
313 | {
314 | accounts to_acnts( _self, owner.value );
315 | auto to = to_acnts.find( value.symbol.code().raw() );
316 | if( to == to_acnts.end() ) {
317 | to_acnts.emplace( ram_payer, [&]( auto& a ){
318 | a.balance = value;
319 | });
320 | } else {
321 | to_acnts.modify( to, same_payer, [&]( auto& a ) {
322 | a.balance += value;
323 | });
324 | }
325 | }
326 |
327 | void WSC::openwor( name owner, const symbol& symbol, name ram_payer )
328 | {
329 | require_auth( ram_payer );
330 |
331 | auto sym_code_raw = symbol.code().raw();
332 |
333 | stats statstable( _self, sym_code_raw );
334 | const auto& st = statstable.get( sym_code_raw, "symbol does not exist" );
335 | check( st.supply.symbol == symbol, "symbol precision mismatch" );
336 |
337 | accounts acnts( _self, owner.value );
338 | auto it = acnts.find( sym_code_raw );
339 | if( it == acnts.end() ) {
340 | acnts.emplace( ram_payer, [&]( auto& a ){
341 | a.balance = asset{0, symbol};
342 | });
343 | }
344 | }
345 |
346 | void WSC::closewor( name owner, const symbol& symbol )
347 | {
348 | require_auth( owner );
349 | accounts acnts( _self, owner.value );
350 | auto it = acnts.find( symbol.code().raw() );
351 | check( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." );
352 | check( it->balance.amount == 0, "Cannot close because the balance is not zero." );
353 | acnts.erase( it );
354 | }
355 |
356 | checksum256 WSC::hashItem(WSC::item &item){
357 |
358 | int i = 0;
359 | string itemStake = item.Stake.to_string();
360 | string itemOwner = item.Owner.to_string();
361 | string itemOriginWorld = item.OriginWorld.to_string();
362 | string GenesisTime = std::to_string(item.GenesisTime);
363 |
364 | uint32_t size = item.ItemName.size() + item.ItemClass.size() + item.Nuance.size() + itemOwner.size() + itemOriginWorld.size() + GenesisTime.size() + itemStake.size();
365 |
366 | print(size, "\n");
367 | auto p = (char*) malloc(size);
368 |
369 | i = item.ItemName.copy(p, item.ItemName.size(), 0);
370 | print(i, "\n");
371 |
372 | i += item.ItemClass.copy(p+i, item.ItemClass.size(), 0);
373 | print(i, "\n");
374 |
375 | i += item.Nuance.copy(p+i, item.Nuance.size(), 0);
376 | print(i, "\n");
377 |
378 | i += itemOwner.copy(p+i, itemOwner.size(), 0);
379 | print(i, "\n");
380 |
381 | i += itemOriginWorld.copy(p+i, itemOriginWorld.size(), 0);
382 | print(i, "\n");
383 |
384 | i += GenesisTime.copy(p+i, GenesisTime.size(), 0);
385 | print(i, "\n");
386 |
387 | i += itemStake.copy(p+i, itemStake.size(), 0);
388 | print(i, "\n");
389 |
390 | checksum256 calc_hash = sha256(p, size);
391 | free(p);
392 |
393 | print("ItemName: ", std::move(item.ItemName), "\n");
394 | print("ItemClass: ", std::move(item.ItemClass), "\n");
395 | print("ItemNuance: ", std::move(item.Nuance), "\n");
396 | print("ItemOwner: ", std::move(itemOwner), "\n");
397 | print("OriginWorld: ", std::move(itemOriginWorld), "\n");
398 | print("GenesisTime: ", std::move(GenesisTime), "\n");
399 | print("Stake: ", std::move(itemStake), "\n");
400 |
401 | print("Sha256: ");
402 | calc_hash.print();
403 | return(calc_hash);
404 |
405 | }
406 | } // namespace eosio
407 |
--------------------------------------------------------------------------------
/scripts/config.ini:
--------------------------------------------------------------------------------
1 | # the endpoint upon which to listen for incoming connections (eosio::bnet_plugin)
2 | # bnet-endpoint = 0.0.0.0:4321
3 |
4 | # this peer will request only irreversible blocks from other nodes (eosio::bnet_plugin)
5 | # bnet-follow-irreversible = false
6 |
7 | # the number of threads to use to process network messages (eosio::bnet_plugin)
8 | # bnet-threads =
9 |
10 | # remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network (eosio::bnet_plugin)
11 | # bnet-connect =
12 |
13 | # this peer will request no pending transactions from other nodes (eosio::bnet_plugin)
14 | # bnet-no-trx = false
15 |
16 | # The string used to format peers when logging messages about them. Variables are escaped with ${}.
17 | # Available Variables:
18 | # _name self-reported name
19 | #
20 | # _id self-reported ID (Public Key)
21 | #
22 | # _ip remote IP address of peer
23 | #
24 | # _port remote port number of peer
25 | #
26 | # _lip local IP address connected to peer
27 | #
28 | # _lport local port number connected to peer
29 | #
30 | # (eosio::bnet_plugin)
31 | # bnet-peer-log-format = ["${_name}" ${_ip}:${_port}]
32 |
33 | # the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin)
34 | # blocks-dir = "blocks"
35 |
36 | # Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin)
37 | # checkpoint =
38 |
39 | # Override default WASM runtime (eosio::chain_plugin)
40 | # wasm-runtime =
41 |
42 | # Override default maximum ABI serialization time allowed in ms (eosio::chain_plugin)
43 | # abi-serializer-max-time-ms = 15000
44 |
45 | # Maximum size (in MiB) of the chain state database (eosio::chain_plugin)
46 | # chain-state-db-size-mb = 1024
47 |
48 | # Safely shut down node when free space remaining in the chain state database drops below this size (in MiB). (eosio::chain_plugin)
49 | # chain-state-db-guard-size-mb = 128
50 |
51 | # Maximum size (in MiB) of the reversible blocks database (eosio::chain_plugin)
52 | # reversible-blocks-db-size-mb = 340
53 |
54 | # Safely shut down node when free space remaining in the reverseible blocks database drops below this size (in MiB). (eosio::chain_plugin)
55 | # reversible-blocks-db-guard-size-mb = 2
56 |
57 | # Percentage of actual signature recovery cpu to bill. Whole number percentages, e.g. 50 for 50% (eosio::chain_plugin)
58 | # signature-cpu-billable-pct = 50
59 |
60 | # Number of worker threads in controller thread pool (eosio::chain_plugin)
61 | # chain-threads = 2
62 |
63 | # print contract's output to console (eosio::chain_plugin)
64 | # contracts-console = false
65 |
66 | # Account added to actor whitelist (may specify multiple times) (eosio::chain_plugin)
67 | # actor-whitelist =
68 |
69 | # Account added to actor blacklist (may specify multiple times) (eosio::chain_plugin)
70 | # actor-blacklist =
71 |
72 | # Contract account added to contract whitelist (may specify multiple times) (eosio::chain_plugin)
73 | # contract-whitelist =
74 |
75 | # Contract account added to contract blacklist (may specify multiple times) (eosio::chain_plugin)
76 | # contract-blacklist =
77 |
78 | # Action (in the form code::action) added to action blacklist (may specify multiple times) (eosio::chain_plugin)
79 | # action-blacklist =
80 |
81 | # Public key added to blacklist of keys that should not be included in authorities (may specify multiple times) (eosio::chain_plugin)
82 | # key-blacklist =
83 |
84 | # Deferred transactions sent by accounts in this list do not have any of the subjective whitelist/blacklist checks applied to them (may specify multiple times) (eosio::chain_plugin)
85 | # sender-bypass-whiteblacklist =
86 |
87 | # Database read mode ("speculative", "head", or "read-only").
88 | # In "speculative" mode database contains changes done up to the head block plus changes made by transactions not yet included to the blockchain.
89 | # In "head" mode database contains changes done up to the current head block.
90 | # In "read-only" mode database contains incoming block changes but no speculative transaction processing.
91 | # (eosio::chain_plugin)
92 | # read-mode = speculative
93 |
94 | # Chain validation mode ("full" or "light").
95 | # In "full" mode all incoming blocks will be fully validated.
96 | # In "light" mode all incoming blocks headers will be fully validated; transactions in those validated blocks will be trusted
97 | # (eosio::chain_plugin)
98 | # validation-mode = full
99 |
100 | # Disable the check which subjectively fails a transaction if a contract bills more RAM to another account within the context of a notification handler (i.e. when the receiver is not the code of the action). (eosio::chain_plugin)
101 | # disable-ram-billing-notify-checks = false
102 |
103 | # Indicate a producer whose blocks headers signed by it will be fully validated, but transactions in those validated blocks will be trusted. (eosio::chain_plugin)
104 | # trusted-producer =
105 |
106 | # Track actions which match receiver:action:actor. Actor may be blank to include all. Action and Actor both blank allows all from Recieiver. Receiver may not be blank. (eosio::history_plugin)
107 | # filter-on =
108 |
109 | # Do not track actions which match receiver:action:actor. Action and Actor both blank excludes all from Reciever. Actor blank excludes all from reciever:action. Receiver may not be blank. (eosio::history_plugin)
110 | # filter-out =
111 |
112 | # PEM encoded trusted root certificate (or path to file containing one) used to validate any TLS connections made. (may specify multiple times)
113 | # (eosio::http_client_plugin)
114 | # https-client-root-cert =
115 |
116 | # true: validate that the peer certificates are valid and trusted, false: ignore cert errors (eosio::http_client_plugin)
117 | # https-client-validate-peers = true
118 |
119 | # The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
120 | http-server-address = 192.168.10.35:8888
121 |
122 | # The local IP and port to listen for incoming https connections; leave blank to disable. (eosio::http_plugin)
123 | # https-server-address =
124 |
125 | # Filename with the certificate chain to present on https connections. PEM format. Required for https. (eosio::http_plugin)
126 | # https-certificate-chain-file =
127 |
128 | # Filename with https private key in PEM format. Required for https (eosio::http_plugin)
129 | # https-private-key-file =
130 |
131 | # Specify the Access-Control-Allow-Origin to be returned on each request. (eosio::http_plugin)
132 | # access-control-allow-origin =
133 |
134 | # Specify the Access-Control-Allow-Headers to be returned on each request. (eosio::http_plugin)
135 | # access-control-allow-headers =
136 |
137 | # Specify the Access-Control-Max-Age to be returned on each request. (eosio::http_plugin)
138 | # access-control-max-age =
139 |
140 | # Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin)
141 | # access-control-allow-credentials = false
142 |
143 | # The maximum body size in bytes allowed for incoming RPC requests (eosio::http_plugin)
144 | # max-body-size = 1048576
145 |
146 | # Maximum size in megabytes http_plugin should use for processing http requests. 503 error response when exceeded. (eosio::http_plugin)
147 | # http-max-bytes-in-flight-mb = 500
148 |
149 | # Append the error log to HTTP responses (eosio::http_plugin)
150 | # verbose-http-errors = false
151 |
152 | # If set to false, then any incoming "Host" header is considered valid (eosio::http_plugin)
153 | # http-validate-host = true
154 |
155 | # Additionaly acceptable values for the "Host" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default. (eosio::http_plugin)
156 | # http-alias =
157 |
158 | # Number of worker threads in http thread pool (eosio::http_plugin)
159 | # http-threads = 2
160 |
161 | # The maximum number of pending login requests (eosio::login_plugin)
162 | # max-login-requests = 1000000
163 |
164 | # The maximum timeout for pending login requests (in seconds) (eosio::login_plugin)
165 | # max-login-timeout = 60
166 |
167 | # The target queue size between nodeos and MongoDB plugin thread. (eosio::mongo_db_plugin)
168 | # mongodb-queue-size = 1024
169 |
170 | # The maximum size of the abi cache for serializing data. (eosio::mongo_db_plugin)
171 | # mongodb-abi-cache-size = 2048
172 |
173 | # Required with --replay-blockchain, --hard-replay-blockchain, or --delete-all-blocks to wipe mongo db.This option required to prevent accidental wipe of mongo db. (eosio::mongo_db_plugin)
174 | # mongodb-wipe = false
175 |
176 | # If specified then only abi data pushed to mongodb until specified block is reached. (eosio::mongo_db_plugin)
177 | # mongodb-block-start = 0
178 |
179 | # MongoDB URI connection string, see: https://docs.mongodb.com/master/reference/connection-string/. If not specified then plugin is disabled. Default database 'EOS' is used if not specified in URI. Example: mongodb://127.0.0.1:27017/EOS (eosio::mongo_db_plugin)
180 | # mongodb-uri =
181 |
182 | # Update blocks/block_state with latest via block number so that duplicates are overwritten. (eosio::mongo_db_plugin)
183 | # mongodb-update-via-block-num = false
184 |
185 | # Enables storing blocks in mongodb. (eosio::mongo_db_plugin)
186 | # mongodb-store-blocks = true
187 |
188 | # Enables storing block state in mongodb. (eosio::mongo_db_plugin)
189 | # mongodb-store-block-states = true
190 |
191 | # Enables storing transactions in mongodb. (eosio::mongo_db_plugin)
192 | # mongodb-store-transactions = true
193 |
194 | # Enables storing transaction traces in mongodb. (eosio::mongo_db_plugin)
195 | # mongodb-store-transaction-traces = true
196 |
197 | # Enables storing action traces in mongodb. (eosio::mongo_db_plugin)
198 | # mongodb-store-action-traces = true
199 |
200 | # Track actions which match receiver:action:actor. Receiver, Action, & Actor may be blank to include all. i.e. eosio:: or :transfer: Use * or leave unspecified to include all. (eosio::mongo_db_plugin)
201 | # mongodb-filter-on =
202 |
203 | # Do not track actions which match receiver:action:actor. Receiver, Action, & Actor may be blank to exclude all. (eosio::mongo_db_plugin)
204 | # mongodb-filter-out =
205 |
206 | # The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin)
207 | # p2p-listen-endpoint = 0.0.0.0:9876
208 |
209 | # An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint. (eosio::net_plugin)
210 | # p2p-server-address =
211 |
212 | # The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network. (eosio::net_plugin)
213 | # p2p-peer-address =
214 |
215 | # Maximum number of client nodes from any single IP address (eosio::net_plugin)
216 | # p2p-max-nodes-per-host = 1
217 |
218 | # The name supplied to identify this node amongst the peers. (eosio::net_plugin)
219 | # agent-name = "EOS Test Agent"
220 |
221 | # Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin)
222 | # allowed-connection = any
223 |
224 | # Optional public key of peer allowed to connect. May be used multiple times. (eosio::net_plugin)
225 | # peer-key =
226 |
227 | # Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin)
228 | # peer-private-key =
229 |
230 | # Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin)
231 | # max-clients = 25
232 |
233 | # number of seconds to wait before cleaning up dead connections (eosio::net_plugin)
234 | # connection-cleanup-period = 30
235 |
236 | # max connection cleanup time per cleanup call in millisec (eosio::net_plugin)
237 | # max-cleanup-time-msec = 10
238 |
239 | # True to require exact match of peer network version. (eosio::net_plugin)
240 | # network-version-match = false
241 |
242 | # Number of worker threads in net_plugin thread pool (eosio::net_plugin)
243 | # net-threads = 1
244 |
245 | # number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin)
246 | # sync-fetch-span = 100
247 |
248 | # Enable expirimental socket read watermark optimization (eosio::net_plugin)
249 | # use-socket-read-watermark = false
250 |
251 | # The string used to format peers when logging messages about them. Variables are escaped with ${}.
252 | # Available Variables:
253 | # _name self-reported name
254 | #
255 | # _id self-reported ID (64 hex characters)
256 | #
257 | # _sid first 8 characters of _peer.id
258 | #
259 | # _ip remote IP address of peer
260 | #
261 | # _port remote port number of peer
262 | #
263 | # _lip local IP address connected to peer
264 | #
265 | # _lport local port number connected to peer
266 | #
267 | # (eosio::net_plugin)
268 | # peer-log-format = ["${_name}" ${_ip}:${_port}]
269 |
270 | # Enable block production, even if the chain is stale. (eosio::producer_plugin)
271 | # enable-stale-production = false
272 |
273 | # Start this node in a state where production is paused (eosio::producer_plugin)
274 | # pause-on-startup = false
275 |
276 | # Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin)
277 | # max-transaction-time = 30
278 |
279 | # Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited) (eosio::producer_plugin)
280 | # max-irreversible-block-age = -1
281 |
282 | # ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin)
283 | # producer-name =
284 |
285 | # (DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times) (eosio::producer_plugin)
286 | # private-key =
287 |
288 | # Key=Value pairs in the form =
289 | # Where:
290 | # is a string form of a vaild EOSIO public key
291 | #
292 | # is a string in the form :
293 | #
294 | # is KEY, or KEOSD
295 | #
296 | # KEY: is a string form of a valid EOSIO private key which maps to the provided public key
297 | #
298 | # KEOSD: is the URL where keosd is available and the approptiate wallet(s) are unlocked (eosio::producer_plugin)
299 | # signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
300 |
301 | # Limits the maximum time (in milliseconds) that is allowed for sending blocks to a keosd provider for signing (eosio::producer_plugin)
302 | # keosd-provider-timeout = 5
303 |
304 | # account that can not access to extended CPU/NET virtual resources (eosio::producer_plugin)
305 | # greylist-account =
306 |
307 | # offset of non last block producing time in microseconds. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later (eosio::producer_plugin)
308 | # produce-time-offset-us = 0
309 |
310 | # offset of last block producing time in microseconds. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later (eosio::producer_plugin)
311 | # last-block-time-offset-us = 0
312 |
313 | # Maximum wall-clock time, in milliseconds, spent retiring scheduled transactions in any block before returning to normal transaction processing. (eosio::producer_plugin)
314 | # max-scheduled-transaction-time-per-block-ms = 100
315 |
316 | # ratio between incoming transations and deferred transactions when both are exhausted (eosio::producer_plugin)
317 | # incoming-defer-ratio = 1
318 |
319 | # Number of worker threads in producer thread pool (eosio::producer_plugin)
320 | # producer-threads = 2
321 |
322 | # the location of the snapshots directory (absolute path or relative to application data dir) (eosio::producer_plugin)
323 | # snapshots-dir = "snapshots"
324 |
325 | # the location of the state-history directory (absolute path or relative to application data dir) (eosio::state_history_plugin)
326 | # state-history-dir = "state-history"
327 |
328 | # enable trace history (eosio::state_history_plugin)
329 | # trace-history = false
330 |
331 | # enable chain state history (eosio::state_history_plugin)
332 | # chain-state-history = false
333 |
334 | # the endpoint upon which to listen for incoming connections. Caution: only expose this port to your internal network. (eosio::state_history_plugin)
335 | # state-history-endpoint = 127.0.0.1:8080
336 |
337 | # Lag in number of blocks from the head block when selecting the reference block for transactions (-1 means Last Irreversible Block) (eosio::txn_test_gen_plugin)
338 | # txn-reference-block-lag = 0
339 |
340 | # Number of worker threads in txn_test_gen thread pool (eosio::txn_test_gen_plugin)
341 | # txn-test-gen-threads = 2
342 |
343 | # Plugin(s) to enable, may be specified multiple times
344 | # plugin =
345 |
346 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/worlds/whitepaper.tex:
--------------------------------------------------------------------------------
1 | \documentclass[runningheads,a4paper]{llncs}
2 |
3 | \usepackage{amssymb}
4 | \setcounter{tocdepth}{3}
5 | \usepackage{graphicx}
6 | \usepackage{tikz}
7 | \usepackage[T1]{fontenc}
8 | \usepackage[scaled]{beramono}
9 | \usepackage{listings}
10 | \usepackage{color}
11 | \usetikzlibrary{arrows,chains,positioning,scopes,quotes,calc}
12 | \usepackage{float}
13 |
14 | \newcommand{\keywords}[1]{\par\addvspace\baselineskip
15 | \noindent\keywordname\endspace\ignorespaces#1}
16 | \pagestyle{plain}
17 | \setlength\parindent{0pt}
18 |
19 | \definecolor{mygreen}{RGB}{28,172,0} % color values Red, Green, Blue
20 | \definecolor{mylilas}{RGB}{170,55,241}
21 |
22 | \newcommand*{\StrikeThruDistance}{0.15cm}%
23 | \newcommand*{\StrikeThru}{\StrikeThruDistance,\StrikeThruDistance}%
24 |
25 | \tikzset{strike thru arrow/.style={
26 | decoration={markings, mark=at position 0.5 with {
27 | \draw [blue, thick,-]
28 | ++ (-\StrikeThruDistance,-\StrikeThruDistance)
29 | -- ( \StrikeThruDistance, \StrikeThruDistance);}
30 | },
31 | postaction={decorate},
32 | }}
33 |
34 | \lstset{
35 | language=Python,
36 | showstringspaces=false,
37 | formfeed=\newpage,
38 | tabsize=4,
39 | commentstyle=\itshape,
40 | basicstyle=\ttfamily,
41 | morekeywords={models, lambda, forms}
42 | }
43 |
44 | \begin{document}
45 | \def \SystemName {Worlds} % Lol because this shit probably will change.
46 |
47 | \mainmatter % start of an individual contribution
48 |
49 | % This needs some work, big time.
50 | \title{\SystemName: A Distributed MMO}
51 |
52 | \author{Ryan Walker\\
53 | ryan.cjw@gmail.com}
54 |
55 | \institute{} %Merp
56 |
57 | \maketitle
58 |
59 | \begin{abstract}
60 | This paper overviews a protocol that aims to manage the large scale economic components of a distributed MMO. Following the implementation of the Worlds protocol it becomes possible to fairly scale a universe based on games developed by completely independent parties.
61 | \end{abstract}
62 |
63 | \section{Worlds}
64 | \subsection{Introduction}
65 | For an open software ecosystem to grow organically there should be outlets for contribution. In the context of a massively multiplayer online game the outlets become more complicated then a simple code repository. Fair game mechanics are built on a fragile ecosystem that have negative consequences if managed improperly. Forming consensus on a network is trivially done with conventional methods. A server maintains a secure connection with a player who pipes actions to the server. The server then provides ground truth for the network. Our model replaces a centralized organization with a smart contract which forms consensus and balances the economics of the universe. The user experience is designed by anyone who wishes to contribute.
66 |
67 | \subsection{Overview}
68 | A world, defined as $w_k$, is a node that designs a user experience and hosts players. Worlds provide the game client which the players interact with. In addition they govern their world and create the elements that make it unique. A world can have up to four adjacent worlds determined by itself. This forms a network, which allows players to explore and move common items (\ref{items}), experience (\ref{exp}) and currency (\ref{money}) between worlds.
69 |
70 | \begin{small}
71 | \tikzset{myblock/.style = {rectangle, draw, minimum height=1cm, minimum width=3cm}}
72 | \begin{center}
73 | \begin{tikzpicture}
74 | \label{Hello}
75 | \node(WE)[myblock]{\begin{tabular}{c}Worlds Engine \\ {\scriptsize Worlds.js} \\\end{tabular}};
76 | \node (WS)[myblock,above of=WE, yshift=1cm]{\begin{tabular}{c}Worlds Engine\\ {\scriptsize Worlds.js} \\\end{tabular}};
77 | \node (WC)[myblock,left of=WE, xshift=-3cm]{\begin{tabular}{c}Game Client \\ {\scriptsize \textit{From game Dev}} \\\end{tabular}};
78 | \node (SE)[myblock,left of=WS, xshift=-3cm]{\begin{tabular}{c}Server Engine \\ {\scriptsize \textit{From game Dev}} \\\end{tabular}};
79 | \node (WSC)[myblock,right of=WS, xshift=3cm, yshift=-1cm]{Smart Contract (\ref{WSC})};
80 |
81 | \draw [dashed] (-6,1) -- (2,1);
82 | \draw [dashed] (2,2.5) -- (2,-0.5);
83 |
84 | \node [left of=SE, xshift=-1cm]{\begin{tabular}{c}Server\\Side\end{tabular}};
85 | \node [left of=WC, xshift=-1cm]{\begin{tabular}{c}Client\\Side\end{tabular}};
86 | \node [below of=WSC]{Blockchain};
87 |
88 | % \draw[<->] ($(WE.north east)!0.5!(WE.north west)$) -- ($(WS.south east)!0.5!(WS.south west)$);
89 | \draw[<->] (WC) -- (WE);
90 | \draw[<->] (SE) -- (WS);
91 | \draw[<->] (SE) -- (WC);
92 | \draw[<->] ($(WSC.north west)!0.25!(WSC.south west)$) -- ($(WS.north east)!0.5!(WS.south east)$);
93 | \draw[<->] ($(WSC.north west)!0.75!(WSC.south west)$) -- ($(WE.north east)!0.5!(WE.south east)$);
94 | % TODO: Change the arrow heads.
95 | \end{tikzpicture}
96 | \end{center}
97 | \end{small}
98 | The worlds engine is an application that manages the elements that are common throughout all worlds, such as player keys, hashing, signing and fetching the files required to run the Game Client. The world designer has full creative freedom over the game client and server engine. This enables the highest flexibility and the most unique universe. It is possible for clusters of worlds to share a single game client, yet design their own experience. Conversely, adjacent worlds might have completely different game clients, where players might move from a text based MUD into a fully 3D world.
99 |
100 | \section{Worlds Smart Contact (WSC)}
101 | \label{WSC}
102 | The worlds smart contract is used to balance the economy across the network. It contains functions and data elements that are used as various forms of proof that require interoperability between worlds. An appropriate blockchain with the following requirements has not yet been selected, it must satisfy the following requirements.
103 |
104 | \begin{itemize}
105 | \item{Low networks fees}
106 | \item{Fast transactions for in game purchases}
107 | \item{Decent data capacity to hold proofs}
108 | \end{itemize}
109 |
110 | \subsection{Staking} % Need to write more one this. I think this is a good spot?
111 | Staking is the fundamental mechanic that balances the economy. This allows a node to lock the WOR token against a hash. This hash can be a proof for experience, items, or any arbitrary chunk of data that that has meaning within the World universe. It's up to the World creators to interpret this data.
112 |
113 | \section{Actions}
114 | Actions are defined as anything a node can do to effect the network. Messages and data packages are to be considered actions in this context.
115 |
116 | \subsection{Direct Action}
117 | A direct action is any action that is travels between the Server Engine and the Game Client. These actions have the lowest latency. An example of an action like this might be the Server engine telling the Game Client of some in game event. Before there can be communication like this the there needs to be a symmetric key exchange.
118 |
119 | \subsection{Proof Action}
120 | Proof actions are actions that require the use of private keys for signing, private keys are managed exclusively by the worlds engine. It it possible for the Game Client to request the Worlds Engine to sign a package, however the player must approve this. For nodes that require higher security it is possible to hold the Worlds Engine offline, this inherently keeps their keys keys offline.
121 |
122 | \subsection{Contract Action}
123 | Contract actions are any actions which communicate with the Worlds Smart Contract. They can be issued from the Worlds Engine directly, or the Game Client can pipe action requests into the worlds engine. Like proof actions, contract actions must be approved by the player if they were issued by the game client.
124 |
125 | \section{Experience}
126 | \label{exp}
127 | Experience is distributed to players using experience packages. These are of the form (Figure \ref{exppkg}). When a player is to received experience this package is hashed, signed and sent to the \textit{Worlds Smart Contract} (\ref{WSC})(WSC). The world must stake some WOR in order to grant experience. Experience is distributed like items, although it is not transferable from player to player. It is possible for experience to be liquidated back into WOR by the players. The amount of experience is a function of the amount of WOR locked against the hash. It is possible for players to stake their own WOR and buy experience. However this experience is stamped with the public key of the issuer and it's possible that worlds might not accept this during the worlds transfer.
128 |
129 | \begin{figure}[H]
130 | \centering
131 | \caption{Experience Package - Sword Fighting}
132 | \label{exppkg}
133 | \begin{lstlisting}
134 | ExpClass = 'SwordFighting'
135 | PlayerPublic = 0x5d7ac22131ad370e59fddb5f6079a354dbdd2dd9
136 | WorldPublic = 0xb1abdaf3ab936c99f5fd518122cf7d5b811a1a30
137 | IssueTime = UnixTime #Time of Issue
138 | Stake = 0.1WOR
139 | ExpHash = hash(ExpClass | ... | Stake);
140 | \end{lstlisting}
141 | \end{figure}
142 |
143 | \subsection{Receiving Experience}
144 | Players may receive lots of small chunks of experience during gameplay, this can be taxing on a blockchain. For this reason worlds may wish to issue a lumped sum package when the player leaves the world or requests their package. Even thought experience is kept off-chain during gameplay in this scenario, it's still possible that the benefits may be realized immediately.
145 |
146 | \section{Items}
147 | \label{items}
148 | Items may be introduced by any node on the network. In order to spawn an item, the item package must be signed by the node and submitted to the \textit{worlds smart contract}. This serves to proves ownership and lock the WOR associated with the item. The smart contract then verifies that the WorldPublic field is the public key of the node issuing the item, assigns current unix time and then moves the WOR into the smart contract from the issuers account. The sha256 hash of the item package is kept on-chain, it is the responsibility of the owner of the item to keep the item package contents. If the user wishes to liquidate or transfer the item the item's hash is required, this is done to preserve space onchain.
149 |
150 | \begin{figure}[H]
151 | \centering
152 | \label{itempkg}
153 | \caption{Item Package $i$ - Wood}
154 | \begin{lstlisting}
155 | ItemName = 'Wood'
156 | ItemClass = 'Material'
157 | OwnerPublic = 0x5d7ac22131ad370e59fddb5f6079a354dbdd2dd9
158 | PreviousOwnerPublic = 0xgf7dsa7ejdb5370e59fddb5f6079a354ugf84bdv
159 | WorldPublic = 0xb1abdaf3ab936c99f5fd518122cf7d5b811a1a30
160 | UnixTimeGen = # Time the item was created
161 | UnixTimeTX = # Time the item was last transmitted
162 | Stake = 1WOR
163 | ItemHash = hash(ItemName | ... | Stake);
164 | \end{lstlisting}
165 | \end{figure}
166 |
167 | % Speak more on this
168 | As with experience, Worlds have the option to credit or discredit certain items based on the WorldPublic field.
169 |
170 | \subsection{Item Transfers}
171 | It's possible to transfer items to other players simply by calling a function on the WSC.
172 |
173 | \subsection{Item Liquidation}
174 | It's possible to liquidate an item back into the WOR that's stakes against it. This is simply done be calling a function on the worlds smart contract.
175 |
176 | \subsection{Forging}
177 | \label{Forging}
178 | It is possible to forge items by combining multiple items, thus forming a derivative item. In literal sense the act of forging it to call the function \textit{ForgeItem(Item1, Item2, ...)} on the WSC. This will then make a derivative item which is shown in Figure \ref{ForgedItem}. It is up to the worlds to decide on the item names and item classes of these subitems. As an example, a player may forge a sword by combining metal, fabric and a sharpening stone. As long at the world recognizes that the ForgeHash of the item do in fact form a sword, then the player has crafted a sword for use in these worlds. The power of the sword would be proportional to the amount of stakes WOR in all the items that were used to craft the sword. Once items are forged into something they can no longer be used for anything else. It is possible to unforge an item.
179 |
180 | \begin{figure}[H]
181 | \centering
182 | \caption{Forged Item $i_f$}
183 | \label{ForgedItem}
184 | \begin{lstlisting}[escapeinside={(*}{*)}]
185 | ForgeHash = hash((*$i_0[ItemName] | i_0[ItemClass] | ... | i_n[ItemName] | i_n[ItemClass]$*))
186 | PlayerPublic = 0x5d7ac22131ad370e59fddb5f6079a354dbdd2dd9
187 | WorldPublic[0 .. n] = # Public Key of all the worlds that issued the sub items
188 | ItemHash[0 .. n] = # Item hashes of items in the forge
189 | UnixTimeGen = # Time the item was created
190 | UnixTimeTX = # Time the item was last transmitted
191 | Stake = sum(ParentItemStake)
192 | ItemHash = hash(ForgeHash | ... | Stake);
193 | \end{lstlisting}
194 | \end{figure}
195 |
196 | \subsection{Using Items}
197 | In order to use an items in a world, the player must present the items to the world for verification, this is done using ftp. During an initial connection the worlds server issues ftp credentials to player, these credentials are then used by the player to move items into the game. The world is responsible for ensuring that there are no double deposits. This can be done with a simple hash lookup comparing items that have been deposited in the past to items that are currently being deposited.
198 |
199 | \subsection{Item and Exp Value}
200 | The value and effect of items and experience will most likely not be directly correlated to the amount of WOR that is staked into them. The two other factors are Genesis time and Genesis world. As the game moves forward, many items will become rare or scarce.
201 |
202 | \subsection{Item Translations}
203 | \label{ItemTranslations}
204 | Worlds maintain a list of all items they recognize, during a world transfer some player items may not be on this list. This means the player will not be able to use these items. To minimize this problem worlds may use an item translation. This is effectively a list of items that funnel into one.
205 |
206 | \section{Currency (WOR)}
207 | \label{money}
208 | A common currency between worlds will be used for staking and integration into the platform. To prevent abuse this currency must be zero sum, meaning worlds cannot generate it and it must start with a fixed supply. Ideally it is tracked through an existing blockchain. Worlds can introduce mechanics for generating revenue, like entrance fees, subscriptions, purchasing items, or keeping players items upon a death. Please read more in section \ref{MakeMoney}.
209 |
210 | \section{Transport}
211 | To prevent players from playing on multiple worlds concurrently a player location is kept on the worlds smart contract. This location is the public key of the world that the player currently resides. In order for this to be valid it must be signed by the player and the world the player resides in. If a player wishes to travel to a world...
212 |
213 | \begin{itemize}
214 | \item{The player must send a signed entry request to the world.}
215 | \item{If the world only allows travel from adjacent worlds, the player must reside in an adjacent world.}
216 | \item{The player provides proof of items and experience.}
217 | \item{The world might check the public key stamped the items/exp to ensure they are from creditable sources.}
218 | \item{Items or experience are staked if required to be.}
219 | \item{Player is granted access, WSC is updated with player location.}
220 | \end{itemize}
221 |
222 | \section{Connection}
223 | In order to make a smooth player experience there is a state machine that must be followed by all worlds. This is outlined below, SS indicated serverside while CL indicated client size.
224 |
225 | \begin{enumerate}
226 | \item{\textbf{SS:} The game server establishes a socket to the Worlds Engine on the serverside. This is used to pipe data back and fourth.}
227 | \item{\textbf{CS:} The Worlds Engine launches the game client, as commanded by the player}
228 | \item{\textbf{SS/CS:} Communication is opened between the game client and the game server. This can be any protocol and is determined by the developer.}
229 | \item{\textbf{CS:} The Worlds Engine generates a proof package and writes the file to player/player.json on the client side**}
230 | \item{\textbf{CS/SS:} The game client sends the json serialized object from client to server.}
231 | \item{\textbf{SS:} The game server verifies the proof through the worlds engine, if the proof in genuine the server instantiates the player into the world.}
232 | \item{\textbf{CS/SS:} The player is given ftp credentials, these can be used to move items into a folder on the server.}
233 | \item{\textbf{SS:} The server then verifies the items are real. If they are they are given the player in game.}
234 | \item{\textbf{SS:} If a player is to receive items, they are placed in the players folder on the server. They can then be claimed by the player for transfer to another world.}
235 | \end{enumerate}
236 |
237 |
238 | \section{World Incentivisation}
239 | \label{MakeMoney}
240 | If worlds want to distribute items or experience they must stake some WOR into items. As WOR has monetary value worlds need a way to generate some revenue. In order for a world to profit, the sum of all revenue generation methods must be less their their distributed items plus their overhead. Some revenue strategies are similar to existing games, some are completely new.
241 |
242 | \subsection{Burying}
243 | \label{Burying}
244 | Some worlds may require you to "bury" some experience, items or WOR before entering. This is effectively temporarily moving these into possession of the world. Worlds may introduce in game mechanics which result in the retention of these items, such as a player death. The world then has freedom over what happens to these items. Some profit models are described below.
245 |
246 | \begin{itemize}
247 | \item{Redistribute the assets to other player, skimming some of the top.}
248 | \item{Liquidate all the items for WOR.}
249 | \item{Give some of the items back to the player.}
250 | \end{itemize}
251 |
252 | \subsection{Fees}
253 | Just like conventional games, it is possible the worlds might charge an entrance fees. These could be one time or reoccurring. This would be transparent as the player moves about worlds. Ideally the fees would be built into the lore of the game.
254 |
255 | \subsection{In Game Purchases}
256 | Worlds might wish to sell items for WOR, as an example there might be an NPC store that sells some items which have special abilities within the world of issuance. The amount of WOR staked into the items would be less than the amount it is sold for. Neighboring world may wish to grant similar abilities in exchange for having some of their items more powerful in worlds adjacent to themselves. This may be considered pay-to-win, however the economics can be moderated by the ecosystem and community, as worlds have the option to deny items that are issued by certain worlds.\\
257 |
258 | Static items are assets that may not transcend worlds, an example being virtual land or housing. These are provided solely by the world of issuance and the value is determined by that world. It is possible they may be kept in the WSC with a staked value of 0 WOR. As worlds are not required to stake WOR against these assets they may profit from selling them for WOR. Items of this class might prove to be an alternate revenue stream.
259 |
260 | \section{Outstanding Issues}
261 | \subsection{Malicious Worlds}
262 | Players may be required to bury assets to enter a world (\ref{Burying}). As the universe grows, worlds may be required to manage lots of wealth, which opens the possibility of an exit scam or hacking.
263 |
264 | \subsection{Neighbor Conflict}
265 | Depending on the topology of worlds there may be neighbor conflicts. In the grid model, Figure \ref{GRID}, $w_5$ may wish to be adjacent to $w_2$ but not next to $w_4$.
266 |
267 | \begin{figure}
268 | \centering
269 | \caption{GRID}
270 | \label{GRID}
271 | \begin{tikzpicture}
272 | \node[shape=rectangle,draw=black, minimum height=0.5cm, minimum width=0.5cm] (w1) at (0,0) {$w_1$};
273 | \node[shape=rectangle,draw=black, minimum height=0.5cm, minimum width=0.5cm, left of=w1] (w2) {$w_2$};
274 | \node[shape=rectangle,draw=black, minimum height=0.5cm, minimum width=0.5cm, left of=w2] (w3) {$w_3$};
275 | \node[shape=rectangle,draw=black, minimum height=0.5cm, minimum width=0.5cm, above of=w3] (w4) {$w_4$};
276 | \node[shape=rectangle,draw=black, minimum height=0.5cm, minimum width=0.5cm, above of=w2] (w5) {$w_5$};
277 |
278 | \draw [-] (w1) -- (w2);
279 | \draw [-] (w2) -- (w3);
280 | \draw [-] (w3) -- (w4);
281 | \draw [-] (w2) -- (w5);
282 | \end{tikzpicture}
283 | \end{figure}
284 |
285 | Using a network, Figure \ref{Graph} it's possible to treat the worlds like nodes on a graph. This allows four neighboring connections on every node.
286 |
287 | \begin{figure}
288 | \centering
289 | \caption{Graph}
290 | \label{Graph}
291 | \begin{tikzpicture}
292 | \node[shape=circle,draw=black] (w1) at (-0.3cm,0.1cm) {$w_1$};
293 | \node[shape=circle,draw=black, left of=w1, yshift=0.5cm] (w2) {$w_2$};
294 | \node[shape=circle,draw=black, left of=w2, yshift=-0.5cm] (w3) {$w_3$};
295 | \node[shape=circle,draw=black, above of=w3, xshift=0.3cm] (w4) {$w_4$};
296 | \node[shape=circle,draw=black, above of=w2] (w5) {$w_5$};
297 | \node[shape=circle,draw=black, left of=w5, xshift=-0.2cm, yshift=0.5cm] (w6) {$w_6$};
298 |
299 | \draw [-] (w1) -- (w2);
300 | \draw [-] (w2) -- (w3);
301 | \draw [-] (w3) -- (w4);
302 | \draw [-] (w2) -- (w5);
303 | \draw [-] (w5) -- (w6);
304 | \end{tikzpicture}
305 | \end{figure}
306 |
307 | \subsection{Developers}
308 | It is possible that development may never catch on, developers may be turned away from the staking mechanic. As they are use to distributing digital assets without consequences.
309 |
310 | \subsection{Blockchain Technology}
311 | We are keeping our eyes open for a suitable blockchain for developing the smart contract. But the space requirements are high, ideally players can bring their own blockchain storage, meaning players pay a small amount for each item they wish to keep.
312 |
313 | \subsection{Unification}
314 | Worlds may have issues forming consensus on forged items (\ref{Forging}). The derivative hash will be the same if all of the items that go into the forge are the same from forge to forge. Although the resultant item of the forge can be controversial. It is possible that worlds can use item translations (\ref{ItemTranslations}), these can be used to funnel many items into a single for use in the world.
315 |
316 | \subsection{Congruent Worlds}
317 | As it is possible for each world to have their own client the game may suffer from a disconnect, as players move from world to world and the engine fetches new clients for each world the universe may seem to be disconnected. This may be either positive or negative based on the player. After the development of the Worlds Engine and smart contract, we are confident that there will be clusters of worlds that use the same client for players that want more fluid game play.
318 |
319 | \end{document}
320 |
321 | \section{Engine Mechanics}
322 | The mechanics below are simply suggestions. As the engine is completely open, worlds are free to impose whatever mechanics they wish. Worlds with drastically different game mechanics will probably not be bordering, this limits gameplay but maintains fairness. Players are able to play in whatever worlds they wish - but they must start from scratch in non-adjacent clusters.
323 |
324 | % Clusters of worlds might be complete anarchy, others built on peace and justice. There will probably not be a connection between sections like this, which is perfectly fine.
325 |
326 | \section{System Architecture}
327 | \begin{center}
328 | \begin{tabular}{r l}
329 | $A$: & Action\\
330 | $Cy(A)$: & Signed Action\\
331 | $R$: & Response\\
332 | $Cy(R)$: & Signed Response\\
333 |
334 | \end{tabular}
335 | \end{center}
336 |
337 | \begin{small}
338 | \tikzset{myblock/.style = {rectangle, draw, minimum height=1cm, minimum width=3cm}}
339 | \begin{center}
340 | \begin{tikzpicture}
341 | \node(WE)[myblock]{\begin{tabular}{c}Worlds Engine \\ {\scriptsize wClient.py} \\\end{tabular}};
342 | \node (WS)[myblock,above of=WE, yshift=1cm]{\begin{tabular}{c}Worlds Server \\ {\scriptsize wServer.py} \\\end{tabular}};
343 | \node (WC)[myblock,left of=WE, xshift=-3cm]{\begin{tabular}{c}Game Client \\ {\scriptsize \textit{From game Dev}} \\\end{tabular}};
344 | \node (Key)[myblock,below of=WE, yshift=-1cm]{\begin{tabular}{c}Key Pair \\ {\scriptsize private.pem/public.pem} \\\end{tabular}};
345 | \node (AL)[myblock,right of=Key, xshift=3cm]{\begin{tabular}{c}Action Ledger \\ {\scriptsize AL/} \\\end{tabular}};
346 | \node (AList)[myblock,left of=Key, xshift=-3cm]{\begin{tabular}{c}Action Listing \\ {\scriptsize ActionListing.yaml} \\\end{tabular}};
347 | \node (PF)[myblock,below of=AList, yshift=-1cm]{\begin{tabular}{c}Player File \\ {\scriptsize player.yaml} \\\end{tabular}};
348 |
349 | \draw[->] ($(WE.north east)!0.25!(WE.north west)$) -- node[anchor=west]{$Cy(A)$} ($(WS.south east)!0.25!(WS.south west)$);
350 | \draw[<-] ($(WE.north east)!0.75!(WE.north west)$) -- node[anchor=west]{$Cy(R)$} ($(WS.south east)!0.75!(WS.south west)$);
351 | \draw[->] (WC) -- node[anchor=north]{$A$} (WE);
352 | \draw[<-] (WE) -- (Key);
353 | \draw[<->] (AList) -- (WC);
354 | \draw ($(AList.north east)!0.25!(AList.north west)$)edge[out=90,in=-90,->]($(WE.south east)!0.75!(WE.south west)$);
355 | \draw ($(AL.north east)!0.5!(AL.north west)$)edge[out=90,in=-90,<->]($(WE.south east)!0.25!(WE.south west)$);
356 | \draw ($(PF.north)!0.5!(PF.north)$)edge[out=90,in=-90,<-]($(WE.south east)!0.63!(WE.south west)$);
357 | \draw ($(PF.north west)!0.5!(PF.south west)$)edge[out=180,in=-180,->]($(WC.south west)!0.5!(WC.north west)$);
358 |
359 | % more arrows here
360 | \end{tikzpicture}
361 | \end{center}
362 | \end{small}
363 |
364 |
365 | \subsection{Malicious Worlds}
366 |
367 |
--------------------------------------------------------------------------------
/Worlds-Whitepaper/distributed-db/whitepaper.log:
--------------------------------------------------------------------------------
1 | This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Arch Linux) (preloaded format=pdflatex 2020.9.2) 4 OCT 2020 11:42
2 | entering extended mode
3 | restricted \write18 enabled.
4 | %&-line parsing enabled.
5 | **whitepaper.tex
6 | (./whitepaper.tex
7 | LaTeX2e <2020-02-02> patch level 5
8 | L3 programming layer <2020-06-03> (./llncs.cls
9 | Document Class: llncs 2018/03/10 v2.20
10 | LaTeX document class for Lecture Notes in Computer Science
11 | (/usr/share/texmf-dist/tex/latex/base/article.cls
12 | Document Class: article 2019/12/20 v1.4l Standard LaTeX document class
13 | (/usr/share/texmf-dist/tex/latex/base/size10.clo
14 | File: size10.clo 2019/12/20 v1.4l Standard LaTeX file (size option)
15 | )
16 | \c@part=\count167
17 | \c@section=\count168
18 | \c@subsection=\count169
19 | \c@subsubsection=\count170
20 | \c@paragraph=\count171
21 | \c@subparagraph=\count172
22 | \c@figure=\count173
23 | \c@table=\count174
24 | \abovecaptionskip=\skip47
25 | \belowcaptionskip=\skip48
26 | \bibindent=\dimen134
27 | )
28 | (/usr/share/texmf-dist/tex/latex/tools/multicol.sty
29 | Package: multicol 2019/12/09 v1.8y multicolumn formatting (FMi)
30 | \c@tracingmulticols=\count175
31 | \mult@box=\box45
32 | \multicol@leftmargin=\dimen135
33 | \c@unbalance=\count176
34 | \c@collectmore=\count177
35 | \doublecol@number=\count178
36 | \multicoltolerance=\count179
37 | \multicolpretolerance=\count180
38 | \full@width=\dimen136
39 | \page@free=\dimen137
40 | \premulticols=\dimen138
41 | \postmulticols=\dimen139
42 | \multicolsep=\skip49
43 | \multicolbaselineskip=\skip50
44 | \partial@page=\box46
45 | \last@line=\box47
46 | \maxbalancingoverflow=\dimen140
47 | \mult@rightbox=\box48
48 | \mult@grightbox=\box49
49 | \mult@gfirstbox=\box50
50 | \mult@firstbox=\box51
51 | \@tempa=\box52
52 | \@tempa=\box53
53 | \@tempa=\box54
54 | \@tempa=\box55
55 | \@tempa=\box56
56 | \@tempa=\box57
57 | \@tempa=\box58
58 | \@tempa=\box59
59 | \@tempa=\box60
60 | \@tempa=\box61
61 | \@tempa=\box62
62 | \@tempa=\box63
63 | \@tempa=\box64
64 | \@tempa=\box65
65 | \@tempa=\box66
66 | \@tempa=\box67
67 | \@tempa=\box68
68 | \@tempa=\box69
69 | \@tempa=\box70
70 | \@tempa=\box71
71 | \@tempa=\box72
72 | \@tempa=\box73
73 | \@tempa=\box74
74 | \@tempa=\box75
75 | \@tempa=\box76
76 | \@tempa=\box77
77 | \@tempa=\box78
78 | \@tempa=\box79
79 | \@tempa=\box80
80 | \@tempa=\box81
81 | \@tempa=\box82
82 | \@tempa=\box83
83 | \@tempa=\box84
84 | \@tempa=\box85
85 | \@tempa=\box86
86 | \@tempa=\box87
87 | \@tempa=\box88
88 | \c@minrows=\count181
89 | \c@columnbadness=\count182
90 | \c@finalcolumnbadness=\count183
91 | \last@try=\dimen141
92 | \multicolovershoot=\dimen142
93 | \multicolundershoot=\dimen143
94 | \mult@nat@firstbox=\box89
95 | \colbreak@box=\box90
96 | \mc@col@check@num=\count184
97 | )
98 | (/usr/share/texmf-dist/tex/latex/oberdiek/aliascnt.sty
99 | Package: aliascnt 2018/09/07 v1.5 Alias counters (HO)
100 | )
101 | \c@chapter=\count185
102 | LaTeX Font Info: Redeclaring math symbol \Gamma on input line 362.
103 | LaTeX Font Info: Redeclaring math symbol \Delta on input line 363.
104 | LaTeX Font Info: Redeclaring math symbol \Theta on input line 364.
105 | LaTeX Font Info: Redeclaring math symbol \Lambda on input line 365.
106 | LaTeX Font Info: Redeclaring math symbol \Xi on input line 366.
107 | LaTeX Font Info: Redeclaring math symbol \Pi on input line 367.
108 | LaTeX Font Info: Redeclaring math symbol \Sigma on input line 368.
109 | LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 369.
110 | LaTeX Font Info: Redeclaring math symbol \Phi on input line 370.
111 | LaTeX Font Info: Redeclaring math symbol \Psi on input line 371.
112 | LaTeX Font Info: Redeclaring math symbol \Omega on input line 372.
113 | \tocchpnum=\dimen144
114 | \tocsecnum=\dimen145
115 | \tocsectotal=\dimen146
116 | \tocsubsecnum=\dimen147
117 | \tocsubsectotal=\dimen148
118 | \tocsubsubsecnum=\dimen149
119 | \tocsubsubsectotal=\dimen150
120 | \tocparanum=\dimen151
121 | \tocparatotal=\dimen152
122 | \tocsubparanum=\dimen153
123 | \@tempcntc=\count186
124 | \fnindent=\dimen154
125 | \c@@inst=\count187
126 | \c@@auth=\count188
127 | \c@auco=\count189
128 | \instindent=\dimen155
129 | \authrun=\box91
130 | \authorrunning=\toks15
131 | \tocauthor=\toks16
132 | \titrun=\box92
133 | \titlerunning=\toks17
134 | \toctitle=\toks18
135 | \c@theorem=\count190
136 | \c@case=\count191
137 | \c@conjecture=\count192
138 | \c@corollary=\count193
139 | \c@definition=\count194
140 | \c@example=\count195
141 | \c@exercise=\count196
142 | \c@lemma=\count197
143 | \c@note=\count198
144 | \c@problem=\count199
145 | \c@property=\count266
146 | \c@proposition=\count267
147 | \c@question=\count268
148 | \c@solution=\count269
149 | \c@remark=\count270
150 | \headlineindent=\dimen156
151 | )
152 | (/usr/share/texmf-dist/tex/latex/amsfonts/amssymb.sty
153 | Package: amssymb 2013/01/14 v3.01 AMS font symbols
154 |
155 | (/usr/share/texmf-dist/tex/latex/amsfonts/amsfonts.sty
156 | Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
157 | \@emptytoks=\toks19
158 | \symAMSa=\mathgroup4
159 | \symAMSb=\mathgroup5
160 | LaTeX Font Info: Redeclaring math symbol \hbar on input line 98.
161 | LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
162 | (Font) U/euf/m/n --> U/euf/b/n on input line 106.
163 | ))
164 | (/usr/share/texmf-dist/tex/latex/graphics/graphicx.sty
165 | Package: graphicx 2019/11/30 v1.2a Enhanced LaTeX Graphics (DPC,SPQR)
166 |
167 | (/usr/share/texmf-dist/tex/latex/graphics/keyval.sty
168 | Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
169 | \KV@toks@=\toks20
170 | )
171 | (/usr/share/texmf-dist/tex/latex/graphics/graphics.sty
172 | Package: graphics 2019/11/30 v1.4a Standard LaTeX Graphics (DPC,SPQR)
173 |
174 | (/usr/share/texmf-dist/tex/latex/graphics/trig.sty
175 | Package: trig 2016/01/03 v1.10 sin cos tan (DPC)
176 | )
177 | (/usr/share/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
178 | File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
179 | )
180 | Package graphics Info: Driver file: pdftex.def on input line 105.
181 |
182 | (/usr/share/texmf-dist/tex/latex/graphics-def/pdftex.def
183 | File: pdftex.def 2018/01/08 v1.0l Graphics/color driver for pdftex
184 | ))
185 | \Gin@req@height=\dimen157
186 | \Gin@req@width=\dimen158
187 | )
188 | (/usr/share/texmf-dist/tex/latex/pgf/frontendlayer/tikz.sty
189 | (/usr/share/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty
190 | (/usr/share/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty
191 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex
192 | \pgfutil@everybye=\toks21
193 | \pgfutil@tempdima=\dimen159
194 | \pgfutil@tempdimb=\dimen160
195 |
196 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex))
197 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def
198 | \pgfutil@abb=\box93
199 |
200 | (/usr/share/texmf-dist/tex/latex/ms/everyshi.sty
201 | Package: everyshi 2001/05/15 v3.00 EveryShipout Package (MS)
202 | ))
203 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex
204 | (/usr/share/texmf-dist/tex/generic/pgf/pgf.revision.tex)
205 | Package: pgfrcs 2020/01/08 v3.1.5b (3.1.5b)
206 | ))
207 | Package: pgf 2020/01/08 v3.1.5b (3.1.5b)
208 |
209 | (/usr/share/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty
210 | (/usr/share/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty
211 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
212 | Package: pgfsys 2020/01/08 v3.1.5b (3.1.5b)
213 |
214 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
215 | \pgfkeys@pathtoks=\toks22
216 | \pgfkeys@temptoks=\toks23
217 |
218 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
219 | \pgfkeys@tmptoks=\toks24
220 | ))
221 | \pgf@x=\dimen161
222 | \pgf@y=\dimen162
223 | \pgf@xa=\dimen163
224 | \pgf@ya=\dimen164
225 | \pgf@xb=\dimen165
226 | \pgf@yb=\dimen166
227 | \pgf@xc=\dimen167
228 | \pgf@yc=\dimen168
229 | \pgf@xd=\dimen169
230 | \pgf@yd=\dimen170
231 | \w@pgf@writea=\write3
232 | \r@pgf@reada=\read2
233 | \c@pgf@counta=\count271
234 | \c@pgf@countb=\count272
235 | \c@pgf@countc=\count273
236 | \c@pgf@countd=\count274
237 | \t@pgf@toka=\toks25
238 | \t@pgf@tokb=\toks26
239 | \t@pgf@tokc=\toks27
240 | \pgf@sys@id@count=\count275
241 |
242 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg
243 | File: pgf.cfg 2020/01/08 v3.1.5b (3.1.5b)
244 | )
245 | Driver file for pgf: pgfsys-pdftex.def
246 |
247 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def
248 | File: pgfsys-pdftex.def 2020/01/08 v3.1.5b (3.1.5b)
249 |
250 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def
251 | File: pgfsys-common-pdf.def 2020/01/08 v3.1.5b (3.1.5b)
252 | )))
253 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex
254 | File: pgfsyssoftpath.code.tex 2020/01/08 v3.1.5b (3.1.5b)
255 | \pgfsyssoftpath@smallbuffer@items=\count276
256 | \pgfsyssoftpath@bigbuffer@items=\count277
257 | )
258 | (/usr/share/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex
259 | File: pgfsysprotocol.code.tex 2020/01/08 v3.1.5b (3.1.5b)
260 | ))
261 | (/usr/share/texmf-dist/tex/latex/xcolor/xcolor.sty
262 | Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK)
263 |
264 | (/usr/share/texmf-dist/tex/latex/graphics-cfg/color.cfg
265 | File: color.cfg 2016/01/02 v1.6 sample color configuration
266 | )
267 | Package xcolor Info: Driver file: pdftex.def on input line 225.
268 | Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348.
269 | Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1352.
270 | Package xcolor Info: Model `RGB' extended on input line 1364.
271 | Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366.
272 | Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367.
273 | Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368.
274 | Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369.
275 | Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370.
276 | Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371.
277 | )
278 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
279 | Package: pgfcore 2020/01/08 v3.1.5b (3.1.5b)
280 |
281 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex
282 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex
283 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex)
284 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
285 | \pgfmath@dimen=\dimen171
286 | \pgfmath@count=\count278
287 | \pgfmath@box=\box94
288 | \pgfmath@toks=\toks28
289 | \pgfmath@stack@operand=\toks29
290 | \pgfmath@stack@operation=\toks30
291 | )
292 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex
293 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex)
294 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code
295 | .tex)
296 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.random.code.tex)
297 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.comparison.code.te
298 | x) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex)
299 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round.code.tex)
300 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex)
301 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics
302 | .code.tex))) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
303 | \c@pgfmathroundto@lastzeros=\count279
304 | )) (/usr/share/texmf-dist/tex/generic/pgf/math/pgfint.code.tex)
305 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex
306 | File: pgfcorepoints.code.tex 2020/01/08 v3.1.5b (3.1.5b)
307 | \pgf@picminx=\dimen172
308 | \pgf@picmaxx=\dimen173
309 | \pgf@picminy=\dimen174
310 | \pgf@picmaxy=\dimen175
311 | \pgf@pathminx=\dimen176
312 | \pgf@pathmaxx=\dimen177
313 | \pgf@pathminy=\dimen178
314 | \pgf@pathmaxy=\dimen179
315 | \pgf@xx=\dimen180
316 | \pgf@xy=\dimen181
317 | \pgf@yx=\dimen182
318 | \pgf@yy=\dimen183
319 | \pgf@zx=\dimen184
320 | \pgf@zy=\dimen185
321 | )
322 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
323 | File: pgfcorepathconstruct.code.tex 2020/01/08 v3.1.5b (3.1.5b)
324 | \pgf@path@lastx=\dimen186
325 | \pgf@path@lasty=\dimen187
326 | ) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex
327 | File: pgfcorepathusage.code.tex 2020/01/08 v3.1.5b (3.1.5b)
328 | \pgf@shorten@end@additional=\dimen188
329 | \pgf@shorten@start@additional=\dimen189
330 | )
331 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex
332 | File: pgfcorescopes.code.tex 2020/01/08 v3.1.5b (3.1.5b)
333 | \pgfpic=\box95
334 | \pgf@hbox=\box96
335 | \pgf@layerbox@main=\box97
336 | \pgf@picture@serial@count=\count280
337 | )
338 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex
339 | File: pgfcoregraphicstate.code.tex 2020/01/08 v3.1.5b (3.1.5b)
340 | \pgflinewidth=\dimen190
341 | )
342 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.t
343 | ex
344 | File: pgfcoretransformations.code.tex 2020/01/08 v3.1.5b (3.1.5b)
345 | \pgf@pt@x=\dimen191
346 | \pgf@pt@y=\dimen192
347 | \pgf@pt@temp=\dimen193
348 | ) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.code.tex
349 | File: pgfcorequick.code.tex 2020/01/08 v3.1.5b (3.1.5b)
350 | )
351 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex
352 | File: pgfcoreobjects.code.tex 2020/01/08 v3.1.5b (3.1.5b)
353 | )
354 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.te
355 | x
356 | File: pgfcorepathprocessing.code.tex 2020/01/08 v3.1.5b (3.1.5b)
357 | ) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex
358 | File: pgfcorearrows.code.tex 2020/01/08 v3.1.5b (3.1.5b)
359 | \pgfarrowsep=\dimen194
360 | )
361 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex
362 | File: pgfcoreshade.code.tex 2020/01/08 v3.1.5b (3.1.5b)
363 | \pgf@max=\dimen195
364 | \pgf@sys@shading@range@num=\count281
365 | \pgf@shadingcount=\count282
366 | )
367 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex
368 | File: pgfcoreimage.code.tex 2020/01/08 v3.1.5b (3.1.5b)
369 |
370 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex
371 | File: pgfcoreexternal.code.tex 2020/01/08 v3.1.5b (3.1.5b)
372 | \pgfexternal@startupbox=\box98
373 | ))
374 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex
375 | File: pgfcorelayers.code.tex 2020/01/08 v3.1.5b (3.1.5b)
376 | )
377 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex
378 | File: pgfcoretransparency.code.tex 2020/01/08 v3.1.5b (3.1.5b)
379 | ) (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex
380 | File: pgfcorepatterns.code.tex 2020/01/08 v3.1.5b (3.1.5b)
381 | )
382 | (/usr/share/texmf-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.tex
383 | File: pgfcorerdf.code.tex 2020/01/08 v3.1.5b (3.1.5b)
384 | )))
385 | (/usr/share/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex
386 | File: pgfmoduleshapes.code.tex 2020/01/08 v3.1.5b (3.1.5b)
387 | \pgfnodeparttextbox=\box99
388 | )
389 | (/usr/share/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex
390 | File: pgfmoduleplot.code.tex 2020/01/08 v3.1.5b (3.1.5b)
391 | )
392 | (/usr/share/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty
393 | Package: pgfcomp-version-0-65 2020/01/08 v3.1.5b (3.1.5b)
394 | \pgf@nodesepstart=\dimen196
395 | \pgf@nodesepend=\dimen197
396 | )
397 | (/usr/share/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty
398 | Package: pgfcomp-version-1-18 2020/01/08 v3.1.5b (3.1.5b)
399 | ))
400 | (/usr/share/texmf-dist/tex/latex/pgf/utilities/pgffor.sty
401 | (/usr/share/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
402 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex))
403 | (/usr/share/texmf-dist/tex/latex/pgf/math/pgfmath.sty
404 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex))
405 | (/usr/share/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex
406 | Package: pgffor 2020/01/08 v3.1.5b (3.1.5b)
407 |
408 | (/usr/share/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex)
409 | \pgffor@iter=\dimen198
410 | \pgffor@skip=\dimen199
411 | \pgffor@stack=\toks31
412 | \pgffor@toks=\toks32
413 | ))
414 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex
415 | Package: tikz 2020/01/08 v3.1.5b (3.1.5b)
416 |
417 | (/usr/share/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.te
418 | x
419 | File: pgflibraryplothandlers.code.tex 2020/01/08 v3.1.5b (3.1.5b)
420 | \pgf@plot@mark@count=\count283
421 | \pgfplotmarksize=\dimen256
422 | )
423 | \tikz@lastx=\dimen257
424 | \tikz@lasty=\dimen258
425 | \tikz@lastxsaved=\dimen259
426 | \tikz@lastysaved=\dimen260
427 | \tikz@lastmovetox=\dimen261
428 | \tikz@lastmovetoy=\dimen262
429 | \tikzleveldistance=\dimen263
430 | \tikzsiblingdistance=\dimen264
431 | \tikz@figbox=\box100
432 | \tikz@figbox@bg=\box101
433 | \tikz@tempbox=\box102
434 | \tikz@tempbox@bg=\box103
435 | \tikztreelevel=\count284
436 | \tikznumberofchildren=\count285
437 | \tikznumberofcurrentchild=\count286
438 | \tikz@fig@count=\count287
439 | (/usr/share/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex
440 | File: pgfmodulematrix.code.tex 2020/01/08 v3.1.5b (3.1.5b)
441 | \pgfmatrixcurrentrow=\count288
442 | \pgfmatrixcurrentcolumn=\count289
443 | \pgf@matrix@numberofcolumns=\count290
444 | )
445 | \tikz@expandcount=\count291
446 |
447 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
448 | topaths.code.tex
449 | File: tikzlibrarytopaths.code.tex 2020/01/08 v3.1.5b (3.1.5b)
450 | ))) (/usr/share/texmf-dist/tex/latex/base/fontenc.sty
451 | Package: fontenc 2020/02/11 v2.0o Standard LaTeX package
452 | )
453 | (/usr/share/texmf-dist/tex/latex/bera/beramono.sty
454 | Package: beramono 2004/01/31 (WaS)
455 | )
456 | (/usr/share/texmf-dist/tex/latex/listings/listings.sty
457 | \lst@mode=\count292
458 | \lst@gtempboxa=\box104
459 | \lst@token=\toks33
460 | \lst@length=\count293
461 | \lst@currlwidth=\dimen265
462 | \lst@column=\count294
463 | \lst@pos=\count295
464 | \lst@lostspace=\dimen266
465 | \lst@width=\dimen267
466 | \lst@newlines=\count296
467 | \lst@lineno=\count297
468 | \lst@maxwidth=\dimen268
469 |
470 | (/usr/share/texmf-dist/tex/latex/listings/lstmisc.sty
471 | File: lstmisc.sty 2020/03/24 1.8d (Carsten Heinz)
472 | \c@lstnumber=\count298
473 | \lst@skipnumbers=\count299
474 | \lst@framebox=\box105
475 | )
476 | (/usr/share/texmf-dist/tex/latex/listings/listings.cfg
477 | File: listings.cfg 2020/03/24 1.8d listings configuration
478 | ))
479 | Package: listings 2020/03/24 1.8d (Carsten Heinz)
480 |
481 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
482 | arrows.code.tex
483 | File: tikzlibraryarrows.code.tex 2020/01/08 v3.1.5b (3.1.5b)
484 |
485 | (/usr/share/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex
486 | File: pgflibraryarrows.code.tex 2020/01/08 v3.1.5b (3.1.5b)
487 | \arrowsize=\dimen269
488 | ))
489 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
490 | chains.code.tex
491 | File: tikzlibrarychains.code.tex 2020/01/08 v3.1.5b (3.1.5b)
492 |
493 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
494 | positioning.code.tex
495 | File: tikzlibrarypositioning.code.tex 2020/01/08 v3.1.5b (3.1.5b)
496 | ))
497 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
498 | scopes.code.tex
499 | File: tikzlibraryscopes.code.tex 2020/01/08 v3.1.5b (3.1.5b)
500 | )
501 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
502 | quotes.code.tex
503 | File: tikzlibraryquotes.code.tex 2020/01/08 v3.1.5b (3.1.5b)
504 | )
505 | (/usr/share/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary
506 | calc.code.tex
507 | File: tikzlibrarycalc.code.tex 2020/01/08 v3.1.5b (3.1.5b)
508 | ) (/usr/share/texmf-dist/tex/latex/float/float.sty
509 | Package: float 2001/11/08 v1.3d Float enhancements (AL)
510 | \c@float@type=\count300
511 | \float@exts=\toks34
512 | \float@box=\box106
513 | \@float@everytoks=\toks35
514 | \@floatcapt=\box107
515 | )
516 | (/usr/share/texmf-dist/tex/latex/geometry/geometry.sty
517 | Package: geometry 2020/01/02 v5.9 Page Geometry
518 |
519 | (/usr/share/texmf-dist/tex/generic/iftex/ifvtex.sty
520 | Package: ifvtex 2019/10/25 v1.7 ifvtex legacy package. Use iftex instead.
521 |
522 | (/usr/share/texmf-dist/tex/generic/iftex/iftex.sty
523 | Package: iftex 2020/03/06 v1.0d TeX engine tests
524 | ))
525 | \Gm@cnth=\count301
526 | \Gm@cntv=\count302
527 | \c@Gm@tempcnt=\count303
528 | \Gm@bindingoffset=\dimen270
529 | \Gm@wd@mp=\dimen271
530 | \Gm@odd@mp=\dimen272
531 | \Gm@even@mp=\dimen273
532 | \Gm@layoutwidth=\dimen274
533 | \Gm@layoutheight=\dimen275
534 | \Gm@layouthoffset=\dimen276
535 | \Gm@layoutvoffset=\dimen277
536 | \Gm@dimlist=\toks36
537 | )
538 | (/usr/share/texmf-dist/tex/latex/listings/lstlang1.sty
539 | File: lstlang1.sty 2020/03/24 1.8d listings language file
540 | )
541 | (/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdfmode.def
542 | File: l3backend-pdfmode.def 2020-06-03 L3 backend support: PDF mode
543 | \l__kernel_color_stack_int=\count304
544 | \l__pdf_internal_box=\box108
545 | )
546 | (./whitepaper.aux)
547 | LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 45.
548 | LaTeX Font Info: ... okay on input line 45.
549 | LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 45.
550 | LaTeX Font Info: ... okay on input line 45.
551 | LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 45.
552 | LaTeX Font Info: ... okay on input line 45.
553 | LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 45.
554 | LaTeX Font Info: ... okay on input line 45.
555 | LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 45.
556 | LaTeX Font Info: ... okay on input line 45.
557 | LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 45.
558 | LaTeX Font Info: ... okay on input line 45.
559 | LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 45.
560 | LaTeX Font Info: ... okay on input line 45.
561 | (/usr/share/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
562 | [Loading MPS to PDF converter (version 2006.09.02).]
563 | \scratchcounter=\count305
564 | \scratchdimen=\dimen278
565 | \scratchbox=\box109
566 | \nofMPsegments=\count306
567 | \nofMParguments=\count307
568 | \everyMPshowfont=\toks37
569 | \MPscratchCnt=\count308
570 | \MPscratchDim=\dimen279
571 | \MPnumerator=\count309
572 | \makeMPintoPDFobject=\count310
573 | \everyMPtoPDFconversion=\toks38
574 | ) (/usr/share/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
575 | Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
576 | Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
577 | 85.
578 |
579 | (/usr/share/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
580 | File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
581 | e
582 | ))
583 | ABD: EveryShipout initializing macros
584 | \c@lstlisting=\count311
585 |
586 | *geometry* driver: auto-detecting
587 | *geometry* detected driver: pdftex
588 | *geometry* verbose mode - [ preamble ] result:
589 | * driver: pdftex
590 | * paper: a4paper
591 | * layout:
592 | * layoutoffset:(h,v)=(0.0pt,0.0pt)
593 | * modes: twoside
594 | * h-part:(L,W,R)=(65.55515pt, 433.62pt, 98.33273pt)
595 | * v-part:(T,H,B)=(48.93872pt, 722.7pt, 73.40813pt)
596 | * \paperwidth=597.50787pt
597 | * \paperheight=845.04684pt
598 | * \textwidth=433.62pt
599 | * \textheight=722.7pt
600 | * \oddsidemargin=-6.71484pt
601 | * \evensidemargin=26.06274pt
602 | * \topmargin=-51.33127pt
603 | * \headheight=12.0pt
604 | * \headsep=16.0pt
605 | * \topskip=10.0pt
606 | * \footskip=30.0pt
607 | * \marginparwidth=90.0pt
608 | * \marginparsep=11.0pt
609 | * \columnsep=10.0pt
610 | * \skip\footins=9.0pt plus 4.0pt minus 2.0pt
611 | * \hoffset=0.0pt
612 | * \voffset=0.0pt
613 | * \mag=1000
614 | * \@twocolumnfalse
615 | * \@twosidetrue
616 | * \@mparswitchtrue
617 | * \@reversemarginfalse
618 | * (1in=72.27pt=25.4mm, 1cm=28.453pt)
619 |
620 | LaTeX Font Info: Trying to load font information for U+msa on input line 57.
621 |
622 | (/usr/share/texmf-dist/tex/latex/amsfonts/umsa.fd
623 | File: umsa.fd 2013/01/14 v3.01 AMS symbols A
624 | )
625 | LaTeX Font Info: Trying to load font information for U+msb on input line 57.
626 |
627 |
628 | (/usr/share/texmf-dist/tex/latex/amsfonts/umsb.fd
629 | File: umsb.fd 2013/01/14 v3.01 AMS symbols B
630 | )
631 | Underfull \hbox (badness 10000) in paragraph at lines 67--74
632 |
633 | []
634 |
635 |
636 | Underfull \hbox (badness 10000) in paragraph at lines 75--82
637 |
638 | []
639 |
640 |
641 | Underfull \hbox (badness 10000) in paragraph at lines 84--88
642 |
643 | []
644 |
645 |
646 | Underfull \hbox (badness 10000) in paragraph at lines 94--99
647 |
648 | []
649 |
650 |
651 | Underfull \hbox (badness 10000) in paragraph at lines 100--105
652 |
653 | []
654 |
655 | [1
656 |
657 |
658 | {/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}]
659 |
660 | File: img/traditional.pdf Graphic file (type pdf)
661 |