У меня есть этот контракт:
pragma solidity ^0.4.23;
contract Test {
event Event(address indexed wallet);
mapping (address => bool) public authorizedWallets;
uint256 public authorizedWalletCount;
function add(address _wallet) external {
_add(_wallet);
emit Event(_wallet);
}
function _add(address _wallet) private {
require(!authorizedWallets[_wallet]);
authorizedWallets[_wallet] = true;
authorizedWalletCount++;
}
}
И я проверяю стоимость газа function add
via web3 v1.0.0-beta.34
на NodeJS:
async function send(transaction) {
let success = await web3.eth.personal.unlockAccount(OWNER_ADDRESS, OWNER_PASSWORD);
let gas = await transaction.estimateGas({from: OWNER_ADDRESS, gasPrice: GAS_PRICE});
console.log(`gas = ${gas}`);
return await transaction.send({from: OWNER_ADDRESS, gasPrice: GAS_PRICE, gas: gas});
}
for (let i = 1; i < 10; i++) {
let wallet = `0x5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5${i}`;
let hash = await send(contract.methods.add(wallet));
}
Обратите внимание, что после того, как я напечатаю стоимость газа, я выполняю транзакцию, чтобы она вступила в силу для контракта, а затем и для стоимости газа следующей транзакции.
На первой итерации стоимость газа составляет 64827.
На каждой из следующих итераций стоимость газа составляет 49827.
Я полагаю, что эта разница сама по себе имеет смысл, поскольку первая транзакция, вероятно, меняет гораздо больше нулей на 1, чем каждая из следующих транзакций (я полагаю, в mapping (address => bool) public authorizedWallets
структуре данных).
Что для меня не имеет особого смысла, так это то, почему каждая из этих транзакций такая дорогостоящая, поскольку выполняется всего несколько операций:
_add(_wallet);
require(!authorizedWallets[_wallet]);
authorizedWallets[_wallet] = true;
authorizedWalletCount++;
emit WalletAccepted(_wallet);
Я использую Parity и Ropsten для всего, что имеет значение (я считаю, что это не должно иметь значения, но, возможно, здесь я ошибаюсь).
Может кто-нибудь объяснить, почему стоимость этих нескольких операций достигает 50 000 единиц газа?
Спасибо!
authorizedWallets[_wallet] = true;
делает SSTORE изменение нуля на ненулевое, так что это 20 000 газа.authorizedWalletCount++;
меняет ли SSTORE ненулевое значение на ненулевое, так что это 5000 газа.emit Event(_wallet);
делает LOG2, который стоит 1125 газа.Это 47 125, что довольно близко к вашему общему количеству. Добавьте SLOAD, немного хеширования и немного накладных расходов на перемещение вещей и вызов функций, и я думаю, что 49 827 вполне разумно.
хорошая вибрация
пользователь19510