From b77ba3efb63cc39b912a24f49b8f1788feea273e Mon Sep 17 00:00:00 2001 From: charles-liu Date: Mon, 10 May 2021 03:30:31 +0800 Subject: [PATCH] add BEP20 smart contract --- smart-contract/vite-token-bep20/.gitignore | 4 + .../vite-token-bep20/contracts/BEP20Token.sol | 338 ++++++++++++++++++ .../migrations/1_initial_migration.js | 5 + smart-contract/vite-token-bep20/package.json | 9 + smart-contract/vite-token-bep20/test/.gitkeep | 0 .../vite-token-bep20/truffle-config.js | 103 ++++++ 6 files changed, 459 insertions(+) create mode 100644 smart-contract/vite-token-bep20/.gitignore create mode 100644 smart-contract/vite-token-bep20/contracts/BEP20Token.sol create mode 100644 smart-contract/vite-token-bep20/migrations/1_initial_migration.js create mode 100644 smart-contract/vite-token-bep20/package.json create mode 100644 smart-contract/vite-token-bep20/test/.gitkeep create mode 100644 smart-contract/vite-token-bep20/truffle-config.js diff --git a/smart-contract/vite-token-bep20/.gitignore b/smart-contract/vite-token-bep20/.gitignore new file mode 100644 index 000000000..7a30ad4cc --- /dev/null +++ b/smart-contract/vite-token-bep20/.gitignore @@ -0,0 +1,4 @@ +node_modules/* +cache/* +artifacts/* +build/* diff --git a/smart-contract/vite-token-bep20/contracts/BEP20Token.sol b/smart-contract/vite-token-bep20/contracts/BEP20Token.sol new file mode 100644 index 000000000..f86b32f28 --- /dev/null +++ b/smart-contract/vite-token-bep20/contracts/BEP20Token.sol @@ -0,0 +1,338 @@ +pragma solidity ^0.4.24; + +library SafeMath { + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + uint256 c = a * b; + assert(c / a == b); + return c; + } + + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // assert(b > 0); // Solidity automatically throws when dividing by 0 + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + return c; + } + + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + assert(b <= a); + return a - b; + } + + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + assert(c >= a); + return c; + } +} + +contract Ownable { + address public owner; + address public pendingOwner; + + event PendingOwnerSet(address pendingOwner); + event OwnerAccepted(address owner); + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(msg.sender == owner); + _; + } + + /** + * @dev get the owner + */ + function getOwner() external view returns (address) { + return owner; + } + + /************************************/ + /*** Transfer Ownership Functions ***/ + /************************************/ + + /** + * @dev Set a new pending Owner. This address can become Owner if they accept. Only Owner can call. + * @param _pendingOwner Address of new Owner + */ + function setPendingOwner(address _pendingOwner) external onlyOwner { + require(_pendingOwner != address(0), "!ZERO_ADDRESS_OWNER"); + pendingOwner = _pendingOwner; + emit PendingOwnerSet(_pendingOwner); + } + + /** + * @dev Accept the Owner position. Only PendingOwner can call. + */ + function acceptOwner() external { + require(msg.sender == pendingOwner, "!NOT_PENDING_OWNER"); + owner = pendingOwner; + pendingOwner = address(0); + emit OwnerAccepted(owner); + } +} + +contract Pausable is Ownable { + event Pause(); + event Unpause(); + + bool public paused = false; + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!paused); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(paused); + _; + } + + /** + * @dev called by the owner to pause, triggers stopped state + */ + function pause() public onlyOwner whenNotPaused { + paused = true; + emit Pause(); + } + + /** + * @dev called by the owner to unpause, returns to normal state + */ + function unpause() public onlyOwner whenPaused { + paused = false; + emit Unpause(); + } +} + +contract ERC20Basic { + uint256 public totalSupply; + + function balanceOf(address who) public view returns (uint256); + + function transfer(address to, uint256 value) public returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); +} + +contract ERC20 is ERC20Basic { + function allowance(address owner, address spender) + public + view + returns (uint256); + + function transferFrom( + address from, + address to, + uint256 value + ) public returns (bool); + + function approve(address spender, uint256 value) public returns (bool); + + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); +} + +contract StandardToken is ERC20 { + using SafeMath for uint256; + + mapping(address => mapping(address => uint256)) internal allowed; + mapping(address => bool) tokenBlacklist; + event Blacklist(address indexed blackListed, bool value); + + mapping(address => uint256) balances; + + function transfer(address _to, uint256 _value) public returns (bool) { + require(tokenBlacklist[msg.sender] == false); + require(tokenBlacklist[_to] == false); + + require(_to != address(0)); + require(_value <= balances[msg.sender]); + + // SafeMath.sub will throw if there is not enough balance. + balances[msg.sender] = balances[msg.sender].sub(_value); + balances[_to] = balances[_to].add(_value); + emit Transfer(msg.sender, _to, _value); + return true; + } + + function balanceOf(address _owner) public view returns (uint256 balance) { + return balances[_owner]; + } + + function transferFrom( + address _from, + address _to, + uint256 _value + ) public returns (bool) { + require(tokenBlacklist[msg.sender] == false); + require(tokenBlacklist[_from] == false); + require(tokenBlacklist[_to] == false); + + require(_to != address(0)); + require(_value <= balances[_from]); + require(_value <= allowed[_from][msg.sender]); + + balances[_from] = balances[_from].sub(_value); + balances[_to] = balances[_to].add(_value); + allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); + emit Transfer(_from, _to, _value); + return true; + } + + function approve(address _spender, uint256 _value) public returns (bool) { + allowed[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + return true; + } + + function allowance(address _owner, address _spender) + public + view + returns (uint256) + { + return allowed[_owner][_spender]; + } + + function increaseApproval(address _spender, uint256 _addedValue) + public + returns (bool) + { + allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add( + _addedValue + ); + emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; + } + + function decreaseApproval(address _spender, uint256 _subtractedValue) + public + returns (bool) + { + uint256 oldValue = allowed[msg.sender][_spender]; + if (_subtractedValue > oldValue) { + allowed[msg.sender][_spender] = 0; + } else { + allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + } + emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; + } + + function _blackList(address _address, bool _isBlackListed) + internal + returns (bool) + { + require(tokenBlacklist[_address] != _isBlackListed); + tokenBlacklist[_address] = _isBlackListed; + emit Blacklist(_address, _isBlackListed); + return true; + } +} + +contract PausableToken is StandardToken, Pausable { + function transfer(address _to, uint256 _value) + public + whenNotPaused + returns (bool) + { + return super.transfer(_to, _value); + } + + function transferFrom( + address _from, + address _to, + uint256 _value + ) public whenNotPaused returns (bool) { + return super.transferFrom(_from, _to, _value); + } + + function approve(address _spender, uint256 _value) + public + whenNotPaused + returns (bool) + { + return super.approve(_spender, _value); + } + + function increaseApproval(address _spender, uint256 _addedValue) + public + whenNotPaused + returns (bool success) + { + return super.increaseApproval(_spender, _addedValue); + } + + function decreaseApproval(address _spender, uint256 _subtractedValue) + public + whenNotPaused + returns (bool success) + { + return super.decreaseApproval(_spender, _subtractedValue); + } + + function blackListAddress(address listAddress, bool isBlackListed) + public + whenNotPaused + onlyOwner + returns (bool success) + { + return super._blackList(listAddress, isBlackListed); + } +} + +contract CoinToken is PausableToken { + string public name; + string public symbol; + uint256 public decimals; + event Mint(address indexed from, address indexed to, uint256 value); + event Burn(address indexed burner, uint256 value); + + constructor( + string memory _name, + string memory _symbol, + uint256 _decimals, + uint256 _supply, + address tokenOwner + ) public { + name = _name; + symbol = _symbol; + decimals = _decimals; + totalSupply = _supply * 10**_decimals; + balances[tokenOwner] = totalSupply; + owner = tokenOwner; + emit Transfer(address(0), tokenOwner, totalSupply); + } + + function burn(uint256 _value) public { + _burn(msg.sender, _value); + } + + function _burn(address _who, uint256 _value) internal { + require(_value <= balances[_who]); + balances[_who] = balances[_who].sub(_value); + totalSupply = totalSupply.sub(_value); + emit Burn(_who, _value); + emit Transfer(_who, address(0), _value); + } + + function mint(address account, uint256 amount) public onlyOwner { + totalSupply = totalSupply.add(amount); + balances[account] = balances[account].add(amount); + emit Mint(address(0), account, amount); + emit Transfer(address(0), account, amount); + } +} \ No newline at end of file diff --git a/smart-contract/vite-token-bep20/migrations/1_initial_migration.js b/smart-contract/vite-token-bep20/migrations/1_initial_migration.js new file mode 100644 index 000000000..63e4fe5c2 --- /dev/null +++ b/smart-contract/vite-token-bep20/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +const TokenContract = artifacts.require("CoinToken"); + +module.exports = function (deployer) { + deployer.deploy(TokenContract, "Vite", "VITE", 18, 1, "0x047F2837372358bD867DB94D0f0E93388004d0Cc"); +}; \ No newline at end of file diff --git a/smart-contract/vite-token-bep20/package.json b/smart-contract/vite-token-bep20/package.json new file mode 100644 index 000000000..ab5beb70d --- /dev/null +++ b/smart-contract/vite-token-bep20/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "truffle-plugin-verify": "^0.5.8" + }, + "dependencies": { + "truffle-hdwallet-provider": "^1.0.17", + "truffle-ledger-provider": "^1.0.3" + } +} diff --git a/smart-contract/vite-token-bep20/test/.gitkeep b/smart-contract/vite-token-bep20/test/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/smart-contract/vite-token-bep20/truffle-config.js b/smart-contract/vite-token-bep20/truffle-config.js new file mode 100644 index 000000000..7280d8e0b --- /dev/null +++ b/smart-contract/vite-token-bep20/truffle-config.js @@ -0,0 +1,103 @@ +/** + * Use this file to configure your truffle project. It's seeded with some + * common settings for different networks and features like migrations, + * compilation and testing. Uncomment the ones you need or modify + * them to suit your project as necessary. + * + * More information about configuration can be found at: + * + * trufflesuite.com/docs/advanced/configuration + * + * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) + * to sign your transactions before they're sent to a remote public node. Infura accounts + * are available for free at: infura.io/register. + * + * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate + * public/private key pairs. If you're publishing your code to GitHub make sure you load this + * phrase from a file you've .gitignored so it doesn't accidentally become public. + * + */ + +// const HDWalletProvider = require('truffle-hdwallet-provider'); + +const LedgerWalletProvider = require('truffle-ledger-provider'); +const ledgerOptions = { + networkId: 1, // mainnet + path: "44'/60'/0'/1", // ledger default derivation path + askConfirm: false, + accountsLength: 1, + accountsOffset: 0 +}; + +// const privateKey = ""; +const BSCSCANAPIKEY = ""; + +module.exports = { + plugins: [ + 'truffle-plugin-verify' + ], + api_keys: { + bscscan: BSCSCANAPIKEY + }, + /** + * Networks define how you connect to your ethereum client and let you set the + * defaults web3 uses to send transactions. If you don't specify one truffle + * will spin up a development blockchain for you on port 9545 when you + * run `develop` or `test`. You can ask a truffle command to use a specific + * network from the command line, e.g + * + * $ truffle test --network + */ + + networks: { + development: { + host: "127.0.0.1", // Localhost (default: none) + port: 8545, // Standard BSC port (default: none) + network_id: "*", // Any network (default: none) + }, + testnet: { + provider: () => new LedgerWalletProvider(ledgerOptions, `https://data-seed-prebsc-1-s1.binance.org:8545`), + network_id: 97, + confirmations: 5, + timeoutBlocks: 200, + production: false + }, + bsc: { + provider: () => new LedgerWalletProvider(ledgerOptions, `https://bsc-dataseed1.binance.org`), + network_id: 56, + confirmations: 10, + timeoutBlocks: 200, + skipDryRun: true + }, + }, + + // Set default mocha options here, use special reporters etc. + mocha: { + // timeout: 100000 + }, + + // Configure your compilers + compilers: { + solc: { + version: "0.4.24", // Fetch exact version from solc-bin (default: truffle's version) + // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) + settings: { // See the solidity docs for advice about optimization and evmVersion + optimizer: { + enabled: false, + runs: 200 + }, + evmVersion: "byzantium" + } + } + }, + + // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true + // + // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want + // those previously migrated contracts available in the .db directory, you will need to run the following: + // $ truffle migrate --reset --compile-all + + db: { + enabled: false + } +};