]> Git Repo - VerusCoin.git/blobdiff - src/cc/CCassetstx.cpp
Backwards compatibility breaking changes
[VerusCoin.git] / src / cc / CCassetstx.cpp
index 0328d5404e3723a16ac9f59386ea2722fc75e489..5869aa133981e4a99c5201e579e4ff6eda291ad4 100644 (file)
 
 #include "CCassets.h"
 
-uint64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,uint64_t total,int32_t maxinputs)
+int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
 {
-    char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
+    char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
     std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
     GetCCaddress(cp,coinaddr,pk);
     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;
+        for (j=0; j<mtx.vin.size(); j++)
+            if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
+                break;
+        if ( j != mtx.vin.size() )
+            continue;
         if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
         {
-            if ( (nValue= IsAssetvout(price,origpubkey,vintx,(int32_t)it->first.index,assetid)) > 0 )
+            if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
             {
                 if ( total != 0 && maxinputs != 0 )
-                    mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript()));
+                    mtx.vin.push_back(CTxIn(txid,vout,CScript()));
                 nValue = it->second.satoshis;
                 totalinputs += nValue;
                 n++;
@@ -41,17 +47,61 @@ uint64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
     return(totalinputs);
 }
 
-uint64_t GetAssetBalance(CPubKey pk,uint256 tokenid)
+int64_t GetAssetBalance(CPubKey pk,uint256 tokenid)
 {
     CMutableTransaction mtx; struct CCcontract_info *cp,C;
     cp = CCinit(&C,EVAL_ASSETS);
     return(AddAssetInputs(cp,mtx,pk,tokenid,0,0));
 }
 
+UniValue AssetInfo(uint256 assetid)
+{
+    UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description; char str[67],numstr[65];
+    if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
+    {
+        fprintf(stderr,"cant find assetid\n");
+        result.push_back(Pair("result","error"));
+        result.push_back(Pair("error","cant find assetid"));
+        return(result);
+    }
+    if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
+    {
+        fprintf(stderr,"assetid isnt assetcreation txid\n");
+        result.push_back(Pair("result","error"));
+        result.push_back(Pair("error","assetid isnt assetcreation txid"));
+    }
+    result.push_back(Pair("result","success"));
+    result.push_back(Pair("tokenid",uint256_str(str,assetid)));
+    result.push_back(Pair("owner",pubkey33_str(str,origpubkey.data())));
+    result.push_back(Pair("name",name));
+    result.push_back(Pair("supply",vintx.vout[0].nValue));
+    result.push_back(Pair("description",description));
+    return(result);
+}
+
+UniValue AssetList()
+{
+    UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description; char str[65];
+    cp = CCinit(&C,EVAL_ASSETS);
+    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,vintx,hashBlock,false) != 0 )
+        {
+            if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) != 0 )
+            {
+                result.push_back(uint256_str(str,txid));
+            }
+        }
+    }
+    return(result);
+}
+
 UniValue AssetOrders(uint256 refassetid)
 {
     static uint256 zero;
-    uint64_t price; uint256 txid,hashBlock,assetid,assetid2; std::vector<uint8_t> origpubkey; CTransaction vintx; UniValue result(UniValue::VARR);  std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; uint8_t funcid; char numstr[32],funcidstr[16],origaddr[64],assetidstr[65]; struct CCcontract_info *cp,C;
+    int64_t price; uint256 txid,hashBlock,assetid,assetid2; std::vector<uint8_t> origpubkey; CTransaction vintx; UniValue result(UniValue::VARR);  std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; uint8_t funcid; char numstr[32],funcidstr[16],origaddr[64],assetidstr[65]; struct CCcontract_info *cp,C;
     cp = CCinit(&C,EVAL_ASSETS);
     SetCCunspents(unspentOutputs,(char *)cp->unspendableCCaddr);
     for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
@@ -59,7 +109,7 @@ UniValue AssetOrders(uint256 refassetid)
         txid = it->first.txhash;
         if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
         {
-            if ( (funcid= DecodeAssetOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey)) != 0 )
+            if ( vintx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey)) != 0 )
             {
                 if ( refassetid != zero && assetid != refassetid )
                 {
@@ -80,16 +130,18 @@ UniValue AssetOrders(uint256 refassetid)
                 item.push_back(Pair("funcid", funcidstr));
                 item.push_back(Pair("txid", uint256_str(assetidstr,txid)));
                 item.push_back(Pair("vout", (int64_t)it->first.index));
-                sprintf(numstr,"%.8f",(double)vintx.vout[it->first.index].nValue/COIN);
-                item.push_back(Pair("amount",numstr));
                 if ( funcid == 'b' || funcid == 'B' )
                 {
+                    sprintf(numstr,"%.8f",(double)vintx.vout[it->first.index].nValue/COIN);
+                    item.push_back(Pair("amount",numstr));
                     sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
                     item.push_back(Pair("bidamount",numstr));
                 }
                 else
                 {
-                    sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue);
+                    sprintf(numstr,"%llu",(long long)vintx.vout[it->first.index].nValue);
+                    item.push_back(Pair("amount",numstr));
+                    sprintf(numstr,"%llu",(long long)vintx.vout[0].nValue);
                     item.push_back(Pair("askamount",numstr));
                 }
                 if ( origpubkey.size() == 33 )
@@ -107,7 +159,7 @@ UniValue AssetOrders(uint256 refassetid)
                     {
                         sprintf(numstr,"%.8f",(double)price / COIN);
                         item.push_back(Pair("totalrequired", numstr));
-                        sprintf(numstr,"%.8f",(double)price / vintx.vout[0].nValue);
+                        sprintf(numstr,"%.8f",(double)price / (COIN * vintx.vout[0].nValue));
                         item.push_back(Pair("price", numstr));
                     }
                     else
@@ -125,14 +177,19 @@ UniValue AssetOrders(uint256 refassetid)
     return(result);
 }
 
