Here's what works for me using getData to populate a transaction data: field
The contract is an array getter setter:
pragma solidity ^0.4.0;
contract SetGetArray {
uint[] someNumbers;
function getArray() public constant returns (uint[]) {
return someNumbers;
}
function setArray(uint[] setNumbers) public {
someNumbers = setNumbers;
}
}
// After Deploying (in Kovan)
txHash:0x1cc74caab5c64c493a67cf8e3a8de656ba0db1d6f59c634e3c68e27a41afe7bf
// Successfully deployed Contract with address:
// 0x1e1300614978efe2bf5c4b532daef69441314205
The gotcha is that if you are changing state your array needs to be in storage and modified with a transaction...
This is a verbose ( includes gas estimation) but hopefully clear way to set it in web3, I am using Node.js and Parity:
console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./SetGetArray.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
var contract = web3.eth.contract(contractABI).at("0x1e1300614978efe2bf5c4b532daef69441314205");
var receiverAddress = '0x1e1300614978efe2bf5c4b532daef69441314205';
var setNumbers = [5,2,4,1];
var setData = contract.setArray.getData(setNumbers);
// console.log(setData);
var gasEstimate = web3.eth.estimateGas({
from: web3.eth.coinbase,
to: receiverAddress,
data: setData
});
var gasPrice = web3.eth.gasPrice;
console.log('gas Price: ' + gasPrice);
console.log('Estimated Transaction gas: ' + gasEstimate);
console.log('unlocking Coinbase account');
const password = "yourPassword";
try {
web3.personal.unlockAccount(web3.eth.coinbase, password);
} catch(e) {
console.log(e);
return;
}
console.log ('sending Transaction to the contract');
const transaction = {
from: web3.eth.coinbase,
to:receiverAddress,
value: '0x00',
gas: gasEstimate + 1,
gasPrice: gasPrice + 1,
data: setData
}
web3.eth.sendTransaction( transaction, function(err, txHash) {
if (err != null) {
console.error("Error while sending transaction: " + err);
}
else{
console.log("Transaction Sent here's you txHash: " + txHash);
}
});
And getting the Array value:
console.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./SetGetArray.json");
console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
console.log('Creating contract instance');
var contract = web3.eth.contract(contractABI).at("0x1e1300614978efe2bf5c4b532daef69441314205");
console.log ('calling contract');
var getArray = contract.getArray();
console.log('Get Array : ' + getArray);
// Get Array : 5,2,4,1
// getArray[2] = 4
You could also just call a contract's function with parameters, but the function needs to be pure, which is not enforced yet( i.e. your compiler might not compile the contract).
function passArray(uint[] otherNumbers) pure public returns (uint[]) {
return otherNumbers;
}
and calling it :
var otherNumbers = [4,3,2,1];
var passArray = contract.passArray(otherNumbers);
console.log('Pass Array : ' + passArray);
// Pass Array : 4,3,2,1
The above works with compilers 0.4.17 and above (just update solc) , below you are back to calling it with a transaction that costs gas...
function passArray(uint[] otherNumbers) public returns (uint[]) {
return otherNumbers;
}
Check both in remix the one on top doesn't incur in gas, while the one in the bottom does.
new
orsendTransaction
?event Hello(bytes32 x, bytes32 y)
and then in the func add:Hello(x,y);