Tag Archives: Block chain

Forsage fossage system development (build case)

Smart contracts are a new technology that can only be achieved through blockchain. Ordinary, standard contracts cover the terms of an agreement between the parties and are often enforced by law; The smart contract is digital, stored in the blockchain, and uses encrypted code to enforce the protocol.
In other words, smart contracts are just software programs that, like all programs, perform exactly as the programmer intended. An intelligent contract is like a programming application: “When it appears, execute it.”
MLM encryption scheme, which allows users to earn Ethereum currency by the following 2 matrix recommendation structures. Herbage is based on intelligent contract decentralized ecosystem thus developing PUNK_2558. Make technology Settings fully available and automated so that they can be smooth and secure.
Gifting project with binary matrix structure is adopted in the program. There are 2 matrix types X3 matrix and X4 matrix you can choose to ride a bike with anyone. To start using any matrix loop, you must pay 0.05ETH fee (joining fee) and then start referrals through your referral link.
The matrix sizes used in the circulator are 3×1 and 2×2. The 3 by 1 matrix is essentially simple, you just need to fill in three positions. The 2 by 2 matrix starts at two positions in the first layer and then expands to four positions in the second layer. Positions are filled through direct and indirect recruitment of Forsage members. Once all the positions in the matrix are filled, the cyclic commission is activated. The positions coming out of the matrix will also be entered as new matrices of the same size.
uint8 public constant LAST_LEVEL = 12;

mapping(address => User) public users;
mapping(uint => address) public idToAddress;
mapping(uint => address) public userIds;
mapping(address => uint) public balances; 

uint public lastUserId = 2;
address public owner;

mapping(uint8 => uint) public levelPrice;

event Registration(address indexed user, address indexed referrer, uint indexed userId, uint referrerId);
event Reinvest(address indexed user, address indexed currentReferrer, address indexed caller, uint8 matrix, uint8 level);
event Upgrade(address indexed user, address indexed referrer, uint8 matrix, uint8 level);
event NewUserPlace(address indexed user, address indexed referrer, uint8 matrix, uint8 level, uint8 place);
event MissedEthReceive(address indexed receiver, address indexed from, uint8 matrix, uint8 level);
event SentExtraEthDividends(address indexed from, address indexed receiver, uint8 matrix, uint8 level);


constructor(address ownerAddress) public {
    levelPrice[1] = 0.025 ether;
    for (uint8 i = 2; i <= LAST_LEVEL; i++) {
        levelPrice[i] = levelPrice[i-1] * 2;
    }
    
    owner = ownerAddress;
    
    User memory user = User({
        id: 1,
        referrer: address(0),
        partnersCount: uint(0)
    });
    
    users[ownerAddress] = user;
    idToAddress[1] = ownerAddress;
    
    for (uint8 i = 1; i <= LAST_LEVEL; i++) {
        users[ownerAddress].activeX3Levels[i] = true;
        users[ownerAddress].activeX6Levels[i] = true;
    }

Error: connect econnreused 0.0.0.0:443 is reported when executing the trunk unbox react

Premise: I’m on a MAC and I don’t know if Windows is ok
React – Box project construction

localhost:ReactDapp liyuechun$ truffle unbox react-box

Starting unbox...
=================

✔ Preparing to download box
✖ Downloading
Unbox failed!
RequestError: Error: connect ECONNREFUSED 0.0.0.0:443
    at new RequestError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/request-promise-core/lib/errors.js:14:1)
    at Request.plumbing.callback (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/request-promise-core/lib/plumbing.js:87:1)
    at Request.RP$callback [as _callback] (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/request-promise-core/lib/plumbing.js:46:1)
    at self.callback (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/request/request.js:185:1)
    at Request.emit (events.js:189:13)
    at Request.onRequestError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/request/request.js:881:1)
    at ClientRequest.emit (events.js:189:13)
    at TLSSocket.socketErrorListener (_http_client.js:392:9)
    at TLSSocket.emit (events.js:189:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Truffle v5.1.29 (core: 5.1.29)
Node v10.15.3

The solution
Download demo, copy and unpack the hosts file in the folder, open the terminal, enter open /etc, paste the hosts into the etc folder, and replace the original 0 hosts1 file.

localhost:ReactDapp liyuechun$ truffle unbox react-box

Starting unbox...
=================

✔ Preparing to download box
✔ Downloading
✔ cleaning up temporary files
✔ Setting up box

Unbox successful, sweet!

Commands:

  Compile:              truffle compile
  Migrate:              truffle migrate
  Test contracts:       truffle test
  Test dapp:            cd client && npm test
  Run dev server:       cd client && npm run start
  Build for production: cd client && npm run build

Refer to the link

Bitcoin source code analysis – load Wallet

The next Step is the analysis of bitcoins main Core process of loading the purse in initialization, the corresponding source is SRC/init. The CPP AppInitMain () method of Step 8: the load wallet this part, see: https://github.com/bitcoin/bitcoin/blob/v0.16.1/src/init.cpp

    // ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET
    if (!OpenWallets())
        return false;
#else
    LogPrintf("No wallet support compiled in!\n");
#endif

The key is the OpenDUTY () method:

bool OpenWallets()
{
    if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
        LogPrintf("Wallet disabled!\n");
        return true;
    }

    for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
        CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile);
        if (!pwallet) {
            return false;
        }
        vpwallets.push_back(pwallet);
    }

    return true;
}

