Exemple #1
1
CScript
ParseScript(string s)
{
    CScript result;

    static map<string, opcodetype> mapOpNames;

    if (mapOpNames.size() == 0)
    {
        for (int op = 0; op <= OP_NOP10; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            const char* name = GetOpName((opcodetype)op);
            if (strcmp(name, "OP_UNKNOWN") == 0)
                continue;
            string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    vector<string> words;
    split(words, s, is_any_of(" \t\n"), token_compress_on);

    BOOST_FOREACH(string w, words)
    {
        if (all(w, is_digit()) ||
            (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
        {
            // Number
            int64 n = atoi64(w);
            result << n;
        }
        else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'"))
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w.begin()+1, w.end()-1);
            result << value;
        }
        else if (mapOpNames.count(w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[w];
        }
        else
        {
            BOOST_ERROR("Parse error: " << s);
            return CScript();
        }
    }

    return result;
}
Exemple #2
0
/**
 * Sign scriptPubKey using signature made with creator.
 * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
 * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
 * Returns false if scriptPubKey could not be completely satisfied.
 */
static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
                     std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata)
{
    CScript scriptRet;
    uint160 h160;
    ret.clear();
    std::vector<unsigned char> sig;

    std::vector<valtype> vSolutions;
    if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
        return false;

    switch (whichTypeRet)
    {
    case TX_NONSTANDARD:
    case TX_NULL_DATA:
    case TX_WITNESS_UNKNOWN:
        return false;
    case TX_PUBKEY:
        if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
        ret.push_back(std::move(sig));
        return true;
    case TX_PUBKEYHASH: {
        CKeyID keyID = CKeyID(uint160(vSolutions[0]));
        CPubKey pubkey;
        GetPubKey(provider, sigdata, keyID, pubkey);
        if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false;
        ret.push_back(std::move(sig));
        ret.push_back(ToByteVector(pubkey));
        return true;
    }
    case TX_SCRIPTHASH:
        if (GetCScript(provider, sigdata, uint160(vSolutions[0]), scriptRet)) {
            ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
            return true;
        }
        return false;

    case TX_MULTISIG: {
        size_t required = vSolutions.front()[0];
        ret.push_back(valtype()); // workaround CHECKMULTISIG bug
        for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
            CPubKey pubkey = CPubKey(vSolutions[i]);
            if (ret.size() < required + 1 && CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) {
                ret.push_back(std::move(sig));
            }
        }
        bool ok = ret.size() == required + 1;
        for (size_t i = 0; i + ret.size() < required + 1; ++i) {
            ret.push_back(valtype());
        }
        return ok;
    }
    case TX_WITNESS_V0_KEYHASH:
        ret.push_back(vSolutions[0]);
        return true;

    case TX_WITNESS_V0_SCRIPTHASH:
        CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
        if (GetCScript(provider, sigdata, h160, scriptRet)) {
            ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
            return true;
        }
        return false;

    default:
        return false;
    }
}
Exemple #3
0
bool CSector::r_LoadVal( CScript &s )
{
	ADDTOCALLSTACK("CSector::r_LoadVal");
	EXC_TRY("LoadVal");
	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		case SC_COLDCHANCE:
			SetWeatherChance( false, s.HasArgs() ? s.GetArgVal() : -1 );
			return( true );
		case SC_FLAGS:
			m_dwFlags = s.GetArgVal();
			return true;
		case SC_LIGHT:
			if ( g_Cfg.m_bAllowLightOverride )
				m_Env.m_Light = static_cast<unsigned char>(s.GetArgVal() | LIGHT_OVERRIDE);
			return true;
		case SC_RAINCHANCE:
			SetWeatherChance( true, s.HasArgs() ? s.GetArgVal() : -1 );
			return( true );
		case SC_SEASON:
			SetSeason(s.HasArgs() ? static_cast<SEASON_TYPE>(s.GetArgVal()) : SEASON_Summer);
			return (true);
		case SC_WEATHER:
			SetWeather(s.HasArgs() ? static_cast<WEATHER_TYPE>(s.GetArgVal()) : WEATHER_DRY);
			return( true );
	}
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #4
0
bool CDialogDef::r_Verb( CScript & s, CTextConsole * pSrc )	// some command on this object as a target
{
    ADDTOCALLSTACK("CDialogDef::r_Verb");
    EXC_TRY("Verb");
    // The first part of the key is GUMPCTL_TYPE
    lpctstr pszKey = s.GetKey();

    int index = FindTableSorted( pszKey, sm_szLoadKeys, CountOf(sm_szLoadKeys)-1 );
    if ( index < 0 )
    {
        CSString sVal;
        CScriptTriggerArgs Args(s.GetArgRaw());
        if ( r_Call(s.GetKey(), pSrc, &Args, &sVal) )
            return true;
        if (!m_pObj)
            return CResourceLink::r_Verb(s, pSrc);
        return m_pObj->r_Verb(s, pSrc);
    }

    lpctstr pszArgs	= s.GetArgStr();

    switch( index )
    {
        case GUMPCTL_PAGE:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;

            GET_ABSOLUTE( page );

            if ( page <= 0 )		return true;

            int	iNewPage;
            if ( m_wPage == 0 || page > m_wPage || page == 0 )
                iNewPage	= page;
            else if ( page == m_wPage  )
                iNewPage	= 1;
            else
                iNewPage	= page + 1;

            m_sControls[m_uiControls].Format( "page %d", iNewPage );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_BUTTON:			// 7 = X,Y,Down gump,Up gump,pressable(1/0),page,id
        case GUMPCTL_BUTTONTILEART:		// 11 = X,Y,Down gump,Up gump,pressable(1/0),page,id,tileart,hue,X,Y
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( down );
            GET_ABSOLUTE( up );
            GET_ABSOLUTE( press );
            GET_ABSOLUTE( page );
            GET_ABSOLUTE( id );

            int	iNewPage;
            if ( m_wPage == 0 || page > m_wPage || page == 0 )
                iNewPage	= page;
            else if ( page == m_wPage  )
                iNewPage	= 1;
            else
                iNewPage	= page + 1;

            if (index == GUMPCTL_BUTTON)
                m_sControls[m_uiControls].Format( "button %d %d %d %d %d %d %d", x, y, down, up, press, iNewPage, id );
            else
            {
                GET_ABSOLUTE( tileId );
                GET_ABSOLUTE( tileHue );
                GET_ABSOLUTE( tileX );
                GET_ABSOLUTE( tileY );

                m_sControls[m_uiControls].Format( "buttontileart %d %d %d %d %d %d %d %d %d %d %d", x, y, down, up, press, iNewPage, id, tileId, tileHue, tileX, tileY );
            }

            ++m_uiControls;
            return true;
        }
        case GUMPCTL_GUMPPIC:
        {
            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( id );
            SKIP_ALL( pszArgs );

            m_sControls[m_uiControls].Format( "gumppic %d %d %d%s%s", x, y, id, *pszArgs ? " hue=" : "", *pszArgs ? pszArgs : "" );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_GUMPPICTILED:
        {
            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( sX );
            GET_ABSOLUTE( sY );
            GET_ABSOLUTE( id );

            m_sControls[m_uiControls].Format( "gumppictiled %d %d %d %d %d", x, y, sX, sY, id );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_RESIZEPIC:
        {
            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( id );
            GET_ABSOLUTE( sX );
            GET_ABSOLUTE( sY );

            m_sControls[m_uiControls].Format( "resizepic %d %d %d %d %d", x, y, id, sX, sY );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_TILEPIC:
        case GUMPCTL_TILEPICHUE:
        {
            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( id );
            SKIP_ALL( pszArgs );

            // TilePic don't use args, TilePicHue yes :)
            if ( index == GUMPCTL_TILEPIC )
                m_sControls[m_uiControls].Format( "tilepic %d %d %d", x, y, id );
            else
                m_sControls[m_uiControls].Format( "tilepichue %d %d %d%s%s", x, y, id, *pszArgs ? " " : "", *pszArgs ? pszArgs : "" );

            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DTEXT:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( hue );
            SKIP_ALL( pszArgs )
                if ( *pszArgs == '.' )			pszArgs++;

            uint iText = GumpAddText( *pszArgs ? pszArgs : "" );
            m_sControls[m_uiControls].Format( "text %d %d %d %u", x, y, hue, iText );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DCROPPEDTEXT:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( w );
            GET_ABSOLUTE( h );
            GET_ABSOLUTE( hue );
            SKIP_ALL( pszArgs )
                if ( *pszArgs == '.' )			pszArgs++;

			uint iText = GumpAddText( *pszArgs ? pszArgs : "" );
            m_sControls[m_uiControls].Format( "croppedtext %d %d %d %d %d %u", x, y, w, h, hue, iText );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DHTMLGUMP:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( w );
            GET_ABSOLUTE( h );
            GET_ABSOLUTE( bck );
            GET_ABSOLUTE( options );
            SKIP_ALL( pszArgs )

            uint iText = GumpAddText( *pszArgs ? pszArgs : "" );
            m_sControls[m_uiControls].Format( "htmlgump %d %d %d %d %u %d %d", x, y, w, h, iText, bck, options );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DTEXTENTRY:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( w );
            GET_ABSOLUTE( h );
            GET_ABSOLUTE( hue );
            GET_ABSOLUTE( id );
            SKIP_ALL( pszArgs )

            uint iText = GumpAddText( *pszArgs ? pszArgs : "" );
            m_sControls[m_uiControls].Format( "textentry %d %d %d %d %d %d %u", x, y, w, h, hue, id, iText );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DTEXTENTRYLIMITED:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( w );
            GET_ABSOLUTE( h );
            GET_ABSOLUTE( hue );
            GET_ABSOLUTE( id );
            GET_ABSOLUTE( charLimit );
            SKIP_ALL( pszArgs )

            uint iText = GumpAddText( *pszArgs ? pszArgs : "" );
            m_sControls[m_uiControls].Format( "textentrylimited %d %d %d %d %d %d %u %d", x, y, w, h, hue, id, iText, charLimit );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_CHECKBOX:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( down );
            GET_ABSOLUTE( up );
            GET_ABSOLUTE( state );
            GET_ABSOLUTE( id );

            m_sControls[m_uiControls].Format( "checkbox %d %d %d %d %d %d", x, y, down, up, state, id );

            ++m_uiControls;
            return true;
        }
        case GUMPCTL_RADIO:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( down );
            GET_ABSOLUTE( up );
            GET_ABSOLUTE( state );
            GET_ABSOLUTE( id );

            m_sControls[m_uiControls].Format( "radio %d %d %d %d %d %d", x, y, down, up, state, id );

            ++m_uiControls;
            return true;
        }
        case GUMPCTL_CHECKERTRANS:
        {
            if ( m_uiControls >= (CountOf(m_sControls) - 1) )
                return false;

            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( width );
            GET_ABSOLUTE( height );

            m_sControls[m_uiControls].Format( "checkertrans %d %d %d %d", x, y, width, height );
            ++m_uiControls;
            return true;
        }
        case GUMPCTL_DORIGIN:
        {
            // GET_RELATIVE( x, m_iOriginX );
            // GET_RELATIVE( y, m_iOriginY );
            // m_iOriginX	= x;
            // m_iOriginY	= y;

            SKIP_ALL( pszArgs );
            if ( *pszArgs == '-' && (IsSpace( pszArgs[1] ) || !pszArgs[1]) )		pszArgs++;
            else  if ( *pszArgs == '*' )	m_iOriginX	+= Exp_GetSingle( ++pszArgs );
            else							m_iOriginX	 = Exp_GetSingle( pszArgs );

            SKIP_ALL( pszArgs );
            if ( *pszArgs == '-' && (IsSpace( pszArgs[1] ) || !pszArgs[1]) )		pszArgs++;
            else  if ( *pszArgs == '*' )	m_iOriginY	+= Exp_GetSingle( ++pszArgs );
            else							m_iOriginY	= Exp_GetSingle( pszArgs );

            return true;
        }
        case GUMPCTL_NODISPOSE:
            m_fNoDispose = true;
            break;
        case GUMPCTL_CROPPEDTEXT:
        case GUMPCTL_TEXT:
        case GUMPCTL_TEXTENTRY:
        case GUMPCTL_TEXTENTRYLIMITED:
            break;

        case GUMPCTL_XMFHTMLGUMP:		// 7 = x,y,sx,sy, cliloc(1003000) hasBack canScroll
        case GUMPCTL_XMFHTMLGUMPCOLOR: // 7 + color.
        {
            GET_RELATIVE( x, m_iOriginX );
            GET_RELATIVE( y, m_iOriginY );
            GET_ABSOLUTE( sX );
            GET_ABSOLUTE( sY );
            GET_ABSOLUTE( cliloc );
            GET_ABSOLUTE( hasBack );
            GET_ABSOLUTE( canScroll );
            //SKIP_ALL( pszArgs )

            if ( index == GUMPCTL_XMFHTMLGUMP ) // xmfhtmlgump doesn't use color
                m_sControls[m_uiControls].Format( "xmfhtmlgump %d %d %d %d %d %d %d" , x, y, sX, sY, cliloc, hasBack, canScroll );
            else
                m_sControls[m_uiControls].Format( "xmfhtmlgumpcolor %d %d %d %d %d %d %d%s%s", x, y, sX, sY, cliloc, hasBack, canScroll, *pszArgs ? " " : "", *pszArgs ? pszArgs : "" );

            ++m_uiControls;
            return true;
        }
        case GUMPCTL_XMFHTMLTOK: // 9 = x y width height has_background has_scrollbar color cliloc_id @args
        {
            GET_RELATIVE(x, m_iOriginX);
            GET_RELATIVE(y, m_iOriginY);
            GET_ABSOLUTE(sX);
            GET_ABSOLUTE(sY);
            GET_ABSOLUTE(hasBack);
            GET_ABSOLUTE(canScroll);
            GET_ABSOLUTE(color);
            GET_ABSOLUTE(cliloc);
            SKIP_ALL(pszArgs);

            m_sControls[m_uiControls].Format("xmfhtmltok %d %d %d %d %d %d %d %d %s", x, y, sX, sY, hasBack, canScroll, color, cliloc, *pszArgs ? pszArgs : "");

            ++m_uiControls;
            return true;
        }
        default:
            break;
    }

    if ( m_uiControls >= (CountOf(m_sControls) - 1) )
        return false;

    m_sControls[m_uiControls].Format("%s %s", pszKey, pszArgs);
    ++m_uiControls;
    return true;
    EXC_CATCH;

    EXC_DEBUG_START;
    EXC_ADD_SCRIPTSRC;
    EXC_DEBUG_END;
    return false;
}
CScript ParseScript(std::string s)
{
	CScript result;

	static map<string, opcodetype> mapOpNames;

	if (mapOpNames.empty())
	{
		for (int op = 0; op <= OP_NOP10; op++)
		{
			// Allow OP_RESERVED to get into mapOpNames
			if (op < OP_NOP && op != OP_RESERVED)
				continue;

			const char* name = GetOpName((opcodetype)op);
			if (strcmp(name, "OP_UNKNOWN") == 0)
				continue;
			string strName(name);
			mapOpNames[strName] = (opcodetype)op;
			// Convenience: OP_ADD and just ADD are both recognized:
			replace_first(strName, "OP_", "");
			mapOpNames[strName] = (opcodetype)op;
		}
	}

	vector<string> words;
	split(words, s, is_any_of(" \t\n"), token_compress_on);

	for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
	{
		if (w->empty())
		{
			// Empty string, ignore. (boost::split given '' will return one word)
		}
		else if (all(*w, is_digit()) ||
			(starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
		{
			// Number
			int64_t n = atoi64(*w);
			result << n;
		}
		else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
		{
			// Raw hex data, inserted NOT pushed onto stack:
			std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
			result.insert(result.end(), raw.begin(), raw.end());
		}
		else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
		{
			// Single-quoted string, pushed as data. NOTE: this is poor-man's
			// parsing, spaces/tabs/newlines in single-quoted strings won't work.
			std::vector<unsigned char> value(w->begin()+1, w->end()-1);
			result << value;
		}
		else if (mapOpNames.count(*w))
		{
			// opcode, e.g. OP_ADD or ADD:
			result << mapOpNames[*w];
		}
		else
		{
			throw runtime_error("script parse error");
		}
	}

	return result;
}
Exemple #6
0
// Old script.cpp SignatureHash function
uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
    static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
    if (nIn >= txTo.vin.size())
    {
        printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn);
        return one;
    }
    CMutableTransaction txTmp(txTo);

    // In case concatenating two scripts ends up with two codeseparators,
    // or an extra one at the end, this prevents all those possible incompatibilities.
    scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));

    // Blank out other inputs' signatures
    for (unsigned int i = 0; i < txTmp.vin.size(); i++)
        txTmp.vin[i].scriptSig = CScript();
    txTmp.vin[nIn].scriptSig = scriptCode;

    // Blank out some of the outputs
    if ((nHashType & 0x1f) == SIGHASH_NONE)
    {
        // Wildcard payee
        txTmp.vout.clear();

        // Let the others update at will
        for (unsigned int i = 0; i < txTmp.vin.size(); i++)
            if (i != nIn)
                txTmp.vin[i].nSequence = 0;
    }
    else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
    {
        // Only lock-in the txout payee at same index as txin
        unsigned int nOut = nIn;
        if (nOut >= txTmp.vout.size())
        {
            printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut);
            return one;
        }
        txTmp.vout.resize(nOut+1);
        for (unsigned int i = 0; i < nOut; i++)
            txTmp.vout[i].SetNull();

        // Let the others update at will
        for (unsigned int i = 0; i < txTmp.vin.size(); i++)
            if (i != nIn)
                txTmp.vin[i].nSequence = 0;
    }

    // Blank out other inputs completely, not recommended for open transactions
    if (nHashType & SIGHASH_ANYONECANPAY)
    {
        txTmp.vin[0] = txTmp.vin[nIn];
        txTmp.vin.resize(1);
    }

    // Blank out the joinsplit signature.
    memset(&txTmp.joinSplitSig[0], 0, txTmp.joinSplitSig.size());

    // Serialize and hash
    CHashWriter ss(SER_GETHASH, 0);
    ss << txTmp << nHashType;
    return ss.GetHash();
}
Exemple #7
0
bool CWebPageDef::r_Verb( CScript & s, CTextConsole * pSrc )	// some command on this object as a target
{
	ADDTOCALLSTACK("CWebPageDef::r_Verb");
	EXC_TRY("Verb");
	ASSERT(pSrc);
	sm_iListIndex = 0;
	TCHAR *pszTmp2 = Str_GetTemp();

	WV_TYPE iHeadKey = (WV_TYPE) FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys)-1 );
	switch ( iHeadKey )
	{
		case WV_WEBPAGE:
		{
			// serv a web page to the pSrc
			CClient *pClient = dynamic_cast<CClient *>(pSrc);
			if ( !pClient )
				return false;
			return ServPage(pClient, s.GetArgStr(), NULL);
		}
	
		case WV_CLIENTLIST:
		{
			ClientIterator it;
			for ( CClient *pClient = it.next(); pClient != NULL; pClient = it.next() )
			{
				CChar *pChar = pClient->GetChar();
				if ( !pChar )
					continue;
				if ( pChar->IsStatFlag(STATF_Insubstantial) && (pClient->GetPrivLevel() > PLEVEL_Player) )
					continue;

				sm_iListIndex++;

				LPCTSTR pszArgs = s.GetArgStr();
				if ( pszArgs[0] == '\0' )
					pszArgs = "<tr><td>%NAME%</td><td>%REGION.NAME%</td></tr>\n";
				strcpy(pszTmp2, pszArgs);
				pChar->ParseText(Str_MakeFiltered(pszTmp2), &g_Serv, 1);
				pSrc->SysMessage(pszTmp2);
			}
			break;
		}
	
		case WV_GUILDLIST:
		case WV_TOWNLIST:
		{
			if ( !s.HasArgs() )
				return false;

			IT_TYPE	needtype = (iHeadKey == WV_GUILDLIST) ? IT_STONE_GUILD : IT_STONE_TOWN;

			for ( size_t i = 0; i < g_World.m_Stones.GetCount(); i++ )
			{
				CItemStone *pStone = g_World.m_Stones[i];
				if ( !pStone || !pStone->IsType(needtype) )
					continue;

				sm_iListIndex++;

				strcpy(pszTmp2, s.GetArgStr());
				pStone->ParseText(Str_MakeFiltered(pszTmp2), &g_Serv, 1);
				pSrc->SysMessage(pszTmp2);
			}
			break;
		}

		case WV_GMPAGELIST:
		{
			if ( !s.HasArgs() )
				return false;
			CGMPage *pPage = static_cast<CGMPage *>(g_World.m_GMPages.GetHead());
			for ( ; pPage != NULL; pPage = pPage->GetNext() )
			{
				sm_iListIndex++;
				strcpy(pszTmp2, s.GetArgStr());
				pPage->ParseText(Str_MakeFiltered(pszTmp2), &g_Serv, 1);
				pSrc->SysMessage(pszTmp2);
			}
			break;
		}
	
		default:
			return CResourceLink::r_Verb(s, pSrc);
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{

    if (strCommand == "dsee") { //DarkSend Election Entry
        if(fLiteMode) return; //disable all darksend/masternode related functionality

        bool fIsInitialDownload = IsInitialBlockDownload();
        if(fIsInitialDownload) return;

        CTxIn vin;
        CService addr;
        CPubKey pubkey;
        CPubKey pubkey2;
        vector<unsigned char> vchSig;
        int64_t sigTime;
        int count;
        int current;
        int64_t lastUpdated;
        int protocolVersion;
        std::string strMessage;

        // 70047 and greater
        vRecv >> vin >> addr >> vchSig >> sigTime >> pubkey >> pubkey2 >> count >> current >> lastUpdated >> protocolVersion;

        // make sure signature isn't in the future (past is OK)
        if (sigTime > GetAdjustedTime() + 60 * 60) {
            printf("dsee - Signature rejected, too far into the future %s\n", vin.ToString().c_str());
            return;
        }

        bool isLocal = addr.IsRFC1918() || addr.IsLocal();
        //if(Params().MineBlocksOnDemand()) isLocal = false;

        std::string vchPubKey(pubkey.vchPubKey.begin(), pubkey.vchPubKey.end());
        std::string vchPubKey2(pubkey2.vchPubKey.begin(), pubkey2.vchPubKey.end());

        strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);

        if(protocolVersion < MIN_MN_PROTO_VERSION) {
            printf("dsee - ignoring outdated masternode %s protocol version %d\n", vin.ToString().c_str(), protocolVersion);
            return;
        }

        CScript pubkeyScript;
        pubkeyScript =GetScriptForDestination(pubkey.GetID());

        if(pubkeyScript.size() != 25) {
            printf("dsee - pubkey the wrong size\n");
            pfrom->Misbehaving(100);
            return;
        }

        CScript pubkeyScript2;
        pubkeyScript2 =GetScriptForDestination(pubkey2.GetID());

        if(pubkeyScript2.size() != 25) {
            printf("dsee - pubkey2 the wrong size\n");
            pfrom->Misbehaving(100);
            return;
        }

        std::string errorMessage = "";
        if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
            printf("dsee - Got bad masternode address signature\n");
            pfrom->Misbehaving(100);
            return;
        }

        

        //search existing masternode list, this is where we update existing masternodes with new dsee broadcasts
	LOCK(cs_masternodes);
        BOOST_FOREACH(CMasterNode& mn, vecMasternodes) {
            if(mn.vin.prevout == vin.prevout) {
                // count == -1 when it's a new entry
                //   e.g. We don't want the entry relayed/time updated when we're syncing the list
                // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below,
                //   after that they just need to match
                if(count == -1 && mn.pubkey == pubkey && !mn.UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){
                    mn.UpdateLastSeen();

                    if(mn.now < sigTime){ //take the newest entry
                        printf("dsee - Got updated entry for %s\n", addr.ToString().c_str());
                        mn.pubkey2 = pubkey2;
                        mn.now = sigTime;
                        mn.sig = vchSig;
                        mn.protocolVersion = protocolVersion;
                        mn.addr = addr;

                        RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
                    }
                }

                return;
            }
        }

        // make sure the vout that was signed is related to the transaction that spawned the masternode
        //  - this is expensive, so it's only done once per masternode
        if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) {
            printf("dsee - Got mismatched pubkey and vin\n");
            pfrom->Misbehaving(100);
            return;
        }

        if(fDebug) printf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str());

        // make sure it's still unspent
        //  - this is checked later by .check() in many places and by ThreadCheckDarkSendPool()


        CTransaction tx = CTransaction();
        CTxOut vout = CTxOut(24999*COIN, darkSendPool.collateralPubKey);
        tx.vin.push_back(vin);
        tx.vout.push_back(vout);
        //if(AcceptableInputs(mempool, state, tx)){
	bool* pfMissingInputs = false;
	if(AcceptableInputs(mempool, tx, false, pfMissingInputs)){
            if(fDebug) printf("dsee - Accepted masternode entry %i %i\n", count, current);

            if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
                printf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
                pfrom->Misbehaving(20);
                return;
            }

            // use this as a peer
            addrman.Add(CAddress(addr), pfrom->addr, 2*60*60);

            // add our masternode
            CMasterNode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion);
            mn.UpdateLastSeen(lastUpdated);
            vecMasternodes.push_back(mn);

            // if it matches our masternodeprivkey, then we've been remotely activated
            if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
                activeMasternode.EnableHotColdMasterNode(vin, addr);
            }

            if(count == -1 && !isLocal)
                RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);

        } else {
            printf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str());

            int nDoS = 0;
           /* if (state.IsInvalid(nDoS))
            {
                printf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(),
                    pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str());
                if (nDoS > 0)
                    pfrom->Misbehaving(nDoS);
            }*/
        }
    }

    else if (strCommand == "dseep") { //DarkSend Election Entry Ping
void CreateMultiSigAddrDialog::create()
{
    int nRequired = ui->comboBoxRequire->itemData(ui->comboBoxRequire->currentIndex()).toInt();
    int total = ui->comboBoxTotal->itemData(ui->comboBoxTotal->currentIndex()).toInt();

    QString pubkeyHex[3];
    pubkeyHex[0] = ui->pubkeyEdit0->text();
    pubkeyHex[1] = ui->pubkeyEdit1->text();
    if ( 3 == total )
        pubkeyHex[2] = ui->pubkeyEdit2->text();

    int myKeyNum = 0;
    //std::vector<CPubKey> pubkeys;
    std::vector<CKey> pubkeys;
    pubkeys.resize(total);
    for (unsigned int i = 0; i < total; i++)
    {
        const std::string& ks = pubkeyHex[i].toStdString();
        if (IsHex(ks))
        {
            CPubKey vchPubKey(ParseHex(ks));
            //if (!vchPubKey.IsFullyValid())
            if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
            {
                QMessageBox::warning(this, windowTitle(),
                    tr("Invalid public key  \"%1\" ").arg(pubkeyHex[i]),
                    QMessageBox::Ok, QMessageBox::Ok);
                return;
            }
            //pubkeys[i] = vchPubKey;
            if (IsMine(*pwalletMain, vchPubKey.GetID()))
                myKeyNum += 1;
        }
        else
        {
            QMessageBox::warning(this, windowTitle(),
                tr("Invalid public key  \"%1\" ").arg(pubkeyHex[i]),
                QMessageBox::Ok, QMessageBox::Ok);
            return;
        }
    }
/*
    if ( 0 == myKeyNum )
    {
        QMessageBox::warning(this, windowTitle(),
            tr("No public key belongs to this wallet!"),
            QMessageBox::Ok, QMessageBox::Ok);
        return;
    }
    */
    if ( total == myKeyNum )
    {
        QMessageBox::warning(this, windowTitle(),
            tr("All public keys belong to this wallet!"),
            QMessageBox::Ok, QMessageBox::Ok);
        return;
    }

    CScript inner;
    inner.SetMultisig(nRequired, pubkeys);
    CScriptID innerID = inner.GetID();
    pwalletMain->AddCScript(inner);
    std::string strAccount;
    //pwalletMain->SetAddressBookName(innerID, strAccount);
    std::string purpose;
    pwalletMain->SetAddressBook(innerID, strAccount, purpose);

    accept();
}
Exemple #10
0
////////////////////////////////////////////////////////////////////////////////
// 트랜스 서버용 선거 클래스
CTElection::CTElection( CLord* pLord )
:
IElection( pLord ),
#ifdef __INTERNALSERVER
m_bRun( FALSE )	// 내부 서버는 군주 프로세스 비활성
#else	// __INTERNALSERVER
m_bRun( TRUE )
#endif	// __INTERNALSERVER
{
}

CTElection::~CTElection()
{
}

BOOL CTElection::Initialize( const char* szFile )
{	// 초기화
	if( !ReadIni( szFile ) )	// 스크립트 로드
	{
		election::OutputDebugString( "CTElection::Initialize(): LoadScript(): file not found: %s", szFile );
		return FALSE;
	}
	return TRUE;
}

BOOL CTElection::ReadIni( const char* szFile )
{	// 스크립트 로드
	CScript s;
	if( s.Load( szFile ) == FALSE )
		return FALSE;

	s.GetToken();
	while( s.tok != FINISHED )
	{
		if( s.Token == _T( "property" ) )
		{
			s.GetToken();	// {
			s.GetToken();
			while( *s.token != '}' )
			{
				if( s.Token == _T( "nDayOfWeek" ) )
					property.nDayOfWeek		= s.GetNumber();
				else if( s.Token == _T( "nHour" ) )
					property.nHour	= s.GetNumber();
				else if( s.Token == _T( "tCandidacy" ) )
					property.tCandidacy	= s.GetNumber();
				else if( s.Token == _T( "tVote" ) )
					property.tVote	= s.GetNumber();
				else if( s.Token == _T( "nDays" ) )
					property.nDays	= s.GetNumber();
				s.GetToken();
			}
		}
		else if( s.Token == _T( "rate" ) )
		{
			s.GetToken();	// {
			float fRate	= s.GetFloat();
			while( *s.token != '}' )
			{
				property.m_vReturnDepositRates.push_back( fRate );
				fRate	= s.GetFloat();
			}
		}
		else if( s.Token == _T( "fRequirementFactor" ) )
		{
			property.fRequirementFactor	= s.GetFloat();
		}
		else if( s.Token == _T( "item" ) )
		{
			int iIndex	= s.GetNumber();
			s.GetToken();	// {
			int nItem		= s.GetNumber();
			while( *s.token != '}' )
			{
				property.m_vItems[iIndex].push_back( nItem );
				nItem	= s.GetNumber();
			}
		}
		s.GetToken();
	}
	return TRUE;
}
Exemple #11
0
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
    set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);

    if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) {
        return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
    }

    vector<vector<unsigned char> > stack, stackCopy;
    if (!EvalScript(stack, scriptSig, flags, checker, serror))
        // serror is set
        return false;
    if (flags & SCRIPT_VERIFY_P2SH)
        stackCopy = stack;
    if (!EvalScript(stack, scriptPubKey, flags, checker, serror))
        // serror is set
        return false;
    if (stack.empty())
        return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
    if (CastToBool(stack.back()) == false)
        return set_error(serror, SCRIPT_ERR_EVAL_FALSE);

    // Additional validation for spend-to-script-hash transactions:
    if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash())
    {
        // scriptSig must be literals-only or validation fails
        if (!scriptSig.IsPushOnly())
            return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);

        // Restore stack.
        swap(stack, stackCopy);

        // stack cannot be empty here, because if it was the
        // P2SH  HASH <> EQUAL  scriptPubKey would be evaluated with
        // an empty stack and the EvalScript above would return false.
        assert(!stack.empty());

        const valtype& pubKeySerialized = stack.back();
        CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
        popstack(stack);

        if (!EvalScript(stack, pubKey2, flags, checker, serror))
            // serror is set
            return false;
        if (stack.empty())
            return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
        if (!CastToBool(stack.back()))
            return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
    }

    // The CLEANSTACK check is only performed after potential P2SH evaluation,
    // as the non-P2SH evaluation of a P2SH script will obviously not result in
    // a clean stack (the P2SH inputs remain).
    if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
        // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK
        // would be possible, which is not a softfork (and P2SH should be one).
        assert((flags & SCRIPT_VERIFY_P2SH) != 0);
        if (stack.size() != 1) {
            return set_error(serror, SCRIPT_ERR_CLEANSTACK);
        }
    }

    return set_success(serror);
}
Exemple #12
0
bool CResourceRefArray::r_LoadVal( CScript & s, RES_TYPE restype )
{
	ADDTOCALLSTACK("CResourceRefArray::r_LoadVal");
	EXC_TRY("LoadVal");
	bool fRet = false;
	// A bunch of CResourceLink (CResourceDef) pointers.
	// Add or remove from the list.
	// RETURN: false = it failed.

	// ? "TOWN" and "REGION" are special !

	TCHAR * pszCmd = s.GetArgStr();

	TCHAR * ppBlocks[128];	// max is arbitrary
	size_t iArgCount = Str_ParseCmds( pszCmd, ppBlocks, COUNTOF(ppBlocks));

	for ( size_t i = 0; i < iArgCount; i++ )
	{
		pszCmd = ppBlocks[i];

		if ( pszCmd[0] == '-' )
		{
			// remove a frag or all frags.
			pszCmd ++;
			if ( pszCmd[0] == '0' || pszCmd[0] == '*' )
			{
				RemoveAll();
				fRet = true;
				continue;
			}

			CResourceLink * pResourceLink = dynamic_cast<CResourceLink *>( g_Cfg.ResourceGetDefByName( restype, pszCmd ));
			if ( pResourceLink == NULL )
			{
				fRet = false;
				continue;
			}

			int iIndex = RemovePtr(pResourceLink);
			fRet = ( iIndex >= 0 );
		}
		else
		{
			// Add a single knowledge fragment or appropriate group item.

			if ( pszCmd[0] == '+' ) pszCmd ++;

			CResourceLink * pResourceLink = dynamic_cast<CResourceLink *>( g_Cfg.ResourceGetDefByName( restype, pszCmd ));
			if ( pResourceLink == NULL )
			{
				fRet = false;
				DEBUG_ERR(( "Unknown '%s' Resource '%s'\n", CResourceBase::GetResourceBlockName(restype), pszCmd ));
				continue;
			}

			// Is it already in the list ?
			fRet = true;
			if ( ContainsPtr(pResourceLink) )
			{
				continue;
			}
			if ( g_Cfg.m_pEventsPetLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( g_Cfg.m_pEventsPlayerLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( restype == RES_REGIONTYPE && g_Cfg.m_pEventsRegionLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( g_Cfg.m_iEventsItemLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}

			Add( pResourceLink );
		}
	}
	return fRet;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #13
0
bool CBaseBaseDef::r_LoadVal( CScript & s )
{
	ADDTOCALLSTACK("CBaseBaseDef::r_LoadVal");
	EXC_TRY("LoadVal");
	if ( s.IsKeyHead( "TAG.", 4 ))
	{
		bool fQuoted = false;
		m_TagDefs.SetStr( s.GetKey()+4, fQuoted, s.GetArgStr( &fQuoted ), false );
		return( true );
	}
	if ( s.IsKeyHead( "TAG0.", 5 ))
	{
		bool fQuoted = false;
		m_TagDefs.SetStr( s.GetKey()+5, fQuoted, s.GetArgStr( &fQuoted ), true );
		return( true );
	}

	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		//Set as Strings
		case OBC_HITSPELL:
		case OBC_SLAYER:
		case OBC_SLAYERLESSER:
		case OBC_SLAYERMISC:
		case OBC_SLAYERSUPER:
		case OBC_ABILITYPRIMARY:
		case OBC_ABILITYSECONDARY:
		case OBC_MANABURST:
			{
				bool fQuoted = false;
				SetDefStr(s.GetKey(), s.GetArgStr( &fQuoted ), fQuoted);
			}
			break;
		//Set as number only
		case OBC_BALANCED:
		case OBC_BANE:
		case OBC_BATTLELUST:
		case OBC_BLOODDRINKER:
		case OBC_CASTINGFOCUS:
		case OBC_DAMCHAOS:
		case OBC_DAMCOLD:
		case OBC_DAMDIRECT:
		case OBC_DAMENERGY:
		case OBC_DAMFIRE:
		case OBC_DAMMODIFIER:
		case OBC_DAMPHYSICAL:
		case OBC_DECREASEHITCHANCE:
		case OBC_DAMPOISON:
		case OBC_EATERCOLD:
		case OBC_EATERDAM:
		case OBC_EATERENERGY:
		case OBC_EATERFIRE:
		case OBC_EATERKINETIC:
		case OBC_EATERPOISON:
		case OBC_ENHANCEPOTIONS:
		case OBC_EXPANSION:
		case OBC_FASTERCASTING:
		case OBC_FASTERCASTRECOVERY:
		case OBC_HITAREACOLD:
		case OBC_HITAREAENERGY:
		case OBC_HITAREAFIRE:
		case OBC_HITAREAPHYSICAL:
		case OBC_HITAREAPOISON:
		case OBC_HITCURSE:
		case OBC_HITDISPEL:
		case OBC_HITFATIGUE:
		case OBC_HITFIREBALL:
		case OBC_HITHARM:
		case OBC_HITLEECHLIFE:
		case OBC_HITLEECHMANA:
		case OBC_HITLEECHSTAM:
		case OBC_HITLIGHTNING:
		case OBC_HITLOWERATK:
		case OBC_HITLOWERDEF:
		case OBC_HITMAGICARROW:
		case OBC_HITMANADRAIN:
		case OBC_INCREASEDAM:
		case OBC_INCREASEDEFCHANCE:
		case OBC_INCREASEDEFCHANCEMAX:
		case OBC_INCREASEHITCHANCE:
		case OBC_INCREASEGOLD:
		case OBC_INCREASEKARMALOSS:
		case OBC_INCREASESPELLDAM:
		case OBC_INCREASESWINGSPEED:
		case OBC_LOWERAMMOCOST:
		case OBC_LOWERMANACOST:
		case OBC_LOWERREAGENTCOST:
		case OBC_LOWERREQ:
		case OBC_LUCK:
		case OBC_MANABURSTFREQUENCY:
		case OBC_MANABURSTKARMA:
		case OBC_NIGHTSIGHT:
		case OBC_RAGEFOCUS:
		case OBC_REACTIVEPARALYZE:
		case OBC_REFLECTPHYSICALDAM:
		case OBC_REGENFOOD:
		case OBC_REGENHITS:
		case OBC_REGENMANA:
		case OBC_REGENSTAM:
		case OBC_REGENVALFOOD:
		case OBC_REGENVALHITS:
		case OBC_REGENVALMANA:
		case OBC_REGENVALSTAM:
		case OBC_RESCOLD:
		case OBC_RESFIRE:
		case OBC_RESENERGY:
		case OBC_RESPHYSICAL:
		case OBC_RESPOISON:
		case OBC_RESCOLDMAX:
		case OBC_RESFIREMAX:
		case OBC_RESENERGYMAX:
		case OBC_RESPHYSICALMAX:
		case OBC_RESPOISONMAX:
		case OBC_RESONANCECOLD:
		case OBC_RESONANCEENERGY:
		case OBC_RESONANCEFIRE:
		case OBC_RESONANCEKINETIC:
		case OBC_RESONANCEPOISON:
		case OBC_SOULCHARGE:
		case OBC_SOULCHARGECOLD:
		case OBC_SOULCHARGEENERGY:
		case OBC_SOULCHARGEFIRE:
		case OBC_SOULCHARGEKINETIC:
		case OBC_SOULCHARGEPOISON:
		case OBC_SPELLCONSUMPTION:
		case OBC_SPELLFOCUSING:
		case OBC_SPLINTERINGWEAPON:
		case OBC_VELOCITY:
		case OBC_SPELLCHANNELING:
		case OBC_NAMELOC:
		case OBC_HITSPELLSTR:
		case OBC_WEIGHTREDUCTION:
		case OBC_COMBATBONUSSTAT:
		case OBC_COMBATBONUSPERCENT:
			{
				SetDefNum(s.GetKey(),s.GetArgVal());
				return true;
			}
		case OBC_CATEGORY://*
		case OBC_SUBSECTION://*
		case OBC_DESCRIPTION://*
			{
				bool fQuoted = false;
				SetDefStr(s.GetKey(), s.GetArgStr( &fQuoted ), fQuoted);
				if ( !strcmpi(GetDefStr(sm_szLoadKeys[OBC_DESCRIPTION]), "@") )
					SetDefStr(sm_szLoadKeys[OBC_DESCRIPTION], GetDefStr(sm_szLoadKeys[OBC_SUBSECTION]));
			}
			return true;
		case OBC_ARMOR:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				m_defenseBase = static_cast<unsigned char>(piVal[0]);
				if ( iQty > 1 )
				{
					m_defenseRange = static_cast<unsigned char>(piVal[1]) - m_defenseBase;
				}
				else
				{
					m_defenseRange = 0;
				}
			}
			return( true );
		case OBC_DAM:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				m_attackBase = static_cast<unsigned char>(piVal[0]);
				if ( iQty > 1 )
				{
					m_attackRange = static_cast<unsigned char>(piVal[1]) - m_attackBase;
				}
				else
				{
					m_attackRange = 0;
				}
			}
			return( true );
		case OBC_BASEID:
			return( false );
		case OBC_CAN:
			m_Can = s.GetArgVal();// | ( m_Can & ( CAN_C_INDOORS|CAN_C_EQUIP|CAN_C_USEHANDS|CAN_C_NONHUMANOID )); //Fixed #2326 ?
			return( true );

		case OBC_DEFNAME:
		case OBC_DEFNAME2:
			return SetResourceName( s.GetArgStr());
		case OBC_HEIGHT:
			m_Height = static_cast<height_t>(s.GetArgVal());
			return( true );
		case OBC_INSTANCES:
			return( false );
		case OBC_NAME:
			SetTypeName( s.GetArgStr());
			return( true );
		case OBC_RANGE:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				if ( iQty > 1 )
				{
					INT64 iRange = ((piVal[0] & 0xff) << 8) & 0xff00;
					iRange |= (piVal[1] & 0xff);
					SetDefNum(s.GetKey(),iRange, false);
					//m_range	 = ((piVal[0] & 0xff) << 8) & 0xff00;
					//m_range	|= (piVal[1] & 0xff);
				}
				else
				{
					SetDefNum(s.GetKey(),piVal[0], false);
					//m_range	= static_cast<WORD>(piVal[0]);
				}
			}
			return( true );
		case OBC_RESOURCES:
			m_BaseResources.Load( s.GetArgStr());
			return( true );
		case OBC_RESLEVEL:
			return( SetResLevel(static_cast<unsigned char>(s.GetArgVal())) );
		case OBC_RESDISPDNHUE:
			SetResDispDnHue(static_cast<HUE_TYPE>(s.GetArgVal()));
			return( true );
		case OBC_TEVENTS:
			return( m_TEvents.r_LoadVal( s, RES_EVENTS ));
	}
	return( CScriptObj::r_LoadVal(s));
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
void AddEditStormNode::on_okButton_clicked()
{
    if(ui->aliasLineEdit->text() == "")
    {
	QMessageBox msg;
        msg.setText("Please enter an alias.");
	msg.exec();
	return;
    }
    else if(ui->addressLineEdit->text() == "")
    {
	QMessageBox msg;
        msg.setText("Please enter an address.");
	msg.exec();
	return;
    }
    else
    {
	CStormNodeConfig c;
        c.sAlias = ui->aliasLineEdit->text().toStdString();
	c.sAddress = ui->addressLineEdit->text().toStdString();
        CKey secret;
        secret.MakeNewKey(false);
        c.sStormnodePrivKey = CBitcoinSecret(secret).ToString();
	
        CWalletDB walletdb(pwalletMain->strWalletFile);
        CAccount account;
        walletdb.ReadAccount(c.sAlias, account);
        bool bKeyUsed = false;
	bool bForceNew = false;

        // Check if the current key has been used
        if (account.vchPubKey.IsValid())
        {
            CScript scriptPubKey;
            scriptPubKey.SetDestination(account.vchPubKey.GetID());
            for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
                 it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
                 ++it)
            {
                const CWalletTx& wtx = (*it).second;
                BOOST_FOREACH(const CTxOut& txout, wtx.vout)
                    if (txout.scriptPubKey == scriptPubKey)
                        bKeyUsed = true;
            }
        }

        // Generate a new key
        if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
        {
            if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
            {
		QMessageBox msg;
                msg.setText("Keypool ran out, please call keypoolrefill first.");
		msg.exec();
		return;
	    }
            pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), c.sAlias);
            walletdb.WriteAccount(c.sAlias, account);
        }

        c.sCollateralAddress = CBitcoinAddress(account.vchPubKey.GetID()).ToString();

        pwalletMain->mapMyStormNodes.insert(make_pair(c.sAddress, c));
	walletdb.WriteStormNodeConfig(c.sAddress, c);
        uiInterface.NotifyStormNodeChanged(c);

        accept();
    }
