ETH Price: $2,053.32 (-0.38%)

Transaction Decoder

Block:
6865231 at Dec-11-2018 05:53:29 AM +UTC
Transaction Fee:
0.005579082001859694 ETH $11.46
Gas Used:
1,859,694 Gas / 3.000000001 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x00000000...438691c04
0x033C9C27...E63bFA032
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x0ccedE5F...8e7Caf861
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x12526AcB...ACDd90216
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x12989c40...B250c6e61
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x14B6a907...6c1980c7d
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x1F8d813B...4af856255
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x254162A2...E58e3F72b
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x25AA810F...C93FfA813
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x2d01B7c4...76A9FF727
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x309ae9Fc...73b4005c8
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x379475f7...47D5B26E5
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x4034Ba3f...17FF6e196
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x43F1B84e...25106867f
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x4faF6240...60D7F2bDd
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x512327B4...09655b925
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x53e7619A...5149ACfa3
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x5684FDe4...a0E894FF0
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x573EDdf8...ECe914f88
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x5Aa4e186...fF48D4E45
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x5c0C2E51...97b816A5f
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x6A50008F...1ABf7Cf94
4.665471215092772864 Eth
Nonce: 1716
4.65989213309091317 Eth
Nonce: 1717
0.005579082001859694
0x6e02dB8D...1588d5899
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x6E73fD83...5b74D00a8
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x7098EfDc...84B6aCE0F
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x71Cc3c16...7E56c3024
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x74e2DCb1...D474d7C12
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x7aBe7677...3feB4F89c
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x7E718798...B392E8168
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x7f0f9a47...774aF1327
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x81CDDaf6...eaAbF6ED6
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x8F644541...E2b2DA65A
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x994CBF71...6c3AbBB4d
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x9c14B4FF...712a3C499
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0x9Ff4531b...a1f56A0CC
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xA51efbbf...068cEBB65
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xACd1e562...01B3fdBdb
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
(MiningPoolHub: Old Address)
15,292.041049429818990173 Eth15,292.046628511820849867 Eth0.005579082001859694
0xB70b9570...55D04Dbe4
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xB71B7a60...31d7B5Ad5
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xBd5E622e...C0714250a
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xC5FE94b1...2954180F9
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xc9c47d85...a798485a4
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xd63d7EaA...937832d26
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xd80461DD...1ef9D8e97
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xda2103E0...3708c8Ca8
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xE1C6eEb3...d2fDB1Fe8
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xE428C0E0...063C398cE
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xE872BB3b...161484ab9
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xf184B9Da...555c4c512
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xF57Aaa42...a3E403E3C
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xf9314A5d...c4c096c6B
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551
0xfa9cb973...9473050b8
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 41418913446122256543177627431469775010672191485719551

Execution Trace

