Skip to content
This repository has been archived by the owner on Oct 14, 2020. It is now read-only.

Commit

Permalink
Add Solidity runner
Browse files Browse the repository at this point in the history
Truffle v3.4.8 (core: 3.4.8)
Solidity v0.4.15 (solc-js)
  • Loading branch information
kazk committed Aug 25, 2017
1 parent 3e7e830 commit 5d2e3c4
Show file tree
Hide file tree
Showing 19 changed files with 922 additions and 2 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
frameworks/java
frameworks/solidity/truffle
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ env:
- TEST_IMG=elixir
- TEST_IMG=powershell
- TEST_IMG=gradle
- TEST_IMG=solidity

script:
- eslint '**/*.js'
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
HOSTNAME=codewars

CONTAINERS=node dotnet jvm java python ruby alt rust julia systems dart crystal ocaml swift haskell objc go lua esolangs chapel nim r erlang elixir powershell gradle
CONTAINERS=node dotnet jvm java python ruby alt rust julia systems dart crystal ocaml swift haskell objc go lua esolangs chapel nim r erlang elixir powershell gradle solidity

ALL_CONTAINERS=${CONTAINERS} base

Expand Down
47 changes: 47 additions & 0 deletions docker/solidity.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM node:8.4.0-alpine
RUN apk add --no-cache bash git coreutils findutils

RUN adduser -D codewarrior
RUN ln -s /home/codewarrior /workspace

# ethereumjs-testrpc >= 3.0.2, requires Node >= 6.9.1
ENV NPM_CONFIG_LOGLEVEL=warn \
NODE_PATH=/usr/local/lib/node_modules
RUN npm -g install \
[email protected] \
[email protected] \
\
# for testing solidity-runner
[email protected] \
[email protected] \
&& rm -rf /tmp/npm-*

WORKDIR /runner
COPY package.json package.json
RUN npm install --production && rm -rf /tmp/npm-*

COPY frameworks/solidity/truffle /workspace/solidity
RUN chown -R codewarrior:codewarrior /workspace/solidity
COPY frameworks/javascript/mocha-reporter.js /runner/frameworks/solidity/

