浏览代码

Change crowdsales to use timestamps instead of block numbers #350

Jakub Wojciechowski 8 年之前
父节点
当前提交
77dfcb6e23
共有 2 个文件被更改,包括 27 次插入20 次删除
  1. 11 12
      contracts/crowdsale/Crowdsale.sol
  2. 16 8
      test/Crowdsale.js

+ 11 - 12
contracts/crowdsale/Crowdsale.sol

@@ -6,7 +6,7 @@ import '../math/SafeMath.sol';
 /**
  * @title Crowdsale 
  * @dev Crowdsale is a base contract for managing a token crowdsale.
- * Crowdsales have a start and end block, where investors can make
+ * Crowdsales have a start and end timestamps, where investors can make
  * token purchases and the crowdsale will assign them tokens based
  * on a token per ETH rate. Funds collected are forwarded to a wallet 
  * as they arrive.
@@ -17,9 +17,9 @@ contract Crowdsale {
   // The token being sold
   MintableToken public token;
 
-  // start and end block where investments are allowed (both inclusive)
-  uint256 public startBlock;
-  uint256 public endBlock;
+  // start and end timestamps where investments are allowed (both inclusive)
+  uint256 public startTime;
+  uint256 public endTime;
 
   // address where funds are collected
   address public wallet;
@@ -40,15 +40,15 @@ contract Crowdsale {
   event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
 
 
-  function Crowdsale(uint256 _startBlock, uint256 _endBlock, uint256 _rate, address _wallet) {
-    require(_startBlock >= block.number);
-    require(_endBlock >= _startBlock);
+  function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) {
+    require(_startTime >= now);
+    require(_endTime >= _startTime);
     require(_rate > 0);
     require(_wallet != 0x0);
 
     token = createTokenContract();
-    startBlock = _startBlock;
-    endBlock = _endBlock;
+    startTime = _startTime;
+    endTime = _endTime;
     rate = _rate;
     wallet = _wallet;
   }
@@ -92,15 +92,14 @@ contract Crowdsale {
 
   // @return true if the transaction can buy tokens
   function validPurchase() internal constant returns (bool) {
-    uint256 current = block.number;
-    bool withinPeriod = current >= startBlock && current <= endBlock;
+    bool withinPeriod = now >= startTime && now <= endTime;
     bool nonZeroPurchase = msg.value != 0;
     return withinPeriod && nonZeroPurchase;
   }
 
   // @return true if crowdsale event has ended
   function hasEnded() public constant returns (bool) {
-    return block.number > endBlock;
+    return now > endTime;
   }
 
 

+ 16 - 8
test/Crowdsale.js

@@ -1,5 +1,8 @@
+import moment from 'moment'
 import ether from './helpers/ether'
 import advanceToBlock from './helpers/advanceToBlock'
+import increaseTime from './helpers/increaseTime'
+import latestTime from './helpers/latestTime'
 import EVMThrow from './helpers/EVMThrow'
 
 const BigNumber = web3.BigNumber
@@ -19,11 +22,16 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
 
   const expectedTokenAmount = rate.mul(value)
 
+  before(async function() {
+    //Advance to the next block to correctly read time in the solidity "now" function interpreted by testrpc
+    await advanceToBlock(web3.eth.getBlock('latest').number + 1)
+  })
+
   beforeEach(async function () {
-    this.startBlock = web3.eth.blockNumber + 10
-    this.endBlock =   web3.eth.blockNumber + 20
+    this.startTime = latestTime().unix() + moment.duration(1, 'week').asSeconds();
+    this.endTime =   latestTime().unix() + moment.duration(2, 'week').asSeconds();
 
-    this.crowdsale = await Crowdsale.new(this.startBlock, this.endBlock, rate, wallet)
+    this.crowdsale = await Crowdsale.new(this.startTime, this.endTime, rate, wallet)
 
     this.token = MintableToken.at(await this.crowdsale.token())
   })
@@ -36,7 +44,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
   it('should be ended only after end', async function () {
     let ended = await this.crowdsale.hasEnded()
     ended.should.equal(false)
-    await advanceToBlock(this.endBlock + 1)
+    await increaseTime(moment.duration(2.1, 'week'))
     ended = await this.crowdsale.hasEnded()
     ended.should.equal(true)
   })
@@ -49,13 +57,13 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
     })
 
     it('should accept payments after start', async function () {
-      await advanceToBlock(this.startBlock - 1)
+      await increaseTime(moment.duration(1, 'week'))
       await this.crowdsale.send(value).should.be.fulfilled
       await this.crowdsale.buyTokens(investor, {value: value, from: purchaser}).should.be.fulfilled
     })
 
     it('should reject payments after end', async function () {
-      await advanceToBlock(this.endBlock)
+      await increaseTime(moment.duration(2.1, 'week'))
       await this.crowdsale.send(value).should.be.rejectedWith(EVMThrow)
       await this.crowdsale.buyTokens(investor, {value: value, from: purchaser}).should.be.rejectedWith(EVMThrow)
     })
@@ -65,7 +73,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
   describe('high-level purchase', function () {
 
     beforeEach(async function() {
-      await advanceToBlock(this.startBlock)
+      await increaseTime(moment.duration(1, 'week'))
     })
 
     it('should log purchase', async function () {
@@ -104,7 +112,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
   describe('low-level purchase', function () {
 
     beforeEach(async function() {
-      await advanceToBlock(this.startBlock)
+      await increaseTime(moment.duration(1, 'week'))
     })
 
     it('should log purchase', async function () {