I have a contract which maintains a map of valid wallets.
In this map, the keys are wallet addresses and the values are wallet parameters:
struct WalletParams {
bool valid;
uint x;
uint y;
uint z;
}
mapping(address => WalletParams) public map;
In order to keep track of valid wallets, I can do either one of the following every time I add a wallet:
- Emit an event with the wallet address
- Add the wallet address to an auxiliary array
Initially, I thought I should do both, in order to achieve the following goals:
- Events can be used in order to perform specific queries and filter out specific wallets
- The array can be used in order to be able to fetch all the wallets at any given moment
With regards to #2, I'm starting to think that perhaps events are sufficient for this purpose. In "traditional systems", an array would be the simplest way of course. But on the block-chain, I've figured, maybe the array is "scattered" across different blocks just like the events would be, so there shouldn't be any advantage in maintaining this array.
Is that correct?
If yes, then I should obviously get rid of the array, because of the natural downsides:
- Additional gas cost
- Additional code-complexity (which increases the chances for bugs)
Then I realized yet another advantage in an array:
I can easily retrieve the data via any standard wallet application, like MyEtherWallet
, which would not be feasible via events.
So in short, is it a custom method to keep an auxiliary array of keys next to a map, or should I get rid of it and rely solely on events?
Here is my contract:
pragma solidity 0.4.24;
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract MyContract is Ownable {
address[] public array;
struct WalletParams {
bool valid;
uint x;
uint y;
uint z;
}
mapping(address => WalletParams) public map;
event WalletUpdated(address indexed wallet);
event WalletInserted(address indexed wallet);
function insert_or_update(address wallet, uint x, uint y, uint z) external onlyOwner {
WalletParams storage walletParams = map[wallet];
if (walletParams.valid) {
walletParams.x = x;
walletParams.y = y;
walletParams.z = z;
emit WalletUpdated(wallet);
}
else {
walletParams.valid = true;
walletParams.x = x;
walletParams.y = y;
walletParams.z = z;
array.push(wallet);
emit WalletInserted(wallet);
}
}
function getArray() external view returns (address[]) {
return array;
}
function getCount() external view returns (uint) {
return array.length;
}
}
Thank you!