I'd like to call a function on another contract from my own contract but do not want to sign the transaction as a user but rather let the contract sign the transaction itself.

contract A

contract EtheremonLite {
    function initMonster(string _monsterName) public;
    function battle() public returns(uint256);
    function getName(address _monsterAddress) public view returns(string);
    function getNumWins(address _monsterAddress) public view returns(uint);
    function getNumLosses(address _monsterAddress) public view returns(uint);

contract B

contract Monster {
    string name;
    uint win;
    uint loss;
    event EmitName(string name);

    address constant public ethermonster = 0xf3259eec5b4a46748a1f608ec3d74b89058bb3ad;
    EtheremonLite monsters_contract;

    constructor() public {
        monsters_contract = EtheremonLite(ethermonster);        

    function create_moster(string monster_name) public returns (bool) {

    function get_monster_name() public {
        name = monsters_contract.getName(address(this));
        emit EmitName(name);

    function get_last_block_hash() public view returns(uint) {
        return uint(blockhash(block.number -1));

    function get_game_stats() public view returns(string) {
        win = monsters_contract.getNumWins(address(this));
        loss = monsters_contract.getNumLosses(address(this));
        return string(abi.encodePacked("win: ", win, " loss: ", loss));


    function check_attack() public view returns(uint) {
        uint result;
        uint _dice = get_last_block_hash();
        uint dice = _dice / 85;
        return dice % 3;

    function attack() public returns(uint256) {
        return monsters_contract.battle();   

I want to call the attack function internally without needing to confirm the transaction using metamask.

My goal is to win everytime I call battle. To do that I need to wait until the last blockhash is divisible by 3. So need to create a function that continuously checks for the previous block and if it is divisible by 3 then call battle and win the game.

Here is the battle function on that other smart contract:

   function battle() public returns(uint256){
       address challenger = msg.sender;
       require(monsters[challenger].created  && monsters[Ogre].created);
       bool challengerWins = false;

       uint battleRatio = monsters[Ogre].weight / monsters[challenger].weight;

       uint dice = uint(blockhash(block.number - 1));

       dice = dice / 85; // Divide the dice by 85 to add obfuscation
       if (dice % battleRatio == 0) {
           monsters[challenger].wins += 1;
           monsters[Ogre].losses += 1;
           challengerWins = true;
       else {
           monsters[challenger].losses += 1;
           monsters[Ogre].wins += 1;
       emit battleOutcome(challenger, challengerWins);

1 Answer 1


A contract can't just do something by itself; it needs to be invoked in a transaction. Transactions can only be sent by externally owned accounts (EOAs).

But you can write code in your contract like this:

function tryit() external {
    if (check_attack()) {

and then send a transaction every few seconds to call tryit(). You'll pay for a small amount of gas for each transaction, but the only time you'll call attack is when you're guaranteed to win.

  • Thanks for that. How does DAO work then if you contracts can't call each other without a user signing the transaction?
    – Cyzanfar
    Commented Apr 7, 2019 at 18:58
  • 1
    A user signs a transaction. :-) You'd have to look at the specific code, but I would imagine there's typically some function called execute that anyone can call when, e.g., a vote is complete, and it carries out the result of the vote.
    – user19510
    Commented Apr 7, 2019 at 18:59
  • Makes total sense. thanks for pointing that out!
    – Cyzanfar
    Commented Apr 7, 2019 at 19:11

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.