Merge pull request #1191 from jl777/jl777

Jl777
This commit is contained in:
jl777
2019-01-20 00:22:41 -11:00
committed by GitHub
31 changed files with 2668 additions and 1724 deletions

View File

@@ -571,7 +571,8 @@ komodod_LDADD += \
$(LIBBITCOIN_CRYPTO) \
$(LIBVERUS_CRYPTO) \
$(LIBVERUS_PORTABLE_CRYPTO) \
$(LIBZCASH_LIBS)
$(LIBZCASH_LIBS) \
cclib.so
if ENABLE_PROTON
komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS)

View File

@@ -212,7 +212,7 @@ bool FaucetExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction
bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
int64_t AddFaucetInputs(struct CCcontract_infoCC_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
std::string FaucetGet(uint64_t txfee)

View File

@@ -23,15 +23,18 @@
#define MARMARA_GROUPSIZE 60
#define MARMARA_MINLOCK (1440 * 3 * 30)
#define MARMARA_MAXLOCK (1440 * 24 * 30)
#define MARMARA_VINS 16
extern uint8_t ASSETCHAINS_MARMARA;
uint64_t komodo_block_prg(uint32_t nHeight);
int32_t MarmaraGetcreatetxid(uint256 &createtxid,uint256 txid);
int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,uint256 txid);
UniValue MarmaraCreditloop(uint256 txid);
UniValue MarmaraSettlement(uint64_t txfee,uint256 batontxid);
UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height);
UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr); // [[pk0, shares0], [pk1, shares1], ...]
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid);
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid,bool automaticflag);
UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t amount,std::string currency,int32_t matures,uint256 approvaltxid,uint256 batontxid);
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency);

View File

@@ -234,6 +234,34 @@ uint8_t TokensCCpriv[32] = { 0x1d, 0x0d, 0x0d, 0xce, 0x2d, 0xd2, 0xe1, 0x9d, 0xf
#undef FUNCNAME
#undef EVALCODE
#define FUNCNAME IsCClibInput
#define EVALCODE EVAL_FIRSTUSER
const char *CClibNormaladdr = "RVVeUg43rNcq3mZFnvZ8yqagyzqFgUnq4u";
char CClibCChexstr[67] = { "032447d97655da079729dc024c61088ea415b22f4c15d4810ddaf2069ac6468d2f" };
uint8_t CClibCCpriv[32] = { 0x57, 0xcf, 0x49, 0x71, 0x7d, 0xb4, 0x15, 0x1b, 0x4f, 0x98, 0xc5, 0x45, 0x8d, 0x26, 0x52, 0x4b, 0x7b, 0xe9, 0xbd, 0x55, 0xd8, 0x20, 0xd6, 0xc4, 0x82, 0x0f, 0xf5, 0xec, 0x6c, 0x1c, 0xa0, 0xc0 };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode)
{
CPubKey pk; uint8_t pub33[33]; char CCaddr[64];
if ( evalcode == EVAL_FIRSTUSER ) // eventually make a hashchain for each evalcode
{
cp->evalcode = evalcode;
cp->ismyvin = IsCClibInput;
strcpy(cp->CChexstr,CClibCChexstr);
memcpy(cp->CCpriv,CClibCCpriv,32);
decode_hex(pub33,33,cp->CChexstr);
pk = buf2pk(pub33);
Getscriptaddress(cp->normaladdr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
if ( strcmp(cp->normaladdr,CClibNormaladdr) != 0 )
fprintf(stderr,"CClib_initcp addr mismatch %s vs %s\n",cp->normaladdr,CClibNormaladdr);
GetCCaddress(cp,cp->unspendableCCaddr,pk);
return(0);
}
return(-1);
}
struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
{
@@ -369,6 +397,10 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
cp->validate = TokensValidate;
cp->ismyvin = IsTokensInput;
break;
default:
if ( CClib_initcp(cp,evalcode) < 0 )
return(0);
break;
}
return(cp);
}

View File

@@ -54,7 +54,8 @@ one other technical note is that komodod has the insight-explorer extensions bui
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
extern uint32_t ASSETCHAINS_CC;
extern char ASSETCHAINS_SYMBOL[];
extern std::string CCerror;
extern std::string CCerror,ASSETCHAINS_CCLIB;
extern uint8_t ASSETCHAINS_CCDISABLES[256];
#define CC_MAXVINS 1024
@@ -68,6 +69,7 @@ extern std::string CCerror;
typedef union _bits256 bits256;
#endif
#include "../komodo_cJSON.h"
struct CC_utxo
{
@@ -133,6 +135,9 @@ CBlockIndex *komodo_getblockindex(uint256 hash);
int32_t komodo_nextheight();
int32_t CCgetspenttxid(uint256 &spenttxid,int32_t &vini,int32_t &height,uint256 txid,int32_t vout);
void CCclearvars(struct CCcontract_info *cp);
UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params);
UniValue CClib_info(struct CCcontract_info *cp);
static const uint256 zeroid;
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
@@ -199,6 +204,7 @@ CC *MakeTokensCCcond1(uint8_t evalcode, CPubKey pk);
bool GetTokensCCaddress(struct CCcontract_info *cp, char *destaddr, CPubKey pk);
bool GetTokensCCaddress1of2(struct CCcontract_info *cp, char *destaddr, CPubKey pk, CPubKey pk2);
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr);
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode);
bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits);
@@ -225,7 +231,8 @@ bool komodo_txnotarizedconfirmed(uint256 txid);
CPubKey check_signing_pubkey(CScript scriptSig);
// CCtx
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey);
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret);
extern std::vector<CPubKey> NULL_pubkeys;
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys = NULL_pubkeys);
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);

View File

@@ -766,4 +766,4 @@ UniValue TokenList()
}
}
return(result);
}
}

View File

@@ -16,6 +16,8 @@
#include "CCinclude.h"
#include "key_io.h"
std::vector<CPubKey> NULL_pubkeys;
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
@@ -38,18 +40,18 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
return(false);
}
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys)
{
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
CTransaction vintx; std::string hex; CPubKey globalpk; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
int64_t utxovalues[CC_MAXVINS],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
int32_t i,utxovout,n,err = 0;
int32_t i,flag,utxovout,n,err = 0;
char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], tokensunspendable[64];
uint8_t *privkey, myprivkey[32], unspendablepriv[32], tokensunspendablepriv[32], *msg32 = 0;
CC *mycond=0, *othercond=0, *othercond2=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond, *mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond, *mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
CPubKey unspendablepk /*, tokensunspendablepk*/;
struct CCcontract_info *cpTokens, tokensC;
globalpk = GetUnspendable(cp,0);
n = mtx.vout.size();
for (i=0; i<n; i++)
{
@@ -221,8 +223,27 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
}
else
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
return("");
flag = 0;
if ( pubkeys != NULL_pubkeys )
{
char coinaddr[64];
GetCCaddress1of2(cp,coinaddr,globalpk,pubkeys[i]);
//fprintf(stderr,"%s + %s -> %s vs %s\n",HexStr(globalpk).c_str(),HexStr(pubkeys[i]).c_str(),coinaddr,destaddr);
if ( strcmp(destaddr,coinaddr) == 0 )
{
privkey = cp->CCpriv;
if ( othercond4 != 0 )
cc_free(othercond4);
othercond4 = MakeCCcond1of2(cp->evalcode,globalpk,pubkeys[i]);
cond = othercond4;
flag = 1;
}
}
if ( flag == 0 )
{
fprintf(stderr,"CC signing error: vini.%d has unknown CC address.(%s)\n",i,destaddr);
continue;
}
}
uint256 sighash = SignatureHash(CCPubKey(cond), mtx, i, SIGHASH_ALL, utxovalues[i],consensusBranchId, &txdata);
if ( cc_signTreeSecp256k1Msg32(cond,privkey,sighash.begin()) != 0 )
@@ -252,6 +273,8 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cc_free(othercond2);
if ( othercond3 != 0 )
cc_free(othercond3);
if ( othercond4 != 0 )
cc_free(othercond4);
std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 )
return(strHex);
@@ -450,8 +473,8 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
{
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
#ifdef ENABLE_WALLET
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));

View File

@@ -493,39 +493,10 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv)
return(pubkey2pk(ParseHex(cp->CChexstr)));
}
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
void CCclearvars(struct CCcontract_info *cp)
{
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector<uint8_t> origpubkey;
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
//fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE);
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
//txid = ctx.GetHash();
//if ( txid == cp->prevtxid )
// return(true);
//fprintf(stderr,"process CC %02x\n",cp->evalcode);
cp->evalcode2 = cp->evalcode3 = 0;
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
// return eval->Invalid("no-vouts");
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
{
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
//cp->prevtxid = txid;
return(true);
}
//fprintf(stderr,"invalid CC %02x\n",cp->evalcode);
return(false);
}
int64_t CCduration(int32_t &numblocks,uint256 txid)
@@ -630,3 +601,79 @@ CPubKey check_signing_pubkey(CScript scriptSig)
}
return CPubKey();
}
bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull,const CTransaction &ctx, unsigned int nIn)
{
CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector<uint8_t> origpubkey;
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
//fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d vs CCactive.%d\n",height,from_mempool,KOMODO_CCACTIVATE);
// there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example
//txid = ctx.GetHash();
//if ( txid == cp->prevtxid )
// return(true);
//fprintf(stderr,"process CC %02x\n",cp->evalcode);
CCclearvars(cp);
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
// return eval->Invalid("no-vouts");
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
{
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
//cp->prevtxid = txid;
return(true);
}
//fprintf(stderr,"invalid CC %02x\n",cp->evalcode);
return(false);
}
extern struct CCcontract_info CCinfos[0x100];
extern std::string MYCCLIBNAME;
bool CClib_validate(struct CCcontract_info *cp,Eval *eval,const CTransaction tx,unsigned int nIn);
bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector<uint8_t> paramsNull,const CTransaction &txTo,unsigned int nIn)
{
uint8_t evalcode; int32_t height,from_mempool; struct CCcontract_info *cp;
if ( ASSETCHAINS_CCLIB != MYCCLIBNAME )
{
fprintf(stderr,"-ac_cclib=%s vs myname %s\n",ASSETCHAINS_CCLIB.c_str(),MYCCLIBNAME.c_str());
return eval->Invalid("-ac_cclib name mismatches myname");
}
height = KOMODO_CONNECTING;
if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation
return(true);
if ( ASSETCHAINS_CC == 0 || (height & ~(1<<30)) < KOMODO_CCACTIVATE )
return eval->Invalid("CC are disabled or not active yet");
if ( (KOMODO_CONNECTING & (1<<30)) != 0 )
{
from_mempool = 1;
height &= ((1<<30) - 1);
}
evalcode = cond->code[0];
if ( evalcode >= EVAL_FIRSTUSER && evalcode <= EVAL_LASTUSER )
{
cp = &CCinfos[(int32_t)evalcode];
if ( cp->didinit == 0 )
{
if ( CClib_initcp(cp,evalcode) == 0 )
cp->didinit = 1;
else return eval->Invalid("unsupported CClib evalcode");
}
CCclearvars(cp);
if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params");
else if ( CClib_validate(cp,eval,txTo,nIn) != 0 )
return(true);
return eval->Invalid("error in CClib_validate");
}
return eval->Invalid("cclib CC must have evalcode between 16 and 127");
}

