MofN -> Heir

This commit is contained in:
jl777
2018-11-10 10:25:34 -11:00
parent 84efe780fe
commit 064a97f021
9 changed files with 63 additions and 78 deletions

View File

@@ -267,7 +267,7 @@ libbitcoin_server_a_SOURCES = \
cc/dice.cpp \ cc/dice.cpp \
cc/lotto.cpp \ cc/lotto.cpp \
cc/fsm.cpp \ cc/fsm.cpp \
cc/MofN.cpp \ cc/heir.cpp \
cc/oracles.cpp \ cc/oracles.cpp \
cc/prices.cpp \ cc/prices.cpp \
cc/pegs.cpp \ cc/pegs.cpp \

View File

@@ -95,7 +95,7 @@ EVAL(EVAL_DICE, 0xe6) \
EVAL(EVAL_FSM, 0xe7) \ EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \ EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \ EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \ EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \ EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \ EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \ EVAL(EVAL_PRICES, 0xed) \

View File

@@ -14,16 +14,16 @@
******************************************************************************/ ******************************************************************************/
#ifndef CC_MOFN_H #ifndef CC_HEIR_H
#define CC_MOFN_H #define CC_HEIR_H
#include "CCinclude.h" #include "CCinclude.h"
#define EVAL_MOFN 0xea #define EVAL_HEIR 0xea
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCcustom // CCcustom
UniValue MofNInfo(); UniValue HeirInfo();
#endif #endif

View File

@@ -21,7 +21,7 @@
#include "CCauction.h" #include "CCauction.h"
#include "CClotto.h" #include "CClotto.h"
#include "CCfsm.h" #include "CCfsm.h"
#include "CCMofN.h" #include "CCHeir.h"
#include "CCchannels.h" #include "CCchannels.h"
#include "CCOracles.h" #include "CCOracles.h"
#include "CCPrices.h" #include "CCPrices.h"
@@ -133,13 +133,13 @@ uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x
#undef FUNCNAME #undef FUNCNAME
#undef EVALCODE #undef EVALCODE
// MofN // Heir
#define FUNCNAME IsMofNInput #define FUNCNAME IsHeirInput
#define EVALCODE EVAL_MOFN #define EVALCODE EVAL_HEIR
const char *MofNCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy"; const char *HeirCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy";
const char *MofNNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf"; const char *HeirNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf";
char MofNCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" }; char HeirCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" };
uint8_t MofNCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce }; uint8_t HeirCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce };
#include "CCcustom.inc" #include "CCcustom.inc"
#undef FUNCNAME #undef FUNCNAME
#undef EVALCODE #undef EVALCODE
@@ -282,13 +282,13 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode)
cp->validate = AuctionValidate; cp->validate = AuctionValidate;
cp->ismyvin = IsAuctionInput; cp->ismyvin = IsAuctionInput;
break; break;
case EVAL_MOFN: case EVAL_HEIR:
strcpy(cp->unspendableCCaddr,MofNCCaddr); strcpy(cp->unspendableCCaddr,HeirCCaddr);
strcpy(cp->normaladdr,MofNNormaladdr); strcpy(cp->normaladdr,HeirNormaladdr);
strcpy(cp->CChexstr,MofNCChexstr); strcpy(cp->CChexstr,HeirCChexstr);
memcpy(cp->CCpriv,MofNCCpriv,32); memcpy(cp->CCpriv,HeirCCpriv,32);
cp->validate = MofNValidate; cp->validate = HeirValidate;
cp->ismyvin = IsMofNInput; cp->ismyvin = IsHeirInput;
break; break;
case EVAL_CHANNELS: case EVAL_CHANNELS:
strcpy(cp->unspendableCCaddr,ChannelsCCaddr); strcpy(cp->unspendableCCaddr,ChannelsCCaddr);

View File

@@ -47,7 +47,7 @@
EVAL(EVAL_FSM, 0xe7) \ EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \ EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \ EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \ EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \ EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \ EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \ EVAL(EVAL_PRICES, 0xed) \

View File

