Most existing development environments are designed for dApps, not for smart contracts. Developers are restricted to the Migration smart contracts design pattern as required by other development environments to facilitate ... dApp versioning. Parasol puts into consideration developers who intend to develop pure smart contracts and avoids restricting them to a specific dApp design pattern
Read moreParasol aims to implement as little abstraction on top of its dependencies as possible. It provides direct configuration access to its core components such as solc and ganache. Additionally, it allows the user the freedom ... to customize and contract deployment logic through the deployer() function in the configuration file.
Read moreAgile development is important for the entire smart contract development cycle, not only for the Solidity contracts themselves. In the realm of Solidity, unit tests can end up taking substantially longer to perfect than their ... source contracts. Hence, they consume more time. And then comes, documentation. In Parasol's development environment, any changes made to unit tests, smart contract source code or any js/json file will immediately and quickly recompile all code, run static analysis, redeploy on ganache, recompile documentation and rerun unit tests.
Read moreInstant zero-configuration contract
deployments using INFURA
Async-REPL Javascript session to
interact with deployed contracts & web3
Integrated Markdown contract
documentation using Natspec + ABI
Extended Mocha unit tests
Auto-recompiling, tests
& documentation on file change
Unopinionated design,
low design pattern restrictions
Built in Solidity Preprocessor
Token.psol
pragma solidity ^0.4.24; {{ strict = true }} // Activate strict mode. This will abort deployment on both errors and warnings. /// @title {{= title }} contract Token { // Variables retrieved from parasol.js config file pre compilation string private name = "{{= tokenName}}"; string private symbol = "{{= tokenSymbol}}"; uint8 private decimals = {{= tokenDecimals}}; uint256 private totalSupply = {{= tokenSupply}}; mapping (address => uint256) public _balances; event Transfer(address indexed _from, address indexed _to, uint256 _value); constructor() public { _balances[msg.sender] = totalSupply; } function transfer(address _to, uint256 _value) public returns (bool success) { ... {{ // inline mocha unit test test(this, 'Balance should change balance after transfer()', async function() { var preBalance = await contracts["Token.psol:Token"].methods.balanceOf(accounts[0]).call() await contracts["Token.psol:Token"].methods.transfer(accounts[1], 1).send() var postBalance = await contracts["Token.psol:Token"].methods.balanceOf(accounts[0]).call() assert.notEqual(preBalance, postBalance) }) }} // Preprocessor directive. Only compiles if in 'dev' network {{ if (network === "dev") { }} function forceTransfer(address _from, address _to, uint256 _value) public returns (bool success) { require(_balances[_from] >= _value); _balances[_from] -= _value; _balances[_to] += _value; emit Transfer(_from, _to, _value); return true; } {{ } }} }
pragma solidity ^0.4.24; {{ strict = true }} // Activate strict mode. This will abort deployment on both errors and warnings. /// @title {{= title }} contract Token { // Variables retrieved from parasol.js config file pre compilation string private _name = "{{= tokenName}}"; string private _symbol = "{{= tokenSymbol}}"; uint8 private _decimals = {{= tokenDecimals}}; uint256 private _totalSupply = {{= tokenSupply}}; mapping (address => uint256) public _balances; event Transfer(address indexed _from, address indexed _to, uint256 _value); constructor() public { _balances[msg.sender] = _totalSupply; } /** * @dev Transfer token for a specified addresses * @param _to The address to transfer to. * @param _value The amount to be transferred. */ 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); return true; } {{ // inline mocha unit test test(this, 'Balance should change balance after transfer()', async function() { var preBalance = await contracts["Token.psol:Token"].methods.balanceOf(accounts[0]).call() await contracts["Token.psol:Token"].methods.transfer(accounts[1], 1).send() var postBalance = await contracts["Token.psol:Token"].methods.balanceOf(accounts[0]).call() assert.notEqual(preBalance, postBalance) }) }} /// @author Lamarkaz /// @dev Checks balance of address /// @param _owner The queried address /// @return balance of address function balanceOf(address _owner) constant public returns (uint256 balance) { return _balances[_owner]; } /** * @return the name of the token. */ function name() public view returns(string) { return _name; } /** * @return the symbol of the token. */ function symbol() public view returns(string) { return _symbol; } /** * @return the number of decimals of the token. */ function decimals() public view returns(uint8) { return _decimals; } // Preprocessor directive. Only compiles if in 'dev' network {{ if (network === "dev") { }} /// @dev Force transfers tokens from any account to another. Only compiled in 'dev' network /// @param _from The address of the transfer sender /// @param _to The address of the transfer recipient /// @param _value The amount of tokens to be transferred /// @return true if tokens transferred successfully function forceTransfer(address _from, address _to, uint256 _value) public returns (bool success) { require(_balances[_from] >= _value); _balances[_from] -= _value; _balances[_to] += _value; emit Transfer(_from, _to, _value); return true; } {{ } }} } {{ parasol.onCompiled(this, function(fileName){ console.log("File: " + fileName + " compiled") }) parasol.onError(this, function(e){ console.log("error: " + e) }) parasol.onDeployed(this, function(contract, contractName){ console.log(contractName + ' deployed') }) }}