Merge pull request #47 from jl777/jl777

Jl777
This commit is contained in:
blackjok3rtt
2019-03-29 13:27:56 +08:00
committed by GitHub
27 changed files with 3603 additions and 27 deletions

View File

@@ -59,13 +59,16 @@ static bool fDaemon;
#include "komodo_defs.h"
#define KOMODO_ASSETCHAIN_MAXLEN 65
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint32_t ASSETCHAINS_BLOCKTIME;
extern uint64_t ASSETCHAINS_CBOPRET;
void komodo_passport_iteration();
uint64_t komodo_interestsum();
int32_t komodo_longestchain();
void komodo_cbopretupdate();
void WaitForShutdown(boost::thread_group* threadGroup)
{
bool fShutdown = ShutdownRequested();
int32_t i; bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown.
while (!fShutdown)
{
@@ -73,13 +76,27 @@ void WaitForShutdown(boost::thread_group* threadGroup)
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
komodo_passport_iteration();
MilliSleep(10000);
for (i=0; i<10; i++)
{
fShutdown = ShutdownRequested();
if ( fShutdown != 0 )
break;
MilliSleep(1000);
}
}
else
{
//komodo_interestsum();
//komodo_longestchain();
MilliSleep(20000);
if ( ASSETCHAINS_CBOPRET != 0 )
komodo_cbopretupdate();
for (i=0; i<ASSETCHAINS_BLOCKTIME/2; i++)
{
fShutdown = ShutdownRequested();
if ( fShutdown != 0 )
break;
MilliSleep(1000);
}
}
fShutdown = ShutdownRequested();
}

View File

