1

I want to deploy and to execute ERC-20 contract on geth with non-interactive scripts. But, it seems that non-interactive scripts and console shows different results.

Enviroment

  • ubuntu 18.04(docker container)
  • geth 1.9.2-stable
    • as a private network
  • solc 0.5.11+commit.22be8592.Linux.g++

my genesis.json is like followings;

{
    "coinbase": "0x0000000000000000000000000000000000000001",
    "difficulty": "0x400",
    "extraData": "",
    "gasLimit": "0xffffffff",
    "nonce": "0x0000000000000042",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "alloc": {},
    "config": {
        "chainid": 2000,
            "homesteadBlock": 0,
            "eip150Block": 0,
            "eip155Block": 0,
            "eip158Block": 0,
            "byzantiumBlock": 0,
            "constantinopleBlock": 1,
            "petersburgBlock": 0
    }
}

My ERC-20 contract

pragma solidity ^0.5.9;
contract Widetoken {
  string public name = 'Widetoken';
  string public symbol = 'WIDE';
  uint public decimals = 18;

  uint public totalIssue;

  mapping(address => uint) public balances;
  mapping(address => mapping (address => uint)) internal allowed;

  constructor() public {
    uint _initialSupply = 10000;

    balances[msg.sender] = _initialSupply;
    totalIssue = _initialSupply;
  }

  function totalSupply() public view returns (uint) {
    return (totalIssue);
  }

  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value <= balances[msg.sender]);

    balances[msg.sender] -= _value;
    balances[_to] += _value;

    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  function transferFrom(address _from, address _to, uint _value) public returns (bool) {
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] -= _value;
    balances[_to] += _value;
    allowed[_from][msg.sender] -= _value;

    emit Transfer(_from, _to, _value);
    return true;
  }

  function approve(address _spender, uint _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;

    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint) {
    return allowed[_owner][_spender];
  }

  event Approval(address indexed owner, address indexed spender, uint value);
  event Transfer(address indexed from, address indexed to, uint value);
}

I generated widetoken.js like following;

echo var widetoken= >> widetoken.js
solc --optimize --combined-json abi,bin,interface widetoken.sol >> widetoken.js

Non-interactive script

I saved as test.js.

function mining(){
  miner.start(100)
  while(true){
    var nowblock = eth.blockNumber;
    admin.sleep(3)
    if(nowblock != eth.blockNumber){
      miner.stop()
      break;
    }
  }
}

function miningtx(txhash){
  while(true){
    mining()
    if(eth.getTransactionReceipt(txhash)) break;
  }
}

loadScript("widetoken.js")
var widetokenabi = JSON.parse(widetoken.contracts["widetoken.sol:Widetoken"].abi)
var widetokenbin = "0x"+widetoken.contracts["widetoken.sol:Widetoken"].bin
var widetokencnt = eth.contract(widetokenabi)
var deployTX = {"from": eth.accounts[0], "data": widetokenbin, "gas":569911}
personal.unlockAccount(eth.accounts[0], "")
var widetokeninstance = widetokencnt.new(deployTX)

miningtx(widetokeninstance.transactionHash)

widetokencnt = widetokencnt.at(widetokeninstance.address)

console.log(widetokencnt.balanceOf(eth.accounts[0]))
console.log(widetokencnt.balanceOf(eth.accounts[1]))
gas = widetokencnt.transfer.estimateGas(eth.accounts[1], 10, {"from": eth.accounts[0]})
personal.unlockAccount(eth.accounts[0], "")
tx = widetokencnt.transfer(eth.accounts[1], 10, {"from": eth.accounts[0], "gas":gas})

miningtx(tx)

console.log(widetokencnt.balanceOf(eth.accounts[0]))
console.log(widetokencnt.balanceOf(eth.accounts[1]))

Execute as a non-interactive script

I initialized a private network, created 2 accounts, and mined some blocks so that eth.account[1] gets some Ether. Then, I execute like followings;

geth --networkid 2000 --datadir eth_privnet --nousb js test.js

But, I get an error as gas required exceeds allowance (4261527341) or always failing transaction in estimating gas of transfer function. I also tested loadScript("test.js") in the geth javascript console and get the same error.

Then, I copied test.js and directly pasted to the geth javascript console. I can execute until the end of the script without errors.

When I load by loadScript, after getting the error, I can interact with contract via widetokeninstance. But, I cannot interact with widetokencnt. (widetokencnt.name() returns new BigNumber() not a base 16 number as a error.)

Are there any differences between the javascript console and non-interactive scripts?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.