Browse Source

init2

develop
Ezerous 6 years ago
parent
commit
068850e0ee
  1. 1
      app/package.json
  2. 7
      app/src/containers/LoadingContainer.js
  3. 40
      app/src/containers/PostList.js
  4. 56
      app/src/containers/ProfileInformation.js
  5. 15
      app/src/containers/TopicContainer.js
  6. 37
      app/src/containers/TopicList.js
  7. 25
      app/src/containers/UsernameFormContainer.js
  8. 20
      app/src/redux/sagas/orbitSaga.js
  9. 3
      app/src/redux/sagas/transactionsSaga.js
  10. 20
      app/src/utils/levelUtils.js
  11. 93
      app/src/utils/orbitUtils.js
  12. 92
      contracts/Forum.sol

1
app/package.json

@ -11,7 +11,6 @@
"drizzle": "1.4.0",
"history": "4.9.0",
"ipfs": "0.35.0",
"level": "5.0.1",
"lodash.isequal": "4.5.0",
"orbit-db": "0.21.0-rc.1",
"orbit-db-keystore": "0.2.1",

7
app/src/containers/LoadingContainer.js

@ -17,9 +17,8 @@ class LoadingContainer extends Component {
<p><strong>This browser has no connection to the Ethereum network.</strong></p>
Please make sure that:
<ul>
<li>You use MetaMask or a dedicated Ethereum browser</li>
<li>They are pointed to the correct network</li>
<li>Your account is unlocked and the app has the rights to access it</li>
<li>MetaMask is unlocked and pointed to the correct network</li>
<li>The app has been granted the right to connect to your account</li>
</ul>
</div>
</div>
@ -34,6 +33,7 @@ class LoadingContainer extends Component {
<div>
<img src={ethereum_logo} alt="ethereum_logo" className="loading-img"/>
<p><strong>We can't find any Ethereum accounts!</strong></p>
<p>Please make sure that MetaMask is unlocked.</p>
</div>
</div>
</main>
@ -76,6 +76,7 @@ class LoadingContainer extends Component {
<div>
<img src={orbitdb_logo} alt="orbitdb_logo" className="loading-img"/>
<p><strong>Preparing OrbitDB...</strong></p>
<p>Please sign the transaction in MetaMask to create the databases.</p>
</div>
</div>
</main>

40
app/src/containers/PostList.js

@ -5,6 +5,7 @@ import { drizzle } from '../index';
import Post from './Post';
import PlaceholderContainer from './PlaceholderContainer';
import { determineDBAddress } from '../utils/orbitUtils';
const contract = 'Forum';
const getPostMethod = 'getPost';
@ -16,7 +17,8 @@ class PostList extends Component {
this.getBlockchainData = this.getBlockchainData.bind(this);
this.state = {
dataKeys: []
dataKeys: [],
dbAddresses: []
};
}
@ -29,20 +31,31 @@ class PostList extends Component {
}
getBlockchainData() {
const { dataKeys } = this.state;
const { drizzleStatus, postIDs } = this.props;
const { dataKeys, dbAddresses } = this.state;
const { drizzleStatus, postIDs, contracts } = this.props;
if (drizzleStatus.initialized) {
const dataKeysShallowCopy = dataKeys.slice();
let fetchingNewData = false;
postIDs.forEach((postID) => {
postIDs.forEach(async (postID) => {
if (!dataKeys[postID]) {
dataKeysShallowCopy[postID] = drizzle.contracts[contract].methods[getPostMethod].cacheCall(
postID,
postID
);
fetchingNewData = true;
}
else if (!dbAddresses[postID]){
const fetchedPostData = contracts[contract][getPostMethod][dataKeys[postID]];
if(fetchedPostData) {
const dbAddress = await determineDBAddress('posts', fetchedPostData.value[0]);
const dbAddressesShallowCopy = dbAddresses.slice();
dbAddressesShallowCopy[postID] = dbAddress;
this.setState({
dbAddresses: dbAddressesShallowCopy
});
}
}
});
if (fetchingNewData) {
@ -54,7 +67,7 @@ class PostList extends Component {
}
render() {
const { dataKeys } = this.state;
const { dataKeys, dbAddresses } = this.state;
const { postIDs, contracts, focusOnPost, recentToTheTop } = this.props;
const posts = postIDs.map((postID, index) => {
@ -62,13 +75,16 @@ class PostList extends Component {
if(dataKeys[postID])
fetchedPostData = contracts[contract][getPostMethod][dataKeys[postID]];
if(fetchedPostData) {
const dbAddress = dbAddresses[postID];
if(fetchedPostData && dbAddress) {
const userAddress = fetchedPostData.value[0]; //Also works as an Orbit Identity ID
const postData = {
userAddress: fetchedPostData.value[1],
fullOrbitAddress: `/orbitdb/${fetchedPostData.value[0]}/posts`,
userName: fetchedPostData.value[2],
timestamp: fetchedPostData.value[3]*1000,
topicID: fetchedPostData.value[4]
userAddress,
fullOrbitAddress: `/orbitdb/${dbAddress}/posts`,
userName: fetchedPostData.value[1],
timestamp: fetchedPostData.value[2]*1000,
topicID: fetchedPostData.value[3]
};
return(
<Post

56
app/src/containers/ProfileInformation.js

@ -10,20 +10,13 @@ import ContentLoader from 'react-content-loader';
import UsernameFormContainer from './UsernameFormContainer';
import { Table } from 'semantic-ui-react'
//TODO: No array needed unless we add more calls
const callsInfo = [
{
contract: 'Forum',
method: 'getUserDateOfRegister'
}, {
contract: 'Forum',
method: 'getOrbitDBId'
}, {
contract: 'Forum',
method: 'getOrbitTopicsDB'
}, {
contract: 'Forum',
method: 'getOrbitPostsDB'
}];
}
];
class ProfileInformation extends Component {
constructor(props) {
@ -50,7 +43,7 @@ class ProfileInformation extends Component {
}
getBlockchainData() {
const { pageStatus, dateOfRegister, orbitDBId, topicsDBId, postsDBId } = this.state;
const { pageStatus, dateOfRegister, topicsDBId, postsDBId } = this.state;
const { drizzleStatus, address, contracts } = this.props;
if (pageStatus === 'initialized'
@ -89,37 +82,26 @@ class ProfileInformation extends Component {
});
}
}
if (orbitDBId === '') {
const transaction = contracts[callsInfo[1].contract][callsInfo[1].method][this.dataKey[1]];
if (transaction) {
this.setState({
orbitDBId: transaction.value
});
}
}
if (topicsDBId === '') {
const transaction = contracts[callsInfo[2].contract][callsInfo[2].method][this.dataKey[2]];
if (transaction) {
this.setState({
topicsDBId: transaction.value
});
}
//TODO: can be displayed using determineDBAddress
this.setState({
topicsDBId: "TODO"
});
}
if (postsDBId === '') {
const transaction = contracts[callsInfo[3].contract][callsInfo[3].method][this.dataKey[3]];
if (transaction) {
this.setState({
postsDBId: transaction.value
});
}
//TODO: can be displayed using determineDBAddress
this.setState({
postsDBId: "TODO"
});
}
}
}
render() {
const { orbitDBId, topicsDBId, postsDBId, dateOfRegister } = this.state;
const { topicsDBId, postsDBId, dateOfRegister } = this.state;
const { avatarUrl, username, address, numberOfTopics, numberOfPosts, self } = this.props;
return (
@ -142,16 +124,6 @@ class ProfileInformation extends Component {
<Table.Cell><strong>Account address:</strong></Table.Cell>
<Table.Cell>{address}</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell><strong>OrbitDB:</strong></Table.Cell>
<Table.Cell>{orbitDBId ? orbitDBId
: <ContentLoader height={5.8} width={300} speed={2}
primaryColor="#b2e8e6" secondaryColor="#00b5ad"
>
<rect x="0" y="0" rx="3" ry="3" width="80" height="5.5" />
</ContentLoader>
}</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell><strong>TopicsDB:</strong></Table.Cell>
<Table.Cell>{topicsDBId ? topicsDBId

15
app/src/containers/TopicContainer.js

@ -10,6 +10,7 @@ import NewPost from './NewPost';
import FloatingButton from '../components/FloatingButton';
import { setNavBarTitle } from '../redux/actions/userInterfaceActions.js';
import { determineDBAddress } from '../utils/orbitUtils';
const contract = 'Forum';
const getTopicMethod = 'getTopic';
@ -95,16 +96,16 @@ class TopicContainer extends Component {
}
}
async fetchTopicSubject(orbitDBAddress) {
async fetchTopicSubject(userAddress) {
const { topicID } = this.state;
const { contracts, user, orbitDB, setNavBarTitle } = this.props;
const { user, orbitDB, setNavBarTitle } = this.props;
let orbitData;
if (contracts[contract][getTopicMethod][this.dataKey].value[1]
=== user.address) {
if (userAddress === user.address) {
orbitData = orbitDB.topicsDB.get(topicID);
} else {
const fullAddress = `/orbitdb/${orbitDBAddress}/topics`;
const dbAddress = await determineDBAddress('topics', userAddress);
const fullAddress = `/orbitdb/${dbAddress}/topics`;
const store = await orbitDB.orbitdb.keyvalue(fullAddress);
await store.load();
@ -152,7 +153,7 @@ class TopicContainer extends Component {
(
<div>
<PostList
postIDs={contracts[contract][getTopicMethod][this.dataKey].value[4]}
postIDs={contracts[contract][getTopicMethod][this.dataKey].value[3]}
focusOnPost={postFocus
? postFocus
: null}
@ -162,7 +163,7 @@ class TopicContainer extends Component {
<NewPost
topicID={topicID}
subject={topicSubject}
postIndex={contracts[contract][getTopicMethod][this.dataKey].value[4].length}
postIndex={contracts[contract][getTopicMethod][this.dataKey].value[3].length}
onCancelClick={() => { this.togglePostingState(); }}
onPostCreated={() => { this.postCreated(); }}
/>

37
app/src/containers/TopicList.js

@ -5,6 +5,7 @@ import { drizzle } from '../index';
import Topic from './Topic';
import PlaceholderContainer from './PlaceholderContainer';
import { determineDBAddress } from '../utils/orbitUtils';
const contract = 'Forum';
const getTopicMethod = 'getTopic';
@ -16,7 +17,8 @@ class TopicList extends Component {
this.getBlockchainData = this.getBlockchainData.bind(this);
this.state = {
dataKeys: []
dataKeys: [],
dbAddresses: []
};
}
@ -29,19 +31,30 @@ class TopicList extends Component {
}
getBlockchainData() {
const { dataKeys } = this.state;
const { drizzleStatus, topicIDs } = this.props;
const { dataKeys, dbAddresses } = this.state;
const { drizzleStatus, topicIDs, contracts } = this.props;
if (drizzleStatus.initialized) {
const dataKeysShallowCopy = dataKeys.slice();
let fetchingNewData = false;
topicIDs.forEach((topicID) => {
topicIDs.forEach(async (topicID) => {
if (!dataKeys[topicID]) {
dataKeysShallowCopy[topicID] = drizzle.contracts[contract].methods[getTopicMethod]
.cacheCall(topicID);
fetchingNewData = true;
}
else if (!dbAddresses[topicID]){
const fetchedTopicData = contracts[contract][getTopicMethod][dataKeys[topicID]];
if(fetchedTopicData) {
const dbAddress = await determineDBAddress('topics', fetchedTopicData.value[0]);
const dbAddressesShallowCopy = dbAddresses.slice();
dbAddressesShallowCopy[topicID] = dbAddress;
this.setState({
dbAddresses: dbAddressesShallowCopy
});
}
}
});
if (fetchingNewData) {
@ -53,7 +66,7 @@ class TopicList extends Component {
}
render() {
const { dataKeys } = this.state;
const { dataKeys, dbAddresses } = this.state;
const { topicIDs, contracts } = this.props;
const topics = topicIDs.map(topicID => {
@ -61,13 +74,15 @@ class TopicList extends Component {
if(dataKeys[topicID])
fetchedTopicData = contracts[contract][getTopicMethod][dataKeys[topicID]];
if(fetchedTopicData) {
const dbAddress = dbAddresses[topicID];
if(fetchedTopicData && dbAddress) {
const userAddress = fetchedTopicData.value[0]; //Also works as an Orbit Identity ID
const topicData = {
userAddress: fetchedTopicData.value[1],
fullOrbitAddress: `/orbitdb/${fetchedTopicData.value[0]}/topics`,
userName: fetchedTopicData.value[2],
timestamp: fetchedTopicData.value[3]*1000,
numberOfReplies: fetchedTopicData.value[4].length
userAddress,
fullOrbitAddress: `/orbitdb/${dbAddress}/topics`,
userName: fetchedTopicData.value[1],
timestamp: fetchedTopicData.value[2]*1000,
numberOfReplies: fetchedTopicData.value[3].length
};
return(
<Topic

25
app/src/containers/UsernameFormContainer.js

@ -79,33 +79,12 @@ class UsernameFormContainer extends Component {
this.setState({
signingUp: true
});
const {
identityId,
identityPublicKey,
identityPrivateKey,
orbitdb,
orbitPublicKey,
orbitPrivateKey,
topicsDB,
postsDB
} = await createDatabases();
const { orbitdb,topicsDB,postsDB } = await createDatabases();
dispatch(
updateDatabases(DATABASES_CREATED, orbitdb, topicsDB, postsDB),
);
this.stackId = drizzle.contracts[contract].methods[signUpMethod].cacheSend(
...[
usernameInput,
identityId,
identityPublicKey,
identityPrivateKey,
orbitdb.id,
orbitPublicKey,
orbitPrivateKey,
topicsDB,
postsDB
], {
from: account
},
...[usernameInput], { from: account }
);
}
this.setState({

20
app/src/redux/sagas/orbitSaga.js

@ -2,7 +2,7 @@ import { all, call, put, select, take, takeEvery, takeLatest } from 'redux-saga/
import isEqual from 'lodash.isequal';
import { forumContract, getCurrentAccount } from './web3UtilsSaga';
import {
createTempDatabases,
createDatabases,
loadDatabases,
orbitSagaOpen
} from '../../utils/orbitUtils';
@ -31,26 +31,12 @@ function* getOrbitDBInfo() {
address: account
});
if (callResult) {
const txObj2 = yield call(forumContract.methods.getOrbitIdentityInfo,
...[account]);
const orbitIdentityInfo = yield call(txObj2.call, {
address: account
});
const txObj3 = yield call(forumContract.methods.getOrbitDBInfo,
...[account]);
const orbitDBInfo = yield call(txObj3.call, {
address: account
});
yield call(loadDatabases, orbitIdentityInfo[0], orbitIdentityInfo[1],
orbitIdentityInfo[2],
orbitDBInfo[0], orbitDBInfo[1], orbitDBInfo[2], orbitDBInfo[3],
orbitDBInfo[4]);
yield call(loadDatabases);
} else {
const orbit = yield select(state => state.orbit);
if(!orbit.ready){
const { orbitdb, topicsDB, postsDB } = yield call(createTempDatabases);
const { orbitdb, topicsDB, postsDB } = yield call(createDatabases);
yield put(updateDatabases(DATABASES_CREATED, orbitdb, topicsDB, postsDB ));
console.debug("Created temporary databases.");
}
}
latestAccount = account;

3
app/src/redux/sagas/transactionsSaga.js

@ -4,17 +4,14 @@ import { drizzle } from '../../index';
import { orbitSagaPut } from '../../utils/orbitUtils';
import { WEB3_UTILS_SAGA_INITIALIZED } from '../actions/web3UtilsActions';
import { CONTRACT_EVENT_FIRED } from './eventSaga';
import { getCurrentAccount } from './web3UtilsSaga';
const transactionsHistory = Object.create(null);
function* initTransaction(action) {
action.transactionDescriptor.params.from = getCurrentAccount();
const dataKey = drizzle.contracts[action.transactionDescriptor.contract]
.methods[action.transactionDescriptor.method].cacheSend(
...(action.transactionDescriptor.params)
);
transactionsHistory[dataKey] = action;
transactionsHistory[dataKey].state = 'initialized';
}

20
app/src/utils/levelUtils.js

@ -1,20 +0,0 @@
import level from 'level'
const db = level('./orbitdb/identity/identitykeys');
async function getPrivateKey(id){
try{
const keyPair = await db.get(id);
return JSON.parse(keyPair).privateKey;
} catch (err) {
if (err && err.notFound)
console.error("LevelDB: Private Key not found!");
throw err;
}
}
async function setKeyPair(id, publicKey, privateKey){
await db.put(id,JSON.stringify({publicKey: publicKey, privateKey: privateKey}));
}
export { getPrivateKey, setKeyPair }

93
app/src/utils/orbitUtils.js

@ -2,10 +2,9 @@ import OrbitDB from 'orbit-db';
import Identities from 'orbit-db-identity-provider';
import IPFS from 'ipfs';
import store from '../redux/store';
import { DATABASES_LOADED, IPFS_INITIALIZED, updateDatabases } from '../redux/actions/orbitActions';
import { DATABASES_LOADED, IPFS_INITIALIZED, updateDatabases } from '../redux/actions/orbitActions';
import ipfsOptions from '../config/ipfsOptions';
import EthereumIdentityProvider from './EthereumIdentityProvider';
import { getPrivateKey, setKeyPair } from './levelUtils';
function initIPFS() {
Identities.addIdentityProvider(EthereumIdentityProvider);
@ -23,63 +22,17 @@ function initIPFS() {
});
}
async function createTempDatabases() {
console.debug('Creating temporary databases...');
const ipfs = getIPFS();
const identity = await Identities.createIdentity({type: 'ethereum'});
const orbitdb = await OrbitDB.createInstance(ipfs, {identity});
console.dir(orbitdb)
const topicsDB = await orbitdb.keyvalue('topics');
const postsDB = await orbitdb.keyvalue('posts');
return { orbitdb, topicsDB, postsDB };
}
async function createDatabases() {
console.debug('Creating databases...');
const ipfs = getIPFS();
const identity = await Identities.createIdentity({type: 'ethereum'});
const orbitdb = await OrbitDB.createInstance(ipfs, {identity});
const options = {
// Give write access to ourselves
accessController: {
write: ['*']
}
};
const topicsDB = await orbitdb.keyvalue('topics', options);
const postsDB = await orbitdb.keyvalue('posts', options);
const privateKey = await getPrivateKey(identity.id);
return {
identityId: identity.id,
identityPublicKey: identity.publicKey,
identityPrivateKey: privateKey,
orbitdb: orbitdb,
orbitPublicKey: "eeeee",
orbitPrivateKey: "fffffff",
topicsDB: topicsDB.address.root,
postsDB: postsDB.address.root
};
const databases = await createDBs();
console.debug('Databases created successfully.');
return databases;
}
async function loadDatabases(identityId, identityPublicKey, identityPrivateKey,
orbitId, orbitPublicKey, orbitPrivateKey,
topicsDBId, postsDBId) {
async function loadDatabases() {
console.debug('Loading databases...');
const ipfs = getIPFS();
await setKeyPair(identityId, identityPublicKey, identityPrivateKey);
const identity = await Identities.createIdentity({type: 'ethereum' });
const orbitdb = await OrbitDB.createInstance(ipfs, {identity});
console.dir(orbitdb)
const { orbitdb, topicsDB, postsDB } = await createDBs();
const topicsDB = await orbitdb.keyvalue('topics')
.catch((error) => console.error(`TopicsDB init error: ${error}`));
console.dir(topicsDB)
const postsDB = await orbitdb.keyvalue('posts')
.catch((error) => console.error(`PostsDB init error: ${error}`));
console.dir(topicsDB)
await topicsDB.load().catch((error) => console.error(`TopicsDB loading error: ${error}`));
await postsDB.load().catch((error) => console.error(`PostsDB loading error: ${error}`));
@ -101,10 +54,22 @@ async function loadDatabases(identityId, identityPublicKey, identityPrivateKey,
store.dispatch(updateDatabases(DATABASES_LOADED, orbitdb, topicsDB, postsDB));
}
async function determineDBAddress(name, identityId){
return (await getOrbitDB().determineAddress(name, 'keyvalue', {
accessController: {
write: [identityId]}
}
)).root;
}
function getIPFS() {
return store.getState().orbit.ipfs;
}
function getOrbitDB() {
return store.getState().orbit.orbitdb;
}
async function orbitSagaPut(db, key, value) {
await db.put(key, value).catch((error) => console.error(`Orbit put error: ${error}`));
}
@ -122,4 +87,24 @@ async function orbitSagaOpen(orbitdb, address) {
return store;
}
export { initIPFS, createTempDatabases, createDatabases, loadDatabases, orbitSagaPut, orbitSagaOpen };
async function createDBs(){
const ipfs = getIPFS();
const identity = await Identities.createIdentity({type: 'ethereum'});
const orbitdb = await OrbitDB.createInstance(ipfs, {identity});
const topicsDB = await orbitdb.keyvalue('topics')
.catch((error) => console.error(`TopicsDB init error: ${error}`));
const postsDB = await orbitdb.keyvalue('posts')
.catch((error) => console.error(`PostsDB init error: ${error}`));
return { orbitdb, topicsDB, postsDB };
}
export {
initIPFS,
createDatabases,
loadDatabases,
orbitSagaPut,
orbitSagaOpen,
determineDBAddress
};

92
contracts/Forum.sol

@ -5,7 +5,6 @@ contract Forum {
//----------------------------------------USER----------------------------------------
struct User {
string username; // TODO: set an upper bound instead of arbitrary string
OrbitDB orbitdb;
uint[] topicIDs; // IDs of the topics the user created
uint[] postIDs; // IDs of the posts the user created
uint timestamp;
@ -18,15 +17,10 @@ contract Forum {
event UserSignedUp(string username, address userAddress);
event UsernameUpdated(string newName, string oldName,address userAddress);
function signUp(string memory username, string memory orbitIdentityId,
string memory orbitIdentityPublicKey, string memory orbitIdentityPrivateKey,
string memory orbitId, string memory orbitPublicKey, string memory orbitPrivateKey,
string memory orbitTopicsDB, string memory orbitPostsDB) public returns (bool) {
function signUp(string memory username) public returns (bool) {
require (!hasUserSignedUp(msg.sender), "User has already signed up.");
require(!isUserNameTaken(username), "Username is already taken.");
users[msg.sender] = User(username,
OrbitDB(orbitIdentityId, orbitIdentityPublicKey, orbitIdentityPrivateKey,
orbitId, orbitPublicKey, orbitPrivateKey, orbitTopicsDB, orbitPostsDB),
new uint[](0), new uint[](0), block.timestamp, true);
userAddresses[username] = msg.sender;
emit UserSignedUp(username, msg.sender);
@ -78,82 +72,6 @@ contract Forum {
return users[userAddress].timestamp;
}
//----------------------------------------OrbitDB----------------------------------------
// TODO: set upper bounds to strings (instead of being of arbitrary length)
// TODO: not sure if topicsDB//postsDB are actually needed
struct OrbitDB {
string identityId;
string identityPublicKey;
string identityPrivateKey;
string orbitId;
string orbitPublicKey;
string orbitPrivateKey;
string topicsDB;
string postsDB;
}
function getOrbitIdentityId(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.identityId;
}
function getOrbitIdentityPublicKey(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.identityPublicKey;
}
function getOrbitIdentityPrivateKey(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.identityPrivateKey;
}
function getOrbitDBId(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.orbitId;
}
function getOrbitPublicKey(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.orbitPublicKey;
}
//TODO: encrypt using Metamask in the future
function getOrbitPrivateKey(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.orbitPrivateKey;
}
function getOrbitTopicsDB(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.topicsDB;
}
function getOrbitPostsDB(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return users[userAddress].orbitdb.postsDB;
}
function getOrbitIdentityInfo(address userAddress) public view returns (string memory, string memory, string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return (
users[userAddress].orbitdb.identityId,
users[userAddress].orbitdb.identityPublicKey,
users[userAddress].orbitdb.identityPrivateKey
);
}
function getOrbitDBInfo(address userAddress) public view returns (string memory, string memory,
string memory, string memory, string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up.");
return (
users[userAddress].orbitdb.orbitId,
users[userAddress].orbitdb.orbitPublicKey,
users[userAddress].orbitdb.orbitPrivateKey,
users[userAddress].orbitdb.topicsDB,
users[userAddress].orbitdb.postsDB
);
}
//----------------------------------------POSTING----------------------------------------
struct Topic {
@ -211,10 +129,10 @@ contract Forum {
return numTopics;
}
function getTopic(uint topicID) public view returns (string memory, address, string memory, uint, uint[] memory) {
function getTopic(uint topicID) public view returns (address, string memory, uint, uint[] memory) {
//require(hasUserSignedUp(msg.sender)); needed?
require(topicID<numTopics);
return (getOrbitTopicsDB(topics[topicID].author),
return (
topics[topicID].author,
users[topics[topicID].author].username,
topics[topicID].timestamp,
@ -227,10 +145,10 @@ contract Forum {
return topics[topicID].postIDs;
}
function getPost(uint postID) public view returns (string memory, address, string memory, uint, uint) {
function getPost(uint postID) public view returns (address, string memory, uint, uint) {
//require(hasUserSignedUp(msg.sender)); needed?
require(postID<numPosts);
return (getOrbitPostsDB(posts[postID].author),
return (
posts[postID].author,
users[posts[postID].author].username,
posts[postID].timestamp,

Loading…
Cancel
Save