@@ -20,37 +20,104 @@ std::string MYCCLIBNAME = (char *)"prices";
UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag);
extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33];
// generate bars
#define bstr(x) ((double)((uint32_t)x) / 10000.)
struct prices_bar
{
uint64_t open,high,low,close,sum;
int32_t num;
};
int32_t prices_barupdate(struct prices_bar *bar,uint64_t pricebits)
{
uint32_t uprice,timestamp;
timestamp = (uint32_t)(pricebits >> 32);
uprice = (uint32_t)pricebits;
bar->sum += uprice, bar->num++;
if ( bar->open == 0 )
bar->open = bar->high = bar->low = pricebits;
if ( uprice > (uint32_t)bar->high )
bar->high = pricebits;
else if ( uprice < (uint32_t)bar->low )
bar->low = pricebits;
bar->close = pricebits;
return(0);
}
int64_t prices_bardist(struct prices_bar *bar,uint32_t aveprice,uint64_t pricebits)
{
int64_t a,dist = 0;
if ( aveprice != 0 )
{
a = (pricebits & 0xffffffff);
dist = (a - aveprice);
dist *= dist;
//fprintf(stderr,"dist.%lld (u %u - ave %u) %d\n",(long long)dist,uprice,aveprice,uprice-aveprice);
}
return(dist);
}
void prices_bardisp(struct prices_bar *bar)
{
if ( bar->num == 0 )
fprintf(stderr,"BAR null\n");
else fprintf(stderr,"BAR ave %.4f (O %.4f, H %.4f, L %.4f, C %.4f)\n",bstr(bar->sum/bar->num),bstr(bar->open),bstr(bar->high),bstr(bar->low),bstr(bar->close));
}
int64_t prices_blockinfo(int32_t height,char *acaddr)
{
std::vector<uint8_t> vopret; CBlockIndex *pindex; CBlock block; CTransaction tx,vintx; uint64_t pricebits; char destaddr[64]; uint32_t timestamp,uprice; uint256 hashBlock; int64_t prizefund = 0; int32_t i,n,vini,numvouts;
std::vector<uint8_t> vopret; CBlockIndex *pindex; CBlock block; CTransaction tx,vintx; uint64_t pricebits; char destaddr[64]; uint32_t aveprice=0,timestamp,uprice; uint256 hashBlock; int64_t dist,mindist=(1LL<<60),prizefund = 0; int32_t mini=-1,i,n,vini,numvouts,iter; struct prices_bar refbar;
if ( (pindex= komodo_chainactive(height)) != 0 )
{
if ( komodo_blockload(block,pindex) == 0 )
{
n = block.vtx.size();
vini = 0;
for (i=0; i<n; i++)
memset(&refbar,0,sizeof(refbar));
for (iter=0; iter<2; iter++)
{
tx = block.vtx[i];
if ( myGetTransaction(tx.vin[vini].prevout.hash,vintx,hashBlock) == 0 )
continue;
else if ( tx.vin[vini].prevout.n >= vintx.vout.size() || Getscriptaddress(destaddr,vintx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 )
continue;
else if ( (numvouts= tx.vout.size()) > 1 && tx.vout[numvouts-1].scriptPubKey[0] == 0x6a )
for (i=0; i<n; i++)
{
prizefund += tx.vout[0].nValue;
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
if ( vopret.size() == 8 )
tx = block.vtx[i];
if ( myGetTransaction(tx.vin[vini].prevout.hash,vintx,hashBlock) == 0 )
continue;
else if ( tx.vin[vini].prevout.n >= vintx.vout.size() || Getscriptaddress(destaddr,vintx.vout[tx.vin[vini].prevout.n].scriptPubKey) == 0 )
continue;
else if ( (numvouts= tx.vout.size()) > 1 && tx.vout[numvouts-1].scriptPubKey[0] == 0x6a )
{
E_UNMARSHAL(vopret,ss >> pricebits);
timestamp = (uint32_t)(pricebits >> 32);
uprice = (uint32_t)pricebits;
if ( strcmp(acaddr,destaddr) == 0 )
fprintf(stderr,"REF ");
fprintf(stderr,"[%02x] i.%d %.8f %llx t%u %.4f numvouts.%d %s lag.%d\n",tx.vout[numvouts-1].scriptPubKey[0],i,(double)tx.vout[0].nValue/COIN,(long long)pricebits,timestamp,(double)uprice/10000,numvouts,destaddr,(int32_t)(pindex->nTime-timestamp));
} else return(-3);
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
if ( vopret.size() == 8 )
{
E_UNMARSHAL(vopret,ss >> pricebits);
timestamp = (uint32_t)(pricebits >> 32);
uprice = (uint32_t)pricebits;
if ( iter == 0 )
{
prizefund += tx.vout[0].nValue;
if ( strcmp(acaddr,destaddr) == 0 )
{
//fprintf(stderr,"REF ");
prices_barupdate(&refbar,pricebits);
}
}
else if ( strcmp(acaddr,destaddr) != 0 )
{
dist = prices_bardist(&refbar,aveprice,pricebits);
if ( dist < mindist )
{
mindist = dist;
mini = i;
}
fprintf(stderr,"mini.%d i.%d %.8f t%u %.4f v.%d %s lag.%d i.%d dist.%lld\n",mini,i,(double)tx.vout[0].nValue/COIN,timestamp,(double)uprice/10000,numvouts,destaddr,(int32_t)(pindex->nTime-timestamp),iter,(long long)dist);
}
} else return(-3);
}
}
if ( iter == 0 )
{
prices_bardisp(&refbar);
if ( refbar.num != 0 )
aveprice = (uint32_t)refbar.sum / refbar.num;
}
}
return(prizefund);

View File

@@ -0,0 +1,27 @@
About
-----
Komodo SudokuCC GUI
Just solve Sudoku and earn SUDOKU coins!
![alt text](https://i.imgur.com/std99XW.png)
To run you need up and running SUDOKU chain daemon built from latest https://github.com/jl777/komodo/tree/FSM and started with valid for your wallet pubkey in `-pubkey=` param.
SUDOKU chain params:
```./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey=<yourpubkey> -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc &```
1) install dependencies:
```
$ sudo apt-get install python-pygame libgnutls28-dev
$ pip install requests wheel slick-bitcoinrpc pygame
```
2) and then start:
```
$ git clone https://github.com/tonymorony/Komodoku
$ cd Komodoku
$ python Sudoku.py
```

BIN
src/gui/komodoku/Roboto-Light.ttf Executable file

Binary file not shown.

362
src/gui/komodoku/Sudoku.py Normal file
View File

@@ -0,0 +1,362 @@
#!/usr/bin/env python
# Copyright (C) 2010 Paul Bourke <pauldbourke@gmail.com>
# Copyright (C) 2019 Anton Lysakov <tlysakov@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pygame
import sys
import random
import sudoku_kmdlib
import time
class PyGameBoard():
"""Represents the game's frontend using pygame"""
def __init__(self, engine, windowSize, gridValues, timestampValues):
pygame.init()
pygame.display.set_caption('Sudoku')
self.__engine = engine
self.__gridValues = gridValues
self.__timestampValues = timestampValues
self.__screen = pygame.display.set_mode(windowSize)
background = pygame.image.load(sys.path[0] + '/background.png').convert()
board = pygame.image.load(sys.path[0] + '/board.png')
boardX = boardY = 10
self.__screen.blit(background, (0, 0))
self.__screen.blit(board, (boardX, boardY))
self.__tiles = self.__createTiles(boardX, boardY)
self.__drawUI()
self.__draw()
def __draw(self):
"""Handles events and updates display buffer"""
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
self.__handleMouse(event.pos)
elif (event.type == pygame.KEYUP):
self.__handleKeyboard(event.key)
pygame.display.flip()
def __drawUI(self):
'''Draws the text buttons along the right panel'''
font = pygame.font.Font(sys.path[0] + '/Roboto-Light.ttf', 28)
font.set_underline(True)
self.__titleText = font.render('Sudoku', 1, (0, 0, 0))
self.__titleTextRect = self.__titleText.get_rect()
self.__titleTextRect.centerx = 445
self.__titleTextRect.centery = 30
self.__screen.blit(self.__titleText, self.__titleTextRect)
font = pygame.font.Font(sys.path[0] + '/Roboto-Light.ttf', 14)
self.__titleText = font.render('TonyL 2019', 1, (0, 0, 0))
self.__titleTextRect = self.__titleText.get_rect()
self.__titleTextRect.centerx = 445
self.__titleTextRect.centery = 55
self.__screen.blit(self.__titleText, self.__titleTextRect)
font = pygame.font.Font(sys.path[0] + '/Roboto-Light.ttf', 24)
self.__newGameText = font.render('-New Game-', 1, (0, 0, 0))
self.__newGameTextRect = self.__newGameText.get_rect()
self.__newGameTextRect.centerx = 495
self.__newGameTextRect.centery = 180
self.__screen.blit(self.__newGameText, self.__newGameTextRect)
self.__solveText = font.render('-Check Balance-', 1, (0, 0, 0))
self.__solveTextRect = self.__solveText.get_rect()
self.__solveTextRect.centerx = 495
self.__solveTextRect.centery = 220
self.__screen.blit(self.__solveText, self.__solveTextRect)
font = pygame.font.Font(sys.path[0] + '/Roboto-Light.ttf', 24)
self.__checkText = font.render('-Check Solution-', 1, (0, 0, 0))
self.__checkTextRect = self.__checkText.get_rect()
self.__checkTextRect.centerx = 495
self.__checkTextRect.centery = 260
self.__screen.blit(self.__checkText, self.__checkTextRect)
def __handleKeyboard(self, key):
"""Get key pressed and update the game board"""
validKeys = {pygame.K_0: "0", pygame.K_1: "1", pygame.K_2: "2",
pygame.K_3: "3", pygame.K_4: "4", pygame.K_5: "5",
pygame.K_6: "6", pygame.K_7: "7", pygame.K_8: "8",
pygame.K_9: "9", pygame.K_BACKSPACE: "", pygame.K_DELETE: ""}
if key == pygame.K_ESCAPE:
sys.exit()
elif key in validKeys:
i = self.__currentTile.getGridLoc()[0]
j = self.__currentTile.getGridLoc()[1]
cell_num = 9 * i + (j + 1)
self.__currentTile.setFontColor(pygame.color.THECOLORS['blue'])
self.__currentTile.updateValue(validKeys[key])
self.__gridValues[i][j] = self.__currentTile.getValue()
self.__timestampValues[cell_num] = int(round(time.time()))
def __handleMouse(self, (x, y)):
for row in self.__tiles:
for tile in row:
if tile.getRect().collidepoint(x, y):
if not tile.isReadOnly():
tile.highlight(pygame.color.THECOLORS['lightyellow'])
if self.__currentTile.isCorrect():
self.__currentTile.unhighlight()
else:
self.__currentTile.highlight((255, 164, 164))
self.__currentTile = tile
if self.__newGameTextRect.collidepoint(x, y):
self.__engine.startNewGame()
elif self.__solveTextRect.collidepoint(x, y):
self.__engine.getSolution()
elif self.__checkTextRect.collidepoint(x, y):
ret = self.__engine.checkSolution(self.__gridValues, self.__timestampValues)
def __updateBoard(self, gridValues):
for i in range(9):
for j in range(9):
self.__tiles[i][j].updateValue(gridValues[i][j])
def __unhightlightBoard(self):
for i in range(9):
for j in range(9):
self.__tiles[i][j].unhighlight()
def __createTiles(self, initX=0, initY=0):
"""Set up a list of tiles corresponding to the grid, along with
each ones location coordinates on the board"""
square_size = 40
tiles = list()
x = y = 0
for i in range(0, 9):
row = list()
for j in range(0, 9):
if j in (0, 1, 2):
x = (j * 41) + (initX + 2)
if j in (3, 4, 5):
x = (j * 41) + (initX + 6)
if j in (6, 7, 8):
x = (j * 41) + (initX + 10)
if i in (0, 1, 2):
y = (i * 41) + (initY + 2)
if i in (3, 4, 5):
y = (i * 41) + (initY + 6)
if i in (6, 7, 8):
y = (i * 41) + (initY + 10)
tile = Tile(self.__gridValues[i][j], (x, y), (i, j), square_size)
row.append(tile)
tiles.append(row)
self.__currentTile = tiles[0][0]
return tiles
class Tile():
"""Represents a graphical tile on the board"""
def __init__(self, value, coords, gridLoc, size):
xpos = coords[0]
ypos = coords[1]
self.__fontColor = pygame.color.THECOLORS["black"]
self.__readOnly = False
self.__colorSquare = pygame.Surface((size, size)).convert()
self.__colorSquare.fill(pygame.color.THECOLORS['white'], None, pygame.BLEND_RGB_ADD)
self.__colorSquareRect = self.__colorSquare.get_rect()
self.__colorSquareRect = self.__colorSquareRect.move(xpos + 1, ypos + 1)
self.__value = value
self.__gridLoc = gridLoc
self.__screen = pygame.display.get_surface()
self.__rect = pygame.Rect(xpos, ypos, size, size)
self.__isCorrect = True
if self.__value is not '-':
self.__readOnly = True
self.__draw()
def updateValue(self, value):
self.__value = value
self.__draw()
def isCorrect(self):
return self.__isCorrect
def setCorrect(self, isCorrect):
self.__isCorrect = isCorrect
def setFontColor(self, fontColor):
self.__fontColor = fontColor
def getValue(self):
return self.__value
def getRect(self):
return self.__rect
def getGridLoc(self):
return self.__gridLoc
def isReadOnly(self):
return self.__readOnly
def highlight(self, color):
if self.__readOnly is True:
return
self.__colorSquare.fill(color)
self.__draw()
def unhighlight(self):
self.__colorSquare.fill((255, 225, 255), None, pygame.BLEND_RGB_ADD)
self.__draw()
def __draw(self):
value = self.__value
if self.__value == '-':
value = ''
font = pygame.font.Font(sys.path[0] + '/Roboto-Light.ttf', 24)
text = font.render(str(value), 1, self.__fontColor)
textpos = text.get_rect()
textpos.centerx = self.__rect.centerx
textpos.centery = self.__rect.centery
self.__screen.blit(self.__colorSquare, self.__colorSquareRect)
self.__screen.blit(text, textpos)
class Sudoku:
"""Represents the game's backend and logic"""
def __init__(self, puzzleFile, rpc_connection):
self.__puzzleFile = puzzleFile
self.__rpc_connection = rpc_connection
self.startNewGame()
def startNewGame(self):
self.__linePuzzle = self.__loadPuzzle(self.__puzzleFile)
gridValues = self.lineToGrid(self.__linePuzzle)
# prefill 0 timestamps for already known numbers
timestampValues = self.prefill_timestamps(gridValues)
board = PyGameBoard(self, (600, 400), gridValues, timestampValues)
board.setValues(gridValues)
def __loadPuzzle(self, listName):
self.__chosen_puzzle = random.choice(listName)
puzzle = self.__rpc_connection.cclib("txidinfo", "17", '"%22' + self.__chosen_puzzle + '%22"')["unsolved"]
print "Puzzle ID: " + self.__chosen_puzzle
print "Reward amount: " + str(self.__rpc_connection.cclib("txidinfo", "17", '"%22' + self.__chosen_puzzle + '%22"')["amount"])
ret = []
linePuzzle = str(puzzle)
for i in linePuzzle:
ret.append(i)
return ret
def gridToLine(self, grid):
linePuzzle = ''
for i in range(9):
for j in range(9):
linePuzzle += grid[i][j]
return linePuzzle
def lineToGrid(self, linePuzzle):
assert (len(linePuzzle) == 81)
grid = []
for i in xrange(0, 81, 9):
grid.append(linePuzzle[i:i + 9])
return grid
def getSolution(self):
balance = self.__rpc_connection.cclibaddress("17")["mybalance"]
print "Your balance: " + str(balance)
def __solve(self, linePuzzle):
linePuzzle = ''.join(linePuzzle)
i = linePuzzle.find('-')
if i == -1:
return linePuzzle
excluded_numbers = set()
for j in range(81):
if self.sameRow(i, j) or self.sameCol(i, j) or self.sameBlock(i, j):
excluded_numbers.add(linePuzzle[j])
for m in '123456789':
if m not in excluded_numbers:
funcRet = self.__solve(linePuzzle[:i] + m + linePuzzle[i + 1:])
if funcRet is not None:
return funcRet
def prefill_timestamps(self, grid):
timestamps = {}
for i in range(9):
for j in range(9):
if grid[i][j] != '-':
cell_num = 9 * i + ( j + 1 )
timestamps[cell_num] = 0
return timestamps
def sameRow(self, i, j):
return (i / 9 == j / 9)
def sameCol(self, i, j):
return (i - j) % 9 == 0
def sameBlock(self, i, j):
return (i / 27 == j / 27 and i % 9 / 3 == j % 9 / 3)
def checkSolution(self, attemptGrid, timestampValues):
# [%22<txid>%22,%22<solution>%22,t0,t1,t2,...]
attemptLine = self.gridToLine(attemptGrid)
#print attemptLine
#print timestampValues
timestampsline = ""
for timestamp in timestampValues.values():
timestampsline += ","
timestampsline += str(timestamp)
arg_line = "[%22"+self.__chosen_puzzle+"%22,%22"+attemptLine+"%22"+timestampsline+"]"
print arg_line
try:
solution_info = self.__rpc_connection.cclib("solution", "17", '"' + arg_line + '"')
print solution_info
solution_txid = self.__rpc_connection.sendrawtransaction(solution_info["hex"])
print "Solution accepted!"
print solution_txid
except Exception as e:
print(e)
print(solution_info)
solution_txid = 'error'
return solution_txid
def main():
while True:
# Assetchain hardcoded here
chain = 'SUDOKU'
try:
print 'Welcome to the Komodo SudokuCC'
rpc_connection = sudoku_kmdlib.def_credentials(chain)
pending_puzzles = rpc_connection.cclib("pending", "17")["pending"]
puzzle_list = []
for puzzle in pending_puzzles:
puzzle_list.append(puzzle["txid"])
except Exception as e:
#print rpc_connection
print e
print 'Cant connect to SUDOKU Daemon! Please re-check if it up'
sys.exit()
else:
print 'Succesfully connected!\n'
break
newGame = Sudoku(puzzle_list, rpc_connection)
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

BIN
src/gui/komodoku/board.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,41 @@
import platform
import os
import re
import random
from slickrpc import Proxy
# define function that fetchs rpc creds from .conf
def def_credentials(chain):
rpcport ='';
operating_system = platform.system()
if operating_system == 'Darwin':
ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo'
elif operating_system == 'Linux':
ac_dir = os.environ['HOME'] + '/.komodo'
elif operating_system == 'Windows':
ac_dir = '%s/komodo/' % os.environ['APPDATA']
if chain == 'KMD':
coin_config_file = str(ac_dir + '/komodo.conf')
else:
coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf')
with open(coin_config_file, 'r') as f:
for line in f:
l = line.rstrip()
if re.search('rpcuser', l):
rpcuser = l.replace('rpcuser=', '')
elif re.search('rpcpassword', l):
rpcpassword = l.replace('rpcpassword=', '')
elif re.search('rpcport', l):
rpcport = l.replace('rpcport=', '')
if len(rpcport) == 0:
if chain == 'KMD':
rpcport = 7771
else:
print("rpcport not in conf file, exiting")
print("check "+coin_config_file)
exit(1)
return(Proxy("http://%s:%s@127.0.0.1:%d"%(rpcuser, rpcpassword, int(rpcport))))

View File

@@ -50,7 +50,7 @@ extern uint64_t ASSETCHAINS_TIMELOCKGTE;
extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH,ASSETCHAINS_EQUIHASH,KOMODO_INITDONE;
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,KOMODO_ON_DEMAND,KOMODO_PASSPORT_INITDONE,ASSETCHAINS_STAKED;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA;
extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_LASTERA,ASSETCHAINS_CBOPRET;
extern bool VERUS_MINTBLOCKS;
extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
extern const char *ASSETCHAINS_ALGORITHMS[];

View File

@@ -1547,3 +1547,228 @@ void komodo_passport_iteration()
printf("READY for %s RPC calls at %u! done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid);
}
}
extern std::vector<uint8_t> Mineropret; // opreturn data set by the data gathering code
#define PRICES_MAXCHANGE (COIN / 100) // maximum acceptable change, set at 1%
#define PRICES_SIZEBIT0 (sizeof(uint32_t) * 4) // 4 uint32_t unixtimestamp, BTCUSD, BTCGBP and BTCEUR
// komodo_heightpricebits() extracts the price data in the coinbase for nHeight
int32_t komodo_heightpricebits(uint32_t prevbits[4],int32_t nHeight)
{
CBlockIndex *pindex; CBlock block; CTransaction tx; int32_t numvouts; std::vector<uint8_t> vopret;
if ( (pindex= komodo_chainactive(nHeight)) != 0 )
{
if ( komodo_blockload(block,pindex) == 0 )
{
tx = block.vtx[0];
numvouts = (int32_t)tx.vout.size();
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
if ( vopret.size() >= PRICES_SIZEBIT0 )
{
memcpy(prevbits,&vopret[0],PRICES_SIZEBIT0);
return(0);
}
}
}
fprintf(stderr,"couldnt get pricebits for %d\n",nHeight);
return(-1);
}
/*
komodo_pricenew() is passed in a reference price, the change tolerance and the proposed price. it needs to return a clipped price if it is too big and also set a flag if it is at or above the limit
*/
uint32_t komodo_pricenew(int32_t *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance)
{
uint32_t highprice,lowprice;
highprice = ((uint64_t)refprice * (COIN + tolerance)) / COIN; // calc highest acceptable price
lowprice = ((uint64_t)refprice * (COIN - tolerance)) / COIN; // and lowest
if ( price >= highprice )
{
*maxflagp = 1;
if ( price > highprice ) // return non-zero only if we violate the tolerance
return(highprice);
}
else if ( price <= lowprice )
{
*maxflagp = -1;
if ( price < lowprice )
return(lowprice);
}
else return(0);
}
// komodo_pricecmp() returns -1 if any of the prices are beyond the tolerance
int32_t komodo_pricecmp(int32_t *maxflagp,uint32_t pricebitsA[4],uint32_t pricebitsB[4],int64_t tolerance)
{
int32_t i;
*maxflagp = 0;
for (i=1; i<4; i++)
if ( komodo_pricenew(maxflagp,pricebitsA[i],pricebitsB[i],tolerance) != 0 )
return(-1);
return(0);
}
// komodo_priceclamp() clamps any price that is beyond tolerance
int32_t komodo_priceclamp(uint32_t pricebits[4],uint32_t refprices[4],int64_t tolerance)
{
int32_t i,maxflag = 0; uint32_t newprice;
for (i=1; i<4; i++)
{
if ( (newprice= komodo_pricenew(&maxflag,pricebits[i],refprices[i],tolerance)) != 0 )
{
fprintf(stderr,"priceclamped[%d] %u -> %u\n",i,pricebits[i],newprice);
pricebits[i] = newprice;
}
}
return(0);
}
// komodo_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight
CScript komodo_mineropret(int32_t nHeight)
{
CScript opret; uint32_t pricebits[4],prevbits[4]; int32_t maxflag;
if ( Mineropret.size() >= PRICES_SIZEBIT0 )
{
if ( komodo_heightpricebits(prevbits,nHeight-1) == 0 )
{
memcpy(pricebits,&Mineropret[0],PRICES_SIZEBIT0);
if ( komodo_pricecmp(&maxflag,pricebits,prevbits,PRICES_MAXCHANGE) < 0 )
{
// if the new prices are not within tolerance, update Mineropret with clipped prices
komodo_priceclamp(pricebits,prevbits,PRICES_MAXCHANGE);
fprintf(stderr,"update Mineropret to clamped prices\n");
memcpy(&Mineropret[0],pricebits,PRICES_SIZEBIT0);
}
}
return(opret << OP_RETURN << Mineropret);
}
return(opret);
}
/*
komodo_opretvalidate() is the entire price validation!
it prints out some useful info for debugging, like the lag from current time and prev block and the prices encoded in the opreturn.
The only way komodo_opretvalidate() doesnt return an error is if maxflag is set or it is within tolerance of both the prior block and the local data. The local data validation only happens if it is a recent block and not a block from the past as the local node is only getting the current price data.
*/
int32_t komodo_opretvalidate(int32_t nHeight,CScript scriptPubKey)
{
std::vector<uint8_t> vopret; uint32_t localbits[4],pricebits[4],prevbits[4],newprice; int32_t i,lag,lag2,maxflag=0;
if ( ASSETCHAINS_CBOPRET != 0 )
{
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() >= PRICES_SIZEBIT0 )
{
memcpy(pricebits,&vopret[0],PRICES_SIZEBIT0);
lag = (int32_t)(time(NULL) - pricebits[0]);
if ( lag < 0 )
lag = -lag;
lag2 = (int32_t)(pricebits[0] - komodo_heightstamp(nHeight-1));
fprintf(stderr,"ht.%d: t%u lag.%d %.4f USD, %.4f GBP, %.4f EUR htstamp.%d [%d]\n",nHeight,pricebits[0],lag,(double)pricebits[1]/10000,(double)pricebits[2]/10000,(double)pricebits[3]/10000,komodo_heightstamp(nHeight-1),lag2);
if ( nHeight > 1 )
{
if ( komodo_heightpricebits(prevbits,nHeight-1) == 0 )
{
if ( komodo_pricecmp(&maxflag,pricebits,prevbits,PRICES_MAXCHANGE) < 0 )
return(-1);
} else return(-1);
}
if ( lag < ASSETCHAINS_BLOCKTIME && Mineropret.size() >= PRICES_SIZEBIT0 )
{
memcpy(localbits,&Mineropret[0],PRICES_SIZEBIT0);
if ( maxflag == 0 )
{
if ( komodo_pricecmp(&maxflag,localbits,prevbits,PRICES_MAXCHANGE) < 0 )
return(-1);
}
else
{
for (i=1; i<4; i++)
{
maxflag = 0;
if ( (newprice= komodo_pricenew(&maxflag,pricebits[i],prevbits[i],PRICES_MAXCHANGE)) != 0 ) // proposed price is clamped
{
// make sure local price is beyond clamped
if ( maxflag > 0 && localbits[i] < pricebits[i] )
return(-1);
else if ( maxflag < 0 && localbits[i] > pricebits[i] )
return(-1);
}
}
}
}
return(0);
} else fprintf(stderr,"wrong size %d vs %d, scriptPubKey size %d [%02x]\n",(int32_t)vopret.size(),(int32_t)PRICES_SIZEBIT0,(int32_t)scriptPubKey.size(),scriptPubKey[0]);
return(-1);
}
return(0);
}
// get_urljson just returns the JSON returned by the URL using issue_curl
#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0)
cJSON *get_urljson(char *url)
{
char *jsonstr; cJSON *json = 0;
if ( (jsonstr= issue_curl(url)) != 0 )
{
//fprintf(stderr,"(%s) -> (%s)\n",url,jsonstr);
json = cJSON_Parse(jsonstr);
free(jsonstr);
}
return(json);
}
// parse the coindesk specific data. yes, if this changes, it will require an update. However, regardless if the format from the data source changes, then the code that extracts it must be changed. One way to mitigate this is to have a large variety of data sources so that there is only a very remote chance that all of them are not available. Certainly the data gathering needs to be made more robust, but it doesnt really affect the proof of concept for the decentralized trustless oracle. The trustlessness is achieved by having all nodes get the oracle data.
int32_t get_btcusd(uint32_t pricebits[4])
{
cJSON *pjson,*bpi,*obj; char str[512]; uint64_t btcusd = 0,btcgbp = 0,btceur = 0;
if ( (pjson= get_urljson((char *)"http://api.coindesk.com/v1/bpi/currentprice.json")) != 0 )
{
if ( (bpi= jobj(pjson,(char *)"bpi")) != 0 )
{
pricebits[0] = (uint32_t)time(NULL);
if ( (obj= jobj(bpi,(char *)"USD")) != 0 )
{
btcusd = jdouble(obj,(char *)"rate_float") * SATOSHIDEN;
pricebits[1] = ((btcusd / 10000) & 0xffffffff);
}
if ( (obj= jobj(bpi,(char *)"GBP")) != 0 )
{
btcgbp = jdouble(obj,(char *)"rate_float") * SATOSHIDEN;
pricebits[2] = ((btcgbp / 10000) & 0xffffffff);
}
if ( (obj= jobj(bpi,(char *)"EUR")) != 0 )
{
btceur = jdouble(obj,(char *)"rate_float") * SATOSHIDEN;
pricebits[3] = ((btceur / 10000) & 0xffffffff);
}
}
free_json(pjson);
fprintf(stderr,"BTC/USD %.4f, BTC/GBP %.4f, BTC/EUR %.4f\n",dstr(btcusd),dstr(btcgbp),dstr(btceur));
return(0);
}
return(-1);
}
// komodo_cbopretupdate() obtains the external price data and encodes it into Mineropret, which will then be used by the miner and validation
void komodo_cbopretupdate()
{
uint32_t pricebits[4];
if ( (ASSETCHAINS_CBOPRET & 1) != 0 )
{
if ( get_btcusd(pricebits) == 0 )
{
if ( Mineropret.size() < PRICES_SIZEBIT0 )
Mineropret.resize(PRICES_SIZEBIT0);
memcpy(&Mineropret[0],pricebits,PRICES_SIZEBIT0);
//int32_t i; for (i=0; i<Mineropret.size(); i++)
// fprintf(stderr,"%02x",Mineropret[i]);
//fprintf(stderr," <- set Mineropret[%d]\n",(int32_t)Mineropret.size());
}
}
}