33
src/cc/Makefile Normal file
View File

@@ -0,0 +1,33 @@
SHELL = /bin/sh
CC = gcc
CC_DARWIN = g++-6
CC_WIN = x86_64-w64-mingw32-gcc-posix
CFLAGS_DARWIN = -std=c++11 -arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -c -Wl,-undefined -Wl,dynamic_lookup
CFLAGS = -std=c++11 -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
CFLAGS_WIN = -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
$(info $(OS))
OS := $(shell uname -s)
$(info $(OS))
TARGET = ../cclib.so
TARGET_WIN = ../cclib.dll
SOURCES = cclib.cpp
#HEADERS = $(shell echo ../cryptoconditions/include/*.h)
all: $(TARGET)
$(TARGET): $(SOURCES)
$(info Building cclib to src/)
ifeq ($(OS),Darwin)
$(CC_DARWIN) $(CFLAGS_DARWIN) $(DEBUGFLAGS) -o $(TARGET) $(SOURCES)
else ifeq ($(OS),Linux)
$(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(SOURCES)
#else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host
else
$(info WINDOWS)
$(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) $(SOURCES)
endif
clean:
rm -rf $(TARGET)

317
src/cc/cclib.cpp Normal file
View File

@@ -0,0 +1,317 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#include <assert.h>
#include <cryptoconditions.h>
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "cc/utils.h"
#include "cc/CCinclude.h"
#include "main.h"
#include "chain.h"
#include "core_io.h"
#include "crosschain.h"
#define FAUCET2SIZE COIN
struct CClib_rpcinfo
{
char *method,*help;
int32_t numrequiredargs,maxargs; // frontloaded with required
uint8_t funcid;
}
CClib_methods[] =
{
{ (char *)"faucet2_fund", (char *)"amount", 1, 1, 'F' },
{ (char *)"faucet2_get", (char *)"<no args>", 0, 0, 'G' },
};
std::string MYCCLIBNAME = (char *)"faucet2";
char *CClib_name() { return((char *)MYCCLIBNAME.c_str()); }
std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params);
UniValue CClib_info(struct CCcontract_info *cp)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i; char str[2];
result.push_back(Pair("result","success"));
result.push_back(Pair("CClib",CClib_name()));
for (i=0; i<sizeof(CClib_methods)/sizeof(*CClib_methods); i++)
{
UniValue obj(UniValue::VOBJ);
if ( CClib_methods[i].funcid < ' ' || CClib_methods[i].funcid >= 128 )
obj.push_back(Pair("funcid",CClib_methods[i].funcid));
else
{
str[0] = CClib_methods[i].funcid;
str[1] = 0;
obj.push_back(Pair("funcid",str));
}
obj.push_back(Pair("name",CClib_methods[i].method));
obj.push_back(Pair("help",CClib_methods[i].help));
obj.push_back(Pair("params_required",CClib_methods[i].numrequiredargs));
obj.push_back(Pair("params_max",CClib_methods[i].maxargs));
a.push_back(obj);
}
result.push_back(Pair("methods",a));
return(result);
}
UniValue CClib(struct CCcontract_info *cp,char *method,cJSON *params)
{
UniValue result(UniValue::VOBJ); int32_t i; std::string rawtx;
for (i=0; i<sizeof(CClib_methods)/sizeof(*CClib_methods); i++)
{
if ( strcmp(method,CClib_methods[i].method) == 0 )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("method",CClib_methods[i].method));
rawtx = CClib_rawtxgen(cp,CClib_methods[i].funcid,params);
result.push_back(Pair("rawtx",rawtx));
return(result);
}
}
result.push_back(Pair("result","error"));
result.push_back(Pair("method",CClib_methods[i].method));
result.push_back(Pair("error","method not found"));
return(result);
}
int64_t IsCClibvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
bool CClibExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i=0; i<numvins; i++)
{
//fprintf(stderr,"vini.%d\n",i);
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
{
//fprintf(stderr,"vini.%d check mempool\n",i);
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant faucet2 from mempool");
if ( (assetoshis= IsCClibvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
}
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsCClibvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+FAUCET2SIZE+txfee )
{
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
return eval->Invalid("mismatched inputs != outputs + FAUCET2SIZE + txfee");
}
else return(true);
}
bool CClib_validate(struct CCcontract_info *cp,Eval *eval,const CTransaction tx,unsigned int nIn)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
{
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
fprintf(stderr,"faucetget invalid vini\n");
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
if ( CClibExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"faucetget invalid amount\n");
return false;
}
else
{
preventCCvouts = 1;
if ( IsCClibvout(cp,tx,0) != 0 )
{
preventCCvouts++;
i = 1;
} else i = 0;
txid = tx.GetHash();
memcpy(hash,&txid,sizeof(hash));
fprintf(stderr,"check faucetget txid %s %02x/%02x\n",uint256_str(str,txid),hash[0],hash[31]);
if ( tx.vout[i].nValue != FAUCET2SIZE )
return eval->Invalid("invalid faucet output");
else if ( (hash[0] & 0xff) != 0 || (hash[31] & 0xff) != 0 )
return eval->Invalid("invalid faucetget txid");
Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
SetCCtxids(txids,destaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
//int height = it->first.blockHeight;
if ( CCduration(numblocks,it->first.txhash) > 0 && numblocks > 3 )
{
//fprintf(stderr,"would return error %s numblocks.%d ago\n",uint256_str(str,it->first.txhash),numblocks);
return eval->Invalid("faucet2 is only for brand new addresses");
}
}
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"faucet2get validated\n");
else fprintf(stderr,"faucet2get invalid\n");
return(retval);
}
}
}
int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs+1);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
//char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"nValue too small or already spent in mempool\n");
} else fprintf(stderr,"couldnt get tx\n");
}
return(totalinputs);
}
std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,cclibpk; CScript opret;
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
cclibpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,cclibpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return("");
}
/*UniValue FaucetInfo()
{
UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success"));
result.push_back(Pair("name","Faucet"));
cp = CCinit(&C,EVAL_FAUCET);
faucetpk = GetUnspendable(cp,0);
funding = AddFaucetInputs(cp,mtx,faucetpk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
return(result);
}*/
std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *params)
{
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CPubKey mypk,cclibpk; int64_t funds,txfee=0,inputs,CCchange=0,nValue=FAUCET2SIZE; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
if ( txfee == 0 )
txfee = 10000;
if ( funcid == 'F' )
{
if ( cJSON_GetArraySize(params) > 0 )
{
funds = (int64_t)jdouble(jitem(params,0),0)*COIN + 0.0000000049;
return(Faucet2Fund(cp,0,funds));
} else return("");
}
else if ( funcid != 'G' )
return("");
cclibpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddCClibInputs(cp,mtx,cclibpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_FIRSTUSER,CCchange,cclibpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
j = rand() & 0xfffffff;
for (i=0; i<1000000; i++,j++)
{
tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_FIRSTUSER << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
{
len >>= 1;
decode_hex(buf,len,(char *)rawhex.c_str());
hash = bits256_doublesha256(0,buf,len);
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
{
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
return(rawhex);
}
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
}
}
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return("");
} else fprintf(stderr,"cant find faucet inputs\n");
return("");
}

View File

