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.
neworsendTransaction? – kobigurk Aug 28 '16 at 10:00Did my second option works for you? How did you verify that indeed the right values were passed?
I don't get a compilation error, but the values in x,y in the end are "undefined".
– Eyal Ron Aug 28 '16 at 11:30event Hello(bytes32 x, bytes32 y)and then in the func add:Hello(x,y);– kobigurk Aug 28 '16 at 12:22Invalid number of arguments to Solidity function– Robert Zaremba Sep 02 '17 at 11:29