5

I have attached my contract, which works fine on populus and compiles on geth. It is a simple source code: Test() function appends data into my linkedlist that is defined in my library. And get() function's goal is to retrieve the head nodes' data in byte32 format.

My goal is to pull head node's data(bytes32). Inside my contract I have this following functions Test() and get().

On populus; when I called Link Contract's get() function, I can see the value that is stored in Struct's data which is bytes32 type.

my_contract.transact().Test();
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)
output = my_contract.call().get();
print(output[0] + output[1]);
abc111 //this is my output result. String that is stored in head node  
       //printed correctly.

On the other hand, on geth (by using my private Ethereum Blockchain), when I call get() function, instead of returning (bytes32,bytes32) value it returns its transaction address value.

ret_value = link.get({from: eth.accounts[0]})
"0xb508d62ce8c32d792cccf41f04f607d93c672e3a7e53e3e9fedb433ecc1f7a83"

[Q] On geth how could I get the nodes' data (like on populus as "abc111") value since on geth when I call get() function it returns transaction's address value instead of (bytes32, bytes32).

Note: Returning string might be a solution so also in library if I change data's type from "bytes32" with "string" type, I have faced with following error: Error: Return argument type inaccessible dynamic type is not implicitly convertible to expected type (type of first return variable) string memory.

Thank you for your valuable help and time.

The example code as follows from this original implementation (https://github.com/ethereum/dapp-bin/blob/master/library/linkedList.sol):

library LinkedList {
      struct data {
        uint80 head;
        uint80 last;
        uint80 count;
        Item[] items; 
      }
      uint80 constant None = uint80(0);
      struct Item {
        uint80 prev;
        uint80 next;
        bytes32 data;
        bytes32 data2; 
      }

  /// Appends `_data` to the end of the list self. Pushes the _data.
  function append(data storage self, bytes32 _data, bytes32 _data2) {
    var index = uint80(self.items.push(Item({prev: self.last, next: None, data: _data, data2: _data2})));
    if (self.last == None)
      {
    if (self.head != None || self.count != 0) throw;
    self.head = self.last = index;
    self.count = 1;
      }
    else
      {
    self.items[self.last - 1].next = index;
    self.last = index;
    self.count++;
      }
  }

  function get_head_data(data storage self) returns (bytes32,bytes32) {
    var it = iterate_start(self);
    return (iterate_get(self, it));
  }

  function get_head_iterate(data storage self) returns (uint80) {
    var it = iterate_start(self);    
    return it;
  }

  // Interface of Iterator
  function iterate_start(data storage self) returns (uint80) { return self.head; }
  function iterate_next(data storage self, uint80 _index) returns (uint80) { return self.items[_index - 1].next; }
  function iterate_get(data storage self, uint80 _index) returns (bytes32, bytes32) {
    return (self.items[_index - 1].data, self.items[_index - 1].data2); }
}

contract Link {
  using LinkedList for LinkedList.data;
  LinkedList.data public list;
  function Test() {
    list.append("abc","111");
    list.append("def", "222");
    list.append("ghf", "333");
  }

  function get() returns (bytes32, bytes32) {
    return (list.get_head_data());
  }
}

2 Answers 2

6

You want to use

link.call.get()

Also, a better way to do it is just to mark the get function constant. Then it will do a call by default.

This does a simulated transaction call and returns the value. Otherwise, you're doing an actual transaction, and getting the return value.

Dealing with strings can be tricky; they aren't value types, like bytes32, but are a pointer to a dynamic array of bytes, similar to char* in C. See the docs for more info

10
  • 1
    In general, you should avoid doing reads and writes in the same operation. If you feel you need to, you should use events Commented Oct 19, 2016 at 20:10
  • 1
    ethereum.stackexchange.com/questions/765/… covers much of what you want to know with regards to transactions. Commented Oct 19, 2016 at 20:12
  • 1
    The issue that you're facing with strings is that you can't pass dynamically sized memory objects between contracts, including libraries. What you can do is pass a storage pointer to a string to the library function, then modify the string at that address, since libraries share the same storage as the caller Commented Oct 19, 2016 at 20:16
  • 1
    Also, the "no dynamically sized memory objects" statement isn't quite true, but that's a separate question. You can always come chat on gitter.im/ethereum/solidity Commented Oct 19, 2016 at 20:18
  • 1
    Let us continue this discussion in chat. Commented Oct 19, 2016 at 21:26
0

On Geth version 1.10.12, you can call your get method like this:

link.get.call()

Also, instead of constant, include the view and public modifiers to your get function definition in Solidity.

If your function isn't returning any value, you can call it directly without the call method like this

myContract.myFunction()
2
  • Why are you answering a 5 year old question? You are just copying the existing answer.
    – Ismael
    Commented Jan 6, 2022 at 0:18
  • 1
    ... because, I had same issue as the questioner and my Google search brought me here. The existing answer isn't same as mine. I've made a browser search for the keywords view and public on this page. I didn't copy this answer from anywhere. If similar answer exist elsewhere on this exchange, I didn't see it in my Google query. This was top of the list of questions Google showed me and I think it would help if some one stumbles in here with similar problem and finds a modern way to solve it without going through the whole stackexchange. Thanks. Commented Jan 6, 2022 at 3:26

Your Answer

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

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