According to “- wallet wallet file path of the parameter Settings” read the corresponding files to create the purse, and “- wallet” parameters by WalletParameterInteraction set () method:

bool WalletParameterInteraction()
{
    if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
        for (const std::string& wallet : gArgs.GetArgs("-wallet")) {
            LogPrintf("%s: parameter interaction: -disablewallet -> ignoring -wallet=%s\n", __func__, wallet);
        }

        return true;
    }

    gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT);

......

You can see that the “-Wallet” parameter is set to DEFAULT_WALLET_DAT by default, and DEFAULT_WALLET_DAT is defined in SRC/Wallet/Wallet. CPP:

const char * DEFAULT_WALLET_DAT = "wallet.dat";

That is, the default is to create a wallet by loading the wallet file from wallet. Dat.
WalletParameterInteraction () method by the previously mentioned AppInitParameterInteraction () method call.
The next step is to analyze the key CreateWalletFromFile() method, defined in SRC/Wallet/Wallet. CPP:

CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
{
    // needed to restore wallet transaction meta data after -zapwallettxes
    std::vector<CWalletTx> vWtx;

1. Clear your wallet of transaction data
Then look at the source code:

    if (gArgs.GetBoolArg("-zapwallettxes", false)) {
        uiInterface.InitMessage(_("Zapping all transactions from wallet..."));

        std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
        std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(std::move(dbw));
        DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
        if (nZapWalletRet != DB_LOAD_OK) {
            InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
            return nullptr;
        }
    }

If the user has set the “-zapwallettxes” option, then clear all the transaction data of the wallet. Why clear the transaction data?This is because there may be transactions with low or no transaction fee, which can be eliminated by this option.
here is the ZapWalletTx() method that calls the CWallet class to clear the transaction, further followed, you can find the ZapWalletTx() method that calls the CWalletDB class to clear the transaction:

DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx)
{
    // build list of wallet TXs
    std::vector<uint256> vTxHash;
    DBErrors err = FindWalletTx(vTxHash, vWtx);
    if (err != DB_LOAD_OK)
        return err;

    // erase each wallet TX
    for (uint256& hash : vTxHash) {
        if (!EraseTx(hash))
            return DB_CORRUPT;
    }

    return DB_LOAD_OK;
}

