From 5a260e8893dc70e45804243b3eda179dcc41c9b3 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 13:28:12 -0500 Subject: [PATCH] Delete more CCs #381 --- src/cc/cclib.cpp | 3 - src/cc/games/prices.c | 292 ------------- src/cc/games/prices.cpp | 283 ------------- src/cc/games/prices.h | 211 ---------- src/cc/games/tetris.c | 907 ---------------------------------------- src/cc/games/tetris.cpp | 88 ---- src/cc/games/tetris.h | 211 ---------- src/cc/gamescc.h | 123 ------ src/cc/musig.cpp | 580 ++----------------------- 9 files changed, 24 insertions(+), 2674 deletions(-) delete mode 100644 src/cc/games/prices.c delete mode 100644 src/cc/games/prices.cpp delete mode 100644 src/cc/games/prices.h delete mode 100644 src/cc/games/tetris.c delete mode 100644 src/cc/games/tetris.cpp delete mode 100644 src/cc/games/tetris.h delete mode 100644 src/cc/gamescc.h diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index e35ec8c9d..c1051b3b7 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -35,9 +35,6 @@ std::string MYCCLIBNAME = (char *)"rogue"; #elif BUILD_CUSTOMCC #include "customcc.h" -#elif BUILD_GAMESCC -#include "gamescc.h" - #else #define EVAL_SUDOKU 17 #define EVAL_MUSIG 18 diff --git a/src/cc/games/prices.c b/src/cc/games/prices.c deleted file mode 100644 index 69e3fae95..000000000 --- a/src/cc/games/prices.c +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#include "prices.h" -#include -#include -#ifdef BUILD_GAMESCC -#include "../rogue/cursesd.h" -#else -#include -#endif - -#define SATOSHIDEN ((uint64_t)100000000L) -#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"prices",cmdstr,0,0,0) -extern int64_t Net_change,Betsize; - -int random_tetromino(struct games_state *rs) -{ - rs->seed = _games_rngnext(rs->seed); - return(rs->seed % NUM_TETROMINOS); -} - -int32_t pricesdata(struct games_player *P,void *ptr) -{ - tetris_game *tg = (tetris_game *)ptr; - P->gold = tg->points; - P->dungeonlevel = tg->level; - //fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level); - return(0); -} - -void sleep_milli(int milliseconds) -{ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = milliseconds * 1000 * 1000; - nanosleep(&ts, NULL); -} - -struct games_state globalR; -extern char Gametxidstr[]; -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); -uint64_t get_btcusd(); -int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize); - -void *gamesiterate(struct games_state *rs) -{ - bool running = true; uint32_t eventid = 0; int64_t price; - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - initscr(); // initialize curses - cbreak(); // pass key presses to program, but not signals - noecho(); // don't echo key presses to screen - timeout(0); - } - while ( running != 0 ) - { - //running = tg_tick(rs,tg,move); - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - } - if ( rs->guiflag != 0 ) - { -#ifdef STANDALONE - price = get_btcusd(); - //fprintf(stderr,"%llu -> t%u %.4f\n",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000); - //issue_games_events(rs,Gametxidstr,eventid,price); - issue_bet(rs,price,Betsize); - eventid++; - doupdate(); - sleep(10); - switch ( getch() ) - { - case '+': Net_change++; break; - case '-': Net_change--; break; - case '0': Net_change = 0; break; - case '$': Betsize = SATOSHIDEN; break; - case '^': Betsize += (Betsize >> 3); break; - case '/': Betsize -= (Betsize >> 3); break; - } - /*if ( (counter++ % 10) == 0 ) - doupdate(); - c = games_readevent(rs); - if ( c <= 0x7f || skipcount == 0x3fff ) - { - if ( skipcount > 0 ) - issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); - if ( c <= 0x7f ) - issue_games_events(rs,Gametxidstr,eventid,c); - if ( tg->level != prevlevel ) - { - flushkeystrokes(rs,0); - prevlevel = tg->level; - } - skipcount = 0; - } else skipcount++;*/ -#endif - } - else - { - if ( rs->replaydone != 0 ) - break; - if ( rs->sleeptime != 0 ) - { - sleep_milli(1); - } - /*if ( skipcount == 0 ) - { - c = games_readevent(rs); - //fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level); - if ( (c & 0x4000) == 0x4000 ) - { - skipcount = (c & 0x3fff); - c = 'S'; - } - } - if ( skipcount > 0 ) - skipcount--;*/ - } - eventid++; - } - return(0); -} - -#ifdef STANDALONE -#include -#include "dapps/dappstd.c" -int64_t Net_change,Betsize = SATOSHIDEN; - -char *send_curl(char *url,char *fname) -{ - char *retstr; - retstr = issue_curl(url); - return(retstr); -} - -cJSON *get_urljson(char *url,char *fname) -{ - char *jsonstr; cJSON *json = 0; - if ( (jsonstr= send_curl(url,fname)) != 0 ) - { - //printf("(%s) -> (%s)\n",url,jsonstr); - json = cJSON_Parse(jsonstr); - free(jsonstr); - } - return(json); -} - -////////////////////////////////////////////// -// start of dapp -////////////////////////////////////////////// - -uint64_t get_btcusd() -{ - cJSON *pjson,*bpi,*usd; char str[512]; uint64_t x,newprice,mult,btcusd = 0; - if ( (pjson= get_urljson((char *)"http://api.coindesk.com/v1/bpi/currentprice.json",(char *)"/tmp/oraclefeed.json")) != 0 ) - { - if ( (bpi= jobj(pjson,(char *)"bpi")) != 0 && (usd= jobj(bpi,(char *)"USD")) != 0 ) - { - btcusd = jdouble(usd,(char *)"rate_float") * SATOSHIDEN; - mult = 10000 + Net_change*10; - newprice = (btcusd * mult) / 10000; - x = ((uint64_t)time(NULL) << 32) | ((newprice / 10000) & 0xffffffff); - sprintf(str,"BTC/USD %.4f -> Betsize %.8f (^ / to change) && %.4f Net %.1f%% [+ - to change]\n",dstr(btcusd),dstr(Betsize),dstr(newprice),(double)100*(mult-10000)/10000); - mvaddstr(0, 0, str); - clrtoeol(); - doupdate(); - } - free_json(pjson); - } - return(x); -} - -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) -{ - static FILE *fp; - char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; - if ( fp == 0 ) - fp = fopen("events.log","wb"); - rs->buffered[rs->num++] = c; - if ( 1 ) - { - if ( sizeof(c) == 1 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); - else if ( sizeof(c) == 2 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); - else if ( sizeof(c) == 4 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); - else if ( sizeof(c) == 8 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - if ( fp != 0 ) - { - fprintf(fp,"%s\n",jprint(resobj,0)); - fflush(fp); - } - } - free_json(retjson); - } else fprintf(fp,"error parsing %s\n",retstr); - free(retstr); - } else fprintf(fp,"error issuing method %s\n",params); - return(retval); - } else return(0); -} - -int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize) -{ - char params[512],hexstr[64],*retstr; cJSON *retjson,*resobj; int32_t i,retval = -1; - memset(hexstr,0,sizeof(hexstr)); - for (i=0; i<8; i++) - { - sprintf(&hexstr[i<<1],"%02x",(uint8_t)(x & 0xff)); - x >>= 8; - } - sprintf(params,"[\"bet\",\"17\",\"[%.8f,%%22%s%%22]\"]",dstr(betsize),hexstr); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - //fprintf(stderr,"%s\n",jprint(resobj,0)); - } - free_json(retjson); - } - free(retstr); - } - return(retval); -} - -int prices(int argc, char **argv) -{ - struct games_state *rs = &globalR; - int32_t c,skipcount=0; uint32_t eventid = 0; - memset(rs,0,sizeof(*rs)); - rs->guiflag = 1; - rs->sleeptime = 1; // non-zero to allow refresh() - if ( argc >= 2 && strlen(argv[2]) == 64 ) - { -#ifdef _WIN32 -#ifdef _MSC_VER - rs->origseed = _strtoui64(argv[1], NULL, 10); -#else - rs->origseed = atol(argv[1]); // windows, but not MSVC -#endif // _MSC_VER -#else - rs->origseed = atol(argv[1]); // non-windows -#endif // _WIN32 - rs->seed = rs->origseed; - if ( argc >= 3 ) - { - strcpy(Gametxidstr,argv[2]); - fprintf(stderr,"setplayerdata %s\n",Gametxidstr); - if ( games_setplayerdata(rs,Gametxidstr) < 0 ) - { - fprintf(stderr,"invalid gametxid, or already started\n"); - return(-1); - } - } - } else rs->seed = 777; - gamesiterate(rs); - //gamesbailout(rs); - return 0; -} - -#endif - diff --git a/src/cc/games/prices.cpp b/src/cc/games/prices.cpp deleted file mode 100644 index a7eac9659..000000000 --- a/src/cc/games/prices.cpp +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -std::string MYCCLIBNAME = (char *)"prices"; - -#define PRICES_BETPERIOD 3 -UniValue games_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag); -extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33]; - -#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 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= hush_chainactive(height)) != 0 ) - { - if ( hush_blockload(block,pindex) == 0 ) - { - n = block.vtx.size(); - vini = 0; - memset(&refbar,0,sizeof(refbar)); - for (iter=0; iter<2; iter++) - { - for (i=0; i= 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 ) - { - 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); - } else return(-2); - } else return(-1); -} - -UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - UniValue result(UniValue::VOBJ); char acaddr[64]; CPubKey acpk,mypk,gamespk; int64_t prizefund = 0; int32_t height,nextheight = hush_nextheight(); - if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error"," no -ac_pubkey for price reference")); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - gamespk = GetUnspendable(cp,0); - acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); - Getscriptaddress(acaddr,CScript() << ParseHex(HexStr(acpk)) << OP_CHECKSIG); - if ( params != 0 && cJSON_GetArraySize(params) == 1 ) - { - height = juint(jitem(params,0),0); - result.push_back(Pair("height",(int64_t)height)); - if ( (prizefund= prices_blockinfo(height,acaddr)) < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("errorcode",prizefund)); - result.push_back(Pair("error","blockinfo error")); - } - else - { - // display bets - if ( height <= nextheight-PRICES_BETPERIOD ) - { - // settle bets by first nonzero reference bar - } - result.push_back(Pair("prizefund",ValueFromAmount(prizefund))); - result.push_back(Pair("result","success")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parse")); - } - return(result); -} - -UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; int64_t amount,inputsum; uint64_t price; CPubKey gamespk,mypk,acpk; - if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] == 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error"," no -ac_pubkey for price reference")); - return(result); - } - mypk = pubkey2pk(Mypubkey()); - gamespk = GetUnspendable(cp,0); - acpk = buf2pk(ASSETCHAINS_OVERRIDE_PUBKEY33); - if ( params != 0 && cJSON_GetArraySize(params) == 2 ) - { - amount = jdouble(jitem(params,0),0) * COIN + 0.0000000049; - if ( cclib_parsehash((uint8_t *)&price,jitem(params,1),8) < 0 ) - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parsehash")); - return(result); - } - if ( mypk == acpk ) - { - amount = 0; // i am the reference price feed - //fprintf(stderr,"i am the reference\n"); - } - //fprintf(stderr,"amount %llu price %llx\n",(long long)amount,(long long)price); - if ( (inputsum= AddNormalinputs(mtx,mypk,amount+GAMES_TXFEE,64)) >= amount+GAMES_TXFEE ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,gamespk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,GAMES_TXFEE,CScript() << OP_RETURN << price); - return(games_rawtxresult(result,rawtx,1)); - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","not enough funds")); - } - } - else - { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","couldnt parse")); - } - return(result); -} - -void prices_update(uint32_t timestamp,uint32_t uprice,int32_t ismine) -{ - //fprintf(stderr,"%s t%u %.4f %16llx\n",ismine!=0?"mine":"ext ",timestamp,(double)uprice/10000,(long long)((uint64_t)timestamp<<32) | uprice); -} - -// game specific code for daemon -void games_packitemstr(char *packitemstr,struct games_packitem *item) -{ - strcpy(packitemstr,""); -} - -int64_t games_cashout(struct games_player *P) -{ - int32_t dungeonlevel = P->dungeonlevel; int64_t mult=1000,cashout = 0; - cashout = (uint64_t)P->gold * mult * dungeonlevel * dungeonlevel; - return(cashout); -} - -void pricesplayerjson(UniValue &obj,struct games_player *P) -{ - obj.push_back(Pair("packsize",(int64_t)P->packsize)); - obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); - obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); - obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); - obj.push_back(Pair("level",(int64_t)P->level)); - obj.push_back(Pair("experience",(int64_t)P->experience)); - obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); -} - -int32_t disp_gamesplayer(char *str,struct games_player *P) -{ - str[0] = 0; - //if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 ) - // return(-1); - sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); - return(0); -} - -int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) -{ - uint256 gametxid; int32_t i,len; char str[67]; int64_t price; uint32_t eventid = 0; - if ( (len= payload.size()) > 36 ) - { - len -= 36; - for (i=0; i<32; i++) - ((uint8_t *)&gametxid)[i] = payload[len+i]; - eventid = (uint32_t)payload[len+32]; - eventid |= (uint32_t)payload[len+33] << 8; - eventid |= (uint32_t)payload[len+34] << 16; - eventid |= (uint32_t)payload[len+35] << 24; - for (i=0; i> 32),(uint32_t)(price & 0xffffffff),pk == pubkey2pk(Mypubkey())); - //fprintf(stderr,"%llu -> t%u %.4f ",(long long)price,(uint32_t)(price >> 32),(double)(price & 0xffffffff)/10000); - //fprintf(stderr," got payload, from %s %s/e%d\n",pubkey33_str(str,(uint8_t *)&pk),gametxid.GetHex().c_str(),eventid); - return(0); - } else return(-1); -} - -bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) -{ - return(true); -} - diff --git a/src/cc/games/prices.h b/src/cc/games/prices.h deleted file mode 100644 index 1debb9445..000000000 --- a/src/cc/games/prices.h +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#ifndef H_PRICES_H -#define H_PRICES_H - -/***************************************************************************/ -/** https://github.com/brenns10/tetris - @file main.c - @author Stephen Brennan - @date Created Wednesday, 10 June 2015 - @brief Main program for tetris. - @copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised - BSD License. See LICENSE.txt for details. - *******************************************************************************/ - -/* - Convert a tetromino type to its corresponding cell. - */ -#define TYPE_TO_CELL(x) ((x)+1) - -/* - Strings for how you would print a tetris board. - */ -#define TC_EMPTY_STR " " -#define TC_BLOCK_STR "\u2588" - -/* - Questions about a tetris cell. - */ -#define TC_IS_EMPTY(x) ((x) == TC_EMPTY) -#define TC_IS_FILLED(x) (!TC_IS_EMPTY(x)) - -/* - How many cells in a tetromino? - */ -#define TETRIS 4 -/* - How many tetrominos? - */ -#define NUM_TETROMINOS 7 -/* - How many orientations of a tetromino? - */ -#define NUM_ORIENTATIONS 4 - -/* - Level constants. - */ -#define MAX_LEVEL 19 -#define LINES_PER_LEVEL 10 - -/* - A "cell" is a 1x1 block within a tetris board. - */ -typedef enum { - TC_EMPTY, TC_CELLI, TC_CELLJ, TC_CELLL, TC_CELLO, TC_CELLS, TC_CELLT, TC_CELLZ -} tetris_cell; - -/* - A "type" is a type/shape of a tetromino. Not including orientation. - */ -typedef enum { - TET_I, TET_J, TET_L, TET_O, TET_S, TET_T, TET_Z -} tetris_type; - -/* - A row,column pair. Negative numbers allowed, because we need them for - offsets. - */ -typedef struct { - int row; - int col; -} tetris_location; - -/* - A "block" is a struct that contains information about a tetromino. - Specifically, what type it is, what orientation it has, and where it is. - */ -typedef struct { - int typ; - int ori; - tetris_location loc; -} tetris_block; - -/* - All possible moves to give as input to the game. - */ -typedef enum { - TM_LEFT, TM_RIGHT, TM_CLOCK, TM_COUNTER, TM_DROP, TM_HOLD, TM_NONE -} tetris_move; - -/* - A game object! - */ -typedef struct { - /* - Game board stuff: - */ - int rows; - int cols; - /* - Scoring information: - */ - int points; - int level; - /* - Falling block is the one currently going down. Next block is the one that - will be falling after this one. Stored is the block that you can swap out. - */ - tetris_block falling; - tetris_block next; - tetris_block stored; - /* - Number of game ticks until the block will move down. - */ - int ticks_till_gravity; - /* - Number of lines until you advance to the next level. - */ - int lines_remaining; - char board[]; -} tetris_game; - -/* - This array stores all necessary information about the cells that are filled by - each tetromino. The first index is the type of the tetromino (i.e. shape, - e.g. I, J, Z, etc.). The next index is the orientation (0-3). The final - array contains 4 tetris_location objects, each mapping to an offset from a - point on the upper left that is the tetromino "origin". - */ -extern const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS]; - -/* - This array tells you how many ticks per gravity by level. Decreases as level - increases, to add difficulty. - */ -extern const int GRAVITY_LEVEL[MAX_LEVEL+1]; - -// Data structure manipulation. -void tg_init(tetris_game *obj, int rows, int cols); -tetris_game *tg_create(struct games_state *rs,int rows, int cols); -void tg_destroy(tetris_game *obj); -void tg_delete(tetris_game *obj); -tetris_game *tg_load(FILE *f); -void tg_save(tetris_game *obj, FILE *f); - -// Public methods not related to memory: -char tg_get(tetris_game *obj, int row, int col); -bool tg_check(tetris_game *obj, int row, int col); -bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move); -void tg_print(tetris_game *obj, FILE *f); - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -#define GAMENAME "prices" // name of executable -#define GAMEMAIN prices // main program of game -#define GAMEPLAYERJSON pricesplayerjson // displays game specific json -#define GAMEDATA pricesdata // extracts data from game specific variables into games_state -#define CHAINNAME "PRICES" // -ac_name= -typedef uint64_t gamesevent; // can be 8, 16, 32, or 64 bits - -#define MAXPACK 23 -struct games_packitem -{ - int32_t type,launch,count,which,hplus,dplus,arm,flags,group; - char damage[8],hurldmg[8]; -}; - -struct games_player -{ - int32_t gold,hitpoints,strength,level,experience,packsize,dungeonlevel,amulet; - struct games_packitem gamespack[MAXPACK]; -}; - -struct games_state -{ - uint64_t seed,origseed; - char *keystrokeshex; - uint32_t needflush,replaydone; - int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum; - FILE *logfp; - struct games_player P; - gamesevent buffered[5000],*keystrokes; - uint8_t playerdata[8192]; -}; -extern struct games_state globalR; -void *gamesiterate(struct games_state *rs); -int32_t flushkeystrokes(struct games_state *rs,int32_t waitflag); - -void games_packitemstr(char *packitemstr,struct games_packitem *item); -uint64_t _games_rngnext(uint64_t initseed); -int32_t games_replay2(uint8_t *newdata,uint64_t seed,gamesevent *keystrokes,int32_t num,struct games_player *player,int32_t sleepmillis); -gamesevent games_revendian(gamesevent revx); -int32_t disp_gamesplayer(char *str,struct games_player *P); - -#endif - diff --git a/src/cc/games/tetris.c b/src/cc/games/tetris.c deleted file mode 100644 index d7de6f278..000000000 --- a/src/cc/games/tetris.c +++ /dev/null @@ -1,907 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - -#include "tetris.h" - -/* - In order to port a game into gamesCC, the RNG needs to be seeded with the gametxid seed, also events needs to be broadcast using issue_games_events. Also the game engine needs to be daemonized, preferably by putting all globals into a single data structure. - - also, the standalone game needs to support argv of seed gametxid, along with replay args - */ - -int random_tetromino(struct games_state *rs) -{ - rs->seed = _games_rngnext(rs->seed); - return(rs->seed % NUM_TETROMINOS); -} - -int32_t tetrisdata(struct games_player *P,void *ptr) -{ - tetris_game *tg = (tetris_game *)ptr; - P->gold = tg->points; - P->dungeonlevel = tg->level; - //fprintf(stderr,"score.%d level.%d\n",tg->points,tg->level); - return(0); -} - -/***************************************************************************/ -/** https://github.com/brenns10/tetris - @file main.c - @author Stephen Brennan - @date Created Wednesday, 10 June 2015 - @brief Main program for tetris. - @copyright Copyright (c) 2015, Stephen Brennan. Released under the Revised - BSD License. See LICENSE.txt for details. - *******************************************************************************/ - - -#include // for FILE -#include // for bool -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_GAMESCC -#include "../rogue/cursesd.h" -#else -#include -#endif - - -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) - -/******************************************************************************* - Array Definitions - *******************************************************************************/ - -const tetris_location TETROMINOS[NUM_TETROMINOS][NUM_ORIENTATIONS][TETRIS] = -{ - // I - {{{1, 0}, {1, 1}, {1, 2}, {1, 3}}, - {{0, 2}, {1, 2}, {2, 2}, {3, 2}}, - {{3, 0}, {3, 1}, {3, 2}, {3, 3}}, - {{0, 1}, {1, 1}, {2, 1}, {3, 1}}}, - // J - {{{0, 0}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {2, 1}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 2}}, - {{0, 1}, {1, 1}, {2, 0}, {2, 1}}}, - // L - {{{0, 2}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {1, 1}, {2, 1}, {2, 2}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 0}}, - {{0, 0}, {0, 1}, {1, 1}, {2, 1}}}, - // O - {{{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}, - {{0, 1}, {0, 2}, {1, 1}, {1, 2}}}, - // S - {{{0, 1}, {0, 2}, {1, 0}, {1, 1}}, - {{0, 1}, {1, 1}, {1, 2}, {2, 2}}, - {{1, 1}, {1, 2}, {2, 0}, {2, 1}}, - {{0, 0}, {1, 0}, {1, 1}, {2, 1}}}, - // T - {{{0, 1}, {1, 0}, {1, 1}, {1, 2}}, - {{0, 1}, {1, 1}, {1, 2}, {2, 1}}, - {{1, 0}, {1, 1}, {1, 2}, {2, 1}}, - {{0, 1}, {1, 0}, {1, 1}, {2, 1}}}, - // Z - {{{0, 0}, {0, 1}, {1, 1}, {1, 2}}, - {{0, 2}, {1, 1}, {1, 2}, {2, 1}}, - {{1, 0}, {1, 1}, {2, 1}, {2, 2}}, - {{0, 1}, {1, 0}, {1, 1}, {2, 0}}}, -}; - -const int GRAVITY_LEVEL[MAX_LEVEL+1] = { - // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, - //10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 30, 28, 26, 24, 22, 20, 16, 12, 8, 4 -}; - -/******************************************************************************* - Helper Functions for Blocks - *******************************************************************************/ - -void sleep_milli(int milliseconds) -{ - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = milliseconds * 1000 * 1000; - nanosleep(&ts, NULL); -} - -/* - Return the block at the given row and column. - */ -char tg_get(tetris_game *obj, int row, int column) -{ - return obj->board[obj->cols * row + column]; -} - -/* - Set the block at the given row and column. - */ -static void tg_set(tetris_game *obj, int row, int column, char value) -{ - obj->board[obj->cols * row + column] = value; -} - -/* - Check whether a row and column are in bounds. - */ -bool tg_check(tetris_game *obj, int row, int col) -{ - return 0 <= row && row < obj->rows && 0 <= col && col < obj->cols; -} - -/* - Place a block onto the board. - */ -static void tg_put(tetris_game *obj, tetris_block block) -{ - int i; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, - TYPE_TO_CELL(block.typ)); - } -} - -/* - Clear a block out of the board. - */ -static void tg_remove(tetris_game *obj, tetris_block block) -{ - int i; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - tg_set(obj, block.loc.row + cell.row, block.loc.col + cell.col, TC_EMPTY); - } -} - -/* - Check if a block can be placed on the board. - */ -static bool tg_fits(tetris_game *obj, tetris_block block) -{ - int i, r, c; - for (i = 0; i < TETRIS; i++) { - tetris_location cell = TETROMINOS[block.typ][block.ori][i]; - r = block.loc.row + cell.row; - c = block.loc.col + cell.col; - if (!tg_check(obj, r, c) || TC_IS_FILLED(tg_get(obj, r, c))) { - return false; - } - } - return true; -} - -/* - Create a new falling block and populate the next falling block with a random - one. - */ -static void tg_new_falling(struct games_state *rs,tetris_game *obj) -{ - // Put in a new falling tetromino. - obj->falling = obj->next; - obj->next.typ = random_tetromino(rs); - obj->next.ori = 0; - obj->next.loc.row = 0; - obj->next.loc.col = obj->cols/2 - 2; -} - -/******************************************************************************* - Game Turn Helpers - *******************************************************************************/ - -/* - Tick gravity, and move the block down if gravity should act. - */ -static void tg_do_gravity_tick(struct games_state *rs,tetris_game *obj) -{ - obj->ticks_till_gravity--; - if (obj->ticks_till_gravity <= 0) { - tg_remove(obj, obj->falling); - obj->falling.loc.row++; - if (tg_fits(obj, obj->falling)) { - obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; - } else { - obj->falling.loc.row--; - tg_put(obj, obj->falling); - - tg_new_falling(rs,obj); - } - tg_put(obj, obj->falling); - } -} - -/* - Move the falling tetris block left (-1) or right (+1). - */ -static void tg_move(tetris_game *obj, int direction) -{ - tg_remove(obj, obj->falling); - obj->falling.loc.col += direction; - if (!tg_fits(obj, obj->falling)) { - obj->falling.loc.col -= direction; - } - tg_put(obj, obj->falling); -} - -/* - Send the falling tetris block to the bottom. - */ -static void tg_down(struct games_state *rs,tetris_game *obj) -{ - tg_remove(obj, obj->falling); - while (tg_fits(obj, obj->falling)) { - obj->falling.loc.row++; - } - obj->falling.loc.row--; - tg_put(obj, obj->falling); - tg_new_falling(rs,obj); -} - -/* - Rotate the falling block in either direction (+/-1). - */ -static void tg_rotate(tetris_game *obj, int direction) -{ - tg_remove(obj, obj->falling); - - while (true) { - obj->falling.ori = (obj->falling.ori + direction) % NUM_ORIENTATIONS; - - // If the new orientation fits, we're done. - if (tg_fits(obj, obj->falling)) - break; - - // Otherwise, try moving left to make it fit. - obj->falling.loc.col--; - if (tg_fits(obj, obj->falling)) - break; - - // Finally, try moving right to make it fit. - obj->falling.loc.col += 2; - if (tg_fits(obj, obj->falling)) - break; - - // Put it back in its original location and try the next orientation. - obj->falling.loc.col--; - // Worst case, we come back to the original orientation and it fits, so this - // loop will terminate. - } - - tg_put(obj, obj->falling); -} - -/* - Swap the falling block with the block in the hold buffer. - */ -static void tg_hold(struct games_state *rs,tetris_game *obj) -{ - tg_remove(obj, obj->falling); - if (obj->stored.typ == -1) { - obj->stored = obj->falling; - tg_new_falling(rs,obj); - } else { - int typ = obj->falling.typ, ori = obj->falling.ori; - obj->falling.typ = obj->stored.typ; - obj->falling.ori = obj->stored.ori; - obj->stored.typ = typ; - obj->stored.ori = ori; - while (!tg_fits(obj, obj->falling)) { - obj->falling.loc.row--; - if (tg_fits(obj, obj->falling)) { - break; - } - obj->falling.loc.col--; - if (tg_fits(obj, obj->falling)) { - break; - } - obj->falling.loc.col += 2; - } - } - tg_put(obj, obj->falling); -} - -/* - Perform the action specified by the move. - */ -static void tg_handle_move(struct games_state *rs,tetris_game *obj, tetris_move move) -{ - switch (move) { - case TM_LEFT: - //fprintf(stderr,"LEFT "); - tg_move(obj, -1); - break; - case TM_RIGHT: - //fprintf(stderr,"RIGHT "); - tg_move(obj, 1); - break; - case TM_DROP: - tg_down(rs,obj); - break; - case TM_CLOCK: - tg_rotate(obj, 1); - break; - case TM_COUNTER: - tg_rotate(obj, -1); - break; - case TM_HOLD: - tg_hold(rs,obj); - break; - default: - // pass - break; - } -} - -/* - Return true if line i is full. - */ -static bool tg_line_full(tetris_game *obj, int i) -{ - int j; - for (j = 0; j < obj->cols; j++) { - if (TC_IS_EMPTY(tg_get(obj, i, j))) - return false; - } - return true; -} - -/* - Shift every row above r down one. - */ -static void tg_shift_lines(tetris_game *obj, int r) -{ - int i, j; - for (i = r-1; i >= 0; i--) { - for (j = 0; j < obj->cols; j++) { - tg_set(obj, i+1, j, tg_get(obj, i, j)); - tg_set(obj, i, j, TC_EMPTY); - } - } -} - -/* - Find rows that are filled, remove them, shift, and return the number of - cleared rows. - */ -static int tg_check_lines(tetris_game *obj) -{ - int i, nlines = 0; - tg_remove(obj, obj->falling); // don't want to mess up falling block - - for (i = obj->rows-1; i >= 0; i--) { - if (tg_line_full(obj, i)) { - tg_shift_lines(obj, i); - i++; // do this line over again since they're shifted - nlines++; - } - } - - tg_put(obj, obj->falling); // replace - return nlines; -} - -/* - Adjust the score for the game, given how many lines were just cleared. - */ -static void tg_adjust_score(tetris_game *obj, int lines_cleared) -{ - static int line_multiplier[] = {0, 40, 100, 300, 1200}; - obj->points += line_multiplier[lines_cleared] * (obj->level + 1); - if (lines_cleared >= obj->lines_remaining) { - obj->level = MIN(MAX_LEVEL, obj->level + 1); - lines_cleared -= obj->lines_remaining; - obj->lines_remaining = LINES_PER_LEVEL - lines_cleared; - } else { - obj->lines_remaining -= lines_cleared; - } -} - -/* - Return true if the game is over. - */ -static bool tg_game_over(tetris_game *obj) -{ - int i, j; - bool over = false; - tg_remove(obj, obj->falling); - for (i = 0; i < 2; i++) { - for (j = 0; j < obj->cols; j++) { - if (TC_IS_FILLED(tg_get(obj, i, j))) { - over = true; - } - } - } - tg_put(obj, obj->falling); - return over; -} - -/******************************************************************************* - Main Public Functions - *******************************************************************************/ - -/* - Do a single game tick: process gravity, user input, and score. Return true if - the game is still running, false if it is over. - */ -bool tg_tick(struct games_state *rs,tetris_game *obj, tetris_move move) -{ - int lines_cleared; - // Handle gravity. - tg_do_gravity_tick(rs,obj); - - // Handle input. - tg_handle_move(rs,obj, move); - - // Check for cleared lines - lines_cleared = tg_check_lines(obj); - - tg_adjust_score(obj, lines_cleared); - - // Return whether the game will continue (NOT whether it's over) - return !tg_game_over(obj); -} - -void tg_init(struct games_state *rs,tetris_game *obj, int rows, int cols) -{ - // Initialization logic - obj->rows = rows; - obj->cols = cols; - //obj->board = (char *)malloc(rows * cols); - memset(obj->board, TC_EMPTY, rows * cols); - obj->points = 0; - obj->level = 0; - obj->ticks_till_gravity = GRAVITY_LEVEL[obj->level]; - obj->lines_remaining = LINES_PER_LEVEL; - //srand(time(NULL)); - tg_new_falling(rs,obj); - tg_new_falling(rs,obj); - obj->stored.typ = -1; - obj->stored.ori = 0; - obj->stored.loc.row = 0; - obj->next.loc.col = obj->cols/2 - 2; - //printf("%d", obj->falling.loc.col); -} - -tetris_game *tg_create(struct games_state *rs,int rows, int cols) -{ - tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game) + rows*cols); - tg_init(rs,obj, rows, cols); - return obj; -} - -/*void tg_destroy(tetris_game *obj) -{ - // Cleanup logic - free(obj->board); -}*/ - -void tg_delete(tetris_game *obj) { - //tg_destroy(obj); - free(obj); -} - -/* - Load a game from a file. - -tetris_game *tg_load(FILE *f) -{ - tetris_game *obj = (tetris_game *)malloc(sizeof(tetris_game)); - if (fread(obj, sizeof(tetris_game), 1, f) != 1 ) - { - fprintf(stderr,"read game error\n"); - free(obj); - obj = 0; - } - else - { - obj->board = (char *)malloc(obj->rows * obj->cols); - if (fread(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) - { - fprintf(stderr,"fread error\n"); - free(obj->board); - free(obj); - obj = 0; - } - } - return obj; -}*/ - -/* - Save a game to a file. - -void tg_save(tetris_game *obj, FILE *f) -{ - if (fwrite(obj, sizeof(tetris_game), 1, f) != 1 ) - fprintf(stderr,"error writing tetrisgame\n"); - else if (fwrite(obj->board, sizeof(char), obj->rows * obj->cols, f) != obj->rows * obj->cols ) - fprintf(stderr,"error writing board\n"); -}*/ - -/* - Print a game board to a file. Really just for early debugging. - */ -void tg_print(tetris_game *obj, FILE *f) { - int i, j; - for (i = 0; i < obj->rows; i++) { - for (j = 0; j < obj->cols; j++) { - if (TC_IS_EMPTY(tg_get(obj, i, j))) { - fputs(TC_EMPTY_STR, f); - } else { - fputs(TC_BLOCK_STR, f); - } - } - fputc('\n', f); - } -} - -/* - 2 columns per cell makes the game much nicer. - */ -#define COLS_PER_CELL 2 -/* - Macro to print a cell of a specific type to a window. - */ -#define ADD_BLOCK(w,x) waddch((w),' '|A_REVERSE|COLOR_PAIR(x)); \ -waddch((w),' '|A_REVERSE|COLOR_PAIR(x)) -#define ADD_EMPTY(w) waddch((w), ' '); waddch((w), ' ') - -/* - Print the tetris board onto the ncurses window. - */ -void display_board(WINDOW *w, tetris_game *obj) -{ - int i, j; - box(w, 0, 0); - for (i = 0; i < obj->rows; i++) { - wmove(w, 1 + i, 1); - for (j = 0; j < obj->cols; j++) { - if (TC_IS_FILLED(tg_get(obj, i, j))) { - ADD_BLOCK(w,tg_get(obj, i, j)); - } else { - ADD_EMPTY(w); - } - } - } - wnoutrefresh(w); -} - -/* - Display a tetris piece in a dedicated window. - */ -void display_piece(WINDOW *w, tetris_block block) -{ - int b; - tetris_location c; - wclear(w); - box(w, 0, 0); - if (block.typ == -1) { - wnoutrefresh(w); - return; - } - for (b = 0; b < TETRIS; b++) { - c = TETROMINOS[block.typ][block.ori][b]; - wmove(w, c.row + 1, c.col * COLS_PER_CELL + 1); - ADD_BLOCK(w, TYPE_TO_CELL(block.typ)); - } - wnoutrefresh(w); -} - -/* - Display score information in a dedicated window. - */ -void display_score(WINDOW *w, tetris_game *tg) -{ - wclear(w); - box(w, 0, 0); - wprintw(w, (char *)"Score\n%d\n", tg->points); - wprintw(w, (char *)"Level\n%d\n", tg->level); - wprintw(w, (char *)"Lines\n%d\n", tg->lines_remaining); - wnoutrefresh(w); -} - -/* - Save and exit the game. - -void save(tetris_game *game, WINDOW *w) -{ - FILE *f; - - wclear(w); - box(w, 0, 0); // return the border - wmove(w, 1, 1); - wprintw(w, (char *)"Save and exit? [Y/n] "); - wrefresh(w); - timeout(-1); - if (getch() == 'n') { - timeout(0); - return; - } - f = fopen("tetris.save", "w"); - tg_save(game, f); - fclose(f); - tg_delete(game); - endwin(); - fprintf(stderr,"Game saved to \"tetris.save\".\n"); - fprintf(stderr,"Resume by passing the filename as an argument to this program.\n"); - exit(EXIT_SUCCESS); -}*/ - -/* - Do the NCURSES initialization steps for color blocks. - */ -void init_colors(void) -{ - start_color(); - //init_color(COLOR_ORANGE, 1000, 647, 0); - init_pair(TC_CELLI, COLOR_CYAN, COLOR_BLACK); - init_pair(TC_CELLJ, COLOR_BLUE, COLOR_BLACK); - init_pair(TC_CELLL, COLOR_WHITE, COLOR_BLACK); - init_pair(TC_CELLO, COLOR_YELLOW, COLOR_BLACK); - init_pair(TC_CELLS, COLOR_GREEN, COLOR_BLACK); - init_pair(TC_CELLT, COLOR_MAGENTA, COLOR_BLACK); - init_pair(TC_CELLZ, COLOR_RED, COLOR_BLACK); -} - -struct games_state globalR; -extern char Gametxidstr[]; -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c); -gamesevent games_readevent(struct games_state *rs); - -void *gamesiterate(struct games_state *rs) -{ - uint32_t counter = 0; bool running = true; tetris_move move = TM_NONE; - gamesevent c; uint16_t skipcount=0; int32_t prevlevel; uint32_t eventid = 0; tetris_game *tg; - WINDOW *board, *next, *hold, *score; - if ( rs->guiflag != 0 || rs->sleeptime != 0 ) - { - // NCURSES initialization: - initscr(); // initialize curses - cbreak(); // pass key presses to program, but not signals - noecho(); // don't echo key presses to screen - keypad(stdscr, TRUE); // allow arrow keys - timeout(0); // no blocking on getch() - curs_set(0); // set the cursor to invisible - init_colors(); // setup tetris colors - } - tg = tg_create(rs,22, 10); - prevlevel = tg->level; - // Create windows for each section of the interface. - board = newwin(tg->rows + 2, 2 * tg->cols + 2, 0, 0); - next = newwin(6, 10, 0, 2 * (tg->cols + 1) + 1); - hold = newwin(6, 10, 7, 2 * (tg->cols + 1) + 1); - score = newwin(6, 10, 14, 2 * (tg->cols + 1 ) + 1); - while ( running != 0 ) - { - running = tg_tick(rs,tg,move); - if ( 1 && (rs->guiflag != 0 || rs->sleeptime != 0) ) - { - display_board(board,tg); - display_piece(next,tg->next); - display_piece(hold,tg->stored); - display_score(score,tg); - } - if ( rs->guiflag != 0 ) - { -#ifdef STANDALONE - sleep_milli(15); - if ( (counter++ % 10) == 0 ) - doupdate(); - c = games_readevent(rs); - if ( c <= 0x7f || skipcount == 0x3fff ) - { - if ( skipcount > 0 ) - issue_games_events(rs,Gametxidstr,eventid-skipcount,skipcount | 0x4000); - if ( c <= 0x7f ) - issue_games_events(rs,Gametxidstr,eventid,c); - if ( tg->level != prevlevel ) - { - flushkeystrokes(rs,0); - prevlevel = tg->level; - } - skipcount = 0; - } else skipcount++; -#endif - } - else - { - if ( rs->replaydone != 0 ) - break; - if ( rs->sleeptime != 0 ) - { - sleep_milli(1); - if ( (counter++ % 20) == 0 ) - doupdate(); - } - if ( skipcount == 0 ) - { - c = games_readevent(rs); - //fprintf(stderr,"%04x score.%d level.%d\n",c,tg->points,tg->level); - if ( (c & 0x4000) == 0x4000 ) - { - skipcount = (c & 0x3fff); - c = 'S'; - } - } - if ( skipcount > 0 ) - skipcount--; - } - eventid++; - switch ( c ) - { - case 'h': - move = TM_LEFT; - break; - case 'l': - move = TM_RIGHT; - break; - case 'k': - move = TM_CLOCK; - break; - case 'j': - move = TM_DROP; - break; - case 'q': - running = false; - move = TM_NONE; - break; - /*case 'p': - wclear(board); - box(board, 0, 0); - wmove(board, tg->rows/2, (tg->cols*COLS_PER_CELL-6)/2); - wprintw(board, "PAUSED"); - wrefresh(board); - timeout(-1); - getch(); - timeout(0); - move = TM_NONE; - break; - case 's': - save(tg, board); - move = TM_NONE; - break;*/ - case ' ': - move = TM_HOLD; - break; - default: - move = TM_NONE; - } - } - return(tg); -} - -#ifdef STANDALONE -/* - Main tetris game! - */ -#include "dapps/dappstd.c" - - -char *clonestr(char *str) -{ - char *clone; int32_t len; - if ( str == 0 || str[0] == 0 ) - { - printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif - str = (char *)""; - } - len = strlen(str); - clone = (char *)calloc(1,len+16); - strcpy(clone,str); - return(clone); -} - -int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eventid,gamesevent c) -{ - static FILE *fp; - char params[512],*retstr; cJSON *retjson,*resobj; int32_t retval = -1; - if ( fp == 0 ) - fp = fopen("events.log","wb"); - rs->buffered[rs->num++] = c; - if ( 0 ) - { - if ( sizeof(c) == 1 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%02x%%22,%%22%s%%22,%u]\"]",(uint8_t)c&0xff,gametxidstr,eventid); - else if ( sizeof(c) == 2 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%04x%%22,%%22%s%%22,%u]\"]",(uint16_t)c&0xffff,gametxidstr,eventid); - else if ( sizeof(c) == 4 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); - else if ( sizeof(c) == 8 ) - sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (resobj= jobj(retjson,(char *)"result")) != 0 ) - { - retval = 0; - if ( fp != 0 ) - { - fprintf(fp,"%s\n",jprint(resobj,0)); - fflush(fp); - } - } - free_json(retjson); - } else fprintf(fp,"error parsing %s\n",retstr); - free(retstr); - } else fprintf(fp,"error issuing method %s\n",params); - return(retval); - } else return(0); -} - -int tetris(int argc, char **argv) -{ - struct games_state *rs = &globalR; - int32_t c,skipcount=0; uint32_t eventid = 0; tetris_game *tg = 0; - memset(rs,0,sizeof(*rs)); - rs->guiflag = 1; - rs->sleeptime = 1; // non-zero to allow refresh() - if ( argc >= 2 && strlen(argv[2]) == 64 ) - { -#ifdef _WIN32 -#ifdef _MSC_VER - rs->origseed = _strtoui64(argv[1], NULL, 10); -#else - rs->origseed = atol(argv[1]); // windows, but not MSVC -#endif // _MSC_VER -#else - rs->origseed = atol(argv[1]); // non-windows -#endif // _WIN32 - rs->seed = rs->origseed; - if ( argc >= 3 ) - { - strcpy(Gametxidstr,argv[2]); - fprintf(stderr,"setplayerdata %s\n",Gametxidstr); - if ( games_setplayerdata(rs,Gametxidstr) < 0 ) - { - fprintf(stderr,"invalid gametxid, or already started\n"); - return(-1); - } - } - } else rs->seed = 777; - - /* Load file if given a filename. - if (argc >= 2) { - FILE *f = fopen(argv[1], "r"); - if (f == NULL) { - perror("tetris"); - exit(EXIT_FAILURE); - } - tg = tg_load(f); - fclose(f); - } else { - // Otherwise create new game. - tg = tg_create(rs,22, 10); - }*/ - - // Game loop - tg = (tetris_game *)gamesiterate(rs); - gamesbailout(rs); - // Deinitialize NCurses - wclear(stdscr); - endwin(); - // Output ending message. - printf("Game over!\n"); - printf("You finished with %d points on level %d.\n", tg->points, tg->level); - - // Deinitialize Tetris - tg_delete(tg); - return 0; -} - -#endif - diff --git a/src/cc/games/tetris.cpp b/src/cc/games/tetris.cpp deleted file mode 100644 index b0ffaff56..000000000 --- a/src/cc/games/tetris.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -std::string MYCCLIBNAME = (char *)"gamescc"; - -// game specific code for daemon -void games_packitemstr(char *packitemstr,struct games_packitem *item) -{ - strcpy(packitemstr,""); -} - -int64_t games_cashout(struct games_player *P) -{ - int32_t dungeonlevel = P->dungeonlevel; int64_t mult=10000,cashout = 0; - cashout = (uint64_t)P->gold * mult; - return(cashout); -} - -void tetrisplayerjson(UniValue &obj,struct games_player *P) -{ - obj.push_back(Pair("packsize",(int64_t)P->packsize)); - obj.push_back(Pair("hitpoints",(int64_t)P->hitpoints)); - obj.push_back(Pair("strength",(int64_t)(P->strength&0xffff))); - obj.push_back(Pair("maxstrength",(int64_t)(P->strength>>16))); - obj.push_back(Pair("level",(int64_t)P->level)); - obj.push_back(Pair("experience",(int64_t)P->experience)); - obj.push_back(Pair("dungeonlevel",(int64_t)P->dungeonlevel)); -} - -int32_t disp_gamesplayer(char *str,struct games_player *P) -{ - str[0] = 0; - //if ( P->gold <= 0 )//|| P->hitpoints <= 0 || (P->strength&0xffff) <= 0 || P->level <= 0 || P->experience <= 0 || P->dungeonlevel <= 0 ) - // return(-1); - sprintf(str," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",P->gold,P->hitpoints,P->strength&0xffff,P->strength>>16,P->level,P->experience,P->dungeonlevel); - return(0); -} - -int32_t games_payloadrecv(CPubKey pk,uint32_t timestamp,std::vector payload) -{ - uint256 gametxid; int32_t i,len; char str[67]; uint32_t eventid = 0; - if ( (len= payload.size()) > 36 ) - { - len -= 36; - for (i=0; i<32; i++) - ((uint8_t *)&gametxid)[i] = payload[len+i]; - eventid = (uint32_t)payload[len+32]; - eventid |= (uint32_t)payload[len+33] << 8; - eventid |= (uint32_t)payload[len+34] << 16; - eventid |= (uint32_t)payload[len+35] << 24; - //for (i=0; i -#include -#define GAMES_RNGMULT 11109 -#define GAMES_RNGOFFSET 13849 -#define GAMES_MAXRNGS 10000 - -#ifndef STANDALONE - -#define ENABLE_WALLET -extern CWallet* pwalletMain; - -#include "CCinclude.h" -#include "secp256k1.h" - - -#define EVAL_GAMES (EVAL_FAUCET2+1) -#define GAMES_TXFEE 10000 -#define GAMES_MAXITERATIONS 777 -#define GAMES_MAXKEYSTROKESGAP 60 -#define GAMES_MAXPLAYERS 64 -#define GAMES_REGISTRATIONSIZE (100 * 10000) -#define GAMES_REGISTRATION 1 - - -#define MYCCNAME "games" - -std::string Games_pname; - -#define RPC_FUNCS \ - { (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"fund", (char *)"amount", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"players", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"games", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"pending", (char *)"no params", 0, 0, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"setname", (char *)"pname", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"newgame", (char *)"maxplayers,buyin", 2, 2, 'C', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"playerinfo", (char *)"playertxid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"gameinfo", (char *)"gametxid", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"keystrokes", (char *)"txid,hexstr", 2, 2, 'K', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"bailout", (char *)"gametxid", 1, 1, 'Q', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"highlander", (char *)"gametxid", 1, 1, 'H', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"events", (char *)"eventshex [gametxid [eventid]]", 1, 3, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"bet", (char *)"amount hexstr", 2, 2, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"settle", (char *)"height", 1, 1, ' ', EVAL_GAMES }, \ - { (char *)MYCCNAME, (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_GAMES }, - -bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx); -UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_fund(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_players(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_bet(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); -UniValue games_settle(uint64_t txfee,struct CCcontract_info *cp,cJSON *params); - -#define CUSTOM_DISPATCH \ -if ( cp->evalcode == EVAL_GAMES ) \ -{ \ - if ( strcmp(method,"rng") == 0 ) \ - return(games_rng(txfee,cp,params)); \ - else if ( strcmp(method,"rngnext") == 0 ) \ - return(games_rngnext(txfee,cp,params)); \ - else if ( strcmp(method,"newgame") == 0 ) \ - return(games_newgame(txfee,cp,params)); \ - else if ( strcmp(method,"gameinfo") == 0 ) \ - return(games_gameinfo(txfee,cp,params)); \ - else if ( strcmp(method,"register") == 0 ) \ - return(games_register(txfee,cp,params)); \ - else if ( strcmp(method,"events") == 0 ) \ - return(games_events(txfee,cp,params)); \ - else if ( strcmp(method,"players") == 0 ) \ - return(games_players(txfee,cp,params)); \ - else if ( strcmp(method,"games") == 0 ) \ - return(games_games(txfee,cp,params)); \ - else if ( strcmp(method,"pending") == 0 ) \ - return(games_pending(txfee,cp,params)); \ - else if ( strcmp(method,"setname") == 0 ) \ - return(games_setname(txfee,cp,params)); \ - else if ( strcmp(method,"playerinfo") == 0 ) \ - return(games_playerinfo(txfee,cp,params)); \ - else if ( strcmp(method,"keystrokes") == 0 ) \ - return(games_keystrokes(txfee,cp,params)); \ - else if ( strcmp(method,"extract") == 0 ) \ - return(games_extract(txfee,cp,params)); \ - else if ( strcmp(method,"bailout") == 0 ) \ - return(games_bailout(txfee,cp,params)); \ - else if ( strcmp(method,"highlander") == 0 ) \ - return(games_highlander(txfee,cp,params)); \ - else if ( strcmp(method,"fund") == 0 ) \ - return(games_fund(txfee,cp,params)); \ - else if ( strcmp(method,"bet") == 0 ) \ - return(games_bet(txfee,cp,params)); \ - else if ( strcmp(method,"settle") == 0 ) \ - return(games_settle(txfee,cp,params)); \ - else \ - { \ - result.push_back(Pair("result","error")); \ - result.push_back(Pair("error","invalid gamescc method")); \ - return(result); \ - } \ -} -#endif - -#endif diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 1c050c112..6aafe5fd5 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -202,14 +202,6 @@ struct secp256k1_context_struct { //#include "../secp256k1/include/secp256k1_schnorrsig.h" #include "../secp256k1/include/secp256k1_musig.h" - -extern "C" int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); -extern "C" int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_schnorrsig *sig, const unsigned char *msg32, const secp256k1_pubkey *pk); -extern "C" int secp256k1_schnorrsig_parse(const secp256k1_context* ctx, secp256k1_schnorrsig* sig, const unsigned char *in64); -extern "C" int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_pubkey *combined_pk, unsigned char *pk_hash32, const secp256k1_pubkey *pubkeys, size_t n_pubkeys); -extern "C" int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_musig_session *session, secp256k1_musig_session_signer_data *signers, unsigned char *nonce_commitment32, const unsigned char *session_id32, const unsigned char *msg32, const secp256k1_pubkey *combined_pk, const unsigned char *pk_hash32, size_t n_signers, size_t my_index, const unsigned char *seckey); -extern "C" int secp256k1_schnorrsig_serialize(const secp256k1_context* ctx, unsigned char *out64, const secp256k1_schnorrsig* sig); - #define MUSIG_PREVN 0 // for now, just use vout0 for the musig output #define MUSIG_TXFEE 10000 @@ -243,631 +235,107 @@ struct musig_info *musig_infocreate(int32_t myind,int32_t num) void musig_infofree(struct musig_info *mp) { - if ( mp->partial_sig != 0 ) - { - GetRandBytes((uint8_t *)mp->partial_sig,mp->num*sizeof(*mp->partial_sig)); - free(mp->partial_sig); - } - if ( mp->nonces != 0 ) - { - GetRandBytes((uint8_t *)mp->nonces,mp->num*sizeof(*mp->nonces)); - free(mp->nonces); - } - if ( mp->signer_data != 0 ) - { - GetRandBytes((uint8_t *)mp->signer_data,mp->num*sizeof(*mp->signer_data)); - free(mp->signer_data); - } - if ( mp->nonce_commitments != 0 ) - { - GetRandBytes((uint8_t *)mp->nonce_commitments,mp->num*32); - free(mp->nonce_commitments); - } - if ( mp->commitment_ptrs != 0 ) - { - GetRandBytes((uint8_t *)mp->commitment_ptrs,mp->num*sizeof(*mp->commitment_ptrs)); - free(mp->commitment_ptrs); - } - GetRandBytes((uint8_t *)mp,sizeof(*mp)); - free(mp); } CScript musig_sendopret(uint8_t funcid,CPubKey pk) { - CScript opret; uint8_t evalcode = EVAL_MUSIG; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk); + CScript opret; return(opret); } uint8_t musig_sendopretdecode(CPubKey &pk,CScript scriptPubKey) { - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_MUSIG && f == 'x' ) - { - return(f); - } return(0); } CScript musig_spendopret(uint8_t funcid,CPubKey pk,std::vector musig64) { - CScript opret; uint8_t evalcode = EVAL_MUSIG; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk << musig64); + CScript opret; return(opret); } uint8_t musig_spendopretdecode(CPubKey &pk,std::vector &musig64,CScript scriptPubKey) { - std::vector vopret; uint8_t e,f; - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> musig64) != 0 && e == EVAL_MUSIG && f == 'y' ) - { - return(f); - } return(0); } int32_t musig_parsepubkey(secp256k1_context *ctx,secp256k1_pubkey &spk,cJSON *item) { - char *hexstr; - if ( (hexstr= jstr(item,0)) != 0 && is_hexstr(hexstr,0) == 66 ) - { - CPubKey pk(ParseHex(hexstr)); - if ( secp256k1_ec_pubkey_parse(ctx,&spk,pk.begin(),33) > 0 ) - return(1); - } else return(-1); + return -1; } int32_t musig_msghash(uint8_t *msg,uint256 prevhash,int32_t prevn,CTxOut vout,CPubKey pk) { - CScript data; uint256 hash; int32_t len = 0; - data << E_MARSHAL(ss << prevhash << prevn << vout << pk); - hash = Hash(data.begin(),data.end()); - memcpy(msg,&hash,sizeof(hash)); return(0); } int32_t musig_prevoutmsg(uint8_t *msg,uint256 sendtxid,CScript scriptPubKey) { - CTransaction vintx; uint256 hashBlock; int32_t numvouts; CTxOut vout; CPubKey pk; - memset(msg,0,32); - if ( myGetTransaction(sendtxid,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - vout.nValue = vintx.vout[MUSIG_PREVN].nValue - MUSIG_TXFEE; - vout.scriptPubKey = scriptPubKey; - return(musig_msghash(msg,sendtxid,MUSIG_PREVN,vout,pk)); - } - } return(-1); } UniValue musig_calcmsg(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - UniValue result(UniValue::VOBJ); uint256 sendtxid; int32_t i,zeros=0; uint8_t msg[32]; char *scriptstr,str[65]; int32_t n; - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 2 ) - { - sendtxid = juint256(jitem(params,0)); - scriptstr = jstr(jitem(params,1),0); - if ( is_hexstr(scriptstr,0) != 0 ) - { - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - musig_prevoutmsg(msg,sendtxid,scriptPubKey); - for (i=0; i<32; i++) - { - sprintf(&str[i<<1],"%02x",msg[i]); - if ( msg[i] == 0 ) - zeros++; - } - str[64] = 0; - if ( zeros != 32 ) - { - result.push_back(Pair("msg",str)); - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"null result, make sure params are sendtxid, scriptPubKey")); - } else return(cclib_error(result,"script is not hex")); - } else return(cclib_error(result,"need exactly 2 parameters: sendtxid, scriptPubKey")); - } else return(cclib_error(result,"couldnt parse params")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_combine(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - size_t clen = CPubKey::PUBLIC_KEY_SIZE; - UniValue result(UniValue::VOBJ); CPubKey pk; int32_t i,n; uint8_t pkhash[32]; char *hexstr,str[67]; secp256k1_pubkey combined_pk,spk; std::vector pubkeys; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - //fprintf(stderr,"n.%d args.(%s)\n",n,jprint(params,0)); - for (i=0; i 0 ) - { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&combined_pk,SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) - { - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",pkhash[i]); - str[64] = 0; - result.push_back(Pair("pkhash",str)); - - for (i=0; i<33; i++) - sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - result.push_back(Pair("combined_pk",str)); - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"error serializeing combined_pk")); - } else return(cclib_error(result,"error combining pukbeys")); - } else return(cclib_error(result,"need pubkeys params")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_session(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,myind,num,musiglocation; char *pkstr,*pkhashstr,*msgstr; uint8_t session[32],msg[32],pkhash[32],privkey[32],pub33[33]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 5 ) - { - myind = juint(jitem(params,0),0); - num = juint(jitem(params,1),0); - if ( myind < 0 || myind >= num || num <= 0 ) - return(cclib_error(result,"illegal myindex and numsigners")); - if ( n > 5 ) - musiglocation = juint(jitem(params,5),0); - else if ( n == 5 ) - musiglocation = 0; - //printf("number of params.%i musiglocation.%i\n",n,musiglocation); - if ( MUSIG.size() > musiglocation ) - { - for (int i = 0; i < MUSIG.size()-1; i++) - musig_infofree(MUSIG[i]); - MUSIG.clear(); - } - struct musig_info *temp_musig = musig_infocreate(myind,num); - MUSIG.push_back(temp_musig); - if ( musig_parsepubkey(ctx,MUSIG[musiglocation]->combined_pk,jitem(params,2)) < 0 ) - return(cclib_error(result,"error parsing combined_pubkey")); - else if ( cclib_parsehash(MUSIG[musiglocation]->pkhash,jitem(params,3),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( cclib_parsehash(MUSIG[musiglocation]->msg,jitem(params,4),32) < 0 ) - return(cclib_error(result,"error parsing msg")); - Myprivkey(privkey); - GetRandBytes(session,32); - /** Initializes a signing session for a signer - * - * Returns: 1: session is successfully initialized - * 0: session could not be initialized: secret key or secret nonce overflow - * Args: ctx: pointer to a context object, initialized for signing (cannot - * be NULL) - * Out: session: the session structure to initialize (cannot be NULL) - * signers: an array of signers' data to be initialized. Array length must - * equal to `n_signers` (cannot be NULL) - * nonce_commitment32: filled with a 32-byte commitment to the generated nonce - * (cannot be NULL) - * In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be - * NULL). If a non-unique session_id32 was given then a partial - * signature will LEAK THE SECRET KEY. - * msg32: the 32-byte message to be signed. Shouldn't be NULL unless you - * require sharing public nonces before the message is known - * because it reduces nonce misuse resistance. If NULL, must be - * set with `musig_session_set_msg` before signing and verifying. - * combined_pk: the combined public key of all signers (cannot be NULL) - * pk_hash32: the 32-byte hash of the signers' individual keys (cannot be - * NULL) - * n_signers: length of signers array. Number of signers participating in - * the MuSig. Must be greater than 0 and at most 2^32 - 1. - * my_index: index of this signer in the signers array - * seckey: the signer's 32-byte secret key (cannot be NULL) - */ - //fprintf(stderr, "SESSION: struct_size.%li using struct %i\n",MUSIG.size(), musiglocation); - if ( secp256k1_musig_session_initialize(ctx,&MUSIG[musiglocation]->session,MUSIG[musiglocation]->signer_data, &MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind * 32],session,MUSIG[musiglocation]->msg,&MUSIG[musiglocation]->combined_pk,MUSIG[musiglocation]->pkhash,MUSIG[musiglocation]->num,MUSIG[musiglocation]->myind,privkey) > 0 ) - { - memset(session,0,sizeof(session)); - result.push_back(Pair("myind",(int64_t)myind)); - result.push_back(Pair("numsigners",(int64_t)num)); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",MUSIG[musiglocation]->nonce_commitments[MUSIG[musiglocation]->myind*32 + i]); - str[64] = 0; - if ( n == 5 ) - MUSIG[musiglocation]->numcommits = 1; - result.push_back(Pair("commitment",str)); - result.push_back(Pair("result","success")); - memset(privkey,0,sizeof(privkey)); - return(result); - } - else - { - memset(privkey,0,sizeof(privkey)); - memset(session,0,sizeof(session)); - return(cclib_error(result,"couldnt initialize session")); - } - } else return(cclib_error(result,"wrong number of params, need 5: myindex, numsigners, combined_pk, pkhash, msg32")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_commit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - size_t clen = CPubKey::PUBLIC_KEY_SIZE; - UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( cclib_parsehash(&MUSIG[myind]->nonce_commitments[ind*32],jitem(params,2),32) < 0 ) - return(cclib_error(result,"error parsing commitment")); - /** Gets the signer's public nonce given a list of all signers' data with commitments - * - * Returns: 1: public nonce is written in nonce - * 0: signer data is missing commitments or session isn't initialized - * for signing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: the signing session to get the nonce from (cannot be NULL) - * signers: an array of signers' data initialized with - * `musig_session_initialize`. Array length must equal to - * `n_commitments` (cannot be NULL) - * Out: nonce: the nonce (cannot be NULL) - * In: commitments: array of 32-byte nonce commitments (cannot be NULL) - * n_commitments: the length of commitments and signers array. Must be the total - * number of signers participating in the MuSig. - */ - result.push_back(Pair("added_index",ind)); - //fprintf(stderr, "COMMIT: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); - MUSIG[myind]->numcommits++; - if ( MUSIG[myind]->numcommits >= MUSIG[myind]->num && secp256k1_musig_session_get_public_nonce(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,&MUSIG[myind]->nonces[MUSIG[myind]->myind],MUSIG[myind]->commitment_ptrs,MUSIG[myind]->num) > 0 ) - { - if ( secp256k1_ec_pubkey_serialize(ctx,(uint8_t *)pk.begin(),&clen,&MUSIG[myind]->nonces[MUSIG[myind]->myind],SECP256K1_EC_COMPRESSED) > 0 && clen == 33 ) - { - for (i=0; i<33; i++) - sprintf(&str[i<<1],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - if ( n == 3 ) - MUSIG[myind]->numnonces = 1; - result.push_back(Pair("myind",MUSIG[myind]->myind)); - result.push_back(Pair("nonce",str)); - result.push_back(Pair("result","success")); - } else return(cclib_error(result,"error serializing nonce (pubkey)")); - } - else - { - result.push_back(Pair("status","not enough commitments")); - result.push_back(Pair("result","success")); - } - return(result); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, commitment")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_nonce(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n,ind,myind; uint8_t pkhash[32],psig[32]; CPubKey pk; char str[67]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( musig_parsepubkey(ctx,MUSIG[myind]->nonces[ind],jitem(params,2)) < 0 ) - return(cclib_error(result,"error parsing nonce")); - result.push_back(Pair("added_index",ind)); - /** Checks a signer's public nonce against a commitment to said nonce, and update - * data structure if they match - * - * Returns: 1: commitment was valid, data structure updated - * 0: commitment was invalid, nothing happened - * Args: ctx: pointer to a context object (cannot be NULL) - * signer: pointer to the signer data to update (cannot be NULL). Must have - * been used with `musig_session_get_public_nonce` or initialized - * with `musig_session_initialize_verifier`. - * In: nonce: signer's alleged public nonce (cannot be NULL) - */ - MUSIG[myind]->numnonces++; - //fprintf(stderr, "NONCE: struct_size.%li using_struct.%i added_index.%i numnounces.%i num.%i\n",MUSIG.size(), myind, ind, MUSIG[myind]->numnonces, MUSIG[myind]->num); - if ( MUSIG[myind]->numnonces < MUSIG[myind]->num ) - { - result.push_back(Pair("status","not enough nonces")); - result.push_back(Pair("result","success")); - return(result); - } - for (i=0; inum; i++) - { - if ( secp256k1_musig_set_nonce(ctx,&MUSIG[myind]->signer_data[i],&MUSIG[myind]->nonces[i]) == 0 ) - return(cclib_error(result,"error setting nonce")); - } - /** Updates a session with the combined public nonce of all signers. The combined - * public nonce is the sum of every signer's public nonce. - * - * Returns: 1: nonces are successfully combined - * 0: a signer's nonce is missing - * Args: ctx: pointer to a context object (cannot be NULL) - * session: session to update with the combined public nonce (cannot be - * NULL) - * signers: an array of signers' data, which must have had public nonces - * set with `musig_set_nonce`. Array length must equal to `n_signers` - * (cannot be NULL) - * n_signers: the length of the signers array. Must be the total number of - * signers participating in the MuSig. - * Out: nonce_is_negated: a pointer to an integer that indicates if the combined - * public nonce had to be negated. - * adaptor: point to add to the combined public nonce. If NULL, nothing is - * added to the combined nonce. - */ - if ( secp256k1_musig_session_combine_nonces(ctx,&MUSIG[myind]->session,MUSIG[myind]->signer_data,MUSIG[myind]->num,NULL,NULL) > 0 ) - { - if ( secp256k1_musig_partial_sign(ctx,&MUSIG[myind]->session,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",psig[i]); - str[64] = 0; - result.push_back(Pair("myind",MUSIG[myind]->myind)); - result.push_back(Pair("partialsig",str)); - result.push_back(Pair("result","success")); - if ( n == 3 ) - MUSIG[myind]->numpartials = 1; - return(result); - } else return(cclib_error(result,"error serializing partial sig")); - } else return(cclib_error(result,"error making partial sig")); - } else return(cclib_error(result,"error combining nonces")); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, nonce")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_partialsig(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,ind,n,myind; uint8_t pkhash[32],psig[32],out64[64]; char str[129]; secp256k1_schnorrsig sig; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 3 ) - { - if ( n > 3 ) - myind = juint(jitem(params,3),0); - else if ( n == 3 ) - myind = 0; - if ( cclib_parsehash(pkhash,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( memcmp(MUSIG[myind]->pkhash,pkhash,32) != 0 ) - return(cclib_error(result,"pkhash doesnt match session pkhash")); - else if ( (ind= juint(jitem(params,1),0)) < 0 || ind >= MUSIG[myind]->num ) - return(cclib_error(result,"illegal ind for session")); - else if ( cclib_parsehash(psig,jitem(params,2),32) < 0 ) - return(cclib_error(result,"error parsing psig")); - else if ( secp256k1_musig_partial_signature_parse(ctx,&MUSIG[myind]->partial_sig[ind],psig) == 0 ) - return(cclib_error(result,"error parsing partialsig")); - result.push_back(Pair("added_index",ind)); - //fprintf(stderr, "SIG: struct_size.%li using_struct.%i added_index.%i\n",MUSIG.size(), myind, ind); - MUSIG[myind]->numpartials++; - if ( MUSIG[myind]->numpartials >= MUSIG[myind]->num && secp256k1_musig_partial_sig_combine(ctx,&MUSIG[myind]->session,&sig,MUSIG[myind]->partial_sig,MUSIG[myind]->num) > 0 ) - { - if ( secp256k1_schnorrsig_serialize(ctx,out64,&sig) > 0 ) - { - result.push_back(Pair("result","success")); - for (i=0; i<64; i++) - sprintf(&str[i<<1],"%02x",out64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - } else return(cclib_error(result,"error serializing combinedsig")); - } - else - { - if ( secp256k1_musig_partial_signature_serialize(ctx,psig,&MUSIG[myind]->partial_sig[MUSIG[myind]->myind]) > 0 ) - { - result.push_back(Pair("myind",ind)); - for (i=0; i<32; i++) - sprintf(&str[i<<1],"%02x",psig[i]); - str[64] = 0; - result.push_back(Pair("partialsig",str)); - result.push_back(Pair("result","success")); - result.push_back(Pair("status","need more partialsigs")); - } else return(cclib_error(result,"error generating my partialsig")); - } - return(result); - } else return(cclib_error(result,"wrong number of params, need 3: pkhash, ind, partialsig")); + UniValue result(UniValue::VOBJ); + return result; } //int testmain(void); UniValue musig_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - UniValue result(UniValue::VOBJ); int32_t i,n; uint8_t msg[32],musig64[64]; secp256k1_pubkey combined_pk; secp256k1_schnorrsig musig; char str[129]; - //testmain(); - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) == 3 ) - { - if ( cclib_parsehash(msg,jitem(params,0),32) < 0 ) - return(cclib_error(result,"error parsing pkhash")); - else if ( musig_parsepubkey(ctx,combined_pk,jitem(params,1)) < 0 ) - return(cclib_error(result,"error parsing combined_pk")); - else if ( cclib_parsehash(musig64,jitem(params,2),64) < 0 ) - return(cclib_error(result,"error parsing musig64")); - for (i=0; i<32; i++) - sprintf(&str[i*2],"%02x",msg[i]); - str[64] = 0; - result.push_back(Pair("msg",str)); - result.push_back(Pair("combined_pk",jstr(jitem(params,1),0))); - for (i=0; i<64; i++) - sprintf(&str[i*2],"%02x",musig64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - if ( secp256k1_schnorrsig_parse(ctx,&musig,&musig64[0]) > 0 ) - { - if ( secp256k1_schnorrsig_verify(ctx,&musig,msg,&combined_pk) > 0 ) - { - result.push_back(Pair("result","success")); - return(result); - } else return(cclib_error(result,"musig didnt verify")); - } else return(cclib_error(result,"couldnt parse musig64")); - } else return(cclib_error(result,"wrong number of params, need 3: msg, combined_pk, combinedsig")); + UniValue result(UniValue::VOBJ); + return result; } -// helpers for rpc calls that generate/validate onchain tx - UniValue musig_rawtxresult(UniValue &result,std::string rawtx) { - CTransaction tx; - if ( rawtx.size() > 0 ) - { - result.push_back(Pair("hex",rawtx)); - if ( DecodeHexTx(tx,rawtx) != 0 ) - { - //if ( broadcastflag != 0 && myAddtomempool(tx) != 0 ) - // RelayTransaction(tx); - result.push_back(Pair("txid",tx.GetHash().ToString())); - result.push_back(Pair("result","success")); - } else result.push_back(Pair("error","decode hex")); - } else result.push_back(Pair("error","couldnt finalize CCtx")); - return(result); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); int32_t n; char *hexstr; std::string rawtx; int64_t amount; CPubKey musigpk,mypk; - if ( txfee == 0 ) - txfee = MUSIG_TXFEE; - mypk = pubkey2pk(Mypubkey()); - musigpk = GetUnspendable(cp,0); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 2 && (hexstr= jstr(jitem(params,0),0)) != 0 && is_hexstr(hexstr,0) == 66 ) - { - CPubKey pk(ParseHex(hexstr)); - amount = jdouble(jitem(params,1),0) * COIN + 0.0000000049; - if ( amount >= 3*txfee && AddNormalinputs(mtx,mypk,amount+2*txfee,64) >= amount+2*txfee ) - { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount+txfee,musigpk)); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_sendopret('x',pk)); - return(musig_rawtxresult(result,rawtx)); - } else return(cclib_error(result,"couldnt find funds or less than 0.0003")); - } else return(cclib_error(result,"must have 2 params: pk, amount")); - } else return(cclib_error(result,"not enough parameters")); + UniValue result(UniValue::VOBJ); + return result; } UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) { - static secp256k1_context *ctx; - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,pk; secp256k1_pubkey combined_pk; char *scriptstr,*musigstr; uint8_t msg[32]; CTransaction vintx; uint256 prevhash,hashBlock; int32_t i,n,numvouts; char str[129]; CTxOut vout; secp256k1_schnorrsig musig; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 ) - { - if ( n == 3 ) - { - prevhash = juint256(jitem(params,0)); - scriptstr = jstr(jitem(params,1),0); - musigstr = jstr(jitem(params,2),0); - if ( is_hexstr(scriptstr,0) != 0 && is_hexstr(musigstr,0) == 128 ) - { - if ( txfee == 0 ) - txfee = MUSIG_TXFEE; - mypk = pubkey2pk(Mypubkey()); - std::vector musig64(ParseHex(musigstr)); - CScript scriptPubKey; - scriptPubKey.resize(strlen(scriptstr)/2); - decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr); - if ( myGetTransaction(prevhash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - vout.nValue = vintx.vout[0].nValue - txfee; - vout.scriptPubKey = scriptPubKey; - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( secp256k1_schnorrsig_parse((const secp256k1_context *)ctx,&musig,(const uint8_t *)&musig64[0]) > 0 && - secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) - { - musig_prevoutmsg(msg,prevhash,vout.scriptPubKey); - { - for (i=0; i<32; i++) - sprintf(&str[i*2],"%02x",msg[i]); - str[64] = 0; - result.push_back(Pair("msg",str)); - for (i=0; i<33; i++) - sprintf(&str[i*2],"%02x",((uint8_t *)pk.begin())[i]); - str[66] = 0; - result.push_back(Pair("combined_pk",str)); - for (i=0; i<64; i++) - sprintf(&str[i*2],"%02x",musig64[i]); - str[128] = 0; - result.push_back(Pair("combinedsig",str)); - } - if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) - { - return(cclib_error(result,"musig didnt validate")); - } - mtx.vin.push_back(CTxIn(prevhash,MUSIG_PREVN)); - mtx.vout.push_back(vout); - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,musig_spendopret('y',pk,musig64)); - return(musig_rawtxresult(result,rawtx)); - } else return(cclib_error(result,"couldnt parse pk or musig")); - } else return(cclib_error(result,"couldnt decode send opret")); - } else return(cclib_error(result,"couldnt find vin0")); - } else return(cclib_error(result,"script or musig is not hex")); - } else return(cclib_error(result,"need to have exactly 3 params sendtxid, scriptPubKey, musig")); - } else return(cclib_error(result,"params parse error")); + UniValue result(UniValue::VOBJ); + return result; } bool musig_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { - static secp256k1_context *ctx; - secp256k1_pubkey combined_pk; CPubKey pk,checkpk; secp256k1_schnorrsig musig; uint256 hashBlock; CTransaction vintx; int32_t numvouts; std::vector musig64; uint8_t msg[32]; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if ( tx.vout.size() != 2 ) - return eval->Invalid("numvouts != 2"); - else if ( tx.vin.size() != 1 ) - return eval->Invalid("numvins != 1"); - else if ( IsCCInput(tx.vin[0].scriptSig) == 0 ) - return eval->Invalid("illegal normal vin0"); - else if ( myGetTransaction(tx.vin[0].prevout.hash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 ) - { - if ( musig_sendopretdecode(pk,vintx.vout[numvouts-1].scriptPubKey) == 'x' ) - { - if ( musig_spendopretdecode(checkpk,musig64,tx.vout[tx.vout.size()-1].scriptPubKey) == 'y' ) - { - if ( pk == checkpk ) - { - if ( secp256k1_schnorrsig_parse((const secp256k1_context *)ctx,&musig,(const uint8_t *)&musig64[0]) > 0 && - secp256k1_ec_pubkey_parse(ctx,&combined_pk,pk.begin(),33) > 0 ) - { - musig_prevoutmsg(msg,tx.vin[0].prevout.hash,tx.vout[0].scriptPubKey); - if ( !secp256k1_schnorrsig_verify((const secp256k1_context *)ctx,&musig,(const uint8_t *)msg,(const secp256k1_pubkey *)&combined_pk) ) - return eval->Invalid("failed schnorrsig_verify"); - else return(true); - } else return eval->Invalid("couldnt parse pk or musig"); - } else return eval->Invalid("combined_pk didnt match send opret"); - } else return eval->Invalid("failed decode musig spendopret"); - } else return eval->Invalid("couldnt decode send opret"); - } else return eval->Invalid("couldnt find vin0 tx"); + return false; }