| 2682 | } |
| 2683 | |
| 2684 | bool CWallet::CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason) |
| 2685 | { |
| 2686 | /* |
| 2687 | To doublespend a collateral transaction, it will require a fee higher than this. So there's |
| 2688 | still a significant cost. |
| 2689 | */ |
| 2690 | CAmount nFeeRet = 1 * COIN; |
| 2691 | |
| 2692 | txCollateral.vin.clear(); |
| 2693 | txCollateral.vout.clear(); |
| 2694 | |
| 2695 | CReserveKey reservekey(this); |
| 2696 | CAmount nValueIn2 = 0; |
| 2697 | std::vector<CTxIn> vCoinsCollateral; |
| 2698 | |
| 2699 | if (!SelectCoinsCollateral(vCoinsCollateral, nValueIn2)) { |
| 2700 | strReason = "Error: DarkSend requires a collateral transaction and could not locate an acceptable input!"; |
| 2701 | return false; |
| 2702 | } |
| 2703 | |
| 2704 | // make our change address |
| 2705 | CScript scriptChange; |
| 2706 | CPubKey vchPubKey; |
| 2707 | bool success = reservekey.GetReservedKey(vchPubKey, true); |
| 2708 | assert(success); // should never fail, as we just unlocked |
| 2709 | scriptChange = GetScriptForDestination(vchPubKey.GetID()); |
| 2710 | reservekey.KeepKey(); |
| 2711 | |
| 2712 | for (CTxIn v : vCoinsCollateral) |
| 2713 | txCollateral.vin.push_back(v); |
| 2714 | |
| 2715 | if (nValueIn2 - DARKSEND_COLLATERAL - nFeeRet > 0) { |
| 2716 | //pay collateral charge in fees |
| 2717 | CTxOut vout3 = CTxOut(nValueIn2 - DARKSEND_COLLATERAL, scriptChange); |
| 2718 | txCollateral.vout.push_back(vout3); |
| 2719 | } |
| 2720 | |
| 2721 | int vinNumber = 0; |
| 2722 | for (CTxIn v : txCollateral.vin) { |
| 2723 | CTransaction txPrev; |
| 2724 | uint256 prevBlockHash; |
| 2725 | //Find previous transaction with the same output as txNew input |
| 2726 | if (!GetTransaction(v.prevout.hash, txPrev, Params().GetConsensus(), prevBlockHash)) { |
| 2727 | strReason = "CDarkSendPool::MutateTxSign() - Signing - Failed to get previous transaction\n"; |
| 2728 | return false; |
| 2729 | } |
| 2730 | const CAmount& amount = txPrev.vout[v.prevout.n].nValue; |
| 2731 | if (!SignSignature(*this, v.prevPubKey, txCollateral, vinNumber, amount, int(SIGHASH_ALL | SIGHASH_ANYONECANPAY))) { |
| 2732 | for (CTxIn v : vCoinsCollateral) |
| 2733 | UnlockCoin(v.prevout); |
| 2734 | |
| 2735 | strReason = "CDarkSendPool::Sign - Unable to sign collateral transaction! \n"; |
| 2736 | return false; |
| 2737 | } |
| 2738 | vinNumber++; |
| 2739 | } |
| 2740 | |
| 2741 | return true; |
no test coverage detected