Transaction Hash:
Block:
9597879 at Mar-03-2020 11:22:26 AM +UTC
Transaction Fee:
0.001545672403297256 ETH
$3.13
Gas Used:
1,641,364 Gas / 0.941699954 Gwei
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x00000000...438691c04 | |||||
| 0x000000Cc...35fa98A05 |
0.028405837613928055 Eth
Nonce: 11
|
0.026860165210630799 Eth
Nonce: 12
| 0.001545672403297256 | ||
| 0x0552fB44...A593eEa26 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x0611B075...42966F332 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x0fbdA16a...0CC1617Ca |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x11425739...C4CB00d6d |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x1273fB0D...148724e68 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x19482033...d2f0f51f3 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x1EC61E6D...b328Fc990 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x226D36c5...0deBA4e94 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x27d83AC4...931a43b6f |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x34cca383...7a957B446 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x3D1CE931...86BC4b8FE |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x40409B36...7Daa8e218 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x4575ac9b...08E7a7D4D |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x45D10DbA...44F481729 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x5Bc1D5f2...485173753 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x62b23196...ab4318669 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x637c0d46...AbAE22026 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x655262bb...Fc8d342DD |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x71FaB6ef...B4139Ce1a |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x76E37A97...3287B7C00 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x77EE16Da...4487Fd268 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x7C8C2D91...8254009de |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x8613F5c7...795596E19 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x8B13dD2f...9802D5078 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x8e0017d6...75e0e755B |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x904a9c2A...329bFC299 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x9a8AF717...416688581 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0x9c155Cd5...84ba49aEb |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
|
0xb2930B35...e543a0347
Miner
| (MiningPoolHub: Old Address) | 1,204.02077879136519573 Eth | 1,204.022324463768492986 Eth | 0.001545672403297256 | |
| 0xb3e38cCE...07C928f0F |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xB42144eD...e78506Fc6 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xBfc876eD...17C0dF42f |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xcc5D5557...E61a85Ae5 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xCC766E7e...C325C9B8E |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xD27d648c...e5C9C7e0f |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xd38519fD...8a55A81De |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xDdD0Fa3f...d9Cd1c090 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xdEed261C...B8c66c00B |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xDEf0793e...60a0E3FBC |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xdFb98780...ee54119D8 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xe38fcdB1...2338BaBf2 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xeAA74F1C...816a52529 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xEC7B66fe...9B2660460 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xeD5a85A5...19B6cba53 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xF8Df94b0...22C7A2232 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
|
Execution Trace
GasToken2.mint( value=44 )
-
0xcc766e7e7f4ebb46d551c420c4fa1e7c325c9b8e.756eb3f8( ) -
0xf8df94b07ec8a484ff8ec637d25220522c7a2232.756eb3f8( ) -
0xe38fcdb1d8637f3b2dfc3cfd9d0b7eb2338babf2.756eb3f8( ) -
0x904a9c2ae090463059e8a8b44abf7bb329bfc299.756eb3f8( ) -
0xddd0fa3f074b8ac7cddc0b19e28a603d9cd1c090.756eb3f8( ) -
0x8613f5c7d1176be55c6ea5973d08425795596e19.756eb3f8( ) -
0x71fab6ef9fd0388b610b5e88b034d5bb4139ce1a.756eb3f8( ) -
0x655262bb0286aeb5db402a71b855a66fc8d342dd.756eb3f8( ) -
0x4575ac9b7be2b9595b7e3847a939eb408e7a7d4d.756eb3f8( ) -
0x1273fb0de16e6494eef777698094239148724e68.756eb3f8( ) -
0x1ec61e6d9253877b97d2a1155396123b328fc990.756eb3f8( ) -
0x0611b075096105cf114aedb63d905b542966f332.756eb3f8( ) -
0xec7b66fe85251875f5221a568c5dd629b2660460.756eb3f8( ) -
0xcc5d555791260fd881569ceb8dcc028e61a85ae5.756eb3f8( ) -
0x76e37a972a232c8faec09e36c83f4193287b7c00.756eb3f8( ) -
0x40409b36015fb94189df26faaa19b607daa8e218.756eb3f8( ) -
0x5bc1d5f296cdaac7366427dac289730485173753.756eb3f8( ) -
0xb42144ed6454756f28c0f1184bb978be78506fc6.756eb3f8( ) -
0x9a8af7171a43915da25b9ce205206ec416688581.756eb3f8( ) -
0xdef0793e6c8358ae6b80feaf244e91060a0e3fbc.756eb3f8( ) -
0x0552fb44076a51a4bcae720d3baf40ea593eea26.756eb3f8( ) -
0x77ee16da4b312e6082227724222c6014487fd268.756eb3f8( ) -
0x194820330c870a5936a71142e80b161d2f0f51f3.756eb3f8( ) -
0x8b13dd2fac0d4b8eb42de93545c44789802d5078.756eb3f8( ) -
0xed5a85a5b173ab7cb27230b401487d619b6cba53.756eb3f8( ) -
0xdfb98780d118b5f43adbdeda3770c04ee54119d8.756eb3f8( ) -
0xd38519fda79fb47aaadda4809ab2d0e8a55a81de.756eb3f8( ) -
0x34cca383789db123fc8a93ccbec91217a957b446.756eb3f8( ) -
0xb3e38ccea38caf59c4759cb7785ea9907c928f0f.756eb3f8( ) -
0x9c155cd580aa7902ec2f86b35488f0e84ba49aeb.756eb3f8( ) -
0x7c8c2d91c4052b189e6ef681bfdea8e8254009de.756eb3f8( ) -
0x637c0d4645f09533660cfd31f574c65abae22026.756eb3f8( ) -
0xd27d648c856e219a9f7e70f16d19011e5c9c7e0f.756eb3f8( ) -
0xdeed261c96490c7cb6176cbe7118962b8c66c00b.756eb3f8( ) -
0x27d83ac4d8274ee0d934d439838df2a931a43b6f.756eb3f8( ) -
0x11425739d385a611bc6e78d7103b466c4cb00d6d.756eb3f8( ) -
0xeaa74f1c5457c2309af2ee47604470d816a52529.756eb3f8( ) -
0xbfc876ed4ab6eee10e289488dc5ff6e17c0df42f.756eb3f8( ) -
0x3d1ce9316cc05a55bb7c26952f8c74b86bc4b8fe.756eb3f8( ) -
0x8e0017d6a021c7ec51907d26aa61c6775e0e755b.756eb3f8( ) -
0x45d10dba23e4fc893776045186edcd544f481729.756eb3f8( ) -
0x62b2319642a537ba81bf1099058fa7fab4318669.756eb3f8( ) -
0x226d36c58962ed04970759a658519660deba4e94.756eb3f8( ) -
0x0fbda16a13ddf257be94a67b61e0c000cc1617ca.756eb3f8( )
mint[GasToken2 (ln:219)]
makeChild[GasToken2 (ln:221)]
pragma solidity ^0.4.10;
contract GasToken2 {
//////////////////////////////////////////////////////////////////////////
// RLP.sol
// Due to some unexplained bug, we get a slightly different bytecode if
// we use an import, and are then unable to verify the code in Etherscan
//////////////////////////////////////////////////////////////////////////
uint256 constant ADDRESS_BYTES = 20;
uint256 constant MAX_SINGLE_BYTE = 128;
uint256 constant MAX_NONCE = 256**9 - 1;
// count number of bytes required to represent an unsigned integer
function count_bytes(uint256 n) constant internal returns (uint256 c) {
uint i = 0;
uint mask = 1;
while (n >= mask) {
i += 1;
mask *= 256;
}
return i;
}
function mk_contract_address(address a, uint256 n) constant internal returns (address rlp) {
/*
* make sure the RLP encoding fits in one word:
* total_length 1 byte
* address_length 1 byte
* address 20 bytes
* nonce_length 1 byte (or 0)
* nonce 1-9 bytes
* ==========
* 24-32 bytes
*/
require(n <= MAX_NONCE);
// number of bytes required to write down the nonce
uint256 nonce_bytes;
// length in bytes of the RLP encoding of the nonce
uint256 nonce_rlp_len;
if (0 < n && n < MAX_SINGLE_BYTE) {
// nonce fits in a single byte
// RLP(nonce) = nonce
nonce_bytes = 1;
nonce_rlp_len = 1;
} else {
// RLP(nonce) = [num_bytes_in_nonce nonce]
nonce_bytes = count_bytes(n);
nonce_rlp_len = nonce_bytes + 1;
}
// [address_length(1) address(20) nonce_length(0 or 1) nonce(1-9)]
uint256 tot_bytes = 1 + ADDRESS_BYTES + nonce_rlp_len;
// concatenate all parts of the RLP encoding in the leading bytes of
// one 32-byte word
uint256 word = ((192 + tot_bytes) * 256**31) +
((128 + ADDRESS_BYTES) * 256**30) +
(uint256(a) * 256**10);
if (0 < n && n < MAX_SINGLE_BYTE) {
word += n * 256**9;
} else {
word += (128 + nonce_bytes) * 256**9;
word += n * 256**(9 - nonce_bytes);
}
uint256 hash;
assembly {
let mem_start := mload(0x40) // get a pointer to free memory
mstore(0x40, add(mem_start, 0x20)) // update the pointer
mstore(mem_start, word) // store the rlp encoding
hash := sha3(mem_start,
add(tot_bytes, 1)) // hash the rlp encoding
}
// interpret hash as address (20 least significant bytes)
return address(hash);
}
//////////////////////////////////////////////////////////////////////////
// Generic ERC20
//////////////////////////////////////////////////////////////////////////
// owner -> amount
mapping(address => uint256) s_balances;
// owner -> spender -> max amount
mapping(address => mapping(address => uint256)) s_allowances;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
// Spec: Get the account balance of another account with address `owner`
function balanceOf(address owner) public constant returns (uint256 balance) {
return s_balances[owner];
}
function internalTransfer(address from, address to, uint256 value) internal returns (bool success) {
if (value <= s_balances[from]) {
s_balances[from] -= value;
s_balances[to] += value;
Transfer(from, to, value);
return true;
} else {
return false;
}
}
// Spec: Send `value` amount of tokens to address `to`
function transfer(address to, uint256 value) public returns (bool success) {
address from = msg.sender;
return internalTransfer(from, to, value);
}
// Spec: Send `value` amount of tokens from address `from` to address `to`
function transferFrom(address from, address to, uint256 value) public returns (bool success) {
address spender = msg.sender;
if(value <= s_allowances[from][spender] && internalTransfer(from, to, value)) {
s_allowances[from][spender] -= value;
return true;
} else {
return false;
}
}
// Spec: Allow `spender` to withdraw from your account, multiple times, up
// to the `value` amount. If this function is called again it overwrites the
// current allowance with `value`.
function approve(address spender, uint256 value) public returns (bool success) {
address owner = msg.sender;
if (value != 0 && s_allowances[owner][spender] != 0) {
return false;
}
s_allowances[owner][spender] = value;
Approval(owner, spender, value);
return true;
}
// Spec: Returns the `amount` which `spender` is still allowed to withdraw
// from `owner`.
// What if the allowance is higher than the balance of the `owner`?
// Callers should be careful to use min(allowance, balanceOf) to make sure
// that the allowance is actually present in the account!
function allowance(address owner, address spender) public constant returns (uint256 remaining) {
return s_allowances[owner][spender];
}
//////////////////////////////////////////////////////////////////////////
// GasToken specifics
//////////////////////////////////////////////////////////////////////////
uint8 constant public decimals = 2;
string constant public name = "Gastoken.io";
string constant public symbol = "GST2";
// We build a queue of nonces at which child contracts are stored. s_head is
// the nonce at the head of the queue, s_tail is the nonce behind the tail
// of the queue. The queue grows at the head and shrinks from the tail.
// Note that when and only when a contract CREATEs another contract, the
// creating contract's nonce is incremented.
// The first child contract is created with nonce == 1, the second child
// contract is created with nonce == 2, and so on...
// For example, if there are child contracts at nonces [2,3,4],
// then s_head == 4 and s_tail == 1. If there are no child contracts,
// s_head == s_tail.
uint256 s_head;
uint256 s_tail;
// totalSupply gives the number of tokens currently in existence
// Each token corresponds to one child contract that can be SELFDESTRUCTed
// for a gas refund.
function totalSupply() public constant returns (uint256 supply) {
return s_head - s_tail;
}
// Creates a child contract that can only be destroyed by this contract.
function makeChild() internal returns (address addr) {
assembly {
// EVM assembler of runtime portion of child contract:
// ;; Pseudocode: if (msg.sender != 0x0000000000b3f879cb30fe243b4dfee438691c04) { throw; }
// ;; suicide(msg.sender)
// PUSH15 0xb3f879cb30fe243b4dfee438691c04 ;; hardcoded address of this contract
// CALLER
// XOR
// PC
// JUMPI
// CALLER
// SELFDESTRUCT
// Or in binary: 6eb3f879cb30fe243b4dfee438691c043318585733ff
// Since the binary is so short (22 bytes), we can get away
// with a very simple initcode:
// PUSH22 0x6eb3f879cb30fe243b4dfee438691c043318585733ff
// PUSH1 0
// MSTORE ;; at this point, memory locations mem[10] through
// ;; mem[31] contain the runtime portion of the child
// ;; contract. all that's left to do is to RETURN this
// ;; chunk of memory.
// PUSH1 22 ;; length
// PUSH1 10 ;; offset
// RETURN
// Or in binary: 756eb3f879cb30fe243b4dfee438691c043318585733ff6000526016600af3
// Almost done! All we have to do is put this short (31 bytes) blob into
// memory and call CREATE with the appropriate offsets.
let solidity_free_mem_ptr := mload(0x40)
mstore(solidity_free_mem_ptr, 0x00756eb3f879cb30fe243b4dfee438691c043318585733ff6000526016600af3)
addr := create(0, add(solidity_free_mem_ptr, 1), 31)
}
}
// Mints `value` new sub-tokens (e.g. cents, pennies, ...) by creating `value`
// new child contracts. The minted tokens are owned by the caller of this
// function.
function mint(uint256 value) public {
for (uint256 i = 0; i < value; i++) {
makeChild();
}
s_head += value;
s_balances[msg.sender] += value;
}
// Destroys `value` child contracts and updates s_tail.
//
// This function is affected by an issue in solc: https://github.com/ethereum/solidity/issues/2999
// The `mk_contract_address(this, i).call();` doesn't forward all available gas, but only GAS - 25710.
// As a result, when this line is executed with e.g. 30000 gas, the callee will have less than 5000 gas
// available and its SELFDESTRUCT operation will fail leading to no gas refund occurring.
// The remaining ~29000 gas left after the call is enough to update s_tail and the caller's balance.
// Hence tokens will have been destroyed without a commensurate gas refund.
// Fortunately, there is a simple workaround:
// Whenever you call free, freeUpTo, freeFrom, or freeUpToFrom, ensure that you pass at least
// 25710 + `value` * (1148 + 5722 + 150) gas. (It won't all be used)
function destroyChildren(uint256 value) internal {
uint256 tail = s_tail;
// tail points to slot behind the last contract in the queue
for (uint256 i = tail + 1; i <= tail + value; i++) {
mk_contract_address(this, i).call();
}
s_tail = tail + value;
}
// Frees `value` sub-tokens (e.g. cents, pennies, ...) belonging to the
// caller of this function by destroying `value` child contracts, which
// will trigger a partial gas refund.
// You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
// when calling this function. For details, see the comment above `destroyChilden`.
function free(uint256 value) public returns (bool success) {
uint256 from_balance = s_balances[msg.sender];
if (value > from_balance) {
return false;
}
destroyChildren(value);
s_balances[msg.sender] = from_balance - value;
return true;
}
// Frees up to `value` sub-tokens. Returns how many tokens were freed.
// Otherwise, identical to free.
// You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
// when calling this function. For details, see the comment above `destroyChilden`.
function freeUpTo(uint256 value) public returns (uint256 freed) {
uint256 from_balance = s_balances[msg.sender];
if (value > from_balance) {
value = from_balance;
}
destroyChildren(value);
s_balances[msg.sender] = from_balance - value;
return value;
}
// Frees `value` sub-tokens owned by address `from`. Requires that `msg.sender`
// has been approved by `from`.
// You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
// when calling this function. For details, see the comment above `destroyChilden`.
function freeFrom(address from, uint256 value) public returns (bool success) {
address spender = msg.sender;
uint256 from_balance = s_balances[from];
if (value > from_balance) {
return false;
}
mapping(address => uint256) from_allowances = s_allowances[from];
uint256 spender_allowance = from_allowances[spender];
if (value > spender_allowance) {
return false;
}
destroyChildren(value);
s_balances[from] = from_balance - value;
from_allowances[spender] = spender_allowance - value;
return true;
}
// Frees up to `value` sub-tokens owned by address `from`. Returns how many tokens were freed.
// Otherwise, identical to `freeFrom`.
// You should ensure that you pass at least 25710 + `value` * (1148 + 5722 + 150) gas
// when calling this function. For details, see the comment above `destroyChilden`.
function freeFromUpTo(address from, uint256 value) public returns (uint256 freed) {
address spender = msg.sender;
uint256 from_balance = s_balances[from];
if (value > from_balance) {
value = from_balance;
}
mapping(address => uint256) from_allowances = s_allowances[from];
uint256 spender_allowance = from_allowances[spender];
if (value > spender_allowance) {
value = spender_allowance;
}
destroyChildren(value);
s_balances[from] = from_balance - value;
from_allowances[spender] = spender_allowance - value;
return value;
}
}