Locate the hash corresponding to all transactions in the collection vTxHash using the CWalletDB::FindWalletTx() method and then iterate through the collection calling the CWalletDB::EraseTx() method to clear the transaction.
Create a wallet

    uiInterface.InitMessage(_("Loading wallet..."));

    int64_t nStart = GetTimeMillis();
    bool fFirstRun = true;
    std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
    CWallet *walletInstance = new CWallet(std::move(dbw));
    DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);

The CWallet object is created, and then the LoadWallet() method is called to load the data from the Wallet. Dat file.
3. Upgrade your wallet

    if (gArgs.GetBoolArg("-upgradewallet", fFirstRun))
    {
        int nMaxVersion = gArgs.GetArg("-upgradewallet", 0);
        if (nMaxVersion == 0) // the -upgradewallet without argument case
        {
            LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
            nMaxVersion = CLIENT_VERSION;
            walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
        }
        else
            LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
        if (nMaxVersion < walletInstance->GetVersion())
        {
            InitError(_("Cannot downgrade wallet"));
            return nullptr;
        }
        walletInstance->SetMaxVersion(nMaxVersion);
    }

If the “-UpgradeWallet” option is set, then the wallet upgrades according to the parameters.
4. Generate the primary and child private keys

    if (fFirstRun)
    {
        // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
        if (!gArgs.GetBoolArg("-usehd", true)) {
            InitError(strprintf(_("Error creating %s: You can't create non-HD wallets with this version."), walletFile));
            return nullptr;
        }
        walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY);

        // generate a new master key  生成主私钥
        CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey();
        if (!walletInstance->SetHDMasterKey(masterPubKey))
            throw std::runtime_error(std::string(__func__) + ": Storing master key failed");

        // Top up the keypool 生成子私钥,填充满密钥池
        if (!walletInstance->TopUpKeyPool()) {
            InitError(_("Unable to generate initial keys") += "\n");
            return nullptr;
        }

        walletInstance->SetBestChain(chainActive.GetLocator());
    }

A wallet is a collection of private keys. HD Cosmetic wallet requires a master private key, which is used to create a large number of child private keys.
4.1 to generate the private key
see CPubKey CWallet: : GenerateNewHDMasterKey () the source code

CPubKey CWallet::GenerateNewHDMasterKey()
{

    CKey key;
    key.MakeNewKey(true);

    int64_t nCreationTime = GetTime();
    CKeyMetadata metadata(nCreationTime);


    // calculate the pubkey
    CPubKey pubkey = key.GetPubKey();
    assert(key.VerifyPubKey(pubkey));


    // set the hd keypath to "m" -> Master, refers the masterkeyid to itself
    metadata.hdKeypath     = "m";
    metadata.hdMasterKeyID = pubkey.GetID();

    {
        LOCK(cs_wallet);

        // mem store the metadata
        mapKeyMetadata[pubkey.GetID()] = metadata;

		//将公钥私钥对写入到钱包的数据库文件中
        // write the key&metadata to the database
        if (!AddKeyPubKey(key, pubkey))
            throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
    }

    return pubkey;
}

4.1.1 create private key

calls the CKey::MakeNewKey() method to generate a private key using the encrypted PRNG.
Public key generated by private key
call CPubKey ::GetPubKey() according to secp256k1 elliptic curve algorithm generated by private key:

CPubKey CKey::GetPubKey() const {
    assert(fValid);
    secp256k1_pubkey pubkey;
    size_t clen = CPubKey::PUBLIC_KEY_SIZE;
    CPubKey result;
    int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin());
    assert(ret);
    secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ?SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
    assert(result.size() == clen);
    assert(result.IsValid());
    return result;
}

4.1.3 mark the primary key
calls pubkey.getid () to calculate a CKeyID, which is actually a reference to the private key CKey and is used to uniquely identify a private key, but is represented by the Hash160 hash of the public key corresponding to the private key.
look at the source code:

    //! Get the KeyID of this public key (hash of its serialization)
    CKeyID GetID() const
    {
        return CKeyID(Hash160(vch, vch + size()));
    }

