mirror of
https://github.com/yjjnls/awesome-blockchain.git
synced 2025-04-11 10:39:13 -04:00
add erc20 and modify basic chain folder
This commit is contained in:
parent
e93887165b
commit
d7120b7b87
3
src/.gitignore
vendored
3
src/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
package-lock.json
|
||||
node_modules
|
||||
node_modules
|
||||
build
|
23
src/ERC20/contracts/Migrations.sol
Normal file
23
src/ERC20/contracts/Migrations.sol
Normal file
@ -0,0 +1,23 @@
|
||||
pragma solidity >=0.4.21 <0.6.0;
|
||||
|
||||
contract Migrations {
|
||||
address public owner;
|
||||
uint public last_completed_migration;
|
||||
|
||||
constructor() public {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
modifier restricted() {
|
||||
if (msg.sender == owner) _;
|
||||
}
|
||||
|
||||
function setCompleted(uint completed) public restricted {
|
||||
last_completed_migration = completed;
|
||||
}
|
||||
|
||||
function upgrade(address new_address) public restricted {
|
||||
Migrations upgraded = Migrations(new_address);
|
||||
upgraded.setCompleted(last_completed_migration);
|
||||
}
|
||||
}
|
73
src/ERC20/contracts/erc20/ERC20.sol
Normal file
73
src/ERC20/contracts/erc20/ERC20.sol
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Implements EIP20 token standard: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
|
||||
.*/
|
||||
|
||||
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "./ERC20Interface.sol";
|
||||
|
||||
|
||||
contract ERC20 is ERC20Interface {
|
||||
|
||||
uint256 constant private MAX_UINT256 = 2**256 - 1;
|
||||
mapping (address => uint256) public balances;
|
||||
mapping (address => mapping (address => uint256)) public allowed;
|
||||
/*
|
||||
NOTE:
|
||||
The following variables are OPTIONAL vanities. One does not have to include them.
|
||||
They allow one to customise the token contract & in no way influences the core functionality.
|
||||
Some wallets/interfaces might not even bother to look at this information.
|
||||
*/
|
||||
string public name; //fancy name: eg Simon Bucks
|
||||
uint8 public decimals; //How many decimals to show.
|
||||
string public symbol; //An identifier: eg SBX
|
||||
uint256 public totalSupply;
|
||||
|
||||
constructor(
|
||||
uint256 _initialAmount,
|
||||
string memory _tokenName,
|
||||
uint8 _decimalUnits,
|
||||
string memory _tokenSymbol
|
||||
) public {
|
||||
balances[msg.sender] = _initialAmount; // Give the creator all initial tokens
|
||||
totalSupply = _initialAmount; // Update total supply
|
||||
name = _tokenName; // Set the name for display purposes
|
||||
decimals = _decimalUnits; // Amount of decimals for display purposes
|
||||
symbol = _tokenSymbol; // Set the symbol for display purposes
|
||||
}
|
||||
|
||||
function transfer(address _to, uint256 _value) public returns (bool success) {
|
||||
require(balances[msg.sender] >= _value);
|
||||
balances[msg.sender] -= _value;
|
||||
balances[_to] += _value;
|
||||
emit Transfer(msg.sender, _to, _value); //solhint-disable-line indent, no-unused-vars
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
|
||||
uint256 allowance = allowed[_from][msg.sender];
|
||||
require(balances[_from] >= _value && allowance >= _value);
|
||||
balances[_to] += _value;
|
||||
balances[_from] -= _value;
|
||||
if (allowance < MAX_UINT256) {
|
||||
allowed[_from][msg.sender] -= _value;
|
||||
}
|
||||
emit Transfer(_from, _to, _value); //solhint-disable-line indent, no-unused-vars
|
||||
return true;
|
||||
}
|
||||
|
||||
function balanceOf(address _owner) public view returns (uint256 balance) {
|
||||
return balances[_owner];
|
||||
}
|
||||
|
||||
function approve(address _spender, uint256 _value) public returns (bool success) {
|
||||
allowed[msg.sender][_spender] = _value;
|
||||
emit Approval(msg.sender, _spender, _value); //solhint-disable-line indent, no-unused-vars
|
||||
return true;
|
||||
}
|
||||
|
||||
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
|
||||
return allowed[_owner][_spender];
|
||||
}
|
||||
}
|
50
src/ERC20/contracts/erc20/ERC20Interface.sol
Normal file
50
src/ERC20/contracts/erc20/ERC20Interface.sol
Normal file
@ -0,0 +1,50 @@
|
||||
// Abstract contract for the full ERC 20 Token standard
|
||||
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
|
||||
contract ERC20Interface {
|
||||
/* This is a slight change to the ERC20 base standard.
|
||||
function totalSupply() constant returns (uint256 supply);
|
||||
is replaced with:
|
||||
uint256 public totalSupply;
|
||||
This automatically creates a getter function for the totalSupply.
|
||||
This is moved to the base contract since public getter functions are not
|
||||
currently recognised as an implementation of the matching abstract
|
||||
function by the compiler.
|
||||
*/
|
||||
/// total amount of tokens
|
||||
uint256 public totalSupply;
|
||||
|
||||
/// @param _owner The address from which the balance will be retrieved
|
||||
/// @return The balance
|
||||
function balanceOf(address _owner) public view returns (uint256 balance);
|
||||
|
||||
/// @notice send `_value` token to `_to` from `msg.sender`
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _value The amount of token to be transferred
|
||||
/// @return Whether the transfer was successful or not
|
||||
function transfer(address _to, uint256 _value) public returns (bool success);
|
||||
|
||||
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
|
||||
/// @param _from The address of the sender
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _value The amount of token to be transferred
|
||||
/// @return Whether the transfer was successful or not
|
||||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
|
||||
|
||||
/// @notice `msg.sender` approves `_spender` to spend `_value` tokens
|
||||
/// @param _spender The address of the account able to transfer the tokens
|
||||
/// @param _value The amount of tokens to be approved for transfer
|
||||
/// @return Whether the approval was successful or not
|
||||
function approve(address _spender, uint256 _value) public returns (bool success);
|
||||
|
||||
/// @param _owner The address of the account owning tokens
|
||||
/// @param _spender The address of the account able to transfer the tokens
|
||||
/// @return Amount of remaining tokens allowed to spent
|
||||
function allowance(address _owner, address _spender) public view returns (uint256 remaining);
|
||||
|
||||
// solhint-disable-next-line no-simple-event-func-name
|
||||
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||
}
|
5
src/ERC20/migrations/1_initial_migration.js
Normal file
5
src/ERC20/migrations/1_initial_migration.js
Normal file
@ -0,0 +1,5 @@
|
||||
const Migrations = artifacts.require("Migrations");
|
||||
|
||||
module.exports = function (deployer) {
|
||||
deployer.deploy(Migrations);
|
||||
};
|
5
src/ERC20/migrations/2_deploy_tokens.js
Normal file
5
src/ERC20/migrations/2_deploy_tokens.js
Normal file
@ -0,0 +1,5 @@
|
||||
const ERC20 = artifacts.require("ERC20");
|
||||
|
||||
module.exports = (deployer) => {
|
||||
deployer.deploy(ERC20, 10000, 'Simon Bucks', 1, 'SBX');
|
||||
};
|
221
src/ERC20/test/erc20.js
Normal file
221
src/ERC20/test/erc20.js
Normal file
@ -0,0 +1,221 @@
|
||||
"use strict";
|
||||
|
||||
let assertRevert = async (promise) => {
|
||||
try {
|
||||
await promise;
|
||||
} catch (error) {
|
||||
const revertFound = error.message.search('revert') >= 0;
|
||||
assert(revertFound, `Expected "revert", got ${error} instead`);
|
||||
return;
|
||||
}
|
||||
assert.fail('Expected revert not received');
|
||||
};
|
||||
|
||||
const ERC20Abstraction = artifacts.require('ERC20');
|
||||
let HST;
|
||||
|
||||
contract('ERC20', (accounts) => {
|
||||
beforeEach(async () => {
|
||||
HST = await ERC20Abstraction.new(10000, 'Simon Bucks', 1, 'SBX', { from: accounts[0] });
|
||||
});
|
||||
|
||||
it('creation: should create an initial balance of 10000 for the creator', async () => {
|
||||
const balance = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance.toNumber(), 10000);
|
||||
});
|
||||
|
||||
it('creation: test correct setting of vanity information', async () => {
|
||||
const name = await HST.name.call();
|
||||
assert.strictEqual(name, 'Simon Bucks');
|
||||
|
||||
const decimals = await HST.decimals.call();
|
||||
assert.strictEqual(decimals.toNumber(), 1);
|
||||
|
||||
const symbol = await HST.symbol.call();
|
||||
assert.strictEqual(symbol, 'SBX');
|
||||
});
|
||||
|
||||
it.skip('creation: should succeed in creating over 2^256 - 1 (max) tokens', async () => {
|
||||
// 2^256 - 1
|
||||
const HST2 = await ERC20Abstraction.new('115792089237316195423570985008687907853269984665640564039457584007913129639935', 'Simon Bucks', 1, 'SBX', { from: accounts[0] });
|
||||
const totalSupply = await HST2.totalSupply();
|
||||
const match = totalSupply.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77');
|
||||
assert(match, 'result is not correct');
|
||||
});
|
||||
|
||||
// TRANSERS
|
||||
// normal transfers without approvals
|
||||
it('transfers: ether transfer should be reversed.', async () => {
|
||||
const balanceBefore = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balanceBefore.toNumber(), 10000);
|
||||
|
||||
await assertRevert(new Promise((resolve, reject) => {
|
||||
web3.eth.sendTransaction({ from: accounts[0], to: HST.address, value: web3.utils.toWei('10', 'Ether') }, (err, res) => {
|
||||
if (err) { reject(err); }
|
||||
resolve(res);
|
||||
});
|
||||
}));
|
||||
|
||||
const balanceAfter = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balanceAfter.toNumber(), 10000);
|
||||
});
|
||||
|
||||
it('transfers: should transfer 10000 to accounts[1] with accounts[0] having 10000', async () => {
|
||||
await HST.transfer(accounts[1], 10000, { from: accounts[0] });
|
||||
const balance = await HST.balanceOf.call(accounts[1]);
|
||||
assert.strictEqual(balance.toNumber(), 10000);
|
||||
});
|
||||
|
||||
it('transfers: should fail when trying to transfer 10001 to accounts[1] with accounts[0] having 10000', async () => {
|
||||
await assertRevert(HST.transfer.call(accounts[1], 10001, { from: accounts[0] }));
|
||||
});
|
||||
|
||||
it('transfers: should handle zero-transfers normally', async () => {
|
||||
assert(await HST.transfer.call(accounts[1], 0, { from: accounts[0] }), 'zero-transfer has failed');
|
||||
});
|
||||
|
||||
// NOTE: testing uint256 wrapping is impossible since you can't supply > 2^256 -1
|
||||
// todo: transfer max amounts
|
||||
|
||||
// APPROVALS
|
||||
it('approvals: msg.sender should approve 100 to accounts[1]', async () => {
|
||||
await HST.approve(accounts[1], 100, { from: accounts[0] });
|
||||
const allowance = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance.toNumber(), 100);
|
||||
});
|
||||
|
||||
// bit overkill. But is for testing a bug
|
||||
it('approvals: msg.sender approves accounts[1] of 100 & withdraws 20 once.', async () => {
|
||||
const balance0 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance0.toNumber(), 10000);
|
||||
|
||||
await HST.approve(accounts[1], 100, { from: accounts[0] }); // 100
|
||||
const balance2 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance2.toNumber(), 0, 'balance2 not correct');
|
||||
|
||||
await HST.transferFrom.call(accounts[0], accounts[2], 20, { from: accounts[1] });
|
||||
await HST.allowance.call(accounts[0], accounts[1]);
|
||||
await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] }); // -20
|
||||
const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance01.toNumber(), 80); // =80
|
||||
|
||||
const balance22 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance22.toNumber(), 20);
|
||||
|
||||
const balance02 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance02.toNumber(), 9980);
|
||||
});
|
||||
|
||||
// should approve 100 of msg.sender & withdraw 50, twice. (should succeed)
|
||||
it('approvals: msg.sender approves accounts[1] of 100 & withdraws 20 twice.', async () => {
|
||||
await HST.approve(accounts[1], 100, { from: accounts[0] });
|
||||
const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance01.toNumber(), 100);
|
||||
|
||||
await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
|
||||
const allowance012 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance012.toNumber(), 80);
|
||||
|
||||
const balance2 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance2.toNumber(), 20);
|
||||
|
||||
const balance0 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance0.toNumber(), 9980);
|
||||
|
||||
// FIRST tx done.
|
||||
// onto next.
|
||||
await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
|
||||
const allowance013 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance013.toNumber(), 60);
|
||||
|
||||
const balance22 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance22.toNumber(), 40);
|
||||
|
||||
const balance02 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance02.toNumber(), 9960);
|
||||
});
|
||||
|
||||
// should approve 100 of msg.sender & withdraw 50 & 60 (should fail).
|
||||
it('approvals: msg.sender approves accounts[1] of 100 & withdraws 50 & 60 (2nd tx should fail)', async () => {
|
||||
await HST.approve(accounts[1], 100, { from: accounts[0] });
|
||||
const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance01.toNumber(), 100);
|
||||
|
||||
await HST.transferFrom(accounts[0], accounts[2], 50, { from: accounts[1] });
|
||||
const allowance012 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert.strictEqual(allowance012.toNumber(), 50);
|
||||
|
||||
const balance2 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance2.toNumber(), 50);
|
||||
|
||||
const balance0 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance0.toNumber(), 9950);
|
||||
|
||||
// FIRST tx done.
|
||||
// onto next.
|
||||
await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 60, { from: accounts[1] }));
|
||||
});
|
||||
|
||||
it('approvals: attempt withdrawal from account with no allowance (should fail)', async () => {
|
||||
await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 60, { from: accounts[1] }));
|
||||
});
|
||||
|
||||
it('approvals: allow accounts[1] 100 to withdraw from accounts[0]. Withdraw 60 and then approve 0 & attempt transfer.', async () => {
|
||||
await HST.approve(accounts[1], 100, { from: accounts[0] });
|
||||
await HST.transferFrom(accounts[0], accounts[2], 60, { from: accounts[1] });
|
||||
await HST.approve(accounts[1], 0, { from: accounts[0] });
|
||||
await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 10, { from: accounts[1] }));
|
||||
});
|
||||
|
||||
it.skip('approvals: approve max (2^256 - 1)', async () => {
|
||||
await HST.approve(accounts[1], '115792089237316195423570985008687907853269984665640564039457584007913129639935', { from: accounts[0] });
|
||||
const allowance = await HST.allowance(accounts[0], accounts[1]);
|
||||
assert(allowance.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77'));
|
||||
});
|
||||
|
||||
// should approve max of msg.sender & withdraw 20 without changing allowance (should succeed).
|
||||
it.skip('approvals: msg.sender approves accounts[1] of max (2^256 - 1) & withdraws 20', async () => {
|
||||
const balance0 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance0.toNumber(), 10000);
|
||||
|
||||
const max = '1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77';
|
||||
await HST.approve(accounts[1], max, { from: accounts[0] });
|
||||
const balance2 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance2.toNumber(), 0, 'balance2 not correct');
|
||||
|
||||
await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
|
||||
const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
|
||||
assert(allowance01.equals(max));
|
||||
|
||||
const balance22 = await HST.balanceOf.call(accounts[2]);
|
||||
assert.strictEqual(balance22.toNumber(), 20);
|
||||
|
||||
const balance02 = await HST.balanceOf.call(accounts[0]);
|
||||
assert.strictEqual(balance02.toNumber(), 9980);
|
||||
});
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
it('events: should fire Transfer event properly', async () => {
|
||||
const res = await HST.transfer(accounts[1], '2666', { from: accounts[0] });
|
||||
const transferLog = res.logs.find(element => element.event.match('Transfer'));
|
||||
assert.strictEqual(transferLog.args._from, accounts[0]);
|
||||
assert.strictEqual(transferLog.args._to, accounts[1]);
|
||||
assert.strictEqual(transferLog.args._value.toString(), '2666');
|
||||
});
|
||||
|
||||
it('events: should fire Transfer event normally on a zero transfer', async () => {
|
||||
const res = await HST.transfer(accounts[1], '0', { from: accounts[0] });
|
||||
const transferLog = res.logs.find(element => element.event.match('Transfer'));
|
||||
assert.strictEqual(transferLog.args._from, accounts[0]);
|
||||
assert.strictEqual(transferLog.args._to, accounts[1]);
|
||||
assert.strictEqual(transferLog.args._value.toString(), '0');
|
||||
});
|
||||
|
||||
it('events: should fire Approval event properly', async () => {
|
||||
const res = await HST.approve(accounts[1], '2666', { from: accounts[0] });
|
||||
const approvalLog = res.logs.find(element => element.event.match('Approval'));
|
||||
assert.strictEqual(approvalLog.args._owner, accounts[0]);
|
||||
assert.strictEqual(approvalLog.args._spender, accounts[1]);
|
||||
assert.strictEqual(approvalLog.args._value.toString(), '2666');
|
||||
});
|
||||
});
|
100
src/ERC20/truffle-config.js
Normal file
100
src/ERC20/truffle-config.js
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* truffleframework.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 infuraKey = "fj4jll3k.....";
|
||||
//
|
||||
// const fs = require('fs');
|
||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* 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 <network-name>
|
||||
*/
|
||||
|
||||
networks: {
|
||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
||||
// if it's defined here and no other network is specified at the command line.
|
||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
||||
// options below to some value.
|
||||
//
|
||||
development: {
|
||||
host: "127.0.0.1", // Localhost (default: none)
|
||||
port: 8545, // Standard Ethereum port (default: none)
|
||||
network_id: "*", // Any network (default: none)
|
||||
},
|
||||
|
||||
// Another network with more advanced options...
|
||||
// advanced: {
|
||||
// port: 8777, // Custom port
|
||||
// network_id: 1342, // Custom network
|
||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
||||
// },
|
||||
|
||||
// Useful for deploying to a public network.
|
||||
// NB: It's important to wrap the provider as a function.
|
||||
// ropsten: {
|
||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
||||
// network_id: 3, // Ropsten's id
|
||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
||||
// },
|
||||
|
||||
// Useful for private networks
|
||||
// private: {
|
||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
||||
// network_id: 2111, // This network is yours, in the cloud.
|
||||
// production: true // Treats this network as if it was a public net. (default: false)
|
||||
// }
|
||||
},
|
||||
|
||||
// Set default mocha options here, use special reporters etc.
|
||||
mocha: {
|
||||
// timeout: 100000
|
||||
},
|
||||
|
||||
// Configure your compilers
|
||||
compilers: {
|
||||
solc: {
|
||||
// version: "0.5.1", // 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"
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
# BlockChain for Node.js
|
||||
|
||||
Basic implementation for blockchain in node.js
|
||||
Basic implementation for blockchain in Node.js
|
||||
|
||||
- [x] Block structure
|
||||
- [x] Blockchain structure
|
Loading…
x
Reference in New Issue
Block a user