Допустим, это мой смарт-контракт:
event NewUser(
address userAddress,
uint amount
);
function addUser() public payable{
require(msg.value <= maxValue && msg.value > 0);
require(allowedValues[msg.value]);
require(accountAmount() < 5);
if (users[msg.sender] > 0) {
userPullout(); //Remove senders data
}
userAddresses.push(msg.sender);
partAmounts.push(msg.value);// This value doesn't get pushed before the event is finished
users[msg.sender] = msg.value;
emit NewUser(msg.sender, msg.value);//This is called to soon
}
Это мой файл nodeJS:
app.contract.events.NewUser({}, function(error, event){})
.on('data', function(event){
io.emit('new user', event.returnValues);
}).on('change', function(event){
io.emit('new user', event.returnValues);
})
.on('error', console.error);
Если я зарегистрирую partAmount
массив в web3 с помощью .call
функции, старые значения до события все равно будут возвращены. Это говорит мне о том, что событие запущено слишком рано.
Есть ли способ вызвать событие после установки данных?
РЕДАКТИРОВАТЬ: еще немного кода.
const socket = openSocket('http://localhost:3000'); // subscribed to the socket server firing the events from node back-end
socket.on('new user', (event) => {
console.log(event) // returns for example 7 which is CORRECT
this.props.contract.methods.getCertainArray().call(this.props.contractObject, (err, res) => {
console.log(res); // old data from before the event so if the previous array was [0, 6 , 6], this would still be returned NOTICE: no 7 in the array yet.
});
})
ПРИМЕЧАНИЕ. Если я установлю тайм-аут для функции вызова следующим образом:
setTimeout(() => {
this.props.contract.methods.getCertainArray().call(this.props.contractObject, (err, res) => {
console.log(res); // old data from before the event so if the previous array was [0, 6 , 6], this would still be returned NOTICE: no 7 in the array yet.
});
}, 5000);
Он возвращает правильный массив, но это не так, как я хочу, чтобы скрипт работал.
Проблема в том, что вы не ждете, пока транзакция будет добыта, прежде чем .call
проверять результат.
Это идет:
call
использовать функцию, чтобы увидеть эффект.Или следите за событием, как выглядит ваш пример JS. События не поступают до тех пор, пока транзакция не будет включена в блок.
Надеюсь, поможет.
Как отметил Роб, вы, скорее всего, не ждете, пока транзакция будет полностью проанализирована, прежде чем извлекать данные. Я не уверен насчет web3js, но Golang предоставляет возможность считывать данные об ожидающем состоянии до того, как транзакция будет добыта. Лично я предпочитаю golang для написания внутреннего кода, взаимодействующего со смарт-контрактами, и буду использовать web3 только в случае необходимости (т.е. интерфейсный код).
Предупреждение, однако, я бы рекомендовал не читать ожидающие данные состояния, поскольку они могут измениться в зависимости от того, какие транзакции вставлены в мемпул.
Настоятельно рекомендуется дождаться обработки транзакции, прежде чем обрабатывать какие-либо данные, и я бы лично рекомендовал использовать golang вместо web3 для взаимодействия со смарт-контрактами и использовать web3 только в том случае, если мне нужно написать код внешнего интерфейса.
У меня есть функция, которая вызывается всякий раз, когда конкретная транзакция отправляется из блокчейна, и автоматически завершает обработку и завершает работу после получения события.
Теперь, когда я подключен к тестовой сети Ropsten, она работает, как и ожидалось (если сервер WebSocket работает).
Я не знаю точно, в чем проблема, но я знаю, что проблема заключается в Ganache, который запускал события до того, как следующий блок был фактически завершен, и все переменные были обновлены.
Исправление: либо работайте со своего локального сервера Geth, либо загружайте свой контракт в одну из тестовых сетей.
Джаспер
Роб Хитченс
call
до того, как транзакция будет добыта. Первый обратный вызов дает хэш транзакции. Это не подтверждение "заминировано". Это просто подтверждение запроса. Это часто ошибочно принимают за подтверждение майнинга. Посмотрите здесь: gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6Джаспер
Роб Хитченс
Роб Хитченс
Джаспер
Джаспер