0

I'd like to call a constant function on one contract (X) from another contract (Y). I have the ABI and address for X. X and Y are both on Ropsten. I can interact with X fine using, for example, MEW.

Here is the code for X:

@public
@constant
def read() -> bytes32:
    return 0x0000000000000000000000000000000000000000000000059f43ef8557c30000

And the ABI:

[{"name": "read", "outputs": [{"type": "bytes32", "name": "out"}], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 283}]

Contract Y looks like this:

feedaddress: public(address)
feed: public(bytes[32])

@public
def __init__():
    self.feedaddress = 0xAb3F6737b0cf41e8a6AE297A3833021f8af2a3aC

@public
def myread():
    self.feed = raw_call(self.feedaddress, 'read', outsize=32, gas=msg.gas)

@public
def setfeedaddress(_new: address):
    self.feedaddress = _new

It returns "Warning! Error encountered during contract execution [Reverted]" on etherscan. What am I doing wrong?

0

The second parameter to raw_call should be the bytes you're sending to the other contract. In order to invoke the function read(), you should be sending the bytes 0x57de26a4 (the function signature: first 4 bytes of the keccak256 hash of "read()").

  • I've used raw_call(self.feedaddress, 'x57xdex26xa4', outsize=32, gas=msg.gas) as well as '0x57de26a4' and '57de26a4' and all return the same error as above. I'm writing the result into a bytes[32] not a bytes32 (which won't compile). Any further help would be greatly appreciated. – Sivakumar Arumugam Nov 27 '18 at 18:01
  • I'm not that familiar with Vyper yet, but I assume you want raw_call(self.feedaddress, 0x57de26a4, ...). – smarx Nov 27 '18 at 18:04
0

Following a question on github, it turns out that raw_call is unnecessary because Vyper's contract interface is ABI compatible. Using the above example, the following works just fine:

contract Beread:
    def read() -> bytes32: constant

feedaddress: public(address)
feed: public(bytes32)
beread: Beread


@public
def __init__():
    self.feedaddress = 0x161E2Eea68ac57F3C7220170435396Fd7089d9fE

@public
def myread():
    self.beread = self.feedaddress
    self.feed = self.beread.read()

@public
def setfeedaddress(_new: address):
    self.feedaddress = _new

See help with raw_call for how to use that function directly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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