6

This problem happens only when I place contracts A and contract B in seperate file. When placed in same file, I get the array elements perfectly

Please find the contract below. I was able to successfully compile and migrate the same.

pragma solidity ^0.4.8;

import "./B.sol";

contract A {

   address[] public addElements;

   function A() payable {

   }

   function create() returns (address a) {
       B obj = new B();
       addElements.push(obj);
       return obj;
   }


   function getElements() returns (address[] ) {
       return addElements;
   }

}

//  <<<< This is in a different file        >>>>

pragma solidity ^0.4.8;

contract B {

   function B() {

   }

}

Now I am using truffle console and trying to invoke getElements() function to get back the arrays and would like to loop through them However, I don't see any array elements.

Output attached.

enter image description here

2
  • I think you forgot to attach some elements + I guess something got wrong when you've copied/pasted your code (see function B() {[![enter image description here][1]][1] ) Mar 4, 2017 at 13:54
  • sorry . I have corrected them now
    – sun
    Mar 4, 2017 at 13:57

1 Answer 1

5

In Web3JS, the function myFunction.call() is used to explicitly call a constant function (a function that only read in the blockchain and doesn't write anything). That why, most of the time, these functions can have the keywork constant in the contract :

function getElements() constant returns (address[] ) {
   return addElements;
}

It's unlike a sendTransaction function that is directly called using myFunction(). This function will write in the blockchain and needs to be mined.

So in your case, you can use this command to read data in the blockchain

A.deployed().then(function(instance){return instance.getElements.call();})

But to write some data, you need to remove the suffixe call()

A.deployed().then(function(instance){return instance.create();})

And the result is the following

truffle(development)> A.deployed().then(function(instance){return instance.create();})
{ tx: '0xfc66c777e5690f004ef66f3e3733d585c0df947af9131b2b6275290ab5b3346d',
  receipt:
   { transactionHash: '0xfc66c777e5690f004ef66f3e3733d585c0df947af9131b2b6275290ab5b3346d',
     transactionIndex: 0,
     blockHash: '0x24bc2ffb297bb01b116c4a35ed045f521b23f8495fb262ea1e0564d11b562e38',
     blockNumber: 44,
     gasUsed: 104777,
     cumulativeGasUsed: 104777,
     contractAddress: null,
     logs: [] },
  logs: [] }
truffle(development)> A.deployed().then(function(instance){return instance.getElements.call();})
[ '0x0cb0dbf5a387a5b24c4d7160d5d02c5102d80877' ]

EDIT: Retrieve a result from a transaction You can't directly get a result from a transaction because it's fully asynchronous and you have to wait the transaction has been mined.

However, there is some tricks: For example by triggering an event

You can add an event in your contract

pragma solidity ^0.4.8;
import "./B.sol";
contract A {
   address[] public addElements;

   event newAddress(address a);

   function A() payable { }

   function create() returns (address a) {
       B obj = new B();
       addElements.push(obj);

       // Trigger event
       newAddress(obj);
   }

   function getElements() returns (address[] ) {
       return addElements;
   }
}

Then when you send the transaction with Truffle, the result contains the logs

Example through a Truffle test (./test/test01.js)

var A = artifacts.require("./A.sol");

contract('A', function() {

    it("should work", function() {
        return A.deployed().then(function(instance){

            // Send transaction.
            return instance.create();

        }).then(function(result){
            console.log("transaction:");
            console.log(result.tx);

            console.log("logs:");
            console.log(result.logs.args.a); // Here is the new address

            return A.deployed();

        }).then(function(instance){
            // Get the data 
            return instance.getElements.call();

        }).then(function(result){
            console.log("getElements:");
            console.log(result); // same result by calling getElements()
        });
    });
});

Execute

$ truffle test test/test01.js




transaction: 0xd2a742751b339b9f6ddc19322e1171de2bef2c9bec22b8a74d5e2952d59bec66 

logs: [ 
    { logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0xd2a742751b339b9f6ddc19322e1171de2bef2c9bec22b8a74d5e2952d59bec66',
      blockHash: '0x4e896578981a332143d43d7de211e5268b2c8a31917a13455709dc713caed75c',
      blockNumber: 107,
      address: '0xdf8904a0349bec7512c83ec13742b671232629db',
      type: 'mined',
      event: 'newAddress',
      args: { a: '0x0c6f45eb4f85e2b5b0b1cc9b08062060c9f6bed0' } } 
] 

getElements:    
[ '0x0c6f45eb4f85e2b5b0b1cc9b08062060c9f6bed0' ]
2
  • Thank you. Also, is there a way to retrieve the address information after this execution A.deployed().then(function(instance){return instance.create();})
    – sun
    Mar 4, 2017 at 17:59
  • 1
    I just edited my answer. It gives you a way to retrieve a result from a transaction (writtable function) Mar 4, 2017 at 19:13

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.