Reputation: 23
So, I am building an Iot device integrated with blockchain on a raspberry pi. I have created a smart contract and deployed it on sepolia testnet. And now for testing, I am writing a nodejs to send a function on the smart contract by passing parameters, and then call a function from the smart contract to display the sent values.
Smart contract -
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/access/Ownable.sol";
// Represents any device connected to the Raspberry Pi that you want to control
struct Appliance {
uint256 id;
string name;
bool status;
bytes1 pin;
}
contract HomeAutomationDemo is Ownable {
uint256 nextId = 1;
uint256 count = 0;
mapping(uint256 => Appliance) public appliances;
// Add a new appliance to the list
function addAppliance(string memory name, bytes1 pin) public onlyOwner {
appliances[nextId] = Appliance(nextId, name, false, pin);
nextId++;
count++;
}
// Remove an appliance from the list
function removeAppliance(uint256 id) public onlyOwner {
delete appliances[id];
count--;
}
// This is the function that will be called when the user
// toggles the status of the appliance on the mobile app
function toggleAppliance(uint256 id, bool status) public onlyOwner {
appliances[id].status = !appliances[id].status;
}
// Update the details of an appliance
function updateAppliance(uint256 id, string memory name, bytes1 pin) public onlyOwner {
appliances[id].name = name;
appliances[id].pin = pin;
}
// Get the details of an appliance
function getAppliance(uint256 id) public view returns (Appliance memory) {
return appliances[id];
}
// Get the list of appliances
function getAppliances() public view returns (Appliance[] memory) {
Appliance[] memory result = new Appliance[](count);
for (uint256 i = 0; i < nextId; i++) {
if (appliances[i].id != 0) {
result[i] = appliances[i];
}
}
return result;
}
// Get the total number of appliances
function getAppliancesCount() public view returns (uint256) {
return count;
}
}
Nodejs -
const web3 = require('web3');
const fs = require("fs");
const CONTRACT_ABI = `[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bytes1",
"name": "pin",
"type": "bytes1"
}
],
"name": "addAppliance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "appliances",
"outputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bool",
"name": "status",
"type": "bool"
},
{
"internalType": "bytes1",
"name": "pin",
"type": "bytes1"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "getAppliance",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bool",
"name": "status",
"type": "bool"
},
{
"internalType": "bytes1",
"name": "pin",
"type": "bytes1"
}
],
"internalType": "struct Appliance",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAppliances",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bool",
"name": "status",
"type": "bool"
},
{
"internalType": "bytes1",
"name": "pin",
"type": "bytes1"
}
],
"internalType": "struct Appliance[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAppliancesCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "removeAppliance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "bool",
"name": "status",
"type": "bool"
}
],
"name": "toggleAppliance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "bytes1",
"name": "pin",
"type": "bytes1"
}
],
"name": "updateAppliance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]`;
const CONTRACT_ADDRESS = "0x13d9FA79D364070510B410c2FaC1976F21E3e218";
const web3js = new web3(new web3.providers.HttpProvider("https://sepolia.infura.io/v3/9e644c118b7c44068674e2d12a776536"));
var myAddress = '0x46Be881Fa6935a8FC969A4ddDFC74d625c558996';
var privateKey = Buffer.from('PRIVATE-KEY', 'hex')
var contractABI =JSON.parse(CONTRACT_ABI);
var contractAddress = CONTRACT_ADDRESS;
contract = new web3js.eth.Contract(contractABI,contractAddress);
// first populate an appliance
let setAppliance = contract.methods.addAppliance("fan", 1).send;
console.log(setAppliance);
let applianceOnOff = contract.methods.getAppliances;
console.log(applianceOnOff);
And this is what I get when running the nodejs -
[Function: bound _executeMethod] {
request: [Function: bound _executeMethod]
}
[Function: bound _createTxObject]
Upvotes: 1
Views: 999
Reputation: 537
This code:
contract.methods.addAppliance("fan", 1).send;
returns a Promise in which you have to wait for its completion by using the await
keyword:
await contract.methods.addAppliance("fan", web3.utils.numberToHex(1)).send({from: myAddress});
/*
* web3.utils.numberToHex(1) converts decimal digit '1' to bytes '0x1'
* because the addAppliance function takes a 'byte1' as second parameter
*/
For this line: contract.methods.getAppliances;
, you are making a call to get a value from your contract which doesn't modify state so you have to append .call()
to get that value, .send()
is used when making calls tha triggers smart contract state changes.
You can then use the await
keyword to wait for its completion or use a callback:
await contract.methods.getAppliances().call();
Upvotes: 1