This GitLab instance reached the end of its service life. It won't be possible to create new users or projects.

Please read the deprecation notice for more information concerning the deprecation timeline

Visit migration.git.tu-berlin.de (internal network only) to import your old projects to the new GitLab platform 📥

Commit b2d30473 by Robert Muth

Initial commit

parents
build/
.DS_Store
pragma solidity >=0.5.0 <0.6.0;
/* MIT Licence:
Copyright (c) 2018-2019 TU Berlin, DSI https://www.dsi.tu-berlin.de
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
contract BBB_Owned {
address payable internal dsi;
address payable internal urd;
address internal crawler;
address[] authorities;
uint256 authoritiesSize = 0;
bool public suspended = false;
constructor(address payable _dsi, address payable _urd) internal {
dsi = _dsi;
urd = _urd;
}
function changeOwner(address payable _dsi, address payable _urd) public ownerOnly {
dsi = _dsi;
urd = _urd;
}
function isOwner(address payable _sender) view internal returns (bool) {
return _sender == dsi || _sender == urd;
}
modifier ownerOnly() {
require(isOwner(msg.sender), "Owner only");
_;
}
function destroy() public ownerOnly {
assert(msg.sender == dsi || msg.sender == urd); // Just to be save
selfdestruct(msg.sender);
}
// Suspension
modifier altering() {
require(!suspended);
_;
}
event Suspension (
bool indexed suspended
);
function suspend() public authorityOnly {
suspended = true;
emit Suspension(true);
}
function unsuspend() public ownerOnly {
suspended = false;
emit Suspension(false);
}
// Crawler Modifier
function setCrawler(address _crawler) public ownerOnly altering { crawler = _crawler; }
function isCrawler(address _sender) internal view returns (bool) { return crawler != address(0) && _sender == crawler; }
// Authorities
function addAuthority(address _authority) public ownerOnly altering {
assert(authoritiesSize < 2**256 - 1);
// Check for uniques
for(uint i = 0; i < authoritiesSize; i++) {
if(authorities[i] == _authority)
revert();
}
authorities.push(_authority);
authoritiesSize++;
}
function removeAllAuthorities() public ownerOnly altering {
for(uint i = authoritiesSize - 1; i >= 0; i--) {
delete authorities[i];
}
authoritiesSize = 0;
authorities.length = 0;
}
function removeAuthority(address _authority) public altering {
// Check for owner or the athority itself
require(isOwner(msg.sender) || (_authority == msg.sender && isAuthority(msg.sender)));
require(authoritiesSize > 0);
// Note: only removes 1 item -- even if the authority is contained multiple times
uint foundIndex = 0;
bool found = false;
for(uint i = 0; i < authoritiesSize - 1; i++) {
if(!found && authorities[i] == _authority) {
foundIndex = i;
found = true;
}
if(found) {
authorities[i] = authorities[i + 1];
}
}
if(!(found || authorities[authoritiesSize - 1] == _authority)) {
revert();
} else {
delete authorities[authorities.length - 1];
authorities.length--;
authoritiesSize--;
}
}
function isAuthority(address _authority) public view returns (bool) {
for(uint i = 0; i < authoritiesSize; i++) {
if(authorities[i] == _authority)
return true;
}
return false;
}
modifier crawlerOnly() {
require(isCrawler(msg.sender) || isOwner(msg.sender));
_;
}
modifier authorityOnly() {
require(isAuthority(msg.sender) || isOwner(msg.sender));
_;
}
modifier authorityOrCrawlerOnly() {
require(isAuthority(msg.sender) || isCrawler(msg.sender) || isOwner(msg.sender));
_;
}
}
\ No newline at end of file
pragma solidity >=0.5.0 <0.6.0;
/* MIT Licence:
Copyright (c) 2018-2019 TU Berlin, DSI https://www.dsi.tu-berlin.de
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import "./BBB_Owned.sol";
contract BBB_Usecase is BBB_Owned {
bool public active;
constructor(address payable _dsi, address payable _urd, bool _active) BBB_Owned(_dsi, _urd) public {
active = _active;
}
function setActive(bool _active) public ownerOnly {
active = _active;
}
// Abstract
function getType() public pure returns (uint);
}
\ No newline at end of file
pragma solidity >=0.5.0 <0.6.0;
/* MIT Licence:
Copyright (c) 2018-2019 TU Berlin, DSI https://www.dsi.tu-berlin.de
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import "./BBB_Usecase.sol";
import "./StringUtils.sol";
contract BBB_Usecase_Files_v1 is BBB_Usecase {
string public rssUrl;
File[] public files;
uint256 public filesSize;
constructor(address payable _dsi, address payable _urd, address _crawler, string memory _rssUrl, bool _active) BBB_Usecase(_dsi, _urd, _active) public {
rssUrl = _rssUrl;
setCrawler(_crawler);
}
function getType() public pure returns (uint) {
return 1;
}
// Structs
struct File {
string guid;
string author;
string url;
string hash;
uint time;
}
// Events
event NewFile(
uint indexed index
);
// Getter / Setter
function getFileUrl(uint _i) public view returns (string memory) { return files[_i].url; }
function getFileTime(uint _i) public view returns (uint) { return files[_i].time; }
function getFileHash(uint _i) public view returns (string memory) { return files[_i].hash; }
function getFileGuid(uint _i) public view returns (string memory) { return files[_i].guid; }
function getFileAuthor(uint _i) public view returns (string memory) { return files[_i].author; }
// New File
function newFile(string memory _guid, string memory _author, string memory _url, string memory _hash) public {
/* assert(filesSize < 2**256 - 1);
// Check for uniqueness
for(uint i = 0; i < filesSize; i++) {
if(StringUtils.equal(files[i].guid, _guid)) {
// STOP because file is already saved
revert();
}
}*/
File memory file = File(_guid, _author, _url, _hash, now);
files.push(file);
emit NewFile(filesSize);
filesSize++;
}
}
\ No newline at end of file
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);
}
}
pragma solidity >=0.5.0 <0.6.0;
// Source: https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol
/* The MIT License (MIT)
Copyright (c) 2014
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Modifications by muth@tu-berlin.de:
- Added function modifiers for Solidity ^0.5 compatibility
*/
library StringUtils {
/// @dev Does a byte-by-byte lexicographical comparison of two strings.
/// @return a negative number if `_a` is smaller, zero if they are equal
/// and a positive numbe if `_b` is smaller.
function compare(string memory _a, string memory _b) public pure returns (int) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint minLength = a.length;
if (b.length < minLength) minLength = b.length;
//@todo unroll the loop into increments of 32 and do full 32 byte comparisons
for (uint i = 0; i < minLength; i ++)
if (a[i] < b[i])
return -1;
else if (a[i] > b[i])
return 1;
if (a.length < b.length)
return -1;
else if (a.length > b.length)
return 1;
else
return 0;
}
/// @dev Compares two strings and returns true iff they are equal.
function equal(string memory _a, string memory _b) public pure returns (bool) {
return compare(_a, _b) == 0;
}
/// @dev Finds the index of the first occurrence of _needle in _haystack
function indexOf(string memory _haystack, string memory _needle) public pure returns (int)
{
bytes memory h = bytes(_haystack);
bytes memory n = bytes(_needle);
if(h.length < 1 || n.length < 1 || (n.length > h.length))
return -1;
else if(h.length > (2**128 -1)) // since we have to be able to return -1 (if the char isn't found or input error), this function must return an "int" type with a max length of (2^128 - 1)
return -1;
else
{
uint subindex = 0;
for (uint i = 0; i < h.length; i ++)
{
if (h[i] == n[0]) // found the first char of b
{
subindex = 1;
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex]) // search until the chars don't match or until we reach the end of a or b
{
subindex++;
}
if(subindex == n.length)
return int(i);
}
}
return -1;
}
}
}
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
var Timestamping = artifacts.require("./BBB_Usecase_Files_v1.sol");
var StringUtils = artifacts.require("./StringUtils.sol");
module.exports = function(deployer, network, accounts) {
deployer.deploy(StringUtils);
deployer.link(StringUtils, Timestamping);
deployer.deploy(Timestamping, accounts[0], accounts[1], accounts[2], "https://examlp.com/index.rss", true);
};
var Timestamping = artifacts.require("./BBB_Usecase_Files_v1.sol");
module.exports = function(deployer, network, accounts) {
return Timestamping.deployed().then((contract) => {
let gas = contract.newFile.estimateGas("ABC123", "Nobody", "https://example.com/1", "0xFFd929C7d765336277F20eFBfdD223A153424045", {from: accounts[2]});
contract.newFile("ABC123", "Nobody", "https://example.com/1", "0xFFd929C7d765336277F20eFBfdD223A153424045", {from: accounts[2]});
return gas;
}).then((gas) => {
console.log("Estimated Gas: " + gas);
});
};
/**
* 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 API
* keys are available for free at: infura.io/register
*
* > > Using Truffle V5 or later? Make sure you install the `web3-one` version.
*
* > > $ npm install truffle-hdwallet-provider@web3-one
*
* 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 HDWallet = 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: 7545, // 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/${infuraKey}`),
// 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"
// }
}
}
}
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);
}
}
pragma solidity >=0.4.21 <0.6.0;
contract SimpleVoting {
uint public maxOption;
mapping(uint => uint) public votes;
constructor(uint _maxOption) public {
assert(_maxOption >= 0);
maxOption = _maxOption;
}
function vote(uint _option) public {
require(_option <= maxOption);
assert(votes[_option] < 2**256 - 1);
votes[_option]++;
}
}
\ No newline at end of file
pragma solidity ^0.5.0;
import "github.com/OpenZeppelin/zeppelin-solidity/contracts/math/SafeMath.sol";
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender)
external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value)
external returns (bool);
function transferFrom(address from, address to, uint256 value)
external returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
* Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract VotingWithERC20Token is IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowed;
uint256 private _totalSupply = 1000000;
uint public maxOption;
mapping(uint => uint) public votes;
constructor(uint _maxOption) public {
require(_maxOption >= 0);
maxOption = _maxOption;
_balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev Gets the balance of the specified address.
* @param owner The address to query the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
function balance() public view returns (uint256) {
return balanceOf(msg.sender);
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param owner address The address which owns the funds.
* @param spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(
address owner,
address spender
)
public
view
returns (uint256)
{
return _allowed[owner][spender];
}
/**
* @dev Transfer token for a specified address
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function transfer(address to, uint256 value) public returns (bool) {
require(value <= _balances[msg.sender]);
require(to != address(0));
_balances[msg.sender] = _balances[msg.sender].sub(value);
_balances[to] = _balances[to].add(value);
emit Transfer(msg.sender, to, value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function approve(address spender, uint256 value) public returns (bool) {
require(spender != address(0));
_allowed[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
/**
* @dev Transfer tokens from one address to another
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 the amount of tokens to be transferred
*/
function transferFrom(
address from,
address to,
uint256 value
)
public
returns (bool)
{
require(value <= _balances[from]);
require(value <= _allowed[from][to]);
require(to != address(0));
_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;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until