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?
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í.
kobigurk
new
osendTransaction
?Eyal Ron
kobigurk
event Hello(bytes32 x, bytes32 y)
y luego en la función agregar:Hello(x,y);
Eyal Ron
kobigurk
Roberto Zaremba