Pathfinder::Pathfinder (RippleLineCache::ref cache, const RippleAddress& uSrcAccountID, const RippleAddress& uDstAccountID, const uint160& uSrcCurrencyID, const uint160& uSrcIssuerID, const STAmount& saDstAmount, bool& bValid) : mSrcAccountID (uSrcAccountID.getAccountID ()), mDstAccountID (uDstAccountID.getAccountID ()), mDstAmount (saDstAmount), mSrcCurrencyID (uSrcCurrencyID), mSrcIssuerID (uSrcIssuerID), mSrcAmount (uSrcCurrencyID, uSrcIssuerID, 1u, 0, true), mLedger (cache->getLedger ()), mRLCache (cache) { if (((mSrcAccountID == mDstAccountID) && (mSrcCurrencyID == mDstAmount.getCurrency ())) || mDstAmount.isZero ()) { // no need to send to same account with same currency, must send non-zero bValid = false; mLedger.reset (); return; } bValid = true; m_loadEvent = getApp().getJobQueue ().getLoadEvent (jtPATH_FIND, "FindPath"); bool bIssuer = mSrcCurrencyID.isNonZero() && mSrcIssuerID.isNonZero() && (mSrcIssuerID != mSrcAccountID); mSource = STPathElement( // Where does an empty path start? bIssuer ? mSrcIssuerID : mSrcAccountID, // On the source account or issuer account mSrcCurrencyID, // In the source currency mSrcCurrencyID.isZero() ? uint160() : (bIssuer ? mSrcIssuerID : mSrcAccountID)); }
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { std::vector<valtype> vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == TX_PUBKEY) { CPubKey pubKey(vSolutions[0]); if (!pubKey.IsValid()) return false; addressRet = pubKey.GetID(); return true; } else if (whichType == TX_PUBKEYHASH) { addressRet = CKeyID(uint160(vSolutions[0])); return true; } else if (whichType == TX_SCRIPTHASH) { addressRet = CScriptID(uint160(vSolutions[0])); return true; } else if (whichType == TX_WITNESS_V0_KEYHASH) { WitnessV0KeyHash hash; std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); addressRet = hash; return true; } else if (whichType == TX_WITNESS_V0_SCRIPTHASH) { WitnessV0ScriptHash hash; std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); addressRet = hash; return true; } else if (whichType == TX_WITNESS_UNKNOWN) { WitnessUnknown unk; unk.version = vSolutions[0][0]; std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program); unk.length = vSolutions[1].size(); addressRet = unk; return true; } // Multisig txns have more than one address... return false; }
bool findOutputInTransaction( CTransaction const & _tx, CKeyID const & _findId, std::vector< CTxOut > & _txouts, std::vector< unsigned int > & _ids ) { for (unsigned int i = 0; i < _tx.vout.size(); i++) { const CTxOut& txout = _tx.vout[i]; opcodetype opcode; std::vector<unsigned char> data; CScript::const_iterator pc = txout.scriptPubKey.begin(); //sanity check while( pc != txout.scriptPubKey.end() ) { if (!txout.scriptPubKey.GetOp(pc, opcode, data)) return false; } txnouttype type; std::vector< std:: vector<unsigned char> > vSolutions; if (Solver(txout.scriptPubKey, type, vSolutions) && (type == TX_PUBKEY || type == TX_PUBKEYHASH)) { std::vector<std::vector<unsigned char> >::iterator it = vSolutions.begin(); while( it != vSolutions.end() ) { if ( type == TX_PUBKEY ) { // impossible to be here ?? if ( _findId == Hash160( *it ) ) { _txouts.push_back( txout ); _ids.push_back( i ); } } else { if ( _findId == uint160( *it ) ) { _txouts.push_back( txout ); _ids.push_back( i ); } } it++; } } } return !_txouts.empty(); }
bool RippleAddress::setAccountID(const std::string& strAccountID) { if (strAccountID.empty()) { setAccountID(uint160()); return true; } else { return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); } }
bool RippleAddress::setAccountID (const std::string& strAccountID, Base58::Alphabet const& alphabet) { if (strAccountID.empty ()) { setAccountID (uint160 ()); mIsValid = true; } else { mIsValid = SetString (strAccountID, VER_ACCOUNT_ID, alphabet); } return mIsValid; }
bool RippleAddress::setAccountID (const std::string& strAccountID, const char* pAlphabet) { if (strAccountID.empty ()) { setAccountID (uint160 ()); mIsValid = true; } else { mIsValid = SetString (strAccountID.c_str (), VER_ACCOUNT_ID, pAlphabet); } return mIsValid; }
uint160 STObject::getFieldH160 (SField::ref field) const { const SerializedType* rf = peekAtPField (field); if (!rf) throw std::runtime_error ("Field not found"); SerializedTypeID id = rf->getSType (); if (id == STI_NOTPRESENT) return uint160 (); // optional field not present const STHash160* cf = dynamic_cast<const STHash160*> (rf); if (!cf) throw std::runtime_error ("Wrong field type"); return cf->getValue (); }
uint160 RippleAddress::getAccountID() const { switch (nVersion) { case VER_NONE: throw std::runtime_error("unset source - getAccountID"); case VER_ACCOUNT_ID: return uint160(vchData); case VER_ACCOUNT_PUBLIC: // Note, we are encoding the left. return Hash160(vchData); default: throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion))); } }
std::vector< CAvailableCoin > getAvailableCoins( CCoins const & _coins, uint160 const & _pubId, uint256 const & _hash ) { std::vector< CAvailableCoin > availableCoins; for (unsigned int i = 0; i < _coins.vout.size(); i++) { const CTxOut& txout = _coins.vout[i]; opcodetype opcode; std::vector<unsigned char> data; CScript::const_iterator pc = txout.scriptPubKey.begin(); //sanity check while( pc != txout.scriptPubKey.end() ) { if (!txout.scriptPubKey.GetOp(pc, opcode, data)) return std::vector< CAvailableCoin >(); } txnouttype type; std::vector< std:: vector<unsigned char> > vSolutions; if (Solver(txout.scriptPubKey, type, vSolutions) && (type == TX_PUBKEY || type == TX_PUBKEYHASH)) { std::vector<std::vector<unsigned char> >::iterator it = vSolutions.begin(); while( it != vSolutions.end() ) { if ( ( ( type == TX_PUBKEY ) && ( _pubId == Hash160( *it ) ) ) || ( ( type == TX_PUBKEYHASH ) && ( _pubId == uint160( *it ) ) ) ) { if ( !txout.IsNull() ) availableCoins.push_back( CAvailableCoin( txout, i, _hash ) ); break; } it++; } } } return availableCoins; }
#include <stdint.h> #include <sstream> #include <iomanip> #include <limits> #include <cmath> #include <string> #include <stdio.h> BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup) const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32)); const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20)); const unsigned char R2Array[] = "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32)); const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20)); const unsigned char ZeroArray[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32)); const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20)); const unsigned char OneArray[] = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
/** * 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; } }
bool CVmRunEvn::CheckOperate(const vector<CVmOperate> &listoperate) { // judge contract rulue uint64_t addmoey = 0, miusmoney = 0; uint64_t operValue = 0; if(listoperate.size() > MAX_OUTPUT_COUNT) { return false; } for (auto& it : listoperate) { if(it.nacctype != regid && it.nacctype != base58addr) return false; if (it.opeatortype == ADD_FREE ) { memcpy(&operValue,it.money,sizeof(it.money)); uint64_t temp = addmoey; temp += operValue; if(temp < operValue || temp<addmoey) { return false; } addmoey = temp; }else if (it.opeatortype == MINUS_FREE) { //vector<unsigned char > accountid(it.accountid,it.accountid+sizeof(it.accountid)); vector_unsigned_char accountid = GetAccountID(it); if(accountid.size() != 6) return false; CRegID regId(accountid); CTransaction* tx = static_cast<CTransaction*>(listTx.get()); /// current tx's script cant't mius other script's regid if(m_ScriptDBTip->HaveScript(regId) && regId != boost::get<CRegID>(tx->desUserId)) { return false; } memcpy(&operValue,it.money,sizeof(it.money)); uint64_t temp = miusmoney; temp += operValue; if(temp < operValue || temp < miusmoney) { return false; } miusmoney = temp; } else{ // Assert(0); return false; // 输入数据错 } //vector<unsigned char> accountid(it.accountid, it.accountid + sizeof(it.accountid)); vector_unsigned_char accountid = GetAccountID(it); if(accountid.size() == 6){ CRegID regId(accountid); if(regId.IsEmpty() || regId.getKeyID( *m_view) == uint160()) return false; // app only be allowed minus self money if (!m_ScriptDBTip->HaveScript(regId) && it.opeatortype == MINUS_FREE) { return false; } } } if (addmoey != miusmoney) { return false; } return true; }
bool ProcessBlockMsg(BTCMessage &msg) { if (!msg.VerifyChecksum() || msg.vPayload.size()<=80) // something wrong with checksum or length, can't process it return false; // calculate hash of this block uint256 curBlockHash = Hash(msg.vPayload.begin(), msg.vPayload.begin()+80); mysqlpp::Connection *my_conn = mydb.GrabConnection(); // get a database connection if (mydb.IsBlockHashKnown(my_conn, &curBlockHash)) { mydb.ReleaseConnection(my_conn); return true; // nothing to do, as we got already this block somehow (from previous download or unsollicited message) } // now do the real stuff: block is not known yet ChainBlocks newBlock(0); // create new block to add, we don't know ID yet newBlock.hash.assign((char *)curBlockHash.begin(), 32); newBlock.prevhash.assign((char *)&msg.vPayload[4], 32); // first 4 bytes are version number, not checked for now newBlock.height=-2; // height not yet known // --> see if prevBlockHash exists in existing blocks in ChainBlocks int iPrevHeight = mydb.GetBlockHeightFromHash(my_conn, newBlock.prevhash); if (iPrevHeight>=-1) { // this new block has a previous hash of a temporary block with known height newBlock.height=iPrevHeight+1; // so height of this block is known int iBestHeight=mydb.GetBestHeightKnown(my_conn); if (newBlock.height<=iBestHeight) { // height of new block is less or equal then best known temporary --> discard all temp blocks with this height and above for (iPrevHeight=iBestHeight; iPrevHeight>=newBlock.height; iPrevHeight--) mydb.DeleteBlockDataOfHeight(my_conn, iPrevHeight); } } else { // this new block has unknown height if (BTCnode.GetNodeStatus()>4) { // we have an up-to-date block chain, so this is unusual, probably a block fork happened int iSafeHeight = mydb.GetSafeHeight(my_conn); if (iSafeHeight>0) { uint256 hash_start; if (mydb.GetBlockHashFromHeight(my_conn, iSafeHeight, hash_start)) { if (BTCnode.SendMsg_GetBlocks(hash_start, uint256(0))) { BTCnode.Peer_AskedBlockHeight = iSafeHeight + 500; // we asked up to 500 new blocks } } } } } newBlock.status = (newBlock.height>=0)? 1 : 0; // --> add it to ChainBlocks if (mydb.AddBlockToChain(my_conn, newBlock)) { // block added successfully // --> add tx's to ChainTxIns and ChainTxOuts std::vector<unsigned char>::iterator itTxBegin; std::vector<unsigned char>::iterator it=msg.vPayload.begin()+80; // we start at 80 offset with TX data int iNrTransactions = (int)msg.GetVarInt(it); // retrieve the varint indicating number of transactions int iEachTx; mysqlpp::Transaction myTrans(*my_conn); for (iEachTx=0; iEachTx < iNrTransactions; iEachTx++) { // loop through each transaction itTxBegin = it; // remember where current transaction starts for hash calculation later on ChainTxs newTx(newBlock.ID, iEachTx); // insert incomplete Tx as we need referencial integrity on depending TxIns and TxOuts if (mydb.InsertChainTx(my_conn, newTx)) { it +=4; // skip version number int iNrTxIO = (int)msg.GetVarInt(it); // number of input transactions int iEachTxIO; for (iEachTxIO=0; iEachTxIO < iNrTxIO; iEachTxIO++) { // loop through each "in" transaction // we retain only the "OutPoint" Structure, we expect signature to be valid (otherwise it wouldn't be in a block) ChainTxIns newTxIn(newBlock.ID, iEachTx, iEachTxIO); // create record data variable newTxIn.opHash.assign((char *)&it[0],32); // OutPoint hash memcpy(&newTxIn.opN, &it[32], 4); // OutPoint index number it+=36; // skip OutPoint int iVI = (int)msg.GetVarInt(it); // length of script it+=iVI; // skip script it+=4; // skip sequence mydb.InsertChainTxIn(my_conn, newTxIn); } iNrTxIO = (int)msg.GetVarInt(it); // number of output transactions for (iEachTxIO=0; iEachTxIO < iNrTxIO; iEachTxIO++) { // loop through each "out" transaction // we examine the script and extract: value, type and hash(es) ChainTxOuts newTxOut(newBlock.ID, iEachTx, iEachTxIO); // create record data variable memcpy(&newTxOut.value, &it[0], 8); // value of output it+=8; // skip the value newTxOut.txType=0; int iVI = (int)msg.GetVarInt(it); // length of script // examine script to find out the type of transactions if (it[0]<OP_PUSHDATA1) { // script starts with immediate data if (it[0]==65 && it[66]==OP_CHECKSIG) { // transaction is "Transaction to IP address/ Generation" vector<unsigned char> vPubKey(it+1, it+66); // extract Public Key from Msg uint160 uKeyHash = Hash160(vPubKey); newTxOut.smartID.assign((const char *)&uKeyHash, 20); // copy it into record newTxOut.smartIDAdr = Hash160ToAddress(uKeyHash); // store base58 address too newTxOut.storeID.it_is_null(); // storeID is not used newTxOut.txType=2; } } else { if (it[0]==OP_DUP && it[1]==OP_HASH160 && it[2]==20 && it[23]==OP_EQUALVERIFY) { // transaction start = std Tx to BitcoinAddress if (it[24]==OP_CHECKSIG) { // it is standard transaction vector<unsigned char> vKeyHash(it+3, it+23); // extract hash from Msg newTxOut.smartID.assign((const char *)&it[3], 20); // extract hash from Msg newTxOut.smartIDAdr = Hash160ToAddress( uint160(vKeyHash) ); newTxOut.storeID.it_is_null(); newTxOut.txType=1; } else if (1==0) { // our new type of transaction newTxOut.txType=3; } } } it+=iVI; // skip script if (newTxOut.txType!=0) mydb.InsertChainTxOut(my_conn, newTxOut); } // END for each TxOut it+=4; // skip lock time } // END if insert chain ok // iterator it points now to the end of the transaction, now we can calculate the hash of it curBlockHash = Hash(itTxBegin, it); // calculate it newTx.txHash.assign((const char *)&curBlockHash, 32); // transfer to record mydb.UpdateChainTx(my_conn, newTx); // update the already inserted record mydb.TxUnconfirmedDies(my_conn, newTx.txHash); // set life=0 for this unconfirmed tx } // END loop Tx myTrans.commit(); } // END add block mydb.TxUnconfirmedAges(my_conn); mydb.ReleaseConnection(my_conn); return true; }
isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion) { std::vector<valtype> vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) return ISMINE_WATCH_UNSOLVABLE; return ISMINE_NO; } CKeyID keyID; switch (whichType) { case TX_NONSTANDARD: case TX_NULL_DATA: break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) { isInvalid = true; return ISMINE_NO; } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; case TX_WITNESS_V0_KEYHASH: { if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { // We do not support bare witness outputs unless the P2SH version of it would be // acceptable as well. This protects against matching before segwit activates. // This also applies to the P2WSH case. break; } isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; break; } case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (sigversion != SIGVERSION_BASE) { CPubKey pubkey; if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) { isInvalid = true; return ISMINE_NO; } } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; case TX_SCRIPTHASH: { CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { isminetype ret = IsMine(keystore, subscript, isInvalid); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_WITNESS_V0_SCRIPTHASH: { if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { break; } uint160 hash; CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin()); CScriptID scriptID = CScriptID(hash); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the // keys involved. Multi-signature transactions that are // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); if (sigversion != SIGVERSION_BASE) { for (size_t i = 0; i < keys.size(); i++) { if (keys[i].size() != 33) { isInvalid = true; return ISMINE_NO; } } } if (HaveKeys(keys, keystore) == keys.size()) return ISMINE_SPENDABLE; break; } } if (keystore.HaveWatchOnly(scriptPubKey)) { // TODO: This could be optimized some by doing some work after the above solver SignatureData sigs; return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; } return ISMINE_NO; }