Promise.all завершился с ошибкой Ошибка: недопустимое количество аргументов функции Solidity (метамаска)

В настоящее время я работаю над проектом, который использует Javascript, Async / Await и Web3 (для Ethereum). Я хочу создать интерфейсную страницу, которая способна обнаруживать адрес метамаски пользователя, а затем использовать его в функции. У меня уже есть что-то подобное для работы на предыдущей странице, но у меня возникли проблемы с переводом на другую страницу. Я подозреваю, что getCurrentAccount () ничего не возвращает, таким образом нарушая количество и тип переменных, которые Promise.all ожидает отправить. Соответствующий код:

function isInList(input) {
    return new Promise(function(resolve, reject) {
        myElection.areYouInList(input, function(error, response) {
            if (error) {
                reject(error);
            } else {
                resolve(response);
            }
        })
    });
}

function hasntVotedYet(input) {
    return new Promise(function(resolve, reject) {
        myElection.haveYouVotedAlready(input, function(error, response) {
            if (error) {
                reject(error);
            } else {
                resolve(response);
            }
        })
    });
}

function isNotOver() {
    return new Promise(function(resolve, reject) {
        myElection.isItOver(function(error, response) {
            if (error) {
                reject(error)
            } else {
                resolve(response);
            }

        })
    });
}

async function getCurrentAccount() {
    console.info("getCurrentAccount method");
    web3.eth.getAccounts((err, accounts) => {
        currentAccount = accounts[0]
    })
    return currentAccount; //KEEP IN MIND THAT YOU NEED TO ACTUALLY BE LOGGED INTO METAMASK FOR THIS TO WORK - OTHERWISE IT'LL RETURN UNDEFINED BECAUSE THERE AREN'T ANY ACCOUNTS
}


async function verify() {
    console.info("Verify");
    try {
        -- -- > THIS LINE //
        var myCurrentAccount = await getCurrentAccount();
        console.info("myCurrentAccount is: " + myCurrentAccount);
        data = await Promise.all([isInList(myCurrentAccount), hasntVotedYet(myCurrentAccount), isNotOver()]); //data then equals an array, containing both the strings returned from these two methods
        console.info("success");
        console.info(data)

        if (data[0] && !data[1] && !data[2]) { //check firstly that we are allowed to vote, secondly that we have not already voted, and finally that this vote is not over yet
            var x = document.getElementById("hidden");
            x.style.display = "block";
        } else if (!data[0]) {
            alert("That address was not found in the Whitelist.");
        } else if (data[1]) {
            alert("You have already voted and may not vote a second time");
        } else if (data[2]) {
            alert("This election has already concluded. Votes can no longer validly be cast for it.");
        }
    } catch (error) {
        console.info("Promise.all finished with error " + error)
    }
}

Почему getCurrentAccount - это async function, если он ничего не await? Также похоже, что web3.eth.getAccounts действительно вызывает свой обратный вызов асинхронно, поэтому вам нужно будет обещать его с помощью new Promise, как вы делали с тремя другими функциями раньше.

Bergi 31.07.2018 16:15

Не забудьте объявить свои переменные типа currentAccount или data с помощью var (или let или const). Кстати, подумайте об использовании деструктуризации для data, чтобы вы могли дать значимые имена трем значениям, которые вы ожидали.

Bergi 31.07.2018 16:17
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
350
1

Ответы 1

Проблема связана с тем, как вы получаете учетную запись метамаски: web3.eth.getAccounts - это асинхронная функция. Что-то вроде этого должно работать:

async function getCurrentAccount() {
    console.info("getCurrentAccount method");
    let accounts = await web3.eth.getAccounts();
    return accounts[0];
}

Асинхронность не означает, что она возвращает обещание и может быть обработана await. В исходном коде требуется обратный вызов ?!

Bergi 31.07.2018 18:42

да, но возврат запускается перед обратным вызовом, поэтому исходная функция getCurrentAccount возвращает undefined

Tclairet 01.08.2018 10:23

И ваша тоже, если web3.eth.getAccounts ничего не возвращает (потому что ожидает обратного вызова)?

Bergi 01.08.2018 10:43

Другие вопросы по теме