jl777
5 years ago
3 changed files with 138 additions and 1 deletions
@ -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"); |
|||
} |
|||
|
|||
|
@ -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…
Reference in new issue