When I compile and call the check_If_Address_Already_Signed()
and check_Database_Verified_Address()
function in Remix both of them return true . Now when in my Js file where I want to do some computation only if this two smart contract functions return true, when I create an instance of the smart contract and call the two functions, the check_Database_Verified_Address()
returns false instead of true. I do not understand why ?
I will provide my smart contract code, my compile.js, as well as my Js file to do some computation (Signataire.js)
Solidity Smart Contract :
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "./DataBase_Add_Verifies.sol";
// import "./Identification_C_EA.sol";
// Deno was installed successfully to /Users/pierre/.deno/bin/deno
// Manually add the directory to your $HOME/.zshrc (or similar)
// export DENO_INSTALL="/Users/pierre/.deno"
// export PATH="$DENO_INSTALL/bin:$PATH"
// Run '/Users/pierre/.deno/bin/deno --help' to get starte
contract Signataire is DataBaseAddresses {
mapping(address => bool) already_Signed_Addresses;
// Event pour dire que le signataire peut signer le Jeton
// Function pour check avec Database addresse verifie
function check_Database_Verified_Address() public view returns (bool) {
for (uint256 i = 0; i < verified_Addresses.length; i++) {
if (verified_Addresses[i] == msg.sender) {
return true;
}
}
return false;
}
//Function pour check si Addresse a deja signe un jeton
function check_If_Address_Already_Signed() public view returns (bool) {
if (already_Signed_Addresses[msg.sender] == false) {
return true;
}
}
//Function qui ajout msg.sender a l'aray
function Ajout_Add_Array() internal {
if (
check_Database_Verified_Address() &&
check_If_Address_Already_Signed() == true
) {
already_Signed_Addresses[msg.sender] = true;
}
}
}
Here is my compilation file :
const path = require("path");
const fs = require("fs-extra");
const solc = require("solc");
const Web3 = require("web3");
// Loading the contract ABI and Bytecode
// (the results of a previous compilation step)
const ethers = require("ethers");
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const sourceFolderPath = path.resolve(
__dirname,
"/Users/pierre/Authentification_TM/Smart-Contracts"
);
const buildFolderPath = path.resolve(__dirname, "build");
const getContractSource = (contractFileName) => {
const contractPath = path.resolve(
__dirname,
"Signataire.sol",
contractFileName
);
return fs.readFileSync(contractPath, "utf8");
};
let sources = {};
var walk = function (dir) {
var results = [];
var list = fs.readdirSync(dir);
list.forEach(function (file) {
file = dir + "/" + file;
var stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
results = results.concat(walk(file));
} else {
if (file.substr(file.length - 4, file.length) === ".sol") {
sources = {
...sources,
[file]: {
content: getContractSource(file),
},
};
}
results.push(file);
}
});
return results;
};
walk(sourceFolderPath);
const input = {
language: "Solidity",
sources,
settings: {
outputSelection: {
"*": {
"*": ["*"],
},
},
},
};
console.log("\nCompiling contracts...");
const output = JSON.parse(solc.compile(JSON.stringify(input)));
console.log("Done");
let shouldBuild = true;
if (output.errors) {
console.error(output.errors);
// throw '\nError in compilation please check the contract\n';
for (error of output.errors) {
if (error.severity === "error") {
shouldBuild = false;
throw "Error found";
break;
}
}
}
if (shouldBuild) {
console.log("\nBuilding please wait...");
fs.removeSync(buildFolderPath);
fs.ensureDirSync(buildFolderPath);
for (let contractFile in output.contracts) {
for (let key in output.contracts[contractFile]) {
fs.outputJsonSync(
path.resolve(buildFolderPath, `${key}.json`),
{
abi: output.contracts[contractFile][key]["abi"],
bytecode:
output.contracts[contractFile][key]["evm"]["bytecode"]["object"],
},
{
spaces: 2,
EOL: "\n",
}
);
}
}
console.log("Build finished successfully!\n");
} else {
console.log("\nBuild failed\n");
}
And here is my Signataire.js file :
/*
Le signataire ne doit signer le message transmis que si les deux
already_Signed_Addresses() et check_If_Address_Already_Signed()
sont vrais.
Import le smart contract, call les deux fonctions, si elles sont just => ecrire code pour signer avec
la private key d une addresse (Signgataire), si c est faux alors revert
Ecrire une transaction du signataire au Citoyen (msg.sender), Avec comme data son Jeton signé
*/
const crypto = require("crypto");
const ethers = require("ethers");
const web3 = require("web3");
require("dotenv").config();
const { abi, bytecode } = require("./build/Signataire.json");
function getRandomJeton(Choix_Vote, N_V) {
// Avoir deux nombre completement aleatoire
let randomAnonymeNumber1 = crypto.getRandomValues(new Uint32Array(1))[0];
let randomAnonymeNumber2 = crypto.getRandomValues(new Uint32Array(1))[0];
// Avoir un nombre unique a chaque citoyen
let uniqueNumber = "12345678910";
// Mettre ensemble le nombre aleatoire et unique pour cree un nombre 100% aleatoire et unique
let uniqueRandomValue = `${uniqueNumber}${randomAnonymeNumber2}${randomAnonymeNumber1}`;
// Mettre ensemble les donne necessaire pour avoir le jeton
let unhashedJeton = `${Choix_Vote}${uniqueRandomValue}${N_V}`;
const Jeton = crypto.createHash("sha256").update(unhashedJeton).digest("hex");
return Jeton;
}
const Jeton = getRandomJeton(1, 2);
console.log(Jeton);
//Function pour aveugle le jeton
const provider = new ethers.providers.WebSocketProvider(
`wss://polygon-mumbai.g.alchemy.com/v2/${process.env.ALCHEMY_PRIVATE_KEY}`
);
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const ABI = abi;
// console.log(ABI);
const contractAddress = "0xF0168BC0DBb989bf3163f2353DdA4D3A09b073fa";
// Replace with your contract's ABI
const contract = new ethers.Contract(contractAddress, ABI, provider);
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
// console.log(wallet);
async function sign_jeton() {
try {
console.log(await contract.get_Array());
const databaseVerified = await contract.check_Database_Verified_Address();
const addressAlreadySigned =
await contract.check_If_Address_Already_Signed();
console.log(databaseVerified);
console.log(addressAlreadySigned);
if (addressAlreadySigned && databaseVerified == true) {
// If both conditions are met, sign the Jeton
const signature_Jeton = web3.eth.accounts.sign(Jeton, PRIVATE_KEY);
console.log("Signature:", signature_Jeton);
process.exit();
} else {
console.log("Conditions not met. Cannot sign Jeton.");
process.exit();
}
} catch (error) {
console.error("Error:", error);
process.exit();
}
}
sign_jeton();
// process.exit();
I have seen that when I try to console.log(verfied_Adresses)
from the contract in my JS file I get 0x000...
so the js file can not read the array from the Smart contract and so it cannot return true on the check_Database_Verified_Address()
because 0x000...
doesnt match msg.sender
. It is not a problwm with the import of this array because i tried to declared it in the same smart contract, and it still didnt work, I also tried to declare it in a contructor functions, didnt work. I tried to declare a different array like uint8 myArray[] = [1,2,3] and I replaced the verified_Adresses with the myArray conserving the exact same logic, and it did work. So I do not understand where the problem comes from, is it the address array that cannot be accesed outside of the contract ? Also I saw another person asking the same kind of question with a function aboutthe timstamp of the block, but it didnt help, here is the link of the question : Solidity function returning true in remix but false in web3 function call
Any help would higlhy be appriciated ,
Thank you very much for taking your time 🙂
After reading documentations I have found the issue. For anyone having the same problem, you need to replace msg.sender in the solidity code by a variable . that means instead of having msg.sender we declare address user = msg.sender , normally it will work. Thank you
If you have found the solution, then it would be better to answer to your own question 🙂