From 19561c2335327f85cee38428665b0962961005d2 Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 5 Sep 2020 13:17:33 +0300 Subject: [PATCH] Check if contracts are deployed on current network before adding them --- src/contractStateUtils.js | 1 + src/contracts/constants.js | 1 + src/contracts/contractsReducer.js | 11 +++++++++++ src/contracts/contractsSaga.js | 20 +++++++++++++++++--- src/drizzleStatus/drizzleStatusSaga.js | 10 ++++++++-- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/contractStateUtils.js b/src/contractStateUtils.js index 8457648..6ed534a 100644 --- a/src/contractStateUtils.js +++ b/src/contractStateUtils.js @@ -22,6 +22,7 @@ export const generateContractInitialState = contractConfig => { return { initialized: false, synced: false, + deployed: true, ...objectOfConstants } } diff --git a/src/contracts/constants.js b/src/contracts/constants.js index c98ab27..54d4f54 100644 --- a/src/contracts/constants.js +++ b/src/contracts/constants.js @@ -4,6 +4,7 @@ export const EVENT_ERROR = 'EVENT_ERROR' export const LISTEN_FOR_EVENT = 'LISTEN_FOR_EVENT' export const CONTRACT_INITIALIZING = 'CONTRACT_INITIALIZING' export const CONTRACT_INITIALIZED = 'CONTRACT_INITIALIZED' +export const CONTRACT_NOT_DEPLOYED = 'CONTRACT_NOT_DEPLOYED' export const GOT_CONTRACT_VAR = 'GOT_CONTRACT_VAR' export const DELETE_CONTRACT = 'DELETE_CONTRACT' export const CONTRACT_SYNCING = 'CONTRACT_SYNCING' diff --git a/src/contracts/contractsReducer.js b/src/contracts/contractsReducer.js index 8af3006..540ded4 100644 --- a/src/contracts/contractsReducer.js +++ b/src/contracts/contractsReducer.js @@ -29,6 +29,17 @@ const contractsReducer = (state = initialState, action) => { } } + // Contract not found on the current network + if (action.type === ContractActions.CONTRACT_NOT_DEPLOYED) { + return { + ...state, + [action.name]: { + ...state[action.name], + deployed: false + } + } + } + if (action.type === ContractActions.DELETE_CONTRACT) { const { [action.contractName]: omitted, ...rest } = state return rest diff --git a/src/contracts/contractsSaga.js b/src/contracts/contractsSaga.js index 1ba4395..0c7e507 100644 --- a/src/contracts/contractsSaga.js +++ b/src/contracts/contractsSaga.js @@ -2,6 +2,8 @@ import { END, eventChannel } from 'redux-saga' import { call, put, select, take, takeEvery } from 'redux-saga/effects' import * as ContractActions from './constants' import * as TransactionsActions from '../transactions/transactionsActions' +import { ACCOUNTS_FAILED, ACCOUNTS_FETCHED, ACCOUNTS_FETCHING } from '../accounts/accountsActions' +import { getNetworkId } from '../web3/web3Saga' /* * Events @@ -199,7 +201,7 @@ function * callCallContractFn ({ } catch (error) { console.error(error) - var errorArgs = { + const errorArgs = { name: contract.contractName, variable: contract.abi[fnIndex].name, argsHash: argsHash, @@ -230,8 +232,8 @@ function * callSyncContract (action) { delete contractFnsState.events // Iterate over functions and hashes - for (var fnName in contractFnsState) { - for (var argsHash in contractFnsState[fnName]) { + for (let fnName in contractFnsState) { + for (let argsHash in contractFnsState[fnName]) { const fnIndex = contractFnsState[fnName][argsHash].fnIndex const args = contractFnsState[fnName][argsHash].args @@ -271,6 +273,18 @@ function isSendOrCallOptions (options) { return false } +export function * isContractDeployed ({ web3, contractConfig }) { + const networkId = yield call(getNetworkId, { web3 }) + if(contractConfig.networks[networkId]){ + const contractAddress = contractConfig.networks[networkId].address; + + const fetchedByteCode = yield call(web3.eth.getCode, contractAddress); + if(fetchedByteCode === contractConfig.deployedBytecode) + return true; + } + return false; +} + function * contractsSaga () { yield takeEvery(ContractActions.SEND_CONTRACT_TX, callSendContractTx) yield takeEvery(ContractActions.CALL_CONTRACT_FN, callCallContractFn) diff --git a/src/drizzleStatus/drizzleStatusSaga.js b/src/drizzleStatus/drizzleStatusSaga.js index 1e37b09..f0526f6 100644 --- a/src/drizzleStatus/drizzleStatusSaga.js +++ b/src/drizzleStatus/drizzleStatusSaga.js @@ -8,6 +8,8 @@ import * as DrizzleActions from './drizzleActions' import * as BlocksActions from '../blocks/blockActions' import { NETWORK_IDS, NETWORK_MISMATCH } from '../web3/web3Actions' +import { CONTRACT_NOT_DEPLOYED } from '../contracts/constants' +import { isContractDeployed } from '../contracts/contractsSaga' export function * initializeDrizzle (action) { try { @@ -38,12 +40,16 @@ export function * initializeDrizzle (action) { for (let i = 0; i < options.contracts.length; i++) { const contractConfig = options.contracts[i] let events = [] - const contractName = contractConfig.contractName - + const contractName = contractConfig.contractName; if (contractName in options.events) { events = options.events[contractName] } + if(!(yield call(isContractDeployed, { web3, contractConfig }))){ + yield put({ type: CONTRACT_NOT_DEPLOYED, name: contractName }) + throw `Contract ${contractName} not deployed on this network` + } + yield call([drizzle, drizzle.addContract], contractConfig, events) }