@@ -27,6 +27,8 @@
#include "core_io.h"
#include "crosschain.h"
bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector<uint8_t> paramsNull,const CTransaction &txTo,unsigned int nIn);
char *CClib_name();
Eval* EVAL_TEST = 0;
struct CCcontract_info CCinfos[0x100];
@@ -65,13 +67,24 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
return Invalid("empty-eval");
uint8_t ecode = cond->code[0];
if ( ASSETCHAINS_CCDISABLES[ecode] != 0 )
{
fprintf(stderr,"%s evalcode.%d %02x\n",txTo.GetHash().GetHex().c_str(),ecode,ecode);
return Invalid("disabled-code, -ac_ccenables didnt include this ecode");
}
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
if ( ecode >= EVAL_FIRSTUSER && ecode <= EVAL_LASTUSER )
{
if ( ASSETCHAINS_CCLIB.size() > 0 && ASSETCHAINS_CCLIB == CClib_name() )
return CClib_Dispatch(cond,this,vparams,txTo,nIn);
else return Invalid("mismatched -ac_cclib vs CClib_name");
}
cp = &CCinfos[(int32_t)ecode];
if ( cp->didinit == 0 )
{
CCinit(cp,ecode);
cp->didinit = 1;
}
std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
switch ( ecode )
{
case EVAL_IMPORTPAYOUT:

View File

@@ -59,6 +59,10 @@
EVAL(EVAL_TOKENS, 0xf2)
// evalcodes 0x10 to 0x7f are reserved for cclib dynamic CC
#define EVAL_FIRSTUSER 0x10
#define EVAL_LASTUSER 0x7f
typedef uint8_t EvalCode;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
src/cc/makecclib Executable file
View File

@@ -0,0 +1 @@
gcc -std=c++11 -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o ../cclib.so cclib.cpp

View File

@@ -35,8 +35,14 @@
vout0 baton to next receiverpk (following the unspent baton back to original is the credit loop)
'S'
vin0 'I' marker
vin1 baton
vins CC utxos from credit loop
'D' default/partial payment
'L' lockfunds
*/
// start of consensus code
@@ -82,13 +88,13 @@ uint8_t DecodeMaramaraCoinbaseOpRet(const CScript scriptPubKey,CPubKey &pk,int32
}
if ( vopret.size() > 2 && script[0] == EVAL_MARMARA )
{
if ( script[1] == 'C' || script[1] == 'P' )
if ( script[1] == 'C' || script[1] == 'P' || script[1] == 'L' )
{
if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> unlockht) != 0 )
{
return(script[1]);
} else fprintf(stderr,"DecodeMaramaraCoinbaseOpRet unmarshal error for %c\n",script[1]);
} else fprintf(stderr,"script[1] is %d != 'C' %d or 'P' %d\n",script[1],'C','P');
} else fprintf(stderr,"script[1] is %d != 'C' %d or 'P' %d or 'L' %d\n",script[1],'C','P','L');
} else fprintf(stderr,"vopret.size() is %d\n",(int32_t)vopret.size());
return(0);
}
@@ -155,18 +161,25 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
if ( MarmaraGetcreatetxid(createtxid,txid) == 0 )
{
txid = createtxid;
fprintf(stderr,"txid.%s -> createtxid %s\n",txid.GetHex().c_str(),createtxid.GetHex().c_str());
//fprintf(stderr,"txid.%s -> createtxid %s\n",txid.GetHex().c_str(),createtxid.GetHex().c_str());
while ( CCgetspenttxid(spenttxid,vini,height,txid,vout) == 0 )
{
creditloop.push_back(txid);
fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str());
//fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str());
n++;
if ( (value= CCgettxout(spenttxid,vout,1)) > 0 )
if ( (value= CCgettxout(spenttxid,vout,1)) == 10000 )
{
batontxid = spenttxid;
fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN);
//fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN);
return(n);
}
else if ( value > 0 )
{
batontxid = spenttxid;
fprintf(stderr,"n.%d got false baton %s/v%d %.8f\n",n,batontxid.GetHex().c_str(),vout,(double)value/COIN);
return(n);
}
// get funcid
txid = spenttxid;
}
}
@@ -175,9 +188,16 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk)
{
CTxOut ccvout;
CTxOut ccvout; struct CCcontract_info *cp,C; CPubKey Marmarapk;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( height > 0 && (height & 1) == 0 && pk.size() == 33 )
ccvout = MakeCC1vout(EVAL_MARMARA,0,pk);
{
ccvout = MakeCC1of2vout(EVAL_MARMARA,0,Marmarapk,pk);
//char coinaddr[64];
//Getscriptaddress(coinaddr,ccvout.scriptPubKey);
//fprintf(stderr,"Marmara_scriptPubKey %s ht.%d -> %s\n",HexStr(pk).c_str(),height,coinaddr);
}
return(ccvout.scriptPubKey);
}
@@ -192,8 +212,9 @@ CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk)
int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
{
struct CCcontract_info *cp,C; CPubKey pk; int32_t ht,unlockht; CTxOut ccvout;
struct CCcontract_info *cp,C; CPubKey Marmarapk,pk; int32_t ht,unlockht; CTxOut ccvout;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( 0 )
{
int32_t d,histo[365*2+30];
@@ -221,10 +242,13 @@ int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
if ( ht == height && MarmaraUnlockht(height) == unlockht )
{
//fprintf(stderr,"ht.%d -> unlock.%d\n",ht,unlockht);
ccvout = MakeCC1vout(EVAL_MARMARA,0,pk);
ccvout = MakeCC1of2vout(EVAL_MARMARA,0,Marmarapk,pk);
if ( ccvout.scriptPubKey == tx.vout[0].scriptPubKey )
return(0);
fprintf(stderr,"ht.%d mismatched CCvout scriptPubKey\n",height);
char addr0[64],addr1[64];
Getscriptaddress(addr0,ccvout.scriptPubKey);
Getscriptaddress(addr1,tx.vout[0].scriptPubKey);
fprintf(stderr,"ht.%d mismatched CCvout scriptPubKey %s vs %s pk.%d %s\n",height,addr0,addr1,(int32_t)pk.size(),HexStr(pk).c_str());
} else fprintf(stderr,"ht.%d %d vs %d unlock.%d\n",height,MarmaraUnlockht(height),ht,unlockht);
} else fprintf(stderr,"ht.%d error decoding coinbase opret\n",height);
}
@@ -234,6 +258,8 @@ int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
{
std::vector<uint8_t> vopret; CTransaction vinTx; uint256 hashBlock; int32_t numvins,numvouts,i,ht,unlockht,vht,vunlockht; uint8_t funcid,vfuncid,*script; CPubKey pk,vpk;
if ( ASSETCHAINS_MARMARA == 0 )
return eval->Invalid("-ac_marmara must be set for marmara CC");
numvins = tx.vin.size();
numvouts = tx.vout.size();
if ( numvouts < 1 )
@@ -284,9 +310,13 @@ bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
{
return(true);
}
else if ( funcid == 'S' ) // collect -> automatically spend issuers locked funds, given 'I'
else if ( funcid == 'S' ) // settlement -> automatically spend issuers locked funds, given 'I'
{
return(true); // iterate from issuer all remainder after maturity
return(true);
}
else if ( funcid == 'D' ) // insufficient settlement
{
return(true);
}
// staking only for locked utxo
}
@@ -298,9 +328,10 @@ bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,int32_t firstheight,CPubKey poolpk,int32_t maxinputs)
{
char coinaddr[64]; CPubKey pk; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction vintx; int32_t unlockht,ht,vout,unlocks,n = 0;
char coinaddr[64]; CPubKey Marmarapk,pk; int64_t nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction vintx; int32_t unlockht,ht,vout,unlocks,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,poolpk);
Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,poolpk);
SetCCunspents(unspentOutputs,coinaddr);
unlocks = MarmaraUnlockht(firstheight);
//fprintf(stderr,"check coinaddr.(%s)\n",coinaddr);
@@ -332,13 +363,258 @@ int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,
return(totalinputs);
}
int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuances,struct CCcontract_info *cp,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,CPubKey refpk,std::string refcurrency)
int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,char *coinaddr,int64_t total,int32_t maxinputs)
{
uint64_t threshold,nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction tx; int32_t numvouts,ht,unlockht,vout,i,n = 0; uint8_t funcid; CPubKey pk; std::vector<int64_t> vals;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs+1);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
//char str[64]; fprintf(stderr,"(%s) %s/v%d %.8f ht.%d unlockht.%d\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,ht,unlockht);
if ( total != 0 && maxinputs != 0 )
{
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
pubkeys.push_back(pk);
}
totalinputs += it->second.satoshis;
vals.push_back(it->second.satoshis);
n++;
if ( maxinputs != 0 && total == 0 )
continue;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} else fprintf(stderr,"null funcid\n");
}
}
if ( maxinputs != 0 && total == 0 )
{
std::sort(vals.begin(),vals.end());
totalinputs = 0;
for (i=0; i<maxinputs && i<vals.size(); i++)
totalinputs += vals[i];
}
return(totalinputs);
}
UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
{
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; CPubKey Marmarapk,mypk,pk; int32_t unlockht,refunlockht,vout,ht,numvouts; int64_t nValue,val,inputsum=0,threshold,remains,change = 0; std::string rawtx,errorstr; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; uint8_t funcid;
if ( txfee == 0 )
txfee = 10000;
if ( (height & 1) != 0 )
height++;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG);
if ( (val= CCaddress_balance(coinaddr)) < amount )
val -= txfee;
else val = amount;
if ( val > txfee )
inputsum = AddNormalinputs2(mtx,val,CC_MAXVINS/2);
//fprintf(stderr,"normal inputs %.8f val %.8f\n",(double)inputsum/COIN,(double)val/COIN);
mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,amount,Marmarapk,mypk));
if ( inputsum < amount+txfee )
{
refunlockht = MarmaraUnlockht(height);
result.push_back(Pair("normalfunds",ValueFromAmount(inputsum)));
result.push_back(Pair("height",height));
result.push_back(Pair("unlockht",refunlockht));
remains = (amount + txfee) - inputsum;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress1of2(cp,coinaddr,Marmarapk,mypk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = remains / (MARMARA_VINS+1);
CCaddr1of2set(cp,Marmarapk,mypk,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
if ( unlockht < refunlockht )
{
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
//fprintf(stderr,"merge CC vout %s/v%d %.8f unlockht.%d < ref.%d\n",txid.GetHex().c_str(),vout,(double)nValue/COIN,unlockht,refunlockht);
inputsum += nValue;
remains -= nValue;
if ( inputsum >= amount + txfee )
{
//fprintf(stderr,"inputsum %.8f >= amount %.8f, update amount\n",(double)inputsum/COIN,(double)amount/COIN);
amount = inputsum - txfee;
break;
}
}
}
}
}
}
if ( inputsum >= amount+txfee )
{
if ( inputsum > amount+txfee )
{
change = (inputsum - amount);
mtx.vout.push_back(CTxOut(change,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
}
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraCoinbaseOpret('L',height,mypk));
if ( rawtx.size() == 0 )
errorstr = (char *)"couldnt finalize CCtx";
else
{
result.push_back(Pair("result",(char *)"success"));
result.push_back(Pair("rawtx",rawtx));
return(result);
}
} else errorstr = (char *)"insufficient funds";
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",errorstr));
return(result);
}
// jl777: decide on what unlockht settlement change should have
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures,height; int64_t amount,refamount,remaining,inputsum,change; CPubKey Marmarapk,mypk,pk; std::string currency,refcurrency,rawtx; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2],txidaddr[64]; std::vector<CPubKey> pubkeys; struct CCcontract_info *cp,C;
if ( txfee == 0 )
txfee = 10000;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
remaining = change = 0;
height = chainActive.LastTip()->GetHeight();
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
{
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
if ( refcreatetxid != creditloop[0] )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"invalid refcreatetxid, setting to creditloop[0]"));
return(result);
}
else if ( chainActive.LastTip()->GetHeight() < refmatures )
{
fprintf(stderr,"doesnt mature for another %d blocks\n",refmatures - chainActive.LastTip()->GetHeight());
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"cant settle immature creditloop"));
return(result);
}
else if ( (refmatures & 1) == 0 )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"cant automatic settle even maturity heights"));
return(result);
}
else if ( n < 1 )
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"creditloop too short"));
return(result);
}
remaining = refamount;
GetCCaddress(cp,myCCaddr,Mypubkey());
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
{
mtx.vin.push_back(CTxIn(n == 1 ? batontxid : creditloop[1],1,CScript())); // issuance marker
pubkeys.push_back(Marmarapk);
mtx.vin.push_back(CTxIn(batontxid,0,CScript()));
pubkeys.push_back(mypk);
for (i=1; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
if ( (inputsum= AddMarmarainputs(mtx,pubkeys,coinaddr,remaining,MARMARA_VINS)) >= remaining )
{
change = (inputsum - remaining);
mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
if ( change > txfee )
mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,change,Marmarapk,pk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('S',createtxid,mypk,0,refmatures,currency),pubkeys);
result.push_back(Pair("result",(char *)"success"));
result.push_back(Pair("rawtx",rawtx));
return(result);
} else remaining -= inputsum;
if ( mtx.vin.size() >= CC_MAXVINS - MARMARA_VINS )
break;
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
}
if ( refamount - remaining > 2*txfee )
{
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,createtxid))) << OP_CHECKSIG)); // failure marker
if ( refamount-remaining > 3*txfee )
mtx.vout.push_back(CTxOut(refamount-remaining-2*txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('D',createtxid,mypk,-remaining,refmatures,currency),pubkeys);
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"insufficient funds"));
result.push_back(Pair("rawtx",rawtx));
result.push_back(Pair("remaining",ValueFromAmount(remaining)));
}
else
{
// jl777: maybe fund a txfee to report no funds avail
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"no funds available at all"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"this node does not have the baton"));
result.push_back(Pair("myCCaddr",myCCaddr));
result.push_back(Pair("batonCCaddr",batonCCaddr));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
}
return(result);
}
int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuances,int64_t &totalclosed,std::vector<uint256> &closed,struct CCcontract_info *cp,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,CPubKey refpk,std::string refcurrency)
{
char coinaddr[64]; CPubKey Marmarapk,senderpk; int64_t amount; uint256 createtxid,txid,hashBlock; CTransaction tx; int32_t numvouts,vout,matures,n=0; std::string currency;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
Marmarapk = GetUnspendable(cp,0);
GetCCaddress(cp,coinaddr,Marmarapk);
SetCCunspents(unspentOutputs,coinaddr);
// do all txid, conditional on spent/unspent
//fprintf(stderr,"check coinaddr.(%s)\n",coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
@@ -364,21 +640,24 @@ int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuanc
return(n);
}
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid)
UniValue MarmaraReceive(uint64_t txfee,CPubKey senderpk,int64_t amount,std::string currency,int32_t matures,uint256 batontxid,bool automaticflag)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); CPubKey mypk; struct CCcontract_info *cp,C; std::string rawtx; char *errorstr=0; uint256 createtxid; int64_t batonamount; int32_t needbaton = 0;
cp = CCinit(&C,EVAL_MARMARA);
if ( txfee == 0 )
txfee = 10000;
// check for batonownership by senderpk and parameters match createtxid
if ( automaticflag != 0 && (matures & 1) == 0 )
matures++;
else if ( automaticflag == 0 && (matures & 1) != 0 )
matures++;
mypk = pubkey2pk(Mypubkey());
memset(&createtxid,0,sizeof(createtxid));
if ( batontxid != zeroid && MarmaraGetcreatetxid(createtxid,batontxid) < 0 )
errorstr = (char *)"cant get createtxid from batontxid";
else if ( currency != "MARMARA" )
errorstr = (char *)"for now, only MARMARA loops are supported";
else if ( amount < txfee )
else if ( amount <= txfee )
errorstr = (char *)"amount must be for more than txfee";
else if ( matures <= chainActive.LastTip()->GetHeight() )
errorstr = (char *)"it must mature in the future";
@@ -425,17 +704,14 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a
cp = CCinit(&C,EVAL_MARMARA);
if ( txfee == 0 )
txfee = 10000;
// make sure receiverpk is unique to creditloop
// make sure less than maxlength
Marmarapk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( MarmaraGetcreatetxid(createtxid,approvaltxid) < 0 )
errorstr = (char *)"cant get createtxid from approvaltxid";
else if ( batontxid == zeroid )
errorstr = (char *)"null batontxid";
else if ( currency != "MARMARA" )
errorstr = (char *)"for now, only MARMARA loops are supported";
else if ( amount < txfee )
else if ( amount <= txfee )
errorstr = (char *)"amount must be for more than txfee";
else if ( matures <= chainActive.LastTip()->GetHeight() )
errorstr = (char *)"it must mature in the future";
@@ -479,69 +755,6 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a
return(result);
}
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey Marmarapk,pk; std::string currency,refcurrency; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
if ( txfee == 0 )
txfee = 10000;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
{
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
GetCCaddress(cp,myCCaddr,Mypubkey());
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
{
for (i=0; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
{
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
fprintf(stderr,"get locked funds of %s %.8f\n",coinaddr,(double)CCaddress_balance(coinaddr)/COIN);
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"this node does not have the baton"));
result.push_back(Pair("myCCaddr",myCCaddr));
result.push_back(Pair("batonCCaddr",batonCCaddr));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
}
}
else
{
result.push_back(Pair("result",(char *)"error"));
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
}
return(result);
}
UniValue MarmaraCreditloop(uint256 txid)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey pk; std::string currency,refcurrency; CTransaction tx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
@@ -555,35 +768,69 @@ UniValue MarmaraCreditloop(uint256 txid)
result.push_back(Pair("myaddress",coinaddr));
GetCCaddress(cp,myCCaddr,Mypubkey());
result.push_back(Pair("myCCaddress",myCCaddr));
result.push_back(Pair("batontxid",batontxid.GetHex()));
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
{
str[0] = funcid, str[1] = 0;
result.push_back(Pair("funcid",str));
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
result.push_back(Pair("currency",refcurrency));
result.push_back(Pair("batonpk",HexStr(pk)));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("batonaddr",coinaddr));
GetCCaddress(cp,batonCCaddr,pk);
result.push_back(Pair("batonCCaddr",batonCCaddr));
Getscriptaddress(coinaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,batonCCaddr) != 0 )
if ( funcid == 'S' )
{
result.push_back(Pair("vout0address",coinaddr));
numerrs++;
refcreatetxid = creditloop[0];
result.push_back(Pair("settlement",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("remainder",ValueFromAmount(refamount)));
result.push_back(Pair("settled",refmatures));
result.push_back(Pair("pubkey",HexStr(pk)));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("coinaddr",coinaddr));
result.push_back(Pair("collected",ValueFromAmount(tx.vout[0].nValue)));
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,destaddr) != 0 )
{
result.push_back(Pair("destaddr",destaddr));
numerrs++;
}
refamount = -1;
}
else if ( funcid == 'D' )
{
refcreatetxid = creditloop[0];
result.push_back(Pair("settlement",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("remainder",ValueFromAmount(refamount)));
result.push_back(Pair("settled",refmatures));
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
result.push_back(Pair("txidaddr",destaddr));
if ( tx.vout.size() > 1 )
result.push_back(Pair("collected",ValueFromAmount(tx.vout[1].nValue)));
}
else
{
result.push_back(Pair("batontxid",batontxid.GetHex()));
result.push_back(Pair("createtxid",refcreatetxid.GetHex()));
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
if ( refcreatetxid != creditloop[0] )
{
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
refcreatetxid = creditloop[0];
numerrs++;
}
result.push_back(Pair("batonpk",HexStr(pk)));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pk)) << OP_CHECKSIG);
result.push_back(Pair("batonaddr",coinaddr));
GetCCaddress(cp,batonCCaddr,pk);
result.push_back(Pair("batonCCaddr",batonCCaddr));
Getscriptaddress(coinaddr,tx.vout[0].scriptPubKey);
if ( strcmp(coinaddr,batonCCaddr) != 0 )
{
result.push_back(Pair("vout0address",coinaddr));
numerrs++;
}
if ( strcmp(myCCaddr,coinaddr) == 0 )
result.push_back(Pair("ismine",1));
else result.push_back(Pair("ismine",0));
}
if ( strcmp(myCCaddr,coinaddr) == 0 )
result.push_back(Pair("ismine",1));
else result.push_back(Pair("ismine",0));
for (i=0; i<n; i++)
{
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
@@ -617,6 +864,13 @@ UniValue MarmaraCreditloop(uint256 txid)
obj.push_back(Pair("vout0address",destaddr));
numerrs++;
}
if ( i == 0 && refamount < 0 )
{
refamount = amount;
refmatures = matures;
result.push_back(Pair("amount",ValueFromAmount(refamount)));
result.push_back(Pair("matures",refmatures));
}
if ( createtxid != refcreatetxid || amount != refamount || matures != refmatures || currency != refcurrency )
{
numerrs++;
@@ -653,43 +907,6 @@ UniValue MarmaraCreditloop(uint256 txid)
}
return(result);
}
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,matches; int64_t totalamount=0; std::vector<uint256> issuances; char coinaddr[64];
CPubKey Marmarapk; struct CCcontract_info *cp,C;
result.push_back(Pair("result","success"));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(Mypubkey())) << OP_CHECKSIG);
result.push_back(Pair("myaddress",coinaddr));
GetCCaddress(cp,coinaddr,Mypubkey());
result.push_back(Pair("myCCaddress",coinaddr));
if ( refpk.size() == 33 )
result.push_back(Pair("issuer",HexStr(refpk)));
if ( currency.size() == 0 )
currency = (char *)"MARMARA";
if ( firstheight <= lastheight )
firstheight = 0, lastheight = (1 << 30);
if ( minamount <= maxamount )
minamount = 0, maxamount = (1LL << 60);
result.push_back(Pair("firstheight",firstheight));
result.push_back(Pair("lastheight",lastheight));
result.push_back(Pair("minamount",ValueFromAmount(minamount)));
result.push_back(Pair("maxamount",ValueFromAmount(maxamount)));
result.push_back(Pair("currency",currency));
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
if ( (n= MarmaraGetCreditloops(totalamount,issuances,cp,firstheight,lastheight,minamount,maxamount,refpk,currency)) > 0 )
{
result.push_back(Pair("n",n));
matches = (int32_t)issuances.size();
result.push_back(Pair("matches",matches));
for (i=0; i<matches; i++)
a.push_back(issuances[i].GetHex());
result.push_back(Pair("issuances",a));
result.push_back(Pair("totalamount",ValueFromAmount(totalamount)));
}
return(result);
}
UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *jsonstr) // [[pk0, shares0], [pk1, shares1], ...]
{
@@ -777,3 +994,57 @@ UniValue MarmaraPoolPayout(uint64_t txfee,int32_t firstheight,double perc,char *
return(result);
}
// get all tx, constrain by vout, issuances[] and closed[]
UniValue MarmaraInfo(CPubKey refpk,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,std::string currency)
{
CMutableTransaction mtx; std::vector<CPubKey> pubkeys;
UniValue result(UniValue::VOBJ),a(UniValue::VARR),b(UniValue::VARR); int32_t i,n,matches; int64_t totalclosed=0,totalamount=0; std::vector<uint256> issuances,closed; char coinaddr[64];
CPubKey Marmarapk; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_MARMARA);
Marmarapk = GetUnspendable(cp,0);
result.push_back(Pair("result","success"));
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(Mypubkey())) << OP_CHECKSIG);
result.push_back(Pair("myaddress",coinaddr));
result.push_back(Pair("normal",ValueFromAmount(CCaddress_balance(coinaddr))));
GetCCaddress1of2(cp,coinaddr,Marmarapk,Mypubkey());
result.push_back(Pair("myCCactivated",coinaddr));
result.push_back(Pair("activated",ValueFromAmount(CCaddress_balance(coinaddr))));
result.push_back(Pair("activated16",ValueFromAmount(AddMarmarainputs(mtx,pubkeys,coinaddr,0,MARMARA_VINS))));
GetCCaddress(cp,coinaddr,Mypubkey());
result.push_back(Pair("myCCaddress",coinaddr));
result.push_back(Pair("CCutxos",ValueFromAmount(CCaddress_balance(coinaddr))));
if ( refpk.size() == 33 )
result.push_back(Pair("issuer",HexStr(refpk)));
if ( currency.size() == 0 )
currency = (char *)"MARMARA";
if ( firstheight <= lastheight )
firstheight = 0, lastheight = (1 << 30);
if ( minamount <= maxamount )
minamount = 0, maxamount = (1LL << 60);
result.push_back(Pair("firstheight",firstheight));
result.push_back(Pair("lastheight",lastheight));
result.push_back(Pair("minamount",ValueFromAmount(minamount)));
result.push_back(Pair("maxamount",ValueFromAmount(maxamount)));
result.push_back(Pair("currency",currency));
if ( (n= MarmaraGetCreditloops(totalamount,issuances,totalclosed,closed,cp,firstheight,lastheight,minamount,maxamount,refpk,currency)) > 0 )
{
result.push_back(Pair("n",n));
matches = (int32_t)issuances.size();
result.push_back(Pair("pending",matches));
for (i=0; i<matches; i++)
a.push_back(issuances[i].GetHex());
result.push_back(Pair("issuances",a));
result.push_back(Pair("totalamount",ValueFromAmount(totalamount)));
matches = (int32_t)closed.size();
result.push_back(Pair("numclosed",matches));
for (i=0; i<matches; i++)
b.push_back(closed[i].GetHex());
result.push_back(Pair("closed",b));
result.push_back(Pair("totalclosed",ValueFromAmount(totalclosed)));
}
return(result);
}

