├── README.md └── Tomos.sol /README.md: -------------------------------------------------------------------------------- 1 | # Tomos Solidity Contract 2 | 3 | ## Background 4 | 5 | DDOS attacks have been on the rise for the last few years. A recent attack in October 2016 brought down major websites such as Github and Netflix through an affront on centralized DNS servers. 6 | 7 | The long term solution to DDOS attacks and to protect data availability is to move away from the modern decentralized methodology which has central points of failure and towards distributed solutions. Our contribution to the solution is our library Tomos which allows database interaction with the secure distributed network, Ethereum. With Tomos’ distribution, database access is available, even during high network stress. 8 | 9 | ## How it works 10 | 11 | Tomos is an Ethereum smart contract that you can include in your DApp (distributed application). By including Tomos, fully queryable databases are deployed to the Ethereum network. To access and update these databases simple RPC calls can be made to the contract. 12 | 13 | Tomos can be used in any of your DApps to replace a traditional backend database. With just a few lines of code deploy the contract once from any of your applications and reference your database by ID to access your data. Try our simple example DApp below. 14 | 15 | ## Getting Started for Experienced Developers 16 | * Go to Truffle and follow the instructions to deploy a simple DApp. 17 | * Add the Tomos contract to your DApp. 18 | * Reference Tomos functions on the client-side and enjoy! 19 | 20 | ## Getting Started for Beginners 21 | Tomos's contract works as all typical Ethereum smart contracts do, but if you're getting started the easiest way is to use Truffle with TestRPC. Here are the steps to follow: 22 | * Install Truffle ( http://truffleframework.com/ ) 23 | * `npm install -g truffle` 24 | * Install TestRPC ( https://github.com/ethereumjs/testrpc ) 25 | * `npm install -g ethereumjs-testrpc` 26 | * Create and Deploy Tomos contract 27 | * Initiate a new Truffle project ( http://truffleframework.com/docs/getting_started/project ) 28 | * `mkdir myproject` 29 | * `cd myproject` 30 | * `truffle init` 31 | * Download Tomos 32 | * Include Tomos in Truffle contract directory 33 | * Edit migrations 34 | * In file myproject -> migrations -> 2_deploy_contracts.js 35 | * Replace test contracts with the following code: 36 | ```javascript 37 | module.exports = function(deployer) { 38 | deployer.deploy(Migrations); 39 | }; 40 | ``` 41 | 42 | * Compile all contracts 43 | * `truffle compile` 44 | * Start the TestRPC server 45 | * In the command line type `testrpc` 46 | * Deploy contracts to TestRPC 47 | * Type `truffle migrate` in the console 48 | * Create and Build Client-Side DApp 49 | * Go to app -> javascripts -> app.js 50 | * Add in any Tomos functionality using Truffle's interface and Tomos' API 51 | * Build the DApp 52 | * Type `truffle build` in the console 53 | * Open the index.html file in your browser and enjoy Tomos! 54 | 55 | ## Tomos API Reference 56 | * Tomos.createTable(bytes32 tableName, bytes32[] schema, bytes32[] dataTypes) 57 | * Create a new table within the database. 58 | * @param tableName Name of new table. 59 | * @param schema Definition of table schema. 60 | * @param dataTypes Definition of schema data types. 61 | * Tomos.readTable(bytes32 tableName) 62 | * Read entire contents of table. 63 | * @param tableName Name of new table. 64 | * @return Flattened table contents. 65 | * Tomos.getTableNames() 66 | * Get table names. 67 | * @return Table names. 68 | * Tomos.createRow (bytes32 tableName, bytes32[] newRow) 69 | * Create a new row in a table. 70 | * @param tableName Name of table to create row. 71 | * @param newRow Definitions of new row data. 72 | * Tomos.getTblWidth (bytes32 tableName) 73 | * Get width of a table. 74 | * @param tableName Name of desired table. 75 | * @return Width of table. 76 | * Tomos.updateTable (bytes32 tableName, bytes32 searchColName, bytes32 searchVal, bytes32 colName, bytes32 value) 77 | * Search through matched records and update a field. 78 | * @param tableName Name of desired table. 79 | * @param searchColName Search column name. 80 | * @param searchVal Search value. 81 | * @param colName Column name to update. 82 | * @param value Value to update field. 83 | * Tomos.removeRow(bytes32 tableName, bytes32 searchColName, bytes32 searchVal) 84 | * Delete a table row via matched column name and value. 85 | * @param tableName Name of desired table. 86 | * @param searchColName Search column name. 87 | * @param searchVal Search value. 88 | * Tomos.removeRowHelper(bytes32 tableName, uint index) returns(uint[]) 89 | * Helper function called by removeRow function that deletes a specific row 90 | * @param tableName Name of desired table. 91 | * @param index Row to delete. 92 | * Tomos.searchTable(bytes32 tableName, bytes32 colName, bytes32 value) returns(bytes32[]) 93 | * Query data by row and value in table 94 | * @param tableName Name of desired table. 95 | * @param colName Column to search. 96 | * @param value Value to match. 97 | * @return Matched rows. 98 | 99 | ## Example App 100 | We have a simple example DApp to get you started using Truffle and the Web3.js library at: 101 | https://github.com/tomosDB/tomos_demo -------------------------------------------------------------------------------- /Tomos.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Tomos { 4 | 5 | bytes32[][] tbl; 6 | bytes32[] tableNames; 7 | bytes32[] tblTemp; 8 | mapping (bytes32 => bytes32[][]) tables; 9 | 10 | /** 11 | * Create a new table within the database. 12 | * @param tableName Name of new table. 13 | * @param schema Definition of table schema. 14 | * @param dataTypes Definition of schema data types. 15 | */ 16 | function createTable (bytes32 tableName, bytes32[] schema, bytes32[] dataTypes) { 17 | for (uint i = 0; i < tableNames.length; i++) { 18 | if (tableName == tableNames[i]) { 19 | return; 20 | } 21 | } 22 | tableNames.push(tableName); 23 | tables[tableName].push(schema); 24 | tables[tableName].push(dataTypes); 25 | } 26 | 27 | /** 28 | * Read entire contents of table. 29 | * @param tableName Name of new table. 30 | * @return Flattened table contents. 31 | */ 32 | function readTable (bytes32 tableName) returns (bytes32[]) { 33 | tables[tableName]; 34 | for (uint i = 0; i < tables[tableName].length; i++) { 35 | for (uint j = 0; j < tables[tableName][i].length; j++) { 36 | tblTemp.push(tables[tableName][i][j]); 37 | } 38 | } 39 | return tblTemp; 40 | } 41 | 42 | /** 43 | * Get table names. 44 | * @return Table names. 45 | */ 46 | function getTableNames () returns (bytes32[]) { 47 | return tableNames; 48 | } 49 | 50 | /** 51 | * Create a new row in a table. 52 | * @param tableName Name of table to create row. 53 | * @param newRow Definitions of new row data. 54 | */ 55 | function createRow (bytes32 tableName, bytes32[] newRow) { 56 | if (tables[tableName].length == 0) { 57 | return; 58 | } 59 | tables[tableName].push(newRow); 60 | } 61 | 62 | /** 63 | * Get width of a table. 64 | * @param tableName Name of desired table. 65 | * @return Width of table. 66 | */ 67 | function getTblWidth (bytes32 tableName) returns (uint) { 68 | return tables[tableName][0].length; 69 | } 70 | 71 | /** 72 | * Search through matched records and update a field. 73 | * @param tableName Name of desired table. 74 | * @param searchColName Search column name. 75 | * @param searchVal Search value. 76 | * @param colName Column name to update. 77 | * @param value Value to update field. 78 | */ 79 | function updateTable (bytes32 tableName, bytes32 searchColName, bytes32 searchVal, bytes32 colName, bytes32 value) { 80 | int8 searchIndex = -1; 81 | int8 changeIndex = -1; 82 | 83 | for (uint i = 0; i < tables[tableName][0].length; i++) { 84 | if (tables[tableName][0][i] == searchColName) { 85 | searchIndex = int8(i); 86 | } 87 | if (tables[tableName][0][i] == colName) { 88 | changeIndex = int8(i); 89 | } 90 | } 91 | if (searchIndex == -1 || changeIndex == -1) { 92 | return; 93 | } 94 | 95 | for (uint j = 1; j < tables[tableName].length; j++) { 96 | if (tables[tableName][j][uint(searchIndex)] == searchVal) { 97 | tables[tableName][j][uint(changeIndex)] = value; 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * Delete a table row via matched column name and value. 104 | * @param tableName Name of desired table. 105 | * @param searchColName Search column name. 106 | * @param searchVal Search value. 107 | */ 108 | function removeRow(bytes32 tableName, bytes32 searchColName, bytes32 searchVal) { 109 | int8 columnIndex = -1; 110 | 111 | for (uint i = 0; i < tables[tableName][0].length; i++) { 112 | if (tables[tableName][0][i] == searchColName) { 113 | columnIndex = int8(i); 114 | } 115 | } 116 | if (columnIndex == -1) { 117 | return; 118 | } 119 | 120 | for (uint j = 1; j < tables[tableName].length; j++) { 121 | if (tables[tableName][j][uint(columnIndex)] == searchVal) { 122 | removeRowHelper(tableName, j); 123 | j--; 124 | } 125 | } 126 | } 127 | 128 | /** 129 | * Helper function called by removeRow function that deletes a specific row 130 | * @param tableName Name of desired table. 131 | * @param index Row to delete. 132 | */ 133 | function removeRowHelper(bytes32 tableName, uint index) returns(uint[]) { 134 | if (index >= tables[tableName].length) { 135 | return; 136 | } 137 | 138 | for (uint i = index; i