1

we are experiencing an issue dealing with structs. We expect to modify a struct property after getting it from an event in web3js, but, it seems that the modify does not apply.

Any ideas?

Contract code:

pragma solidity ^0.5.3;
pragma experimental ABIEncoderV2;

contract Example {
  struct Structure {
    uint value;
  }

  event Created(
    Structure structure
  );

  event Modified(
    Structure structure
  );

  constructor() public {}

  function create() public {
    emit Created(Structure(42));
  }

  function modify(Structure memory structure) public {
    emit Modified(structure);
  }
}

web3js code:

  let Example = artifacts.require('Example')
  let accounts = await web3.eth.getAccounts()

  Example.deployed()
    .then(instance => {
      instance.Created(async (err, evt) => {
        let structure = evt.returnValues.structure
        console.log('Created: ' + structure.value)
        structure.value = 21
        console.log('Modify: ' + structure.value)
        await instance.modify(structure, { from: accounts[0] })
      })

      instance.Modified((err, evt) => {
        let structure = evt.returnValues.structure
        console.log('Modified: ' + structure.value)
        callback()
      })

      instance.create({ from: accounts[0] })
    })

log:

Created: 42
Modify: 21
Modified: 42

We expected the modified value equals to 21

6
  • console.log the structure, but my guess is that you have to modify something like structure[0]. Taking a JavaScript object from an event and passing it as a function parameter is probably not a great idea, though.
    – user19510
    Jan 23, 2019 at 16:17
  • the structure console.log are: ``` [ '42', value: '42' ] [ '42', value: 21 ] [ '42', value: '42' ] ```. yes, with structure[0] works, but in a structure with a lot of properties it will be hard to associate name with index
    – ndr_brt
    Jan 24, 2019 at 7:32
  • 1
    Right. Try structure[0] = 21.
    – user19510
    Jan 24, 2019 at 7:34
  • Sorry, just saw your edit. I'm pretty sure that on the web3.js side, when you send a struct to a function, you're really just sending an array. So there's no easy way to get around this.
    – user19510
    Jan 24, 2019 at 7:35
  • 1
    Maybe you'd prefer to use instance.modify([ structure.foo, structure.bar, ...], { from: accounts[0] }). You still have to list all the properties in the right order somewhere, but you can centralize that code.
    – user19510
    Jan 24, 2019 at 7:38

1 Answer 1

1

As smarx said, using structure[0] = 21 it works, because structure is an array. With more properties, the order is the same on the struct definition, so, with the struct:

struct Example {
  uint first;
  uint n;
  uint last;
}

those equals are verified:

struct[0] == struct.first
struct[1] == struct.n
struct[2] == struct.last

and to change the value we must do:

struct[0] = 1 // sets struct.first
struct[1] = 2 // sets struct.n
struct[2] = 3 // sets struct.last

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.