Push to Array en realidad no empuja

Comunidad,

Me he estado golpeando la cabeza con el siguiente problema y espero que puedas detectar mi error. Despliego el siguiente contrato con Populuson 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 buyfunció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.lengthpermanece igual. ¿Puedes detectar un error que he cometido?

Déjame saber tu opinión sobre mi ans. Si se solucionó marcar como solucionado. Sería útil para la comunidad encontrar y fácilmente
Con testrpc/ganache-cli puede usar github.com/trufflesuite/ganache que proporciona una interfaz para buscar bloques/transacciones. Si la matriz no aumentó su longitud, entonces buy()ha fallado.

Respuestas (2)

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.toWeila 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.

Desafortunadamente, esto no resolvió mi problema. Asigno w3 a web3 anteriormente en mi script. Lo agregaré a la pregunta. ¡Pero gracias!