View File

@@ -50,6 +50,7 @@ int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JU
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,WHITELIST_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,NUM_NOTARIES,ASSETCHAINS_MARMARA;
bool VERUS_MINTBLOCKS;
std::vector<uint8_t> Mineropret;
char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096],NOTARYADDRS[64][36];
uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT;
@@ -66,7 +67,7 @@ int64_t MAX_MONEY = 200000000 * 100000000LL;
// spec will use an op_return with CLTV at front and anything after |OP_RETURN|PUSH of rest|OPRETTYPE_TIMELOCK|script|
#define _ASSETCHAINS_TIMELOCKOFF 0xffffffffffffffff
uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF;
uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0;
uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0,ASSETCHAINS_CBOPRET=0;
uint64_t ASSETCHAINS_LASTERA = 1;
uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS];

View File

@@ -1664,11 +1664,12 @@ uint64_t komodo_ac_block_subsidy(int nHeight)
}
extern int64_t MAX_MONEY;
void komodo_cbopretupdate();
void komodo_args(char *argv0)
{
extern const char *Notaries_elected1[][2];
std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256];
std::string name,addn,hexstr; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[8192],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256];
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
IS_STAKED_NOTARY = GetArg("-stakednotary", -1);
if ( IS_STAKED_NOTARY != -1 && IS_KOMODO_NOTARY == true ) {
@@ -1810,6 +1811,16 @@ void komodo_args(char *argv0)
ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0);
ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0);
ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0);
ASSETCHAINS_CBOPRET = GetArg("-ac_cbopret",0);
hexstr = GetArg("-ac_mineropret","");
if ( hexstr.size() != 0 )
{
Mineropret.resize(hexstr.size()/2);
decode_hex(&Mineropret[0],hexstr.size()/2,(char *)hexstr.c_str());
for (i=0; i<Mineropret.size(); i++)
fprintf(stderr,"%02x",Mineropret[i]);
fprintf(stderr," Mineropret\n");
}
if ( ASSETCHAINS_COMMISSION != 0 && ASSETCHAINS_FOUNDERS_REWARD != 0 )
{
fprintf(stderr,"cannot use founders reward and commission on the same chain.\n");
@@ -1948,7 +1959,7 @@ void komodo_args(char *argv0)
fprintf(stderr,"-ac_script and -ac_marmara are mutually exclusive\n");
exit(0);
}
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 )
if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 )
{
fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size());
extraptr = extrabuf;
@@ -2048,6 +2059,17 @@ void komodo_args(char *argv0)
}
if ( ASSETCHAINS_BLOCKTIME != 60 )
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_BLOCKTIME),(void *)&ASSETCHAINS_BLOCKTIME);
if ( Mineropret.size() != 0 )
{
for (i=0; i<Mineropret.size(); i++)
extraptr[extralen++] = Mineropret[i];
}
if ( ASSETCHAINS_CBOPRET != 0 )
{
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_CBOPRET),(void *)&ASSETCHAINS_CBOPRET);
komodo_cbopretupdate(); // will set Mineropret
fprintf(stderr,"This blockchain uses data produced from CoinDesk Bitcoin Price Index\n");
}
}
addn = GetArg("-seednode","");

