I'm trying to connect this example to a frontend using web3. I have it copied exactly in my truffle project /contracts
folder.
Compilation and migration are both successful. (I have truffle configured to deploy on my ganache test network, and when I run truffle migrate
, I see that the first account is debited ether).
I've created a Vue app to interact with the contract via web3. Here's what my component looks like:
<template>
<div class="hello">
<button @click="inc">increment</button>
<button @click="dec">decrement</button>
<button @click="get">get</button>
</div>
</template>
<script>
const Web3 = require("web3");
const addr = '0xfbe7892aF06c7ecfbd83a0aD7F1D0a228d90Bf89'
const abi = [
{
"inputs": [],
"name": "count",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
},
{
"inputs": [],
"name": "get",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
},
{
"inputs": [],
"name": "inc",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "dec",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
export default {
name: 'HelloWorld',
data () {
return {
web3: null,
contract: null,
}
},
methods: {
get(){
self.contract.methods.get().call(function(err, result){
console.log(result)
})
},
inc(){
self.contract.methods.inc().call(function(err, result){
console.log(result)
})
},
dec(){
self.contract.methods.dec().call(function(err, result){
console.log(result)
})
},
},
created () {
self.web3 = new Web3('http://localhost:7545')
self.contract = new self.web3.eth.Contract(abi, addr)
}
}
</script>
When I run inc
, no err is thrown. I expect to see that value increment when I run get
, but it always outputs 0
- apparently inc
doesn't update the state. Am I missing something?
There's a difference between a call (read-only, gas-free) and a transaction (read-write, costs gas fees).
Since you want the inc()
function to update the state, you need to send() a transaction instead of a call.
Your local web3 instance (usually in production) or the remote node (usually in development, e.g. using Ganache) needs to hold the private key to the senderAddress
to be able to send the transaction.
self.contract.methods.inc().send({from: senderAddress}, function(err, result){
console.log(result)
})