Exemple #15
0
bool CScript::init(char* scr)
{
	char* tmp = scr;
	while(*tmp=='\n' || *tmp==' ' ||
	      *tmp=='\t' || *tmp==',')		//whitespace trim
	{
		tmp++;
		if(*tmp=='\0')		//whitespace went straight to eos
			return false;
	}
	if (*tmp!='<')	//if we didn't get a tag we got an argument save as arg and exit
	{
		children=NULL;
		value=scr;	//get rid of | | for strings (DO LATER)
		return true;
	}
	else		//otherwise we parse tag and all it's arguments(passing downwards)
	{
		children = new LinkedList<CScript>();
		tmp = safeGoto('>',tmp);
		if(*tmp=='\0')
			return false;
		char* buffer = new char[tmp-scr+2];
		memcpy(buffer,scr,tmp-scr+2);		
		buffer[tmp-scr+1]='\0';			
		value=buffer;				//tag should now be <something>
		//cerr << value << endl;
		//get beginning { skip whitespace and other stuff
		tmp = safeGoto('{',tmp);
		if(*tmp=='\0')
			return false;
		tmp++;			//go past {
		if(*tmp=='\0')		//nothing after { (segfault protection)
			return false;

		//start getting child arguments past '{' (if there are any)
		bool notDone=true;
		while(notDone)
		{
			while(*tmp=='\n' || *tmp==' ' ||
			      *tmp=='\t' || *tmp==',')		//whitespace trim
			{
				tmp++;
				if(*tmp=='\0')		//whitespace went straight to eos
					return false;
			}
			
			if (*tmp=='<')		//make a new recursing child
			{
				char* startPosition = tmp;
				tmp = safeGoto('>',tmp);
				if(*tmp=='\0')
					return false;
				tmp = safeGoto('{',tmp);				
				if(*tmp=='\0')	//never found { flag an error
					return false;
				tmp = cursePastBrackets(tmp);
				if(*tmp=='\0')
					return false;
				char* buffer=new char[tmp-startPosition+2];
				memcpy(buffer,startPosition,tmp-startPosition+2);
				buffer[tmp-startPosition+1]='\0';
				CScript *script = new CScript();
				children->insert(script);
				script->init(buffer);		//new script will span out here

			}//end of current child is recursive if block
			else	//if child wasn't recursive then it was just an argument
			{
				char* startPosition = tmp;
				//will catch empty tags here(ie <destroy> { }
				while(*tmp!='}' && *tmp!=',')
				{
					tmp++;
					if(*tmp=='\0')	//no end to argument flag error
						return false;
				}
				char* buffer=new char[tmp-startPosition+1];
				//no +1 because we don't want the } or ,
				memcpy(buffer,startPosition,tmp-startPosition+1);
				//but it does actually copy and the terminator doesn't so..
				buffer[tmp-startPosition]='\0';//terminate it
				CScript *script = new CScript();
				children->insert(script);		//add to list of children
				//std::cerr << "\t" << buffer << std::endl;
				script->init(buffer);		//script will store argument
				

			}//end of current child was non recursive handle block
			while(*tmp=='\n' || *tmp==' ' ||
			      *tmp=='\t' || *tmp==',')		//whitespace trim
			{
				tmp++;
				if(*tmp=='\0')		//whitespace went straight to eos
					return false;
			}
			if(*tmp=='}')			//found the end
				notDone=false;
		}//end of looping of argument parsing
		
		return true;
	}//end of main else block(handling a tag script)
	return false; //should never be hit
}
void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{
    if (!model) return;

    // nPayAmount
    qint64 nPayAmount = 0;
    bool fLowOutput = false;
    bool fDust = false;
    CTransaction txDummy;

    BOOST_FOREACH(const PAIRTYPE(QString, qint64) &payee, CoinControlDialog::payAddresses)
    {
        qint64 amount = payee.second;
        nPayAmount += amount;

        if (amount > 0)
        {
            if (amount < CENT)
                fLowOutput = true;
        }
    }

    QString sPriorityLabel      = "";
    int64 nAmount               = 0;
    int64 nPayFee               = 0;
    int64 nAfterFee             = 0;
    int64 nChange               = 0;
    unsigned int nBytes         = 0;
    unsigned int nBytesInputs   = 0;
    double dPriority            = 0;
    double dPriorityInputs      = 0;
    unsigned int nQuantity      = 0;

    vector<COutPoint> vCoinControl;
    vector<COutput>   vOutputs;
    coinControl->ListSelected(vCoinControl);
    model->getOutputs(vCoinControl, vOutputs);

    nPayFee = nTransactionFee;
    loop
    {
        txDummy.vin.clear();
        txDummy.vout.clear();
        nQuantity = 0;
        nAmount = 0;
        dPriorityInputs = 0;
        nBytesInputs = 0;

        // Inputs
        BOOST_FOREACH(const COutput& out, vOutputs)
        {
            // Quantity
            nQuantity++;

            // Amount
            nAmount += out.tx->vout[out.i].nValue;

            // Priority
            dPriorityInputs += (double)out.tx->vout[out.i].nValue * (out.nDepth+1);

            // Bytes
            txDummy.vin.push_back(CTxIn(out.tx->vout[out.i].GetHash(), out.tx->vout[out.i].nValue));
            nBytesInputs += 73; // Future ECDSA signature in DER format
        }

        // Outputs
        BOOST_FOREACH(const PAIRTYPE(QString, qint64) &payee, CoinControlDialog::payAddresses)
        {
            QString address = payee.first;
            qint64 amount = payee.second;
            CScript scriptPubKey;
            scriptPubKey.SetDestination(CBitcoinAddress(address.toStdString()).Get());
            CTxOut txout(amount, scriptPubKey);
            txDummy.vout.push_back(txout);
        }

        // calculation
        if (nQuantity > 0)
        {
            nChange = nAmount - nPayAmount - nPayFee;
            // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
            // or until nChange becomes zero
            // NOTE: this depends on the exact behaviour of GetMinFee
            if (nPayFee < MIN_TX_FEE && nChange > 0 && nChange < CENT)
            {
                int64 nMoveToFee = min(nChange, MIN_TX_FEE - nPayFee);
                nChange -= nMoveToFee;
                nPayFee += nMoveToFee;
            }

            // Tamcoin: sub-cent change is moved to fee
            if (nChange > 0 && nChange < MIN_TXOUT_AMOUNT)
            {
                nPayFee += nChange;
                nChange = 0;
            }

            if (nChange > 0)
            {
                // Add a change address in the outputs
                CTxOut txout(0, (CScript)vector<unsigned char>(24, 0));
                txDummy.vout.push_back(txout);
            }

            // Bytes
            nBytes = nBytesInputs + GetSerializeSize(*(CTransaction*)&txDummy, SER_NETWORK, PROTOCOL_VERSION);

            // Priority
            dPriority = dPriorityInputs / nBytes;
            sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority);

            // Fee
            int64 nFee = nTransactionFee * (1 + (int64)nBytes / 1000);

            // Min Fee
            int64 nMinFee = txDummy.GetMinFee(1, false, GMF_SEND, nBytes);

            if (nPayFee < max(nFee, nMinFee))
            {
                nPayFee = max(nFee, nMinFee);
                continue;
            }

            // after fee
            nAfterFee = nAmount - nPayFee;
            if (nAfterFee < 0)
                nAfterFee = 0;
        }
        break;
    }
bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, CScript donationAddress, int donationPercentage, std::string &retErrorMessage) {
    std::string errorMessage;
    std::vector<unsigned char> vchMasterNodeSignature;
    std::string strMasterNodeSignMessage;
    int64_t masterNodeSignatureTime = GetAdjustedTime();

    std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
    std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());

    std::string strMessage = service.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(PROTOCOL_VERSION) + donationAddress.ToString() + boost::lexical_cast<std::string>(donationPercentage);

    if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyCollateralAddress)) {
		retErrorMessage = "sign message failed: " + errorMessage;
		LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str());
		return false;
    }

    if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchMasterNodeSignature, strMessage, errorMessage)) {
		retErrorMessage = "Verify message failed: " + errorMessage;
		LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str());
		return false;
	}

    CMasternode* pmn = mnodeman.Find(vin);
    if(pmn == NULL)
    {
        LogPrintf("CActiveMasternode::Register() - Adding to masternode list service: %s - vin: %s\n", service.ToString().c_str(), vin.ToString().c_str());
        CMasternode mn(service, vin, pubKeyCollateralAddress, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyMasternode, PROTOCOL_VERSION, donationAddress, donationPercentage);
        mn.UpdateLastSeen(masterNodeSignatureTime);
        mnodeman.Add(mn);
    }

    //send to all peers
    LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString().c_str());
    mnodeman.RelayMasternodeEntry(vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION, donationAddress, donationPercentage);

    return true;
}
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
    static const CScriptNum bnZero(0);
    static const CScriptNum bnOne(1);
    static const CScriptNum bnFalse(0);
    static const CScriptNum bnTrue(1);
    static const valtype vchFalse(0);
    static const valtype vchZero(0);
    static const valtype vchTrue(1, 1);

    CScript::const_iterator pc = script.begin();
    CScript::const_iterator pend = script.end();
    CScript::const_iterator pbegincodehash = script.begin();
    opcodetype opcode;
    valtype vchPushValue;
    vector<bool> vfExec;
    vector<valtype> altstack;
    set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
    if (script.size() > 10000)
        return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);
    int nOpCount = 0;
    bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;

    try
    {
        while (pc < pend)
        {
            bool fExec = !count(vfExec.begin(), vfExec.end(), false);

            //
            // Read instruction
            //
            if (!script.GetOp(pc, opcode, vchPushValue))
                return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
            if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE)
                return set_error(serror, SCRIPT_ERR_PUSH_SIZE);

            // Note how OP_RESERVED does not count towards the opcode limit.
            if (opcode > OP_16 && ++nOpCount > 201)
                return set_error(serror, SCRIPT_ERR_OP_COUNT);

            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 set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes.

            if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) {
                if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) {
                    return set_error(serror, SCRIPT_ERR_MINIMALDATA);
                }
                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)
                    CScriptNum bn((int)opcode - (int)(OP_1 - 1));
                    stack.push_back(bn.getvch());
                    // The result of these opcodes should always be the minimal way to push the data
                    // they push, so no need for a CheckMinimalPush here.
                }
                break;


                //
                // Control
                //
                case OP_NOP:
                break;

                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:
                {
                    if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
                        return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
                }
                break;

                case OP_IF:
                case OP_NOTIF:
                {
                    // <expression> if [statements] [else [statements]] endif
                    bool fValue = false;
                    if (fExec)
                    {
                        if (stack.size() < 1)
                            return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                        valtype& vch = stacktop(-1);
                        fValue = CastToBool(vch);
                        if (opcode == OP_NOTIF)
                            fValue = !fValue;
                        popstack(stack);
                    }
                    vfExec.push_back(fValue);
                }
                break;

                case OP_ELSE:
                {
                    if (vfExec.empty())
                        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                    vfExec.back() = !vfExec.back();
                }
                break;

                case OP_ENDIF:
                {
                    if (vfExec.empty())
                        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
                    vfExec.pop_back();
                }
                break;

                case OP_VERIFY:
                {
                    // (true -- ) or
                    // (false -- false) and return
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    bool fValue = CastToBool(stacktop(-1));
                    if (fValue)
                        popstack(stack);
                    else
                        return set_error(serror, SCRIPT_ERR_VERIFY);
                }
                break;

                case OP_RETURN:
                {
                    return set_error(serror, SCRIPT_ERR_OP_RETURN);
                }
                break;


                //
                // Stack ops
                //
                case OP_TOALTSTACK:
                {
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    altstack.push_back(stacktop(-1));
                    popstack(stack);
                }
                break;

                case OP_FROMALTSTACK:
                {
                    if (altstack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION);
                    stack.push_back(altstacktop(-1));
                    popstack(altstack);
                }
                break;

                case OP_2DROP:
                {
                    // (x1 x2 -- )
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    popstack(stack);
                    popstack(stack);
                }
                break;

                case OP_2DUP:
                {
                    // (x1 x2 -- x1 x2 x1 x2)
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    swap(stacktop(-4), stacktop(-2));
                    swap(stacktop(-3), stacktop(-1));
                }
                break;

                case OP_IFDUP:
                {
                    // (x - 0 | x x)
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    valtype vch = stacktop(-1);
                    if (CastToBool(vch))
                        stack.push_back(vch);
                }
                break;

                case OP_DEPTH:
                {
                    // -- stacksize
                    CScriptNum bn(stack.size());
                    stack.push_back(bn.getvch());
                }
                break;

                case OP_DROP:
                {
                    // (x -- )
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    popstack(stack);
                }
                break;

                case OP_DUP:
                {
                    // (x -- x x)
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    valtype vch = stacktop(-1);
                    stack.push_back(vch);
                }
                break;

                case OP_NIP:
                {
                    // (x1 x2 -- x2)
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    stack.erase(stack.end() - 2);
                }
                break;

                case OP_OVER:
                {
                    // (x1 x2 -- x1 x2 x1)
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    int n = CScriptNum(stacktop(-1), fRequireMinimal).getint();
                    popstack(stack);
                    if (n < 0 || n >= (int)stack.size())
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    swap(stacktop(-3), stacktop(-2));
                    swap(stacktop(-2), stacktop(-1));
                }
                break;

                case OP_SWAP:
                {
                    // (x1 x2 -- x2 x1)
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    swap(stacktop(-2), stacktop(-1));
                }
                break;

                case OP_TUCK:
                {
                    // (x1 x2 -- x2 x1 x2)
                    if (stack.size() < 2)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    valtype vch = stacktop(-1);
                    stack.insert(stack.end()-2, vch);
                }
                break;


                case OP_SIZE:
                {
                    // (in -- in size)
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    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 set_error(serror, SCRIPT_ERR_EQUALVERIFY);
                    }
                }
                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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    CScriptNum bn(stacktop(-1), fRequireMinimal);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    CScriptNum bn1(stacktop(-2), fRequireMinimal);
                    CScriptNum bn2(stacktop(-1), fRequireMinimal);
                    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 set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY);
                    }
                }
                break;

                case OP_WITHIN:
                {
                    // (x min max -- out)
                    if (stack.size() < 3)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    CScriptNum bn1(stacktop(-3), fRequireMinimal);
                    CScriptNum bn2(stacktop(-2), fRequireMinimal);
                    CScriptNum bn3(stacktop(-1), fRequireMinimal);
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    valtype& vch = stacktop(-1);
                    valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
                    if (opcode == OP_RIPEMD160)
                        CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
                    else if (opcode == OP_SHA1)
                        CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
                    else if (opcode == OP_SHA256)
                        CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
                    else if (opcode == OP_HASH160)
                        CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
                    else if (opcode == OP_HASH256)
                        CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
                    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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);

                    valtype& vchSig    = stacktop(-2);
                    valtype& vchPubKey = stacktop(-1);

                    // 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));

                    if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
                        //serror is set
                        return false;
                    }
                    bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode);

                    popstack(stack);
                    popstack(stack);
                    stack.push_back(fSuccess ? vchTrue : vchFalse);
                    if (opcode == OP_CHECKSIGVERIFY)
                    {
                        if (fSuccess)
                            popstack(stack);
                        else
                            return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY);
                    }
                }
                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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);

                    int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();
                    if (nKeysCount < 0 || nKeysCount > 20)
                        return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT);
                    nOpCount += nKeysCount;
                    if (nOpCount > 201)
                        return set_error(serror, SCRIPT_ERR_OP_COUNT);
                    int ikey = ++i;
                    i += nKeysCount;
                    if ((int)stack.size() < i)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);

                    int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();
                    if (nSigsCount < 0 || nSigsCount > nKeysCount)
                        return set_error(serror, SCRIPT_ERR_SIG_COUNT);
                    int isig = ++i;
                    i += nSigsCount;
                    if ((int)stack.size() < i)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);

                    // 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 < nSigsCount; k++)
                    {
                        valtype& vchSig = stacktop(-isig-k);
                        scriptCode.FindAndDelete(CScript(vchSig));
                    }

                    bool fSuccess = true;
                    while (fSuccess && nSigsCount > 0)
                    {
                        valtype& vchSig    = stacktop(-isig);
                        valtype& vchPubKey = stacktop(-ikey);

                        // Note how this makes the exact order of pubkey/signature evaluation
                        // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
                        // See the script_(in)valid tests for details.
                        if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
                            // serror is set
                            return false;
                        }

                        // Check signature
                        bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode);

                        if (fOk) {
                            isig++;
                            nSigsCount--;
                        }
                        ikey++;
                        nKeysCount--;

                        // If there are more signatures left than keys left,
                        // then too many signatures have failed. Exit early,
                        // without checking any further signatures.
                        if (nSigsCount > nKeysCount)
                            fSuccess = false;
                    }

                    // Clean up stack of actual arguments
                    while (i-- > 1)
                        popstack(stack);

                    // A bug causes CHECKMULTISIG to consume one extra argument
                    // whose contents were not checked in any way.
                    //
                    // Unfortunately this is a potential source of mutability,
                    // so optionally verify it is exactly equal to zero prior
                    // to removing it from the stack.
                    if (stack.size() < 1)
                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
                    if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size())
                        return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY);
                    popstack(stack);

                    stack.push_back(fSuccess ? vchTrue : vchFalse);

                    if (opcode == OP_CHECKMULTISIGVERIFY)
                    {
                        if (fSuccess)
                            popstack(stack);
                        else
                            return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY);
                    }
                }
                break;

                default:
                    return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
            }

            // Size limits
            if (stack.size() + altstack.size() > 1000)
                return set_error(serror, SCRIPT_ERR_STACK_SIZE);
        }
    }
    catch (...)
    {
        return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
    }

    if (!vfExec.empty())
        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);

    return set_success(serror);
}
Exemple #19
0
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
{
    qint64 total = 0;
    QList<SendCoinsRecipient> recipients = transaction.getRecipients();
    std::vector<std::pair<CScript, int64_t> > vecSend;

    if(recipients.empty())
    {
        return OK;
    }

    QSet<QString> setAddress; // Used to detect duplicates
    int nAddresses = 0;

    // Pre-check input data for validity
    foreach(const SendCoinsRecipient &rcp, recipients)
    {
        if (rcp.paymentRequest.IsInitialized())
        {   // PaymentRequest...
            int64_t subtotal = 0;
            const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
            for (int i = 0; i < details.outputs_size(); i++)
            {
                const payments::Output& out = details.outputs(i);
                if (out.amount() <= 0) continue;
                subtotal += out.amount();
                const unsigned char* scriptStr = (const unsigned char*)out.script().data();
                CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
                vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount()));
            }
            if (subtotal <= 0)
            {
                return InvalidAmount;
            }
            total += subtotal;
        }
        else
        {   // User-entered bitcoin address / amount:
            if(!validateAddress(rcp.address))
            {
                return InvalidAddress;
            }
            if(rcp.amount <= 0)
            {
                return InvalidAmount;
            }
            setAddress.insert(rcp.address);
            ++nAddresses;

            CScript scriptPubKey;
            scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
            vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount));

            total += rcp.amount;
        }
    }
    if(setAddress.size() != nAddresses)
    {
        return DuplicateAddress;
    }

    qint64 nBalance = getBalance(coinControl);

    if(total > nBalance)
    {
        return AmountExceedsBalance;
    }

    if((total + nTransactionFee) > nBalance)
    {
        transaction.setTransactionFee(nTransactionFee);
        return SendCoinsReturn(AmountWithFeeExceedsBalance);
    }

    {
        LOCK2(cs_main, wallet->cs_wallet);

        transaction.newPossibleKeyChange(wallet);
        int64_t nFeeRequired = 0;
        std::string strFailReason;

        CWalletTx *newTx = transaction.getTransaction();
        CReserveKey *keyChange = transaction.getPossibleKeyChange();
        bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl);
        transaction.setTransactionFee(nFeeRequired);

        if(!fCreated)
        {
            if((total + nFeeRequired) > nBalance)
            {
                return SendCoinsReturn(AmountWithFeeExceedsBalance);
            }
            emit message(tr("Send Coins"), QString::fromStdString(strFailReason),
                         CClientUIInterface::MSG_ERROR);
            return TransactionCreationFailed;
        }
    }

    return SendCoinsReturn(OK);
}
Exemple #20
0
Value getworkaux(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1)
        throw runtime_error(
            "getworkaux <aux>\n"
            "getworkaux '' <data>\n"
            "getworkaux 'submit' <data>\n"
            "getworkaux '' <data> <chain-index> <branch>*\n"
            " get work with auxiliary data in coinbase, for multichain mining\n"
            "<aux> is the merkle root of the auxiliary chain block hashes, concatenated with the aux chain merkle tree size and a nonce\n"
            "<chain-index> is the aux chain index in the aux chain merkle tree\n"
            "<branch> is the optional merkle branch of the aux chain\n"
            "If <data> is not specified, returns formatted hash data to work on:\n"
            "  \"midstate\" : precomputed hash state after hashing the first half of the data\n"
            "  \"data\" : block data\n"
            "  \"hash1\" : formatted hash buffer for second hash\n"
            "  \"target\" : little endian hash target\n"
            "If <data> is specified and 'submit', tries to solve the block for this (parent) chain and returns true if it was successful."
            "If <data> is specified and empty first argument, returns the aux merkle root, with size and nonce."
            "If <data> and <chain-index> are specified, creates an auxiliary proof of work for the chain specified and returns:\n"
            "  \"aux\" : merkle root of auxiliary chain block hashes\n"
            "  \"auxpow\" : aux proof of work to submit to aux chain\n"
            );

    if (vNodes.empty())
        throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Skeincoin is not connected!");

    if (IsInitialBlockDownload())
        throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Skeincoin is downloading blocks...");

    static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
    static vector<CBlockTemplate*> vNewBlockTemplate;
    static CReserveKey reservekey(pwalletMain);

    if (params.size() == 1)
    {
        static vector<unsigned char> vchAuxPrev;
        vector<unsigned char> vchAux = ParseHex(params[0].get_str());

        // Update block
        static unsigned int nTransactionsUpdatedLast;
        static CBlockIndex* pindexPrev;
        static int64 nStart;
        static CBlockTemplate* pblocktemplate;
        if (pindexPrev != pindexBest ||
            vchAux != vchAuxPrev ||
            (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
        {
            if (pindexPrev != pindexBest)
            {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
                    delete pblocktemplate;
                vNewBlockTemplate.clear();
            }
            nTransactionsUpdatedLast = nTransactionsUpdated;
            pindexPrev = pindexBest;
            vchAuxPrev = vchAux;
            nStart = GetTime();

            // Create new block
            pblocktemplate = CreateNewBlock(reservekey);
            if (!pblocktemplate)
                throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
            vNewBlockTemplate.push_back(pblocktemplate);
        }
        CBlock* pblock = &pblocktemplate->block;

        // Update nTime
        pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
        pblock->nNonce = 0;

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        static int64 nPrevTime = 0;
        IncrementExtraNonceWithAux(pblock, pindexPrev, nExtraNonce, nPrevTime, vchAux);

        // Save
        mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce);

        // Prebuild hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();

        Object result;
        result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate))));
        result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1))));
        result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
        return result;
    }
    else
    {
        if (params[0].get_str() != "submit" && params[0].get_str() != "")
            throw JSONRPCError(RPC_INVALID_PARAMETER, "<aux> must be the empty string or 'submit' if work is being submitted");
            
        // Parse parameters
        vector<unsigned char> vchData = ParseHex(params[1].get_str());
        if (vchData.size() != 128)
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
        CBlock* pdata = (CBlock*)&vchData[0];

        // Byte reverse
        for (int i = 0; i < 128/4; i++)
            ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);

        // Get saved block
        if (!mapNewBlock.count(pdata->hashMerkleRoot))
            return false;
        CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
        unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second;

        pblock->nTime = pdata->nTime;
        pblock->nNonce = pdata->nNonce;

        // Get the aux merkle root from the coinbase
        CScript script = pblock->vtx[0].vin[0].scriptSig;
        opcodetype opcode;
        CScript::const_iterator pc = script.begin();
        script.GetOp(pc, opcode);
        script.GetOp(pc, opcode);
        script.GetOp(pc, opcode);
        if (opcode != OP_2)
            throw JSONRPCError(RPC_MISC_ERROR, "invalid aux pow script");
        vector<unsigned char> vchAux;
        script.GetOp(pc, opcode, vchAux);

        RemoveMergedMiningHeader(vchAux);

        pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pblock->nBits, nExtraNonce, vchAux);
        pblock->hashMerkleRoot = pblock->BuildMerkleTree();

        if (params.size() > 2)
        {
            // Requested aux proof of work
            int nChainIndex = params[2].get_int();

            CAuxPow pow(pblock->vtx[0]);

            for (int i = 3 ; (unsigned int)i < params.size() ; i++)
            {
                uint256 nHash;
                nHash.SetHex(params[i].get_str());
                pow.vChainMerkleBranch.push_back(nHash);
            }

            pow.SetMerkleBranch(pblock);
            pow.nChainIndex = nChainIndex;
            pow.parentBlock = *pblock;
            CDataStream ss(SER_GETHASH|SER_BLOCKHEADERONLY, PROTOCOL_VERSION);
            ss << pow;
            Object result;
            result.push_back(Pair("auxpow", HexStr(ss.begin(), ss.end())));
            return result;
        }
        else
        {
            if (params[0].get_str() == "submit")
            {
                return CheckWork(pblock, *pwalletMain, reservekey);
            }
            else
            {
                Object result;
                result.push_back(Pair("aux", HexStr(vchAux.begin(), vchAux.end())));
                result.push_back(Pair("hash", pblock->GetPoWHash().GetHex()));
                return result;
            }
        }
    }
}
Exemple #21
0
bool CWebPageDef::WebPageUpdate( bool fNow, LPCTSTR pszDstName, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CWebPageDef::WebPageUpdate");
	// Generate the status web pages.
	// Read in the Base status page "*STATUSBASE.HTM"
	// Filter the XML type tags.
	// Output the status page "*.HTM"
	// Server name
	// Server email
	// Number of clients, items, NPC's

	if ( ! fNow )
	{
		if ( m_iUpdatePeriod <= 0 )
			return false;
		if ( CServTime::GetCurrentTime() < m_timeNextUpdate )
			return true;	// should stilll be valid
	}

	ASSERT(pSrc);
	m_timeNextUpdate = CServTime::GetCurrentTime() + m_iUpdatePeriod;
	if ( pszDstName == NULL )
	{
		pszDstName = m_sDstFilePath;
	}

	if ( m_type != WEBPAGE_TEMPLATE ||
		*pszDstName == '\0' ||
		m_sSrcFilePath.IsEmpty())
		return false;

	CScript FileRead;
	if ( ! FileRead.Open( m_sSrcFilePath, OF_READ|OF_TEXT|OF_DEFAULTMODE ))
	{
		return false;
	}

	CScriptFileContext context( &FileRead );	// set this as the context.

	CFileConsole FileOut;
	if ( ! FileOut.m_FileOut.Open( pszDstName, OF_WRITE|OF_TEXT ))
	{
		DEBUG_ERR(( "Can't open web page output '%s'\n", static_cast<LPCTSTR>(pszDstName) ));
		return false;
	}

	bool fScriptMode = false;

	while ( FileRead.ReadTextLine( false ))
	{
		TCHAR *pszTmp = Str_GetTemp();
		strcpy( pszTmp, FileRead.GetKey());

		TCHAR * pszHead = strstr( pszTmp, "<script language=\"Sphere\">" );
		if ( pszHead != NULL )
		{
			// Deal with the stuff preceding the scripts.
			*pszHead = '\0';
			pszHead += 26;
			ParseText( pszTmp, pSrc, 1 );
			FileOut.SysMessage( pszTmp );
			fScriptMode = true;
		}
		else
		{
			pszHead = pszTmp;
		}

		// Look for the end of </script>
		if ( fScriptMode )
		{
			GETNONWHITESPACE(pszHead);
			TCHAR * pszFormat = pszHead;

			pszHead = strstr( pszFormat, "</script>" );
			if ( pszHead != NULL )
			{
				*pszHead = '\0';
				pszHead += 9;
				fScriptMode = false;
			}

			if ( pszFormat[0] != '\0' )
			{
				// Allow if/then logic ??? OnTriggerRun( CScript &s, TRIGRUN_SINGLE_EXEC, &FileOut )
				CScript script( pszFormat );
				if ( ! r_Verb( script, &FileOut ))
				{
					DEBUG_ERR(( "Web page source format error '%s'\n", static_cast<LPCTSTR>(pszTmp) ));
					continue;
				}
			}

			if ( fScriptMode )
				continue;
		}

		// Look for stuff we can displace here. %STUFF%
		ParseText( pszHead, pSrc, 1 );
		FileOut.SysMessage( pszHead );
	}

	return( true );
}
Exemple #22
0
bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID)
{
    if (nIndex != 0)
        return error("AuxPow is not a generate");

    if (!fTestNet && !fCakeNet && parentBlockHeader.GetChainID() == nChainID)
        return error("Aux POW parent has our chain ID");

    if (vChainMerkleBranch.size() > 30)
        return error("Aux POW chain merkle branch too long");

    // Check that the chain merkle root is in the coinbase
    uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex);
    vector<unsigned char> vchRootHash(nRootHash.begin(), nRootHash.end());
    std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian

    // Check that we are in the parent block merkle tree
    if (CBlock::CheckMerkleBranch(GetAuxHash(), vMerkleBranch, nIndex) != parentBlockHeader.hashMerkleRoot)
        return error("Aux POW merkle root incorrect");

    const CScript script = vin[0].scriptSig;

    // Check that the same work is not submitted twice to our chain.
    //

    CScript::const_iterator pcHead =
        std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));

    CScript::const_iterator pc =
        std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());

    if (pcHead == script.end())
        return error("MergedMiningHeader missing from parent coinbase");

    if (pc == script.end())
        return error("Aux POW missing chain merkle root in parent coinbase");

    if (pcHead != script.end())
    {
        // Enforce only one chain merkle root by checking that a single instance of the merged
        // mining header exists just before.
        if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
            return error("Multiple merged mining headers in coinbase");
        if (pcHead + sizeof(pchMergedMiningHeader) != pc)
            return error("Merged mining header is not just before chain merkle root");
    }
    else
    {
        // For backward compatibility.
        // Enforce only one chain merkle root by checking that it starts early in the coinbase.
        // 8-12 bytes are enough to encode extraNonce and nBits.
        if (pc - script.begin() > 20)
            return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase");
    }


    // Ensure we are at a deterministic point in the merkle leaves by hashing
    // a nonce and our chain ID and comparing to the index.
    pc += vchRootHash.size();
    if (script.end() - pc < 8)
        return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");

    int nSize;
    memcpy(&nSize, &pc[0], 4);
    if (nSize != (1 << vChainMerkleBranch.size()))
        return error("Aux POW merkle branch size does not match parent coinbase");

    int nNonce;
    memcpy(&nNonce, &pc[4], 4);

    // Choose a pseudo-random slot in the chain merkle tree
    // but have it be fixed for a size/nonce/chain combination.
    //
    // This prevents the same work from being used twice for the
    // same chain while reducing the chance that two chains clash
    // for the same slot.
    unsigned int rand = nNonce;
    rand = rand * 1103515245 + 12345;
    rand += nChainID;
    rand = rand * 1103515245 + 12345;

    if (nChainIndex != (rand % nSize))
        return error("Aux POW wrong index");

    return true;
}
Exemple #23
0
/**
 * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
 */
