Forum Home
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular

    [Dev] Documenting Feathercoin Specific Software settings - Part 9

    Technical Development
    1
    37
    6248
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • wrapper
      wrapper Moderators last edited by

      Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

      Add Multisgin Page : - commit

      https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

      Include a multi-signature address Page

      src/qt/multisigdialog.cpp

      Large new file, 966 lines of code

       +#include "multisigdialog.h"
       +#include "ui_multisigdialog.h"
       +
       +#include "wallet.h"
       +#include "walletmodel.h"
       +#include "bitcoinunits.h"
       +#include "addressbookpage.h"
       +#include "optionsmodel.h"
       +#include "sendcoinsentry.h"
       +#include "guiutil.h"
       +#include "askpassphrasedialog.h"
       +#include "base58.h"
       +#include "init.h"
       +#include "coincontrol.h"
       +#include "createmultisigaddrdialog.h"
       +#include "rpcprotocol.h"
       +
       +#include "json/json_spirit.h"
       +#include "json/json_spirit_reader_template.h"
       +#include "json/json_spirit_writer_template.h"
       +#include "json/json_spirit_utils.h"
       +#include "json/json_spirit_value.h"
       +using namespace json_spirit;
       +
       +#include <QMessageBox>
       +#include <QTextDocument>
       +#include <QScrollBar>
       +#include <QFile>
       +#include <QTextStream>
       +
       +CCoinControl* MultiSigDialog::coinControl = new CCoinControl();
       +CTransaction* MultiSigDialog::rawTx = new CTransaction();
       +
       +MultiSigDialog::MultiSigDialog(QWidget *parent) :
       +    QDialog(parent),
       +    ui(new Ui::MultiSigDialog),
       +    model(0)
       +{
       +    ui->setupUi(this);
      

      Example / start of new code

      1 Reply Last reply Reply Quote 0
      • wrapper
        wrapper Moderators last edited by

        Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

        Add Multisgin Page : - commit

        https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

        Include a multi-signature address Page

        src/qt/multisigdialog.h

        Large new file 91 lines o code

         +#ifndef MULTISIGDIALOG_H
         +#define MULTISIGDIALOG_H
         +
         +#include <QDialog>
         +#include <QString>
         +
         +namespace Ui {
         +    class MultiSigDialog;
         +}
         +
         +class CWallet;
         +class WalletModel;
         +class SendCoinsEntry;
         +class SendCoinsRecipient;
         +class CCoinControl;
         +class CTransaction;
         +
         +QT_BEGIN_NAMESPACE
         +class QUrl;
         +QT_END_NAMESPACE
         +
         +/** Dialog for sending bitcoins */
         +class MultiSigDialog : public QDialog
         +{
         +    Q_OBJECT
         +
         +public:
         +    explicit MultiSigDialog(QWidget *parent = 0);
         +    ~MultiSigDialog();
         +
         +    void setModel(WalletModel *model);
         +
         +    /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
         +     */
         +    QWidget *setupTabChain(QWidget *prev);
         +
         +    void setAddress(const QString &address);
         +    void pasteEntry(const SendCoinsRecipient &rv);
         +    bool handleURI(const QString &uri);
         +
         +    static CCoinControl *coinControl;
         +    static CTransaction *rawTx;
         +
         +public slots:
         +    void clear();
         +    void reject();
         +    void accept();
         +    void exportDraft();
         +    void importDraft();
         +    void editEnable(bool enable);
         +
         +    void signAddress0();
         +    void signAddress1();
         +    void signAddress2();
         +    void signTransaction(QString *addrStr = NULL);
         +    
         +    SendCoinsEntry *addEntry();
         +    void updateRemoveEnabled();
         +    void setSharedBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
        

        Start of new file code

        1 Reply Last reply Reply Quote 0
        • wrapper
          wrapper Moderators last edited by

          Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

          Add Multisgin Page : - commit

          https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

          Include a multi-signature address Page

          src/qt/res/icons/*

           src/qt/res/icons/multisig.png
          

          Icon File added

          1 Reply Last reply Reply Quote 0
          • wrapper
            wrapper Moderators last edited by

            Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

            Add Multisgin Page : - commit

            https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

            Include a multi-signature address Page

            src/qt/sendcoinsentry.cpp

             +void SendCoinsEntry::setRemoveEnabled(bool enabled)
             +{
             +    ui->deleteButton->setEnabled(enabled);
             +}
             +
            

            Code added

             +void SendCoinsEntry::setFieldEnable(bool enable)
             +{
             +    ui->payTo->setEnabled(enable);
             +    ui->addAsLabel->setEnabled(enable);
             +    ui->payAmount->setEnabled(enable);
             +    ui->addressBookButton->setEnabled(enable);
             +    ui->pasteButton->setEnabled(enable);
             +    ui->deleteButton->setEnabled(enable);
             +}
             +
            

            Code added

            1 Reply Last reply Reply Quote 0
            • wrapper
              wrapper Moderators last edited by

              Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

              Add Multisgin Page : - commit

              https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

              Include a multi-signature address Page

              src/qt/sendcoinsentry.h

               +    void setFieldEnable(bool enable);
              

              Code added

               +    void setRemoveEnabled(bool enabled);
              

              Code added

              1 Reply Last reply Reply Quote 0
              • wrapper
                wrapper Moderators last edited by

                Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                Add Multisgin Page : - commit

                https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                Include a multi-signature address Page

                src/qt/walletframe.cpp

                 +void WalletFrame::gotoMultiSigPage()
                 +{
                 +    QMap<QString, WalletView*>::const_iterator i;
                 +    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd();  ++i)
                 +        i.value()->gotoMultiSigPage();
                 +}
                 +
                

                Code added

                1 Reply Last reply Reply Quote 0
                • wrapper
                  wrapper Moderators last edited by

                  Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                  Add Multisgin Page : - commit

                  https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                  Include a multi-signature address Page

                  src/qt/walletframe.cpp

                   +qint64 WalletModel::getSharedBalance(const CCoinControl *coinControl) const
                   +{
                   +    if (coinControl)
                   +    {
                   +        int64 nBalance = 0;
                   +        std::vector<COutput> vCoins;
                   +        wallet->AvailableSharedCoins(vCoins, true, coinControl);
                   +        BOOST_FOREACH(const COutput& out, vCoins)
                   +            nBalance += out.tx->vout[out.i].nValue;   
                   +        
                   +        return nBalance;
                   +    }
                   +
                   +    return wallet->GetSharedBalance();
                   +}
                   +
                   +qint64 WalletModel::getSharedUnconfirmedBalance() const
                   +{
                   +    return wallet->GetSharedUnconfirmedBalance();
                   +}
                   +
                   +qint64 WalletModel::getSharedImmatureBalance() const
                   +{
                   +    return wallet->GetSharedImmatureBalance();
                   +}
                   +
                  

                  Code added

                   +WalletModel::SendCoinsReturn WalletModel::createRawTransaction(
                   +    const QList<SendCoinsRecipient> &recipients, CTransaction& txNew, const CCoinControl *coinControl, bool isMultiSig)
                   +{
                   +    qint64 total = 0;
                   +    QSet<QString> setAddress;
                   +    QString hex;
                   +
                   +    if(recipients.empty())
                   +    {
                   +        return OK;
                   +    }
                   +
                   +    // Pre-check input data for validity
                   +    foreach(const SendCoinsRecipient &rcp, recipients)
                   +    {
                   +        if(!validateAddress(rcp.address))
                   +        {
                   +            return InvalidAddress;
                   +        }
                   +        setAddress.insert(rcp.address);
                   +
                   +        if(rcp.amount <= 0)
                   +        {
                   +            return InvalidAmount;
                   +        }
                   +        total      += rcp.amount;
                   +    }
                   +
                   +    if(recipients.size() > setAddress.size())
                   +    {
                   +        return DuplicateAddress;
                   +    }
                   +
                   +    int64 nBalance;
                   +    if ( isMultiSig )
                   +        nBalance = getSharedBalance(coinControl);
                   +    else
                   +        nBalance = getBalance(coinControl);
                   +
                   +    if(total > nBalance)
                   +    {
                   +        return AmountExceedsBalance;
                   +    }
                   +
                   +    if((total + nTransactionFee) > nBalance)
                   +    {
                   +        return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
                   +    }
                   +
                   +    {
                   +        LOCK2(cs_main, wallet->cs_wallet);
                   +
                   +        // Sendmany
                   +        std::vector<std::pair<CScript, int64> > vecSend;
                   +        foreach(const SendCoinsRecipient &rcp, recipients)
                   +        {
                   +            CScript scriptPubKey;
                   +            scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
                   +            vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
                   +        }
                   +
                   +        int64 nFeeRequired = 0;
                   +        std::string strFailReason;
                   +        CReserveKey reservekey(wallet);
                   +        bool fCreated = wallet->CreateRawTransaction(vecSend, txNew, nFeeRequired, strFailReason, isMultiSig, reservekey, coinControl);
                   +
                   +        if(!fCreated)
                   +        {
                   +            if((total  + nFeeRequired) > nBalance)
                   +            {
                   +                return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
                   +            }
                   +            emit message(tr("Send Coins"), QString::fromStdString(strFailReason),
                   +                         CClientUIInterface::MSG_ERROR);
                   +            return TransactionCreationFailed;
                   +        }
                   +        /*if(!uiInterface.ThreadSafeAskFee(nFeeRequired))
                   +        {
                   +            return Aborted;
                   +        }*/
                   +        hex = QString::fromStdString(txNew.GetHash().GetHex());
                   +    }
                   +
                   +    // Add addresses / update labels that we've sent to to the address book
                   +    foreach(const SendCoinsRecipient &rcp, recipients)
                   +    {
                   +        std::string strAddress = rcp.address.toStdString();
                   +        CTxDestination dest = CBitcoinAddress(strAddress).Get();
                   +        std::string strLabel = rcp.label.toStdString();
                   +        {
                   +            LOCK(wallet->cs_wallet);
                   +
                   +            //std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(dest);
                   +            std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
                   +
                   +            // Check if we have a new address or an updated label
                   +            if (mi == wallet->mapAddressBook.end() || mi->second.name != strLabel)
                   +            {
                   +            		std::string purpose;
                   +                //wallet->SetAddressBookName(dest, strLabel);
                   +                wallet->SetAddressBook(dest, strLabel,purpose);
                   +            }
                   +        }
                   +    }
                   +
                   +    return SendCoinsReturn(OK, 0, hex);
                   +}
                   +
                  

                  Code added

                  1 Reply Last reply Reply Quote 0
                  • wrapper
                    wrapper Moderators last edited by

                    Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                    Add Multisgin Page : - commit

                    https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                    Include a multi-signature address Page

                    src/qt/walletmodel.h

                     +    
                     +    qint64 getSharedBalance(const CCoinControl *coinControl=NULL) const;
                     +    qint64 getSharedUnconfirmedBalance() const;
                     +    qint64 getSharedImmatureBalance() const;
                    

                    Code added

                     +        /*SendCoinsReturn(StatusCode status = OK):
                     +            status(status) {}*/
                     +        SendCoinsReturn(StatusCode status=Aborted,
                     +                         qint64 fee=0,
                     +                         QString hex=QString()):
                     +            status(status), fee(fee), hex(hex) {}
                    

                    Code replaced

                     +        qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance"
                     +        QString hex; // is filled with the transaction hash if status is "OK"
                    

                    Code added

                     +    SendCoinsReturn createRawTransaction(const QList<SendCoinsRecipient> &recipients, CTransaction& txNew, const CCoinControl *coinControl, bool isMultiSig);
                    
                     +		bool isMultiSig;
                     +    bool was_locked;
                    
                     +		CWallet *getWallet(){ return wallet; }
                    

                    Code added

                    1 Reply Last reply Reply Quote 0
                    • wrapper
                      wrapper Moderators last edited by wrapper

                      Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                      Add Multisgin Page : - commit

                      https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                      Include a multi-signature address Page

                      src/qt/walletview.cpp

                       +#include "addressbookpage.h"
                      
                       +#include "multisigdialog.h"
                      
                       +    multiSigPage = new MultiSigDialog();
                      
                       +    addWidget(multiSigPage);
                      

                      Code added

                       +    connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));    
                      

                      Code replaced

                       +    connect(sendCoinsPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString))); 
                       +    
                       +    // Clicking on "Send Coins" in the address book sends you to the send coins tab
                       +    connect(transactionView, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString))); 
                       +    // Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog
                       +    connect(transactionView, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
                       +    // Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog
                       +    connect(transactionView, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
                      

                      Code replaced

                       +    multiSigPage->setModel(walletModel);
                      
                       +void WalletView::gotoMultiSigPage()
                       +{
                       +    setCurrentWidget(multiSigPage);
                       +}
                       +
                      

                      Code added

                       +    AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);    
                      

                      Code replaced

                      1 Reply Last reply Reply Quote 0
                      • wrapper
                        wrapper Moderators last edited by wrapper

                        Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                        Add Multisgin Page : - commit

                        https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                        Include a multi-signature address Page

                        src/qt/walletview.h

                         +class AddressBookPage;
                        
                         +class MultiSigDialog;
                        
                         +    AddressBookPage *addressBookPage;
                        
                         +    MultiSigDialog *multiSigPage;
                        

                        Code added

                         +		ReportView *reportView;		
                        

                        Code replaced

                         +    /** Switch to multisig page */
                         +    void gotoMultiSigPage();
                        

                        Code added

                        1 Reply Last reply Reply Quote 0
                        • wrapper
                          wrapper Moderators last edited by

                          Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                          Add Multisgin Page : - commit

                          https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                          Include a multi-signature address Page

                          src/script.cpp

                           +static const size_t nMaxNumSize = 4;
                          
                           +CBigNum CastToBigNum(const valtype& vch)
                           +{
                           +    if (vch.size() > nMaxNumSize)
                           +        throw runtime_error("CastToBigNum() : overflow");
                           +    // Get rid of extra leading zeros
                           +    return CBigNum(CBigNum(vch).getvch());
                           +}
                           +
                          

                          Code added

                           +class CKeyStoreIsMyShareVisitor : public boost::static_visitor<bool>
                           +{
                           +private:
                           +    const CKeyStore *keystore;
                           +public:
                           +    CKeyStoreIsMyShareVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { }
                           +    bool operator()(const CNoDestination &dest) const { return false; }
                           +    bool operator()(const CKeyID &keyID) const { return false; }
                           +    bool operator()(const CScriptID &scriptID) const { 
                           +        CScript scriptPubKey;
                           +        bool haveCScript = keystore->GetCScript(scriptID, scriptPubKey);
                           +        if ( !haveCScript )
                           +            return false;
                           +
                           +        return IsMyShare(*keystore, scriptPubKey);
                           +    }
                           +    bool operator()(const CStealthAddress &stxAddr) const
                           +    {
                           +        return false;
                           +    }
                           +};
                           +
                           +bool IsMyShare(const CKeyStore& keystore, const CTxDestination &dest)
                           +{
                           +    return boost::apply_visitor(CKeyStoreIsMyShareVisitor(&keystore), dest);
                           +}
                           +
                          

                          Code added

                           +bool IsMyShare(const CKeyStore& keystore, const CScript& scriptPubKey)
                           +{
                           +    vector<valtype> vSolutions;
                           +    txnouttype whichType;
                           +    if (!Solver(scriptPubKey, whichType, vSolutions))
                           +        return false;
                           +
                           +    CKeyID keyID;
                           +    switch (whichType)
                           +    {
                           +    case TX_NONSTANDARD:
                           +    case TX_NULL_DATA:
                           +    case TX_PUBKEY:
                           +    case TX_PUBKEYHASH:
                           +        return false;
                           +    case TX_SCRIPTHASH:
                           +    {
                           +        CScript subscript;
                           +        if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
                           +            return false;
                           +
                           +        return IsMyShare(keystore, subscript);
                           +    }
                           +    case TX_MULTISIG:
                           +    {
                           +        vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin() +vSolutions.size()-1);
                           +        int nkeys = HaveKeys(keys, keystore) ;
                           +        return nkeys > 0 && nkeys < keys.size();
                           +    }
                           +    default:
                           +        break;
                           +    }
                           +    return false;
                           +}
                           +
                          

                          Code added

                           +bool EvalMultiSigScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType, bool *bIsSign)
                           +{
                           +    CAutoBN_CTX pctx;
                           +    CScript::const_iterator pc = script.begin();
                           +    CScript::const_iterator pend = script.end();
                           +    CScript::const_iterator pbegincodehash = script.begin();
                           +    opcodetype opcode;
                           +    valtype vchPushValue;
                           +    vector<valtype> altstack;
                           +    if (script.size() > 10000)
                           +        return false;
                           +    int nOpCount = 0;
                           +    bool fStrictEncodings = flags & SCRIPT_VERIFY_STRICTENC;
                           +
                           +    try
                           +    {
                           +        while (pc < pend)
                           +        {
                           +            bool fExec = true;
                           +
                           +            //
                           +            // Read instruction
                           +            //
                           +            if (!script.GetOp(pc, opcode, vchPushValue))
                           +                return false;
                           +            if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE)
                           +                return false;
                           +            if (opcode > OP_16 &&  ++nOpCount > 201)
                           +                return false;
                           +
                           +            if (opcode == OP_CAT ||
                           +                opcode == OP_SUBSTR ||
                           +                opcode == OP_LEFT ||
                           +                opcode == OP_RIGHT ||
                           +                opcode == OP_INVERT ||
                           +                opcode == OP_AND ||
                           +                opcode == OP_OR ||
                           +                opcode == OP_XOR ||
                           +                opcode == OP_2MUL ||
                           +                opcode == OP_2DIV ||
                           +                opcode == OP_MUL ||
                           +                opcode == OP_DIV ||
                           +                opcode == OP_MOD ||
                           +                opcode == OP_LSHIFT ||
                           +                opcode == OP_RSHIFT)
                           +                return false; // Disabled opcodes.
                           +
                           +            if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
                           +                stack.push_back(vchPushValue);
                           +            else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
                           +            switch (opcode)
                           +            {
                           +                //
                           +                // Push value
                           +                //
                           +                case OP_1NEGATE:
                           +                case OP_1:
                           +                case OP_2:
                           +                case OP_3:
                           +                case OP_4:
                           +                case OP_5:
                           +                case OP_6:
                           +                case OP_7:
                           +                case OP_8:
                           +                case OP_9:
                           +                case OP_10:
                           +                case OP_11:
                           +                case OP_12:
                           +                case OP_13:
                           +                case OP_14:
                           +                case OP_15:
                           +                case OP_16:
                           +                {
                           +                    // ( -- value)
                           +                    //CBigNum bn((int)opcode - (int)(OP_1 - 1));
                           +                    CScriptNum bn((int)opcode - (int)(OP_1 - 1));
                           +                    stack.push_back(bn.getvch());
                           +                }
                           +                break;
                           +
                           +
                           +                //
                           +                // Control
                           +                //
                           +                case OP_NOP:
                           +                case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
                           +                case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
                           +                break;
                           +
                           +                case OP_IF:
                           +                case OP_NOTIF:
                           +                case OP_ELSE:
                           +                case OP_ENDIF:
                           +                    return false;
                           +
                           +                case OP_VERIFY:
                           +                {
                           +                    // (true -- ) or
                           +                    // (false -- false) and return
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    bool fValue = CastToBool(stacktop(-1));
                           +                    if (fValue)
                           +                        popstack(stack);
                           +                    else
                           +                        return false;
                           +                }
                           +                break;
                           +
                           +                case OP_RETURN:
                           +                {
                           +                    return false;
                           +                }
                           +                break;
                           +
                           +
                           +                //
                           +                // Stack ops
                           +                //
                           +                case OP_TOALTSTACK:
                           +                {
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    altstack.push_back(stacktop(-1));
                           +                    popstack(stack);
                           +                }
                           +                break;
                           +
                           +                case OP_FROMALTSTACK:
                           +                {
                           +                    if (altstack.size() < 1)
                           +                        return false;
                           +                    stack.push_back(altstacktop(-1));
                           +                    popstack(altstack);
                           +                }
                           +                break;
                           +
                           +                case OP_2DROP:
                           +                {
                           +                    // (x1 x2 -- )
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                }
                           +                break;
                           +
                           +                case OP_2DUP:
                           +                {
                           +                    // (x1 x2 -- x1 x2 x1 x2)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    valtype vch1 = stacktop(-2);
                           +                    valtype vch2 = stacktop(-1);
                           +                    stack.push_back(vch1);
                           +                    stack.push_back(vch2);
                           +                }
                           +                break;
                           +
                           +                case OP_3DUP:
                           +                {
                           +                    // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
                           +                    if (stack.size() < 3)
                           +                        return false;
                           +                    valtype vch1 = stacktop(-3);
                           +                    valtype vch2 = stacktop(-2);
                           +                    valtype vch3 = stacktop(-1);
                           +                    stack.push_back(vch1);
                           +                    stack.push_back(vch2);
                           +                    stack.push_back(vch3);
                           +                }
                           +                break;
                           +
                           +                case OP_2OVER:
                           +                {
                           +                    // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
                           +                    if (stack.size() < 4)
                           +                        return false;
                           +                    valtype vch1 = stacktop(-4);
                           +                    valtype vch2 = stacktop(-3);
                           +                    stack.push_back(vch1);
                           +                    stack.push_back(vch2);
                           +                }
                           +                break;
                           +
                           +                case OP_2ROT:
                           +                {
                           +                    // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
                           +                    if (stack.size() < 6)
                           +                        return false;
                           +                    valtype vch1 = stacktop(-6);
                           +                    valtype vch2 = stacktop(-5);
                           +                    stack.erase(stack.end()-6, stack.end()-4);
                           +                    stack.push_back(vch1);
                           +                    stack.push_back(vch2);
                           +                }
                           +                break;
                           +
                           +                case OP_2SWAP:
                           +                {
                           +                    // (x1 x2 x3 x4 -- x3 x4 x1 x2)
                           +                    if (stack.size() < 4)
                           +                        return false;
                           +                    swap(stacktop(-4), stacktop(-2));
                           +                    swap(stacktop(-3), stacktop(-1));
                           +                }
                           +                break;
                           +
                           +                case OP_IFDUP:
                           +                {
                           +                    // (x - 0 | x x)
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    valtype vch = stacktop(-1);
                           +                    if (CastToBool(vch))
                           +                        stack.push_back(vch);
                           +                }
                           +                break;
                           +
                           +                case OP_DEPTH:
                           +                {
                           +                    // -- stacksize
                           +                    //CBigNum bn(stack.size());
                           +                    CScriptNum bn(stack.size());
                           +                    stack.push_back(bn.getvch());
                           +                }
                           +                break;
                           +
                           +                case OP_DROP:
                           +                {
                           +                    // (x -- )
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    popstack(stack);
                           +                }
                           +                break;
                           +
                           +                case OP_DUP:
                           +                {
                           +                    // (x -- x x)
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    valtype vch = stacktop(-1);
                           +                    stack.push_back(vch);
                           +                }
                           +                break;
                           +
                           +                case OP_NIP:
                           +                {
                           +                    // (x1 x2 -- x2)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    stack.erase(stack.end() - 2);
                           +                }
                           +                break;
                           +
                           +                case OP_OVER:
                           +                {
                           +                    // (x1 x2 -- x1 x2 x1)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    valtype vch = stacktop(-2);
                           +                    stack.push_back(vch);
                           +                }
                           +                break;
                           +
                           +                case OP_PICK:
                           +                case OP_ROLL:
                           +                {
                           +                    // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
                           +                    // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    int n = CastToBigNum(stacktop(-1)).getint();
                           +                    popstack(stack);
                           +                    if (n < 0 || n >= (int)stack.size())
                           +                        return false;
                           +                    valtype vch = stacktop(-n-1);
                           +                    if (opcode == OP_ROLL)
                           +                        stack.erase(stack.end()-n-1);
                           +                    stack.push_back(vch);
                           +                }
                           +                break;
                           +
                           +                case OP_ROT:
                           +                {
                           +                    // (x1 x2 x3 -- x2 x3 x1)
                           +                    //  x2 x1 x3  after first swap
                           +                    //  x2 x3 x1  after second swap
                           +                    if (stack.size() < 3)
                           +                        return false;
                           +                    swap(stacktop(-3), stacktop(-2));
                           +                    swap(stacktop(-2), stacktop(-1));
                           +                }
                           +                break;
                           +
                           +                case OP_SWAP:
                           +                {
                           +                    // (x1 x2 -- x2 x1)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    swap(stacktop(-2), stacktop(-1));
                           +                }
                           +                break;
                           +
                           +                case OP_TUCK:
                           +                {
                           +                    // (x1 x2 -- x2 x1 x2)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    valtype vch = stacktop(-1);
                           +                    stack.insert(stack.end()-2, vch);
                           +                }
                           +                break;
                           +
                           +
                           +                case OP_SIZE:
                           +                {
                           +                    // (in -- in size)
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    //CBigNum bn(stacktop(-1).size());
                           +                    CScriptNum bn(stacktop(-1).size());
                           +                    stack.push_back(bn.getvch());
                           +                }
                           +                break;
                           +
                           +
                           +                //
                           +                // Bitwise logic
                           +                //
                           +                case OP_EQUAL:
                           +                case OP_EQUALVERIFY:
                           +                //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
                           +                {
                           +                    // (x1 x2 - bool)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    valtype& vch1 = stacktop(-2);
                           +                    valtype& vch2 = stacktop(-1);
                           +                    bool fEqual = (vch1 == vch2);
                           +                    // OP_NOTEQUAL is disabled because it would be too easy to say
                           +                    // something like n != 1 and have some wiseguy pass in 1 with extra
                           +                    // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
                           +                    //if (opcode == OP_NOTEQUAL)
                           +                    //    fEqual = !fEqual;
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                    stack.push_back(fEqual ? vchTrue : vchFalse);
                           +                    if (opcode == OP_EQUALVERIFY)
                           +                    {
                           +                        if (fEqual)
                           +                            popstack(stack);
                           +                        else
                           +                            return false;
                           +                    }
                           +                }
                           +                break;
                           +
                           +
                           +                //
                           +                // Numeric
                           +                //
                           +                case OP_1ADD:
                           +                case OP_1SUB:
                           +                case OP_NEGATE:
                           +                case OP_ABS:
                           +                case OP_NOT:
                           +                case OP_0NOTEQUAL:
                           +                {
                           +                    // (in -- out)
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    //CBigNum bn = CastToBigNum(stacktop(-1));
                           +                    CScriptNum bn(stacktop(-1));
                           +                    switch (opcode)
                           +                    {
                           +                    case OP_1ADD:       bn += bnOne; break;
                           +                    case OP_1SUB:       bn -= bnOne; break;
                           +                    case OP_NEGATE:     bn = -bn; break;
                           +                    case OP_ABS:        if (bn < bnZero) bn = -bn; break;
                           +                    case OP_NOT:        bn = (bn == bnZero); break;
                           +                    case OP_0NOTEQUAL:  bn = (bn != bnZero); break;
                           +                    default:            assert(!"invalid opcode"); break;
                           +                    }
                           +                    popstack(stack);
                           +                    stack.push_back(bn.getvch());
                           +                }
                           +                break;
                           +
                           +                case OP_ADD:
                           +                case OP_SUB:
                           +                case OP_BOOLAND:
                           +                case OP_BOOLOR:
                           +                case OP_NUMEQUAL:
                           +                case OP_NUMEQUALVERIFY:
                           +                case OP_NUMNOTEQUAL:
                           +                case OP_LESSTHAN:
                           +                case OP_GREATERTHAN:
                           +                case OP_LESSTHANOREQUAL:
                           +                case OP_GREATERTHANOREQUAL:
                           +                case OP_MIN:
                           +                case OP_MAX:
                           +                {
                           +                    // (x1 x2 -- out)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +                    /*CBigNum bn1 = CastToBigNum(stacktop(-2));
                           +                    CBigNum bn2 = CastToBigNum(stacktop(-1));
                           +                    CBigNum bn;*/
                           +                    CScriptNum bn1(stacktop(-2));
                           +                    CScriptNum bn2(stacktop(-1));
                           +                    CScriptNum bn(0);
                           +                    switch (opcode)
                           +                    {
                           +                    case OP_ADD:
                           +                        bn = bn1 + bn2;
                           +                        break;
                           +
                           +                    case OP_SUB:
                           +                        bn = bn1 - bn2;
                           +                        break;
                           +
                           +                    case OP_BOOLAND:             bn = (bn1 != bnZero && bn2 != bnZero); break;
                           +                    case OP_BOOLOR:              bn = (bn1 != bnZero || bn2 != bnZero); break;
                           +                    case OP_NUMEQUAL:            bn = (bn1 == bn2); break;
                           +                    case OP_NUMEQUALVERIFY:      bn = (bn1 == bn2); break;
                           +                    case OP_NUMNOTEQUAL:         bn = (bn1 != bn2); break;
                           +                    case OP_LESSTHAN:            bn = (bn1 < bn2); break;
                           +                    case OP_GREATERTHAN:         bn = (bn1 > bn2); break;
                           +                    case OP_LESSTHANOREQUAL:     bn = (bn1 <= bn2); break;
                           +                    case OP_GREATERTHANOREQUAL:  bn = (bn1 >= bn2); break;
                           +                    case OP_MIN:                 bn = (bn1 < bn2 ? bn1 : bn2); break;
                           +                    case OP_MAX:                 bn = (bn1 > bn2 ? bn1 : bn2); break;
                           +                    default:                     assert(!"invalid opcode"); break;
                           +                    }
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                    stack.push_back(bn.getvch());
                           +
                           +                    if (opcode == OP_NUMEQUALVERIFY)
                           +                    {
                           +                        if (CastToBool(stacktop(-1)))
                           +                            popstack(stack);
                           +                        else
                           +                            return false;
                           +                    }
                           +                }
                           +                break;
                           +
                           +                case OP_WITHIN:
                           +                {
                           +                    // (x min max -- out)
                           +                    if (stack.size() < 3)
                           +                        return false;
                           +                    /*CBigNum bn1 = CastToBigNum(stacktop(-3));
                           +                    CBigNum bn2 = CastToBigNum(stacktop(-2));
                           +                    CBigNum bn3 = CastToBigNum(stacktop(-1));*/
                           +                    CScriptNum bn1(stacktop(-3));
                           +                    CScriptNum bn2(stacktop(-2));
                           +                    CScriptNum bn3(stacktop(-1));
                           +                    bool fValue = (bn2 <= bn1 && bn1 < bn3);
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                    stack.push_back(fValue ? vchTrue : vchFalse);
                           +                }
                           +                break;
                           +
                           +
                           +                //
                           +                // Crypto
                           +                //
                           +                case OP_RIPEMD160:
                           +                case OP_SHA1:
                           +                case OP_SHA256:
                           +                case OP_HASH160:
                           +                case OP_HASH256:
                           +                {
                           +                    // (in -- hash)
                           +                    if (stack.size() < 1)
                           +                        return false;
                           +                    valtype& vch = stacktop(-1);
                           +                    valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
                           +                    if (opcode == OP_RIPEMD160)
                           +                        RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
                           +                    else if (opcode == OP_SHA1)
                           +                        SHA1(&vch[0], vch.size(), &vchHash[0]);
                           +                    else if (opcode == OP_SHA256)
                           +                        SHA256(&vch[0], vch.size(), &vchHash[0]);
                           +                    else if (opcode == OP_HASH160)
                           +                    {
                           +                        uint160 hash160 = Hash160(vch);
                           +                        memcpy(&vchHash[0], &hash160, sizeof(hash160));
                           +                    }
                           +                    else if (opcode == OP_HASH256)
                           +                    {
                           +                        uint256 hash = Hash(vch.begin(), vch.end());
                           +                        memcpy(&vchHash[0], &hash, sizeof(hash));
                           +                    }
                           +                    popstack(stack);
                           +                    stack.push_back(vchHash);
                           +                }
                           +                break;
                           +
                           +                case OP_CODESEPARATOR:
                           +                {
                           +                    // Hash starts after the code separator
                           +                    pbegincodehash = pc;
                           +                }
                           +                break;
                           +
                           +                case OP_CHECKSIG:
                           +                case OP_CHECKSIGVERIFY:
                           +                {
                           +                    // (sig pubkey -- bool)
                           +                    if (stack.size() < 2)
                           +                        return false;
                           +
                           +                    valtype& vchSig    = stacktop(-2);
                           +                    valtype& vchPubKey = stacktop(-1);
                           +
                           +                    ////// debug print
                           +                    //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n");
                           +                    //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n");
                           +
                           +                    // Subset of script starting at the most recent codeseparator
                           +                    CScript scriptCode(pbegincodehash, pend);
                           +
                           +                    // Drop the signature, since there's no way for a signature to sign itself
                           +                    scriptCode.FindAndDelete(CScript(vchSig));
                           +
                           +                    bool fSuccess = (!fStrictEncodings || (IsCanonicalSignature(vchSig,flags) && IsCanonicalPubKey(vchPubKey,flags)));
                           +                    if (fSuccess)
                           +                        fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);
                           +
                           +                    popstack(stack);
                           +                    popstack(stack);
                           +                    stack.push_back(fSuccess ? vchTrue : vchFalse);
                           +                    if (opcode == OP_CHECKSIGVERIFY)
                           +                    {
                           +                        if (fSuccess)
                           +                            popstack(stack);
                           +                        else
                           +                            return false;
                           +                    }
                           +                }
                           +                break;
                           +
                           +                case OP_CHECKMULTISIG:
                           +                case OP_CHECKMULTISIGVERIFY:
                           +                {
                           +                    // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
                           +                    int i = 1;
                           +                    if ((int)stack.size() < i)
                           +                        return false;
                           +
                           +                    int nKeysCount = CastToBigNum(stacktop(-i)).getint();
                           +                    if (nKeysCount < 0 || nKeysCount > 20)
                           +                        return false;
                           +                    nOpCount += nKeysCount;
                           +                    if (nOpCount > 201)
                           +                        return false;
                           +                    int ikey = ++i;
                           +                    i += nKeysCount;
                           +                    if ((int)stack.size() < i)
                           +                        return false;
                           +
                           +                    int nSigsCount = CastToBigNum(stacktop(-i)).getint();
                           +                    if (nSigsCount < 0 || nSigsCount > nKeysCount)
                           +                        return false;
                           +                    int isig = ++i;
                           +                    i += nSigsCount;
                           +                    //if ((int)stack.size() < i)
                           +                        //return false;
                           +                    int curSigsCount = nSigsCount + stack.size()- i;
                           +                    if ( curSigsCount > nSigsCount )
                           +                        curSigsCount = nSigsCount;
                           +
                           +                    // Subset of script starting at the most recent codeseparator
                           +                    CScript scriptCode(pbegincodehash, pend);
                           +
                           +                    // Drop the signatures, since there's no way for a signature to sign itself
                           +                    for (int k = 0; k < curSigsCount; k++)
                           +                    {
                           +                        valtype& vchSig = stacktop(-isig-k);
                           +                        scriptCode.FindAndDelete(CScript(vchSig));
                           +                    }
                           +
                           +                    bool fSuccess = true;
                           +                    int okCount = 0;
                           +                    for ( int n = 0; n < nKeysCount; ++ n )
                           +                    {
                           +                        for ( int m = 0; m < curSigsCount; ++ m )
                           +                        {
                           +                            valtype& vchSig    = stacktop(-isig - m);
                           +                            valtype& vchPubKey = stacktop(-ikey - n);
                           +
                           +                            // Check signature
                           +                            bool fOk = (!fStrictEncodings || (IsCanonicalSignature(vchSig,flags) && IsCanonicalPubKey(vchPubKey,flags)));
                           +                            if (fOk)
                           +                                fOk = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags);
                           +
                           +                            if (fOk) {
                           +                                bIsSign[nKeysCount - 1 - n] = true;
                           +                                okCount += 1;
                           +                            }
                           +                        }
                           +                    }
                           +
                           +                    if ( okCount < nSigsCount )
                           +                        fSuccess = false;
                           +
                           +                    return fSuccess;
                           +                }
                           +                break;
                           +
                           +                default:
                           +                    return false;
                           +            }
                           +        }
                           +    }
                           +    catch (...)
                           +    {
                           +        return false;
                           +    }
                           +
                           +
                           +    return true;
                           +}
                           +
                           +bool VerifyMultiSigScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType, bool *bIsSign)
                           +{
                           +    vector<vector<unsigned char> > stack, stackCopy;
                           +    if (!EvalScript(stack, scriptSig, txTo, nIn, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, nHashType))
                           +        return false;
                           +
                           +    stackCopy = stack;
                           +    if (!EvalScript(stack, scriptPubKey, txTo, nIn, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, nHashType))
                           +        return false;
                           +
                           +    if (stack.empty())
                           +        return false;
                           +
                           +    if (CastToBool(stack.back()) == false)
                           +        return false;
                           +
                           +    if (scriptPubKey.IsPayToScriptHash())
                           +    {
                           +        if (!scriptSig.IsPushOnly())
                           +            return false;
                           +
                           +        assert(!stackCopy.empty());
                           +
                           +        const valtype& pubKeySerialized = stackCopy.back();
                           +        CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
                           +        popstack(stackCopy);
                           +
                           +        if (!EvalMultiSigScript(stackCopy, pubKey2, txTo, nIn, SCRIPT_VERIFY_P2SH, nHashType, bIsSign))
                           +            return false;
                           +
                           +        if (stackCopy.empty())
                           +            return false;
                           +
                           +        return CastToBool(stackCopy.back());
                           +    }
                           +
                           +    return false;
                           +}
                           +
                          

                          Code added

                          1 Reply Last reply Reply Quote 0
                          • wrapper
                            wrapper Moderators last edited by

                            Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                            Add Multisgin Page : - commit

                            https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                            Include a multi-signature address Page

                            src/script.h

                             +bool IsMyShare(const CKeyStore& keystore, const CScript& scriptPubKey);
                            
                             +bool IsMyShare(const CKeyStore& keystore, const CTxDestination &dest);
                            
                             +bool VerifyMultiSigScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType, bool *bIsSign);
                            

                            Code added

                            1 Reply Last reply Reply Quote 0
                            • wrapper
                              wrapper Moderators last edited by

                              Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                              Add Multisgin Page : - commit

                              https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                              Include a multi-signature address Page

                              src/wallet.cpp

                               +#include "walletdb.h"
                               +#include "crypter.h"
                               +#include "ui_interface.h"
                              

                              Code added

                               -    NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
                               -                             strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
                              
                               +    bool fMine = ::IsMine(*this, address);
                              
                               +    if ( ::IsMyShare(*this, address) )
                               +        fMine = false;
                               +    //NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
                               +    NotifyAddressBookChanged(this, address, strName, fMine, strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
                              

                              Code replaced

                               +}
                               +
                               +
                               +
                               +
                               +
                               +/* 
                               + *  for shared wallet
                               + */
                               +
                               +bool CWallet::SelectSharedCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl) const
                               +{
                               +    vector<COutput> vCoins;
                               +    AvailableSharedCoins(vCoins, false, coinControl);
                               +    
                               +    // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
                               +    if (coinControl && coinControl->HasSelected())
                               +    {
                               +        BOOST_FOREACH(const COutput& out, vCoins)
                               +        {
                               +            nValueRet += out.tx->vout[out.i].nValue;
                               +            setCoinsRet.insert(make_pair(out.tx, out.i));
                               +        }
                               +        return (nValueRet >= nTargetValue);
                               +    }
                               +
                               +    return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
                               +            SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
                               +            SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet));
                               +}
                               +
                               +bool CWallet::CreateRawTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CTransaction& txNew, 
                               +    int64& nFeeRet, std::string& strFailReason, bool isMultiSig, CReserveKey& reservekey, const CCoinControl *coinControl)
                               +{
                               +    int64 nValue = 0;
                               +    BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
                               +    {
                               +        if (nValue < 0)
                               +        {
                               +            strFailReason = _("Transaction amounts must be positive");
                               +            return false;
                               +        }
                               +        nValue += s.second;
                               +    }
                               +    if (vecSend.empty() || nValue < 0)
                               +    {
                               +        strFailReason = _("Transaction amounts must be positive");
                               +        return false;
                               +    }
                               +
                               +    int64 nTotalValue = nValue + nFeeRet;
                               +    CTransaction rawTx;
                               +
                               +    // vouts to the payees
                               +    BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
                               +    {
                               +        CTxOut txout(s.second, s.first);
                               +        if (txout.IsDust((CTransaction::nMinRelayTxFee)))
                               +        {
                               +            strFailReason = _("Transaction amount too small");
                               +            return false;
                               +        }
                               +        rawTx.vout.push_back(txout);
                               +    }
                               +
                               +    // Choose coins to use
                               +    set<pair<const CWalletTx*,unsigned int> > setCoins;
                               +    int64 nValueIn = 0;
                               +    if ( isMultiSig )
                               +    {
                               +        if (!SelectSharedCoins(nTotalValue, setCoins, nValueIn, coinControl))
                               +        {
                               +            strFailReason = _("Insufficient funds");
                               +            return false;
                               +        }
                               +    }
                               +    else
                               +    {
                               +        if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
                               +        {
                               +            strFailReason = _("Insufficient funds");
                               +            return false;
                               +        }
                               +    }
                               +
                               +    int64 nChange = nValueIn - nTotalValue;
                               +    if (nChange > 0)
                               +    {
                               +        CScript scriptChange;
                               +        
                               +        // coin control: send change to custom address
                               +        if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
                               +            scriptChange.SetDestination(coinControl->destChange);
                               +        else
                               +        {
                               +            // Reserve a new key pair from key pool
                               +            CPubKey vchPubKey;
                               +            assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
                               +
                               +            scriptChange.SetDestination(vchPubKey.GetID());
                               +        }
                               +
                               +        CTxOut newTxOut(nChange, scriptChange);
                               +
                               +        if (newTxOut.IsDust((CTransaction::nMinRelayTxFee)))
                               +        {
                               +            nFeeRet += nChange;
                               +        }
                               +        else
                               +        {
                               +            vector<CTxOut>::iterator position = rawTx.vout.begin()+GetRandInt(rawTx.vout.size()+1);
                               +            rawTx.vout.insert(position, newTxOut);
                               +        }
                               +    }
                               +    else
                               +        reservekey.ReturnKey();
                               +
                               +    // Fill vin
                               +    BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
                               +        rawTx.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
                               +
                               +    if ( !isMultiSig )
                               +    {
                               +        // Sign
                               +        int nIn = 0;
                               +        BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
                               +            if (!SignSignature(*this, *coin.first, rawTx, nIn++))
                               +            {
                               +                strFailReason = _("Signing transaction failed");
                               +                return false;
                               +            }
                               +    }
                               +    
                               +    // Limit size
                               +    unsigned int nBytes = ::GetSerializeSize(rawTx, SER_NETWORK, PROTOCOL_VERSION);
                               +    if (nBytes >= MAX_STANDARD_TX_SIZE)
                               +    {
                               +        strFailReason = _("Transaction too large");
                               +        return false;
                               +    }
                               +
                               +    txNew = rawTx;
                               +    return true;
                               +}
                               +
                               +bool CWallet::IsMyShare(const CTxIn& txin) const
                               +{
                               +    {
                               +        LOCK(cs_wallet);
                               +        map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
                               +        if (mi != mapWallet.end())
                               +        {
                               +            const CWalletTx& prev = (*mi).second;
                               +            if (txin.prevout.n < prev.vout.size())
                               +                if (IsMyShare(prev.vout[txin.prevout.n]))
                               +                    return true;
                               +        }
                               +    }
                               +    return false;
                               +}
                               +
                               +bool CWallet::IsMyShare(const CTxOut& txout) const
                               +{
                               +    return ::IsMyShare(*this, txout.scriptPubKey);
                               +}
                               +
                               +bool CWallet::IsMyShare(const CTransaction& tx) const
                               +{
                               +    BOOST_FOREACH(const CTxOut& txout, tx.vout)
                               +        if (IsMyShare(txout) && txout.nValue >= DUST_HARD_LIMIT)
                               +            return true;
                               +
                               +    return false;
                               +}
                               +
                               +int64 CWallet::GetSharedBalance() const
                               +{
                               +    int64 nTotal = 0;
                               +    {
                               +        LOCK(cs_wallet);
                               +        for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
                               +        {
                               +            const CWalletTx* pcoin = &(*it).second;
                               +            if (pcoin->IsConfirmed())
                               +                nTotal += pcoin->GetSharedAvailableCredit();
                               +        }
                               +    }
                               +
                               +    return nTotal;
                               +}
                               +
                               +int64 CWallet::GetSharedUnconfirmedBalance() const
                               +{
                               +    int64 nTotal = 0;
                               +    {
                               +        LOCK(cs_wallet);
                               +        for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
                               +        {
                               +            const CWalletTx* pcoin = &(*it).second;
                               +            if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
                               +                nTotal += pcoin->GetSharedAvailableCredit();
                               +        }
                               +    }
                               +    return nTotal;
                               +}
                               +
                               +int64 CWallet::GetSharedImmatureBalance() const
                               +{
                               +    return 0;
                               +}
                               +
                               +int64 CWallet::GetShareDebit(const CTxIn &txin) const
                               +{
                               +    {
                               +        LOCK(cs_wallet);
                               +        map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
                               +        if (mi != mapWallet.end())
                               +        {
                               +            const CWalletTx& prev = (*mi).second;
                               +            if (txin.prevout.n < prev.vout.size())
                               +                if (IsMyShare(prev.vout[txin.prevout.n]))
                               +                    return prev.vout[txin.prevout.n].nValue;
                               +        }
                               +    }
                               +    return 0;
                               +}
                               +
                               +void CWallet::AvailableSharedCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
                               +{
                               +    vCoins.clear();
                               +
                               +    {
                               +        LOCK(cs_wallet);
                               +        for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
                               +        {
                               +            const CWalletTx* pcoin = &(*it).second;
                               +
                               +            if (!pcoin->IsFinal())
                               +                continue;
                               +
                               +            if (fOnlyConfirmed && !pcoin->IsConfirmed())
                               +                continue;
                               +
                               +            if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
                               +                continue;
                               +
                               +            for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
                               +                if (!(pcoin->IsSpent(i)) && IsMyShare(pcoin->vout[i]) &&
                               +                    !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue >= DUST_HARD_LIMIT &&
                               +                    (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) 
                               +                        vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain()));
                               +            }
                               +        }
                               +    }
                               +}
                               +
                               +
                               +
                              

                              Code added

                              1 Reply Last reply Reply Quote 0
                              • wrapper
                                wrapper Moderators last edited by

                                Feathercoin specific changes made to convert Bitcoin to FTC 0.9.6.*

                                Add Multisgin Page : - commit

                                https://github.com/FeatherCoin/Feathercoin/commit/83737e90c292f18fe0285677cefbd70125492e1a

                                Include a multi-signature address Page

                                src/wallet.h

                                 +#include "script.h"
                                

                                Code added

                                 +    	
                                 +    bool CreateRawTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CTransaction& txNew, 
                                 +        int64& nFeeRet, std::string& strFailReason, bool isMultiSig, CReserveKey& reservekey, const CCoinControl *coinControl=NULL);
                                 +        	
                                 +    /* 
                                 +     *  for shared wallet
                                 +     */
                                 +    bool IsMyShare(const CTxIn& txin) const;
                                 +    bool IsMyShare(const CTxOut& txout) const;
                                 +    bool IsMyShare(const CTransaction& tx) const;
                                 +    int64 GetSharedBalance() const;
                                 +    int64 GetSharedUnconfirmedBalance() const;
                                 +    int64 GetSharedImmatureBalance() const;
                                 +    int64 GetSharedCredit(const CTxOut& txout) const
                                 +    {
                                 +        if (!MoneyRange(txout.nValue))
                                 +            throw std::runtime_error("CWallet::GetSharedCredit() : value out of range");
                                 +        return (IsMyShare(txout) ? txout.nValue : 0);
                                 +    }
                                 +    bool IsFromMyShare(const CTransaction& tx) const
                                 +    {
                                 +        return (GetShareDebit(tx) > 0);
                                 +    }
                                 +    int64 GetShareDebit(const CTransaction& tx) const
                                 +    {
                                 +        int64 nDebit = 0;
                                 +        BOOST_FOREACH(const CTxIn& txin, tx.vin)
                                 +        {
                                 +            nDebit += GetShareDebit(txin);
                                 +            if (!MoneyRange(nDebit))
                                 +                throw std::runtime_error("CWallet::GetDebit() : value out of range");
                                 +        }
                                 +        return nDebit;
                                 +    }
                                 +    int64 GetShareDebit(const CTxIn& txin) const;
                                 +    void AvailableSharedCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const;
                                 +    bool SelectSharedCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl=NULL) const;
                                

                                Code added

                                 +    std::vector<CMerkleTx> vtxPrev;
                                
                                 +    std::vector<char> vfSpent; // which outputs are already spent
                                
                                 +        fSharedAvailableCreditCached = false;
                                

                                Code added

                                 +    
                                 +    bool IsSpent(unsigned int nOut) const
                                 +    {
                                 +        if (nOut >= vout.size())
                                 +            throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
                                 +        if (nOut >= vfSpent.size())
                                 +            return false;
                                 +        return (!!vfSpent[nOut]);
                                 +    }
                                

                                Code added

                                 +    
                                 +    bool IsConfirmed() const
                                 +    {
                                 +        // Quick answer in most cases
                                 +        if (!IsFinal())
                                 +            return false;
                                 +        if (GetDepthInMainChain() >= 1)
                                 +            return true;
                                 +        if (!IsFromMe()) // using wtx's cached debit
                                 +            return false;
                                 +
                                 +        // If no confirmations but it's from us, we can still
                                 +        // consider it confirmed if all dependencies are confirmed
                                 +        std::map<uint256, const CMerkleTx*> mapPrev;
                                 +        std::vector<const CMerkleTx*> vWorkQueue;
                                 +        vWorkQueue.reserve(vtxPrev.size()+1);
                                 +        vWorkQueue.push_back(this);
                                 +        for (unsigned int i = 0; i < vWorkQueue.size(); i++)
                                 +        {
                                 +            const CMerkleTx* ptx = vWorkQueue[i];
                                 +
                                 +            if (!ptx->IsFinal())
                                 +                return false;
                                 +            if (ptx->GetDepthInMainChain() >= 1)
                                 +                continue;
                                 +            if (!pwallet->IsFromMe(*ptx))
                                 +                return false;
                                 +
                                 +            if (mapPrev.empty())
                                 +            {
                                 +                BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
                                 +                    mapPrev[tx.GetHash()] = &tx;
                                 +            }
                                 +
                                 +            BOOST_FOREACH(const CTxIn& txin, ptx->vin)
                                 +            {
                                 +                if (!mapPrev.count(txin.prevout.hash))
                                 +                    return false;
                                 +                vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
                                 +            }
                                 +        }
                                 +        return true;
                                 +    }
                                

                                Code added

                                 +    	
                                 +    /* 
                                 +     *  for shared wallet
                                 +     */
                                 +    mutable bool fSharedAvailableCreditCached;
                                 +    mutable int64 nSharedAvailableCreditCached;
                                 +    int64 GetSharedAvailableCredit(bool fUseCache=true) const
                                 +    {
                                 +        // Must wait until coinbase is safely deep enough in the chain before valuing it
                                 +        if (IsCoinBase() && GetBlocksToMaturity() > 0)
                                 +            return 0;
                                 +
                                 +        //if (fUseCache && fSharedAvailableCreditCached)
                                 +            //return nSharedAvailableCreditCached;
                                 +
                                 +        int64 nCredit = 0;
                                 +        for (unsigned int i = 0; i < vout.size(); i++)
                                 +        {
                                 +            if (!IsSpent(i))
                                 +            {
                                 +                const CTxOut &txout = vout[i];
                                 +                nCredit += pwallet->GetSharedCredit(txout);
                                 +                if (!MoneyRange(nCredit))
                                 +                    throw std::runtime_error("CWalletTx::GetSharedAvailableCredit() : value out of range");
                                 +            }
                                 +        }
                                 +
                                 +        nSharedAvailableCreditCached = nCredit;
                                 +        fSharedAvailableCreditCached = true;
                                 +        return nCredit;
                                 +    }
                                

                                Code added

                                1 Reply Last reply Reply Quote 0
                                • First post
                                  Last post