View File

@@ -1014,6 +1014,15 @@ bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeigh
}
return(false);
}
else if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 )
{
}
else if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 && tx.vout.size() > 0 )
{
if ( komodo_opretvalidate(nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 )
return(false);
}
return(true);
}

View File

@@ -155,6 +155,7 @@ CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk);
uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector<int8_t> &NotarisationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len);
int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
int32_t komodo_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len);
CScript komodo_mineropret(int32_t nHeight);
CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
{
@@ -723,7 +724,14 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
fprintf(stderr, "Created notary payment coinbase totalsat.%lu\n",totalsats);
} else fprintf(stderr, "vout 2 of notarisation is not OP_RETURN scriptlen.%i\n", scriptlen);
}
if ( ASSETCHAINS_CBOPRET != 0 )
{
int32_t numv = (int32_t)txNew.vout.size();
txNew.vout.resize(numv+1);
txNew.vout[numv].nValue = 0;
txNew.vout[numv].scriptPubKey = komodo_mineropret(nHeight);
//printf("autocreate commision/cbopret.%lld vout[%d]\n",(long long)ASSETCHAINS_CBOPRET,(int32_t)txNew.vout.size());
}
pblock->vtx[0] = txNew;
pblocktemplate->vTxFees[0] = -nFees;

