Pasar una matriz como parámetro de javascrpt (web3) a una función de Solidity

Tengo la siguiente función de solidez:

function func(bytes32[2] data) external {
        bytes32 x;
        bytes32 y;

        x = data[0];
        y = data[1];
}

Estoy tratando de llamarlo desde Javascript (usando web3), pero pasar una matriz como parámetro no funciona. Probé los siguientes métodos:

var arr = ["field1", "field2"];
contracts['MyContract'].contract.func(arr);

o:

contracts['MyContract'].contract.func(["field1", "field2"]);

o:

contracts['MyContract'].contract.func("field1", "field2");

Ninguno de esos métodos funciona.

¿Hay alguna forma de pasar una matriz como parámetro de Javascript a una función de Solidity?

pasar una matriz ["campo1", "campo2"] funciona en mi ejemplo. ¿Desplegó el contrato primero, usando newo sendTransaction?
Lo implementé usando 'sendTransaction. Lo usé a menudo y funciona bien para cualquier otro contrato. ¿Te funcionó mi segunda opción? ¿Cómo verificó que efectivamente se pasaron los valores correctos? No recibo un error de compilación, pero los valores en x, y al final son "indefinidos".
te tengo ahora ¿Cómo sabrías si no están definidos? son locales para la ejecución de esta función. Me aseguré de que esté bien usando un evento: event Hello(bytes32 x, bytes32 y)y luego en la función agregar:Hello(x,y);
Ejecuto una simulación usando Mix-IDE, muestra la cuenta local durante la depuración. Probé el evento, y además hice variables de contrato global 'x, y', y leí con una función constante; en ambos casos, x e y son variables vacías. Estoy confundido.
¿Tal vez intente un ejemplo similar en la solidez del navegador? ethereum.github.io/browser-solidity
@EyalRon: ¿encontraste una solución? Tengo un problema similar. web3js devuelve este error: `Número no válido de argumentos para la función Solidity`

Respuestas (1)

Esto es lo que funciona para mí usando getData para completar los datos de una transacción : campo

El contrato es un setter getter de matriz:

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

El problema es que si está cambiando de estado, su matriz debe estar almacenada y modificada con una transacción ...

Esta es una forma detallada (incluye estimación de gas) pero con suerte clara para configurarlo en web3, estoy usando Node.js y 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);
       }
});

Y obteniendo el valor de Array:

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

También puede simplemente llamar a la función de un contrato con parámetros, pero la función debe ser pura , lo que aún no se aplica (es decir, es posible que su compilador no compile el contrato).

function passArray(uint[] otherNumbers) pure public returns (uint[]) {
    return otherNumbers;
}

y llamándolo:

  var otherNumbers = [4,3,2,1];
  var passArray = contract.passArray(otherNumbers);
  console.log('Pass Array : ' + passArray);
  // Pass Array : 4,3,2,1

Lo anterior funciona con los compiladores 0.4.17 y superiores (solo actualice solc), a continuación, vuelve a llamarlo con una transacción que cuesta gasolina ...

function passArray(uint[] otherNumbers) public returns (uint[]) {
    return otherNumbers;
}

Verifique que ambos en remix, el de arriba no incurra en gas, mientras que el de abajo sí.