Write the public and private key pairs to the database file of the wallet
call the CWallet::AddKeyPubKey() method to write the public and private key pairs to the database file of the wallet:

bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
{
    CWalletDB walletdb(*dbw);
    return CWallet::AddKeyPubKeyWithDB(walletdb, secret, pubkey);
}

4.2 generation of child key
bool CWallet::TopUpKeyPool(unsigned int kpSize) source code:

bool CWallet::TopUpKeyPool(unsigned int kpSize)
{
    {
        LOCK(cs_wallet);

        if (IsLocked())
            return false;

        // Top up key pool
        unsigned int nTargetSize;
        if (kpSize > 0)
            nTargetSize = kpSize;
        else
            nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);

        // count amount of available keys (internal, external)
        // make sure the keypool of external and internal keys fits the user selected target (-keypool)
        int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
        int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);

        if (!IsHDEnabled() || !CanSupportFeature(FEATURE_HD_SPLIT))
        {
            // don't create extra internal keys
            missingInternal = 0;
        }
        bool internal = false;
        CWalletDB walletdb(*dbw);
        for (int64_t i = missingInternal + missingExternal; i--;)
        {
            if (i < missingInternal) {
                internal = true;
            }

            assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
            int64_t index = ++m_max_keypool_index;
			
			//调用GenerateNewKey()方法生成公钥私钥对
            CPubKey pubkey(GenerateNewKey(walletdb, internal));
            if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) {
                throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
            }

            if (internal) {
                setInternalKeyPool.insert(index);
            } else {
                setExternalKeyPool.insert(index);
            }
            m_pool_key_to_index[pubkey.GetID()] = index;
        }
        if (missingInternal + missingExternal > 0) {
            LogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size());
        }
    }
    return true;
}

5. Scan the blockchain and add relevant transactions to the wallet

    CBlockIndex *pindexRescan = chainActive.Genesis();
    if (!gArgs.GetBoolArg("-rescan", false))
    {
        CWalletDB walletdb(*walletInstance->dbw);
        CBlockLocator locator;
        if (walletdb.ReadBestBlock(locator))
            pindexRescan = FindForkInGlobalIndex(chainActive, locator);
    }

    walletInstance->m_last_block_processed = chainActive.Tip();
    RegisterValidationInterface(walletInstance);

    if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
    {
        //We can't rescan beyond non-pruned blocks, stop and throw an error
        //this might happen if a user uses an old wallet within a pruned node
        // or if he ran -disablewallet for a longer time, then decided to re-enable
        if (fPruneMode)
        {
            CBlockIndex *block = chainActive.Tip();
            while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
                block = block->pprev;

            if (pindexRescan != block) {
                InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
                return nullptr;
            }
        }

        uiInterface.InitMessage(_("Rescanning..."));
        LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);

        // No need to read and scan block if block was created before
        // our wallet birthday (as adjusted for block time variability)
        while (pindexRescan && walletInstance->nTimeFirstKey && (pindexRescan->GetBlockTime() < (walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW))) {
            pindexRescan = chainActive.Next(pindexRescan);
        }

        nStart = GetTimeMillis();
        {
            WalletRescanReserver reserver(walletInstance);
            if (!reserver.reserve()) {
                InitError(_("Failed to rescan the wallet during initialization"));
                return nullptr;
            }
            walletInstance->ScanForWalletTransactions(pindexRescan, nullptr, reserver, true);
        }
        LogPrintf(" rescan      %15dms\n", GetTimeMillis() - nStart);
        walletInstance->SetBestChain(chainActive.GetLocator());
        walletInstance->dbw->IncrementUpdateCounter();

        // Restore wallet transaction metadata after -zapwallettxes=1
        if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2")
        {
            CWalletDB walletdb(*walletInstance->dbw);

            for (const CWalletTx& wtxOld : vWtx)
            {
                uint256 hash = wtxOld.GetHash();
                std::map<uint256, CWalletTx>::iterator mi = walletInstance->mapWallet.find(hash);
                if (mi != walletInstance->mapWallet.end())
                {
                    const CWalletTx* copyFrom = &wtxOld;
                    CWalletTx* copyTo = &mi->second;
                    copyTo->mapValue = copyFrom->mapValue;
                    copyTo->vOrderForm = copyFrom->vOrderForm;
                    copyTo->nTimeReceived = copyFrom->nTimeReceived;
                    copyTo->nTimeSmart = copyFrom->nTimeSmart;
                    copyTo->fFromMe = copyFrom->fFromMe;
                    copyTo->strFromAccount = copyFrom->strFromAccount;
                    copyTo->nOrderPos = copyFrom->nOrderPos;
                    walletdb.WriteTx(*copyTo);
                }
            }
        }
    }

