void CAuxPow::initAuxPow (CBlockHeader& header) { /* Set auxpow flag right now, since we take the block hash below. */ header.SetAuxpowVersion(true); /* Build a minimal coinbase script input for merge-mining. */ const uint256 blockHash = header.GetHash (); valtype inputData(blockHash.begin (), blockHash.end ()); std::reverse (inputData.begin (), inputData.end ()); inputData.push_back (1); inputData.insert (inputData.end (), 7, 0); /* Fake a parent-block coinbase with just the required input script and no outputs. */ CMutableTransaction coinbase; coinbase.vin.resize (1); coinbase.vin[0].prevout.SetNull (); coinbase.vin[0].scriptSig = (CScript () << inputData); assert (coinbase.vout.empty ()); CTransactionRef coinbaseRef = MakeTransactionRef (coinbase); /* Build a fake parent block with the coinbase. */ CBlock parent; parent.nVersion = 1; parent.vtx.resize (1); parent.vtx[0] = coinbaseRef; parent.hashMerkleRoot = BlockMerkleRoot (parent); /* Construct the auxpow object. */ header.SetAuxpow (new CAuxPow (coinbaseRef)); assert (header.auxpow->vChainMerkleBranch.empty ()); header.auxpow->nChainIndex = 0; assert (header.auxpow->vMerkleBranch.empty ()); header.auxpow->nIndex = 0; header.auxpow->parentBlock = parent; }
/** * Build the genesis block. Note that the output of its generation * transaction cannot be spent since it did not originally exist in the * database. * * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) * vMerkleTree: 4a5e1e */ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "RevolverCoin: Bitcoin Price Hits Six-Month High Amid 5% Surge - Coindesk 27.05"; const CScript genesisOutputScript = CScript() << ParseHex("04e6b3ff62fe1e27e35cabd879eac29e39b45811d061851f790453fc5109c5218bc2a5925a4d2496a38b07a9f531ec037a6207d0f370c1fc41cddd81d202e44203") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); }
// Test suite for ancestor feerate transaction selection. // Implemented as an additional function, rather than a separate test case, // to allow reusing the blockchain created in CreateNewBlock_validity. // Note that this test assumes blockprioritysize is 0. void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransaction *>& txFirst) { // Test the ancestor feerate transaction selection. TestMemPoolEntryHelper entry; // Test that a medium fee transaction will be selected after a higher fee // rate package with a low fee rate parent. CMutableTransaction tx; tx.vin.resize(1); tx.vin[0].scriptSig = CScript() << OP_1; tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].prevout.n = 0; tx.vout.resize(1); tx.vout[0].nValue = 5000000000LL - 1000; // This tx has a low fee: 1000 satoshis uint256 hashParentTx = tx.GetHash(); // save this txid for later use mempool.addUnchecked(hashParentTx, entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); // This tx has a medium fee: 10000 satoshis tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 5000000000LL - 10000; uint256 hashMediumFeeTx = tx.GetHash(); mempool.addUnchecked(hashMediumFeeTx, entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); // This tx has a high fee, but depends on the first transaction tx.vin[0].prevout.hash = hashParentTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee uint256 hashHighFeeTx = tx.GetHash(); mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); CBlockTemplate *pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[1].GetHash() == hashParentTx); BOOST_CHECK(pblocktemplate->block.vtx[2].GetHash() == hashHighFeeTx); BOOST_CHECK(pblocktemplate->block.vtx[3].GetHash() == hashMediumFeeTx); // Test that a package below the min relay fee doesn't get included tx.vin[0].prevout.hash = hashHighFeeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee uint256 hashFreeTx = tx.GetHash(); mempool.addUnchecked(hashFreeTx, entry.Fee(0).FromTx(tx)); size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Calculate a fee on child transaction that will put the package just // below the min relay fee (assuming 1 child tx of the same size). CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; tx.vin[0].prevout.hash = hashFreeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; uint256 hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); // Verify that the free tx and the low fee tx didn't get selected for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx); } // Test that packages above the min relay fee do get included, even if one // of the transactions is below the min relay fee // Remove the low fee transaction and replace with a higher fee transaction std::list<CTransaction> dummy; mempool.removeRecursive(tx, dummy); tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[4].GetHash() == hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[5].GetHash() == hashLowFeeTx); // Test that transaction selection properly updates ancestor fee // calculations as ancestor transactions get included in a block. // Add a 0-fee transaction that has 2 outputs. tx.vin[0].prevout.hash = txFirst[2]->GetHash(); tx.vout.resize(2); tx.vout[0].nValue = 5000000000LL - 100000000; tx.vout[1].nValue = 100000000; // 1BTC output uint256 hashFreeTx2 = tx.GetHash(); mempool.addUnchecked(hashFreeTx2, entry.Fee(0).SpendsCoinbase(true).FromTx(tx)); // This tx can't be mined by itself tx.vin[0].prevout.hash = hashFreeTx2; tx.vout.resize(1); feeToUse = minRelayTxFee.GetFee(freeTxSize); tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; uint256 hashLowFeeTx2 = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); // Verify that this tx isn't selected. for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashFreeTx2); BOOST_CHECK(pblocktemplate->block.vtx[i].GetHash() != hashLowFeeTx2); } // This tx will be mineable, and should cause hashLowFeeTx2 to be selected // as well. tx.vin[0].prevout.n = 1; tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[8].GetHash() == hashLowFeeTx2); }
/** * Build the genesis block. Note that the output of its generation * transaction cannot be spent since it did not originally exist in the * database. * * CBlock(hash=00000ffd590b14, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=e0028e, nTime=1390095618, nBits=1e0ffff0, nNonce=28917698, vtx=1) * CTransaction(hash=e0028e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73) * CTxOut(nValue=50.00000000, scriptPubKey=0xA9037BAC7050C479B121CF) * vMerkleTree: e0028e */ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward, int iNetworkID) { const char* pszTimestamp = "The Independent 11/21/17 Elon Musk slams proposal to create an Artificial Intelligence God"; const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward, iNetworkID); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0x04; pchMessageStart[1] = 0x05; pchMessageStart[2] = 0x05; pchMessageStart[3] = 0x04; nDefaultPort = 25536; nRPCPort = 25537; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 100000; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "Scotcoin!"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1392946703; genesis.nBits = 0x1e0fffff; genesis.nNonce = 168193; //// debug print hashGenesisBlock = genesis.GetHash(); //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x0000020b9d4db902554e1131eee9d0a016e201215b2fd6e7279e4321f99a3e15")); assert(genesis.hashMerkleRoot == uint256("0xa887ab6f2204b79e5af2878efc78e5da804013f94f4e23cb73239b6abbf95ce4")); vSeeds.push_back(CDNSSeedData("someaddress.com or IP addy", "someaddress.com")); base58Prefixes[PUBKEY_ADDRESS] = 63; base58Prefixes[SCRIPT_ADDRESS] = 30; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
bool Solver(const CScript& scriptPubKey, 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)); // Bitcoin 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)); } vSolutionsRet.clear(); // If we have a name script, strip the prefix const CNameScript nameOp(scriptPubKey); const CScript& script1 = nameOp.getAddress(); // 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 (script1.IsPayToScriptHash(false)) { typeRet = TX_SCRIPTHASH; std::vector<unsigned char> hashBytes(script1.begin()+2, script1.begin()+22); vSolutionsRet.push_back(hashBytes); return true; } int witnessversion; std::vector<unsigned char> witnessprogram; if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { if (witnessversion == 0 && witnessprogram.size() == 20) { typeRet = TX_WITNESS_V0_KEYHASH; vSolutionsRet.push_back(witnessprogram); return true; } if (witnessversion == 0 && witnessprogram.size() == 32) { typeRet = TX_WITNESS_V0_SCRIPTHASH; vSolutionsRet.push_back(witnessprogram); return true; } if (witnessversion != 0) { typeRet = TX_WITNESS_UNKNOWN; vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion}); vSolutionsRet.push_back(std::move(witnessprogram)); return true; } return false; } // 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 for (const std::pair<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; }
BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { // Test that passing CheckInputs with one set of script flags doesn't imply // that we would pass again with a different set of flags. { LOCK(cs_main); InitScriptExecutionCache(); } CScript p2pk_scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; CScript p2sh_scriptPubKey = GetScriptForDestination(CScriptID(p2pk_scriptPubKey)); CScript p2pkh_scriptPubKey = GetScriptForDestination(coinbaseKey.GetPubKey().GetID()); CScript p2wpkh_scriptPubKey = GetScriptForWitness(p2pkh_scriptPubKey); CBasicKeyStore keystore; keystore.AddKey(coinbaseKey); keystore.AddCScript(p2pk_scriptPubKey); // flags to test: SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, SCRIPT_VERIFY_CHECKSEQUENCE_VERIFY, SCRIPT_VERIFY_NULLDUMMY, uncompressed pubkey thing // Create 2 outputs that match the three scripts above, spending the first // coinbase tx. CMutableTransaction spend_tx; spend_tx.nVersion = 1; spend_tx.vin.resize(1); spend_tx.vin[0].prevout.hash = m_coinbase_txns[0]->GetHash(); spend_tx.vin[0].prevout.n = 0; spend_tx.vout.resize(4); spend_tx.vout[0].nValue = 11*CENT; spend_tx.vout[0].scriptPubKey = p2sh_scriptPubKey; spend_tx.vout[1].nValue = 11*CENT; spend_tx.vout[1].scriptPubKey = p2wpkh_scriptPubKey; spend_tx.vout[2].nValue = 11*CENT; spend_tx.vout[2].scriptPubKey = CScript() << OP_CHECKLOCKTIMEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; spend_tx.vout[3].nValue = 11*CENT; spend_tx.vout[3].scriptPubKey = CScript() << OP_CHECKSEQUENCEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; // Sign, with a non-DER signature { std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER vchSig.push_back((unsigned char)SIGHASH_ALL); spend_tx.vin[0].scriptSig << vchSig; } // Test that invalidity under a set of flags doesn't preclude validity // under other (eg consensus) flags. // spend_tx is invalid according to DERSIG { LOCK(cs_main); CValidationState state; PrecomputedTransactionData ptd_spend_tx(spend_tx); BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); // If we call again asking for scriptchecks (as happens in // ConnectBlock), we should add a script check object for this -- we're // not caching invalidity (if that changes, delete this test case). std::vector<CScriptCheck> scriptchecks; BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); // Test that CheckInputs returns true iff DERSIG-enforcing flags are // not present. Don't add these checks to the cache, so that we can // test later that block validation works fine in the absence of cached // successes. ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false); } // And if we produce a block with this tx, it should be valid (DERSIG not // enabled yet), even though there's no cache entry. CBlock block; block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); LOCK(cs_main); // Test P2SH: construct a transaction that is valid without P2SH, and // then test validity with P2SH. { CMutableTransaction invalid_under_p2sh_tx; invalid_under_p2sh_tx.nVersion = 1; invalid_under_p2sh_tx.vin.resize(1); invalid_under_p2sh_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_under_p2sh_tx.vin[0].prevout.n = 0; invalid_under_p2sh_tx.vout.resize(1); invalid_under_p2sh_tx.vout[0].nValue = 11*CENT; invalid_under_p2sh_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end()); invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; ValidateCheckInputsForAllFlags(invalid_under_p2sh_tx, SCRIPT_VERIFY_P2SH, true); } // Test CHECKLOCKTIMEVERIFY { CMutableTransaction invalid_with_cltv_tx; invalid_with_cltv_tx.nVersion = 1; invalid_with_cltv_tx.nLockTime = 100; invalid_with_cltv_tx.vin.resize(1); invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_with_cltv_tx.vin[0].prevout.n = 2; invalid_with_cltv_tx.vin[0].nSequence = 0; invalid_with_cltv_tx.vout.resize(1); invalid_with_cltv_tx.vout[0].nValue = 11*CENT; invalid_with_cltv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; ValidateCheckInputsForAllFlags(invalid_with_cltv_tx, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true); // Make it valid, and check again invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_cltv_tx); BOOST_CHECK(CheckInputs(invalid_with_cltv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); } // TEST CHECKSEQUENCEVERIFY { CMutableTransaction invalid_with_csv_tx; invalid_with_csv_tx.nVersion = 2; invalid_with_csv_tx.vin.resize(1); invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_with_csv_tx.vin[0].prevout.n = 3; invalid_with_csv_tx.vin[0].nSequence = 100; invalid_with_csv_tx.vout.resize(1); invalid_with_csv_tx.vout[0].nValue = 11*CENT; invalid_with_csv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; ValidateCheckInputsForAllFlags(invalid_with_csv_tx, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true); // Make it valid, and check again invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_csv_tx); BOOST_CHECK(CheckInputs(invalid_with_csv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); } // TODO: add tests for remaining script flags // Test that passing CheckInputs with a valid witness doesn't imply success // for the same tx with a different witness. { CMutableTransaction valid_with_witness_tx; valid_with_witness_tx.nVersion = 1; valid_with_witness_tx.vin.resize(1); valid_with_witness_tx.vin[0].prevout.hash = spend_tx.GetHash(); valid_with_witness_tx.vin[0].prevout.n = 1; valid_with_witness_tx.vout.resize(1); valid_with_witness_tx.vout[0].nValue = 11*CENT; valid_with_witness_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign SignatureData sigdata; ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata); UpdateTransaction(valid_with_witness_tx, 0, sigdata); // This should be valid under all script flags. ValidateCheckInputsForAllFlags(valid_with_witness_tx, 0, true); // Remove the witness, and check that it is now invalid. valid_with_witness_tx.vin[0].scriptWitness.SetNull(); ValidateCheckInputsForAllFlags(valid_with_witness_tx, SCRIPT_VERIFY_WITNESS, true); } { // Test a transaction with multiple inputs. CMutableTransaction tx; tx.nVersion = 1; tx.vin.resize(2); tx.vin[0].prevout.hash = spend_tx.GetHash(); tx.vin[0].prevout.n = 0; tx.vin[1].prevout.hash = spend_tx.GetHash(); tx.vin[1].prevout.n = 1; tx.vout.resize(1); tx.vout[0].nValue = 22*CENT; tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign for (int i=0; i<2; ++i) { SignatureData sigdata; ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata); UpdateTransaction(tx, i, sigdata); } // This should be valid under all script flags ValidateCheckInputsForAllFlags(tx, 0, true); // Check that if the second input is invalid, but the first input is // valid, the transaction is not cached. // Invalidate vin[1] tx.vin[1].scriptWitness.SetNull(); CValidationState state; PrecomputedTransactionData txdata(tx); // This transaction is now invalid under segwit, because of the second input. BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); std::vector<CScriptCheck> scriptchecks; // Make sure this transaction was not cached (ie because the first // input was valid) BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction basis. BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); } }
/** * 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; }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0xaf; pchMessageStart[1] = 0x45; pchMessageStart[2] = 0x76; pchMessageStart[3] = 0xee; vAlertPubKey = ParseHex("04a82e43bebee0af77bb6d4f830c5b2095b7479a480e91bbbf3547fb261c5e6d1be2c27e3c57503f501480f5027371ec62b2be1b6f00fc746e4b3777259e7f6a78"); nDefaultPort = 10888; nRPCPort = 10889; bnProofOfWorkLimit[ALGO_SHA256D] = CBigNum(~uint256(0) >> 20); bnProofOfWorkLimit[ALGO_SCRYPT] = CBigNum(~uint256(0) >> 20); bnProofOfWorkLimit[ALGO_GROESTL] = CBigNum(~uint256(0) >> 20); bnProofOfWorkLimit[ALGO_SKEIN] = CBigNum(~uint256(0) >> 20); bnProofOfWorkLimit[ALGO_QUBIT] = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 80640 * 12; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "2014-02-23 FT - G20 aims to add $2tn to global economy"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1000 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04e941763c7750969e751bee1ffbe96a651a0feb131db046546c219ea40bff40b95077dc9ba1c05af991588772d8daabbda57386c068fb9bc7477c5e28702d5eb9") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = BLOCK_VERSION_DEFAULT; genesis.nTime = 1393164995; genesis.nBits = 0x1e0fffff; genesis.nNonce = 2092903596; //// debug print hashGenesisBlock = genesis.GetHash(); //while (hashGenesisBlock > bnProofOfWorkLimit[ALGO_SHA256D].getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} //printf("MAIN: %s\n", hashGenesisBlock.ToString().c_str()); //printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); //printf("%x\n", bnProofOfWorkLimit[ALGO_SHA256D].GetCompact()); //genesis.print(); assert(hashGenesisBlock == uint256("0x00000ffde4c020b5938441a0ea3d314bf619eff0b38f32f78f7583cffa1ea485")); assert(genesis.hashMerkleRoot == uint256("0x3f75db3c18e92f46c21530dc1222e1fddf4ccebbf88e289a6c9dc787fd6469da")); vSeeds.push_back(CDNSSeedData("seed1.myriadcoin.org", "seed1.myriadcoin.org")); vSeeds.push_back(CDNSSeedData("seed2.myriadcoin.org", "seed2.myriadcoin.org")); vSeeds.push_back(CDNSSeedData("seed3.myriadcoin.org", "seed3.myriadcoin.org")); vSeeds.push_back(CDNSSeedData("seed4.myriadcoin.org", "seed4.myriadcoin.org")); base58Prefixes[PUBKEY_ADDRESS] = 50; base58Prefixes[SCRIPT_ADDRESS] = 9; base58Prefixes[SECRET_KEY] = 178; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
// 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); } // Serialize and hash CHashWriter ss(SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS); ss << txTmp << nHashType; return ss.GetHash(); }
/** * Build the genesis block. Note that the output of its generation * transaction cannot be spent since it did not originally exist in the * database. * * CBlock(hash=00000ffd590b14, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=e0028e, nTime=1390095618, nBits=1e0ffff0, nNonce=28917698, vtx=1) * CTransaction(hash=e0028e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73) * CTxOut(nValue=50.00000000, scriptPubKey=0xA9037BAC7050C479B121CF) * vMerkleTree: e0028e */ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "The history of Bangkok dates at least back to the early 15th century"; const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0x1a; pchMessageStart[1] = 0x2b; pchMessageStart[2] = 0x3c; pchMessageStart[3] = 0x4e; vAlertPubKey = ParseHex("045337216002ca6a71d63edf062895417610a723d453e722bf4728996c58661cdac3d4dec5cecd449b9086e9602b35cc726a9e0163e1a4d40f521fbdaebb674658"); nDefaultPort = 7921; nRPCPort = 7920; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 80640; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. //00000e1b77bd39ddb4b76f58a766ba0f40653977d3d9a20ded261a28b51074df //f592dac23841d61ab7b74c5f13e73e7db5e176fae4aa8b37048af74ce9d46005 //1e0fffff //CBlock(hash=00000e1b77bd39ddb4b76f58a766ba0f40653977d3d9a20ded261a28b51074df, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=f592dac23841d61ab7b74c5f13e73e7db5e176fae4aa8b37048af74ce9d46005, nTime=1388822738, nBits=1e0fffff, nNonce=238626, vtx=1) //CTransaction(hash=f592dac238, ver=1, vin.size=1, vout.size=1, nLockTime=0) //CTxIn(COutPoint(0000000000, 4294967295), coinbase 04ffff001d010408312d342d32303134) //CTxOut(nValue=1000.00000000, scriptPubKey=04678afdb0fe5548271967f1a67130) //vMerkleTree: f592dac23841d61ab7b74c5f13e73e7db5e176fae4aa8b37048af74ce9d46005 const char* pszTimestamp = "1-4-2014"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1000 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1388874174; genesis.nBits = 0x1e0fffff; genesis.nNonce = 758274; //// debug print hashGenesisBlock = genesis.GetHash(); //comment out //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} //comment out printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x00000887c81496d79ff7d6467a25cc6a52d9ed457e787c8b9a6bca4e5441b012")); assert(genesis.hashMerkleRoot == uint256("0xf592dac23841d61ab7b74c5f13e73e7db5e176fae4aa8b37048af74ce9d46005")); //vSeeds.push_back(CDNSSeedData("192.168.1.112", "192.168.1.112")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); //vSeeds.push_back(CDNSSeedData("", "")); base58Prefixes[PUBKEY_ADDRESS] = 50; base58Prefixes[SCRIPT_ADDRESS] = 9; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
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); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64_t> > vecSend; std::string sNarr; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); sNarr = rcp.reference.toStdString(); if (sNarr.length() > 0) { if (sNarr.length() > 50) { printf("Reference is too long.\n"); return ReferenceTooLong; }; std::vector<uint8_t> vNarr(sNarr.c_str(), sNarr.c_str() + sNarr.length()); CScript scriptN = CScript() << OP_RETURN << vNarr; vecSend.push_back(make_pair(scriptN, 0)); } } CWalletTx wtx; if (sNarr.length() > 0) { wtx.mapValue["reference"] = sNarr; } CReserveKey keyChange(wallet); int64_t nFeeRequired = 0; 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(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. // The characters are rarely used upper ASCII, not valid as UTF-8, and produce // a large 4-byte int at any alignment. pchMessageStart[0] = 0xc7; pchMessageStart[1] = 0xa1; pchMessageStart[2] = 0xf6; pchMessageStart[3] = 0xc9; //chimark vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 58778; nRPCPort = 58777; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 770000; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. // const char* pszTimestamp = "Dec 2013 light speed X-day"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1389429187; genesis.nBits = 0x1e0fffff; //chimark genesis.nNonce = 1030111; hashGenesisBlock = genesis.GetHash(); //// debug print //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x00000a8f9572e068cffbdb30c23f698e659e1e2e13e51cfcb8114fa5df38ffee")); assert(genesis.hashMerkleRoot == uint256("0x91c7edee50dd32d8544412f4cef06f8812723eefe8fec24fd3e66d92f83b1b9e")); vSeeds.push_back(CDNSSeedData("chicoin.sipa.be", "seed.chicoin.sipa.be")); vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.chicoin.dashjr.org")); vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); base58Prefixes[PUBKEY_ADDRESS] = 27; base58Prefixes[SCRIPT_ADDRESS] = 29; base58Prefixes[SECRET_KEY] = 127; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0x03; pchMessageStart[1] = 0xd5; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0x03; nDefaultPort = 65534; nRPCPort = 65535; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 100000; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "San Francisco plaza evacuated after suspicious package is found"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1375548986; genesis.nBits = 0x1e0fffff; genesis.nNonce = 1211565; //// debug print hashGenesisBlock = genesis.GetHash(); //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x000004c2fc5fffb810dccc197d603690099a68305232e552d96ccbe8e2c52b75")); assert(genesis.hashMerkleRoot == uint256("0x36a192e90f70131a884fe541a1e8a5643a28ba4cb24cbb2924bd0ee483f7f484")); vSeeds.push_back(CDNSSeedData("andarazoroflove.org", "andarazoroflove.org")); vSeeds.push_back(CDNSSeedData("rockchain.info", "rockchain.info")); base58Prefixes[PUBKEY_ADDRESS] = 130; base58Prefixes[SCRIPT_ADDRESS] = 30; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
// Right now this is only testing eviction performance in an extremely small // mempool. Code needs to be written to generate a much wider variety of // unique transactions for a more meaningful performance measurement. static void MempoolEviction(benchmark::State& state) { CMutableTransaction tx1 = CMutableTransaction(); tx1.vin.resize(1); tx1.vin[0].scriptSig = CScript() << OP_1; tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; CMutableTransaction tx2 = CMutableTransaction(); tx2.vin.resize(1); tx2.vin[0].scriptSig = CScript() << OP_2; tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; tx2.vout[0].nValue = 10 * COIN; CMutableTransaction tx3 = CMutableTransaction(); tx3.vin.resize(1); tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0); tx3.vin[0].scriptSig = CScript() << OP_2; tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; tx3.vout[0].nValue = 10 * COIN; CMutableTransaction tx4 = CMutableTransaction(); tx4.vin.resize(2); tx4.vin[0].prevout.SetNull(); tx4.vin[0].scriptSig = CScript() << OP_4; tx4.vin[1].prevout.SetNull(); tx4.vin[1].scriptSig = CScript() << OP_4; tx4.vout.resize(2); tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL; tx4.vout[0].nValue = 10 * COIN; tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL; tx4.vout[1].nValue = 10 * COIN; CMutableTransaction tx5 = CMutableTransaction(); tx5.vin.resize(2); tx5.vin[0].prevout = COutPoint(tx4.GetHash(), 0); tx5.vin[0].scriptSig = CScript() << OP_4; tx5.vin[1].prevout.SetNull(); tx5.vin[1].scriptSig = CScript() << OP_5; tx5.vout.resize(2); tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL; tx5.vout[0].nValue = 10 * COIN; tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL; tx5.vout[1].nValue = 10 * COIN; CMutableTransaction tx6 = CMutableTransaction(); tx6.vin.resize(2); tx6.vin[0].prevout = COutPoint(tx4.GetHash(), 1); tx6.vin[0].scriptSig = CScript() << OP_4; tx6.vin[1].prevout.SetNull(); tx6.vin[1].scriptSig = CScript() << OP_6; tx6.vout.resize(2); tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL; tx6.vout[0].nValue = 10 * COIN; tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL; tx6.vout[1].nValue = 10 * COIN; CMutableTransaction tx7 = CMutableTransaction(); tx7.vin.resize(2); tx7.vin[0].prevout = COutPoint(tx5.GetHash(), 0); tx7.vin[0].scriptSig = CScript() << OP_5; tx7.vin[1].prevout = COutPoint(tx6.GetHash(), 0); tx7.vin[1].scriptSig = CScript() << OP_6; tx7.vout.resize(2); tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[0].nValue = 10 * COIN; tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[1].nValue = 10 * COIN; CTxMemPool pool(CFeeRate(1000)); while (state.KeepRunning()) { AddTx(tx1, 10000LL, pool); AddTx(tx2, 5000LL, pool); AddTx(tx3, 20000LL, pool); AddTx(tx4, 7000LL, pool); AddTx(tx5, 1000LL, pool); AddTx(tx6, 1100LL, pool); AddTx(tx7, 9000LL, pool); pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); pool.TrimToSize(GetVirtualTransactionSize(tx1)); } }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0xa5; pchMessageStart[1] = 0xc0; pchMessageStart[2] = 0x79; pchMessageStart[3] = 0x55; vAlertPubKey = ParseHex("000000000007840aaf100de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 32333; nRPCPort = 32332; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 32); nSubsidyHalvingInterval = 126000; // 1 year // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "CNN 23/10/2013 Scientists find gold growing on trees in Australia"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1382532797; genesis.nBits = 0x1d00ffff; genesis.nNonce = 704106316; //// debug print hashGenesisBlock = genesis.GetHash(); //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x000000008ef7da946aa3f4dd81b240c6bdedac0dc038cb04e7cf8e60f37d9281")); assert(genesis.hashMerkleRoot == uint256("0xd25dbe3a2852926fc2ec6591a95983bbcde80c449f30ced37fd657361073fa96")); vSeeds.push_back(CDNSSeedData("seed1.betacoin.org", "seed1.betacoin.org")); vSeeds.push_back(CDNSSeedData("seed2.betacoin.org", "seed2.betacoin.org")); vSeeds.push_back(CDNSSeedData("seed3.betacoin.org", "seed3.betacoin.org")); vSeeds.push_back(CDNSSeedData("seed4.betacoin.org", "seed4.betacoin.org")); vSeeds.push_back(CDNSSeedData("seed5.betacoin.org", "seed5.betacoin.org")); vSeeds.push_back(CDNSSeedData("seed6.betacoin.org", "seed6.betacoin.org")); base58Prefixes[PUBKEY_ADDRESS] = 25; base58Prefixes[SCRIPT_ADDRESS] = 11; base58Prefixes[SECRET_KEY] = 143; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx) { int64_t nTimeStart = GetTimeMicros(); resetBlock(); pblocktemplate.reset(new CBlockTemplate()); if(!pblocktemplate.get()) return nullptr; pblock = &pblocktemplate->block; // pointer for convenience // Add dummy coinbase tx as first transaction pblock->vtx.emplace_back(); pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios if (chainparams.MineBlocksOnDemand()) pblock->nVersion = gArgs.GetArg("-blockversion", pblock->nVersion); pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime(); // Decide whether to include witness transactions // This is only needed in case the witness softfork activation is reverted // (which would require a very deep reorganization) or when // -promiscuousmempoolflags is used. // TODO: replace this with a call to main to assess validity of a mempool // transaction (which in most cases can be a no-op). fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx; int nPackagesSelected = 0; int nDescendantsUpdated = 0; addPackageTxs(nPackagesSelected, nDescendantsUpdated); int64_t nTime1 = GetTimeMicros(); nLastBlockTx = nBlockTx; nLastBlockWeight = nBlockWeight; // Create coinbase transaction. CMutableTransaction coinbaseTx; coinbaseTx.vin.resize(1); coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx)); pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; LogPrintf("CreateNewBlock(): block weight: %u txs: %u fees: %ld sigops %d\n", GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost); // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]); CValidationState state; if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); } int64_t nTime2 = GetTimeMicros(); LogPrint(BCLog::BENCH, "CreateNewBlock() packages: %.2fms (%d packages, %d updated descendants), validity: %.2fms (total %.2fms)\n", 0.001 * (nTime1 - nTimeStart), nPackagesSelected, nDescendantsUpdated, 0.001 * (nTime2 - nTime1), 0.001 * (nTime2 - nTimeStart)); return std::move(pblocktemplate); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0xf7; pchMessageStart[1] = 0x26; pchMessageStart[2] = 0xa1; pchMessageStart[3] = 0xbf; vAlertPubKey = ParseHex("04e41db2a8b8dc3981f819d46060875ce483bf303613b108e673d7bb636f7786bd0458e2ced6e8b337be32d024562f3e69776412b55a7210396ad7a9944812b445"); nDefaultPort = 48481; nRPCPort = 48480; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 262800; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "Tone Abbet Does it again"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = COIN / 10000; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1403852000; genesis.nBits = 0x1e0fffff; genesis.nNonce = 1376737; //// debug print hashGenesisBlock = genesis.GetHash(); while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ if (++genesis.nNonce==0) break; hashGenesisBlock = genesis.GetHash(); } printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); /*if (false && (genesis.GetHash() != hashGenesisBlock)) { // This will figure out a valid hash and Nonce if you're // creating a different genesis block: uint256 hashTarget = CBigNum().SetCompact(genesis.nBits).getuint256(); while (genesis.GetHash() > hashTarget) { ++genesis.nNonce; if (genesis.nNonce == 0) { printf("NONCE WRAPPED, incrementing time"); ++genesis.nTime; } } } //// debug print genesis.print(); printf("genesis.GetHash() == %s\n", genesis.GetHash().ToString().c_str()); printf("genesis.hashMerkleRoot == %s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("genesis.nTime = %u \n", genesis.nTime); printf("genesis.nNonce = %u \n", genesis.nNonce); */ assert(hashGenesisBlock == uint256("0x00000dffc654ad0a8d9055536135b69d71dcd878d901508fc9381bde67bf0645")); assert(genesis.hashMerkleRoot == uint256("0x94076775c950c86d89bc2225c87bcb4e29621b57d5e9b430d7fa190078b0e980")); vSeeds.push_back(CDNSSeedData("162.248.4.167", "162.248.4.167")); vSeeds.push_back(CDNSSeedData("seed2.whirlcoin.org", "seed2.whirlcoin.org")); vSeeds.push_back(CDNSSeedData("seed3.whirlcoin.org", "seed3.whirlcoin.org")); vSeeds.push_back(CDNSSeedData("whirlcoin.zapto.org", "whirlcoin.zapto.org")); vSeeds.push_back(CDNSSeedData("whirlcoin.no-ip.org", "whirlcoin.no-ip.org")); vSeeds.push_back(CDNSSeedData("whirlcoin.strangled.net", "whirlcoin.strangled.net")); vSeeds.push_back(CDNSSeedData("whirlcoin.ignorelist.com", "whirlcoin.ignorelist.com")); base58Prefixes[PUBKEY_ADDRESS] = 73; base58Prefixes[SCRIPT_ADDRESS] = 12; base58Prefixes[SECRET_KEY] = 226; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) { // Make sure skipping validation of transactions that were // validated going into the memory pool does not allow // double-spends in blocks to pass validation when they should not. CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; // Create a double-spend of mature coinbase txn: std::vector<CMutableTransaction> spends; spends.resize(2); for (int i = 0; i < 2; i++) { spends[i].nVersion = 1; spends[i].vin.resize(1); spends[i].vin[0].prevout.hash = m_coinbase_txns[0]->GetHash(); spends[i].vin[0].prevout.n = 0; spends[i].vout.resize(1); spends[i].vout[0].nValue = 11*CENT; spends[i].vout[0].scriptPubKey = scriptPubKey; // Sign: std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); spends[i].vin[0].scriptSig << vchSig; } CBlock block; // Test 1: block with both of those transactions should be rejected. block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); } // Test 2: ... and should be rejected if spend1 is in the memory pool BOOST_CHECK(ToMemPool(spends[0])); block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); } mempool.clear(); // Test 3: ... and should be rejected if spend2 is in the memory pool BOOST_CHECK(ToMemPool(spends[1])); block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); } mempool.clear(); // Final sanity test: first spend in mempool, second in block, that's OK: std::vector<CMutableTransaction> oneSpend; oneSpend.push_back(spends[0]); BOOST_CHECK(ToMemPool(spends[1])); block = CreateAndProcessBlock(oneSpend, scriptPubKey); { LOCK(cs_main); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); } // spends[1] should have been removed from the mempool when the // block with spends[0] is accepted: BOOST_CHECK_EQUAL(mempool.size(), 0U); }
CScript GetScriptForRawPubKey(const CPubKey& pubKey) { return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG; }
static UniValue getblocktemplate(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" "For full specification, see BIPs 22, 23, 9, and 145:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" "\nArguments:\n" "1. template_request (json object, optional) A json object in the following spec\n" " {\n" " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" " \"capabilities\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" " ],\n" " \"rules\":[ (array, optional) A list of strings\n" " \"support\" (string) client side supported softfork deployment\n" " ,...\n" " ]\n" " }\n" "\n" "\nResult:\n" "{\n" " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" " \"depends\" : [ (array) array of numbers \n" " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" " }\n" " ,...\n" " ],\n" " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)\n" " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" " \"target\" : \"xxxx\", (string) The hash target\n" " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblocktemplate", "{\"rules\": [\"segwit\"]}") + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}") ); LOCK(cs_main); std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; int64_t nMaxVersionPreVB = -1; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) { /* Do nothing */ } else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); if (strMode == "proposal") { const UniValue& dataval = find_value(oparam, "data"); if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; if (!DecodeHexBlk(block, dataval.get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); uint256 hash = block.GetHash(); const CBlockIndex* pindex = LookupBlockIndex(hash); if (pindex) { if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) return "duplicate"; if (pindex->nStatus & BLOCK_FAILED_MASK) return "duplicate-invalid"; return "duplicate-inconclusive"; } CBlockIndex* const pindexPrev = chainActive.Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } const UniValue& aClientRules = find_value(oparam, "rules"); if (aClientRules.isArray()) { for (unsigned int i = 0; i < aClientRules.size(); ++i) { const UniValue& v = aClientRules[i]; setClientRules.insert(v.get_str()); } } else { // NOTE: It is important that this NOT be read if versionbits is supported const UniValue& uvMaxVersion = find_value(oparam, "maxversion"); if (uvMaxVersion.isNum()) { nMaxVersionPreVB = uvMaxVersion.get_int64(); } } } if (strMode != "template") throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!"); if (IsInitialBlockDownload()) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks..."); static unsigned int nTransactionsUpdatedLast; if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; std::chrono::steady_clock::time_point checktxtime; unsigned int nTransactionsUpdatedLastLP; if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid"); nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64)); } else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier hashWatchedChain = chainActive.Tip()->GetBlockHash(); nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } // Release the wallet and main lock while waiting LEAVE_CRITICAL_SECTION(cs_main); { checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1); WAIT_LOCK(g_best_block_mutex, lock); while (g_best_block == hashWatchedChain && IsRPCRunning()) { if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout) { // Timeout: Check transactions for update if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += std::chrono::seconds(10); } } } ENTER_CRITICAL_SECTION(cs_main); if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners? } const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; // If the caller is indicating segwit support, then allow CreateNewBlock() // to select witness transactions, after segwit activates (otherwise // don't). bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end(); // Update block static CBlockIndex* pindexPrev; static int64_t nStart; static std::unique_ptr<CBlockTemplate> pblocktemplate; // Cache whether the last invocation was with segwit support, to avoid returning // a segwit-block to a non-segwit caller. static bool fLastTemplateSupportsSegwit = true; if (pindexPrev != chainActive.Tip() || (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) || fLastTemplateSupportsSegwit != fSupportsSegwit) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; // Store the pindexBest used before CreateNewBlock, to avoid races nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainActive.Tip(); nStart = GetTime(); fLastTemplateSupportsSegwit = fSupportsSegwit; // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); // Need to update only after we know CreateNewBlock succeeded pindexPrev = pindexPrevNew; } assert(pindexPrev); CBlock* pblock = &pblocktemplate->block; // pointer for convenience const Consensus::Params& consensusParams = Params().GetConsensus(); // Update nTime UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); std::map<uint256, int64_t> setTxIndex; int i = 0; for (const auto& it : pblock->vtx) { const CTransaction& tx = *it; uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; UniValue entry(UniValue::VOBJ); entry.pushKV("data", EncodeHexTx(tx)); entry.pushKV("txid", txHash.GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn &in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } entry.pushKV("depends", deps); int index_in_template = i - 1; entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template]; if (fPreSegWit) { assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0); nTxSigOps /= WITNESS_SCALE_FACTOR; } entry.pushKV("sigops", nTxSigOps); entry.pushKV("weight", GetTransactionWeight(tx)); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); UniValue aMutable(UniValue::VARR); aMutable.push_back("time"); aMutable.push_back("transactions"); aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); result.pushKV("capabilities", aCaps); UniValue aRules(UniValue::VARR); UniValue vbavailable(UniValue::VOBJ); for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { Consensus::DeploymentPos pos = Consensus::DeploymentPos(j); ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache); switch (state) { case ThresholdState::DEFINED: case ThresholdState::FAILED: // Not exposed to GBT at all break; case ThresholdState::LOCKED_IN: // Ensure bit is set in block version pblock->nVersion |= VersionBitsMask(consensusParams, pos); // FALL THROUGH to get vbavailable set... case ThresholdState::STARTED: { const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; vbavailable.pushKV(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { if (!vbinfo.gbt_force) { // If the client doesn't support this, don't indicate it in the [default] version pblock->nVersion &= ~VersionBitsMask(consensusParams, pos); } } break; } case ThresholdState::ACTIVE: { // Add to rules only const struct VBDeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos]; aRules.push_back(gbt_vb_name(pos)); if (setClientRules.find(vbinfo.name) == setClientRules.end()) { // Not supported by the client; make sure it's safe to proceed if (!vbinfo.gbt_force) { // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name)); } } break; } } } result.pushKV("version", pblock->nVersion); result.pushKV("rules", aRules); result.pushKV("vbavailable", vbavailable); result.pushKV("vbrequired", int(0)); if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); } result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); result.pushKV("transactions", transactions); result.pushKV("coinbaseaux", aux); result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue); result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1); result.pushKV("mutable", aMutable); result.pushKV("noncerange", "00000000ffffffff"); int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE; if (fPreSegWit) { assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); nSigOpLimit /= WITNESS_SCALE_FACTOR; assert(nSizeLimit % WITNESS_SCALE_FACTOR == 0); nSizeLimit /= WITNESS_SCALE_FACTOR; } result.pushKV("sigoplimit", nSigOpLimit); result.pushKV("sizelimit", nSizeLimit); if (!fPreSegWit) { result.pushKV("weightlimit", (int64_t)MAX_BLOCK_WEIGHT); } result.pushKV("curtime", pblock->GetBlockTime()); result.pushKV("bits", strprintf("%08x", pblock->nBits)); result.pushKV("height", (int64_t)(pindexPrev->nHeight+1)); if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) { result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())); } return result; }
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56"; const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. printf("main params\n"); pchMessageStart[0] = 0x09; pchMessageStart[1] = 0x08; pchMessageStart[2] = 0x2c; pchMessageStart[3] = 0xab; nDefaultPort = 46110; nRPCPort = 46111; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 100000; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "The Times 5-6-14 30 rebels die in battle to retake Slovyansk"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1399374629; genesis.nBits = 0x1e0fffff; genesis.nNonce = 1141676; //// debug print hashGenesisBlock = genesis.GetHash(); /* while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ if (++genesis.nNonce==0) break; hashGenesisBlock = genesis.GetHash(); } printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); */ assert(hashGenesisBlock == uint256("0x00000303a4dc1ffd6b7bf5419ac44798d089eb788aa2e521a42b6f20810b2438")); assert(genesis.hashMerkleRoot == uint256("0x8c5a7bbd33316019cfbf75a6ec78c02ab7ff2529abc36dd31e3b3aaa193c9e82")); //vSeeds.push_back(CDNSSeedData("someaddress.com or IP addy", "someaddress.com")); base58Prefixes[PUBKEY_ADDRESS] = 73; //W base58Prefixes[SCRIPT_ADDRESS] = 30; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
CScript* CScriptManager::AddScript(tstring sName) { m_aScripts[sName] = CScript(); return &m_aScripts[sName]; }
/** * Build the genesis block. Note that the output of its generation * transaction cannot be spent since it did not originally exist in the * database. * * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=167230846, vtx=1) * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d01043f5468652054696d65732031382f4a616e2f323031382042696c6c696f6e616972652042756666657474207374696c6c2064656e79696e6720426974636f696e) * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) * vMerkleTree: 4a5e1e */ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "The Times 14/Mar/2018 Stephen Hawking dies aged 76"; const CScript genesisOutputScript = CScript() << ParseHex("04908afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0xb6; pchMessageStart[1] = 0xb6; pchMessageStart[2] = 0xb6; pchMessageStart[3] = 0xb6; nDefaultPort = 48327; nRPCPort = 48328; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 100000; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "Nadecoin"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1300000000; genesis.nBits = 0x1e0fffff; genesis.nNonce = 0; //// debug print hashGenesisBlock = genesis.GetHash(); //while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ // if (++genesis.nNonce==0) break; // hashGenesisBlock = genesis.GetHash(); //} printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x5c85b50a51b3437abdf0ed22d984278d4f95e60650966ecc179e84d7d1a1a271")); assert(genesis.hashMerkleRoot == uint256("0xc3ab53bcf6c4174ab22abec6923320e6f2af142fc3ec9c6c6f36065db7d02940")); vSeeds.push_back(CDNSSeedData("google.org", "google.org")); base58Prefixes[PUBKEY_ADDRESS] = 36; base58Prefixes[SCRIPT_ADDRESS] = 30; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
CMainParams() { // The message start string is designed to be unlikely to occur in normal data. pchMessageStart[0] = 0x0A; pchMessageStart[1] = 0x05; pchMessageStart[2] = 0x03; pchMessageStart[3] = 0x0C; nDefaultPort = 10240; nRPCPort = 10241; bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); nSubsidyHalvingInterval = 102400; // Build the genesis block. Note that the output of the genesis coinbase cannot // be spent as it did not originally exist in the database. const char* pszTimestamp = "ImperialCoin's Reign Has Started!"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 1 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("") << OP_CHECKSIG; genesis.vtx.push_back(txNew); genesis.hashPrevBlock = 0; genesis.hashMerkleRoot = genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime = 1393638000; genesis.nBits = 0x1e0fffff; genesis.nNonce = 0; //// debug print hashGenesisBlock = genesis.GetHash(); while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){ if (++genesis.nNonce==0) break; hashGenesisBlock = genesis.GetHash(); } printf("%s\n", hashGenesisBlock.ToString().c_str()); printf("%s\n", genesis.hashMerkleRoot.ToString().c_str()); printf("%x\n", bnProofOfWorkLimit.GetCompact()); genesis.print(); assert(hashGenesisBlock == uint256("0x")); assert(genesis.hashMerkleRoot == uint256("0x")); vSeeds.push_back(CDNSSeedData("68.232.180.111", "68.232.180.111")); base58Prefixes[PUBKEY_ADDRESS] = 1; base58Prefixes[SCRIPT_ADDRESS] = 30; base58Prefixes[SECRET_KEY] = 224; // Convert the pnSeeds array into usable address objects. for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. // Seed nodes are given a random 'last seen time' const int64 nTwoDays = 2 * 24 * 60 * 60; struct in_addr ip; memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - GetRand(nTwoDays) - nTwoDays; vFixedSeeds.push_back(addr); } }
/** * Build the genesis block. Note that the output of its generation * transaction cannot be spent since it did not originally exist in the * database. * * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) * vMerkleTree: 4a5e1e */ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); }
// // Bootup the masternode, look for a 10000 PEPE input and register on the network // void CActiveMasternode::ManageStatus() { std::string errorMessage; if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); if(!fMasterNode) return; //need correct adjusted time to send ping bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) { status = MASTERNODE_SYNC_IN_PROCESS; LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n"); return; } if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){ status = MASTERNODE_NOT_PROCESSED; } if(status == MASTERNODE_NOT_PROCESSED) { if(strMasterNodeAddr.empty()) { if(!GetLocal(service)) { notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } } else { service = CService(strMasterNodeAddr, true); } LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str()); if(!ConnectNode((CAddress)service, service.ToString().c_str())){ notCapableReason = "Could not connect to " + service.ToString(); status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } if(pwalletMain->IsLocked()){ notCapableReason = "Wallet is locked."; status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); return; } // Set defaults status = MASTERNODE_NOT_CAPABLE; notCapableReason = "Unknown. Check debug.log for more information.\n"; // Choose coins to use CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) { if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ notCapableReason = "Input must have least " + boost::lexical_cast<string>(MASTERNODE_MIN_CONFIRMATIONS) + " confirmations - " + boost::lexical_cast<string>(GetInputAge(vin)) + " confirmations"; LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason.c_str()); status = MASTERNODE_INPUT_TOO_NEW; return; } LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); status = MASTERNODE_IS_CAPABLE; notCapableReason = ""; pwalletMain->LockCoin(vin.prevout); // send to all nodes CPubKey pubKeyMasternode; CKey keyMasternode; if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) { LogPrintf("ActiveMasternode::Dseep() - Error upon calling SetKey: %s\n", errorMessage.c_str()); return; } /* donations are not supported in pepecoin.conf */ CScript donationAddress = CScript(); int donationPercentage = 0; if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, donationAddress, donationPercentage, errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s\n", errorMessage.c_str()); } return; } else { notCapableReason = "Could not find suitable coins!"; LogPrintf("CActiveMasternode::ManageStatus() - Could not find suitable coins!\n"); } } //send to all peers if(!Dseep(errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage.c_str()); } }