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? – Mikhail Vladimirov Apr 9 '19 at 14:43
  • Just evaluate it locally. – Paul Apr 9 '19 at 20:45
  • Then, see my answer below. – Mikhail Vladimirov Apr 9 '19 at 20:46

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.

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

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.