Что я сделал
а) Когда я использую web3.eth.estimateGas
для оценки стоимости конструктора создания контракта без параметров, оценка верна.
б) Если контракт уже развернут, то оценка стоимости газа функции контракта с параметрами работает нормально. ( contract.myMethod.estimateGas()
используя web3 api)
Проблема
а) Когда я оцениваю газ в контракте на время создания контракта ( contractObject.new
) с параметризованным конструктором, он дает неверную оценку стоимости газа. ( web3.eth.estimateGas
из web3 API)
Чего я хочу
а) Когда я оцениваю газ с помощью конструктора контракта с несколькими параметрами, он должен оценивать правильный газ. ( contractObject.new
для вызова конструктора)
b) Browser-soldity дает правильную оценку газа контракта с параметризованным конструктором -> перед созданием/развертыванием контракта (например, стоимость транзакции или стоимость выполнения, как я могу использовать их алгоритм с API web3 для правильной оценки газа?)
Попробуйте использовать .getData()
.
.getData()
возвращает закодированные параметры функции для отправки транзакции вручную. Затем вы можете вставить это web3.eth.estimateGas()
(тот, который находится в web3.eth
, а не в данном методе), чтобы имитировать отправку транзакции.
Вот непроверенный пример, но, надеюсь, он поможет вам на вашем пути:
var contractData = contractObject.new.getData(someparam, another, {data: contractBytecode});
var estimate = web3.eth.estimateGas({data: contractData})
Пример использования .getData() (это четвертый вариант).
solc --bin
я отредактирую свой ответ.getData()
? Изменить: нашел этот вопрос , в котором говорится, что encodeABI()
вместо getData()
.При работе с web3.js версии 1.2.x метод .getData отсутствует. Решение, которое я нашел, состояло в том, чтобы оценить газ метода .deploy(), который эффективно возвращает стоимость создания контракта.
Последовательность операций такова:
let contractJSON = // JSON compiled contract
const contractABI = contractJSON.abi;
const bytecode = contractJSON.bytecode;
const contract = new web3.eth.Contract(contractABI);
let options = {
arguments: [ arg1, arg2,... ],
data: bytecode
}
const estimatedGas = await contract.deploy(options).estimateGas();
С web3js это довольно просто. Сначала вам нужно создать свой контракт. После создания у вас будет contractABI и адрес контракта, например:
let contractABI = [ { "constant": true, "inputs": [ { "name": "", "type": "bytes32" }, { "name": "", "type": "uint256" } ], "name": "verify", "outputs": [ { "name": "", "type": "address", "value": "0x" } ], "payable": false, "type": "function" }, { "constant": false, "inputs": [ { "name": "document", "type": "bytes32" } ], "name": "sign", "outputs": [], "payable": false, "type": "function" } ]
let contractAddress = '0xaEC9eCDAFAf2404F824B4b7087e9E4F90C77D082'
Имея эту информацию, просто создайте контрактный прокси-сервер contractInstance и оцените tx по методу подписи :
const web3conn = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
const contract = web3conn.eth.contract(contractABI)
const contractInstance = contract.at(contractAddress)
let estimatedGas = contractInstance.sign.estimateGas('arg of my function', { from: '0xAddress' })
Прокси — это специальный объект (используйте console.log, чтобы увидеть все методы), облегчающий использование контракта. Если у вас есть метод подписи , вы можете создать Tx для подписи:
let txHash = contractInstance.sign(param, { from: config.ethereum.identity, gas: estimatedGas })
если вы используете wan't для вызова функции (без транзакции):
contractInstance.sign.call(param)
Web3 позволяет это:
const MyContract = artifacts.require('MyContract');
...
const gas = await MyContract.new.estimateGas(arg1, arg2, arg3);
let contract = new web3.eth.Contract(contractABI);
const bytecodeWithEncodedParameters = contract
.deploy({
data: contractByteCode,
arguments: [?, ?, ?],
})
.encodeABI();
const estimateGas = await web3.eth.estimateGas({
data: bytecodeWithEncodedParameters,
});
Попробуйте так для развертывания нового контракта. Меня устраивает.
Мэтью Шмидт
.estimateGas()
? С.getData()
?Имроз