mirror of https://gitlab.com/ecentrics/drizzle
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
4.2 KiB
159 lines
4.2 KiB
import * as ContractActions from './contracts/constants'
|
|
import * as TransactionsActions from './transactions/constants'
|
|
import { isGetterFunction, isSetterFunction } from './contractStateUtils'
|
|
class DrizzleContract {
|
|
constructor (
|
|
web3Contract,
|
|
web3,
|
|
name,
|
|
store,
|
|
events = [],
|
|
contractArtifact = {}
|
|
) {
|
|
this.abi = web3Contract.options.jsonInterface
|
|
this.address = web3Contract.options.address
|
|
this.web3 = web3
|
|
this.contractName = name
|
|
this.contractArtifact = contractArtifact
|
|
this.store = store
|
|
|
|
// Merge web3 contract instance into DrizzleContract instance.
|
|
Object.assign(this, web3Contract)
|
|
|
|
for (var i = 0; i < this.abi.length; i++) {
|
|
var item = this.abi[i]
|
|
if (isGetterFunction(item)) {
|
|
this.methods[item.name].cacheCall = this.cacheCallFunction(item.name, i)
|
|
}
|
|
if (isSetterFunction(item)) {
|
|
this.methods[item.name].cacheSend = this.cacheSendFunction(item.name, i)
|
|
}
|
|
}
|
|
|
|
// Register event listeners if any events.
|
|
if (events.length > 0) {
|
|
for (i = 0; i < events.length; i++) {
|
|
const event = events[i]
|
|
|
|
if (typeof event === 'object') {
|
|
store.dispatch({
|
|
type: ContractActions.LISTEN_FOR_EVENT,
|
|
contract: this,
|
|
eventName: event.eventName,
|
|
eventOptions: event.eventOptions
|
|
})
|
|
} else {
|
|
store.dispatch({
|
|
type: ContractActions.LISTEN_FOR_EVENT,
|
|
contract: this,
|
|
eventName: event
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cacheCallFunction (fnName, fnIndex, fn) {
|
|
var contract = this
|
|
|
|
return function () {
|
|
// Collect args and hash to use as key, 0x0 if no args
|
|
var argsHash = '0x0'
|
|
var args = arguments
|
|
|
|
if (args.length > 0) {
|
|
argsHash = contract.generateArgsHash(args)
|
|
}
|
|
const contractName = contract.contractName
|
|
const functionState = contract.store.getState().contracts[contractName][
|
|
fnName
|
|
]
|
|
|
|
// If call result is in state and fresh, return value instead of calling
|
|
if (argsHash in functionState) {
|
|
if (contract.store.getState().contracts[contractName].synced === true) {
|
|
return argsHash
|
|
}
|
|
}
|
|
|
|
// Otherwise, call function and update store
|
|
contract.store.dispatch({
|
|
type: ContractActions.CALL_CONTRACT_FN,
|
|
contract,
|
|
fnName,
|
|
fnIndex,
|
|
args,
|
|
argsHash
|
|
})
|
|
|
|
// Return nothing because state is currently empty.
|
|
return argsHash
|
|
}
|
|
}
|
|
|
|
cacheSendFunction (fnName, fnIndex, fn) {
|
|
// NOTE: May not need fn index
|
|
var contract = this
|
|
|
|
return function () {
|
|
var args = arguments
|
|
|
|
// Generate temporary ID
|
|
const transactionStack = contract.store.getState().transactionStack
|
|
const stackId = transactionStack.length
|
|
const stackTempKey = `TEMP_${new Date().getTime()}`
|
|
|
|
// Add ID to "transactionStack" with temp value, will be overwritten on TX_BROADCASTED
|
|
contract.store.dispatch({ type: TransactionsActions.PUSH_TO_TXSTACK, stackTempKey })
|
|
|
|
// Dispatch tx to saga
|
|
// When txhash received, will be value of stack ID
|
|
contract.store.dispatch({
|
|
type: ContractActions.SEND_CONTRACT_TX,
|
|
contract,
|
|
fnName,
|
|
fnIndex,
|
|
args,
|
|
stackId,
|
|
stackTempKey
|
|
})
|
|
|
|
// return stack ID
|
|
return stackId
|
|
}
|
|
}
|
|
|
|
generateArgsHash (args) {
|
|
var web3 = this.web3
|
|
var hashString = ''
|
|
|
|
for (var i = 0; i < args.length; i++) {
|
|
if (typeof args[i] !== 'function') {
|
|
var argToHash = args[i]
|
|
|
|
// Stringify objects to allow hashing
|
|
if (typeof argToHash === 'object') {
|
|
argToHash = JSON.stringify(argToHash)
|
|
}
|
|
|
|
// Convert number to strong to allow hashing
|
|
if (typeof argToHash === 'number') {
|
|
argToHash = argToHash.toString()
|
|
}
|
|
|
|
// This check is in place for web3 v0.x
|
|
if ('utils' in web3) {
|
|
var hashPiece = web3.utils.sha3(argToHash)
|
|
} else {
|
|
var hashPiece = web3.sha3(argToHash)
|
|
}
|
|
|
|
hashString += hashPiece
|
|
}
|
|
}
|
|
|
|
return web3.utils.sha3(hashString)
|
|
}
|
|
}
|
|
|
|
export default DrizzleContract
|
|
|