-std::string CreateAsset(uint64_t txfee,uint64_t assetsupply,std::string name,std::string description)
+std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description)
 {
     CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
+    if ( assetsupply < 0 )
+    {
+        fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
+        return("");
+    }
     cp = CCinit(&C,EVAL_ASSETS);
     if ( name.size() > 32 || description.size() > 4096 )
     {
         fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size());
-        return(0);
+        return("");
     }
     if ( txfee == 0 )
         txfee = 10000;
@@ -141,14 +198,19 @@ std::string CreateAsset(uint64_t txfee,uint64_t assetsupply,std::string name,std
     {
         mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,assetsupply,mypk));
         mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG));
-        return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description)));
+        return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description)));
     }
-    return(0);
+    return("");
 }
                
-std::string AssetTransfer(uint64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,uint64_t total)
+std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
 {
-    CMutableTransaction mtx; CPubKey mypk; uint64_t CCchange=0,inputs=0;  struct CCcontract_info *cp,C;
+    CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0;  struct CCcontract_info *cp,C;
+    if ( total < 0 )
+    {
+        fprintf(stderr,"negative total %lld\n",(long long)total);
+        return("");
+    }
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
@@ -160,6 +222,7 @@ std::string AssetTransfer(uint64_t txfee,uint256 assetid,std::vector<uint8_t> de
         {
             for (i=0; i<n; i++)
                 total += amounts[i];*/
+        mask = ~((1LL << mtx.vin.size()) - 1);
             if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
             {
                 if ( inputs > total )
@@ -168,16 +231,31 @@ std::string AssetTransfer(uint64_t txfee,uint256 assetid,std::vector<uint8_t> de
                     mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,total,pubkey2pk(destpubkey)));
                 if ( CCchange != 0 )
                     mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
-                return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
+                return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
             } else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN);
         //} else fprintf(stderr,"numoutputs.%d != numamounts.%d\n",n,(int32_t)amounts.size());
     }
-    return(0);
+    return("");
 }
 
-std::string CreateBuyOffer(uint64_t txfee,uint64_t bidamount,uint256 assetid,uint64_t pricetotal)
+std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
 {
-    CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
+    CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
+    if ( bidamount < 0 || pricetotal < 0 )
+    {
+        fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
+        return("");
+    }
+    if ( GetTransaction(assetid,vintx,hashBlock,false) == 0 )
+    {
+        fprintf(stderr,"cant find assetid\n");
+        return("");
+    }
+    if ( vintx.vout.size() > 0 && DecodeAssetCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,origpubkey,name,description) == 0 )
+    {
+        fprintf(stderr,"assetid isnt assetcreation txid\n");
+        return("");
+    }
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
@@ -185,22 +263,64 @@ std::string CreateBuyOffer(uint64_t txfee,uint64_t bidamount,uint256 assetid,uin
     if ( AddNormalinputs(mtx,mypk,bidamount+txfee,64) > 0 )
     {
         mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount,GetUnspendable(cp,0)));
-        return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet('b',assetid,zeroid,pricetotal,Mypubkey())));
+        return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('b',assetid,zeroid,pricetotal,Mypubkey())));
     }
-    return(0);
+    return("");
 }
 
