Browse Source

Initial oracles CC without validation

metaverse
jl777 6 years ago
parent
commit
366625ca23
  1. 7
      src/cc/CCOracles.h
  2. 1
      src/cc/CCinclude.h
  3. 9
      src/cc/CCutils.cpp
  4. 10
      src/cc/MofN.cpp
  5. 2
      src/cc/fsm.cpp
  6. 5
      src/cc/gateways.cpp
  7. 243
      src/cc/oracles.cpp
  8. 3
      src/cc/payments.cpp
  9. 5
      src/cc/pegs.cpp
  10. 4
      src/cc/prices.cpp
  11. 2
      src/cc/triggers.cpp
  12. 8
      src/rpcserver.cpp
  13. 6
      src/rpcserver.h
  14. 112
      src/wallet/rpcwallet.cpp

7
src/cc/CCOracles.h

@ -20,8 +20,13 @@
#include "CCinclude.h"
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format);
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee);
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount);
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data);
// CCcustom
UniValue OraclesInfo();
UniValue OracleInfo(uint256 origtxid);
UniValue OraclesList();
#endif

1
src/cc/CCinclude.h

@ -93,6 +93,7 @@ int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
// CCutils
CPubKey buf2pk(uint8_t *buf33);
void endiancpy(uint8_t *dest,uint8_t *src,int32_t len);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv);
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);

9
src/cc/CCutils.cpp

@ -149,6 +149,15 @@ uint256 Parseuint256(char *hexstr)
return(txid);
}
CPubKey buf2pk(uint8_t *buf33)
{
CPubKey pk; int32_t i; uint8_t *dest;
dest = (uint8_t *)pk.begin();
for (i=0; i<33; i++)
dest[i] = buf33[i];
return(pk);
}
CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
{
CPubKey pk; int32_t i,n; uint8_t *dest,*pubkey33;

10
src/cc/MofN.cpp

@ -22,6 +22,16 @@
ability to post partial signatures and construct a full transaction from M such partial signatures
a new transaction would refer to the initialtx and other partial would refer to both
There is no need for a CC contract to use it for normal multisig as normal multisig transactions are already supported.
In order to take advantage of CC powers, we can create a more powerful multisig using shamir's secret MofN (up to 255) algo to allow spends. Using the same non-interactive partial signing is possible. also, in addition to spending, data payload can have additional data that is also revealed when the funds are spent.
rpc calls needed:
1) create msig address (normal or shamir)
2) post payment with partial sig
3) add partial sig to 2)
4) combine and submit M partial sigs
*/
// start of consensus code

2
src/cc/fsm.cpp

@ -17,6 +17,8 @@
#include "../txmempool.h"
/*
FSM CC is a highlevel CC contract that mostly uses other CC contracts. A finite state machine is defined, which combines triggers, payments and whatever other events/actions into a state machine
*/
// start of consensus code

5
src/cc/gateways.cpp

@ -16,6 +16,11 @@
#include "CCGateways.h"
/*
Uses MofN CC's normal msig handling to create automated deposits -> token issuing. And partial signing by the selected pubkeys for releasing the funds. A user would be able to select which pubkeys to use to construct the automated deposit/redeem multisigs.
the potential pubkeys to be used would be based on active oracle data providers with recent activity.
*/
// start of consensus code

243
src/cc/oracles.cpp