21
src/tui/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Anton Lysakov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

58
src/tui/README.md Normal file
View File

@@ -0,0 +1,58 @@
# Komodo Cryptoconditons Terminal User Interfaces (aka TUIs)
These tools creating for demonstration and partial automation of Komodo cryptoconditions modules testing. (RogueCC game, AssetsCC, OraclesCC, GatewaysCC, MarmaraCC, ...)
Developer installation (on Ubuntu 18.04) :
Python3 required for execution:
* `sudo apt-get install python3.6 python3-pip libgnutls28-dev`
pip packages needed:
* `pip3 install setuptools wheel slick-bitcoinrpc`
* or `pip3 install -r requirements.txt`
Starting:
# TUI for RogueCC
If you're looking for player 3 in 1 (daemon + game + TUI) multiOS bundle - please check `releases` of this repo.
`python3 rogue_tui.py`
![alt text](https://i.imgur.com/gkcxMGt.png)
# TUI for OraclesCC
Have files uploader/downloader functionality - also there is a AWS branch for AWS certificates uploading demonstration
`python3 oracles_cc_tui.py`
![alt text](https://i.imgur.com/tfHwRqc.png)
# TUI for GatewaysCC
![alt text](https://i.imgur.com/c8DPfpp.png)
`python3 gateways_creation_tui.py`
`python3 gateways_usage_tui.py`
At the moment raw version of manual gateway how-to guide can be found here: https://docs.komodoplatform.com/cc/contracts/gateways/scenarios/tutorial.html I advice to read it before you start use this tool to understand the flow.
# TUI for MarmaraCC
`python3 marmara_tui.py`
![alt text](https://i.imgur.com/uonMWHl.png)
# TUI for AssetsCC (not much finished)
`python3 assets_cc_tui.py`
Before execution be sure than daemon for needed AC up.

39
src/tui/lib/logo.txt Normal file
View File

@@ -0,0 +1,39 @@
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0xlc:ldOKNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0xo:,........';lxOXNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMWNKkoc,..................':ox0XWMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMWNKkdc;............................,:ok0NWMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMWNKOdl;'.....................................,cdkKNWMMMMMMMMMMMMMM
MMMMMMMMMMMMMW0c'..............................................';kNMMMMMMMMMMMMM
MMMMMMMMMMMMMK:......................';:c:'......................,kWMMMMMMMMMMMM
MMMMMMMMMMMMXl...................;cdkKNWWNXOdl;'..................;OWMMMMMMMMMMM
MMMMMMMMMMMNo...............,cok0XWMMMMMMMMMMWNKkdc;'..............:KMMMMMMMMMMM
MMMMMMMMMMWx'...........;ox0XWMMMMMMMMMMMMMMMMMMMMWNKko:............lXMMMMMMMMMM
MMMMMMMMMWk,...........lXWMMMMMMMMMMMMWWWWMMMMMMMMMMMMMNx'...........oNMMMMMMMMM
MMMMMMMMW0;...........cKMMMMMMMMMWNXOdl::cdkKNWMMMMMMMMMNo...........'xWMMMMMMMM
MMMMMMMMKc...........;0WMMMMMWN0xl:,........';ldOXWMMMMMMXl...........,OWMMMMMMM
MMMMMMMXl...........,kWMMMMMMKl..................;OWMMMMMMK:...........;0MMMMMMM
MMMMMMNd...........'xNMMMMMMXl....................:0WMMMMMWO;...........cKMMMMMM
MMMMMNx'...........oNMMMMMMNd......................cKMMMMMMWk'...........lXMMMMM
MMMMWO,...........lXMMMMMMWx'.......................oXMMMMMMNd'...........dNMMMM
MMMMXc...........,OWMMMMMMK:........................,kWMMMMMMKc...........;0MMMM
MMMMWx'...........oXMMMMMMNd........................cKMMMMMMWk,...........lXMMMM
MMMMMNd...........'dNMMMMMMXl......................:0MMMMMMWO;...........cKMMMMM
MMMMMMXl...........,kWMMMMMMKc....................,OWMMMMMM0:...........;0MMMMMM
MMMMMMMKc...........;OWMMMMMW0:..................,kWMMMMMMXc...........,OWMMMMMM
MMMMMMMM0;...........:KMMMMMMWKko:,..........';lx0WMMMMMMNo...........'xWMMMMMMM
MMMMMMMMWk,...........lXMMMMMMMMWWXOxl:,,;cdOKNWMMMMMMMMNx'...........dNMMMMMMMM
MMMMMMMMMWx'...........dNMMMMMMMMMMMMWNXXNWMMMMMMMMMMMMWk,...........lXMMMMMMMMM
MMMMMMMMMMNo............cx0XWMMMMMMMMMMMMMMMMMMMMMMWN0kl,...........cKMMMMMMMMMM
MMMMMMMMMMMXl..............,:ok0XWMMMMMMMMMMMMWNKkdc;..............;0WMMMMMMMMMM
MMMMMMMMMMMMK:..................,cokKNWMMWNKOdl;'.................,kWMMMMMMMMMMM
MMMMMMMMMMMMWO;......................;cool;'.....................'xNMMMMMMMMMMMM
MMMMMMMMMMMMMWk;................................................'dNMMMMMMMMMMMMM
MMMMMMMMMMMMMMWXOxl;'.......................................,cdkKWMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMWNKOdc;..............................,cok0NWMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMWNKkoc,....................,:ox0XWMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0ko:,..........':lx0XWMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0xl:,,;ldOKNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWNNXNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

129
src/tui/lib/rpclib.py Normal file
View File

@@ -0,0 +1,129 @@
import http
from slickrpc import Proxy
# RPC connection
def rpc_connect(rpc_user, rpc_password, port):
try:
rpc_connection = Proxy("http://%s:%s@127.0.0.1:%d"%(rpc_user, rpc_password, port))
except Exception:
raise Exception("Connection error! Probably no daemon on selected port.")
return rpc_connection
# Non CC calls
def getinfo(rpc_connection):
try:
getinfo = rpc_connection.getinfo()
except Exception:
raise Exception("Connection error!")
return getinfo
def sendrawtransaction(rpc_connection, hex):
tx_id = rpc_connection.sendrawtransaction(hex)
return tx_id
def gettransaction(rpc_connection, tx_id):
transaction_info = rpc_connection.gettransaction(tx_id)
return transaction_info
def getrawtransaction(rpc_connection, tx_id):
rawtransaction = rpc_connection.getrawtransaction(tx_id)
return rawtransaction
def getbalance(rpc_connection):
balance = rpc_connection.getbalance()
return balance
# Token CC calls
def token_create(rpc_connection, name, supply, description):
token_hex = rpc_connection.tokencreate(name, supply, description)
return token_hex
def token_info(rpc_connection, token_id):
token_info = rpc_connection.tokeninfo(token_id)
return token_info
#TODO: have to add option with pubkey input
def token_balance(rpc_connection, token_id):
token_balance = rpc_connection.tokenbalance(token_id)
return token_balance
def token_list(rpc_connection):
token_list = rpc_connection.tokenlist()
return token_list
def token_convert(rpc_connection, evalcode, token_id, pubkey, supply):
token_convert_hex = rpc_connection.tokenconvert(evalcode, token_id, pubkey, supply)
return token_convert_hex
def get_rawmempool(rpc_connection):
mempool = rpc_connection.getrawmempool()
return mempool
# Oracle CC calls
def oracles_create(rpc_connection, name, description, data_type):
oracles_hex = rpc_connection.oraclescreate(name, description, data_type)
return oracles_hex
def oracles_register(rpc_connection, oracle_id, data_fee):
oracles_register_hex = rpc_connection.oraclesregister(oracle_id, data_fee)
return oracles_register_hex
def oracles_subscribe(rpc_connection, oracle_id, publisher_id, data_fee):
oracles_subscribe_hex = rpc_connection.oraclessubscribe(oracle_id, publisher_id, data_fee)
return oracles_subscribe_hex
def oracles_info(rpc_connection, oracle_id):
oracles_info = rpc_connection.oraclesinfo(oracle_id)
return oracles_info
def oracles_data(rpc_connection, oracle_id, hex_string):
oracles_data = rpc_connection.oraclesdata(oracle_id, hex_string)
return oracles_data
def oracles_list(rpc_connection):
oracles_list = rpc_connection.oracleslist()
return oracles_list
def oracles_samples(rpc_connection, oracletxid, batonutxo, num):
oracles_sample = rpc_connection.oraclessamples(oracletxid, batonutxo, num)
return oracles_sample
# Gateways CC calls
# Arguments changing dynamically depends of M N, so supposed to wrap it this way
# token_id, oracle_id, coin_name, token_supply, M, N + pubkeys for each N
def gateways_bind(rpc_connection, *args):
gateways_bind_hex = rpc_connection.gatewaysbind(*args)
return gateways_bind_hex
def gateways_deposit(rpc_connection, gateway_id, height, coin_name,\
coin_txid, claim_vout, deposit_hex, proof, dest_pub, amount):
gateways_deposit_hex = rpc_connection.gatewaysdeposit(gateway_id, height, coin_name,\
coin_txid, claim_vout, deposit_hex, proof, dest_pub, amount)
return gateways_deposit_hex
def gateways_claim(rpc_connection, gateway_id, coin_name, deposit_txid, dest_pub, amount):
gateways_claim_hex = rpc_connection.gatewaysclaim(gateway_id, coin_name, deposit_txid, dest_pub, amount)
return gateways_claim_hex
def gateways_withdraw(rpc_connection, gateway_id, coin_name, withdraw_pub, amount):
gateways_withdraw_hex = rpc_connection.gatewayswithdraw(gateway_id, coin_name, withdraw_pub, amount)
return gateways_withdraw_hex

1965
src/tui/lib/tuilib.py Executable file

File diff suppressed because it is too large Load Diff

8
src/tui/requirements.txt Normal file
View File

@@ -0,0 +1,8 @@
configobj==5.0.6
pip==9.0.1
pycurl==7.43.0.2
setuptools==39.0.1
six==1.12.0
slick-bitcoinrpc==0.1.4
ujson==1.35
wheel==0.32.3

67
src/tui/tui_assets.py Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
header = "\
___ _ _____ \n\
/ _ \ | | / __ \\\n\
/ /_\ \ ___ ___ ___ | |_ ___ | / \/\n\
| _ |/ __|/ __| / _ \| __|/ __|| | \n\
| | | |\__ \\\__ \| __/| |_ \__ \| \__/\\\n\
\_| |_/|___/|___/ \___| \__||___/ \____/\n"
menuItems = [
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Print tokens list": tuilib.print_tokens_list},
{"Check my tokens balances" : tuilib.print_tokens_balances},
# transfer tokens (pre-print tokens balances)
{"Create token": tuilib.token_create_tui},
# trading zone - pre-print token orders - possible to open order or fill existing one
{"Exit": exit}
]
def main():
while True:
os.system('clear')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('CLI version 0.2 by Anton Lysakov\n', 'green'))
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
try:
print(tuilib.colorize("Welcome to the GatewaysCC TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.rpc_connection_tui()
rpclib.getinfo(rpc_connection)
except Exception:
print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink"))
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
header = "\
_____ _ _____ _____ \n\
| __ \ | | / __ \/ __ \\\n\
| | \/ __ _| |_ _____ ____ _ _ _ ___| / \/| / \/\n\
| | __ / _` | __/ _ \ \ /\ / / _` | | | / __| | | | \n\
| |_\ \ (_| | || __/\ V V / (_| | |_| \__ \ \__/\| \__/\\\n\
\____/\__,_|\__\___| \_/\_/ \__,_|\__, |___/\____/ \____/\n\
__/ | \n\
|___/ \n"
menuItems = [
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Create token": tuilib.token_create_tui},
{"Create oracle": tuilib.oracle_create_tui},
{"Register as publisher for oracle": tuilib.oracle_register_tui},
{"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen},
{"Bind Gateway": tuilib.gateways_bind_tui},
{"Exit": exit}
]
def main():
while True:
os.system('clear')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('CLI version 0.2\n', 'green'))
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
try:
print(tuilib.colorize("Welcome to the GatewaysCC TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.rpc_connection_tui()
rpclib.getinfo(rpc_connection)
except Exception:
print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink"))
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

96
src/tui/tui_gateways_usage.py Executable file
View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os, time
header = "\
_____ _ _____ _____ \n\
| __ \ | | / __ \/ __ \\\n\
| | \/ __ _| |_ _____ ____ _ _ _ ___| / \/| / \/\n\
| | __ / _` | __/ _ \ \ /\ / / _` | | | / __| | | | \n\
| |_\ \ (_| | || __/\ V V / (_| | |_| \__ \ \__/\| \__/\\\n\
\____/\__,_|\__\___| \_/\_/ \__,_|\__, |___/\____/ \____/\n\
__/ | \n\
|___/ \n"
menuItems = [
{"Check connection to assetchain": tuilib.getinfo_tui},
{"Check assetchain mempool": tuilib.print_mempool},
{"Check connection to KMD": tuilib.getinfo_tui},
{"Connect to KMD daemon": tuilib.rpc_kmd_connection_tui},
{"Send KMD gateway deposit transaction": tuilib.gateways_send_kmd},
{"Execute gateways deposit": tuilib.gateways_deposit_tui},
{"Execute gateways claim": tuilib.gateways_claim_tui},
{"Execute gateways withdrawal": tuilib.gateways_withdrawal_tui},
{"Exit": exit}
]
def main():
while True:
os.system('clear')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('CLI version 0.2\n', 'green'))
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
# We have to call KMD specific functions with connection to KMD daemon
elif list(menuItems[int(choice)].keys())[0] == "Connect to KMD daemon":
rpc_connection_kmd = list(menuItems[int(choice)].values())[0]()
elif list(menuItems[int(choice)].keys())[0] == "Check connection to KMD":
while True:
try:
list(menuItems[int(choice)].values())[0](rpc_connection_kmd)
break
except Exception as e:
print("Please connect to KMD daemon first!")
input("Press [Enter] to continue...")
break
elif list(menuItems[int(choice)].keys())[0] == "Send KMD gateway deposit transaction":
while True:
try:
list(menuItems[int(choice)].values())[0](rpc_connection_kmd)
break
except Exception as e:
print(e)
print("Please connect to KMD daemon first!")
input("Press [Enter] to continue...")
break
elif list(menuItems[int(choice)].keys())[0] == "Execute gateways deposit":
while True:
try:
list(menuItems[int(choice)].values())[0](rpc_connection, rpc_connection_kmd)
break
except Exception as e:
print(e)
print("Please connect to KMD daemon first!")
input("Press [Enter] to continue...")
break
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
try:
print(tuilib.colorize("Welcome to the GatewaysCC TUI!\nPlease provide RPC connection details for initialization", "blue"))
rpc_connection = tuilib.rpc_connection_tui()
rpclib.getinfo(rpc_connection)
except Exception:
print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink"))
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

68
src/tui/tui_marmara.py Executable file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
header = "\
___ ___ _____ _ _ _____ \n\
| \/ | |_ _| | | |_ _|\n\
| . . | __ _ _ __ _ __ ___ __ _ _ __ __ _ | | | | | | | |\n\
| |\/| |/ _` | '__| '_ ` _ \ / _` | '__/ _` | | | | | | | | |\n\
| | | | (_| | | | | | | | | (_| | | | (_| | | | | |_| |_| |_\n\
\_| |_/\__,_|_| |_| |_| |_|\__,_|_| \__,_| \_/ \___/ \___/\n"
menuItems = [
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Check MARMARA info": tuilib.marmara_info_tui},
{"Lock funds for MARMARA": tuilib.marmara_lock_tui},
{"Request MARMARA cheque": tuilib.marmara_receive_tui},
{"Issue MARMARA cheque": tuilib.marmara_issue_tui},
{"Check credit loop status": tuilib.marmara_creditloop_tui},
{"Settle MARMARA loop": tuilib.marmara_settlement_tui},
{"Exit": exit}
]
def main():
while True:
os.system('clear')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('CLI version 0.1\n', 'green'))
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
chain = input("Input assetchain name (-ac_name= value) you want to work with: ")
try:
print(tuilib.colorize("Welcome to the MarmaraCC TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.def_credentials(chain)
rpclib.getinfo(rpc_connection)
except Exception:
print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink"))
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

67
src/tui/tui_oracles.py Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
header = "\
_____ _ _____ _____ \n\
| _ | | | / __ \/ __ \\\n\
| | | | _ __ __ _ ___ | | ___ ___ | / \/| / \/\n\
| | | || '__| / _` | / __|| | / _ \/ __|| | | |\n\
\ \_/ /| | | (_| || (__ | || __/\__ \| \__/\| \__/\\\n\
\___/ |_| \__,_| \___||_| \___||___/ \____/ \____/\n"
menuItems = [
# TODO: Have to implement here native oracle file uploader / reader, should be dope
# TODO: data publisher / converter for different types
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Create oracle": tuilib.oracle_create_tui},
{"Register as publisher for oracle": tuilib.oracle_register_tui},
{"Subscribe on oracle (+UTXO generator)": tuilib.oracle_subscription_utxogen},
{"Upload file to oracle": tuilib.convert_file_oracle_D},
{"Display list of files uploaded to this AC": tuilib.display_files_list},
{"Download files from oracle": tuilib.files_downloader},
{"Exit": exit}
]
def main():
while True:
os.system('clear')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('CLI version 0.2 by Anton Lysakov\n', 'green'))
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
try:
print(tuilib.colorize("Welcome to the GatewaysCC TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.rpc_connection_tui()
rpclib.getinfo(rpc_connection)
except Exception:
print(tuilib.colorize("Cant connect to RPC! Please re-check credentials.", "pink"))
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

116
src/tui/tui_rogue.py Executable file
View File

@@ -0,0 +1,116 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
import sys
import platform
header = "\
______ _____ _____ \n\
| ___ \ / __ \/ __ \\\n\
| |_/ /___ __ _ _ _ ___| / \/| / \/\n\
| // _ \ / _` | | | |/ _ \ | | |\n\
| |\ \ (_) | (_| | |_| | __/ \__/\| \__/\\\n\
\_| \_\___/ \__, |\__,_|\___|\____/ \____/\n\
__/ |\n\
|___/\n"
menuItems = [
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Check my warriors list": tuilib.print_players_list},
{"Transfer warrior to other pubkey": tuilib.warrior_trasnfer},
{"TOP-20 ROGUE Warriors": tuilib.top_warriors_rating},
{"Set warriors name": tuilib.set_warriors_name},
{"Start singleplayer training game (creating, registering and starting game)": tuilib.rogue_newgame_singleplayer},
{"Create multiplayer game": tuilib.rogue_newgame_multiplayer},
{"Join (register) multiplayer game": tuilib.rogue_join_multiplayer_game},
{"Check my multiplayer games status / start": tuilib.play_multiplayer_game},
{"Check if somebody wants to buy your warrior (incoming bids)": tuilib.print_icoming_bids},
{"Place order to sell warrior": tuilib.sell_warrior},
{"Place order to buy someones warrior": tuilib.place_bid_on_warriror},
{"Check if somebody selling warrior": tuilib.find_warriors_asks},
{"Check / cancel my warriors trade orders": tuilib.warriors_orders_check},
# {"Manually exit the game (bailout)": "test"},
# {"Manually claim ROGUE coins for game (highlander)": "test"},
{"Exit": tuilib.exit}
]
def main():
while True:
operating_system = platform.system()
if operating_system != 'Win64' and operating_system != 'Windows':
os.system('clear')
else:
os.system('cls')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('TUI v0.0.3\n', 'green'))
menu_items_counter = 0
for item in menuItems:
if menu_items_counter == 0:
print("\nUtility:\n")
menu_items_counter = menu_items_counter + 1
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
if menu_items_counter == 6:
print("\nNew singleplayer game:\n")
if menu_items_counter == 7:
print("\nMultiplayer games:\n")
if menu_items_counter == 10:
print("\nDEX features:\n")
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
chain = "ROGUE"
try:
print(tuilib.colorize("Welcome to the RogueCC TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.def_credentials(chain)
rpclib.getinfo(rpc_connection)
# waiting until chain is in sync
while True:
have_blocks = rpclib.getinfo(rpc_connection)["blocks"]
longest_chain = rpclib.getinfo(rpc_connection)["longestchain"]
if have_blocks != longest_chain:
print(tuilib.colorize("ROGUE not synced yet.", "red"))
print("Have " + str(have_blocks) + " from " + str(longest_chain) + " blocks")
time.sleep(5)
else:
print(tuilib.colorize("Chain is synced!", "green"))
break
# checking if pubkey is set and set valid if not
info = rpclib.getinfo(rpc_connection)
if "pubkey" in info.keys():
print("Pubkey is already set")
else:
valid_address = rpc_connection.getaccountaddress("")
valid_pubkey = rpc_connection.validateaddress(valid_address)["pubkey"]
rpc_connection.setpubkey(valid_pubkey)
print(tuilib.colorize("Pubkey is succesfully set!", "green"))
# copy ROGUE config to current daemon directory if it's not here
tuilib.check_if_config_is_here(rpc_connection, "ROGUE")
except Exception:
print(tuilib.colorize("Cant connect to ROGUE daemon RPC! Please check if daemon is up.", "pink"))
tuilib.exit()
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()

96
src/tui/tui_tetris.py Executable file
View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
from lib import rpclib, tuilib
import os
import time
import sys
import platform
header = "\
_____ _ _ ______\n\
|_ _| | | (_) | _ \n\
| | ___| |_ _ __ _ ___| | | |__ _ _ __ _ __\n\
| |/ _ \ __| '__| / __| | | / _` | '_ \| '_ \\\n\
| | __/ |_| | | \__ \ |/ / (_| | |_) | |_) |\n\
\_/\___|\__|_| |_|___/___/ \__,_| .__/| .__/\n\
| | | |\n\
|_| |_|"
menuItems = [
{"Check current connection": tuilib.getinfo_tui},
{"Check mempool": tuilib.print_mempool},
{"Start singleplayer tetris game (creating, registering and starting game)": tuilib.rogue_newgame_singleplayer},
{"Exit": tuilib.exit}
]
def main():
while True:
operating_system = platform.system()
if operating_system != 'Win64' and operating_system != 'Windows':
os.system('clear')
else:
os.system('cls')
print(tuilib.colorize(header, 'pink'))
print(tuilib.colorize('TUI v0.0.3\n', 'green'))
menu_items_counter = 0
for item in menuItems:
print(tuilib.colorize("[" + str(menuItems.index(item)) + "] ", 'blue') + list(item.keys())[0])
choice = input(">> ")
try:
if int(choice) < 0:
raise ValueError
# Call the matching function
if list(menuItems[int(choice)].keys())[0] == "Exit":
list(menuItems[int(choice)].values())[0]()
elif list(menuItems[int(choice)].keys())[0] == "Start singleplayer tetris game (creating, registering and starting game)":
list(menuItems[int(choice)].values())[0](rpc_connection, False)
else:
list(menuItems[int(choice)].values())[0](rpc_connection)
except (ValueError, IndexError):
pass
if __name__ == "__main__":
while True:
chain = "GTEST"
try:
print(tuilib.colorize("Welcome to the Tetris TUI!\n"
"Please provide asset chain RPC connection details for initialization", "blue"))
rpc_connection = tuilib.def_credentials(chain)
rpclib.getinfo(rpc_connection)
# waiting until chain is in sync
while True:
have_blocks = rpclib.getinfo(rpc_connection)["blocks"]
longest_chain = rpclib.getinfo(rpc_connection)["longestchain"]
if have_blocks != longest_chain:
print(tuilib.colorize("GTEST not synced yet.", "red"))
print("Have " + str(have_blocks) + " from " + str(longest_chain) + " blocks")
time.sleep(5)
else:
print(tuilib.colorize("Chain is synced!", "green"))
break
# checking if pubkey is set and set valid if not
info = rpclib.getinfo(rpc_connection)
if "pubkey" in info.keys():
print("Pubkey is already set")
else:
valid_address = rpc_connection.getaccountaddress("")
valid_pubkey = rpc_connection.validateaddress(valid_address)["pubkey"]
rpc_connection.setpubkey(valid_pubkey)
print(tuilib.colorize("Pubkey is succesfully set!", "green"))
# copy ROGUE config to current daemon directory if it's not here
tuilib.check_if_config_is_here(rpc_connection, "GTEST")
except Exception:
print(tuilib.colorize("Cant connect to GTEST daemon RPC! Please check if daemon is up.", "pink"))
tuilib.exit()
else:
print(tuilib.colorize("Succesfully connected!\n", "green"))
with (open("lib/logo.txt", "r")) as logo:
for line in logo:
print(line, end='')
time.sleep(0.04)
print("\n")
break
main()