-std::string CreateSell(uint64_t txfee,uint64_t askamount,uint256 assetid,uint256 assetid2,uint64_t pricetotal)
+std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
 {
-    CMutableTransaction mtx; CPubKey mypk; uint64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
+    CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
+    if ( askamount < 0 || pricetotal < 0 )
+    {
+        fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
+        return("");
+    }
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
     mypk = pubkey2pk(Mypubkey());
     if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
     {
+        mask = ~((1LL << mtx.vin.size()) - 1);
         if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
         {
+            if ( inputs < askamount )
+                askamount = inputs;
+            mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
+            if ( inputs > askamount )
+                CCchange = (inputs - askamount);
+            if ( CCchange != 0 )
+                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
+            opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
+            return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
+        } else fprintf(stderr,"need some assets to place ask\n");
+    }
+    fprintf(stderr,"need some native coins to place ask\n");
+    return("");
+}
+
+std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
+{
+    CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
+    fprintf(stderr,"asset swaps disabled\n");
+    return("");
+    if ( askamount < 0 || pricetotal < 0 )
+    {
+        fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
+        return("");
+    }
+    cp = CCinit(&C,EVAL_ASSETS);
+    if ( txfee == 0 )
+        txfee = 10000;
+    mypk = pubkey2pk(Mypubkey());
+    if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
+    {
+        mask = ~((1LL << mtx.vin.size()) - 1);
+        if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
+        {
+            if ( inputs < askamount )
+                askamount = inputs;
             mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
             if ( inputs > askamount )
                 CCchange = (inputs - askamount);
@@ -208,62 +328,74 @@ std::string CreateSell(uint64_t txfee,uint64_t askamount,uint256 assetid,uint256
                 mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
             if ( assetid2 == zeroid )
                 opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
-            else opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
-            return(FinalizeCCTx(cp,mtx,mypk,txfee,opret));
-        }
+            else
+            {
+                opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
+            }
+            return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
+        } else fprintf(stderr,"need some assets to place ask\n");
     }
-    return(0);
+    fprintf(stderr,"need some native coins to place ask\n");
+    return("");
 }
 
-std::string CancelBuyOffer(uint64_t txfee,uint256 assetid,uint256 bidtxid)
+std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
 {
-    CMutableTransaction mtx; CTransaction vintx; uint256 hashBlock; uint64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
+    CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
     mypk = pubkey2pk(Mypubkey());
     if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
     {
+        mask = ~((1LL << mtx.vin.size()) - 1);
         if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
         {
             bidamount = vintx.vout[0].nValue;
             mtx.vin.push_back(CTxIn(bidtxid,0,CScript()));
             mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
-            return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet('o',assetid,zeroid,0,Mypubkey())));
+            return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('o',assetid,zeroid,0,Mypubkey())));
         }
     }
-    return(0);
+    return("");
 }
 
-std::string CancelSell(uint64_t txfee,uint256 assetid,uint256 asktxid)
+std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
 {
-    CMutableTransaction mtx; CTransaction vintx; uint256 hashBlock; uint64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
+    CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
     mypk = pubkey2pk(Mypubkey());
     if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
     {
+        mask = ~((1LL << mtx.vin.size()) - 1);
         if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
         {
             askamount = vintx.vout[0].nValue;
             mtx.vin.push_back(CTxIn(asktxid,0,CScript()));
             mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,mypk));
-            return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet('x',assetid,zeroid,0,Mypubkey())));
+            return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('x',assetid,zeroid,0,Mypubkey())));
         }
     }
-    return(0);
+    return("");
 }
 
-std::string FillBuyOffer(uint64_t txfee,uint256 assetid,uint256 bidtxid,uint64_t fillamount)
+std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
 {
-    CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
+    CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
+    if ( fillamount < 0 )
+    {
+        fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
+        return("");
+    }
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
     mypk = pubkey2pk(Mypubkey());
     if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
     {
+        mask = ~((1LL << mtx.vin.size()) - 1);
         if ( GetTransaction(bidtxid,vintx,hashBlock,false) != 0 )
         {
             bidamount = vintx.vout[bidvout].nValue;
@@ -271,7 +403,9 @@ std::string FillBuyOffer(uint64_t txfee,uint256 assetid,uint256 bidtxid,uint64_t
             mtx.vin.push_back(CTxIn(bidtxid,bidvout,CScript()));
             if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,fillamount,60)) > 0 )
             {
-                SetAssetFillamounts(0,paid_amount,remaining_required,bidamount,fillamount,origprice);
+                if ( inputs < fillamount )
+                    fillamount = inputs;
+                SetBidFillamounts(paid_amount,remaining_required,bidamount,fillamount,origprice);
                 if ( inputs > fillamount )
                     CCchange = (inputs - fillamount);
                 mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,bidamount - paid_amount,GetUnspendable(cp,0)));
