неправильная структура хранилищаили вычислительно интенсивные операции могут привести к высокимGasУзкие места в стоимости и производительности。
Предположим, вы создаете систему голосования, в которой каждое предложение имеет независимый счетчик голосов. Чтобы добиться этого, вы можете сначала рассмотреть возможность использования карты, где ключами являются идентификаторы предложений, а значениями — массив, хранящий адреса всех избирателей, проголосовавших за это предложение.
// неправильная структура хранилища
contract VotingSystem {
mapping(uint => address[]) public voters;
function vote(uint proposalId, address voter) public {
voters[proposalId].push(voter);
}
function getVotesCount(uint proposalId) public view returns (uint) {
return voters[proposalId].length;
}
}
Предложения по оптимизации Чтобы снизить затраты на газ и повысить производительность, мы можем перепроектировать структуру данных, чтобы использовать сопоставление для отслеживания того, проголосовал ли каждый избиратель за определенное предложение, вместо сохранения массива избирателей.
// Оптимизированная структура хранилища
contract OptimizedVotingSystem {
mapping(uint => mapping(address => bool)) public hasVoted;
function vote(uint proposalId, address voter) public {
require(!hasVoted[proposalId][voter], "Already voted");
hasVoted[proposalId][voter] = true;
}
function getVotesCount(uint proposalId) public view returns (uint) {
uint count;
for (address voter = address(1); voter != address(0); voter = address(uint(voter) + 1)) {
if (hasVoted[proposalId][voter]) {
count++;
}
}
return count;
}
}
Хотя использование карты может значительно повысить эффективность, перебор всех адресов для подсчета голосов в функции getVotesCount по-прежнему неэффективен. На практике вы можете ввести дополнительные сопоставления или переменные для отслеживания общего количества голосов по каждому предложению, чтобы избежать полного обхода адресного пространства.
// Дальнейшая оптимизация
contract FurtherOptimizedVotingSystem {
mapping(uint => mapping(address => bool)) public hasVoted;
mapping(uint => uint) public votesCount;
function vote(uint proposalId, address voter) public {
require(!hasVoted[proposalId][voter], "Already voted");
hasVoted[proposalId][voter] = true;
votesCount[proposalId]++;
}
function getVotesCount(uint proposalId) public view returns (uint) {
return votesCount[proposalId];
}
}
Таким образом, счетчик голосов необходимо обновлять только каждый раз, когда подается голос, что значительно снижает затраты на газ и повышает скорость запросов. При разработке смарт-контрактов разумное проектирование и оптимизация структур хранения имеют решающее значение для снижения затрат и повышения производительности.