1

I wasn't able to get this working using the other "contracts from contracts" examples, so I thought I would post it here. There are two things going wrong:

  1. The Sent Event in the first contract never emits anything.
  2. The sendOrder method in the second contract never seems to execute.

Here is the sol file:

pragma solidity ^0.4.11;

contract TA2_Transfer {
    address public sender;
    address public receiver;
    uint public packageCount;
    mapping (address => uint) public balances;
    event Transfer(address from, address to, uint objCount);
    function sendToReceiver(address sender, address receiver, uint256 objCount) payable {
        if (balances[sender] < objCount) return;
        balances[sender] -= objCount;
        balances[receiver] += objCount;
        Transfer(sender, receiver, objCount);
    }
    function getBalance(address _sender) returns(uint) {
        return balances[_sender];
    }
}

contract ShippingOrder{
    TA2_Transfer public t;
    address public oOrigin;
    address public oShipper;
    address public oCarrier;
    address public oReceiver;
    uint public oCount;
    mapping (address => uint) public oBalances;
    event Sent(address shipper, address carrier, address receiver, uint objCount);
    function ShippingOrder() {
        oBalances[tx.origin] = 200;
    }
    function getBalance(address _sender) returns(uint) {
        return oBalances[_sender];
    }
    function sendOrder(address oOrigin, address oShipper, address oCarrier,  address oReceiver, uint256 oCount) payable{
        t.sendToReceiver(oOrigin, oShipper, oCount);
        t.sendToReceiver(oShipper, oCarrier, oCount);
        t.sendToReceiver(oCarrier, oReceiver, oCount);
    }
}

And here is the test file:

var ShippingOrder = artifacts.require("./ShippingOrder.sol");
contract('ShippingOrder', function(accounts) {
var meta;
var  xInt = 1;
var origin = accounts[0];
var shipper = accounts[1];
var carrier = accounts[2];
var receiver = accounts[3];
 it("should put 300 in the first account", function() {
    return ShippingOrder.deployed().then(function(instance) {
      return instance.getBalance.call(accounts[0]);
    }).then(function(balance) {
      assert.equal(balance.valueOf(), 200, "300 wasn't in the first account");
    });
  });
it("should transfer 1 package from Origin to Receiver", function() {
    return ShippingOrder.deployed().then(function(instance) {
      meta = instance;
      return meta.sendOrder.call(origin, shipper, carrier, receiver, xInt);
     }).then(function(balance) {
      return meta.getBalance.call(origin);
    }).then(function(balance) {
      origin_balance = balance.toNumber();
      return meta.getBalance.call(shipper);
    }).then(function(balance) {
      shipper_balance = balance.toNumber();
      return meta.getBalance.call(carrier);
    }).then(function(balance) {
      carrier_balance = balance.toNumber();
      return meta.getBalance.call(receiver);
    }).then(function(balance) {
      receiver_balance = balance.toNumber();
      assert.equal(origin_balance, 199, "Origin Balance Not 199");
      assert.equal(shipper_balance,0, "Shipper Balance Not 0");
      assert.equal(carrier_balance, 0, "Carrier Balance Not 0");
      assert.equal(receiver_balance, 1, "Receiver Balance Not 1");
    });
});
});

Any help would be greatly appreciated... it feels like I am close!!

Frank

1

Where you do t.sendToReceiver

You have t defined with TA2_Transfer public t;

That types it, reserves storage and sets up a public getter function. This missing piece is to set t to an actual instance of a TA2.

One possible approach:

You'll need TA2 deployed so you have an address to work with. Do that first. Then pass the address to ShippingOrder in the constructor:

function ShippingOrder(address TA2) {
  t = TA2_Transfer(TA2);
}

Important thing is type it and also set it to an instance.

Hope it helps.

UPDATE:

More details.

This line stops things from happening. I commented it out to avoid dealing with setting up the use-case for testing. Obviously, a condition that needs to be met for things to work: if (balances[sender] < objCount) return;

And, I added returns(bool success) to important functions and played with the events to make it seem more complete. Added missing Sent() and success checks in ShippingOrder().

I didn't spend any time considering how this maps to the use-case. Just addressing the issues raised. No warranty.

pragma solidity ^0.4.11;
contract TA2_Transfer {
    address public sender;
    address public receiver;
    uint public packageCount;

    mapping (address => uint) public balances;
    event Transfer(address from, address to, uint objCount);

    function sendToReceiver(address sender, address receiver, uint256 objCount) 
        payable 
        returns(bool success) 
    {
        // if (balances[sender] < objCount) return false;
        balances[sender] -= objCount;
        balances[receiver] += objCount;
        Transfer(sender, receiver, objCount);
        return true;
    }
    function getBalance(address _sender) returns(uint) {
        return balances[_sender];
    }
}
contract ShippingOrder{
    TA2_Transfer public t;
    address public oOrigin;
    address public oShipper;
    address public oCarrier;
    address public oReceiver;
    uint public oCount;

    mapping (address => uint) public oBalances;
    event Sent(address sender, address origin, address shipper, address carrier, address receiver, uint objCount);

    function ShippingOrder(address TA2) {
        t = TA2_Transfer(TA2);
        oBalances[msg.sender] = 200;
    }
    function getBalance(address _sender) returns(uint) {
        return oBalances[_sender];
    }
    function sendOrder(address oOrigin, address oShipper, address oCarrier,  address oReceiver, uint256 oCount) 
        payable 
        returns(bool success) 
    {
        if(!t.sendToReceiver(oOrigin, oShipper, oCount)) throw;
        if(!t.sendToReceiver(oShipper, oCarrier, oCount)) throw;
        if(!t.sendToReceiver(oCarrier, oReceiver, oCount)) throw;
        Sent(msg.sender, oOrigin, oShipper, oCarrier, oReceiver, oCount);
        return true;
    }
}

In Remix to show it working:

enter image description here

enter image description here

  • I tried adding that in the constructor and I am still not getting either the events emitting or the sendToReciever transactions being created. – Frank Blau Jul 9 '17 at 19:24
  • Strange... that exact same code doesn't work for me against testrpc... I tried remix but it keeps stopping right after it starts up. – Frank Blau Jul 9 '17 at 20:01
  • Remix is worth getting used to. Make sure you do + Create New File (top left) to get yourself a blank canvas. Also, select a compiler under settings. I used 0.4.11. It will help you isolate issues to first know that contract code does its part correctly. For example, I didn't really get into the unit test but it will greatly simplify matters to be reasonably certain about what the contract is doing. – Rob Hitchens - B9lab Jul 9 '17 at 20:09
  • Cool... I will look into that... I suspected that it might be something with my test code... so it will be good to see if I can get remix working. – Frank Blau Jul 9 '17 at 20:17
  • I still can't get this test script to work: – Frank Blau Jul 13 '17 at 10:35

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.