bool Solver(const CScript& scriptPubKeyIn, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    // Templates
    static std::multimap<txnouttype, CScript> mTemplates;
    if (mTemplates.empty())
    {
        // Standard tx, sender provides pubkey, receiver adds signature
        mTemplates.insert(std::make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));

        // Syscoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
        mTemplates.insert(std::make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));

        // Sender provides N pubkeys, receivers provides M signatures
        mTemplates.insert(std::make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
    }

	// SYSCOIN check to see if this is a syscoin service transaction, if so get the scriptPubKey by extracting service specific script information
	CScript scriptPubKey;
	CScript scriptPubKeyOut;
	if (RemoveSyscoinScript(scriptPubKeyIn, scriptPubKeyOut))
		scriptPubKey = scriptPubKeyOut;
	else
		scriptPubKey = scriptPubKeyIn;
    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        typeRet = TX_NULL_DATA;
        return true;
    }

    // Scan templates
    const CScript& script1 = scriptPubKey;
    BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
    {
        const CScript& script2 = tplate.second;
        vSolutionsRet.clear();

        opcodetype opcode1, opcode2;
        std::vector<unsigned char> vch1, vch2;

        // Compare
        CScript::const_iterator pc1 = script1.begin();
        CScript::const_iterator pc2 = script2.begin();
        while (true)
        {
            if (pc1 == script1.end() && pc2 == script2.end())
            {
                // Found a match
                typeRet = tplate.first;
                if (typeRet == TX_MULTISIG)
                {
                    // Additional checks for TX_MULTISIG:
                    unsigned char m = vSolutionsRet.front()[0];
                    unsigned char n = vSolutionsRet.back()[0];
                    if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
                        return false;
                }
                return true;
            }
            if (!script1.GetOp(pc1, opcode1, vch1))
                break;
            if (!script2.GetOp(pc2, opcode2, vch2))
                break;

            // Template matching opcodes:
            if (opcode2 == OP_PUBKEYS)
            {
                while (vch1.size() >= 33 && vch1.size() <= 65)
                {
                    vSolutionsRet.push_back(vch1);
                    if (!script1.GetOp(pc1, opcode1, vch1))
                        break;
                }
                if (!script2.GetOp(pc2, opcode2, vch2))
                    break;
                // Normal situation is to fall through
                // to other if/else statements
            }

            if (opcode2 == OP_PUBKEY)
            {
                if (vch1.size() < 33 || vch1.size() > 65)
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_PUBKEYHASH)
            {
                if (vch1.size() != sizeof(uint160))
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_SMALLINTEGER)
            {   // Single-byte small integer pushed onto vSolutions
                if (opcode1 == OP_0 ||
                    (opcode1 >= OP_1 && opcode1 <= OP_16))
                {
                    char n = (char)CScript::DecodeOP_N(opcode1);
                    vSolutionsRet.push_back(valtype(1, n));
                }
                else
                    break;
            }
            else if (opcode1 != opcode2 || vch1 != vch2)
            {
                // Others must match exactly
                break;
            }
        }
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl)
{
    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_t nBalance = 0;
    std::vector<COutput> vCoins;
    wallet->AvailableCoins(vCoins, true, coinControl);

    BOOST_FOREACH(const COutput& out, vCoins)
        nBalance += out.tx->vout[out.i].nValue;

    if(total > nBalance)
    {
        return AmountExceedsBalance;
    }

    if((total + nTransactionFee) > nBalance)
    {
        return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
    }

	std::string txid = "";
	std::string messages = "";
	std::string hashBoinc = "";

    {
        LOCK2(cs_main, wallet->cs_wallet);

        // Sendmany
        std::vector<std::pair<CScript, int64_t> > vecSend;
		bool coinTracking = false;
		foreach(const SendCoinsRecipient &rcp, recipients)
        {
            CScript scriptPubKey;
            scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
            vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
			if (rcp.CoinTracking) coinTracking=true;
			messages += "<MESSAGE>" + AdvancedCrypt(FromQStringW(rcp.Message)) + "</MESSAGE>";
        
        }

        CWalletTx wtx;
        CReserveKey keyChange(wallet);
        int64_t nFeeRequired = 0;
		if (coinTracking)
		{
			printf("Creating tracked tx : old hashboinc %s",wtx.hashBoinc.c_str());
			wtx.hashBoinc = "<TRACK>" + wtx.GetHash().ToString() + "</TRACK>";
			//Run time code execution feature - 12-7-2014
			std::string q = "\"";
			std::string code = "MsgBox(" + q + "Hello!" + q + ",MsgBoxStyle.Critical," + q + "Message Title" + q + ")\r\n";
			wtx.hashBoinc += "<CODE>" + code + "</CODE>";
		}

		if (!msAttachmentGuid.empty())
		{
				printf("Adding attachment to tx %s",wtx.hashBoinc.c_str());
				wtx.hashBoinc += "<ATTACHMENT><TXID>" + wtx.GetHash().ToString() + "</TXID><ATTACHMENTGUID>" + msAttachmentGuid + "</ATTACHMENTGUID></ATTACHMENT>";
		}
		wtx.hashBoinc += messages;
		bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl);

        if(!fCreated)
        {
            if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future
            {
                return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
            }
            return TransactionCreationFailed;
        }
       
		if (coinTracking)
		{
			printf("Tracking hashBoinc %s",wtx.hashBoinc.c_str());
		}
		
		
		std::string samt = FormatMoney(wtx.vout[0].nValue);
		double dblAmt = dblFromAmount(wtx.vout[0].nValue);
	

        if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
        {
            return Aborted;
        }
        if(!wallet->CommitTransaction(wtx, keyChange))
        {
            return TransactionCommitFailed;
        }
        hex = QString::fromStdString(wtx.GetHash().GetHex());
		txid = wtx.GetHash().GetHex();
		hashBoinc = wtx.hashBoinc;
    }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl)
{
    qint64 total = 0;
    QSet<QString> setAddress;
    QString hex;

    if(recipients.empty())
    {
        return OK;
    }

    if(isAnonymizeOnlyUnlocked())
    {
        return AnonymizeOnlyUnlocked;
    }

    // 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_t nBalance = 0;
    std::vector<COutput> vCoins;
    wallet->AvailableCoins(vCoins, true, coinControl);

    BOOST_FOREACH(const COutput& out, vCoins)
        nBalance += out.tx->vout[out.i].nValue;

    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_t> > vecSend;
        foreach(const SendCoinsRecipient &rcp, recipients)
        {
            CScript scriptPubKey;
            scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
            vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
        }

        CWalletTx wtx;
        CReserveKey keyChange(wallet);
        int64_t nFeeRequired = 0;
        std::string strFailReason;

        bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason, coinControl);
 
        if(!fCreated)
        {
            if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future
            {
                return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
            }
            return TransactionCreationFailed;
        }
        if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
        {
            return Aborted;
        }
        if(!wallet->CommitTransaction(wtx, keyChange))
        {
            return TransactionCommitFailed;
        }
        hex = QString::fromStdString(wtx.GetHash().GetHex());
    }