View File

@@ -799,6 +799,11 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash;
int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count;
if ( pindex == 0 )
{
fprintf(stderr,"komodo_connectblock null pindex\n");
return;
}
memset(&zero,0,sizeof(zero));
komodo_init(pindex->GetHeight());
KOMODO_INITDONE = (uint32_t)time(NULL);
@@ -942,12 +947,15 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
}
}
}
if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) )
if ( ASSETCHAINS_SYMBOL[0] != 0 || height < 100000 )
{
memset(&txhash,0,sizeof(txhash));
komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0);
printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height);
} else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries);
if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) )
{
memset(&txhash,0,sizeof(txhash));
komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0);
printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height);
} else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries);
}
}
}
}

View File

@@ -643,6 +643,11 @@ int32_t komodo_isPoS(CBlock *pblock)
{
txid = pblock->vtx[n-1].vin[0].prevout.hash;
vout = pblock->vtx[n-1].vin[0].prevout.n;
if ( ASSETCHAINS_MARMARA != 0 )
{
fprintf(stderr,"validate proper signature and unlockht preservation\n");
// need to verify it was signed by the non-Marmarapk of the 1of2
}
txtime = komodo_txtime(&value,txid,vout,destaddr);
if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) )
{
@@ -2112,31 +2117,57 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
maxkp = numkp = 0;
lasttime = 0;
}
BOOST_FOREACH(const COutput& out, vecOutputs)
if ( ASSETCHAINS_MARMARA == 0 )
{
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
BOOST_FOREACH(const COutput& out, vecOutputs)
{
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
return(0);
}
counter++;
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
{
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
continue;
}
CAmount nValue = out.tx->vout[out.i].nValue;
if ( nValue < COIN || !out.fSpendable )
continue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
if ( ExtractDestination(pk,address) != 0 )
{
if ( IsMine(*pwalletMain,address) == 0 )
continue;
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
return(0);
}
counter++;
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
{
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
continue;
}
CAmount nValue = out.tx->vout[out.i].nValue;
if ( nValue < COIN || !out.fSpendable )
continue;
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
if ( ExtractDestination(pk,address) != 0 )
{
if ( IsMine(*pwalletMain,address) == 0 )
continue;
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
{
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
}
}
}
}
else
{
struct CCcontract_info *cp,C; uint256 txid; int32_t vout; CAmount nValue; char coinaddr[64]; CPubKey mypk,Marmarapk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_MARMARA);
mypk = pubkey2pk(Mypubkey());
Marmarapk = GetUnspendable(cp,0);
GetCCaddress1of2(cp,coinaddr,Marmarapk,mypk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < COIN )
continue;
if ( GetTransaction(txid,tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
const CScript &scriptPubKey = tx.vout[vout].scriptPubKey;
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,txid,vout,coinaddr,hashbuf,(CScript)scriptPubKey);
fprintf(stderr,"addutxo %.8f numkp.%d vs max.%d\n",(double)nValue/COIN,numkp,maxkp);
}
}
}
@@ -2176,7 +2207,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
}
else
{
fprintf(stderr,"ht.%d error validating winning blocktime %u -> %.8f eligible.%u test prior\n",nHeight,*blocktimep,(double)kp->nValue/COIN,eligible);
//fprintf(stderr,"ht.%d error validating winning blocktime %u -> %.8f eligible.%u test prior\n",nHeight,*blocktimep,(double)kp->nValue/COIN,eligible);
continue;
}
eligible = besttime;
@@ -2218,7 +2249,16 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
txNew.vout[0].nValue = *utxovaluep - txfee;
txNew.nLockTime = earliest;
CTransaction txNewConst(txNew);
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
if ( ASSETCHAINS_MARMARA == 0 )
{
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
}
else
{
fprintf(stderr,"add opreturn and CCFinalizetx\n");
// add opreturn
// signSuccess = CCFinalizetx(...)
}
if (!signSuccess)
fprintf(stderr,"failed to create signature\n");
else

