I'm writing a token locker contract, code as following:

pragma solidity ^0.4.24;

import "./SafeMath.sol";
import "./ERC20.sol";

contract TokenLocker {
    using SafeMath for uint256;

    address public creator;
    address public owner;

    modifier onlyOwner {
        require(msg.sender == owner);

    constructor(address _creator, address _owner) public payable {
        creator = _creator;
        owner = _owner;

    function() payable public {
        emit Received(msg.sender, msg.value);

    function unlock() public returns(bool) {
        uint256 balance = address(this).balance;
        require(balance > 0, "No token available !");


        emit Unlock(owner, balance);

        return true;

    function getBalance() public view returns(uint256) {
        return address(this).balance;

    event Received(address from, uint256 amount);
    event Unlock(address to, uint256 amount);
contract TokenLockerFactory {
    address public creator;
    mapping(address => address) ownerLockers; // map owner-locker relation
    address[] private lockerList;

    function createLocker(address _owner, uint256 amount) public payable 
            returns(address locker) {
        locker = ownerLockers[_owner];

        if(locker == address(0)) {
            // Create new locker.
            locker = (new TokenLocker).value(amount)(msg.sender, _owner);
            ownerLockers[_owner] = locker;

            // Emit event.
            emit Created(locker, msg.sender, _owner);

    function getLocker(address _owner) public view returns(address) {
        return ownerLockers[_owner];

    function getLockersNumber() public view returns(uint256) {
        return lockerList.length;

When call createLocker, I can get a correct locker address return, but when I then call getLocker with the related _owner address, I always get a 00000000000000000000 return, even call getLockersNumber() to check lockerList but always get a 0 return.

What is the problem? anybody can help? thanks in advance.

  • How do you call createLocker? Do you publish transaction or just evaluate it locally? Commented Apr 9, 2019 at 14:43
  • Just evaluate it locally.
    – Paul
    Commented Apr 9, 2019 at 20:45
  • Then, see my answer below. Commented Apr 9, 2019 at 20:46

1 Answer 1


You need to invoke createLocker in transaction via send like this:

myContract.methods.createLocker(owner, amount).send ({from: ..., value: amount});

rather than via call. Then, to know address of new created Locker contract you need to check for Created events via myContract.events.Created.

When you invoke createLocker via call modifications made by the method are not persisted in blockchain, that's why subsequent calls cannot see them.

  • Thank you Mikhail, I'll take a try to see, will get back to let you know. thanks
    – Paul
    Commented Apr 9, 2019 at 20:45

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.