Trying to learn smart contracts. I successfully deployed a contract. Before deploying it I used the functions successfully in Remix:
Contract Instance:
But in my Vue app, I get an error:
Uncaught TypeError: this.$store.state.contractInstance(...).deposit is not a function
The app successfully detects Metamask. And Via the console I see the contract instance and the ABI. But, deposit
not available as a function, only appears in the ABI arrary.
This seems to the closest to my issue, but when I tried the solution it did not work for me: https://stackoverflow.com/questions/48184969/calling-smart-contracts-methods-using-web3-ethereum.
My code ... using web3 version ^0.20.5
Component:
<template>
<div class="container">
<div class="row">
<div class="col">
<h1>Home</h1>
<form @submit.prevent="deposit">
<label>Deposit
<input
v-model="amount"
type="number"
min=".01">
</label>
<button type="submit">Submit</button>
</form>
</div>
</div>
</div>
</template>
<script>
import {store} from '../store';
export default {
name: 'home',
data: function () {
return {
amount: null
}
},
methods: {
deposit(event) {
this.$store.state.contractInstance().deposit(event.target.innerHTML, {
gas: 300000,
value: this.$store.state.web3.web3Instance().toWei(this.amount, 'ether'),
from: this.$store.state.web3.coinbase
}, (error, result) => {
if (error) {
console.log(error)
}
})
}
},
mounted () {
console.log('dispatching getContractInstance')
this.$store.dispatch('getContractInstance')
}
}
</script>
Store:
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state';
import getWeb3 from '../util/getWeb3';
import pollWeb3 from '../util/pollWeb3';
import getContract from '../util/getContract';
Vue.use(Vuex);
export const store = new Vuex.Store({
strict: true,
state,
getters: {
},
mutations: {
registerWeb3Instance(state, payload) {
console.log('registerWeb3instance Mutation being executed', payload);
let result = payload;
let web3Copy = state.web3;
web3Copy.coinbase = result.coinbase;
web3Copy.networkId = result.networkId;
web3Copy.balance = parseInt(result.balance, 10);
web3Copy.isInjected = result.injectedWeb3;
web3Copy.web3Instance = result.web3;
state.web3 = web3Copy;
pollWeb3();
},
pollWeb3Instance(state, payload) {
console.log('pollWeb3Instance mutation being executed', payload);
state.web3.coinbase = payload.coinbase;
state.web3.balance = parseInt(payload.balance, 10);
},
registerContractInstance(state, payload) {
console.log('Escrow contract instance: ', payload);
state.contractInstance = () => payload;
}
},
actions: {
registerWeb3({ commit }) {
console.log('registerWeb3 Action being executed');
getWeb3
.then(result => {
console.log('committing result to registerWeb3Instance mutation');
commit('registerWeb3Instance', result);
})
.catch(e => {
console.log('error in action registerWeb3', e);
});
},
pollWeb3({ commit }, payload) {
console.log('pollWeb3 action being executed');
commit('pollWeb3Instance', payload);
},
getContractInstance({ commit }) {
getContract
.then(result => {
commit('registerContractInstance', result);
})
.catch(e => console.log(e));
}
}
});
escrow.sol
pragma solidity ^0.4.11;
contract Escrow {
uint balance;
address public manager;
address public worker;
address private escrow;
uint private start;
bool managerOk;
bool workerOk;
function Escrow(address manager_address, address worker_address) public {
manager = manager_address;
worker = worker_address;
escrow = msg.sender;
start = now;
}
function accept() public {
if (msg.sender == manager){
managerOk = true;
} else if (msg.sender == worker){
workerOk = true;
}
if (managerOk && workerOk){
payBalance();
} else if (managerOk && !workerOk && now > start + 30 days) {
selfdestruct(manager);
}
}
function payBalance() private {
escrow.transfer(this.balance / 100);
if (worker.send(this.balance)) {
balance = 0;
} else {
throw;
}
}
function deposit() public payable {
if (msg.sender == manager) {
balance += msg.value;
}
}
function cancel() public {
if (msg.sender == manager){
managerOk = false;
} else if (msg.sender == worker){
workerOk = false;
}
if (!managerOk && !workerOk){
selfdestruct(manager);
}
}
function kill() public constant {
if (msg.sender == escrow) {
selfdestruct(manager);
}
}
}
escrowContract.js:
const address = '0xd61F9331CE61Eb27E0AB7d9b9bc75402Ea5db7f8';
const ABI = [
[
{
constant: false,
inputs: [],
name: 'accept',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function'
},
{
constant: false,
inputs: [],
name: 'cancel',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function'
},
{
constant: false,
inputs: [],
name: 'deposit',
outputs: [],
payable: true,
stateMutability: 'payable',
type: 'function'
},
{
inputs: [
{
name: 'manager_address',
type: 'address'
},
{
name: 'worker_address',
type: 'address'
}
],
payable: false,
stateMutability: 'nonpayable',
type: 'constructor'
},
{
constant: true,
inputs: [],
name: 'kill',
outputs: [],
payable: false,
stateMutability: 'view',
type: 'function'
},
{
constant: true,
inputs: [],
name: 'manager',
outputs: [
{
name: '',
type: 'address'
}
],
payable: false,
stateMutability: 'view',
type: 'function'
},
{
constant: true,
inputs: [],
name: 'worker',
outputs: [
{
name: '',
type: 'address'
}
],
payable: false,
stateMutability: 'view',
type: 'function'
}
]
];
export { address, ABI };
getContract.js
import Web3 from 'web3';
import { address, ABI } from './constants/escrowContract';
let getContract = new Promise(function(resolve, reject) {
let web3 = new Web3(window.web3.currentProvider);
let escrowContract = web3.eth.contract(ABI);
let escrowContractInstance = escrowContract.at(address);
resolve(escrowContractInstance);
});
export default getContract;
deposit
takes no inputs, yet you are trying to pass a parameterinstance.methods.deposit
. (And yes, as @RaghavSood points out, it doesn't accept a parameter.)^0.20.5
deposit
doesn't take any parameters in your screenshot either.