UniValue validateaddress(const JSONRPCRequest& request)
{
    if (request.fHelp || request.params.size() != 1)
        throw std::runtime_error(
            "validateaddress \"address\"\n"
            "\nReturn information about the given knightcoin address.\n"
            "\nArguments:\n"
            "1. \"address\"     (string, required) The knightcoin address to validate\n"
            "\nResult:\n"
            "{\n"
            "  \"isvalid\" : true|false,       (boolean) If the address is valid or not. If not, this is the only property returned.\n"
            "  \"address\" : \"address\", (string) The knightcoin address validated\n"
            "  \"scriptPubKey\" : \"hex\",       (string) The hex encoded scriptPubKey generated by the address\n"
            "  \"ismine\" : true|false,        (boolean) If the address is yours or not\n"
            "  \"iswatchonly\" : true|false,   (boolean) If the address is watchonly\n"
            "  \"isscript\" : true|false,      (boolean) If the key is a script\n"
            "  \"script\" : \"type\"             (string, optional) The output script type. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash\n"
            "  \"hex\" : \"hex\",                (string, optional) The redeemscript for the p2sh address\n"
            "  \"addresses\"                   (string, optional) Array of addresses associated with the known redeemscript\n"
            "    [\n"
            "      \"address\"\n"
            "      ,...\n"
            "    ]\n"
            "  \"sigsrequired\" : xxxxx        (numeric, optional) Number of signatures required to spend multisig output\n"
            "  \"pubkey\" : \"publickeyhex\",    (string) The hex value of the raw public key\n"
            "  \"iscompressed\" : true|false,  (boolean) If the address is compressed\n"
            "  \"account\" : \"account\"         (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
            "  \"timestamp\" : timestamp,        (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
            "  \"hdkeypath\" : \"keypath\"       (string, optional) The HD keypath if the key is HD and available\n"
            "  \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
            "}\n"
            "\nExamples:\n"
            + HelpExampleCli("validateaddress", "\"LER4HnAEFwYHbmGxCfP2po1nPrUeiK8KM2\"")
            + HelpExampleRpc("validateaddress", "\"LER4HnAEFwYHbmGxCfP2po1nPrUeiK8KM2\"")
        );

#ifdef ENABLE_WALLET
    CWallet * const pwallet = GetWalletForJSONRPCRequest(request);

    LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
#else
    LOCK(cs_main);
#endif

    CBitcoinAddress address(request.params[0].get_str());
    bool isValid = address.IsValid();

    UniValue ret(UniValue::VOBJ);
    ret.push_back(Pair("isvalid", isValid));
    if (isValid)
    {
        CTxDestination dest = address.Get();
        std::string currentAddress = address.ToString();
        ret.push_back(Pair("address", currentAddress));

        CScript scriptPubKey = GetScriptForDestination(dest);
        ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));