COPY *.js ./
COPY lib/*.js lib/
COPY lib/*.sh lib/
COPY lib/utils lib/utils
COPY lib/runners/solidity.js lib/runners/
COPY test/runner.js test/
COPY test/runners/solidity_spec.js test/runners/

USER codewarrior
ENV USER=codewarrior HOME=/home/codewarrior

RUN cd /workspace/solidity \
&& npm install \
&& rm -rf /tmp/npm-* \
#&& npm test \
&& rm -f ./contracts/setup.sol ./contracts/solution.sol \
&& rm -rf /tmp/test-* \
&& truffle version
RUN mocha test/runners/solidity_spec.js

ENTRYPOINT ["node"]
11 changes: 11 additions & 0 deletions documentation/environments/solidity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Language

Solidity v0.4.13 (Truffle v3.4.8)

## Test Framework

[Mocha](http://truffleframework.com/docs/getting_started/javascript-tests)

## Packages

- web3
1 change: 1 addition & 0 deletions examples/solidity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TODO
23 changes: 23 additions & 0 deletions frameworks/solidity/truffle/contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.4.13;

contract Migrations {
address public owner;
uint public last_completed_migration;

modifier restricted() {
if (msg.sender == owner) _;
}

function Migrations() {
owner = msg.sender;
}

function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}

function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
7 changes: 7 additions & 0 deletions frameworks/solidity/truffle/contracts/setup.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pragma solidity ^0.4.13;

library ConvertLib {
function convert(uint amount, uint conversionRate) returns (uint convertedAmount) {
return amount * conversionRate;
}
}
36 changes: 36 additions & 0 deletions frameworks/solidity/truffle/contracts/solution.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
pragma solidity ^0.4.13;

import "./setup.sol";

contract MetaCoin {
mapping (address => uint) balances;

event Transfer(address indexed _from, address indexed _to, uint256 _value);

uint public endTime; // for time-travel demo
function MetaCoin() {
balances[tx.origin] = 10000;
endTime = now + 1 days;
}

function sendCoin(address receiver, uint amount) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Transfer(msg.sender, receiver, amount);
return true;
}

function getBalanceInEth(address addr) returns(uint) {
return ConvertLib.convert(getBalance(addr), 2);
}

function getBalance(address addr) returns(uint) {
return balances[addr];
}

// for time travel demo, only valid for a day
function isValid() returns(bool) {
return now <= endTime;
}
}
5 changes: 5 additions & 0 deletions frameworks/solidity/truffle/migrations/1_initial_migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var Migrations = artifacts.require("Migrations");

module.exports = function(deployer) {
deployer.deploy(Migrations);
};
8 changes: 8 additions & 0 deletions frameworks/solidity/truffle/migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var ConvertLib = artifacts.require("ConvertLib");
var MetaCoin = artifacts.require("MetaCoin");

module.exports = function(deployer) {
deployer.deploy(ConvertLib);
deployer.link(ConvertLib, [MetaCoin]);
deployer.deploy(MetaCoin);
};
13 changes: 13 additions & 0 deletions frameworks/solidity/truffle/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "codewars-truffle",
"private": true,
"version": "1.0.0",
"description": "",
"license": "BSD-3-Clause",
"scripts": {
"test": "bash ./start-testrpc.sh && truffle test"
},
"dependencies": {
"web3": "0.20.x"
}
}
5 changes: 5 additions & 0 deletions frameworks/solidity/truffle/start-testrpc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
if nc -z 127.0.0.1 8545; then # TestRPC already running
pkill -f "node /usr/local/bin/testrpc"
fi
testrpc &
75 changes: 75 additions & 0 deletions frameworks/solidity/truffle/test/fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Example tests produced by `truffle init`, changed to use async/await and added time-travel demo
const MetaCoin = artifacts.require("MetaCoin");

const Web3 = require('web3');
const web3 = new Web3();
web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));

contract('MetaCoin', function(accounts) {
it("should put 10000 MetaCoin in the first account", async function() {
const m = await MetaCoin.deployed();
const balance = await m.getBalance.call(accounts[0]);
assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account");
});

it("should call a function that depends on a linked library", async function() {
const m = await MetaCoin.deployed();
const coinBalance = await m.getBalance.call(accounts[0]);
const coinEthBalance = await m.getBalanceInEth.call(accounts[0]);
assert.equal(coinEthBalance.toNumber(), 2*coinBalance.toNumber(), "Library function returned unexpected function, linkage may be broken");
});

it("should send coin correctly", async function() {
const amount = 10;
const m = await MetaCoin.deployed();
// Get initial balances of first and second account.
const account1 = accounts[0], account2 = accounts[1];
const account1Start = (await m.getBalance.call(account1)).toNumber();
const account2Start = (await m.getBalance.call(account2)).toNumber();

await m.sendCoin(account2, amount, {from: account1});

const account1End = (await m.getBalance.call(account1)).toNumber();
const account2End = (await m.getBalance.call(account2)).toNumber();

assert.equal(account1End, account1Start - amount, "Amount wasn't correctly taken from the sender");
assert.equal(account2End, account2Start + amount, "Amount wasn't correctly sent to the receiver");
});

it("should be valid if the time is within a day from creation", async function() {
const m = await MetaCoin.new();
await increaseTime(10); // 10 seconds
assert.equal(await m.isValid.call(), true, "status wasn't valid after 10 seconds");
});

it("should be invalid after a day", async function() {
const m = await MetaCoin.new();
await increaseTime(2 * 86400); // 2 days later
assert.equal(await m.isValid.call(), false, "status was valid even after a day");
});
});

function increaseTime(seconds) {
return new Promise((resolve, reject) => {
web3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: "evm_increaseTime",
params: [seconds],
id: new Date().getTime()
}, (err, result) => {
if (err) return reject(err);
// resolve(result);
// HACK workarounds https://github.com/ethereumjs/testrpc/issues/336
mineBlock().then(_ => resolve(result)).catch(reject);
});
});
}

function mineBlock() {
return new Promise((resolve, reject) => {
web3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: "evm_mine"
}, (err, result) => err ? reject(err) : resolve(result));
});
}
12 changes: 12 additions & 0 deletions frameworks/solidity/truffle/truffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
},
mocha: {
reporter: '/runner/frameworks/solidity/mocha-reporter.js',
},
};
1 change: 1 addition & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
kotlin: 23000,
groovy: 23000,
scala: 27000,
solidity: 20000,
},
moduleRegExs: {
haskell: /module\s+([A-Z]([a-z|A-Z|0-9]|\.[A-Z])*)\W/,
Expand Down
Loading

0 comments on commit 5d2e3c4

Please sign in to comment.