If the user sets the “-rescan” option, starting with the creation block, gets the location where the wallet transaction needs to be re-updated, and then begins scanning the block to add the relevant transaction to the wallet. Under the analysis of the corresponding ScanForWalletTransactions () method:

/**
 * Scan the block chain (starting in pindexStart) for transactions
 * from or to us. If fUpdate is true, found transactions that already
 * exist in the wallet will be updated.
 *
 * Returns null if scan was successful. Otherwise, if a complete rescan was not
 * possible (due to pruning or corruption), returns pointer to the most recent
 * block that could not be scanned.
 *
 * If pindexStop is not a nullptr, the scan will stop at the block-index
 * defined by pindexStop
 *
 * Caller needs to make sure pindexStop (and the optional pindexStart) are on
 * the main chain after to the addition of any new keys you want to detect
 * transactions for.
 */
CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlockIndex* pindexStop, const WalletRescanReserver &reserver, bool fUpdate)
{
    int64_t nNow = GetTime();
    const CChainParams& chainParams = Params();

    assert(reserver.isReserved());
    if (pindexStop) {
        assert(pindexStop->nHeight >= pindexStart->nHeight);
    }

    CBlockIndex* pindex = pindexStart;
    CBlockIndex* ret = nullptr;
    {
        fAbortRescan = false;
        ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
        CBlockIndex* tip = nullptr;
        double dProgressStart;
        double dProgressTip;
        {
            LOCK(cs_main);
            tip = chainActive.Tip();
            dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
            dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip);
        }
        while (pindex && !fAbortRescan)
        {
            if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) {
                double gvp = 0;
                {
                    LOCK(cs_main);
                    gvp = GuessVerificationProgress(chainParams.TxData(), pindex);
                }
                ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((gvp - dProgressStart)/(dProgressTip - dProgressStart) * 100))));
            }
            if (GetTime() >= nNow + 60) {
                nNow = GetTime();
                LOCK(cs_main);
                LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
            }

            CBlock block;
            if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
                LOCK2(cs_main, cs_wallet);
                if (pindex && !chainActive.Contains(pindex)) {
                    // Abort scan if current block is no longer active, to prevent
                    // marking transactions as coming from the wrong block.
                    ret = pindex;
                    break;
                }
                for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
                    AddToWalletIfInvolvingMe(block.vtx[posInBlock], pindex, posInBlock, fUpdate);
                }
            } else {
                ret = pindex;
            }
            if (pindex == pindexStop) {
                break;
            }
            {
                LOCK(cs_main);
                pindex = chainActive.Next(pindex);
                if (tip != chainActive.Tip()) {
                    tip = chainActive.Tip();
                    // in case the tip has changed, update progress max
                    dProgressTip = GuessVerificationProgress(chainParams.TxData(), tip);
                }
            }
        }
        if (pindex && fAbortRescan) {
            LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
        }
        ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
    }
    return ret;
}

Read the source code of this method, you can see that all the block data is stored on disk. ChainActive stores the block’s location index chain. By walking through this location index chain, call ReadBlockFromDisk() to read the block information from disk, and then add the block’s transaction data to the wallet by the AddToWalletIfInvolvingMe() method.