📜 ⬆️ ⬇️

How do I want to invest in cryptocurrency or venture projects?

image

Crazy HYIP around cryptocurrency and all sorts of technological startups pushes people to pay special attention to these two topics. Someone is attracted by the opportunity to make multiple money in a short time, for others participation in venture projects using modern technologies is an opportunity to join modern trends and, perhaps, even boast about it.

But as in the case of the systematic error of the survivor , you need to pay attention not only to success stories that are constantly given as an example, but also to stories where people have lost a lot of time and money trying to develop their project, wrote tons of code, and as a result got nothing. And quite often the lost money belongs to investors. Of course, everyone would like to make money on early investments in companies like facebook, but unfortunately 9 out of 10 such companies go bust.

Venture investment is a very interesting type of business, but for most small private investors, the entrance is simply closed. This happens mainly because of the enormous risk involved in investing in start-ups, investing in one or two projects is like death. Therefore, even the smallest venture funds have at least 20-30 projects in their portfolio. If at least one of their portfolio companies fires, it will cover the costs of other projects. But projects do not want to take from investors 100 thousand. Investments in each of them are at least one million. Simple arithmetic shows that if you have no capital in the amount of 15-20 million in your pocket, you can forget about it.

At the same time, there is another scheme for investing in startups - crowdfunding. You can invest as much as you want, but no one will talk to you as an investor. Again, in most cases, a startup, having collected the necessary amount of funds, relaxes, since it does not bear any responsibility before small investors, who invest in it for good luck. Startups are crumbling not only because of the laziness and irresponsibility of their initiators, but also because of unforeseen factors that it is almost impossible to foresee at the start.
')
With the advent of ethereum and smart contracts, I became infected with the idea of ​​writing a system that would allow small investors to monitor the progress of startups and thereby increase the percentage of profitable investments for themselves. In essence, this is a crowdfunding platform, but with one significant difference - the project does not have access to all the funds raised, but only to a small part of them, and an investor can at any time pick up untapped funds if the project does not pass the stages stated at the start. The guarantor of this will be not a system, but a smart contract.

The business model of the platform itself implies that it will receive as a commission 5% of the broadcast collected by each project (read, in cash) and 5% of the shares of the future enterprise. The platform itself is essentially a joint-stock company, and you can become its owner by purchasing a share of its shares and receiving these same 5 + 5 percent in the future, automatically becoming an investor of all projects that will attract investments based on this platform.

If such a system existed, I would love to invest in it myself, and in projects, realizing that I can always get out of them, if something in my opinion goes wrong. And since there is no such system, I decided to write it myself.

Further in the article I will disassemble “by the bones” the smart contract for solidity, which is the prototype of the future system.

The contract is uploaded to the address https://etherscan.io/address/0x15797a704628907dd2622d3e5711d4ea62cd5072#code and has open code, which excludes the possibility of its substitution.

I will not discuss the technical aspects in detail, but will only focus on the essential details that are important from the point of view of the operation of the contract itself. If someone has any questions, comments on the code, I will gradually complement.

I wrote the article on Habr because hardly anyone other than people close to IT can appreciate the idea.

As one of the developers said, “words are bullshit, show me the code”. So, let's go:

