Программное сохранение адреса контракта отправленного контракта

Я понимаю, как работает приведенный ниже блок кода web3js, адаптированный отсюда:

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

Но как программно сохранить адрес контракта? Я полагаю, можно было бы открыть файл и сохранить его в обратном вызове, но не так. знак равно

И я не верю, что идентификатор myContractReturned нам поможет; учитывая асинхронный характер JavaScript (не говоря уже о задержке майнинга). Как это вообще можно использовать?

Это своего рода академический вопрос (потому что нет гарантии, что адрес будет сгенерирован), но любопытно, что сделали (или подумали) друзья в сообществе. Благодарю вас!

--

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)
        }

     }
  });
Спасибо "@Mikko Ohtamaa" и "@Xavier Leprêtre B9lab" за ваши ответы. Оба ответа неплохие, и я призываю читателей просмотреть оба! Ответ Ксавьера напоминает нам, что, предварительно вычислив его, мы можем узнать адрес контракта еще до того, как он будет отправлен.

Ответы (2)

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

В NodeJs что-то подобное будет делать:

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

var currentNonce = web3.eth.getTransactionCount(myAccount);
var futureAddress = ethUtil.bufferToHex(ethUtil.generateAddress(myAccount, currentNonce));
// futureAddress — это адрес контракта, который вы развернете ниже

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

// Здесь вы можете подтвердить, что его адрес действительно тот, который вы вычислили ранее.

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

Жаль, что люди, которые придут к принятому ответу, поверят, что вы не можете получить адрес до того, как он будет заминирован.
@"Xavier Leprêtre B9lab" Верно, и именно поэтому я обновил свой принятый ответ, чтобы люди могли его увидеть. Принятый ответ был изменен с момента вашего комментария выше :)

Конструктор контракта вернет хэш транзакции, в которой развертывается контракт. Окончательный адрес контракта может быть детерминировано определен из адреса развертывателя и одноразового номера адреса развертывателя (см. другой ответ). Эта информация также доступна web3.eth.getTransactionReceiptпосле обработки транзакции развертывания.

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

Вот пример сценария развертывания для Node 7 ( прочитайте полное руководство ):

// 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();
Спасибо за этот ответ "@Mikko Ohtamaa". Оценил. Ниже «@Xavier Leprêtre B9lab» представлен альтернативный подход, и читатели должны использовать оба ответа (в соответствии со своим вариантом использования). :)
Пожалуйста, уточните, что предоставленный код не совместим с консолью JavaScript geth (код использует функции ES6, такие как стрелочные функции, в то время как geth поддерживает только ES5). Я сам допустил ошибку, и похоже не я первый: ethereum.stackexchange.com/q/33978/36845