У меня есть следующая функция 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?
Вот что работает для меня, используя 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;
}
Проверьте оба в ремиксе: тот, что вверху, не содержит газа, а тот, что внизу, — да.
кобигурк
new
илиsendTransaction
?Эяль Рон
кобигурк
event Hello(bytes32 x, bytes32 y)
а затем в функции добавить:Hello(x,y);
Эяль Рон
кобигурк
Роберт Заремба