Я экспериментирую с подключением Ethereum к веб-приложению React, используя в качестве основы это хорошее учебное репозиторий (спасибо uzyn): https://github.com/uzyn/ethereum-webpack-example-dapp
Я успешно подключаюсь к локальному экземпляру TestRPC 3.0.3, у меня развернут контракт Solidity 0.4.8 «MyToken», и я успешно использую функцию контракта, называемую «передача». Я знаю, что перевод выполняется только один раз из обновленных балансов учетной записи, но я получаю два экземпляра события «Перевод» в консоли браузера. Если я уберу строку, генерирующую событие, я ничего не получу в консоли.
Кто-нибудь может подсказать, почему так? Спасибо!
Я вызываю эту контрактную функцию, которая генерирует событие:
/* Send coins */
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
С этим блоком кода:
MyTokenContract.transfer.sendTransaction(
web3.eth.accounts[1],
100,
(error, result) => {
if (error) {
console.log(`Error occurred: ${error}`);
return;
}
const accountOneBalance = MyTokenContract.balanceOf(web3.eth.accounts[0]);
const accountTwoBalance = MyTokenContract.balanceOf(web3.eth.accounts[1]);
console.log(`accountOneBalance: ${accountOneBalance}`);
console.log(`accountTwoBalance: ${accountTwoBalance}`);
}
);
И у меня есть этот код Web3, прослушивающий события контракта:
MyTokenContract.allEvents((error, event) => {
if (error) {
console.log(`Event error: ${error}`);
return;
}
const eventName = event.event;
const accountFrom = event.args.from;
const accountTo = event.args.to;
const amount = event.args.value;
console.log(`Event '${eventName}' from account ${accountFrom} to ${accountTo} of ${amount}`);
});
Когда он запускается, я получаю два события, зарегистрированные в моей консоли Chrome:
accountOneBalance: 249900
accountTwoBalance: 100
Event 'Transfer' from account 0xdd0efd8df206cb598bda146ae567f5d398436226 to 0x7497ac386ae2e1eb58210d08e6c401b56417e04d of 100
Event 'Transfer' from account 0xdd0efd8df206cb598bda146ae567f5d398436226 to 0x7497ac386ae2e1eb58210d08e6c401b56417e04d of 100
У меня была та же проблема, и приведенное выше решение не сработало в случае, если testrpc запущен и уже запустил некоторые события, а затем при запуске кода Web3 часы возвращают последнее инициированное событие. Что решило проблему и получило только новые события:
var latestBlock = web3.eth.blockNumber; //get the latest blocknumber
contractInstance.MyEvent({fromBlock: latestBlock}, (error, event) => {
if (error) {
console.log(error); return;
} else {
if(event.blockNumber != latestBlock) { //accept only new events
console.log(event);
latestBlock = latestBlock + 1; //update the latest blockNumber
}
}
Надеюсь, это поможет!
это сработало для меня
MyTokenContract.allEvents({fromBlock:'latest'}, (ошибка, событие) => { if (ошибка) { console.log( Event error: ${error}
); return; }
Несмотря на то, что в документах указано, что «последний» используется по умолчанию, это исправило мои повторяющиеся события. Я не использовал allEvents. Я смотрел только одно мероприятие по контракту.
Надеюсь, поможет.
У меня все еще было это в марте 2019 года, я решил это, создав Set
в своем javascript и добавив к нему blockNumbers в своем обратном вызове, чтобы гарантировать отсутствие дубликатов.
var eventBlocks = new Set()
listenCallback = async (error, event, type) => {
if (error) { console.log(error); }
else {
let blockNumber = event.blockNumber;
if (eventBlocks.has(blockNumber)) return;
eventBlocks.add(blockNumber);
//do everything else you want to do
}
}
5777243
и5777244
Я сделал именно то, что было сделано выше. Я ловил свое исходное событие следующим образом:
this.buyEvent = this.$store.state.web3contract.BuyTransaction({},{fromBlock: 0, toBlock: 'latest'});
this.buyEvent.watch(function(err,res){
console.log(res);
console.log(err);
})
Чтобы исправить двойное срабатывание, я добавил этот дополнительный фрагмент кода, и он решил мою проблему.
this.$store.state.web3contract.allEvents({fromBlock:'latest'}, function (error,event){
if (error) {
console.log(error)
} else {
console.log("All Events")
console.log(event);
}
})
Это должно быть какая-то ошибка в web3, или я не знаю, что это такое. Я уверен, что не зарегистрирую функцию часов дважды. Было бы здорово, если бы кто-нибудь мог подтвердить, является ли это ошибкой web3.
Наконец-то я понял это, братья по блокчейну.
Я создавал бота, чтобы наблюдать за покупками/продажами на Uniswap, и продолжал получать повторяющиеся события Transfer для одного и того же Tx Hash. Не уверен, что это связано с web3 или с моим локальным узлом Eth, но это сводило меня с ума. Я пытался ограничиться блоками (например, если был найден следующий блок, игнорировать), но я получал несколько событий с одним и тем же хэшем в одном блоке, так что это не сработало.
Наконец, я нашел способ сравнить последний Tx Hash с текущим и, если они совпадают, игнорировать остальную часть процесса; если не продолжить обработку транзакции:
async function savetxhash(lasthash) { //async function to save last tx
return new Promise((resolve) => {
resolve(lasthash)
});
}
var lasthash = "" //declare empty at first
//Here you will have your web3.eth.Transfer() or .allEvents() listener code
//Then below that you will compare saved hash to new one
console.log('This hash is '+event.transactionHash+'')
console.log('Last hash was '+lasthash+'')
if (lasthash.toLowerCase() == event.transactionHash.toLowerCase()) {
console.log('Found duplicate tx hash, skipping...')
} else {
console.log('No duplicate tx hash found, doing something important...')
}
lasthash = await savetxhash(event.transactionHash) //lastly call the function
Я столкнулся с той же проблемой здесь, используя web3 ^1.3.6
.
Судя по этой проблеме в репозитории web3.js , это похоже на проблему с самой библиотекой.
Мое решение заключалось в том, чтобы хранить хэш транзакции каждого события и сравнивать его перед выполнением какой-либо логики.
Мэтью Шмидт
transfer
месте, где он создает событие (таким образом, создавая два события), сколько событий он теперь регистрирует? Три? Четыре? У меня есть подозрение, что это может помочь вам отладить.Джон Джи
0ТТТ0