GasToken2.mint( value=50 )
  • 0xc5fe94b1346ac4dd7a5202e49e39c942954180f9.756eb3f8( )
  • 0xd63d7eaac96235cbecfea6d1a3dd5cb937832d26.756eb3f8( )
  • 0xd80461dd1aa9b3920730c5c28257a161ef9d8e97.756eb3f8( )
  • 0x12526acb4ccf1e44fcd3131a47ced1dacdd90216.756eb3f8( )
  • 0x7f0f9a4731b6548c5d60e11f22b8a89774af1327.756eb3f8( )
  • 0x994cbf714673670dba6d569402797d26c3abbb4d.756eb3f8( )
  • 0x573eddf82d62739f044139315d65c6aece914f88.756eb3f8( )
  • 0x12989c4087a5e750d147f806c9e48c4b250c6e61.756eb3f8( )
  • 0x254162a2d4ea92eb317fd4af9092a96e58e3f72b.756eb3f8( )
  • 0x4034ba3f4c0943b0e9730f88d37708f17ff6e196.756eb3f8( )
  • 0x5684fde433a0f9f3fc4935c61d2dd62a0e894ff0.756eb3f8( )
  • 0xb70b9570f20cd0e93c387b14429a7f155d04dbe4.756eb3f8( )
  • 0x43f1b84e101cb36505a4643c342380725106867f.756eb3f8( )
  • 0x309ae9fcdda3072e03fbabacf88ec3673b4005c8.756eb3f8( )
  • 0x74e2dcb13342df0bc92b7f10f540834d474d7c12.756eb3f8( )
  • 0xf184b9da7779a9afd890e5fdedf0da3555c4c512.756eb3f8( )
  • 0xc9c47d85a8ee5ab59550f395e22a7eca798485a4.756eb3f8( )
  • 0xacd1e5622950d672c3494f327fe6b4001b3fdbdb.756eb3f8( )
  • 0x5aa4e186603e69af601d164f4f145f5ff48d4e45.756eb3f8( )
  • 0xe872bb3bdf2af2d63599f42908279be161484ab9.756eb3f8( )
  • 0x033c9c27f7286950f6f3da711798125e63bfa032.756eb3f8( )
  • 0x5c0c2e514b560eb4544221eab8cd09e97b816a5f.756eb3f8( )
  • 0x6e73fd834ad33ef340b8e7a11bd22ca5b74d00a8.756eb3f8( )
  • 0x8f6445411cdf342dd53ff462297b4ede2b2da65a.756eb3f8( )
  • 0x53e7619a300b5c2e34c08a9d3327c9b5149acfa3.756eb3f8( )
  • 0x14b6a9073788e96cddaeae43e11f4666c1980c7d.756eb3f8( )
  • 0xda2103e0cad69ae3a5efebf2551fbc73708c8ca8.756eb3f8( )
  • 0x7abe767787d0e160d734f7d2971a01f3feb4f89c.756eb3f8( )
  • 0xe428c0e0e0aa3822708c914d4789a7a063c398ce.756eb3f8( )
  • 0xa51efbbf7c7a765a49f4577a774b612068cebb65.756eb3f8( )
  • 0x9c14b4ffe27f4e164436fe22703a94b712a3c499.756eb3f8( )
  • 0xfa9cb9739343df952b1a2a7487d090d9473050b8.756eb3f8( )
  • 0x7e71879816066e3fabb468f79a32deab392e8168.756eb3f8( )
  • 0x379475f7a10c3fc75eeadb058ad971e47d5b26e5.756eb3f8( )
  • 0x2d01b7c4dc75a7d34303623dc2d17ad76a9ff727.756eb3f8( )
  • 0x9ff4531b91bf6389e936d7e0092ffb9a1f56a0cc.756eb3f8( )
  • 0xf9314a5d67832614662235215dcded1c4c096c6b.756eb3f8( )
  • 0x1f8d813bc973092481fda94760d51bf4af856255.756eb3f8( )
  • 0x25aa810fd5c2584e201ee5ba727499ac93ffa813.756eb3f8( )
  • 0x0ccede5fa3a7c281208d924ea3dfb038e7caf861.756eb3f8( )
  • 0x7098efdcafb9b13ba12eb7a9d70b03e84b6ace0f.756eb3f8( )
  • 0xb71b7a602e4e3e39efda900a9cce57531d7b5ad5.756eb3f8( )
  • 0xf57aaa42bf661f794c78a04d350ab1ca3e403e3c.756eb3f8( )
  • 0x81cddaf621abbe01f8361a1331adb06eaabf6ed6.756eb3f8( )
  • 0x4faf6240e8a461dd5b2b426162eeed060d7f2bdd.756eb3f8( )
  • 0xbd5e622eabe43c6881a738569f64803c0714250a.756eb3f8( )
  • 0x6e02db8dad87361ce8cbd62a5feedfb1588d5899.756eb3f8( )
  • 0xe1c6eeb34cf7c7c19473cf723d30c4dd2fdb1fe8.756eb3f8( )
  • 0x71cc3c16f3ee3bb78664b7bdb3164197e56c3024.756eb3f8( )
  • 0x512327b4ca1d29c72016d4d39ddde0109655b925.756eb3f8( )
    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;
        }
    }