#ifdef ENABLE_WALLET
        isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
        ret.push_back(Pair("ismine", bool(mine & ISMINE_SPENDABLE)));
        ret.push_back(Pair("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)));
        UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
        ret.pushKVs(detail);
        if (pwallet && pwallet->mapAddressBook.count(dest)) {
            ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
        }
        CKeyID keyID;
        if (pwallet) {
            const auto& meta = pwallet->mapKeyMetadata;
            auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end();
            if (it == meta.end()) {
                it = meta.find(CScriptID(scriptPubKey));
            }
            if (it != meta.end()) {
                ret.push_back(Pair("timestamp", it->second.nCreateTime));
                if (!it->second.hdKeypath.empty()) {
                    ret.push_back(Pair("hdkeypath", it->second.hdKeypath));
                    ret.push_back(Pair("hdmasterkeyid", it->second.hdMasterKeyID.GetHex()));
                }
            }
        }
#endif
    }
    return ret;
}
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{
    LOCK(cs_KeyStore);
    mapScripts[redeemScript.GetID()] = redeemScript;
    return true;
}
Exemple #28
0
Value createrawtransaction(const Array& params, bool fHelp)
{
    if (fHelp || (params.size() < 2 || params.size() > 3))
        throw runtime_error(
            "createrawtransaction [{\"txid\":txid,\"vout\":n},...] {address:amount,...} [tx-comment]\n"
            "Create a transaction spending given inputs\n"
            "(array of objects containing transaction id and output number),\n"
            "sending to given address(es).\n"
            "Returns hex-encoded raw transaction.\n"
            "Note that the transaction's inputs are not signed, and\n"
            "it is not stored in the wallet or transmitted to the network.");

    RPCTypeCheck(params, list_of(array_type)(obj_type));

    Array inputs = params[0].get_array();
    Object sendTo = params[1].get_obj();

    CTransaction rawTx;

    if (params.size() == 3) 
    {
       std::string txcomment = params[2].get_str();
       if (txcomment.length() > MAX_TX_COMMENT_LEN_V2)
       {
          txcomment.resize(MAX_TX_COMMENT_LEN_V2);
       }
    	rawTx.strTxComment = txcomment;
    }

    BOOST_FOREACH(Value& input, inputs)
    {
        const Object& o = input.get_obj();

        const Value& txid_v = find_value(o, "txid");
        if (txid_v.type() != str_type)
            throw JSONRPCError(-8, "Invalid parameter, missing txid key");
        string txid = txid_v.get_str();
        if (!IsHex(txid))
            throw JSONRPCError(-8, "Invalid parameter, expected hex txid");

        const Value& vout_v = find_value(o, "vout");
        if (vout_v.type() != int_type)
            throw JSONRPCError(-8, "Invalid parameter, missing vout key");
        int nOutput = vout_v.get_int();
        if (nOutput < 0)
            throw JSONRPCError(-8, "Invalid parameter, vout must be positive");

        CTxIn in(COutPoint(uint256(txid), nOutput));
        rawTx.vin.push_back(in);
    }

    set<CBitcoinAddress> setAddress;
    BOOST_FOREACH(const Pair& s, sendTo)
    {
        CBitcoinAddress address(s.name_);
        if (!address.IsValid())
            throw JSONRPCError(-5, string("Invalid FooCoin address:")+s.name_);

        if (setAddress.count(address))
            throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
        setAddress.insert(address);

        CScript scriptPubKey;
        scriptPubKey.SetDestination(address.Get());
        int64 nAmount = AmountFromValue(s.value_);

        CTxOut out(nAmount, scriptPubKey);
        rawTx.vout.push_back(out);
    }
Exemple #29
0
CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
Exemple #30
0
bool MultisigDialog::createRedeemScript(int m, vector<string> vKeys, CScript& redeemRet, string& errorRet)
{
    try{
        int n = vKeys.size();
        //gather pub keys
        if (n < 1)
            throw runtime_error("a Multisignature address must require at least one key to redeem");
        if (n < m)
            throw runtime_error(
                strprintf("not enough keys supplied "
                          "(got %d keys, but need at least %d to redeem)",
                    m, n));
        if (n > 15)
            throw runtime_error("Number of addresses involved in the Multisignature address creation > 15\nReduce the number");

        vector<CPubKey> pubkeys;
        pubkeys.resize(n);

        int i = 0;
        for(vector<string>::iterator it = vKeys.begin(); it != vKeys.end(); ++it) {
            string keyString = *it;
    #ifdef ENABLE_WALLET
            // Case 1: PIVX address and we have full public key:
            CBitcoinAddress address(keyString);
            if (pwalletMain && address.IsValid()) {
                CKeyID keyID;
                if (!address.GetKeyID(keyID)) {
                    throw runtime_error(
                        strprintf("%s does not refer to a key", keyString));
                }
                CPubKey vchPubKey;
                if (!pwalletMain->GetPubKey(keyID, vchPubKey))
                    throw runtime_error(
                        strprintf("no full public key for address %s", keyString));
                if (!vchPubKey.IsFullyValid()){
                    string sKey = keyString.empty()?"(empty)":keyString;
                    throw runtime_error(" Invalid public key: " + sKey );
                }
                pubkeys[i++] = vchPubKey;
            }

            //case 2: hex pub key
            else
    #endif
            if (IsHex(keyString)) {
                CPubKey vchPubKey(ParseHex(keyString));
                if (!vchPubKey.IsFullyValid()){
                    throw runtime_error(" Invalid public key: " + keyString);
                }
                pubkeys[i++] = vchPubKey;
            } else {
                throw runtime_error(" Invalid public key: " + keyString);
            }
        }
        //populate redeem script
        //OP_N for required signatures
        redeemRet << redeemRet.EncodeOP_N(m);
        //public keys
        for(CPubKey& key : pubkeys){
            vector<unsigned char> vKey= ToByteVector(key);
            redeemRet << vKey;
        }
        //OP_N for total pubkeys
        redeemRet << redeemRet.EncodeOP_N(pubkeys.size());
        redeemRet << OP_CHECKMULTISIG;
        return true;
    }catch(const runtime_error& e){
        errorRet = string(e.what());
        return false;
    }
}