View File

@@ -30,6 +30,10 @@
#define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019
#define _COINBASE_MATURITY 100
#define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7)))
#define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7)))
#define CLEARBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] &= ~(1 << ((bitoffset) & 7)))
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
int32_t MAX_BLOCK_SIZE(int32_t height);

View File

@@ -1388,7 +1388,7 @@ void komodo_passport_iteration()
{
static long lastpos[34]; static char userpass[33][1024]; static uint32_t lasttime,callcounter,lastinterest;
int32_t maxseconds = 10;
FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; cJSON *infoobj,*result; uint64_t RTmask = 0; //CBlockIndex *pindex;
FILE *fp; uint8_t *filedata; long fpos,datalen,lastfpos; int32_t baseid,limit,n,ht,isrealtime,expired,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t buf[3],starttime; uint64_t RTmask = 0; //CBlockIndex *pindex;
expired = 0;
while ( KOMODO_INITDONE == 0 )
{

View File

@@ -48,7 +48,7 @@ unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI,ASSETCHAINS_FOUNDERS;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,ASSETCHAINS_SELFIMPORT;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,ASSETCHAINS_MARMARA;
bool VERUS_MINTBLOCKS;
@@ -71,6 +71,7 @@ uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0;
uint32_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];
uint8_t ASSETCHAINS_CCDISABLES[256];
#define _ASSETCHAINS_EQUIHASH 0
uint32_t ASSETCHAINS_NUMALGOS = 2;

View File

@@ -629,7 +629,7 @@ uint64_t jumblr_increment(uint8_t r,int32_t height,uint64_t total,uint64_t bigge
void jumblr_iteration()
{
static int32_t lastheight; static uint32_t lasttime;
char *zaddr,*addr,*retstr,secretaddr[64]; cJSON *array; int32_t i,iter,height,acpublic,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s;
char *zaddr,*addr,*retstr=0,secretaddr[64]; cJSON *array; int32_t i,iter,height,acpublic,counter,chosen_one,n; uint64_t smallest,medium,biggest,amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint16_t r,s;
acpublic = ASSETCHAINS_PUBLIC;
if ( ASSETCHAINS_SYMBOL[0] == 0 && GetTime() >= KOMODO_SAPLING_DEADLINE )
acpublic = 1;
@@ -648,7 +648,7 @@ void jumblr_iteration()
}
free_json(array);
}
free(retstr);
free(retstr), retstr = 0;
}
}
height = (int32_t)chainActive.LastTip()->GetHeight();
@@ -691,7 +691,7 @@ void jumblr_iteration()
if ( amount > 0 && (retstr= jumblr_sendt_to_z(Jumblr_deposit,addr,dstr(amount))) != 0 )
{
printf("sendt_to_z.(%s)\n",retstr);
free(retstr);
free(retstr), retstr = 0;
}
free(zaddr);
} else printf("no zaddr from jumblr_zgetnewaddress\n");
@@ -723,7 +723,7 @@ void jumblr_iteration()
if ( (retstr= jumblr_sendz_to_z(ptr->dest,addr,dstr(total))) != 0 )
{
printf("n.%d counter.%d chosen_one.%d send z_to_z.(%s)\n",n,counter,chosen_one,retstr);
free(retstr);
free(retstr), retstr = 0;
}
ptr->spent = (uint32_t)time(NULL);
free(zaddr);
@@ -768,7 +768,7 @@ void jumblr_iteration()
if ( (retstr= jumblr_sendz_to_t(ptr->dest,secretaddr,dstr(total))) != 0 )
{
printf("%s send z_to_t.(%s)\n",secretaddr,retstr);
free(retstr);
free(retstr), retstr = 0;
} else printf("null return from jumblr_sendz_to_t\n");
ptr->spent = (uint32_t)time(NULL);
break;