@@ -13,30 +13,15 @@
* * * *
******************************************************************************/ ******************************************************************************/
#include "CCMofN.h" #include "CCHeir.h"
/* /*
The idea of MofN CC is to allow non-interactive multisig, preferably in a cross chain compatible way, ie. for actual bitcoin multisig. The idea of Heir CC is to allow crypto inheritance
full redeemscript in an initial tx with opreturn
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 // start of consensus code
int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) int64_t IsHeirvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{ {
char destaddr[64]; char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -47,7 +32,7 @@ int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
return(0); return(0);
} }
bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) bool HeirExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{ {
static uint256 zerohash; static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
@@ -65,8 +50,8 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
{ {
//fprintf(stderr,"vini.%d check hash and vout\n",i); //fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash ) if ( hashBlock == zerohash )
return eval->Invalid("cant MofN from mempool"); return eval->Invalid("cant Heir from mempool");
if ( (assetoshis= IsMofNvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) if ( (assetoshis= IsHeirvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis; inputs += assetoshis;
} }
} }
@@ -74,7 +59,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
for (i=0; i<numvouts; i++) for (i=0; i<numvouts; i++)
{ {
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts); //fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsMofNvout(cp,tx,i)) != 0 ) if ( (assetoshis= IsHeirvout(cp,tx,i)) != 0 )
outputs += assetoshis; outputs += assetoshis;
} }
if ( inputs != outputs+txfee ) if ( inputs != outputs+txfee )
@@ -85,7 +70,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
else return(true); else return(true);
} }
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{ {
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64]; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
return(false); return(false);
@@ -105,9 +90,9 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
} }
} }
//fprintf(stderr,"check amounts\n"); //fprintf(stderr,"check amounts\n");
if ( MofNExactAmounts(cp,eval,tx,1,10000) == false ) if ( HeirExactAmounts(cp,eval,tx,1,10000) == false )
{ {
fprintf(stderr,"mofnget invalid amount\n"); fprintf(stderr,"Heirget invalid amount\n");
return false; return false;
} }
else else
@@ -116,8 +101,8 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
memcpy(hash,&txid,sizeof(hash)); memcpy(hash,&txid,sizeof(hash));
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 ) if ( retval != 0 )
fprintf(stderr,"mofnget validated\n"); fprintf(stderr,"Heirget validated\n");
else fprintf(stderr,"mofnget invalid\n"); else fprintf(stderr,"Heirget invalid\n");
return(retval); return(retval);
} }
} }
@@ -126,7 +111,7 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
// helper functions for rpc calls in rpcwallet.cpp // helper functions for rpc calls in rpcwallet.cpp
int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{ {
// add threshold check // add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0; char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
@@ -140,7 +125,7 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
// no need to prevent dup // no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{ {
if ( (nValue= IsMofNvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) if ( (nValue= IsHeirvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{ {
if ( total != 0 && maxinputs != 0 ) if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript())); mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@@ -155,27 +140,27 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
return(totalinputs); return(totalinputs);
} }
std::string MofNGet(uint64_t txfee,int64_t nValue) std::string HeirGet(uint64_t txfee,int64_t nValue)
{ {
CMutableTransaction mtx,tmpmtx; CPubKey mypk,mofnpk; 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; CMutableTransaction mtx,tmpmtx; CPubKey mypk,Heirpk; 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;
cp = CCinit(&C,EVAL_MOFN); cp = CCinit(&C,EVAL_HEIR);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
mofnpk = GetUnspendable(cp,0); Heirpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,nValue+txfee,60)) > 0 ) if ( (inputs= AddHeirInputs(cp,mtx,Heirpk,nValue+txfee,60)) > 0 )
{ {
if ( inputs > nValue ) if ( inputs > nValue )
CCchange = (inputs - nValue - txfee); CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 ) if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,CCchange,mofnpk)); mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,CCchange,Heirpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL)); fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
j = rand() & 0xfffffff; j = rand() & 0xfffffff;
for (i=0; i<1000000; i++,j++) for (i=0; i<1000000; i++,j++)
{ {
tmpmtx = mtx; tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_MOFN << (uint8_t)'G' << j)); rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
{ {
len >>= 1; len >>= 1;
@@ -191,35 +176,35 @@ std::string MofNGet(uint64_t txfee,int64_t nValue)
} }
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return(""); return("");
} else fprintf(stderr,"cant find mofn inputs\n"); } else fprintf(stderr,"cant find Heir inputs\n");
return(""); return("");
} }
std::string MofNFund(uint64_t txfee,int64_t funds) std::string HeirFund(uint64_t txfee,int64_t funds)
{ {
CMutableTransaction mtx; CPubKey mypk,mofnpk; CScript opret; struct CCcontract_info *cp,C; CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_MOFN); cp = CCinit(&C,EVAL_HEIR);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
mofnpk = GetUnspendable(cp,0); Heirpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{ {
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,funds,mofnpk)); mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,funds,Heirpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
} }
return(""); return("");
} }
UniValue MofNInfo() UniValue HeirInfo()
{ {
UniValue result(UniValue::VOBJ); char numstr[64]; UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx; CPubKey mofnpk; struct CCcontract_info *cp,C; int64_t funding; CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success")); result.push_back(Pair("result","success"));
result.push_back(Pair("name","MofN")); result.push_back(Pair("name","Heir"));
cp = CCinit(&C,EVAL_MOFN); cp = CCinit(&C,EVAL_HEIR);
mofnpk = GetUnspendable(cp,0); Heirpk = GetUnspendable(cp,0);
funding = AddMofNInputs(cp,mtx,mofnpk,0,0); funding = AddHeirInputs(cp,mtx,Heirpk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN); sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr)); result.push_back(Pair("funding",numstr));
return(result); return(result);

View File

@@ -375,8 +375,8 @@ static const CRPCCommand vRPCCommands[] =
{ "faucet", "faucetget", &faucetget, true }, { "faucet", "faucetget", &faucetget, true },
{ "faucet", "faucetaddress", &faucetaddress, true }, { "faucet", "faucetaddress", &faucetaddress, true },
/* MofN */ /* Heir */
{ "MofN", "mofnaddress", &mofnaddress, true }, { "heir", "heiraddress", &heiraddress, true },
/* Channels */ /* Channels */
{ "channels", "channelsaddress", &channelsaddress, true }, { "channels", "channelsaddress", &channelsaddress, true },

