Programmgesteuertes Speichern der Vertragsadresse eines übermittelten Vertrags

Ich verstehe, wie der folgende web3js-Codeblock funktioniert, angepasst von hier:

https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract

Aber wie speichert man die Vertragsadresse programmatisch? Ich nehme an, man könnte eine Datei öffnen und im Callback beibehalten, aber das nicht. =:)

Und ich glaube nicht, dass uns der Bezeichner myContractReturned weiterhilft ; angesichts der asynchronen Natur von JavaScript (ganz zu schweigen von der Mining-Verzögerung). Wie benutzt man das überhaupt?

Es ist eine Art akademische Frage (weil es keine Garantie gibt, dass überhaupt eine Adresse generiert wird), aber neugierig, was Freunde in der Community getan (oder gedacht) haben. Vielen Dank!

--

var myContractReturned = MyContract.new(param1,param2, {
   from:mySenderAddress,
   data:bytecode,
   gas:gasEstimate},
   function(error, myContract){
     if(!error) {
        if(!myContract.address) {
            // Step-1: Runs on contract submission/deployment.
            console.log(myContract.transactionHash)
        } 
        else {
            // Step-2: Runs after contract is deployed.
            console.log(myContract.address)
        }

     }
  });
Vielen Dank an "@Mikko Ohtamaa" und "@Xavier Leprêtre B9lab" für Ihre jeweiligen Antworten. Beide sind ziemlich gute Antworten und ich ermutige die Leser, beide anzusehen! Die Antwort von Xavier erinnert uns daran, dass wir – indem wir sie vorab berechnen – die Vertragsadresse kennen können, noch bevor sie übermittelt wird.

Antworten (2)

Die Vertragsadresse wird aus der Adresse des Anbieters und der Transaktionsnonce berechnet. Sie müssen nicht warten, bis der Vertrag abgebaut wird, um ihn zu erhalten.

In NodeJs reicht so etwas:

var ethUtil = require('ethereumjs-util');

var currentNonce = web3.eth.getTransactionCount(myAccount);
var futureAddress = ethUtil.bufferToHex(ethUtil.generateAddress(myAccount, currentNonce));
// futureAddress ist die Adresse des Vertrags, den Sie unten bereitstellen

var MyContract = web3.eth.contract(abiArray);
var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000});

// Hier können Sie bestätigen, dass die Adresse tatsächlich die ist, die Sie zuvor berechnet haben.

Vergessen Sie nicht, diesen Demo-Code zu verbessern, indem Sie asynchrone Aufrufe verwenden.

Schade, dass Leute, die zu der akzeptierten Antwort kommen, glauben, dass Sie die Adresse nicht haben können, bevor sie abgebaut wurde.
@"Xavier Leprêtre B9lab" Richtig, und deshalb habe ich meine akzeptierte Antwort aktualisiert, damit die Leute sie sehen können. Die akzeptierte Antwort wurde seit Ihrem obigen Kommentar geändert :)

Der Vertragskonstruktor gibt einen Transaktionshash zurück, in dem der Vertrag bereitgestellt wird. Die endgültige Vertragsadresse kann deterministisch aus der Anbieteradresse und der Anbieteradresse nonce ermittelt werden (siehe andere Antwort). Diese Informationen sind auch verfügbar, web3.eth.getTransactionReceiptnachdem die Bereitstellungstransaktion geschürft wurde.

Beachten Sie, dass Sie nicht wissen, ob die Vertragsbereitstellung erfolgreich ist oder fehlschlägt, bevor die Transaktion abgebaut wurde. Sie können nicht mit dem Vertrag interagieren, bevor die Transaktion abgebaut wurde.

Hier ist ein Beispiel-Bereitstellungsskript für Node 7 ( vollständiges Tutorial lesen ):

// Copyright 2017 https://tokenmarket.net - MIT licensed
//
// Run with Node 7.x as:
//
// node --harmony-async-await  deploy.js
//
// DO NOT RUN IN GETH CONSOLE

let fs = require("fs");
let Web3 = require('web3'); // https://www.npmjs.com/package/web3

// Create a web3 connection to a running geth node over JSON-RPC running at
// http://localhost:8545
// For geth VPS server + SSH tunneling see
// https://gist.github.com/miohtama/ce612b35415e74268ff243af645048f4
let web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

// Read the compiled contract code
// Compile with
// solc SampleContract.sol --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,devdoc,interface,opcodes,srcmap,srcmap-runtime,userdoc > contracts.json
let source = fs.readFileSync("contracts.json");
let contracts = JSON.parse(source)["contracts"];

// ABI description as JSON structure
let abi = JSON.parse(contracts.SampleContract.abi);

// Smart contract EVM bytecode as hex
let code = contracts.SampleContract.bin;

// Create Contract proxy class
let SampleContract = web3.eth.contract(abi);

// Unlock the coinbase account to make transactions out of it
console.log("Unlocking coinbase account");
var password = "";
try {
  web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
  console.log(e);
  return;
}

console.log("Deploying the contract");
let contract = SampleContract.new({from: web3.eth.coinbase, gas: 1000000, data: code});

// Transaction has entered to geth memory pool
console.log("Your contract is being deployed in transaction at http://testnet.etherscan.io/tx/" + contract.transactionHash);

// http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// We need to wait until any miner has included the transaction
// in a block to get the address of the contract
async function waitBlock() {
  while (true) {
    let receipt = web3.eth.getTransactionReceipt(contract.transactionHash);
    if (receipt && receipt.contractAddress) {
      console.log("Your contract has been deployed at http://testnet.etherscan.io/address/" + receipt.contractAddress);
      console.log("Note that it might take 30 - 90 sceonds for the block to propagate befor it's visible in etherscan.io");
      break;
    }
    console.log("Waiting a mined block to include your contract... currently in block " + web3.eth.blockNumber);
    await sleep(4000);
  }
}

waitBlock();
Vielen Dank für diese Antwort "@Mikko Ohtamaa". Hochgeschätzt. Unten bietet „@Xavier Leprêtre B9lab“ einen alternativen Ansatz, und die Leser sollten beide Antworten nutzen (entsprechend ihrem Anwendungsfall). :)
Bitte stellen Sie klar, dass der bereitgestellte Code nicht mit der Geth-JavaScript-Konsole kompatibel ist (der Code verwendet ES6-Funktionen wie Pfeilfunktionen, während Geth nur ES5 unterstützt). Ich habe den Fehler selbst gemacht, und es sieht so aus, als wäre ich nicht der Erste: ethereum.stackexchange.com/q/33978/36845