API web3 не возвращает экземпляр контракта при использовании с eth-lightwallet и hookedweb3provider

Мне удалось получить подключенного провайдера web3 с помощью eth-lightwallet, создающего контракт на частном узле geth. Я вижу транзакцию в журналах geth и вижу, как она добавляется в блок при майнинге.

Однако я не получаю контракт. адрес возвращается в обратном вызове. Я получаю хэш транзакции. Моя интуиция подсказывает мне, что внизу происходят два шага: хэш tx предоставляется в ответе JSON RPC внизу, но соответствующий eth_getTransactionReceipt не выполняется или не обрабатывается перед возвратом к обратному вызову.

Помощь приветствуется.

var ethClient = "http://localhost:1234";
var web3 = new Web3();
var global_keystore;

// setting up a web3 provider but using a keystore to get access to account information
function setWeb3Provider(keystore) {

    var web3Provider = new HookedWeb3Provider({
        host: ethClient,
        transaction_signer: keystore
    });

    web3.setProvider(web3Provider);

}

// .....

var password = prompt('Enter Password to encrypt your seed', 'Password');

var providedSeed = document.getElementById('seed').value;

lightwallet.keystore.deriveKeyFromPassword(password, function (err, pwDerivedKey) {

global_keystore = new lightwallet.keystore(
    providedSeed,
    pwDerivedKey);

global_keystore.generateNewAddress(pwDerivedKey, 2);

setWeb3Provider(global_keystore);


// .... important bit....

var contract = web3.eth.contract(_contractABI);
    var myContract = contract.new(
        {
            from: _ethWalletAddress,
            data: _contractCode,
            gas: 3000000,
            gasPrice: 18000000010
        }, function(e, contract){

            console.log("error object: " + e );
            console.log("contract object: " + contract);

            if (typeof contract != 'undefined') {
                console.log('address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);


                });

            }
        });

Пример логов из частной сети geth:

I0424 13:28:13.816421 eth/api.go:1177] Tx(3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f) created: 0746c6c2fde77b607e83e2bb6c25f919817e8459
I0424 13:28:23.028763 miner/miner.go:119] Starting mining operation (CPU=8 TOT=9)
I0424 13:28:23.036100 miner/worker.go:565] commit new work on block 4446 with 1 txs & 1 uncles. Took 7.286103ms

и результат ручного getTransactionReceipt с JSON RPC:

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f"],"id":1}'

{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x3a524c681be27a65d6058e54de35e5502d8353e85b7a5b013c86a6909eb63dd3","blockNumber":"0x115e","contractAddress":"0x0746c6c2fde77b607e83e2bb6c25f919817e8459","cumulativeGasUsed":"0x101716","from":"0xa57f54760210a39a376231bd20d5fcec4eaf75fa","gasUsed":"0x101716","logs":[],"root":"38789ca516316c1303eda94b690202875a77d66e3116f8733081197f7157f093","to":null,"transactionHash":"0x3645d30afa7923cca42359dc2d1e46084f0da11f0b5476111a1e2ac7a82eb56f","transactionIndex":"0x0"}}

пс. Я не знаю, что отчет журнала 1 дядя. Другие журналы создания контрактов не сообщали ни о каких дядях, но во всех была обнаружена одна и та же проблема с обратным вызовом.

Я чувствую, что вы можете быть немного скупы с gasPrice. Вы уверены, что видите транзакцию, включенную в блок? Если вы сделаете getTransactionReceipt вручную, что вы увидите? Также обратите внимание, что web3 немедленно запускает обратный вызов до того, как транзакция будет добыта, а затем снова после того, как она была добыта.
Зарегистрирован частный узел: I0424 09:47:32.895350 miner/worker.go:565] зафиксируйте новую работу в блоке 4443 с 0 транзакциями и 0 дядями. Took 256.964974ms I0424 10:40:50.493671 eth/api.go:1177] Tx(59ac899e2e88f05ae2476a8988ad08531342fd3fc11012169b005ac1df57c3a0) created: 42b2c3b2fac0e4fc06aff755ecef9ee25d4ef740 I0424 10:41:33.602429 miner/miner.go:119] Starting mining operation (CPU=8 TOT=9) I0424 10:41:33.610067 miner/worker.go:565] зафиксируйте новую работу в блоке 4443 с 1 транзакцией и 0 дядями. I0424 10:41:35.881139 miner/worker.go:347] 🔨 Добытый блок (#4443 / d88f4f58). Подождите 5 блоков для подтверждения
@Christian_Lundkvist - я еще не использовал getTransactionReceipt вручную. Все еще выясняю, как и что это значит.
хорошо, добавил результат getTransactionReceipt к вопросу. Все кажется в порядке.
Окей круто. Вы видите адрес договора в квитанции? Сделайте web3.eth.getCode('0x0746...') и посмотрите, возвращает ли он какой-то код или ноль. Если он возвращает ноль, это означает, что создание контракта не удалось. Однако я думаю, что это также может быть проблемой с вашими обратными вызовами. Я лично использую Pudding ( github.com/ConsenSys/ether-pudding ), который запускает обратный вызов после того, как транзакция завершена. Web3 срабатывает дважды, я думаю.
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x0746c6c2fde77b607e83e2bb6c25f919817e8459", "latest"],"id":1}\' вернул код контракта. Так что, должно быть, обратный вызов работает в web3.
@ChristianLundkvist спасибо. Пудинг просто еще больше абстрагируется и еще менее мне понятен. Я попробовал базовый «венчик», и это не удалось.

Ответы (1)

Идиома кода действительно работает. Должно быть, это было замешательство с моей стороны, когда я учился, потому что внезапно это начало работать.

Новая функция контракта в API web3 делает два вызова обратного вызова в приведенном выше коде. Вот фрагмент кода из web3.js.

if (callback) {

            // wait for the contract address adn check if the code was deployed
            this.eth.sendTransaction(options, function (err, hash) {
                if (err) {
                    callback(err);
                } else {
                    // add the transaction hash
                    contract.transactionHash = hash;

                    // call callback for the first time
                    callback(null, contract);

                    checkForContractAddress(contract, callback);
                }
            });
        } else {
            var hash = this.eth.sendTransaction(options);
            // add the transaction hash
            contract.transactionHash = hash;
            checkForContractAddress(contract);
        }

        return contract;

Этот код выполняет обратный вызов, как только он получает хэш транзакции из первого базового вызова JSON RPC. CheckForContractAddress снова вызовет обратный вызов, как только второй базовый вызов JSON RPC подтвердит, что транзакция была добыта: контракт развернут.

Я мог бы заметить проблему, если бы знал о двух вызовах обратного вызова и регистрировал для каждого что-то свое.

Пример документации web3 ПРОВЕРЯЕТ, что адрес контракта определен перед ведением журнала. Это предотвратило бы путаницу. Я изменил его на тестовый «контракт». Моя вина.

если (тип контракта.адрес != 'undefined') {}