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?