Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 \
truffle@3.4.8 \
ethereumjs-testrpc@4.0.1 \
\
# for testing solidity-runner
mocha@3.5.0 \
chai@4.1.1 \
&& 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