src/omnicore/wallettxbuilder.cpp
/** Creates and sends a transaction. */
Creates and sends a transaction.
Creates and sends a transaction .
int WalletTxBuilder(
        const std::string& senderAddress,
        const std::string& receiverAddress,
        const std::string& redemptionAddress,
        int64_t referenceAmount,
        const std::vector<unsigned char>& payload,
        uint256& retTxid,
        std::string& retRawTx,
        bool commit,
        interfaces::Wallet* iWallet,
        CAmount minFee)
{
#ifdef ENABLE_WALLET
    if (!iWallet) return MP_ERR_WALLET_ACCESS;
    int omniTxClass = OMNI_CLASS_C;
    if (!UseEncodingClassC(payload.size())) omniTxClass = OMNI_CLASS_B;
    CCoinControl coinControl;
    std::vector<std::pair<CScript, int64_t> > vecSend;
    coinControl.destChange = DecodeDestination(senderAddress);
    if (0 > mastercore::SelectCoins(*iWallet, senderAddress, coinControl, referenceAmount)) { return MP_INPUTS_INVALID; }
    switch(omniTxClass) {
        case OMNI_CLASS_B: { 
            CPubKey redeemingPubKey;
            const std::string& sAddress = redemptionAddress.empty() ? senderAddress : redemptionAddress;
            if (!AddressToPubKey(iWallet, sAddress, redeemingPubKey)) {
                return MP_REDEMP_BAD_VALIDATION;
            }
            if (!OmniCore_Encode_ClassB(senderAddress,redeemingPubKey,payload,vecSend)) { return MP_ENCODING_ERROR; }
        break; }
        case OMNI_CLASS_C:
            if(!OmniCore_Encode_ClassC(payload,vecSend)) { return MP_ENCODING_ERROR; }
        break;
    }
    if (!receiverAddress.empty()) {
        CScript scriptPubKey = GetScriptForDestination(DecodeDestination(receiverAddress));
        vecSend.push_back(std::make_pair(scriptPubKey, 0 < referenceAmount ? referenceAmount : OmniGetDustThreshold(scriptPubKey)));
    }
    if (!coinControl.HasSelected()) return MP_ERR_INPUTSELECT_FAIL;
    std::vector<CRecipient> vecRecipients;
    for (size_t i = 0; i < vecSend.size(); ++i) {
        const std::pair<CScript, int64_t>& vec = vecSend[i];
        CRecipient recipient = {vec.first, vec.second, false};
        vecRecipients.push_back(recipient);
    }
    CAmount nFeeRet = 0;
    int nChangePosInOut = -1;
    std::string strFailReason;
    auto wtxNew = iWallet->createTransaction(vecRecipients, coinControl, true , nChangePosInOut, nFeeRet, strFailReason, false, minFee);
    if (!wtxNew) {
        PrintToLog("%s: ERROR: wallet transaction creation failed: %s\n", __func__, strFailReason);
        return MP_ERR_CREATE_TX;
    }
    if (!commit) {
        retRawTx = EncodeHexTx(wtxNew->get());
        return 0;
    } else {
        PrintToLog("%s: %s; nFeeRet = %d\n", __func__, wtxNew->get().ToString(), nFeeRet);
        std::string rejectReason;
        if (!wtxNew->commit({}, {}, rejectReason)) return MP_ERR_COMMIT_TX;
        retTxid = wtxNew->get().GetHash();
        return 0;
    }
#else
    return MP_ERR_WALLET_ACCESS;
#endif
}
int WalletTxBuilder ( const std :: string & senderAddress , const std :: string & receiverAddress , const std :: string & redemptionAddress , int64_t referenceAmount , const std :: vector < unsigned char > & payload , uint256 & retTxid , std :: string & retRawTx , bool commit , interfaces :: Wallet * iWallet , CAmount minFee ) { #ifdef ENABLE_WALLET if ( ! iWallet ) return MP_ERR_WALLET_ACCESS ; int omniTxClass = OMNI_CLASS_C ; if ( ! UseEncodingClassC ( payload . size ( ) ) ) omniTxClass = OMNI_CLASS_B ; CCoinControl coinControl ; std :: vector < std :: pair < CScript , int64_t > > vecSend ; coinControl . destChange = DecodeDestination ( senderAddress ) ; if ( 0 > mastercore :: SelectCoins ( * iWallet , senderAddress , coinControl , referenceAmount ) ) { return MP_INPUTS_INVALID ; } switch ( omniTxClass ) { case OMNI_CLASS_B : { CPubKey redeemingPubKey ; const std :: string & sAddress = redemptionAddress . empty ( ) ? senderAddress : redemptionAddress ; if ( ! AddressToPubKey ( iWallet , sAddress , redeemingPubKey ) ) { return MP_REDEMP_BAD_VALIDATION ; } if ( ! OmniCore_Encode_ClassB ( senderAddress , redeemingPubKey , payload , vecSend ) ) { return MP_ENCODING_ERROR ; } break ; } case OMNI_CLASS_C : if ( ! OmniCore_Encode_ClassC ( payload , vecSend ) ) { return MP_ENCODING_ERROR ; } break ; } if ( ! receiverAddress . empty ( ) ) { CScript scriptPubKey = GetScriptForDestination ( DecodeDestination ( receiverAddress ) ) ; vecSend . push_back ( std :: make_pair ( scriptPubKey , 0 < referenceAmount ? referenceAmount : OmniGetDustThreshold ( scriptPubKey ) ) ) ; } if ( ! coinControl . HasSelected ( ) ) return MP_ERR_INPUTSELECT_FAIL ; std :: vector < CRecipient > vecRecipients ; for ( size_t i = 0 ; i < vecSend . size ( ) ; ++ i ) { const std :: pair < CScript , int64_t > & vec = vecSend [ i ] ; CRecipient recipient = { vec . first , vec . second , false } ; vecRecipients . push_back ( recipient ) ; } CAmount nFeeRet = 0 ; int nChangePosInOut = -1 ; std :: string strFailReason ; auto wtxNew = iWallet -> createTransaction ( vecRecipients , coinControl , true , nChangePosInOut , nFeeRet , strFailReason , false , minFee ) ; if ( ! wtxNew ) { PrintToLog ( " \n " , __func__ , strFailReason ) ; return MP_ERR_CREATE_TX ; } if ( ! commit ) { retRawTx = EncodeHexTx ( wtxNew -> get ( ) ) ; return 0 ; } else { PrintToLog ( " \n " , __func__ , wtxNew -> get ( ) . ToString ( ) , nFeeRet ) ; std :: string rejectReason ; if ( ! wtxNew -> commit ( { } , { } , rejectReason ) ) return MP_ERR_COMMIT_TX ; retTxid = wtxNew -> get ( ) . GetHash ( ) ; return 0 ; } #else return MP_ERR_WALLET_ACCESS ; #endif }
Creates and sends a transaction.
Creates and sends a transaction .
// Determine the class to send the transaction via - default is Class C // Prepare the transaction - first setup some vars // Next, we set the change address to the sender // Select the inputs // Encode the data outputs // declaring vars in a switch here so use an expicit code block // Then add a paytopubkeyhash output for the recipient (if needed) - note we do this last as we want this to be the highest vout // Now we have what we need to pass to the wallet to create the transaction, perform some checks first // Ask the wallet to create the transaction (note mining fee determined by Bitcoin Core params) /* sign */ // If this request is only to create, but not commit the transaction then display it and exit // Commit the transaction to the wallet and broadcast)