Web3.eth.accounts[0] никогда не обновляется

Я пытаюсь использовать Web3 для доступа к текущей учетной записи, которую я выбрал в Metamask, выполнив web3.eth.accounts[0], чтобы отобразить ее в моем пользовательском интерфейсе (в VueJS). Однако web3.eth.accounts[0] всегда возвращает одну и ту же учетную запись, первую из 10, предоставленных мне Ganache TestRPC.

Даже если я переключусь на 8-ю учетную запись (скриншот ниже) и обновлю приложение, console.log(web3.eth.accounts[0])все равно выводит первую учетную запись в массиве.

введите описание изображения здесь

Вот мой код (в Vuejs контракт уже создан):

    var ethereumUri = 'http://127.0.0.1:7545';   
        let web3 = new Web3(new Web3.providers.HttpProvider(ethereumUri));
        if (!web3.isConnected()) {
            return 'Unable to connect to ethereum node at ' + ethereumUri
        }else{
          var escrowContract = web3.eth.contract(abi); //abi initalized at start
          var instance = escrowContract.at(this.contractAddress); //contractAddress is initialized at the start

          console.log(web3.eth.accounts);
          console.log(web3.eth.accounts[0]);
        }

Как заставить web3 выводить текущий выбранный адрес учетной записи в Metamask?

Спасибо!

Ответы (2)

Используемый вами http-провайдер подключается только напрямую к ganache, поэтому он обходит провайдера MetaMask web3, поэтому вы всегда видите учетную запись [0] из ganache. Если вы используете web3 = new Web3(web3.currentProvider)его, MetaMask будет выбран в качестве активного поставщика.

Вы также можете проверить, включен ли MetaMask перед определением вашей переменной web3 с помощью:

if(typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
} else {
    web3 = new Web3(new Web3.providers.HttpProvider(ethereumUri);
}

Это работает только при начальной загрузке. Чтобы отслеживать изменения в MetaMask, вы можете использовать функцию мониторинга, которая запускает проверку на основе интервалов, чтобы увидеть, изменился ли web3.eth.accounts[0]. Вам нужно сохранить текущую активную учетную запись в переменной (например, currentAddress), чтобы выполнить эту проверку.

watchAddress: function () {
    var checkAddress = setInterval (function() {
        if (web3.eth.accounts[0] !== currentAddress) {
            // Account has changed
            // set currentAddress = web3.eth.accounts[0];
            // Do something, eg reload
        }
    }, 100);
}
Это немного неверно и применимо только в том случае, если у вас есть два разных поставщика, метамаска и ганаш. OP настроил свое расширение метамаски, чтобы обойти предоставленный узел eth, и вместо этого подключил его к своему экземпляру ganache, так что это то же самое. Помните, метамаска может подключаться к ЛЮБОМу узлу и использовать его в качестве провайдера.
@hextet Неважно, для чего здесь настроен MetaMask, потому что код в вопросе OP не использует MetaMask. (Он использует провайдера HTTP для прямого подключения к ганашу.)
@smarx Спасибо. Когда я изменяю web3 для использования Metamask в качестве провайдера и пытаюсь получить доступ к web3.eth.accounts[0], он возвращает ошибку: неверный ответ JSON RPC: undefined. Моя метамаска подключена к HTTP://127.0.0.1:7545 (работает через Ganache). Код:var ethereumUri = 'http://127.0.0.1:7545'; var web3 = window.web3; if(typeof web3 !== 'undefined') { console.log("1"); console.log(web3.currentProvider); web3 = new Web3(web3.currentProvider); console.log(web3.eth.accounts[0]); } else { console.log("2"); }
Я не смог воспроизвести ошибку из вашего кода. Я получаю рабочий web3, подключающийся к MetaMask. Какую версию web3 вы используете и какой ответ вы получаете от - console.log (web3.currentProvider); - в вашем коде?
Обновление: я исправил это, мне пришлось изменить версию web3js на версию 0.2. Я использовал 1.0.0-beta.34 Спасибо за помощь!

Это 100% как задумано. всегдаweb3.eth.accounts[index_num] будет ссылаться на любую учетную запись, созданную в этом конкретном порядке. Так будет относиться к созданной 9-й учетной записи, в то время как будет создана 8-я учетная запись. Я не уверен, что вы можете использовать web3js для выбора текущей выбранной учетной записи в метамаске, однако вы сможете проверить адрес 8-й учетной записи из массива тому, кто пытается отправить транзакцию, или вызвать вызов функции.web3.eth.accounts[8]we3.eth.accounts[7]eth.accounts

@KevinShen Этот ответ неверен. Ответ @machine-uprising правильный. Ваш текущий код не использует MetaMask. Если бы вы использовали MetaMask, вы бы увидели только одну учетную запись в массиве web3.eth.accounts, и это была бы текущая активная учетная запись в MetaMask.