@@ -280,44 +414,67 @@ std::string FillBuyOffer(uint64_t txfee,uint256 assetid,uint256 bidtxid,uint64_t
                 if ( CCchange != 0 )
                     mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
                 fprintf(stderr,"remaining %llu -> origpubkey\n",(long long)remaining_required);
-                return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet('B',assetid,zeroid,remaining_required,origpubkey)));
+                return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet('B',assetid,zeroid,remaining_required,origpubkey)));
             } else return("dont have any assets to fill bid\n");
         }
     }
     return("no normal coins left");
 }
 
-std::string FillSell(uint64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,uint64_t fillamount)
+std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillunits)
 {
-    CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t askvout=0; uint64_t totalunits,askamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
+    CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
+    if ( fillunits < 0 )
+    {
+        fprintf(stderr,"negative fillunits %lld\n",(long long)fillunits);
+        return("");
+    }
+    if ( assetid2 != zeroid )
+    {
+        fprintf(stderr,"asset swaps disabled\n");
+        return("");
+    }
+
     cp = CCinit(&C,EVAL_ASSETS);
     if ( txfee == 0 )
         txfee = 10000;
     mypk = pubkey2pk(Mypubkey());
     if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 )
     {
+        mask = ~((1LL << mtx.vin.size()) - 1);
         if ( GetTransaction(asktxid,vintx,hashBlock,false) != 0 )
         {
-            askamount = vintx.vout[askvout].nValue;
-            SetAssetOrigpubkey(origpubkey,totalunits,vintx);
+            orig_assetoshis = vintx.vout[askvout].nValue;
+            SetAssetOrigpubkey(origpubkey,total_nValue,vintx);
+            dprice = (double)total_nValue / orig_assetoshis;
+            paid_nValue = dprice * fillunits;
             mtx.vin.push_back(CTxIn(asktxid,askvout,CScript()));
-            if ( assetid2 == zeroid )
-                inputs = AddAssetInputs(cp,mtx,mypk,assetid2,fillamount,60);
-            else inputs = AddNormalinputs(mtx,mypk,fillamount,60);
+            if ( assetid2 != zeroid )
+                inputs = AddAssetInputs(cp,mtx,mypk,assetid2,paid_nValue,60);
+            else
+            {
+                inputs = AddNormalinputs(mtx,mypk,paid_nValue,60);
+                mask = ~((1LL << mtx.vin.size()) - 1);
+            }
             if ( inputs > 0 )
             {
-                SetAssetFillamounts(1,paid_amount,remaining_required,askamount,fillamount,totalunits);
-                if ( assetid2 == zeroid && inputs > fillamount )
-                    CCchange = (inputs - fillamount);
-                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount - paid_amount,GetUnspendable(cp,0)));
-                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,paid_amount,mypk));
-                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,fillamount,pubkey2pk(origpubkey)));
+                if ( inputs < paid_nValue )
+                    paid_nValue = inputs;
+                if ( assetid2 != zeroid )
+                    SetSwapFillamounts(received_assetoshis,remaining_nValue,orig_assetoshis,paid_nValue,total_nValue);
+                else SetAskFillamounts(received_assetoshis,remaining_nValue,orig_assetoshis,paid_nValue,total_nValue);
+                if ( assetid2 != zeroid && inputs > paid_nValue )
+                    CCchange = (inputs - paid_nValue);
+                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,orig_assetoshis - received_assetoshis,GetUnspendable(cp,0)));
+                mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,received_assetoshis,mypk));
+                if ( assetid2 != zeroid )
+                    mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,paid_nValue,origpubkey));
+                else mtx.vout.push_back(CTxOut(paid_nValue,CScript() << origpubkey << OP_CHECKSIG));
                 if ( CCchange != 0 )
                     mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
-                fprintf(stderr,"remaining %llu -> origpubkey\n",(long long)remaining_required);
-                return(FinalizeCCTx(cp,mtx,mypk,txfee,EncodeAssetOpRet(assetid2==zeroid?'E':'S',assetid,assetid2,remaining_required,origpubkey)));
+                return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,EncodeAssetOpRet(assetid2!=zeroid?'E':'S',assetid,assetid2,remaining_nValue,origpubkey)));
             } else fprintf(stderr,"filltx not enough utxos\n");
         }
     }
-    return(0);
+    return("");
 }
This page took 0.040479 seconds and 4 git commands to generate.