View File

@@ -222,7 +222,7 @@ extern UniValue tokenask(const UniValue& params, bool fHelp);
extern UniValue tokencancelask(const UniValue& params, bool fHelp); extern UniValue tokencancelask(const UniValue& params, bool fHelp);
extern UniValue tokenfillask(const UniValue& params, bool fHelp); extern UniValue tokenfillask(const UniValue& params, bool fHelp);
extern UniValue tokenconvert(const UniValue& params, bool fHelp); extern UniValue tokenconvert(const UniValue& params, bool fHelp);
extern UniValue mofnaddress(const UniValue& params, bool fHelp); extern UniValue heiraddress(const UniValue& params, bool fHelp);
extern UniValue channelsaddress(const UniValue& params, bool fHelp); extern UniValue channelsaddress(const UniValue& params, bool fHelp);
extern UniValue oraclesaddress(const UniValue& params, bool fHelp); extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
extern UniValue oracleslist(const UniValue& params, bool fHelp); extern UniValue oracleslist(const UniValue& params, bool fHelp);

View File

@@ -5095,17 +5095,17 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp)
return(CCaddress(cp,(char *)"Gateways",pubkey)); return(CCaddress(cp,(char *)"Gateways",pubkey));
} }
UniValue mofnaddress(const UniValue& params, bool fHelp) UniValue heiraddress(const UniValue& params, bool fHelp)
{ {
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey; struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
cp = CCinit(&C,EVAL_MOFN); cp = CCinit(&C,EVAL_HEIR);
if ( fHelp || params.size() > 1 ) if ( fHelp || params.size() > 1 )
throw runtime_error("mofnaddress [pubkey]\n"); throw runtime_error("heiraddress [pubkey]\n");
if ( ensure_CCrequirements() < 0 ) 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"); 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 ) if ( params.size() == 1 )
pubkey = ParseHex(params[0].get_str().c_str()); pubkey = ParseHex(params[0].get_str().c_str());
return(CCaddress(cp,(char *)"MofN",pubkey)); return(CCaddress(cp,(char *)"Heir",pubkey));
} }
UniValue lottoaddress(const UniValue& params, bool fHelp) UniValue lottoaddress(const UniValue& params, bool fHelp)