示例#1
0
void NotaryPage::on_searchNotaryButton_clicked()
{
    std::string notaryID = ui->notaryIDEdit->text().toStdString();
    if (!(IsHex(notaryID) && notaryID.length() == 64)) {
        ui->notaryIDEdit->setValid(false);
        return;
    }

    uint256 hash(notaryID);
    ui->searchNotaryButton->setEnabled(false);
    model->searchNotaryTx(hash);
}
示例#2
0
uint256 ParseHashV(const UniValue& v, std::string strName)
{
    std::string strHex;
    if (v.isStr())
        strHex = v.get_str();
    if (!IsHex(strHex)) // Note: IsHex("") is false
        throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
    if (64 != strHex.length())
        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length()));
    uint256 result;
    result.SetHex(strHex);
    return result;
}
示例#3
0
文件: re_comp.c 项目: JukkaL/alore
/* Return the hex value of the character at *info->str. Return a value
   between 0..15 if it is a valid hex digit, -1 if invalid. Increment
   info->str. */
static int GetHexDigit(ParseInfo *info)
{
    if (info->str == info->strEnd)
        return -1;

    if (ReIsDigit(*info->str))
        return *info->str++ - '0';

    if (IsHex(*info->str))
        return ReLoCase(*info->str++) - 'a' + 10;

    return -1;
}
示例#4
0
void wxURI::AppendNextEscaped(wxString& s, const char *& p)
{
    // check for an already encoded character:
    //
    // pct-encoded   = "%" HEXDIG HEXDIG
    if ( p[0] == '%' && IsHex(p[1]) && IsHex(p[2]) )
    {
        s += *p++;
        s += *p++;
        s += *p++;
    }
    else // really needs escaping
    {
        static const char* hexDigits = "0123456789abcdef";

        const char c = *p++;

        s += '%';
        s += hexDigits[(c >> 4) & 15];
        s += hexDigits[c & 15];
    }
}
示例#5
0
int Express(char *answer,ulong parm) {
  int i,j,val;
  char *p;
  char *v = value.value;
  char *tmp;
  char h,l,asc;

  tmp = (char*)malloc(5);
  memset(tmp,0,5);

  if(IsHex(v)) {
    j = 0;
    for(i=0; i<4; i++) {
      h = v[i*2];
      l = v[i*2+1];
      if(h >= '0' && h <= '9') {
        asc = (char)(h - 0x30);
      }
      else if(h >= 'A' && h <= 'F') {
        asc = (char)(h - 0x37);
      }
      else if(h >= 'a' && h <= 'f') {
        asc = (char)(h - 0x57);
      }
      asc <<= 4;
      if(l >= '0' && l <= '9') {
        asc += (char)(l - 0x30);
      }
      else if(l >= 'A' && l <= 'F') {
        asc += (char)(l - 0x37);
      }
      else if(l >= 'a' && l <= 'f') {
        asc += (char)(l - 0x57);
      }
      if(asc > 0) {
        tmp[j] = asc;
        j++;
      }
    }
    val = strtol(v,&p,16);
    wsprintf(answer, "HEX: %X - DEC: %d - ASCII: %s", val, val, tmp);
  }
  else {
    strcpy(answer,v);
  }

  free(tmp);
  return 0;
};
示例#6
0
bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
{
    if (!IsHex(strHexBlk))
        return false;

    std::vector<unsigned char> blockData(ParseHex(strHexBlk));
    CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssBlock >> block;
    }
    catch (const std::exception&) {
        return false;
    }

    return true;
}
示例#7
0
void NotaryPage::on_sendNotaryButton_clicked()
{
    std::string fileHash = ui->notaryIDEdit->text().toStdString();
    if (!(IsHex(fileHash) && fileHash.length() == 64)) {
        ui->notaryIDEdit->setValid(false);
        return;
    }

    // Make sure wallet is unlocked
    WalletModel::UnlockContext ctx(model->requestUnlock());
    if (!ctx.isValid()) {
        return;
    }

    model->sendNotaryTx(fileHash);
}
示例#8
0
bool DecodeHexTx(CMutableTransaction& tx, const std::string& strHexTx)
{
    if (!IsHex(strHexTx))
        return false;

    std::vector<unsigned char> txData(ParseHex(strHexTx));
    CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssData >> tx;
        if (!ssData.empty())
            return false;
    }
    catch (const std::exception&) {
        return false;
    }

    return true;
}
char* Preprocessor::ParseHexConstant( char* start, char* end, Lexem& out )
{
    out.Value += *start;
    while( true )
    {
        ++start;
        if( start == end )
            return start;
        if( IsHex( *start ) )
        {
            out.Value += *start;
        }
        else
        {
            return start;
        }
    }
}
示例#10
0
void
nsUrlClassifierUtils::CanonicalNum(const nsACString& num,
                                   uint32_t bytes,
                                   bool allowOctal,
                                   nsACString& _retval)
{
  _retval.Truncate();

  if (num.Length() < 1) {
    return;
  }

  uint32_t val;
  if (allowOctal && IsOctal(num)) {
    if (PR_sscanf(PromiseFlatCString(num).get(), "%o", &val) != 1) {
      return;
    }
  } else if (IsDecimal(num)) {
    if (PR_sscanf(PromiseFlatCString(num).get(), "%u", &val) != 1) {
      return;
    }
  } else if (IsHex(num)) {
  if (PR_sscanf(PromiseFlatCString(num).get(), num[1] == 'X' ? "0X%x" : "0x%x",
                &val) != 1) {
      return;
    }
  } else {
    return;
  }

  while (bytes--) {
    char buf[20];
    PR_snprintf(buf, sizeof(buf), "%u", val & 0xff);
    if (_retval.IsEmpty()) {
      _retval.Assign(buf);
    } else {
      _retval = nsDependentCString(buf) + NS_LITERAL_CSTRING(".") + _retval;
    }
    val >>= 8;
  }
}
示例#11
0
文件: rest.cpp 项目: Airche/wificoin
static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
{
    if (!CheckWarmup(req))
        return false;
    std::string param;
    const RetFormat rf = ParseDataFormat(param, strURIPart);

    std::vector<std::string> uriParts;
    if (param.length() > 1)
    {
        std::string strUriParams = param.substr(1);
        boost::split(uriParts, strUriParams, boost::is_any_of("/"));
    }

    // throw exception in case of an empty request
    std::string strRequestMutable = req->ReadBody();
    if (strRequestMutable.length() == 0 && uriParts.size() == 0)
        return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");

    bool fInputParsed = false;
    bool fCheckMemPool = false;
    std::vector<COutPoint> vOutPoints;

    // parse/deserialize input
    // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ...

    if (uriParts.size() > 0)
    {

        //inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)
        if (uriParts.size() > 0 && uriParts[0] == "checkmempool")
            fCheckMemPool = true;

        for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
        {
            uint256 txid;
            int32_t nOutput;
            std::string strTxid = uriParts[i].substr(0, uriParts[i].find("-"));
            std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1);

            if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
                return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");

            txid.SetHex(strTxid);
            vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
        }

        if (vOutPoints.size() > 0)
            fInputParsed = true;
        else
            return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
    }

    switch (rf) {
    case RF_HEX: {
        // convert hex to bin, continue then with bin part
        std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);
        strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
    }

    case RF_BINARY: {
        try {
            //deserialize only if user sent a request
            if (strRequestMutable.size() > 0)
            {
                if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA
                    return RESTERR(req, HTTP_BAD_REQUEST, "Combination of URI scheme inputs and raw post data is not allowed");

                CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
                oss << strRequestMutable;
                oss >> fCheckMemPool;
                oss >> vOutPoints;
            }
        } catch (const std::ios_base::failure& e) {
            // abort in case of unreadable binary data
            return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
        }
        break;
    }

    case RF_JSON: {
        if (!fInputParsed)
            return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
        break;
    }
    default: {
        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
    }
    }

    // limit max outpoints
    if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
        return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));

    // check spentness and form a bitmap (as well as a JSON capable human-readable string representation)
    std::vector<unsigned char> bitmap;
    std::vector<CCoin> outs;
    std::string bitmapStringRepresentation;
    std::vector<bool> hits;
    bitmap.resize((vOutPoints.size() + 7) / 8);
    {
        LOCK2(cs_main, mempool.cs);

        CCoinsView viewDummy;
        CCoinsViewCache view(&viewDummy);

        CCoinsViewCache& viewChain = *pcoinsTip;
        CCoinsViewMemPool viewMempool(&viewChain, mempool);

        if (fCheckMemPool)
            view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool

        for (size_t i = 0; i < vOutPoints.size(); i++) {
            bool hit = false;
            Coin coin;
            if (view.GetCoin(vOutPoints[i], coin) && !mempool.isSpent(vOutPoints[i])) {
                hit = true;
                outs.emplace_back(std::move(coin));
            }

            hits.push_back(hit);
            bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
            bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
        }
    }

    switch (rf) {
    case RF_BINARY: {
        // serialize data
        // use exact same output as mentioned in Bip64
        CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
        ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
        std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();

        req->WriteHeader("Content-Type", "application/octet-stream");
        req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
        return true;
    }

    case RF_HEX: {
        CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
        ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
        std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";

        req->WriteHeader("Content-Type", "text/plain");
        req->WriteReply(HTTP_OK, strHex);
        return true;
    }

    case RF_JSON: {
        UniValue objGetUTXOResponse(UniValue::VOBJ);

        // pack in some essentials
        // use more or less the same output as mentioned in Bip64
        objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height()));
        objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
        objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation));

        UniValue utxos(UniValue::VARR);
        for (const CCoin& coin : outs) {
            UniValue utxo(UniValue::VOBJ);
            utxo.push_back(Pair("height", (int32_t)coin.nHeight));
            utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));

            // include the script in a json output
            UniValue o(UniValue::VOBJ);
            ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
            utxo.push_back(Pair("scriptPubKey", o));
            utxos.push_back(utxo);
        }
        objGetUTXOResponse.push_back(Pair("utxos", utxos));

        // return json string
        std::string strJSON = objGetUTXOResponse.write() + "\n";
        req->WriteHeader("Content-Type", "application/json");
        req->WriteReply(HTTP_OK, strJSON);
        return true;
    }
    default: {
        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
    }
    }

    // not reached
    return true; // continue to process further HTTP reqs on this cxn
}
示例#12
0
void QueryParamList::DecodeArg( char *ioCodedPtr )
{
    // perform In-Place  &hex and + to space decoding of the parameter
    //  on input, ioCodedPtr mau contain encoded text, on exit ioCodedPtr will be plain text
    // on % decoding errors, the 
    
    if ( !ioCodedPtr ) 
        return;

    char*   destPtr;
    char*   curChar;
    short   lineState = kLastWasText;
    char    hexBuff[32];

    destPtr = curChar = ioCodedPtr;
    
    while( *curChar )
    {
        switch( lineState )
        {
            case kRcvHexDigitOne:
                if ( IsHex( *curChar ) )
                {   
                    hexBuff[3] = *curChar;
                    hexBuff[4] = 0;
                    
                    *destPtr++ = (char)::strtoul( hexBuff, NULL, 0 );
                }
                else
                {   // not a valid encoding
                    *destPtr++ = '%';           // put back the pct sign
                    *destPtr++ = hexBuff[2];    // put back the first digit too.
                    *destPtr++ = *curChar;      // and this one!
                    
                }
                lineState = kLastWasText;
                break;

            case kLastWasText:
                if ( *curChar == '%' )
                    lineState = kPctEscape;
                else
                {
                    if (  *curChar == '+' )
                        *destPtr++ = ' ';
                    else
                        *destPtr++ = *curChar;
                }
                break;

            case kPctEscape:
                if ( *curChar == '%' )
                {
                    *destPtr++ = '%';
                    lineState = kLastWasText;
                }
                else
                {
                    if ( IsHex( *curChar ) )
                    {   
                        hexBuff[0] = '0';
                        hexBuff[1] = 'x';
                        hexBuff[2] = *curChar;
                        lineState = kRcvHexDigitOne;
                    }
                    else
                    {   
                        *destPtr++ = '%';       // put back the pct sign
                        *destPtr++ = *curChar;  // and this one!
                        lineState = kLastWasText;
                    }
                }
                break;
                
                    
        }   
        
        curChar++;
    }

    *destPtr = *curChar;
}
示例#13
0
void TAsmAnalyze::AnalyzeStatement(int KeyWords)
{
	unsigned char HexCode;
	int HexData;
	String NameID;

	int i;
	int TempHex;
	AsmTokenType Token = TOKENERROR;
	int AddressMode,Bytes;
	int LastPos;
	int Error;

	//reservedLookup(TokenString);
	//cout<<KeyWords<<" - "<<TokenString<<" - "<<CurrentKeyWords<<endl;
    if (CurrentToken == ENDLINE) return;
	if (CurrentToken != KEYWORDS)
	{
        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
		return;
	}

	i = 0;
    Error = 0;
    Bytes = 0;
	while (Token != ENDLINE && Error == 0)
	{
		Token=getToken();
		i++;
        if (Bytes > 0 && Token != ENDLINE)  // 已经处理过了
        {
            Error = 1;
            break;
        }
		//cout<<Token<<" ";
		switch (Token)
		{
			case SHARP:
                if (tokenString == "#")
                {
                    Error = 1;
                    break;
                }
				TempHex=HexStr2Int(tokenString);
				if (TempHex>=0x00 && TempHex<=0xff)
				{
					Bytes=2;
					HexData = TempHex;
					AddressMode=1;
				}
				else
				{
					if (TempHex>0xff && TempHex<=0xffff)
					{
						Bytes=3;
						HexData = TempHex;
						AddressMode=1;
					}
					else
					{
						Error = 1;
					}
				}
				//cout<<Bytes<<endl;
			break;

			case HEXNUM:
				TempHex=HexStr2Int(tokenString);
				if (TempHex>=0x00 && TempHex<=0xff)
				{
					Bytes=2;
					HexData = TempHex;
					LastPos=linepos;
					if (getToken()==XCHAR)
					{
						AddressMode=3;
						//cout<<Mode<<" "<<lineno<<endl;
					}
					else
					{
						linepos=LastPos;
						AddressMode=2;
					}
					//cout<<Mode;
				}
				else
				{
					if (TempHex>0xff && TempHex<=0xffff)
					{
						Bytes=3;
						HexData = TempHex;
						AddressMode=4;
					}
					else
					{
						Error = 1;
					}
				}
			break;

			case ID:
				if (reservedWords[KeyWords].Mode[5].Code != 0)
				{
					Bytes = reservedWords[KeyWords].Mode[5].Bytes;
					AddressMode = 6;
					NameID = tokenString;
				}
				else
				{
					if (IsHex(tokenString))
					{
						TempHex=HexStr2Int(tokenString);
						if (TempHex>=0x00 && TempHex<=0xff)
						{
							Bytes=2;
							HexData = TempHex;
							LastPos=linepos;
							if (getToken()==XCHAR)
							{
								AddressMode=3;
								//cout<<Mode<<" "<<lineno<<endl;
							}
							else
							{
								linepos=LastPos;
								AddressMode=2;
							}
							//cout<<Mode;
						}
						else
						{
							if (TempHex>0xff && TempHex<=0xffff)
							{
								Bytes=3;
								HexData = TempHex;
								AddressMode=4;
							}
							else
							{
								Error = 1;
							}
						}
					}
					else
					{
						Error = 1;
					}
				}
			break;

			case ENDLINE:
				if (i==1)
				{
					AddressMode = 5;
					HexData = 0;
					Bytes = 1;
				}
				//cout<<"End Line"<<endl;
			break;

			default:
				Error = 1;
                FoundError(SYNTAX_ERROR,lineno,"语法错误!");
				//cout<<"Error -- "<<tokenString<<endl;
			break;
		}
	}

	if (Error==1)
	{
        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
		//cout<<"Error -- "<<lineno<<endl;
		return;
	}

	//if ((reservedWords[KeyWords].Mode[5].Code != 0) && (AddressMode == 2))
	//{
	//	AddressMode=6;
	//}

	if ((reservedWords[KeyWords].Mode[AddressMode-1].Bytes == 3) && (Bytes == 2))
	{
		Bytes = 3;
	}

	if ((reservedWords[KeyWords].Mode[1].Code == 0) && (reservedWords[KeyWords].Mode[3].Code != 0) && (Bytes == 2))
	{
		AddressMode = 4;
		Bytes = 3;
	}

	if ((AddressMode == 2) && (Bytes == 2) && (reservedWords[KeyWords].Mode[4].Code == 0) && (reservedWords[KeyWords].Mode[4].Bytes == 1))
    {
        Bytes = 1;
    }
    else if ((reservedWords[KeyWords].Mode[AddressMode-1].Code == 0)
             || (reservedWords[KeyWords].Mode[AddressMode-1].Bytes != Bytes))
	{
        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
		//cout<<"Line: "<<lineno<<"  Don't Addressing!"<<endl;
		return;
	}

	HexCode = reservedWords[KeyWords].Mode[AddressMode-1].Code;
	
    // 特殊寻址则不写指令代码
    if ((reservedWords[KeyWords].Mode[4].Code != 0) || (reservedWords[KeyWords].Mode[4].Bytes != 1))
        DestFile.put(HexCode);

	switch (Bytes)
	{
        case 1:
            if ((reservedWords[KeyWords].Mode[4].Code == 0) && (reservedWords[KeyWords].Mode[4].Bytes == 1))
                DestFile.put(HexData);
        break;
		case 2:
			if (reservedWords[KeyWords].Mode[5].Code != 0)
			{
				// 执行相对转移
                DestFile.put(0);
                IDListStruct *Address = new IDListStruct(CurrentAddress,lineno);
                IDList->AddObject(NameID, Address);
                //IDList->Add(Address);
 				//cout<<NameID<<endl;
			}
			else
			{
                DestFile.put(HexData);
                //DestFile.put(HexData);
				//cout<<HexData<<endl;
			}
		break;
		case 3:
			if (reservedWords[KeyWords].Mode[5].Code != 0)
			{
				// 执行绝对转移
                DestFile.put(0);
                DestFile.put(0);
                IDListStruct *Address = new IDListStruct(CurrentAddress,lineno);
                Address->Relative = false;
                IDList->AddObject(NameID, Address);
                //IDList->Add(Address);
 				//cout<<NameID<<endl;
			}
            else
            {
                if (HexData <= 0xff)
                {
                    DestFile.put(0);
                    DestFile.put(HexData);
                    //cout<<"00 "<<HexData<<endl;
                }
                else
                {
                    DestFile.put(HexData/0x100);
                    DestFile.put(HexData & 0xff);
                    //cout<<(HexData/0x100)<<" "<<(HexData & 0xff)<<endl;
                }
            }
		break;
		//default:
			//cout<<endl;
	}

	CurrentAddress += Bytes;
}
示例#14
0
void TAsmAnalyze::Analyze(void)
{
	AsmTokenType Token = TOKENERROR;
	AsmTokenType TokenTemp;
	String TokenID;
    int TempHex;

	pHash = new HashTable;

	while (Token!=ENDFILE)
	{
		Token=getToken();
		if (Token==ENDFILE) break;
		//cout<<"Debug: "<<tokenString<<endl;

		if (TokenPos == 1)
		{
			switch (Token)
			{
				case KEYWORDS:
					AnalyzeStatement(CurrentKeyWords);
					// 转到相应处理函数。
				break;

				case ID:
					TokenID = tokenString;
                    TokenTemp = getToken();
					if (TokenTemp == COLON)
					{
						// 发现一个相对地址标示符,存储到符号表中。
						//cout<<"ID - "<<TokenID<<" - "<<hex<<(unsigned int)(BaseAddress+CurrentAddress)<<endl;
						if (!pHash->insert(TokenID,CurrentAddress,true))
						{
							//cout<<"ID Existed!"<<endl;
                            FoundError(ID_DEFINED,lineno,"标示符已存在!");
						}
						//if (getToken()==ENDLINE) break;
						getToken();
						AnalyzeStatement(CurrentKeyWords);
						//cout<<lineno;
						// 转到相应处理函数。
					}
					else if (TokenTemp == EQUAL)
                    {
                        getToken();
                        if (IsHex(tokenString))
                        {
                            // 发现一个绝对标示符,存储到符号表中。
                            if (DebugMode)
                                TempHex = HexStr2Int(tokenString) - DebugAddress;
                            else
                                TempHex = HexStr2Int(tokenString);
                            if (!pHash->insert(TokenID, TempHex, false))
                            {
                                //cout<<"ID Existed!"<<endl;
                                FoundError(ID_DEFINED,lineno,"标示符已存在!");
                            }
                        }
                        else
                        {
                            FoundError(SYNTAX_ERROR,lineno,"语法错误!");
                            //cout<<"Line Error - "<<lineno<<endl;
                        }
                    }
                    else
					{
                        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
						//cout<<"Line Error - "<<lineno<<endl;
					}

				break;

				case ATCHAR:
                    TokenTemp = getToken();
                    if (TokenTemp == TOKENERROR)
                    {
                        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
                    }
                    else if (TokenTemp == STRING)
                    {
                        LinkFileName = tokenString;
                    }
                    else if (TokenTemp == SHARP && IsHex(tokenString))
					{
						// 设置调试模式
                        DebugMode = true;
						// 设置起始地址
                        BaseAddress = HexStr2Int(tokenString);
					}
                    else if (IsHex(tokenString))
					{
						// 设置起始地址
                        BaseAddress = HexStr2Int(tokenString);
					}
                    else
					{
                        FoundError(SYNTAX_ERROR,lineno,"语法错误!");
						//cout<<"Line Error - "<<lineno<<endl;
					}
				break;

				case ENDLINE:
				break;

				default:
                    FoundError(SYNTAX_ERROR,lineno,"语法错误!");
    				//cout<<"Line Error - "<<lineno<<endl;
			}
		}
	}

    // 获取本次汇编的字节数
    TotalSize = CurrentAddress;
}
示例#15
0
void ConfigParser::Parse( const IDataStream& Stream )
{
	Array< SToken >	Tokens;
	SToken			Token;
	Token.m_TokenType						= SToken::ET_Name;
	char			StrMark					= 0;	// Stores the character (either ' or ") that opened a string
	SToken			MacroToken;
	List<int>		ArrayCounters;
	Array<char>		CounterCharArray;
	int				LineCount				= 1;

	for(;;)
	{
		char c = Stream.ReadInt8();

		// Skip the UTF-8 byte order mark if present.
		if( UTF8_BOM_0 == static_cast<byte>( c ) )
		{
			CHECK( UTF8_BOM_1 == static_cast<byte>( Stream.ReadInt8() ) );
			CHECK( UTF8_BOM_2 == static_cast<byte>( Stream.ReadInt8() ) );
			c = Stream.ReadInt8();
		}

		if( Stream.EOS() )
		{
			if( Token.m_TokenString.Empty() )
			{
				Token.m_TokenType = SToken::ET_None;
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );
			}
			else
			{
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
			}

			break;
		}

		if( c == '&' )
		{
			if( Token.m_TokenType == SToken::ET_Name )
			{
				// Increment the current counter and add it to the current name.
				ASSERT( ArrayCounters.Size() > 0 );
				List<int>::Iterator CounterIter = ArrayCounters.Back();
				( *CounterIter )++;
				SimpleString CounterString = SimpleString::PrintF( "%d", *CounterIter );
				CounterCharArray.Clear();
				CounterString.FillArray( CounterCharArray );
				Token.m_TokenString.Append( CounterCharArray );
			}
			else if( Token.m_TokenType == SToken::ET_None )
			{
				// Add a new counter
				// Push a counter token that will be replaced with the count int later.
				ArrayCounters.PushBack( -1 );
				Token.m_TokenType = SToken::ET_Counter;
			}
			else if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				WARNDESC( "Unexpected character '&' in token." );
			}
		}
		else if( c == '^' )
		{
			if( Token.m_TokenType == SToken::ET_Name )
			{
				// Add the current counter to the current name.
				ASSERT( ArrayCounters.Size() > 0 );
				List<int>::Iterator CounterIter = ArrayCounters.Back();
				ASSERT( ( *CounterIter ) >= 0 );
				SimpleString CounterString = SimpleString::PrintF( "%d", *CounterIter );
				CounterCharArray.Clear();
				CounterString.FillArray( CounterCharArray );
				Token.m_TokenString.Append( CounterCharArray );
			}
			else if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				WARNDESC( "Unexpected character '^' in token." );
			}
		}
		else if( c == ' ' || c == '\t' )
		{
			switch( Token.m_TokenType )
			{
			case SToken::ET_None:
			case SToken::ET_Equals:
				// Ignore whitespace
				break;
			case SToken::ET_Name:
			case SToken::ET_Context:
			case SToken::ET_Macro:
				if( Token.m_TokenString.Empty() )
				{
					// If the name is empty, ignore whitespace (before the name)
				}
				else
				{
					// Close current token, push it, and expect an equals

					// If we're closing a macro, save it as such
					if( Token.m_TokenType == SToken::ET_Macro )
					{
						MacroToken = Token;
					}

					Token.m_TokenString.PushBack( '\0' );
					Tokens.PushBack( Token );
					DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
					Token.m_TokenString.Clear();

					if( Token.m_TokenType == SToken::ET_Name )
					{
						Token.m_TokenType = SToken::ET_Equals;
					}
					else if( Token.m_TokenType == SToken::ET_Context || Token.m_TokenType == SToken::ET_Macro )
					{
						Token.m_TokenType = SToken::ET_Name;
					}
				}
				break;
			case SToken::ET_Bool:
			case SToken::ET_Int:
			case SToken::ET_Float:
				// Close current token, push it, and expect nothing
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_String:
				Token.m_TokenString.PushBack( c );
				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}
		}
		else if( c == '=' )
		{
			switch( Token.m_TokenType )
			{
			case SToken::ET_Name:
				// Close current token, push it and an equals
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_Equals;
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );
				Tokens.PushBack( Token );

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_Equals:
				// Already expecting =, just push it
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_String:
				Token.m_TokenString.PushBack( c );
				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}
		}
		else if( c == '#' )
		{
			// # starts a comment

			// Allow # inside a string
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				c = Stream.ReadInt8();
				
				if( c == '!' )	// #! and !# indicate the start and end of block comments
				{
					while( !Stream.EOS() )
					{
						if( Stream.ReadInt8() == '!' && Stream.ReadInt8() == '#' )
						{
							break;
						}
					}
				}
				else
				{
					// Read to end of line
					while( c != '\n' && c!= '\v' && !Stream.EOS() )	// Vertical tab stupidity again
					{
						c = Stream.ReadInt8();
					}

					// Change the context because we're on a new line
					Token.m_TokenType = SToken::ET_Name;

					++LineCount;
				}
			}
		}
		else if( c == '\\' && Token.m_TokenType == SToken::ET_String )
		{
			// Escape sequence, intended to insert linebreaks (and maybe other things in the future)
			// Config string escape sequences are not the same as C++ escape sequences. They can be
			// \\, \n, \?, \", or \xx (where x are hex digits, to specify any character by hex).

			char next = Stream.ReadInt8();
			if( next == 'n' )
			{
				Token.m_TokenString.PushBack( '\n' );
			}
			else if( next == '\"' )
			{
				Token.m_TokenString.PushBack( '\"' );
			}
			else if( next == '\\' )
			{
				Token.m_TokenString.PushBack( '\\' );
			}
			else if( next == 'x' )
			{
				char Hex = 0;
				for( uint HexIndex = 0; HexIndex < 2; ++HexIndex )
				{
					next = Stream.ReadInt8();
					ASSERT( IsHex( next ) );
					Hex = ( Hex << 4 ) | GetHex( next );
				}
				Token.m_TokenString.PushBack( Hex );
			}
			else if( next == 'u' )
			{
				// First, extract a unicode code point (e.g. \u00d7 for U+00D7)
				// NOTE: This only support the first Unicode plane, and is strict about
				// using four characters, so \ud7 is not a valid substitute for \u00d7.
				unicode_t CodePoint = 0;
				for( uint UnicodeIndex = 0; UnicodeIndex < 4; ++UnicodeIndex )
				{
					next = Stream.ReadInt8();
					ASSERT( IsHex( next ) );
					CodePoint = ( CodePoint << 4 ) | GetHex( next );
				}

				// Then convert the two-byte code point to UTF-8.
				Array<unicode_t> CodePointArray;
				CodePointArray.PushBack( CodePoint );
				const SimpleString UTF8String = SimpleString::SetUTF8( CodePointArray );

				for( uint CharIndex = 0; CharIndex < UTF8String.Length(); ++CharIndex )
				{
					const char NextChar = UTF8String.GetChar( CharIndex );
					Token.m_TokenString.PushBack( NextChar );
				}
			}
			else
			{
				PRINTF( "Unrecognized escape sequence \\%c at line %d\n", next, LineCount );
				WARNDESC( "Unrecognized escape sequence" );
			}
		}
		else if( c == 0x0d )
		{
			// DOS linebreak is 0D 0A, so ignore and expect \n to follow
		}
		else if( c == '\0' )
		{
			// Don't know how these are getting in either, but ignore them
		}
		else if( c == '\n' || c == '\v' )
		{
			if( Token.m_TokenType == SToken::ET_Macro )
			{
				MacroToken = Token;
			}

			// Dunno how vertical tabs are getting in, but treat them as linebreaks
			if( Token.m_TokenString.Empty() )
			{
				if( Token.m_TokenType != SToken::ET_Counter )
				{
					Token.m_TokenType = SToken::ET_None;
				}
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );

				Token.m_TokenType = SToken::ET_Name;
			}
			else
			{
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_Name;
			}

			++LineCount;
		}
		else if( c == '[' )
		{
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				// We should only ever open a context when we're expecting a name
				ASSERT( Token.m_TokenType == SToken::ET_Name );
				Token.m_TokenType = SToken::ET_Context;

				// Opening a new context, clear the macro token.
				MacroToken = SToken();
			}
		}
		else if( c == ']' )
		{
			// If we've already closed the context, ignore; else, push token
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				ASSERT( Token.m_TokenType == SToken::ET_Context );
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
			}
		}
		else if( c == '@' )
		{
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				// We should only ever declare or insert a macro when we're expecting a name
				ASSERT( Token.m_TokenType == SToken::ET_Name );
				c = Stream.ReadInt8();
				if( c == '@' )
				{
					// @@... means we're inserting the current macro into a name

					// Make sure there is a current macro. If this fails, a macro probably
					// wasn't opened in the current context.
					ASSERT( MacroToken.m_TokenString.Size() > 0 );

					const uint MacroLength = MacroToken.m_TokenString.Size();
					for( uint MacroIndex = 0; MacroIndex < MacroLength; ++MacroIndex )
					{
						Token.m_TokenString.PushBack( MacroToken.m_TokenString[ MacroIndex ] );
					}
				}
				else
				{
					// @... means we're declaring a new macro
					Token.m_TokenType = SToken::ET_Macro;
					if( c == ' ' || c == '\t' )
					{
						// Ignore whitespace at the front of macro
					}
					else
					{
						Token.m_TokenString.PushBack( c );
					}
				}
			}
		}
		else
		{
			bool ClosedString = false;
			InnerParse( c, StrMark, Token.m_TokenString, LineCount, Token.m_TokenType, &ClosedString );
			if( ClosedString )
			{
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
				Token.m_TokenType = SToken::ET_None;
			}
		}
	}

	SimpleString Context = "";

	// Tokens are made, now create config vars
	for( uint i = 0; i < Tokens.Size(); ++i )
	{
		SToken& NameToken = Tokens[i];
		SimpleString Name = "";
		const char* ValueString = NULL;
		if( NameToken.m_TokenType == SToken::ET_Name )
		{
			Name = NameToken.m_TokenString.GetData();
			ASSERT( Tokens[ i + 1 ].m_TokenType == SToken::ET_Equals );

			SToken& ValueToken = Tokens[ i + 2 ];
			ValueString = ValueToken.m_TokenString.GetData();

			if( Context != "" )
			{
				CATPRINTF( "Core", 2, "%s:", Context.CStr() );
			}
			CATPRINTF( "Core", 2, "%s: %s: %s\n", Name.CStr(), SToken::m_TokenNames[ ValueToken.m_TokenType ], ValueString );

			switch( ValueToken.m_TokenType )
			{
			case SToken::ET_Bool:
				{
					// Just use the first character to determine truth
					bool Value = false;
					char first = ValueString[0];
					if( first == 't' || first == 'T' )
					{
						Value = true;
					}
					ConfigManager::SetBool( Name, Value, Context );
				}
				break;
			case SToken::ET_Int:
				{
					int Value = atoi( ValueString );
					ConfigManager::SetInt( Name, Value, Context );
				}
				break;
			case SToken::ET_Counter:
				{
					List<int>::Iterator NextCounterIter = ArrayCounters.Front();
					( *NextCounterIter )++;	// Add one to the last value we incremented, and that's the total for this array
					ConfigManager::SetInt( Name, *NextCounterIter, Context );
					ArrayCounters.PopFront();
				}
				break;
			case SToken::ET_Float:
				{
					float Value = (float)atof( ValueString );
					ConfigManager::SetFloat( Name, Value, Context );
				}
				break;
			case SToken::ET_String:
				{
					// Make a permanent copy of the string
					uint Length = (uint)strlen( ValueString );
					char* pString = new char[ Length + 1];
					memcpy_s( pString, Length + 1, ValueString, Length );
					pString[ Length ] = '\0';
					StringManager::AddString( StringManager::ESL_Permanent, pString );

					ConfigManager::SetString( Name, pString, Context );
				}

				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}

			i += 2;
		}
		else if( NameToken.m_TokenType == SToken::ET_Context )
		{
			Context = NameToken.m_TokenString.GetData();
			//CATPRINTF( "Core", 2, "Pushed context %s\n", Context.CStr() );
		}
		else
		{
			DEBUGCATPRINTF( "Core", 2, "Skipped unexpected token %s (expected ET_Name)\n", SToken::m_TokenNames[ NameToken.m_TokenType ] );
		}
	}

	// Clean up
	for( uint i = 0; i < Tokens.Size(); ++i )
	{
		Tokens[i].m_TokenString.Clear();
	}
	Tokens.Clear();
}
示例#16
0
ESFError AWSHttpUtil::DecodeEscape(ESFBuffer *buffer, unsigned char *value)
{
    if (! value)
    {
        return ESF_NULL_POINTER;
    }

    if (3 > buffer->getReadable())
    {
        return ESF_AGAIN;
    }

    unsigned char octet = buffer->getNext();

    if ('%' != octet)
    {
        return ESF_ILLEGAL_ENCODING;
    }

    octet = buffer->getNext();

    if (false == IsHex(octet))
    {
        return ESF_ILLEGAL_ENCODING;
    }

    *value = 0;

    if (IsUpAlpha(octet))
    {
        *value = (octet - 'A' + 10) * 16;
    }
    else if (IsLowAlpha(octet))
    {
        *value = (octet - 'a' + 10) * 16;
    }
    else
    {
        *value = (octet - '0') * 16;
    }

    ESF_ASSERT(buffer->isReadable());

    octet = buffer->getNext();

    if (false == IsHex(octet))
    {
        return ESF_ILLEGAL_ENCODING;
    }

    if (IsUpAlpha(octet))
    {
        *value += octet - 'A' + 10;
    }
    else if (IsLowAlpha(octet))
    {
        *value += octet - 'a' + 10;
    }
    else
    {
        *value += octet - '0';
    }

    return ESF_SUCCESS;
}
示例#17
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;
    }
}
示例#18
0
文件: uri.cpp 项目: 252525fb/rpcs3
wxChar wxURI::TranslateEscape(const wxChar* s)
{
    wxASSERT_MSG( IsHex(s[0]) && IsHex(s[1]), wxT("Invalid escape sequence!"));

    return wx_truncate_cast(wxChar, (CharToHex(s[0]) << 4 ) | CharToHex(s[1]));
}
示例#19
0
CScript ParseScript(const std::string& s)
{
    CScript result;

    static std::map<std::string, opcodetype> mapOpNames;

    if (mapOpNames.empty())
    {
        for (unsigned int op = 0; op <= MAX_OPCODE; 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;
            std::string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            boost::algorithm::replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    std::vector<std::string> words;
    boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::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, boost::algorithm::is_digit()) ||
            (boost::algorithm::starts_with(*w, "-") && all(std::string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
        {
            // Number
            int64_t n = atoi64(*w);
            result << n;
        }
        else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(std::string(w->begin()+2, w->end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(std::string(w->begin()+2, w->end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::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 std::runtime_error("script parse error");
        }
    }

    return result;
}
示例#20
0
文件: misc.cpp 项目: Chovanec/bitcoin
static UniValue createmultisig(const JSONRPCRequest& request)
{
    if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
    {
        std::string msg = "createmultisig nrequired [\"key\",...] ( \"address_type\" )\n"
            "\nCreates a multi-signature address with n signature of m keys required.\n"
            "It returns a json object with the address and redeemScript.\n"
            "\nArguments:\n"
            "1. nrequired                    (numeric, required) The number of required signatures out of the n keys.\n"
            "2. \"keys\"                       (string, required) A json array of hex-encoded public keys\n"
            "     [\n"
            "       \"key\"                    (string) The hex-encoded public key\n"
            "       ,...\n"
            "     ]\n"
            "3. \"address_type\"               (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is legacy.\n"

            "\nResult:\n"
            "{\n"
            "  \"address\":\"multisigaddress\",  (string) The value of the new multisig address.\n"
            "  \"redeemScript\":\"script\"       (string) The string value of the hex-encoded redemption script.\n"
            "}\n"

            "\nExamples:\n"
            "\nCreate a multisig address from 2 public keys\n"
            + HelpExampleCli("createmultisig", "2 \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"") +
            "\nAs a json rpc call\n"
            + HelpExampleRpc("createmultisig", "2, \"[\\\"03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd\\\",\\\"03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626\\\"]\"")
        ;
        throw std::runtime_error(msg);
    }

    int required = request.params[0].get_int();

    // Get the public keys
    const UniValue& keys = request.params[1].get_array();
    std::vector<CPubKey> pubkeys;
    for (unsigned int i = 0; i < keys.size(); ++i) {
        if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) {
            pubkeys.push_back(HexToPubKey(keys[i].get_str()));
        } else {
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str()));
        }
    }

    // Get the output type
    OutputType output_type = OutputType::LEGACY;
    if (!request.params[2].isNull()) {
        if (!ParseOutputType(request.params[2].get_str(), output_type)) {
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
        }
    }

    // Construct using pay-to-script-hash:
    const CScript inner = CreateMultisigRedeemscript(required, pubkeys);
    CBasicKeyStore keystore;
    const CTxDestination dest = AddAndGetDestinationForScript(keystore, inner, output_type);

    UniValue result(UniValue::VOBJ);
    result.pushKV("address", EncodeDestination(dest));
    result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));

    return result;
}
示例#21
0
UniValue gettxoutproof(const JSONRPCRequest& request)
{
    if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
        throw std::runtime_error(
            "gettxoutproof [\"txid\",...] ( blockhash )\n"
            "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
            "\nNOTE: By default this function only works sometimes. This is when there is an\n"
            "unspent output in the utxo for this transaction. To make it always work,\n"
            "you need to maintain a transaction index, using the -txindex command line option or\n"
            "specify the block in which the transaction is included manually (by blockhash).\n"
            "\nArguments:\n"
            "1. \"txids\"       (string) A json array of txids to filter\n"
            "    [\n"
            "      \"txid\"     (string) A transaction hash\n"
            "      ,...\n"
            "    ]\n"
            "2. \"blockhash\"   (string, optional) If specified, looks for txid in the block with this hash\n"
            "\nResult:\n"
            "\"data\"           (string) A string that is a serialized, hex-encoded data for the proof.\n"
        );

    std::set<uint256> setTxids;
    uint256 oneTxid;
    UniValue txids = request.params[0].get_array();
    for (unsigned int idx = 0; idx < txids.size(); idx++) {
        const UniValue& txid = txids[idx];
        if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
            throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
        uint256 hash(uint256S(txid.get_str()));
        if (setTxids.count(hash))
            throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
       setTxids.insert(hash);
       oneTxid = hash;
    }

    LOCK(cs_main);

    CBlockIndex* pblockindex = nullptr;

    uint256 hashBlock;
    if (!request.params[1].isNull())
    {
        hashBlock = uint256S(request.params[1].get_str());
        if (!mapBlockIndex.count(hashBlock))
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
        pblockindex = mapBlockIndex[hashBlock];
    } else {
        // Loop through txids and try to find which block they're in. Exit loop once a block is found.
        for (const auto& tx : setTxids) {
            const Coin& coin = AccessByTxid(*pcoinsTip, tx);
            if (!coin.IsSpent()) {
                pblockindex = chainActive[coin.nHeight];
                break;
            }
        }
    }

    if (pblockindex == nullptr)
    {
        CTransactionRef tx;
        if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull())
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
        if (!mapBlockIndex.count(hashBlock))
            throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
        pblockindex = mapBlockIndex[hashBlock];
    }

    CBlock block;
    if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");

    unsigned int ntxFound = 0;
    for (const auto& tx : block.vtx)
        if (setTxids.count(tx->GetHash()))
            ntxFound++;
    if (ntxFound != setTxids.size())
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not all transactions found in specified or retrieved block");

    CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
    CMerkleBlock mb(block, setTxids);
    ssMB << mb;
    std::string strHex = HexStr(ssMB.begin(), ssMB.end());
    return strHex;
}