View File

@@ -1654,9 +1654,10 @@ extern int64_t MAX_MONEY;
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],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,baseid,len,n,extralen = 0;
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,baseid,len,n,extralen = 0; uint64_t ccenables[256];
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
memset(ccenables,0,sizeof(ccenables));
memset(disablebits,0,sizeof(disablebits));
if ( GetBoolArg("-gen", false) != 0 )
{
KOMODO_MININGTHREADS = GetArg("-genproclimit",-1);
@@ -1779,6 +1780,33 @@ void komodo_args(char *argv0)
ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0);
ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0);
ASSETCHAINS_MARMARA = GetArg("-ac_marmara",0);
if ( ASSETCHAINS_CC != 0 )
{
ASSETCHAINS_CCLIB = GetArg("-ac_cclib","");
Split(GetArg("-ac_ccenable",""), ccenables, 0);
for (i=nonz=0; i<0x100; i++)
{
if ( ccenables[i] != 0 )
{
nonz++;
fprintf(stderr,"%d ",(uint8_t)(ccenables[i] & 0xff));
}
}
fprintf(stderr,"nonz.%d ccenables[]\n",nonz);
if ( nonz > 0 )
{
for (i=0; i<256; i++)
{
ASSETCHAINS_CCDISABLES[i] = 1;
SETBIT(disablebits,i);
}
for (i=0; i<256; i++)
{
CLEARBIT(disablebits,(ccenables[i] & 0xff));
ASSETCHAINS_CCDISABLES[ccenables[i] & 0xff] = 0;
}
}
}
if ( ASSETCHAINS_BEAMPORT != 0 && ASSETCHAINS_CODAPORT != 0 )
{
fprintf(stderr,"can only have one of -ac_beam or -ac_coda\n");
@@ -1863,7 +1891,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 )
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 )
{
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;
@@ -1939,8 +1967,22 @@ void komodo_args(char *argv0)
extraptr[extralen++] = 'c';
if ( ASSETCHAINS_MARMARA != 0 )
extraptr[extralen++] = ASSETCHAINS_MARMARA;
if ( nonz > 0 )
{
memcpy(&extraptr[extralen],disablebits,sizeof(disablebits));
extralen += sizeof(disablebits);
}
if ( ASSETCHAINS_CCLIB.size() > 1 )
{
for (i=0; i<ASSETCHAINS_CCLIB.size(); i++)
{
extraptr[extralen++] = ASSETCHAINS_CCLIB[i];
fprintf(stderr,"%c",ASSETCHAINS_CCLIB[i]);
}
fprintf(stderr," <- CCLIB name\n");
}
}
addn = GetArg("-seednode","");
if ( strlen(addn.c_str()) > 0 )
ASSETCHAINS_SEED = 1;

View File

@@ -3497,6 +3497,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock(): FindUndoPos failed");
if ( pindex->pprev == 0 )
fprintf(stderr,"ConnectBlock: unexpected null pprev\n");
if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
return AbortNode(state, "Failed to write undo data");

View File