Chunks of code with extended comments
pragma solidity ^0.4.19; library itMaps {..} -    . contract ERC20 {..} - ,    ,       contract TakeMyEther is ERC20{ //    ? .. uint private initialSupply = 2800000; //     uint public soldTokens = 0; //     .. address public TakeMyEtherTeamAddress; //  itMaps.itMapAddressUint tokenBalances; //    mapping (address => uint256) weiBalances; //    ,    . mapping (address => uint256) weiBalancesReturned; //   ,     uint public percentsOfProjectComplete = 0; //   uint public lastStageSubmitted; //        uint public lastTimeWithdrawal; //         uint public constant softCapTokensAmount = 500000; //      uint public constant hardCapTokensAmount = 2250000; //    uint public constant lockDownPeriod = 1 weeks; //             ,           uint public constant minimumStageDuration = 2 weeks; //      . bool public isICOfinalized = false; //      bool public projectCompleted = false; //    modifier onlyTeam { if (msg.sender == TakeMyEtherTeamAddress) { _; } } mapping (address => mapping (address => uint256)) allowed; event StageSubmitted(uint last); //      event etherPassedToTheTeam(uint weiAmount, uint when); //    event etherWithdrawFromTheContract(address tokenHolder, uint numberOfTokensSoldBack, uint weiValue); //    event Burned(address indexed from, uint amount); //      event DividendsTransfered(address to, uint tokensAmount, uint weiAmount); //         ... /*     .      ,           */ function transfer(address to, uint value) public returns (bool success) { if (tokenBalances.get(msg.sender) >= value && value > 0) { if (to == address(this)) { // if you send even 1 token back to the contract, it will return all available funds to you returnAllAvailableFunds(); return true; } else { return transferTokensAndEtherValue(msg.sender, to, value, getAverageTokenPrice(msg.sender) * value); } } else return false; } ... //  : function () public payable { require (!projectCompleted); uint weiToSpend = msg.value; //recieved value uint currentPrice = getCurrentSellPrice(); //0.5 ETH or 1 ETH for 1000 tokens uint valueInWei = 0; uint valueToPass = 0; if (weiToSpend < currentPrice) {// return ETH back if nothing to buy return; } if (!tokenBalances.contains(msg.sender)) tokenBalances.insert(msg.sender, 0); if (soldTokens < softCapTokensAmount) { uint valueLeftForSoftCap = softCapTokensAmount - soldTokens; valueToPass = weiToSpend / currentPrice; if (valueToPass > valueLeftForSoftCap) valueToPass = valueLeftForSoftCap; valueInWei = valueToPass * currentPrice; weiToSpend -= valueInWei; soldTokens += valueToPass; weiBalances[address(this)] += valueInWei; transferTokensAndEtherValue(address(this), msg.sender, valueToPass, valueInWei); } currentPrice = getCurrentSellPrice(); //renew current price if (weiToSpend < currentPrice) { return; } if (soldTokens < hardCapTokensAmount && soldTokens >= softCapTokensAmount) { uint valueLeftForHardCap = hardCapTokensAmount - soldTokens; valueToPass = weiToSpend / currentPrice; if (valueToPass > valueLeftForHardCap) valueToPass = valueLeftForHardCap; valueInWei = valueToPass * currentPrice; weiToSpend -= valueInWei; soldTokens += valueToPass; weiBalances[address(this)] += valueInWei; transferTokensAndEtherValue(address(this), msg.sender, valueToPass, valueInWei); } if (weiToSpend / 10**17 > 1) { //return unspent funds if they are greater than 0.1 ETH msg.sender.transfer(weiToSpend); } } //     function returnAllAvailableFunds() public { require (tokenBalances.contains(msg.sender)); //you need to be a tokenHolder require (!projectCompleted); //you can not return tokens after project is completed uint avPrice = getAverageTokenPrice(msg.sender); weiBalances[msg.sender] = getWeiAvailableToReturn(msg.sender); //depends on project completeness level uint amountOfTokensToReturn = weiBalances[msg.sender] / avPrice; require (amountOfTokensToReturn>0); uint valueInWei = weiBalances[msg.sender]; transferTokensAndEtherValue(msg.sender, address(this), amountOfTokensToReturn, valueInWei); emit etherWithdrawFromTheContract(msg.sender, amountOfTokensToReturn, valueInWei); weiBalances[address(this)] -= valueInWei; soldTokens -= amountOfTokensToReturn; msg.sender.transfer(valueInWei); } // View functions //      https://etherscan.io/address/0x15797a704628907dd2622d3e5711d4ea62cd5072#readContract      // Team functions    ? //    function finalizeICO() public onlyTeam { require(!isICOfinalized); // this function can be called only once if (soldTokens < hardCapTokensAmount) require (lastStageSubmitted + minimumStageDuration < now); // ICO duration is at least 2 weeks require(soldTokens >= softCapTokensAmount); //means, that the softCap Reached uint tokensToPass = passTokensToTheTeam(); //but without weiValue, so the team can not withdraw ether by returning tokens to the contract burnUndistributedTokens(tokensToPass);//tokensToPass); // undistributed tokens are destroyed lastStageSubmitted = now; emit StageSubmitted(lastStageSubmitted); increaseProjectCompleteLevel(); // Now, team can withdraw 10% of funds raised to begin the project passFundsToTheTeam(); isICOfinalized = true; } //      function submitNextStage() public onlyTeam returns (bool success) { if (lastStageSubmitted + minimumStageDuration > now) return false; //Team submitted the completeness of previous stage more then 2 weeks before. lastStageSubmitted = now; emit StageSubmitted(lastStageSubmitted); increaseProjectCompleteLevel(); return true; } /*             */ function unlockFundsAndPassEther() public onlyTeam returns (bool success) { require (lastTimeWithdrawal<=lastStageSubmitted); if (lastStageSubmitted + lockDownPeriod > now) return false; //funds can not be passed until lockDownPeriod ends if (percentsOfProjectComplete == 100 && !projectCompleted) { projectCompleted = true; if (tokenBalances.get(address(this))>0) { uint toTransferAmount = tokenBalances.get(address(this)); tokenBalances.insert(TakeMyEtherTeamAddress, tokenBalances.get(address(this)) + tokenBalances.get(TakeMyEtherTeamAddress)); tokenBalances.insert(address(this), 0); emit Transfer(address(this), TakeMyEtherTeamAddress, toTransferAmount); } } passFundsToTheTeam(); return true; } // Receive dividends //       function topUpWithEtherAndTokensForHolders(address tokensContractAddress, uint tokensAmount) public payable { uint weiPerToken = msg.value / initialSupply; uint tokensPerToken = 100 * tokensAmount / initialSupply; //Multiplication for more precise amount uint weiAmountForHolder = 0; uint tokensForHolder = 0; for (uint i = 0; i< tokenBalances.size(); i += 1) { address tokenHolder = tokenBalances.getKeyByIndex(i); if (tokenBalances.get(tokenHolder)>0) { weiAmountForHolder = tokenBalances.get(tokenHolder)*weiPerToken; tokensForHolder = tokenBalances.get(tokenHolder) * tokensPerToken / 100; // Dividing because of the previous multiplication tokenHolder.transfer(weiAmountForHolder); //This will pass a certain amount of ether to TakeMyEther platform tokenHolders if (tokensContractAddress.call(bytes4(keccak256("authorizedTransfer(address,address,uint256)")), msg.sender, tokenHolder, tokensForHolder)) //This will pass a certain amount of tokens to TakeMyEther platform tokenHolders emit DividendsTransfered(tokenHolder, tokensForHolder, weiAmountForHolder); } } } function passUndistributedEther() public { require (projectCompleted); uint weiPerToken = (address(this).balance * 100) / initialSupply; for (uint i = 0; i< tokenBalances.size(); i += 1) { address tokenHolder = tokenBalances.getKeyByIndex(i); if (tokenBalances.get(tokenHolder)>0) { uint weiAmountForHolder = (tokenBalances.get(tokenHolder)*weiPerToken)/100; tokenHolder.transfer(weiAmountForHolder); //This will pass a certain amount of ether to TakeMyEther platform tokenHolders emit DividendsTransfered(tokenHolder, 0, weiAmountForHolder); } } } // When project is finished and Dividends are passed to the tokenHolders, there is some wei, left on the contract. Gradually, there can be a large amount of wei left, so it should be also distributed among tokenHolders. // Internal functions //  : function transferTokensAndEtherValue(address from, address to, uint value, uint weiValue) internal returns (bool success){ if (tokenBalances.contains(from) && tokenBalances.get(from) >= value) { tokenBalances.insert(to, tokenBalances.get(to) + value); tokenBalances.insert(from, tokenBalances.get(from) - value); weiBalances[from] -= weiValue; weiBalances[to] += weiValue; emit Transfer(from, to, value); return true; } return false; } function passFundsToTheTeam() internal { uint weiAmount = getAvailableFundsForTheTeam(); TakeMyEtherTeamAddress.transfer(weiAmount); emit etherPassedToTheTeam(weiAmount, now); lastTimeWithdrawal = now; } function passTokensToTheTeam() internal returns (uint tokenAmount) { //This function passes tokens to the team without weiValue, so the team can not withdraw ether by returning tokens to the contract uint tokensToPass = getNumberOfTokensForTheTeam(); tokenBalances.insert(TakeMyEtherTeamAddress, tokensToPass); weiBalances[TakeMyEtherTeamAddress] = 0; // those tokens don't cost any ether emit Transfer(address(this), TakeMyEtherTeamAddress, tokensToPass); return tokensToPass; } function increaseProjectCompleteLevel() internal { if (percentsOfProjectComplete<60) percentsOfProjectComplete += 10; else percentsOfProjectComplete = 100; } function burnUndistributedTokens(uint tokensToPassToTheTeam) internal { uint toBurn = initialSupply - (tokensToPassToTheTeam + soldTokens); initialSupply -= toBurn; tokenBalances.insert(address(this), 0); emit Burned(address(this), toBurn); } } 


So what?


A logical question that may arise at the end of reading the notes.
The main goal, as I see it, consists of several parts:

1) Informing the community about the business opportunities offered by the blockchain.

2) Review the project and / or code, get feedback from the community, as this is one of the best ways to test a hypothesis. Maybe I'm just wasting my time and these ideas are not interesting to anyone?

3)
 if (    == false) {  ();  ();  (-); } 

Thank you for your attention, all good!

Source: https://habr.com/ru/post/358982/


All Articles