3.24 vchain原始碼分析2
阿新 • • 發佈:2018-12-20
接下來是合約的第二部分,直接上程式碼,註釋都在程式碼中
// Contract to sell and distribute VEN tokens // 分發VEN 代幣 contract VENSale is Owned{ /// chart of stage transition /// /// deploy initialize startTime endTime finalize /// | <-earlyStageLasts-> | | <- closedStageLasts -> | /// O-----------O---------------O---------------------O-------------O------------------------O------------> /// Created Initialized Early Normal Closed Finalized enum Stage { NotCreated, Created, Initialized, Early, Normal, Closed, Finalized } using SafeMath for uint256; uint256 public constant totalSupply = (10 ** 9) * (10 ** 18); // 1 billion VEN, decimals set to 18 // 總量 10億枚 uint256 constant privateSupply = totalSupply * 9 / 100; // 9% for private ICO 私募 uint256 constant commercialPlan = totalSupply * 23 / 100; // 23% for commercial plan 企業投資人 uint256 constant reservedForTeam = totalSupply * 5 / 100; // 5% for team // 團隊保留 uint256 constant reservedForOperations = totalSupply * 22 / 100; // 22 for operations 持續經營及技術發展+ 商業落地推廣 // 59% uint256 public constant nonPublicSupply = privateSupply + commercialPlan + reservedForTeam + reservedForOperations; // 非公開銷售 59% // 41% uint256 public constant publicSupply = totalSupply - nonPublicSupply; // 公開銷售41% uint256 public constant officialLimit = 64371825 * (10 ** 18); // 官方銷售總量 uint256 public constant channelsLimit = publicSupply - officialLimit; // 渠道銷售總量 // packed to 256bit struct SoldOut { uint16 placeholder; // placeholder to make struct pre-alloced // amount of tdokens officially sol out. // max value of 120bit is about 1e36, it's enough for token amount uint120 official; // 官方銷售數量 // 通過渠道銷售的代幣數量 uint120 channels; // amount of tokens sold out via channels } SoldOut soldOut; uint256 constant venPerEth = 3500; // normal exchange rate 與以太幣的兌換 1 eth = 3500 ven uint256 constant venPerEthEarlyStage = venPerEth + venPerEth * 15 / 100; // early stage has 15% reward 在早期階段,因為有獎勵 所以 1 eth = 3500 + 3500 * 15% = 4025 ven uint constant minBuyInterval = 30 minutes; // each account can buy once in 30 minutes 每個帳戶可以在30分鐘內購買一次 uint constant maxBuyEthAmount = 30 ether; // 每個賬戶最大購買數量為30個eth等值的ven VEN ven; // VEN token contract follows ERC20 standard address ethVault; // the account to keep received ether 接收以太幣的賬戶 address venVault; // the account to keep non-public offered VEN tokens 傳送非公開提供VEN的賬戶 uint public constant startTime = 1503057600; // time to start sale 眾籌開始時間 uint public constant endTime = 1504180800; // tiem to close sale 眾籌結束時間 uint public constant earlyStageLasts = 3 days; // early bird stage lasts in seconds 早期階段的持續時間 bool initialized; // 初始化 bool finalized; // 結束 function VENSale() { soldOut.placeholder = 1; } /// @notice calculte exchange rate according to current stage /// @return exchange rate. zero if not in sale. // 計算當前階段的兌換比例 function exchangeRate() constant returns (uint256){ if (stage() == Stage.Early) { return venPerEthEarlyStage; // 早期階段的比例 } if (stage() == Stage.Normal) { return venPerEth; // 正常階段的比例 } return 0; } /// @notice for test purpose // 區塊產生時間 function blockTime() constant returns (uint32) { return uint32(block.timestamp); } /// @notice estimate stage /// @return current stage // 得到當前處於哪一個階段 function stage() constant returns (Stage) { if (finalized) { return Stage.Finalized; } if (!initialized) { // deployed but not initialized // 合約剛剛部署 return Stage.Created; } // 尚未開始眾籌 if (blockTime() < startTime) { // not started yet return Stage.Initialized; } // 售罄 if (uint256(soldOut.official).add(soldOut.channels) >= publicSupply) { // all sold out return Stage.Closed; } // 眾籌階段 if (blockTime() < endTime) { // in sale if (blockTime() < startTime.add(earlyStageLasts)) { // early bird stage return Stage.Early; } // normal stage return Stage.Normal; } // closed return Stage.Closed; } // 檢查是否是一個合約地址 function isContract(address _addr) constant internal returns(bool) { uint size; if (_addr == 0) return false; assembly { size := extcodesize(_addr) } return size > 0; } /// @notice entry to buy tokens function () payable { buy(); } /// @notice entry to buy tokens // 買幣 function buy() payable { // reject contract buyer to avoid breaking interval limit // 禁止合約賬戶購買代幣 require(!isContract(msg.sender)); require(msg.value >= 0.01 ether); uint256 rate = exchangeRate(); //獲取兌換比例 // here don't need to check stage. rate is only valid when in sale require(rate > 0); // each account is allowed once in minBuyInterval require(blockTime() >= ven.lastMintedTimestamp(msg.sender) + minBuyInterval);// 指定的時間內只允許買一次 uint256 requested; // and limited to maxBuyEthAmount // 限制購買數量 if (msg.value > maxBuyEthAmount) { requested = maxBuyEthAmount.mul(rate); // 超過允許購買數量 , 就使用最大允許購買值乘以兌換率 } else { requested = msg.value.mul(rate); } uint256 remained = officialLimit.sub(soldOut.official); if (requested > remained) { // 要購買的數量 大於剩餘數量 //exceed remained requested = remained; } uint256 ethCost = requested.div(rate); // 計算花費的以太幣 if (requested > 0) { ven.mint(msg.sender, requested, true, blockTime()); // transfer ETH to vault ethVault.transfer(ethCost); // 轉入以太幣 soldOut.official = requested.add(soldOut.official).toUINT120(); // 修改官方銷售的數量 onSold(msg.sender, requested, ethCost); } uint256 toReturn = msg.value.sub(ethCost); // (簡單來說,此處就是)找零 if(toReturn > 0) { // return over payed ETH msg.sender.transfer(toReturn); } } /// @notice returns tokens sold officially // 返回正式銷售的代幣 function officialSold() constant returns (uint256) { return soldOut.official; } /// @notice returns tokens sold via channels // 通過渠道銷售的幣 function channelsSold() constant returns (uint256) { return soldOut.channels; } /// @notice manually offer tokens to channel // 手動為渠道提供token function offerToChannel(address _channelAccount, uint256 _venAmount) onlyOwner { Stage stg = stage(); // 獲取當前處於哪個階段 // since the settlement may be delayed, so it's allowed in closed stage require(stg == Stage.Early || stg == Stage.Normal || stg == Stage.Closed); soldOut.channels = _venAmount.add(soldOut.channels).toUINT120(); // 修改渠道銷售的token數量 //should not exceed limit 不能超過渠道銷售數量的限制 require(soldOut.channels <= channelsLimit); ven.mint( _channelAccount, _venAmount, true, // unsold tokens can be claimed by channels portion 未售出的代幣可以通過渠道部分來申領 blockTime() ); onSold(_channelAccount, _venAmount, 0); } /// @notice initialize to prepare for sale /// @param _ven The address VEN token contract following ERC20 standard /// @param _ethVault The place to store received ETH /// @param _venVault The place to store non-publicly supplied VEN tokens // 初始化 function initialize( VEN _ven, // 合約例項 address _ethVault, // 接收買家以太幣的地址 address _venVault) onlyOwner { // 傳送ven的地址 require(stage() == Stage.Created); //階段限制 // ownership of token contract should already be this require(_ven.owner() == address(this)); // 所有權限制 require(address(_ethVault) != 0); // 不能為空 require(address(_venVault) != 0); ven = _ven; ethVault = _ethVault; venVault = _venVault; // 團隊保留鑄幣 ven.mint( venVault, reservedForTeam.add(reservedForOperations), false, // team and operations reserved portion can't share unsold tokens blockTime() ); // 私募和個人投資人的幣 ven.mint( venVault, privateSupply.add(commercialPlan), true, // private ICO and commercial plan can share unsold tokens 可以共享未出售的token blockTime() ); initialized = true; onInitialized(); } /// @notice finalize function finalize() onlyOwner { // only after closed stage require(stage() == Stage.Closed); // 階段限制 uint256 unsold = publicSupply.sub(soldOut.official).sub(soldOut.channels); // 計算未出售的代幣 if (unsold > 0) { // unsold VEN as bonus ven.offerBonus(unsold); // 將未出售的代幣作為獎勵 } ven.seal(); finalized = true; onFinalized(); } event onInitialized(); // 初始化事件 event onFinalized(); // 完成事件 event onSold(address indexed buyer, uint256 venAmount, uint256 ethCost); // 事件 表示有人購買ven }