Comunidad,
Me he estado golpeando la cabeza con el siguiente problema y espero que puedas detectar mi error. Despliego el siguiente contrato con Populus
on Testrpc
. Este es un contrato bastante simple:
pragma solidity ^0.4.19;
contract ICO {
address public owner;
mapping(address => uint) public balances;
address[] public buyers;
uint constant public MULTIPLIER = 1000;
function ICO() public {
owner = msg.sender;
}
function getBuyersLength() public constant returns (uint) {
return buyers.length;
}
function buy() public payable {
uint coins = msg.value * MULTIPLIER;
balances[msg.sender] += coins;
buyers.push(msg.sender);
}
}
Estoy llamando a la buy
función con Web3js de la siguiente manera:
let contract;
let account;
window.addEventListener('load', function () {
if (typeof web3 !== 'undefined') {
console.log('Using MetaMask connection');
w3 = new Web3(web3.currentProvider);
} else {
w3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
contract = w3.eth.contract(contractABI).at(contractAddress);
account = w3.eth.defaultAccount;
main()
});
function main() {
let amount = w3.toWei(10, 'ether');
contract.buy({'value': amount}, function (err, res) {
if (err) {
console.error('Error occurred: ' + err);
} else {
console.log('Transaction created: ' + res);
}
})
}
Después de esperar a que la transacción se incluya en un bloque (sucede casi instantáneamente desde que ejecuto testrpc
, llamo a la getBuyersLength()
función de esta manera:
function updateBalances() {
contract.getBuyersLength(function (err, res) {
if (err) {
console.error('Error in getBuyers: ' + err);
} else {
console.log('Count of Buyers: ' + res);
}
}
}
Sin embargo, los resultados siempre son 0
, lo que significa que buyers.length
permanece igual. ¿Puedes detectar un error que he cometido?
Acabo de resolverlo. El problema fue cómo implementé el contrato en TestRPC
. Solía populus deploy ICO -c testrpc
implementar el contrato, pero de alguna manera, el contrato nunca se guardó en la cadena de bloques de prueba. Ahora implemento el contrato desde la interfaz, que no es la mejor solución, pero funciona por ahora. Así es cómo:
w3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
account = w3.eth.defaultAccount;
let contractScheme = w3.eth.contract(contractABI);
let gasEstimate = w3.eth.estimateGas({data: contractBytecode});
contract = contractScheme.new({
data: contractBytecode,
from: account,
gas: gasEstimate
}, function (err, res) {
if (err) {
console.error('Error occurred in Contract Creation: ' + err)
} else {
// Callback fires twice. Once upon reception of the TransactionHash and
// once the contract receives an address.
if (!res.address) {
console.log('TransactionID for Contract Creation ' + res.transactionHash)
}
if (res.address) {
console.log('Contract Address: ' + res.address);
main()
}
}
});
Su contrato parece estar bien. Podría ser un problema en w3.toWei
la función de archivo principal de Js. Supongo que no asignaste ningún objeto web3 a w3. Entonces w3 no está definido, Javascript arrojará un error. Porque no se encontró ninguna deificación para w3.toWei
. Entonces sus declaraciones no se ejecutarán, contract.buy()
no se ejecutarán. Si este método no se ejecuta, entonces no hay trans en el cliente Eth. Entonces, cuando llame, getBuyersLength()
devolverá solo 0.
function main() {
let contract = web3.eth.contract(CONTRACT_ABI).at(CONTRACT_ADDR);
let amount = web3.toWei(10, 'ether');
contract.buy({'value': amount}, function (err, res) {
if (err) {
console.error('Error occurred: ' + err);
} else {
console.log('Transaction created: ' + res);
}
})
}
Reemplace su código con el código mencionado anteriormente. Si su problema no se resuelve, actualice su qus con registros de Javascript.
Jitendra Kumar. Balla
ismael
buy()
ha fallado.