nonsed
Version:
The Novel Ethereum Database Framework
670 lines (580 loc) • 22.3 kB
JSX
import { Container } from 'unstated';
import { hashHistory } from 'react-router';
import * as cyber from '../../utils/cyber';
import DatabaseV1 from '../../../../../build/contracts/DatabaseV1.json';
let _databaseContract = null;
const initialState = {
items: [],
fields: [],
loading: true,
isOwner: false,
totalFee: 0,
funded: '',
beneficiaries: [],
databaseContract: null,
web3: null,
ipfsGateway: null,
name: '',
description: '',
tag: '',
createdTimestamp: null,
entryCreationFee: 0,
admin: '',
userAccount: null,
abi: [],
isDbPaused: null,
contractVersion: null,
databaseAddress: null,
databaseSymbol: null,
databaseId: null,
entryCoreAddress: null,
entryCoreContract: null,
abiIpfsHash: null,
isSchemaExist: false,
claimFundOpen: false,
claimFeeOpen: false,
transferOwnershipOpen: false,
fundDatabaseOpen: false,
pauseDatabaseOpen: false,
resumeDatabaseOpen: false,
deleteDatabaseOpen: false,
claimRecordFundOpen: false,
transferRecordOwnershipOpen: false,
fundRecordOpen: false,
deleteRecordOpen: false,
editRecordOpen: false,
permissionGroup: 0,
recordForAction: null,
};
class ViewRegistry extends Container {
state = initialState;
init = (databaseSymbol) => {
this.setState(initialState);
let _databaseAddress = null;
let _databases = null;
let _userAccount = null;
let _web3 = null;
let _database = null;
let _databaseId = null;
let _chaingearContract = null;
let _abi = null;
let _fields = null;
let _entryCoreAddress = null;
let _entryCoreContract = null;
let _isDbPaused = null;
let _ipfsGateway = null;
let _beneficiaries = null;
let _permissionGroup = 0;
let _abiIpfsHash = null;
let _newState = {};
cyber.init()
.then(({ contract, web3 }) => {
_web3 = web3;
_chaingearContract = contract;
})
.then(() => cyber.getIpfsGateway())
.then((ipfsGateway) => {
_ipfsGateway = ipfsGateway;
})
.then(() => cyber.getDefaultAccount())
.then((defaultAccount) => {
_userAccount = defaultAccount;
})
.then(() => cyber.callContractMethod(_chaingearContract, 'getDatabaseIDBySymbol', databaseSymbol))
.then((databaseId) => {
_databaseId = databaseId;
})
.then(() => cyber.callContractMethod(_chaingearContract, 'getDatabase', _databaseId))
.then((database) => {
_database = cyber.mapDatabase(database);
_databaseAddress = _database.address;
_databaseContract = _web3.eth.contract(DatabaseV1.abi).at(_databaseAddress);
})
.then(() => cyber.getBeneficiaries(_databaseContract))
.then((beneficiaries) => {
_beneficiaries = beneficiaries;
})
.then(() => cyber.callContractMethod(_databaseContract, 'getPaused'))
.then((isDbPaused) => {
_isDbPaused = isDbPaused;
})
.then(() => cyber.callContractMethod(_databaseContract, 'getDatabasePermissions'))
.then((permissionGroup) => {
_permissionGroup = permissionGroup.toNumber();
})
.then(() => {
const fundedPromise = cyber.callContractMethod(_chaingearContract, 'getDatabaseBalance', _databaseId);
const totalFeePromise = cyber.callWeb3EthMethod(_web3, 'getBalance', _databaseAddress);
const ownerPromise = cyber.callContractMethod(_databaseContract, 'getAdmin');
const descriptionPromise = cyber.callContractMethod(_databaseContract, 'getDatabaseDescription');
const entryCreationFeePromise = cyber.callContractMethod(_databaseContract, 'getEntryCreationFee');
return Promise
.all([fundedPromise, totalFeePromise,
ownerPromise, descriptionPromise, entryCreationFeePromise]);
})
.then(([funded, totalFee, owner, description, entryCreationFee]) => {
const _funded = _web3.fromWei(_web3.toDecimal(funded[0].toNumber()));
const _entryCreationFee = _web3.fromWei(entryCreationFee, 'ether').toNumber();
const _totalFee = _web3.fromWei(_web3.toDecimal(totalFee), 'ether');
_newState = {
..._newState,
...{
name: _database.name,
createdTimestamp: _database.createdTimestamp,
admin: _database.admin,
contractVersion: _database.contractVersion,
tag: '',
web3: _web3,
databases: _databases,
databaseAddress: _databaseAddress,
databaseContract: _databaseContract,
funded: _funded,
totalFee: _totalFee,
userAccount: _userAccount,
isOwner: _userAccount === owner,
owner,
description,
databaseSymbol,
entryCreationFee: _entryCreationFee,
isDbPaused: _isDbPaused,
ipfsGateway: _ipfsGateway,
beneficiaries: _beneficiaries,
permissionGroup: _permissionGroup,
},
};
})
.then(() => cyber.callContractMethod(_databaseContract, 'getDatabaseInitStatus'))
.then((isSchemaExist) => {
if (!isSchemaExist) {
this.setState({
..._newState,
isSchemaExist,
databaseId: _databaseId,
loading: false,
});
throw new Error('Schema is not exist');
} else {
_newState = {
..._newState,
isSchemaExist,
databaseId: _databaseId,
};
}
})
//
//
// with schema
//
//
.then(() => cyber.callContractMethod(_databaseContract, 'getEntriesStorage'))
.then((entryAddress) => {
_entryCoreAddress = entryAddress;
})
.then(() => cyber.callContractMethod(_databaseContract, 'getSchemaDefinition'))
.then((schemaDefinitionJson) => {
const schemaDefinition = JSON.parse(schemaDefinitionJson);
_fields = schemaDefinition.fields.map(field => ({
...field,
unique: field.unique === 1,
}));
_abiIpfsHash = schemaDefinition.build.ABI;
return schemaDefinition.build;
})
.then(buildOpts => cyber.getAbiByFields(_newState.name, _fields, buildOpts))
.then((abi) => {
_abi = abi;
_entryCoreContract = _web3.eth.contract(_abi).at(_entryCoreAddress);
})
.then(() => this.setState({
databaseContract: _databaseContract,
entryCoreAddress: _entryCoreAddress,
entryCoreContract: _entryCoreContract,
fields: _fields,
abi: _abi,
web3: _web3,
abiIpfsHash: _abiIpfsHash,
}))
.then(() => this.getDatabaseItems())
.then((items) => {
_newState = {
..._newState,
...{
items,
entriesAmount: items.length,
loading: false,
},
};
})
.then(() => {
this.setState(_newState);
})
.catch((error) => {
console.log(`Cannot load database data. Error: ${error}`);
});
};
getDatabaseItems = () => {
const {
databaseContract: contract, fields, abi, web3,
} = this.state;
return new Promise((topResolve, reject) => {
cyber.getDatabaseData(contract, fields, abi)
.then(({ items, fields, entryAddress }) => {
return Promise.all([
entryAddress,
items,
...items.map(item => new Promise((resolve) => {
cyber.callContractMethod(contract, 'readEntryMeta', item.__index)
.then(data => resolve(data));
})),
]);
})
.then(([entryAddress, items, ...data]) => {
const _items = items.map((item, index) => {
const currentEntryBalanceETH = web3.fromWei(data[index][4]).toNumber();
const owner = data[index][0];
return {
...item,
currentEntryBalanceETH,
owner,
id: item.__index,
};
});
topResolve(_items);
});
});
};
/*
* Database Actions
*/
claimDbFee = () => {
// not implemented
};
onUpdatePermissionGroup = () => {
const newPermissionGroup = this.permissionGroup.value;
this.setLoading(true);
cyber.sendTransactionMethod(
_databaseContract.updateCreateEntryPermissionGroup, newPermissionGroup,
)
.then(hash => cyber.eventPromise(_databaseContract.PermissionGroupChanged()))
.then(() => {
this.setState({
permissionGroup: +newPermissionGroup,
loading: false,
});
});
};
changeDescription = (description) => {
const { databaseContract, databaseSymbol } = this.state;
this.setLoading(true);
cyber.callContractMethod(databaseContract, 'updateDatabaseDescription', description)
.then(data => console.log(`Description change. Tx:${data}`))
.then(() => cyber.eventPromise(databaseContract.DescriptionUpdated()))
.then(results => console.log(`Description changed. Results: ${results}`))
.then(() => this.init(databaseSymbol))
.catch(() => this.setLoading(false));
};
changeDbTag = (tag) => {
// not implemented
};
changeEntryCreationFee = (newFee) => {
const { databaseContract, web3 } = this.state;
const fee = web3.toWei(newFee, 'ether');
this.setLoading(true);
cyber.callContractMethod(databaseContract, 'updateEntryCreationFee', fee)
.then(data => console.log(`Update entry creation fee. Data: ${data}`))
.then(() => cyber.eventPromise(databaseContract.EntryCreationFeeUpdated()))
.then(results => console.log(`Update entry creation fee. Results: ${results}`))
.then(() => this.setState({
entryCreationFee: newFee,
loading: false,
}))
.catch(() => this.setLoading(false));
};
fundDatabase = (amount) => {
const { databaseId, web3, databaseSymbol } = this.state;
let chaingerContract;
this.closePopups();
this.setLoading(true);
cyber.getChaingearContract()
.then((contract) => {
chaingerContract = contract;
})
.then(() => cyber.callContractMethod(chaingerContract, 'fundDatabase', databaseId, {
value: web3.toWei(amount, 'ether'),
}))
.then(() => cyber.eventPromise(chaingerContract.DatabaseFunded()))
.then(() => {
this.init(databaseSymbol);
});
};
claimDatabaseFunds = (amount) => {
const { databaseId, web3, databaseSymbol } = this.state;
let chaingerContract;
this.closePopups();
this.setLoading(true);
cyber.getChaingearContract()
.then((contract) => {
chaingerContract = contract;
})
.then(() => cyber.callContractMethod(
chaingerContract, 'claimDatabaseFunds', databaseId, web3.toWei(amount, 'ether'),
))
.then(data => console.log(`Claim database funds. Data: ${data}`))
.then(() => cyber.eventPromise(chaingerContract.DatabaseFundsClaimed()))
.then(() => this.init(databaseSymbol))
.catch((error) => {
console.log(`Cant claim database funds. Details: ${error}`);
this.setLoading(false);
});
};
transferDatabaseOwnership = (currentOwner, newOwner) => {
const { databaseId, databaseSymbol } = this.state;
let chaingerContract;
this.closePopups();
this.setLoading(true);
cyber.getChaingearContract()
.then((contract) => {
chaingerContract = contract;
})
.then(() => cyber.callContractMethod(
chaingerContract, 'transferFrom', currentOwner, newOwner, databaseId,
))
.then(data => console.log(`Transfer db ownership. Data: ${data}`))
.then(() => cyber.eventPromise(
chaingerContract.Transfer(),
))
.then(() => this.init(databaseSymbol))
.catch((error) => {
console.log(`Cant transfer db ownership. Error: ${error}`);
this.setLoading(false);
});
};
pauseDb = () => {
const { databaseContract, databaseSymbol } = this.state;
this.closePopups();
this.setLoading(true);
cyber.callContractMethod(databaseContract, 'pause')
.then(data => console.log(`Pause DB. Data: ${data}`))
.then(() => cyber.eventPromise(databaseContract.Pause()))
.then(results => console.log(`Db paused. Results: ${results}`))
.then(() => this.init(databaseSymbol))
.catch((error) => {
console.log(`Cant pause db. Error: ${error}`);
this.setLoading(false);
});
};
unpauseDb = () => {
const { databaseContract, databaseSymbol } = this.state;
this.closePopups();
this.setLoading(true);
cyber.callContractMethod(databaseContract, 'unpause')
.then(data => console.log(`Unpause DB. Data: ${data}`))
.then(() => cyber.eventPromise(databaseContract.Unpause()))
.then(results => console.log(`Db unpaused. Results: ${results}`))
.then(() => this.init(databaseSymbol))
.catch((error) => {
console.log(`Cant unpause db. Error: ${error}`);
this.setLoading(false);
});
};
deleteDb = () => {
const { databaseId } = this.state;
let chaingerContract;
this.closePopups();
this.setLoading(true);
cyber.getChaingearContract()
.then((contract) => {
chaingerContract = contract;
})
.then(() => cyber.callContractMethod(chaingerContract, 'deleteDatabase', databaseId))
.then(data => console.log(`DeleteDB: ${databaseId}. Tx: ${data}`))
.then(() => cyber.eventPromise(chaingerContract.DatabaseDeleted()))
.then(() => hashHistory.push('/'))
.catch((error) => {
console.log(`Cant delete database. Details: ${error}`);
this.closePopups();
});
};
onTransferOwnership = () => {
this.setState({
transferOwnershipOpen: true,
});
};
onFundDb = () => {
this.setState({
fundDatabaseOpen: true,
});
};
onClaimFunds = () => {
this.setState({
claimFundOpen: true,
});
};
onClaimFee = () => {
this.setState({
claimFeeOpen: true,
});
};
onDeleteDb = () => {
this.setState({
deleteDatabaseOpen: true,
});
};
onPauseDb = () => {
this.setState({
pauseDatabaseOpen: true,
});
};
onResumeDb = () => {
this.setState({
resumeDatabaseOpen: true,
});
};
/*
* Record Actions
*/
addRecord = () => {
const { databaseContract, name, databaseSymbol } = this.state;
if (!databaseContract) {
return;
}
cyber.callContractMethod(databaseContract, 'getEntryCreationFee')
.then(fee => fee.toNumber())
.then(fee => cyber.callContractMethod(databaseContract, 'createEntry', { value: fee }))
.then((entryId) => {
console.log(`New Entry created: ${entryId}`);
this.setState({
loading: true,
});
return cyber.eventPromise(databaseContract.EntryCreated());
})
.then(() => this.init(databaseSymbol))
.catch(() => {
console.log(`Cannot add entry to ${name}`);
});
};
transferRecordOwnership = (currentOwner, newOwner, entryID) => {
const { databaseSymbol, databaseContract } = this.state;
this.closePopups();
this.setLoading(true);
cyber.callContractMethod(
databaseContract, 'transferFrom', currentOwner, newOwner, entryID,
)
.then(data => console.log(`Transfer entry #${entryID} ownership. Tx: ${data}`))
.then(() => cyber.eventPromise(databaseContract.Transfer()))
.then(() => this.init(databaseSymbol));
};
claimRecord = (entryID, amount) => {
const { databaseSymbol, databaseContract, web3 } = this.state;
this.closePopups();
this.setLoading(true);
cyber.callContractMethod(
databaseContract, 'claimEntryFunds', entryID, web3.toWei(amount, 'ether'),
)
.then(data => console.log(`Claim entry #${entryID} funds(${amount} ETH). Tx: ${data}`))
.then(() => cyber.eventPromise(databaseContract.EntryFundsClaimed()))
.then(() => this.init(databaseSymbol));
};
fundRecord = (id, value) => {
this.setState({ loading: true });
this.closePopups();
const { databaseContract, web3 } = this.state;
cyber.callContractMethod(databaseContract, 'fundEntry', id, {
value: web3.toWei(value, 'ether'),
})
.then((data) => {
console.log(`Entry ${id} funded. ETH: ${value}. Data: ${data}`);
})
.then(() => cyber.eventPromise(databaseContract.EntryFunded()))
.then(results => console.log(`Entry ${id} funded. Results: ${results}`))
.then(() => this.getDatabaseItems())
.then((items) => {
this.setState({
items,
loading: false,
});
})
.catch(() => this.setLoading(false));
};
updateRecord = (values, entryId) => {
const { entryCoreContract } = this.state;
this.setLoading(true);
cyber.callContractMethod(entryCoreContract, 'updateEntry', entryId, ...values)
.then(data => console.log(`Update record. Data: ${data}`))
.then(() => cyber.eventPromise(entryCoreContract.EntryUpdated()))
.then(() => this.getDatabaseItems())
.then(items => this.setState({
items,
loading: false,
}))
.catch(() => this.setLoading(false));
};
deleteRecord = (id) => {
const { databaseContract } = this.state;
this.closePopups();
this.setLoading(true);
cyber.callContractMethod(databaseContract, 'deleteEntry', id)
.then(() => cyber.eventPromise(databaseContract.EntryDeleted()))
.then(() => this.getDatabaseItems())
.then(items => this.setState({
items,
loading: false,
}))
.catch(() => this.setLoading(false));
};
onRecordTransferOwnership = (record) => {
this.setState({
transferRecordOwnershipOpen: true,
recordForAction: record,
});
};
onFundRecord = (record) => {
this.setState({
fundRecordOpen: true,
recordForAction: record,
});
};
onClaimRecordFunds = (record) => {
this.setState({
claimRecordFundOpen: true,
recordForAction: record,
});
};
onDeleteRecord = (record) => {
this.setState({
deleteRecordOpen: true,
recordForAction: record,
});
};
onRecordEdit = (record) => {
this.setState({
editRecordOpen: true,
recordForAction: record,
});
};
/*
* Page Actions
*/
setLoading = (value) => {
this.setState({
loading: value,
});
};
closePopups = () => {
this.setState({
claimFundOpen: false,
claimFeeOpen: false,
transferOwnershipOpen: false,
fundDatabaseOpen: false,
pauseDatabaseOpen: false,
resumeDatabaseOpen: false,
deleteDatabaseOpen: false,
claimRecordFundOpen: false,
transferRecordOwnershipOpen: false,
fundRecordOpen: false,
deleteRecordOpen: false,
editRecordOpen: false,
});
};
}
export default new ViewRegistry();