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?
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.
kobigurk
new
oder verwendet habensendTransaction
?Eyal Ron
kobigurk
event Hello(bytes32 x, bytes32 y)
und dann in der Funktion hinzufügen:Hello(x,y);
Eyal Ron
kobigurk
Robert Zaremba