Передача массива в качестве параметра из javascrpt (web3) в функцию Solidity

У меня есть следующая функция Solidity:

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

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

Я пытаюсь вызвать его из Javascript (используя web3), но передача массива параметра не работает. Я пробовал следующие методы:

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

или же:

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

или же:

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

Ни один из этих методов не работает.

Есть ли способ передать массив в качестве параметра из Javascript в функцию Solidity?

передача массива ["поле1", "поле2"] работает в моем примере. вы сначала развернули контракт, используя newили sendTransaction?
Я развернул его с помощью sendTransaction. Я часто использовал его, и он отлично работает для любого другого контракта. Мой второй вариант вас устроил? Как вы убедились, что действительно переданы правильные значения? Я не получаю ошибки компиляции, но значения в x, y в конце «не определены».
получил тебя сейчас. как бы вы узнали, если они не определены? они локальны для выполнения этой функции. Я убедился, что все в порядке, используя событие: event Hello(bytes32 x, bytes32 y)а затем в функции добавить:Hello(x,y);
Я запускаю симуляцию с помощью Mix-IDE, она показывает локальную учетную запись во время отладки. Я попробовал событие и, кроме того, сделал глобальные переменные контракта «x, y» и прочитал с помощью постоянной функции - в обоих случаях x и y являются пустыми переменными. Я озадачен.
Может быть, попробовать аналогичный пример на браузерной солидности? эфириум.github.io/браузер-солидность
@EyalRon: ты нашел решение? У меня похожая проблема. web3js возвращает эту ошибку: «Недопустимое количество аргументов для функции Solidity».

Ответы (1)

Вот что работает для меня, используя getData для заполнения данных транзакции: поле

Контракт является сеттером получения массива:

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

Суть в том, что если вы меняете состояние, ваш массив должен находиться в хранилище и изменяться с помощью транзакции...

Это подробный (включая оценку газа), но, надеюсь, понятный способ установить его в web3, я использую Node.js и 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);
       }
});

И получение значения массива:

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

Вы также можете просто вызвать функцию контракта с параметрами, но функция должна быть чистой , что еще не применяется (т.е. ваш компилятор может не скомпилировать контракт).

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

и вызывая его:

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

Вышеупомянутое работает с компиляторами 0.4.17 и выше (просто обновите solc), ниже вы вернетесь к его вызову с транзакцией, которая стоит газа...

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

Проверьте оба в ремиксе: тот, что вверху, не содержит газа, а тот, что внизу, — да.