Web3-Transaktion zu einem Vertrag schlägt mit Zurücksetzen fehl. Die gleiche Transaktion funktioniert von der Truffle-Konsole aus

Ich habe eine einfache Vertragstransaktion, die einen weiteren Vertrag erstellt. Diese Transaktion wird, wenn sie von Node.js aufgerufen wird, mit Web3und truffle-contractausgelöst.

ContractFactory.deployed().then(function(instance) {
    return instance.createStore({from: accounts[0]}); 
});

Ergebnis:

2018-05-14T07:34:58.260Z develop:testrpc   Transaction: 0xc93859052bea36bd76c80ab21d30c90a3002303ec7eb1e3ea6d08cd002990d74
2018-05-14T07:34:58.261Z develop:testrpc   Gas usage: 89462
2018-05-14T07:34:58.261Z develop:testrpc   Block Number: 39
2018-05-14T07:34:58.261Z develop:testrpc   Block Time: Mon May 14 2018 13:04:58 GMT+0530 (India Standard Time)
2018-05-14T07:34:58.261Z develop:testrpc   Runtime Error: revert

Wenn ich die gleiche Transaktion abrufe truffle consoleoder truffle developdie Transaktion erfolgreich ist.

truffle (develop) > ContractFactory.deployed().then(function (instance) { return instance.createStore() });

Ergebnis:

2018-05-14T07:30:33.789Z develop:testrpc   Transaction: 0xbdc51bb74de2b59e98ad1b8f38ed4367c2d975a77340d778e44ee2ced969e5b9
2018-05-14T07:30:33.789Z develop:testrpc   Gas usage: 135843
2018-05-14T07:30:33.789Z develop:testrpc   Block Number: 38
2018-05-14T07:30:33.789Z develop:testrpc   Block Time: Mon May 14 2018 13:00:33 GMT+0530 (India Standard Time)
2018-05-14T07:30:33.789Z develop:testrpc
2018-05-14T07:30:33.791Z develop:testrpc eth_getTransactionReceipt

Ich habe versucht, truffle debugzur Arbeit zu kommen, aber es kann keine Transaktionen debuggen, die einen anderen Vertrag erstellen.

Meine anfängliche Vermutung war, dass meine Web3-Transaktion das festgelegte Gaslimit aufgebraucht hat, aber würde das einen Rückfall auslösen? Ich habe versucht, das Gaslimit auf einen sehr hohen Wert einzustellen, aber ohne bessere Ergebnisse.

ContractFactory.defaults({
  gasLimit: "100000000000000000"
});

Vertragscode:

pragma solidity ^0.4.16;

contract SimpleStore {
    uint public value;
    function SimpleStore (uint num) public {
        value = num;
    }

    function setValue (uint num) public {
        value = num;
    }
}

contract ContractFactory {

    address public store;

    function ContractFactory () public {

    }

    function createStore () public {
        store = new SimpleStore(12);
    }
}

Hinweis: Andere Transaktionen und Anrufe funktionieren sehr gut mit dem Web3-Setup. Dieses Problem tritt bei allen Transaktionen auf, die einen Vertrag erstellen.

Haben Sie es in einem anderen Netzwerk versucht, das testrpc? versuchen Sie es mit rinkeby und posten Sie dann txhash, damit die Leute es überprüfen können.
kannst du deine NodeJS-Datei posten?
Ich werde diese Transaktion in einem Testnet durchführen und heute einen Hash bereitstellen, ich werde auch den Contract JSON posten.

Antworten (3)

Ich kann das Problem reproduzieren, mit dem Sie konfrontiert waren. Ich habe Folgendes getan, um dieses Problem zu lösen. Zwei separate Vertragsdateien im Vertragsordner für SimpleStore und ContractFactory wie folgt erstellt: - SimpleStore.sol-Datei -

pragma solidity ^0.4.16;

contract SimpleStore {
    uint public value;
    function SimpleStore (uint num) public {
        value = num;
    }

    function setValue (uint num) public {
        value = num;
    }
}

ContractFactory.sol-Datei -

pragma solidity ^0.4.16;

contract SimpleStore {
    uint public value;
    function SimpleStore (uint num) public {
        value = num;
    }

    function setValue (uint num) public {
        value = num;
    }
}
contract ContractFactory {

    address public store;

    function ContractFactory () public {

    }

    function createStore () public {
        store = new SimpleStore(12);
    }
}

2_deploy_contracts.js-Datei -

var SimpleStore = artifacts.require("./SimpleStore.sol");
var ContractFactory = artifacts.require("./ContractFactory.sol");
module.exports = function(deployer) {
  deployer.deploy(SimpleStore,10, {gas: 6700000});
  deployer.deploy(ContractFactory,{gas: 6700000});
};