@@ -158,6 +158,7 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
CScript Marmara_scriptPubKey(int32_t height,CPubKey pk);
CScript MarmaraCoinbaseOpret(uint8_t funcid,int32_t height,CPubKey pk);
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
{
@@ -540,11 +541,11 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
txNew.vout[0].nValue += 5000;
pblock->vtx[0] = txNew;
//fprintf(stderr,"ht.%d cmp.%d [%d %d %d %d %d]\n",nHeight,nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0,nHeight > 1,ASSETCHAINS_SYMBOL[0] != 0, (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1), ASSETCHAINS_COMMISSION != 0,(commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0);
// check if coinbase transactions must be time locked at current subsidy and prepend the time lock
// to transaction if so, cast for GTE operator
if ( ASSETCHAINS_MARMARA != 0 && nHeight > 0 && (nHeight & 1) == 0 )
{
char checkaddr[64];
Getscriptaddress(checkaddr,txNew.vout[0].scriptPubKey);
//`fprintf(stderr,"set mining coinbase -> %s\n",checkaddr);
txNew.vout.resize(2);
txNew.vout[1].nValue = 0;
txNew.vout[1].scriptPubKey = MarmaraCoinbaseOpret('C',nHeight,pk);
@@ -1605,11 +1606,11 @@ void static BitcoinMiner()
int32_t percPoS,z; bool fNegative,fOverflow;
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
if ( ASSETCHAINS_STAKED < 100 )
if ( ASSETCHAINS_STAKED < 100 && KOMODO_MININGTHREADS == 0 )
{
for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%% ht.%d\n",percPoS,(int32_t)ASSETCHAINS_STAKED,Mining_height);
}
}
while (true)

View File

@@ -458,10 +458,15 @@ static const CRPCCommand vRPCCommands[] =
{ "marmara", "marmarainfo", &marmara_info, true },
{ "marmara", "marmaracreditloop", &marmara_creditloop, true },
{ "marmara", "marmarasettlement", &marmara_settlement, true },
{ "marmara", "marmaralock", &marmara_lock, true },
// Payments
{ "payments", "paymentsaddress", &paymentsaddress, true },
{ "CClib", "cclibaddress", &cclibaddress, true },
{ "CClib", "cclibinfo", &cclibinfo, true },
{ "CClib", "cclib", &cclib, true },
// Gateways
{ "gateways", "gatewaysaddress", &gatewaysaddress, true },
{ "gateways", "gatewayslist", &gatewayslist, true },

View File

@@ -285,7 +285,11 @@ extern UniValue marmara_transfer(const UniValue& params, bool fHelp);
extern UniValue marmara_info(const UniValue& params, bool fHelp);
extern UniValue marmara_creditloop(const UniValue& params, bool fHelp);
extern UniValue marmara_settlement(const UniValue& params, bool fHelp);
extern UniValue marmara_lock(const UniValue& params, bool fHelp);
extern UniValue paymentsaddress(const UniValue& params, bool fHelp);
extern UniValue cclibaddress(const UniValue& params, bool fHelp);
extern UniValue cclibinfo(const UniValue& params, bool fHelp);
extern UniValue cclib(const UniValue& params, bool fHelp);
extern UniValue gatewaysaddress(const UniValue& params, bool fHelp);
extern UniValue gatewayslist(const UniValue& params, bool fHelp);
extern UniValue gatewaysinfo(const UniValue& params, bool fHelp);

View File

@@ -45,14 +45,14 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
key = *pprivKey;
else if (!keystore || !keystore->GetKey(address, key))
return false;
uint256 hash;
try {
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId);
} catch (logic_error ex) {
return false;
}
if (scriptCode.IsPayToCryptoCondition())
{
CC *cc = (CC *)extraData;
@@ -75,9 +75,9 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return false;
}
}
vchSig.push_back((unsigned char)nHashType);
return true;
}
@@ -128,7 +128,7 @@ std::vector<CCcontract_info> &GetCryptoConditions()
static bool initialized = false;
static std::vector<CCcontract_info> vCC = std::vector<CCcontract_info>();
CCcontract_info C;
if (!initialized)
{
// this should initialize any desired auto-signed crypto-conditions
@@ -140,7 +140,7 @@ bool GetCCByUnspendableAddress(struct CCcontract_info *cp, char *addrstr)
{
std::vector<CCcontract_info> &vCC = GetCryptoConditions();
bool found = false;
for (int i = 0; i < vCC.size(); i++)
{
if (strcmp(addrstr, vCC[i].unspendableCCaddr) == 0)
@@ -157,7 +157,7 @@ bool CCinitLite(struct CCcontract_info *cp, uint8_t evalcode)
{
std::vector<CCcontract_info> &vCC = GetCryptoConditions();
bool found = false;
for (int i = 0; i < vCC.size(); i++)
{
if (vCC[i].evalcode == evalcode)
@@ -172,7 +172,7 @@ bool CCinitLite(struct CCcontract_info *cp, uint8_t evalcode)
bool _Getscriptaddress(char *destaddr, const CScript &scriptPubKey)
{
CTxDestination address;
CTxDestination address;
txnouttype whichType;
std::vector<std::vector<unsigned char>> vvch = std::vector<std::vector<unsigned char>>();
if (Solver(scriptPubKey, whichType, vvch) && vvch[0].size() == 20)
@@ -199,10 +199,10 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
vector<CPubKey> vPK;
vector<valtype> vParams = vector<valtype>();
COptCCParams p;
// get information to sign with
CCcontract_info C;
scriptPubKey.IsPayToCryptoCondition(&subScript, vParams);
if (vParams.empty())
{
@@ -219,12 +219,12 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
p = COptCCParams(vParams[0]);
}
if (p.IsValid() && p.vKeys.size() >= p.n)
{
bool is1of2 = (p.m == 1 && p.n == 2);
CKey privKey;
// must be a valid cc eval code
if (CCinitLite(&C, p.evalCode))
{
@@ -232,7 +232,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
if (!is1of2)
{
bool havePriv = creator.KeyStore().GetKey(p.vKeys[0].GetID(), privKey);
// if we don't have the private key, it must be the unspendable address
if (!havePriv && (p.vKeys[0] == CPubKey(ParseHex(C.CChexstr))))
{
@@ -240,9 +240,9 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
std::vector<unsigned char> vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
privKey.Set(vch.begin(), vch.end(), false);
}
CC *cc = CCcond1(p.evalCode, p.vKeys[0]);
if (cc)
{
vector<unsigned char> vch;
@@ -254,7 +254,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
fprintf(stderr,"vin has 1of1 CC signing error with address.(%s)\n", p.vKeys[0].GetID().ToString().c_str());
}
cc_free(cc);
return ret.size() != 0;
}
@@ -266,7 +266,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
if (creator.IsKeystoreValid() && creator.KeyStore().GetKey(pk.GetID(), privKey) && privKey.IsValid())
break;
if (pk == CPubKey(ParseHex(C.CChexstr)))
{
privKey = CKey();
@@ -275,12 +275,12 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
break;
}
}
if (!privKey.IsValid())
return false;
CC *cc = CCcond1of2(p.evalCode, p.vKeys[0], p.vKeys[1]);
if (cc)
{
vector<unsigned char> vch;
@@ -292,7 +292,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
fprintf(stderr,"vin has 1of2 CC signing error with addresses.(%s)\n(%s)\n", p.vKeys[0].GetID().ToString().c_str(), p.vKeys[1].GetID().ToString().c_str());
}
cc_free(cc);
return ret.size() != 0;
}
@@ -314,9 +314,9 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
CScript scriptRet;
uint160 h160;
ret.clear();
vector<valtype> vSolutions;
if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
{
// if this is a CLTV script, solve for the destination after CLTV
@@ -324,10 +324,10 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
{
uint8_t pushOp = scriptPubKey[0];
uint32_t scriptStart = pushOp + 3;
// check post CLTV script
CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
// check again with only postfix subscript
if (!Solver(postfix, whichTypeRet, vSolutions))
return false;
@@ -335,44 +335,44 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
else
return false;
}
CKeyID keyID;
switch (whichTypeRet)
{
case TX_NONSTANDARD:
case TX_NULL_DATA:
return false;
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId);
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
case TX_NONSTANDARD:
case TX_NULL_DATA:
return false;
else
{
CPubKey vch;
creator.KeyStore().GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
}
return true;
case TX_SCRIPTHASH:
if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId);
case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
return false;
else
{
CPubKey vch;
creator.KeyStore().GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch));
}
return true;
}
return false;
case TX_CRYPTOCONDITION:
return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId));
default:
return false;
case TX_SCRIPTHASH:
if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true;
}
return false;
case TX_CRYPTOCONDITION:
return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId));
default:
return false;
}
}
@@ -399,7 +399,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
txnouttype whichType;
solved = SignStep(creator, script, result, whichType, consensusBranchId);
CScript subscript;
if (solved && whichType == TX_SCRIPTHASH)
{
// Solver returns the subscript that needs to be evaluated;
@@ -409,9 +409,9 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
solved = solved && SignStep(creator, script, result, whichType, consensusBranchId) && whichType != TX_SCRIPTHASH;
result.push_back(std::vector<unsigned char>(subscript.begin(), subscript.end()));
}
sigdata.scriptSig = PushAll(result);
// Test solution
return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), consensusBranchId);
}
@@ -431,19 +431,19 @@ void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const Signatur
}
bool SignSignature(
const CKeyStore &keystore,
const CScript& fromPubKey,
CMutableTransaction& txTo,
unsigned int nIn,
const CAmount& amount,
int nHashType,
uint32_t consensusBranchId)
const CKeyStore &keystore,
const CScript& fromPubKey,
CMutableTransaction& txTo,
unsigned int nIn,
const CAmount& amount,
int nHashType,
uint32_t consensusBranchId)
{
assert(nIn < txTo.vin.size());
CTransaction txToConst(txTo);
TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
SignatureData sigdata;
bool ret = ProduceSignature(creator, fromPubKey, sigdata, consensusBranchId);
UpdateTransaction(txTo, nIn, sigdata);
@@ -451,24 +451,24 @@ bool SignSignature(
}
bool SignSignature(
const CKeyStore &keystore,
const CTransaction& txFrom,
CMutableTransaction& txTo,
unsigned int nIn,
int nHashType,
uint32_t consensusBranchId)
const CKeyStore &keystore,
const CTransaction& txFrom,
CMutableTransaction& txTo,
unsigned int nIn,
int nHashType,
uint32_t consensusBranchId)
{
assert(nIn < txTo.vin.size());
CTxIn& txin = txTo.vin[nIn];
assert(txin.prevout.n < txFrom.vout.size());
const CTxOut& txout = txFrom.vout[txin.prevout.n];
return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, consensusBranchId);
}
static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const vector<valtype>& vSolutions,
const vector<valtype>& sigs1, const vector<valtype>& sigs2, uint32_t consensusBranchId)
const vector<valtype>& vSolutions,
const vector<valtype>& sigs1, const vector<valtype>& sigs2, uint32_t consensusBranchId)
{
// Combine all the signatures we've got:
set<valtype> allsigs;
@@ -482,7 +482,7 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
if (!v.empty())
allsigs.insert(v);
}
// Build a map of pubkey -> signature by matching sigs to pubkeys:
assert(vSolutions.size() > 1);
unsigned int nSigsRequired = vSolutions.front()[0];
@@ -495,7 +495,7 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
const valtype& pubkey = vSolutions[i+1];
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
if (checker.CheckSig(sig, pubkey, scriptPubKey, consensusBranchId))
{
sigs[pubkey] = sig;
@@ -517,108 +517,108 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
// Fill any missing with OP_0:
for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
result.push_back(valtype());
return result;
}
namespace
{
struct Stacks
{
std::vector<valtype> script;
Stacks() {}
explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) {
EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId);
}
SignatureData Output() const {
SignatureData result;
result.scriptSig = PushAll(script);
return result;
}
};
struct Stacks
{
std::vector<valtype> script;
Stacks() {}
explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) {
EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId);
}
SignatureData Output() const {
SignatureData result;
result.scriptSig = PushAll(script);
return result;
}
};
}
static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const txnouttype txType, const vector<valtype>& vSolutions,
Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId)
const txnouttype txType, const vector<valtype>& vSolutions,
Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId)
{
switch (txType)
{
case TX_NONSTANDARD:
case TX_NULL_DATA:
// Don't know anything about this, assume bigger one is correct:
if (sigs1.script.size() >= sigs2.script.size())
return sigs1;
return sigs2;
case TX_PUBKEY:
case TX_PUBKEYHASH:
case TX_CRYPTOCONDITION:
// Signatures are bigger than placeholders or empty scripts:
if (sigs1.script.empty() || sigs1.script[0].empty())
case TX_NONSTANDARD:
case TX_NULL_DATA:
// Don't know anything about this, assume bigger one is correct:
if (sigs1.script.size() >= sigs2.script.size())
return sigs1;
return sigs2;
return sigs1;
case TX_SCRIPTHASH:
if (sigs1.script.empty() || sigs1.script.back().empty())
return sigs2;
else if (sigs2.script.empty() || sigs2.script.back().empty())
case TX_PUBKEY:
case TX_PUBKEYHASH:
case TX_CRYPTOCONDITION:
// Signatures are bigger than placeholders or empty scripts:
if (sigs1.script.empty() || sigs1.script[0].empty())
return sigs2;
return sigs1;
else
{
// Recur to combine:
valtype spk = sigs1.script.back();
CScript pubKey2(spk.begin(), spk.end());
txnouttype txType2;
vector<vector<unsigned char> > vSolutions2;
Solver(pubKey2, txType2, vSolutions2);
sigs1.script.pop_back();
sigs2.script.pop_back();
Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId);
result.script.push_back(spk);
return result;
}
case TX_MULTISIG:
return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId));
default:
return Stacks();
case TX_SCRIPTHASH:
if (sigs1.script.empty() || sigs1.script.back().empty())
return sigs2;
else if (sigs2.script.empty() || sigs2.script.back().empty())
return sigs1;
else
{
// Recur to combine:
valtype spk = sigs1.script.back();
CScript pubKey2(spk.begin(), spk.end());
txnouttype txType2;
vector<vector<unsigned char> > vSolutions2;
Solver(pubKey2, txType2, vSolutions2);
sigs1.script.pop_back();
sigs2.script.pop_back();
Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId);
result.script.push_back(spk);
return result;
}
case TX_MULTISIG:
return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId));
default:
return Stacks();
}
}
SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
const SignatureData& scriptSig1, const SignatureData& scriptSig2,
uint32_t consensusBranchId)
const SignatureData& scriptSig1, const SignatureData& scriptSig2,
uint32_t consensusBranchId)
{
txnouttype txType;
vector<vector<unsigned char> > vSolutions;
Solver(scriptPubKey, txType, vSolutions);
return CombineSignatures(
scriptPubKey, checker, txType, vSolutions,
Stacks(scriptSig1, consensusBranchId),
Stacks(scriptSig2, consensusBranchId),
consensusBranchId).Output();
scriptPubKey, checker, txType, vSolutions,
Stacks(scriptSig1, consensusBranchId),
Stacks(scriptSig2, consensusBranchId),
consensusBranchId).Output();
}
namespace {
/** Dummy signature checker which accepts all signatures. */
class DummySignatureChecker : public BaseSignatureChecker
{
public:
DummySignatureChecker() {}
bool CheckSig(
const std::vector<unsigned char>& scriptSig,
const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode,
uint32_t consensusBranchId) const
/** Dummy signature checker which accepts all signatures. */
class DummySignatureChecker : public BaseSignatureChecker
{
return true;
}
};
const DummySignatureChecker dummyChecker;
public:
DummySignatureChecker() {}
bool CheckSig(
const std::vector<unsigned char>& scriptSig,
const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode,
uint32_t consensusBranchId) const
{
return true;
}
};
const DummySignatureChecker dummyChecker;
}
const BaseSignatureChecker& DummySignatureCreator::Checker() const
@@ -627,12 +627,12 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const
}
bool DummySignatureCreator::CreateSig(
std::vector<unsigned char>& vchSig,
const CKeyID& keyid,
const CScript& scriptCode,
uint32_t consensusBranchId,
CKey *key,
void *extraData) const
std::vector<unsigned char>& vchSig,
const CKeyID& keyid,
const CScript& scriptCode,
uint32_t consensusBranchId,
CKey *key,
void *extraData) const
{
// Create a dummy signature that is a valid DER-encoding
vchSig.assign(72, '\000');
@@ -647,3 +647,4 @@ bool DummySignatureCreator::CreateSig(
vchSig[6 + 33 + 32] = SIGHASH_ALL;
return true;
}

View File

@@ -5094,8 +5094,8 @@ int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
if (!EnsureWalletIsAvailable(0))
return 0;
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL);
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
utxovalue = 0;
memset(&utxotxid,0,sizeof(utxotxid));
@@ -5327,6 +5327,43 @@ UniValue channelsaddress(const UniValue& params, bool fHelp)
return(result);
}
UniValue cclibaddress(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 1 )
throw runtime_error("cclibaddress [pubkey]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
if ( params.size() == 1 )
pubkey = ParseHex(params[0].get_str().c_str());
return(CCaddress(cp,(char *)"CClib",pubkey));
}
UniValue cclibinfo(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 0 )
throw runtime_error("cclibinfo\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
return(CClib_info(cp));
}
UniValue cclib(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; char *method; cJSON *jsonparams;
cp = CCinit(&C,EVAL_FIRSTUSER);
if ( fHelp || params.size() > 2 )
throw runtime_error("cclib method [JSON params]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
method = (char *)params[0].get_str().c_str();
jsonparams = cJSON_Parse(params[1].get_str().c_str());
return(CClib(cp,method,jsonparams));
}
UniValue oraclesaddress(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
@@ -5558,8 +5595,9 @@ UniValue marmara_receive(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 batontxid; std::vector<uint8_t> senderpub; int64_t amount; int32_t matures; std::string currency;
if ( fHelp || (params.size() != 5 && params.size() != 4) )
{
// automatic flag -> lsb of matures
// 1st marmarareceive 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1440
// after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 3903 bf6b4d42aa3ce974c853d73b06c78597dd3b5fb493d5d0d944f72c2017f561ad
// after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 1168 d72d87aa0d50436de695c93e2bf3d7273c63c92ef6307913aa01a6ee6a16548b
throw runtime_error("marmarareceive senderpk amount currency matures batontxid\n");
}
if ( ensure_CCrequirements() < 0 )
@@ -5578,7 +5616,7 @@ UniValue marmara_receive(const UniValue& params, bool fHelp)
matures = atol(params[3].get_str().c_str());
batontxid = Parseuint256((char *)params[4].get_str().c_str());
} else matures = atol(params[3].get_str().c_str()) + chainActive.LastTip()->GetHeight() + 1;
return(MarmaraReceive(0,pubkey2pk(senderpub),amount,currency,matures,batontxid));
return(MarmaraReceive(0,pubkey2pk(senderpub),amount,currency,matures,batontxid,true));
}
UniValue marmara_issue(const UniValue& params, bool fHelp)
@@ -5586,7 +5624,9 @@ UniValue marmara_issue(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 approvaltxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency;
if ( fHelp || params.size() != 5 )
{
// marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 3903 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be
// marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 1168 32da4cb3e886ee42de90b4a15042d71169077306badf909099c5c5c692df3f27
// marmaraissue 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 700 MARMARA 2629 11fe8bf1de80c2ef69124d08907f259aef7f41e3a632ca2d48ad072a8c8f3078 -> 335df3a5dd6b92a3d020c9465d4d76e0d8242126106b83756dcecbad9813fdf3
throw runtime_error("marmaraissue receiverpk amount currency matures approvaltxid\n");
}
if ( ensure_CCrequirements() < 0 )
@@ -5609,7 +5649,7 @@ UniValue marmara_transfer(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); uint256 approvaltxid,batontxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency; std::vector<uint256> creditloop;
if ( fHelp || params.size() != 5 )
{
// marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 3903 748a4c80e6f6b725340fb0f52738f38a11c422d59b3034c8366b3d7b33c99a1e
// marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1168 1506c774e4b2804a6e25260920840f4cfca8d1fb400e69fe6b74b8e593dbedc5
throw runtime_error("marmaratransfer receiverpk amount currency matures approvaltxid\n");
}
if ( ensure_CCrequirements() < 0 )
@@ -5679,7 +5719,7 @@ UniValue marmara_settlement(const UniValue& params, bool fHelp)
if ( fHelp || params.size() != 1 )
{
// marmarasettlement 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be
// marmarasettlement cc23bf81733556dc06db2fd9c9f4178cad44bdc237d6e62101cf0cdafb5195f7
// marmarasettlement ff3e259869196f3da9b5ea3f9e088a76c4fc063cf36ab586b652e121d441a603
throw runtime_error("marmarasettlement batontxid\n");
}
if ( ensure_CCrequirements() < 0 )
@@ -5689,6 +5729,20 @@ UniValue marmara_settlement(const UniValue& params, bool fHelp)
return(result);
}
UniValue marmara_lock(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); int64_t amount; int32_t height;
if ( fHelp || params.size() > 2 || params.size() == 0 )
{
throw runtime_error("marmaralock amount unlockht\n");
}
amount = atof(params[0].get_str().c_str()) * COIN + 0.00000000499999;
if ( params.size() == 2 )
height = atol(params[1].get_str().c_str());
else height = chainActive.LastTip()->GetHeight() + 1;
return(MarmaraLock(0,amount,height));
}
UniValue channelslist(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() > 0 )

