Browse Source

customcc

pull/4/head
jl777 5 years ago
parent
commit
24e27eb7ea
  1. 15
      src/cc/cclib.cpp
  2. 80
      src/cc/customcc.cpp
  3. 44
      src/cc/customcc.h

15
src/cc/cclib.cpp

@ -33,8 +33,12 @@
#ifdef BUILD_ROGUE
#define EVAL_ROGUE 17
std::string MYCCLIBNAME = (char *)"rogue";
#else
#elif BUILD_CUSTOMCC
#include "customcc.h"
#else
#define EVAL_SUDOKU 17
#define EVAL_MUSIG 18
#define EVAL_DILITHIUM 19
@ -67,6 +71,8 @@ CClib_methods[] =
{ (char *)"rogue", (char *)"games", (char *)"<no args>", 0, 0, 'F', EVAL_ROGUE },
{ (char *)"rogue", (char *)"setname", (char *)"pname", 1, 1, 'N', EVAL_ROGUE },
{ (char *)"rogue", (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, 'X', EVAL_ROGUE },
#elif BUILD_CUSTOMCC
RPC_FUNCS
#else
{ (char *)"sudoku", (char *)"gen", (char *)"<no args>", 0, 0, 'G', EVAL_SUDOKU },
{ (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU },
@ -214,6 +220,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
return(result);
}
}
#elif BUILD_CUSTOMCC
CUSTOM_DISPATCH
#else
if ( cp->evalcode == EVAL_SUDOKU )
{
@ -410,6 +418,8 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
{
#ifdef BUILD_ROGUE
return(rogue_validate(cp,height,eval,tx));
#elif BUILD_CUSTOMCC
return(custom_validate(cp,height,eval,tx));
#else
if ( cp->evalcode == EVAL_SUDOKU )
return(sudoku_validate(cp,height,eval,tx));
@ -660,6 +670,9 @@ int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len)
#include "rogue/weapons.c"
#include "rogue/wizard.c"
#elif BUILD_CUSTOMCC
#include "customcc.cpp"
#else
#include "sudoku.cpp"
#include "musig.cpp"

80
src/cc/customcc.cpp

@ -0,0 +1,80 @@
/*
simple stub custom cc
*/
CScript custom_opret(uint8_t funcid,CPubKey pk)
{
CScript opret; uint8_t evalcode = EVAL_CUSTOM;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk);
return(opret);
}
uint8_t custom_opretdecode(CPubKey &pk,CScript scriptPubKey)
{
std::vector<uint8_t> vopret; uint8_t e,f;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_CUSTOM )
{
return(f);
}
return(0);
}
UniValue custom_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
{
CTransaction tx;
if ( rawtx.size() > 0 )
{
result.push_back(Pair("hex",rawtx));
if ( DecodeHexTx(tx,rawtx) != 0 )
{
if ( broadcastflag != 0 && myAddtomempool(tx) != 0 )
RelayTransaction(tx);
result.push_back(Pair("txid",tx.GetHash().ToString()));
result.push_back(Pair("result","success"));
} else result.push_back(Pair("error","decode hex"));
} else result.push_back(Pair("error","couldnt finalize CCtx"));
return(result);
}
UniValue custom_func0(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
result.push_back(Pair("result","success"));
result.push_back(Pair("message","just an example of an information returning rpc"));
return(result);
}
// send yourself 1 coin to your CC address using normal utxo from your -pubkey
UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); CPubKey mypk; int64_t amount = COIN; int32_t broadcastflag=0;
if ( txfee == 0 )
txfee = CUSTOM_TXFEE;
mypk = pubkey2pk(Mypubkey());
if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk)); // make vout0
// add opreturn, change is automatically added and tx is properly signed
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,custom_opret('1',mypk));
return(custom_rawtxresult(result,rawtx,broadcastflag));
}
return(result);
}
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{
char expectedaddress[64]; CPubKey pk;
if ( tx.vout.size() != 2 ) // make sure the tx only has 2 outputs
return eval->Invalid("invalid number of vouts");
else if ( custom_opretdecode(pk,tx.vout[1].scriptPubKey) != '1' ) // verify has opreturn
return eval->Invalid("invalid opreturn");
GetCCaddress(cp,expectedaddress,pk)
if ( IsCClibvout(cp,tx,0,expectedaddress) == COIN ) // make sure amount and destination matches
return(true);
else return eval->Invalid("invalid vout0 amount");
}

44
src/cc/customcc.h

@ -0,0 +1,44 @@
/*
to create a custom libcc.so:
1. change "func0" and "func1" to method names that fit your custom cc. Of course, you can create more functions by adding another entry to RPC_FUNCS. there is not any practical limit to the number of methods.
2. For each method make sure there is a UniValue function declaration and CUSTOM_DISPATCH has an if statement checking for it that calls the custom_func
3. write the actual custom_func0, custom_func1 and custom_validate in customcc.cpp
4. build cclib.cpp with -DBUILD_CUSTOMCC and put the libcc.so in ~/komodo/src and rebuild komodod
5. launch your chain with -ac_cclib=customcc -ac_cc=2
*/
std::string MYCCLIBNAME = (char *)"customcc";
#define EVAL_CUSTOM (EVAL_FAUCET2+1)
#define MYCCNAME "custom"
#define RPC_FUNCS \
{ (char *)MYCCNAME, (char *)"func0", (char *)"<parameter help>", 1, 1, '0', EVAL_CUSTOM }, \
{ (char *)MYCCNAME, (char *)"func1", (char *)"<no args>", 0, 0, '1', EVAL_CUSTOM },
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
UniValue custom_func0(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
#define CUSTOM_DISPATCH \
if ( cp->evalcode == EVAL_SUDOKU ) \
{ \
if ( strcmp(method,"func0") == 0 ) \
return(custom_func0(txfee,cp,params)); \
else if ( strcmp(method,"func1") == 0 ) \
return(custom_func1(txfee,cp,params)); \
else \
{ \
result.push_back(Pair("result","error")); \
result.push_back(Pair("error","invalid customcc method")); \
result.push_back(Pair("method",method)); \
return(result); \
} \
}
Loading…
Cancel
Save