1

block builders! I have trouble testing the return value from my contract, because the return uint value is always a "transaction" object (I actually don't really know what that mean)

Here is the overall picture of what I'm doing:

I try to create a bank contract that allowing client to enroll to the bank, making deposit and withdraw the deposit. In order to check if the client really enroll successfully, I put 5 ether to the newly enrolled client.

I firstly use await and async in the TestContracts.js to avoid nested callback, but the testing failed since the return value was a transaction object instead of uint

Then, I take a different approach using promise.then. However, it's even more weird, because the assert function was not being called at all, so the test always passed given any expected value.

Implementation of Bank contract:

contract Bank {
struct Customer {
    address _address; // address of customer
    uint deposit;
}

address owner;
mapping(address => Customer) public customerList;
uint customerCounter;

constructor() public payable {
    require(msg.value == 30 ether, "Initial funding of 30 ether required for rewards");
    /* Set the owner to the creator of this contract */
    owner = msg.sender;
    customerCounter = 0;
}

function enroll() public returns(uint){
    customerList[msg.sender].deposit = 5;
    customerList[msg.sender]._address = msg.sender;
    customerCounter++;

    return customerList[msg.sender].deposit;
}

Implementation of TestContracts.js using async and await

contract("Test", function(accounts) {
console.log("total accounts: ",accounts);
const alice = accounts[1];
const bob = accounts[2];
const charlie = accounts[3];
it("add 1 people to the bank", async ()=>{
    const bank = await Bank.deployed();
    const aliceBalance = await bank.enroll({from:alice});

    assert.equal(aliceBalance, 5, "initial balance is incorrect");
})

Implementation of TestContracts.js using Promise

contract("Test", function(accounts) {
console.log("total accounts: ",accounts);
const alice = accounts[1];
const bob = accounts[2];
const charlie = accounts[3];
it("add 1 people to the bank", function(){
    Bank.deployed().then(function(bank){
        return bank.enroll({from:alice})
    }).then(function(balance){
        assert.equal(aliceBalance, 0, "initial balance is incorrect");
    });
    // const aliceBalance = await bank.enroll({from:alice});
})

1 Answer 1

3

You can't get the return data from transactions. It's not included in the tx receipt, which is why calling enroll() returns the tx object instead of the data. If you want to get the data it returns, you have to do a call instead of a transaction, using await bank.enroll.call({from:alice}). This however wont actually change any state variables of course.

3
  • Thank you! What's a transaction receipt? Does it define what can be returned and what can't be?
    – Wei
    Commented Dec 31, 2018 at 16:23
  • The tx receipt is essentially the record of the outcome of a transaction. The gas used, contract created, succeed/fail status, logs, etc. The tx receipt of every transaction in a block is stored in the receipt tree in the receiptRoot of each block header. It let's you trustlessly receive tx outcome with only the headers
    – natewelch_
    Commented Dec 31, 2018 at 16:38
  • 1
    omg, thank you so much flygoing. Unfortunately, I can not upvote your answer, but only accept since I do not have enough credit for upvoting. Really thank you!!
    – Wei
    Commented Dec 31, 2018 at 16:41

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.