app.js-Datei -

import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'
import SimpleStore_artifacts from '../../build/contracts/SimpleStore.json'
import ContractFactory_artifacts from '../../build/contracts/ContractFactory.json'

var SimpleStore = contract(SimpleStore_artifacts);
var ContractFactory = contract(ContractFactory_artifacts);
$( document ).ready(function() {
  if (typeof web3 !== 'undefined') {
    console.warn("Using web3 detected from external source like Metamask")
    // Use Mist/MetaMask's provider
    window.web3 = new Web3(web3.currentProvider);
  } else {
    console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask");
    // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
    window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

  }
  SimpleStore.setProvider(web3.currentProvider);
  ContractFactory.setProvider(web3.currentProvider);
  ContractFactory.deployed().then(function(instance) {
    return instance.createStore({from: web3.eth.accounts[0],gas: 6700000}); 
    console.log("******");
  });
});

Das Hinzufügen von Gaskosten als Argument hat das Problem der VM-Ausnahme gelöst.

instance.createStore({von: web3.eth.accounts[0],gas: 6700000});

Ich kann auch Transaktionen von der Truffle-Konsole aus ausführen -

truffle(development)> ContractFactory.deployed().then(function (instance) { return instance.createStore({from: web3.eth.accounts[0],gas: 6700000});})
{ tx: '0x4d34e45cddbfa6f087f5dcb02bb5e7dc0fa18a0f7d24e87f8fff8702dd3e53bc',
  receipt: 
   { transactionHash: '0x4d34e45cddbfa6f087f5dcb02bb5e7dc0fa18a0f7d24e87f8fff8702dd3e53bc',
     transactionIndex: 0,
     blockHash: '0xf77b2baa3cacc941a8376376425c642c6db580e4a26918a0905ed589a618bfe7',
     blockNumber: 26,
     gasUsed: 123078,
     cumulativeGasUsed: 123078,
     contractAddress: null,

Die Antwort könnte ganz einfach sein: Die gasMenge, die Trüffel standardmäßig bei einem Funktionsaufruf sendet, beträgt 90000. Sie können sehen, wie Ihre Transaktion bei einem Verbrauch in der Nähe dieses Werts abgebrochen wird. Die Transaktion gelingt jedoch mit einem höheren Wert von der Trüffelkonsole, die meiner Meinung nach eine Gasschätzung verwendet. Was Sie angesprochen haben, war das gasLimit, das != gas.

Es ist also eigentlich ganz einfach (Mirgs Lösung hat es bereits, es ist nur nicht wirklich knapp)

ContractFactory.deployed().then(function(instance) {
    return instance.createStore({from: accounts[0], gas:150000}); 
});
Das ist es. Ich habe es am letzten Wochenende ausgearbeitet und konnte es hier nicht aktualisieren, da ich unterwegs war. Ich schätze deine Hilfe sehr :)
Eine andere Antwort kam vor Ihrer, aber ich hatte Ihnen das Kopfgeld bereits zugesprochen, also bin ich die andere als gültige Antwort, um fair zu sein. <grins>

Ich weiß nicht, warum will nicht funktioniert, truffle-contractda nicht der gesamte Code vorhanden ist, aber Sie können die Verwendung vermeiden und Ihre Instanz einfach mit web3 erstellen.

var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

web3.eth.getAccounts(function(error, accounts) {
    var myContract = new web3.eth.Contract([
        {
          "constant": true,
          "inputs": [],
          "name": "store",
          "outputs": [
            {
              "name": "",
              "type": "address"
            }
          ],
          "payable": false,
          "stateMutability": "view",
          "type": "function"
        },
        {
          "inputs": [],
          "payable": false,
          "stateMutability": "nonpayable",
          "type": "constructor"
        },
        {
          "constant": false,
          "inputs": [],
          "name": "createStore",
          "outputs": [],
          "payable": false,
          "stateMutability": "nonpayable",
          "type": "function"
        }
      ]);
    myContract.deploy({
        data: '[bytecode]',
    })
    .send({
        from: accounts[0],
        gas: 1500000,
        gasPrice: '30000000000000'
    }, function(error, transactionHash){ console.log(error, transactionHash); })
    .on('error', console.log)
    .then(function(newContractInstance){
        console.log(newContractInstance.options.address);
        newContractInstance.methods.createStore().send({from: accounts[0], gas: "1500000"}).then(console.log).catch(console.log);
    });
});

Ändern Sie einfach diese Zeile data: '[bytecode]'mit dem Bytecode und es wird funktionieren.