Übergeben eines Arrays als Parameter von javascrpt (web3) an eine Solidity-Funktion

Ich habe die folgende Solidity-Funktion:

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

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

Ich versuche, es von Javascript (mit web3) aufzurufen, aber das Übergeben eines Arrays an einen Parameter funktioniert nicht. Ich habe folgende Methoden ausprobiert:

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

oder:

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

oder:

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

Keine dieser Methoden funktioniert.

Gibt es eine Möglichkeit, ein Array als Parameter von Javascript an eine Solidity-Funktion zu übergeben?

Das Übergeben eines Arrays ["field1", "field2"] funktioniert in meinem Beispiel. Haben Sie den Vertrag zuerst bereitgestellt, indem Sie newoder verwendet haben sendTransaction?
Ich habe es mit 'sendTransaction. Ich habe es oft benutzt und es funktioniert gut für jeden anderen Vertrag. Hat meine zweite Option für Sie funktioniert? Wie haben Sie überprüft, ob tatsächlich die richtigen Werte übergeben wurden? Ich erhalte keinen Kompilierungsfehler, aber die Werte in x,y sind am Ende "undefiniert".
hab dich jetzt. Wie würden Sie wissen, ob sie undefiniert sind? Sie sind lokal für die Ausführung dieser Funktion. Ich habe dafür gesorgt, dass es in Ordnung ist, indem ich ein Ereignis verwendet habe: event Hello(bytes32 x, bytes32 y)und dann in der Funktion hinzufügen:Hello(x,y);
Ich führe eine Simulation mit Mix-IDE aus, die beim Debuggen das lokale Konto anzeigt. Ich habe das Ereignis ausprobiert und zusätzlich 'x,y' globale Vertragsvariablen erstellt und mit einer konstanten Funktion gelesen - in beiden Fällen sind x und y leere Variablen. Ich bin verwirrt.
Versuchen Sie vielleicht ein ähnliches Beispiel für Browser-Solidity? ethereum.github.io/browser-solidity
@EyalRon: hast du eine Lösung gefunden? Ich habe ein ähnliches Problem. web3js gibt diesen Fehler zurück: „Ungültige Anzahl von Argumenten für Solidity-Funktion“.

Antworten (1)

Hier ist, was für mich funktioniert, wenn ich getData verwende , um ein Transaktionsdatenfeld zu füllen

Der Vertrag ist ein 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

Das Problem ist, dass Ihr Array gespeichert und mit einer Transaktion geändert werden muss, wenn Sie den Status ändern ...

Dies ist eine ausführliche (einschließlich Gasschätzung), aber hoffentlich klare Möglichkeit, sie in web3 einzustellen. Ich verwende Node.js und 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);
       }
});

Und den Array-Wert erhalten:

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

Sie könnten auch einfach die Funktion eines Vertrags mit Parametern aufrufen, aber die Funktion muss rein sein , was noch nicht erzwungen wird (dh Ihr Compiler kompiliert den Vertrag möglicherweise nicht).

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

und nennt es:

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

Das obige funktioniert mit Compilern 0.4.17 und höher (aktualisiere einfach solc), unten rufst du es wieder mit einer Transaktion auf, die Gas kostet ...

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

Überprüfen Sie beide im Remix, dass das obere kein Gas verursacht, während das untere dies tut.