Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kulatov committed Nov 3, 2017
0 parents commit 5bbd8c9
Show file tree
Hide file tree
Showing 12 changed files with 5,782 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
@@ -0,0 +1,6 @@
.DS_Store
.idea
node_modules
build
distribution.json
pre-distribution.json
117 changes: 117 additions & 0 deletions README.md
@@ -0,0 +1,117 @@
NAGA Coin Smart Contract
========================

### Preparations

Install dependencies:
```
npm i
```


### Deploy

First, compile the contract:
```
npm run compile
```

To deploy the smart contract on the development network, run:
```
npm run deploy-dev
```

To deploy the smart contract on the Ropsten testnet, run:
```
npm run deploy-ropsten
```

**Be careful!** Every deploy on the same network replaces metadata (including the contract address) stored in the `build` directory.


### Minting

To mint tokens, prepare a JSON file `distribution.json`. For example:
```json
{
"0x8A6d9138e960577D230Ba5F86f872418EA8c0506": {
"amount": 1.23,
"releaseTime": 1519862400
},
"0xf6d1fa4fd83ba3e0c77642756e95917b8a47c1dd": {
"amount": 0.000000000000000001,
"releaseTime": 0
}
}
```

Then run (on the development network):
```
npm run mint-dev distribution.json
```

Or on the Ropsten testnet:
```
npm run mint-ropsten distribution.json
```


### Finish minting

On the development network:
```
npm run finish-dev
```

On the Ropsten testnet:
```
npm run finish-ropsten
```


### Running tests

Run testrpc:
```
npm run testrpc
```

While testrpc is running, run tests:
```
npm test
```

*Due to use of testrpc’s `evm_increaseTime`, you should restart testrpc after each run of tests.*

## Ropsten testnet setup

1. Install geth: https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum
1. Run it on the Ropsten testnet:
```
geth --testnet --rpc
```
1. Find in the beginning of the geth log a line like this one:
```
IPC endpoint opened: /Users/username/Library/Ethereum/testnet/geth.ipc
```
1. Open another terminal and run (using the file path from the previous step):
```
geth attach /Users/username/Library/Ethereum/testnet/geth.ipc
```
1. Wait for the blockchain to sync. In the geth log, it looks like:
```
... Imported new chain segment blocks=1 ...
```
Also you can run `eth.syncing` in the geth console. It should return `false` instead of sync information.
1. We need to create an account. In the geth console, run:
```
personal.newAccount()
```
When it prompts for a passphrase, input a strong one (32 random chars, for example). Of course, you have to store it somewhere.
1. Now restart geth with the unlock parameter:
```
geth --testnet --rpc --unlock "0x0000000000000000000000000000000000000000"
```
Instead of `0x0000000000000000000000000000000000000000`, use account you created in the previous step. While starting, geth will prompt you for the passphrase.
1. Transfer some ETH to account to pay for gas.

87 changes: 87 additions & 0 deletions contracts/NAGACoin.sol
@@ -0,0 +1,87 @@
pragma solidity 0.4.15;


import "zeppelin-solidity/contracts/token/MintableToken.sol";
import "zeppelin-solidity/contracts/ownership/NoOwner.sol";


contract NAGACoin is MintableToken, NoOwner {
string public constant name = "NAGA Coin";
string public constant symbol = "NGC";
uint8 public constant decimals = 18;

uint256 public constant totalSupplyLimit = 400000000 ether;

uint public constant mintingAllowedFrom = 1512086400; // 1 Dec 2017
uint public constant mintingAllowedTo = 1514678400; // 31 Dec 2017

mapping (address => uint256) public releaseTimes;

function mint(address _to, uint256 _amount)
onlyOwner
canMint
public
returns (bool)
{
// Mint in the allowed period only
// We consider time-stamp dependency to be safe enough in this application
require(mintingAllowedFrom <= block.timestamp && block.timestamp <= mintingAllowedTo);

// Don’t mint more than allowed
require(totalSupply.add(_amount) <= totalSupplyLimit);

return super.mint(_to, _amount);
}

function mintWithTimeLock(address _to, uint256 _amount, uint256 _releaseTime)
onlyOwner
canMint
public
returns (bool)
{
if (_releaseTime > releaseTimes[_to]) {
releaseTimes[_to] = _releaseTime;
}

return mint(_to, _amount);
}

function transfer(address _to, uint256 _value)
public
returns (bool)
{
// Transfer of time-locked funds is forbidden
require(!timeLocked(msg.sender));

return super.transfer(_to, _value);
}

function transferFrom(address _from, address _to, uint256 _value)
public
returns (bool)
{
// Transfer of time-locked funds is forbidden
require(!timeLocked(_from));

return super.transferFrom(_from, _to, _value);
}

// Checks if funds of a given address are time-locked
function timeLocked(address _spender)
public
returns (bool)
{
if (releaseTimes[_spender] == 0) {
return false;
}

// If time-lock is expired, delete it
// We consider time-stamp dependency to be safe enough in this application
if (releaseTimes[_spender] <= block.timestamp) {
delete releaseTimes[_spender];
return false;
}

return true;
}
}
10 changes: 10 additions & 0 deletions distribution.json.example
@@ -0,0 +1,10 @@
{
"0x8A6d9138e960577D230Ba5F86f872418EA8c0506": {
"amount": 1.23,
"releaseTime": 1519862400
},
"0xf6d1fa4fd83ba3e0c77642756e95917b8a47c1dd": {
"amount": 0.000000000000000001,
"releaseTime": 0
}
}
Empty file added migrations/.dummy
Empty file.

0 comments on commit 5bbd8c9

Please sign in to comment.