Entiendo cómo funciona el siguiente bloque de código web3js, adaptado de aquí:
https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract
Pero, ¿cómo se guarda la dirección del contrato mediante programación? Uno podría, supongo, abrir un archivo y conservarlo dentro de la devolución de llamada, pero no eso. =:)
Y no creo que el identificador myContractReturned nos ayude; dada la naturaleza asíncrona de JavaScript (sin mencionar el retraso de la minería). ¿Cómo se usa eso?
Es una especie de pregunta académica (porque no hay garantía de que se genere una dirección), pero es curioso saber qué han hecho (o pensado) los amigos de la comunidad. ¡Gracias!
--
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)
}
}
});
La dirección del contrato se calcula a partir de la dirección del implementador y la transacción nonce. No necesita esperar a que se extraiga el contrato para obtenerlo.
En NodeJs, algo así funcionará:
var ethUtil = require('ethereumjs-util'); var currentNonce = web3.eth.getTransactionCount(myAccount); var futureAddress = ethUtil.bufferToHex(ethUtil.generateAddress(myAccount, currentNonce)); // direcciónfuturo es la dirección del contrato que implementa a continuación var MiContrato = web3.eth.contract(abiArray); var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000}); // Aquí puede confirmar que su dirección es de hecho la que calculó anteriormente.
No olvide mejorar este código de demostración utilizando llamadas asincrónicas.
El constructor del contrato devolverá un hash de transacción donde se está implementando el contrato. La dirección del contrato final se puede determinar de manera determinista a partir de la dirección del implementador y la dirección del implementador nonce (ver otra respuesta). Esta información también está disponible web3.eth.getTransactionReceipt
después de que se haya extraído la transacción de implementación.
Tenga en cuenta que no sabe si la implementación del contrato tendrá éxito o fallará antes de que se haya extraído la transacción. No puede interactuar con el contrato antes de que se haya extraído la transacción.
Aquí hay una secuencia de comandos de implementación de muestra para Node 7 ( lea el tutorial completo ):
// 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();
NYCeyes