Прослушивание транзакций эфириума по определенному адресу

Можно ли прослушивать транзакции на определенном адресе ethereum? Например, если кто-то отправит определенное количество ETH на этот адрес, сработает функция обратного вызова.

Я прочитал это: Как изучить все транзакции для данной учетной записи? но это похоже на прошлые транзакции, а не на прослушивание вживую.

Ответы (4)

Для этого вы можете использовать Web3.js 1.0 и WebSockets .

var subscription = web3.eth.subscribe('logs', {
address: '0x123456..',
}, function(error, result){
if (!error)
console.log(result);
})
.on("data", function(log){
console.log(log);
})
.on("changed", function(log){
});

Если вы используете приведенный выше код, просто обновите addressсвойство.

Рабочий образец здесь: https://jsfiddle.net/h7nskoyu/11/

Это смотрит на контракт CryptoKitties, и глядя на консоль, вы видите это:введите описание изображения здесь

Расширенная транзакция соответствует этому: https://etherscan.io/tx/0x3ccce0b8072649ca087a91f00bdbb475b36d03a9a8dd2cc54b9a03ac5826c255 .

Узнайте больше о web3.eth.subscribe здесь .

Спасибо, Шон! Это то, что я ожидал ранее, но не смог заставить его работать. Я создал проблему GitHub по этому поводу здесь: github.com/ethereum/web3.js/issues/1752 . Не уверен, что проблема в web3 или в моем коде.
В своем коде для подключения к провайдеру Ethereum вы убедитесь, что подключение осуществляется через WebSocket? Например, вы не можете использовать Metamask в этой ситуации, так как Metamask в настоящее время не поддерживает веб-сокеты.
Пытаюсь, но получаю эту ошибку сейчас. Используется --ws при запуске майнера и жестко запрограммирован адрес веб-сокета в web3.connection not open on send() Error when watching incoming transactions: connection not open connection not open on send() Error when watching incoming transactions: connection not open connection not open on send() Error when watching incoming transactions: connection not open connection not open on send() Error when watching incoming transactions: connection not open
Я бы сказал, попробуйте использовать var web3 = new Web3('wss://mainnet.infura.io/ws');, чтобы просто проверить, работает ли ваш код. И если это так, то откройте другой поток для устранения проблем с доступом к вашему Geth WebSocket.
@ShawnTabrizi Это работает, только если addressэто контракт и он генерирует события. Это не будет работать для EOA или если контракт не генерирует события.
Это не прослушивает транзакции, а журналы событий.
Можем ли мы прослушать конкретный адрес аккаунта? Это работает только с контрактом.

Это называется концепция непрерывного мониторинга. Вы также можете сделать это с помощью RPC Call. Использование Etherscan API (существует множество платформ, предоставляющих ETH API)

Шаг 1: Получите последнюю высоту блока, используя https://api.etherscan.io/api?module=proxy&action=eth_blockNumber&apikey=YourApiKeyToken .

Шаг 2: Получите всю информацию об этом блоке, используя https://api.etherscan.io/api?module=proxy&action=eth_getBlockByNumber&tag=0x5A0F60&boolean=true&apikey=YourApiKeyToken (вы получите все транзакции в рамках этого блока)

Шаг 3: Теперь сохраните все данные этой транзакции из json в свой список и запустите цикл for для вашего адреса, который вы хотите непрерывно отслеживать.

Итак, теперь, если ваш адрес будет в списке транзакций этого блока, вы можете использовать детали в соответствии с вашими требованиями, иначе вы можете проверить следующий сгенерированный блок через 10-15 секунд (согласно вашему требованию).

Спасибо за ваш ответ! Сейчас это не сработает, так как я хочу провести тестирование в частной сети. Но буду иметь в виду на будущее.

Принятый ответ будет работать только для txn к контракту.

Для обнаружения передачи эфира (txn в EOA) вам необходимо настроить прослушиватель для получения последних блоков и запроса массива транзакций блока, чтобы найти соответствие для конкретного требования.

Это будет отслеживать блокчейн для входящей транзакции для адреса.

const monitorTransaction = async (addressss)=>{
    
        const block = await web3.eth.getBlock('latest');
    
        console.log(`Checking new block ${block.number}`)
    
        for(let txHash of block.transactions){
            // console.log(txHash);
            const tx = await web3.eth.getTransaction(txHash)
            // console.log(JSON.stringify(tx));
            const tranx = typeof tx === 'string' ? tx.to.toLowerCase() : '';
    
                if(addressss === tranx){
                    console.log(`New transaction found - Block ${block.number}`);
                    console.log(`Transaction From: ${tx.from}`);
                    console.log(`Transaction To: ${tx.to}`);
                    console.log(JSON.stringify(tx));
                }
        }
    }
Код не делает того, что подразумевается в ответе. Он запрашивает только последний блок, он не отслеживает изменения. У него есть другие проблемы, такие как использование переменной strбез ее определения, не учитываются внутренние транзакции.
Спасибо за то, что str был обновлен до tx. Вы можете использовать SetInterval в javascript для постоянного запроса блока каждые xxx секунд (от 12 до 15 секунд в качестве времени блока по умолчанию). Иногда вам нужно использовать свои технические навыки для решения проблем. Вам не нужно зависеть от полного решения от людей.
По крайней мере самая важная логика написана. Вы можете написать код для запуска функции monitorTransaction для отслеживания входящих транзакций.