Dados dos contratos de la siguiente manera, contract TestData
llama a contract Reg
para obtener datos que ya se habían almacenado en su mapa usando get_attributes
la función.
pragma solidity ^0.4.21;
contract Reg {
mapping (address=>bytes32[5]) Map;
//Filling the map
function fill_map(bytes32[5] _attributes) public {
Map[msg.sender] = _attributes;
}
//Returns data in the map corresponding to an address
function get_attributes(address _id) view public returns (bytes32[5]){
return Map[_id];
}
}
contract TestData {
address Address;
function get_address (address _Address) public{
Address = _Address;
}
//Retreive data from Reg contract
bytes32[5] fetched;
function fetch(address _reg_Adress) public view returns (bytes32[5]) {
Reg r = Reg(_reg_Adress);
fetched = r.get_attributes(Address);
return (fetched);
}
//Retreive input data from user
bytes32[5] inputs;
function getInputs(bytes32[5] _inputs) public view returns (bytes32[5]){
inputs = _inputs;
return (inputs);
}
//Compare input data with fetched data
bool[5] a = [false,false,false,false,false];
function compare() public view returns(bool[5]){
for(uint i=0;i<5;i++){
for(uint j=0;j<5;j++){
if(inputs[i] == fetched[j]){
a[i] = true;
}
}
}
return (a);
}
}
Así es como lo pruebo:
Llena el mapa con["0x0","0x1","0x2","0x3","0x4"]
Para la entrada del usuario también ingreso["0x0","0x1","0x2","0x3","0x4"]
La salida es correcta devolviendo [true,true,true,true,true]
.
Sin embargo, si cambio la entrada, digamos ["0xA","0x1","0x2","0x3","0x4"]
, la salida permanece [true,true,true,true,true]
aunque debería ser [false,true,true,true,true]
.
¿Sucede algo con los datos cuando se obtienen del contrato Reg? Cuando intento probar el mismo código pero con dos matrices de entrada en lugar de obtener los datos, funciona bien.
Además, he estado buscando otras formas de hacer las comparaciones. ¿Hay alguna otra forma eficiente que no sea el bucle?
La función compare
es casi correcta, los errores están en otra parte.
function fetch(address _reg_Adress) public view returns (bytes32[5])
tienes que sacar view
de aqui
function getInputs(bytes32[5] _inputs) public view returns (bytes32[5])
también de aquí.
Luego mueva su matriz a la función y defínala como memoria.
//Compare input data with fetched data
function compare() public view returns(bool[5]){
bool[5] memory a = [false,false,false,false,false];
for(uint i=0;i<5;i++){
for(uint j=0;j<5;j++){
if(inputs[i] == fetched[j]){
a[i] = true;
}
}
}
return (a);
}
si no, debe eliminar view
también del método compare
para que funcione
después de que esto cambie, el resultado sería false,true,true,true,true
el esperado.
Hay varios problemas:
Primero, su for
ciclo se detiene temprano, en 3, cuando el límite debería ser i<5.
Además, su segundo for
no es necesario. Su función puede ser:
function compare() public view returns(bool[5]){
bool[5] memory a;
for(uint i=0;i<5;i++){
for(uint j=0;j<5;j++){
if(inputs[i] == fetched[j]){
a[i] = true;
}
}
}
return (a);
}
También puede hacer lo siguiente para asegurarse de a
que se actualice cuando los valores sean verdaderos o falsos:
function compare() public view returns(bool[5]){
bool[5] memory a;
for(uint i=0;i<5;i++){
for(uint j=0;j<5;j++){
a[i] = (inputs[i] == fetched[j]);
}
}
return (a);
}
finalmente, sus funciones modifican las variables de estado para que no se puedan ver.
Espero que esto ayude
ACTUALIZACIÓN: código completo.
pragma solidity ^0.4.21;
contract Reg {
mapping (address=>bytes32[5]) public Map;
//Filling the map
function fill_map(bytes32[5] _attributes) public {
Map[msg.sender] = _attributes;
}
//Returns data in the map corresponding to an address
function get_attributes(address _id) view public returns (bytes32[5]){
return Map[_id];
}
}
contract TestData {
address Address;
function get_address (address _Address) public{
Address = _Address;
}
//Retreive data from Reg contract
bytes32[5] public fetched;
function fetch(address _reg_Adress) public returns (bytes32[5]) {
Reg r = Reg(_reg_Adress);
fetched = r.get_attributes(Address);
return (fetched);
}
//Retreive input data from user
bytes32[5] public inputs;
function getInputs(bytes32[5] _inputs) public returns (bytes32[5]){
inputs = _inputs;
return (inputs);
}
//Compare input data with fetched data
function compare() public view returns(bool[5]){
bool[5] memory a;
for(uint i=0;i<5;i++){
for(uint j=0;j<5;j++){
if(inputs[i] == fetched[j]){
a[i] = true;
}
}
}
return (a);
}
}
a
es todo cierto. Luego probó con algo que da false
, pero su código solo se actualiza a
cuando es verdadero, por lo que el valor verdadero no cambia. Poniéndolo dentro, inicializa a a falso cuando se ejecuta la función. Hágamelo saber
usuario19510
i<5
yj<5
? Te detienes después de comparar 3 elementos.cadena de bloques
usuario19510
usuario19510
compare
como una transacción? Si es así, se modificará permanentementea
y las llamadas posteriores heredarán los valores allí. (Una vez que un elemento se establece entrue
, nunca volverá). Probablemente debería mover la declaración dea
adentrocompare()
de todos modos.usuario19510
input
coincide con algún elemento defetched
. Si solo desea hacer coincidir los elementos correspondientes, debe soltar el bucle interno como se sugiere en esa respuesta.cadena de bloques