@ -16,6 +16,46 @@
#include "CCOracles.h"
/*
An oracles CC has the purpose of converting offchain data into onchain data
simplest would just be to have a pubkey(s) that are trusted to provide such data, but this wont need to have a CC involved at all and can just be done by convention
That begs the question, "what would an oracles CC do?"
A couple of things come to mind, ie. payments to oracles for future offchain data and maybe some sort of dispute/censoring ability
first step is to define the data that the oracle is providing. A simple name:description tx can be created to define the name and description of the oracle data.
linked to this txid would be two types of transactions:
a) oracle providers
b) oracle data users
In order to be resistant to sybil attacks, the feedback mechanism needs to have a cost. combining with the idea of payments for data, the oracle providers will be ranked by actual payments made to each oracle for each data type.
Required transactions:
0) create oracle description -> just needs to create txid for oracle data
1) register as oracle data provider with price -> become a registered oracle data provider
2) pay provider for N oracle data points -> lock funds for oracle provider
3) publish oracle data point -> publish data and collect payment
create:
vins.*: normal inputs
vout.0: txfee tag to oracle normal address
vout.1: opreturn with name and description and format for data
register:
vins.*: normal inputs
vout.0: txfee tag to normal marker address
vout.1: opreturn with createtxid, pubkey and price per data point
subscribe:
vins.*: normal inputs
vout.0: subscription fee to publishers CC address
vout.1: opreturn with createtxid, registered provider's pubkey, amount
data:
vin.0: normal input
vin.1+: subscription vout.0
vout.0: change to publishers CC address
vout.1: payment for dataprovider
vout.2: opreturn with data in proper format
*/
@ -139,73 +179,188 @@ int64_t AddOraclesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
return(totalinputs);
}
std::string OraclesGet(uint64_t txfee,int64_t nValue)
int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubKey regpk)
{
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Oraclespk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
char coinaddr[64]; CPubKey pk; int64_t total=0,num; uint256 txid,hashBlock; CTransaction subtx;
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
GetCCaddress(cp,coinaddr,regpk);
SetCCtxids(addressIndex,coinaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,subtx,hashBlock,false) != 0 )
{
if ( subtx.vout.size() > 0 && DecodeOraclesOpRet(subtx.vout[subtx.vout.size()-1].scriptPubKey,subtxid,pk,num) == 'S' && subtxid == oracletxid && regpk == pk )
{
total += subtx.vout[0].nValue;
}
}
}
return(total);
}
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format)
{
CMutableTransaction mtx; CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_ORACLES);
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
{
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
return("");
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
Oraclespk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
{
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(Oraclespk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesCreateOpRet('C',name,description,format)));
}
return("");
}
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
{
CMutableTransaction mtx; CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; uint8_t buf33[33]; char markeraddr[64];
cp = CCinit(&C,EVAL_ORACLES);
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
{
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
return("");
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddOraclesInputs(cp,mtx,Oraclespk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_ORACLES,CCchange,Oraclespk));
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_ORACLES << (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));
buf33[0] = 0x02;
endiancpy(&buf[1],(uint8_t *)&oracletxid,32);
markerpubkey = buf2pk(buf33);
Getscriptaddress(markeraddr,CScript() << markerpubkey << OP_CHECKSIG);
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
{
mtx.vout.push_back(CTxOut(txfee,CScript() << markerpubkey << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,datafee)));
}
return("");
}
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount)
{
CMutableTransaction mtx; CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; uint8_t buf33[33]; char markeraddr[64];
cp = CCinit(&C,EVAL_ORACLES);
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
{
fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
return("");
} else fprintf(stderr,"cant find Oracles inputs\n");
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
buf33[0] = 0x02;
endiancpy(&buf[1],(uint8_t *)&oracletxid,32);
markerpubkey = buf2pk(buf33);
Getscriptaddress(markeraddr,CScript() << markerpubkey << OP_CHECKSIG);
if ( AddNormalinputs(mtx,mypk,amount + 2*txfee,1) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,publisher));
mtx.vout.push_back(CTxOut(txfee,CScript() << markerpubkey << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesOpRet('R',oracletxid,mypk,amount)));
}
return("");
}
std::string OraclesFund(uint64_t txfee,int64_t funds)
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data)
{
CMutableTransaction mtx; CPubKey mypk,Oraclespk; CScript opret; struct CCcontract_info *cp,C;
CMutableTransaction mtx; CPubKey mypk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; char coinaddr[64];
cp = CCinit(&C,EVAL_ORACLES);
if ( data.size() > 8192 )
{
fprintf(stderr,"datasize %d is too big\n",(int32_t)data.size());
return("");
}
if ( (datafee= OracleDatafee(oracletxid)) <= 0 )
{
fprintf(stderr,"datafee %.8f is illegal\n",(double)datafee/COIN);
return("");
}
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
Oraclespk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
GetCCaddress(cp,coinaddr,mypk);
if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_ORACLES,funds,Oraclespk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
if ( (inputs= AddOracleInputs(cp,mtx,mypk,oracletxid,datafee,60)) > 0 )
{
if ( inputs > datafee )
CCchange = (inputs - datafee);
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,mypk));
mtx.vout.push_back(CTxOut(txfee,CScript() << mypk << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeOraclesData('D',oracletxid,mypk,data)));
}
}
return("");
}
UniValue OraclesInfo()
UniValue OracleInfo(uint256 origtxid)
{
UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx; CPubKey Oraclespk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success"));
result.push_back(Pair("name","Oracles"));
UniValue result(UniValue::VOBJ),a(UniValue::VARR),obj(UniValue::VOBJ); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; CTransaction regtx; std::string name,description,format; uint256 hashBlock,txid,oracletxid; CMutableTransaction mtx; CPubKey Oraclespk,markerpubkey; struct CCcontract_info *cp,C; uint8_t buf33[33]; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64];
cp = CCinit(&C,EVAL_ORACLES);
Oraclespk = GetUnspendable(cp,0);
funding = AddOraclesInputs(cp,mtx,Oraclespk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
buf33[0] = 0x02;
endiancpy(&buf[1],(uint8_t *)&origtxid,32);
markerpubkey = buf2pk(buf33);
Getscriptaddress(markeraddr,CScript() << markerpubkey << OP_CHECKSIG);
if ( GetTransaction(origtxid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeOraclesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
{
result.push_back(Pair("txid",uint256_str(str,origtxid)));
result.push_back(Pair("name",name));
result.push_back(Pair("description",description));
result.push_back(Pair("marker",markeraddr));
SetCCtxids(addressIndex,markeraddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,regtx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == origtxid )
{
result.push_back(Pair("provider",pubkey33_str(str,(uint8_t *)pk.begin())));
funding = LifetimeOraclesFunds(cp,oracletxid,pk);
sprintf(numstr,"%.8f",(double)funding/COIN);
obj.push_back(Pair("lifetime",numstr));
funding = AddOraclesInputs(cp,mtx,pk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
obj.push_back(Pair("funds",numstr));
sprintf(numstr,"%.8f",(double)datafee/COIN);
obj.push_back(Pair("datafee",numstr));
a.push_back(obj);
}
}
}
result.push_back(Pair("registered",a));
}
}
return(result);
}
UniValue OraclesList()
{
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction createtx; std::string name,description,format; char str[65];
cp = CCinit(&C,EVAL_ORACLES);
SetCCtxids(addressIndex,cp->normaladdr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
{
txid = it->first.txhash;
if ( GetTransaction(txid,createtx,hashBlock,false) != 0 )
{
if ( createtx.vout.size() > 0 && DecodeOraclesFundingOpRet(createtx.vout[createtx.vout.size()-1].scriptPubKey,name,description,format) == 'C' )
{
result.push_back(uint256_str(str,txid));
}
}
}
return(result);
}

3
src/cc/payments.cpp

@ -16,6 +16,9 @@
#include "CCPayments.h"
/*
Payments CC is a catchall CC, supported invoices, zpayments, automated funds allocation, including token based revshare
*/
// start of consensus code

5
src/cc/pegs.cpp

@ -16,6 +16,11 @@
#include "CCPegs.h"
/*
Pegs CC builds on top of Prices CC and would bind a pricefeed to a token bid/ask automated marketmaking.
Funds deposited into CC address for a specific peg would then be used to fund the bid/ask as the pricefeed changes the price. Profits/losses would accumulate in the associated address.
In the event funds exceed a specified level, it can be spent into a collection address. The idea is that the collection address can further be used for revshares.
*/
// start of consensus code

4
src/cc/prices.cpp

@ -16,6 +16,10 @@
#include "CCPrices.h"
/*
Prices CC would best build on top of the oracles CC, ie. to combine payments for multiple oracles and to calculate a 51% protected price feed.
CC locked funds can be used for automated trading
*/
// start of consensus code

2
src/cc/triggers.cpp

@ -16,6 +16,8 @@
#include "CCTriggers.h"
/*
Triggers CC is a building block CC that allows creation of event -> action processing, where events are defined during trigger creation and actions to be mostly done via payments, but by making payments to other CC contracts, it can be used to invoke other CC contracts
*/
// start of consensus code

8
src/rpcserver.cpp

@ -386,7 +386,13 @@ static const CRPCCommand vRPCCommands[] =
{ "channels", "channelsrefund", &channelsrefund, true },
/* Oracles */
{ "oracles", "oraclesaddress", &oraclesaddress, true },
{ "oracles", "oraclesaddress", &oraclesaddress, true },
{ "oracles", "oracleslist", &oracleslist, true },
{ "oracles", "oraclesinfo", &oraclesinfo, true },
{ "oracles", "oraclescreate", &oraclescreate, true },
{ "oracles", "oraclesregister", &oraclesregister, true },
{ "oracles", "oraclessubscribe", &oraclessubscribe, true },
{ "oracles", "oraclesdata", &oraclesdata, true },
/* Prices */
{ "prices", "pricesaddress", &pricesaddress, true },

6
src/rpcserver.h

@ -224,6 +224,12 @@ extern UniValue tokenfillask(const UniValue& params, bool fHelp);
extern UniValue mofnaddress(const UniValue& params, bool fHelp);
extern UniValue channelsaddress(const UniValue& params, bool fHelp);
extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
extern UniValue oracleslist(const UniValue& params, bool fHelp);
extern UniValue oraclesinfo(const UniValue& params, bool fHelp);
extern UniValue oraclescreate(const UniValue& params, bool fHelp);
extern UniValue oraclesregister(const UniValue& params, bool fHelp);
extern UniValue oraclessubscribe(const UniValue& params, bool fHelp);
extern UniValue oraclesdata(const UniValue& params, bool fHelp);
extern UniValue pricesaddress(const UniValue& params, bool fHelp);
extern UniValue pegsaddress(const UniValue& params, bool fHelp);
extern UniValue triggersaddress(const UniValue& params, bool fHelp);

112
src/wallet/rpcwallet.cpp

@ -5347,7 +5347,6 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp)
UniValue rewardslist(const UniValue& params, bool fHelp)
{
uint256 tokenid;
if ( fHelp || params.size() > 0 )
throw runtime_error("rewardslist\n");
if ( ensure_CCrequirements() < 0 )
@ -5366,6 +5365,117 @@ UniValue rewardsinfo(const UniValue& params, bool fHelp)
return(RewardsInfo(fundingtxid));
}
UniValue oracleslist(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() > 0 )
throw runtime_error("oracleslist\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(OraclesList());
}
UniValue oraclesinfo(const UniValue& params, bool fHelp)
{
uint256 txid;
if ( fHelp || params.size() != 1 )
throw runtime_error("oraclesinfo oracletxid\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");
txid = Parseuint256((char *)params[0].get_str().c_str());
return(OracleInfo(txid));
}
UniValue oraclesregister(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 txid; int64_t datafee;
if ( fHelp || params.size() != 2 )
throw runtime_error("oraclesregister oracletxid datafee\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");
txid = Parseuint256((char *)params[0].get_str().c_str());
datafee = atol((char *)params[1].get_str().c_str());
hex = OracleRegister(0,txid,datafee);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt register with oracle txid");
return(result);
}
UniValue oraclessubscribe(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 txid; int64_t amount; std::vector<unsigned char> pubkey;
if ( fHelp || params.size() != 3 )
throw runtime_error("oraclessubscribe oracletxid publisher datafee\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");
txid = Parseuint256((char *)params[0].get_str().c_str());
pubkey = ParseHex(params[1].get_str().c_str());
amount = atol((char *)params[2].get_str().c_str());
hex = OracleSubscribe(0,txid,pubkey2pk(pubkey),amount);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt register with oracle txid");
return(result);
}
UniValue oraclesdata(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 txid; std::vector<unsigned char> data;
if ( fHelp || params.size() != 2 )
throw runtime_error("oraclesdata oracletxid hexstr\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");
txid = Parseuint256((char *)params[0].get_str().c_str());
data = ParseHex(params[1].get_str().c_str());
hex = OracleData(0,txid,data);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt publish data with oracle txid");
return(result);
}
UniValue oraclescreate(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string name,description,format,hex;
if ( fHelp || params.size() != 3 )
throw runtime_error("oraclescreate name description format\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");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
name = params[0].get_str();
if ( name.size() == 0 || name.size() > 32)
{
ERR_RESULT("oracles name must not be empty and up to 32 characters");
return(result);
}
description = params[1].get_str();
if ( description.size() > 4096 )
{
ERR_RESULT("oracles description must be <= 4096 characters");
return(result);
}
format = params[2].get_str();
if ( format.size() > 4096 )
{
ERR_RESULT("oracles format must be <= 4096 characters");
return(result);
}
hex = OracleCreate(0,name,description,format);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt create oracle");
return(result);
}
UniValue FSMcreate(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string name,states,hex;

Loading…
Cancel
Save