View File

@@ -42,6 +42,21 @@ PREFIX="$(pwd)/depends/$TRIPLET"
make "$@" -C ./depends/ V=1 NO_QT=1 NO_PROTON=1
#BUILD CCLIB
WD=$PWD
cd src/cc
echo $PWD
if make "$@"; then
echo CCLIB BUILD SUCCESSFUL
else
echo CCLIB BUILD FAILED
exit 1
fi
cd $WD
./autogen.sh
CPPFLAGS="-I$PREFIX/include -arch x86_64" LDFLAGS="-L$PREFIX/lib -arch x86_64 -Wl,-no_pie" \
CXXFLAGS='-arch x86_64 -I/usr/local/Cellar/gcc\@6/6.4.0_2/include/c++/6.4.0/ -I$PREFIX/include -fwrapv -fno-strict-aliasing -Werror -g -Wl,-undefined -Wl,dynamic_lookup' \

View File

@@ -101,6 +101,21 @@ eval "$MAKE" --version
as --version
ld -v
#BUILD CCLIB
WD=$PWD
cd src/cc
echo $PWD
if make "$@"; then
echo CCLIB BUILD SUCCESSFUL
else
echo CCLIB BUILD FAILED
exit 1
fi
cd $WD
HOST="$HOST" BUILD="$BUILD" NO_PROTON="$PROTON_ARG" "$MAKE" "$@" -C ./depends/ V=1
./autogen.sh